1 /*
2 Copyright (C) 2005, 2004, 2012 Erik Eliasson, Johan Bilien, Werner Dittmann
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18 * In addition, as a special exception, the copyright holders give
19 * permission to link the code of portions of this program with the
20 * OpenSSL library under certain conditions as described in each
21 * individual source file, and distribute linked combinations
22 * including the two.
23 * You must obey the GNU General Public License in all respects
24 * for all of the code used other than OpenSSL. If you modify
25 * file(s) with this exception, you may extend this exception to your
26 * version of the file(s), but you are not obligated to do so. If you
27 * do not wish to do so, delete this exception statement from your
28 * version. If you delete this exception statement from all source
29 * files in the program, then also delete it here.
30 */
31
39
41
42 #include <gcrypt.h> // the include of gcrypt
43 #include <stdlib.h>
46
47 #include <stdio.h>
48
51 }
52
54 key(NULL), algorithm(algo) {
55
58 }
59
63 gcry_cipher_close(static_cast<gcry_cipher_hd_t>(
key));
66 delete[] (uint8_t*)
key;
67 }
69 }
70 }
71
72 static int twoFishInit = 0;
73
75
76 // release an existing key before setting a new one
79 gcry_cipher_close(static_cast<gcry_cipher_hd_t>(
key));
81 }
82
83 int algo = 0;
84 if (keyLength == 16) {
85 algo = GCRY_CIPHER_AES;
86 }
87 else if (keyLength == 32) {
88 algo = GCRY_CIPHER_AES256;
89 }
90 else {
91 return false;
92 }
93 gcry_cipher_hd_t tmp;
94 gcry_cipher_open(&tmp, algo, GCRY_CIPHER_MODE_ECB, 0);
96 gcry_cipher_setkey(static_cast<gcry_cipher_hd_t>(
key), k, keyLength);
97 }
99 if (!twoFishInit) {
101 twoFishInit = 1;
102 }
104 delete[] (uint8_t*)
key;
105
109 }
110 else
111 return false;
112
113 return true;
114 }
115
116
120 gcry_cipher_encrypt (static_cast<gcry_cipher_hd_t>(
key),
125 }
126 }
127
129 uint8_t* iv ) {
130 uint16_t ctr = 0;
131
133
135 //compute the cipher stream
136 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
137 iv[15] = (uint8_t)((ctr & 0x00FF));
138
140 }
142 // Treat the last bytes:
143 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
144 iv[15] = (uint8_t)((ctr & 0x00FF));
145
147 memcpy(&output[ctr*SRTP_BLOCK_SIZE], temp, length % SRTP_BLOCK_SIZE);
148 }
149 }
150
152 uint8_t* output, uint8_t* iv ) {
153
155 return;
156
157 uint16_t ctr = 0;
159
161 for ( ctr = 0; ctr < l; ctr++ ) {
162 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
163 iv[15] = (uint8_t)((ctr & 0x00FF));
164
167 *output++ = temp[i] ^ *input++;
168 }
169
170 }
172 if (l > 0) {
173 // Treat the last bytes:
174 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
175 iv[15] = (uint8_t)((ctr & 0x00FF));
176
178 for (int i = 0; i < l; i++ ) {
179 *output++ = temp[i] ^ *input++;
180 }
181 }
182 }
183
185
187 return;
188
189 uint16_t ctr = 0;
191
193 for (ctr = 0; ctr < l; ctr++ ) {
194 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
195 iv[15] = (uint8_t)((ctr & 0x00FF));
196
199 *data++ ^= temp[i];
200 }
201
202 }
204 if (l > 0) {
205 // Treat the last bytes:
206 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
207 iv[15] = (uint8_t)((ctr & 0x00FF));
208
210 for (int i = 0; i < l; i++ ) {
211 *data++ ^= temp[i];
212 }
213 }
214
215 }
216
218
219 f8_encrypt(data, data_length, const_cast<uint8_t*>(data), iv, f8Cipher);
220 }
221
222 #define MAX_KEYLEN 32
223
225 uint8_t* salt, int32_t saltLen) {
226
227 unsigned char *cp_in, *cp_in1, *cp_out;
228
231
233 return;
234
235 if (saltLen > keyLen)
236 return;
237 /*
238 * First copy the salt into the mask field, then fill with 0x55 to
239 * get a full key.
240 */
241 memcpy(saltMask, salt, saltLen);
242 memset(saltMask+saltLen, 0x55, keyLen-saltLen);
243
244 /*
245 * XOR the original key with the above created mask to
246 * get the special key.
247 */
248 cp_out = maskedKey;
250 cp_in1 = saltMask;
251 for (int i = 0; i < keyLen; i++) {
252 *cp_out++ = *cp_in++ ^ *cp_in1++;
253 }
254 /*
255 * Prepare the a new AES cipher with the special key to compute IV'
256 */
258 }
259
262
263 int offset = 0;
264
267
269
271 return;
272
273 /*
274 * Get memory for the derived IV (IV')
275 */
277 /*
278 * Use the derived IV encryption setup to encrypt the original IV to produce IV'.
279 */
281
282 f8ctx.
J = 0;
// initialize the counter
283 f8ctx.
S = S;
// get the key stream buffer
284
286
291 }
292 if (in_length > 0) {
294 }
295 }
296
298
299 int i;
300 const uint8_t *cp_in;
301 uint8_t* cp_in1, *cp_out;
302 uint32_t *ui32p;
303
304 /*
305 * XOR the previous key stream with IV'
306 * ( S(-1) xor IV' )
307 */
311 *cp_out++ ^= *cp_in++;
312 }
313 /*
314 * Now XOR (S(n-1) xor IV') with the current counter, then increment the counter
315 */
316 ui32p = (uint32_t *)f8ctx->
S;
317 ui32p[3] ^= htonl(f8ctx->
J);
319 /*
320 * Now compute the new key stream using encrypt
321 */
323 /*
324 * as the last step XOR the plain text with the key stream to produce
325 * the ciphertext.
326 */
327 cp_out = out;
328 cp_in = in;
330 for (i = 0; i < length; i++) {
331 *cp_out++ = *cp_in++ ^ *cp_in1++;
332 }
333 return length;
334 }
335
Implments the SRTP encryption modes as defined in RFC3711.
bool setNewKey(const uint8_t *key, int32_t keyLength)
Set new key.
Structure that contains a prepared Twofish key.
unsigned char Twofish_Byte
A Twofish_Byte must be an unsigned 8-bit integer.
int Twofish_initialise()
Initialise and test the Twofish implementation.
unsigned char * ivAccent
second IV
const int SrtpEncryptionAESF8
void get_ctr_cipher_stream(uint8_t *output, uint32_t length, uint8_t *iv)
Computes the cipher stream for AES CM mode.
const int SrtpEncryptionTWOF8
int processBlock(F8_CIPHER_CTX *f8ctx, const uint8_t *in, int32_t length, uint8_t *out)
const int SrtpEncryptionTWOCM
SrtpSymCrypto(int algo=SrtpEncryptionAESCM)
void ctr_encrypt(const uint8_t *input, uint32_t inputLen, uint8_t *output, uint8_t *iv)
Counter-mode encryption.
void f8_encrypt(const uint8_t *data, uint32_t dataLen, uint8_t *iv, SrtpSymCrypto *f8Cipher)
AES F8 mode encryption, in place.
unsigned char * S
Intermetiade buffer.
Class which implements SRTP AES cryptographic functions.
void Twofish_encrypt(Twofish_key *xkey, Twofish_Byte p[16], Twofish_Byte c[16])
Encrypt a single block of data.
int Twofish_prepare_key(Twofish_Byte key[], int key_len, Twofish_key *xkey)
Convert a cipher key to the internal form used for encryption and decryption.
void f8_deriveForIV(SrtpSymCrypto *f8Cipher, uint8_t *key, int32_t keyLen, uint8_t *salt, int32_t saltLen)
Derive a AES context to compute the IV'.
const int SrtpEncryptionAESCM
void encrypt(const uint8_t *input, uint8_t *output)
Encrypts the inpout to the output.