blob: bfeb8b852e4a27fcd978d0594328c6d66ca14753 [file] [log] [blame]
Cullen Jennings235513a2005-09-21 22:51:36 +00001/*
2 * srtp.c
3 *
4 * the secure real-time transport protocol
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9/*
10 *
David McGrew7629bf22006-06-08 17:00:25 +000011 * Copyright (c) 2001-2006, Cisco Systems, Inc.
Cullen Jennings235513a2005-09-21 22:51:36 +000012 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials provided
24 * with the distribution.
25 *
26 * Neither the name of the Cisco Systems, Inc. nor the names of its
27 * contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
41 * OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
43 */
44
45
David McGrew79870d62007-06-15 18:17:39 +000046#include "srtp.h"
47#include "ekt.h" /* for SRTP Encrypted Key Transport */
Cullen Jennings235513a2005-09-21 22:51:36 +000048#include "alloc.h" /* for crypto_alloc() */
Cullen Jennings235513a2005-09-21 22:51:36 +000049
Marcus Sundberg735eb4f2005-10-03 15:31:07 +000050#ifndef SRTP_KERNEL
51# include <limits.h>
52# ifdef HAVE_NETINET_IN_H
53# include <netinet/in.h>
54# elif defined(HAVE_WINSOCK2_H)
55# include <winsock2.h>
56# endif
57#endif /* ! SRTP_KERNEL */
Marcus Sundberge4e34f92005-10-02 20:19:35 +000058
59
Cullen Jennings235513a2005-09-21 22:51:36 +000060/* the debug module for srtp */
61
62debug_module_t mod_srtp = {
63 0, /* debugging is off by default */
64 "srtp" /* printable name for module */
65};
66
67#define octets_in_rtp_header 12
68#define uint32s_in_rtp_header 3
69#define octets_in_rtcp_header 8
70#define uint32s_in_rtcp_header 2
71
Cullen Jennings235513a2005-09-21 22:51:36 +000072
73err_status_t
74srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
75 const srtp_policy_t *p) {
76 srtp_stream_ctx_t *str;
77 err_status_t stat;
78
79 /*
80 * This function allocates the stream context, rtp and rtcp ciphers
81 * and auth functions, and key limit structure. If there is a
82 * failure during allocation, we free all previously allocated
83 * memory and return a failure code. The code could probably
84 * be improved, but it works and should be clear.
85 */
86
87 /* allocate srtp stream and set str_ptr */
88 str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));
89 if (str == NULL)
90 return err_status_alloc_fail;
91 *str_ptr = str;
92
93 /* allocate cipher */
94 stat = crypto_kernel_alloc_cipher(p->rtp.cipher_type,
95 &str->rtp_cipher,
96 p->rtp.cipher_key_len);
97 if (stat) {
98 crypto_free(str);
99 return stat;
100 }
101
102 /* allocate auth function */
103 stat = crypto_kernel_alloc_auth(p->rtp.auth_type,
104 &str->rtp_auth,
105 p->rtp.auth_key_len,
106 p->rtp.auth_tag_len);
107 if (stat) {
108 cipher_dealloc(str->rtp_cipher);
109 crypto_free(str);
110 return stat;
111 }
112
113 /* allocate key limit structure */
Derek MacDonald17127da2006-07-12 22:22:08 +0000114 str->limit = (key_limit_ctx_t*) crypto_alloc(sizeof(key_limit_ctx_t));
Cullen Jennings235513a2005-09-21 22:51:36 +0000115 if (str->limit == NULL) {
116 auth_dealloc(str->rtp_auth);
117 cipher_dealloc(str->rtp_cipher);
118 crypto_free(str);
119 return err_status_alloc_fail;
120 }
121
122 /*
123 * ...and now the RTCP-specific initialization - first, allocate
124 * the cipher
125 */
126 stat = crypto_kernel_alloc_cipher(p->rtcp.cipher_type,
127 &str->rtcp_cipher,
128 p->rtcp.cipher_key_len);
129 if (stat) {
130 auth_dealloc(str->rtp_auth);
131 cipher_dealloc(str->rtp_cipher);
132 crypto_free(str->limit);
133 crypto_free(str);
134 return stat;
135 }
136
137 /* allocate auth function */
138 stat = crypto_kernel_alloc_auth(p->rtcp.auth_type,
139 &str->rtcp_auth,
140 p->rtcp.auth_key_len,
141 p->rtcp.auth_tag_len);
142 if (stat) {
143 cipher_dealloc(str->rtcp_cipher);
144 auth_dealloc(str->rtp_auth);
145 cipher_dealloc(str->rtp_cipher);
146 crypto_free(str->limit);
147 crypto_free(str);
148 return stat;
149 }
150
David McGrew79870d62007-06-15 18:17:39 +0000151 /* allocate ekt data associated with stream */
152 stat = ekt_alloc(&str->ekt, p->ekt);
153 if (stat) {
154 auth_dealloc(str->rtcp_auth);
155 cipher_dealloc(str->rtcp_cipher);
156 auth_dealloc(str->rtp_auth);
157 cipher_dealloc(str->rtp_cipher);
158 crypto_free(str->limit);
159 crypto_free(str);
160 return stat;
161 }
162
Cullen Jennings235513a2005-09-21 22:51:36 +0000163 return err_status_ok;
164}
165
166err_status_t
167srtp_stream_dealloc(srtp_t session, srtp_stream_ctx_t *stream) {
168 err_status_t status;
169
170 /*
171 * we use a conservative deallocation strategy - if any deallocation
172 * fails, then we report that fact without trying to deallocate
173 * anything else
174 */
175
176 /* deallocate cipher, if it is not the same as that in template */
David McGrewfec49dd2005-09-23 19:34:11 +0000177 if (session->stream_template
Cullen Jennings235513a2005-09-21 22:51:36 +0000178 && stream->rtp_cipher == session->stream_template->rtp_cipher) {
179 /* do nothing */
180 } else {
181 status = cipher_dealloc(stream->rtp_cipher);
182 if (status)
David McGrewfec49dd2005-09-23 19:34:11 +0000183 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000184 }
185
186 /* deallocate auth function, if it is not the same as that in template */
187 if (session->stream_template
188 && stream->rtp_auth == session->stream_template->rtp_auth) {
189 /* do nothing */
190 } else {
191 status = auth_dealloc(stream->rtp_auth);
192 if (status)
193 return status;
194 }
195
David McGrewfec49dd2005-09-23 19:34:11 +0000196 /* deallocate key usage limit, if it is not the same as that in template */
197 if (session->stream_template
198 && stream->limit == session->stream_template->limit) {
199 /* do nothing */
200 } else {
Cullen Jennings235513a2005-09-21 22:51:36 +0000201 crypto_free(stream->limit);
David McGrewfec49dd2005-09-23 19:34:11 +0000202 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000203
204 /*
205 * deallocate rtcp cipher, if it is not the same as that in
206 * template
207 */
208 if (session->stream_template
209 && stream->rtcp_cipher == session->stream_template->rtcp_cipher) {
210 /* do nothing */
211 } else {
212 status = cipher_dealloc(stream->rtcp_cipher);
213 if (status)
214 return status;
215 }
216
217 /*
218 * deallocate rtcp auth function, if it is not the same as that in
219 * template
220 */
221 if (session->stream_template
222 && stream->rtcp_auth == session->stream_template->rtcp_auth) {
223 /* do nothing */
224 } else {
225 status = auth_dealloc(stream->rtcp_auth);
226 if (status)
227 return status;
228 }
David McGrew79870d62007-06-15 18:17:39 +0000229
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000230 status = rdbx_dealloc(&stream->rtp_rdbx);
231 if (status)
232 return status;
233
David McGrew79870d62007-06-15 18:17:39 +0000234 /* DAM - need to deallocate EKT here */
Cullen Jennings235513a2005-09-21 22:51:36 +0000235
236 /* deallocate srtp stream context */
237 crypto_free(stream);
238
239 return err_status_ok;
240}
241
242
243/*
244 * srtp_stream_clone(stream_template, new) allocates a new stream and
245 * initializes it using the cipher and auth of the stream_template
246 *
247 * the only unique data in a cloned stream is the replay database and
248 * the SSRC
249 */
250
251err_status_t
252srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
253 uint32_t ssrc,
254 srtp_stream_ctx_t **str_ptr) {
255 err_status_t status;
256 srtp_stream_ctx_t *str;
257
258 debug_print(mod_srtp, "cloning stream (SSRC: 0x%08x)", ssrc);
259
260 /* allocate srtp stream and set str_ptr */
261 str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));
262 if (str == NULL)
263 return err_status_alloc_fail;
264 *str_ptr = str;
265
266 /* set cipher and auth pointers to those of the template */
267 str->rtp_cipher = stream_template->rtp_cipher;
268 str->rtp_auth = stream_template->rtp_auth;
269 str->rtcp_cipher = stream_template->rtcp_cipher;
270 str->rtcp_auth = stream_template->rtcp_auth;
271
272 /* set key limit to point to that of the template */
273 status = key_limit_clone(stream_template->limit, &str->limit);
274 if (status)
275 return status;
276
277 /* initialize replay databases */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000278 status = rdbx_init(&str->rtp_rdbx,
279 rdbx_get_window_size(&stream_template->rtp_rdbx));
280 if (status)
281 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000282 rdb_init(&str->rtcp_rdb);
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +0000283 str->allow_repeat_tx = stream_template->allow_repeat_tx;
Cullen Jennings235513a2005-09-21 22:51:36 +0000284
285 /* set ssrc to that provided */
286 str->ssrc = ssrc;
287
288 /* set direction and security services */
289 str->direction = stream_template->direction;
290 str->rtp_services = stream_template->rtp_services;
291 str->rtcp_services = stream_template->rtcp_services;
292
David McGrew79870d62007-06-15 18:17:39 +0000293 /* set pointer to EKT data associated with stream */
294 str->ekt = stream_template->ekt;
295
Cullen Jennings235513a2005-09-21 22:51:36 +0000296 /* defensive coding */
297 str->next = NULL;
298
299 return err_status_ok;
300}
301
302
303/*
304 * key derivation functions, internal to libSRTP
305 *
306 * srtp_kdf_t is a key derivation context
307 *
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000308 * srtp_kdf_init(&kdf, cipher_id, k, keylen) initializes kdf to use cipher
309 * described by cipher_id, with the master key k with length in octets keylen.
Cullen Jennings235513a2005-09-21 22:51:36 +0000310 *
311 * srtp_kdf_generate(&kdf, l, kl, keylen) derives the key
312 * corresponding to label l and puts it into kl; the length
313 * of the key in octets is provided as keylen. this function
314 * should be called once for each subkey that is derived.
315 *
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000316 * srtp_kdf_clear(&kdf) zeroizes and deallocates the kdf state
Cullen Jennings235513a2005-09-21 22:51:36 +0000317 */
318
319typedef enum {
320 label_rtp_encryption = 0x00,
321 label_rtp_msg_auth = 0x01,
322 label_rtp_salt = 0x02,
323 label_rtcp_encryption = 0x03,
324 label_rtcp_msg_auth = 0x04,
325 label_rtcp_salt = 0x05
326} srtp_prf_label;
327
328
329/*
330 * srtp_kdf_t represents a key derivation function. The SRTP
331 * default KDF is the only one implemented at present.
332 */
333
334typedef struct {
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000335 cipher_t *cipher; /* cipher used for key derivation */
Cullen Jennings235513a2005-09-21 22:51:36 +0000336} srtp_kdf_t;
337
338err_status_t
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000339srtp_kdf_init(srtp_kdf_t *kdf, cipher_type_id_t cipher_id, const uint8_t *key, int length) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000340
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000341 err_status_t stat;
342 stat = crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, length);
343 if (stat)
344 return stat;
345
346 stat = cipher_init(kdf->cipher, key, direction_encrypt);
347 if (stat) {
348 cipher_dealloc(kdf->cipher);
349 return stat;
350 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000351
352 return err_status_ok;
353}
354
355err_status_t
356srtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label,
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000357 uint8_t *key, unsigned length) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000358
359 v128_t nonce;
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000360 err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000361
362 /* set eigth octet of nonce to <label>, set the rest of it to zero */
363 v128_set_to_zero(&nonce);
Marcus Sundberg7627bc52005-10-08 16:38:06 +0000364 nonce.v8[7] = label;
Cullen Jennings235513a2005-09-21 22:51:36 +0000365
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000366 status = cipher_set_iv(kdf->cipher, &nonce);
367 if (status)
368 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000369
370 /* generate keystream output */
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000371 octet_string_set_to_zero(key, length);
372 status = cipher_encrypt(kdf->cipher, key, &length);
373 if (status)
374 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000375
376 return err_status_ok;
377}
378
379err_status_t
380srtp_kdf_clear(srtp_kdf_t *kdf) {
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000381 err_status_t status;
382 status = cipher_dealloc(kdf->cipher);
383 if (status)
384 return status;
385 kdf->cipher = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +0000386
387 return err_status_ok;
388}
389
390/*
391 * end of key derivation functions
392 */
393
394#define MAX_SRTP_KEY_LEN 256
395
396
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000397/* Get the base key length corresponding to a given combined key+salt
398 * length for the given cipher.
399 * Assumption is that for AES-ICM a key length < 30 is Ismacryp using
400 * AES-128 and short salts; everything else uses a salt length of 14.
401 * TODO: key and salt lengths should be separate fields in the policy. */
402inline int base_key_length(const cipher_type_t *cipher, int key_length)
403{
Jonathan Lennoxf4332412010-05-20 22:10:20 +0000404 if (cipher->id != AES_ICM)
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000405 return key_length;
406 else if (key_length > 16 && key_length < 30)
407 return 16;
408 return key_length - 14;
409}
410
David McGrew576e1482006-06-09 21:47:44 +0000411err_status_t
412srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) {
413 err_status_t stat;
414 srtp_kdf_t kdf;
415 uint8_t tmp_key[MAX_SRTP_KEY_LEN];
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000416 int kdf_keylen = 30, rtp_keylen, rtcp_keylen;
417 int rtp_base_key_len, rtp_salt_len;
418 int rtcp_base_key_len, rtcp_salt_len;
419
420 /* If RTP or RTCP have a key length > AES-128, assume matching kdf. */
421 /* TODO: kdf algorithm, master key length, and master salt length should
422 * be part of srtp_policy_t. */
423 rtp_keylen = cipher_get_key_length(srtp->rtp_cipher);
424 if (rtp_keylen > kdf_keylen)
425 kdf_keylen = rtp_keylen;
426
427 rtcp_keylen = cipher_get_key_length(srtp->rtcp_cipher);
428 if (rtcp_keylen > kdf_keylen)
429 kdf_keylen = rtcp_keylen;
430
David McGrew576e1482006-06-09 21:47:44 +0000431 /* initialize KDF state */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000432 stat = srtp_kdf_init(&kdf, AES_ICM, (const uint8_t *)key, kdf_keylen);
433 if (stat) {
434 return err_status_init_fail;
435 }
436
437 rtp_base_key_len = base_key_length(srtp->rtp_cipher->type, rtp_keylen);
438 rtp_salt_len = rtp_keylen - rtp_base_key_len;
David McGrew576e1482006-06-09 21:47:44 +0000439
440 /* generate encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000441 stat = srtp_kdf_generate(&kdf, label_rtp_encryption,
442 tmp_key, rtp_base_key_len);
443 if (stat) {
444 /* zeroize temp buffer */
445 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
446 return err_status_init_fail;
447 }
448
David McGrew576e1482006-06-09 21:47:44 +0000449 /*
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000450 * if the cipher in the srtp context uses a salt, then we need
David McGrew576e1482006-06-09 21:47:44 +0000451 * to generate the salt value
452 */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000453 if (rtp_salt_len > 0) {
454 debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL);
David McGrew576e1482006-06-09 21:47:44 +0000455
456 /* generate encryption salt, put after encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000457 stat = srtp_kdf_generate(&kdf, label_rtp_salt,
458 tmp_key + rtp_base_key_len, rtp_salt_len);
459 if (stat) {
460 /* zeroize temp buffer */
461 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
462 return err_status_init_fail;
463 }
David McGrew576e1482006-06-09 21:47:44 +0000464 }
465 debug_print(mod_srtp, "cipher key: %s",
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000466 octet_string_hex_string(tmp_key, rtp_keylen));
David McGrew576e1482006-06-09 21:47:44 +0000467
468 /* initialize cipher */
469 stat = cipher_init(srtp->rtp_cipher, tmp_key, direction_any);
470 if (stat) {
471 /* zeroize temp buffer */
472 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
473 return err_status_init_fail;
474 }
475
476 /* generate authentication key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000477 stat = srtp_kdf_generate(&kdf, label_rtp_msg_auth,
478 tmp_key, auth_get_key_length(srtp->rtp_auth));
479 if (stat) {
480 /* zeroize temp buffer */
481 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
482 return err_status_init_fail;
483 }
David McGrew576e1482006-06-09 21:47:44 +0000484 debug_print(mod_srtp, "auth key: %s",
485 octet_string_hex_string(tmp_key,
486 auth_get_key_length(srtp->rtp_auth)));
487
488 /* initialize auth function */
489 stat = auth_init(srtp->rtp_auth, tmp_key);
490 if (stat) {
491 /* zeroize temp buffer */
492 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
493 return err_status_init_fail;
494 }
495
496 /*
497 * ...now initialize SRTCP keys
498 */
499
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000500 rtcp_base_key_len = base_key_length(srtp->rtcp_cipher->type, rtcp_keylen);
501 rtcp_salt_len = rtcp_keylen - rtcp_base_key_len;
502
David McGrew576e1482006-06-09 21:47:44 +0000503 /* generate encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000504 stat = srtp_kdf_generate(&kdf, label_rtcp_encryption,
505 tmp_key, rtcp_base_key_len);
506 if (stat) {
507 /* zeroize temp buffer */
508 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
509 return err_status_init_fail;
510 }
511
David McGrew576e1482006-06-09 21:47:44 +0000512 /*
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000513 * if the cipher in the srtp context uses a salt, then we need
David McGrew576e1482006-06-09 21:47:44 +0000514 * to generate the salt value
515 */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000516 if (rtcp_salt_len > 0) {
517 debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt",
518 NULL);
David McGrew576e1482006-06-09 21:47:44 +0000519
520 /* generate encryption salt, put after encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000521 stat = srtp_kdf_generate(&kdf, label_rtcp_salt,
522 tmp_key + rtcp_base_key_len, rtcp_salt_len);
523 if (stat) {
524 /* zeroize temp buffer */
525 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
526 return err_status_init_fail;
527 }
David McGrew576e1482006-06-09 21:47:44 +0000528 }
529 debug_print(mod_srtp, "rtcp cipher key: %s",
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000530 octet_string_hex_string(tmp_key, rtcp_keylen));
David McGrew576e1482006-06-09 21:47:44 +0000531
532 /* initialize cipher */
533 stat = cipher_init(srtp->rtcp_cipher, tmp_key, direction_any);
534 if (stat) {
535 /* zeroize temp buffer */
536 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
537 return err_status_init_fail;
538 }
539
540 /* generate authentication key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000541 stat = srtp_kdf_generate(&kdf, label_rtcp_msg_auth,
542 tmp_key, auth_get_key_length(srtp->rtcp_auth));
543 if (stat) {
544 /* zeroize temp buffer */
545 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
546 return err_status_init_fail;
547 }
548
David McGrew576e1482006-06-09 21:47:44 +0000549 debug_print(mod_srtp, "rtcp auth key: %s",
550 octet_string_hex_string(tmp_key,
551 auth_get_key_length(srtp->rtcp_auth)));
552
553 /* initialize auth function */
554 stat = auth_init(srtp->rtcp_auth, tmp_key);
555 if (stat) {
556 /* zeroize temp buffer */
557 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
558 return err_status_init_fail;
559 }
560
561 /* clear memory then return */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000562 stat = srtp_kdf_clear(&kdf);
David McGrew576e1482006-06-09 21:47:44 +0000563 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000564 if (stat)
565 return err_status_init_fail;
David McGrew576e1482006-06-09 21:47:44 +0000566
567 return err_status_ok;
568}
Cullen Jennings235513a2005-09-21 22:51:36 +0000569
570err_status_t
571srtp_stream_init(srtp_stream_ctx_t *srtp,
572 const srtp_policy_t *p) {
David McGrew576e1482006-06-09 21:47:44 +0000573 err_status_t err;
Cullen Jennings235513a2005-09-21 22:51:36 +0000574
575 debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)",
576 p->ssrc.value);
577
578 /* initialize replay database */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000579 /* window size MUST be at least 64. MAY be larger. Values more than
580 * 2^15 aren't meaningful due to how extended sequence numbers are
581 * calculated. Let a window size of 0 imply the default value. */
582
583 if (p->window_size != 0 && (p->window_size < 64 || p->window_size >= 0x8000))
584 return err_status_bad_param;
585
586 if (p->window_size != 0)
587 err = rdbx_init(&srtp->rtp_rdbx, p->window_size);
588 else
589 err = rdbx_init(&srtp->rtp_rdbx, 128);
590 if (err) return err;
Cullen Jennings235513a2005-09-21 22:51:36 +0000591
592 /* initialize key limit to maximum value */
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000593#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +0000594{
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000595 uint64_t temp;
596 temp = make64(UINT_MAX,UINT_MAX);
597 key_limit_set(srtp->limit, temp);
Cullen Jennings235513a2005-09-21 22:51:36 +0000598}
599#else
600 key_limit_set(srtp->limit, 0xffffffffffffLL);
601#endif
602
603 /* set the SSRC value */
604 srtp->ssrc = htonl(p->ssrc.value);
605
606 /* set the security service flags */
607 srtp->rtp_services = p->rtp.sec_serv;
608 srtp->rtcp_services = p->rtcp.sec_serv;
609
610 /*
611 * set direction to unknown - this flag gets checked in srtp_protect(),
612 * srtp_unprotect(), srtp_protect_rtcp(), and srtp_unprotect_rtcp(), and
613 * gets set appropriately if it is set to unknown.
614 */
615 srtp->direction = dir_unknown;
616
David McGrew576e1482006-06-09 21:47:44 +0000617 /* initialize SRTCP replay database */
Cullen Jennings235513a2005-09-21 22:51:36 +0000618 rdb_init(&srtp->rtcp_rdb);
619
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +0000620 /* initialize allow_repeat_tx */
621 /* guard against uninitialized memory: allow only 0 or 1 here */
622 if (p->allow_repeat_tx != 0 && p->allow_repeat_tx != 1) {
623 rdbx_dealloc(&srtp->rtp_rdbx);
624 return err_status_bad_param;
625 }
626 srtp->allow_repeat_tx = p->allow_repeat_tx;
627
Cullen Jennings235513a2005-09-21 22:51:36 +0000628 /* DAM - no RTCP key limit at present */
629
David McGrew576e1482006-06-09 21:47:44 +0000630 /* initialize keys */
631 err = srtp_stream_init_keys(srtp, p->key);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000632 if (err) {
633 rdbx_dealloc(&srtp->rtp_rdbx);
634 return err;
635 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000636
David McGrew79870d62007-06-15 18:17:39 +0000637 /*
638 * if EKT is in use, then initialize the EKT data associated with
639 * the stream
640 */
641 err = ekt_stream_init_from_policy(srtp->ekt, p->ekt);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000642 if (err) {
643 rdbx_dealloc(&srtp->rtp_rdbx);
644 return err;
645 }
David McGrew79870d62007-06-15 18:17:39 +0000646
Cullen Jennings235513a2005-09-21 22:51:36 +0000647 return err_status_ok;
648 }
649
650
651 /*
652 * srtp_event_reporter is an event handler function that merely
653 * reports the events that are reported by the callbacks
654 */
655
656 void
657 srtp_event_reporter(srtp_event_data_t *data) {
658
659 err_report(err_level_warning, "srtp: in stream 0x%x: ",
660 data->stream->ssrc);
661
662 switch(data->event) {
663 case event_ssrc_collision:
664 err_report(err_level_warning, "\tSSRC collision\n");
665 break;
666 case event_key_soft_limit:
667 err_report(err_level_warning, "\tkey usage soft limit reached\n");
668 break;
669 case event_key_hard_limit:
670 err_report(err_level_warning, "\tkey usage hard limit reached\n");
671 break;
672 case event_packet_index_limit:
673 err_report(err_level_warning, "\tpacket index limit reached\n");
674 break;
675 default:
676 err_report(err_level_warning, "\tunknown event reported to handler\n");
677 }
678 }
679
680 /*
681 * srtp_event_handler is a global variable holding a pointer to the
682 * event handler function; this function is called for any unexpected
683 * event that needs to be handled out of the SRTP data path. see
684 * srtp_event_t in srtp.h for more info
685 *
686 * it is okay to set srtp_event_handler to NULL, but we set
687 * it to the srtp_event_reporter.
688 */
689
690 static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter;
691
692 err_status_t
693 srtp_install_event_handler(srtp_event_handler_func_t func) {
694
695 /*
696 * note that we accept NULL arguments intentionally - calling this
697 * function with a NULL arguments removes an event handler that's
698 * been previously installed
699 */
700
701 /* set global event handling function */
702 srtp_event_handler = func;
703 return err_status_ok;
704 }
705
706 err_status_t
707 srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +0000708 srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000709 uint32_t *enc_start; /* pointer to start of encrypted portion */
710 uint32_t *auth_start; /* pointer to start of auth. portion */
711 unsigned enc_octet_len = 0; /* number of octets in encrypted portion */
712 xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
713 int delta; /* delta of local pkt idx and that in hdr */
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000714 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
Cullen Jennings235513a2005-09-21 22:51:36 +0000715 err_status_t status;
716 int tag_len;
717 srtp_stream_ctx_t *stream;
718 int prefix_len;
719
720 debug_print(mod_srtp, "function srtp_protect", NULL);
721
722 /* we assume the hdr is 32-bit aligned to start */
723
724 /* check the packet length - it must at least contain a full header */
725 if (*pkt_octet_len < octets_in_rtp_header)
726 return err_status_bad_param;
727
728 /*
729 * look up ssrc in srtp_stream list, and process the packet with
730 * the appropriate stream. if we haven't seen this stream before,
731 * there's a template key for this srtp_session, and the cipher
732 * supports key-sharing, then we assume that a new stream using
733 * that key has just started up
734 */
735 stream = srtp_get_stream(ctx, hdr->ssrc);
736 if (stream == NULL) {
737 if (ctx->stream_template != NULL) {
738 srtp_stream_ctx_t *new_stream;
739
740 /* allocate and initialize a new stream */
741 status = srtp_stream_clone(ctx->stream_template,
David McGrewfec49dd2005-09-23 19:34:11 +0000742 hdr->ssrc, &new_stream);
Cullen Jennings235513a2005-09-21 22:51:36 +0000743 if (status)
744 return status;
745
746 /* add new stream to the head of the stream_list */
747 new_stream->next = ctx->stream_list;
748 ctx->stream_list = new_stream;
749
750 /* set direction to outbound */
751 new_stream->direction = dir_srtp_sender;
752
753 /* set stream (the pointer used in this function) */
754 stream = new_stream;
755 } else {
756 /* no template stream, so we return an error */
757 return err_status_no_ctx;
758 }
759 }
760
761 /*
762 * verify that stream is for sending traffic - this check will
763 * detect SSRC collisions, since a stream that appears in both
764 * srtp_protect() and srtp_unprotect() will fail this test in one of
765 * those functions.
766 */
767 if (stream->direction != dir_srtp_sender) {
768 if (stream->direction == dir_unknown) {
769 stream->direction = dir_srtp_sender;
770 } else {
771 srtp_handle_event(ctx, stream, event_ssrc_collision);
772 }
773 }
774
775 /*
776 * update the key usage limit, and check it to make sure that we
777 * didn't just hit either the soft limit or the hard limit, and call
778 * the event handler if we hit either.
779 */
780 switch(key_limit_update(stream->limit)) {
781 case key_event_normal:
782 break;
783 case key_event_soft_limit:
784 srtp_handle_event(ctx, stream, event_key_soft_limit);
785 break;
786 case key_event_hard_limit:
787 srtp_handle_event(ctx, stream, event_key_hard_limit);
David McGrewfec49dd2005-09-23 19:34:11 +0000788 return err_status_key_expired;
Cullen Jennings235513a2005-09-21 22:51:36 +0000789 default:
790 break;
791 }
792
793 /* get tag length from stream */
794 tag_len = auth_get_tag_length(stream->rtp_auth);
795
796 /*
797 * find starting point for encryption and length of data to be
798 * encrypted - the encrypted portion starts after the rtp header
799 * extension, if present; otherwise, it starts after the last csrc,
800 * if any are present
801 *
802 * if we're not providing confidentiality, set enc_start to NULL
803 */
804 if (stream->rtp_services & sec_serv_conf) {
805 enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
David McGrew14829302005-10-10 18:53:19 +0000806 if (hdr->x == 1) {
807 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
808 enc_start += (ntohs(xtn_hdr->length) + 1);
809 }
David McGrewc4fc00b2006-06-08 18:51:27 +0000810 enc_octet_len = (unsigned int)(*pkt_octet_len
811 - ((enc_start - (uint32_t *)hdr) << 2));
Cullen Jennings235513a2005-09-21 22:51:36 +0000812 } else {
813 enc_start = NULL;
814 }
815
816 /*
817 * if we're providing authentication, set the auth_start and auth_tag
818 * pointers to the proper locations; otherwise, set auth_start to NULL
819 * to indicate that no authentication is needed
820 */
821 if (stream->rtp_services & sec_serv_auth) {
822 auth_start = (uint32_t *)hdr;
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000823 auth_tag = (uint8_t *)hdr + *pkt_octet_len;
Cullen Jennings235513a2005-09-21 22:51:36 +0000824 } else {
825 auth_start = NULL;
826 auth_tag = NULL;
827 }
828
829 /*
830 * estimate the packet index using the start of the replay window
831 * and the sequence number from the header
832 */
833 delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
834 status = rdbx_check(&stream->rtp_rdbx, delta);
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +0000835 if (status) {
836 if (status != err_status_replay_fail || !stream->allow_repeat_tx)
837 return status; /* we've been asked to reuse an index */
838 }
839 else
840 rdbx_add_index(&stream->rtp_rdbx, delta);
Cullen Jennings235513a2005-09-21 22:51:36 +0000841
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000842#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +0000843 debug_print2(mod_srtp, "estimated packet index: %08x%08x",
844 high32(est),low32(est));
845#else
846 debug_print(mod_srtp, "estimated packet index: %016llx", est);
847#endif
848
849 /*
850 * if we're using rindael counter mode, set nonce and seq
851 */
Jonathan Lennoxf4332412010-05-20 22:10:20 +0000852 if (stream->rtp_cipher->type->id == AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000853 v128_t iv;
854
855 iv.v32[0] = 0;
856 iv.v32[1] = hdr->ssrc;
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000857#ifdef NO_64BIT_MATH
858 iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
David McGrewfec49dd2005-09-23 19:34:11 +0000859 low32(est) << 16));
Cullen Jennings235513a2005-09-21 22:51:36 +0000860#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000861 iv.v64[1] = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +0000862#endif
863 status = cipher_set_iv(stream->rtp_cipher, &iv);
864
865 } else {
866 v128_t iv;
867
868 /* otherwise, set the index to est */
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000869#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +0000870 iv.v32[0] = 0;
871 iv.v32[1] = 0;
872#else
873 iv.v64[0] = 0;
874#endif
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000875 iv.v64[1] = be64_to_cpu(est);
Cullen Jennings235513a2005-09-21 22:51:36 +0000876 status = cipher_set_iv(stream->rtp_cipher, &iv);
877 }
878 if (status)
879 return err_status_cipher_fail;
880
881 /* shift est, put into network byte order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000882#ifdef NO_64BIT_MATH
883 est = be64_to_cpu(make64((high32(est) << 16) |
Cullen Jennings235513a2005-09-21 22:51:36 +0000884 (low32(est) >> 16),
Randell Jesup811e1442005-09-28 22:43:41 +0000885 low32(est) << 16));
Cullen Jennings235513a2005-09-21 22:51:36 +0000886#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000887 est = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +0000888#endif
889
890 /*
891 * if we're authenticating using a universal hash, put the keystream
892 * prefix into the authentication tag
893 */
894 if (auth_start) {
895
896 prefix_len = auth_get_prefix_length(stream->rtp_auth);
897 if (prefix_len) {
898 status = cipher_output(stream->rtp_cipher, auth_tag, prefix_len);
899 if (status)
900 return err_status_cipher_fail;
901 debug_print(mod_srtp, "keystream prefix: %s",
902 octet_string_hex_string(auth_tag, prefix_len));
903 }
904 }
905
906 /* if we're encrypting, exor keystream into the message */
907 if (enc_start) {
908 status = cipher_encrypt(stream->rtp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000909 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000910 if (status)
911 return err_status_cipher_fail;
912 }
913
914 /*
915 * if we're authenticating, run authentication function and put result
916 * into the auth_tag
917 */
918 if (auth_start) {
919
920 /* initialize auth func context */
921 status = auth_start(stream->rtp_auth);
922 if (status) return status;
923
924 /* run auth func over packet */
925 status = auth_update(stream->rtp_auth,
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000926 (uint8_t *)auth_start, *pkt_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000927 if (status) return status;
928
929 /* run auth func over ROC, put result into auth_tag */
David McGrew89fb7ea2005-09-26 19:33:44 +0000930 debug_print(mod_srtp, "estimated packet index: %016llx", est);
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000931 status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +0000932 debug_print(mod_srtp, "srtp auth tag: %s",
933 octet_string_hex_string(auth_tag, tag_len));
934 if (status)
935 return err_status_auth_fail;
936
937 }
938
939 if (auth_tag) {
940
941 /* increase the packet length by the length of the auth tag */
942 *pkt_octet_len += tag_len;
943 }
944
945 return err_status_ok;
946}
947
948
949err_status_t
950srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +0000951 srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000952 uint32_t *enc_start; /* pointer to start of encrypted portion */
953 uint32_t *auth_start; /* pointer to start of auth. portion */
David McGrewbb077322006-07-18 19:45:45 +0000954 unsigned enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000955 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
Cullen Jennings235513a2005-09-21 22:51:36 +0000956 xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
957 int delta; /* delta of local pkt idx and that in hdr */
958 v128_t iv;
959 err_status_t status;
960 srtp_stream_ctx_t *stream;
Marcus Sundberg410faaa2005-09-29 12:36:43 +0000961 uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
Cullen Jennings235513a2005-09-21 22:51:36 +0000962 int tag_len, prefix_len;
963
964 debug_print(mod_srtp, "function srtp_unprotect", NULL);
965
966 /* we assume the hdr is 32-bit aligned to start */
967
968 /* check the packet length - it must at least contain a full header */
969 if (*pkt_octet_len < octets_in_rtp_header)
970 return err_status_bad_param;
971
972 /*
973 * look up ssrc in srtp_stream list, and process the packet with
974 * the appropriate stream. if we haven't seen this stream before,
975 * there's only one key for this srtp_session, and the cipher
976 * supports key-sharing, then we assume that a new stream using
977 * that key has just started up
978 */
979 stream = srtp_get_stream(ctx, hdr->ssrc);
980 if (stream == NULL) {
981 if (ctx->stream_template != NULL) {
982 stream = ctx->stream_template;
983 debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)",
984 hdr->ssrc);
985
986 /*
987 * set estimated packet index to sequence number from header,
988 * and set delta equal to the same value
989 */
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000990#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +0000991 est = (xtd_seq_num_t) make64(0,ntohs(hdr->seq));
992 delta = low32(est);
993#else
994 est = (xtd_seq_num_t) ntohs(hdr->seq);
David McGrewc4fc00b2006-06-08 18:51:27 +0000995 delta = (int)est;
Cullen Jennings235513a2005-09-21 22:51:36 +0000996#endif
997 } else {
998
999 /*
1000 * no stream corresponding to SSRC found, and we don't do
1001 * key-sharing, so return an error
1002 */
1003 return err_status_no_ctx;
1004 }
1005 } else {
1006
1007 /* estimate packet index from seq. num. in header */
1008 delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001009
1010 /* check replay database */
1011 status = rdbx_check(&stream->rtp_rdbx, delta);
1012 if (status)
1013 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001014 }
1015
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001016#ifdef NO_64BIT_MATH
David McGrewfec49dd2005-09-23 19:34:11 +00001017 debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),low32(est));
1018#else
1019 debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
1020#endif
Cullen Jennings235513a2005-09-21 22:51:36 +00001021
Cullen Jennings235513a2005-09-21 22:51:36 +00001022 /* get tag length from stream */
1023 tag_len = auth_get_tag_length(stream->rtp_auth);
1024
1025 /*
1026 * set the cipher's IV properly, depending on whatever cipher we
1027 * happen to be using
1028 */
Jonathan Lennoxf4332412010-05-20 22:10:20 +00001029 if (stream->rtp_cipher->type->id == AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001030
1031 /* aes counter mode */
1032 iv.v32[0] = 0;
1033 iv.v32[1] = hdr->ssrc; /* still in network order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001034#ifdef NO_64BIT_MATH
1035 iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
Cullen Jennings235513a2005-09-21 22:51:36 +00001036 low32(est) << 16));
1037#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001038 iv.v64[1] = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001039#endif
Jonathan Lennox1c93fd72010-05-18 16:37:50 +00001040 status = cipher_set_iv(stream->rtp_cipher, &iv);
Cullen Jennings235513a2005-09-21 22:51:36 +00001041 } else {
1042
1043 /* no particular format - set the iv to the pakcet index */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001044#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001045 iv.v32[0] = 0;
1046 iv.v32[1] = 0;
1047#else
1048 iv.v64[0] = 0;
1049#endif
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001050 iv.v64[1] = be64_to_cpu(est);
Cullen Jennings235513a2005-09-21 22:51:36 +00001051 status = cipher_set_iv(stream->rtp_cipher, &iv);
1052 }
1053 if (status)
1054 return err_status_cipher_fail;
1055
1056 /* shift est, put into network byte order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001057#ifdef NO_64BIT_MATH
1058 est = be64_to_cpu(make64((high32(est) << 16) |
Cullen Jennings235513a2005-09-21 22:51:36 +00001059 (low32(est) >> 16),
1060 low32(est) << 16));
1061#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001062 est = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001063#endif
1064
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001065 /*
1066 * find starting point for decryption and length of data to be
1067 * decrypted - the encrypted portion starts after the rtp header
1068 * extension, if present; otherwise, it starts after the last csrc,
1069 * if any are present
1070 *
1071 * if we're not providing confidentiality, set enc_start to NULL
1072 */
1073 if (stream->rtp_services & sec_serv_conf) {
1074 enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
David McGrew14829302005-10-10 18:53:19 +00001075 if (hdr->x == 1) {
1076 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
1077 enc_start += (ntohs(xtn_hdr->length) + 1);
1078 }
David McGrewc4fc00b2006-06-08 18:51:27 +00001079 enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len
1080 - ((enc_start - (uint32_t *)hdr) << 2));
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001081 } else {
1082 enc_start = NULL;
1083 }
1084
Cullen Jennings235513a2005-09-21 22:51:36 +00001085 /*
1086 * if we're providing authentication, set the auth_start and auth_tag
1087 * pointers to the proper locations; otherwise, set auth_start to NULL
1088 * to indicate that no authentication is needed
1089 */
1090 if (stream->rtp_services & sec_serv_auth) {
1091 auth_start = (uint32_t *)hdr;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001092 auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00001093 } else {
1094 auth_start = NULL;
1095 auth_tag = NULL;
1096 }
1097
1098 /*
1099 * if we expect message authentication, run the authentication
1100 * function and compare the result with the value of the auth_tag
1101 */
1102 if (auth_start) {
1103
1104 /*
1105 * if we're using a universal hash, then we need to compute the
1106 * keystream prefix for encrypting the universal hash output
1107 *
1108 * if the keystream prefix length is zero, then we know that
1109 * the authenticator isn't using a universal hash function
1110 */
1111 if (stream->rtp_auth->prefix_len != 0) {
1112
1113 prefix_len = auth_get_prefix_length(stream->rtp_auth);
1114 status = cipher_output(stream->rtp_cipher, tmp_tag, prefix_len);
1115 debug_print(mod_srtp, "keystream prefix: %s",
1116 octet_string_hex_string(tmp_tag, prefix_len));
1117 if (status)
1118 return err_status_cipher_fail;
1119 }
1120
1121 /* initialize auth func context */
1122 status = auth_start(stream->rtp_auth);
1123 if (status) return status;
David McGrewfec49dd2005-09-23 19:34:11 +00001124
Cullen Jennings235513a2005-09-21 22:51:36 +00001125 /* now compute auth function over packet */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001126 status = auth_update(stream->rtp_auth, (uint8_t *)auth_start,
Cullen Jennings235513a2005-09-21 22:51:36 +00001127 *pkt_octet_len - tag_len);
1128
1129 /* run auth func over ROC, then write tmp tag */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001130 status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00001131
1132 debug_print(mod_srtp, "computed auth tag: %s",
1133 octet_string_hex_string(tmp_tag, tag_len));
1134 debug_print(mod_srtp, "packet auth tag: %s",
1135 octet_string_hex_string(auth_tag, tag_len));
1136 if (status)
1137 return err_status_auth_fail;
1138
1139 if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
1140 return err_status_auth_fail;
1141 }
1142
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001143 /*
1144 * update the key usage limit, and check it to make sure that we
1145 * didn't just hit either the soft limit or the hard limit, and call
1146 * the event handler if we hit either.
1147 */
1148 switch(key_limit_update(stream->limit)) {
1149 case key_event_normal:
1150 break;
1151 case key_event_soft_limit:
1152 srtp_handle_event(ctx, stream, event_key_soft_limit);
1153 break;
1154 case key_event_hard_limit:
1155 srtp_handle_event(ctx, stream, event_key_hard_limit);
1156 return err_status_key_expired;
1157 default:
1158 break;
1159 }
1160
Cullen Jennings235513a2005-09-21 22:51:36 +00001161 /* if we're encrypting, add keystream into ciphertext */
1162 if (enc_start) {
1163 status = cipher_encrypt(stream->rtp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001164 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001165 if (status)
1166 return err_status_cipher_fail;
1167 }
1168
1169 /*
1170 * verify that stream is for received traffic - this check will
1171 * detect SSRC collisions, since a stream that appears in both
1172 * srtp_protect() and srtp_unprotect() will fail this test in one of
1173 * those functions.
1174 *
1175 * we do this check *after* the authentication check, so that the
1176 * latter check will catch any attempts to fool us into thinking
1177 * that we've got a collision
1178 */
1179 if (stream->direction != dir_srtp_receiver) {
1180 if (stream->direction == dir_unknown) {
1181 stream->direction = dir_srtp_receiver;
1182 } else {
1183 srtp_handle_event(ctx, stream, event_ssrc_collision);
1184 }
1185 }
1186
1187 /*
1188 * if the stream is a 'provisional' one, in which the template context
1189 * is used, then we need to allocate a new stream at this point, since
1190 * the authentication passed
1191 */
1192 if (stream == ctx->stream_template) {
1193 srtp_stream_ctx_t *new_stream;
1194
1195 /*
1196 * allocate and initialize a new stream
1197 *
1198 * note that we indicate failure if we can't allocate the new
1199 * stream, and some implementations will want to not return
1200 * failure here
1201 */
1202 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
1203 if (status)
1204 return status;
1205
1206 /* add new stream to the head of the stream_list */
1207 new_stream->next = ctx->stream_list;
1208 ctx->stream_list = new_stream;
1209
1210 /* set stream (the pointer used in this function) */
1211 stream = new_stream;
1212 }
1213
1214 /*
1215 * the message authentication function passed, so add the packet
1216 * index into the replay database
1217 */
1218 rdbx_add_index(&stream->rtp_rdbx, delta);
1219
1220 /* decrease the packet length by the length of the auth tag */
1221 *pkt_octet_len -= tag_len;
1222
1223 return err_status_ok;
1224}
1225
1226err_status_t
1227srtp_init() {
1228 err_status_t status;
1229
1230 /* initialize crypto kernel */
1231 status = crypto_kernel_init();
1232 if (status)
1233 return status;
1234
1235 /* load srtp debug module into the kernel */
1236 status = crypto_kernel_load_debug_module(&mod_srtp);
1237 if (status)
1238 return status;
1239
1240 return err_status_ok;
1241}
1242
Jonathan Lennox5ae76332010-05-15 04:48:59 +00001243err_status_t
1244srtp_shutdown() {
1245 err_status_t status;
1246
1247 /* shut down crypto kernel */
1248 status = crypto_kernel_shutdown();
1249 if (status)
1250 return status;
1251
1252 /* shutting down crypto kernel frees the srtp debug module as well */
1253
1254 return err_status_ok;
1255}
1256
1257
Cullen Jennings235513a2005-09-21 22:51:36 +00001258/*
1259 * The following code is under consideration for removal. See
1260 * SRTP_MAX_TRAILER_LEN
1261 */
1262#if 0
1263
1264/*
1265 * srtp_get_trailer_length(&a) returns the number of octets that will
1266 * be added to an RTP packet by the SRTP processing. This value
1267 * is constant for a given srtp_stream_t (i.e. between initializations).
1268 */
1269
1270int
1271srtp_get_trailer_length(const srtp_stream_t s) {
1272 return auth_get_tag_length(s->rtp_auth);
1273}
1274
1275#endif
1276
1277/*
1278 * srtp_get_stream(ssrc) returns a pointer to the stream corresponding
1279 * to ssrc, or NULL if no stream exists for that ssrc
1280 *
1281 * this is an internal function
1282 */
1283
1284srtp_stream_ctx_t *
1285srtp_get_stream(srtp_t srtp, uint32_t ssrc) {
1286 srtp_stream_ctx_t *stream;
1287
1288 /* walk down list until ssrc is found */
1289 stream = srtp->stream_list;
1290 while (stream != NULL) {
1291 if (stream->ssrc == ssrc)
1292 return stream;
1293 stream = stream->next;
1294 }
1295
1296 /* we haven't found our ssrc, so return a null */
1297 return NULL;
1298}
1299
1300err_status_t
1301srtp_dealloc(srtp_t session) {
1302 srtp_stream_ctx_t *stream;
1303 err_status_t status;
1304
1305 /*
1306 * we take a conservative deallocation strategy - if we encounter an
1307 * error deallocating a stream, then we stop trying to deallocate
1308 * memory and just return an error
1309 */
1310
1311 /* walk list of streams, deallocating as we go */
1312 stream = session->stream_list;
1313 while (stream != NULL) {
1314 srtp_stream_t next = stream->next;
1315 status = srtp_stream_dealloc(session, stream);
1316 if (status)
1317 return status;
1318 stream = next;
1319 }
1320
1321 /* deallocate stream template, if there is one */
1322 if (session->stream_template != NULL) {
David McGrewfec49dd2005-09-23 19:34:11 +00001323 status = auth_dealloc(session->stream_template->rtcp_auth);
1324 if (status)
1325 return status;
1326 status = cipher_dealloc(session->stream_template->rtcp_cipher);
1327 if (status)
1328 return status;
1329 crypto_free(session->stream_template->limit);
Cullen Jennings235513a2005-09-21 22:51:36 +00001330 status = cipher_dealloc(session->stream_template->rtp_cipher);
1331 if (status)
1332 return status;
1333 status = auth_dealloc(session->stream_template->rtp_auth);
1334 if (status)
1335 return status;
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001336 status = rdbx_dealloc(&session->stream_template->rtp_rdbx);
1337 if (status)
1338 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001339 crypto_free(session->stream_template);
1340 }
1341
1342 /* deallocate session context */
1343 crypto_free(session);
1344
1345 return err_status_ok;
1346}
1347
1348
1349err_status_t
1350srtp_add_stream(srtp_t session,
1351 const srtp_policy_t *policy) {
1352 err_status_t status;
1353 srtp_stream_t tmp;
1354
Marcus Sundberg67398e62005-10-05 12:39:51 +00001355 /* sanity check arguments */
1356 if ((session == NULL) || (policy == NULL) || (policy->key == NULL))
1357 return err_status_bad_param;
1358
Cullen Jennings235513a2005-09-21 22:51:36 +00001359 /* allocate stream */
1360 status = srtp_stream_alloc(&tmp, policy);
1361 if (status) {
1362 return status;
1363 }
1364
1365 /* initialize stream */
1366 status = srtp_stream_init(tmp, policy);
1367 if (status) {
1368 crypto_free(tmp);
1369 return status;
1370 }
1371
1372 /*
1373 * set the head of the stream list or the template to point to the
1374 * stream that we've just alloced and init'ed, depending on whether
1375 * or not it has a wildcard SSRC value or not
1376 *
1377 * if the template stream has already been set, then the policy is
1378 * inconsistent, so we return a bad_param error code
1379 */
1380 switch (policy->ssrc.type) {
1381 case (ssrc_any_outbound):
1382 if (session->stream_template) {
1383 return err_status_bad_param;
1384 }
1385 session->stream_template = tmp;
1386 session->stream_template->direction = dir_srtp_sender;
1387 break;
1388 case (ssrc_any_inbound):
1389 if (session->stream_template) {
1390 return err_status_bad_param;
1391 }
1392 session->stream_template = tmp;
1393 session->stream_template->direction = dir_srtp_receiver;
1394 break;
1395 case (ssrc_specific):
1396 tmp->next = session->stream_list;
1397 session->stream_list = tmp;
1398 break;
1399 case (ssrc_undefined):
1400 default:
1401 crypto_free(tmp);
1402 return err_status_bad_param;
1403 }
1404
1405 return err_status_ok;
1406}
1407
1408
1409err_status_t
1410srtp_create(srtp_t *session, /* handle for session */
1411 const srtp_policy_t *policy) { /* SRTP policy (list) */
1412 err_status_t stat;
1413 srtp_ctx_t *ctx;
1414
1415 /* sanity check arguments */
Marcus Sundberg67398e62005-10-05 12:39:51 +00001416 if (session == NULL)
Cullen Jennings235513a2005-09-21 22:51:36 +00001417 return err_status_bad_param;
1418
1419 /* allocate srtp context and set ctx_ptr */
1420 ctx = (srtp_ctx_t *) crypto_alloc(sizeof(srtp_ctx_t));
1421 if (ctx == NULL)
1422 return err_status_alloc_fail;
1423 *session = ctx;
1424
1425 /*
1426 * loop over elements in the policy list, allocating and
1427 * initializing a stream for each element
1428 */
1429 ctx->stream_template = NULL;
1430 ctx->stream_list = NULL;
1431 while (policy != NULL) {
1432
1433 stat = srtp_add_stream(ctx, policy);
1434 if (stat) {
Marcus Sundberg67398e62005-10-05 12:39:51 +00001435 /* clean up everything */
1436 srtp_dealloc(*session);
Cullen Jennings235513a2005-09-21 22:51:36 +00001437 return stat;
1438 }
1439
1440 /* set policy to next item in list */
1441 policy = policy->next;
1442 }
1443
1444 return err_status_ok;
1445}
1446
1447
1448err_status_t
1449srtp_remove_stream(srtp_t session, uint32_t ssrc) {
1450 srtp_stream_ctx_t *stream, *last_stream;
1451 err_status_t status;
1452
1453 /* sanity check arguments */
1454 if (session == NULL)
1455 return err_status_bad_param;
1456
1457 /* find stream in list; complain if not found */
1458 last_stream = stream = session->stream_list;
1459 while ((stream != NULL) && (ssrc != stream->ssrc)) {
1460 last_stream = stream;
1461 stream = stream->next;
1462 }
1463 if (stream == NULL)
1464 return err_status_no_ctx;
1465
1466 /* remove stream from the list */
1467 last_stream->next = stream->next;
1468
1469 /* deallocate the stream */
1470 status = srtp_stream_dealloc(session, stream);
1471 if (status)
1472 return status;
1473
1474 return err_status_ok;
1475}
1476
1477
1478/*
1479 * the default policy - provides a convenient way for callers to use
1480 * the default security policy
1481 *
1482 * this policy is that defined in the current SRTP internet draft.
1483 *
1484 */
1485
1486/*
1487 * NOTE: cipher_key_len is really key len (128 bits) plus salt len
1488 * (112 bits)
1489 */
1490/* There are hard-coded 16's for base_key_len in the key generation code */
1491
1492void
1493crypto_policy_set_rtp_default(crypto_policy_t *p) {
1494
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001495 p->cipher_type = AES_ICM;
Cullen Jennings235513a2005-09-21 22:51:36 +00001496 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
1497 p->auth_type = HMAC_SHA1;
1498 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
1499 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
1500 p->sec_serv = sec_serv_conf_and_auth;
1501
1502}
1503
1504void
1505crypto_policy_set_rtcp_default(crypto_policy_t *p) {
1506
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001507 p->cipher_type = AES_ICM;
Cullen Jennings235513a2005-09-21 22:51:36 +00001508 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
1509 p->auth_type = HMAC_SHA1;
1510 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
1511 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
1512 p->sec_serv = sec_serv_conf_and_auth;
1513
1514}
1515
David McGrewa8546882006-01-12 17:56:02 +00001516void
1517crypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p) {
1518
1519 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00001520 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00001521 *
1522 * note that this crypto policy is intended for SRTP, but not SRTCP
1523 */
1524
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001525 p->cipher_type = AES_ICM;
David McGrewa8546882006-01-12 17:56:02 +00001526 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
1527 p->auth_type = HMAC_SHA1;
1528 p->auth_key_len = 20; /* 160 bit key */
1529 p->auth_tag_len = 4; /* 32 bit tag */
1530 p->sec_serv = sec_serv_conf_and_auth;
1531
1532}
1533
1534
1535void
1536crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p) {
1537
1538 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00001539 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00001540 *
1541 * note that this crypto policy is intended for SRTP, but not SRTCP
1542 */
1543
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001544 p->cipher_type = AES_ICM;
David McGrewa8546882006-01-12 17:56:02 +00001545 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
1546 p->auth_type = NULL_AUTH;
1547 p->auth_key_len = 0;
1548 p->auth_tag_len = 0;
1549 p->sec_serv = sec_serv_conf;
1550
1551}
1552
1553
1554void
1555crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p) {
1556
1557 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00001558 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00001559 */
1560
1561 p->cipher_type = NULL_CIPHER;
1562 p->cipher_key_len = 0;
1563 p->auth_type = HMAC_SHA1;
1564 p->auth_key_len = 20;
1565 p->auth_tag_len = 10;
1566 p->sec_serv = sec_serv_auth;
1567
1568}
1569
1570
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001571void
1572crypto_policy_set_aes_cm_256_hmac_sha1_80(crypto_policy_t *p) {
1573
1574 /*
1575 * corresponds to draft-ietf-avt-big-aes-03.txt
1576 */
1577
1578 p->cipher_type = AES_ICM;
1579 p->cipher_key_len = 46;
1580 p->auth_type = HMAC_SHA1;
1581 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
1582 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
1583 p->sec_serv = sec_serv_conf_and_auth;
1584}
1585
1586
1587void
1588crypto_policy_set_aes_cm_256_hmac_sha1_32(crypto_policy_t *p) {
1589
1590 /*
1591 * corresponds to draft-ietf-avt-big-aes-03.txt
1592 *
1593 * note that this crypto policy is intended for SRTP, but not SRTCP
1594 */
1595
1596 p->cipher_type = AES_ICM;
1597 p->cipher_key_len = 46;
1598 p->auth_type = HMAC_SHA1;
1599 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
1600 p->auth_tag_len = 4; /* default 80 bits per RFC 3711 */
1601 p->sec_serv = sec_serv_conf_and_auth;
1602}
1603
1604
Cullen Jennings235513a2005-09-21 22:51:36 +00001605/*
1606 * secure rtcp functions
1607 */
1608
1609err_status_t
1610srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00001611 srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00001612 uint32_t *enc_start; /* pointer to start of encrypted portion */
1613 uint32_t *auth_start; /* pointer to start of auth. portion */
1614 uint32_t *trailer; /* pointer to start of trailer */
David McGrewbb077322006-07-18 19:45:45 +00001615 unsigned enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001616 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
Cullen Jennings235513a2005-09-21 22:51:36 +00001617 err_status_t status;
1618 int tag_len;
1619 srtp_stream_ctx_t *stream;
1620 int prefix_len;
1621 uint32_t seq_num;
1622
1623 /* we assume the hdr is 32-bit aligned to start */
1624 /*
1625 * look up ssrc in srtp_stream list, and process the packet with
1626 * the appropriate stream. if we haven't seen this stream before,
1627 * there's only one key for this srtp_session, and the cipher
1628 * supports key-sharing, then we assume that a new stream using
1629 * that key has just started up
1630 */
1631 stream = srtp_get_stream(ctx, hdr->ssrc);
1632 if (stream == NULL) {
1633 if (ctx->stream_template != NULL) {
1634 srtp_stream_ctx_t *new_stream;
1635
1636 /* allocate and initialize a new stream */
1637 status = srtp_stream_clone(ctx->stream_template,
1638 hdr->ssrc, &new_stream);
1639 if (status)
1640 return status;
1641
1642 /* add new stream to the head of the stream_list */
1643 new_stream->next = ctx->stream_list;
1644 ctx->stream_list = new_stream;
1645
1646 /* set stream (the pointer used in this function) */
1647 stream = new_stream;
1648 } else {
1649 /* no template stream, so we return an error */
1650 return err_status_no_ctx;
1651 }
1652 }
1653
1654 /*
1655 * verify that stream is for sending traffic - this check will
1656 * detect SSRC collisions, since a stream that appears in both
1657 * srtp_protect() and srtp_unprotect() will fail this test in one of
1658 * those functions.
1659 */
1660 if (stream->direction != dir_srtp_sender) {
1661 if (stream->direction == dir_unknown) {
David McGrewc34f7402006-03-09 21:17:00 +00001662 stream->direction = dir_srtp_sender;
Cullen Jennings235513a2005-09-21 22:51:36 +00001663 } else {
1664 srtp_handle_event(ctx, stream, event_ssrc_collision);
1665 }
1666 }
1667
1668 /* get tag length from stream context */
1669 tag_len = auth_get_tag_length(stream->rtcp_auth);
1670
1671 /*
1672 * set encryption start and encryption length - if we're not
1673 * providing confidentiality, set enc_start to NULL
1674 */
1675 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
1676 enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
1677
1678 /* all of the packet, except the header, gets encrypted */
1679 /* NOTE: hdr->length is not usable - it refers to only the first
1680 RTCP report in the compound packet! */
1681 /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
1682 multiples of 32-bits (RFC 3550 6.1) */
1683 trailer = (uint32_t *) ((char *)enc_start + enc_octet_len);
1684
1685 if (stream->rtcp_services & sec_serv_conf) {
1686 *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
1687 } else {
1688 enc_start = NULL;
1689 enc_octet_len = 0;
1690 /* 0 is network-order independant */
1691 *trailer = 0x00000000; /* set encrypt bit */
1692 }
1693
1694 /*
1695 * set the auth_start and auth_tag pointers to the proper locations
1696 * (note that srtpc *always* provides authentication, unlike srtp)
1697 */
1698 /* Note: This would need to change for optional mikey data */
1699 auth_start = (uint32_t *)hdr;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001700 auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t);
Cullen Jennings235513a2005-09-21 22:51:36 +00001701
David McGrew79870d62007-06-15 18:17:39 +00001702 /* perform EKT processing if needed */
1703 ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len,
1704 rdbx_get_packet_index(&stream->rtp_rdbx));
1705
Cullen Jennings235513a2005-09-21 22:51:36 +00001706 /*
1707 * check sequence number for overruns, and copy it into the packet
1708 * if its value isn't too big
1709 */
1710 status = rdb_increment(&stream->rtcp_rdb);
1711 if (status)
1712 return status;
1713 seq_num = rdb_get_value(&stream->rtcp_rdb);
1714 *trailer |= htonl(seq_num);
1715 debug_print(mod_srtp, "srtcp index: %x", seq_num);
1716
1717 /*
1718 * if we're using rindael counter mode, set nonce and seq
1719 */
Jonathan Lennoxf4332412010-05-20 22:10:20 +00001720 if (stream->rtcp_cipher->type->id == AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001721 v128_t iv;
1722
1723 iv.v32[0] = 0;
1724 iv.v32[1] = hdr->ssrc; /* still in network order! */
1725 iv.v32[2] = htonl(seq_num >> 16);
1726 iv.v32[3] = htonl(seq_num << 16);
Jonathan Lennox1c93fd72010-05-18 16:37:50 +00001727 status = cipher_set_iv(stream->rtcp_cipher, &iv);
Cullen Jennings235513a2005-09-21 22:51:36 +00001728
1729 } else {
1730 v128_t iv;
1731
1732 /* otherwise, just set the index to seq_num */
1733 iv.v32[0] = 0;
1734 iv.v32[1] = 0;
1735 iv.v32[2] = 0;
1736 iv.v32[3] = htonl(seq_num);
1737 status = cipher_set_iv(stream->rtcp_cipher, &iv);
1738 }
1739 if (status)
1740 return err_status_cipher_fail;
1741
1742 /*
1743 * if we're authenticating using a universal hash, put the keystream
1744 * prefix into the authentication tag
1745 */
1746
1747 /* if auth_start is non-null, then put keystream into tag */
1748 if (auth_start) {
1749
1750 /* put keystream prefix into auth_tag */
1751 prefix_len = auth_get_prefix_length(stream->rtcp_auth);
1752 status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
1753
1754 debug_print(mod_srtp, "keystream prefix: %s",
1755 octet_string_hex_string(auth_tag, prefix_len));
1756
1757 if (status)
1758 return err_status_cipher_fail;
1759 }
1760
1761 /* if we're encrypting, exor keystream into the message */
1762 if (enc_start) {
1763 status = cipher_encrypt(stream->rtcp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001764 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001765 if (status)
1766 return err_status_cipher_fail;
1767 }
1768
1769 /* initialize auth func context */
1770 auth_start(stream->rtcp_auth);
1771
David McGrew9c70f292006-05-03 19:38:38 +00001772 /*
1773 * run auth func over packet (including trailer), and write the
1774 * result at auth_tag
1775 */
Cullen Jennings235513a2005-09-21 22:51:36 +00001776 status = auth_compute(stream->rtcp_auth,
David McGrew9c70f292006-05-03 19:38:38 +00001777 (uint8_t *)auth_start,
1778 (*pkt_octet_len) + sizeof(srtcp_trailer_t),
1779 auth_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00001780 debug_print(mod_srtp, "srtcp auth tag: %s",
1781 octet_string_hex_string(auth_tag, tag_len));
1782 if (status)
1783 return err_status_auth_fail;
1784
1785 /* increase the packet length by the length of the auth tag and seq_num*/
1786 *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
1787
1788 return err_status_ok;
1789}
1790
1791
1792err_status_t
1793srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00001794 srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00001795 uint32_t *enc_start; /* pointer to start of encrypted portion */
1796 uint32_t *auth_start; /* pointer to start of auth. portion */
1797 uint32_t *trailer; /* pointer to start of trailer */
David McGrewbb077322006-07-18 19:45:45 +00001798 unsigned enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001799 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
1800 uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
David McGrew79870d62007-06-15 18:17:39 +00001801 uint8_t tag_copy[SRTP_MAX_TAG_LEN];
Cullen Jennings235513a2005-09-21 22:51:36 +00001802 err_status_t status;
David McGrew79870d62007-06-15 18:17:39 +00001803 unsigned auth_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00001804 int tag_len;
1805 srtp_stream_ctx_t *stream;
1806 int prefix_len;
1807 uint32_t seq_num;
1808
1809 /* we assume the hdr is 32-bit aligned to start */
1810 /*
1811 * look up ssrc in srtp_stream list, and process the packet with
1812 * the appropriate stream. if we haven't seen this stream before,
1813 * there's only one key for this srtp_session, and the cipher
1814 * supports key-sharing, then we assume that a new stream using
1815 * that key has just started up
1816 */
1817 stream = srtp_get_stream(ctx, hdr->ssrc);
1818 if (stream == NULL) {
1819 if (ctx->stream_template != NULL) {
1820 stream = ctx->stream_template;
David McGrew79870d62007-06-15 18:17:39 +00001821
1822 /*
1823 * check to see if stream_template has an EKT data structure, in
1824 * which case we initialize the template using the EKT policy
1825 * referenced by that data (which consists of decrypting the
1826 * master key from the EKT field)
1827 *
1828 * this function initializes a *provisional* stream, and this
1829 * stream should not be accepted until and unless the packet
1830 * passes its authentication check
1831 */
1832 if (stream->ekt != NULL) {
1833 status = srtp_stream_init_from_ekt(stream, srtcp_hdr, *pkt_octet_len);
1834 if (status)
1835 return status;
1836 }
1837
Cullen Jennings235513a2005-09-21 22:51:36 +00001838 debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)",
1839 hdr->ssrc);
1840 } else {
1841 /* no template stream, so we return an error */
1842 return err_status_no_ctx;
1843 }
1844 }
1845
1846 /* get tag length from stream context */
1847 tag_len = auth_get_tag_length(stream->rtcp_auth);
1848
1849 /*
1850 * set encryption start, encryption length, and trailer
1851 */
1852 enc_octet_len = *pkt_octet_len -
1853 (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t));
1854 /* index & E (encryption) bit follow normal data. hdr->len
1855 is the number of words (32-bit) in the normal packet minus 1 */
1856 /* This should point trailer to the word past the end of the
1857 normal data. */
1858 /* This would need to be modified for optional mikey data */
1859 /*
1860 * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
1861 * multiples of 32-bits (RFC 3550 6.1)
1862 */
1863 trailer = (uint32_t *) ((char *) hdr +
1864 *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t)));
1865 if (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) {
1866 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
1867 } else {
1868 enc_octet_len = 0;
1869 enc_start = NULL; /* this indicates that there's no encryption */
1870 }
1871
1872 /*
1873 * set the auth_start and auth_tag pointers to the proper locations
1874 * (note that srtcp *always* uses authentication, unlike srtp)
1875 */
1876 auth_start = (uint32_t *)hdr;
David McGrew79870d62007-06-15 18:17:39 +00001877 auth_len = *pkt_octet_len - tag_len;
1878 auth_tag = (uint8_t *)hdr + auth_len;
1879
1880 /*
1881 * if EKT is in use, then we make a copy of the tag from the packet,
1882 * and then zeroize the location of the base tag
1883 *
1884 * we first re-position the auth_tag pointer so that it points to
1885 * the base tag
1886 */
1887 if (stream->ekt) {
1888 auth_tag -= ekt_octets_after_base_tag(stream->ekt);
1889 memcpy(tag_copy, auth_tag, tag_len);
1890 octet_string_set_to_zero(auth_tag, tag_len);
1891 auth_tag = tag_copy;
1892 auth_len += tag_len;
1893 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001894
1895 /*
1896 * check the sequence number for replays
1897 */
1898 /* this is easier than dealing with bitfield access */
1899 seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
David McGrew9c70f292006-05-03 19:38:38 +00001900 debug_print(mod_srtp, "srtcp index: %x", seq_num);
Cullen Jennings235513a2005-09-21 22:51:36 +00001901 status = rdb_check(&stream->rtcp_rdb, seq_num);
1902 if (status)
1903 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001904
1905 /*
1906 * if we're using aes counter mode, set nonce and seq
1907 */
Jonathan Lennoxf4332412010-05-20 22:10:20 +00001908 if (stream->rtcp_cipher->type->id == AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001909 v128_t iv;
1910
1911 iv.v32[0] = 0;
1912 iv.v32[1] = hdr->ssrc; /* still in network order! */
1913 iv.v32[2] = htonl(seq_num >> 16);
1914 iv.v32[3] = htonl(seq_num << 16);
Jonathan Lennox1c93fd72010-05-18 16:37:50 +00001915 status = cipher_set_iv(stream->rtcp_cipher, &iv);
Cullen Jennings235513a2005-09-21 22:51:36 +00001916
1917 } else {
1918 v128_t iv;
1919
1920 /* otherwise, just set the index to seq_num */
1921 iv.v32[0] = 0;
1922 iv.v32[1] = 0;
1923 iv.v32[2] = 0;
1924 iv.v32[3] = htonl(seq_num);
1925 status = cipher_set_iv(stream->rtcp_cipher, &iv);
1926
1927 }
1928 if (status)
1929 return err_status_cipher_fail;
1930
1931 /* initialize auth func context */
1932 auth_start(stream->rtcp_auth);
1933
1934 /* run auth func over packet, put result into tmp_tag */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001935 status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start,
David McGrew79870d62007-06-15 18:17:39 +00001936 auth_len, tmp_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00001937 debug_print(mod_srtp, "srtcp computed tag: %s",
1938 octet_string_hex_string(tmp_tag, tag_len));
1939 if (status)
1940 return err_status_auth_fail;
1941
1942 /* compare the tag just computed with the one in the packet */
1943 debug_print(mod_srtp, "srtcp tag from packet: %s",
1944 octet_string_hex_string(auth_tag, tag_len));
1945 if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
1946 return err_status_auth_fail;
1947
1948 /*
1949 * if we're authenticating using a universal hash, put the keystream
1950 * prefix into the authentication tag
1951 */
1952 prefix_len = auth_get_prefix_length(stream->rtcp_auth);
1953 if (prefix_len) {
1954 status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
1955 debug_print(mod_srtp, "keystream prefix: %s",
1956 octet_string_hex_string(auth_tag, prefix_len));
1957 if (status)
1958 return err_status_cipher_fail;
1959 }
1960
1961 /* if we're decrypting, exor keystream into the message */
1962 if (enc_start) {
1963 status = cipher_encrypt(stream->rtcp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001964 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001965 if (status)
1966 return err_status_cipher_fail;
1967 }
1968
David McGrew79870d62007-06-15 18:17:39 +00001969 /* decrease the packet length by the length of the auth tag and seq_num */
Cullen Jennings235513a2005-09-21 22:51:36 +00001970 *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
1971
David McGrew79870d62007-06-15 18:17:39 +00001972 /*
1973 * if EKT is in effect, subtract the EKT data out of the packet
1974 * length
1975 */
1976 *pkt_octet_len -= ekt_octets_after_base_tag(stream->ekt);
1977
Cullen Jennings235513a2005-09-21 22:51:36 +00001978 /*
1979 * verify that stream is for received traffic - this check will
1980 * detect SSRC collisions, since a stream that appears in both
1981 * srtp_protect() and srtp_unprotect() will fail this test in one of
1982 * those functions.
1983 *
1984 * we do this check *after* the authentication check, so that the
1985 * latter check will catch any attempts to fool us into thinking
1986 * that we've got a collision
1987 */
1988 if (stream->direction != dir_srtp_receiver) {
1989 if (stream->direction == dir_unknown) {
1990 stream->direction = dir_srtp_receiver;
1991 } else {
1992 srtp_handle_event(ctx, stream, event_ssrc_collision);
1993 }
1994 }
1995
1996 /*
1997 * if the stream is a 'provisional' one, in which the template context
1998 * is used, then we need to allocate a new stream at this point, since
1999 * the authentication passed
2000 */
2001 if (stream == ctx->stream_template) {
2002 srtp_stream_ctx_t *new_stream;
2003
2004 /*
2005 * allocate and initialize a new stream
2006 *
2007 * note that we indicate failure if we can't allocate the new
2008 * stream, and some implementations will want to not return
2009 * failure here
2010 */
2011 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
2012 if (status)
2013 return status;
2014
2015 /* add new stream to the head of the stream_list */
2016 new_stream->next = ctx->stream_list;
2017 ctx->stream_list = new_stream;
2018
2019 /* set stream (the pointer used in this function) */
2020 stream = new_stream;
2021 }
2022
2023 /* we've passed the authentication check, so add seq_num to the rdb */
2024 rdb_add_index(&stream->rtcp_rdb, seq_num);
2025
2026
2027 return err_status_ok;
2028}
David McGrew0cb86ee2006-07-07 15:46:57 +00002029
2030
2031
2032/*
2033 * dtls keying for srtp
2034 */
2035
2036err_status_t
2037crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy,
2038 srtp_profile_t profile) {
2039
2040 /* set SRTP policy from the SRTP profile in the key set */
2041 switch(profile) {
2042 case srtp_profile_aes128_cm_sha1_80:
2043 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
2044 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
2045 break;
2046 case srtp_profile_aes128_cm_sha1_32:
2047 crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);
2048 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
2049 break;
2050 case srtp_profile_null_sha1_80:
2051 crypto_policy_set_null_cipher_hmac_sha1_80(policy);
2052 crypto_policy_set_null_cipher_hmac_sha1_80(policy);
2053 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002054 case srtp_profile_aes256_cm_sha1_80:
2055 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
2056 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
2057 break;
2058 case srtp_profile_aes256_cm_sha1_32:
2059 crypto_policy_set_aes_cm_256_hmac_sha1_32(policy);
2060 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
2061 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00002062 /* the following profiles are not (yet) supported */
2063 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00002064 default:
2065 return err_status_bad_param;
2066 }
2067
2068 return err_status_ok;
2069}
2070
2071err_status_t
2072crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy,
2073 srtp_profile_t profile) {
2074
2075 /* set SRTP policy from the SRTP profile in the key set */
2076 switch(profile) {
2077 case srtp_profile_aes128_cm_sha1_80:
2078 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
2079 break;
2080 case srtp_profile_aes128_cm_sha1_32:
2081 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
2082 break;
2083 case srtp_profile_null_sha1_80:
2084 crypto_policy_set_null_cipher_hmac_sha1_80(policy);
2085 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002086 case srtp_profile_aes256_cm_sha1_80:
2087 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
2088 break;
2089 case srtp_profile_aes256_cm_sha1_32:
2090 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
2091 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00002092 /* the following profiles are not (yet) supported */
2093 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00002094 default:
2095 return err_status_bad_param;
2096 }
2097
2098 return err_status_ok;
2099}
2100
2101void
2102append_salt_to_key(uint8_t *key, unsigned int bytes_in_key,
2103 uint8_t *salt, unsigned int bytes_in_salt) {
2104
2105 memcpy(key + bytes_in_key, salt, bytes_in_salt);
2106
2107}
2108
2109unsigned int
2110srtp_profile_get_master_key_length(srtp_profile_t profile) {
2111
2112 switch(profile) {
2113 case srtp_profile_aes128_cm_sha1_80:
2114 return 16;
2115 break;
2116 case srtp_profile_aes128_cm_sha1_32:
2117 return 16;
2118 break;
2119 case srtp_profile_null_sha1_80:
2120 return 16;
2121 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002122 case srtp_profile_aes256_cm_sha1_80:
2123 return 32;
2124 break;
2125 case srtp_profile_aes256_cm_sha1_32:
2126 return 32;
2127 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00002128 /* the following profiles are not (yet) supported */
2129 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00002130 default:
2131 return 0; /* indicate error by returning a zero */
2132 }
2133}
2134
2135unsigned int
2136srtp_profile_get_master_salt_length(srtp_profile_t profile) {
2137
2138 switch(profile) {
2139 case srtp_profile_aes128_cm_sha1_80:
2140 return 14;
2141 break;
2142 case srtp_profile_aes128_cm_sha1_32:
2143 return 14;
2144 break;
2145 case srtp_profile_null_sha1_80:
2146 return 14;
2147 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002148 case srtp_profile_aes256_cm_sha1_80:
2149 return 14;
2150 break;
2151 case srtp_profile_aes256_cm_sha1_32:
2152 return 14;
2153 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00002154 /* the following profiles are not (yet) supported */
2155 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00002156 default:
2157 return 0; /* indicate error by returning a zero */
2158 }
2159}