blob: cd0f1b8e9a999134256d1a3a6cc3bee45f198104 [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) {
jfigus3f93c3c2014-12-01 15:38:09 -0500150 srtp_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);
jfigus3f93c3c2014-12-01 15:38:09 -0500159 srtp_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);
jfigus3f93c3c2014-12-01 15:38:09 -0500174 srtp_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) {
jfigus3f93c3c2014-12-01 15:38:09 -0500186 srtp_cipher_dealloc(str->rtcp_cipher);
Cullen Jennings235513a2005-09-21 22:51:36 +0000187 auth_dealloc(str->rtp_auth);
jfigus3f93c3c2014-12-01 15:38:09 -0500188 srtp_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);
jfigus3f93c3c2014-12-01 15:38:09 -0500198 srtp_cipher_dealloc(str->rtcp_cipher);
David McGrew79870d62007-06-15 18:17:39 +0000199 auth_dealloc(str->rtp_auth);
jfigus3f93c3c2014-12-01 15:38:09 -0500200 srtp_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 {
jfigus3f93c3c2014-12-01 15:38:09 -0500224 status = srtp_cipher_dealloc(stream->rtp_cipher);
Cullen Jennings235513a2005-09-21 22:51:36 +0000225 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 {
jfigus3f93c3c2014-12-01 15:38:09 -0500255 status = srtp_cipher_dealloc(stream->rtcp_cipher);
Cullen Jennings235513a2005-09-21 22:51:36 +0000256 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
jfigus3f93c3c2014-12-01 15:38:09 -0500406 stat = srtp_cipher_init(kdf->cipher, key);
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000407 if (stat) {
jfigus3f93c3c2014-12-01 15:38:09 -0500408 srtp_cipher_dealloc(kdf->cipher);
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000409 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);
jfigus2964a152014-11-25 15:25:37 -0500432 status = srtp_cipher_encrypt(kdf->cipher, key, &length);
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000433 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;
jfigus3f93c3c2014-12-01 15:38:09 -0500442 status = srtp_cipher_dealloc(kdf->cipher);
Jonathan Lennox953f46f2010-05-18 16:35:09 +0000443 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 */
jfigus3f93c3c2014-12-01 15:38:09 -0500563 stat = srtp_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 */
jfigus3f93c3c2014-12-01 15:38:09 -0500633 stat = srtp_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 */
jfigus2964a152014-11-25 15:25:37 -0500981 status = srtp_cipher_encrypt(stream->rtp_cipher,
jfigus8c36da22013-10-01 16:41:19 -0400982 (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 */
jfigus2964a152014-11-25 15:25:37 -05001100 status = srtp_cipher_decrypt(stream->rtp_cipher, (uint8_t*)enc_start, &enc_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04001101 if (status) {
1102 return status;
1103 }
1104
1105 /*
1106 * verify that stream is for received traffic - this check will
1107 * detect SSRC collisions, since a stream that appears in both
1108 * srtp_protect() and srtp_unprotect() will fail this test in one of
1109 * those functions.
1110 *
1111 * we do this check *after* the authentication check, so that the
1112 * latter check will catch any attempts to fool us into thinking
1113 * that we've got a collision
1114 */
1115 if (stream->direction != dir_srtp_receiver) {
1116 if (stream->direction == dir_unknown) {
1117 stream->direction = dir_srtp_receiver;
1118 } else {
1119 srtp_handle_event(ctx, stream, event_ssrc_collision);
1120 }
1121 }
1122
1123 /*
1124 * if the stream is a 'provisional' one, in which the template context
1125 * is used, then we need to allocate a new stream at this point, since
1126 * the authentication passed
1127 */
1128 if (stream == ctx->stream_template) {
1129 srtp_stream_ctx_t *new_stream;
1130
1131 /*
1132 * allocate and initialize a new stream
1133 *
1134 * note that we indicate failure if we can't allocate the new
1135 * stream, and some implementations will want to not return
1136 * failure here
1137 */
1138 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
1139 if (status) {
1140 return status;
1141 }
1142
1143 /* add new stream to the head of the stream_list */
1144 new_stream->next = ctx->stream_list;
1145 ctx->stream_list = new_stream;
1146
1147 /* set stream (the pointer used in this function) */
1148 stream = new_stream;
1149 }
1150
1151 /*
1152 * the message authentication function passed, so add the packet
1153 * index into the replay database
1154 */
jfigusde8deb32014-11-25 12:58:11 -05001155 srtp_rdbx_add_index(&stream->rtp_rdbx, delta);
jfigus8c36da22013-10-01 16:41:19 -04001156
1157 /* decrease the packet length by the length of the auth tag */
1158 *pkt_octet_len -= tag_len;
1159
jfigus857009c2014-11-05 11:17:43 -05001160 return srtp_err_status_ok;
jfigus8c36da22013-10-01 16:41:19 -04001161}
1162
1163
1164
1165
jfigus857009c2014-11-05 11:17:43 -05001166 srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001167 srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00001168 srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00001169 uint32_t *enc_start; /* pointer to start of encrypted portion */
1170 uint32_t *auth_start; /* pointer to start of auth. portion */
Travis Cross1b8b1e72014-07-02 15:32:36 +00001171 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigusde8deb32014-11-25 12:58:11 -05001172 srtp_xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
Cullen Jennings235513a2005-09-21 22:51:36 +00001173 int delta; /* delta of local pkt idx and that in hdr */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001174 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
jfigus857009c2014-11-05 11:17:43 -05001175 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001176 int tag_len;
1177 srtp_stream_ctx_t *stream;
jfigus2964a152014-11-25 15:25:37 -05001178 uint32_t prefix_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00001179
1180 debug_print(mod_srtp, "function srtp_protect", NULL);
1181
1182 /* we assume the hdr is 32-bit aligned to start */
1183
1184 /* check the packet length - it must at least contain a full header */
1185 if (*pkt_octet_len < octets_in_rtp_header)
jfigus857009c2014-11-05 11:17:43 -05001186 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001187
1188 /*
1189 * look up ssrc in srtp_stream list, and process the packet with
1190 * the appropriate stream. if we haven't seen this stream before,
1191 * there's a template key for this srtp_session, and the cipher
1192 * supports key-sharing, then we assume that a new stream using
1193 * that key has just started up
1194 */
1195 stream = srtp_get_stream(ctx, hdr->ssrc);
1196 if (stream == NULL) {
1197 if (ctx->stream_template != NULL) {
1198 srtp_stream_ctx_t *new_stream;
1199
1200 /* allocate and initialize a new stream */
1201 status = srtp_stream_clone(ctx->stream_template,
David McGrewfec49dd2005-09-23 19:34:11 +00001202 hdr->ssrc, &new_stream);
Cullen Jennings235513a2005-09-21 22:51:36 +00001203 if (status)
1204 return status;
1205
1206 /* add new stream to the head of the stream_list */
1207 new_stream->next = ctx->stream_list;
1208 ctx->stream_list = new_stream;
1209
1210 /* set direction to outbound */
1211 new_stream->direction = dir_srtp_sender;
1212
1213 /* set stream (the pointer used in this function) */
1214 stream = new_stream;
1215 } else {
1216 /* no template stream, so we return an error */
jfigus857009c2014-11-05 11:17:43 -05001217 return srtp_err_status_no_ctx;
Cullen Jennings235513a2005-09-21 22:51:36 +00001218 }
1219 }
1220
1221 /*
1222 * verify that stream is for sending traffic - this check will
1223 * detect SSRC collisions, since a stream that appears in both
1224 * srtp_protect() and srtp_unprotect() will fail this test in one of
1225 * those functions.
1226 */
jfigus8c36da22013-10-01 16:41:19 -04001227 if (stream->direction != dir_srtp_sender) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001228 if (stream->direction == dir_unknown) {
1229 stream->direction = dir_srtp_sender;
1230 } else {
1231 srtp_handle_event(ctx, stream, event_ssrc_collision);
1232 }
jfigus8c36da22013-10-01 16:41:19 -04001233 }
1234
1235 /*
1236 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
1237 * the request to our AEAD handler.
1238 */
jfigus67b9c732014-11-20 10:17:21 -05001239 if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
1240 stream->rtp_cipher->algorithm == SRTP_AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00001241 return srtp_protect_aead(ctx, stream, rtp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04001242 }
Cullen Jennings235513a2005-09-21 22:51:36 +00001243
1244 /*
1245 * update the key usage limit, and check it to make sure that we
1246 * didn't just hit either the soft limit or the hard limit, and call
1247 * the event handler if we hit either.
1248 */
jfigusc7cdc9a2014-11-19 16:19:08 -05001249 switch(srtp_key_limit_update(stream->limit)) {
1250 case srtp_key_event_normal:
Cullen Jennings235513a2005-09-21 22:51:36 +00001251 break;
jfigusc7cdc9a2014-11-19 16:19:08 -05001252 case srtp_key_event_soft_limit:
Cullen Jennings235513a2005-09-21 22:51:36 +00001253 srtp_handle_event(ctx, stream, event_key_soft_limit);
1254 break;
jfigusc7cdc9a2014-11-19 16:19:08 -05001255 case srtp_key_event_hard_limit:
Cullen Jennings235513a2005-09-21 22:51:36 +00001256 srtp_handle_event(ctx, stream, event_key_hard_limit);
jfigus857009c2014-11-05 11:17:43 -05001257 return srtp_err_status_key_expired;
Cullen Jennings235513a2005-09-21 22:51:36 +00001258 default:
1259 break;
1260 }
1261
1262 /* get tag length from stream */
jfigus8f669722014-11-19 15:20:03 -05001263 tag_len = srtp_auth_get_tag_length(stream->rtp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00001264
1265 /*
1266 * find starting point for encryption and length of data to be
1267 * encrypted - the encrypted portion starts after the rtp header
1268 * extension, if present; otherwise, it starts after the last csrc,
1269 * if any are present
1270 *
1271 * if we're not providing confidentiality, set enc_start to NULL
1272 */
1273 if (stream->rtp_services & sec_serv_conf) {
1274 enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
David McGrew14829302005-10-10 18:53:19 +00001275 if (hdr->x == 1) {
1276 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
1277 enc_start += (ntohs(xtn_hdr->length) + 1);
Travis Cross83439f72014-07-02 14:18:46 +00001278 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
jfigus857009c2014-11-05 11:17:43 -05001279 return srtp_err_status_parse_err;
David McGrew14829302005-10-10 18:53:19 +00001280 }
Travis Crossdee3ee82014-07-02 15:20:12 +00001281 enc_octet_len = (unsigned int)(*pkt_octet_len -
1282 ((uint8_t*)enc_start - (uint8_t*)hdr));
Cullen Jennings235513a2005-09-21 22:51:36 +00001283 } else {
1284 enc_start = NULL;
1285 }
1286
1287 /*
1288 * if we're providing authentication, set the auth_start and auth_tag
1289 * pointers to the proper locations; otherwise, set auth_start to NULL
1290 * to indicate that no authentication is needed
1291 */
1292 if (stream->rtp_services & sec_serv_auth) {
1293 auth_start = (uint32_t *)hdr;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001294 auth_tag = (uint8_t *)hdr + *pkt_octet_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00001295 } else {
1296 auth_start = NULL;
1297 auth_tag = NULL;
1298 }
1299
1300 /*
1301 * estimate the packet index using the start of the replay window
1302 * and the sequence number from the header
1303 */
jfigusde8deb32014-11-25 12:58:11 -05001304 delta = srtp_rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
1305 status = srtp_rdbx_check(&stream->rtp_rdbx, delta);
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001306 if (status) {
jfigus857009c2014-11-05 11:17:43 -05001307 if (status != srtp_err_status_replay_fail || !stream->allow_repeat_tx)
Jonathan Lennoxdcee5c62010-05-17 22:08:40 +00001308 return status; /* we've been asked to reuse an index */
1309 }
1310 else
jfigusde8deb32014-11-25 12:58:11 -05001311 srtp_rdbx_add_index(&stream->rtp_rdbx, delta);
Cullen Jennings235513a2005-09-21 22:51:36 +00001312
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001313#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001314 debug_print2(mod_srtp, "estimated packet index: %08x%08x",
1315 high32(est),low32(est));
1316#else
1317 debug_print(mod_srtp, "estimated packet index: %016llx", est);
1318#endif
1319
1320 /*
1321 * if we're using rindael counter mode, set nonce and seq
1322 */
jfigus67b9c732014-11-20 10:17:21 -05001323 if (stream->rtp_cipher->type->id == SRTP_AES_ICM ||
1324 stream->rtp_cipher->type->id == SRTP_AES_256_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001325 v128_t iv;
1326
1327 iv.v32[0] = 0;
1328 iv.v32[1] = hdr->ssrc;
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001329#ifdef NO_64BIT_MATH
1330 iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
David McGrewfec49dd2005-09-23 19:34:11 +00001331 low32(est) << 16));
Cullen Jennings235513a2005-09-21 22:51:36 +00001332#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001333 iv.v64[1] = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001334#endif
jfigus7882dd92013-08-02 16:08:23 -04001335 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001336
1337 } else {
1338 v128_t iv;
1339
1340 /* otherwise, set the index to est */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001341#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001342 iv.v32[0] = 0;
1343 iv.v32[1] = 0;
1344#else
1345 iv.v64[0] = 0;
1346#endif
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001347 iv.v64[1] = be64_to_cpu(est);
jfigus7882dd92013-08-02 16:08:23 -04001348 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001349 }
1350 if (status)
jfigus857009c2014-11-05 11:17:43 -05001351 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001352
1353 /* shift est, put into network byte order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001354#ifdef NO_64BIT_MATH
1355 est = be64_to_cpu(make64((high32(est) << 16) |
Cullen Jennings235513a2005-09-21 22:51:36 +00001356 (low32(est) >> 16),
Randell Jesup811e1442005-09-28 22:43:41 +00001357 low32(est) << 16));
Cullen Jennings235513a2005-09-21 22:51:36 +00001358#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001359 est = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001360#endif
1361
1362 /*
1363 * if we're authenticating using a universal hash, put the keystream
1364 * prefix into the authentication tag
1365 */
1366 if (auth_start) {
1367
jfigus8f669722014-11-19 15:20:03 -05001368 prefix_len = srtp_auth_get_prefix_length(stream->rtp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00001369 if (prefix_len) {
jfigus2964a152014-11-25 15:25:37 -05001370 status = srtp_cipher_output(stream->rtp_cipher, auth_tag, &prefix_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001371 if (status)
jfigus857009c2014-11-05 11:17:43 -05001372 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001373 debug_print(mod_srtp, "keystream prefix: %s",
jfigus46d6b472014-11-14 16:42:01 -05001374 srtp_octet_string_hex_string(auth_tag, prefix_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001375 }
1376 }
1377
1378 /* if we're encrypting, exor keystream into the message */
1379 if (enc_start) {
jfigus2964a152014-11-25 15:25:37 -05001380 status = srtp_cipher_encrypt(stream->rtp_cipher,
1381 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001382 if (status)
jfigus857009c2014-11-05 11:17:43 -05001383 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001384 }
1385
1386 /*
1387 * if we're authenticating, run authentication function and put result
1388 * into the auth_tag
1389 */
1390 if (auth_start) {
1391
1392 /* initialize auth func context */
1393 status = auth_start(stream->rtp_auth);
1394 if (status) return status;
1395
1396 /* run auth func over packet */
1397 status = auth_update(stream->rtp_auth,
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001398 (uint8_t *)auth_start, *pkt_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001399 if (status) return status;
1400
1401 /* run auth func over ROC, put result into auth_tag */
David McGrew89fb7ea2005-09-26 19:33:44 +00001402 debug_print(mod_srtp, "estimated packet index: %016llx", est);
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001403 status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00001404 debug_print(mod_srtp, "srtp auth tag: %s",
jfigus46d6b472014-11-14 16:42:01 -05001405 srtp_octet_string_hex_string(auth_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001406 if (status)
jfigus857009c2014-11-05 11:17:43 -05001407 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001408
1409 }
1410
1411 if (auth_tag) {
1412
1413 /* increase the packet length by the length of the auth tag */
1414 *pkt_octet_len += tag_len;
1415 }
1416
jfigus857009c2014-11-05 11:17:43 -05001417 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001418}
1419
1420
jfigus857009c2014-11-05 11:17:43 -05001421srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001422srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00001423 srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00001424 uint32_t *enc_start; /* pointer to start of encrypted portion */
1425 uint32_t *auth_start; /* pointer to start of auth. portion */
Travis Cross1b8b1e72014-07-02 15:32:36 +00001426 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001427 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
jfigusde8deb32014-11-25 12:58:11 -05001428 srtp_xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */
Cullen Jennings235513a2005-09-21 22:51:36 +00001429 int delta; /* delta of local pkt idx and that in hdr */
1430 v128_t iv;
jfigus857009c2014-11-05 11:17:43 -05001431 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001432 srtp_stream_ctx_t *stream;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001433 uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
jfigus2964a152014-11-25 15:25:37 -05001434 uint32_t tag_len, prefix_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00001435
1436 debug_print(mod_srtp, "function srtp_unprotect", NULL);
1437
1438 /* we assume the hdr is 32-bit aligned to start */
1439
1440 /* check the packet length - it must at least contain a full header */
1441 if (*pkt_octet_len < octets_in_rtp_header)
jfigus857009c2014-11-05 11:17:43 -05001442 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001443
1444 /*
1445 * look up ssrc in srtp_stream list, and process the packet with
1446 * the appropriate stream. if we haven't seen this stream before,
1447 * there's only one key for this srtp_session, and the cipher
1448 * supports key-sharing, then we assume that a new stream using
1449 * that key has just started up
1450 */
1451 stream = srtp_get_stream(ctx, hdr->ssrc);
1452 if (stream == NULL) {
1453 if (ctx->stream_template != NULL) {
1454 stream = ctx->stream_template;
1455 debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)",
1456 hdr->ssrc);
1457
1458 /*
1459 * set estimated packet index to sequence number from header,
1460 * and set delta equal to the same value
1461 */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001462#ifdef NO_64BIT_MATH
jfigusde8deb32014-11-25 12:58:11 -05001463 est = (srtp_xtd_seq_num_t) make64(0,ntohs(hdr->seq));
Cullen Jennings235513a2005-09-21 22:51:36 +00001464 delta = low32(est);
1465#else
jfigusde8deb32014-11-25 12:58:11 -05001466 est = (srtp_xtd_seq_num_t) ntohs(hdr->seq);
David McGrewc4fc00b2006-06-08 18:51:27 +00001467 delta = (int)est;
Cullen Jennings235513a2005-09-21 22:51:36 +00001468#endif
1469 } else {
1470
1471 /*
1472 * no stream corresponding to SSRC found, and we don't do
1473 * key-sharing, so return an error
1474 */
jfigus857009c2014-11-05 11:17:43 -05001475 return srtp_err_status_no_ctx;
Cullen Jennings235513a2005-09-21 22:51:36 +00001476 }
1477 } else {
1478
1479 /* estimate packet index from seq. num. in header */
jfigusde8deb32014-11-25 12:58:11 -05001480 delta = srtp_rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001481
1482 /* check replay database */
jfigusde8deb32014-11-25 12:58:11 -05001483 status = srtp_rdbx_check(&stream->rtp_rdbx, delta);
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001484 if (status)
1485 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001486 }
1487
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001488#ifdef NO_64BIT_MATH
David McGrewfec49dd2005-09-23 19:34:11 +00001489 debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),low32(est));
1490#else
1491 debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
1492#endif
Cullen Jennings235513a2005-09-21 22:51:36 +00001493
jfigus8c36da22013-10-01 16:41:19 -04001494 /*
1495 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
1496 * the request to our AEAD handler.
1497 */
jfigus67b9c732014-11-20 10:17:21 -05001498 if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
1499 stream->rtp_cipher->algorithm == SRTP_AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00001500 return srtp_unprotect_aead(ctx, stream, delta, est, srtp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04001501 }
1502
Cullen Jennings235513a2005-09-21 22:51:36 +00001503 /* get tag length from stream */
jfigus8f669722014-11-19 15:20:03 -05001504 tag_len = srtp_auth_get_tag_length(stream->rtp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00001505
1506 /*
1507 * set the cipher's IV properly, depending on whatever cipher we
1508 * happen to be using
1509 */
jfigus67b9c732014-11-20 10:17:21 -05001510 if (stream->rtp_cipher->type->id == SRTP_AES_ICM ||
1511 stream->rtp_cipher->type->id == SRTP_AES_256_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001512
1513 /* aes counter mode */
1514 iv.v32[0] = 0;
1515 iv.v32[1] = hdr->ssrc; /* still in network order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001516#ifdef NO_64BIT_MATH
1517 iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
Cullen Jennings235513a2005-09-21 22:51:36 +00001518 low32(est) << 16));
1519#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001520 iv.v64[1] = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001521#endif
jfigus7882dd92013-08-02 16:08:23 -04001522 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001523 } else {
1524
1525 /* no particular format - set the iv to the pakcet index */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001526#ifdef NO_64BIT_MATH
Cullen Jennings235513a2005-09-21 22:51:36 +00001527 iv.v32[0] = 0;
1528 iv.v32[1] = 0;
1529#else
1530 iv.v64[0] = 0;
1531#endif
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001532 iv.v64[1] = be64_to_cpu(est);
jfigus7882dd92013-08-02 16:08:23 -04001533 status = cipher_set_iv(stream->rtp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00001534 }
1535 if (status)
jfigus857009c2014-11-05 11:17:43 -05001536 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001537
1538 /* shift est, put into network byte order */
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001539#ifdef NO_64BIT_MATH
1540 est = be64_to_cpu(make64((high32(est) << 16) |
Cullen Jennings235513a2005-09-21 22:51:36 +00001541 (low32(est) >> 16),
1542 low32(est) << 16));
1543#else
Marcus Sundberge4e34f92005-10-02 20:19:35 +00001544 est = be64_to_cpu(est << 16);
Cullen Jennings235513a2005-09-21 22:51:36 +00001545#endif
1546
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001547 /*
1548 * find starting point for decryption and length of data to be
1549 * decrypted - the encrypted portion starts after the rtp header
1550 * extension, if present; otherwise, it starts after the last csrc,
1551 * if any are present
1552 *
1553 * if we're not providing confidentiality, set enc_start to NULL
1554 */
1555 if (stream->rtp_services & sec_serv_conf) {
1556 enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
David McGrew14829302005-10-10 18:53:19 +00001557 if (hdr->x == 1) {
1558 srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
1559 enc_start += (ntohs(xtn_hdr->length) + 1);
1560 }
Travis Cross83439f72014-07-02 14:18:46 +00001561 if (!((uint8_t*)enc_start < (uint8_t*)hdr + *pkt_octet_len))
jfigus857009c2014-11-05 11:17:43 -05001562 return srtp_err_status_parse_err;
Travis Crossdee3ee82014-07-02 15:20:12 +00001563 enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len -
1564 ((uint8_t*)enc_start - (uint8_t*)hdr));
Marcus Sundberg0c324cb2005-10-10 17:23:47 +00001565 } else {
1566 enc_start = NULL;
1567 }
1568
Cullen Jennings235513a2005-09-21 22:51:36 +00001569 /*
1570 * if we're providing authentication, set the auth_start and auth_tag
1571 * pointers to the proper locations; otherwise, set auth_start to NULL
1572 * to indicate that no authentication is needed
1573 */
1574 if (stream->rtp_services & sec_serv_auth) {
1575 auth_start = (uint32_t *)hdr;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001576 auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00001577 } else {
1578 auth_start = NULL;
1579 auth_tag = NULL;
1580 }
1581
1582 /*
1583 * if we expect message authentication, run the authentication
1584 * function and compare the result with the value of the auth_tag
1585 */
1586 if (auth_start) {
1587
1588 /*
1589 * if we're using a universal hash, then we need to compute the
1590 * keystream prefix for encrypting the universal hash output
1591 *
1592 * if the keystream prefix length is zero, then we know that
1593 * the authenticator isn't using a universal hash function
1594 */
1595 if (stream->rtp_auth->prefix_len != 0) {
1596
jfigus8f669722014-11-19 15:20:03 -05001597 prefix_len = srtp_auth_get_prefix_length(stream->rtp_auth);
jfigus2964a152014-11-25 15:25:37 -05001598 status = srtp_cipher_output(stream->rtp_cipher, tmp_tag, &prefix_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001599 debug_print(mod_srtp, "keystream prefix: %s",
jfigus46d6b472014-11-14 16:42:01 -05001600 srtp_octet_string_hex_string(tmp_tag, prefix_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001601 if (status)
jfigus857009c2014-11-05 11:17:43 -05001602 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001603 }
1604
1605 /* initialize auth func context */
1606 status = auth_start(stream->rtp_auth);
1607 if (status) return status;
David McGrewfec49dd2005-09-23 19:34:11 +00001608
Cullen Jennings235513a2005-09-21 22:51:36 +00001609 /* now compute auth function over packet */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001610 status = auth_update(stream->rtp_auth, (uint8_t *)auth_start,
Cullen Jennings235513a2005-09-21 22:51:36 +00001611 *pkt_octet_len - tag_len);
1612
1613 /* run auth func over ROC, then write tmp tag */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00001614 status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00001615
1616 debug_print(mod_srtp, "computed auth tag: %s",
jfigus46d6b472014-11-14 16:42:01 -05001617 srtp_octet_string_hex_string(tmp_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001618 debug_print(mod_srtp, "packet auth tag: %s",
jfigus46d6b472014-11-14 16:42:01 -05001619 srtp_octet_string_hex_string(auth_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00001620 if (status)
jfigus857009c2014-11-05 11:17:43 -05001621 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001622
1623 if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
jfigus857009c2014-11-05 11:17:43 -05001624 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001625 }
1626
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001627 /*
1628 * update the key usage limit, and check it to make sure that we
1629 * didn't just hit either the soft limit or the hard limit, and call
1630 * the event handler if we hit either.
1631 */
jfigusc7cdc9a2014-11-19 16:19:08 -05001632 switch(srtp_key_limit_update(stream->limit)) {
1633 case srtp_key_event_normal:
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001634 break;
jfigusc7cdc9a2014-11-19 16:19:08 -05001635 case srtp_key_event_soft_limit:
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001636 srtp_handle_event(ctx, stream, event_key_soft_limit);
1637 break;
jfigusc7cdc9a2014-11-19 16:19:08 -05001638 case srtp_key_event_hard_limit:
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001639 srtp_handle_event(ctx, stream, event_key_hard_limit);
jfigus857009c2014-11-05 11:17:43 -05001640 return srtp_err_status_key_expired;
Marcus Sundbergfc4d1382005-10-08 18:28:16 +00001641 default:
1642 break;
1643 }
1644
Jonathan Lennox23dc1e22010-06-01 18:19:04 +00001645 /* if we're decrypting, add keystream into ciphertext */
Cullen Jennings235513a2005-09-21 22:51:36 +00001646 if (enc_start) {
jfigus2964a152014-11-25 15:25:37 -05001647 status = srtp_cipher_decrypt(stream->rtp_cipher, (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00001648 if (status)
jfigus857009c2014-11-05 11:17:43 -05001649 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001650 }
1651
1652 /*
1653 * verify that stream is for received traffic - this check will
1654 * detect SSRC collisions, since a stream that appears in both
1655 * srtp_protect() and srtp_unprotect() will fail this test in one of
1656 * those functions.
1657 *
1658 * we do this check *after* the authentication check, so that the
1659 * latter check will catch any attempts to fool us into thinking
1660 * that we've got a collision
1661 */
1662 if (stream->direction != dir_srtp_receiver) {
1663 if (stream->direction == dir_unknown) {
1664 stream->direction = dir_srtp_receiver;
1665 } else {
1666 srtp_handle_event(ctx, stream, event_ssrc_collision);
1667 }
1668 }
1669
1670 /*
1671 * if the stream is a 'provisional' one, in which the template context
1672 * is used, then we need to allocate a new stream at this point, since
1673 * the authentication passed
1674 */
1675 if (stream == ctx->stream_template) {
1676 srtp_stream_ctx_t *new_stream;
1677
1678 /*
1679 * allocate and initialize a new stream
1680 *
1681 * note that we indicate failure if we can't allocate the new
1682 * stream, and some implementations will want to not return
1683 * failure here
1684 */
1685 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
1686 if (status)
1687 return status;
1688
1689 /* add new stream to the head of the stream_list */
1690 new_stream->next = ctx->stream_list;
1691 ctx->stream_list = new_stream;
1692
1693 /* set stream (the pointer used in this function) */
1694 stream = new_stream;
1695 }
1696
1697 /*
1698 * the message authentication function passed, so add the packet
1699 * index into the replay database
1700 */
jfigusde8deb32014-11-25 12:58:11 -05001701 srtp_rdbx_add_index(&stream->rtp_rdbx, delta);
Cullen Jennings235513a2005-09-21 22:51:36 +00001702
1703 /* decrease the packet length by the length of the auth tag */
1704 *pkt_octet_len -= tag_len;
1705
jfigus857009c2014-11-05 11:17:43 -05001706 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001707}
1708
jfigus857009c2014-11-05 11:17:43 -05001709srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001710srtp_init() {
jfigus857009c2014-11-05 11:17:43 -05001711 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001712
1713 /* initialize crypto kernel */
jfigus92736bc2014-11-21 10:30:54 -05001714 status = srtp_crypto_kernel_init();
Cullen Jennings235513a2005-09-21 22:51:36 +00001715 if (status)
1716 return status;
1717
1718 /* load srtp debug module into the kernel */
jfigus92736bc2014-11-21 10:30:54 -05001719 status = srtp_crypto_kernel_load_debug_module(&mod_srtp);
Cullen Jennings235513a2005-09-21 22:51:36 +00001720 if (status)
1721 return status;
1722
jfigus857009c2014-11-05 11:17:43 -05001723 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001724}
1725
jfigus857009c2014-11-05 11:17:43 -05001726srtp_err_status_t
Jonathan Lennox5ae76332010-05-15 04:48:59 +00001727srtp_shutdown() {
jfigus857009c2014-11-05 11:17:43 -05001728 srtp_err_status_t status;
Jonathan Lennox5ae76332010-05-15 04:48:59 +00001729
1730 /* shut down crypto kernel */
jfigus92736bc2014-11-21 10:30:54 -05001731 status = srtp_crypto_kernel_shutdown();
Jonathan Lennox5ae76332010-05-15 04:48:59 +00001732 if (status)
1733 return status;
1734
1735 /* shutting down crypto kernel frees the srtp debug module as well */
1736
jfigus857009c2014-11-05 11:17:43 -05001737 return srtp_err_status_ok;
Jonathan Lennox5ae76332010-05-15 04:48:59 +00001738}
1739
1740
Cullen Jennings235513a2005-09-21 22:51:36 +00001741/*
1742 * The following code is under consideration for removal. See
1743 * SRTP_MAX_TRAILER_LEN
1744 */
1745#if 0
1746
1747/*
1748 * srtp_get_trailer_length(&a) returns the number of octets that will
1749 * be added to an RTP packet by the SRTP processing. This value
1750 * is constant for a given srtp_stream_t (i.e. between initializations).
1751 */
1752
1753int
1754srtp_get_trailer_length(const srtp_stream_t s) {
jfigus8f669722014-11-19 15:20:03 -05001755 return srtp_auth_get_tag_length(s->rtp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00001756}
1757
1758#endif
1759
1760/*
1761 * srtp_get_stream(ssrc) returns a pointer to the stream corresponding
1762 * to ssrc, or NULL if no stream exists for that ssrc
1763 *
1764 * this is an internal function
1765 */
1766
1767srtp_stream_ctx_t *
1768srtp_get_stream(srtp_t srtp, uint32_t ssrc) {
1769 srtp_stream_ctx_t *stream;
1770
1771 /* walk down list until ssrc is found */
1772 stream = srtp->stream_list;
1773 while (stream != NULL) {
1774 if (stream->ssrc == ssrc)
1775 return stream;
1776 stream = stream->next;
1777 }
1778
1779 /* we haven't found our ssrc, so return a null */
1780 return NULL;
1781}
1782
jfigus857009c2014-11-05 11:17:43 -05001783srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001784srtp_dealloc(srtp_t session) {
1785 srtp_stream_ctx_t *stream;
jfigus857009c2014-11-05 11:17:43 -05001786 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001787
1788 /*
1789 * we take a conservative deallocation strategy - if we encounter an
1790 * error deallocating a stream, then we stop trying to deallocate
1791 * memory and just return an error
1792 */
1793
1794 /* walk list of streams, deallocating as we go */
1795 stream = session->stream_list;
1796 while (stream != NULL) {
1797 srtp_stream_t next = stream->next;
1798 status = srtp_stream_dealloc(session, stream);
1799 if (status)
1800 return status;
1801 stream = next;
1802 }
1803
1804 /* deallocate stream template, if there is one */
1805 if (session->stream_template != NULL) {
David McGrewfec49dd2005-09-23 19:34:11 +00001806 status = auth_dealloc(session->stream_template->rtcp_auth);
1807 if (status)
1808 return status;
jfigus3f93c3c2014-12-01 15:38:09 -05001809 status = srtp_cipher_dealloc(session->stream_template->rtcp_cipher);
David McGrewfec49dd2005-09-23 19:34:11 +00001810 if (status)
1811 return status;
jfigused755f52014-11-19 14:57:19 -05001812 srtp_crypto_free(session->stream_template->limit);
jfigus3f93c3c2014-12-01 15:38:09 -05001813 status = srtp_cipher_dealloc(session->stream_template->rtp_cipher);
Cullen Jennings235513a2005-09-21 22:51:36 +00001814 if (status)
1815 return status;
1816 status = auth_dealloc(session->stream_template->rtp_auth);
1817 if (status)
1818 return status;
jfigusde8deb32014-11-25 12:58:11 -05001819 status = srtp_rdbx_dealloc(&session->stream_template->rtp_rdbx);
Jonathan Lennoxa1242f82010-05-17 21:46:04 +00001820 if (status)
1821 return status;
jfigused755f52014-11-19 14:57:19 -05001822 srtp_crypto_free(session->stream_template);
Cullen Jennings235513a2005-09-21 22:51:36 +00001823 }
1824
1825 /* deallocate session context */
jfigused755f52014-11-19 14:57:19 -05001826 srtp_crypto_free(session);
Cullen Jennings235513a2005-09-21 22:51:36 +00001827
jfigus857009c2014-11-05 11:17:43 -05001828 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001829}
1830
1831
jfigus857009c2014-11-05 11:17:43 -05001832srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001833srtp_add_stream(srtp_t session,
1834 const srtp_policy_t *policy) {
jfigus857009c2014-11-05 11:17:43 -05001835 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001836 srtp_stream_t tmp;
1837
Marcus Sundberg67398e62005-10-05 12:39:51 +00001838 /* sanity check arguments */
1839 if ((session == NULL) || (policy == NULL) || (policy->key == NULL))
jfigus857009c2014-11-05 11:17:43 -05001840 return srtp_err_status_bad_param;
Marcus Sundberg67398e62005-10-05 12:39:51 +00001841
Cullen Jennings235513a2005-09-21 22:51:36 +00001842 /* allocate stream */
1843 status = srtp_stream_alloc(&tmp, policy);
1844 if (status) {
1845 return status;
1846 }
1847
1848 /* initialize stream */
1849 status = srtp_stream_init(tmp, policy);
1850 if (status) {
jfigused755f52014-11-19 14:57:19 -05001851 srtp_crypto_free(tmp);
Cullen Jennings235513a2005-09-21 22:51:36 +00001852 return status;
1853 }
1854
1855 /*
1856 * set the head of the stream list or the template to point to the
1857 * stream that we've just alloced and init'ed, depending on whether
1858 * or not it has a wildcard SSRC value or not
1859 *
1860 * if the template stream has already been set, then the policy is
1861 * inconsistent, so we return a bad_param error code
1862 */
1863 switch (policy->ssrc.type) {
1864 case (ssrc_any_outbound):
1865 if (session->stream_template) {
jfigus857009c2014-11-05 11:17:43 -05001866 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001867 }
1868 session->stream_template = tmp;
1869 session->stream_template->direction = dir_srtp_sender;
1870 break;
1871 case (ssrc_any_inbound):
1872 if (session->stream_template) {
jfigus857009c2014-11-05 11:17:43 -05001873 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001874 }
1875 session->stream_template = tmp;
1876 session->stream_template->direction = dir_srtp_receiver;
1877 break;
1878 case (ssrc_specific):
1879 tmp->next = session->stream_list;
1880 session->stream_list = tmp;
1881 break;
1882 case (ssrc_undefined):
1883 default:
jfigused755f52014-11-19 14:57:19 -05001884 srtp_crypto_free(tmp);
jfigus857009c2014-11-05 11:17:43 -05001885 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001886 }
1887
jfigus857009c2014-11-05 11:17:43 -05001888 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001889}
1890
1891
jfigus857009c2014-11-05 11:17:43 -05001892srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001893srtp_create(srtp_t *session, /* handle for session */
1894 const srtp_policy_t *policy) { /* SRTP policy (list) */
jfigus857009c2014-11-05 11:17:43 -05001895 srtp_err_status_t stat;
Cullen Jennings235513a2005-09-21 22:51:36 +00001896 srtp_ctx_t *ctx;
1897
1898 /* sanity check arguments */
Marcus Sundberg67398e62005-10-05 12:39:51 +00001899 if (session == NULL)
jfigus857009c2014-11-05 11:17:43 -05001900 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001901
1902 /* allocate srtp context and set ctx_ptr */
jfigused755f52014-11-19 14:57:19 -05001903 ctx = (srtp_ctx_t *) srtp_crypto_alloc(sizeof(srtp_ctx_t));
Cullen Jennings235513a2005-09-21 22:51:36 +00001904 if (ctx == NULL)
jfigus857009c2014-11-05 11:17:43 -05001905 return srtp_err_status_alloc_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00001906 *session = ctx;
1907
1908 /*
1909 * loop over elements in the policy list, allocating and
1910 * initializing a stream for each element
1911 */
1912 ctx->stream_template = NULL;
1913 ctx->stream_list = NULL;
Iñaki Baz Castillo241fec32014-08-21 00:51:00 +02001914 ctx->user_data = NULL;
Cullen Jennings235513a2005-09-21 22:51:36 +00001915 while (policy != NULL) {
1916
1917 stat = srtp_add_stream(ctx, policy);
1918 if (stat) {
Marcus Sundberg67398e62005-10-05 12:39:51 +00001919 /* clean up everything */
1920 srtp_dealloc(*session);
Cullen Jennings235513a2005-09-21 22:51:36 +00001921 return stat;
1922 }
1923
1924 /* set policy to next item in list */
1925 policy = policy->next;
1926 }
1927
jfigus857009c2014-11-05 11:17:43 -05001928 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001929}
1930
1931
jfigus857009c2014-11-05 11:17:43 -05001932srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00001933srtp_remove_stream(srtp_t session, uint32_t ssrc) {
1934 srtp_stream_ctx_t *stream, *last_stream;
jfigus857009c2014-11-05 11:17:43 -05001935 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00001936
1937 /* sanity check arguments */
1938 if (session == NULL)
jfigus857009c2014-11-05 11:17:43 -05001939 return srtp_err_status_bad_param;
Cullen Jennings235513a2005-09-21 22:51:36 +00001940
1941 /* find stream in list; complain if not found */
1942 last_stream = stream = session->stream_list;
1943 while ((stream != NULL) && (ssrc != stream->ssrc)) {
1944 last_stream = stream;
1945 stream = stream->next;
1946 }
1947 if (stream == NULL)
jfigus857009c2014-11-05 11:17:43 -05001948 return srtp_err_status_no_ctx;
Cullen Jennings235513a2005-09-21 22:51:36 +00001949
1950 /* remove stream from the list */
Jonathan Lennox20505b32010-05-27 19:22:25 +00001951 if (last_stream == stream)
1952 /* stream was first in list */
1953 session->stream_list = stream->next;
1954 else
1955 last_stream->next = stream->next;
Cullen Jennings235513a2005-09-21 22:51:36 +00001956
1957 /* deallocate the stream */
1958 status = srtp_stream_dealloc(session, stream);
1959 if (status)
1960 return status;
1961
jfigus857009c2014-11-05 11:17:43 -05001962 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00001963}
1964
1965
1966/*
1967 * the default policy - provides a convenient way for callers to use
1968 * the default security policy
1969 *
1970 * this policy is that defined in the current SRTP internet draft.
1971 *
1972 */
1973
1974/*
1975 * NOTE: cipher_key_len is really key len (128 bits) plus salt len
1976 * (112 bits)
1977 */
1978/* There are hard-coded 16's for base_key_len in the key generation code */
1979
1980void
jfigus857009c2014-11-05 11:17:43 -05001981srtp_crypto_policy_set_rtp_default(srtp_crypto_policy_t *p) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001982
jfigus67b9c732014-11-20 10:17:21 -05001983 p->cipher_type = SRTP_AES_ICM;
Cullen Jennings235513a2005-09-21 22:51:36 +00001984 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
jfigus67b9c732014-11-20 10:17:21 -05001985 p->auth_type = SRTP_HMAC_SHA1;
Cullen Jennings235513a2005-09-21 22:51:36 +00001986 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
1987 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
1988 p->sec_serv = sec_serv_conf_and_auth;
1989
1990}
1991
1992void
jfigus857009c2014-11-05 11:17:43 -05001993srtp_crypto_policy_set_rtcp_default(srtp_crypto_policy_t *p) {
Cullen Jennings235513a2005-09-21 22:51:36 +00001994
jfigus67b9c732014-11-20 10:17:21 -05001995 p->cipher_type = SRTP_AES_ICM;
Cullen Jennings235513a2005-09-21 22:51:36 +00001996 p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */
jfigus67b9c732014-11-20 10:17:21 -05001997 p->auth_type = SRTP_HMAC_SHA1;
Cullen Jennings235513a2005-09-21 22:51:36 +00001998 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
1999 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
2000 p->sec_serv = sec_serv_conf_and_auth;
2001
2002}
2003
David McGrewa8546882006-01-12 17:56:02 +00002004void
jfigus857009c2014-11-05 11:17:43 -05002005srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(srtp_crypto_policy_t *p) {
David McGrewa8546882006-01-12 17:56:02 +00002006
2007 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00002008 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00002009 *
2010 * note that this crypto policy is intended for SRTP, but not SRTCP
2011 */
2012
jfigus67b9c732014-11-20 10:17:21 -05002013 p->cipher_type = SRTP_AES_ICM;
David McGrewa8546882006-01-12 17:56:02 +00002014 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
jfigus67b9c732014-11-20 10:17:21 -05002015 p->auth_type = SRTP_HMAC_SHA1;
David McGrewa8546882006-01-12 17:56:02 +00002016 p->auth_key_len = 20; /* 160 bit key */
2017 p->auth_tag_len = 4; /* 32 bit tag */
2018 p->sec_serv = sec_serv_conf_and_auth;
2019
2020}
2021
2022
2023void
jfigus857009c2014-11-05 11:17:43 -05002024srtp_crypto_policy_set_aes_cm_128_null_auth(srtp_crypto_policy_t *p) {
David McGrewa8546882006-01-12 17:56:02 +00002025
2026 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00002027 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00002028 *
2029 * note that this crypto policy is intended for SRTP, but not SRTCP
2030 */
2031
jfigus67b9c732014-11-20 10:17:21 -05002032 p->cipher_type = SRTP_AES_ICM;
David McGrewa8546882006-01-12 17:56:02 +00002033 p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */
jfigus67b9c732014-11-20 10:17:21 -05002034 p->auth_type = SRTP_NULL_AUTH;
David McGrewa8546882006-01-12 17:56:02 +00002035 p->auth_key_len = 0;
2036 p->auth_tag_len = 0;
2037 p->sec_serv = sec_serv_conf;
2038
2039}
2040
2041
2042void
jfigus857009c2014-11-05 11:17:43 -05002043srtp_crypto_policy_set_null_cipher_hmac_sha1_80(srtp_crypto_policy_t *p) {
David McGrewa8546882006-01-12 17:56:02 +00002044
2045 /*
Jonathan Lennoxd8d5cd02010-05-17 20:08:17 +00002046 * corresponds to RFC 4568
David McGrewa8546882006-01-12 17:56:02 +00002047 */
2048
jfigus67b9c732014-11-20 10:17:21 -05002049 p->cipher_type = SRTP_NULL_CIPHER;
David McGrewa8546882006-01-12 17:56:02 +00002050 p->cipher_key_len = 0;
jfigus67b9c732014-11-20 10:17:21 -05002051 p->auth_type = SRTP_HMAC_SHA1;
David McGrewa8546882006-01-12 17:56:02 +00002052 p->auth_key_len = 20;
2053 p->auth_tag_len = 10;
2054 p->sec_serv = sec_serv_auth;
2055
2056}
2057
jfigus267956d2014-11-06 10:49:21 -05002058void
2059srtp_crypto_policy_set_null_cipher_hmac_null(srtp_crypto_policy_t *p) {
2060
2061 /*
2062 * Should only be used for testing
2063 */
2064
jfigus67b9c732014-11-20 10:17:21 -05002065 p->cipher_type = SRTP_NULL_CIPHER;
jfigus267956d2014-11-06 10:49:21 -05002066 p->cipher_key_len = 0;
jfigus67b9c732014-11-20 10:17:21 -05002067 p->auth_type = SRTP_NULL_AUTH;
jfigus267956d2014-11-06 10:49:21 -05002068 p->auth_key_len = 0;
2069 p->auth_tag_len = 0;
2070 p->sec_serv = sec_serv_none;
2071
2072}
2073
David McGrewa8546882006-01-12 17:56:02 +00002074
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002075void
jfigus857009c2014-11-05 11:17:43 -05002076srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(srtp_crypto_policy_t *p) {
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002077
2078 /*
2079 * corresponds to draft-ietf-avt-big-aes-03.txt
2080 */
2081
jfigus67b9c732014-11-20 10:17:21 -05002082 p->cipher_type = SRTP_AES_ICM;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002083 p->cipher_key_len = 46;
jfigus67b9c732014-11-20 10:17:21 -05002084 p->auth_type = SRTP_HMAC_SHA1;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002085 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
2086 p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
2087 p->sec_serv = sec_serv_conf_and_auth;
2088}
2089
2090
2091void
jfigus857009c2014-11-05 11:17:43 -05002092srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(srtp_crypto_policy_t *p) {
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002093
2094 /*
2095 * corresponds to draft-ietf-avt-big-aes-03.txt
2096 *
2097 * note that this crypto policy is intended for SRTP, but not SRTCP
2098 */
2099
jfigus67b9c732014-11-20 10:17:21 -05002100 p->cipher_type = SRTP_AES_ICM;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002101 p->cipher_key_len = 46;
jfigus67b9c732014-11-20 10:17:21 -05002102 p->auth_type = SRTP_HMAC_SHA1;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002103 p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
2104 p->auth_tag_len = 4; /* default 80 bits per RFC 3711 */
2105 p->sec_serv = sec_serv_conf_and_auth;
2106}
2107
jfigus8c36da22013-10-01 16:41:19 -04002108/*
2109 * AES-256 with no authentication.
2110 */
2111void
jfigus857009c2014-11-05 11:17:43 -05002112srtp_crypto_policy_set_aes_cm_256_null_auth (srtp_crypto_policy_t *p)
jfigus8c36da22013-10-01 16:41:19 -04002113{
jfigus67b9c732014-11-20 10:17:21 -05002114 p->cipher_type = SRTP_AES_ICM;
jfigus8c36da22013-10-01 16:41:19 -04002115 p->cipher_key_len = 46;
jfigus67b9c732014-11-20 10:17:21 -05002116 p->auth_type = SRTP_NULL_AUTH;
jfigus8c36da22013-10-01 16:41:19 -04002117 p->auth_key_len = 0;
2118 p->auth_tag_len = 0;
2119 p->sec_serv = sec_serv_conf;
2120}
2121
2122#ifdef OPENSSL
2123/*
2124 * AES-128 GCM mode with 8 octet auth tag.
2125 */
2126void
jfigus857009c2014-11-05 11:17:43 -05002127srtp_crypto_policy_set_aes_gcm_128_8_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002128 p->cipher_type = SRTP_AES_128_GCM;
jfigus857009c2014-11-05 11:17:43 -05002129 p->cipher_key_len = SRTP_AES_128_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002130 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigus8c36da22013-10-01 16:41:19 -04002131 p->auth_key_len = 0;
2132 p->auth_tag_len = 8; /* 8 octet tag length */
2133 p->sec_serv = sec_serv_conf_and_auth;
2134}
2135
2136/*
2137 * AES-256 GCM mode with 8 octet auth tag.
2138 */
2139void
jfigus857009c2014-11-05 11:17:43 -05002140srtp_crypto_policy_set_aes_gcm_256_8_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002141 p->cipher_type = SRTP_AES_256_GCM;
jfigus857009c2014-11-05 11:17:43 -05002142 p->cipher_key_len = SRTP_AES_256_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002143 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigus8c36da22013-10-01 16:41:19 -04002144 p->auth_key_len = 0;
2145 p->auth_tag_len = 8; /* 8 octet tag length */
2146 p->sec_serv = sec_serv_conf_and_auth;
2147}
2148
2149/*
2150 * AES-128 GCM mode with 8 octet auth tag, no RTCP encryption.
2151 */
2152void
jfigus857009c2014-11-05 11:17:43 -05002153srtp_crypto_policy_set_aes_gcm_128_8_only_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002154 p->cipher_type = SRTP_AES_128_GCM;
jfigus857009c2014-11-05 11:17:43 -05002155 p->cipher_key_len = SRTP_AES_128_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002156 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigus8c36da22013-10-01 16:41:19 -04002157 p->auth_key_len = 0;
2158 p->auth_tag_len = 8; /* 8 octet tag length */
2159 p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
2160}
2161
2162/*
2163 * AES-256 GCM mode with 8 octet auth tag, no RTCP encryption.
2164 */
2165void
jfigus857009c2014-11-05 11:17:43 -05002166srtp_crypto_policy_set_aes_gcm_256_8_only_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002167 p->cipher_type = SRTP_AES_256_GCM;
jfigus857009c2014-11-05 11:17:43 -05002168 p->cipher_key_len = SRTP_AES_256_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002169 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigus8c36da22013-10-01 16:41:19 -04002170 p->auth_key_len = 0;
2171 p->auth_tag_len = 8; /* 8 octet tag length */
2172 p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
2173}
jfigusc13c1002014-05-08 13:34:53 -04002174
2175/*
2176 * AES-128 GCM mode with 16 octet auth tag.
2177 */
2178void
jfigus857009c2014-11-05 11:17:43 -05002179srtp_crypto_policy_set_aes_gcm_128_16_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002180 p->cipher_type = SRTP_AES_128_GCM;
jfigus857009c2014-11-05 11:17:43 -05002181 p->cipher_key_len = SRTP_AES_128_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002182 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigusc13c1002014-05-08 13:34:53 -04002183 p->auth_key_len = 0;
2184 p->auth_tag_len = 16; /* 16 octet tag length */
2185 p->sec_serv = sec_serv_conf_and_auth;
2186}
2187
2188/*
2189 * AES-256 GCM mode with 16 octet auth tag.
2190 */
2191void
jfigus857009c2014-11-05 11:17:43 -05002192srtp_crypto_policy_set_aes_gcm_256_16_auth(srtp_crypto_policy_t *p) {
jfigus67b9c732014-11-20 10:17:21 -05002193 p->cipher_type = SRTP_AES_256_GCM;
jfigus857009c2014-11-05 11:17:43 -05002194 p->cipher_key_len = SRTP_AES_256_GCM_KEYSIZE_WSALT;
jfigus67b9c732014-11-20 10:17:21 -05002195 p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
jfigusc13c1002014-05-08 13:34:53 -04002196 p->auth_key_len = 0;
2197 p->auth_tag_len = 16; /* 16 octet tag length */
2198 p->sec_serv = sec_serv_conf_and_auth;
2199}
2200
jfigus8c36da22013-10-01 16:41:19 -04002201#endif
Jonathan Lennox5df951a2010-05-20 20:55:54 +00002202
Cullen Jennings235513a2005-09-21 22:51:36 +00002203/*
2204 * secure rtcp functions
2205 */
2206
jfigus8c36da22013-10-01 16:41:19 -04002207/*
2208 * AEAD uses a new IV formation method. This function implements
2209 * section 10.1 from draft-ietf-avtcore-srtp-aes-gcm-07.txt. The
2210 * calculation is defined as, where (+) is the xor operation:
2211 *
2212 * 0 1 2 3 4 5 6 7 8 9 10 11
2213 * +--+--+--+--+--+--+--+--+--+--+--+--+
2214 * |00|00| SSRC |00|00|0+SRTCP Idx|---+
2215 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2216 * |
2217 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2218 * | Encryption Salt |->(+)
2219 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2220 * |
2221 * +--+--+--+--+--+--+--+--+--+--+--+--+ |
2222 * | Initialization Vector |<--+
2223 * +--+--+--+--+--+--+--+--+--+--+--+--+*
2224 *
2225 * Input: *stream - pointer to SRTP stream context, used to retrieve
2226 * the SALT
2227 * *iv - Pointer to recieve the calculated IV
2228 * seq_num - The SEQ value to use for the IV calculation.
2229 * *hdr - The RTP header, used to get the SSRC value
2230 *
2231 */
2232static void srtp_calc_aead_iv_srtcp(srtp_stream_ctx_t *stream, v128_t *iv,
2233 uint32_t seq_num, srtcp_hdr_t *hdr)
2234{
2235 v128_t in;
2236 v128_t salt;
2237
2238 memset(&in, 0, sizeof(v128_t));
2239 memset(&salt, 0, sizeof(v128_t));
2240
2241 in.v16[0] = 0;
2242 memcpy(&in.v16[1], &hdr->ssrc, 4); /* still in network order! */
2243 in.v16[3] = 0;
2244 in.v32[2] = 0x7FFFFFFF & htonl(seq_num); /* bit 32 is suppose to be zero */
2245
2246 debug_print(mod_srtp, "Pre-salted RTCP IV = %s\n", v128_hex_string(&in));
2247
2248 /*
2249 * Get the SALT value from the context
2250 */
2251 memcpy(salt.v8, stream->c_salt, 12);
2252 debug_print(mod_srtp, "RTCP SALT = %s\n", v128_hex_string(&salt));
2253
2254 /*
2255 * Finally, apply the SALT to the input
2256 */
2257 v128_xor(iv, &in, &salt);
2258}
2259
2260/*
2261 * This code handles AEAD ciphers for outgoing RTCP. We currently support
2262 * AES-GCM mode with 128 or 256 bit keys.
2263 */
jfigus857009c2014-11-05 11:17:43 -05002264static srtp_err_status_t
jfigus8c36da22013-10-01 16:41:19 -04002265srtp_protect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream,
Travis Cross31844002014-07-02 16:18:57 +00002266 void *rtcp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -04002267{
2268 srtcp_hdr_t *hdr = (srtcp_hdr_t*)rtcp_hdr;
2269 uint32_t *enc_start; /* pointer to start of encrypted portion */
2270 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002271 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -04002272 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
jfigus857009c2014-11-05 11:17:43 -05002273 srtp_err_status_t status;
jfigus8c36da22013-10-01 16:41:19 -04002274 int tag_len;
2275 uint32_t seq_num;
2276 v128_t iv;
2277 uint32_t tseq;
2278
2279 /* get tag length from stream context */
jfigus8f669722014-11-19 15:20:03 -05002280 tag_len = srtp_auth_get_tag_length(stream->rtcp_auth);
jfigus8c36da22013-10-01 16:41:19 -04002281
2282 /*
2283 * set encryption start and encryption length - if we're not
2284 * providing confidentiality, set enc_start to NULL
2285 */
2286 enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header;
2287 enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
2288
2289 /* NOTE: hdr->length is not usable - it refers to only the first
2290 RTCP report in the compound packet! */
2291 /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2292 multiples of 32-bits (RFC 3550 6.1) */
2293 trailer = (uint32_t*)((char*)enc_start + enc_octet_len + tag_len);
2294
2295 if (stream->rtcp_services & sec_serv_conf) {
2296 *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
2297 } else {
2298 enc_start = NULL;
2299 enc_octet_len = 0;
2300 /* 0 is network-order independant */
2301 *trailer = 0x00000000; /* set encrypt bit */
2302 }
2303
2304 /*
2305 * set the auth_tag pointer to the proper location, which is after
2306 * the payload, but before the trailer
2307 * (note that srtpc *always* provides authentication, unlike srtp)
2308 */
2309 /* Note: This would need to change for optional mikey data */
2310 auth_tag = (uint8_t*)hdr + *pkt_octet_len;
2311
2312 /*
2313 * check sequence number for overruns, and copy it into the packet
2314 * if its value isn't too big
2315 */
jfigusde8deb32014-11-25 12:58:11 -05002316 status = srtp_rdb_increment(&stream->rtcp_rdb);
jfigus8c36da22013-10-01 16:41:19 -04002317 if (status) {
2318 return status;
2319 }
jfigusde8deb32014-11-25 12:58:11 -05002320 seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
jfigus8c36da22013-10-01 16:41:19 -04002321 *trailer |= htonl(seq_num);
2322 debug_print(mod_srtp, "srtcp index: %x", seq_num);
2323
2324 /*
2325 * Calculating the IV and pass it down to the cipher
2326 */
2327 srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
2328 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
2329 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002330 return srtp_err_status_cipher_fail;
jfigus8c36da22013-10-01 16:41:19 -04002331 }
2332
2333 /*
2334 * Set the AAD for GCM mode
2335 */
2336 if (enc_start) {
2337 /*
2338 * If payload encryption is enabled, then the AAD consist of
2339 * the RTCP header and the seq# at the end of the packet
2340 */
2341 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2342 octets_in_rtcp_header);
2343 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002344 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002345 }
2346 } else {
2347 /*
2348 * Since payload encryption is not enabled, we must authenticate
2349 * the entire packet as described in section 10.3 in revision 07
2350 * of the draft.
2351 */
2352 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2353 *pkt_octet_len);
2354 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002355 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002356 }
2357 }
2358 /*
2359 * put the idx# into network byte order and process it as AAD
2360 */
2361 tseq = htonl(*trailer);
2362 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq,
2363 sizeof(srtcp_trailer_t));
2364 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002365 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002366 }
2367
2368 /* if we're encrypting, exor keystream into the message */
2369 if (enc_start) {
jfigus2964a152014-11-25 15:25:37 -05002370 status = srtp_cipher_encrypt(stream->rtcp_cipher,
2371 (uint8_t*)enc_start, &enc_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04002372 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002373 return srtp_err_status_cipher_fail;
jfigus8c36da22013-10-01 16:41:19 -04002374 }
2375 /*
2376 * Get the tag and append that to the output
2377 */
2378 status = cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag,
2379 &tag_len);
2380 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002381 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002382 }
2383 enc_octet_len += tag_len;
2384 } else {
2385 /*
2386 * Even though we're not encrypting the payload, we need
2387 * to run the cipher to get the auth tag.
2388 */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002389 unsigned int nolen = 0;
jfigus2964a152014-11-25 15:25:37 -05002390 status = srtp_cipher_encrypt(stream->rtcp_cipher, NULL, &nolen);
jfigus8c36da22013-10-01 16:41:19 -04002391 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002392 return srtp_err_status_cipher_fail;
jfigus8c36da22013-10-01 16:41:19 -04002393 }
2394 /*
2395 * Get the tag and append that to the output
2396 */
2397 status = cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag,
2398 &tag_len);
2399 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002400 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002401 }
2402 enc_octet_len += tag_len;
2403 }
2404
2405 /* increase the packet length by the length of the auth tag and seq_num*/
2406 *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
2407
jfigus857009c2014-11-05 11:17:43 -05002408 return srtp_err_status_ok;
jfigus8c36da22013-10-01 16:41:19 -04002409}
2410
2411/*
2412 * This function handles incoming SRTCP packets while in AEAD mode,
2413 * which currently supports AES-GCM encryption. Note, the auth tag is
2414 * at the end of the packet stream and is automatically checked by GCM
2415 * when decrypting the payload.
2416 */
jfigus857009c2014-11-05 11:17:43 -05002417static srtp_err_status_t
jfigus8c36da22013-10-01 16:41:19 -04002418srtp_unprotect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream,
Travis Cross31844002014-07-02 16:18:57 +00002419 void *srtcp_hdr, unsigned int *pkt_octet_len)
jfigus8c36da22013-10-01 16:41:19 -04002420{
2421 srtcp_hdr_t *hdr = (srtcp_hdr_t*)srtcp_hdr;
2422 uint32_t *enc_start; /* pointer to start of encrypted portion */
2423 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002424 unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
jfigus8c36da22013-10-01 16:41:19 -04002425 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
jfigus857009c2014-11-05 11:17:43 -05002426 srtp_err_status_t status;
jfigus8c36da22013-10-01 16:41:19 -04002427 int tag_len;
2428 unsigned int tmp_len;
2429 uint32_t seq_num;
2430 v128_t iv;
2431 uint32_t tseq;
2432
2433 /* get tag length from stream context */
jfigus8f669722014-11-19 15:20:03 -05002434 tag_len = srtp_auth_get_tag_length(stream->rtcp_auth);
jfigus8c36da22013-10-01 16:41:19 -04002435
jfigus8c36da22013-10-01 16:41:19 -04002436 /*
2437 * set encryption start, encryption length, and trailer
2438 */
2439 /* index & E (encryption) bit follow normal data. hdr->len
2440 is the number of words (32-bit) in the normal packet minus 1 */
2441 /* This should point trailer to the word past the end of the
2442 normal data. */
2443 /* This would need to be modified for optional mikey data */
2444 /*
2445 * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2446 * multiples of 32-bits (RFC 3550 6.1)
2447 */
2448 trailer = (uint32_t*)((char*)hdr + *pkt_octet_len - sizeof(srtcp_trailer_t));
2449 /*
2450 * We pass the tag down to the cipher when doing GCM mode
2451 */
2452 enc_octet_len = *pkt_octet_len - (octets_in_rtcp_header +
2453 sizeof(srtcp_trailer_t));
2454 auth_tag = (uint8_t*)hdr + *pkt_octet_len - tag_len - sizeof(srtcp_trailer_t);
2455
2456 if (*((unsigned char*)trailer) & SRTCP_E_BYTE_BIT) {
2457 enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header;
2458 } else {
2459 enc_octet_len = 0;
2460 enc_start = NULL; /* this indicates that there's no encryption */
2461 }
2462
2463 /*
2464 * check the sequence number for replays
2465 */
2466 /* this is easier than dealing with bitfield access */
2467 seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
2468 debug_print(mod_srtp, "srtcp index: %x", seq_num);
jfigusde8deb32014-11-25 12:58:11 -05002469 status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
jfigus8c36da22013-10-01 16:41:19 -04002470 if (status) {
2471 return status;
2472 }
2473
2474 /*
2475 * Calculate and set the IV
2476 */
2477 srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
2478 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
2479 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002480 return srtp_err_status_cipher_fail;
jfigus8c36da22013-10-01 16:41:19 -04002481 }
2482
2483 /*
2484 * Set the AAD for GCM mode
2485 */
2486 if (enc_start) {
2487 /*
2488 * If payload encryption is enabled, then the AAD consist of
2489 * the RTCP header and the seq# at the end of the packet
2490 */
2491 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2492 octets_in_rtcp_header);
2493 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002494 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002495 }
2496 } else {
2497 /*
2498 * Since payload encryption is not enabled, we must authenticate
2499 * the entire packet as described in section 10.3 in revision 07
2500 * of the draft.
2501 */
2502 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr,
2503 (*pkt_octet_len - tag_len - sizeof(srtcp_trailer_t)));
2504 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002505 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002506 }
2507 }
2508
2509 /*
2510 * put the idx# into network byte order, and process it as AAD
2511 */
2512 tseq = htonl(*trailer);
2513 status = cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq,
2514 sizeof(srtcp_trailer_t));
2515 if (status) {
jfigus857009c2014-11-05 11:17:43 -05002516 return ( srtp_err_status_cipher_fail);
jfigus8c36da22013-10-01 16:41:19 -04002517 }
2518
2519 /* if we're decrypting, exor keystream into the message */
2520 if (enc_start) {
jfigus2964a152014-11-25 15:25:37 -05002521 status = srtp_cipher_decrypt(stream->rtcp_cipher, (uint8_t*)enc_start, &enc_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04002522 if (status) {
2523 return status;
2524 }
2525 } else {
2526 /*
2527 * Still need to run the cipher to check the tag
2528 */
2529 tmp_len = tag_len;
jfigus2964a152014-11-25 15:25:37 -05002530 status = srtp_cipher_decrypt(stream->rtcp_cipher, (uint8_t*)auth_tag, &tmp_len);
jfigus8c36da22013-10-01 16:41:19 -04002531 if (status) {
2532 return status;
2533 }
2534 }
2535
2536 /* decrease the packet length by the length of the auth tag and seq_num*/
2537 *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
2538
2539 /*
2540 * verify that stream is for received traffic - this check will
2541 * detect SSRC collisions, since a stream that appears in both
2542 * srtp_protect() and srtp_unprotect() will fail this test in one of
2543 * those functions.
2544 *
2545 * we do this check *after* the authentication check, so that the
2546 * latter check will catch any attempts to fool us into thinking
2547 * that we've got a collision
2548 */
2549 if (stream->direction != dir_srtp_receiver) {
2550 if (stream->direction == dir_unknown) {
2551 stream->direction = dir_srtp_receiver;
2552 } else {
2553 srtp_handle_event(ctx, stream, event_ssrc_collision);
2554 }
2555 }
2556
2557 /*
2558 * if the stream is a 'provisional' one, in which the template context
2559 * is used, then we need to allocate a new stream at this point, since
2560 * the authentication passed
2561 */
2562 if (stream == ctx->stream_template) {
2563 srtp_stream_ctx_t *new_stream;
2564
2565 /*
2566 * allocate and initialize a new stream
2567 *
2568 * note that we indicate failure if we can't allocate the new
2569 * stream, and some implementations will want to not return
2570 * failure here
2571 */
2572 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
2573 if (status) {
2574 return status;
2575 }
2576
2577 /* add new stream to the head of the stream_list */
2578 new_stream->next = ctx->stream_list;
2579 ctx->stream_list = new_stream;
2580
2581 /* set stream (the pointer used in this function) */
2582 stream = new_stream;
2583 }
2584
2585 /* we've passed the authentication check, so add seq_num to the rdb */
jfigusde8deb32014-11-25 12:58:11 -05002586 srtp_rdb_add_index(&stream->rtcp_rdb, seq_num);
jfigus8c36da22013-10-01 16:41:19 -04002587
jfigus857009c2014-11-05 11:17:43 -05002588 return srtp_err_status_ok;
jfigus8c36da22013-10-01 16:41:19 -04002589}
2590
jfigus857009c2014-11-05 11:17:43 -05002591srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00002592srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00002593 srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00002594 uint32_t *enc_start; /* pointer to start of encrypted portion */
2595 uint32_t *auth_start; /* pointer to start of auth. portion */
2596 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002597 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002598 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
jfigus857009c2014-11-05 11:17:43 -05002599 srtp_err_status_t status;
Cullen Jennings235513a2005-09-21 22:51:36 +00002600 int tag_len;
2601 srtp_stream_ctx_t *stream;
jfigus2964a152014-11-25 15:25:37 -05002602 uint32_t prefix_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00002603 uint32_t seq_num;
2604
2605 /* we assume the hdr is 32-bit aligned to start */
Travis Cross8ba46eb2014-06-29 18:42:29 +00002606
2607 /* check the packet length - it must at least contain a full header */
2608 if (*pkt_octet_len < octets_in_rtcp_header)
jfigus857009c2014-11-05 11:17:43 -05002609 return srtp_err_status_bad_param;
Travis Cross8ba46eb2014-06-29 18:42:29 +00002610
Cullen Jennings235513a2005-09-21 22:51:36 +00002611 /*
2612 * look up ssrc in srtp_stream list, and process the packet with
2613 * the appropriate stream. if we haven't seen this stream before,
2614 * there's only one key for this srtp_session, and the cipher
2615 * supports key-sharing, then we assume that a new stream using
2616 * that key has just started up
2617 */
2618 stream = srtp_get_stream(ctx, hdr->ssrc);
2619 if (stream == NULL) {
2620 if (ctx->stream_template != NULL) {
2621 srtp_stream_ctx_t *new_stream;
2622
2623 /* allocate and initialize a new stream */
2624 status = srtp_stream_clone(ctx->stream_template,
2625 hdr->ssrc, &new_stream);
2626 if (status)
2627 return status;
2628
2629 /* add new stream to the head of the stream_list */
2630 new_stream->next = ctx->stream_list;
2631 ctx->stream_list = new_stream;
2632
2633 /* set stream (the pointer used in this function) */
2634 stream = new_stream;
2635 } else {
2636 /* no template stream, so we return an error */
jfigus857009c2014-11-05 11:17:43 -05002637 return srtp_err_status_no_ctx;
Cullen Jennings235513a2005-09-21 22:51:36 +00002638 }
2639 }
2640
2641 /*
2642 * verify that stream is for sending traffic - this check will
2643 * detect SSRC collisions, since a stream that appears in both
2644 * srtp_protect() and srtp_unprotect() will fail this test in one of
2645 * those functions.
2646 */
2647 if (stream->direction != dir_srtp_sender) {
2648 if (stream->direction == dir_unknown) {
David McGrewc34f7402006-03-09 21:17:00 +00002649 stream->direction = dir_srtp_sender;
Cullen Jennings235513a2005-09-21 22:51:36 +00002650 } else {
2651 srtp_handle_event(ctx, stream, event_ssrc_collision);
2652 }
2653 }
2654
jfigus8c36da22013-10-01 16:41:19 -04002655 /*
2656 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
2657 * the request to our AEAD handler.
2658 */
jfigus67b9c732014-11-20 10:17:21 -05002659 if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
2660 stream->rtp_cipher->algorithm == SRTP_AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00002661 return srtp_protect_rtcp_aead(ctx, stream, rtcp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04002662 }
2663
Cullen Jennings235513a2005-09-21 22:51:36 +00002664 /* get tag length from stream context */
jfigus8f669722014-11-19 15:20:03 -05002665 tag_len = srtp_auth_get_tag_length(stream->rtcp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00002666
2667 /*
2668 * set encryption start and encryption length - if we're not
2669 * providing confidentiality, set enc_start to NULL
2670 */
2671 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
2672 enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
2673
2674 /* all of the packet, except the header, gets encrypted */
2675 /* NOTE: hdr->length is not usable - it refers to only the first
2676 RTCP report in the compound packet! */
2677 /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2678 multiples of 32-bits (RFC 3550 6.1) */
2679 trailer = (uint32_t *) ((char *)enc_start + enc_octet_len);
2680
2681 if (stream->rtcp_services & sec_serv_conf) {
2682 *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
2683 } else {
2684 enc_start = NULL;
2685 enc_octet_len = 0;
2686 /* 0 is network-order independant */
2687 *trailer = 0x00000000; /* set encrypt bit */
2688 }
2689
2690 /*
2691 * set the auth_start and auth_tag pointers to the proper locations
2692 * (note that srtpc *always* provides authentication, unlike srtp)
2693 */
2694 /* Note: This would need to change for optional mikey data */
2695 auth_start = (uint32_t *)hdr;
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002696 auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t);
Cullen Jennings235513a2005-09-21 22:51:36 +00002697
David McGrew79870d62007-06-15 18:17:39 +00002698 /* perform EKT processing if needed */
jfigusc5887e72014-11-06 09:46:18 -05002699 srtp_ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len,
jfigusde8deb32014-11-25 12:58:11 -05002700 srtp_rdbx_get_packet_index(&stream->rtp_rdbx));
David McGrew79870d62007-06-15 18:17:39 +00002701
Cullen Jennings235513a2005-09-21 22:51:36 +00002702 /*
2703 * check sequence number for overruns, and copy it into the packet
2704 * if its value isn't too big
2705 */
jfigusde8deb32014-11-25 12:58:11 -05002706 status = srtp_rdb_increment(&stream->rtcp_rdb);
Cullen Jennings235513a2005-09-21 22:51:36 +00002707 if (status)
2708 return status;
jfigusde8deb32014-11-25 12:58:11 -05002709 seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
Cullen Jennings235513a2005-09-21 22:51:36 +00002710 *trailer |= htonl(seq_num);
2711 debug_print(mod_srtp, "srtcp index: %x", seq_num);
2712
2713 /*
2714 * if we're using rindael counter mode, set nonce and seq
2715 */
jfigus67b9c732014-11-20 10:17:21 -05002716 if (stream->rtcp_cipher->type->id == SRTP_AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002717 v128_t iv;
2718
2719 iv.v32[0] = 0;
2720 iv.v32[1] = hdr->ssrc; /* still in network order! */
2721 iv.v32[2] = htonl(seq_num >> 16);
2722 iv.v32[3] = htonl(seq_num << 16);
jfigus7882dd92013-08-02 16:08:23 -04002723 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002724
2725 } else {
2726 v128_t iv;
2727
2728 /* otherwise, just set the index to seq_num */
2729 iv.v32[0] = 0;
2730 iv.v32[1] = 0;
2731 iv.v32[2] = 0;
2732 iv.v32[3] = htonl(seq_num);
jfigus7882dd92013-08-02 16:08:23 -04002733 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_encrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002734 }
2735 if (status)
jfigus857009c2014-11-05 11:17:43 -05002736 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002737
2738 /*
2739 * if we're authenticating using a universal hash, put the keystream
2740 * prefix into the authentication tag
2741 */
2742
2743 /* if auth_start is non-null, then put keystream into tag */
2744 if (auth_start) {
2745
2746 /* put keystream prefix into auth_tag */
jfigus8f669722014-11-19 15:20:03 -05002747 prefix_len = srtp_auth_get_prefix_length(stream->rtcp_auth);
jfigus2964a152014-11-25 15:25:37 -05002748 status = srtp_cipher_output(stream->rtcp_cipher, auth_tag, &prefix_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002749
2750 debug_print(mod_srtp, "keystream prefix: %s",
jfigus46d6b472014-11-14 16:42:01 -05002751 srtp_octet_string_hex_string(auth_tag, prefix_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00002752
2753 if (status)
jfigus857009c2014-11-05 11:17:43 -05002754 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002755 }
2756
2757 /* if we're encrypting, exor keystream into the message */
2758 if (enc_start) {
jfigus2964a152014-11-25 15:25:37 -05002759 status = srtp_cipher_encrypt(stream->rtcp_cipher,
2760 (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002761 if (status)
jfigus857009c2014-11-05 11:17:43 -05002762 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002763 }
2764
2765 /* initialize auth func context */
2766 auth_start(stream->rtcp_auth);
2767
David McGrew9c70f292006-05-03 19:38:38 +00002768 /*
2769 * run auth func over packet (including trailer), and write the
2770 * result at auth_tag
2771 */
Cullen Jennings235513a2005-09-21 22:51:36 +00002772 status = auth_compute(stream->rtcp_auth,
David McGrew9c70f292006-05-03 19:38:38 +00002773 (uint8_t *)auth_start,
2774 (*pkt_octet_len) + sizeof(srtcp_trailer_t),
2775 auth_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00002776 debug_print(mod_srtp, "srtcp auth tag: %s",
jfigus46d6b472014-11-14 16:42:01 -05002777 srtp_octet_string_hex_string(auth_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00002778 if (status)
jfigus857009c2014-11-05 11:17:43 -05002779 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002780
2781 /* increase the packet length by the length of the auth tag and seq_num*/
2782 *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
2783
jfigus857009c2014-11-05 11:17:43 -05002784 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00002785}
2786
2787
jfigus857009c2014-11-05 11:17:43 -05002788srtp_err_status_t
Cullen Jennings235513a2005-09-21 22:51:36 +00002789srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) {
Derek MacDonald17127da2006-07-12 22:22:08 +00002790 srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
Cullen Jennings235513a2005-09-21 22:51:36 +00002791 uint32_t *enc_start; /* pointer to start of encrypted portion */
2792 uint32_t *auth_start; /* pointer to start of auth. portion */
2793 uint32_t *trailer; /* pointer to start of trailer */
Travis Cross1b8b1e72014-07-02 15:32:36 +00002794 unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002795 uint8_t *auth_tag = NULL; /* location of auth_tag within packet */
2796 uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
David McGrew79870d62007-06-15 18:17:39 +00002797 uint8_t tag_copy[SRTP_MAX_TAG_LEN];
jfigus857009c2014-11-05 11:17:43 -05002798 srtp_err_status_t status;
Travis Cross1b8b1e72014-07-02 15:32:36 +00002799 unsigned int auth_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00002800 int tag_len;
2801 srtp_stream_ctx_t *stream;
jfigus2964a152014-11-25 15:25:37 -05002802 uint32_t prefix_len;
Cullen Jennings235513a2005-09-21 22:51:36 +00002803 uint32_t seq_num;
TV Sriram4986a362013-05-06 11:24:03 -07002804 int e_bit_in_packet; /* whether the E-bit was found in the packet */
2805 int sec_serv_confidentiality; /* whether confidentiality was requested */
Cullen Jennings235513a2005-09-21 22:51:36 +00002806
2807 /* we assume the hdr is 32-bit aligned to start */
Travis Cross444a5442014-07-02 16:01:01 +00002808
Travis Crosse896bf72014-07-07 19:59:33 +00002809 /* check that the length value is sane; we'll check again once we
2810 know the tag length, but we at least want to know that it is
2811 a positive value */
2812 if (*pkt_octet_len < octets_in_rtcp_header + sizeof(srtcp_trailer_t))
jfigus857009c2014-11-05 11:17:43 -05002813 return srtp_err_status_bad_param;
Travis Crosse896bf72014-07-07 19:59:33 +00002814
Cullen Jennings235513a2005-09-21 22:51:36 +00002815 /*
2816 * look up ssrc in srtp_stream list, and process the packet with
2817 * the appropriate stream. if we haven't seen this stream before,
2818 * there's only one key for this srtp_session, and the cipher
2819 * supports key-sharing, then we assume that a new stream using
2820 * that key has just started up
2821 */
2822 stream = srtp_get_stream(ctx, hdr->ssrc);
2823 if (stream == NULL) {
2824 if (ctx->stream_template != NULL) {
2825 stream = ctx->stream_template;
David McGrew79870d62007-06-15 18:17:39 +00002826
2827 /*
2828 * check to see if stream_template has an EKT data structure, in
2829 * which case we initialize the template using the EKT policy
2830 * referenced by that data (which consists of decrypting the
2831 * master key from the EKT field)
2832 *
2833 * this function initializes a *provisional* stream, and this
2834 * stream should not be accepted until and unless the packet
2835 * passes its authentication check
2836 */
2837 if (stream->ekt != NULL) {
2838 status = srtp_stream_init_from_ekt(stream, srtcp_hdr, *pkt_octet_len);
2839 if (status)
2840 return status;
2841 }
2842
Cullen Jennings235513a2005-09-21 22:51:36 +00002843 debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)",
2844 hdr->ssrc);
2845 } else {
2846 /* no template stream, so we return an error */
jfigus857009c2014-11-05 11:17:43 -05002847 return srtp_err_status_no_ctx;
Cullen Jennings235513a2005-09-21 22:51:36 +00002848 }
2849 }
2850
Travis Cross8ba46eb2014-06-29 18:42:29 +00002851 /* get tag length from stream context */
jfigus8f669722014-11-19 15:20:03 -05002852 tag_len = srtp_auth_get_tag_length(stream->rtcp_auth);
Travis Cross8ba46eb2014-06-29 18:42:29 +00002853
2854 /* check the packet length - it must contain at least a full RTCP
2855 header, an auth tag (if applicable), and the SRTCP encrypted flag
2856 and 31-bit index value */
jfigus73e30932014-07-07 15:50:32 -04002857 if (*pkt_octet_len < (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t))) {
jfigus857009c2014-11-05 11:17:43 -05002858 return srtp_err_status_bad_param;
jfigus73e30932014-07-07 15:50:32 -04002859 }
Travis Cross8ba46eb2014-06-29 18:42:29 +00002860
jfigus8c36da22013-10-01 16:41:19 -04002861 /*
2862 * Check if this is an AEAD stream (GCM mode). If so, then dispatch
2863 * the request to our AEAD handler.
2864 */
jfigus67b9c732014-11-20 10:17:21 -05002865 if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
2866 stream->rtp_cipher->algorithm == SRTP_AES_256_GCM) {
Travis Cross31844002014-07-02 16:18:57 +00002867 return srtp_unprotect_rtcp_aead(ctx, stream, srtcp_hdr, (unsigned int*)pkt_octet_len);
jfigus8c36da22013-10-01 16:41:19 -04002868 }
2869
TV Sriram4986a362013-05-06 11:24:03 -07002870 sec_serv_confidentiality = stream->rtcp_services == sec_serv_conf ||
2871 stream->rtcp_services == sec_serv_conf_and_auth;
2872
Cullen Jennings235513a2005-09-21 22:51:36 +00002873 /*
2874 * set encryption start, encryption length, and trailer
2875 */
2876 enc_octet_len = *pkt_octet_len -
2877 (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t));
2878 /* index & E (encryption) bit follow normal data. hdr->len
2879 is the number of words (32-bit) in the normal packet minus 1 */
2880 /* This should point trailer to the word past the end of the
2881 normal data. */
2882 /* This would need to be modified for optional mikey data */
2883 /*
2884 * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
2885 * multiples of 32-bits (RFC 3550 6.1)
2886 */
2887 trailer = (uint32_t *) ((char *) hdr +
TV Sriram4986a362013-05-06 11:24:03 -07002888 *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t)));
2889 e_bit_in_packet =
2890 (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) == SRTCP_E_BYTE_BIT;
2891 if (e_bit_in_packet != sec_serv_confidentiality) {
jfigus857009c2014-11-05 11:17:43 -05002892 return srtp_err_status_cant_check;
TV Sriram4986a362013-05-06 11:24:03 -07002893 }
2894 if (sec_serv_confidentiality) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002895 enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
2896 } else {
2897 enc_octet_len = 0;
2898 enc_start = NULL; /* this indicates that there's no encryption */
2899 }
2900
2901 /*
2902 * set the auth_start and auth_tag pointers to the proper locations
2903 * (note that srtcp *always* uses authentication, unlike srtp)
2904 */
2905 auth_start = (uint32_t *)hdr;
David McGrew79870d62007-06-15 18:17:39 +00002906 auth_len = *pkt_octet_len - tag_len;
2907 auth_tag = (uint8_t *)hdr + auth_len;
2908
2909 /*
2910 * if EKT is in use, then we make a copy of the tag from the packet,
2911 * and then zeroize the location of the base tag
2912 *
2913 * we first re-position the auth_tag pointer so that it points to
2914 * the base tag
2915 */
2916 if (stream->ekt) {
jfigusc5887e72014-11-06 09:46:18 -05002917 auth_tag -= srtp_ekt_octets_after_base_tag(stream->ekt);
David McGrew79870d62007-06-15 18:17:39 +00002918 memcpy(tag_copy, auth_tag, tag_len);
2919 octet_string_set_to_zero(auth_tag, tag_len);
2920 auth_tag = tag_copy;
2921 auth_len += tag_len;
2922 }
Cullen Jennings235513a2005-09-21 22:51:36 +00002923
2924 /*
2925 * check the sequence number for replays
2926 */
2927 /* this is easier than dealing with bitfield access */
2928 seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
David McGrew9c70f292006-05-03 19:38:38 +00002929 debug_print(mod_srtp, "srtcp index: %x", seq_num);
jfigusde8deb32014-11-25 12:58:11 -05002930 status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
Cullen Jennings235513a2005-09-21 22:51:36 +00002931 if (status)
2932 return status;
Cullen Jennings235513a2005-09-21 22:51:36 +00002933
2934 /*
2935 * if we're using aes counter mode, set nonce and seq
2936 */
jfigus67b9c732014-11-20 10:17:21 -05002937 if (stream->rtcp_cipher->type->id == SRTP_AES_ICM) {
Cullen Jennings235513a2005-09-21 22:51:36 +00002938 v128_t iv;
2939
2940 iv.v32[0] = 0;
2941 iv.v32[1] = hdr->ssrc; /* still in network order! */
2942 iv.v32[2] = htonl(seq_num >> 16);
2943 iv.v32[3] = htonl(seq_num << 16);
jfigus7882dd92013-08-02 16:08:23 -04002944 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002945
2946 } else {
2947 v128_t iv;
2948
2949 /* otherwise, just set the index to seq_num */
2950 iv.v32[0] = 0;
2951 iv.v32[1] = 0;
2952 iv.v32[2] = 0;
2953 iv.v32[3] = htonl(seq_num);
jfigus7882dd92013-08-02 16:08:23 -04002954 status = cipher_set_iv(stream->rtcp_cipher, &iv, direction_decrypt);
Cullen Jennings235513a2005-09-21 22:51:36 +00002955
2956 }
2957 if (status)
jfigus857009c2014-11-05 11:17:43 -05002958 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002959
2960 /* initialize auth func context */
2961 auth_start(stream->rtcp_auth);
2962
2963 /* run auth func over packet, put result into tmp_tag */
Marcus Sundberg410faaa2005-09-29 12:36:43 +00002964 status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start,
David McGrew79870d62007-06-15 18:17:39 +00002965 auth_len, tmp_tag);
Cullen Jennings235513a2005-09-21 22:51:36 +00002966 debug_print(mod_srtp, "srtcp computed tag: %s",
jfigus46d6b472014-11-14 16:42:01 -05002967 srtp_octet_string_hex_string(tmp_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00002968 if (status)
jfigus857009c2014-11-05 11:17:43 -05002969 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002970
2971 /* compare the tag just computed with the one in the packet */
2972 debug_print(mod_srtp, "srtcp tag from packet: %s",
jfigus46d6b472014-11-14 16:42:01 -05002973 srtp_octet_string_hex_string(auth_tag, tag_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00002974 if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
jfigus857009c2014-11-05 11:17:43 -05002975 return srtp_err_status_auth_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002976
2977 /*
2978 * if we're authenticating using a universal hash, put the keystream
2979 * prefix into the authentication tag
2980 */
jfigus8f669722014-11-19 15:20:03 -05002981 prefix_len = srtp_auth_get_prefix_length(stream->rtcp_auth);
Cullen Jennings235513a2005-09-21 22:51:36 +00002982 if (prefix_len) {
jfigus2964a152014-11-25 15:25:37 -05002983 status = srtp_cipher_output(stream->rtcp_cipher, auth_tag, &prefix_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002984 debug_print(mod_srtp, "keystream prefix: %s",
jfigus46d6b472014-11-14 16:42:01 -05002985 srtp_octet_string_hex_string(auth_tag, prefix_len));
Cullen Jennings235513a2005-09-21 22:51:36 +00002986 if (status)
jfigus857009c2014-11-05 11:17:43 -05002987 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002988 }
2989
2990 /* if we're decrypting, exor keystream into the message */
2991 if (enc_start) {
jfigus2964a152014-11-25 15:25:37 -05002992 status = srtp_cipher_decrypt(stream->rtcp_cipher, (uint8_t *)enc_start, &enc_octet_len);
Cullen Jennings235513a2005-09-21 22:51:36 +00002993 if (status)
jfigus857009c2014-11-05 11:17:43 -05002994 return srtp_err_status_cipher_fail;
Cullen Jennings235513a2005-09-21 22:51:36 +00002995 }
2996
David McGrew79870d62007-06-15 18:17:39 +00002997 /* decrease the packet length by the length of the auth tag and seq_num */
Cullen Jennings235513a2005-09-21 22:51:36 +00002998 *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
2999
David McGrew79870d62007-06-15 18:17:39 +00003000 /*
3001 * if EKT is in effect, subtract the EKT data out of the packet
3002 * length
3003 */
jfigusc5887e72014-11-06 09:46:18 -05003004 *pkt_octet_len -= srtp_ekt_octets_after_base_tag(stream->ekt);
David McGrew79870d62007-06-15 18:17:39 +00003005
Cullen Jennings235513a2005-09-21 22:51:36 +00003006 /*
3007 * verify that stream is for received traffic - this check will
3008 * detect SSRC collisions, since a stream that appears in both
3009 * srtp_protect() and srtp_unprotect() will fail this test in one of
3010 * those functions.
3011 *
3012 * we do this check *after* the authentication check, so that the
3013 * latter check will catch any attempts to fool us into thinking
3014 * that we've got a collision
3015 */
3016 if (stream->direction != dir_srtp_receiver) {
3017 if (stream->direction == dir_unknown) {
3018 stream->direction = dir_srtp_receiver;
3019 } else {
3020 srtp_handle_event(ctx, stream, event_ssrc_collision);
3021 }
3022 }
3023
3024 /*
3025 * if the stream is a 'provisional' one, in which the template context
3026 * is used, then we need to allocate a new stream at this point, since
3027 * the authentication passed
3028 */
3029 if (stream == ctx->stream_template) {
3030 srtp_stream_ctx_t *new_stream;
3031
3032 /*
3033 * allocate and initialize a new stream
3034 *
3035 * note that we indicate failure if we can't allocate the new
3036 * stream, and some implementations will want to not return
3037 * failure here
3038 */
3039 status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
3040 if (status)
3041 return status;
3042
3043 /* add new stream to the head of the stream_list */
3044 new_stream->next = ctx->stream_list;
3045 ctx->stream_list = new_stream;
3046
3047 /* set stream (the pointer used in this function) */
3048 stream = new_stream;
3049 }
3050
3051 /* we've passed the authentication check, so add seq_num to the rdb */
jfigusde8deb32014-11-25 12:58:11 -05003052 srtp_rdb_add_index(&stream->rtcp_rdb, seq_num);
Cullen Jennings235513a2005-09-21 22:51:36 +00003053
3054
jfigus857009c2014-11-05 11:17:43 -05003055 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +00003056}
David McGrew0cb86ee2006-07-07 15:46:57 +00003057
3058
Iñaki Baz Castillo241fec32014-08-21 00:51:00 +02003059/*
3060 * user data within srtp_t context
3061 */
3062
3063void
3064srtp_set_user_data(srtp_t ctx, void *data) {
3065 ctx->user_data = data;
3066}
3067
3068void*
3069srtp_get_user_data(srtp_t ctx) {
3070 return ctx->user_data;
3071}
3072
David McGrew0cb86ee2006-07-07 15:46:57 +00003073
3074/*
3075 * dtls keying for srtp
3076 */
3077
jfigus857009c2014-11-05 11:17:43 -05003078srtp_err_status_t
3079srtp_crypto_policy_set_from_profile_for_rtp(srtp_crypto_policy_t *policy,
3080 srtp_profile_t profile) {
David McGrew0cb86ee2006-07-07 15:46:57 +00003081
3082 /* set SRTP policy from the SRTP profile in the key set */
3083 switch(profile) {
3084 case srtp_profile_aes128_cm_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003085 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003086 break;
3087 case srtp_profile_aes128_cm_sha1_32:
jfigus857009c2014-11-05 11:17:43 -05003088 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003089 break;
3090 case srtp_profile_null_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003091 srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003092 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003093 case srtp_profile_aes256_cm_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003094 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003095 break;
3096 case srtp_profile_aes256_cm_sha1_32:
jfigus857009c2014-11-05 11:17:43 -05003097 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(policy);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003098 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003099 /* the following profiles are not (yet) supported */
3100 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003101 default:
jfigus857009c2014-11-05 11:17:43 -05003102 return srtp_err_status_bad_param;
David McGrew0cb86ee2006-07-07 15:46:57 +00003103 }
3104
jfigus857009c2014-11-05 11:17:43 -05003105 return srtp_err_status_ok;
David McGrew0cb86ee2006-07-07 15:46:57 +00003106}
3107
jfigus857009c2014-11-05 11:17:43 -05003108srtp_err_status_t
3109srtp_crypto_policy_set_from_profile_for_rtcp(srtp_crypto_policy_t *policy,
3110 srtp_profile_t profile) {
David McGrew0cb86ee2006-07-07 15:46:57 +00003111
3112 /* set SRTP policy from the SRTP profile in the key set */
3113 switch(profile) {
3114 case srtp_profile_aes128_cm_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003115 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003116 break;
3117 case srtp_profile_aes128_cm_sha1_32:
jfigus0acbb032013-05-30 16:47:02 -04003118 /* We do not honor the 32-bit auth tag request since
3119 * this is not compliant with RFC 3711 */
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_null_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003123 srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
David McGrew0cb86ee2006-07-07 15:46:57 +00003124 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003125 case srtp_profile_aes256_cm_sha1_80:
jfigus857009c2014-11-05 11:17:43 -05003126 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003127 break;
3128 case srtp_profile_aes256_cm_sha1_32:
jfigus0acbb032013-05-30 16:47:02 -04003129 /* We do not honor the 32-bit auth tag request since
3130 * this is not compliant with RFC 3711 */
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;
David McGrew0cb86ee2006-07-07 15:46:57 +00003133 /* the following profiles are not (yet) supported */
3134 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003135 default:
jfigus857009c2014-11-05 11:17:43 -05003136 return srtp_err_status_bad_param;
David McGrew0cb86ee2006-07-07 15:46:57 +00003137 }
3138
jfigus857009c2014-11-05 11:17:43 -05003139 return srtp_err_status_ok;
David McGrew0cb86ee2006-07-07 15:46:57 +00003140}
3141
jfigus857009c2014-11-05 11:17:43 -05003142void 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 +00003143 memcpy(key + bytes_in_key, salt, bytes_in_salt);
David McGrew0cb86ee2006-07-07 15:46:57 +00003144}
3145
3146unsigned int
3147srtp_profile_get_master_key_length(srtp_profile_t profile) {
3148
3149 switch(profile) {
3150 case srtp_profile_aes128_cm_sha1_80:
3151 return 16;
3152 break;
3153 case srtp_profile_aes128_cm_sha1_32:
3154 return 16;
3155 break;
3156 case srtp_profile_null_sha1_80:
3157 return 16;
3158 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003159 case srtp_profile_aes256_cm_sha1_80:
3160 return 32;
3161 break;
3162 case srtp_profile_aes256_cm_sha1_32:
3163 return 32;
3164 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003165 /* the following profiles are not (yet) supported */
3166 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003167 default:
3168 return 0; /* indicate error by returning a zero */
3169 }
3170}
3171
3172unsigned int
3173srtp_profile_get_master_salt_length(srtp_profile_t profile) {
3174
3175 switch(profile) {
3176 case srtp_profile_aes128_cm_sha1_80:
3177 return 14;
3178 break;
3179 case srtp_profile_aes128_cm_sha1_32:
3180 return 14;
3181 break;
3182 case srtp_profile_null_sha1_80:
3183 return 14;
3184 break;
Jonathan Lennox5df951a2010-05-20 20:55:54 +00003185 case srtp_profile_aes256_cm_sha1_80:
3186 return 14;
3187 break;
3188 case srtp_profile_aes256_cm_sha1_32:
3189 return 14;
3190 break;
David McGrew0cb86ee2006-07-07 15:46:57 +00003191 /* the following profiles are not (yet) supported */
3192 case srtp_profile_null_sha1_32:
David McGrew0cb86ee2006-07-07 15:46:57 +00003193 default:
3194 return 0; /* indicate error by returning a zero */
3195 }
3196}
jfigus46d6b472014-11-14 16:42:01 -05003197
3198/*
3199 * SRTP debug interface
3200 */
3201srtp_err_status_t srtp_set_debug_module(char *mod_name, int v)
3202{
jfigus92736bc2014-11-21 10:30:54 -05003203 return srtp_crypto_kernel_set_debug_module(mod_name, v);
jfigus46d6b472014-11-14 16:42:01 -05003204}
3205
3206srtp_err_status_t srtp_list_debug_modules(void)
3207{
jfigus92736bc2014-11-21 10:30:54 -05003208 return srtp_crypto_kernel_list_debug_modules();
jfigus46d6b472014-11-14 16:42:01 -05003209}
3210