Bug Summary

File:libs/srtp/srtp/srtp.c
Location:line 1573, column 5
Description:Value stored to 'status' is never read

Annotated Source Code

1/*
2 * srtp.c
3 *
4 * the secure real-time transport protocol
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9/*
10 *
11 * Copyright (c) 2001-2006, Cisco Systems, Inc.
12 * 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
46#include "srtp.h"
47#include "ekt.h" /* for SRTP Encrypted Key Transport */
48#include "alloc.h" /* for crypto_alloc() */
49#ifdef OPENSSL1
50#include "aes_gcm_ossl.h" /* for AES GCM mode */
51#endif
52
53#ifndef SRTP_KERNEL
54# include <limits.h>
55# ifdef HAVE_NETINET_IN_H1
56# include <netinet/in.h>
57# elif defined(HAVE_WINSOCK2_H)
58# include <winsock2.h>
59# endif
60#endif /* ! SRTP_KERNEL */
61
62
63/* the debug module for srtp */
64
65debug_module_t mod_srtp = {
66 0, /* debugging is off by default */
67 "srtp" /* printable name for module */
68};
69
70#define octets_in_rtp_header12 12
71#define uint32s_in_rtp_header3 3
72#define octets_in_rtcp_header8 8
73#define uint32s_in_rtcp_header2 2
74
75
76err_status_t
77srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
78 const srtp_policy_t *p) {
79 srtp_stream_ctx_t *str;
80 err_status_t stat;
81
82 /*
83 * This function allocates the stream context, rtp and rtcp ciphers
84 * and auth functions, and key limit structure. If there is a
85 * failure during allocation, we free all previously allocated
86 * memory and return a failure code. The code could probably
87 * be improved, but it works and should be clear.
88 */
89
90 /* allocate srtp stream and set str_ptr */
91 str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));
92 if (str == NULL((void*)0))
93 return err_status_alloc_fail;
94 *str_ptr = str;
95
96 /* allocate cipher */
97 stat = crypto_kernel_alloc_cipher(p->rtp.cipher_type,
98 &str->rtp_cipher,
99 p->rtp.cipher_key_len,
100 p->rtp.auth_tag_len);
101 if (stat) {
102 crypto_free(str);
103 return stat;
104 }
105
106 /* allocate auth function */
107 stat = crypto_kernel_alloc_auth(p->rtp.auth_type,
108 &str->rtp_auth,
109 p->rtp.auth_key_len,
110 p->rtp.auth_tag_len);
111 if (stat) {
112 cipher_dealloc(str->rtp_cipher)(((str->rtp_cipher)->type)->dealloc(str->rtp_cipher
))
;
113 crypto_free(str);
114 return stat;
115 }
116
117 /* allocate key limit structure */
118 str->limit = (key_limit_ctx_t*) crypto_alloc(sizeof(key_limit_ctx_t));
119 if (str->limit == NULL((void*)0)) {
120 auth_dealloc(str->rtp_auth)(((str->rtp_auth)->type)->dealloc(str->rtp_auth));
121 cipher_dealloc(str->rtp_cipher)(((str->rtp_cipher)->type)->dealloc(str->rtp_cipher
))
;
122 crypto_free(str);
123 return err_status_alloc_fail;
124 }
125
126 /*
127 * ...and now the RTCP-specific initialization - first, allocate
128 * the cipher
129 */
130 stat = crypto_kernel_alloc_cipher(p->rtcp.cipher_type,
131 &str->rtcp_cipher,
132 p->rtcp.cipher_key_len,
133 p->rtcp.auth_tag_len);
134 if (stat) {
135 auth_dealloc(str->rtp_auth)(((str->rtp_auth)->type)->dealloc(str->rtp_auth));
136 cipher_dealloc(str->rtp_cipher)(((str->rtp_cipher)->type)->dealloc(str->rtp_cipher
))
;
137 crypto_free(str->limit);
138 crypto_free(str);
139 return stat;
140 }
141
142 /* allocate auth function */
143 stat = crypto_kernel_alloc_auth(p->rtcp.auth_type,
144 &str->rtcp_auth,
145 p->rtcp.auth_key_len,
146 p->rtcp.auth_tag_len);
147 if (stat) {
148 cipher_dealloc(str->rtcp_cipher)(((str->rtcp_cipher)->type)->dealloc(str->rtcp_cipher
))
;
149 auth_dealloc(str->rtp_auth)(((str->rtp_auth)->type)->dealloc(str->rtp_auth));
150 cipher_dealloc(str->rtp_cipher)(((str->rtp_cipher)->type)->dealloc(str->rtp_cipher
))
;
151 crypto_free(str->limit);
152 crypto_free(str);
153 return stat;
154 }
155
156 /* allocate ekt data associated with stream */
157 stat = ekt_alloc(&str->ekt, p->ekt);
158 if (stat) {
159 auth_dealloc(str->rtcp_auth)(((str->rtcp_auth)->type)->dealloc(str->rtcp_auth
))
;
160 cipher_dealloc(str->rtcp_cipher)(((str->rtcp_cipher)->type)->dealloc(str->rtcp_cipher
))
;
161 auth_dealloc(str->rtp_auth)(((str->rtp_auth)->type)->dealloc(str->rtp_auth));
162 cipher_dealloc(str->rtp_cipher)(((str->rtp_cipher)->type)->dealloc(str->rtp_cipher
))
;
163 crypto_free(str->limit);
164 crypto_free(str);
165 return stat;
166 }
167
168 return err_status_ok;
169}
170
171err_status_t
172srtp_stream_dealloc(srtp_t session, srtp_stream_ctx_t *stream) {
173 err_status_t status;
174
175 /*
176 * we use a conservative deallocation strategy - if any deallocation
177 * fails, then we report that fact without trying to deallocate
178 * anything else
179 */
180
181 /* deallocate cipher, if it is not the same as that in template */
182 if (session->stream_template
183 && stream->rtp_cipher == session->stream_template->rtp_cipher) {
184 /* do nothing */
185 } else {
186 status = cipher_dealloc(stream->rtp_cipher)(((stream->rtp_cipher)->type)->dealloc(stream->rtp_cipher
))
;
187 if (status)
188 return status;
189 }
190
191 /* deallocate auth function, if it is not the same as that in template */
192 if (session->stream_template
193 && stream->rtp_auth == session->stream_template->rtp_auth) {
194 /* do nothing */
195 } else {
196 status = auth_dealloc(stream->rtp_auth)(((stream->rtp_auth)->type)->dealloc(stream->rtp_auth
))
;
197 if (status)
198 return status;
199 }
200
201 /* deallocate key usage limit, if it is not the same as that in template */
202 if (session->stream_template
203 && stream->limit == session->stream_template->limit) {
204 /* do nothing */
205 } else {
206 crypto_free(stream->limit);
207 }
208
209 /*
210 * deallocate rtcp cipher, if it is not the same as that in
211 * template
212 */
213 if (session->stream_template
214 && stream->rtcp_cipher == session->stream_template->rtcp_cipher) {
215 /* do nothing */
216 } else {
217 status = cipher_dealloc(stream->rtcp_cipher)(((stream->rtcp_cipher)->type)->dealloc(stream->rtcp_cipher
))
;
218 if (status)
219 return status;
220 }
221
222 /*
223 * deallocate rtcp auth function, if it is not the same as that in
224 * template
225 */
226 if (session->stream_template
227 && stream->rtcp_auth == session->stream_template->rtcp_auth) {
228 /* do nothing */
229 } else {
230 status = auth_dealloc(stream->rtcp_auth)(((stream->rtcp_auth)->type)->dealloc(stream->rtcp_auth
))
;
231 if (status)
232 return status;
233 }
234
235 status = rdbx_dealloc(&stream->rtp_rdbx);
236 if (status)
237 return status;
238
239 /* DAM - need to deallocate EKT here */
240
241 /*
242 * zeroize the salt value
243 */
244 memset(stream->salt, 0, SRTP_AEAD_SALT_LEN12);
245 memset(stream->c_salt, 0, SRTP_AEAD_SALT_LEN12);
246
247
248 /* deallocate srtp stream context */
249 crypto_free(stream);
250
251 return err_status_ok;
252}
253
254
255/*
256 * srtp_stream_clone(stream_template, new) allocates a new stream and
257 * initializes it using the cipher and auth of the stream_template
258 *
259 * the only unique data in a cloned stream is the replay database and
260 * the SSRC
261 */
262
263err_status_t
264srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
265 uint32_t ssrc,
266 srtp_stream_ctx_t **str_ptr) {
267 err_status_t status;
268 srtp_stream_ctx_t *str;
269
270 debug_print(mod_srtp, "cloning stream (SSRC: 0x%08x)", ssrc)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "cloning stream (SSRC: 0x%08x)"
"\n"), mod_srtp.name, ssrc)
;
271
272 /* allocate srtp stream and set str_ptr */
273 str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));
274 if (str == NULL((void*)0))
275 return err_status_alloc_fail;
276 *str_ptr = str;
277
278 /* set cipher and auth pointers to those of the template */
279 str->rtp_cipher = stream_template->rtp_cipher;
280 str->rtp_auth = stream_template->rtp_auth;
281 str->rtcp_cipher = stream_template->rtcp_cipher;
282 str->rtcp_auth = stream_template->rtcp_auth;
283
284 /* set key limit to point to that of the template */
285 status = key_limit_clone(stream_template->limit, &str->limit);
286 if (status) {
287 crypto_free(*str_ptr);
288 *str_ptr = NULL((void*)0);
289 return status;
290 }
291
292 /* initialize replay databases */
293 status = rdbx_init(&str->rtp_rdbx,
294 rdbx_get_window_size(&stream_template->rtp_rdbx));
295 if (status) {
296 crypto_free(*str_ptr);
297 *str_ptr = NULL((void*)0);
298 return status;
299 }
300 rdb_init(&str->rtcp_rdb);
301 str->allow_repeat_tx = stream_template->allow_repeat_tx;
302
303 /* set ssrc to that provided */
304 str->ssrc = ssrc;
305
306 /* set direction and security services */
307 str->direction = stream_template->direction;
308 str->rtp_services = stream_template->rtp_services;
309 str->rtcp_services = stream_template->rtcp_services;
310
311 /* set pointer to EKT data associated with stream */
312 str->ekt = stream_template->ekt;
313
314 /* Copy the salt values */
315 memcpy(str->salt, stream_template->salt, SRTP_AEAD_SALT_LEN12);
316 memcpy(str->c_salt, stream_template->c_salt, SRTP_AEAD_SALT_LEN12);
317
318 /* defensive coding */
319 str->next = NULL((void*)0);
320
321 return err_status_ok;
322}
323
324
325/*
326 * key derivation functions, internal to libSRTP
327 *
328 * srtp_kdf_t is a key derivation context
329 *
330 * srtp_kdf_init(&kdf, cipher_id, k, keylen) initializes kdf to use cipher
331 * described by cipher_id, with the master key k with length in octets keylen.
332 *
333 * srtp_kdf_generate(&kdf, l, kl, keylen) derives the key
334 * corresponding to label l and puts it into kl; the length
335 * of the key in octets is provided as keylen. this function
336 * should be called once for each subkey that is derived.
337 *
338 * srtp_kdf_clear(&kdf) zeroizes and deallocates the kdf state
339 */
340
341typedef enum {
342 label_rtp_encryption = 0x00,
343 label_rtp_msg_auth = 0x01,
344 label_rtp_salt = 0x02,
345 label_rtcp_encryption = 0x03,
346 label_rtcp_msg_auth = 0x04,
347 label_rtcp_salt = 0x05
348} srtp_prf_label;
349
350
351/*
352 * srtp_kdf_t represents a key derivation function. The SRTP
353 * default KDF is the only one implemented at present.
354 */
355
356typedef struct {
357 cipher_t *cipher; /* cipher used for key derivation */
358} srtp_kdf_t;
359
360err_status_t
361srtp_kdf_init(srtp_kdf_t *kdf, cipher_type_id_t cipher_id, const uint8_t *key, int length) {
362
363 err_status_t stat;
364 stat = crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, length, 0);
365 if (stat)
366 return stat;
367
368 stat = cipher_init(kdf->cipher, key)(((kdf->cipher)->type)->init(((kdf->cipher)->state
), (key), ((kdf->cipher)->key_len)))
;
369 if (stat) {
370 cipher_dealloc(kdf->cipher)(((kdf->cipher)->type)->dealloc(kdf->cipher));
371 return stat;
372 }
373
374 return err_status_ok;
375}
376
377err_status_t
378srtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label,
379 uint8_t *key, unsigned int length) {
380
381 v128_t nonce;
382 err_status_t status;
383
384 /* set eigth octet of nonce to <label>, set the rest of it to zero */
385 v128_set_to_zero(&nonce)( (&nonce)->v32[0] = 0, (&nonce)->v32[1] = 0, (
&nonce)->v32[2] = 0, (&nonce)->v32[3] = 0 )
;
386 nonce.v8[7] = label;
387
388 status = cipher_set_iv(kdf->cipher, &nonce, direction_encrypt)((kdf->cipher) ? (((kdf->cipher)->type)->set_iv((
(cipher_pointer_t)(kdf->cipher)->state), (&nonce), (
direction_encrypt))) : err_status_no_such_op)
;
389 if (status)
390 return status;
391
392 /* generate keystream output */
393 octet_string_set_to_zero(key, length);
394 status = cipher_encrypt(kdf->cipher, key, &length)(((kdf->cipher)->type)->encrypt(((kdf->cipher)->
state), (key), (&length)))
;
395 if (status)
396 return status;
397
398 return err_status_ok;
399}
400
401err_status_t
402srtp_kdf_clear(srtp_kdf_t *kdf) {
403 err_status_t status;
404 status = cipher_dealloc(kdf->cipher)(((kdf->cipher)->type)->dealloc(kdf->cipher));
405 if (status)
406 return status;
407 kdf->cipher = NULL((void*)0);
408
409 return err_status_ok;
410}
411
412/*
413 * end of key derivation functions
414 */
415
416#define MAX_SRTP_KEY_LEN256 256
417
418
419/* Get the base key length corresponding to a given combined key+salt
420 * length for the given cipher.
421 * Assumption is that for AES-ICM a key length < 30 is Ismacryp using
422 * AES-128 and short salts; everything else uses a salt length of 14.
423 * TODO: key and salt lengths should be separate fields in the policy. */
424static inlineinline int base_key_length(const cipher_type_t *cipher, int key_length)
425{
426 switch (cipher->id) {
427 case AES_128_ICM1:
428 case AES_192_ICM4:
429 case AES_256_ICM5:
430 /* The legacy modes are derived from
431 * the configured key length on the policy */
432 return key_length - 14;
433 break;
434 case AES_128_GCM6:
435 return 16;
436 break;
437 case AES_256_GCM7:
438 return 32;
439 break;
440 default:
441 return key_length;
442 break;
443 }
444}
445
446err_status_t
447srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) {
448 err_status_t stat;
449 srtp_kdf_t kdf;
450 uint8_t tmp_key[MAX_SRTP_KEY_LEN256];
451 int kdf_keylen = 30, rtp_keylen, rtcp_keylen;
452 int rtp_base_key_len, rtp_salt_len;
453 int rtcp_base_key_len, rtcp_salt_len;
454
455 /* If RTP or RTCP have a key length > AES-128, assume matching kdf. */
456 /* TODO: kdf algorithm, master key length, and master salt length should
457 * be part of srtp_policy_t. */
458 rtp_keylen = cipher_get_key_length(srtp->rtp_cipher);
459 rtcp_keylen = cipher_get_key_length(srtp->rtcp_cipher);
460 rtp_base_key_len = base_key_length(srtp->rtp_cipher->type, rtp_keylen);
461 rtp_salt_len = rtp_keylen - rtp_base_key_len;
462
463 if (rtp_keylen > kdf_keylen) {
464 kdf_keylen = 46; /* AES-CTR mode is always used for KDF */
465 }
466
467 if (rtcp_keylen > kdf_keylen) {
468 kdf_keylen = 46; /* AES-CTR mode is always used for KDF */
469 }
470
471 debug_print(mod_srtp, "srtp key len: %d", rtp_keylen)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtp key len: %d"
"\n"), mod_srtp.name, rtp_keylen)
;
472 debug_print(mod_srtp, "srtcp key len: %d", rtcp_keylen)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp key len: %d"
"\n"), mod_srtp.name, rtcp_keylen)
;
473 debug_print(mod_srtp, "base key len: %d", rtp_base_key_len)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "base key len: %d"
"\n"), mod_srtp.name, rtp_base_key_len)
;
474 debug_print(mod_srtp, "kdf key len: %d", kdf_keylen)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "kdf key len: %d"
"\n"), mod_srtp.name, kdf_keylen)
;
475 debug_print(mod_srtp, "rtp salt len: %d", rtp_salt_len)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "rtp salt len: %d"
"\n"), mod_srtp.name, rtp_salt_len)
;
476
477 /*
478 * Make sure the key given to us is 'zero' appended. GCM
479 * mode uses a shorter master SALT (96 bits), but still relies on
480 * the legacy CTR mode KDF, which uses a 112 bit master SALT.
481 */
482 memset(tmp_key, 0x0, MAX_SRTP_KEY_LEN256);
483 memcpy(tmp_key, key, (rtp_base_key_len + rtp_salt_len));
484
485 /* initialize KDF state */
486 stat = srtp_kdf_init(&kdf, AES_ICM1, (const uint8_t *)tmp_key, kdf_keylen);
487 if (stat) {
488 return err_status_init_fail;
489 }
490
491 /* generate encryption key */
492 stat = srtp_kdf_generate(&kdf, label_rtp_encryption,
493 tmp_key, rtp_base_key_len);
494 if (stat) {
495 /* zeroize temp buffer */
496 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN256);
497 return err_status_init_fail;
498 }
499 debug_print(mod_srtp, "cipher key: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "cipher key: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key, rtp_base_key_len
))
500 octet_string_hex_string(tmp_key, rtp_base_key_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "cipher key: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key, rtp_base_key_len
))
;
501
502 /*
503 * if the cipher in the srtp context uses a salt, then we need
504 * to generate the salt value
505 */
506 if (rtp_salt_len > 0) {
507 debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "found rtp_salt_len > 0, generating salt"
"\n"), mod_srtp.name, ((void*)0))
;
508
509 /* generate encryption salt, put after encryption key */
510 stat = srtp_kdf_generate(&kdf, label_rtp_salt,
511 tmp_key + rtp_base_key_len, rtp_salt_len);
512 if (stat) {
513 /* zeroize temp buffer */
514 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN256);
515 return err_status_init_fail;
516 }
517 memcpy(srtp->salt, tmp_key + rtp_base_key_len, SRTP_AEAD_SALT_LEN12);
518 }
519 if (rtp_salt_len > 0) {
520 debug_print(mod_srtp, "cipher salt: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "cipher salt: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key + rtp_base_key_len
, rtp_salt_len))
521 octet_string_hex_string(tmp_key + rtp_base_key_len, rtp_salt_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "cipher salt: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key + rtp_base_key_len
, rtp_salt_len))
;
522 }
523
524 /* initialize cipher */
525 stat = cipher_init(srtp->rtp_cipher, tmp_key)(((srtp->rtp_cipher)->type)->init(((srtp->rtp_cipher
)->state), (tmp_key), ((srtp->rtp_cipher)->key_len))
)
;
526 if (stat) {
527 /* zeroize temp buffer */
528 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN256);
529 return err_status_init_fail;
530 }
531
532 /* generate authentication key */
533 stat = srtp_kdf_generate(&kdf, label_rtp_msg_auth,
534 tmp_key, auth_get_key_length(srtp->rtp_auth));
535 if (stat) {
536 /* zeroize temp buffer */
537 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN256);
538 return err_status_init_fail;
539 }
540 debug_print(mod_srtp, "auth key: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "auth key: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key, auth_get_key_length
(srtp->rtp_auth)))
541 octet_string_hex_string(tmp_key,if (mod_srtp.on) err_report(err_level_debug, ("%s: " "auth key: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key, auth_get_key_length
(srtp->rtp_auth)))
542 auth_get_key_length(srtp->rtp_auth)))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "auth key: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key, auth_get_key_length
(srtp->rtp_auth)))
;
543
544 /* initialize auth function */
545 stat = auth_init(srtp->rtp_auth, tmp_key)(((srtp->rtp_auth)->type)->init((srtp->rtp_auth)->
state, (tmp_key), ((srtp->rtp_auth)->key_len)))
;
546 if (stat) {
547 /* zeroize temp buffer */
548 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN256);
549 return err_status_init_fail;
550 }
551
552 /*
553 * ...now initialize SRTCP keys
554 */
555
556 rtcp_base_key_len = base_key_length(srtp->rtcp_cipher->type, rtcp_keylen);
557 rtcp_salt_len = rtcp_keylen - rtcp_base_key_len;
558 debug_print(mod_srtp, "rtcp salt len: %d", rtcp_salt_len)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "rtcp salt len: %d"
"\n"), mod_srtp.name, rtcp_salt_len)
;
559
560 /* generate encryption key */
561 stat = srtp_kdf_generate(&kdf, label_rtcp_encryption,
562 tmp_key, rtcp_base_key_len);
563 if (stat) {
564 /* zeroize temp buffer */
565 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN256);
566 return err_status_init_fail;
567 }
568
569 /*
570 * if the cipher in the srtp context uses a salt, then we need
571 * to generate the salt value
572 */
573 if (rtcp_salt_len > 0) {
574 debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "found rtcp_salt_len > 0, generating rtcp salt"
"\n"), mod_srtp.name, ((void*)0))
575 NULL)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "found rtcp_salt_len > 0, generating rtcp salt"
"\n"), mod_srtp.name, ((void*)0))
;
576
577 /* generate encryption salt, put after encryption key */
578 stat = srtp_kdf_generate(&kdf, label_rtcp_salt,
579 tmp_key + rtcp_base_key_len, rtcp_salt_len);
580 if (stat) {
581 /* zeroize temp buffer */
582 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN256);
583 return err_status_init_fail;
584 }
585 memcpy(srtp->c_salt, tmp_key + rtcp_base_key_len, SRTP_AEAD_SALT_LEN12);
586 }
587 debug_print(mod_srtp, "rtcp cipher key: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "rtcp cipher key: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key, rtcp_base_key_len
))
588 octet_string_hex_string(tmp_key, rtcp_base_key_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "rtcp cipher key: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key, rtcp_base_key_len
))
;
589 if (rtcp_salt_len > 0) {
590 debug_print(mod_srtp, "rtcp cipher salt: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "rtcp cipher salt: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key + rtcp_base_key_len
, rtcp_salt_len))
591 octet_string_hex_string(tmp_key + rtcp_base_key_len, rtcp_salt_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "rtcp cipher salt: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key + rtcp_base_key_len
, rtcp_salt_len))
;
592 }
593
594 /* initialize cipher */
595 stat = cipher_init(srtp->rtcp_cipher, tmp_key)(((srtp->rtcp_cipher)->type)->init(((srtp->rtcp_cipher
)->state), (tmp_key), ((srtp->rtcp_cipher)->key_len)
))
;
596 if (stat) {
597 /* zeroize temp buffer */
598 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN256);
599 return err_status_init_fail;
600 }
601
602 /* generate authentication key */
603 stat = srtp_kdf_generate(&kdf, label_rtcp_msg_auth,
604 tmp_key, auth_get_key_length(srtp->rtcp_auth));
605 if (stat) {
606 /* zeroize temp buffer */
607 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN256);
608 return err_status_init_fail;
609 }
610
611 debug_print(mod_srtp, "rtcp auth key: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "rtcp auth key: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key, auth_get_key_length
(srtp->rtcp_auth)))
612 octet_string_hex_string(tmp_key,if (mod_srtp.on) err_report(err_level_debug, ("%s: " "rtcp auth key: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key, auth_get_key_length
(srtp->rtcp_auth)))
613 auth_get_key_length(srtp->rtcp_auth)))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "rtcp auth key: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_key, auth_get_key_length
(srtp->rtcp_auth)))
;
614
615 /* initialize auth function */
616 stat = auth_init(srtp->rtcp_auth, tmp_key)(((srtp->rtcp_auth)->type)->init((srtp->rtcp_auth
)->state, (tmp_key), ((srtp->rtcp_auth)->key_len)))
;
617 if (stat) {
618 /* zeroize temp buffer */
619 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN256);
620 return err_status_init_fail;
621 }
622
623 /* clear memory then return */
624 stat = srtp_kdf_clear(&kdf);
625 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN256);
626 if (stat)
627 return err_status_init_fail;
628
629 return err_status_ok;
630}
631
632err_status_t
633srtp_stream_init(srtp_stream_ctx_t *srtp,
634 const srtp_policy_t *p) {
635 err_status_t err;
636
637 debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "initializing stream (SSRC: 0x%08x)"
"\n"), mod_srtp.name, p->ssrc.value)
638 p->ssrc.value)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "initializing stream (SSRC: 0x%08x)"
"\n"), mod_srtp.name, p->ssrc.value)
;
639
640 /* initialize replay database */
641 /* window size MUST be at least 64. MAY be larger. Values more than
642 * 2^15 aren't meaningful due to how extended sequence numbers are
643 * calculated. Let a window size of 0 imply the default value. */
644
645 if (p->window_size != 0 && (p->window_size < 64 || p->window_size >= 0x8000))
646 return err_status_bad_param;
647
648 if (p->window_size != 0)
649 err = rdbx_init(&srtp->rtp_rdbx, p->window_size);
650 else
651 err = rdbx_init(&srtp->rtp_rdbx, 128);
652 if (err) return err;
653
654 /* initialize key limit to maximum value */
655#ifdef NO_64BIT_MATH
656{
657 uint64_t temp;
658 temp = make64(UINT_MAX(2147483647 *2U +1U),UINT_MAX(2147483647 *2U +1U));
659 key_limit_set(srtp->limit, temp);
660}
661#else
662 key_limit_set(srtp->limit, 0xffffffffffffLL);
663#endif
664
665 /* set the SSRC value */
666 srtp->ssrc = htonl(p->ssrc.value)(__extension__ ({ unsigned int __v, __x = (p->ssrc.value);
if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
667
668 /* set the security service flags */
669 srtp->rtp_services = p->rtp.sec_serv;
670 srtp->rtcp_services = p->rtcp.sec_serv;
671
672 /*
673 * set direction to unknown - this flag gets checked in srtp_protect(),
674 * srtp_unprotect(), srtp_protect_rtcp(), and srtp_unprotect_rtcp(), and
675 * gets set appropriately if it is set to unknown.
676 */
677 srtp->direction = dir_unknown;
678
679 /* initialize SRTCP replay database */
680 rdb_init(&srtp->rtcp_rdb);
681
682 /* initialize allow_repeat_tx */
683 /* guard against uninitialized memory: allow only 0 or 1 here */
684 if (p->allow_repeat_tx != 0 && p->allow_repeat_tx != 1) {
685 rdbx_dealloc(&srtp->rtp_rdbx);
686 return err_status_bad_param;
687 }
688 srtp->allow_repeat_tx = p->allow_repeat_tx;
689
690 /* DAM - no RTCP key limit at present */
691
692 /* initialize keys */
693 err = srtp_stream_init_keys(srtp, p->key);
694 if (err) {
695 rdbx_dealloc(&srtp->rtp_rdbx);
696 return err;
697 }
698
699 /*
700 * if EKT is in use, then initialize the EKT data associated with
701 * the stream
702 */
703 err = ekt_stream_init_from_policy(srtp->ekt, p->ekt);
704 if (err) {
705 rdbx_dealloc(&srtp->rtp_rdbx);
706 return err;
707 }
708
709 return err_status_ok;
710 }
711
712
713 /*
714 * srtp_event_reporter is an event handler function that merely
715 * reports the events that are reported by the callbacks
716 */
717
718 void
719 srtp_event_reporter(srtp_event_data_t *data) {
720
721 err_report(err_level_warning, "srtp: in stream 0x%x: ",
722 data->stream->ssrc);
723
724 switch(data->event) {
725 case event_ssrc_collision:
726 err_report(err_level_warning, "\tSSRC collision\n");
727 break;
728 case event_key_soft_limit:
729 err_report(err_level_warning, "\tkey usage soft limit reached\n");
730 break;
731 case event_key_hard_limit:
732 err_report(err_level_warning, "\tkey usage hard limit reached\n");
733 break;
734 case event_packet_index_limit:
735 err_report(err_level_warning, "\tpacket index limit reached\n");
736 break;
737 default:
738 err_report(err_level_warning, "\tunknown event reported to handler\n");
739 }
740 }
741
742 /*
743 * srtp_event_handler is a global variable holding a pointer to the
744 * event handler function; this function is called for any unexpected
745 * event that needs to be handled out of the SRTP data path. see
746 * srtp_event_t in srtp.h for more info
747 *
748 * it is okay to set srtp_event_handler to NULL, but we set
749 * it to the srtp_event_reporter.
750 */
751
752 static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter;
753
754 err_status_t
755 srtp_install_event_handler(srtp_event_handler_func_t func) {
756
757 /*
758 * note that we accept NULL arguments intentionally - calling this
759 * function with a NULL arguments removes an event handler that's
760 * been previously installed
761 */
762
763 /* set global event handling function */
764 srtp_event_handler = func;
765 return err_status_ok;
766 }
767
768/*
769 * AEAD uses a new IV formation method. This function implements
770 * section 9.1 from draft-ietf-avtcore-srtp-aes-gcm-07.txt. The
771 * calculation is defined as, where (+) is the xor operation:
772 *
773 *
774 * 0 0 0 0 0 0 0 0 0 0 1 1
775 * 0 1 2 3 4 5 6 7 8 9 0 1
776 * +--+--+--+--+--+--+--+--+--+--+--+--+
777 * |00|00| SSRC | ROC | SEQ |---+
778 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
779 * |
780 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
781 * | Encryption Salt |->(+)
782 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
783 * |
784 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
785 * | Initialization Vector |<--+
786 * +--+--+--+--+--+--+--+--+--+--+--+--+*
787 *
788 * Input: *stream - pointer to SRTP stream context, used to retrieve
789 * the SALT
790 * *iv - Pointer to receive the calculated IV
791 * *seq - The ROC and SEQ value to use for the
792 * IV calculation.
793 * *hdr - The RTP header, used to get the SSRC value
794 *
795 */
796static void srtp_calc_aead_iv(srtp_stream_ctx_t *stream, v128_t *iv,
797 xtd_seq_num_t *seq, srtp_hdr_t *hdr)
798{
799 v128_t in;
800 v128_t salt;
801
802#ifdef NO_64BIT_MATH
803 uint32_t local_roc = ((high32(*seq) << 16) |
804 (low32(*seq) >> 16));
805 uint16_t local_seq = (uint16_t) (low32(*seq));
806#else
807 uint32_t local_roc = (uint32_t)(*seq >> 16);
808 uint16_t local_seq = (uint16_t) *seq;
809#endif
810
811 memset(&in, 0, sizeof(v128_t));
812 memset(&salt, 0, sizeof(v128_t));
813
814 in.v16[5] = htons(local_seq)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (local_seq); if (__builtin_constant_p (__x)) __v = ((unsigned
short int) ((((__x) >> 8) & 0xff) | (((__x) & 0xff
) << 8))); else __asm__ ("rorw $8, %w0" : "=r" (__v) : "0"
(__x) : "cc"); __v; }))
;
815 local_roc = htonl(local_roc)(__extension__ ({ unsigned int __v, __x = (local_roc); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
816 memcpy(&in.v16[3], &local_roc, sizeof(local_roc));
817
818 /*
819 * Copy in the RTP SSRC value
820 */
821 memcpy(&in.v8[2], &hdr->ssrc, 4);
822 debug_print(mod_srtp, "Pre-salted RTP IV = %s\n", v128_hex_string(&in))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "Pre-salted RTP IV = %s\n"
"\n"), mod_srtp.name, v128_hex_string(&in))
;
823
824 /*
825 * Get the SALT value from the context
826 */
827 memcpy(salt.v8, stream->salt, SRTP_AEAD_SALT_LEN12);
828 debug_print(mod_srtp, "RTP SALT = %s\n", v128_hex_string(&salt))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "RTP SALT = %s\n"
"\n"), mod_srtp.name, v128_hex_string(&salt))
;
829
830 /*
831 * Finally, apply tyhe SALT to the input
832 */
833 v128_xor(iv, &in, &salt)( (iv)->v32[0] = (&in)->v32[0] ^ (&salt)->v32
[0], (iv)->v32[1] = (&in)->v32[1] ^ (&salt)->
v32[1], (iv)->v32[2] = (&in)->v32[2] ^ (&salt)->
v32[2], (iv)->v32[3] = (&in)->v32[3] ^ (&salt)->
v32[3] )
;
834}
835
836
837/*
838 * This function handles outgoing SRTP packets while in AEAD mode,
839 * which currently supports AES-GCM encryption. All packets are
840 * encrypted and authenticated.
841 */
842static err_status_t
843srtp_protect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream,
844 void *rtp_hdr, unsigned int *pkt_octet_len)
845{
846 srtp_hdr_t *hdr = (srtp_hdr_t*)rtp_hdr;
847 uint32_t *enc_start; /* pointer to start of encrypted portion */
848 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
849 xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
850 int delta; /* delta of local pkt idx and that in hdr */
851 err_status_t status;
852 int tag_len;
853 v128_t iv;
854 unsigned int aad_len;
855
856 debug_print(mod_srtp, "function srtp_protect_aead", NULL)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "function srtp_protect_aead"
"\n"), mod_srtp.name, ((void*)0))
;
857
858 /*
859 * update the key usage limit, and check it to make sure that we
860 * didn't just hit either the soft limit or the hard limit, and call
861 * the event handler if we hit either.
862 */
863 switch (key_limit_update(stream->limit)) {
864 case key_event_normal:
865 break;
866 case key_event_hard_limit:
867 srtp_handle_event(ctx, stream, event_key_hard_limit)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_key_hard_limit
; srtp_event_handler(&data); }
;
868 return err_status_key_expired;
869 case key_event_soft_limit:
870 default:
871 srtp_handle_event(ctx, stream, event_key_soft_limit)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_key_soft_limit
; srtp_event_handler(&data); }
;
872 break;
873 }
874
875 /* get tag length from stream */
876 tag_len = auth_get_tag_length(stream->rtp_auth);
877
878 /*
879 * find starting point for encryption and length of data to be
880 * encrypted - the encrypted portion starts after the rtp header
881 * extension, if present; otherwise, it starts after the last csrc,
882 * if any are present
883 */
884 enc_start = (uint32_t*)hdr + uint32s_in_rtp_header3 + hdr->cc;
885 if (hdr->x == 1) {
886 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t*)enc_start;
887 enc_start += (ntohs(xtn_hdr->length)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (xtn_hdr->length); if (__builtin_constant_p (__x)) __v
= ((unsigned short int) ((((__x) >> 8) & 0xff) | (
((__x) & 0xff) << 8))); else __asm__ ("rorw $8, %w0"
: "=r" (__v) : "0" (__x) : "cc"); __v; }))
+ 1);
888 }
889 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
890 return err_status_parse_err;
891 enc_octet_len = (unsigned int)(*pkt_octet_len -
892 ((uint8_t*)enc_start - (uint8_t*)hdr));
893
894 /*
895 * estimate the packet index using the start of the replay window
896 * and the sequence number from the header
897 */
898 delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (hdr->seq); if (__builtin_constant_p (__x)) __v = ((
unsigned short int) ((((__x) >> 8) & 0xff) | (((__x
) & 0xff) << 8))); else __asm__ ("rorw $8, %w0" : "=r"
(__v) : "0" (__x) : "cc"); __v; }))
);
899 status = rdbx_check(&stream->rtp_rdbx, delta);
900 if (status) {
901 if (status != err_status_replay_fail || !stream->allow_repeat_tx) {
902 return status; /* we've been asked to reuse an index */
903 }
904 } else {
905 rdbx_add_index(&stream->rtp_rdbx, delta);
906 }
907
908#ifdef NO_64BIT_MATH
909 debug_print2(mod_srtp, "estimated packet index: %08x%08x",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "estimated packet index: %08x%08x"
"\n"), mod_srtp.name, high32(est),low32(est))
910 high32(est), low32(est))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "estimated packet index: %08x%08x"
"\n"), mod_srtp.name, high32(est),low32(est))
;
911#else
912 debug_print(mod_srtp, "estimated packet index: %016llx", est)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "estimated packet index: %016llx"
"\n"), mod_srtp.name, est)
;
913#endif
914
915 /*
916 * AEAD uses a new IV formation method
917 */
918 srtp_calc_aead_iv(stream, &iv, &est, hdr);
919 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt)((stream->rtp_cipher) ? (((stream->rtp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtp_cipher)->state
), (&iv), (direction_encrypt))) : err_status_no_such_op)
;
920 if (status) {
921 return err_status_cipher_fail;
922 }
923
924 /* shift est, put into network byte order */
925#ifdef NO_64BIT_MATH
926 est = be64_to_cpu(make64((high32(est) << 16) |(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
927 (low32(est) >> 16),(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
928 low32(est) << 16))(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
;
929#else
930 est = be64_to_cpu(est << 16)(__extension__ ({ __uint64_t __v, __x = ((est << 16)); if
(__builtin_constant_p (__x)) __v = (__extension__ ((((__x) &
0xff00000000000000ull) >> 56) | (((__x) & 0x00ff000000000000ull
) >> 40) | (((__x) & 0x0000ff0000000000ull) >>
24) | (((__x) & 0x000000ff00000000ull) >> 8) | (((
__x) & 0x00000000ff000000ull) << 8) | (((__x) &
0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
;
931#endif
932
933 /*
934 * Set the AAD over the RTP header
935 */
936 aad_len = (uint8_t *)enc_start - (uint8_t *)hdr;
937 status = cipher_set_aad(stream->rtp_cipher, (uint8_t*)hdr, aad_len)(((stream->rtp_cipher) && (((stream->rtp_cipher
)->type)->set_aad)) ? (((stream->rtp_cipher)->type
)->set_aad(((stream->rtp_cipher)->state), ((uint8_t*
)hdr), (aad_len))) : err_status_no_such_op)
;
938 if (status) {
939 return ( err_status_cipher_fail);
940 }
941
942 /* Encrypt the payload */
943 status = cipher_encrypt(stream->rtp_cipher,(((stream->rtp_cipher)->type)->encrypt(((stream->
rtp_cipher)->state), ((uint8_t*)enc_start), (&enc_octet_len
)))
944 (uint8_t*)enc_start, &enc_octet_len)(((stream->rtp_cipher)->type)->encrypt(((stream->
rtp_cipher)->state), ((uint8_t*)enc_start), (&enc_octet_len
)))
;
945 if (status) {
946 return err_status_cipher_fail;
947 }
948 /*
949 * If we're doing GCM, we need to get the tag
950 * and append that to the output
951 */
952 status = cipher_get_tag(stream->rtp_cipher,(((stream->rtp_cipher)->type)->get_tag(((stream->
rtp_cipher)->state), ((uint8_t*)enc_start+enc_octet_len), (
&tag_len)))
953 (uint8_t*)enc_start+enc_octet_len, &tag_len)(((stream->rtp_cipher)->type)->get_tag(((stream->
rtp_cipher)->state), ((uint8_t*)enc_start+enc_octet_len), (
&tag_len)))
;
954 if (status) {
955 return ( err_status_cipher_fail);
956 }
957 enc_octet_len += tag_len;
958
959 /* increase the packet length by the length of the auth tag */
960 *pkt_octet_len += tag_len;
961
962 return err_status_ok;
963}
964
965
966/*
967 * This function handles incoming SRTP packets while in AEAD mode,
968 * which currently supports AES-GCM encryption. All packets are
969 * encrypted and authenticated. Note, the auth tag is at the end
970 * of the packet stream and is automatically checked by GCM
971 * when decrypting the payload.
972 */
973static err_status_t
974srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
975 xtd_seq_num_t est, void *srtp_hdr, unsigned int *pkt_octet_len)
976{
977 srtp_hdr_t *hdr = (srtp_hdr_t*)srtp_hdr;
978 uint32_t *enc_start; /* pointer to start of encrypted portion */
979 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
980 v128_t iv;
981 err_status_t status;
982 int tag_len;
983 unsigned int aad_len;
984
985 debug_print(mod_srtp, "function srtp_unprotect_aead", NULL)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "function srtp_unprotect_aead"
"\n"), mod_srtp.name, ((void*)0))
;
986
987#ifdef NO_64BIT_MATH
988 debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est), low32(est))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "estimated u_packet index: %08x%08x"
"\n"), mod_srtp.name, high32(est),low32(est))
;
989#else
990 debug_print(mod_srtp, "estimated u_packet index: %016llx", est)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "estimated u_packet index: %016llx"
"\n"), mod_srtp.name, est)
;
991#endif
992
993 /* get tag length from stream */
994 tag_len = auth_get_tag_length(stream->rtp_auth);
995
996 /*
997 * AEAD uses a new IV formation method
998 */
999 srtp_calc_aead_iv(stream, &iv, &est, hdr);
1000 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt)((stream->rtp_cipher) ? (((stream->rtp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtp_cipher)->state
), (&iv), (direction_decrypt))) : err_status_no_such_op)
;
1001 if (status) {
1002 return err_status_cipher_fail;
1003 }
1004
1005 /*
1006 * find starting point for decryption and length of data to be
1007 * decrypted - the encrypted portion starts after the rtp header
1008 * extension, if present; otherwise, it starts after the last csrc,
1009 * if any are present
1010 */
1011 enc_start = (uint32_t*)hdr + uint32s_in_rtp_header3 + hdr->cc;
1012 if (hdr->x == 1) {
1013 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t*)enc_start;
1014 enc_start += (ntohs(xtn_hdr->length)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (xtn_hdr->length); if (__builtin_constant_p (__x)) __v
= ((unsigned short int) ((((__x) >> 8) & 0xff) | (
((__x) & 0xff) << 8))); else __asm__ ("rorw $8, %w0"
: "=r" (__v) : "0" (__x) : "cc"); __v; }))
+ 1);
1015 }
1016 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
1017 return err_status_parse_err;
1018 /*
1019 * We pass the tag down to the cipher when doing GCM mode
1020 */
1021 enc_octet_len = (unsigned int)(*pkt_octet_len -
1022 ((uint8_t*)enc_start - (uint8_t*)hdr));
1023
1024 /*
1025 * Sanity check the encrypted payload length against
1026 * the tag size. It must always be at least as large
1027 * as the tag length.
1028 */
1029 if (enc_octet_len < tag_len) {
1030 return err_status_cipher_fail;
1031 }
1032
1033 /*
1034 * update the key usage limit, and check it to make sure that we
1035 * didn't just hit either the soft limit or the hard limit, and call
1036 * the event handler if we hit either.
1037 */
1038 switch (key_limit_update(stream->limit)) {
1039 case key_event_normal:
1040 break;
1041 case key_event_soft_limit:
1042 srtp_handle_event(ctx, stream, event_key_soft_limit)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_key_soft_limit
; srtp_event_handler(&data); }
;
1043 break;
1044 case key_event_hard_limit:
1045 srtp_handle_event(ctx, stream, event_key_hard_limit)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_key_hard_limit
; srtp_event_handler(&data); }
;
1046 return err_status_key_expired;
1047 default:
1048 break;
1049 }
1050
1051 /*
1052 * Set the AAD for AES-GCM, which is the RTP header
1053 */
1054 aad_len = (uint8_t *)enc_start - (uint8_t *)hdr;
1055 status = cipher_set_aad(stream->rtp_cipher, (uint8_t*)hdr, aad_len)(((stream->rtp_cipher) && (((stream->rtp_cipher
)->type)->set_aad)) ? (((stream->rtp_cipher)->type
)->set_aad(((stream->rtp_cipher)->state), ((uint8_t*
)hdr), (aad_len))) : err_status_no_such_op)
;
1056 if (status) {
1057 return ( err_status_cipher_fail);
1058 }
1059
1060 /* Decrypt the ciphertext. This also checks the auth tag based
1061 * on the AAD we just specified above */
1062 status = cipher_decrypt(stream->rtp_cipher,(((stream->rtp_cipher)->type)->decrypt(((stream->
rtp_cipher)->state), ((uint8_t*)enc_start), (&enc_octet_len
)))
1063 (uint8_t*)enc_start, &enc_octet_len)(((stream->rtp_cipher)->type)->decrypt(((stream->
rtp_cipher)->state), ((uint8_t*)enc_start), (&enc_octet_len
)))
;
1064 if (status) {
1065 return status;
1066 }
1067
1068 /*
1069 * verify that stream is for received traffic - this check will
1070 * detect SSRC collisions, since a stream that appears in both
1071 * srtp_protect() and srtp_unprotect() will fail this test in one of
1072 * those functions.
1073 *
1074 * we do this check *after* the authentication check, so that the
1075 * latter check will catch any attempts to fool us into thinking
1076 * that we've got a collision
1077 */
1078 if (stream->direction != dir_srtp_receiver) {
1079 if (stream->direction == dir_unknown) {
1080 stream->direction = dir_srtp_receiver;
1081 } else {
1082 srtp_handle_event(ctx, stream, event_ssrc_collision)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_ssrc_collision
; srtp_event_handler(&data); }
;
1083 }
1084 }
1085
1086 /*
1087 * if the stream is a 'provisional' one, in which the template context
1088 * is used, then we need to allocate a new stream at this point, since
1089 * the authentication passed
1090 */
1091 if (stream == ctx->stream_template) {
1092 srtp_stream_ctx_t *new_stream;
1093
1094 /*
1095 * allocate and initialize a new stream
1096 *
1097 * note that we indicate failure if we can't allocate the new
1098 * stream, and some implementations will want to not return
1099 * failure here
1100 */
1101 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
1102 if (status) {
1103 return status;
1104 }
1105
1106 /* add new stream to the head of the stream_list */
1107 new_stream->next = ctx->stream_list;
1108 ctx->stream_list = new_stream;
1109
1110 /* set stream (the pointer used in this function) */
1111 stream = new_stream;
1112 }
1113
1114 /*
1115 * the message authentication function passed, so add the packet
1116 * index into the replay database
1117 */
1118 rdbx_add_index(&stream->rtp_rdbx, delta);
1119
1120 /* decrease the packet length by the length of the auth tag */
1121 *pkt_octet_len -= tag_len;
1122
1123 return err_status_ok;
1124}
1125
1126
1127
1128
1129 err_status_t
1130 srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) {
1131 srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
1132 uint32_t *enc_start; /* pointer to start of encrypted portion */
1133 uint32_t *auth_start; /* pointer to start of auth. portion */
1134 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
1135 xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
1136 int delta; /* delta of local pkt idx and that in hdr */
1137 uint8_t *auth_tag = NULL((void*)0); /* location of auth_tag within packet */
1138 err_status_t status;
1139 int tag_len;
1140 srtp_stream_ctx_t *stream;
1141 int prefix_len;
1142
1143 debug_print(mod_srtp, "function srtp_protect", NULL)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "function srtp_protect"
"\n"), mod_srtp.name, ((void*)0))
;
1144
1145 /* we assume the hdr is 32-bit aligned to start */
1146
1147 /* check the packet length - it must at least contain a full header */
1148 if (*pkt_octet_len < octets_in_rtp_header12)
1149 return err_status_bad_param;
1150
1151 /*
1152 * look up ssrc in srtp_stream list, and process the packet with
1153 * the appropriate stream. if we haven't seen this stream before,
1154 * there's a template key for this srtp_session, and the cipher
1155 * supports key-sharing, then we assume that a new stream using
1156 * that key has just started up
1157 */
1158 stream = srtp_get_stream(ctx, hdr->ssrc);
1159 if (stream == NULL((void*)0)) {
1160 if (ctx->stream_template != NULL((void*)0)) {
1161 srtp_stream_ctx_t *new_stream;
1162
1163 /* allocate and initialize a new stream */
1164 status = srtp_stream_clone(ctx->stream_template,
1165 hdr->ssrc, &new_stream);
1166 if (status)
1167 return status;
1168
1169 /* add new stream to the head of the stream_list */
1170 new_stream->next = ctx->stream_list;
1171 ctx->stream_list = new_stream;
1172
1173 /* set direction to outbound */
1174 new_stream->direction = dir_srtp_sender;
1175
1176 /* set stream (the pointer used in this function) */
1177 stream = new_stream;
1178 } else {
1179 /* no template stream, so we return an error */
1180 return err_status_no_ctx;
1181 }
1182 }
1183
1184 /*
1185 * verify that stream is for sending traffic - this check will
1186 * detect SSRC collisions, since a stream that appears in both
1187 * srtp_protect() and srtp_unprotect() will fail this test in one of
1188 * those functions.
1189 */
1190 if (stream->direction != dir_srtp_sender) {
1191 if (stream->direction == dir_unknown) {
1192 stream->direction = dir_srtp_sender;
1193 } else {
1194 srtp_handle_event(ctx, stream, event_ssrc_collision)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_ssrc_collision
; srtp_event_handler(&data); }
;
1195 }
1196 }
1197
1198 /*
1199 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
1200 * the request to our AEAD handler.
1201 */
1202 if (stream->rtp_cipher->algorithm == AES_128_GCM6 ||
1203 stream->rtp_cipher->algorithm == AES_256_GCM7) {
1204 return srtp_protect_aead(ctx, stream, rtp_hdr, (unsigned int*)pkt_octet_len);
1205 }
1206
1207 /*
1208 * update the key usage limit, and check it to make sure that we
1209 * didn't just hit either the soft limit or the hard limit, and call
1210 * the event handler if we hit either.
1211 */
1212 switch(key_limit_update(stream->limit)) {
1213 case key_event_normal:
1214 break;
1215 case key_event_soft_limit:
1216 srtp_handle_event(ctx, stream, event_key_soft_limit)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_key_soft_limit
; srtp_event_handler(&data); }
;
1217 break;
1218 case key_event_hard_limit:
1219 srtp_handle_event(ctx, stream, event_key_hard_limit)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_key_hard_limit
; srtp_event_handler(&data); }
;
1220 return err_status_key_expired;
1221 default:
1222 break;
1223 }
1224
1225 /* get tag length from stream */
1226 tag_len = auth_get_tag_length(stream->rtp_auth);
1227
1228 /*
1229 * find starting point for encryption and length of data to be
1230 * encrypted - the encrypted portion starts after the rtp header
1231 * extension, if present; otherwise, it starts after the last csrc,
1232 * if any are present
1233 *
1234 * if we're not providing confidentiality, set enc_start to NULL
1235 */
1236 if (stream->rtp_services & sec_serv_conf) {
1237 enc_start = (uint32_t *)hdr + uint32s_in_rtp_header3 + hdr->cc;
1238 if (hdr->x == 1) {
1239 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
1240 enc_start += (ntohs(xtn_hdr->length)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (xtn_hdr->length); if (__builtin_constant_p (__x)) __v
= ((unsigned short int) ((((__x) >> 8) & 0xff) | (
((__x) & 0xff) << 8))); else __asm__ ("rorw $8, %w0"
: "=r" (__v) : "0" (__x) : "cc"); __v; }))
+ 1);
1241 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
1242 return err_status_parse_err;
1243 }
1244 enc_octet_len = (unsigned int)(*pkt_octet_len -
1245 ((uint8_t*)enc_start - (uint8_t*)hdr));
1246 } else {
1247 enc_start = NULL((void*)0);
1248 }
1249
1250 /*
1251 * if we're providing authentication, set the auth_start and auth_tag
1252 * pointers to the proper locations; otherwise, set auth_start to NULL
1253 * to indicate that no authentication is needed
1254 */
1255 if (stream->rtp_services & sec_serv_auth) {
1256 auth_start = (uint32_t *)hdr;
1257 auth_tag = (uint8_t *)hdr + *pkt_octet_len;
1258 } else {
1259 auth_start = NULL((void*)0);
1260 auth_tag = NULL((void*)0);
1261 }
1262
1263 /*
1264 * estimate the packet index using the start of the replay window
1265 * and the sequence number from the header
1266 */
1267 delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (hdr->seq); if (__builtin_constant_p (__x)) __v = ((
unsigned short int) ((((__x) >> 8) & 0xff) | (((__x
) & 0xff) << 8))); else __asm__ ("rorw $8, %w0" : "=r"
(__v) : "0" (__x) : "cc"); __v; }))
);
1268 status = rdbx_check(&stream->rtp_rdbx, delta);
1269 if (status) {
1270 if (status != err_status_replay_fail || !stream->allow_repeat_tx)
1271 return status; /* we've been asked to reuse an index */
1272 }
1273 else
1274 rdbx_add_index(&stream->rtp_rdbx, delta);
1275
1276#ifdef NO_64BIT_MATH
1277 debug_print2(mod_srtp, "estimated packet index: %08x%08x",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "estimated packet index: %08x%08x"
"\n"), mod_srtp.name, high32(est),low32(est))
1278 high32(est),low32(est))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "estimated packet index: %08x%08x"
"\n"), mod_srtp.name, high32(est),low32(est))
;
1279#else
1280 debug_print(mod_srtp, "estimated packet index: %016llx", est)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "estimated packet index: %016llx"
"\n"), mod_srtp.name, est)
;
1281#endif
1282
1283 /*
1284 * if we're using rindael counter mode, set nonce and seq
1285 */
1286 if (stream->rtp_cipher->type->id == AES_ICM1 ||
1287 stream->rtp_cipher->type->id == AES_256_ICM5) {
1288 v128_t iv;
1289
1290 iv.v32[0] = 0;
1291 iv.v32[1] = hdr->ssrc;
1292#ifdef NO_64BIT_MATH
1293 iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
1294 low32(est) << 16))(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
;
1295#else
1296 iv.v64[1] = be64_to_cpu(est << 16)(__extension__ ({ __uint64_t __v, __x = ((est << 16)); if
(__builtin_constant_p (__x)) __v = (__extension__ ((((__x) &
0xff00000000000000ull) >> 56) | (((__x) & 0x00ff000000000000ull
) >> 40) | (((__x) & 0x0000ff0000000000ull) >>
24) | (((__x) & 0x000000ff00000000ull) >> 8) | (((
__x) & 0x00000000ff000000ull) << 8) | (((__x) &
0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
;
1297#endif
1298 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt)((stream->rtp_cipher) ? (((stream->rtp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtp_cipher)->state
), (&iv), (direction_encrypt))) : err_status_no_such_op)
;
1299
1300 } else {
1301 v128_t iv;
1302
1303 /* otherwise, set the index to est */
1304#ifdef NO_64BIT_MATH
1305 iv.v32[0] = 0;
1306 iv.v32[1] = 0;
1307#else
1308 iv.v64[0] = 0;
1309#endif
1310 iv.v64[1] = be64_to_cpu(est)(__extension__ ({ __uint64_t __v, __x = ((est)); if (__builtin_constant_p
(__x)) __v = (__extension__ ((((__x) & 0xff00000000000000ull
) >> 56) | (((__x) & 0x00ff000000000000ull) >>
40) | (((__x) & 0x0000ff0000000000ull) >> 24) | ((
(__x) & 0x000000ff00000000ull) >> 8) | (((__x) &
0x00000000ff000000ull) << 8) | (((__x) & 0x0000000000ff0000ull
) << 24) | (((__x) & 0x000000000000ff00ull) <<
40) | (((__x) & 0x00000000000000ffull) << 56))); else
__asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v; }))
;
1311 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt)((stream->rtp_cipher) ? (((stream->rtp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtp_cipher)->state
), (&iv), (direction_encrypt))) : err_status_no_such_op)
;
1312 }
1313 if (status)
1314 return err_status_cipher_fail;
1315
1316 /* shift est, put into network byte order */
1317#ifdef NO_64BIT_MATH
1318 est = be64_to_cpu(make64((high32(est) << 16) |(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
1319 (low32(est) >> 16),(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
1320 low32(est) << 16))(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
;
1321#else
1322 est = be64_to_cpu(est << 16)(__extension__ ({ __uint64_t __v, __x = ((est << 16)); if
(__builtin_constant_p (__x)) __v = (__extension__ ((((__x) &
0xff00000000000000ull) >> 56) | (((__x) & 0x00ff000000000000ull
) >> 40) | (((__x) & 0x0000ff0000000000ull) >>
24) | (((__x) & 0x000000ff00000000ull) >> 8) | (((
__x) & 0x00000000ff000000ull) << 8) | (((__x) &
0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
;
1323#endif
1324
1325 /*
1326 * if we're authenticating using a universal hash, put the keystream
1327 * prefix into the authentication tag
1328 */
1329 if (auth_start) {
1330
1331 prefix_len = auth_get_prefix_length(stream->rtp_auth);
1332 if (prefix_len) {
1333 status = cipher_output(stream->rtp_cipher, auth_tag, prefix_len);
1334 if (status)
1335 return err_status_cipher_fail;
1336 debug_print(mod_srtp, "keystream prefix: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "keystream prefix: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, prefix_len
))
1337 octet_string_hex_string(auth_tag, prefix_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "keystream prefix: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, prefix_len
))
;
1338 }
1339 }
1340
1341 /* if we're encrypting, exor keystream into the message */
1342 if (enc_start) {
1343 status = cipher_encrypt(stream->rtp_cipher,(((stream->rtp_cipher)->type)->encrypt(((stream->
rtp_cipher)->state), ((uint8_t *)enc_start), (&enc_octet_len
)))
1344 (uint8_t *)enc_start, &enc_octet_len)(((stream->rtp_cipher)->type)->encrypt(((stream->
rtp_cipher)->state), ((uint8_t *)enc_start), (&enc_octet_len
)))
;
1345 if (status)
1346 return err_status_cipher_fail;
1347 }
1348
1349 /*
1350 * if we're authenticating, run authentication function and put result
1351 * into the auth_tag
1352 */
1353 if (auth_start) {
1354
1355 /* initialize auth func context */
1356 status = auth_start(stream->rtp_auth)(((stream->rtp_auth)->type)->start((stream->rtp_auth
)->state))
;
1357 if (status) return status;
1358
1359 /* run auth func over packet */
1360 status = auth_update(stream->rtp_auth,(((stream->rtp_auth)->type)->update((stream->rtp_auth
)->state, ((uint8_t *)auth_start), (*pkt_octet_len)))
1361 (uint8_t *)auth_start, *pkt_octet_len)(((stream->rtp_auth)->type)->update((stream->rtp_auth
)->state, ((uint8_t *)auth_start), (*pkt_octet_len)))
;
1362 if (status) return status;
1363
1364 /* run auth func over ROC, put result into auth_tag */
1365 debug_print(mod_srtp, "estimated packet index: %016llx", est)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "estimated packet index: %016llx"
"\n"), mod_srtp.name, est)
;
1366 status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag)(((stream->rtp_auth)->type)->compute((stream->rtp_auth
)->state, ((uint8_t *)&est), (4), (stream->rtp_auth
)->out_len, (auth_tag)))
;
1367 debug_print(mod_srtp, "srtp auth tag: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtp auth tag: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, tag_len
))
1368 octet_string_hex_string(auth_tag, tag_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtp auth tag: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, tag_len
))
;
1369 if (status)
1370 return err_status_auth_fail;
1371
1372 }
1373
1374 if (auth_tag) {
1375
1376 /* increase the packet length by the length of the auth tag */
1377 *pkt_octet_len += tag_len;
1378 }
1379
1380 return err_status_ok;
1381}
1382
1383
1384err_status_t
1385srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
1386 srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr;
1387 uint32_t *enc_start; /* pointer to start of encrypted portion */
1388 uint32_t *auth_start; /* pointer to start of auth. portion */
1389 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
1390 uint8_t *auth_tag = NULL((void*)0); /* location of auth_tag within packet */
1391 xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
1392 int delta; /* delta of local pkt idx and that in hdr */
1393 v128_t iv;
1394 err_status_t status;
1395 srtp_stream_ctx_t *stream;
1396 uint8_t tmp_tag[SRTP_MAX_TAG_LEN12];
1397 int tag_len, prefix_len;
1398
1399 debug_print(mod_srtp, "function srtp_unprotect", NULL)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "function srtp_unprotect"
"\n"), mod_srtp.name, ((void*)0))
;
1400
1401 /* we assume the hdr is 32-bit aligned to start */
1402
1403 /* check the packet length - it must at least contain a full header */
1404 if (*pkt_octet_len < octets_in_rtp_header12)
1405 return err_status_bad_param;
1406
1407 /*
1408 * look up ssrc in srtp_stream list, and process the packet with
1409 * the appropriate stream. if we haven't seen this stream before,
1410 * there's only one key for this srtp_session, and the cipher
1411 * supports key-sharing, then we assume that a new stream using
1412 * that key has just started up
1413 */
1414 stream = srtp_get_stream(ctx, hdr->ssrc);
1415 if (stream == NULL((void*)0)) {
1416 if (ctx->stream_template != NULL((void*)0)) {
1417 stream = ctx->stream_template;
1418 debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "using provisional stream (SSRC: 0x%08x)"
"\n"), mod_srtp.name, hdr->ssrc)
1419 hdr->ssrc)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "using provisional stream (SSRC: 0x%08x)"
"\n"), mod_srtp.name, hdr->ssrc)
;
1420
1421 /*
1422 * set estimated packet index to sequence number from header,
1423 * and set delta equal to the same value
1424 */
1425#ifdef NO_64BIT_MATH
1426 est = (xtd_seq_num_t) make64(0,ntohs(hdr->seq)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (hdr->seq); if (__builtin_constant_p (__x)) __v = ((
unsigned short int) ((((__x) >> 8) & 0xff) | (((__x
) & 0xff) << 8))); else __asm__ ("rorw $8, %w0" : "=r"
(__v) : "0" (__x) : "cc"); __v; }))
);
1427 delta = low32(est);
1428#else
1429 est = (xtd_seq_num_t) ntohs(hdr->seq)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (hdr->seq); if (__builtin_constant_p (__x)) __v = ((
unsigned short int) ((((__x) >> 8) & 0xff) | (((__x
) & 0xff) << 8))); else __asm__ ("rorw $8, %w0" : "=r"
(__v) : "0" (__x) : "cc"); __v; }))
;
1430 delta = (int)est;
1431#endif
1432 } else {
1433
1434 /*
1435 * no stream corresponding to SSRC found, and we don't do
1436 * key-sharing, so return an error
1437 */
1438 return err_status_no_ctx;
1439 }
1440 } else {
1441
1442 /* estimate packet index from seq. num. in header */
1443 delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (hdr->seq); if (__builtin_constant_p (__x)) __v = ((
unsigned short int) ((((__x) >> 8) & 0xff) | (((__x
) & 0xff) << 8))); else __asm__ ("rorw $8, %w0" : "=r"
(__v) : "0" (__x) : "cc"); __v; }))
);
1444
1445 /* check replay database */
1446 status = rdbx_check(&stream->rtp_rdbx, delta);
1447 if (status)
1448 return status;
1449 }
1450
1451#ifdef NO_64BIT_MATH
1452 debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),low32(est))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "estimated u_packet index: %08x%08x"
"\n"), mod_srtp.name, high32(est),low32(est))
;
1453#else
1454 debug_print(mod_srtp, "estimated u_packet index: %016llx", est)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "estimated u_packet index: %016llx"
"\n"), mod_srtp.name, est)
;
1455#endif
1456
1457 /*
1458 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
1459 * the request to our AEAD handler.
1460 */
1461 if (stream->rtp_cipher->algorithm == AES_128_GCM6 ||
1462 stream->rtp_cipher->algorithm == AES_256_GCM7) {
1463 return srtp_unprotect_aead(ctx, stream, delta, est, srtp_hdr, (unsigned int*)pkt_octet_len);
1464 }
1465
1466 /* get tag length from stream */
1467 tag_len = auth_get_tag_length(stream->rtp_auth);
1468
1469 /*
1470 * set the cipher's IV properly, depending on whatever cipher we
1471 * happen to be using
1472 */
1473 if (stream->rtp_cipher->type->id == AES_ICM1 ||
1474 stream->rtp_cipher->type->id == AES_256_ICM5) {
1475
1476 /* aes counter mode */
1477 iv.v32[0] = 0;
1478 iv.v32[1] = hdr->ssrc; /* still in network order */
1479#ifdef NO_64BIT_MATH
1480 iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
1481 low32(est) << 16))(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
;
1482#else
1483 iv.v64[1] = be64_to_cpu(est << 16)(__extension__ ({ __uint64_t __v, __x = ((est << 16)); if
(__builtin_constant_p (__x)) __v = (__extension__ ((((__x) &
0xff00000000000000ull) >> 56) | (((__x) & 0x00ff000000000000ull
) >> 40) | (((__x) & 0x0000ff0000000000ull) >>
24) | (((__x) & 0x000000ff00000000ull) >> 8) | (((
__x) & 0x00000000ff000000ull) << 8) | (((__x) &
0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
;
1484#endif
1485 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt)((stream->rtp_cipher) ? (((stream->rtp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtp_cipher)->state
), (&iv), (direction_decrypt))) : err_status_no_such_op)
;
1486 } else {
1487
1488 /* no particular format - set the iv to the pakcet index */
1489#ifdef NO_64BIT_MATH
1490 iv.v32[0] = 0;
1491 iv.v32[1] = 0;
1492#else
1493 iv.v64[0] = 0;
1494#endif
1495 iv.v64[1] = be64_to_cpu(est)(__extension__ ({ __uint64_t __v, __x = ((est)); if (__builtin_constant_p
(__x)) __v = (__extension__ ((((__x) & 0xff00000000000000ull
) >> 56) | (((__x) & 0x00ff000000000000ull) >>
40) | (((__x) & 0x0000ff0000000000ull) >> 24) | ((
(__x) & 0x000000ff00000000ull) >> 8) | (((__x) &
0x00000000ff000000ull) << 8) | (((__x) & 0x0000000000ff0000ull
) << 24) | (((__x) & 0x000000000000ff00ull) <<
40) | (((__x) & 0x00000000000000ffull) << 56))); else
__asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v; }))
;
1496 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt)((stream->rtp_cipher) ? (((stream->rtp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtp_cipher)->state
), (&iv), (direction_decrypt))) : err_status_no_such_op)
;
1497 }
1498 if (status)
1499 return err_status_cipher_fail;
1500
1501 /* shift est, put into network byte order */
1502#ifdef NO_64BIT_MATH
1503 est = be64_to_cpu(make64((high32(est) << 16) |(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
1504 (low32(est) >> 16),(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
1505 low32(est) << 16))(__extension__ ({ __uint64_t __v, __x = ((make64((high32(est)
<< 16) | (low32(est) >> 16), low32(est) <<
16))); if (__builtin_constant_p (__x)) __v = (__extension__ (
(((__x) & 0xff00000000000000ull) >> 56) | (((__x) &
0x00ff000000000000ull) >> 40) | (((__x) & 0x0000ff0000000000ull
) >> 24) | (((__x) & 0x000000ff00000000ull) >>
8) | (((__x) & 0x00000000ff000000ull) << 8) | (((__x
) & 0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
;
1506#else
1507 est = be64_to_cpu(est << 16)(__extension__ ({ __uint64_t __v, __x = ((est << 16)); if
(__builtin_constant_p (__x)) __v = (__extension__ ((((__x) &
0xff00000000000000ull) >> 56) | (((__x) & 0x00ff000000000000ull
) >> 40) | (((__x) & 0x0000ff0000000000ull) >>
24) | (((__x) & 0x000000ff00000000ull) >> 8) | (((
__x) & 0x00000000ff000000ull) << 8) | (((__x) &
0x0000000000ff0000ull) << 24) | (((__x) & 0x000000000000ff00ull
) << 40) | (((__x) & 0x00000000000000ffull) <<
56))); else __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); __v
; }))
;
1508#endif
1509
1510 /*
1511 * find starting point for decryption and length of data to be
1512 * decrypted - the encrypted portion starts after the rtp header
1513 * extension, if present; otherwise, it starts after the last csrc,
1514 * if any are present
1515 *
1516 * if we're not providing confidentiality, set enc_start to NULL
1517 */
1518 if (stream->rtp_services & sec_serv_conf) {
1519 enc_start = (uint32_t *)hdr + uint32s_in_rtp_header3 + hdr->cc;
1520 if (hdr->x == 1) {
1521 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
1522 enc_start += (ntohs(xtn_hdr->length)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (xtn_hdr->length); if (__builtin_constant_p (__x)) __v
= ((unsigned short int) ((((__x) >> 8) & 0xff) | (
((__x) & 0xff) << 8))); else __asm__ ("rorw $8, %w0"
: "=r" (__v) : "0" (__x) : "cc"); __v; }))
+ 1);
1523 }
1524 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
1525 return err_status_parse_err;
1526 enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len -
1527 ((uint8_t*)enc_start - (uint8_t*)hdr));
1528 } else {
1529 enc_start = NULL((void*)0);
1530 }
1531
1532 /*
1533 * if we're providing authentication, set the auth_start and auth_tag
1534 * pointers to the proper locations; otherwise, set auth_start to NULL
1535 * to indicate that no authentication is needed
1536 */
1537 if (stream->rtp_services & sec_serv_auth) {
1538 auth_start = (uint32_t *)hdr;
1539 auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len;
1540 } else {
1541 auth_start = NULL((void*)0);
1542 auth_tag = NULL((void*)0);
1543 }
1544
1545 /*
1546 * if we expect message authentication, run the authentication
1547 * function and compare the result with the value of the auth_tag
1548 */
1549 if (auth_start) {
1550
1551 /*
1552 * if we're using a universal hash, then we need to compute the
1553 * keystream prefix for encrypting the universal hash output
1554 *
1555 * if the keystream prefix length is zero, then we know that
1556 * the authenticator isn't using a universal hash function
1557 */
1558 if (stream->rtp_auth->prefix_len != 0) {
1559
1560 prefix_len = auth_get_prefix_length(stream->rtp_auth);
1561 status = cipher_output(stream->rtp_cipher, tmp_tag, prefix_len);
1562 debug_print(mod_srtp, "keystream prefix: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "keystream prefix: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_tag, prefix_len
))
1563 octet_string_hex_string(tmp_tag, prefix_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "keystream prefix: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_tag, prefix_len
))
;
1564 if (status)
1565 return err_status_cipher_fail;
1566 }
1567
1568 /* initialize auth func context */
1569 status = auth_start(stream->rtp_auth)(((stream->rtp_auth)->type)->start((stream->rtp_auth
)->state))
;
1570 if (status) return status;
1571
1572 /* now compute auth function over packet */
1573 status = auth_update(stream->rtp_auth, (uint8_t *)auth_start,(((stream->rtp_auth)->type)->update((stream->rtp_auth
)->state, ((uint8_t *)auth_start), (*pkt_octet_len - tag_len
)))
Value stored to 'status' is never read
1574 *pkt_octet_len - tag_len)(((stream->rtp_auth)->type)->update((stream->rtp_auth
)->state, ((uint8_t *)auth_start), (*pkt_octet_len - tag_len
)))
;
1575
1576 /* run auth func over ROC, then write tmp tag */
1577 status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag)(((stream->rtp_auth)->type)->compute((stream->rtp_auth
)->state, ((uint8_t *)&est), (4), (stream->rtp_auth
)->out_len, (tmp_tag)))
;
1578
1579 debug_print(mod_srtp, "computed auth tag: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "computed auth tag: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_tag, tag_len
))
1580 octet_string_hex_string(tmp_tag, tag_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "computed auth tag: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_tag, tag_len
))
;
1581 debug_print(mod_srtp, "packet auth tag: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "packet auth tag: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, tag_len
))
1582 octet_string_hex_string(auth_tag, tag_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "packet auth tag: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, tag_len
))
;
1583 if (status)
1584 return err_status_auth_fail;
1585
1586 if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
1587 return err_status_auth_fail;
1588 }
1589
1590 /*
1591 * update the key usage limit, and check it to make sure that we
1592 * didn't just hit either the soft limit or the hard limit, and call
1593 * the event handler if we hit either.
1594 */
1595 switch(key_limit_update(stream->limit)) {
1596 case key_event_normal:
1597 break;
1598 case key_event_soft_limit:
1599 srtp_handle_event(ctx, stream, event_key_soft_limit)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_key_soft_limit
; srtp_event_handler(&data); }
;
1600 break;
1601 case key_event_hard_limit:
1602 srtp_handle_event(ctx, stream, event_key_hard_limit)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_key_hard_limit
; srtp_event_handler(&data); }
;
1603 return err_status_key_expired;
1604 default:
1605 break;
1606 }
1607
1608 /* if we're decrypting, add keystream into ciphertext */
1609 if (enc_start) {
1610 status = cipher_decrypt(stream->rtp_cipher,(((stream->rtp_cipher)->type)->decrypt(((stream->
rtp_cipher)->state), ((uint8_t *)enc_start), (&enc_octet_len
)))
1611 (uint8_t *)enc_start, &enc_octet_len)(((stream->rtp_cipher)->type)->decrypt(((stream->
rtp_cipher)->state), ((uint8_t *)enc_start), (&enc_octet_len
)))
;
1612 if (status)
1613 return err_status_cipher_fail;
1614 }
1615
1616 /*
1617 * verify that stream is for received traffic - this check will
1618 * detect SSRC collisions, since a stream that appears in both
1619 * srtp_protect() and srtp_unprotect() will fail this test in one of
1620 * those functions.
1621 *
1622 * we do this check *after* the authentication check, so that the
1623 * latter check will catch any attempts to fool us into thinking
1624 * that we've got a collision
1625 */
1626 if (stream->direction != dir_srtp_receiver) {
1627 if (stream->direction == dir_unknown) {
1628 stream->direction = dir_srtp_receiver;
1629 } else {
1630 srtp_handle_event(ctx, stream, event_ssrc_collision)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_ssrc_collision
; srtp_event_handler(&data); }
;
1631 }
1632 }
1633
1634 /*
1635 * if the stream is a 'provisional' one, in which the template context
1636 * is used, then we need to allocate a new stream at this point, since
1637 * the authentication passed
1638 */
1639 if (stream == ctx->stream_template) {
1640 srtp_stream_ctx_t *new_stream;
1641
1642 /*
1643 * allocate and initialize a new stream
1644 *
1645 * note that we indicate failure if we can't allocate the new
1646 * stream, and some implementations will want to not return
1647 * failure here
1648 */
1649 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
1650 if (status)
1651 return status;
1652
1653 /* add new stream to the head of the stream_list */
1654 new_stream->next = ctx->stream_list;
1655 ctx->stream_list = new_stream;
1656
1657 /* set stream (the pointer used in this function) */
1658 stream = new_stream;
1659 }
1660
1661 /*
1662 * the message authentication function passed, so add the packet
1663 * index into the replay database
1664 */
1665 rdbx_add_index(&stream->rtp_rdbx, delta);
1666
1667 /* decrease the packet length by the length of the auth tag */
1668 *pkt_octet_len -= tag_len;
1669
1670 return err_status_ok;
1671}
1672
1673err_status_t
1674srtp_init() {
1675 err_status_t status;
1676
1677 /* initialize crypto kernel */
1678 status = crypto_kernel_init();
1679 if (status)
1680 return status;
1681
1682 /* load srtp debug module into the kernel */
1683 status = crypto_kernel_load_debug_module(&mod_srtp);
1684 if (status)
1685 return status;
1686
1687 return err_status_ok;
1688}
1689
1690err_status_t
1691srtp_shutdown() {
1692 err_status_t status;
1693
1694 /* shut down crypto kernel */
1695 status = crypto_kernel_shutdown();
1696 if (status)
1697 return status;
1698
1699 /* shutting down crypto kernel frees the srtp debug module as well */
1700
1701 return err_status_ok;
1702}
1703
1704
1705/*
1706 * The following code is under consideration for removal. See
1707 * SRTP_MAX_TRAILER_LEN
1708 */
1709#if 0
1710
1711/*
1712 * srtp_get_trailer_length(&a) returns the number of octets that will
1713 * be added to an RTP packet by the SRTP processing. This value
1714 * is constant for a given srtp_stream_t (i.e. between initializations).
1715 */
1716
1717int
1718srtp_get_trailer_length(const srtp_stream_t s) {
1719 return auth_get_tag_length(s->rtp_auth);
1720}
1721
1722#endif
1723
1724/*
1725 * srtp_get_stream(ssrc) returns a pointer to the stream corresponding
1726 * to ssrc, or NULL if no stream exists for that ssrc
1727 *
1728 * this is an internal function
1729 */
1730
1731srtp_stream_ctx_t *
1732srtp_get_stream(srtp_t srtp, uint32_t ssrc) {
1733 srtp_stream_ctx_t *stream;
1734
1735 /* walk down list until ssrc is found */
1736 stream = srtp->stream_list;
1737 while (stream != NULL((void*)0)) {
1738 if (stream->ssrc == ssrc)
1739 return stream;
1740 stream = stream->next;
1741 }
1742
1743 /* we haven't found our ssrc, so return a null */
1744 return NULL((void*)0);
1745}
1746
1747err_status_t
1748srtp_dealloc(srtp_t session) {
1749 srtp_stream_ctx_t *stream;
1750 err_status_t status;
1751
1752 /*
1753 * we take a conservative deallocation strategy - if we encounter an
1754 * error deallocating a stream, then we stop trying to deallocate
1755 * memory and just return an error
1756 */
1757
1758 /* walk list of streams, deallocating as we go */
1759 stream = session->stream_list;
1760 while (stream != NULL((void*)0)) {
1761 srtp_stream_t next = stream->next;
1762 status = srtp_stream_dealloc(session, stream);
1763 if (status)
1764 return status;
1765 stream = next;
1766 }
1767
1768 /* deallocate stream template, if there is one */
1769 if (session->stream_template != NULL((void*)0)) {
1770 status = auth_dealloc(session->stream_template->rtcp_auth)(((session->stream_template->rtcp_auth)->type)->dealloc
(session->stream_template->rtcp_auth))
;
1771 if (status)
1772 return status;
1773 status = cipher_dealloc(session->stream_template->rtcp_cipher)(((session->stream_template->rtcp_cipher)->type)->
dealloc(session->stream_template->rtcp_cipher))
;
1774 if (status)
1775 return status;
1776 crypto_free(session->stream_template->limit);
1777 status = cipher_dealloc(session->stream_template->rtp_cipher)(((session->stream_template->rtp_cipher)->type)->
dealloc(session->stream_template->rtp_cipher))
;
1778 if (status)
1779 return status;
1780 status = auth_dealloc(session->stream_template->rtp_auth)(((session->stream_template->rtp_auth)->type)->dealloc
(session->stream_template->rtp_auth))
;
1781 if (status)
1782 return status;
1783 status = rdbx_dealloc(&session->stream_template->rtp_rdbx);
1784 if (status)
1785 return status;
1786 crypto_free(session->stream_template);
1787 }
1788
1789 /* deallocate session context */
1790 crypto_free(session);
1791
1792 return err_status_ok;
1793}
1794
1795
1796err_status_t
1797srtp_add_stream(srtp_t session,
1798 const srtp_policy_t *policy) {
1799 err_status_t status;
1800 srtp_stream_t tmp;
1801
1802 /* sanity check arguments */
1803 if ((session == NULL((void*)0)) || (policy == NULL((void*)0)) || (policy->key == NULL((void*)0)))
1804 return err_status_bad_param;
1805
1806 /* allocate stream */
1807 status = srtp_stream_alloc(&tmp, policy);
1808 if (status) {
1809 return status;
1810 }
1811
1812 /* initialize stream */
1813 status = srtp_stream_init(tmp, policy);
1814 if (status) {
1815 crypto_free(tmp);
1816 return status;
1817 }
1818
1819 /*
1820 * set the head of the stream list or the template to point to the
1821 * stream that we've just alloced and init'ed, depending on whether
1822 * or not it has a wildcard SSRC value or not
1823 *
1824 * if the template stream has already been set, then the policy is
1825 * inconsistent, so we return a bad_param error code
1826 */
1827 switch (policy->ssrc.type) {
1828 case (ssrc_any_outbound):
1829 if (session->stream_template) {
1830 return err_status_bad_param;
1831 }
1832 session->stream_template = tmp;
1833 session->stream_template->direction = dir_srtp_sender;
1834 break;
1835 case (ssrc_any_inbound):
1836 if (session->stream_template) {
1837 return err_status_bad_param;
1838 }
1839 session->stream_template = tmp;
1840 session->stream_template->direction = dir_srtp_receiver;
1841 break;
1842 case (ssrc_specific):
1843 tmp->next = session->stream_list;
1844 session->stream_list = tmp;
1845 break;
1846 case (ssrc_undefined):
1847 default:
1848 crypto_free(tmp);
1849 return err_status_bad_param;
1850 }
1851
1852 return err_status_ok;
1853}
1854
1855
1856err_status_t
1857srtp_create(srtp_t *session, /* handle for session */
1858 const srtp_policy_t *policy) { /* SRTP policy (list) */
1859 err_status_t stat;
1860 srtp_ctx_t *ctx;
1861
1862 /* sanity check arguments */
1863 if (session == NULL((void*)0))
1864 return err_status_bad_param;
1865
1866 /* allocate srtp context and set ctx_ptr */
1867 ctx = (srtp_ctx_t *) crypto_alloc(sizeof(srtp_ctx_t));
1868 if (ctx == NULL((void*)0))
1869 return err_status_alloc_fail;
1870 *session = ctx;
1871
1872 /*
1873 * loop over elements in the policy list, allocating and
1874 * initializing a stream for each element
1875 */
1876 ctx->stream_template = NULL((void*)0);
1877 ctx->stream_list = NULL((void*)0);
1878 while (policy != NULL((void*)0)) {
1879
1880 stat = srtp_add_stream(ctx, policy);
1881 if (stat) {
1882 /* clean up everything */
1883 srtp_dealloc(*session);
1884 return stat;
1885 }
1886
1887 /* set policy to next item in list */
1888 policy = policy->next;
1889 }
1890
1891 return err_status_ok;
1892}
1893
1894
1895err_status_t
1896srtp_remove_stream(srtp_t session, uint32_t ssrc) {
1897 srtp_stream_ctx_t *stream, *last_stream;
1898 err_status_t status;
1899
1900 /* sanity check arguments */
1901 if (session == NULL((void*)0))
1902 return err_status_bad_param;
1903
1904 /* find stream in list; complain if not found */
1905 last_stream = stream = session->stream_list;
1906 while ((stream != NULL((void*)0)) && (ssrc != stream->ssrc)) {
1907 last_stream = stream;
1908 stream = stream->next;
1909 }
1910 if (stream == NULL((void*)0))
1911 return err_status_no_ctx;
1912
1913 /* remove stream from the list */
1914 if (last_stream == stream)
1915 /* stream was first in list */
1916 session->stream_list = stream->next;
1917 else
1918 last_stream->next = stream->next;
1919
1920 /* deallocate the stream */
1921 status = srtp_stream_dealloc(session, stream);
1922 if (status)
1923 return status;
1924
1925 return err_status_ok;
1926}
1927
1928
1929/*
1930 * the default policy - provides a convenient way for callers to use
1931 * the default security policy
1932 *
1933 * this policy is that defined in the current SRTP internet draft.
1934 *
1935 */
1936
1937/*
1938 * NOTE: cipher_key_len is really key len (128 bits) plus salt len
1939 * (112 bits)
1940 */
1941/* There are hard-coded 16's for base_key_len in the key generation code */
1942
1943void
1944crypto_policy_set_rtp_default(crypto_policy_t *p) {
1945
1946 p->cipher_type = AES_ICM1;
1947 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
1948 p->auth_type = HMAC_SHA13;
1949 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
1950 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
1951 p->sec_serv = sec_serv_conf_and_auth;
1952
1953}
1954
1955void
1956crypto_policy_set_rtcp_default(crypto_policy_t *p) {
1957
1958 p->cipher_type = AES_ICM1;
1959 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
1960 p->auth_type = HMAC_SHA13;
1961 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
1962 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
1963 p->sec_serv = sec_serv_conf_and_auth;
1964
1965}
1966
1967void
1968crypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p) {
1969
1970 /*
1971 * corresponds to RFC 4568
1972 *
1973 * note that this crypto policy is intended for SRTP, but not SRTCP
1974 */
1975
1976 p->cipher_type = AES_ICM1;
1977 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
1978 p->auth_type = HMAC_SHA13;
1979 p->auth_key_len = 20; /* 160 bit key */
1980 p->auth_tag_len = 4; /* 32 bit tag */
1981 p->sec_serv = sec_serv_conf_and_auth;
1982
1983}
1984
1985
1986void
1987crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p) {
1988
1989 /*
1990 * corresponds to RFC 4568
1991 *
1992 * note that this crypto policy is intended for SRTP, but not SRTCP
1993 */
1994
1995 p->cipher_type = AES_ICM1;
1996 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
1997 p->auth_type = NULL_AUTH0;
1998 p->auth_key_len = 0;
1999 p->auth_tag_len = 0;
2000 p->sec_serv = sec_serv_conf;
2001
2002}
2003
2004
2005void
2006crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p) {
2007
2008 /*
2009 * corresponds to RFC 4568
2010 */
2011
2012 p->cipher_type = NULL_CIPHER0;
2013 p->cipher_key_len = 0;
2014 p->auth_type = HMAC_SHA13;
2015 p->auth_key_len = 20;
2016 p->auth_tag_len = 10;
2017 p->sec_serv = sec_serv_auth;
2018
2019}
2020
2021
2022void
2023crypto_policy_set_aes_cm_256_hmac_sha1_80(crypto_policy_t *p) {
2024
2025 /*
2026 * corresponds to draft-ietf-avt-big-aes-03.txt
2027 */
2028
2029 p->cipher_type = AES_ICM1;
2030 p->cipher_key_len = 46;
2031 p->auth_type = HMAC_SHA13;
2032 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
2033 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
2034 p->sec_serv = sec_serv_conf_and_auth;
2035}
2036
2037
2038void
2039crypto_policy_set_aes_cm_256_hmac_sha1_32(crypto_policy_t *p) {
2040
2041 /*
2042 * corresponds to draft-ietf-avt-big-aes-03.txt
2043 *
2044 * note that this crypto policy is intended for SRTP, but not SRTCP
2045 */
2046
2047 p->cipher_type = AES_ICM1;
2048 p->cipher_key_len = 46;
2049 p->auth_type = HMAC_SHA13;
2050 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
2051 p->auth_tag_len = 4; /* default 80 bits per RFC 3711 */
2052 p->sec_serv = sec_serv_conf_and_auth;
2053}
2054
2055/*
2056 * AES-256 with no authentication.
2057 */
2058void
2059crypto_policy_set_aes_cm_256_null_auth (crypto_policy_t *p)
2060{
2061 p->cipher_type = AES_ICM1;
2062 p->cipher_key_len = 46;
2063 p->auth_type = NULL_AUTH0;
2064 p->auth_key_len = 0;
2065 p->auth_tag_len = 0;
2066 p->sec_serv = sec_serv_conf;
2067}
2068
2069#ifdef OPENSSL1
2070/*
2071 * AES-128 GCM mode with 8 octet auth tag.
2072 */
2073void
2074crypto_policy_set_aes_gcm_128_8_auth(crypto_policy_t *p) {
2075 p->cipher_type = AES_128_GCM6;
2076 p->cipher_key_len = AES_128_GCM_KEYSIZE_WSALT12 + 16;
2077 p->auth_type = NULL_AUTH0; /* GCM handles the auth for us */
2078 p->auth_key_len = 0;
2079 p->auth_tag_len = 8; /* 8 octet tag length */
2080 p->sec_serv = sec_serv_conf_and_auth;
2081}
2082
2083/*
2084 * AES-256 GCM mode with 8 octet auth tag.
2085 */
2086void
2087crypto_policy_set_aes_gcm_256_8_auth(crypto_policy_t *p) {
2088 p->cipher_type = AES_256_GCM7;
2089 p->cipher_key_len = AES_256_GCM_KEYSIZE_WSALT12 + 32;
2090 p->auth_type = NULL_AUTH0; /* GCM handles the auth for us */
2091 p->auth_key_len = 0;
2092 p->auth_tag_len = 8; /* 8 octet tag length */
2093 p->sec_serv = sec_serv_conf_and_auth;
2094}
2095
2096/*
2097 * AES-128 GCM mode with 8 octet auth tag, no RTCP encryption.
2098 */
2099void
2100crypto_policy_set_aes_gcm_128_8_only_auth(crypto_policy_t *p) {
2101 p->cipher_type = AES_128_GCM6;
2102 p->cipher_key_len = AES_128_GCM_KEYSIZE_WSALT12 + 16;
2103 p->auth_type = NULL_AUTH0; /* GCM handles the auth for us */
2104 p->auth_key_len = 0;
2105 p->auth_tag_len = 8; /* 8 octet tag length */
2106 p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
2107}
2108
2109/*
2110 * AES-256 GCM mode with 8 octet auth tag, no RTCP encryption.
2111 */
2112void
2113crypto_policy_set_aes_gcm_256_8_only_auth(crypto_policy_t *p) {
2114 p->cipher_type = AES_256_GCM7;
2115 p->cipher_key_len = AES_256_GCM_KEYSIZE_WSALT12 + 32;
2116 p->auth_type = NULL_AUTH0; /* GCM handles the auth for us */
2117 p->auth_key_len = 0;
2118 p->auth_tag_len = 8; /* 8 octet tag length */
2119 p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
2120}
2121
2122/*
2123 * AES-128 GCM mode with 16 octet auth tag.
2124 */
2125void
2126crypto_policy_set_aes_gcm_128_16_auth(crypto_policy_t *p) {
2127 p->cipher_type = AES_128_GCM6;
2128 p->cipher_key_len = AES_128_GCM_KEYSIZE_WSALT12 + 16;
2129 p->auth_type = NULL_AUTH0; /* GCM handles the auth for us */
2130 p->auth_key_len = 0;
2131 p->auth_tag_len = 16; /* 16 octet tag length */
2132 p->sec_serv = sec_serv_conf_and_auth;
2133}
2134
2135/*
2136 * AES-256 GCM mode with 16 octet auth tag.
2137 */
2138void
2139crypto_policy_set_aes_gcm_256_16_auth(crypto_policy_t *p) {
2140 p->cipher_type = AES_256_GCM7;
2141 p->cipher_key_len = AES_256_GCM_KEYSIZE_WSALT12 + 32;
2142 p->auth_type = NULL_AUTH0; /* GCM handles the auth for us */
2143 p->auth_key_len = 0;
2144 p->auth_tag_len = 16; /* 16 octet tag length */
2145 p->sec_serv = sec_serv_conf_and_auth;
2146}
2147
2148#endif
2149
2150/*
2151 * secure rtcp functions
2152 */
2153
2154/*
2155 * AEAD uses a new IV formation method. This function implements
2156 * section 10.1 from draft-ietf-avtcore-srtp-aes-gcm-07.txt. The
2157 * calculation is defined as, where (+) is the xor operation:
2158 *
2159 * 0 1 2 3 4 5 6 7 8 9 10 11
2160 * +--+--+--+--+--+--+--+--+--+--+--+--+
2161 * |00|00| SSRC |00|00|0+SRTCP Idx|---+
2162 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2163 * |
2164 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2165 * | Encryption Salt |->(+)
2166 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2167 * |
2168 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2169 * | Initialization Vector |<--+
2170 * +--+--+--+--+--+--+--+--+--+--+--+--+*
2171 *
2172 * Input: *stream - pointer to SRTP stream context, used to retrieve
2173 * the SALT
2174 * *iv - Pointer to recieve the calculated IV
2175 * seq_num - The SEQ value to use for the IV calculation.
2176 * *hdr - The RTP header, used to get the SSRC value
2177 *
2178 */
2179static void srtp_calc_aead_iv_srtcp(srtp_stream_ctx_t *stream, v128_t *iv,
2180 uint32_t seq_num, srtcp_hdr_t *hdr)
2181{
2182 v128_t in;
2183 v128_t salt;
2184
2185 memset(&in, 0, sizeof(v128_t));
2186 memset(&salt, 0, sizeof(v128_t));
2187
2188 in.v16[0] = 0;
2189 memcpy(&in.v16[1], &hdr->ssrc, 4); /* still in network order! */
2190 in.v16[3] = 0;
2191 in.v32[2] = 0x7FFFFFFF & htonl(seq_num)(__extension__ ({ unsigned int __v, __x = (seq_num); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
; /* bit 32 is suppose to be zero */
2192
2193 debug_print(mod_srtp, "Pre-salted RTCP IV = %s\n", v128_hex_string(&in))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "Pre-salted RTCP IV = %s\n"
"\n"), mod_srtp.name, v128_hex_string(&in))
;
2194
2195 /*
2196 * Get the SALT value from the context
2197 */
2198 memcpy(salt.v8, stream->c_salt, 12);
2199 debug_print(mod_srtp, "RTCP SALT = %s\n", v128_hex_string(&salt))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "RTCP SALT = %s\n"
"\n"), mod_srtp.name, v128_hex_string(&salt))
;
2200
2201 /*
2202 * Finally, apply the SALT to the input
2203 */
2204 v128_xor(iv, &in, &salt)( (iv)->v32[0] = (&in)->v32[0] ^ (&salt)->v32
[0], (iv)->v32[1] = (&in)->v32[1] ^ (&salt)->
v32[1], (iv)->v32[2] = (&in)->v32[2] ^ (&salt)->
v32[2], (iv)->v32[3] = (&in)->v32[3] ^ (&salt)->
v32[3] )
;
2205}
2206
2207/*
2208 * This code handles AEAD ciphers for outgoing RTCP. We currently support
2209 * AES-GCM mode with 128 or 256 bit keys.
2210 */
2211static err_status_t
2212srtp_protect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream,
2213 void *rtcp_hdr, unsigned int *pkt_octet_len)
2214{
2215 srtcp_hdr_t *hdr = (srtcp_hdr_t*)rtcp_hdr;
2216 uint32_t *enc_start; /* pointer to start of encrypted portion */
2217 uint32_t *trailer; /* pointer to start of trailer */
2218 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
2219 uint8_t *auth_tag = NULL((void*)0); /* location of auth_tag within packet */
2220 err_status_t status;
2221 int tag_len;
2222 uint32_t seq_num;
2223 v128_t iv;
2224 uint32_t tseq;
2225
2226 /* get tag length from stream context */
2227 tag_len = auth_get_tag_length(stream->rtcp_auth);
2228
2229 /*
2230 * set encryption start and encryption length - if we're not
2231 * providing confidentiality, set enc_start to NULL
2232 */
2233 enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header2;
2234 enc_octet_len = *pkt_octet_len - octets_in_rtcp_header8;
2235
2236 /* NOTE: hdr->length is not usable - it refers to only the first
2237 RTCP report in the compound packet! */
2238 /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2239 multiples of 32-bits (RFC 3550 6.1) */
2240 trailer = (uint32_t*)((char*)enc_start + enc_octet_len + tag_len);
2241
2242 if (stream->rtcp_services & sec_serv_conf) {
2243 *trailer = htonl(SRTCP_E_BIT)(__extension__ ({ unsigned int __v, __x = (0x80000000); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
; /* set encrypt bit */
2244 } else {
2245 enc_start = NULL((void*)0);
2246 enc_octet_len = 0;
2247 /* 0 is network-order independant */
2248 *trailer = 0x00000000; /* set encrypt bit */
2249 }
2250
2251 /*
2252 * set the auth_tag pointer to the proper location, which is after
2253 * the payload, but before the trailer
2254 * (note that srtpc *always* provides authentication, unlike srtp)
2255 */
2256 /* Note: This would need to change for optional mikey data */
2257 auth_tag = (uint8_t*)hdr + *pkt_octet_len;
2258
2259 /*
2260 * check sequence number for overruns, and copy it into the packet
2261 * if its value isn't too big
2262 */
2263 status = rdb_increment(&stream->rtcp_rdb);
2264 if (status) {
2265 return status;
2266 }
2267 seq_num = rdb_get_value(&stream->rtcp_rdb);
2268 *trailer |= htonl(seq_num)(__extension__ ({ unsigned int __v, __x = (seq_num); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
2269 debug_print(mod_srtp, "srtcp index: %x", seq_num)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp index: %x"
"\n"), mod_srtp.name, seq_num)
;
2270
2271 /*
2272 * Calculating the IV and pass it down to the cipher
2273 */
2274 srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
2275 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt)((stream->rtcp_cipher) ? (((stream->rtcp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtcp_cipher)->
state), (&iv), (direction_encrypt))) : err_status_no_such_op
)
;
2276 if (status) {
2277 return err_status_cipher_fail;
2278 }
2279
2280 /*
2281 * Set the AAD for GCM mode
2282 */
2283 if (enc_start) {
2284 /*
2285 * If payload encryption is enabled, then the AAD consist of
2286 * the RTCP header and the seq# at the end of the packet
2287 */
2288 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)hdr), (8))) : err_status_no_such_op)
2289 octets_in_rtcp_header)(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)hdr), (8))) : err_status_no_such_op)
;
2290 if (status) {
2291 return ( err_status_cipher_fail);
2292 }
2293 } else {
2294 /*
2295 * Since payload encryption is not enabled, we must authenticate
2296 * the entire packet as described in section 10.3 in revision 07
2297 * of the draft.
2298 */
2299 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)hdr), (*pkt_octet_len))) : err_status_no_such_op)
2300 *pkt_octet_len)(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)hdr), (*pkt_octet_len))) : err_status_no_such_op)
;
2301 if (status) {
2302 return ( err_status_cipher_fail);
2303 }
2304 }
2305 /*
2306 * put the idx# into network byte order and process it as AAD
2307 */
2308 tseq = htonl(*trailer)(__extension__ ({ unsigned int __v, __x = (*trailer); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
2309 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq,(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)&tseq), (sizeof(srtcp_trailer_t)))) : err_status_no_such_op
)
2310 sizeof(srtcp_trailer_t))(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)&tseq), (sizeof(srtcp_trailer_t)))) : err_status_no_such_op
)
;
2311 if (status) {
2312 return ( err_status_cipher_fail);
2313 }
2314
2315 /* if we're encrypting, exor keystream into the message */
2316 if (enc_start) {
2317 status = cipher_encrypt(stream->rtcp_cipher,(((stream->rtcp_cipher)->type)->encrypt(((stream->
rtcp_cipher)->state), ((uint8_t*)enc_start), (&enc_octet_len
)))
2318 (uint8_t*)enc_start, &enc_octet_len)(((stream->rtcp_cipher)->type)->encrypt(((stream->
rtcp_cipher)->state), ((uint8_t*)enc_start), (&enc_octet_len
)))
;
2319 if (status) {
2320 return err_status_cipher_fail;
2321 }
2322 /*
2323 * Get the tag and append that to the output
2324 */
2325 status = cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag,(((stream->rtcp_cipher)->type)->get_tag(((stream->
rtcp_cipher)->state), ((uint8_t*)auth_tag), (&tag_len)
))
2326 &tag_len)(((stream->rtcp_cipher)->type)->get_tag(((stream->
rtcp_cipher)->state), ((uint8_t*)auth_tag), (&tag_len)
))
;
2327 if (status) {
2328 return ( err_status_cipher_fail);
2329 }
2330 enc_octet_len += tag_len;
2331 } else {
2332 /*
2333 * Even though we're not encrypting the payload, we need
2334 * to run the cipher to get the auth tag.
2335 */
2336 unsigned int nolen = 0;
2337 status = cipher_encrypt(stream->rtcp_cipher, NULL, &nolen)(((stream->rtcp_cipher)->type)->encrypt(((stream->
rtcp_cipher)->state), (((void*)0)), (&nolen)))
;
2338 if (status) {
2339 return err_status_cipher_fail;
2340 }
2341 /*
2342 * Get the tag and append that to the output
2343 */
2344 status = cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag,(((stream->rtcp_cipher)->type)->get_tag(((stream->
rtcp_cipher)->state), ((uint8_t*)auth_tag), (&tag_len)
))
2345 &tag_len)(((stream->rtcp_cipher)->type)->get_tag(((stream->
rtcp_cipher)->state), ((uint8_t*)auth_tag), (&tag_len)
))
;
2346 if (status) {
2347 return ( err_status_cipher_fail);
2348 }
2349 enc_octet_len += tag_len;
2350 }
2351
2352 /* increase the packet length by the length of the auth tag and seq_num*/
2353 *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
2354
2355 return err_status_ok;
2356}
2357
2358/*
2359 * This function handles incoming SRTCP packets while in AEAD mode,
2360 * which currently supports AES-GCM encryption. Note, the auth tag is
2361 * at the end of the packet stream and is automatically checked by GCM
2362 * when decrypting the payload.
2363 */
2364static err_status_t
2365srtp_unprotect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream,
2366 void *srtcp_hdr, unsigned int *pkt_octet_len)
2367{
2368 srtcp_hdr_t *hdr = (srtcp_hdr_t*)srtcp_hdr;
2369 uint32_t *enc_start; /* pointer to start of encrypted portion */
2370 uint32_t *trailer; /* pointer to start of trailer */
2371 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
2372 uint8_t *auth_tag = NULL((void*)0); /* location of auth_tag within packet */
2373 err_status_t status;
2374 int tag_len;
2375 unsigned int tmp_len;
2376 uint32_t seq_num;
2377 v128_t iv;
2378 uint32_t tseq;
2379
2380 /* get tag length from stream context */
2381 tag_len = auth_get_tag_length(stream->rtcp_auth);
2382
2383 /*
2384 * set encryption start, encryption length, and trailer
2385 */
2386 /* index & E (encryption) bit follow normal data. hdr->len
2387 is the number of words (32-bit) in the normal packet minus 1 */
2388 /* This should point trailer to the word past the end of the
2389 normal data. */
2390 /* This would need to be modified for optional mikey data */
2391 /*
2392 * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2393 * multiples of 32-bits (RFC 3550 6.1)
2394 */
2395 trailer = (uint32_t*)((char*)hdr + *pkt_octet_len - sizeof(srtcp_trailer_t));
2396 /*
2397 * We pass the tag down to the cipher when doing GCM mode
2398 */
2399 enc_octet_len = *pkt_octet_len - (octets_in_rtcp_header8 +
2400 sizeof(srtcp_trailer_t));
2401 auth_tag = (uint8_t*)hdr + *pkt_octet_len - tag_len - sizeof(srtcp_trailer_t);
2402
2403 if (*((unsigned char*)trailer) & SRTCP_E_BYTE_BIT0x80) {
2404 enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header2;
2405 } else {
2406 enc_octet_len = 0;
2407 enc_start = NULL((void*)0); /* this indicates that there's no encryption */
2408 }
2409
2410 /*
2411 * check the sequence number for replays
2412 */
2413 /* this is easier than dealing with bitfield access */
2414 seq_num = ntohl(*trailer)(__extension__ ({ unsigned int __v, __x = (*trailer); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
& SRTCP_INDEX_MASK0x7fffffff;
2415 debug_print(mod_srtp, "srtcp index: %x", seq_num)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp index: %x"
"\n"), mod_srtp.name, seq_num)
;
2416 status = rdb_check(&stream->rtcp_rdb, seq_num);
2417 if (status) {
2418 return status;
2419 }
2420
2421 /*
2422 * Calculate and set the IV
2423 */
2424 srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
2425 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt)((stream->rtcp_cipher) ? (((stream->rtcp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtcp_cipher)->
state), (&iv), (direction_decrypt))) : err_status_no_such_op
)
;
2426 if (status) {
2427 return err_status_cipher_fail;
2428 }
2429
2430 /*
2431 * Set the AAD for GCM mode
2432 */
2433 if (enc_start) {
2434 /*
2435 * If payload encryption is enabled, then the AAD consist of
2436 * the RTCP header and the seq# at the end of the packet
2437 */
2438 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)hdr), (8))) : err_status_no_such_op)
2439 octets_in_rtcp_header)(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)hdr), (8))) : err_status_no_such_op)
;
2440 if (status) {
2441 return ( err_status_cipher_fail);
2442 }
2443 } else {
2444 /*
2445 * Since payload encryption is not enabled, we must authenticate
2446 * the entire packet as described in section 10.3 in revision 07
2447 * of the draft.
2448 */
2449 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)hdr), ((*pkt_octet_len - tag_len - sizeof(srtcp_trailer_t))
))) : err_status_no_such_op)
2450 (*pkt_octet_len - tag_len - sizeof(srtcp_trailer_t)))(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)hdr), ((*pkt_octet_len - tag_len - sizeof(srtcp_trailer_t))
))) : err_status_no_such_op)
;
2451 if (status) {
2452 return ( err_status_cipher_fail);
2453 }
2454 }
2455
2456 /*
2457 * put the idx# into network byte order, and process it as AAD
2458 */
2459 tseq = htonl(*trailer)(__extension__ ({ unsigned int __v, __x = (*trailer); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
2460 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq,(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)&tseq), (sizeof(srtcp_trailer_t)))) : err_status_no_such_op
)
2461 sizeof(srtcp_trailer_t))(((stream->rtcp_cipher) && (((stream->rtcp_cipher
)->type)->set_aad)) ? (((stream->rtcp_cipher)->type
)->set_aad(((stream->rtcp_cipher)->state), ((uint8_t
*)&tseq), (sizeof(srtcp_trailer_t)))) : err_status_no_such_op
)
;
2462 if (status) {
2463 return ( err_status_cipher_fail);
2464 }
2465
2466 /* if we're decrypting, exor keystream into the message */
2467 if (enc_start) {
2468 status = cipher_decrypt(stream->rtcp_cipher,(((stream->rtcp_cipher)->type)->decrypt(((stream->
rtcp_cipher)->state), ((uint8_t*)enc_start), (&enc_octet_len
)))
2469 (uint8_t*)enc_start, &enc_octet_len)(((stream->rtcp_cipher)->type)->decrypt(((stream->
rtcp_cipher)->state), ((uint8_t*)enc_start), (&enc_octet_len
)))
;
2470 if (status) {
2471 return status;
2472 }
2473 } else {
2474 /*
2475 * Still need to run the cipher to check the tag
2476 */
2477 tmp_len = tag_len;
2478 status = cipher_decrypt(stream->rtcp_cipher, (uint8_t*)auth_tag,(((stream->rtcp_cipher)->type)->decrypt(((stream->
rtcp_cipher)->state), ((uint8_t*)auth_tag), (&tmp_len)
))
2479 &tmp_len)(((stream->rtcp_cipher)->type)->decrypt(((stream->
rtcp_cipher)->state), ((uint8_t*)auth_tag), (&tmp_len)
))
;
2480 if (status) {
2481 return status;
2482 }
2483 }
2484
2485 /* decrease the packet length by the length of the auth tag and seq_num*/
2486 *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
2487
2488 /*
2489 * verify that stream is for received traffic - this check will
2490 * detect SSRC collisions, since a stream that appears in both
2491 * srtp_protect() and srtp_unprotect() will fail this test in one of
2492 * those functions.
2493 *
2494 * we do this check *after* the authentication check, so that the
2495 * latter check will catch any attempts to fool us into thinking
2496 * that we've got a collision
2497 */
2498 if (stream->direction != dir_srtp_receiver) {
2499 if (stream->direction == dir_unknown) {
2500 stream->direction = dir_srtp_receiver;
2501 } else {
2502 srtp_handle_event(ctx, stream, event_ssrc_collision)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_ssrc_collision
; srtp_event_handler(&data); }
;
2503 }
2504 }
2505
2506 /*
2507 * if the stream is a 'provisional' one, in which the template context
2508 * is used, then we need to allocate a new stream at this point, since
2509 * the authentication passed
2510 */
2511 if (stream == ctx->stream_template) {
2512 srtp_stream_ctx_t *new_stream;
2513
2514 /*
2515 * allocate and initialize a new stream
2516 *
2517 * note that we indicate failure if we can't allocate the new
2518 * stream, and some implementations will want to not return
2519 * failure here
2520 */
2521 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
2522 if (status) {
2523 return status;
2524 }
2525
2526 /* add new stream to the head of the stream_list */
2527 new_stream->next = ctx->stream_list;
2528 ctx->stream_list = new_stream;
2529
2530 /* set stream (the pointer used in this function) */
2531 stream = new_stream;
2532 }
2533
2534 /* we've passed the authentication check, so add seq_num to the rdb */
2535 rdb_add_index(&stream->rtcp_rdb, seq_num);
2536
2537 return err_status_ok;
2538}
2539
2540err_status_t
2541srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {
2542 srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
2543 uint32_t *enc_start; /* pointer to start of encrypted portion */
2544 uint32_t *auth_start; /* pointer to start of auth. portion */
2545 uint32_t *trailer; /* pointer to start of trailer */
2546 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
2547 uint8_t *auth_tag = NULL((void*)0); /* location of auth_tag within packet */
2548 err_status_t status;
2549 int tag_len;
2550 srtp_stream_ctx_t *stream;
2551 int prefix_len;
2552 uint32_t seq_num;
2553
2554 /* we assume the hdr is 32-bit aligned to start */
2555
2556 /* check the packet length - it must at least contain a full header */
2557 if (*pkt_octet_len < octets_in_rtcp_header8)
2558 return err_status_bad_param;
2559
2560 /*
2561 * look up ssrc in srtp_stream list, and process the packet with
2562 * the appropriate stream. if we haven't seen this stream before,
2563 * there's only one key for this srtp_session, and the cipher
2564 * supports key-sharing, then we assume that a new stream using
2565 * that key has just started up
2566 */
2567 stream = srtp_get_stream(ctx, hdr->ssrc);
2568 if (stream == NULL((void*)0)) {
2569 if (ctx->stream_template != NULL((void*)0)) {
2570 srtp_stream_ctx_t *new_stream;
2571
2572 /* allocate and initialize a new stream */
2573 status = srtp_stream_clone(ctx->stream_template,
2574 hdr->ssrc, &new_stream);
2575 if (status)
2576 return status;
2577
2578 /* add new stream to the head of the stream_list */
2579 new_stream->next = ctx->stream_list;
2580 ctx->stream_list = new_stream;
2581
2582 /* set stream (the pointer used in this function) */
2583 stream = new_stream;
2584 } else {
2585 /* no template stream, so we return an error */
2586 return err_status_no_ctx;
2587 }
2588 }
2589
2590 /*
2591 * verify that stream is for sending traffic - this check will
2592 * detect SSRC collisions, since a stream that appears in both
2593 * srtp_protect() and srtp_unprotect() will fail this test in one of
2594 * those functions.
2595 */
2596 if (stream->direction != dir_srtp_sender) {
2597 if (stream->direction == dir_unknown) {
2598 stream->direction = dir_srtp_sender;
2599 } else {
2600 srtp_handle_event(ctx, stream, event_ssrc_collision)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_ssrc_collision
; srtp_event_handler(&data); }
;
2601 }
2602 }
2603
2604 /*
2605 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
2606 * the request to our AEAD handler.
2607 */
2608 if (stream->rtp_cipher->algorithm == AES_128_GCM6 ||
2609 stream->rtp_cipher->algorithm == AES_256_GCM7) {
2610 return srtp_protect_rtcp_aead(ctx, stream, rtcp_hdr, (unsigned int*)pkt_octet_len);
2611 }
2612
2613 /* get tag length from stream context */
2614 tag_len = auth_get_tag_length(stream->rtcp_auth);
2615
2616 /*
2617 * set encryption start and encryption length - if we're not
2618 * providing confidentiality, set enc_start to NULL
2619 */
2620 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header2;
2621 enc_octet_len = *pkt_octet_len - octets_in_rtcp_header8;
2622
2623 /* all of the packet, except the header, gets encrypted */
2624 /* NOTE: hdr->length is not usable - it refers to only the first
2625 RTCP report in the compound packet! */
2626 /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2627 multiples of 32-bits (RFC 3550 6.1) */
2628 trailer = (uint32_t *) ((char *)enc_start + enc_octet_len);
2629
2630 if (stream->rtcp_services & sec_serv_conf) {
2631 *trailer = htonl(SRTCP_E_BIT)(__extension__ ({ unsigned int __v, __x = (0x80000000); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
; /* set encrypt bit */
2632 } else {
2633 enc_start = NULL((void*)0);
2634 enc_octet_len = 0;
2635 /* 0 is network-order independant */
2636 *trailer = 0x00000000; /* set encrypt bit */
2637 }
2638
2639 /*
2640 * set the auth_start and auth_tag pointers to the proper locations
2641 * (note that srtpc *always* provides authentication, unlike srtp)
2642 */
2643 /* Note: This would need to change for optional mikey data */
2644 auth_start = (uint32_t *)hdr;
2645 auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t);
2646
2647 /* perform EKT processing if needed */
2648 ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len,
2649 rdbx_get_packet_index(&stream->rtp_rdbx));
2650
2651 /*
2652 * check sequence number for overruns, and copy it into the packet
2653 * if its value isn't too big
2654 */
2655 status = rdb_increment(&stream->rtcp_rdb);
2656 if (status)
2657 return status;
2658 seq_num = rdb_get_value(&stream->rtcp_rdb);
2659 *trailer |= htonl(seq_num)(__extension__ ({ unsigned int __v, __x = (seq_num); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
2660 debug_print(mod_srtp, "srtcp index: %x", seq_num)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp index: %x"
"\n"), mod_srtp.name, seq_num)
;
2661
2662 /*
2663 * if we're using rindael counter mode, set nonce and seq
2664 */
2665 if (stream->rtcp_cipher->type->id == AES_ICM1) {
2666 v128_t iv;
2667
2668 iv.v32[0] = 0;
2669 iv.v32[1] = hdr->ssrc; /* still in network order! */
2670 iv.v32[2] = htonl(seq_num >> 16)(__extension__ ({ unsigned int __v, __x = (seq_num >> 16
); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
2671 iv.v32[3] = htonl(seq_num << 16)(__extension__ ({ unsigned int __v, __x = (seq_num << 16
); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
2672 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt)((stream->rtcp_cipher) ? (((stream->rtcp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtcp_cipher)->
state), (&iv), (direction_encrypt))) : err_status_no_such_op
)
;
2673
2674 } else {
2675 v128_t iv;
2676
2677 /* otherwise, just set the index to seq_num */
2678 iv.v32[0] = 0;
2679 iv.v32[1] = 0;
2680 iv.v32[2] = 0;
2681 iv.v32[3] = htonl(seq_num)(__extension__ ({ unsigned int __v, __x = (seq_num); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
2682 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt)((stream->rtcp_cipher) ? (((stream->rtcp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtcp_cipher)->
state), (&iv), (direction_encrypt))) : err_status_no_such_op
)
;
2683 }
2684 if (status)
2685 return err_status_cipher_fail;
2686
2687 /*
2688 * if we're authenticating using a universal hash, put the keystream
2689 * prefix into the authentication tag
2690 */
2691
2692 /* if auth_start is non-null, then put keystream into tag */
2693 if (auth_start) {
2694
2695 /* put keystream prefix into auth_tag */
2696 prefix_len = auth_get_prefix_length(stream->rtcp_auth);
2697 status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
2698
2699 debug_print(mod_srtp, "keystream prefix: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "keystream prefix: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, prefix_len
))
2700 octet_string_hex_string(auth_tag, prefix_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "keystream prefix: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, prefix_len
))
;
2701
2702 if (status)
2703 return err_status_cipher_fail;
2704 }
2705
2706 /* if we're encrypting, exor keystream into the message */
2707 if (enc_start) {
2708 status = cipher_encrypt(stream->rtcp_cipher,(((stream->rtcp_cipher)->type)->encrypt(((stream->
rtcp_cipher)->state), ((uint8_t *)enc_start), (&enc_octet_len
)))
2709 (uint8_t *)enc_start, &enc_octet_len)(((stream->rtcp_cipher)->type)->encrypt(((stream->
rtcp_cipher)->state), ((uint8_t *)enc_start), (&enc_octet_len
)))
;
2710 if (status)
2711 return err_status_cipher_fail;
2712 }
2713
2714 /* initialize auth func context */
2715 auth_start(stream->rtcp_auth)(((stream->rtcp_auth)->type)->start((stream->rtcp_auth
)->state))
;
2716
2717 /*
2718 * run auth func over packet (including trailer), and write the
2719 * result at auth_tag
2720 */
2721 status = auth_compute(stream->rtcp_auth,(((stream->rtcp_auth)->type)->compute((stream->rtcp_auth
)->state, ((uint8_t *)auth_start), ((*pkt_octet_len) + sizeof
(srtcp_trailer_t)), (stream->rtcp_auth)->out_len, (auth_tag
)))
2722 (uint8_t *)auth_start,(((stream->rtcp_auth)->type)->compute((stream->rtcp_auth
)->state, ((uint8_t *)auth_start), ((*pkt_octet_len) + sizeof
(srtcp_trailer_t)), (stream->rtcp_auth)->out_len, (auth_tag
)))
2723 (*pkt_octet_len) + sizeof(srtcp_trailer_t),(((stream->rtcp_auth)->type)->compute((stream->rtcp_auth
)->state, ((uint8_t *)auth_start), ((*pkt_octet_len) + sizeof
(srtcp_trailer_t)), (stream->rtcp_auth)->out_len, (auth_tag
)))
2724 auth_tag)(((stream->rtcp_auth)->type)->compute((stream->rtcp_auth
)->state, ((uint8_t *)auth_start), ((*pkt_octet_len) + sizeof
(srtcp_trailer_t)), (stream->rtcp_auth)->out_len, (auth_tag
)))
;
2725 debug_print(mod_srtp, "srtcp auth tag: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp auth tag: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, tag_len
))
2726 octet_string_hex_string(auth_tag, tag_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp auth tag: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, tag_len
))
;
2727 if (status)
2728 return err_status_auth_fail;
2729
2730 /* increase the packet length by the length of the auth tag and seq_num*/
2731 *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
2732
2733 return err_status_ok;
2734}
2735
2736
2737err_status_t
2738srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) {
2739 srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
2740 uint32_t *enc_start; /* pointer to start of encrypted portion */
2741 uint32_t *auth_start; /* pointer to start of auth. portion */
2742 uint32_t *trailer; /* pointer to start of trailer */
2743 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
2744 uint8_t *auth_tag = NULL((void*)0); /* location of auth_tag within packet */
2745 uint8_t tmp_tag[SRTP_MAX_TAG_LEN12];
2746 uint8_t tag_copy[SRTP_MAX_TAG_LEN12];
2747 err_status_t status;
2748 unsigned int auth_len;
2749 int tag_len;
2750 srtp_stream_ctx_t *stream;
2751 int prefix_len;
2752 uint32_t seq_num;
2753 int e_bit_in_packet; /* whether the E-bit was found in the packet */
2754 int sec_serv_confidentiality; /* whether confidentiality was requested */
2755
2756 /* we assume the hdr is 32-bit aligned to start */
2757
2758 /* check that the length value is sane; we'll check again once we
2759 know the tag length, but we at least want to know that it is
2760 a positive value */
2761 if (*pkt_octet_len < octets_in_rtcp_header8 + sizeof(srtcp_trailer_t))
2762 return err_status_bad_param;
2763
2764 /*
2765 * look up ssrc in srtp_stream list, and process the packet with
2766 * the appropriate stream. if we haven't seen this stream before,
2767 * there's only one key for this srtp_session, and the cipher
2768 * supports key-sharing, then we assume that a new stream using
2769 * that key has just started up
2770 */
2771 stream = srtp_get_stream(ctx, hdr->ssrc);
2772 if (stream == NULL((void*)0)) {
2773 if (ctx->stream_template != NULL((void*)0)) {
2774 stream = ctx->stream_template;
2775
2776 /*
2777 * check to see if stream_template has an EKT data structure, in
2778 * which case we initialize the template using the EKT policy
2779 * referenced by that data (which consists of decrypting the
2780 * master key from the EKT field)
2781 *
2782 * this function initializes a *provisional* stream, and this
2783 * stream should not be accepted until and unless the packet
2784 * passes its authentication check
2785 */
2786 if (stream->ekt != NULL((void*)0)) {
2787 status = srtp_stream_init_from_ekt(stream, srtcp_hdr, *pkt_octet_len);
2788 if (status)
2789 return status;
2790 }
2791
2792 debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp using provisional stream (SSRC: 0x%08x)"
"\n"), mod_srtp.name, hdr->ssrc)
2793 hdr->ssrc)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp using provisional stream (SSRC: 0x%08x)"
"\n"), mod_srtp.name, hdr->ssrc)
;
2794 } else {
2795 /* no template stream, so we return an error */
2796 return err_status_no_ctx;
2797 }
2798 }
2799
2800 /* get tag length from stream context */
2801 tag_len = auth_get_tag_length(stream->rtcp_auth);
2802
2803 /* check the packet length - it must contain at least a full RTCP
2804 header, an auth tag (if applicable), and the SRTCP encrypted flag
2805 and 31-bit index value */
2806 if (*pkt_octet_len < (octets_in_rtcp_header8 + tag_len + sizeof(srtcp_trailer_t))) {
2807 return err_status_bad_param;
2808 }
2809
2810 /*
2811 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
2812 * the request to our AEAD handler.
2813 */
2814 if (stream->rtp_cipher->algorithm == AES_128_GCM6 ||
2815 stream->rtp_cipher->algorithm == AES_256_GCM7) {
2816 return srtp_unprotect_rtcp_aead(ctx, stream, srtcp_hdr, (unsigned int*)pkt_octet_len);
2817 }
2818
2819 sec_serv_confidentiality = stream->rtcp_services == sec_serv_conf ||
2820 stream->rtcp_services == sec_serv_conf_and_auth;
2821
2822 /*
2823 * set encryption start, encryption length, and trailer
2824 */
2825 enc_octet_len = *pkt_octet_len -
2826 (octets_in_rtcp_header8 + tag_len + sizeof(srtcp_trailer_t));
2827 /* index & E (encryption) bit follow normal data. hdr->len
2828 is the number of words (32-bit) in the normal packet minus 1 */
2829 /* This should point trailer to the word past the end of the
2830 normal data. */
2831 /* This would need to be modified for optional mikey data */
2832 /*
2833 * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2834 * multiples of 32-bits (RFC 3550 6.1)
2835 */
2836 trailer = (uint32_t *) ((char *) hdr +
2837 *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t)));
2838 e_bit_in_packet =
2839 (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT0x80) == SRTCP_E_BYTE_BIT0x80;
2840 if (e_bit_in_packet != sec_serv_confidentiality) {
2841 return err_status_cant_check;
2842 }
2843 if (sec_serv_confidentiality) {
2844 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header2;
2845 } else {
2846 enc_octet_len = 0;
2847 enc_start = NULL((void*)0); /* this indicates that there's no encryption */
2848 }
2849
2850 /*
2851 * set the auth_start and auth_tag pointers to the proper locations
2852 * (note that srtcp *always* uses authentication, unlike srtp)
2853 */
2854 auth_start = (uint32_t *)hdr;
2855 auth_len = *pkt_octet_len - tag_len;
2856 auth_tag = (uint8_t *)hdr + auth_len;
2857
2858 /*
2859 * if EKT is in use, then we make a copy of the tag from the packet,
2860 * and then zeroize the location of the base tag
2861 *
2862 * we first re-position the auth_tag pointer so that it points to
2863 * the base tag
2864 */
2865 if (stream->ekt) {
2866 auth_tag -= ekt_octets_after_base_tag(stream->ekt);
2867 memcpy(tag_copy, auth_tag, tag_len);
2868 octet_string_set_to_zero(auth_tag, tag_len);
2869 auth_tag = tag_copy;
2870 auth_len += tag_len;
2871 }
2872
2873 /*
2874 * check the sequence number for replays
2875 */
2876 /* this is easier than dealing with bitfield access */
2877 seq_num = ntohl(*trailer)(__extension__ ({ unsigned int __v, __x = (*trailer); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
& SRTCP_INDEX_MASK0x7fffffff;
2878 debug_print(mod_srtp, "srtcp index: %x", seq_num)if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp index: %x"
"\n"), mod_srtp.name, seq_num)
;
2879 status = rdb_check(&stream->rtcp_rdb, seq_num);
2880 if (status)
2881 return status;
2882
2883 /*
2884 * if we're using aes counter mode, set nonce and seq
2885 */
2886 if (stream->rtcp_cipher->type->id == AES_ICM1) {
2887 v128_t iv;
2888
2889 iv.v32[0] = 0;
2890 iv.v32[1] = hdr->ssrc; /* still in network order! */
2891 iv.v32[2] = htonl(seq_num >> 16)(__extension__ ({ unsigned int __v, __x = (seq_num >> 16
); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
2892 iv.v32[3] = htonl(seq_num << 16)(__extension__ ({ unsigned int __v, __x = (seq_num << 16
); if (__builtin_constant_p (__x)) __v = ((((__x) & 0xff000000
) >> 24) | (((__x) & 0x00ff0000) >> 8) | (((__x
) & 0x0000ff00) << 8) | (((__x) & 0x000000ff) <<
24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); __v
; }))
;
2893 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt)((stream->rtcp_cipher) ? (((stream->rtcp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtcp_cipher)->
state), (&iv), (direction_decrypt))) : err_status_no_such_op
)
;
2894
2895 } else {
2896 v128_t iv;
2897
2898 /* otherwise, just set the index to seq_num */
2899 iv.v32[0] = 0;
2900 iv.v32[1] = 0;
2901 iv.v32[2] = 0;
2902 iv.v32[3] = htonl(seq_num)(__extension__ ({ unsigned int __v, __x = (seq_num); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
2903 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt)((stream->rtcp_cipher) ? (((stream->rtcp_cipher)->type
)->set_iv(((cipher_pointer_t)(stream->rtcp_cipher)->
state), (&iv), (direction_decrypt))) : err_status_no_such_op
)
;
2904
2905 }
2906 if (status)
2907 return err_status_cipher_fail;
2908
2909 /* initialize auth func context */
2910 auth_start(stream->rtcp_auth)(((stream->rtcp_auth)->type)->start((stream->rtcp_auth
)->state))
;
2911
2912 /* run auth func over packet, put result into tmp_tag */
2913 status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start,(((stream->rtcp_auth)->type)->compute((stream->rtcp_auth
)->state, ((uint8_t *)auth_start), (auth_len), (stream->
rtcp_auth)->out_len, (tmp_tag)))
2914 auth_len, tmp_tag)(((stream->rtcp_auth)->type)->compute((stream->rtcp_auth
)->state, ((uint8_t *)auth_start), (auth_len), (stream->
rtcp_auth)->out_len, (tmp_tag)))
;
2915 debug_print(mod_srtp, "srtcp computed tag: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp computed tag: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_tag, tag_len
))
2916 octet_string_hex_string(tmp_tag, tag_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp computed tag: %s"
"\n"), mod_srtp.name, octet_string_hex_string(tmp_tag, tag_len
))
;
2917 if (status)
2918 return err_status_auth_fail;
2919
2920 /* compare the tag just computed with the one in the packet */
2921 debug_print(mod_srtp, "srtcp tag from packet: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp tag from packet: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, tag_len
))
2922 octet_string_hex_string(auth_tag, tag_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "srtcp tag from packet: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, tag_len
))
;
2923 if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
2924 return err_status_auth_fail;
2925
2926 /*
2927 * if we're authenticating using a universal hash, put the keystream
2928 * prefix into the authentication tag
2929 */
2930 prefix_len = auth_get_prefix_length(stream->rtcp_auth);
2931 if (prefix_len) {
2932 status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
2933 debug_print(mod_srtp, "keystream prefix: %s",if (mod_srtp.on) err_report(err_level_debug, ("%s: " "keystream prefix: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, prefix_len
))
2934 octet_string_hex_string(auth_tag, prefix_len))if (mod_srtp.on) err_report(err_level_debug, ("%s: " "keystream prefix: %s"
"\n"), mod_srtp.name, octet_string_hex_string(auth_tag, prefix_len
))
;
2935 if (status)
2936 return err_status_cipher_fail;
2937 }
2938
2939 /* if we're decrypting, exor keystream into the message */
2940 if (enc_start) {
2941 status = cipher_decrypt(stream->rtcp_cipher,(((stream->rtcp_cipher)->type)->decrypt(((stream->
rtcp_cipher)->state), ((uint8_t *)enc_start), (&enc_octet_len
)))
2942 (uint8_t *)enc_start, &enc_octet_len)(((stream->rtcp_cipher)->type)->decrypt(((stream->
rtcp_cipher)->state), ((uint8_t *)enc_start), (&enc_octet_len
)))
;
2943 if (status)
2944 return err_status_cipher_fail;
2945 }
2946
2947 /* decrease the packet length by the length of the auth tag and seq_num */
2948 *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
2949
2950 /*
2951 * if EKT is in effect, subtract the EKT data out of the packet
2952 * length
2953 */
2954 *pkt_octet_len -= ekt_octets_after_base_tag(stream->ekt);
2955
2956 /*
2957 * verify that stream is for received traffic - this check will
2958 * detect SSRC collisions, since a stream that appears in both
2959 * srtp_protect() and srtp_unprotect() will fail this test in one of
2960 * those functions.
2961 *
2962 * we do this check *after* the authentication check, so that the
2963 * latter check will catch any attempts to fool us into thinking
2964 * that we've got a collision
2965 */
2966 if (stream->direction != dir_srtp_receiver) {
2967 if (stream->direction == dir_unknown) {
2968 stream->direction = dir_srtp_receiver;
2969 } else {
2970 srtp_handle_event(ctx, stream, event_ssrc_collision)if(srtp_event_handler) { srtp_event_data_t data; data.session
= ctx; data.stream = stream; data.event = event_ssrc_collision
; srtp_event_handler(&data); }
;
2971 }
2972 }
2973
2974 /*
2975 * if the stream is a 'provisional' one, in which the template context
2976 * is used, then we need to allocate a new stream at this point, since
2977 * the authentication passed
2978 */
2979 if (stream == ctx->stream_template) {
2980 srtp_stream_ctx_t *new_stream;
2981
2982 /*
2983 * allocate and initialize a new stream
2984 *
2985 * note that we indicate failure if we can't allocate the new
2986 * stream, and some implementations will want to not return
2987 * failure here
2988 */
2989 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
2990 if (status)
2991 return status;
2992
2993 /* add new stream to the head of the stream_list */
2994 new_stream->next = ctx->stream_list;
2995 ctx->stream_list = new_stream;
2996
2997 /* set stream (the pointer used in this function) */
2998 stream = new_stream;
2999 }
3000
3001 /* we've passed the authentication check, so add seq_num to the rdb */
3002 rdb_add_index(&stream->rtcp_rdb, seq_num);
3003
3004
3005 return err_status_ok;
3006}
3007
3008
3009
3010/*
3011 * dtls keying for srtp
3012 */
3013
3014err_status_t
3015crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy,
3016 srtp_profile_t profile) {
3017
3018 /* set SRTP policy from the SRTP profile in the key set */
3019 switch(profile) {
3020 case srtp_profile_aes128_cm_sha1_80:
3021 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy)crypto_policy_set_rtp_default(policy);
3022 break;
3023 case srtp_profile_aes128_cm_sha1_32:
3024 crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);
3025 break;
3026 case srtp_profile_null_sha1_80:
3027 crypto_policy_set_null_cipher_hmac_sha1_80(policy);
3028 break;
3029 case srtp_profile_aes256_cm_sha1_80:
3030 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
3031 break;
3032 case srtp_profile_aes256_cm_sha1_32:
3033 crypto_policy_set_aes_cm_256_hmac_sha1_32(policy);
3034 break;
3035 /* the following profiles are not (yet) supported */
3036 case srtp_profile_null_sha1_32:
3037 default:
3038 return err_status_bad_param;
3039 }
3040
3041 return err_status_ok;
3042}
3043
3044err_status_t
3045crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy,
3046 srtp_profile_t profile) {
3047
3048 /* set SRTP policy from the SRTP profile in the key set */
3049 switch(profile) {
3050 case srtp_profile_aes128_cm_sha1_80:
3051 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy)crypto_policy_set_rtp_default(policy);
3052 break;
3053 case srtp_profile_aes128_cm_sha1_32:
3054 /* We do not honor the 32-bit auth tag request since
3055 * this is not compliant with RFC 3711 */
3056 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy)crypto_policy_set_rtp_default(policy);
3057 break;
3058 case srtp_profile_null_sha1_80:
3059 crypto_policy_set_null_cipher_hmac_sha1_80(policy);
3060 break;
3061 case srtp_profile_aes256_cm_sha1_80:
3062 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
3063 break;
3064 case srtp_profile_aes256_cm_sha1_32:
3065 /* We do not honor the 32-bit auth tag request since
3066 * this is not compliant with RFC 3711 */
3067 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
3068 break;
3069 /* the following profiles are not (yet) supported */
3070 case srtp_profile_null_sha1_32:
3071 default:
3072 return err_status_bad_param;
3073 }
3074
3075 return err_status_ok;
3076}
3077
3078void
3079append_salt_to_key(uint8_t *key, unsigned int bytes_in_key,
3080 uint8_t *salt, unsigned int bytes_in_salt) {
3081
3082 memcpy(key + bytes_in_key, salt, bytes_in_salt);
3083
3084}
3085
3086unsigned int
3087srtp_profile_get_master_key_length(srtp_profile_t profile) {
3088
3089 switch(profile) {
3090 case srtp_profile_aes128_cm_sha1_80:
3091 return 16;
3092 break;
3093 case srtp_profile_aes128_cm_sha1_32:
3094 return 16;
3095 break;
3096 case srtp_profile_null_sha1_80:
3097 return 16;
3098 break;
3099 case srtp_profile_aes256_cm_sha1_80:
3100 return 32;
3101 break;
3102 case srtp_profile_aes256_cm_sha1_32:
3103 return 32;
3104 break;
3105 /* the following profiles are not (yet) supported */
3106 case srtp_profile_null_sha1_32:
3107 default:
3108 return 0; /* indicate error by returning a zero */
3109 }
3110}
3111
3112unsigned int
3113srtp_profile_get_master_salt_length(srtp_profile_t profile) {
3114
3115 switch(profile) {
3116 case srtp_profile_aes128_cm_sha1_80:
3117 return 14;
3118 break;
3119 case srtp_profile_aes128_cm_sha1_32:
3120 return 14;
3121 break;
3122 case srtp_profile_null_sha1_80:
3123 return 14;
3124 break;
3125 case srtp_profile_aes256_cm_sha1_80:
3126 return 14;
3127 break;
3128 case srtp_profile_aes256_cm_sha1_32:
3129 return 14;
3130 break;
3131 /* the following profiles are not (yet) supported */
3132 case srtp_profile_null_sha1_32:
3133 default:
3134 return 0; /* indicate error by returning a zero */
3135 }
3136}