ccRTP 2.1.2
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SrtpSymCrypto.h
Go to the documentation of this file.
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>
46 #include <CryptoContext.h>
47 
48 #ifndef SRTP_BLOCK_SIZE
49 #define SRTP_BLOCK_SIZE 16
50 #endif
51 
52 typedef struct _f8_ctx {
53  unsigned char *S;
54  unsigned char *ivAccent;
55  uint32_t J;
57 
78 public:
80 
89  SrtpSymCrypto(uint8_t* key, int32_t key_length, int algo = SrtpEncryptionAESCM);
90 
92 
105  void encrypt( const uint8_t* input, uint8_t* output );
106 
119  bool setNewKey(const uint8_t* key, int32_t keyLength);
120 
136  void get_ctr_cipher_stream(uint8_t* output, uint32_t length, uint8_t* iv);
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 
196  void f8_deriveForIV(SrtpSymCrypto* f8Cipher, uint8_t* key, int32_t keyLen, uint8_t* salt, int32_t saltLen);
197 
218  void f8_encrypt(const uint8_t* data, uint32_t dataLen, uint8_t* iv, SrtpSymCrypto* f8Cipher);
219 
243  void f8_encrypt(const uint8_t* data, uint32_t dataLen, uint8_t* out, uint8_t* iv, SrtpSymCrypto* f8Cipher);
244 
245 private:
246  int processBlock(F8_CIPHER_CTX* f8ctx, const uint8_t* in, int32_t length, uint8_t* out);
247  void* key;
248  int32_t algorithm;
249 };
250 
251 #pragma GCC visibility push(default)
252 int testF8();
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 
324 int testF8()
325 {
327  SrtpSymCrypto* f8AesCipher = new SrtpSymCrypto(SrtpEncryptionAESF8);
328 
329  aesCipher->setNewKey(key, sizeof(key));
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.
Definition: SrtpSymCrypto.h:77
bool setNewKey(const uint8_t *key, int32_t keyLength)
Set new key.
unsigned char * ivAccent
second IV
Definition: SrtpSymCrypto.h:54
const int SrtpEncryptionAESF8
Definition: CryptoContext.h:36
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)
uint32_t J
Counter.
Definition: SrtpSymCrypto.h:55
int32_t algorithm
SrtpSymCrypto(int algo=SrtpEncryptionAESCM)
void ctr_encrypt(const uint8_t *input, uint32_t inputLen, uint8_t *output, uint8_t *iv)
Counter-mode encryption.
int testF8()
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.
Definition: SrtpSymCrypto.h:53
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
Definition: CryptoContext.h:35
void encrypt(const uint8_t *input, uint8_t *output)
Encrypts the inpout to the output.