1 /*
2 Copyright (C) 2004-2006 the Minisip Team
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
19 /* Copyright (C) 2004-2012
20 *
21 * Authors: Israel Abad <i_abad@terra.es>
22 * Erik Eliasson <eliasson@it.kth.se>
23 * Johan Bilien <jobi@via.ecp.fr>
24 * Joachim Orrblad <joachim@orrblad.com>
25 * Werner Dittmann <Werner.Dittmann@t-online.de>
26 */
27
28 #include <iostream>
29
30 #include <ccrtp-config.h>
31
32 #ifdef SRTP_SUPPORT
35 #endif
36
37 #include <commoncpp/config.h>
38 #include <commoncpp/export.h>
41
42 NAMESPACE_COMMONCPP
43
45 ssrcCtx(ssrc),
46 using_mki(false),mkiLength(0),mki(NULL), s_l(0),
47 replay_window(0),
48 master_key(NULL), master_key_length(0),
49 master_salt(NULL), master_salt_length(0),
50 n_e(0),k_e(NULL),n_a(0),k_a(NULL),n_s(0),k_s(NULL),
52 ekeyl(0), akeyl(0), skeyl(0),
53 macCtx(NULL), cipher(NULL), f8Cipher(NULL)
54 {}
55
56 #ifdef SRTP_SUPPORT
58 const int32 ealg,
59 const int32 aalg,
60 uint8* master_key,
61 int32 master_key_length,
62 uint8* master_salt,
63 int32 master_salt_length,
64 int32 ekeyl,
65 int32 akeyl,
66 int32 skeyl,
67 int32 tagLength):
68
69 ssrcCtx(ssrc),using_mki(false),mkiLength(0),mki(NULL),
70 replay_window(0), macCtx(NULL), cipher(NULL), f8Cipher(NULL)
71 {
77
80 memcpy(this->master_key, master_key, master_key_length);
81
84 memcpy(this->master_salt, master_salt, master_salt_length);
85
86 switch( ealg ) {
92 break;
93
96 // fall through
97
104 break;
105
108 // fall through
109
116 break;
117 }
118
119 switch( aalg ) {
123 this->tagLength = 0;
124 break;
125
131 break;
132 }
133 }
134
135 #endif
136
138
139 #ifdef SRTP_SUPPORT
142
143 if (master_key_length > 0) {
144 memset(master_key, 0, master_key_length);
145 master_key_length = 0;
147 }
148 if (master_salt_length > 0) {
149 memset(master_salt, 0, master_salt_length);
150 master_salt_length = 0;
152 }
157 }
162 }
167 }
171 }
175 }
177 switch(aalg) {
180 break;
181
184 break;
185 }
186 }
187 #endif
188
191 }
192
194 {
196 return;
197 }
198 #ifdef SRTP_SUPPORT
200
201 /* Compute the CM IV (refer to chapter 4.1.1 in RFC 3711):
202 *
203 * k_s XX XX XX XX XX XX XX XX XX XX XX XX XX XX
204 * SSRC XX XX XX XX
205 * index XX XX XX XX
206 * ------------------------------------------------------XOR
207 * IV XX XX XX XX XX XX XX XX XX XX XX XX XX XX 00 00
208 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
209 */
210 unsigned char iv[16];
211
216
217 // The shifts transform the ssrc and index into network order
218 iv[4] = ((ssrc >> 24) & 0xff) ^
k_s[4];
219 iv[5] = ((ssrc >> 16) & 0xff) ^
k_s[5];
220 iv[6] = ((ssrc >> 8) & 0xff) ^
k_s[6];
221 iv[7] = (ssrc & 0xff) ^
k_s[7];
222
225
226 iv[10] = ((index >> 24) & 0xff) ^
k_s[10];
227 iv[11] = ((index >> 16) & 0xff) ^
k_s[11];
228 iv[12] = ((index >> 8) & 0xff) ^
k_s[12];
229 iv[13] = (index & 0xff) ^
k_s[13];
230
231 iv[14] = iv[15] = 0;
232
233 cipher->ctr_encrypt(rtp, len, iv);
234 }
235
237
238 unsigned char iv[16];
239
240 // 4 bytes of the iv are zero
241 // the first byte of the RTP header is not used.
242 iv[0] = 0;
243 iv[1] = 0;
244 iv[2] = 0;
245 iv[3] = 0;
246
247 // Need the encryption flag
248 index = index | 0x80000000;
249
250 // set the index and the encrypt flag in network order into IV
251 iv[4] = index >> 24;
252 iv[5] = index >> 16;
253 iv[6] = index >> 8;
254 iv[7] = index;
255
256 // The fixed header follows and fills the rest of the IV
257 memcpy(iv+8, rtp, 8);
258
260 }
261 #endif
262 }
263
264 /* Warning: tag must have been initialized */
266 {
268 return;
269 }
270 #ifdef SRTP_SUPPORT
271 int32_t macL;
272
273 unsigned char temp[20];
274 const unsigned char* chunks[3];
275 unsigned int chunkLength[3];
276 uint32_t beIndex = htonl(index);
277
279 chunkLength[0] = len;
280
281 chunks[1] = (unsigned char *)&beIndex;
282 chunkLength[1] = 4;
283 chunks[2] = NULL;
284
285 switch (aalg) {
288 chunks, // data chunks to hash
289 chunkLength, // length of the data to hash
290 temp, &macL);
291 /* truncate the result */
293 break;
296 chunks, // data chunks to hash
297 chunkLength, // length of the data to hash
298 temp);
299 /* truncate the result */
301 break;
302 }
303 #endif
304 }
305
306 #ifdef SRTP_SUPPORT
307 /* used by the key derivation method */
308 static void computeIv(unsigned char* iv, uint8 label, uint8* master_salt)
309 {
310 //printf( "Key_ID: %llx\n", key_id );
311
312 /* compute the IV
313 key_id: XX XX XX XX XX XX XX
314 master_salt: XX XX XX XX XX XX XX XX XX XX XX XX XX XX
315 ------------------------------------------------------------ XOR
316 IV: XX XX XX XX XX XX XX XX XX XX XX XX XX XX 00 00
317 */
318
319 memcpy(iv, master_salt, 14);
320 iv[7] ^= label;
321
322 iv[14] = iv[15] = 0;
323 }
324 #endif
325
326 /* Derives the srtp session keys from the master key */
328 {
329 #ifdef SRTP_SUPPORT
330 uint8 iv[16];
331
332 // prepare AES cipher to compute derived keys.
333 cipher->setNewKey(master_key, master_key_length);
334 memset(master_key, 0, master_key_length);
335
336 // compute the session encryption key
337 uint8 label = 3;
338 computeIv(iv, label, master_salt);
340
341 // compute the session authentication key
342 label = 4;
343 computeIv(iv, label, master_salt);
345
346 // Initialize MAC context with the derived key
347 switch (aalg) {
350 break;
352 // Skein MAC uses number of bits as MAC size, not just bytes
354 break;
355 }
357
358 // compute the session salt
359 label = 5;
360 computeIv(iv, label, master_salt);
362 memset(master_salt, 0, master_salt_length);
363
364 // as last step prepare ciphers with derived key.
369 #endif
370 }
371
373 {
374 #ifdef SRTP_SUPPORT
376 /* No security policy, don't use the replay protection */
377 return true;
378 }
379
380 int64 delta =
s_l - index;
381 if (delta > 0) {
382 /* Packet not yet received*/
383 return true;
384 }
385 else {
387 /* Packet too old */
388 return false;
389 }
390 else {
392 /* Packet already received ! */
393 return false;
394 }
395 else {
396 /* Packet not yet received */
397 return true;
398 }
399 }
400 }
401 #else
402 return true;
403 #endif
404 }
405
407 {
408 #ifdef SRTP_SUPPORT
409 int64 delta = index -
s_l;
410
411 /* update the replay bitmask */
412 if( delta > 0 ){
415 }
416 else {
418 }
419 s_l = index;
420
421 #endif
422 }
423
425 {
426 #ifdef SRTP_SUPPORT
428 ssrc,
429 this->ealg, // encryption algo
430 this->aalg, // authentication algo
431 this->master_key, // Master Key
432 this->master_key_length, // Master Key length
433 this->master_salt, // Master Salt
434 this->master_salt_length, // Master Salt length
435 this->ekeyl, // encryption keyl
436 this->akeyl, // authentication key len
437 this->skeyl, // session salt len
438 this->tagLength); // authentication tag len
439
440 return pcc;
441 #else
442 return NULL;
443 #endif
444 }
445
446 END_NAMESPACE
447
Implments the SRTP encryption modes as defined in RFC3711.
void deriveSrtcpKeys()
Perform key derivation according to SRTP specification.
The implementation for a SRTCP cryptographic context.
int32 getTagLength() const
Get the length of the SRTP authentication tag in bytes.
CryptoContextCtrl(uint32 ssrc)
Constructor for empty SRTP cryptographic context.
uint32 master_salt_length
#define REPLAY_WINDOW_SIZE
void hmacSha1Ctx(void *ctx, const uint8_t *data, uint32_t data_length, uint8_t *mac, int32_t *mac_length)
Compute SHA1 HMAC.
const int SrtpEncryptionAESF8
void srtcpEncrypt(uint8 *rtp, size_t len, uint64 index, uint32 ssrc)
Perform SRTP encryption.
void * createSha1HmacContext(uint8_t *key, int32_t key_length)
Create and initialize a SHA1 HMAC context.
void macSkeinCtx(void *ctx, const uint8_t *data, uint32_t data_length, uint8_t *mac)
Compute Skein MAC.
void freeSkeinMacContext(void *ctx)
Free Skein MAC context.
void freeSha1HmacContext(void *ctx)
Free SHA1 HMAC context.
void * createSkeinMacContext(uint8_t *key, int32_t key_length, int32_t mac_length, SkeinSize_t skeinSize)
Create and initialize a Skein MAC context.
const int SrtpEncryptionTWOF8
Functions to compute SHA1 HAMAC.
const int SrtpEncryptionTWOCM
Function that provide Skein MAC support.
const int SrtpAuthenticationSkeinHmac
bool checkReplay(uint32 newSeqNumber)
Check for packet replay.
void srtcpAuthenticate(uint8 *rtp, size_t len, uint32 roc, uint8 *tag)
Compute the authentication tag.
const int SrtpEncryptionNull
const int SrtpAuthenticationSha1Hmac
Base elements for RTP stacks: constants, types and global functions.
CryptoContextCtrl * newCryptoContextForSSRC(uint32 ssrc)
Derive a new Crypto Context for use with a new SSRC.
const int SrtpAuthenticationNull
void update(uint32 newSeqNumber)
Update the SRTP packet index.
const int SrtpEncryptionAESCM
~CryptoContextCtrl()
Destructor.