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
40 #include <stdlib.h>
41 #include <openssl/aes.h> // the include of openSSL
44 #include <string.h>
45 #include <stdio.h>
46
47 #if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32)
48 #include <windows.h>
49 #else
50 #include <arpa/inet.h>
51 #endif
52
54 }
55
57 key(NULL), algorithm(algo) {
58
59 setNewKey(k, keyLength);
60 }
61
65 memset(
key, 0,
sizeof(AES_KEY) );
66 }
69 }
70 delete[] (uint8_t*)
key;
72 }
73 }
74
75 static int twoFishInit = 0;
76
78 // release an existing key before setting a new one
80 delete[] (uint8_t*)
key;
81
82 if (!(keyLength == 16 || keyLength == 32)) {
83 return false;
84 }
86 key =
new uint8_t[
sizeof(AES_KEY)];
87 memset(
key, 0,
sizeof(AES_KEY) );
88 AES_set_encrypt_key(k, keyLength*8, (AES_KEY *)
key);
89 }
91 if (!twoFishInit) {
93 twoFishInit = 1;
94 }
98 }
99 else
100 return false;
101
102 return true;
103 }
104
105
108 AES_encrypt(input, output, (AES_KEY *)
key);
109 }
113 }
114 }
115
117 uint8_t* iv ) {
118 uint16_t ctr = 0;
120
122 //compute the cipher stream
123 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
124 iv[15] = (uint8_t)((ctr & 0x00FF));
125
127 }
129 // Treat the last bytes:
130 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
131 iv[15] = (uint8_t)((ctr & 0x00FF));
132
134 memcpy(&output[ctr*SRTP_BLOCK_SIZE], temp, length % SRTP_BLOCK_SIZE );
135 }
136 }
137
139 uint8_t* output, uint8_t* iv ) {
140
142 return;
143
144 uint16_t ctr = 0;
146
148 for (ctr = 0; ctr < l; ctr++ ) {
149 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
150 iv[15] = (uint8_t)((ctr & 0x00FF));
151
154 *output++ = temp[i] ^ *input++;
155 }
156
157 }
159 if (l > 0) {
160 // Treat the last bytes:
161 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
162 iv[15] = (uint8_t)((ctr & 0x00FF));
163
165 for (int i = 0; i < l; i++ ) {
166 *output++ = temp[i] ^ *input++;
167 }
168 }
169 }
170
172
174 return;
175
176 uint16_t ctr = 0;
178
180 for (ctr = 0; ctr < l; ctr++ ) {
181 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
182 iv[15] = (uint8_t)((ctr & 0x00FF));
183
186 *data++ ^= temp[i];
187 }
188
189 }
191 if (l > 0) {
192 // Treat the last bytes:
193 iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
194 iv[15] = (uint8_t)((ctr & 0x00FF));
195
197 for (int i = 0; i < l; i++ ) {
198 *data++ ^= temp[i];
199 }
200 }
201 }
202
205
206 f8_encrypt(data, data_length, const_cast<uint8_t*>(data), iv, f8Cipher);
207 }
208
209 #define MAX_KEYLEN 32
210
212 uint8_t* salt, int32_t saltLen) {
213
214 unsigned char *cp_in, *cp_in1, *cp_out;
215
218
220 return;
221
222 if (saltLen > keyLen)
223 return;
224 /*
225 * First copy the salt into the mask field, then fill with 0x55 to
226 * get a full key.
227 */
228 memcpy(saltMask, salt, saltLen);
229 memset(saltMask+saltLen, 0x55, keyLen-saltLen);
230
231 /*
232 * XOR the original key with the above created mask to
233 * get the special key.
234 */
235 cp_out = maskedKey;
237 cp_in1 = saltMask;
238 for (int i = 0; i < keyLen; i++) {
239 *cp_out++ = *cp_in++ ^ *cp_in1++;
240 }
241 /*
242 * Prepare the a new AES cipher with the special key to compute IV'
243 */
245 }
246
249
250
251 int offset = 0;
252
255
257
259 return;
260 /*
261 * Get memory for the derived IV (IV')
262 */
264 /*
265 * Use the derived IV encryption setup to encrypt the original IV to produce IV'.
266 */
268
269 f8ctx.
J = 0;
// initialize the counter
270 f8ctx.
S = S;
// get the key stream buffer
271
272 memset(f8ctx.
S, 0, SRTP_BLOCK_SIZE);
// initial value for key stream
273
274 while (in_length >= SRTP_BLOCK_SIZE) {
275 processBlock(&f8ctx, in+offset, SRTP_BLOCK_SIZE, out+offset);
278 }
279 if (in_length > 0) {
281 }
282 }
283
285
286 int i;
287 const uint8_t *cp_in;
288 uint8_t* cp_in1, *cp_out;
289 uint32_t *ui32p;
290
291 /*
292 * XOR the previous key stream with IV'
293 * ( S(-1) xor IV' )
294 */
298 *cp_out++ ^= *cp_in++;
299 }
300 /*
301 * Now XOR (S(n-1) xor IV') with the current counter, then increment the counter
302 */
303 ui32p = (uint32_t *)f8ctx->
S;
304 ui32p[3] ^= htonl(f8ctx->
J);
306 /*
307 * Now compute the new key stream using AES encrypt
308 */
310 /*
311 * as the last step XOR the plain text with the key stream to produce
312 * the ciphertext.
313 */
314 cp_out = out;
315 cp_in = in;
317 for (i = 0; i < length; i++) {
318 *cp_out++ = *cp_in++ ^ *cp_in1++;
319 }
320 return length;
321 }
322
323
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.