1 /*
2 Copyright (C) 2005, 2004, 2010, 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
32
33
34 #ifndef SRTPSYMCRYPTO_H
35 #define SRTPSYMCRYPTO_H
36
45 #include <stdint.h>
47
48 #ifndef SRTP_BLOCK_SIZE
49 #define SRTP_BLOCK_SIZE 16
50 #endif
51
57
78 public:
80
90
92
105 void encrypt(
const uint8_t* input, uint8_t* output );
106
119 bool setNewKey(
const uint8_t* key, int32_t keyLength);
120
137
156 void ctr_encrypt(
const uint8_t* input, uint32_t inputLen, uint8_t* output, uint8_t* iv );
157
174 void ctr_encrypt(uint8_t* data, uint32_t data_length, uint8_t* iv );
175
197
219
244
245 private:
249 };
250
251 #pragma GCC visibility push(default)
253 #pragma GCC visibility pop
254
255 /* Only SrtpSymCrypto functions define the MAKE_F8_TEST */
256 #ifdef MAKE_F8_TEST
257
258 #include <cstring>
259 #include <iostream>
260 #include <cstdio>
261
262 #if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32)
263 #include <windows.h>
264 #else
265 #include <arpa/inet.h>
266 #endif
267
268 using namespace std;
269
270 static void hexdump(const char* title, const unsigned char *s, int l)
271 {
272 int n=0;
273
274 if (s == NULL) return;
275
276 fprintf(stderr, "%s",title);
277 for( ; n < l ; ++n) {
278 if((n%16) == 0)
279 fprintf(stderr, "\n%04x",n);
280 fprintf(stderr, " %02x",s[n]);
281 }
282 fprintf(stderr, "\n");
283 }
284
285 /*
286 * The F8 test vectors according to RFC3711
287 */
288 static unsigned char salt[] = {0x32, 0xf2, 0x87, 0x0d};
289
290 static unsigned char iv[] = { 0x00, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5,
291 0x5c, 0x62, 0x15, 0x99, 0xd4, 0x62, 0x56, 0x4a};
292
293 static unsigned char key[]= { 0x23, 0x48, 0x29, 0x00, 0x84, 0x67, 0xbe, 0x18,
294 0x6c, 0x3d, 0xe1, 0x4a, 0xae, 0x72, 0xd6, 0x2c};
295
296 static unsigned char payload[] = {
297 0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x72, 0x61,
298 0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73,
299 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
300 0x6e, 0x65, 0x78, 0x74, 0x20, 0x62, 0x65, 0x73,
301 0x74, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67}; // 39 bytes
302
303 static unsigned char cipherText[] = {
304 0x01, 0x9c, 0xe7, 0xa2, 0x6e, 0x78, 0x54, 0x01,
305 0x4a, 0x63, 0x66, 0xaa, 0x95, 0xd4, 0xee, 0xfd,
306 0x1a, 0xd4, 0x17, 0x2a, 0x14, 0xf9, 0xfa, 0xf4,
307 0x55, 0xb7, 0xf1, 0xd4, 0xb6, 0x2b, 0xd0, 0x8f,
308 0x56, 0x2c, 0x0e, 0xef, 0x7c, 0x48, 0x02}; // 39 bytes
309
310 // static unsigned char rtpPacketHeader[] = {
311 // 0x80, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5,
312 // 0x5c, 0x62, 0x15, 0x99};
313
314 static unsigned char rtpPacket[] = {
315 0x80, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5,
316 0x5c, 0x62, 0x15, 0x99, // header
317 0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x72, 0x61, // payload
318 0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73,
319 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
320 0x6e, 0x65, 0x78, 0x74, 0x20, 0x62, 0x65, 0x73,
321 0x74, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67};
322 static uint32_t ROC = 0xd462564a;
323
325 {
328
330
331 /* Create the F8 IV (refer to chapter 4.1.2.2 in RFC 3711):
332 *
333 * IV = 0x00 || M || PT || SEQ || TS || SSRC || ROC
334 * 8Bit 1bit 7bit 16bit 32bit 32bit 32bit
335 * ------------\ /--------------------------------------------------
336 * XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
337 */
338
339 unsigned char derivedIv[16];
340 uint32_t* ui32p = (uint32_t*)derivedIv;
341
342 memcpy(derivedIv, rtpPacket, 12);
343 derivedIv[0] = 0;
344
345 // set ROC in network order into IV
346 ui32p[3] = htonl(ROC);
347
348 int32_t pad = 0;
349
350 if (memcmp(iv, derivedIv, 16) != 0) {
351 cerr << "Wrong IV constructed" << endl;
352 hexdump("derivedIv", derivedIv, 16);
353 hexdump("test vector Iv", iv, 16);
354 return -1;
355 }
356
357 aesCipher->
f8_deriveForIV(f8AesCipher, key,
sizeof(key), salt,
sizeof(salt));
358
359 // now encrypt the RTP payload data
360 aesCipher->
f8_encrypt(rtpPacket + 12,
sizeof(rtpPacket)-12+pad,
361 derivedIv, f8AesCipher);
362
363 // compare with test vector cipher data
364 if (memcmp(rtpPacket+12, cipherText, sizeof(rtpPacket)-12+pad) != 0) {
365 cerr << "cipher data mismatch" << endl;
366 hexdump("computed cipher data", rtpPacket+12, sizeof(rtpPacket)-12+pad);
367 hexdump("Test vcetor cipher data", cipherText, sizeof(cipherText));
368 return -1;
369 }
370
371 // Now decrypt the data to get the payload data again
372 aesCipher->
f8_encrypt(rtpPacket+12,
sizeof(rtpPacket)-12+pad, derivedIv, f8AesCipher);
373
374 // compare decrypted data with test vector payload data
375 if (memcmp(rtpPacket+12, payload, sizeof(rtpPacket)-12+pad) != 0) {
376 cerr << "payload data mismatch" << endl;
377 hexdump("computed payload data", rtpPacket+12, sizeof(rtpPacket)-12+pad);
378 hexdump("Test vector payload data", payload, sizeof(payload));
379 return -1;
380 }
381 return 0;
382 }
383 #endif
384
389 #endif
390
Implments the SRTP encryption modes as defined in RFC3711.
bool setNewKey(const uint8_t *key, int32_t keyLength)
Set new key.
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.
struct _f8_ctx F8_CIPHER_CTX
int processBlock(F8_CIPHER_CTX *f8ctx, const uint8_t *in, int32_t length, uint8_t *out)
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.
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.