blob: e9cdaa94c53be7f41dcf49b6597477a1999c22b2 [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
jfigusa9ac8982014-10-31 14:49:31 -040045#include "srtp.h"
Teerapap Changwichukarn6cffe242014-09-24 11:24:07 +080046#include "srtp_priv.h"
jfigusa9ac8982014-10-31 14:49:31 -040047#include "crypto_types.h"
48#include "err.h"
David McGrew79870d62007-06-15 18:17:39 +000049#include "ekt.h" /* for SRTP Encrypted Key Transport */
jfigused755f52014-11-19 14:57:19 -050050#include "alloc.h" /* for srtp_crypto_alloc() */
jfigus8719f952014-04-08 09:15:49 -040051#ifdef OPENSSL
52#include "aes_gcm_ossl.h" /* for AES GCM mode */
53#endif
Cullen Jennings235513a2005-09-21 22:51:36 +000054
jfigusa6cf2082014-11-21 10:04:03 -050055#include <limits.h>
56#ifdef HAVE_NETINET_IN_H
57# include <netinet/in.h>
58#elif defined(HAVE_WINSOCK2_H)
59# include <winsock2.h>
60#endif
Marcus Sundberge4e34f92005-10-02 20:19:35 +000061
62
Cullen Jennings235513a2005-09-21 22:51:36 +000063/* the debug module for srtp */
64
jfigus02d6f032014-11-21 10:56:42 -050065srtp_debug_module_t mod_srtp = {
Cullen Jennings235513a2005-09-21 22:51:36 +000066 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
jfigus857009c2014-11-05 11:17:43 -0500114srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000115srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
116 const srtp_policy_t *p) {
117 srtp_stream_ctx_t *str;
jfigus857009c2014-11-05 11:17:43 -0500118 srtp_err_status_t stat;
Cullen Jennings235513a2005-09-21 22:51:36 +0000119
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 */
jfigused755f52014-11-19 14:57:19 -0500129 str = (srtp_stream_ctx_t *) srtp_crypto_alloc(sizeof(srtp_stream_ctx_t));
Cullen Jennings235513a2005-09-21 22:51:36 +0000130 if (str == NULL)
jfigus857009c2014-11-05 11:17:43 -0500131 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000132 *str_ptr = str;
133
134 /* allocate cipher */
jfigus92736bc2014-11-21 10:30:54 -0500135 stat = srtp_crypto_kernel_alloc_cipher(p->rtp.cipher_type,
Cullen Jennings235513a2005-09-21 22:51:36 +0000136 &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) {
jfigused755f52014-11-19 14:57:19 -0500140 srtp_crypto_free(str);
Cullen Jennings235513a2005-09-21 22:51:36 +0000141 return stat;
142 }
143
144 /* allocate auth function */
jfigus92736bc2014-11-21 10:30:54 -0500145 stat = srtp_crypto_kernel_alloc_auth(p->rtp.auth_type,
Cullen Jennings235513a2005-09-21 22:51:36 +0000146 &str->rtp_auth,
147 p->rtp.auth_key_len,
148 p->rtp.auth_tag_len);
149 if (stat) {
150 cipher_dealloc(str->rtp_cipher);
jfigused755f52014-11-19 14:57:19 -0500151 srtp_crypto_free(str);
Cullen Jennings235513a2005-09-21 22:51:36 +0000152 return stat;
153 }
154
155 /* allocate key limit structure */
jfigusc7cdc9a2014-11-19 16:19:08 -0500156 str->limit = (srtp_key_limit_ctx_t*) srtp_crypto_alloc(sizeof(srtp_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);
jfigused755f52014-11-19 14:57:19 -0500160 srtp_crypto_free(str);
jfigus857009c2014-11-05 11:17:43 -0500161 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000162 }
163
164 /*
165 * ...and now the RTCP-specific initialization - first, allocate
166 * the cipher
167 */
jfigus92736bc2014-11-21 10:30:54 -0500168 stat = srtp_crypto_kernel_alloc_cipher(p->rtcp.cipher_type,
Cullen Jennings235513a2005-09-21 22:51:36 +0000169 &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);
jfigused755f52014-11-19 14:57:19 -0500175 srtp_crypto_free(str->limit);
176 srtp_crypto_free(str);
Cullen Jennings235513a2005-09-21 22:51:36 +0000177 return stat;
178 }
179
180 /* allocate auth function */
jfigus92736bc2014-11-21 10:30:54 -0500181 stat = srtp_crypto_kernel_alloc_auth(p->rtcp.auth_type,
Cullen Jennings235513a2005-09-21 22:51:36 +0000182 &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);
jfigused755f52014-11-19 14:57:19 -0500189 srtp_crypto_free(str->limit);
190 srtp_crypto_free(str);
Cullen Jennings235513a2005-09-21 22:51:36 +0000191 return stat;
192 }
193
David McGrew79870d62007-06-15 18:17:39 +0000194 /* allocate ekt data associated with stream */
jfigusc5887e72014-11-06 09:46:18 -0500195 stat = srtp_ekt_alloc(&str->ekt, p->ekt);
David McGrew79870d62007-06-15 18:17:39 +0000196 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);
jfigused755f52014-11-19 14:57:19 -0500201 srtp_crypto_free(str->limit);
202 srtp_crypto_free(str);
David McGrew79870d62007-06-15 18:17:39 +0000203 return stat;
204 }
205
jfigus857009c2014-11-05 11:17:43 -0500206 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000207}
208
jfigus857009c2014-11-05 11:17:43 -0500209srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000210srtp_stream_dealloc(srtp_t session, srtp_stream_ctx_t *stream) {
jfigus857009c2014-11-05 11:17:43 -0500211 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000212
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 {
jfigused755f52014-11-19 14:57:19 -0500244 srtp_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
jfigusde8deb32014-11-25 12:58:11 -0500273 status = srtp_rdbx_dealloc(&stream->rtp_rdbx);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000274 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 */
jfigused755f52014-11-19 14:57:19 -0500287 srtp_crypto_free(stream);
Cullen Jennings235513a2005-09-21 22:51:36 +0000288
jfigus857009c2014-11-05 11:17:43 -0500289 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000290}
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
jfigus857009c2014-11-05 11:17:43 -0500301srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000302srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
303 uint32_t ssrc,
304 srtp_stream_ctx_t **str_ptr) {
jfigus857009c2014-11-05 11:17:43 -0500305 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +0000306 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 */
jfigused755f52014-11-19 14:57:19 -0500311 str = (srtp_stream_ctx_t *) srtp_crypto_alloc(sizeof(srtp_stream_ctx_t));
Cullen Jennings235513a2005-09-21 22:51:36 +0000312 if (str == NULL)
jfigus857009c2014-11-05 11:17:43 -0500313 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +0000314 *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 */
jfigusc7cdc9a2014-11-19 16:19:08 -0500323 status = srtp_key_limit_clone(stream_template->limit, &str->limit);
jfigus8c36da22013-10-01 16:41:19 -0400324 if (status) {
jfigused755f52014-11-19 14:57:19 -0500325 srtp_crypto_free(*str_ptr);
jfigus8c36da22013-10-01 16:41:19 -0400326 *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 */
jfigusde8deb32014-11-25 12:58:11 -0500331 status = srtp_rdbx_init(&str->rtp_rdbx,
332 srtp_rdbx_get_window_size(&stream_template->rtp_rdbx));
jfigus8c36da22013-10-01 16:41:19 -0400333 if (status) {
jfigused755f52014-11-19 14:57:19 -0500334 srtp_crypto_free(*str_ptr);
jfigus8c36da22013-10-01 16:41:19 -0400335 *str_ptr = NULL;
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000336 return status;
jfigus8c36da22013-10-01 16:41:19 -0400337 }
jfigusde8deb32014-11-25 12:58:11 -0500338 srtp_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
jfigus857009c2014-11-05 11:17:43 -0500359 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000360}
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 {
jfigus9a840432014-11-19 15:48:21 -0500395 srtp_cipher_t *cipher; /* cipher used for key derivation */
Cullen Jennings235513a2005-09-21 22:51:36 +0000396} srtp_kdf_t;
397
jfigus857009c2014-11-05 11:17:43 -0500398srtp_err_status_t
399srtp_kdf_init(srtp_kdf_t *kdf, srtp_cipher_type_id_t cipher_id, const uint8_t *key, int length) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000400
jfigus857009c2014-11-05 11:17:43 -0500401 srtp_err_status_t stat;
jfigus92736bc2014-11-21 10:30:54 -0500402 stat = srtp_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
jfigus857009c2014-11-05 11:17:43 -0500412 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000413}
414
jfigus857009c2014-11-05 11:17:43 -0500415srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000416srtp_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;
jfigus857009c2014-11-05 11:17:43 -0500420 srtp_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
jfigus857009c2014-11-05 11:17:43 -0500436 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000437}
438
jfigus857009c2014-11-05 11:17:43 -0500439srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000440srtp_kdf_clear(srtp_kdf_t *kdf) {
jfigus857009c2014-11-05 11:17:43 -0500441 srtp_err_status_t status;
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000442 status = cipher_dealloc(kdf->cipher);
443 if (status)
444 return status;
445 kdf->cipher = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +0000446
jfigus857009c2014-11-05 11:17:43 -0500447 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000448}
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. */
jfigus9a840432014-11-19 15:48:21 -0500462static inline int base_key_length(const srtp_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) {
jfigus67b9c732014-11-20 10:17:21 -0500465 case SRTP_AES_128_ICM:
466 case SRTP_AES_192_ICM:
467 case SRTP_AES_256_ICM:
jfigus8c36da22013-10-01 16:41:19 -0400468 /* The legacy modes are derived from
469 * the configured key length on the policy */
470 return key_length - 14;
471 break;
jfigus67b9c732014-11-20 10:17:21 -0500472 case SRTP_AES_128_GCM:
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000473 return 16;
jfigus8c36da22013-10-01 16:41:19 -0400474 break;
jfigus67b9c732014-11-20 10:17:21 -0500475 case SRTP_AES_256_GCM:
jfigus8c36da22013-10-01 16:41:19 -0400476 return 32;
477 break;
478 default:
479 return key_length;
480 break;
481 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000482}
483
jfigus857009c2014-11-05 11:17:43 -0500484srtp_err_status_t
David McGrew576e1482006-06-09 21:47:44 +0000485srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) {
jfigus857009c2014-11-05 11:17:43 -0500486 srtp_err_status_t stat;
David McGrew576e1482006-06-09 21:47:44 +0000487 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. */
jfigus9a840432014-11-19 15:48:21 -0500496 rtp_keylen = srtp_cipher_get_key_length(srtp->rtp_cipher);
497 rtcp_keylen = srtp_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 */
jfigus67b9c732014-11-20 10:17:21 -0500524 stat = srtp_kdf_init(&kdf, SRTP_AES_ICM, (const uint8_t *)tmp_key, kdf_keylen);
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000525 if (stat) {
jfigus857009c2014-11-05 11:17:43 -0500526 return srtp_err_status_init_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000527 }
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);
jfigus857009c2014-11-05 11:17:43 -0500535 return srtp_err_status_init_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000536 }
jfigus8719f952014-04-08 09:15:49 -0400537 debug_print(mod_srtp, "cipher key: %s",
jfigus46d6b472014-11-14 16:42:01 -0500538 srtp_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);
jfigus857009c2014-11-05 11:17:43 -0500553 return srtp_err_status_init_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000554 }
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",
jfigus46d6b472014-11-14 16:42:01 -0500559 srtp_octet_string_hex_string(tmp_key + rtp_base_key_len, rtp_salt_len));
Jonathan Lennoxc0f1f1b2012-04-26 23:16:00 +0000560 }
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);
jfigus857009c2014-11-05 11:17:43 -0500567 return srtp_err_status_init_fail;
David McGrew576e1482006-06-09 21:47:44 +0000568 }
569
570 /* generate authentication key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000571 stat = srtp_kdf_generate(&kdf, label_rtp_msg_auth,
jfigus8f669722014-11-19 15:20:03 -0500572 tmp_key, srtp_auth_get_key_length(srtp->rtp_auth));
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000573 if (stat) {
574 /* zeroize temp buffer */
575 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
jfigus857009c2014-11-05 11:17:43 -0500576 return srtp_err_status_init_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000577 }
David McGrew576e1482006-06-09 21:47:44 +0000578 debug_print(mod_srtp, "auth key: %s",
jfigus46d6b472014-11-14 16:42:01 -0500579 srtp_octet_string_hex_string(tmp_key,
jfigus8f669722014-11-19 15:20:03 -0500580 srtp_auth_get_key_length(srtp->rtp_auth)));
David McGrew576e1482006-06-09 21:47:44 +0000581
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);
jfigus857009c2014-11-05 11:17:43 -0500587 return srtp_err_status_init_fail;
David McGrew576e1482006-06-09 21:47:44 +0000588 }
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);
jfigus857009c2014-11-05 11:17:43 -0500604 return srtp_err_status_init_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000605 }
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);
jfigus857009c2014-11-05 11:17:43 -0500621 return srtp_err_status_init_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000622 }
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",
jfigus46d6b472014-11-14 16:42:01 -0500626 srtp_octet_string_hex_string(tmp_key, rtcp_base_key_len));
Jonathan Lennoxc0f1f1b2012-04-26 23:16:00 +0000627 if (rtcp_salt_len > 0) {
628 debug_print(mod_srtp, "rtcp cipher salt: %s",
jfigus46d6b472014-11-14 16:42:01 -0500629 srtp_octet_string_hex_string(tmp_key + rtcp_base_key_len, rtcp_salt_len));
Jonathan Lennoxc0f1f1b2012-04-26 23:16:00 +0000630 }
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);
jfigus857009c2014-11-05 11:17:43 -0500637 return srtp_err_status_init_fail;
David McGrew576e1482006-06-09 21:47:44 +0000638 }
639
640 /* generate authentication key */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000641 stat = srtp_kdf_generate(&kdf, label_rtcp_msg_auth,
jfigus8f669722014-11-19 15:20:03 -0500642 tmp_key, srtp_auth_get_key_length(srtp->rtcp_auth));
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000643 if (stat) {
644 /* zeroize temp buffer */
645 octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
jfigus857009c2014-11-05 11:17:43 -0500646 return srtp_err_status_init_fail;
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000647 }
648
David McGrew576e1482006-06-09 21:47:44 +0000649 debug_print(mod_srtp, "rtcp auth key: %s",
jfigus46d6b472014-11-14 16:42:01 -0500650 srtp_octet_string_hex_string(tmp_key,
jfigus8f669722014-11-19 15:20:03 -0500651 srtp_auth_get_key_length(srtp->rtcp_auth)));
David McGrew576e1482006-06-09 21:47:44 +0000652
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);
jfigus857009c2014-11-05 11:17:43 -0500658 return srtp_err_status_init_fail;
David McGrew576e1482006-06-09 21:47:44 +0000659 }
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)
jfigus857009c2014-11-05 11:17:43 -0500665 return srtp_err_status_init_fail;
David McGrew576e1482006-06-09 21:47:44 +0000666
jfigus857009c2014-11-05 11:17:43 -0500667 return srtp_err_status_ok;
David McGrew576e1482006-06-09 21:47:44 +0000668}
Cullen Jennings235513a2005-09-21 22:51:36 +0000669
jfigus857009c2014-11-05 11:17:43 -0500670srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000671srtp_stream_init(srtp_stream_ctx_t *srtp,
672 const srtp_policy_t *p) {
jfigus857009c2014-11-05 11:17:43 -0500673 srtp_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))
jfigus857009c2014-11-05 11:17:43 -0500684 return srtp_err_status_bad_param;
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000685
686 if (p->window_size != 0)
jfigusde8deb32014-11-25 12:58:11 -0500687 err = srtp_rdbx_init(&srtp->rtp_rdbx, p->window_size);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000688 else
jfigusde8deb32014-11-25 12:58:11 -0500689 err = srtp_rdbx_init(&srtp->rtp_rdbx, 128);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000690 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);
jfigusc7cdc9a2014-11-19 16:19:08 -0500697 srtp_key_limit_set(srtp->limit, temp);
Cullen Jennings235513a2005-09-21 22:51:36 +0000698}
699#else
jfigusc7cdc9a2014-11-19 16:19:08 -0500700 srtp_key_limit_set(srtp->limit, 0xffffffffffffLL);
Cullen Jennings235513a2005-09-21 22:51:36 +0000701#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 */
jfigusde8deb32014-11-25 12:58:11 -0500718 srtp_rdb_init(&srtp->rtcp_rdb);
Cullen Jennings235513a2005-09-21 22:51:36 +0000719
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) {
jfigusde8deb32014-11-25 12:58:11 -0500723 srtp_rdbx_dealloc(&srtp->rtp_rdbx);
jfigus857009c2014-11-05 11:17:43 -0500724 return srtp_err_status_bad_param;
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +0000725 }
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) {
jfigusde8deb32014-11-25 12:58:11 -0500733 srtp_rdbx_dealloc(&srtp->rtp_rdbx);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000734 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 */
jfigusc5887e72014-11-06 09:46:18 -0500741 err = srtp_ekt_stream_init_from_policy(srtp->ekt, p->ekt);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000742 if (err) {
jfigusde8deb32014-11-25 12:58:11 -0500743 srtp_rdbx_dealloc(&srtp->rtp_rdbx);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +0000744 return err;
745 }
David McGrew79870d62007-06-15 18:17:39 +0000746
jfigus857009c2014-11-05 11:17:43 -0500747 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000748 }
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
jfigus02d6f032014-11-21 10:56:42 -0500759 srtp_err_report(srtp_err_level_warning, "srtp: in stream 0x%x: ",
Cullen Jennings235513a2005-09-21 22:51:36 +0000760 data->stream->ssrc);
761
762 switch(data->event) {
763 case event_ssrc_collision:
jfigus02d6f032014-11-21 10:56:42 -0500764 srtp_err_report(srtp_err_level_warning, "\tSSRC collision\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000765 break;
766 case event_key_soft_limit:
jfigus02d6f032014-11-21 10:56:42 -0500767 srtp_err_report(srtp_err_level_warning, "\tkey usage soft limit reached\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000768 break;
769 case event_key_hard_limit:
jfigus02d6f032014-11-21 10:56:42 -0500770 srtp_err_report(srtp_err_level_warning, "\tkey usage hard limit reached\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000771 break;
772 case event_packet_index_limit:
jfigus02d6f032014-11-21 10:56:42 -0500773 srtp_err_report(srtp_err_level_warning, "\tpacket index limit reached\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000774 break;
775 default:
jfigus02d6f032014-11-21 10:56:42 -0500776 srtp_err_report(srtp_err_level_warning, "\tunknown event reported to handler\n");
Cullen Jennings235513a2005-09-21 22:51:36 +0000777 }
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
jfigus857009c2014-11-05 11:17:43 -0500792 srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +0000793 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;
jfigus857009c2014-11-05 11:17:43 -0500803 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000804 }
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,
jfigusde8deb32014-11-25 12:58:11 -0500835 srtp_xtd_seq_num_t *seq, srtp_hdr_t *hdr)
jfigus8c36da22013-10-01 16:41:19 -0400836{
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 */
jfigus857009c2014-11-05 11:17:43 -0500880static srtp_err_status_t
jfigus8c36da22013-10-01 16:41:19 -0400881srtp_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 */
jfigusde8deb32014-11-25 12:58:11 -0500887 srtp_xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
jfigus8c36da22013-10-01 16:41:19 -0400888 int delta; /* delta of local pkt idx and that in hdr */
jfigus857009c2014-11-05 11:17:43 -0500889 srtp_err_status_t status;
jfigus8c36da22013-10-01 16:41:19 -0400890 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 */
jfigusc7cdc9a2014-11-19 16:19:08 -0500901 switch (srtp_key_limit_update(stream->limit)) {
902 case srtp_key_event_normal:
jfigus8c36da22013-10-01 16:41:19 -0400903 break;
jfigusc7cdc9a2014-11-19 16:19:08 -0500904 case srtp_key_event_hard_limit:
jfigus8c36da22013-10-01 16:41:19 -0400905 srtp_handle_event(ctx, stream, event_key_hard_limit);
jfigus857009c2014-11-05 11:17:43 -0500906 return srtp_err_status_key_expired;
jfigusc7cdc9a2014-11-19 16:19:08 -0500907 case srtp_key_event_soft_limit:
jfigus8c36da22013-10-01 16:41:19 -0400908 default:
909 srtp_handle_event(ctx, stream, event_key_soft_limit);
910 break;
911 }
912
913 /* get tag length from stream */
jfigus8f669722014-11-19 15:20:03 -0500914 tag_len = srtp_auth_get_tag_length(stream->rtp_auth);
jfigus8c36da22013-10-01 16:41:19 -0400915
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))
jfigus857009c2014-11-05 11:17:43 -0500928 return srtp_err_status_parse_err;
Travis Cross3600c272014-06-29 17:32:33 +0000929 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 */
jfigusde8deb32014-11-25 12:58:11 -0500936 delta = srtp_rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
937 status = srtp_rdbx_check(&stream->rtp_rdbx, delta);
jfigus8c36da22013-10-01 16:41:19 -0400938 if (status) {
jfigus857009c2014-11-05 11:17:43 -0500939 if (status != srtp_err_status_replay_fail || !stream->allow_repeat_tx) {
jfigus8c36da22013-10-01 16:41:19 -0400940 return status; /* we've been asked to reuse an index */
941 }
942 } else {
jfigusde8deb32014-11-25 12:58:11 -0500943 srtp_rdbx_add_index(&stream->rtp_rdbx, delta);
jfigus8c36da22013-10-01 16:41:19 -0400944 }
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) {
jfigus857009c2014-11-05 11:17:43 -0500959 return srtp_err_status_cipher_fail;
jfigus8c36da22013-10-01 16:41:19 -0400960 }
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) {
jfigus857009c2014-11-05 11:17:43 -0500977 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -0400978 }
979
980 /* Encrypt the payload */
981 status = cipher_encrypt(stream->rtp_cipher,
982 (uint8_t*)enc_start, &enc_octet_len);
983 if (status) {
jfigus857009c2014-11-05 11:17:43 -0500984 return srtp_err_status_cipher_fail;
jfigus8c36da22013-10-01 16:41:19 -0400985 }
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) {
jfigus857009c2014-11-05 11:17:43 -0500993 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -0400994 }
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
jfigus857009c2014-11-05 11:17:43 -05001000 return srtp_err_status_ok;
jfigus8c36da22013-10-01 16:41:19 -04001001}
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 */
jfigus857009c2014-11-05 11:17:43 -05001011static srtp_err_status_t
jfigus8c36da22013-10-01 16:41:19 -04001012srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta,
jfigusde8deb32014-11-25 12:58:11 -05001013 srtp_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;
jfigus857009c2014-11-05 11:17:43 -05001019 srtp_err_status_t status;
jfigus8c36da22013-10-01 16:41:19 -04001020 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 */
jfigus8f669722014-11-19 15:20:03 -05001032 tag_len = srtp_auth_get_tag_length(stream->rtp_auth);
jfigus8c36da22013-10-01 16:41:19 -04001033
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) {
jfigus857009c2014-11-05 11:17:43 -05001040 return srtp_err_status_cipher_fail;
jfigus8c36da22013-10-01 16:41:19 -04001041 }
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))
jfigus857009c2014-11-05 11:17:43 -05001055 return srtp_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) {
jfigus857009c2014-11-05 11:17:43 -05001068 return srtp_err_status_cipher_fail;
jfigusc13c1002014-05-08 13:34:53 -04001069 }
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 */
jfigusc7cdc9a2014-11-19 16:19:08 -05001076 switch (srtp_key_limit_update(stream->limit)) {
1077 case srtp_key_event_normal:
jfigus8c36da22013-10-01 16:41:19 -04001078 break;
jfigusc7cdc9a2014-11-19 16:19:08 -05001079 case srtp_key_event_soft_limit:
jfigus8c36da22013-10-01 16:41:19 -04001080 srtp_handle_event(ctx, stream, event_key_soft_limit);
1081 break;
jfigusc7cdc9a2014-11-19 16:19:08 -05001082 case srtp_key_event_hard_limit:
jfigus8c36da22013-10-01 16:41:19 -04001083 srtp_handle_event(ctx, stream, event_key_hard_limit);
jfigus857009c2014-11-05 11:17:43 -05001084 return srtp_err_status_key_expired;
jfigus8c36da22013-10-01 16:41:19 -04001085 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) {
jfigus857009c2014-11-05 11:17:43 -05001095 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04001096 }
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 */
jfigusde8deb32014-11-25 12:58:11 -05001156 srtp_rdbx_add_index(&stream->rtp_rdbx, delta);
jfigus8c36da22013-10-01 16:41:19 -04001157
1158 /* decrease the packet length by the length of the auth tag */
1159 *pkt_octet_len -= tag_len;
1160
jfigus857009c2014-11-05 11:17:43 -05001161 return srtp_err_status_ok;
jfigus8c36da22013-10-01 16:41:19 -04001162}
1163
1164
1165
1166
jfigus857009c2014-11-05 11:17:43 -05001167 srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001168 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 */
jfigusde8deb32014-11-25 12:58:11 -05001173 srtp_xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
Cullen Jennings235513a2005-09-21 22:51:36 +00001174 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 */
jfigus857009c2014-11-05 11:17:43 -05001176 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001177 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)
jfigus857009c2014-11-05 11:17:43 -05001187 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001188
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 */
jfigus857009c2014-11-05 11:17:43 -05001218 return srtp_err_status_no_ctx;
Cullen Jennings235513a2005-09-21 22:51:36 +00001219 }
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 */
jfigus67b9c732014-11-20 10:17:21 -05001240 if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
1241 stream->rtp_cipher->algorithm == SRTP_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 */
jfigusc7cdc9a2014-11-19 16:19:08 -05001250 switch(srtp_key_limit_update(stream->limit)) {
1251 case srtp_key_event_normal:
Cullen Jennings235513a2005-09-21 22:51:36 +00001252 break;
jfigusc7cdc9a2014-11-19 16:19:08 -05001253 case srtp_key_event_soft_limit:
Cullen Jennings235513a2005-09-21 22:51:36 +00001254 srtp_handle_event(ctx, stream, event_key_soft_limit);
1255 break;
jfigusc7cdc9a2014-11-19 16:19:08 -05001256 case srtp_key_event_hard_limit:
Cullen Jennings235513a2005-09-21 22:51:36 +00001257 srtp_handle_event(ctx, stream, event_key_hard_limit);
jfigus857009c2014-11-05 11:17:43 -05001258 return srtp_err_status_key_expired;
Cullen Jennings235513a2005-09-21 22:51:36 +00001259 default:
1260 break;
1261 }
1262
1263 /* get tag length from stream */
jfigus8f669722014-11-19 15:20:03 -05001264 tag_len = srtp_auth_get_tag_length(stream->rtp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00001265
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))
jfigus857009c2014-11-05 11:17:43 -05001280 return srtp_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 */
jfigusde8deb32014-11-25 12:58:11 -05001305 delta = srtp_rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
1306 status = srtp_rdbx_check(&stream->rtp_rdbx, delta);
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001307 if (status) {
jfigus857009c2014-11-05 11:17:43 -05001308 if (status != srtp_err_status_replay_fail || !stream->allow_repeat_tx)
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001309 return status; /* we've been asked to reuse an index */
1310 }
1311 else
jfigusde8deb32014-11-25 12:58:11 -05001312 srtp_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 */
jfigus67b9c732014-11-20 10:17:21 -05001324 if (stream->rtp_cipher->type->id == SRTP_AES_ICM ||
1325 stream->rtp_cipher->type->id == SRTP_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)
jfigus857009c2014-11-05 11:17:43 -05001352 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001353
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
jfigus8f669722014-11-19 15:20:03 -05001369 prefix_len = srtp_auth_get_prefix_length(stream->rtp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00001370 if (prefix_len) {
jfigus9a840432014-11-19 15:48:21 -05001371 status = srtp_cipher_output(stream->rtp_cipher, auth_tag, prefix_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001372 if (status)
jfigus857009c2014-11-05 11:17:43 -05001373 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001374 debug_print(mod_srtp, "keystream prefix: %s",
jfigus46d6b472014-11-14 16:42:01 -05001375 srtp_octet_string_hex_string(auth_tag, prefix_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001376 }
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)
jfigus857009c2014-11-05 11:17:43 -05001384 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001385 }
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",
jfigus46d6b472014-11-14 16:42:01 -05001406 srtp_octet_string_hex_string(auth_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001407 if (status)
jfigus857009c2014-11-05 11:17:43 -05001408 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001409
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
jfigus857009c2014-11-05 11:17:43 -05001418 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001419}
1420
1421
jfigus857009c2014-11-05 11:17:43 -05001422srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001423srtp_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 */
jfigusde8deb32014-11-25 12:58:11 -05001429 srtp_xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
Cullen Jennings235513a2005-09-21 22:51:36 +00001430 int delta; /* delta of local pkt idx and that in hdr */
1431 v128_t iv;
jfigus857009c2014-11-05 11:17:43 -05001432 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001433 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)
jfigus857009c2014-11-05 11:17:43 -05001443 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001444
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
jfigusde8deb32014-11-25 12:58:11 -05001464 est = (srtp_xtd_seq_num_t) make64(0,ntohs(hdr->seq));
Cullen Jennings235513a2005-09-21 22:51:36 +00001465 delta = low32(est);
1466#else
jfigusde8deb32014-11-25 12:58:11 -05001467 est = (srtp_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 */
jfigus857009c2014-11-05 11:17:43 -05001476 return srtp_err_status_no_ctx;
Cullen Jennings235513a2005-09-21 22:51:36 +00001477 }
1478 } else {
1479
1480 /* estimate packet index from seq. num. in header */
jfigusde8deb32014-11-25 12:58:11 -05001481 delta = srtp_rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001482
1483 /* check replay database */
jfigusde8deb32014-11-25 12:58:11 -05001484 status = srtp_rdbx_check(&stream->rtp_rdbx, delta);
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001485 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 */
jfigus67b9c732014-11-20 10:17:21 -05001499 if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
1500 stream->rtp_cipher->algorithm == SRTP_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 */
jfigus8f669722014-11-19 15:20:03 -05001505 tag_len = srtp_auth_get_tag_length(stream->rtp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00001506
1507 /*
1508 * set the cipher's IV properly, depending on whatever cipher we
1509 * happen to be using
1510 */
jfigus67b9c732014-11-20 10:17:21 -05001511 if (stream->rtp_cipher->type->id == SRTP_AES_ICM ||
1512 stream->rtp_cipher->type->id == SRTP_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)
jfigus857009c2014-11-05 11:17:43 -05001537 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001538
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))
jfigus857009c2014-11-05 11:17:43 -05001563 return srtp_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
jfigus8f669722014-11-19 15:20:03 -05001598 prefix_len = srtp_auth_get_prefix_length(stream->rtp_auth);
jfigus9a840432014-11-19 15:48:21 -05001599 status = srtp_cipher_output(stream->rtp_cipher, tmp_tag, prefix_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001600 debug_print(mod_srtp, "keystream prefix: %s",
jfigus46d6b472014-11-14 16:42:01 -05001601 srtp_octet_string_hex_string(tmp_tag, prefix_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001602 if (status)
jfigus857009c2014-11-05 11:17:43 -05001603 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001604 }
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",
jfigus46d6b472014-11-14 16:42:01 -05001618 srtp_octet_string_hex_string(tmp_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001619 debug_print(mod_srtp, "packet auth tag: %s",
jfigus46d6b472014-11-14 16:42:01 -05001620 srtp_octet_string_hex_string(auth_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001621 if (status)
jfigus857009c2014-11-05 11:17:43 -05001622 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001623
1624 if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
jfigus857009c2014-11-05 11:17:43 -05001625 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001626 }
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 */
jfigusc7cdc9a2014-11-19 16:19:08 -05001633 switch(srtp_key_limit_update(stream->limit)) {
1634 case srtp_key_event_normal:
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001635 break;
jfigusc7cdc9a2014-11-19 16:19:08 -05001636 case srtp_key_event_soft_limit:
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001637 srtp_handle_event(ctx, stream, event_key_soft_limit);
1638 break;
jfigusc7cdc9a2014-11-19 16:19:08 -05001639 case srtp_key_event_hard_limit:
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001640 srtp_handle_event(ctx, stream, event_key_hard_limit);
jfigus857009c2014-11-05 11:17:43 -05001641 return srtp_err_status_key_expired;
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001642 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)
jfigus857009c2014-11-05 11:17:43 -05001651 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001652 }
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 */
jfigusde8deb32014-11-25 12:58:11 -05001703 srtp_rdbx_add_index(&stream->rtp_rdbx, delta);
Cullen Jennings235513a2005-09-21 22:51:36 +00001704
1705 /* decrease the packet length by the length of the auth tag */
1706 *pkt_octet_len -= tag_len;
1707
jfigus857009c2014-11-05 11:17:43 -05001708 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001709}
1710
jfigus857009c2014-11-05 11:17:43 -05001711srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001712srtp_init() {
jfigus857009c2014-11-05 11:17:43 -05001713 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001714
1715 /* initialize crypto kernel */
jfigus92736bc2014-11-21 10:30:54 -05001716 status = srtp_crypto_kernel_init();
Cullen Jennings235513a2005-09-21 22:51:36 +00001717 if (status)
1718 return status;
1719
1720 /* load srtp debug module into the kernel */
jfigus92736bc2014-11-21 10:30:54 -05001721 status = srtp_crypto_kernel_load_debug_module(&mod_srtp);
Cullen Jennings235513a2005-09-21 22:51:36 +00001722 if (status)
1723 return status;
1724
jfigus857009c2014-11-05 11:17:43 -05001725 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001726}
1727
jfigus857009c2014-11-05 11:17:43 -05001728srtp_err_status_t
Jonathan Lennox5ae76332010-05-15 04:48:59 +00001729srtp_shutdown() {
jfigus857009c2014-11-05 11:17:43 -05001730 srtp_err_status_t status;
Jonathan Lennox5ae76332010-05-15 04:48:59 +00001731
1732 /* shut down crypto kernel */
jfigus92736bc2014-11-21 10:30:54 -05001733 status = srtp_crypto_kernel_shutdown();
Jonathan Lennox5ae76332010-05-15 04:48:59 +00001734 if (status)
1735 return status;
1736
1737 /* shutting down crypto kernel frees the srtp debug module as well */
1738
jfigus857009c2014-11-05 11:17:43 -05001739 return srtp_err_status_ok;
Jonathan Lennox5ae76332010-05-15 04:48:59 +00001740}
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) {
jfigus8f669722014-11-19 15:20:03 -05001757 return srtp_auth_get_tag_length(s->rtp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00001758}
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
jfigus857009c2014-11-05 11:17:43 -05001785srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001786srtp_dealloc(srtp_t session) {
1787 srtp_stream_ctx_t *stream;
jfigus857009c2014-11-05 11:17:43 -05001788 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001789
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;
jfigused755f52014-11-19 14:57:19 -05001814 srtp_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;
jfigusde8deb32014-11-25 12:58:11 -05001821 status = srtp_rdbx_dealloc(&session->stream_template->rtp_rdbx);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001822 if (status)
1823 return status;
jfigused755f52014-11-19 14:57:19 -05001824 srtp_crypto_free(session->stream_template);
Cullen Jennings235513a2005-09-21 22:51:36 +00001825 }
1826
1827 /* deallocate session context */
jfigused755f52014-11-19 14:57:19 -05001828 srtp_crypto_free(session);
Cullen Jennings235513a2005-09-21 22:51:36 +00001829
jfigus857009c2014-11-05 11:17:43 -05001830 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001831}
1832
1833
jfigus857009c2014-11-05 11:17:43 -05001834srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001835srtp_add_stream(srtp_t session,
1836 const srtp_policy_t *policy) {
jfigus857009c2014-11-05 11:17:43 -05001837 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001838 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))
jfigus857009c2014-11-05 11:17:43 -05001842 return srtp_err_status_bad_param;
Marcus Sundberg67398e62005-10-05 12:39:51 +00001843
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) {
jfigused755f52014-11-19 14:57:19 -05001853 srtp_crypto_free(tmp);
Cullen Jennings235513a2005-09-21 22:51:36 +00001854 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) {
jfigus857009c2014-11-05 11:17:43 -05001868 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001869 }
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) {
jfigus857009c2014-11-05 11:17:43 -05001875 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001876 }
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:
jfigused755f52014-11-19 14:57:19 -05001886 srtp_crypto_free(tmp);
jfigus857009c2014-11-05 11:17:43 -05001887 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001888 }
1889
jfigus857009c2014-11-05 11:17:43 -05001890 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001891}
1892
1893
jfigus857009c2014-11-05 11:17:43 -05001894srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001895srtp_create(srtp_t *session, /* handle for session */
1896 const srtp_policy_t *policy) { /* SRTP policy (list) */
jfigus857009c2014-11-05 11:17:43 -05001897 srtp_err_status_t stat;
Cullen Jennings235513a2005-09-21 22:51:36 +00001898 srtp_ctx_t *ctx;
1899
1900 /* sanity check arguments */
Marcus Sundberg67398e62005-10-05 12:39:51 +00001901 if (session == NULL)
jfigus857009c2014-11-05 11:17:43 -05001902 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001903
1904 /* allocate srtp context and set ctx_ptr */
jfigused755f52014-11-19 14:57:19 -05001905 ctx = (srtp_ctx_t *) srtp_crypto_alloc(sizeof(srtp_ctx_t));
Cullen Jennings235513a2005-09-21 22:51:36 +00001906 if (ctx == NULL)
jfigus857009c2014-11-05 11:17:43 -05001907 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001908 *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
jfigus857009c2014-11-05 11:17:43 -05001930 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001931}
1932
1933
jfigus857009c2014-11-05 11:17:43 -05001934srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001935srtp_remove_stream(srtp_t session, uint32_t ssrc) {
1936 srtp_stream_ctx_t *stream, *last_stream;
jfigus857009c2014-11-05 11:17:43 -05001937 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001938
1939 /* sanity check arguments */
1940 if (session == NULL)
jfigus857009c2014-11-05 11:17:43 -05001941 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001942
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)
jfigus857009c2014-11-05 11:17:43 -05001950 return srtp_err_status_no_ctx;
Cullen Jennings235513a2005-09-21 22:51:36 +00001951
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
jfigus857009c2014-11-05 11:17:43 -05001964 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001965}
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
jfigus857009c2014-11-05 11:17:43 -05001983srtp_crypto_policy_set_rtp_default(srtp_crypto_policy_t *p) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001984
jfigus67b9c732014-11-20 10:17:21 -05001985 p->cipher_type = SRTP_AES_ICM;
Cullen Jennings235513a2005-09-21 22:51:36 +00001986 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
jfigus67b9c732014-11-20 10:17:21 -05001987 p->auth_type = SRTP_HMAC_SHA1;
Cullen Jennings235513a2005-09-21 22:51:36 +00001988 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
jfigus857009c2014-11-05 11:17:43 -05001995srtp_crypto_policy_set_rtcp_default(srtp_crypto_policy_t *p) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001996
jfigus67b9c732014-11-20 10:17:21 -05001997 p->cipher_type = SRTP_AES_ICM;
Cullen Jennings235513a2005-09-21 22:51:36 +00001998 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
jfigus67b9c732014-11-20 10:17:21 -05001999 p->auth_type = SRTP_HMAC_SHA1;
Cullen Jennings235513a2005-09-21 22:51:36 +00002000 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
jfigus857009c2014-11-05 11:17:43 -05002007srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(srtp_crypto_policy_t *p) {
David McGrewa8546882006-01-12 17:56:02 +00002008
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
jfigus67b9c732014-11-20 10:17:21 -05002015 p->cipher_type = SRTP_AES_ICM;
David McGrewa8546882006-01-12 17:56:02 +00002016 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
jfigus67b9c732014-11-20 10:17:21 -05002017 p->auth_type = SRTP_HMAC_SHA1;
David McGrewa8546882006-01-12 17:56:02 +00002018 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
jfigus857009c2014-11-05 11:17:43 -05002026srtp_crypto_policy_set_aes_cm_128_null_auth(srtp_crypto_policy_t *p) {
David McGrewa8546882006-01-12 17:56:02 +00002027
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
jfigus67b9c732014-11-20 10:17:21 -05002034 p->cipher_type = SRTP_AES_ICM;
David McGrewa8546882006-01-12 17:56:02 +00002035 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
jfigus67b9c732014-11-20 10:17:21 -05002036 p->auth_type = SRTP_NULL_AUTH;
David McGrewa8546882006-01-12 17:56:02 +00002037 p->auth_key_len = 0;
2038 p->auth_tag_len = 0;
2039 p->sec_serv = sec_serv_conf;
2040
2041}
2042
2043
2044void
jfigus857009c2014-11-05 11:17:43 -05002045srtp_crypto_policy_set_null_cipher_hmac_sha1_80(srtp_crypto_policy_t *p) {
David McGrewa8546882006-01-12 17:56:02 +00002046
2047 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00002048 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00002049 */
2050
jfigus67b9c732014-11-20 10:17:21 -05002051 p->cipher_type = SRTP_NULL_CIPHER;
David McGrewa8546882006-01-12 17:56:02 +00002052 p->cipher_key_len = 0;
jfigus67b9c732014-11-20 10:17:21 -05002053 p->auth_type = SRTP_HMAC_SHA1;
David McGrewa8546882006-01-12 17:56:02 +00002054 p->auth_key_len = 20;
2055 p->auth_tag_len = 10;
2056 p->sec_serv = sec_serv_auth;
2057
2058}
2059
jfigus267956d2014-11-06 10:49:21 -05002060void
2061srtp_crypto_policy_set_null_cipher_hmac_null(srtp_crypto_policy_t *p) {
2062
2063 /*
2064 * Should only be used for testing
2065 */
2066
jfigus67b9c732014-11-20 10:17:21 -05002067 p->cipher_type = SRTP_NULL_CIPHER;
jfigus267956d2014-11-06 10:49:21 -05002068 p->cipher_key_len = 0;
jfigus67b9c732014-11-20 10:17:21 -05002069 p->auth_type = SRTP_NULL_AUTH;
jfigus267956d2014-11-06 10:49:21 -05002070 p->auth_key_len = 0;
2071 p->auth_tag_len = 0;
2072 p->sec_serv = sec_serv_none;
2073
2074}
2075
David McGrewa8546882006-01-12 17:56:02 +00002076
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002077void
jfigus857009c2014-11-05 11:17:43 -05002078srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(srtp_crypto_policy_t *p) {
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002079
2080 /*
2081 * corresponds to draft-ietf-avt-big-aes-03.txt
2082 */
2083
jfigus67b9c732014-11-20 10:17:21 -05002084 p->cipher_type = SRTP_AES_ICM;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002085 p->cipher_key_len = 46;
jfigus67b9c732014-11-20 10:17:21 -05002086 p->auth_type = SRTP_HMAC_SHA1;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002087 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
2088 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
2089 p->sec_serv = sec_serv_conf_and_auth;
2090}
2091
2092
2093void
jfigus857009c2014-11-05 11:17:43 -05002094srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(srtp_crypto_policy_t *p) {
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002095
2096 /*
2097 * corresponds to draft-ietf-avt-big-aes-03.txt
2098 *
2099 * note that this crypto policy is intended for SRTP, but not SRTCP
2100 */
2101
jfigus67b9c732014-11-20 10:17:21 -05002102 p->cipher_type = SRTP_AES_ICM;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002103 p->cipher_key_len = 46;
jfigus67b9c732014-11-20 10:17:21 -05002104 p->auth_type = SRTP_HMAC_SHA1;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002105 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
2106 p->auth_tag_len = 4; /* default 80 bits per RFC 3711 */
2107 p->sec_serv = sec_serv_conf_and_auth;
2108}
2109
jfigus8c36da22013-10-01 16:41:19 -04002110/*
2111 * AES-256 with no authentication.
2112 */
2113void
jfigus857009c2014-11-05 11:17:43 -05002114srtp_crypto_policy_set_aes_cm_256_null_auth (srtp_crypto_policy_t *p)
jfigus8c36da22013-10-01 16:41:19 -04002115{
jfigus67b9c732014-11-20 10:17:21 -05002116 p->cipher_type = SRTP_AES_ICM;
jfigus8c36da22013-10-01 16:41:19 -04002117 p->cipher_key_len = 46;
jfigus67b9c732014-11-20 10:17:21 -05002118 p->auth_type = SRTP_NULL_AUTH;
jfigus8c36da22013-10-01 16:41:19 -04002119 p->auth_key_len = 0;
2120 p->auth_tag_len = 0;
2121 p->sec_serv = sec_serv_conf;
2122}
2123
2124#ifdef OPENSSL
2125/*
2126 * AES-128 GCM mode with 8 octet auth tag.
2127 */
2128void
jfigus857009c2014-11-05 11:17:43 -05002129srtp_crypto_policy_set_aes_gcm_128_8_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002130 p->cipher_type = SRTP_AES_128_GCM;
jfigus857009c2014-11-05 11:17:43 -05002131 p->cipher_key_len = SRTP_AES_128_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002132 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigus8c36da22013-10-01 16:41:19 -04002133 p->auth_key_len = 0;
2134 p->auth_tag_len = 8; /* 8 octet tag length */
2135 p->sec_serv = sec_serv_conf_and_auth;
2136}
2137
2138/*
2139 * AES-256 GCM mode with 8 octet auth tag.
2140 */
2141void
jfigus857009c2014-11-05 11:17:43 -05002142srtp_crypto_policy_set_aes_gcm_256_8_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002143 p->cipher_type = SRTP_AES_256_GCM;
jfigus857009c2014-11-05 11:17:43 -05002144 p->cipher_key_len = SRTP_AES_256_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002145 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigus8c36da22013-10-01 16:41:19 -04002146 p->auth_key_len = 0;
2147 p->auth_tag_len = 8; /* 8 octet tag length */
2148 p->sec_serv = sec_serv_conf_and_auth;
2149}
2150
2151/*
2152 * AES-128 GCM mode with 8 octet auth tag, no RTCP encryption.
2153 */
2154void
jfigus857009c2014-11-05 11:17:43 -05002155srtp_crypto_policy_set_aes_gcm_128_8_only_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002156 p->cipher_type = SRTP_AES_128_GCM;
jfigus857009c2014-11-05 11:17:43 -05002157 p->cipher_key_len = SRTP_AES_128_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002158 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigus8c36da22013-10-01 16:41:19 -04002159 p->auth_key_len = 0;
2160 p->auth_tag_len = 8; /* 8 octet tag length */
2161 p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
2162}
2163
2164/*
2165 * AES-256 GCM mode with 8 octet auth tag, no RTCP encryption.
2166 */
2167void
jfigus857009c2014-11-05 11:17:43 -05002168srtp_crypto_policy_set_aes_gcm_256_8_only_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002169 p->cipher_type = SRTP_AES_256_GCM;
jfigus857009c2014-11-05 11:17:43 -05002170 p->cipher_key_len = SRTP_AES_256_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002171 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigus8c36da22013-10-01 16:41:19 -04002172 p->auth_key_len = 0;
2173 p->auth_tag_len = 8; /* 8 octet tag length */
2174 p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
2175}
jfigusc13c1002014-05-08 13:34:53 -04002176
2177/*
2178 * AES-128 GCM mode with 16 octet auth tag.
2179 */
2180void
jfigus857009c2014-11-05 11:17:43 -05002181srtp_crypto_policy_set_aes_gcm_128_16_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002182 p->cipher_type = SRTP_AES_128_GCM;
jfigus857009c2014-11-05 11:17:43 -05002183 p->cipher_key_len = SRTP_AES_128_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002184 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigusc13c1002014-05-08 13:34:53 -04002185 p->auth_key_len = 0;
2186 p->auth_tag_len = 16; /* 16 octet tag length */
2187 p->sec_serv = sec_serv_conf_and_auth;
2188}
2189
2190/*
2191 * AES-256 GCM mode with 16 octet auth tag.
2192 */
2193void
jfigus857009c2014-11-05 11:17:43 -05002194srtp_crypto_policy_set_aes_gcm_256_16_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002195 p->cipher_type = SRTP_AES_256_GCM;
jfigus857009c2014-11-05 11:17:43 -05002196 p->cipher_key_len = SRTP_AES_256_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002197 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigusc13c1002014-05-08 13:34:53 -04002198 p->auth_key_len = 0;
2199 p->auth_tag_len = 16; /* 16 octet tag length */
2200 p->sec_serv = sec_serv_conf_and_auth;
2201}
2202
jfigus8c36da22013-10-01 16:41:19 -04002203#endif
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002204
Cullen Jennings235513a2005-09-21 22:51:36 +00002205/*
2206 * secure rtcp functions
2207 */
2208
jfigus8c36da22013-10-01 16:41:19 -04002209/*
2210 * AEAD uses a new IV formation method. This function implements
2211 * section 10.1 from draft-ietf-avtcore-srtp-aes-gcm-07.txt. The
2212 * calculation is defined as, where (+) is the xor operation:
2213 *
2214 * 0 1 2 3 4 5 6 7 8 9 10 11
2215 * +--+--+--+--+--+--+--+--+--+--+--+--+
2216 * |00|00| SSRC |00|00|0+SRTCP Idx|---+
2217 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2218 * |
2219 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2220 * | Encryption Salt |->(+)
2221 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2222 * |
2223 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2224 * | Initialization Vector |<--+
2225 * +--+--+--+--+--+--+--+--+--+--+--+--+*
2226 *
2227 * Input: *stream - pointer to SRTP stream context, used to retrieve
2228 * the SALT
2229 * *iv - Pointer to recieve the calculated IV
2230 * seq_num - The SEQ value to use for the IV calculation.
2231 * *hdr - The RTP header, used to get the SSRC value
2232 *
2233 */
2234static void srtp_calc_aead_iv_srtcp(srtp_stream_ctx_t *stream, v128_t *iv,
2235 uint32_t seq_num, srtcp_hdr_t *hdr)
2236{
2237 v128_t in;
2238 v128_t salt;
2239
2240 memset(&in, 0, sizeof(v128_t));
2241 memset(&salt, 0, sizeof(v128_t));
2242
2243 in.v16[0] = 0;
2244 memcpy(&in.v16[1], &hdr->ssrc, 4); /* still in network order! */
2245 in.v16[3] = 0;
2246 in.v32[2] = 0x7FFFFFFF & htonl(seq_num); /* bit 32 is suppose to be zero */
2247
2248 debug_print(mod_srtp, "Pre-salted RTCP IV = %s\n", v128_hex_string(&in));
2249
2250 /*
2251 * Get the SALT value from the context
2252 */
2253 memcpy(salt.v8, stream->c_salt, 12);
2254 debug_print(mod_srtp, "RTCP SALT = %s\n", v128_hex_string(&salt));
2255
2256 /*
2257 * Finally, apply the SALT to the input
2258 */
2259 v128_xor(iv, &in, &salt);
2260}
2261
2262/*
2263 * This code handles AEAD ciphers for outgoing RTCP. We currently support
2264 * AES-GCM mode with 128 or 256 bit keys.
2265 */
jfigus857009c2014-11-05 11:17:43 -05002266static srtp_err_status_t
jfigus8c36da22013-10-01 16:41:19 -04002267srtp_protect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream,
Travis Cross31844002014-07-02 16:18:57 +00002268 void *rtcp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -04002269{
2270 srtcp_hdr_t *hdr = (srtcp_hdr_t*)rtcp_hdr;
2271 uint32_t *enc_start; /* pointer to start of encrypted portion */
2272 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002273 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -04002274 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
jfigus857009c2014-11-05 11:17:43 -05002275 srtp_err_status_t status;
jfigus8c36da22013-10-01 16:41:19 -04002276 int tag_len;
2277 uint32_t seq_num;
2278 v128_t iv;
2279 uint32_t tseq;
2280
2281 /* get tag length from stream context */
jfigus8f669722014-11-19 15:20:03 -05002282 tag_len = srtp_auth_get_tag_length(stream->rtcp_auth);
jfigus8c36da22013-10-01 16:41:19 -04002283
2284 /*
2285 * set encryption start and encryption length - if we're not
2286 * providing confidentiality, set enc_start to NULL
2287 */
2288 enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header;
2289 enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
2290
2291 /* NOTE: hdr->length is not usable - it refers to only the first
2292 RTCP report in the compound packet! */
2293 /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2294 multiples of 32-bits (RFC 3550 6.1) */
2295 trailer = (uint32_t*)((char*)enc_start + enc_octet_len + tag_len);
2296
2297 if (stream->rtcp_services & sec_serv_conf) {
2298 *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
2299 } else {
2300 enc_start = NULL;
2301 enc_octet_len = 0;
2302 /* 0 is network-order independant */
2303 *trailer = 0x00000000; /* set encrypt bit */
2304 }
2305
2306 /*
2307 * set the auth_tag pointer to the proper location, which is after
2308 * the payload, but before the trailer
2309 * (note that srtpc *always* provides authentication, unlike srtp)
2310 */
2311 /* Note: This would need to change for optional mikey data */
2312 auth_tag = (uint8_t*)hdr + *pkt_octet_len;
2313
2314 /*
2315 * check sequence number for overruns, and copy it into the packet
2316 * if its value isn't too big
2317 */
jfigusde8deb32014-11-25 12:58:11 -05002318 status = srtp_rdb_increment(&stream->rtcp_rdb);
jfigus8c36da22013-10-01 16:41:19 -04002319 if (status) {
2320 return status;
2321 }
jfigusde8deb32014-11-25 12:58:11 -05002322 seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
jfigus8c36da22013-10-01 16:41:19 -04002323 *trailer |= htonl(seq_num);
2324 debug_print(mod_srtp, "srtcp index: %x", seq_num);
2325
2326 /*
2327 * Calculating the IV and pass it down to the cipher
2328 */
2329 srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
2330 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
2331 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002332 return srtp_err_status_cipher_fail;
jfigus8c36da22013-10-01 16:41:19 -04002333 }
2334
2335 /*
2336 * Set the AAD for GCM mode
2337 */
2338 if (enc_start) {
2339 /*
2340 * If payload encryption is enabled, then the AAD consist of
2341 * the RTCP header and the seq# at the end of the packet
2342 */
2343 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2344 octets_in_rtcp_header);
2345 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002346 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002347 }
2348 } else {
2349 /*
2350 * Since payload encryption is not enabled, we must authenticate
2351 * the entire packet as described in section 10.3 in revision 07
2352 * of the draft.
2353 */
2354 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2355 *pkt_octet_len);
2356 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002357 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002358 }
2359 }
2360 /*
2361 * put the idx# into network byte order and process it as AAD
2362 */
2363 tseq = htonl(*trailer);
2364 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq,
2365 sizeof(srtcp_trailer_t));
2366 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002367 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002368 }
2369
2370 /* if we're encrypting, exor keystream into the message */
2371 if (enc_start) {
2372 status = cipher_encrypt(stream->rtcp_cipher,
2373 (uint8_t*)enc_start, &enc_octet_len);
2374 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002375 return srtp_err_status_cipher_fail;
jfigus8c36da22013-10-01 16:41:19 -04002376 }
2377 /*
2378 * Get the tag and append that to the output
2379 */
2380 status = cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag,
2381 &tag_len);
2382 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002383 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002384 }
2385 enc_octet_len += tag_len;
2386 } else {
2387 /*
2388 * Even though we're not encrypting the payload, we need
2389 * to run the cipher to get the auth tag.
2390 */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002391 unsigned int nolen = 0;
jfigus8c36da22013-10-01 16:41:19 -04002392 status = cipher_encrypt(stream->rtcp_cipher, NULL, &nolen);
2393 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002394 return srtp_err_status_cipher_fail;
jfigus8c36da22013-10-01 16:41:19 -04002395 }
2396 /*
2397 * Get the tag and append that to the output
2398 */
2399 status = cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag,
2400 &tag_len);
2401 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002402 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002403 }
2404 enc_octet_len += tag_len;
2405 }
2406
2407 /* increase the packet length by the length of the auth tag and seq_num*/
2408 *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
2409
jfigus857009c2014-11-05 11:17:43 -05002410 return srtp_err_status_ok;
jfigus8c36da22013-10-01 16:41:19 -04002411}
2412
2413/*
2414 * This function handles incoming SRTCP packets while in AEAD mode,
2415 * which currently supports AES-GCM encryption. Note, the auth tag is
2416 * at the end of the packet stream and is automatically checked by GCM
2417 * when decrypting the payload.
2418 */
jfigus857009c2014-11-05 11:17:43 -05002419static srtp_err_status_t
jfigus8c36da22013-10-01 16:41:19 -04002420srtp_unprotect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream,
Travis Cross31844002014-07-02 16:18:57 +00002421 void *srtcp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -04002422{
2423 srtcp_hdr_t *hdr = (srtcp_hdr_t*)srtcp_hdr;
2424 uint32_t *enc_start; /* pointer to start of encrypted portion */
2425 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002426 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -04002427 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
jfigus857009c2014-11-05 11:17:43 -05002428 srtp_err_status_t status;
jfigus8c36da22013-10-01 16:41:19 -04002429 int tag_len;
2430 unsigned int tmp_len;
2431 uint32_t seq_num;
2432 v128_t iv;
2433 uint32_t tseq;
2434
2435 /* get tag length from stream context */
jfigus8f669722014-11-19 15:20:03 -05002436 tag_len = srtp_auth_get_tag_length(stream->rtcp_auth);
jfigus8c36da22013-10-01 16:41:19 -04002437
jfigus8c36da22013-10-01 16:41:19 -04002438 /*
2439 * set encryption start, encryption length, and trailer
2440 */
2441 /* index & E (encryption) bit follow normal data. hdr->len
2442 is the number of words (32-bit) in the normal packet minus 1 */
2443 /* This should point trailer to the word past the end of the
2444 normal data. */
2445 /* This would need to be modified for optional mikey data */
2446 /*
2447 * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2448 * multiples of 32-bits (RFC 3550 6.1)
2449 */
2450 trailer = (uint32_t*)((char*)hdr + *pkt_octet_len - sizeof(srtcp_trailer_t));
2451 /*
2452 * We pass the tag down to the cipher when doing GCM mode
2453 */
2454 enc_octet_len = *pkt_octet_len - (octets_in_rtcp_header +
2455 sizeof(srtcp_trailer_t));
2456 auth_tag = (uint8_t*)hdr + *pkt_octet_len - tag_len - sizeof(srtcp_trailer_t);
2457
2458 if (*((unsigned char*)trailer) & SRTCP_E_BYTE_BIT) {
2459 enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header;
2460 } else {
2461 enc_octet_len = 0;
2462 enc_start = NULL; /* this indicates that there's no encryption */
2463 }
2464
2465 /*
2466 * check the sequence number for replays
2467 */
2468 /* this is easier than dealing with bitfield access */
2469 seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
2470 debug_print(mod_srtp, "srtcp index: %x", seq_num);
jfigusde8deb32014-11-25 12:58:11 -05002471 status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
jfigus8c36da22013-10-01 16:41:19 -04002472 if (status) {
2473 return status;
2474 }
2475
2476 /*
2477 * Calculate and set the IV
2478 */
2479 srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
2480 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
2481 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002482 return srtp_err_status_cipher_fail;
jfigus8c36da22013-10-01 16:41:19 -04002483 }
2484
2485 /*
2486 * Set the AAD for GCM mode
2487 */
2488 if (enc_start) {
2489 /*
2490 * If payload encryption is enabled, then the AAD consist of
2491 * the RTCP header and the seq# at the end of the packet
2492 */
2493 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2494 octets_in_rtcp_header);
2495 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002496 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002497 }
2498 } else {
2499 /*
2500 * Since payload encryption is not enabled, we must authenticate
2501 * the entire packet as described in section 10.3 in revision 07
2502 * of the draft.
2503 */
2504 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2505 (*pkt_octet_len - tag_len - sizeof(srtcp_trailer_t)));
2506 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002507 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002508 }
2509 }
2510
2511 /*
2512 * put the idx# into network byte order, and process it as AAD
2513 */
2514 tseq = htonl(*trailer);
2515 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq,
2516 sizeof(srtcp_trailer_t));
2517 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002518 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002519 }
2520
2521 /* if we're decrypting, exor keystream into the message */
2522 if (enc_start) {
2523 status = cipher_decrypt(stream->rtcp_cipher,
2524 (uint8_t*)enc_start, &enc_octet_len);
2525 if (status) {
2526 return status;
2527 }
2528 } else {
2529 /*
2530 * Still need to run the cipher to check the tag
2531 */
2532 tmp_len = tag_len;
2533 status = cipher_decrypt(stream->rtcp_cipher, (uint8_t*)auth_tag,
2534 &tmp_len);
2535 if (status) {
2536 return status;
2537 }
2538 }
2539
2540 /* decrease the packet length by the length of the auth tag and seq_num*/
2541 *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
2542
2543 /*
2544 * verify that stream is for received traffic - this check will
2545 * detect SSRC collisions, since a stream that appears in both
2546 * srtp_protect() and srtp_unprotect() will fail this test in one of
2547 * those functions.
2548 *
2549 * we do this check *after* the authentication check, so that the
2550 * latter check will catch any attempts to fool us into thinking
2551 * that we've got a collision
2552 */
2553 if (stream->direction != dir_srtp_receiver) {
2554 if (stream->direction == dir_unknown) {
2555 stream->direction = dir_srtp_receiver;
2556 } else {
2557 srtp_handle_event(ctx, stream, event_ssrc_collision);
2558 }
2559 }
2560
2561 /*
2562 * if the stream is a 'provisional' one, in which the template context
2563 * is used, then we need to allocate a new stream at this point, since
2564 * the authentication passed
2565 */
2566 if (stream == ctx->stream_template) {
2567 srtp_stream_ctx_t *new_stream;
2568
2569 /*
2570 * allocate and initialize a new stream
2571 *
2572 * note that we indicate failure if we can't allocate the new
2573 * stream, and some implementations will want to not return
2574 * failure here
2575 */
2576 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
2577 if (status) {
2578 return status;
2579 }
2580
2581 /* add new stream to the head of the stream_list */
2582 new_stream->next = ctx->stream_list;
2583 ctx->stream_list = new_stream;
2584
2585 /* set stream (the pointer used in this function) */
2586 stream = new_stream;
2587 }
2588
2589 /* we've passed the authentication check, so add seq_num to the rdb */
jfigusde8deb32014-11-25 12:58:11 -05002590 srtp_rdb_add_index(&stream->rtcp_rdb, seq_num);
jfigus8c36da22013-10-01 16:41:19 -04002591
jfigus857009c2014-11-05 11:17:43 -05002592 return srtp_err_status_ok;
jfigus8c36da22013-10-01 16:41:19 -04002593}
2594
jfigus857009c2014-11-05 11:17:43 -05002595srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00002596srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00002597 srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00002598 uint32_t *enc_start; /* pointer to start of encrypted portion */
2599 uint32_t *auth_start; /* pointer to start of auth. portion */
2600 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002601 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002602 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
jfigus857009c2014-11-05 11:17:43 -05002603 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00002604 int tag_len;
2605 srtp_stream_ctx_t *stream;
2606 int prefix_len;
2607 uint32_t seq_num;
2608
2609 /* we assume the hdr is 32-bit aligned to start */
Travis Cross8ba46eb2014-06-29 18:42:29 +00002610
2611 /* check the packet length - it must at least contain a full header */
2612 if (*pkt_octet_len < octets_in_rtcp_header)
jfigus857009c2014-11-05 11:17:43 -05002613 return srtp_err_status_bad_param;
Travis Cross8ba46eb2014-06-29 18:42:29 +00002614
Cullen Jennings235513a2005-09-21 22:51:36 +00002615 /*
2616 * look up ssrc in srtp_stream list, and process the packet with
2617 * the appropriate stream. if we haven't seen this stream before,
2618 * there's only one key for this srtp_session, and the cipher
2619 * supports key-sharing, then we assume that a new stream using
2620 * that key has just started up
2621 */
2622 stream = srtp_get_stream(ctx, hdr->ssrc);
2623 if (stream == NULL) {
2624 if (ctx->stream_template != NULL) {
2625 srtp_stream_ctx_t *new_stream;
2626
2627 /* allocate and initialize a new stream */
2628 status = srtp_stream_clone(ctx->stream_template,
2629 hdr->ssrc, &new_stream);
2630 if (status)
2631 return status;
2632
2633 /* add new stream to the head of the stream_list */
2634 new_stream->next = ctx->stream_list;
2635 ctx->stream_list = new_stream;
2636
2637 /* set stream (the pointer used in this function) */
2638 stream = new_stream;
2639 } else {
2640 /* no template stream, so we return an error */
jfigus857009c2014-11-05 11:17:43 -05002641 return srtp_err_status_no_ctx;
Cullen Jennings235513a2005-09-21 22:51:36 +00002642 }
2643 }
2644
2645 /*
2646 * verify that stream is for sending traffic - this check will
2647 * detect SSRC collisions, since a stream that appears in both
2648 * srtp_protect() and srtp_unprotect() will fail this test in one of
2649 * those functions.
2650 */
2651 if (stream->direction != dir_srtp_sender) {
2652 if (stream->direction == dir_unknown) {
David McGrewc34f7402006-03-09 21:17:00 +00002653 stream->direction = dir_srtp_sender;
Cullen Jennings235513a2005-09-21 22:51:36 +00002654 } else {
2655 srtp_handle_event(ctx, stream, event_ssrc_collision);
2656 }
2657 }
2658
jfigus8c36da22013-10-01 16:41:19 -04002659 /*
2660 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
2661 * the request to our AEAD handler.
2662 */
jfigus67b9c732014-11-20 10:17:21 -05002663 if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
2664 stream->rtp_cipher->algorithm == SRTP_AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00002665 return srtp_protect_rtcp_aead(ctx, stream, rtcp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04002666 }
2667
Cullen Jennings235513a2005-09-21 22:51:36 +00002668 /* get tag length from stream context */
jfigus8f669722014-11-19 15:20:03 -05002669 tag_len = srtp_auth_get_tag_length(stream->rtcp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00002670
2671 /*
2672 * set encryption start and encryption length - if we're not
2673 * providing confidentiality, set enc_start to NULL
2674 */
2675 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
2676 enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
2677
2678 /* all of the packet, except the header, gets encrypted */
2679 /* NOTE: hdr->length is not usable - it refers to only the first
2680 RTCP report in the compound packet! */
2681 /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2682 multiples of 32-bits (RFC 3550 6.1) */
2683 trailer = (uint32_t *) ((char *)enc_start + enc_octet_len);
2684
2685 if (stream->rtcp_services & sec_serv_conf) {
2686 *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
2687 } else {
2688 enc_start = NULL;
2689 enc_octet_len = 0;
2690 /* 0 is network-order independant */
2691 *trailer = 0x00000000; /* set encrypt bit */
2692 }
2693
2694 /*
2695 * set the auth_start and auth_tag pointers to the proper locations
2696 * (note that srtpc *always* provides authentication, unlike srtp)
2697 */
2698 /* Note: This would need to change for optional mikey data */
2699 auth_start = (uint32_t *)hdr;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002700 auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t);
Cullen Jennings235513a2005-09-21 22:51:36 +00002701
David McGrew79870d62007-06-15 18:17:39 +00002702 /* perform EKT processing if needed */
jfigusc5887e72014-11-06 09:46:18 -05002703 srtp_ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len,
jfigusde8deb32014-11-25 12:58:11 -05002704 srtp_rdbx_get_packet_index(&stream->rtp_rdbx));
David McGrew79870d62007-06-15 18:17:39 +00002705
Cullen Jennings235513a2005-09-21 22:51:36 +00002706 /*
2707 * check sequence number for overruns, and copy it into the packet
2708 * if its value isn't too big
2709 */
jfigusde8deb32014-11-25 12:58:11 -05002710 status = srtp_rdb_increment(&stream->rtcp_rdb);
Cullen Jennings235513a2005-09-21 22:51:36 +00002711 if (status)
2712 return status;
jfigusde8deb32014-11-25 12:58:11 -05002713 seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
Cullen Jennings235513a2005-09-21 22:51:36 +00002714 *trailer |= htonl(seq_num);
2715 debug_print(mod_srtp, "srtcp index: %x", seq_num);
2716
2717 /*
2718 * if we're using rindael counter mode, set nonce and seq
2719 */
jfigus67b9c732014-11-20 10:17:21 -05002720 if (stream->rtcp_cipher->type->id == SRTP_AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002721 v128_t iv;
2722
2723 iv.v32[0] = 0;
2724 iv.v32[1] = hdr->ssrc; /* still in network order! */
2725 iv.v32[2] = htonl(seq_num >> 16);
2726 iv.v32[3] = htonl(seq_num << 16);
jfigus7882dd92013-08-02 16:08:23 -04002727 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002728
2729 } else {
2730 v128_t iv;
2731
2732 /* otherwise, just set the index to seq_num */
2733 iv.v32[0] = 0;
2734 iv.v32[1] = 0;
2735 iv.v32[2] = 0;
2736 iv.v32[3] = htonl(seq_num);
jfigus7882dd92013-08-02 16:08:23 -04002737 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002738 }
2739 if (status)
jfigus857009c2014-11-05 11:17:43 -05002740 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002741
2742 /*
2743 * if we're authenticating using a universal hash, put the keystream
2744 * prefix into the authentication tag
2745 */
2746
2747 /* if auth_start is non-null, then put keystream into tag */
2748 if (auth_start) {
2749
2750 /* put keystream prefix into auth_tag */
jfigus8f669722014-11-19 15:20:03 -05002751 prefix_len = srtp_auth_get_prefix_length(stream->rtcp_auth);
jfigus9a840432014-11-19 15:48:21 -05002752 status = srtp_cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002753
2754 debug_print(mod_srtp, "keystream prefix: %s",
jfigus46d6b472014-11-14 16:42:01 -05002755 srtp_octet_string_hex_string(auth_tag, prefix_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00002756
2757 if (status)
jfigus857009c2014-11-05 11:17:43 -05002758 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002759 }
2760
2761 /* if we're encrypting, exor keystream into the message */
2762 if (enc_start) {
2763 status = cipher_encrypt(stream->rtcp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002764 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002765 if (status)
jfigus857009c2014-11-05 11:17:43 -05002766 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002767 }
2768
2769 /* initialize auth func context */
2770 auth_start(stream->rtcp_auth);
2771
David McGrew9c70f292006-05-03 19:38:38 +00002772 /*
2773 * run auth func over packet (including trailer), and write the
2774 * result at auth_tag
2775 */
Cullen Jennings235513a2005-09-21 22:51:36 +00002776 status = auth_compute(stream->rtcp_auth,
David McGrew9c70f292006-05-03 19:38:38 +00002777 (uint8_t *)auth_start,
2778 (*pkt_octet_len) + sizeof(srtcp_trailer_t),
2779 auth_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00002780 debug_print(mod_srtp, "srtcp auth tag: %s",
jfigus46d6b472014-11-14 16:42:01 -05002781 srtp_octet_string_hex_string(auth_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00002782 if (status)
jfigus857009c2014-11-05 11:17:43 -05002783 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002784
2785 /* increase the packet length by the length of the auth tag and seq_num*/
2786 *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
2787
jfigus857009c2014-11-05 11:17:43 -05002788 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00002789}
2790
2791
jfigus857009c2014-11-05 11:17:43 -05002792srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00002793srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00002794 srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00002795 uint32_t *enc_start; /* pointer to start of encrypted portion */
2796 uint32_t *auth_start; /* pointer to start of auth. portion */
2797 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002798 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002799 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
2800 uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
David McGrew79870d62007-06-15 18:17:39 +00002801 uint8_t tag_copy[SRTP_MAX_TAG_LEN];
jfigus857009c2014-11-05 11:17:43 -05002802 srtp_err_status_t status;
Travis Cross1b8b1e72014-07-02 15:32:36 +00002803 unsigned int auth_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00002804 int tag_len;
2805 srtp_stream_ctx_t *stream;
2806 int prefix_len;
2807 uint32_t seq_num;
TV Sriram4986a362013-05-06 11:24:03 -07002808 int e_bit_in_packet; /* whether the E-bit was found in the packet */
2809 int sec_serv_confidentiality; /* whether confidentiality was requested */
Cullen Jennings235513a2005-09-21 22:51:36 +00002810
2811 /* we assume the hdr is 32-bit aligned to start */
Travis Cross444a5442014-07-02 16:01:01 +00002812
Travis Crosse896bf72014-07-07 19:59:33 +00002813 /* check that the length value is sane; we'll check again once we
2814 know the tag length, but we at least want to know that it is
2815 a positive value */
2816 if (*pkt_octet_len < octets_in_rtcp_header + sizeof(srtcp_trailer_t))
jfigus857009c2014-11-05 11:17:43 -05002817 return srtp_err_status_bad_param;
Travis Crosse896bf72014-07-07 19:59:33 +00002818
Cullen Jennings235513a2005-09-21 22:51:36 +00002819 /*
2820 * look up ssrc in srtp_stream list, and process the packet with
2821 * the appropriate stream. if we haven't seen this stream before,
2822 * there's only one key for this srtp_session, and the cipher
2823 * supports key-sharing, then we assume that a new stream using
2824 * that key has just started up
2825 */
2826 stream = srtp_get_stream(ctx, hdr->ssrc);
2827 if (stream == NULL) {
2828 if (ctx->stream_template != NULL) {
2829 stream = ctx->stream_template;
David McGrew79870d62007-06-15 18:17:39 +00002830
2831 /*
2832 * check to see if stream_template has an EKT data structure, in
2833 * which case we initialize the template using the EKT policy
2834 * referenced by that data (which consists of decrypting the
2835 * master key from the EKT field)
2836 *
2837 * this function initializes a *provisional* stream, and this
2838 * stream should not be accepted until and unless the packet
2839 * passes its authentication check
2840 */
2841 if (stream->ekt != NULL) {
2842 status = srtp_stream_init_from_ekt(stream, srtcp_hdr, *pkt_octet_len);
2843 if (status)
2844 return status;
2845 }
2846
Cullen Jennings235513a2005-09-21 22:51:36 +00002847 debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)",
2848 hdr->ssrc);
2849 } else {
2850 /* no template stream, so we return an error */
jfigus857009c2014-11-05 11:17:43 -05002851 return srtp_err_status_no_ctx;
Cullen Jennings235513a2005-09-21 22:51:36 +00002852 }
2853 }
2854
Travis Cross8ba46eb2014-06-29 18:42:29 +00002855 /* get tag length from stream context */
jfigus8f669722014-11-19 15:20:03 -05002856 tag_len = srtp_auth_get_tag_length(stream->rtcp_auth);
Travis Cross8ba46eb2014-06-29 18:42:29 +00002857
2858 /* check the packet length - it must contain at least a full RTCP
2859 header, an auth tag (if applicable), and the SRTCP encrypted flag
2860 and 31-bit index value */
jfigus73e30932014-07-07 15:50:32 -04002861 if (*pkt_octet_len < (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t))) {
jfigus857009c2014-11-05 11:17:43 -05002862 return srtp_err_status_bad_param;
jfigus73e30932014-07-07 15:50:32 -04002863 }
Travis Cross8ba46eb2014-06-29 18:42:29 +00002864
jfigus8c36da22013-10-01 16:41:19 -04002865 /*
2866 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
2867 * the request to our AEAD handler.
2868 */
jfigus67b9c732014-11-20 10:17:21 -05002869 if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
2870 stream->rtp_cipher->algorithm == SRTP_AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00002871 return srtp_unprotect_rtcp_aead(ctx, stream, srtcp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04002872 }
2873
TV Sriram4986a362013-05-06 11:24:03 -07002874 sec_serv_confidentiality = stream->rtcp_services == sec_serv_conf ||
2875 stream->rtcp_services == sec_serv_conf_and_auth;
2876
Cullen Jennings235513a2005-09-21 22:51:36 +00002877 /*
2878 * set encryption start, encryption length, and trailer
2879 */
2880 enc_octet_len = *pkt_octet_len -
2881 (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t));
2882 /* index & E (encryption) bit follow normal data. hdr->len
2883 is the number of words (32-bit) in the normal packet minus 1 */
2884 /* This should point trailer to the word past the end of the
2885 normal data. */
2886 /* This would need to be modified for optional mikey data */
2887 /*
2888 * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2889 * multiples of 32-bits (RFC 3550 6.1)
2890 */
2891 trailer = (uint32_t *) ((char *) hdr +
TV Sriram4986a362013-05-06 11:24:03 -07002892 *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t)));
2893 e_bit_in_packet =
2894 (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) == SRTCP_E_BYTE_BIT;
2895 if (e_bit_in_packet != sec_serv_confidentiality) {
jfigus857009c2014-11-05 11:17:43 -05002896 return srtp_err_status_cant_check;
TV Sriram4986a362013-05-06 11:24:03 -07002897 }
2898 if (sec_serv_confidentiality) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002899 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
2900 } else {
2901 enc_octet_len = 0;
2902 enc_start = NULL; /* this indicates that there's no encryption */
2903 }
2904
2905 /*
2906 * set the auth_start and auth_tag pointers to the proper locations
2907 * (note that srtcp *always* uses authentication, unlike srtp)
2908 */
2909 auth_start = (uint32_t *)hdr;
David McGrew79870d62007-06-15 18:17:39 +00002910 auth_len = *pkt_octet_len - tag_len;
2911 auth_tag = (uint8_t *)hdr + auth_len;
2912
2913 /*
2914 * if EKT is in use, then we make a copy of the tag from the packet,
2915 * and then zeroize the location of the base tag
2916 *
2917 * we first re-position the auth_tag pointer so that it points to
2918 * the base tag
2919 */
2920 if (stream->ekt) {
jfigusc5887e72014-11-06 09:46:18 -05002921 auth_tag -= srtp_ekt_octets_after_base_tag(stream->ekt);
David McGrew79870d62007-06-15 18:17:39 +00002922 memcpy(tag_copy, auth_tag, tag_len);
2923 octet_string_set_to_zero(auth_tag, tag_len);
2924 auth_tag = tag_copy;
2925 auth_len += tag_len;
2926 }
Cullen Jennings235513a2005-09-21 22:51:36 +00002927
2928 /*
2929 * check the sequence number for replays
2930 */
2931 /* this is easier than dealing with bitfield access */
2932 seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
David McGrew9c70f292006-05-03 19:38:38 +00002933 debug_print(mod_srtp, "srtcp index: %x", seq_num);
jfigusde8deb32014-11-25 12:58:11 -05002934 status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
Cullen Jennings235513a2005-09-21 22:51:36 +00002935 if (status)
2936 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00002937
2938 /*
2939 * if we're using aes counter mode, set nonce and seq
2940 */
jfigus67b9c732014-11-20 10:17:21 -05002941 if (stream->rtcp_cipher->type->id == SRTP_AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002942 v128_t iv;
2943
2944 iv.v32[0] = 0;
2945 iv.v32[1] = hdr->ssrc; /* still in network order! */
2946 iv.v32[2] = htonl(seq_num >> 16);
2947 iv.v32[3] = htonl(seq_num << 16);
jfigus7882dd92013-08-02 16:08:23 -04002948 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002949
2950 } else {
2951 v128_t iv;
2952
2953 /* otherwise, just set the index to seq_num */
2954 iv.v32[0] = 0;
2955 iv.v32[1] = 0;
2956 iv.v32[2] = 0;
2957 iv.v32[3] = htonl(seq_num);
jfigus7882dd92013-08-02 16:08:23 -04002958 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002959
2960 }
2961 if (status)
jfigus857009c2014-11-05 11:17:43 -05002962 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002963
2964 /* initialize auth func context */
2965 auth_start(stream->rtcp_auth);
2966
2967 /* run auth func over packet, put result into tmp_tag */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002968 status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start,
David McGrew79870d62007-06-15 18:17:39 +00002969 auth_len, tmp_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00002970 debug_print(mod_srtp, "srtcp computed tag: %s",
jfigus46d6b472014-11-14 16:42:01 -05002971 srtp_octet_string_hex_string(tmp_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00002972 if (status)
jfigus857009c2014-11-05 11:17:43 -05002973 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002974
2975 /* compare the tag just computed with the one in the packet */
2976 debug_print(mod_srtp, "srtcp tag from packet: %s",
jfigus46d6b472014-11-14 16:42:01 -05002977 srtp_octet_string_hex_string(auth_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00002978 if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
jfigus857009c2014-11-05 11:17:43 -05002979 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002980
2981 /*
2982 * if we're authenticating using a universal hash, put the keystream
2983 * prefix into the authentication tag
2984 */
jfigus8f669722014-11-19 15:20:03 -05002985 prefix_len = srtp_auth_get_prefix_length(stream->rtcp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00002986 if (prefix_len) {
jfigus9a840432014-11-19 15:48:21 -05002987 status = srtp_cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002988 debug_print(mod_srtp, "keystream prefix: %s",
jfigus46d6b472014-11-14 16:42:01 -05002989 srtp_octet_string_hex_string(auth_tag, prefix_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00002990 if (status)
jfigus857009c2014-11-05 11:17:43 -05002991 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002992 }
2993
2994 /* if we're decrypting, exor keystream into the message */
2995 if (enc_start) {
Jonathan Lennox23dc1e22010-06-01 18:19:04 +00002996 status = cipher_decrypt(stream->rtcp_cipher,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002997 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002998 if (status)
jfigus857009c2014-11-05 11:17:43 -05002999 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00003000 }
3001
David McGrew79870d62007-06-15 18:17:39 +00003002 /* decrease the packet length by the length of the auth tag and seq_num */
Cullen Jennings235513a2005-09-21 22:51:36 +00003003 *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
3004
David McGrew79870d62007-06-15 18:17:39 +00003005 /*
3006 * if EKT is in effect, subtract the EKT data out of the packet
3007 * length
3008 */
jfigusc5887e72014-11-06 09:46:18 -05003009 *pkt_octet_len -= srtp_ekt_octets_after_base_tag(stream->ekt);
David McGrew79870d62007-06-15 18:17:39 +00003010
Cullen Jennings235513a2005-09-21 22:51:36 +00003011 /*
3012 * verify that stream is for received traffic - this check will
3013 * detect SSRC collisions, since a stream that appears in both
3014 * srtp_protect() and srtp_unprotect() will fail this test in one of
3015 * those functions.
3016 *
3017 * we do this check *after* the authentication check, so that the
3018 * latter check will catch any attempts to fool us into thinking
3019 * that we've got a collision
3020 */
3021 if (stream->direction != dir_srtp_receiver) {
3022 if (stream->direction == dir_unknown) {
3023 stream->direction = dir_srtp_receiver;
3024 } else {
3025 srtp_handle_event(ctx, stream, event_ssrc_collision);
3026 }
3027 }
3028
3029 /*
3030 * if the stream is a 'provisional' one, in which the template context
3031 * is used, then we need to allocate a new stream at this point, since
3032 * the authentication passed
3033 */
3034 if (stream == ctx->stream_template) {
3035 srtp_stream_ctx_t *new_stream;
3036
3037 /*
3038 * allocate and initialize a new stream
3039 *
3040 * note that we indicate failure if we can't allocate the new
3041 * stream, and some implementations will want to not return
3042 * failure here
3043 */
3044 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
3045 if (status)
3046 return status;
3047
3048 /* add new stream to the head of the stream_list */
3049 new_stream->next = ctx->stream_list;
3050 ctx->stream_list = new_stream;
3051
3052 /* set stream (the pointer used in this function) */
3053 stream = new_stream;
3054 }
3055
3056 /* we've passed the authentication check, so add seq_num to the rdb */
jfigusde8deb32014-11-25 12:58:11 -05003057 srtp_rdb_add_index(&stream->rtcp_rdb, seq_num);
Cullen Jennings235513a2005-09-21 22:51:36 +00003058
3059
jfigus857009c2014-11-05 11:17:43 -05003060 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00003061}
David McGrew0cb86ee2006-07-07 15:46:57 +00003062
3063
Iñaki Baz Castillo241fec32014-08-21 00:51:00 +02003064/*
3065 * user data within srtp_t context
3066 */
3067
3068void
3069srtp_set_user_data(srtp_t ctx, void *data) {
3070 ctx->user_data = data;
3071}
3072
3073void*
3074srtp_get_user_data(srtp_t ctx) {
3075 return ctx->user_data;
3076}
3077
David McGrew0cb86ee2006-07-07 15:46:57 +00003078
3079/*
3080 * dtls keying for srtp
3081 */
3082
jfigus857009c2014-11-05 11:17:43 -05003083srtp_err_status_t
3084srtp_crypto_policy_set_from_profile_for_rtp(srtp_crypto_policy_t *policy,
3085 srtp_profile_t profile) {
David McGrew0cb86ee2006-07-07 15:46:57 +00003086
3087 /* set SRTP policy from the SRTP profile in the key set */
3088 switch(profile) {
3089 case srtp_profile_aes128_cm_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003090 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003091 break;
3092 case srtp_profile_aes128_cm_sha1_32:
jfigus857009c2014-11-05 11:17:43 -05003093 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003094 break;
3095 case srtp_profile_null_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003096 srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003097 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003098 case srtp_profile_aes256_cm_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003099 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003100 break;
3101 case srtp_profile_aes256_cm_sha1_32:
jfigus857009c2014-11-05 11:17:43 -05003102 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(policy);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003103 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003104 /* the following profiles are not (yet) supported */
3105 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003106 default:
jfigus857009c2014-11-05 11:17:43 -05003107 return srtp_err_status_bad_param;
David McGrew0cb86ee2006-07-07 15:46:57 +00003108 }
3109
jfigus857009c2014-11-05 11:17:43 -05003110 return srtp_err_status_ok;
David McGrew0cb86ee2006-07-07 15:46:57 +00003111}
3112
jfigus857009c2014-11-05 11:17:43 -05003113srtp_err_status_t
3114srtp_crypto_policy_set_from_profile_for_rtcp(srtp_crypto_policy_t *policy,
3115 srtp_profile_t profile) {
David McGrew0cb86ee2006-07-07 15:46:57 +00003116
3117 /* set SRTP policy from the SRTP profile in the key set */
3118 switch(profile) {
3119 case srtp_profile_aes128_cm_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003120 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003121 break;
3122 case srtp_profile_aes128_cm_sha1_32:
jfigus0acbb032013-05-30 16:47:02 -04003123 /* We do not honor the 32-bit auth tag request since
3124 * this is not compliant with RFC 3711 */
jfigus857009c2014-11-05 11:17:43 -05003125 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003126 break;
3127 case srtp_profile_null_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003128 srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003129 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003130 case srtp_profile_aes256_cm_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003131 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003132 break;
3133 case srtp_profile_aes256_cm_sha1_32:
jfigus0acbb032013-05-30 16:47:02 -04003134 /* We do not honor the 32-bit auth tag request since
3135 * this is not compliant with RFC 3711 */
jfigus857009c2014-11-05 11:17:43 -05003136 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003137 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003138 /* the following profiles are not (yet) supported */
3139 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003140 default:
jfigus857009c2014-11-05 11:17:43 -05003141 return srtp_err_status_bad_param;
David McGrew0cb86ee2006-07-07 15:46:57 +00003142 }
3143
jfigus857009c2014-11-05 11:17:43 -05003144 return srtp_err_status_ok;
David McGrew0cb86ee2006-07-07 15:46:57 +00003145}
3146
jfigus857009c2014-11-05 11:17:43 -05003147void srtp_append_salt_to_key(uint8_t *key, unsigned int bytes_in_key, uint8_t *salt, unsigned int bytes_in_salt) {
David McGrew0cb86ee2006-07-07 15:46:57 +00003148 memcpy(key + bytes_in_key, salt, bytes_in_salt);
David McGrew0cb86ee2006-07-07 15:46:57 +00003149}
3150
3151unsigned int
3152srtp_profile_get_master_key_length(srtp_profile_t profile) {
3153
3154 switch(profile) {
3155 case srtp_profile_aes128_cm_sha1_80:
3156 return 16;
3157 break;
3158 case srtp_profile_aes128_cm_sha1_32:
3159 return 16;
3160 break;
3161 case srtp_profile_null_sha1_80:
3162 return 16;
3163 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003164 case srtp_profile_aes256_cm_sha1_80:
3165 return 32;
3166 break;
3167 case srtp_profile_aes256_cm_sha1_32:
3168 return 32;
3169 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003170 /* the following profiles are not (yet) supported */
3171 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003172 default:
3173 return 0; /* indicate error by returning a zero */
3174 }
3175}
3176
3177unsigned int
3178srtp_profile_get_master_salt_length(srtp_profile_t profile) {
3179
3180 switch(profile) {
3181 case srtp_profile_aes128_cm_sha1_80:
3182 return 14;
3183 break;
3184 case srtp_profile_aes128_cm_sha1_32:
3185 return 14;
3186 break;
3187 case srtp_profile_null_sha1_80:
3188 return 14;
3189 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003190 case srtp_profile_aes256_cm_sha1_80:
3191 return 14;
3192 break;
3193 case srtp_profile_aes256_cm_sha1_32:
3194 return 14;
3195 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003196 /* the following profiles are not (yet) supported */
3197 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003198 default:
3199 return 0; /* indicate error by returning a zero */
3200 }
3201}
jfigus46d6b472014-11-14 16:42:01 -05003202
3203/*
3204 * SRTP debug interface
3205 */
3206srtp_err_status_t srtp_set_debug_module(char *mod_name, int v)
3207{
jfigus92736bc2014-11-21 10:30:54 -05003208 return srtp_crypto_kernel_set_debug_module(mod_name, v);
jfigus46d6b472014-11-14 16:42:01 -05003209}
3210
3211srtp_err_status_t srtp_list_debug_modules(void)
3212{
jfigus92736bc2014-11-21 10:30:54 -05003213 return srtp_crypto_kernel_list_debug_modules();
jfigus46d6b472014-11-14 16:42:01 -05003214}
3215