blob: 45432f44d4e65b3dab5be9540b3c429c85ae8170 [file] [log] [blame]
Cullen Jennings235513a2005-09-21 22:51:36 +00001/*
2 * srtp.c
3 *
4 * the secure real-time transport protocol
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9/*
10 *
David McGrew7629bf22006-06-08 17:00:25 +000011 * Copyright (c) 2001-2006, Cisco Systems, Inc.
Cullen Jennings235513a2005-09-21 22:51:36 +000012 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials provided
24 * with the distribution.
25 *
26 * Neither the name of the Cisco Systems, Inc. nor the names of its
27 * contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
41 * OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
43 */
44
45
Teerapap Changwichukarn6cffe242014-09-24 11:24:07 +080046#include "srtp_priv.h"
David McGrew79870d62007-06-15 18:17:39 +000047#include "ekt.h" /* for SRTP Encrypted Key Transport */
Cullen Jennings235513a2005-09-21 22:51:36 +000048#include "alloc.h" /* for crypto_alloc() */
jfigus8719f952014-04-08 09:15:49 -040049#ifdef OPENSSL
50#include "aes_gcm_ossl.h" /* for AES GCM mode */
51#endif
Cullen Jennings235513a2005-09-21 22:51:36 +000052
Marcus Sundberg735eb4f2005-10-03 15:31:07 +000053#ifndef SRTP_KERNEL
54# include <limits.h>
55# ifdef HAVE_NETINET_IN_H
56# include <netinet/in.h>
57# elif defined(HAVE_WINSOCK2_H)
58# include <winsock2.h>
59# endif
60#endif /* ! SRTP_KERNEL */
Marcus Sundberge4e34f92005-10-02 20:19:35 +000061
62
Cullen Jennings235513a2005-09-21 22:51:36 +000063/* 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_header 12
71#define uint32s_in_rtp_header 3
72#define octets_in_rtcp_header 8
73#define uint32s_in_rtcp_header 2
74
Cullen Jennings235513a2005-09-21 22:51:36 +000075
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)
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,
jfigusc13c1002014-05-08 13:34:53 -040099 p->rtp.cipher_key_len,
100 p->rtp.auth_tag_len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000101 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);
113 crypto_free(str);
114 return stat;
115 }
116
117 /* allocate key limit structure */
Derek MacDonald17127da2006-07-12 22:22:08 +0000118 str->limit = (key_limit_ctx_t*) crypto_alloc(sizeof(key_limit_ctx_t));
Cullen Jennings235513a2005-09-21 22:51:36 +0000119 if (str->limit == NULL) {
120 auth_dealloc(str->rtp_auth);
121 cipher_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,
jfigusc13c1002014-05-08 13:34:53 -0400132 p->rtcp.cipher_key_len,
133 p->rtcp.auth_tag_len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000134 if (stat) {
135 auth_dealloc(str->rtp_auth);
136 cipher_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);
149 auth_dealloc(str->rtp_auth);
150 cipher_dealloc(str->rtp_cipher);
151 crypto_free(str->limit);
152 crypto_free(str);
153 return stat;
154 }
155
David McGrew79870d62007-06-15 18:17:39 +0000156 /* allocate ekt data associated with stream */
157 stat = ekt_alloc(&str->ekt, p->ekt);
158 if (stat) {
159 auth_dealloc(str->rtcp_auth);
160 cipher_dealloc(str->rtcp_cipher);
161 auth_dealloc(str->rtp_auth);
162 cipher_dealloc(str->rtp_cipher);
163 crypto_free(str->limit);
164 crypto_free(str);
165 return stat;
166 }
167
Cullen Jennings235513a2005-09-21 22:51:36 +0000168 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 */
David McGrewfec49dd2005-09-23 19:34:11 +0000182 if (session->stream_template
Cullen Jennings235513a2005-09-21 22:51:36 +0000183 && stream->rtp_cipher == session->stream_template->rtp_cipher) {
184 /* do nothing */
185 } else {
186 status = cipher_dealloc(stream->rtp_cipher);
187 if (status)
David McGrewfec49dd2005-09-23 19:34:11 +0000188 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000189 }
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);
197 if (status)
198 return status;
199 }
200
David McGrewfec49dd2005-09-23 19:34:11 +0000201 /* 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 {
Cullen Jennings235513a2005-09-21 22:51:36 +0000206 crypto_free(stream->limit);
David McGrewfec49dd2005-09-23 19:34:11 +0000207 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000208
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);
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);
231 if (status)
232 return status;
233 }
David McGrew79870d62007-06-15 18:17:39 +0000234
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000235 status = rdbx_dealloc(&stream->rtp_rdbx);
236 if (status)
237 return status;
238
David McGrew79870d62007-06-15 18:17:39 +0000239 /* DAM - need to deallocate EKT here */
jfigus8c36da22013-10-01 16:41:19 -0400240
241 /*
242 * zeroize the salt value
243 */
244 memset(stream->salt, 0, SRTP_AEAD_SALT_LEN);
245 memset(stream->c_salt, 0, SRTP_AEAD_SALT_LEN);
246
Cullen Jennings235513a2005-09-21 22:51:36 +0000247
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);
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)
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);
jfigus8c36da22013-10-01 16:41:19 -0400286 if (status) {
287 crypto_free(*str_ptr);
288 *str_ptr = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +0000289 return status;
jfigus8c36da22013-10-01 16:41:19 -0400290 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000291
292 /* initialize replay databases */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000293 status = rdbx_init(&str->rtp_rdbx,
294 rdbx_get_window_size(&stream_template->rtp_rdbx));
jfigus8c36da22013-10-01 16:41:19 -0400295 if (status) {
296 crypto_free(*str_ptr);
297 *str_ptr = NULL;
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000298 return status;
jfigus8c36da22013-10-01 16:41:19 -0400299 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000300 rdb_init(&str->rtcp_rdb);
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +0000301 str->allow_repeat_tx = stream_template->allow_repeat_tx;
Cullen Jennings235513a2005-09-21 22:51:36 +0000302
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
David McGrew79870d62007-06-15 18:17:39 +0000311 /* set pointer to EKT data associated with stream */
312 str->ekt = stream_template->ekt;
313
jfigus8c36da22013-10-01 16:41:19 -0400314 /* Copy the salt values */
315 memcpy(str->salt, stream_template->salt, SRTP_AEAD_SALT_LEN);
316 memcpy(str->c_salt, stream_template->c_salt, SRTP_AEAD_SALT_LEN);
317
Cullen Jennings235513a2005-09-21 22:51:36 +0000318 /* defensive coding */
319 str->next = NULL;
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 *
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000330 * 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.
Cullen Jennings235513a2005-09-21 22:51:36 +0000332 *
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 *
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000338 * srtp_kdf_clear(&kdf) zeroizes and deallocates the kdf state
Cullen Jennings235513a2005-09-21 22:51:36 +0000339 */
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 {
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000357 cipher_t *cipher; /* cipher used for key derivation */
Cullen Jennings235513a2005-09-21 22:51:36 +0000358} srtp_kdf_t;
359
360err_status_t
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000361srtp_kdf_init(srtp_kdf_t *kdf, cipher_type_id_t cipher_id, const uint8_t *key, int length) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000362
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000363 err_status_t stat;
jfigusc13c1002014-05-08 13:34:53 -0400364 stat = crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, length, 0);
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000365 if (stat)
366 return stat;
367
jfigus7882dd92013-08-02 16:08:23 -0400368 stat = cipher_init(kdf->cipher, key);
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000369 if (stat) {
370 cipher_dealloc(kdf->cipher);
371 return stat;
372 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000373
374 return err_status_ok;
375}
376
377err_status_t
378srtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label,
Travis Cross1b8b1e72014-07-02 15:32:36 +0000379 uint8_t *key, unsigned int length) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000380
381 v128_t nonce;
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000382 err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000383
384 /* set eigth octet of nonce to <label>, set the rest of it to zero */
385 v128_set_to_zero(&nonce);
Marcus Sundberg7627bc52005-10-08 16:38:06 +0000386 nonce.v8[7] = label;
Cullen Jennings235513a2005-09-21 22:51:36 +0000387
jfigus7882dd92013-08-02 16:08:23 -0400388 status = cipher_set_iv(kdf->cipher, &nonce, direction_encrypt);
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000389 if (status)
390 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000391
392 /* generate keystream output */
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000393 octet_string_set_to_zero(key, length);
394 status = cipher_encrypt(kdf->cipher, key, &length);
395 if (status)
396 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000397
398 return err_status_ok;
399}
400
401err_status_t
402srtp_kdf_clear(srtp_kdf_t *kdf) {
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000403 err_status_t status;
404 status = cipher_dealloc(kdf->cipher);
405 if (status)
406 return status;
407 kdf->cipher = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +0000408
409 return err_status_ok;
410}
411
412/*
413 * end of key derivation functions
414 */
415
416#define MAX_SRTP_KEY_LEN 256
417
418
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000419/* 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. */
Jonathan Lennoxe2774db2011-10-27 16:06:12 +0000424static inline int base_key_length(const cipher_type_t *cipher, int key_length)
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000425{
jfigus8c36da22013-10-01 16:41:19 -0400426 switch (cipher->id) {
427 case AES_128_ICM:
428 case AES_192_ICM:
429 case AES_256_ICM:
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_GCM:
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000435 return 16;
jfigus8c36da22013-10-01 16:41:19 -0400436 break;
437 case AES_256_GCM:
438 return 32;
439 break;
440 default:
441 return key_length;
442 break;
443 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000444}
445
David McGrew576e1482006-06-09 21:47:44 +0000446err_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_LEN];
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000451 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);
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000459 rtcp_keylen = cipher_get_key_length(srtp->rtcp_cipher);
jfigus8719f952014-04-08 09:15:49 -0400460 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
jfigus8c36da22013-10-01 16:41:19 -0400471 debug_print(mod_srtp, "srtp key len: %d", rtp_keylen);
472 debug_print(mod_srtp, "srtcp key len: %d", rtcp_keylen);
jfigus8719f952014-04-08 09:15:49 -0400473 debug_print(mod_srtp, "base key len: %d", rtp_base_key_len);
474 debug_print(mod_srtp, "kdf key len: %d", kdf_keylen);
475 debug_print(mod_srtp, "rtp salt len: %d", 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_LEN);
483 memcpy(tmp_key, key, (rtp_base_key_len + rtp_salt_len));
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000484
David McGrew576e1482006-06-09 21:47:44 +0000485 /* initialize KDF state */
jfigus8719f952014-04-08 09:15:49 -0400486 stat = srtp_kdf_init(&kdf, AES_ICM, (const uint8_t *)tmp_key, kdf_keylen);
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000487 if (stat) {
488 return err_status_init_fail;
489 }
David McGrew576e1482006-06-09 21:47:44 +0000490
491 /* generate encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000492 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_LEN);
497 return err_status_init_fail;
498 }
jfigus8719f952014-04-08 09:15:49 -0400499 debug_print(mod_srtp, "cipher key: %s",
500 octet_string_hex_string(tmp_key, rtp_base_key_len));
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000501
David McGrew576e1482006-06-09 21:47:44 +0000502 /*
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000503 * if the cipher in the srtp context uses a salt, then we need
David McGrew576e1482006-06-09 21:47:44 +0000504 * to generate the salt value
505 */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000506 if (rtp_salt_len > 0) {
507 debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL);
David McGrew576e1482006-06-09 21:47:44 +0000508
509 /* generate encryption salt, put after encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000510 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_LEN);
515 return err_status_init_fail;
516 }
jfigus8c36da22013-10-01 16:41:19 -0400517 memcpy(srtp->salt, tmp_key + rtp_base_key_len, SRTP_AEAD_SALT_LEN);
David McGrew576e1482006-06-09 21:47:44 +0000518 }
Jonathan Lennoxc0f1f1b2012-04-26 23:16:00 +0000519 if (rtp_salt_len > 0) {
520 debug_print(mod_srtp, "cipher salt: %s",
521 octet_string_hex_string(tmp_key + rtp_base_key_len, rtp_salt_len));
522 }
David McGrew576e1482006-06-09 21:47:44 +0000523
524 /* initialize cipher */
jfigus7882dd92013-08-02 16:08:23 -0400525 stat = cipher_init(srtp->rtp_cipher, tmp_key);
David McGrew576e1482006-06-09 21:47:44 +0000526 if (stat) {
527 /* zeroize temp buffer */
528 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
529 return err_status_init_fail;
530 }
531
532 /* generate authentication key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000533 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_LEN);
538 return err_status_init_fail;
539 }
David McGrew576e1482006-06-09 21:47:44 +0000540 debug_print(mod_srtp, "auth key: %s",
541 octet_string_hex_string(tmp_key,
542 auth_get_key_length(srtp->rtp_auth)));
543
544 /* initialize auth function */
545 stat = auth_init(srtp->rtp_auth, tmp_key);
546 if (stat) {
547 /* zeroize temp buffer */
548 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
549 return err_status_init_fail;
550 }
551
552 /*
553 * ...now initialize SRTCP keys
554 */
555
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000556 rtcp_base_key_len = base_key_length(srtp->rtcp_cipher->type, rtcp_keylen);
557 rtcp_salt_len = rtcp_keylen - rtcp_base_key_len;
jfigus8c36da22013-10-01 16:41:19 -0400558 debug_print(mod_srtp, "rtcp salt len: %d", rtcp_salt_len);
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000559
David McGrew576e1482006-06-09 21:47:44 +0000560 /* generate encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000561 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_LEN);
566 return err_status_init_fail;
567 }
568
David McGrew576e1482006-06-09 21:47:44 +0000569 /*
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000570 * if the cipher in the srtp context uses a salt, then we need
David McGrew576e1482006-06-09 21:47:44 +0000571 * to generate the salt value
572 */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000573 if (rtcp_salt_len > 0) {
574 debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt",
575 NULL);
David McGrew576e1482006-06-09 21:47:44 +0000576
577 /* generate encryption salt, put after encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000578 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_LEN);
583 return err_status_init_fail;
584 }
jfigus8c36da22013-10-01 16:41:19 -0400585 memcpy(srtp->c_salt, tmp_key + rtcp_base_key_len, SRTP_AEAD_SALT_LEN);
David McGrew576e1482006-06-09 21:47:44 +0000586 }
587 debug_print(mod_srtp, "rtcp cipher key: %s",
Jonathan Lennoxc0f1f1b2012-04-26 23:16:00 +0000588 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",
591 octet_string_hex_string(tmp_key + rtcp_base_key_len, rtcp_salt_len));
592 }
David McGrew576e1482006-06-09 21:47:44 +0000593
594 /* initialize cipher */
jfigus7882dd92013-08-02 16:08:23 -0400595 stat = cipher_init(srtp->rtcp_cipher, tmp_key);
David McGrew576e1482006-06-09 21:47:44 +0000596 if (stat) {
597 /* zeroize temp buffer */
598 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
599 return err_status_init_fail;
600 }
601
602 /* generate authentication key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000603 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_LEN);
608 return err_status_init_fail;
609 }
610
David McGrew576e1482006-06-09 21:47:44 +0000611 debug_print(mod_srtp, "rtcp auth key: %s",
612 octet_string_hex_string(tmp_key,
613 auth_get_key_length(srtp->rtcp_auth)));
614
615 /* initialize auth function */
616 stat = auth_init(srtp->rtcp_auth, tmp_key);
617 if (stat) {
618 /* zeroize temp buffer */
619 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
620 return err_status_init_fail;
621 }
622
623 /* clear memory then return */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000624 stat = srtp_kdf_clear(&kdf);
David McGrew576e1482006-06-09 21:47:44 +0000625 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000626 if (stat)
627 return err_status_init_fail;
David McGrew576e1482006-06-09 21:47:44 +0000628
629 return err_status_ok;
630}
Cullen Jennings235513a2005-09-21 22:51:36 +0000631
632err_status_t
633srtp_stream_init(srtp_stream_ctx_t *srtp,
634 const srtp_policy_t *p) {
David McGrew576e1482006-06-09 21:47:44 +0000635 err_status_t err;
Cullen Jennings235513a2005-09-21 22:51:36 +0000636
637 debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)",
638 p->ssrc.value);
639
640 /* initialize replay database */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000641 /* 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;
Cullen Jennings235513a2005-09-21 22:51:36 +0000653
654 /* initialize key limit to maximum value */
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000655#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +0000656{
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000657 uint64_t temp;
658 temp = make64(UINT_MAX,UINT_MAX);
659 key_limit_set(srtp->limit, temp);
Cullen Jennings235513a2005-09-21 22:51:36 +0000660}
661#else
662 key_limit_set(srtp->limit, 0xffffffffffffLL);
663#endif
664
665 /* set the SSRC value */
666 srtp->ssrc = htonl(p->ssrc.value);
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
David McGrew576e1482006-06-09 21:47:44 +0000679 /* initialize SRTCP replay database */
Cullen Jennings235513a2005-09-21 22:51:36 +0000680 rdb_init(&srtp->rtcp_rdb);
681
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +0000682 /* 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
Cullen Jennings235513a2005-09-21 22:51:36 +0000690 /* DAM - no RTCP key limit at present */
691
David McGrew576e1482006-06-09 21:47:44 +0000692 /* initialize keys */
693 err = srtp_stream_init_keys(srtp, p->key);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000694 if (err) {
695 rdbx_dealloc(&srtp->rtp_rdbx);
696 return err;
697 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000698
David McGrew79870d62007-06-15 18:17:39 +0000699 /*
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);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000704 if (err) {
705 rdbx_dealloc(&srtp->rtp_rdbx);
706 return err;
707 }
David McGrew79870d62007-06-15 18:17:39 +0000708
Cullen Jennings235513a2005-09-21 22:51:36 +0000709 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
jfigus8c36da22013-10-01 16:41:19 -0400768/*
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;
Dmitry Sobinov367d5d32014-03-27 22:36:32 +0700801
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
jfigus8c36da22013-10-01 16:41:19 -0400810
811 memset(&in, 0, sizeof(v128_t));
812 memset(&salt, 0, sizeof(v128_t));
813
Dmitry Sobinov367d5d32014-03-27 22:36:32 +0700814 in.v16[5] = htons(local_seq);
815 local_roc = htonl(local_roc);
816 memcpy(&in.v16[3], &local_roc, sizeof(local_roc));
jfigus8c36da22013-10-01 16:41:19 -0400817
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));
823
824 /*
825 * Get the SALT value from the context
826 */
827 memcpy(salt.v8, stream->salt, SRTP_AEAD_SALT_LEN);
828 debug_print(mod_srtp, "RTP SALT = %s\n", v128_hex_string(&salt));
829
830 /*
831 * Finally, apply tyhe SALT to the input
832 */
833 v128_xor(iv, &in, &salt);
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,
Travis Cross31844002014-07-02 16:18:57 +0000844 void *rtp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -0400845{
846 srtp_hdr_t *hdr = (srtp_hdr_t*)rtp_hdr;
847 uint32_t *enc_start; /* pointer to start of encrypted portion */
Travis Cross1b8b1e72014-07-02 15:32:36 +0000848 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -0400849 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);
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);
868 return err_status_key_expired;
869 case key_event_soft_limit:
870 default:
871 srtp_handle_event(ctx, stream, event_key_soft_limit);
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
jfigus8c36da22013-10-01 16:41:19 -0400883 */
Travis Cross3600c272014-06-29 17:32:33 +0000884 enc_start = (uint32_t*)hdr + uint32s_in_rtp_header + 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) + 1);
888 }
Travis Cross83439f72014-07-02 14:18:46 +0000889 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
Travis Cross3600c272014-06-29 17:32:33 +0000890 return err_status_parse_err;
891 enc_octet_len = (unsigned int)(*pkt_octet_len -
Travis Crossdee3ee82014-07-02 15:20:12 +0000892 ((uint8_t*)enc_start - (uint8_t*)hdr));
jfigus8c36da22013-10-01 16:41:19 -0400893
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));
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",
910 high32(est), low32(est));
911#else
912 debug_print(mod_srtp, "estimated packet index: %016llx", 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);
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) |
927 (low32(est) >> 16),
928 low32(est) << 16));
929#else
930 est = be64_to_cpu(est << 16);
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);
938 if (status) {
939 return ( err_status_cipher_fail);
940 }
941
942 /* Encrypt the payload */
943 status = cipher_encrypt(stream->rtp_cipher,
944 (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,
953 (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,
Travis Cross31844002014-07-02 16:18:57 +0000975 xtd_seq_num_t est, void *srtp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -0400976{
977 srtp_hdr_t *hdr = (srtp_hdr_t*)srtp_hdr;
978 uint32_t *enc_start; /* pointer to start of encrypted portion */
Travis Cross1b8b1e72014-07-02 15:32:36 +0000979 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -0400980 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);
986
987#ifdef NO_64BIT_MATH
988 debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est), low32(est));
989#else
990 debug_print(mod_srtp, "estimated u_packet index: %016llx", 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);
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_header + 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) + 1);
1015 }
Travis Cross83439f72014-07-02 14:18:46 +00001016 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
Travis Crossfe367612014-06-29 01:10:29 +00001017 return err_status_parse_err;
jfigus8c36da22013-10-01 16:41:19 -04001018 /*
1019 * We pass the tag down to the cipher when doing GCM mode
1020 */
Travis Cross7d4c1032014-07-02 14:46:53 +00001021 enc_octet_len = (unsigned int)(*pkt_octet_len -
Travis Crossdee3ee82014-07-02 15:20:12 +00001022 ((uint8_t*)enc_start - (uint8_t*)hdr));
jfigus8c36da22013-10-01 16:41:19 -04001023
1024 /*
jfigusc13c1002014-05-08 13:34:53 -04001025 * 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 /*
jfigus8c36da22013-10-01 16:41:19 -04001034 * 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);
1043 break;
1044 case key_event_hard_limit:
1045 srtp_handle_event(ctx, stream, event_key_hard_limit);
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);
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,
1063 (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);
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
Cullen Jennings235513a2005-09-21 22:51:36 +00001129 err_status_t
1130 srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00001131 srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00001132 uint32_t *enc_start; /* pointer to start of encrypted portion */
1133 uint32_t *auth_start; /* pointer to start of auth. portion */
Travis Cross1b8b1e72014-07-02 15:32:36 +00001134 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
Cullen Jennings235513a2005-09-21 22:51:36 +00001135 xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
1136 int delta; /* delta of local pkt idx and that in hdr */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001137 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
Cullen Jennings235513a2005-09-21 22:51:36 +00001138 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);
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_header)
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) {
1160 if (ctx->stream_template != NULL) {
1161 srtp_stream_ctx_t *new_stream;
1162
1163 /* allocate and initialize a new stream */
1164 status = srtp_stream_clone(ctx->stream_template,
David McGrewfec49dd2005-09-23 19:34:11 +00001165 hdr->ssrc, &new_stream);
Cullen Jennings235513a2005-09-21 22:51:36 +00001166 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 */
jfigus8c36da22013-10-01 16:41:19 -04001190 if (stream->direction != dir_srtp_sender) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001191 if (stream->direction == dir_unknown) {
1192 stream->direction = dir_srtp_sender;
1193 } else {
1194 srtp_handle_event(ctx, stream, event_ssrc_collision);
1195 }
jfigus8c36da22013-10-01 16:41:19 -04001196 }
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_GCM ||
1203 stream->rtp_cipher->algorithm == AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00001204 return srtp_protect_aead(ctx, stream, rtp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04001205 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001206
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);
1217 break;
1218 case key_event_hard_limit:
1219 srtp_handle_event(ctx, stream, event_key_hard_limit);
David McGrewfec49dd2005-09-23 19:34:11 +00001220 return err_status_key_expired;
Cullen Jennings235513a2005-09-21 22:51:36 +00001221 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_header + hdr->cc;
David McGrew14829302005-10-10 18:53:19 +00001238 if (hdr->x == 1) {
1239 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
1240 enc_start += (ntohs(xtn_hdr->length) + 1);
Travis Cross83439f72014-07-02 14:18:46 +00001241 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
Travis Crossfe367612014-06-29 01:10:29 +00001242 return err_status_parse_err;
David McGrew14829302005-10-10 18:53:19 +00001243 }
Travis Crossdee3ee82014-07-02 15:20:12 +00001244 enc_octet_len = (unsigned int)(*pkt_octet_len -
1245 ((uint8_t*)enc_start - (uint8_t*)hdr));
Cullen Jennings235513a2005-09-21 22:51:36 +00001246 } else {
1247 enc_start = NULL;
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;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001257 auth_tag = (uint8_t *)hdr + *pkt_octet_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00001258 } else {
1259 auth_start = NULL;
1260 auth_tag = NULL;
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));
1268 status = rdbx_check(&stream->rtp_rdbx, delta);
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001269 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);
Cullen Jennings235513a2005-09-21 22:51:36 +00001275
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001276#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001277 debug_print2(mod_srtp, "estimated packet index: %08x%08x",
1278 high32(est),low32(est));
1279#else
1280 debug_print(mod_srtp, "estimated packet index: %016llx", est);
1281#endif
1282
1283 /*
1284 * if we're using rindael counter mode, set nonce and seq
1285 */
jfigus8c36da22013-10-01 16:41:19 -04001286 if (stream->rtp_cipher->type->id == AES_ICM ||
1287 stream->rtp_cipher->type->id == AES_256_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001288 v128_t iv;
1289
1290 iv.v32[0] = 0;
1291 iv.v32[1] = hdr->ssrc;
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001292#ifdef NO_64BIT_MATH
1293 iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
David McGrewfec49dd2005-09-23 19:34:11 +00001294 low32(est) << 16));
Cullen Jennings235513a2005-09-21 22:51:36 +00001295#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001296 iv.v64[1] = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001297#endif
jfigus7882dd92013-08-02 16:08:23 -04001298 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001299
1300 } else {
1301 v128_t iv;
1302
1303 /* otherwise, set the index to est */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001304#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001305 iv.v32[0] = 0;
1306 iv.v32[1] = 0;
1307#else
1308 iv.v64[0] = 0;
1309#endif
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001310 iv.v64[1] = be64_to_cpu(est);
jfigus7882dd92013-08-02 16:08:23 -04001311 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001312 }
1313 if (status)
1314 return err_status_cipher_fail;
1315
1316 /* shift est, put into network byte order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001317#ifdef NO_64BIT_MATH
1318 est = be64_to_cpu(make64((high32(est) << 16) |
Cullen Jennings235513a2005-09-21 22:51:36 +00001319 (low32(est) >> 16),
Randell Jesup811e1442005-09-28 22:43:41 +00001320 low32(est) << 16));
Cullen Jennings235513a2005-09-21 22:51:36 +00001321#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001322 est = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001323#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",
1337 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,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001344 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001345 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);
1357 if (status) return status;
1358
1359 /* run auth func over packet */
1360 status = auth_update(stream->rtp_auth,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001361 (uint8_t *)auth_start, *pkt_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001362 if (status) return status;
1363
1364 /* run auth func over ROC, put result into auth_tag */
David McGrew89fb7ea2005-09-26 19:33:44 +00001365 debug_print(mod_srtp, "estimated packet index: %016llx", est);
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001366 status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00001367 debug_print(mod_srtp, "srtp auth tag: %s",
1368 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) {
Derek MacDonald17127da2006-07-12 22:22:08 +00001386 srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00001387 uint32_t *enc_start; /* pointer to start of encrypted portion */
1388 uint32_t *auth_start; /* pointer to start of auth. portion */
Travis Cross1b8b1e72014-07-02 15:32:36 +00001389 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001390 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
Cullen Jennings235513a2005-09-21 22:51:36 +00001391 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;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001396 uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
Cullen Jennings235513a2005-09-21 22:51:36 +00001397 int tag_len, prefix_len;
1398
1399 debug_print(mod_srtp, "function srtp_unprotect", NULL);
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_header)
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) {
1416 if (ctx->stream_template != NULL) {
1417 stream = ctx->stream_template;
1418 debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)",
1419 hdr->ssrc);
1420
1421 /*
1422 * set estimated packet index to sequence number from header,
1423 * and set delta equal to the same value
1424 */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001425#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001426 est = (xtd_seq_num_t) make64(0,ntohs(hdr->seq));
1427 delta = low32(est);
1428#else
1429 est = (xtd_seq_num_t) ntohs(hdr->seq);
David McGrewc4fc00b2006-06-08 18:51:27 +00001430 delta = (int)est;
Cullen Jennings235513a2005-09-21 22:51:36 +00001431#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));
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001444
1445 /* check replay database */
1446 status = rdbx_check(&stream->rtp_rdbx, delta);
1447 if (status)
1448 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001449 }
1450
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001451#ifdef NO_64BIT_MATH
David McGrewfec49dd2005-09-23 19:34:11 +00001452 debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),low32(est));
1453#else
1454 debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
1455#endif
Cullen Jennings235513a2005-09-21 22:51:36 +00001456
jfigus8c36da22013-10-01 16:41:19 -04001457 /*
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_GCM ||
1462 stream->rtp_cipher->algorithm == AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00001463 return srtp_unprotect_aead(ctx, stream, delta, est, srtp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04001464 }
1465
Cullen Jennings235513a2005-09-21 22:51:36 +00001466 /* 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 */
jfigus8c36da22013-10-01 16:41:19 -04001473 if (stream->rtp_cipher->type->id == AES_ICM ||
1474 stream->rtp_cipher->type->id == AES_256_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001475
1476 /* aes counter mode */
1477 iv.v32[0] = 0;
1478 iv.v32[1] = hdr->ssrc; /* still in network order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001479#ifdef NO_64BIT_MATH
1480 iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
Cullen Jennings235513a2005-09-21 22:51:36 +00001481 low32(est) << 16));
1482#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001483 iv.v64[1] = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001484#endif
jfigus7882dd92013-08-02 16:08:23 -04001485 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001486 } else {
1487
1488 /* no particular format - set the iv to the pakcet index */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001489#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001490 iv.v32[0] = 0;
1491 iv.v32[1] = 0;
1492#else
1493 iv.v64[0] = 0;
1494#endif
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001495 iv.v64[1] = be64_to_cpu(est);
jfigus7882dd92013-08-02 16:08:23 -04001496 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001497 }
1498 if (status)
1499 return err_status_cipher_fail;
1500
1501 /* shift est, put into network byte order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001502#ifdef NO_64BIT_MATH
1503 est = be64_to_cpu(make64((high32(est) << 16) |
Cullen Jennings235513a2005-09-21 22:51:36 +00001504 (low32(est) >> 16),
1505 low32(est) << 16));
1506#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001507 est = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001508#endif
1509
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001510 /*
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_header + hdr->cc;
David McGrew14829302005-10-10 18:53:19 +00001520 if (hdr->x == 1) {
1521 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
1522 enc_start += (ntohs(xtn_hdr->length) + 1);
1523 }
Travis Cross83439f72014-07-02 14:18:46 +00001524 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
Travis Crossfe367612014-06-29 01:10:29 +00001525 return err_status_parse_err;
Travis Crossdee3ee82014-07-02 15:20:12 +00001526 enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len -
1527 ((uint8_t*)enc_start - (uint8_t*)hdr));
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001528 } else {
1529 enc_start = NULL;
1530 }
1531
Cullen Jennings235513a2005-09-21 22:51:36 +00001532 /*
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;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001539 auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00001540 } else {
1541 auth_start = NULL;
1542 auth_tag = NULL;
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",
1563 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);
1570 if (status) return status;
David McGrewfec49dd2005-09-23 19:34:11 +00001571
Cullen Jennings235513a2005-09-21 22:51:36 +00001572 /* now compute auth function over packet */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001573 status = auth_update(stream->rtp_auth, (uint8_t *)auth_start,
Cullen Jennings235513a2005-09-21 22:51:36 +00001574 *pkt_octet_len - tag_len);
1575
1576 /* run auth func over ROC, then write tmp tag */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001577 status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00001578
1579 debug_print(mod_srtp, "computed auth tag: %s",
1580 octet_string_hex_string(tmp_tag, tag_len));
1581 debug_print(mod_srtp, "packet auth tag: %s",
1582 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
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001590 /*
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);
1600 break;
1601 case key_event_hard_limit:
1602 srtp_handle_event(ctx, stream, event_key_hard_limit);
1603 return err_status_key_expired;
1604 default:
1605 break;
1606 }
1607
Jonathan Lennox23dc1e22010-06-01 18:19:04 +00001608 /* if we're decrypting, add keystream into ciphertext */
Cullen Jennings235513a2005-09-21 22:51:36 +00001609 if (enc_start) {
Jonathan Lennox23dc1e22010-06-01 18:19:04 +00001610 status = cipher_decrypt(stream->rtp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001611 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001612 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);
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
Jonathan Lennox5ae76332010-05-15 04:48:59 +00001690err_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
Cullen Jennings235513a2005-09-21 22:51:36 +00001705/*
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) {
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;
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) {
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) {
David McGrewfec49dd2005-09-23 19:34:11 +00001770 status = auth_dealloc(session->stream_template->rtcp_auth);
1771 if (status)
1772 return status;
1773 status = cipher_dealloc(session->stream_template->rtcp_cipher);
1774 if (status)
1775 return status;
1776 crypto_free(session->stream_template->limit);
Cullen Jennings235513a2005-09-21 22:51:36 +00001777 status = cipher_dealloc(session->stream_template->rtp_cipher);
1778 if (status)
1779 return status;
1780 status = auth_dealloc(session->stream_template->rtp_auth);
1781 if (status)
1782 return status;
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001783 status = rdbx_dealloc(&session->stream_template->rtp_rdbx);
1784 if (status)
1785 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001786 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
Marcus Sundberg67398e62005-10-05 12:39:51 +00001802 /* sanity check arguments */
1803 if ((session == NULL) || (policy == NULL) || (policy->key == NULL))
1804 return err_status_bad_param;
1805
Cullen Jennings235513a2005-09-21 22:51:36 +00001806 /* 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 */
Marcus Sundberg67398e62005-10-05 12:39:51 +00001863 if (session == NULL)
Cullen Jennings235513a2005-09-21 22:51:36 +00001864 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)
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;
1877 ctx->stream_list = NULL;
IƱaki Baz Castillo241fec32014-08-21 00:51:00 +02001878 ctx->user_data = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +00001879 while (policy != NULL) {
1880
1881 stat = srtp_add_stream(ctx, policy);
1882 if (stat) {
Marcus Sundberg67398e62005-10-05 12:39:51 +00001883 /* clean up everything */
1884 srtp_dealloc(*session);
Cullen Jennings235513a2005-09-21 22:51:36 +00001885 return stat;
1886 }
1887
1888 /* set policy to next item in list */
1889 policy = policy->next;
1890 }
1891
1892 return err_status_ok;
1893}
1894
1895
1896err_status_t
1897srtp_remove_stream(srtp_t session, uint32_t ssrc) {
1898 srtp_stream_ctx_t *stream, *last_stream;
1899 err_status_t status;
1900
1901 /* sanity check arguments */
1902 if (session == NULL)
1903 return err_status_bad_param;
1904
1905 /* find stream in list; complain if not found */
1906 last_stream = stream = session->stream_list;
1907 while ((stream != NULL) && (ssrc != stream->ssrc)) {
1908 last_stream = stream;
1909 stream = stream->next;
1910 }
1911 if (stream == NULL)
1912 return err_status_no_ctx;
1913
1914 /* remove stream from the list */
Jonathan Lennox20505b32010-05-27 19:22:25 +00001915 if (last_stream == stream)
1916 /* stream was first in list */
1917 session->stream_list = stream->next;
1918 else
1919 last_stream->next = stream->next;
Cullen Jennings235513a2005-09-21 22:51:36 +00001920
1921 /* deallocate the stream */
1922 status = srtp_stream_dealloc(session, stream);
1923 if (status)
1924 return status;
1925
1926 return err_status_ok;
1927}
1928
1929
1930/*
1931 * the default policy - provides a convenient way for callers to use
1932 * the default security policy
1933 *
1934 * this policy is that defined in the current SRTP internet draft.
1935 *
1936 */
1937
1938/*
1939 * NOTE: cipher_key_len is really key len (128 bits) plus salt len
1940 * (112 bits)
1941 */
1942/* There are hard-coded 16's for base_key_len in the key generation code */
1943
1944void
1945crypto_policy_set_rtp_default(crypto_policy_t *p) {
1946
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001947 p->cipher_type = AES_ICM;
Cullen Jennings235513a2005-09-21 22:51:36 +00001948 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
1949 p->auth_type = HMAC_SHA1;
1950 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
1951 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
1952 p->sec_serv = sec_serv_conf_and_auth;
1953
1954}
1955
1956void
1957crypto_policy_set_rtcp_default(crypto_policy_t *p) {
1958
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001959 p->cipher_type = AES_ICM;
Cullen Jennings235513a2005-09-21 22:51:36 +00001960 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
1961 p->auth_type = HMAC_SHA1;
1962 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
1963 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
1964 p->sec_serv = sec_serv_conf_and_auth;
1965
1966}
1967
David McGrewa8546882006-01-12 17:56:02 +00001968void
1969crypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p) {
1970
1971 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00001972 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00001973 *
1974 * note that this crypto policy is intended for SRTP, but not SRTCP
1975 */
1976
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001977 p->cipher_type = AES_ICM;
David McGrewa8546882006-01-12 17:56:02 +00001978 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
1979 p->auth_type = HMAC_SHA1;
1980 p->auth_key_len = 20; /* 160 bit key */
1981 p->auth_tag_len = 4; /* 32 bit tag */
1982 p->sec_serv = sec_serv_conf_and_auth;
1983
1984}
1985
1986
1987void
1988crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p) {
1989
1990 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00001991 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00001992 *
1993 * note that this crypto policy is intended for SRTP, but not SRTCP
1994 */
1995
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001996 p->cipher_type = AES_ICM;
David McGrewa8546882006-01-12 17:56:02 +00001997 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
1998 p->auth_type = NULL_AUTH;
1999 p->auth_key_len = 0;
2000 p->auth_tag_len = 0;
2001 p->sec_serv = sec_serv_conf;
2002
2003}
2004
2005
2006void
2007crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p) {
2008
2009 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00002010 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00002011 */
2012
2013 p->cipher_type = NULL_CIPHER;
2014 p->cipher_key_len = 0;
2015 p->auth_type = HMAC_SHA1;
2016 p->auth_key_len = 20;
2017 p->auth_tag_len = 10;
2018 p->sec_serv = sec_serv_auth;
2019
2020}
2021
2022
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002023void
2024crypto_policy_set_aes_cm_256_hmac_sha1_80(crypto_policy_t *p) {
2025
2026 /*
2027 * corresponds to draft-ietf-avt-big-aes-03.txt
2028 */
2029
2030 p->cipher_type = AES_ICM;
2031 p->cipher_key_len = 46;
2032 p->auth_type = HMAC_SHA1;
2033 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
2034 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
2035 p->sec_serv = sec_serv_conf_and_auth;
2036}
2037
2038
2039void
2040crypto_policy_set_aes_cm_256_hmac_sha1_32(crypto_policy_t *p) {
2041
2042 /*
2043 * corresponds to draft-ietf-avt-big-aes-03.txt
2044 *
2045 * note that this crypto policy is intended for SRTP, but not SRTCP
2046 */
2047
2048 p->cipher_type = AES_ICM;
2049 p->cipher_key_len = 46;
2050 p->auth_type = HMAC_SHA1;
2051 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
2052 p->auth_tag_len = 4; /* default 80 bits per RFC 3711 */
2053 p->sec_serv = sec_serv_conf_and_auth;
2054}
2055
jfigus8c36da22013-10-01 16:41:19 -04002056/*
2057 * AES-256 with no authentication.
2058 */
2059void
2060crypto_policy_set_aes_cm_256_null_auth (crypto_policy_t *p)
2061{
2062 p->cipher_type = AES_ICM;
2063 p->cipher_key_len = 46;
2064 p->auth_type = NULL_AUTH;
2065 p->auth_key_len = 0;
2066 p->auth_tag_len = 0;
2067 p->sec_serv = sec_serv_conf;
2068}
2069
2070#ifdef OPENSSL
2071/*
2072 * AES-128 GCM mode with 8 octet auth tag.
2073 */
2074void
2075crypto_policy_set_aes_gcm_128_8_auth(crypto_policy_t *p) {
2076 p->cipher_type = AES_128_GCM;
jfigus8719f952014-04-08 09:15:49 -04002077 p->cipher_key_len = AES_128_GCM_KEYSIZE_WSALT;
jfigus8c36da22013-10-01 16:41:19 -04002078 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2079 p->auth_key_len = 0;
2080 p->auth_tag_len = 8; /* 8 octet tag length */
2081 p->sec_serv = sec_serv_conf_and_auth;
2082}
2083
2084/*
2085 * AES-256 GCM mode with 8 octet auth tag.
2086 */
2087void
2088crypto_policy_set_aes_gcm_256_8_auth(crypto_policy_t *p) {
2089 p->cipher_type = AES_256_GCM;
jfigus8719f952014-04-08 09:15:49 -04002090 p->cipher_key_len = AES_256_GCM_KEYSIZE_WSALT;
jfigus8c36da22013-10-01 16:41:19 -04002091 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2092 p->auth_key_len = 0;
2093 p->auth_tag_len = 8; /* 8 octet tag length */
2094 p->sec_serv = sec_serv_conf_and_auth;
2095}
2096
2097/*
2098 * AES-128 GCM mode with 8 octet auth tag, no RTCP encryption.
2099 */
2100void
2101crypto_policy_set_aes_gcm_128_8_only_auth(crypto_policy_t *p) {
2102 p->cipher_type = AES_128_GCM;
jfigus8719f952014-04-08 09:15:49 -04002103 p->cipher_key_len = AES_128_GCM_KEYSIZE_WSALT;
jfigus8c36da22013-10-01 16:41:19 -04002104 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2105 p->auth_key_len = 0;
2106 p->auth_tag_len = 8; /* 8 octet tag length */
2107 p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
2108}
2109
2110/*
2111 * AES-256 GCM mode with 8 octet auth tag, no RTCP encryption.
2112 */
2113void
2114crypto_policy_set_aes_gcm_256_8_only_auth(crypto_policy_t *p) {
2115 p->cipher_type = AES_256_GCM;
jfigus8719f952014-04-08 09:15:49 -04002116 p->cipher_key_len = AES_256_GCM_KEYSIZE_WSALT;
jfigus8c36da22013-10-01 16:41:19 -04002117 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2118 p->auth_key_len = 0;
2119 p->auth_tag_len = 8; /* 8 octet tag length */
2120 p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
2121}
jfigusc13c1002014-05-08 13:34:53 -04002122
2123/*
2124 * AES-128 GCM mode with 16 octet auth tag.
2125 */
2126void
2127crypto_policy_set_aes_gcm_128_16_auth(crypto_policy_t *p) {
2128 p->cipher_type = AES_128_GCM;
2129 p->cipher_key_len = AES_128_GCM_KEYSIZE_WSALT;
2130 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2131 p->auth_key_len = 0;
2132 p->auth_tag_len = 16; /* 16 octet tag length */
2133 p->sec_serv = sec_serv_conf_and_auth;
2134}
2135
2136/*
2137 * AES-256 GCM mode with 16 octet auth tag.
2138 */
2139void
2140crypto_policy_set_aes_gcm_256_16_auth(crypto_policy_t *p) {
2141 p->cipher_type = AES_256_GCM;
2142 p->cipher_key_len = AES_256_GCM_KEYSIZE_WSALT;
2143 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2144 p->auth_key_len = 0;
2145 p->auth_tag_len = 16; /* 16 octet tag length */
2146 p->sec_serv = sec_serv_conf_and_auth;
2147}
2148
jfigus8c36da22013-10-01 16:41:19 -04002149#endif
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002150
Cullen Jennings235513a2005-09-21 22:51:36 +00002151/*
2152 * secure rtcp functions
2153 */
2154
jfigus8c36da22013-10-01 16:41:19 -04002155/*
2156 * AEAD uses a new IV formation method. This function implements
2157 * section 10.1 from draft-ietf-avtcore-srtp-aes-gcm-07.txt. The
2158 * calculation is defined as, where (+) is the xor operation:
2159 *
2160 * 0 1 2 3 4 5 6 7 8 9 10 11
2161 * +--+--+--+--+--+--+--+--+--+--+--+--+
2162 * |00|00| SSRC |00|00|0+SRTCP Idx|---+
2163 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2164 * |
2165 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2166 * | Encryption Salt |->(+)
2167 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2168 * |
2169 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2170 * | Initialization Vector |<--+
2171 * +--+--+--+--+--+--+--+--+--+--+--+--+*
2172 *
2173 * Input: *stream - pointer to SRTP stream context, used to retrieve
2174 * the SALT
2175 * *iv - Pointer to recieve the calculated IV
2176 * seq_num - The SEQ value to use for the IV calculation.
2177 * *hdr - The RTP header, used to get the SSRC value
2178 *
2179 */
2180static void srtp_calc_aead_iv_srtcp(srtp_stream_ctx_t *stream, v128_t *iv,
2181 uint32_t seq_num, srtcp_hdr_t *hdr)
2182{
2183 v128_t in;
2184 v128_t salt;
2185
2186 memset(&in, 0, sizeof(v128_t));
2187 memset(&salt, 0, sizeof(v128_t));
2188
2189 in.v16[0] = 0;
2190 memcpy(&in.v16[1], &hdr->ssrc, 4); /* still in network order! */
2191 in.v16[3] = 0;
2192 in.v32[2] = 0x7FFFFFFF & htonl(seq_num); /* bit 32 is suppose to be zero */
2193
2194 debug_print(mod_srtp, "Pre-salted RTCP IV = %s\n", v128_hex_string(&in));
2195
2196 /*
2197 * Get the SALT value from the context
2198 */
2199 memcpy(salt.v8, stream->c_salt, 12);
2200 debug_print(mod_srtp, "RTCP SALT = %s\n", v128_hex_string(&salt));
2201
2202 /*
2203 * Finally, apply the SALT to the input
2204 */
2205 v128_xor(iv, &in, &salt);
2206}
2207
2208/*
2209 * This code handles AEAD ciphers for outgoing RTCP. We currently support
2210 * AES-GCM mode with 128 or 256 bit keys.
2211 */
2212static err_status_t
2213srtp_protect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream,
Travis Cross31844002014-07-02 16:18:57 +00002214 void *rtcp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -04002215{
2216 srtcp_hdr_t *hdr = (srtcp_hdr_t*)rtcp_hdr;
2217 uint32_t *enc_start; /* pointer to start of encrypted portion */
2218 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002219 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -04002220 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
2221 err_status_t status;
2222 int tag_len;
2223 uint32_t seq_num;
2224 v128_t iv;
2225 uint32_t tseq;
2226
2227 /* get tag length from stream context */
2228 tag_len = auth_get_tag_length(stream->rtcp_auth);
2229
2230 /*
2231 * set encryption start and encryption length - if we're not
2232 * providing confidentiality, set enc_start to NULL
2233 */
2234 enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header;
2235 enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
2236
2237 /* NOTE: hdr->length is not usable - it refers to only the first
2238 RTCP report in the compound packet! */
2239 /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2240 multiples of 32-bits (RFC 3550 6.1) */
2241 trailer = (uint32_t*)((char*)enc_start + enc_octet_len + tag_len);
2242
2243 if (stream->rtcp_services & sec_serv_conf) {
2244 *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
2245 } else {
2246 enc_start = NULL;
2247 enc_octet_len = 0;
2248 /* 0 is network-order independant */
2249 *trailer = 0x00000000; /* set encrypt bit */
2250 }
2251
2252 /*
2253 * set the auth_tag pointer to the proper location, which is after
2254 * the payload, but before the trailer
2255 * (note that srtpc *always* provides authentication, unlike srtp)
2256 */
2257 /* Note: This would need to change for optional mikey data */
2258 auth_tag = (uint8_t*)hdr + *pkt_octet_len;
2259
2260 /*
2261 * check sequence number for overruns, and copy it into the packet
2262 * if its value isn't too big
2263 */
2264 status = rdb_increment(&stream->rtcp_rdb);
2265 if (status) {
2266 return status;
2267 }
2268 seq_num = rdb_get_value(&stream->rtcp_rdb);
2269 *trailer |= htonl(seq_num);
2270 debug_print(mod_srtp, "srtcp index: %x", seq_num);
2271
2272 /*
2273 * Calculating the IV and pass it down to the cipher
2274 */
2275 srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
2276 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
2277 if (status) {
2278 return err_status_cipher_fail;
2279 }
2280
2281 /*
2282 * Set the AAD for GCM mode
2283 */
2284 if (enc_start) {
2285 /*
2286 * If payload encryption is enabled, then the AAD consist of
2287 * the RTCP header and the seq# at the end of the packet
2288 */
2289 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2290 octets_in_rtcp_header);
2291 if (status) {
2292 return ( err_status_cipher_fail);
2293 }
2294 } else {
2295 /*
2296 * Since payload encryption is not enabled, we must authenticate
2297 * the entire packet as described in section 10.3 in revision 07
2298 * of the draft.
2299 */
2300 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2301 *pkt_octet_len);
2302 if (status) {
2303 return ( err_status_cipher_fail);
2304 }
2305 }
2306 /*
2307 * put the idx# into network byte order and process it as AAD
2308 */
2309 tseq = htonl(*trailer);
2310 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq,
2311 sizeof(srtcp_trailer_t));
2312 if (status) {
2313 return ( err_status_cipher_fail);
2314 }
2315
2316 /* if we're encrypting, exor keystream into the message */
2317 if (enc_start) {
2318 status = cipher_encrypt(stream->rtcp_cipher,
2319 (uint8_t*)enc_start, &enc_octet_len);
2320 if (status) {
2321 return err_status_cipher_fail;
2322 }
2323 /*
2324 * Get the tag and append that to the output
2325 */
2326 status = cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag,
2327 &tag_len);
2328 if (status) {
2329 return ( err_status_cipher_fail);
2330 }
2331 enc_octet_len += tag_len;
2332 } else {
2333 /*
2334 * Even though we're not encrypting the payload, we need
2335 * to run the cipher to get the auth tag.
2336 */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002337 unsigned int nolen = 0;
jfigus8c36da22013-10-01 16:41:19 -04002338 status = cipher_encrypt(stream->rtcp_cipher, NULL, &nolen);
2339 if (status) {
2340 return err_status_cipher_fail;
2341 }
2342 /*
2343 * Get the tag and append that to the output
2344 */
2345 status = cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag,
2346 &tag_len);
2347 if (status) {
2348 return ( err_status_cipher_fail);
2349 }
2350 enc_octet_len += tag_len;
2351 }
2352
2353 /* increase the packet length by the length of the auth tag and seq_num*/
2354 *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
2355
2356 return err_status_ok;
2357}
2358
2359/*
2360 * This function handles incoming SRTCP packets while in AEAD mode,
2361 * which currently supports AES-GCM encryption. Note, the auth tag is
2362 * at the end of the packet stream and is automatically checked by GCM
2363 * when decrypting the payload.
2364 */
2365static err_status_t
2366srtp_unprotect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream,
Travis Cross31844002014-07-02 16:18:57 +00002367 void *srtcp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -04002368{
2369 srtcp_hdr_t *hdr = (srtcp_hdr_t*)srtcp_hdr;
2370 uint32_t *enc_start; /* pointer to start of encrypted portion */
2371 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002372 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -04002373 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
2374 err_status_t status;
2375 int tag_len;
2376 unsigned int tmp_len;
2377 uint32_t seq_num;
2378 v128_t iv;
2379 uint32_t tseq;
2380
2381 /* get tag length from stream context */
2382 tag_len = auth_get_tag_length(stream->rtcp_auth);
2383
jfigus8c36da22013-10-01 16:41:19 -04002384 /*
2385 * set encryption start, encryption length, and trailer
2386 */
2387 /* index & E (encryption) bit follow normal data. hdr->len
2388 is the number of words (32-bit) in the normal packet minus 1 */
2389 /* This should point trailer to the word past the end of the
2390 normal data. */
2391 /* This would need to be modified for optional mikey data */
2392 /*
2393 * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2394 * multiples of 32-bits (RFC 3550 6.1)
2395 */
2396 trailer = (uint32_t*)((char*)hdr + *pkt_octet_len - sizeof(srtcp_trailer_t));
2397 /*
2398 * We pass the tag down to the cipher when doing GCM mode
2399 */
2400 enc_octet_len = *pkt_octet_len - (octets_in_rtcp_header +
2401 sizeof(srtcp_trailer_t));
2402 auth_tag = (uint8_t*)hdr + *pkt_octet_len - tag_len - sizeof(srtcp_trailer_t);
2403
2404 if (*((unsigned char*)trailer) & SRTCP_E_BYTE_BIT) {
2405 enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header;
2406 } else {
2407 enc_octet_len = 0;
2408 enc_start = NULL; /* this indicates that there's no encryption */
2409 }
2410
2411 /*
2412 * check the sequence number for replays
2413 */
2414 /* this is easier than dealing with bitfield access */
2415 seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
2416 debug_print(mod_srtp, "srtcp index: %x", seq_num);
2417 status = rdb_check(&stream->rtcp_rdb, seq_num);
2418 if (status) {
2419 return status;
2420 }
2421
2422 /*
2423 * Calculate and set the IV
2424 */
2425 srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
2426 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
2427 if (status) {
2428 return err_status_cipher_fail;
2429 }
2430
2431 /*
2432 * Set the AAD for GCM mode
2433 */
2434 if (enc_start) {
2435 /*
2436 * If payload encryption is enabled, then the AAD consist of
2437 * the RTCP header and the seq# at the end of the packet
2438 */
2439 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2440 octets_in_rtcp_header);
2441 if (status) {
2442 return ( err_status_cipher_fail);
2443 }
2444 } else {
2445 /*
2446 * Since payload encryption is not enabled, we must authenticate
2447 * the entire packet as described in section 10.3 in revision 07
2448 * of the draft.
2449 */
2450 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2451 (*pkt_octet_len - tag_len - sizeof(srtcp_trailer_t)));
2452 if (status) {
2453 return ( err_status_cipher_fail);
2454 }
2455 }
2456
2457 /*
2458 * put the idx# into network byte order, and process it as AAD
2459 */
2460 tseq = htonl(*trailer);
2461 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq,
2462 sizeof(srtcp_trailer_t));
2463 if (status) {
2464 return ( err_status_cipher_fail);
2465 }
2466
2467 /* if we're decrypting, exor keystream into the message */
2468 if (enc_start) {
2469 status = cipher_decrypt(stream->rtcp_cipher,
2470 (uint8_t*)enc_start, &enc_octet_len);
2471 if (status) {
2472 return status;
2473 }
2474 } else {
2475 /*
2476 * Still need to run the cipher to check the tag
2477 */
2478 tmp_len = tag_len;
2479 status = cipher_decrypt(stream->rtcp_cipher, (uint8_t*)auth_tag,
2480 &tmp_len);
2481 if (status) {
2482 return status;
2483 }
2484 }
2485
2486 /* decrease the packet length by the length of the auth tag and seq_num*/
2487 *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
2488
2489 /*
2490 * verify that stream is for received traffic - this check will
2491 * detect SSRC collisions, since a stream that appears in both
2492 * srtp_protect() and srtp_unprotect() will fail this test in one of
2493 * those functions.
2494 *
2495 * we do this check *after* the authentication check, so that the
2496 * latter check will catch any attempts to fool us into thinking
2497 * that we've got a collision
2498 */
2499 if (stream->direction != dir_srtp_receiver) {
2500 if (stream->direction == dir_unknown) {
2501 stream->direction = dir_srtp_receiver;
2502 } else {
2503 srtp_handle_event(ctx, stream, event_ssrc_collision);
2504 }
2505 }
2506
2507 /*
2508 * if the stream is a 'provisional' one, in which the template context
2509 * is used, then we need to allocate a new stream at this point, since
2510 * the authentication passed
2511 */
2512 if (stream == ctx->stream_template) {
2513 srtp_stream_ctx_t *new_stream;
2514
2515 /*
2516 * allocate and initialize a new stream
2517 *
2518 * note that we indicate failure if we can't allocate the new
2519 * stream, and some implementations will want to not return
2520 * failure here
2521 */
2522 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
2523 if (status) {
2524 return status;
2525 }
2526
2527 /* add new stream to the head of the stream_list */
2528 new_stream->next = ctx->stream_list;
2529 ctx->stream_list = new_stream;
2530
2531 /* set stream (the pointer used in this function) */
2532 stream = new_stream;
2533 }
2534
2535 /* we've passed the authentication check, so add seq_num to the rdb */
2536 rdb_add_index(&stream->rtcp_rdb, seq_num);
2537
2538 return err_status_ok;
2539}
2540
Cullen Jennings235513a2005-09-21 22:51:36 +00002541err_status_t
2542srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00002543 srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00002544 uint32_t *enc_start; /* pointer to start of encrypted portion */
2545 uint32_t *auth_start; /* pointer to start of auth. portion */
2546 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002547 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002548 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
Cullen Jennings235513a2005-09-21 22:51:36 +00002549 err_status_t status;
2550 int tag_len;
2551 srtp_stream_ctx_t *stream;
2552 int prefix_len;
2553 uint32_t seq_num;
2554
2555 /* we assume the hdr is 32-bit aligned to start */
Travis Cross8ba46eb2014-06-29 18:42:29 +00002556
2557 /* check the packet length - it must at least contain a full header */
2558 if (*pkt_octet_len < octets_in_rtcp_header)
2559 return err_status_bad_param;
2560
Cullen Jennings235513a2005-09-21 22:51:36 +00002561 /*
2562 * look up ssrc in srtp_stream list, and process the packet with
2563 * the appropriate stream. if we haven't seen this stream before,
2564 * there's only one key for this srtp_session, and the cipher
2565 * supports key-sharing, then we assume that a new stream using
2566 * that key has just started up
2567 */
2568 stream = srtp_get_stream(ctx, hdr->ssrc);
2569 if (stream == NULL) {
2570 if (ctx->stream_template != NULL) {
2571 srtp_stream_ctx_t *new_stream;
2572
2573 /* allocate and initialize a new stream */
2574 status = srtp_stream_clone(ctx->stream_template,
2575 hdr->ssrc, &new_stream);
2576 if (status)
2577 return status;
2578
2579 /* add new stream to the head of the stream_list */
2580 new_stream->next = ctx->stream_list;
2581 ctx->stream_list = new_stream;
2582
2583 /* set stream (the pointer used in this function) */
2584 stream = new_stream;
2585 } else {
2586 /* no template stream, so we return an error */
2587 return err_status_no_ctx;
2588 }
2589 }
2590
2591 /*
2592 * verify that stream is for sending traffic - this check will
2593 * detect SSRC collisions, since a stream that appears in both
2594 * srtp_protect() and srtp_unprotect() will fail this test in one of
2595 * those functions.
2596 */
2597 if (stream->direction != dir_srtp_sender) {
2598 if (stream->direction == dir_unknown) {
David McGrewc34f7402006-03-09 21:17:00 +00002599 stream->direction = dir_srtp_sender;
Cullen Jennings235513a2005-09-21 22:51:36 +00002600 } else {
2601 srtp_handle_event(ctx, stream, event_ssrc_collision);
2602 }
2603 }
2604
jfigus8c36da22013-10-01 16:41:19 -04002605 /*
2606 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
2607 * the request to our AEAD handler.
2608 */
2609 if (stream->rtp_cipher->algorithm == AES_128_GCM ||
2610 stream->rtp_cipher->algorithm == AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00002611 return srtp_protect_rtcp_aead(ctx, stream, rtcp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04002612 }
2613
Cullen Jennings235513a2005-09-21 22:51:36 +00002614 /* get tag length from stream context */
2615 tag_len = auth_get_tag_length(stream->rtcp_auth);
2616
2617 /*
2618 * set encryption start and encryption length - if we're not
2619 * providing confidentiality, set enc_start to NULL
2620 */
2621 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
2622 enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
2623
2624 /* all of the packet, except the header, gets encrypted */
2625 /* NOTE: hdr->length is not usable - it refers to only the first
2626 RTCP report in the compound packet! */
2627 /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2628 multiples of 32-bits (RFC 3550 6.1) */
2629 trailer = (uint32_t *) ((char *)enc_start + enc_octet_len);
2630
2631 if (stream->rtcp_services & sec_serv_conf) {
2632 *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
2633 } else {
2634 enc_start = NULL;
2635 enc_octet_len = 0;
2636 /* 0 is network-order independant */
2637 *trailer = 0x00000000; /* set encrypt bit */
2638 }
2639
2640 /*
2641 * set the auth_start and auth_tag pointers to the proper locations
2642 * (note that srtpc *always* provides authentication, unlike srtp)
2643 */
2644 /* Note: This would need to change for optional mikey data */
2645 auth_start = (uint32_t *)hdr;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002646 auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t);
Cullen Jennings235513a2005-09-21 22:51:36 +00002647
David McGrew79870d62007-06-15 18:17:39 +00002648 /* perform EKT processing if needed */
2649 ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len,
2650 rdbx_get_packet_index(&stream->rtp_rdbx));
2651
Cullen Jennings235513a2005-09-21 22:51:36 +00002652 /*
2653 * check sequence number for overruns, and copy it into the packet
2654 * if its value isn't too big
2655 */
2656 status = rdb_increment(&stream->rtcp_rdb);
2657 if (status)
2658 return status;
2659 seq_num = rdb_get_value(&stream->rtcp_rdb);
2660 *trailer |= htonl(seq_num);
2661 debug_print(mod_srtp, "srtcp index: %x", seq_num);
2662
2663 /*
2664 * if we're using rindael counter mode, set nonce and seq
2665 */
Jonathan Lennoxf4332412010-05-20 22:10:20 +00002666 if (stream->rtcp_cipher->type->id == AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002667 v128_t iv;
2668
2669 iv.v32[0] = 0;
2670 iv.v32[1] = hdr->ssrc; /* still in network order! */
2671 iv.v32[2] = htonl(seq_num >> 16);
2672 iv.v32[3] = htonl(seq_num << 16);
jfigus7882dd92013-08-02 16:08:23 -04002673 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002674
2675 } else {
2676 v128_t iv;
2677
2678 /* otherwise, just set the index to seq_num */
2679 iv.v32[0] = 0;
2680 iv.v32[1] = 0;
2681 iv.v32[2] = 0;
2682 iv.v32[3] = htonl(seq_num);
jfigus7882dd92013-08-02 16:08:23 -04002683 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002684 }
2685 if (status)
2686 return err_status_cipher_fail;
2687
2688 /*
2689 * if we're authenticating using a universal hash, put the keystream
2690 * prefix into the authentication tag
2691 */
2692
2693 /* if auth_start is non-null, then put keystream into tag */
2694 if (auth_start) {
2695
2696 /* put keystream prefix into auth_tag */
2697 prefix_len = auth_get_prefix_length(stream->rtcp_auth);
2698 status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
2699
2700 debug_print(mod_srtp, "keystream prefix: %s",
2701 octet_string_hex_string(auth_tag, prefix_len));
2702
2703 if (status)
2704 return err_status_cipher_fail;
2705 }
2706
2707 /* if we're encrypting, exor keystream into the message */
2708 if (enc_start) {
2709 status = cipher_encrypt(stream->rtcp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002710 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002711 if (status)
2712 return err_status_cipher_fail;
2713 }
2714
2715 /* initialize auth func context */
2716 auth_start(stream->rtcp_auth);
2717
David McGrew9c70f292006-05-03 19:38:38 +00002718 /*
2719 * run auth func over packet (including trailer), and write the
2720 * result at auth_tag
2721 */
Cullen Jennings235513a2005-09-21 22:51:36 +00002722 status = auth_compute(stream->rtcp_auth,
David McGrew9c70f292006-05-03 19:38:38 +00002723 (uint8_t *)auth_start,
2724 (*pkt_octet_len) + sizeof(srtcp_trailer_t),
2725 auth_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00002726 debug_print(mod_srtp, "srtcp auth tag: %s",
2727 octet_string_hex_string(auth_tag, tag_len));
2728 if (status)
2729 return err_status_auth_fail;
2730
2731 /* increase the packet length by the length of the auth tag and seq_num*/
2732 *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
2733
2734 return err_status_ok;
2735}
2736
2737
2738err_status_t
2739srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00002740 srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00002741 uint32_t *enc_start; /* pointer to start of encrypted portion */
2742 uint32_t *auth_start; /* pointer to start of auth. portion */
2743 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002744 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002745 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
2746 uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
David McGrew79870d62007-06-15 18:17:39 +00002747 uint8_t tag_copy[SRTP_MAX_TAG_LEN];
Cullen Jennings235513a2005-09-21 22:51:36 +00002748 err_status_t status;
Travis Cross1b8b1e72014-07-02 15:32:36 +00002749 unsigned int auth_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00002750 int tag_len;
2751 srtp_stream_ctx_t *stream;
2752 int prefix_len;
2753 uint32_t seq_num;
TV Sriram4986a362013-05-06 11:24:03 -07002754 int e_bit_in_packet; /* whether the E-bit was found in the packet */
2755 int sec_serv_confidentiality; /* whether confidentiality was requested */
Cullen Jennings235513a2005-09-21 22:51:36 +00002756
2757 /* we assume the hdr is 32-bit aligned to start */
Travis Cross444a5442014-07-02 16:01:01 +00002758
Travis Crosse896bf72014-07-07 19:59:33 +00002759 /* check that the length value is sane; we'll check again once we
2760 know the tag length, but we at least want to know that it is
2761 a positive value */
2762 if (*pkt_octet_len < octets_in_rtcp_header + sizeof(srtcp_trailer_t))
2763 return err_status_bad_param;
2764
Cullen Jennings235513a2005-09-21 22:51:36 +00002765 /*
2766 * look up ssrc in srtp_stream list, and process the packet with
2767 * the appropriate stream. if we haven't seen this stream before,
2768 * there's only one key for this srtp_session, and the cipher
2769 * supports key-sharing, then we assume that a new stream using
2770 * that key has just started up
2771 */
2772 stream = srtp_get_stream(ctx, hdr->ssrc);
2773 if (stream == NULL) {
2774 if (ctx->stream_template != NULL) {
2775 stream = ctx->stream_template;
David McGrew79870d62007-06-15 18:17:39 +00002776
2777 /*
2778 * check to see if stream_template has an EKT data structure, in
2779 * which case we initialize the template using the EKT policy
2780 * referenced by that data (which consists of decrypting the
2781 * master key from the EKT field)
2782 *
2783 * this function initializes a *provisional* stream, and this
2784 * stream should not be accepted until and unless the packet
2785 * passes its authentication check
2786 */
2787 if (stream->ekt != NULL) {
2788 status = srtp_stream_init_from_ekt(stream, srtcp_hdr, *pkt_octet_len);
2789 if (status)
2790 return status;
2791 }
2792
Cullen Jennings235513a2005-09-21 22:51:36 +00002793 debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)",
2794 hdr->ssrc);
2795 } else {
2796 /* no template stream, so we return an error */
2797 return err_status_no_ctx;
2798 }
2799 }
2800
Travis Cross8ba46eb2014-06-29 18:42:29 +00002801 /* get tag length from stream context */
2802 tag_len = auth_get_tag_length(stream->rtcp_auth);
2803
2804 /* check the packet length - it must contain at least a full RTCP
2805 header, an auth tag (if applicable), and the SRTCP encrypted flag
2806 and 31-bit index value */
jfigus73e30932014-07-07 15:50:32 -04002807 if (*pkt_octet_len < (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t))) {
Travis Cross8ba46eb2014-06-29 18:42:29 +00002808 return err_status_bad_param;
jfigus73e30932014-07-07 15:50:32 -04002809 }
Travis Cross8ba46eb2014-06-29 18:42:29 +00002810
jfigus8c36da22013-10-01 16:41:19 -04002811 /*
2812 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
2813 * the request to our AEAD handler.
2814 */
2815 if (stream->rtp_cipher->algorithm == AES_128_GCM ||
2816 stream->rtp_cipher->algorithm == AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00002817 return srtp_unprotect_rtcp_aead(ctx, stream, srtcp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04002818 }
2819
TV Sriram4986a362013-05-06 11:24:03 -07002820 sec_serv_confidentiality = stream->rtcp_services == sec_serv_conf ||
2821 stream->rtcp_services == sec_serv_conf_and_auth;
2822
Cullen Jennings235513a2005-09-21 22:51:36 +00002823 /*
2824 * set encryption start, encryption length, and trailer
2825 */
2826 enc_octet_len = *pkt_octet_len -
2827 (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t));
2828 /* index & E (encryption) bit follow normal data. hdr->len
2829 is the number of words (32-bit) in the normal packet minus 1 */
2830 /* This should point trailer to the word past the end of the
2831 normal data. */
2832 /* This would need to be modified for optional mikey data */
2833 /*
2834 * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2835 * multiples of 32-bits (RFC 3550 6.1)
2836 */
2837 trailer = (uint32_t *) ((char *) hdr +
TV Sriram4986a362013-05-06 11:24:03 -07002838 *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t)));
2839 e_bit_in_packet =
2840 (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) == SRTCP_E_BYTE_BIT;
2841 if (e_bit_in_packet != sec_serv_confidentiality) {
2842 return err_status_cant_check;
2843 }
2844 if (sec_serv_confidentiality) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002845 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
2846 } else {
2847 enc_octet_len = 0;
2848 enc_start = NULL; /* this indicates that there's no encryption */
2849 }
2850
2851 /*
2852 * set the auth_start and auth_tag pointers to the proper locations
2853 * (note that srtcp *always* uses authentication, unlike srtp)
2854 */
2855 auth_start = (uint32_t *)hdr;
David McGrew79870d62007-06-15 18:17:39 +00002856 auth_len = *pkt_octet_len - tag_len;
2857 auth_tag = (uint8_t *)hdr + auth_len;
2858
2859 /*
2860 * if EKT is in use, then we make a copy of the tag from the packet,
2861 * and then zeroize the location of the base tag
2862 *
2863 * we first re-position the auth_tag pointer so that it points to
2864 * the base tag
2865 */
2866 if (stream->ekt) {
2867 auth_tag -= ekt_octets_after_base_tag(stream->ekt);
2868 memcpy(tag_copy, auth_tag, tag_len);
2869 octet_string_set_to_zero(auth_tag, tag_len);
2870 auth_tag = tag_copy;
2871 auth_len += tag_len;
2872 }
Cullen Jennings235513a2005-09-21 22:51:36 +00002873
2874 /*
2875 * check the sequence number for replays
2876 */
2877 /* this is easier than dealing with bitfield access */
2878 seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
David McGrew9c70f292006-05-03 19:38:38 +00002879 debug_print(mod_srtp, "srtcp index: %x", seq_num);
Cullen Jennings235513a2005-09-21 22:51:36 +00002880 status = rdb_check(&stream->rtcp_rdb, seq_num);
2881 if (status)
2882 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00002883
2884 /*
2885 * if we're using aes counter mode, set nonce and seq
2886 */
Jonathan Lennoxf4332412010-05-20 22:10:20 +00002887 if (stream->rtcp_cipher->type->id == AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002888 v128_t iv;
2889
2890 iv.v32[0] = 0;
2891 iv.v32[1] = hdr->ssrc; /* still in network order! */
2892 iv.v32[2] = htonl(seq_num >> 16);
2893 iv.v32[3] = htonl(seq_num << 16);
jfigus7882dd92013-08-02 16:08:23 -04002894 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002895
2896 } else {
2897 v128_t iv;
2898
2899 /* otherwise, just set the index to seq_num */
2900 iv.v32[0] = 0;
2901 iv.v32[1] = 0;
2902 iv.v32[2] = 0;
2903 iv.v32[3] = htonl(seq_num);
jfigus7882dd92013-08-02 16:08:23 -04002904 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002905
2906 }
2907 if (status)
2908 return err_status_cipher_fail;
2909
2910 /* initialize auth func context */
2911 auth_start(stream->rtcp_auth);
2912
2913 /* run auth func over packet, put result into tmp_tag */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002914 status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start,
David McGrew79870d62007-06-15 18:17:39 +00002915 auth_len, tmp_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00002916 debug_print(mod_srtp, "srtcp computed tag: %s",
2917 octet_string_hex_string(tmp_tag, tag_len));
2918 if (status)
2919 return err_status_auth_fail;
2920
2921 /* compare the tag just computed with the one in the packet */
2922 debug_print(mod_srtp, "srtcp tag from packet: %s",
2923 octet_string_hex_string(auth_tag, tag_len));
2924 if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
2925 return err_status_auth_fail;
2926
2927 /*
2928 * if we're authenticating using a universal hash, put the keystream
2929 * prefix into the authentication tag
2930 */
2931 prefix_len = auth_get_prefix_length(stream->rtcp_auth);
2932 if (prefix_len) {
2933 status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
2934 debug_print(mod_srtp, "keystream prefix: %s",
2935 octet_string_hex_string(auth_tag, prefix_len));
2936 if (status)
2937 return err_status_cipher_fail;
2938 }
2939
2940 /* if we're decrypting, exor keystream into the message */
2941 if (enc_start) {
Jonathan Lennox23dc1e22010-06-01 18:19:04 +00002942 status = cipher_decrypt(stream->rtcp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002943 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002944 if (status)
2945 return err_status_cipher_fail;
2946 }
2947
David McGrew79870d62007-06-15 18:17:39 +00002948 /* decrease the packet length by the length of the auth tag and seq_num */
Cullen Jennings235513a2005-09-21 22:51:36 +00002949 *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
2950
David McGrew79870d62007-06-15 18:17:39 +00002951 /*
2952 * if EKT is in effect, subtract the EKT data out of the packet
2953 * length
2954 */
2955 *pkt_octet_len -= ekt_octets_after_base_tag(stream->ekt);
2956
Cullen Jennings235513a2005-09-21 22:51:36 +00002957 /*
2958 * verify that stream is for received traffic - this check will
2959 * detect SSRC collisions, since a stream that appears in both
2960 * srtp_protect() and srtp_unprotect() will fail this test in one of
2961 * those functions.
2962 *
2963 * we do this check *after* the authentication check, so that the
2964 * latter check will catch any attempts to fool us into thinking
2965 * that we've got a collision
2966 */
2967 if (stream->direction != dir_srtp_receiver) {
2968 if (stream->direction == dir_unknown) {
2969 stream->direction = dir_srtp_receiver;
2970 } else {
2971 srtp_handle_event(ctx, stream, event_ssrc_collision);
2972 }
2973 }
2974
2975 /*
2976 * if the stream is a 'provisional' one, in which the template context
2977 * is used, then we need to allocate a new stream at this point, since
2978 * the authentication passed
2979 */
2980 if (stream == ctx->stream_template) {
2981 srtp_stream_ctx_t *new_stream;
2982
2983 /*
2984 * allocate and initialize a new stream
2985 *
2986 * note that we indicate failure if we can't allocate the new
2987 * stream, and some implementations will want to not return
2988 * failure here
2989 */
2990 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
2991 if (status)
2992 return status;
2993
2994 /* add new stream to the head of the stream_list */
2995 new_stream->next = ctx->stream_list;
2996 ctx->stream_list = new_stream;
2997
2998 /* set stream (the pointer used in this function) */
2999 stream = new_stream;
3000 }
3001
3002 /* we've passed the authentication check, so add seq_num to the rdb */
3003 rdb_add_index(&stream->rtcp_rdb, seq_num);
3004
3005
3006 return err_status_ok;
3007}
David McGrew0cb86ee2006-07-07 15:46:57 +00003008
3009
IƱaki Baz Castillo241fec32014-08-21 00:51:00 +02003010/*
3011 * user data within srtp_t context
3012 */
3013
3014void
3015srtp_set_user_data(srtp_t ctx, void *data) {
3016 ctx->user_data = data;
3017}
3018
3019void*
3020srtp_get_user_data(srtp_t ctx) {
3021 return ctx->user_data;
3022}
3023
David McGrew0cb86ee2006-07-07 15:46:57 +00003024
3025/*
3026 * dtls keying for srtp
3027 */
3028
3029err_status_t
3030crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy,
3031 srtp_profile_t profile) {
3032
3033 /* set SRTP policy from the SRTP profile in the key set */
3034 switch(profile) {
3035 case srtp_profile_aes128_cm_sha1_80:
3036 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003037 break;
3038 case srtp_profile_aes128_cm_sha1_32:
3039 crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003040 break;
3041 case srtp_profile_null_sha1_80:
3042 crypto_policy_set_null_cipher_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003043 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003044 case srtp_profile_aes256_cm_sha1_80:
3045 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003046 break;
3047 case srtp_profile_aes256_cm_sha1_32:
3048 crypto_policy_set_aes_cm_256_hmac_sha1_32(policy);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003049 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003050 /* the following profiles are not (yet) supported */
3051 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003052 default:
3053 return err_status_bad_param;
3054 }
3055
3056 return err_status_ok;
3057}
3058
3059err_status_t
3060crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy,
3061 srtp_profile_t profile) {
3062
3063 /* set SRTP policy from the SRTP profile in the key set */
3064 switch(profile) {
3065 case srtp_profile_aes128_cm_sha1_80:
3066 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
3067 break;
3068 case srtp_profile_aes128_cm_sha1_32:
jfigus0acbb032013-05-30 16:47:02 -04003069 /* We do not honor the 32-bit auth tag request since
3070 * this is not compliant with RFC 3711 */
David McGrew0cb86ee2006-07-07 15:46:57 +00003071 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
3072 break;
3073 case srtp_profile_null_sha1_80:
3074 crypto_policy_set_null_cipher_hmac_sha1_80(policy);
3075 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003076 case srtp_profile_aes256_cm_sha1_80:
3077 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
3078 break;
3079 case srtp_profile_aes256_cm_sha1_32:
jfigus0acbb032013-05-30 16:47:02 -04003080 /* We do not honor the 32-bit auth tag request since
3081 * this is not compliant with RFC 3711 */
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003082 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
3083 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003084 /* the following profiles are not (yet) supported */
3085 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003086 default:
3087 return err_status_bad_param;
3088 }
3089
3090 return err_status_ok;
3091}
3092
3093void
3094append_salt_to_key(uint8_t *key, unsigned int bytes_in_key,
3095 uint8_t *salt, unsigned int bytes_in_salt) {
3096
3097 memcpy(key + bytes_in_key, salt, bytes_in_salt);
3098
3099}
3100
3101unsigned int
3102srtp_profile_get_master_key_length(srtp_profile_t profile) {
3103
3104 switch(profile) {
3105 case srtp_profile_aes128_cm_sha1_80:
3106 return 16;
3107 break;
3108 case srtp_profile_aes128_cm_sha1_32:
3109 return 16;
3110 break;
3111 case srtp_profile_null_sha1_80:
3112 return 16;
3113 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003114 case srtp_profile_aes256_cm_sha1_80:
3115 return 32;
3116 break;
3117 case srtp_profile_aes256_cm_sha1_32:
3118 return 32;
3119 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003120 /* the following profiles are not (yet) supported */
3121 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003122 default:
3123 return 0; /* indicate error by returning a zero */
3124 }
3125}
3126
3127unsigned int
3128srtp_profile_get_master_salt_length(srtp_profile_t profile) {
3129
3130 switch(profile) {
3131 case srtp_profile_aes128_cm_sha1_80:
3132 return 14;
3133 break;
3134 case srtp_profile_aes128_cm_sha1_32:
3135 return 14;
3136 break;
3137 case srtp_profile_null_sha1_80:
3138 return 14;
3139 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003140 case srtp_profile_aes256_cm_sha1_80:
3141 return 14;
3142 break;
3143 case srtp_profile_aes256_cm_sha1_32:
3144 return 14;
3145 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003146 /* the following profiles are not (yet) supported */
3147 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003148 default:
3149 return 0; /* indicate error by returning a zero */
3150 }
3151}