blob: 8841a9ec3add0ffc75c87ae6b2ab113e37946da9 [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
Christian Oiend4e3eec2014-10-24 10:14:08 +020075const char *srtp_get_version_string ()
jfigusf62b64d2014-10-08 13:53:57 -040076{
77 /*
78 * Simply return the autotools generated string
79 */
80 return SRTP_VER_STRING;
81}
82
83unsigned int srtp_get_version ()
84{
85 unsigned int major = 0, minor = 0, micro = 0;
86 unsigned int rv = 0;
jfigusb2edbef2014-10-13 10:15:15 -040087 int parse_rv;
jfigusf62b64d2014-10-08 13:53:57 -040088
89 /*
90 * Parse the autotools generated version
91 */
jfigusb2edbef2014-10-13 10:15:15 -040092 parse_rv = sscanf(SRTP_VERSION, "%u.%u.%u", &major, &minor, &micro);
93 if (parse_rv != 3) {
94 /*
95 * We're expected to parse all 3 version levels.
96 * If not, then this must not be an official release.
97 * Return all zeros on the version
98 */
99 return (0);
100 }
jfigusf62b64d2014-10-08 13:53:57 -0400101
102 /*
103 * We allow 8 bits for the major and minor, while
104 * allowing 16 bits for the micro. 16 bits for the micro
105 * may be beneficial for a continuous delivery model
106 * in the future.
107 */
108 rv |= (major & 0xFF) << 24;
109 rv |= (minor & 0xFF) << 16;
110 rv |= micro & 0xFF;
111 return rv;
112}
Cullen Jennings235513a2005-09-21 22:51:36 +0000113
114err_status_t
115srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
116 const srtp_policy_t *p) {
117 srtp_stream_ctx_t *str;
118 err_status_t stat;
119
120 /*
121 * This function allocates the stream context, rtp and rtcp ciphers
122 * and auth functions, and key limit structure. If there is a
123 * failure during allocation, we free all previously allocated
124 * memory and return a failure code. The code could probably
125 * be improved, but it works and should be clear.
126 */
127
128 /* allocate srtp stream and set str_ptr */
129 str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));
130 if (str == NULL)
131 return err_status_alloc_fail;
132 *str_ptr = str;
133
134 /* allocate cipher */
135 stat = crypto_kernel_alloc_cipher(p->rtp.cipher_type,
136 &str->rtp_cipher,
jfigusc13c1002014-05-08 13:34:53 -0400137 p->rtp.cipher_key_len,
138 p->rtp.auth_tag_len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000139 if (stat) {
140 crypto_free(str);
141 return stat;
142 }
143
144 /* allocate auth function */
145 stat = crypto_kernel_alloc_auth(p->rtp.auth_type,
146 &str->rtp_auth,
147 p->rtp.auth_key_len,
148 p->rtp.auth_tag_len);
149 if (stat) {
150 cipher_dealloc(str->rtp_cipher);
151 crypto_free(str);
152 return stat;
153 }
154
155 /* allocate key limit structure */
Derek MacDonald17127da2006-07-12 22:22:08 +0000156 str->limit = (key_limit_ctx_t*) crypto_alloc(sizeof(key_limit_ctx_t));
Cullen Jennings235513a2005-09-21 22:51:36 +0000157 if (str->limit == NULL) {
158 auth_dealloc(str->rtp_auth);
159 cipher_dealloc(str->rtp_cipher);
160 crypto_free(str);
161 return err_status_alloc_fail;
162 }
163
164 /*
165 * ...and now the RTCP-specific initialization - first, allocate
166 * the cipher
167 */
168 stat = crypto_kernel_alloc_cipher(p->rtcp.cipher_type,
169 &str->rtcp_cipher,
jfigusc13c1002014-05-08 13:34:53 -0400170 p->rtcp.cipher_key_len,
171 p->rtcp.auth_tag_len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000172 if (stat) {
173 auth_dealloc(str->rtp_auth);
174 cipher_dealloc(str->rtp_cipher);
175 crypto_free(str->limit);
176 crypto_free(str);
177 return stat;
178 }
179
180 /* allocate auth function */
181 stat = crypto_kernel_alloc_auth(p->rtcp.auth_type,
182 &str->rtcp_auth,
183 p->rtcp.auth_key_len,
184 p->rtcp.auth_tag_len);
185 if (stat) {
186 cipher_dealloc(str->rtcp_cipher);
187 auth_dealloc(str->rtp_auth);
188 cipher_dealloc(str->rtp_cipher);
189 crypto_free(str->limit);
190 crypto_free(str);
191 return stat;
192 }
193
David McGrew79870d62007-06-15 18:17:39 +0000194 /* allocate ekt data associated with stream */
195 stat = ekt_alloc(&str->ekt, p->ekt);
196 if (stat) {
197 auth_dealloc(str->rtcp_auth);
198 cipher_dealloc(str->rtcp_cipher);
199 auth_dealloc(str->rtp_auth);
200 cipher_dealloc(str->rtp_cipher);
201 crypto_free(str->limit);
202 crypto_free(str);
203 return stat;
204 }
205
Cullen Jennings235513a2005-09-21 22:51:36 +0000206 return err_status_ok;
207}
208
209err_status_t
210srtp_stream_dealloc(srtp_t session, srtp_stream_ctx_t *stream) {
211 err_status_t status;
212
213 /*
214 * we use a conservative deallocation strategy - if any deallocation
215 * fails, then we report that fact without trying to deallocate
216 * anything else
217 */
218
219 /* deallocate cipher, if it is not the same as that in template */
David McGrewfec49dd2005-09-23 19:34:11 +0000220 if (session->stream_template
Cullen Jennings235513a2005-09-21 22:51:36 +0000221 && stream->rtp_cipher == session->stream_template->rtp_cipher) {
222 /* do nothing */
223 } else {
224 status = cipher_dealloc(stream->rtp_cipher);
225 if (status)
David McGrewfec49dd2005-09-23 19:34:11 +0000226 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000227 }
228
229 /* deallocate auth function, if it is not the same as that in template */
230 if (session->stream_template
231 && stream->rtp_auth == session->stream_template->rtp_auth) {
232 /* do nothing */
233 } else {
234 status = auth_dealloc(stream->rtp_auth);
235 if (status)
236 return status;
237 }
238
David McGrewfec49dd2005-09-23 19:34:11 +0000239 /* deallocate key usage limit, if it is not the same as that in template */
240 if (session->stream_template
241 && stream->limit == session->stream_template->limit) {
242 /* do nothing */
243 } else {
Cullen Jennings235513a2005-09-21 22:51:36 +0000244 crypto_free(stream->limit);
David McGrewfec49dd2005-09-23 19:34:11 +0000245 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000246
247 /*
248 * deallocate rtcp cipher, if it is not the same as that in
249 * template
250 */
251 if (session->stream_template
252 && stream->rtcp_cipher == session->stream_template->rtcp_cipher) {
253 /* do nothing */
254 } else {
255 status = cipher_dealloc(stream->rtcp_cipher);
256 if (status)
257 return status;
258 }
259
260 /*
261 * deallocate rtcp auth function, if it is not the same as that in
262 * template
263 */
264 if (session->stream_template
265 && stream->rtcp_auth == session->stream_template->rtcp_auth) {
266 /* do nothing */
267 } else {
268 status = auth_dealloc(stream->rtcp_auth);
269 if (status)
270 return status;
271 }
David McGrew79870d62007-06-15 18:17:39 +0000272
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000273 status = rdbx_dealloc(&stream->rtp_rdbx);
274 if (status)
275 return status;
276
David McGrew79870d62007-06-15 18:17:39 +0000277 /* DAM - need to deallocate EKT here */
jfigus8c36da22013-10-01 16:41:19 -0400278
279 /*
280 * zeroize the salt value
281 */
282 memset(stream->salt, 0, SRTP_AEAD_SALT_LEN);
283 memset(stream->c_salt, 0, SRTP_AEAD_SALT_LEN);
284
Cullen Jennings235513a2005-09-21 22:51:36 +0000285
286 /* deallocate srtp stream context */
287 crypto_free(stream);
288
289 return err_status_ok;
290}
291
292
293/*
294 * srtp_stream_clone(stream_template, new) allocates a new stream and
295 * initializes it using the cipher and auth of the stream_template
296 *
297 * the only unique data in a cloned stream is the replay database and
298 * the SSRC
299 */
300
301err_status_t
302srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
303 uint32_t ssrc,
304 srtp_stream_ctx_t **str_ptr) {
305 err_status_t status;
306 srtp_stream_ctx_t *str;
307
308 debug_print(mod_srtp, "cloning stream (SSRC: 0x%08x)", ssrc);
309
310 /* allocate srtp stream and set str_ptr */
311 str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));
312 if (str == NULL)
313 return err_status_alloc_fail;
314 *str_ptr = str;
315
316 /* set cipher and auth pointers to those of the template */
317 str->rtp_cipher = stream_template->rtp_cipher;
318 str->rtp_auth = stream_template->rtp_auth;
319 str->rtcp_cipher = stream_template->rtcp_cipher;
320 str->rtcp_auth = stream_template->rtcp_auth;
321
322 /* set key limit to point to that of the template */
323 status = key_limit_clone(stream_template->limit, &str->limit);
jfigus8c36da22013-10-01 16:41:19 -0400324 if (status) {
325 crypto_free(*str_ptr);
326 *str_ptr = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +0000327 return status;
jfigus8c36da22013-10-01 16:41:19 -0400328 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000329
330 /* initialize replay databases */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000331 status = rdbx_init(&str->rtp_rdbx,
332 rdbx_get_window_size(&stream_template->rtp_rdbx));
jfigus8c36da22013-10-01 16:41:19 -0400333 if (status) {
334 crypto_free(*str_ptr);
335 *str_ptr = NULL;
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000336 return status;
jfigus8c36da22013-10-01 16:41:19 -0400337 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000338 rdb_init(&str->rtcp_rdb);
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +0000339 str->allow_repeat_tx = stream_template->allow_repeat_tx;
Cullen Jennings235513a2005-09-21 22:51:36 +0000340
341 /* set ssrc to that provided */
342 str->ssrc = ssrc;
343
344 /* set direction and security services */
345 str->direction = stream_template->direction;
346 str->rtp_services = stream_template->rtp_services;
347 str->rtcp_services = stream_template->rtcp_services;
348
David McGrew79870d62007-06-15 18:17:39 +0000349 /* set pointer to EKT data associated with stream */
350 str->ekt = stream_template->ekt;
351
jfigus8c36da22013-10-01 16:41:19 -0400352 /* Copy the salt values */
353 memcpy(str->salt, stream_template->salt, SRTP_AEAD_SALT_LEN);
354 memcpy(str->c_salt, stream_template->c_salt, SRTP_AEAD_SALT_LEN);
355
Cullen Jennings235513a2005-09-21 22:51:36 +0000356 /* defensive coding */
357 str->next = NULL;
358
359 return err_status_ok;
360}
361
362
363/*
364 * key derivation functions, internal to libSRTP
365 *
366 * srtp_kdf_t is a key derivation context
367 *
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000368 * srtp_kdf_init(&kdf, cipher_id, k, keylen) initializes kdf to use cipher
369 * described by cipher_id, with the master key k with length in octets keylen.
Cullen Jennings235513a2005-09-21 22:51:36 +0000370 *
371 * srtp_kdf_generate(&kdf, l, kl, keylen) derives the key
372 * corresponding to label l and puts it into kl; the length
373 * of the key in octets is provided as keylen. this function
374 * should be called once for each subkey that is derived.
375 *
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000376 * srtp_kdf_clear(&kdf) zeroizes and deallocates the kdf state
Cullen Jennings235513a2005-09-21 22:51:36 +0000377 */
378
379typedef enum {
380 label_rtp_encryption = 0x00,
381 label_rtp_msg_auth = 0x01,
382 label_rtp_salt = 0x02,
383 label_rtcp_encryption = 0x03,
384 label_rtcp_msg_auth = 0x04,
385 label_rtcp_salt = 0x05
386} srtp_prf_label;
387
388
389/*
390 * srtp_kdf_t represents a key derivation function. The SRTP
391 * default KDF is the only one implemented at present.
392 */
393
394typedef struct {
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000395 cipher_t *cipher; /* cipher used for key derivation */
Cullen Jennings235513a2005-09-21 22:51:36 +0000396} srtp_kdf_t;
397
398err_status_t
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000399srtp_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 +0000400
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000401 err_status_t stat;
jfigusc13c1002014-05-08 13:34:53 -0400402 stat = crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, length, 0);
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000403 if (stat)
404 return stat;
405
jfigus7882dd92013-08-02 16:08:23 -0400406 stat = cipher_init(kdf->cipher, key);
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000407 if (stat) {
408 cipher_dealloc(kdf->cipher);
409 return stat;
410 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000411
412 return err_status_ok;
413}
414
415err_status_t
416srtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label,
Travis Cross1b8b1e72014-07-02 15:32:36 +0000417 uint8_t *key, unsigned int length) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000418
419 v128_t nonce;
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000420 err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000421
422 /* set eigth octet of nonce to <label>, set the rest of it to zero */
423 v128_set_to_zero(&nonce);
Marcus Sundberg7627bc52005-10-08 16:38:06 +0000424 nonce.v8[7] = label;
Cullen Jennings235513a2005-09-21 22:51:36 +0000425
jfigus7882dd92013-08-02 16:08:23 -0400426 status = cipher_set_iv(kdf->cipher, &nonce, direction_encrypt);
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000427 if (status)
428 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000429
430 /* generate keystream output */
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000431 octet_string_set_to_zero(key, length);
432 status = cipher_encrypt(kdf->cipher, key, &length);
433 if (status)
434 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000435
436 return err_status_ok;
437}
438
439err_status_t
440srtp_kdf_clear(srtp_kdf_t *kdf) {
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000441 err_status_t status;
442 status = cipher_dealloc(kdf->cipher);
443 if (status)
444 return status;
445 kdf->cipher = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +0000446
447 return err_status_ok;
448}
449
450/*
451 * end of key derivation functions
452 */
453
454#define MAX_SRTP_KEY_LEN 256
455
456
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000457/* Get the base key length corresponding to a given combined key+salt
458 * length for the given cipher.
459 * Assumption is that for AES-ICM a key length < 30 is Ismacryp using
460 * AES-128 and short salts; everything else uses a salt length of 14.
461 * TODO: key and salt lengths should be separate fields in the policy. */
Jonathan Lennoxe2774db2011-10-27 16:06:12 +0000462static inline int base_key_length(const cipher_type_t *cipher, int key_length)
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000463{
jfigus8c36da22013-10-01 16:41:19 -0400464 switch (cipher->id) {
465 case AES_128_ICM:
466 case AES_192_ICM:
467 case AES_256_ICM:
468 /* The legacy modes are derived from
469 * the configured key length on the policy */
470 return key_length - 14;
471 break;
472 case AES_128_GCM:
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000473 return 16;
jfigus8c36da22013-10-01 16:41:19 -0400474 break;
475 case AES_256_GCM:
476 return 32;
477 break;
478 default:
479 return key_length;
480 break;
481 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000482}
483
David McGrew576e1482006-06-09 21:47:44 +0000484err_status_t
485srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) {
486 err_status_t stat;
487 srtp_kdf_t kdf;
488 uint8_t tmp_key[MAX_SRTP_KEY_LEN];
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000489 int kdf_keylen = 30, rtp_keylen, rtcp_keylen;
490 int rtp_base_key_len, rtp_salt_len;
491 int rtcp_base_key_len, rtcp_salt_len;
492
493 /* If RTP or RTCP have a key length > AES-128, assume matching kdf. */
494 /* TODO: kdf algorithm, master key length, and master salt length should
495 * be part of srtp_policy_t. */
496 rtp_keylen = cipher_get_key_length(srtp->rtp_cipher);
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000497 rtcp_keylen = cipher_get_key_length(srtp->rtcp_cipher);
jfigus8719f952014-04-08 09:15:49 -0400498 rtp_base_key_len = base_key_length(srtp->rtp_cipher->type, rtp_keylen);
499 rtp_salt_len = rtp_keylen - rtp_base_key_len;
500
501 if (rtp_keylen > kdf_keylen) {
502 kdf_keylen = 46; /* AES-CTR mode is always used for KDF */
503 }
504
505 if (rtcp_keylen > kdf_keylen) {
506 kdf_keylen = 46; /* AES-CTR mode is always used for KDF */
507 }
508
jfigus8c36da22013-10-01 16:41:19 -0400509 debug_print(mod_srtp, "srtp key len: %d", rtp_keylen);
510 debug_print(mod_srtp, "srtcp key len: %d", rtcp_keylen);
jfigus8719f952014-04-08 09:15:49 -0400511 debug_print(mod_srtp, "base key len: %d", rtp_base_key_len);
512 debug_print(mod_srtp, "kdf key len: %d", kdf_keylen);
513 debug_print(mod_srtp, "rtp salt len: %d", rtp_salt_len);
514
515 /*
516 * Make sure the key given to us is 'zero' appended. GCM
517 * mode uses a shorter master SALT (96 bits), but still relies on
518 * the legacy CTR mode KDF, which uses a 112 bit master SALT.
519 */
520 memset(tmp_key, 0x0, MAX_SRTP_KEY_LEN);
521 memcpy(tmp_key, key, (rtp_base_key_len + rtp_salt_len));
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000522
David McGrew576e1482006-06-09 21:47:44 +0000523 /* initialize KDF state */
jfigus8719f952014-04-08 09:15:49 -0400524 stat = srtp_kdf_init(&kdf, AES_ICM, (const uint8_t *)tmp_key, kdf_keylen);
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000525 if (stat) {
526 return err_status_init_fail;
527 }
David McGrew576e1482006-06-09 21:47:44 +0000528
529 /* generate encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000530 stat = srtp_kdf_generate(&kdf, label_rtp_encryption,
531 tmp_key, rtp_base_key_len);
532 if (stat) {
533 /* zeroize temp buffer */
534 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
535 return err_status_init_fail;
536 }
jfigus8719f952014-04-08 09:15:49 -0400537 debug_print(mod_srtp, "cipher key: %s",
538 octet_string_hex_string(tmp_key, rtp_base_key_len));
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000539
David McGrew576e1482006-06-09 21:47:44 +0000540 /*
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000541 * if the cipher in the srtp context uses a salt, then we need
David McGrew576e1482006-06-09 21:47:44 +0000542 * to generate the salt value
543 */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000544 if (rtp_salt_len > 0) {
545 debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL);
David McGrew576e1482006-06-09 21:47:44 +0000546
547 /* generate encryption salt, put after encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000548 stat = srtp_kdf_generate(&kdf, label_rtp_salt,
549 tmp_key + rtp_base_key_len, rtp_salt_len);
550 if (stat) {
551 /* zeroize temp buffer */
552 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
553 return err_status_init_fail;
554 }
jfigus8c36da22013-10-01 16:41:19 -0400555 memcpy(srtp->salt, tmp_key + rtp_base_key_len, SRTP_AEAD_SALT_LEN);
David McGrew576e1482006-06-09 21:47:44 +0000556 }
Jonathan Lennoxc0f1f1b2012-04-26 23:16:00 +0000557 if (rtp_salt_len > 0) {
558 debug_print(mod_srtp, "cipher salt: %s",
559 octet_string_hex_string(tmp_key + rtp_base_key_len, rtp_salt_len));
560 }
David McGrew576e1482006-06-09 21:47:44 +0000561
562 /* initialize cipher */
jfigus7882dd92013-08-02 16:08:23 -0400563 stat = cipher_init(srtp->rtp_cipher, tmp_key);
David McGrew576e1482006-06-09 21:47:44 +0000564 if (stat) {
565 /* zeroize temp buffer */
566 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
567 return err_status_init_fail;
568 }
569
570 /* generate authentication key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000571 stat = srtp_kdf_generate(&kdf, label_rtp_msg_auth,
572 tmp_key, auth_get_key_length(srtp->rtp_auth));
573 if (stat) {
574 /* zeroize temp buffer */
575 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
576 return err_status_init_fail;
577 }
David McGrew576e1482006-06-09 21:47:44 +0000578 debug_print(mod_srtp, "auth key: %s",
579 octet_string_hex_string(tmp_key,
580 auth_get_key_length(srtp->rtp_auth)));
581
582 /* initialize auth function */
583 stat = auth_init(srtp->rtp_auth, tmp_key);
584 if (stat) {
585 /* zeroize temp buffer */
586 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
587 return err_status_init_fail;
588 }
589
590 /*
591 * ...now initialize SRTCP keys
592 */
593
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000594 rtcp_base_key_len = base_key_length(srtp->rtcp_cipher->type, rtcp_keylen);
595 rtcp_salt_len = rtcp_keylen - rtcp_base_key_len;
jfigus8c36da22013-10-01 16:41:19 -0400596 debug_print(mod_srtp, "rtcp salt len: %d", rtcp_salt_len);
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000597
David McGrew576e1482006-06-09 21:47:44 +0000598 /* generate encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000599 stat = srtp_kdf_generate(&kdf, label_rtcp_encryption,
600 tmp_key, rtcp_base_key_len);
601 if (stat) {
602 /* zeroize temp buffer */
603 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
604 return err_status_init_fail;
605 }
606
David McGrew576e1482006-06-09 21:47:44 +0000607 /*
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000608 * if the cipher in the srtp context uses a salt, then we need
David McGrew576e1482006-06-09 21:47:44 +0000609 * to generate the salt value
610 */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000611 if (rtcp_salt_len > 0) {
612 debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt",
613 NULL);
David McGrew576e1482006-06-09 21:47:44 +0000614
615 /* generate encryption salt, put after encryption key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000616 stat = srtp_kdf_generate(&kdf, label_rtcp_salt,
617 tmp_key + rtcp_base_key_len, rtcp_salt_len);
618 if (stat) {
619 /* zeroize temp buffer */
620 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
621 return err_status_init_fail;
622 }
jfigus8c36da22013-10-01 16:41:19 -0400623 memcpy(srtp->c_salt, tmp_key + rtcp_base_key_len, SRTP_AEAD_SALT_LEN);
David McGrew576e1482006-06-09 21:47:44 +0000624 }
625 debug_print(mod_srtp, "rtcp cipher key: %s",
Jonathan Lennoxc0f1f1b2012-04-26 23:16:00 +0000626 octet_string_hex_string(tmp_key, rtcp_base_key_len));
627 if (rtcp_salt_len > 0) {
628 debug_print(mod_srtp, "rtcp cipher salt: %s",
629 octet_string_hex_string(tmp_key + rtcp_base_key_len, rtcp_salt_len));
630 }
David McGrew576e1482006-06-09 21:47:44 +0000631
632 /* initialize cipher */
jfigus7882dd92013-08-02 16:08:23 -0400633 stat = cipher_init(srtp->rtcp_cipher, tmp_key);
David McGrew576e1482006-06-09 21:47:44 +0000634 if (stat) {
635 /* zeroize temp buffer */
636 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
637 return err_status_init_fail;
638 }
639
640 /* generate authentication key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000641 stat = srtp_kdf_generate(&kdf, label_rtcp_msg_auth,
642 tmp_key, auth_get_key_length(srtp->rtcp_auth));
643 if (stat) {
644 /* zeroize temp buffer */
645 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
646 return err_status_init_fail;
647 }
648
David McGrew576e1482006-06-09 21:47:44 +0000649 debug_print(mod_srtp, "rtcp auth key: %s",
650 octet_string_hex_string(tmp_key,
651 auth_get_key_length(srtp->rtcp_auth)));
652
653 /* initialize auth function */
654 stat = auth_init(srtp->rtcp_auth, tmp_key);
655 if (stat) {
656 /* zeroize temp buffer */
657 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
658 return err_status_init_fail;
659 }
660
661 /* clear memory then return */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000662 stat = srtp_kdf_clear(&kdf);
David McGrew576e1482006-06-09 21:47:44 +0000663 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000664 if (stat)
665 return err_status_init_fail;
David McGrew576e1482006-06-09 21:47:44 +0000666
667 return err_status_ok;
668}
Cullen Jennings235513a2005-09-21 22:51:36 +0000669
670err_status_t
671srtp_stream_init(srtp_stream_ctx_t *srtp,
672 const srtp_policy_t *p) {
David McGrew576e1482006-06-09 21:47:44 +0000673 err_status_t err;
Cullen Jennings235513a2005-09-21 22:51:36 +0000674
675 debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)",
676 p->ssrc.value);
677
678 /* initialize replay database */
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000679 /* window size MUST be at least 64. MAY be larger. Values more than
680 * 2^15 aren't meaningful due to how extended sequence numbers are
681 * calculated. Let a window size of 0 imply the default value. */
682
683 if (p->window_size != 0 && (p->window_size < 64 || p->window_size >= 0x8000))
684 return err_status_bad_param;
685
686 if (p->window_size != 0)
687 err = rdbx_init(&srtp->rtp_rdbx, p->window_size);
688 else
689 err = rdbx_init(&srtp->rtp_rdbx, 128);
690 if (err) return err;
Cullen Jennings235513a2005-09-21 22:51:36 +0000691
692 /* initialize key limit to maximum value */
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000693#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +0000694{
Marcus Sundberge4e34f92005-10-02 20:19:35 +0000695 uint64_t temp;
696 temp = make64(UINT_MAX,UINT_MAX);
697 key_limit_set(srtp->limit, temp);
Cullen Jennings235513a2005-09-21 22:51:36 +0000698}
699#else
700 key_limit_set(srtp->limit, 0xffffffffffffLL);
701#endif
702
703 /* set the SSRC value */
704 srtp->ssrc = htonl(p->ssrc.value);
705
706 /* set the security service flags */
707 srtp->rtp_services = p->rtp.sec_serv;
708 srtp->rtcp_services = p->rtcp.sec_serv;
709
710 /*
711 * set direction to unknown - this flag gets checked in srtp_protect(),
712 * srtp_unprotect(), srtp_protect_rtcp(), and srtp_unprotect_rtcp(), and
713 * gets set appropriately if it is set to unknown.
714 */
715 srtp->direction = dir_unknown;
716
David McGrew576e1482006-06-09 21:47:44 +0000717 /* initialize SRTCP replay database */
Cullen Jennings235513a2005-09-21 22:51:36 +0000718 rdb_init(&srtp->rtcp_rdb);
719
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +0000720 /* initialize allow_repeat_tx */
721 /* guard against uninitialized memory: allow only 0 or 1 here */
722 if (p->allow_repeat_tx != 0 && p->allow_repeat_tx != 1) {
723 rdbx_dealloc(&srtp->rtp_rdbx);
724 return err_status_bad_param;
725 }
726 srtp->allow_repeat_tx = p->allow_repeat_tx;
727
Cullen Jennings235513a2005-09-21 22:51:36 +0000728 /* DAM - no RTCP key limit at present */
729
David McGrew576e1482006-06-09 21:47:44 +0000730 /* initialize keys */
731 err = srtp_stream_init_keys(srtp, p->key);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000732 if (err) {
733 rdbx_dealloc(&srtp->rtp_rdbx);
734 return err;
735 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000736
David McGrew79870d62007-06-15 18:17:39 +0000737 /*
738 * if EKT is in use, then initialize the EKT data associated with
739 * the stream
740 */
741 err = ekt_stream_init_from_policy(srtp->ekt, p->ekt);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000742 if (err) {
743 rdbx_dealloc(&srtp->rtp_rdbx);
744 return err;
745 }
David McGrew79870d62007-06-15 18:17:39 +0000746
Cullen Jennings235513a2005-09-21 22:51:36 +0000747 return err_status_ok;
748 }
749
750
751 /*
752 * srtp_event_reporter is an event handler function that merely
753 * reports the events that are reported by the callbacks
754 */
755
756 void
757 srtp_event_reporter(srtp_event_data_t *data) {
758
759 err_report(err_level_warning, "srtp: in stream 0x%x: ",
760 data->stream->ssrc);
761
762 switch(data->event) {
763 case event_ssrc_collision:
764 err_report(err_level_warning, "\tSSRC collision\n");
765 break;
766 case event_key_soft_limit:
767 err_report(err_level_warning, "\tkey usage soft limit reached\n");
768 break;
769 case event_key_hard_limit:
770 err_report(err_level_warning, "\tkey usage hard limit reached\n");
771 break;
772 case event_packet_index_limit:
773 err_report(err_level_warning, "\tpacket index limit reached\n");
774 break;
775 default:
776 err_report(err_level_warning, "\tunknown event reported to handler\n");
777 }
778 }
779
780 /*
781 * srtp_event_handler is a global variable holding a pointer to the
782 * event handler function; this function is called for any unexpected
783 * event that needs to be handled out of the SRTP data path. see
784 * srtp_event_t in srtp.h for more info
785 *
786 * it is okay to set srtp_event_handler to NULL, but we set
787 * it to the srtp_event_reporter.
788 */
789
790 static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter;
791
792 err_status_t
793 srtp_install_event_handler(srtp_event_handler_func_t func) {
794
795 /*
796 * note that we accept NULL arguments intentionally - calling this
797 * function with a NULL arguments removes an event handler that's
798 * been previously installed
799 */
800
801 /* set global event handling function */
802 srtp_event_handler = func;
803 return err_status_ok;
804 }
805
jfigus8c36da22013-10-01 16:41:19 -0400806/*
807 * AEAD uses a new IV formation method. This function implements
808 * section 9.1 from draft-ietf-avtcore-srtp-aes-gcm-07.txt. The
809 * calculation is defined as, where (+) is the xor operation:
810 *
811 *
812 * 0 0 0 0 0 0 0 0 0 0 1 1
813 * 0 1 2 3 4 5 6 7 8 9 0 1
814 * +--+--+--+--+--+--+--+--+--+--+--+--+
815 * |00|00| SSRC | ROC | SEQ |---+
816 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
817 * |
818 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
819 * | Encryption Salt |->(+)
820 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
821 * |
822 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
823 * | Initialization Vector |<--+
824 * +--+--+--+--+--+--+--+--+--+--+--+--+*
825 *
826 * Input: *stream - pointer to SRTP stream context, used to retrieve
827 * the SALT
828 * *iv - Pointer to receive the calculated IV
829 * *seq - The ROC and SEQ value to use for the
830 * IV calculation.
831 * *hdr - The RTP header, used to get the SSRC value
832 *
833 */
834static void srtp_calc_aead_iv(srtp_stream_ctx_t *stream, v128_t *iv,
835 xtd_seq_num_t *seq, srtp_hdr_t *hdr)
836{
837 v128_t in;
838 v128_t salt;
Dmitry Sobinov367d5d32014-03-27 22:36:32 +0700839
840#ifdef NO_64BIT_MATH
841 uint32_t local_roc = ((high32(*seq) << 16) |
842 (low32(*seq) >> 16));
843 uint16_t local_seq = (uint16_t) (low32(*seq));
844#else
845 uint32_t local_roc = (uint32_t)(*seq >> 16);
846 uint16_t local_seq = (uint16_t) *seq;
847#endif
jfigus8c36da22013-10-01 16:41:19 -0400848
849 memset(&in, 0, sizeof(v128_t));
850 memset(&salt, 0, sizeof(v128_t));
851
Dmitry Sobinov367d5d32014-03-27 22:36:32 +0700852 in.v16[5] = htons(local_seq);
853 local_roc = htonl(local_roc);
854 memcpy(&in.v16[3], &local_roc, sizeof(local_roc));
jfigus8c36da22013-10-01 16:41:19 -0400855
856 /*
857 * Copy in the RTP SSRC value
858 */
859 memcpy(&in.v8[2], &hdr->ssrc, 4);
860 debug_print(mod_srtp, "Pre-salted RTP IV = %s\n", v128_hex_string(&in));
861
862 /*
863 * Get the SALT value from the context
864 */
865 memcpy(salt.v8, stream->salt, SRTP_AEAD_SALT_LEN);
866 debug_print(mod_srtp, "RTP SALT = %s\n", v128_hex_string(&salt));
867
868 /*
869 * Finally, apply tyhe SALT to the input
870 */
871 v128_xor(iv, &in, &salt);
872}
873
874
875/*
876 * This function handles outgoing SRTP packets while in AEAD mode,
877 * which currently supports AES-GCM encryption. All packets are
878 * encrypted and authenticated.
879 */
880static err_status_t
881srtp_protect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream,
Travis Cross31844002014-07-02 16:18:57 +0000882 void *rtp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -0400883{
884 srtp_hdr_t *hdr = (srtp_hdr_t*)rtp_hdr;
885 uint32_t *enc_start; /* pointer to start of encrypted portion */
Travis Cross1b8b1e72014-07-02 15:32:36 +0000886 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -0400887 xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
888 int delta; /* delta of local pkt idx and that in hdr */
889 err_status_t status;
890 int tag_len;
891 v128_t iv;
892 unsigned int aad_len;
893
894 debug_print(mod_srtp, "function srtp_protect_aead", NULL);
895
896 /*
897 * update the key usage limit, and check it to make sure that we
898 * didn't just hit either the soft limit or the hard limit, and call
899 * the event handler if we hit either.
900 */
901 switch (key_limit_update(stream->limit)) {
902 case key_event_normal:
903 break;
904 case key_event_hard_limit:
905 srtp_handle_event(ctx, stream, event_key_hard_limit);
906 return err_status_key_expired;
907 case key_event_soft_limit:
908 default:
909 srtp_handle_event(ctx, stream, event_key_soft_limit);
910 break;
911 }
912
913 /* get tag length from stream */
914 tag_len = auth_get_tag_length(stream->rtp_auth);
915
916 /*
917 * find starting point for encryption and length of data to be
918 * encrypted - the encrypted portion starts after the rtp header
919 * extension, if present; otherwise, it starts after the last csrc,
920 * if any are present
jfigus8c36da22013-10-01 16:41:19 -0400921 */
Travis Cross3600c272014-06-29 17:32:33 +0000922 enc_start = (uint32_t*)hdr + uint32s_in_rtp_header + hdr->cc;
923 if (hdr->x == 1) {
924 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t*)enc_start;
925 enc_start += (ntohs(xtn_hdr->length) + 1);
926 }
Travis Cross83439f72014-07-02 14:18:46 +0000927 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
Travis Cross3600c272014-06-29 17:32:33 +0000928 return err_status_parse_err;
929 enc_octet_len = (unsigned int)(*pkt_octet_len -
Travis Crossdee3ee82014-07-02 15:20:12 +0000930 ((uint8_t*)enc_start - (uint8_t*)hdr));
jfigus8c36da22013-10-01 16:41:19 -0400931
932 /*
933 * estimate the packet index using the start of the replay window
934 * and the sequence number from the header
935 */
936 delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
937 status = rdbx_check(&stream->rtp_rdbx, delta);
938 if (status) {
939 if (status != err_status_replay_fail || !stream->allow_repeat_tx) {
940 return status; /* we've been asked to reuse an index */
941 }
942 } else {
943 rdbx_add_index(&stream->rtp_rdbx, delta);
944 }
945
946#ifdef NO_64BIT_MATH
947 debug_print2(mod_srtp, "estimated packet index: %08x%08x",
948 high32(est), low32(est));
949#else
950 debug_print(mod_srtp, "estimated packet index: %016llx", est);
951#endif
952
953 /*
954 * AEAD uses a new IV formation method
955 */
956 srtp_calc_aead_iv(stream, &iv, &est, hdr);
957 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt);
958 if (status) {
959 return err_status_cipher_fail;
960 }
961
962 /* shift est, put into network byte order */
963#ifdef NO_64BIT_MATH
964 est = be64_to_cpu(make64((high32(est) << 16) |
965 (low32(est) >> 16),
966 low32(est) << 16));
967#else
968 est = be64_to_cpu(est << 16);
969#endif
970
971 /*
972 * Set the AAD over the RTP header
973 */
974 aad_len = (uint8_t *)enc_start - (uint8_t *)hdr;
975 status = cipher_set_aad(stream->rtp_cipher, (uint8_t*)hdr, aad_len);
976 if (status) {
977 return ( err_status_cipher_fail);
978 }
979
980 /* Encrypt the payload */
981 status = cipher_encrypt(stream->rtp_cipher,
982 (uint8_t*)enc_start, &enc_octet_len);
983 if (status) {
984 return err_status_cipher_fail;
985 }
986 /*
987 * If we're doing GCM, we need to get the tag
988 * and append that to the output
989 */
990 status = cipher_get_tag(stream->rtp_cipher,
991 (uint8_t*)enc_start+enc_octet_len, &tag_len);
992 if (status) {
993 return ( err_status_cipher_fail);
994 }
995 enc_octet_len += tag_len;
996
997 /* increase the packet length by the length of the auth tag */
998 *pkt_octet_len += tag_len;
999
1000 return err_status_ok;
1001}
1002
1003
1004/*
1005 * This function handles incoming SRTP packets while in AEAD mode,
1006 * which currently supports AES-GCM encryption. All packets are
1007 * encrypted and authenticated. Note, the auth tag is at the end
1008 * of the packet stream and is automatically checked by GCM
1009 * when decrypting the payload.
1010 */
1011static err_status_t
1012srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
Travis Cross31844002014-07-02 16:18:57 +00001013 xtd_seq_num_t est, void *srtp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -04001014{
1015 srtp_hdr_t *hdr = (srtp_hdr_t*)srtp_hdr;
1016 uint32_t *enc_start; /* pointer to start of encrypted portion */
Travis Cross1b8b1e72014-07-02 15:32:36 +00001017 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -04001018 v128_t iv;
1019 err_status_t status;
1020 int tag_len;
1021 unsigned int aad_len;
1022
1023 debug_print(mod_srtp, "function srtp_unprotect_aead", NULL);
1024
1025#ifdef NO_64BIT_MATH
1026 debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est), low32(est));
1027#else
1028 debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
1029#endif
1030
1031 /* get tag length from stream */
1032 tag_len = auth_get_tag_length(stream->rtp_auth);
1033
1034 /*
1035 * AEAD uses a new IV formation method
1036 */
1037 srtp_calc_aead_iv(stream, &iv, &est, hdr);
1038 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt);
1039 if (status) {
1040 return err_status_cipher_fail;
1041 }
1042
1043 /*
1044 * find starting point for decryption and length of data to be
1045 * decrypted - the encrypted portion starts after the rtp header
1046 * extension, if present; otherwise, it starts after the last csrc,
1047 * if any are present
1048 */
1049 enc_start = (uint32_t*)hdr + uint32s_in_rtp_header + hdr->cc;
1050 if (hdr->x == 1) {
1051 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t*)enc_start;
1052 enc_start += (ntohs(xtn_hdr->length) + 1);
1053 }
Travis Cross83439f72014-07-02 14:18:46 +00001054 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
Travis Crossfe367612014-06-29 01:10:29 +00001055 return err_status_parse_err;
jfigus8c36da22013-10-01 16:41:19 -04001056 /*
1057 * We pass the tag down to the cipher when doing GCM mode
1058 */
Travis Cross7d4c1032014-07-02 14:46:53 +00001059 enc_octet_len = (unsigned int)(*pkt_octet_len -
Travis Crossdee3ee82014-07-02 15:20:12 +00001060 ((uint8_t*)enc_start - (uint8_t*)hdr));
jfigus8c36da22013-10-01 16:41:19 -04001061
1062 /*
jfigusc13c1002014-05-08 13:34:53 -04001063 * Sanity check the encrypted payload length against
1064 * the tag size. It must always be at least as large
1065 * as the tag length.
1066 */
1067 if (enc_octet_len < tag_len) {
1068 return err_status_cipher_fail;
1069 }
1070
1071 /*
jfigus8c36da22013-10-01 16:41:19 -04001072 * update the key usage limit, and check it to make sure that we
1073 * didn't just hit either the soft limit or the hard limit, and call
1074 * the event handler if we hit either.
1075 */
1076 switch (key_limit_update(stream->limit)) {
1077 case key_event_normal:
1078 break;
1079 case key_event_soft_limit:
1080 srtp_handle_event(ctx, stream, event_key_soft_limit);
1081 break;
1082 case key_event_hard_limit:
1083 srtp_handle_event(ctx, stream, event_key_hard_limit);
1084 return err_status_key_expired;
1085 default:
1086 break;
1087 }
1088
1089 /*
1090 * Set the AAD for AES-GCM, which is the RTP header
1091 */
1092 aad_len = (uint8_t *)enc_start - (uint8_t *)hdr;
1093 status = cipher_set_aad(stream->rtp_cipher, (uint8_t*)hdr, aad_len);
1094 if (status) {
1095 return ( err_status_cipher_fail);
1096 }
1097
1098 /* Decrypt the ciphertext. This also checks the auth tag based
1099 * on the AAD we just specified above */
1100 status = cipher_decrypt(stream->rtp_cipher,
1101 (uint8_t*)enc_start, &enc_octet_len);
1102 if (status) {
1103 return status;
1104 }
1105
1106 /*
1107 * verify that stream is for received traffic - this check will
1108 * detect SSRC collisions, since a stream that appears in both
1109 * srtp_protect() and srtp_unprotect() will fail this test in one of
1110 * those functions.
1111 *
1112 * we do this check *after* the authentication check, so that the
1113 * latter check will catch any attempts to fool us into thinking
1114 * that we've got a collision
1115 */
1116 if (stream->direction != dir_srtp_receiver) {
1117 if (stream->direction == dir_unknown) {
1118 stream->direction = dir_srtp_receiver;
1119 } else {
1120 srtp_handle_event(ctx, stream, event_ssrc_collision);
1121 }
1122 }
1123
1124 /*
1125 * if the stream is a 'provisional' one, in which the template context
1126 * is used, then we need to allocate a new stream at this point, since
1127 * the authentication passed
1128 */
1129 if (stream == ctx->stream_template) {
1130 srtp_stream_ctx_t *new_stream;
1131
1132 /*
1133 * allocate and initialize a new stream
1134 *
1135 * note that we indicate failure if we can't allocate the new
1136 * stream, and some implementations will want to not return
1137 * failure here
1138 */
1139 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
1140 if (status) {
1141 return status;
1142 }
1143
1144 /* add new stream to the head of the stream_list */
1145 new_stream->next = ctx->stream_list;
1146 ctx->stream_list = new_stream;
1147
1148 /* set stream (the pointer used in this function) */
1149 stream = new_stream;
1150 }
1151
1152 /*
1153 * the message authentication function passed, so add the packet
1154 * index into the replay database
1155 */
1156 rdbx_add_index(&stream->rtp_rdbx, delta);
1157
1158 /* decrease the packet length by the length of the auth tag */
1159 *pkt_octet_len -= tag_len;
1160
1161 return err_status_ok;
1162}
1163
1164
1165
1166
Cullen Jennings235513a2005-09-21 22:51:36 +00001167 err_status_t
1168 srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00001169 srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00001170 uint32_t *enc_start; /* pointer to start of encrypted portion */
1171 uint32_t *auth_start; /* pointer to start of auth. portion */
Travis Cross1b8b1e72014-07-02 15:32:36 +00001172 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
Cullen Jennings235513a2005-09-21 22:51:36 +00001173 xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
1174 int delta; /* delta of local pkt idx and that in hdr */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001175 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
Cullen Jennings235513a2005-09-21 22:51:36 +00001176 err_status_t status;
1177 int tag_len;
1178 srtp_stream_ctx_t *stream;
1179 int prefix_len;
1180
1181 debug_print(mod_srtp, "function srtp_protect", NULL);
1182
1183 /* we assume the hdr is 32-bit aligned to start */
1184
1185 /* check the packet length - it must at least contain a full header */
1186 if (*pkt_octet_len < octets_in_rtp_header)
1187 return err_status_bad_param;
1188
1189 /*
1190 * look up ssrc in srtp_stream list, and process the packet with
1191 * the appropriate stream. if we haven't seen this stream before,
1192 * there's a template key for this srtp_session, and the cipher
1193 * supports key-sharing, then we assume that a new stream using
1194 * that key has just started up
1195 */
1196 stream = srtp_get_stream(ctx, hdr->ssrc);
1197 if (stream == NULL) {
1198 if (ctx->stream_template != NULL) {
1199 srtp_stream_ctx_t *new_stream;
1200
1201 /* allocate and initialize a new stream */
1202 status = srtp_stream_clone(ctx->stream_template,
David McGrewfec49dd2005-09-23 19:34:11 +00001203 hdr->ssrc, &new_stream);
Cullen Jennings235513a2005-09-21 22:51:36 +00001204 if (status)
1205 return status;
1206
1207 /* add new stream to the head of the stream_list */
1208 new_stream->next = ctx->stream_list;
1209 ctx->stream_list = new_stream;
1210
1211 /* set direction to outbound */
1212 new_stream->direction = dir_srtp_sender;
1213
1214 /* set stream (the pointer used in this function) */
1215 stream = new_stream;
1216 } else {
1217 /* no template stream, so we return an error */
1218 return err_status_no_ctx;
1219 }
1220 }
1221
1222 /*
1223 * verify that stream is for sending traffic - this check will
1224 * detect SSRC collisions, since a stream that appears in both
1225 * srtp_protect() and srtp_unprotect() will fail this test in one of
1226 * those functions.
1227 */
jfigus8c36da22013-10-01 16:41:19 -04001228 if (stream->direction != dir_srtp_sender) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001229 if (stream->direction == dir_unknown) {
1230 stream->direction = dir_srtp_sender;
1231 } else {
1232 srtp_handle_event(ctx, stream, event_ssrc_collision);
1233 }
jfigus8c36da22013-10-01 16:41:19 -04001234 }
1235
1236 /*
1237 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
1238 * the request to our AEAD handler.
1239 */
1240 if (stream->rtp_cipher->algorithm == AES_128_GCM ||
1241 stream->rtp_cipher->algorithm == AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00001242 return srtp_protect_aead(ctx, stream, rtp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04001243 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001244
1245 /*
1246 * update the key usage limit, and check it to make sure that we
1247 * didn't just hit either the soft limit or the hard limit, and call
1248 * the event handler if we hit either.
1249 */
1250 switch(key_limit_update(stream->limit)) {
1251 case key_event_normal:
1252 break;
1253 case key_event_soft_limit:
1254 srtp_handle_event(ctx, stream, event_key_soft_limit);
1255 break;
1256 case key_event_hard_limit:
1257 srtp_handle_event(ctx, stream, event_key_hard_limit);
David McGrewfec49dd2005-09-23 19:34:11 +00001258 return err_status_key_expired;
Cullen Jennings235513a2005-09-21 22:51:36 +00001259 default:
1260 break;
1261 }
1262
1263 /* get tag length from stream */
1264 tag_len = auth_get_tag_length(stream->rtp_auth);
1265
1266 /*
1267 * find starting point for encryption and length of data to be
1268 * encrypted - the encrypted portion starts after the rtp header
1269 * extension, if present; otherwise, it starts after the last csrc,
1270 * if any are present
1271 *
1272 * if we're not providing confidentiality, set enc_start to NULL
1273 */
1274 if (stream->rtp_services & sec_serv_conf) {
1275 enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
David McGrew14829302005-10-10 18:53:19 +00001276 if (hdr->x == 1) {
1277 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
1278 enc_start += (ntohs(xtn_hdr->length) + 1);
Travis Cross83439f72014-07-02 14:18:46 +00001279 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
Travis Crossfe367612014-06-29 01:10:29 +00001280 return err_status_parse_err;
David McGrew14829302005-10-10 18:53:19 +00001281 }
Travis Crossdee3ee82014-07-02 15:20:12 +00001282 enc_octet_len = (unsigned int)(*pkt_octet_len -
1283 ((uint8_t*)enc_start - (uint8_t*)hdr));
Cullen Jennings235513a2005-09-21 22:51:36 +00001284 } else {
1285 enc_start = NULL;
1286 }
1287
1288 /*
1289 * if we're providing authentication, set the auth_start and auth_tag
1290 * pointers to the proper locations; otherwise, set auth_start to NULL
1291 * to indicate that no authentication is needed
1292 */
1293 if (stream->rtp_services & sec_serv_auth) {
1294 auth_start = (uint32_t *)hdr;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001295 auth_tag = (uint8_t *)hdr + *pkt_octet_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00001296 } else {
1297 auth_start = NULL;
1298 auth_tag = NULL;
1299 }
1300
1301 /*
1302 * estimate the packet index using the start of the replay window
1303 * and the sequence number from the header
1304 */
1305 delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
1306 status = rdbx_check(&stream->rtp_rdbx, delta);
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001307 if (status) {
1308 if (status != err_status_replay_fail || !stream->allow_repeat_tx)
1309 return status; /* we've been asked to reuse an index */
1310 }
1311 else
1312 rdbx_add_index(&stream->rtp_rdbx, delta);
Cullen Jennings235513a2005-09-21 22:51:36 +00001313
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001314#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001315 debug_print2(mod_srtp, "estimated packet index: %08x%08x",
1316 high32(est),low32(est));
1317#else
1318 debug_print(mod_srtp, "estimated packet index: %016llx", est);
1319#endif
1320
1321 /*
1322 * if we're using rindael counter mode, set nonce and seq
1323 */
jfigus8c36da22013-10-01 16:41:19 -04001324 if (stream->rtp_cipher->type->id == AES_ICM ||
1325 stream->rtp_cipher->type->id == AES_256_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001326 v128_t iv;
1327
1328 iv.v32[0] = 0;
1329 iv.v32[1] = hdr->ssrc;
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001330#ifdef NO_64BIT_MATH
1331 iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
David McGrewfec49dd2005-09-23 19:34:11 +00001332 low32(est) << 16));
Cullen Jennings235513a2005-09-21 22:51:36 +00001333#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001334 iv.v64[1] = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001335#endif
jfigus7882dd92013-08-02 16:08:23 -04001336 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001337
1338 } else {
1339 v128_t iv;
1340
1341 /* otherwise, set the index to est */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001342#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001343 iv.v32[0] = 0;
1344 iv.v32[1] = 0;
1345#else
1346 iv.v64[0] = 0;
1347#endif
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001348 iv.v64[1] = be64_to_cpu(est);
jfigus7882dd92013-08-02 16:08:23 -04001349 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001350 }
1351 if (status)
1352 return err_status_cipher_fail;
1353
1354 /* shift est, put into network byte order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001355#ifdef NO_64BIT_MATH
1356 est = be64_to_cpu(make64((high32(est) << 16) |
Cullen Jennings235513a2005-09-21 22:51:36 +00001357 (low32(est) >> 16),
Randell Jesup811e1442005-09-28 22:43:41 +00001358 low32(est) << 16));
Cullen Jennings235513a2005-09-21 22:51:36 +00001359#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001360 est = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001361#endif
1362
1363 /*
1364 * if we're authenticating using a universal hash, put the keystream
1365 * prefix into the authentication tag
1366 */
1367 if (auth_start) {
1368
1369 prefix_len = auth_get_prefix_length(stream->rtp_auth);
1370 if (prefix_len) {
1371 status = cipher_output(stream->rtp_cipher, auth_tag, prefix_len);
1372 if (status)
1373 return err_status_cipher_fail;
1374 debug_print(mod_srtp, "keystream prefix: %s",
1375 octet_string_hex_string(auth_tag, prefix_len));
1376 }
1377 }
1378
1379 /* if we're encrypting, exor keystream into the message */
1380 if (enc_start) {
1381 status = cipher_encrypt(stream->rtp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001382 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001383 if (status)
1384 return err_status_cipher_fail;
1385 }
1386
1387 /*
1388 * if we're authenticating, run authentication function and put result
1389 * into the auth_tag
1390 */
1391 if (auth_start) {
1392
1393 /* initialize auth func context */
1394 status = auth_start(stream->rtp_auth);
1395 if (status) return status;
1396
1397 /* run auth func over packet */
1398 status = auth_update(stream->rtp_auth,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001399 (uint8_t *)auth_start, *pkt_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001400 if (status) return status;
1401
1402 /* run auth func over ROC, put result into auth_tag */
David McGrew89fb7ea2005-09-26 19:33:44 +00001403 debug_print(mod_srtp, "estimated packet index: %016llx", est);
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001404 status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00001405 debug_print(mod_srtp, "srtp auth tag: %s",
1406 octet_string_hex_string(auth_tag, tag_len));
1407 if (status)
1408 return err_status_auth_fail;
1409
1410 }
1411
1412 if (auth_tag) {
1413
1414 /* increase the packet length by the length of the auth tag */
1415 *pkt_octet_len += tag_len;
1416 }
1417
1418 return err_status_ok;
1419}
1420
1421
1422err_status_t
1423srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00001424 srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00001425 uint32_t *enc_start; /* pointer to start of encrypted portion */
1426 uint32_t *auth_start; /* pointer to start of auth. portion */
Travis Cross1b8b1e72014-07-02 15:32:36 +00001427 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001428 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
Cullen Jennings235513a2005-09-21 22:51:36 +00001429 xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
1430 int delta; /* delta of local pkt idx and that in hdr */
1431 v128_t iv;
1432 err_status_t status;
1433 srtp_stream_ctx_t *stream;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001434 uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
Cullen Jennings235513a2005-09-21 22:51:36 +00001435 int tag_len, prefix_len;
1436
1437 debug_print(mod_srtp, "function srtp_unprotect", NULL);
1438
1439 /* we assume the hdr is 32-bit aligned to start */
1440
1441 /* check the packet length - it must at least contain a full header */
1442 if (*pkt_octet_len < octets_in_rtp_header)
1443 return err_status_bad_param;
1444
1445 /*
1446 * look up ssrc in srtp_stream list, and process the packet with
1447 * the appropriate stream. if we haven't seen this stream before,
1448 * there's only one key for this srtp_session, and the cipher
1449 * supports key-sharing, then we assume that a new stream using
1450 * that key has just started up
1451 */
1452 stream = srtp_get_stream(ctx, hdr->ssrc);
1453 if (stream == NULL) {
1454 if (ctx->stream_template != NULL) {
1455 stream = ctx->stream_template;
1456 debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)",
1457 hdr->ssrc);
1458
1459 /*
1460 * set estimated packet index to sequence number from header,
1461 * and set delta equal to the same value
1462 */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001463#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001464 est = (xtd_seq_num_t) make64(0,ntohs(hdr->seq));
1465 delta = low32(est);
1466#else
1467 est = (xtd_seq_num_t) ntohs(hdr->seq);
David McGrewc4fc00b2006-06-08 18:51:27 +00001468 delta = (int)est;
Cullen Jennings235513a2005-09-21 22:51:36 +00001469#endif
1470 } else {
1471
1472 /*
1473 * no stream corresponding to SSRC found, and we don't do
1474 * key-sharing, so return an error
1475 */
1476 return err_status_no_ctx;
1477 }
1478 } else {
1479
1480 /* estimate packet index from seq. num. in header */
1481 delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001482
1483 /* check replay database */
1484 status = rdbx_check(&stream->rtp_rdbx, delta);
1485 if (status)
1486 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001487 }
1488
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001489#ifdef NO_64BIT_MATH
David McGrewfec49dd2005-09-23 19:34:11 +00001490 debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),low32(est));
1491#else
1492 debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
1493#endif
Cullen Jennings235513a2005-09-21 22:51:36 +00001494
jfigus8c36da22013-10-01 16:41:19 -04001495 /*
1496 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
1497 * the request to our AEAD handler.
1498 */
1499 if (stream->rtp_cipher->algorithm == AES_128_GCM ||
1500 stream->rtp_cipher->algorithm == AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00001501 return srtp_unprotect_aead(ctx, stream, delta, est, srtp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04001502 }
1503
Cullen Jennings235513a2005-09-21 22:51:36 +00001504 /* get tag length from stream */
1505 tag_len = auth_get_tag_length(stream->rtp_auth);
1506
1507 /*
1508 * set the cipher's IV properly, depending on whatever cipher we
1509 * happen to be using
1510 */
jfigus8c36da22013-10-01 16:41:19 -04001511 if (stream->rtp_cipher->type->id == AES_ICM ||
1512 stream->rtp_cipher->type->id == AES_256_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001513
1514 /* aes counter mode */
1515 iv.v32[0] = 0;
1516 iv.v32[1] = hdr->ssrc; /* still in network order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001517#ifdef NO_64BIT_MATH
1518 iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
Cullen Jennings235513a2005-09-21 22:51:36 +00001519 low32(est) << 16));
1520#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001521 iv.v64[1] = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001522#endif
jfigus7882dd92013-08-02 16:08:23 -04001523 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001524 } else {
1525
1526 /* no particular format - set the iv to the pakcet index */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001527#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001528 iv.v32[0] = 0;
1529 iv.v32[1] = 0;
1530#else
1531 iv.v64[0] = 0;
1532#endif
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001533 iv.v64[1] = be64_to_cpu(est);
jfigus7882dd92013-08-02 16:08:23 -04001534 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001535 }
1536 if (status)
1537 return err_status_cipher_fail;
1538
1539 /* shift est, put into network byte order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001540#ifdef NO_64BIT_MATH
1541 est = be64_to_cpu(make64((high32(est) << 16) |
Cullen Jennings235513a2005-09-21 22:51:36 +00001542 (low32(est) >> 16),
1543 low32(est) << 16));
1544#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001545 est = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001546#endif
1547
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001548 /*
1549 * find starting point for decryption and length of data to be
1550 * decrypted - the encrypted portion starts after the rtp header
1551 * extension, if present; otherwise, it starts after the last csrc,
1552 * if any are present
1553 *
1554 * if we're not providing confidentiality, set enc_start to NULL
1555 */
1556 if (stream->rtp_services & sec_serv_conf) {
1557 enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
David McGrew14829302005-10-10 18:53:19 +00001558 if (hdr->x == 1) {
1559 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
1560 enc_start += (ntohs(xtn_hdr->length) + 1);
1561 }
Travis Cross83439f72014-07-02 14:18:46 +00001562 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
Travis Crossfe367612014-06-29 01:10:29 +00001563 return err_status_parse_err;
Travis Crossdee3ee82014-07-02 15:20:12 +00001564 enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len -
1565 ((uint8_t*)enc_start - (uint8_t*)hdr));
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001566 } else {
1567 enc_start = NULL;
1568 }
1569
Cullen Jennings235513a2005-09-21 22:51:36 +00001570 /*
1571 * if we're providing authentication, set the auth_start and auth_tag
1572 * pointers to the proper locations; otherwise, set auth_start to NULL
1573 * to indicate that no authentication is needed
1574 */
1575 if (stream->rtp_services & sec_serv_auth) {
1576 auth_start = (uint32_t *)hdr;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001577 auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00001578 } else {
1579 auth_start = NULL;
1580 auth_tag = NULL;
1581 }
1582
1583 /*
1584 * if we expect message authentication, run the authentication
1585 * function and compare the result with the value of the auth_tag
1586 */
1587 if (auth_start) {
1588
1589 /*
1590 * if we're using a universal hash, then we need to compute the
1591 * keystream prefix for encrypting the universal hash output
1592 *
1593 * if the keystream prefix length is zero, then we know that
1594 * the authenticator isn't using a universal hash function
1595 */
1596 if (stream->rtp_auth->prefix_len != 0) {
1597
1598 prefix_len = auth_get_prefix_length(stream->rtp_auth);
1599 status = cipher_output(stream->rtp_cipher, tmp_tag, prefix_len);
1600 debug_print(mod_srtp, "keystream prefix: %s",
1601 octet_string_hex_string(tmp_tag, prefix_len));
1602 if (status)
1603 return err_status_cipher_fail;
1604 }
1605
1606 /* initialize auth func context */
1607 status = auth_start(stream->rtp_auth);
1608 if (status) return status;
David McGrewfec49dd2005-09-23 19:34:11 +00001609
Cullen Jennings235513a2005-09-21 22:51:36 +00001610 /* now compute auth function over packet */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001611 status = auth_update(stream->rtp_auth, (uint8_t *)auth_start,
Cullen Jennings235513a2005-09-21 22:51:36 +00001612 *pkt_octet_len - tag_len);
1613
1614 /* run auth func over ROC, then write tmp tag */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001615 status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00001616
1617 debug_print(mod_srtp, "computed auth tag: %s",
1618 octet_string_hex_string(tmp_tag, tag_len));
1619 debug_print(mod_srtp, "packet auth tag: %s",
1620 octet_string_hex_string(auth_tag, tag_len));
1621 if (status)
1622 return err_status_auth_fail;
1623
1624 if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
1625 return err_status_auth_fail;
1626 }
1627
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001628 /*
1629 * update the key usage limit, and check it to make sure that we
1630 * didn't just hit either the soft limit or the hard limit, and call
1631 * the event handler if we hit either.
1632 */
1633 switch(key_limit_update(stream->limit)) {
1634 case key_event_normal:
1635 break;
1636 case key_event_soft_limit:
1637 srtp_handle_event(ctx, stream, event_key_soft_limit);
1638 break;
1639 case key_event_hard_limit:
1640 srtp_handle_event(ctx, stream, event_key_hard_limit);
1641 return err_status_key_expired;
1642 default:
1643 break;
1644 }
1645
Jonathan Lennox23dc1e22010-06-01 18:19:04 +00001646 /* if we're decrypting, add keystream into ciphertext */
Cullen Jennings235513a2005-09-21 22:51:36 +00001647 if (enc_start) {
Jonathan Lennox23dc1e22010-06-01 18:19:04 +00001648 status = cipher_decrypt(stream->rtp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001649 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001650 if (status)
1651 return err_status_cipher_fail;
1652 }
1653
1654 /*
1655 * verify that stream is for received traffic - this check will
1656 * detect SSRC collisions, since a stream that appears in both
1657 * srtp_protect() and srtp_unprotect() will fail this test in one of
1658 * those functions.
1659 *
1660 * we do this check *after* the authentication check, so that the
1661 * latter check will catch any attempts to fool us into thinking
1662 * that we've got a collision
1663 */
1664 if (stream->direction != dir_srtp_receiver) {
1665 if (stream->direction == dir_unknown) {
1666 stream->direction = dir_srtp_receiver;
1667 } else {
1668 srtp_handle_event(ctx, stream, event_ssrc_collision);
1669 }
1670 }
1671
1672 /*
1673 * if the stream is a 'provisional' one, in which the template context
1674 * is used, then we need to allocate a new stream at this point, since
1675 * the authentication passed
1676 */
1677 if (stream == ctx->stream_template) {
1678 srtp_stream_ctx_t *new_stream;
1679
1680 /*
1681 * allocate and initialize a new stream
1682 *
1683 * note that we indicate failure if we can't allocate the new
1684 * stream, and some implementations will want to not return
1685 * failure here
1686 */
1687 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
1688 if (status)
1689 return status;
1690
1691 /* add new stream to the head of the stream_list */
1692 new_stream->next = ctx->stream_list;
1693 ctx->stream_list = new_stream;
1694
1695 /* set stream (the pointer used in this function) */
1696 stream = new_stream;
1697 }
1698
1699 /*
1700 * the message authentication function passed, so add the packet
1701 * index into the replay database
1702 */
1703 rdbx_add_index(&stream->rtp_rdbx, delta);
1704
1705 /* decrease the packet length by the length of the auth tag */
1706 *pkt_octet_len -= tag_len;
1707
1708 return err_status_ok;
1709}
1710
1711err_status_t
1712srtp_init() {
1713 err_status_t status;
1714
1715 /* initialize crypto kernel */
1716 status = crypto_kernel_init();
1717 if (status)
1718 return status;
1719
1720 /* load srtp debug module into the kernel */
1721 status = crypto_kernel_load_debug_module(&mod_srtp);
1722 if (status)
1723 return status;
1724
1725 return err_status_ok;
1726}
1727
Jonathan Lennox5ae76332010-05-15 04:48:59 +00001728err_status_t
1729srtp_shutdown() {
1730 err_status_t status;
1731
1732 /* shut down crypto kernel */
1733 status = crypto_kernel_shutdown();
1734 if (status)
1735 return status;
1736
1737 /* shutting down crypto kernel frees the srtp debug module as well */
1738
1739 return err_status_ok;
1740}
1741
1742
Cullen Jennings235513a2005-09-21 22:51:36 +00001743/*
1744 * The following code is under consideration for removal. See
1745 * SRTP_MAX_TRAILER_LEN
1746 */
1747#if 0
1748
1749/*
1750 * srtp_get_trailer_length(&a) returns the number of octets that will
1751 * be added to an RTP packet by the SRTP processing. This value
1752 * is constant for a given srtp_stream_t (i.e. between initializations).
1753 */
1754
1755int
1756srtp_get_trailer_length(const srtp_stream_t s) {
1757 return auth_get_tag_length(s->rtp_auth);
1758}
1759
1760#endif
1761
1762/*
1763 * srtp_get_stream(ssrc) returns a pointer to the stream corresponding
1764 * to ssrc, or NULL if no stream exists for that ssrc
1765 *
1766 * this is an internal function
1767 */
1768
1769srtp_stream_ctx_t *
1770srtp_get_stream(srtp_t srtp, uint32_t ssrc) {
1771 srtp_stream_ctx_t *stream;
1772
1773 /* walk down list until ssrc is found */
1774 stream = srtp->stream_list;
1775 while (stream != NULL) {
1776 if (stream->ssrc == ssrc)
1777 return stream;
1778 stream = stream->next;
1779 }
1780
1781 /* we haven't found our ssrc, so return a null */
1782 return NULL;
1783}
1784
1785err_status_t
1786srtp_dealloc(srtp_t session) {
1787 srtp_stream_ctx_t *stream;
1788 err_status_t status;
1789
1790 /*
1791 * we take a conservative deallocation strategy - if we encounter an
1792 * error deallocating a stream, then we stop trying to deallocate
1793 * memory and just return an error
1794 */
1795
1796 /* walk list of streams, deallocating as we go */
1797 stream = session->stream_list;
1798 while (stream != NULL) {
1799 srtp_stream_t next = stream->next;
1800 status = srtp_stream_dealloc(session, stream);
1801 if (status)
1802 return status;
1803 stream = next;
1804 }
1805
1806 /* deallocate stream template, if there is one */
1807 if (session->stream_template != NULL) {
David McGrewfec49dd2005-09-23 19:34:11 +00001808 status = auth_dealloc(session->stream_template->rtcp_auth);
1809 if (status)
1810 return status;
1811 status = cipher_dealloc(session->stream_template->rtcp_cipher);
1812 if (status)
1813 return status;
1814 crypto_free(session->stream_template->limit);
Cullen Jennings235513a2005-09-21 22:51:36 +00001815 status = cipher_dealloc(session->stream_template->rtp_cipher);
1816 if (status)
1817 return status;
1818 status = auth_dealloc(session->stream_template->rtp_auth);
1819 if (status)
1820 return status;
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001821 status = rdbx_dealloc(&session->stream_template->rtp_rdbx);
1822 if (status)
1823 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001824 crypto_free(session->stream_template);
1825 }
1826
1827 /* deallocate session context */
1828 crypto_free(session);
1829
1830 return err_status_ok;
1831}
1832
1833
1834err_status_t
1835srtp_add_stream(srtp_t session,
1836 const srtp_policy_t *policy) {
1837 err_status_t status;
1838 srtp_stream_t tmp;
1839
Marcus Sundberg67398e62005-10-05 12:39:51 +00001840 /* sanity check arguments */
1841 if ((session == NULL) || (policy == NULL) || (policy->key == NULL))
1842 return err_status_bad_param;
1843
Cullen Jennings235513a2005-09-21 22:51:36 +00001844 /* allocate stream */
1845 status = srtp_stream_alloc(&tmp, policy);
1846 if (status) {
1847 return status;
1848 }
1849
1850 /* initialize stream */
1851 status = srtp_stream_init(tmp, policy);
1852 if (status) {
1853 crypto_free(tmp);
1854 return status;
1855 }
1856
1857 /*
1858 * set the head of the stream list or the template to point to the
1859 * stream that we've just alloced and init'ed, depending on whether
1860 * or not it has a wildcard SSRC value or not
1861 *
1862 * if the template stream has already been set, then the policy is
1863 * inconsistent, so we return a bad_param error code
1864 */
1865 switch (policy->ssrc.type) {
1866 case (ssrc_any_outbound):
1867 if (session->stream_template) {
1868 return err_status_bad_param;
1869 }
1870 session->stream_template = tmp;
1871 session->stream_template->direction = dir_srtp_sender;
1872 break;
1873 case (ssrc_any_inbound):
1874 if (session->stream_template) {
1875 return err_status_bad_param;
1876 }
1877 session->stream_template = tmp;
1878 session->stream_template->direction = dir_srtp_receiver;
1879 break;
1880 case (ssrc_specific):
1881 tmp->next = session->stream_list;
1882 session->stream_list = tmp;
1883 break;
1884 case (ssrc_undefined):
1885 default:
1886 crypto_free(tmp);
1887 return err_status_bad_param;
1888 }
1889
1890 return err_status_ok;
1891}
1892
1893
1894err_status_t
1895srtp_create(srtp_t *session, /* handle for session */
1896 const srtp_policy_t *policy) { /* SRTP policy (list) */
1897 err_status_t stat;
1898 srtp_ctx_t *ctx;
1899
1900 /* sanity check arguments */
Marcus Sundberg67398e62005-10-05 12:39:51 +00001901 if (session == NULL)
Cullen Jennings235513a2005-09-21 22:51:36 +00001902 return err_status_bad_param;
1903
1904 /* allocate srtp context and set ctx_ptr */
1905 ctx = (srtp_ctx_t *) crypto_alloc(sizeof(srtp_ctx_t));
1906 if (ctx == NULL)
1907 return err_status_alloc_fail;
1908 *session = ctx;
1909
1910 /*
1911 * loop over elements in the policy list, allocating and
1912 * initializing a stream for each element
1913 */
1914 ctx->stream_template = NULL;
1915 ctx->stream_list = NULL;
IƱaki Baz Castillo241fec32014-08-21 00:51:00 +02001916 ctx->user_data = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +00001917 while (policy != NULL) {
1918
1919 stat = srtp_add_stream(ctx, policy);
1920 if (stat) {
Marcus Sundberg67398e62005-10-05 12:39:51 +00001921 /* clean up everything */
1922 srtp_dealloc(*session);
Cullen Jennings235513a2005-09-21 22:51:36 +00001923 return stat;
1924 }
1925
1926 /* set policy to next item in list */
1927 policy = policy->next;
1928 }
1929
1930 return err_status_ok;
1931}
1932
1933
1934err_status_t
1935srtp_remove_stream(srtp_t session, uint32_t ssrc) {
1936 srtp_stream_ctx_t *stream, *last_stream;
1937 err_status_t status;
1938
1939 /* sanity check arguments */
1940 if (session == NULL)
1941 return err_status_bad_param;
1942
1943 /* find stream in list; complain if not found */
1944 last_stream = stream = session->stream_list;
1945 while ((stream != NULL) && (ssrc != stream->ssrc)) {
1946 last_stream = stream;
1947 stream = stream->next;
1948 }
1949 if (stream == NULL)
1950 return err_status_no_ctx;
1951
1952 /* remove stream from the list */
Jonathan Lennox20505b32010-05-27 19:22:25 +00001953 if (last_stream == stream)
1954 /* stream was first in list */
1955 session->stream_list = stream->next;
1956 else
1957 last_stream->next = stream->next;
Cullen Jennings235513a2005-09-21 22:51:36 +00001958
1959 /* deallocate the stream */
1960 status = srtp_stream_dealloc(session, stream);
1961 if (status)
1962 return status;
1963
1964 return err_status_ok;
1965}
1966
1967
1968/*
1969 * the default policy - provides a convenient way for callers to use
1970 * the default security policy
1971 *
1972 * this policy is that defined in the current SRTP internet draft.
1973 *
1974 */
1975
1976/*
1977 * NOTE: cipher_key_len is really key len (128 bits) plus salt len
1978 * (112 bits)
1979 */
1980/* There are hard-coded 16's for base_key_len in the key generation code */
1981
1982void
1983crypto_policy_set_rtp_default(crypto_policy_t *p) {
1984
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001985 p->cipher_type = AES_ICM;
Cullen Jennings235513a2005-09-21 22:51:36 +00001986 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
1987 p->auth_type = HMAC_SHA1;
1988 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
1989 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
1990 p->sec_serv = sec_serv_conf_and_auth;
1991
1992}
1993
1994void
1995crypto_policy_set_rtcp_default(crypto_policy_t *p) {
1996
Jonathan Lennox5df951a2010-05-20 20:55:54 +00001997 p->cipher_type = AES_ICM;
Cullen Jennings235513a2005-09-21 22:51:36 +00001998 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
1999 p->auth_type = HMAC_SHA1;
2000 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
2001 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
2002 p->sec_serv = sec_serv_conf_and_auth;
2003
2004}
2005
David McGrewa8546882006-01-12 17:56:02 +00002006void
2007crypto_policy_set_aes_cm_128_hmac_sha1_32(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 * note that this crypto policy is intended for SRTP, but not SRTCP
2013 */
2014
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002015 p->cipher_type = AES_ICM;
David McGrewa8546882006-01-12 17:56:02 +00002016 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
2017 p->auth_type = HMAC_SHA1;
2018 p->auth_key_len = 20; /* 160 bit key */
2019 p->auth_tag_len = 4; /* 32 bit tag */
2020 p->sec_serv = sec_serv_conf_and_auth;
2021
2022}
2023
2024
2025void
2026crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p) {
2027
2028 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00002029 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00002030 *
2031 * note that this crypto policy is intended for SRTP, but not SRTCP
2032 */
2033
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002034 p->cipher_type = AES_ICM;
David McGrewa8546882006-01-12 17:56:02 +00002035 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
2036 p->auth_type = NULL_AUTH;
2037 p->auth_key_len = 0;
2038 p->auth_tag_len = 0;
2039 p->sec_serv = sec_serv_conf;
2040
2041}
2042
2043
2044void
2045crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p) {
2046
2047 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00002048 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00002049 */
2050
2051 p->cipher_type = NULL_CIPHER;
2052 p->cipher_key_len = 0;
2053 p->auth_type = HMAC_SHA1;
2054 p->auth_key_len = 20;
2055 p->auth_tag_len = 10;
2056 p->sec_serv = sec_serv_auth;
2057
2058}
2059
2060
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002061void
2062crypto_policy_set_aes_cm_256_hmac_sha1_80(crypto_policy_t *p) {
2063
2064 /*
2065 * corresponds to draft-ietf-avt-big-aes-03.txt
2066 */
2067
2068 p->cipher_type = AES_ICM;
2069 p->cipher_key_len = 46;
2070 p->auth_type = HMAC_SHA1;
2071 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
2072 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
2073 p->sec_serv = sec_serv_conf_and_auth;
2074}
2075
2076
2077void
2078crypto_policy_set_aes_cm_256_hmac_sha1_32(crypto_policy_t *p) {
2079
2080 /*
2081 * corresponds to draft-ietf-avt-big-aes-03.txt
2082 *
2083 * note that this crypto policy is intended for SRTP, but not SRTCP
2084 */
2085
2086 p->cipher_type = AES_ICM;
2087 p->cipher_key_len = 46;
2088 p->auth_type = HMAC_SHA1;
2089 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
2090 p->auth_tag_len = 4; /* default 80 bits per RFC 3711 */
2091 p->sec_serv = sec_serv_conf_and_auth;
2092}
2093
jfigus8c36da22013-10-01 16:41:19 -04002094/*
2095 * AES-256 with no authentication.
2096 */
2097void
2098crypto_policy_set_aes_cm_256_null_auth (crypto_policy_t *p)
2099{
2100 p->cipher_type = AES_ICM;
2101 p->cipher_key_len = 46;
2102 p->auth_type = NULL_AUTH;
2103 p->auth_key_len = 0;
2104 p->auth_tag_len = 0;
2105 p->sec_serv = sec_serv_conf;
2106}
2107
2108#ifdef OPENSSL
2109/*
2110 * AES-128 GCM mode with 8 octet auth tag.
2111 */
2112void
2113crypto_policy_set_aes_gcm_128_8_auth(crypto_policy_t *p) {
2114 p->cipher_type = AES_128_GCM;
jfigus8719f952014-04-08 09:15:49 -04002115 p->cipher_key_len = AES_128_GCM_KEYSIZE_WSALT;
jfigus8c36da22013-10-01 16:41:19 -04002116 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2117 p->auth_key_len = 0;
2118 p->auth_tag_len = 8; /* 8 octet tag length */
2119 p->sec_serv = sec_serv_conf_and_auth;
2120}
2121
2122/*
2123 * AES-256 GCM mode with 8 octet auth tag.
2124 */
2125void
2126crypto_policy_set_aes_gcm_256_8_auth(crypto_policy_t *p) {
2127 p->cipher_type = AES_256_GCM;
jfigus8719f952014-04-08 09:15:49 -04002128 p->cipher_key_len = AES_256_GCM_KEYSIZE_WSALT;
jfigus8c36da22013-10-01 16:41:19 -04002129 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2130 p->auth_key_len = 0;
2131 p->auth_tag_len = 8; /* 8 octet tag length */
2132 p->sec_serv = sec_serv_conf_and_auth;
2133}
2134
2135/*
2136 * AES-128 GCM mode with 8 octet auth tag, no RTCP encryption.
2137 */
2138void
2139crypto_policy_set_aes_gcm_128_8_only_auth(crypto_policy_t *p) {
2140 p->cipher_type = AES_128_GCM;
jfigus8719f952014-04-08 09:15:49 -04002141 p->cipher_key_len = AES_128_GCM_KEYSIZE_WSALT;
jfigus8c36da22013-10-01 16:41:19 -04002142 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2143 p->auth_key_len = 0;
2144 p->auth_tag_len = 8; /* 8 octet tag length */
2145 p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
2146}
2147
2148/*
2149 * AES-256 GCM mode with 8 octet auth tag, no RTCP encryption.
2150 */
2151void
2152crypto_policy_set_aes_gcm_256_8_only_auth(crypto_policy_t *p) {
2153 p->cipher_type = AES_256_GCM;
jfigus8719f952014-04-08 09:15:49 -04002154 p->cipher_key_len = AES_256_GCM_KEYSIZE_WSALT;
jfigus8c36da22013-10-01 16:41:19 -04002155 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2156 p->auth_key_len = 0;
2157 p->auth_tag_len = 8; /* 8 octet tag length */
2158 p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
2159}
jfigusc13c1002014-05-08 13:34:53 -04002160
2161/*
2162 * AES-128 GCM mode with 16 octet auth tag.
2163 */
2164void
2165crypto_policy_set_aes_gcm_128_16_auth(crypto_policy_t *p) {
2166 p->cipher_type = AES_128_GCM;
2167 p->cipher_key_len = AES_128_GCM_KEYSIZE_WSALT;
2168 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2169 p->auth_key_len = 0;
2170 p->auth_tag_len = 16; /* 16 octet tag length */
2171 p->sec_serv = sec_serv_conf_and_auth;
2172}
2173
2174/*
2175 * AES-256 GCM mode with 16 octet auth tag.
2176 */
2177void
2178crypto_policy_set_aes_gcm_256_16_auth(crypto_policy_t *p) {
2179 p->cipher_type = AES_256_GCM;
2180 p->cipher_key_len = AES_256_GCM_KEYSIZE_WSALT;
2181 p->auth_type = NULL_AUTH; /* GCM handles the auth for us */
2182 p->auth_key_len = 0;
2183 p->auth_tag_len = 16; /* 16 octet tag length */
2184 p->sec_serv = sec_serv_conf_and_auth;
2185}
2186
jfigus8c36da22013-10-01 16:41:19 -04002187#endif
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002188
Cullen Jennings235513a2005-09-21 22:51:36 +00002189/*
2190 * secure rtcp functions
2191 */
2192
jfigus8c36da22013-10-01 16:41:19 -04002193/*
2194 * AEAD uses a new IV formation method. This function implements
2195 * section 10.1 from draft-ietf-avtcore-srtp-aes-gcm-07.txt. The
2196 * calculation is defined as, where (+) is the xor operation:
2197 *
2198 * 0 1 2 3 4 5 6 7 8 9 10 11
2199 * +--+--+--+--+--+--+--+--+--+--+--+--+
2200 * |00|00| SSRC |00|00|0+SRTCP Idx|---+
2201 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2202 * |
2203 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2204 * | Encryption Salt |->(+)
2205 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2206 * |
2207 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2208 * | Initialization Vector |<--+
2209 * +--+--+--+--+--+--+--+--+--+--+--+--+*
2210 *
2211 * Input: *stream - pointer to SRTP stream context, used to retrieve
2212 * the SALT
2213 * *iv - Pointer to recieve the calculated IV
2214 * seq_num - The SEQ value to use for the IV calculation.
2215 * *hdr - The RTP header, used to get the SSRC value
2216 *
2217 */
2218static void srtp_calc_aead_iv_srtcp(srtp_stream_ctx_t *stream, v128_t *iv,
2219 uint32_t seq_num, srtcp_hdr_t *hdr)
2220{
2221 v128_t in;
2222 v128_t salt;
2223
2224 memset(&in, 0, sizeof(v128_t));
2225 memset(&salt, 0, sizeof(v128_t));
2226
2227 in.v16[0] = 0;
2228 memcpy(&in.v16[1], &hdr->ssrc, 4); /* still in network order! */
2229 in.v16[3] = 0;
2230 in.v32[2] = 0x7FFFFFFF & htonl(seq_num); /* bit 32 is suppose to be zero */
2231
2232 debug_print(mod_srtp, "Pre-salted RTCP IV = %s\n", v128_hex_string(&in));
2233
2234 /*
2235 * Get the SALT value from the context
2236 */
2237 memcpy(salt.v8, stream->c_salt, 12);
2238 debug_print(mod_srtp, "RTCP SALT = %s\n", v128_hex_string(&salt));
2239
2240 /*
2241 * Finally, apply the SALT to the input
2242 */
2243 v128_xor(iv, &in, &salt);
2244}
2245
2246/*
2247 * This code handles AEAD ciphers for outgoing RTCP. We currently support
2248 * AES-GCM mode with 128 or 256 bit keys.
2249 */
2250static err_status_t
2251srtp_protect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream,
Travis Cross31844002014-07-02 16:18:57 +00002252 void *rtcp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -04002253{
2254 srtcp_hdr_t *hdr = (srtcp_hdr_t*)rtcp_hdr;
2255 uint32_t *enc_start; /* pointer to start of encrypted portion */
2256 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002257 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -04002258 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
2259 err_status_t status;
2260 int tag_len;
2261 uint32_t seq_num;
2262 v128_t iv;
2263 uint32_t tseq;
2264
2265 /* get tag length from stream context */
2266 tag_len = auth_get_tag_length(stream->rtcp_auth);
2267
2268 /*
2269 * set encryption start and encryption length - if we're not
2270 * providing confidentiality, set enc_start to NULL
2271 */
2272 enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header;
2273 enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
2274
2275 /* NOTE: hdr->length is not usable - it refers to only the first
2276 RTCP report in the compound packet! */
2277 /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2278 multiples of 32-bits (RFC 3550 6.1) */
2279 trailer = (uint32_t*)((char*)enc_start + enc_octet_len + tag_len);
2280
2281 if (stream->rtcp_services & sec_serv_conf) {
2282 *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
2283 } else {
2284 enc_start = NULL;
2285 enc_octet_len = 0;
2286 /* 0 is network-order independant */
2287 *trailer = 0x00000000; /* set encrypt bit */
2288 }
2289
2290 /*
2291 * set the auth_tag pointer to the proper location, which is after
2292 * the payload, but before the trailer
2293 * (note that srtpc *always* provides authentication, unlike srtp)
2294 */
2295 /* Note: This would need to change for optional mikey data */
2296 auth_tag = (uint8_t*)hdr + *pkt_octet_len;
2297
2298 /*
2299 * check sequence number for overruns, and copy it into the packet
2300 * if its value isn't too big
2301 */
2302 status = rdb_increment(&stream->rtcp_rdb);
2303 if (status) {
2304 return status;
2305 }
2306 seq_num = rdb_get_value(&stream->rtcp_rdb);
2307 *trailer |= htonl(seq_num);
2308 debug_print(mod_srtp, "srtcp index: %x", seq_num);
2309
2310 /*
2311 * Calculating the IV and pass it down to the cipher
2312 */
2313 srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
2314 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
2315 if (status) {
2316 return err_status_cipher_fail;
2317 }
2318
2319 /*
2320 * Set the AAD for GCM mode
2321 */
2322 if (enc_start) {
2323 /*
2324 * If payload encryption is enabled, then the AAD consist of
2325 * the RTCP header and the seq# at the end of the packet
2326 */
2327 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2328 octets_in_rtcp_header);
2329 if (status) {
2330 return ( err_status_cipher_fail);
2331 }
2332 } else {
2333 /*
2334 * Since payload encryption is not enabled, we must authenticate
2335 * the entire packet as described in section 10.3 in revision 07
2336 * of the draft.
2337 */
2338 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2339 *pkt_octet_len);
2340 if (status) {
2341 return ( err_status_cipher_fail);
2342 }
2343 }
2344 /*
2345 * put the idx# into network byte order and process it as AAD
2346 */
2347 tseq = htonl(*trailer);
2348 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq,
2349 sizeof(srtcp_trailer_t));
2350 if (status) {
2351 return ( err_status_cipher_fail);
2352 }
2353
2354 /* if we're encrypting, exor keystream into the message */
2355 if (enc_start) {
2356 status = cipher_encrypt(stream->rtcp_cipher,
2357 (uint8_t*)enc_start, &enc_octet_len);
2358 if (status) {
2359 return err_status_cipher_fail;
2360 }
2361 /*
2362 * Get the tag and append that to the output
2363 */
2364 status = cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag,
2365 &tag_len);
2366 if (status) {
2367 return ( err_status_cipher_fail);
2368 }
2369 enc_octet_len += tag_len;
2370 } else {
2371 /*
2372 * Even though we're not encrypting the payload, we need
2373 * to run the cipher to get the auth tag.
2374 */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002375 unsigned int nolen = 0;
jfigus8c36da22013-10-01 16:41:19 -04002376 status = cipher_encrypt(stream->rtcp_cipher, NULL, &nolen);
2377 if (status) {
2378 return err_status_cipher_fail;
2379 }
2380 /*
2381 * Get the tag and append that to the output
2382 */
2383 status = cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag,
2384 &tag_len);
2385 if (status) {
2386 return ( err_status_cipher_fail);
2387 }
2388 enc_octet_len += tag_len;
2389 }
2390
2391 /* increase the packet length by the length of the auth tag and seq_num*/
2392 *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
2393
2394 return err_status_ok;
2395}
2396
2397/*
2398 * This function handles incoming SRTCP packets while in AEAD mode,
2399 * which currently supports AES-GCM encryption. Note, the auth tag is
2400 * at the end of the packet stream and is automatically checked by GCM
2401 * when decrypting the payload.
2402 */
2403static err_status_t
2404srtp_unprotect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream,
Travis Cross31844002014-07-02 16:18:57 +00002405 void *srtcp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -04002406{
2407 srtcp_hdr_t *hdr = (srtcp_hdr_t*)srtcp_hdr;
2408 uint32_t *enc_start; /* pointer to start of encrypted portion */
2409 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002410 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -04002411 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
2412 err_status_t status;
2413 int tag_len;
2414 unsigned int tmp_len;
2415 uint32_t seq_num;
2416 v128_t iv;
2417 uint32_t tseq;
2418
2419 /* get tag length from stream context */
2420 tag_len = auth_get_tag_length(stream->rtcp_auth);
2421
jfigus8c36da22013-10-01 16:41:19 -04002422 /*
2423 * set encryption start, encryption length, and trailer
2424 */
2425 /* index & E (encryption) bit follow normal data. hdr->len
2426 is the number of words (32-bit) in the normal packet minus 1 */
2427 /* This should point trailer to the word past the end of the
2428 normal data. */
2429 /* This would need to be modified for optional mikey data */
2430 /*
2431 * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2432 * multiples of 32-bits (RFC 3550 6.1)
2433 */
2434 trailer = (uint32_t*)((char*)hdr + *pkt_octet_len - sizeof(srtcp_trailer_t));
2435 /*
2436 * We pass the tag down to the cipher when doing GCM mode
2437 */
2438 enc_octet_len = *pkt_octet_len - (octets_in_rtcp_header +
2439 sizeof(srtcp_trailer_t));
2440 auth_tag = (uint8_t*)hdr + *pkt_octet_len - tag_len - sizeof(srtcp_trailer_t);
2441
2442 if (*((unsigned char*)trailer) & SRTCP_E_BYTE_BIT) {
2443 enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header;
2444 } else {
2445 enc_octet_len = 0;
2446 enc_start = NULL; /* this indicates that there's no encryption */
2447 }
2448
2449 /*
2450 * check the sequence number for replays
2451 */
2452 /* this is easier than dealing with bitfield access */
2453 seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
2454 debug_print(mod_srtp, "srtcp index: %x", seq_num);
2455 status = rdb_check(&stream->rtcp_rdb, seq_num);
2456 if (status) {
2457 return status;
2458 }
2459
2460 /*
2461 * Calculate and set the IV
2462 */
2463 srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
2464 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
2465 if (status) {
2466 return err_status_cipher_fail;
2467 }
2468
2469 /*
2470 * Set the AAD for GCM mode
2471 */
2472 if (enc_start) {
2473 /*
2474 * If payload encryption is enabled, then the AAD consist of
2475 * the RTCP header and the seq# at the end of the packet
2476 */
2477 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2478 octets_in_rtcp_header);
2479 if (status) {
2480 return ( err_status_cipher_fail);
2481 }
2482 } else {
2483 /*
2484 * Since payload encryption is not enabled, we must authenticate
2485 * the entire packet as described in section 10.3 in revision 07
2486 * of the draft.
2487 */
2488 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2489 (*pkt_octet_len - tag_len - sizeof(srtcp_trailer_t)));
2490 if (status) {
2491 return ( err_status_cipher_fail);
2492 }
2493 }
2494
2495 /*
2496 * put the idx# into network byte order, and process it as AAD
2497 */
2498 tseq = htonl(*trailer);
2499 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq,
2500 sizeof(srtcp_trailer_t));
2501 if (status) {
2502 return ( err_status_cipher_fail);
2503 }
2504
2505 /* if we're decrypting, exor keystream into the message */
2506 if (enc_start) {
2507 status = cipher_decrypt(stream->rtcp_cipher,
2508 (uint8_t*)enc_start, &enc_octet_len);
2509 if (status) {
2510 return status;
2511 }
2512 } else {
2513 /*
2514 * Still need to run the cipher to check the tag
2515 */
2516 tmp_len = tag_len;
2517 status = cipher_decrypt(stream->rtcp_cipher, (uint8_t*)auth_tag,
2518 &tmp_len);
2519 if (status) {
2520 return status;
2521 }
2522 }
2523
2524 /* decrease the packet length by the length of the auth tag and seq_num*/
2525 *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
2526
2527 /*
2528 * verify that stream is for received traffic - this check will
2529 * detect SSRC collisions, since a stream that appears in both
2530 * srtp_protect() and srtp_unprotect() will fail this test in one of
2531 * those functions.
2532 *
2533 * we do this check *after* the authentication check, so that the
2534 * latter check will catch any attempts to fool us into thinking
2535 * that we've got a collision
2536 */
2537 if (stream->direction != dir_srtp_receiver) {
2538 if (stream->direction == dir_unknown) {
2539 stream->direction = dir_srtp_receiver;
2540 } else {
2541 srtp_handle_event(ctx, stream, event_ssrc_collision);
2542 }
2543 }
2544
2545 /*
2546 * if the stream is a 'provisional' one, in which the template context
2547 * is used, then we need to allocate a new stream at this point, since
2548 * the authentication passed
2549 */
2550 if (stream == ctx->stream_template) {
2551 srtp_stream_ctx_t *new_stream;
2552
2553 /*
2554 * allocate and initialize a new stream
2555 *
2556 * note that we indicate failure if we can't allocate the new
2557 * stream, and some implementations will want to not return
2558 * failure here
2559 */
2560 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
2561 if (status) {
2562 return status;
2563 }
2564
2565 /* add new stream to the head of the stream_list */
2566 new_stream->next = ctx->stream_list;
2567 ctx->stream_list = new_stream;
2568
2569 /* set stream (the pointer used in this function) */
2570 stream = new_stream;
2571 }
2572
2573 /* we've passed the authentication check, so add seq_num to the rdb */
2574 rdb_add_index(&stream->rtcp_rdb, seq_num);
2575
2576 return err_status_ok;
2577}
2578
Cullen Jennings235513a2005-09-21 22:51:36 +00002579err_status_t
2580srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00002581 srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00002582 uint32_t *enc_start; /* pointer to start of encrypted portion */
2583 uint32_t *auth_start; /* pointer to start of auth. portion */
2584 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002585 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002586 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
Cullen Jennings235513a2005-09-21 22:51:36 +00002587 err_status_t status;
2588 int tag_len;
2589 srtp_stream_ctx_t *stream;
2590 int prefix_len;
2591 uint32_t seq_num;
2592
2593 /* we assume the hdr is 32-bit aligned to start */
Travis Cross8ba46eb2014-06-29 18:42:29 +00002594
2595 /* check the packet length - it must at least contain a full header */
2596 if (*pkt_octet_len < octets_in_rtcp_header)
2597 return err_status_bad_param;
2598
Cullen Jennings235513a2005-09-21 22:51:36 +00002599 /*
2600 * look up ssrc in srtp_stream list, and process the packet with
2601 * the appropriate stream. if we haven't seen this stream before,
2602 * there's only one key for this srtp_session, and the cipher
2603 * supports key-sharing, then we assume that a new stream using
2604 * that key has just started up
2605 */
2606 stream = srtp_get_stream(ctx, hdr->ssrc);
2607 if (stream == NULL) {
2608 if (ctx->stream_template != NULL) {
2609 srtp_stream_ctx_t *new_stream;
2610
2611 /* allocate and initialize a new stream */
2612 status = srtp_stream_clone(ctx->stream_template,
2613 hdr->ssrc, &new_stream);
2614 if (status)
2615 return status;
2616
2617 /* add new stream to the head of the stream_list */
2618 new_stream->next = ctx->stream_list;
2619 ctx->stream_list = new_stream;
2620
2621 /* set stream (the pointer used in this function) */
2622 stream = new_stream;
2623 } else {
2624 /* no template stream, so we return an error */
2625 return err_status_no_ctx;
2626 }
2627 }
2628
2629 /*
2630 * verify that stream is for sending traffic - this check will
2631 * detect SSRC collisions, since a stream that appears in both
2632 * srtp_protect() and srtp_unprotect() will fail this test in one of
2633 * those functions.
2634 */
2635 if (stream->direction != dir_srtp_sender) {
2636 if (stream->direction == dir_unknown) {
David McGrewc34f7402006-03-09 21:17:00 +00002637 stream->direction = dir_srtp_sender;
Cullen Jennings235513a2005-09-21 22:51:36 +00002638 } else {
2639 srtp_handle_event(ctx, stream, event_ssrc_collision);
2640 }
2641 }
2642
jfigus8c36da22013-10-01 16:41:19 -04002643 /*
2644 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
2645 * the request to our AEAD handler.
2646 */
2647 if (stream->rtp_cipher->algorithm == AES_128_GCM ||
2648 stream->rtp_cipher->algorithm == AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00002649 return srtp_protect_rtcp_aead(ctx, stream, rtcp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04002650 }
2651
Cullen Jennings235513a2005-09-21 22:51:36 +00002652 /* get tag length from stream context */
2653 tag_len = auth_get_tag_length(stream->rtcp_auth);
2654
2655 /*
2656 * set encryption start and encryption length - if we're not
2657 * providing confidentiality, set enc_start to NULL
2658 */
2659 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
2660 enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
2661
2662 /* all of the packet, except the header, gets encrypted */
2663 /* NOTE: hdr->length is not usable - it refers to only the first
2664 RTCP report in the compound packet! */
2665 /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2666 multiples of 32-bits (RFC 3550 6.1) */
2667 trailer = (uint32_t *) ((char *)enc_start + enc_octet_len);
2668
2669 if (stream->rtcp_services & sec_serv_conf) {
2670 *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
2671 } else {
2672 enc_start = NULL;
2673 enc_octet_len = 0;
2674 /* 0 is network-order independant */
2675 *trailer = 0x00000000; /* set encrypt bit */
2676 }
2677
2678 /*
2679 * set the auth_start and auth_tag pointers to the proper locations
2680 * (note that srtpc *always* provides authentication, unlike srtp)
2681 */
2682 /* Note: This would need to change for optional mikey data */
2683 auth_start = (uint32_t *)hdr;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002684 auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t);
Cullen Jennings235513a2005-09-21 22:51:36 +00002685
David McGrew79870d62007-06-15 18:17:39 +00002686 /* perform EKT processing if needed */
2687 ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len,
2688 rdbx_get_packet_index(&stream->rtp_rdbx));
2689
Cullen Jennings235513a2005-09-21 22:51:36 +00002690 /*
2691 * check sequence number for overruns, and copy it into the packet
2692 * if its value isn't too big
2693 */
2694 status = rdb_increment(&stream->rtcp_rdb);
2695 if (status)
2696 return status;
2697 seq_num = rdb_get_value(&stream->rtcp_rdb);
2698 *trailer |= htonl(seq_num);
2699 debug_print(mod_srtp, "srtcp index: %x", seq_num);
2700
2701 /*
2702 * if we're using rindael counter mode, set nonce and seq
2703 */
Jonathan Lennoxf4332412010-05-20 22:10:20 +00002704 if (stream->rtcp_cipher->type->id == AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002705 v128_t iv;
2706
2707 iv.v32[0] = 0;
2708 iv.v32[1] = hdr->ssrc; /* still in network order! */
2709 iv.v32[2] = htonl(seq_num >> 16);
2710 iv.v32[3] = htonl(seq_num << 16);
jfigus7882dd92013-08-02 16:08:23 -04002711 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002712
2713 } else {
2714 v128_t iv;
2715
2716 /* otherwise, just set the index to seq_num */
2717 iv.v32[0] = 0;
2718 iv.v32[1] = 0;
2719 iv.v32[2] = 0;
2720 iv.v32[3] = htonl(seq_num);
jfigus7882dd92013-08-02 16:08:23 -04002721 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002722 }
2723 if (status)
2724 return err_status_cipher_fail;
2725
2726 /*
2727 * if we're authenticating using a universal hash, put the keystream
2728 * prefix into the authentication tag
2729 */
2730
2731 /* if auth_start is non-null, then put keystream into tag */
2732 if (auth_start) {
2733
2734 /* put keystream prefix into auth_tag */
2735 prefix_len = auth_get_prefix_length(stream->rtcp_auth);
2736 status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
2737
2738 debug_print(mod_srtp, "keystream prefix: %s",
2739 octet_string_hex_string(auth_tag, prefix_len));
2740
2741 if (status)
2742 return err_status_cipher_fail;
2743 }
2744
2745 /* if we're encrypting, exor keystream into the message */
2746 if (enc_start) {
2747 status = cipher_encrypt(stream->rtcp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002748 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002749 if (status)
2750 return err_status_cipher_fail;
2751 }
2752
2753 /* initialize auth func context */
2754 auth_start(stream->rtcp_auth);
2755
David McGrew9c70f292006-05-03 19:38:38 +00002756 /*
2757 * run auth func over packet (including trailer), and write the
2758 * result at auth_tag
2759 */
Cullen Jennings235513a2005-09-21 22:51:36 +00002760 status = auth_compute(stream->rtcp_auth,
David McGrew9c70f292006-05-03 19:38:38 +00002761 (uint8_t *)auth_start,
2762 (*pkt_octet_len) + sizeof(srtcp_trailer_t),
2763 auth_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00002764 debug_print(mod_srtp, "srtcp auth tag: %s",
2765 octet_string_hex_string(auth_tag, tag_len));
2766 if (status)
2767 return err_status_auth_fail;
2768
2769 /* increase the packet length by the length of the auth tag and seq_num*/
2770 *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
2771
2772 return err_status_ok;
2773}
2774
2775
2776err_status_t
2777srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00002778 srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00002779 uint32_t *enc_start; /* pointer to start of encrypted portion */
2780 uint32_t *auth_start; /* pointer to start of auth. portion */
2781 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002782 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002783 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
2784 uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
David McGrew79870d62007-06-15 18:17:39 +00002785 uint8_t tag_copy[SRTP_MAX_TAG_LEN];
Cullen Jennings235513a2005-09-21 22:51:36 +00002786 err_status_t status;
Travis Cross1b8b1e72014-07-02 15:32:36 +00002787 unsigned int auth_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00002788 int tag_len;
2789 srtp_stream_ctx_t *stream;
2790 int prefix_len;
2791 uint32_t seq_num;
TV Sriram4986a362013-05-06 11:24:03 -07002792 int e_bit_in_packet; /* whether the E-bit was found in the packet */
2793 int sec_serv_confidentiality; /* whether confidentiality was requested */
Cullen Jennings235513a2005-09-21 22:51:36 +00002794
2795 /* we assume the hdr is 32-bit aligned to start */
Travis Cross444a5442014-07-02 16:01:01 +00002796
Travis Crosse896bf72014-07-07 19:59:33 +00002797 /* check that the length value is sane; we'll check again once we
2798 know the tag length, but we at least want to know that it is
2799 a positive value */
2800 if (*pkt_octet_len < octets_in_rtcp_header + sizeof(srtcp_trailer_t))
2801 return err_status_bad_param;
2802
Cullen Jennings235513a2005-09-21 22:51:36 +00002803 /*
2804 * look up ssrc in srtp_stream list, and process the packet with
2805 * the appropriate stream. if we haven't seen this stream before,
2806 * there's only one key for this srtp_session, and the cipher
2807 * supports key-sharing, then we assume that a new stream using
2808 * that key has just started up
2809 */
2810 stream = srtp_get_stream(ctx, hdr->ssrc);
2811 if (stream == NULL) {
2812 if (ctx->stream_template != NULL) {
2813 stream = ctx->stream_template;
David McGrew79870d62007-06-15 18:17:39 +00002814
2815 /*
2816 * check to see if stream_template has an EKT data structure, in
2817 * which case we initialize the template using the EKT policy
2818 * referenced by that data (which consists of decrypting the
2819 * master key from the EKT field)
2820 *
2821 * this function initializes a *provisional* stream, and this
2822 * stream should not be accepted until and unless the packet
2823 * passes its authentication check
2824 */
2825 if (stream->ekt != NULL) {
2826 status = srtp_stream_init_from_ekt(stream, srtcp_hdr, *pkt_octet_len);
2827 if (status)
2828 return status;
2829 }
2830
Cullen Jennings235513a2005-09-21 22:51:36 +00002831 debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)",
2832 hdr->ssrc);
2833 } else {
2834 /* no template stream, so we return an error */
2835 return err_status_no_ctx;
2836 }
2837 }
2838
Travis Cross8ba46eb2014-06-29 18:42:29 +00002839 /* get tag length from stream context */
2840 tag_len = auth_get_tag_length(stream->rtcp_auth);
2841
2842 /* check the packet length - it must contain at least a full RTCP
2843 header, an auth tag (if applicable), and the SRTCP encrypted flag
2844 and 31-bit index value */
jfigus73e30932014-07-07 15:50:32 -04002845 if (*pkt_octet_len < (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t))) {
Travis Cross8ba46eb2014-06-29 18:42:29 +00002846 return err_status_bad_param;
jfigus73e30932014-07-07 15:50:32 -04002847 }
Travis Cross8ba46eb2014-06-29 18:42:29 +00002848
jfigus8c36da22013-10-01 16:41:19 -04002849 /*
2850 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
2851 * the request to our AEAD handler.
2852 */
2853 if (stream->rtp_cipher->algorithm == AES_128_GCM ||
2854 stream->rtp_cipher->algorithm == AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00002855 return srtp_unprotect_rtcp_aead(ctx, stream, srtcp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04002856 }
2857
TV Sriram4986a362013-05-06 11:24:03 -07002858 sec_serv_confidentiality = stream->rtcp_services == sec_serv_conf ||
2859 stream->rtcp_services == sec_serv_conf_and_auth;
2860
Cullen Jennings235513a2005-09-21 22:51:36 +00002861 /*
2862 * set encryption start, encryption length, and trailer
2863 */
2864 enc_octet_len = *pkt_octet_len -
2865 (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t));
2866 /* index & E (encryption) bit follow normal data. hdr->len
2867 is the number of words (32-bit) in the normal packet minus 1 */
2868 /* This should point trailer to the word past the end of the
2869 normal data. */
2870 /* This would need to be modified for optional mikey data */
2871 /*
2872 * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2873 * multiples of 32-bits (RFC 3550 6.1)
2874 */
2875 trailer = (uint32_t *) ((char *) hdr +
TV Sriram4986a362013-05-06 11:24:03 -07002876 *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t)));
2877 e_bit_in_packet =
2878 (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) == SRTCP_E_BYTE_BIT;
2879 if (e_bit_in_packet != sec_serv_confidentiality) {
2880 return err_status_cant_check;
2881 }
2882 if (sec_serv_confidentiality) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002883 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
2884 } else {
2885 enc_octet_len = 0;
2886 enc_start = NULL; /* this indicates that there's no encryption */
2887 }
2888
2889 /*
2890 * set the auth_start and auth_tag pointers to the proper locations
2891 * (note that srtcp *always* uses authentication, unlike srtp)
2892 */
2893 auth_start = (uint32_t *)hdr;
David McGrew79870d62007-06-15 18:17:39 +00002894 auth_len = *pkt_octet_len - tag_len;
2895 auth_tag = (uint8_t *)hdr + auth_len;
2896
2897 /*
2898 * if EKT is in use, then we make a copy of the tag from the packet,
2899 * and then zeroize the location of the base tag
2900 *
2901 * we first re-position the auth_tag pointer so that it points to
2902 * the base tag
2903 */
2904 if (stream->ekt) {
2905 auth_tag -= ekt_octets_after_base_tag(stream->ekt);
2906 memcpy(tag_copy, auth_tag, tag_len);
2907 octet_string_set_to_zero(auth_tag, tag_len);
2908 auth_tag = tag_copy;
2909 auth_len += tag_len;
2910 }
Cullen Jennings235513a2005-09-21 22:51:36 +00002911
2912 /*
2913 * check the sequence number for replays
2914 */
2915 /* this is easier than dealing with bitfield access */
2916 seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
David McGrew9c70f292006-05-03 19:38:38 +00002917 debug_print(mod_srtp, "srtcp index: %x", seq_num);
Cullen Jennings235513a2005-09-21 22:51:36 +00002918 status = rdb_check(&stream->rtcp_rdb, seq_num);
2919 if (status)
2920 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00002921
2922 /*
2923 * if we're using aes counter mode, set nonce and seq
2924 */
Jonathan Lennoxf4332412010-05-20 22:10:20 +00002925 if (stream->rtcp_cipher->type->id == AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002926 v128_t iv;
2927
2928 iv.v32[0] = 0;
2929 iv.v32[1] = hdr->ssrc; /* still in network order! */
2930 iv.v32[2] = htonl(seq_num >> 16);
2931 iv.v32[3] = htonl(seq_num << 16);
jfigus7882dd92013-08-02 16:08:23 -04002932 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002933
2934 } else {
2935 v128_t iv;
2936
2937 /* otherwise, just set the index to seq_num */
2938 iv.v32[0] = 0;
2939 iv.v32[1] = 0;
2940 iv.v32[2] = 0;
2941 iv.v32[3] = htonl(seq_num);
jfigus7882dd92013-08-02 16:08:23 -04002942 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002943
2944 }
2945 if (status)
2946 return err_status_cipher_fail;
2947
2948 /* initialize auth func context */
2949 auth_start(stream->rtcp_auth);
2950
2951 /* run auth func over packet, put result into tmp_tag */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002952 status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start,
David McGrew79870d62007-06-15 18:17:39 +00002953 auth_len, tmp_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00002954 debug_print(mod_srtp, "srtcp computed tag: %s",
2955 octet_string_hex_string(tmp_tag, tag_len));
2956 if (status)
2957 return err_status_auth_fail;
2958
2959 /* compare the tag just computed with the one in the packet */
2960 debug_print(mod_srtp, "srtcp tag from packet: %s",
2961 octet_string_hex_string(auth_tag, tag_len));
2962 if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
2963 return err_status_auth_fail;
2964
2965 /*
2966 * if we're authenticating using a universal hash, put the keystream
2967 * prefix into the authentication tag
2968 */
2969 prefix_len = auth_get_prefix_length(stream->rtcp_auth);
2970 if (prefix_len) {
2971 status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
2972 debug_print(mod_srtp, "keystream prefix: %s",
2973 octet_string_hex_string(auth_tag, prefix_len));
2974 if (status)
2975 return err_status_cipher_fail;
2976 }
2977
2978 /* if we're decrypting, exor keystream into the message */
2979 if (enc_start) {
Jonathan Lennox23dc1e22010-06-01 18:19:04 +00002980 status = cipher_decrypt(stream->rtcp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002981 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002982 if (status)
2983 return err_status_cipher_fail;
2984 }
2985
David McGrew79870d62007-06-15 18:17:39 +00002986 /* decrease the packet length by the length of the auth tag and seq_num */
Cullen Jennings235513a2005-09-21 22:51:36 +00002987 *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
2988
David McGrew79870d62007-06-15 18:17:39 +00002989 /*
2990 * if EKT is in effect, subtract the EKT data out of the packet
2991 * length
2992 */
2993 *pkt_octet_len -= ekt_octets_after_base_tag(stream->ekt);
2994
Cullen Jennings235513a2005-09-21 22:51:36 +00002995 /*
2996 * verify that stream is for received traffic - this check will
2997 * detect SSRC collisions, since a stream that appears in both
2998 * srtp_protect() and srtp_unprotect() will fail this test in one of
2999 * those functions.
3000 *
3001 * we do this check *after* the authentication check, so that the
3002 * latter check will catch any attempts to fool us into thinking
3003 * that we've got a collision
3004 */
3005 if (stream->direction != dir_srtp_receiver) {
3006 if (stream->direction == dir_unknown) {
3007 stream->direction = dir_srtp_receiver;
3008 } else {
3009 srtp_handle_event(ctx, stream, event_ssrc_collision);
3010 }
3011 }
3012
3013 /*
3014 * if the stream is a 'provisional' one, in which the template context
3015 * is used, then we need to allocate a new stream at this point, since
3016 * the authentication passed
3017 */
3018 if (stream == ctx->stream_template) {
3019 srtp_stream_ctx_t *new_stream;
3020
3021 /*
3022 * allocate and initialize a new stream
3023 *
3024 * note that we indicate failure if we can't allocate the new
3025 * stream, and some implementations will want to not return
3026 * failure here
3027 */
3028 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
3029 if (status)
3030 return status;
3031
3032 /* add new stream to the head of the stream_list */
3033 new_stream->next = ctx->stream_list;
3034 ctx->stream_list = new_stream;
3035
3036 /* set stream (the pointer used in this function) */
3037 stream = new_stream;
3038 }
3039
3040 /* we've passed the authentication check, so add seq_num to the rdb */
3041 rdb_add_index(&stream->rtcp_rdb, seq_num);
3042
3043
3044 return err_status_ok;
3045}
David McGrew0cb86ee2006-07-07 15:46:57 +00003046
3047
IƱaki Baz Castillo241fec32014-08-21 00:51:00 +02003048/*
3049 * user data within srtp_t context
3050 */
3051
3052void
3053srtp_set_user_data(srtp_t ctx, void *data) {
3054 ctx->user_data = data;
3055}
3056
3057void*
3058srtp_get_user_data(srtp_t ctx) {
3059 return ctx->user_data;
3060}
3061
David McGrew0cb86ee2006-07-07 15:46:57 +00003062
3063/*
3064 * dtls keying for srtp
3065 */
3066
3067err_status_t
3068crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy,
3069 srtp_profile_t profile) {
3070
3071 /* set SRTP policy from the SRTP profile in the key set */
3072 switch(profile) {
3073 case srtp_profile_aes128_cm_sha1_80:
3074 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003075 break;
3076 case srtp_profile_aes128_cm_sha1_32:
3077 crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003078 break;
3079 case srtp_profile_null_sha1_80:
3080 crypto_policy_set_null_cipher_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003081 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003082 case srtp_profile_aes256_cm_sha1_80:
3083 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003084 break;
3085 case srtp_profile_aes256_cm_sha1_32:
3086 crypto_policy_set_aes_cm_256_hmac_sha1_32(policy);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003087 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003088 /* the following profiles are not (yet) supported */
3089 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003090 default:
3091 return err_status_bad_param;
3092 }
3093
3094 return err_status_ok;
3095}
3096
3097err_status_t
3098crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy,
3099 srtp_profile_t profile) {
3100
3101 /* set SRTP policy from the SRTP profile in the key set */
3102 switch(profile) {
3103 case srtp_profile_aes128_cm_sha1_80:
3104 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
3105 break;
3106 case srtp_profile_aes128_cm_sha1_32:
jfigus0acbb032013-05-30 16:47:02 -04003107 /* We do not honor the 32-bit auth tag request since
3108 * this is not compliant with RFC 3711 */
David McGrew0cb86ee2006-07-07 15:46:57 +00003109 crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
3110 break;
3111 case srtp_profile_null_sha1_80:
3112 crypto_policy_set_null_cipher_hmac_sha1_80(policy);
3113 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003114 case srtp_profile_aes256_cm_sha1_80:
3115 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
3116 break;
3117 case srtp_profile_aes256_cm_sha1_32:
jfigus0acbb032013-05-30 16:47:02 -04003118 /* We do not honor the 32-bit auth tag request since
3119 * this is not compliant with RFC 3711 */
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003120 crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
3121 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003122 /* the following profiles are not (yet) supported */
3123 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003124 default:
3125 return err_status_bad_param;
3126 }
3127
3128 return err_status_ok;
3129}
3130
3131void
3132append_salt_to_key(uint8_t *key, unsigned int bytes_in_key,
3133 uint8_t *salt, unsigned int bytes_in_salt) {
3134
3135 memcpy(key + bytes_in_key, salt, bytes_in_salt);
3136
3137}
3138
3139unsigned int
3140srtp_profile_get_master_key_length(srtp_profile_t profile) {
3141
3142 switch(profile) {
3143 case srtp_profile_aes128_cm_sha1_80:
3144 return 16;
3145 break;
3146 case srtp_profile_aes128_cm_sha1_32:
3147 return 16;
3148 break;
3149 case srtp_profile_null_sha1_80:
3150 return 16;
3151 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003152 case srtp_profile_aes256_cm_sha1_80:
3153 return 32;
3154 break;
3155 case srtp_profile_aes256_cm_sha1_32:
3156 return 32;
3157 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003158 /* the following profiles are not (yet) supported */
3159 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003160 default:
3161 return 0; /* indicate error by returning a zero */
3162 }
3163}
3164
3165unsigned int
3166srtp_profile_get_master_salt_length(srtp_profile_t profile) {
3167
3168 switch(profile) {
3169 case srtp_profile_aes128_cm_sha1_80:
3170 return 14;
3171 break;
3172 case srtp_profile_aes128_cm_sha1_32:
3173 return 14;
3174 break;
3175 case srtp_profile_null_sha1_80:
3176 return 14;
3177 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003178 case srtp_profile_aes256_cm_sha1_80:
3179 return 14;
3180 break;
3181 case srtp_profile_aes256_cm_sha1_32:
3182 return 14;
3183 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003184 /* the following profiles are not (yet) supported */
3185 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003186 default:
3187 return 0; /* indicate error by returning a zero */
3188 }
3189}