1386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 2386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp.c 3386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 4386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the secure real-time transport protocol 5386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 6386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * David A. McGrew 7386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Cisco Systems, Inc. 8386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 9386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 10386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 11386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Copyright (c) 2001-2006, Cisco Systems, Inc. 12386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * All rights reserved. 13386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 14386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Redistribution and use in source and binary forms, with or without 15386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * modification, are permitted provided that the following conditions 16386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * are met: 17386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 18386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Redistributions of source code must retain the above copyright 19386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * notice, this list of conditions and the following disclaimer. 20386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 21386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Redistributions in binary form must reproduce the above 22386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * copyright notice, this list of conditions and the following 23386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * disclaimer in the documentation and/or other materials provided 24386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * with the distribution. 25386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 26386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Neither the name of the Cisco Systems, Inc. nor the names of its 27386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * contributors may be used to endorse or promote products derived 28386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * from this software without specific prior written permission. 29386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 30386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 33386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 34386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 37386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 41386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * OF THE POSSIBILITY OF SUCH DAMAGE. 42386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 43386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 44386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 45386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 46386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "srtp.h" 47386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "ekt.h" /* for SRTP Encrypted Key Transport */ 48386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "aes_icm.h" /* aes_icm is used in the KDF */ 49386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "alloc.h" /* for crypto_alloc() */ 50386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 51386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifndef SRTP_KERNEL 52386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# include <limits.h> 53386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# ifdef HAVE_NETINET_IN_H 54386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# include <netinet/in.h> 55386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# elif defined(HAVE_WINSOCK2_H) 56386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# include <winsock2.h> 57386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari# endif 58386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif /* ! SRTP_KERNEL */ 59386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 60386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 61386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariextern cipher_type_t aes_icm; 62386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariextern auth_type_t tmmhv2; 63386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 64386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* the debug module for srtp */ 65386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 66386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaridebug_module_t mod_srtp = { 67386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 0, /* debugging is off by default */ 68386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari "srtp" /* printable name for module */ 69386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}; 70386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 71386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define octets_in_rtp_header 12 72386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define uint32s_in_rtp_header 3 73386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define octets_in_rtcp_header 8 74386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define uint32s_in_rtcp_header 2 75386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 76386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 77386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 78386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_stream_alloc(srtp_stream_ctx_t **str_ptr, 79386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari const srtp_policy_t *p) { 80386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *str; 81386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t stat; 82386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 83386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 84386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * This function allocates the stream context, rtp and rtcp ciphers 85386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * and auth functions, and key limit structure. If there is a 86386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * failure during allocation, we free all previously allocated 87386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * memory and return a failure code. The code could probably 88386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * be improved, but it works and should be clear. 89386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 90386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 91386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* allocate srtp stream and set str_ptr */ 92386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t)); 93386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (str == NULL) 94386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_alloc_fail; 95386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *str_ptr = str; 96386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 97386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* allocate cipher */ 98386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stat = crypto_kernel_alloc_cipher(p->rtp.cipher_type, 99386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari &str->rtp_cipher, 100386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->rtp.cipher_key_len); 101386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stat) { 102386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari goto err_rtp_cipher_alloc; 103386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 104386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 105386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* allocate auth function */ 106386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stat = crypto_kernel_alloc_auth(p->rtp.auth_type, 107386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari &str->rtp_auth, 108386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->rtp.auth_key_len, 109386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->rtp.auth_tag_len); 110386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 111386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stat) { 112386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari goto err_rtp_auth_alloc; 113386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 114386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 115386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* allocate key limit structure */ 116386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->limit = (key_limit_ctx_t*) crypto_alloc(sizeof(key_limit_ctx_t)); 117386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (str->limit == NULL) { 118386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stat = err_status_alloc_fail; 119386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari goto err_limit_alloc; 120386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 121386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 122386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 123386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * ...and now the RTCP-specific initialization - first, allocate 124386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the cipher 125386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 126386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stat = crypto_kernel_alloc_cipher(p->rtcp.cipher_type, 127386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari &str->rtcp_cipher, 128386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->rtcp.cipher_key_len); 129386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stat) { 130386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari goto err_rtcp_cipher_alloc; 131386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 132386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 133386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* allocate auth function */ 134386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stat = crypto_kernel_alloc_auth(p->rtcp.auth_type, 135386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari &str->rtcp_auth, 136386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->rtcp.auth_key_len, 137386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->rtcp.auth_tag_len); 138386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stat) { 139386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari goto err_rtcp_auth_alloc; 140386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 141386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 142386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* allocate ekt data associated with stream */ 143386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stat = ekt_alloc(&str->ekt, p->ekt); 144386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stat) { 145386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari goto err_ekt_alloc; 146386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 147386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 148386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 149386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 150386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_ekt_alloc: 151386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_dealloc(str->rtcp_auth); 152386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_rtcp_auth_alloc: 153386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari cipher_dealloc(str->rtcp_cipher); 154386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_rtcp_cipher_alloc: 155386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_free(str->limit); 156386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_limit_alloc: 157386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_dealloc(str->rtp_auth); 158386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_rtp_auth_alloc: 159386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari cipher_dealloc(str->rtp_cipher); 160386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_rtp_cipher_alloc: 161386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_free(str); 162386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return stat; 163386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 164386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 165386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 166386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_stream_dealloc(srtp_stream_ctx_t *stream, 167386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *stream_template) { 168386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 169386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 170386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 171386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * we use a conservative deallocation strategy - if any deallocation 172386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * fails, then we report that fact without trying to deallocate 173386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * anything else 174386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 175386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 176386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* deallocate cipher, if it is not the same as that in template */ 177386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (!stream_template || stream->rtp_cipher != stream_template->rtp_cipher) { 178386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_dealloc(stream->rtp_cipher); 179386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 180386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 181386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 182386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 183386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* deallocate auth function, if it is not the same as that in template */ 184386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (!stream_template || stream->rtp_auth != stream_template->rtp_auth) { 185386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = auth_dealloc(stream->rtp_auth); 186386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 187386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 188386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 189386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 190386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* deallocate key usage limit, if it is not the same as that in template */ 191386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (!stream_template || stream->limit != stream_template->limit) { 192386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_free(stream->limit); 193386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 194386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 195386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 196386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * deallocate rtcp cipher, if it is not the same as that in 197386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * template 198386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 199386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (!stream_template || stream->rtcp_cipher != stream_template->rtcp_cipher) { 200386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_dealloc(stream->rtcp_cipher); 201386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 202386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 203386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 204386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 205386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 206386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * deallocate rtcp auth function, if it is not the same as that in 207386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * template 208386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 209386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (!stream_template || stream->rtcp_auth != stream_template->rtcp_auth) { 210386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = auth_dealloc(stream->rtcp_auth); 211386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 212386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 213386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 214386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 215386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* DAM - need to deallocate EKT here */ 216386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 217386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* deallocate srtp stream context */ 218386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_free(stream); 219386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 220386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 221386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 222386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 223386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 224386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 225386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_stream_clone(stream_template, new) allocates a new stream and 226386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * initializes it using the cipher and auth of the stream_template 227386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 228386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the only unique data in a cloned stream is the replay database and 229386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the SSRC 230386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 231386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 232386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 233386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_stream_clone(const srtp_stream_ctx_t *stream_template, 234386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t ssrc, 235386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t **str_ptr) { 236386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 237386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *str; 238386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 239386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "cloning stream (SSRC: 0x%08x)", ssrc); 240386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 241386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* allocate srtp stream and set str_ptr */ 242386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t)); 243386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (str == NULL) 244386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_alloc_fail; 245386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *str_ptr = str; 246386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 247386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set cipher and auth pointers to those of the template */ 248386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->rtp_cipher = stream_template->rtp_cipher; 249386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->rtp_auth = stream_template->rtp_auth; 250386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->rtcp_cipher = stream_template->rtcp_cipher; 251386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->rtcp_auth = stream_template->rtcp_auth; 252386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 253386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set key limit to point to that of the template */ 254386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = key_limit_clone(stream_template->limit, &str->limit); 255386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 256386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 257386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 258386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize replay databases */ 259386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = rdbx_init(&str->rtp_rdbx, 260386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari rdbx_get_window_size(&stream_template->rtp_rdbx)); 261386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 262386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 263386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari rdb_init(&str->rtcp_rdb); 264386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->allow_repeat_tx = stream_template->allow_repeat_tx; 265386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 266386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set ssrc to that provided */ 267386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->ssrc = ssrc; 268386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 269386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set direction and security services */ 270386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->direction = stream_template->direction; 271386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->rtp_services = stream_template->rtp_services; 272386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->rtcp_services = stream_template->rtcp_services; 273386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 274386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set pointer to EKT data associated with stream */ 275386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->ekt = stream_template->ekt; 276386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 277386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* defensive coding */ 278386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari str->next = NULL; 279386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 280386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 281386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 282386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 283386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 284386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 285386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * key derivation functions, internal to libSRTP 286386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 287386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_kdf_t is a key derivation context 288386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 289386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_kdf_init(&kdf, k) initializes kdf with the key k 290386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 291386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_kdf_generate(&kdf, l, kl, keylen) derives the key 292386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * corresponding to label l and puts it into kl; the length 293386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * of the key in octets is provided as keylen. this function 294386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * should be called once for each subkey that is derived. 295386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 296386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_kdf_clear(&kdf) zeroizes the kdf state 297386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 298386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 299386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaritypedef enum { 300386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari label_rtp_encryption = 0x00, 301386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari label_rtp_msg_auth = 0x01, 302386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari label_rtp_salt = 0x02, 303386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari label_rtcp_encryption = 0x03, 304386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari label_rtcp_msg_auth = 0x04, 305386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari label_rtcp_salt = 0x05 306386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} srtp_prf_label; 307386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 308386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 309386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 310386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_kdf_t represents a key derivation function. The SRTP 311386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * default KDF is the only one implemented at present. 312386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 313386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 314386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaritypedef struct { 315386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari aes_icm_ctx_t c; /* cipher used for key derivation */ 316386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} srtp_kdf_t; 317386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 318386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 319386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_kdf_init(srtp_kdf_t *kdf, const uint8_t key[30]) { 320386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 321386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari aes_icm_context_init(&kdf->c, key); 322386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 323386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 324386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 325386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 326386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 327386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label, 328386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint8_t *key, int length) { 329386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 330386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari v128_t nonce; 331386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 332386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set eigth octet of nonce to <label>, set the rest of it to zero */ 333386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari v128_set_to_zero(&nonce); 334386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari nonce.v8[7] = label; 335386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 336386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari aes_icm_set_iv(&kdf->c, &nonce); 337386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 338386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* generate keystream output */ 339386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari aes_icm_output(&kdf->c, key, length); 340386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 341386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 342386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 343386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 344386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 345386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_kdf_clear(srtp_kdf_t *kdf) { 346386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 347386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* zeroize aes context */ 348386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_set_to_zero((uint8_t *)kdf, sizeof(srtp_kdf_t)); 349386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 350386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 351386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 352386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 353386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 354386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * end of key derivation functions 355386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 356386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 357386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define MAX_SRTP_KEY_LEN 256 358386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 359386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 360386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 361386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) { 362386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t stat; 363386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_kdf_t kdf; 364386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint8_t tmp_key[MAX_SRTP_KEY_LEN]; 365386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 366386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize KDF state */ 367386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_kdf_init(&kdf, (const uint8_t *)key); 368386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 369386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* generate encryption key */ 370386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_kdf_generate(&kdf, label_rtp_encryption, 371386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari tmp_key, cipher_get_key_length(srtp->rtp_cipher)); 372386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 373386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if the cipher in the srtp context is aes_icm, then we need 374386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * to generate the salt value 375386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 376386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (srtp->rtp_cipher->type == &aes_icm) { 377386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* FIX!!! this is really the cipher key length; rest is salt */ 378386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int base_key_len = 16; 379386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int salt_len = cipher_get_key_length(srtp->rtp_cipher) - base_key_len; 380386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 381386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "found aes_icm, generating salt", NULL); 382386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 383386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* generate encryption salt, put after encryption key */ 384386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_kdf_generate(&kdf, label_rtp_salt, 385386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari tmp_key + base_key_len, salt_len); 386386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 387386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "cipher key: %s", 388386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(tmp_key, 389386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari cipher_get_key_length(srtp->rtp_cipher))); 390386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 391386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize cipher */ 392386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stat = cipher_init(srtp->rtp_cipher, tmp_key, direction_any); 393386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stat) { 394386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* zeroize temp buffer */ 395386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); 396386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_init_fail; 397386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 398386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 399386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* generate authentication key */ 400386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_kdf_generate(&kdf, label_rtp_msg_auth, 401386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari tmp_key, auth_get_key_length(srtp->rtp_auth)); 402386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "auth key: %s", 403386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(tmp_key, 404386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_get_key_length(srtp->rtp_auth))); 405386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 406386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize auth function */ 407386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stat = auth_init(srtp->rtp_auth, tmp_key); 408386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stat) { 409386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* zeroize temp buffer */ 410386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); 411386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_init_fail; 412386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 413386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 414386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 415386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * ...now initialize SRTCP keys 416386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 417386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 418386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* generate encryption key */ 419386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_kdf_generate(&kdf, label_rtcp_encryption, 420386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari tmp_key, cipher_get_key_length(srtp->rtcp_cipher)); 421386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 422386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if the cipher in the srtp context is aes_icm, then we need 423386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * to generate the salt value 424386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 425386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (srtp->rtcp_cipher->type == &aes_icm) { 426386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* FIX!!! this is really the cipher key length; rest is salt */ 427386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int base_key_len = 16; 428386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int salt_len = cipher_get_key_length(srtp->rtcp_cipher) - base_key_len; 429386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 430386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "found aes_icm, generating rtcp salt", NULL); 431386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 432386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* generate encryption salt, put after encryption key */ 433386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_kdf_generate(&kdf, label_rtcp_salt, 434386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari tmp_key + base_key_len, salt_len); 435386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 436386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "rtcp cipher key: %s", 437386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(tmp_key, 438386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari cipher_get_key_length(srtp->rtcp_cipher))); 439386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 440386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize cipher */ 441386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stat = cipher_init(srtp->rtcp_cipher, tmp_key, direction_any); 442386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stat) { 443386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* zeroize temp buffer */ 444386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); 445386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_init_fail; 446386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 447386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 448386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* generate authentication key */ 449386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_kdf_generate(&kdf, label_rtcp_msg_auth, 450386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari tmp_key, auth_get_key_length(srtp->rtcp_auth)); 451386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "rtcp auth key: %s", 452386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(tmp_key, 453386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_get_key_length(srtp->rtcp_auth))); 454386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 455386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize auth function */ 456386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stat = auth_init(srtp->rtcp_auth, tmp_key); 457386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stat) { 458386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* zeroize temp buffer */ 459386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); 460386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_init_fail; 461386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 462386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 463386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* clear memory then return */ 464386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_kdf_clear(&kdf); 465386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN); 466386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 467386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 468386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 469386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 470386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 471386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_stream_init(srtp_stream_ctx_t *srtp, 472386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari const srtp_policy_t *p) { 473386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t err; 474386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 475386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)", 476386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->ssrc.value); 477386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 478386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize replay database */ 479386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err = rdbx_init(&srtp->rtp_rdbx, p->window_size); 480386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (err) return err; 481386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 482386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize key limit to maximum value */ 483386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH 484386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari{ 485386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint64_t temp; 486386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari temp = make64(UINT_MAX,UINT_MAX); 487386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari key_limit_set(srtp->limit, temp); 488386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 489386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else 490386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari key_limit_set(srtp->limit, 0xffffffffffffLL); 491386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 492386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 493386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set the SSRC value */ 494386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp->ssrc = htonl(p->ssrc.value); 495386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 496386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set the security service flags */ 497386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp->rtp_services = p->rtp.sec_serv; 498386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp->rtcp_services = p->rtcp.sec_serv; 499386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 500386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 501386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * set direction to unknown - this flag gets checked in srtp_protect(), 502386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_unprotect(), srtp_protect_rtcp(), and srtp_unprotect_rtcp(), and 503386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * gets set appropriately if it is set to unknown. 504386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 505386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp->direction = dir_unknown; 506386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 507386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize SRTCP replay database */ 508386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari rdb_init(&srtp->rtcp_rdb); 509386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 510386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize allow_repeat_tx */ 511386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp->allow_repeat_tx = p->allow_repeat_tx; 512386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 513386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* DAM - no RTCP key limit at present */ 514386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 515386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize keys */ 516386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err = srtp_stream_init_keys(srtp, p->key); 517386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (err) { 518386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari rdbx_uninit(&srtp->rtp_rdbx); 519386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err; 520386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 521386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 522386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 523386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if EKT is in use, then initialize the EKT data associated with 524386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the stream 525386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 526386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err = ekt_stream_init_from_policy(srtp->ekt, p->ekt); 527386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (err) { 528386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari rdbx_uninit(&srtp->rtp_rdbx); 529386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err; 530386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 531386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 532386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 533386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 534386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 535386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 536386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_stream_uninit(srtp_stream_ctx_t *srtp) { 537386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return rdbx_uninit(&srtp->rtp_rdbx); 538386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 539386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 540386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 541386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 542386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_event_reporter is an event handler function that merely 543386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * reports the events that are reported by the callbacks 544386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 545386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 546386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari void 547386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_event_reporter(srtp_event_data_t *data) { 548386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 549386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_report(err_level_warning, "srtp: in stream 0x%x: ", 550386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari data->stream->ssrc); 551386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 552386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari switch(data->event) { 553386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case event_ssrc_collision: 554386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_report(err_level_warning, "\tSSRC collision\n"); 555386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 556386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case event_key_soft_limit: 557386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_report(err_level_warning, "\tkey usage soft limit reached\n"); 558386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 559386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case event_key_hard_limit: 560386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_report(err_level_warning, "\tkey usage hard limit reached\n"); 561386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 562386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case event_packet_index_limit: 563386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_report(err_level_warning, "\tpacket index limit reached\n"); 564386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 565386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari default: 566386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_report(err_level_warning, "\tunknown event reported to handler\n"); 567386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 568386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 569386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 570386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 571386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_event_handler is a global variable holding a pointer to the 572386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * event handler function; this function is called for any unexpected 573386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * event that needs to be handled out of the SRTP data path. see 574386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_event_t in srtp.h for more info 575386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 576386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * it is okay to set srtp_event_handler to NULL, but we set 577386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * it to the srtp_event_reporter. 578386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 579386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 580386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter; 581386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 582386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t 583386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_install_event_handler(srtp_event_handler_func_t func) { 584386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 585386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 586386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * note that we accept NULL arguments intentionally - calling this 587386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * function with a NULL arguments removes an event handler that's 588386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * been previously installed 589386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 590386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 591386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set global event handling function */ 592386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_event_handler = func; 593386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 594386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 595386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 596386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t 597386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) { 598386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr; 599386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t *enc_start; /* pointer to start of encrypted portion */ 600386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t *auth_start; /* pointer to start of auth. portion */ 601386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned enc_octet_len = 0; /* number of octets in encrypted portion */ 602386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */ 603386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int delta; /* delta of local pkt idx and that in hdr */ 604386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ 605386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 606386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int tag_len; 607386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *stream; 608386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int prefix_len; 609386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 610386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "function srtp_protect", NULL); 611386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 612386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* we assume the hdr is 32-bit aligned to start */ 613386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 614386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* check the packet length - it must at least contain a full header */ 615386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (*pkt_octet_len < octets_in_rtp_header) 616386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_bad_param; 617386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 618386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 619386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * look up ssrc in srtp_stream list, and process the packet with 620386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the appropriate stream. if we haven't seen this stream before, 621386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * there's a template key for this srtp_session, and the cipher 622386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * supports key-sharing, then we assume that a new stream using 623386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * that key has just started up 624386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 625386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = srtp_get_stream(ctx, hdr->ssrc); 626386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream == NULL) { 627386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (ctx->stream_template != NULL) { 628386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *new_stream; 629386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 630386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* allocate and initialize a new stream */ 631386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = srtp_stream_clone(ctx->stream_template, 632386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari hdr->ssrc, &new_stream); 633386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 634386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 635386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 636386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* add new stream to the head of the stream_list */ 637386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari new_stream->next = ctx->stream_list; 638386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari ctx->stream_list = new_stream; 639386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 640386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set direction to outbound */ 641386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari new_stream->direction = dir_srtp_sender; 642386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 643386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set stream (the pointer used in this function) */ 644386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = new_stream; 645386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 646386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* no template stream, so we return an error */ 647386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_no_ctx; 648386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 649386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 650386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 651386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 652386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * verify that stream is for sending traffic - this check will 653386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * detect SSRC collisions, since a stream that appears in both 654386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_protect() and srtp_unprotect() will fail this test in one of 655386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * those functions. 656386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 657386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->direction != dir_srtp_sender) { 658386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->direction == dir_unknown) { 659386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream->direction = dir_srtp_sender; 660386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 661386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_handle_event(ctx, stream, event_ssrc_collision); 662386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 663386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 664386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 665386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 666386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * update the key usage limit, and check it to make sure that we 667386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * didn't just hit either the soft limit or the hard limit, and call 668386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the event handler if we hit either. 669386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 670386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari switch(key_limit_update(stream->limit)) { 671386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case key_event_normal: 672386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 673386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case key_event_soft_limit: 674386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_handle_event(ctx, stream, event_key_soft_limit); 675386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 676386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case key_event_hard_limit: 677386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_handle_event(ctx, stream, event_key_hard_limit); 678386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_key_expired; 679386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari default: 680386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 681386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 682386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 683386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* get tag length from stream */ 684386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari tag_len = auth_get_tag_length(stream->rtp_auth); 685386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 686386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 687386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * find starting point for encryption and length of data to be 688386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * encrypted - the encrypted portion starts after the rtp header 689386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * extension, if present; otherwise, it starts after the last csrc, 690386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if any are present 691386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 692386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're not providing confidentiality, set enc_start to NULL 693386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 694386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->rtp_services & sec_serv_conf) { 695386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; 696386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (hdr->x == 1) { 697386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start; 698386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_start += (ntohs(xtn_hdr->length) + 1); 699386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 700386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_octet_len = (unsigned int)(*pkt_octet_len 701386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari - ((enc_start - (uint32_t *)hdr) << 2)); 702386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 703386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_start = NULL; 704386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 705386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 706386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 707386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're providing authentication, set the auth_start and auth_tag 708386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * pointers to the proper locations; otherwise, set auth_start to NULL 709386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * to indicate that no authentication is needed 710386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 711386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->rtp_services & sec_serv_auth) { 712386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_start = (uint32_t *)hdr; 713386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag = (uint8_t *)hdr + *pkt_octet_len; 714386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 715386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_start = NULL; 716386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag = NULL; 717386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 718386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 719386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 720386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * estimate the packet index using the start of the replay window 721386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * and the sequence number from the header 722386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 723386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq)); 724386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = rdbx_check(&stream->rtp_rdbx, delta); 725386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) { 726386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status != err_status_replay_fail || !stream->allow_repeat_tx) 727386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; /* we've been asked to reuse an index */ 728386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 729386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari else 730386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari rdbx_add_index(&stream->rtp_rdbx, delta); 731386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 732386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH 733386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print2(mod_srtp, "estimated packet index: %08x%08x", 734386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari high32(est),low32(est)); 735386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else 736386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "estimated packet index: %016llx", est); 737386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 738386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 739386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 740386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're using rindael counter mode, set nonce and seq 741386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 742386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->rtp_cipher->type == &aes_icm) { 743386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari v128_t iv; 744386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 745386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[0] = 0; 746386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[1] = hdr->ssrc; 747386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH 748386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16), 749386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari low32(est) << 16)); 750386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else 751386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v64[1] = be64_to_cpu(est << 16); 752386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 753386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_set_iv(stream->rtp_cipher, &iv); 754386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 755386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 756386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari v128_t iv; 757386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 758386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* otherwise, set the index to est */ 759386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH 760386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[0] = 0; 761386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[1] = 0; 762386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else 763386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v64[0] = 0; 764386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 765386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v64[1] = be64_to_cpu(est); 766386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_set_iv(stream->rtp_cipher, &iv); 767386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 768386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 769386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 770386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 771386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* shift est, put into network byte order */ 772386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH 773386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari est = be64_to_cpu(make64((high32(est) << 16) | 774386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari (low32(est) >> 16), 775386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari low32(est) << 16)); 776386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else 777386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari est = be64_to_cpu(est << 16); 778386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 779386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 780386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 781386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're authenticating using a universal hash, put the keystream 782386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * prefix into the authentication tag 783386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 784386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (auth_start) { 785386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 786386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari prefix_len = auth_get_prefix_length(stream->rtp_auth); 787386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (prefix_len) { 788386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_output(stream->rtp_cipher, auth_tag, prefix_len); 789386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 790386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 791386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "keystream prefix: %s", 792386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(auth_tag, prefix_len)); 793386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 794386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 795386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 796386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* if we're encrypting, exor keystream into the message */ 797386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (enc_start) { 798386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_encrypt(stream->rtp_cipher, 799386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari (uint8_t *)enc_start, &enc_octet_len); 800386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 801386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 802386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 803386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 804386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 805386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're authenticating, run authentication function and put result 806386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * into the auth_tag 807386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 808386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (auth_start) { 809386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 810386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize auth func context */ 811386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = auth_start(stream->rtp_auth); 812386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 813386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 814386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* run auth func over packet */ 815386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = auth_update(stream->rtp_auth, 816386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari (uint8_t *)auth_start, *pkt_octet_len); 817386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 818386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 819386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* run auth func over ROC, put result into auth_tag */ 820386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "estimated packet index: %016llx", est); 821386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag); 822386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "srtp auth tag: %s", 823386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(auth_tag, tag_len)); 824386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 825386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_auth_fail; 826386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 827386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 828386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 829386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (auth_tag) { 830386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 831386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* increase the packet length by the length of the auth tag */ 832386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *pkt_octet_len += tag_len; 833386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 834386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 835386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 836386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 837386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 838386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 839386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 840386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) { 841386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr; 842386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t *enc_start; /* pointer to start of encrypted portion */ 843386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t *auth_start; /* pointer to start of auth. portion */ 844386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned enc_octet_len = 0;/* number of octets in encrypted portion */ 845386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ 846386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr */ 847386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int delta; /* delta of local pkt idx and that in hdr */ 848386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari v128_t iv; 849386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 850386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *stream; 851386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint8_t tmp_tag[SRTP_MAX_TAG_LEN]; 852386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int tag_len, prefix_len; 853386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 854386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "function srtp_unprotect", NULL); 855386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 856386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* we assume the hdr is 32-bit aligned to start */ 857386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 858386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* check the packet length - it must at least contain a full header */ 859386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (*pkt_octet_len < octets_in_rtp_header) 860386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_bad_param; 861386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 862386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 863386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * look up ssrc in srtp_stream list, and process the packet with 864386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the appropriate stream. if we haven't seen this stream before, 865386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * there's only one key for this srtp_session, and the cipher 866386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * supports key-sharing, then we assume that a new stream using 867386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * that key has just started up 868386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 869386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = srtp_get_stream(ctx, hdr->ssrc); 870386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream == NULL) { 871386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (ctx->stream_template != NULL) { 872386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = ctx->stream_template; 873386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)", 874386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari hdr->ssrc); 875386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 876386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 877386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * set estimated packet index to sequence number from header, 878386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * and set delta equal to the same value 879386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 880386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH 881386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari est = (xtd_seq_num_t) make64(0,ntohs(hdr->seq)); 882386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari delta = low32(est); 883386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else 884386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari est = (xtd_seq_num_t) ntohs(hdr->seq); 885386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari delta = (int)est; 886386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 887386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 888386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 889386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 890386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * no stream corresponding to SSRC found, and we don't do 891386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * key-sharing, so return an error 892386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 893386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_no_ctx; 894386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 895386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 896386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 897386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* estimate packet index from seq. num. in header */ 898386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq)); 899386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 900386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* check replay database */ 901386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = rdbx_check(&stream->rtp_rdbx, delta); 902386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 903386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 904386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 905386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 906386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH 907386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),low32(est)); 908386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else 909386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "estimated u_packet index: %016llx", est); 910386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 911386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 912386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* get tag length from stream */ 913386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari tag_len = auth_get_tag_length(stream->rtp_auth); 914386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 915386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 916386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * set the cipher's IV properly, depending on whatever cipher we 917386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * happen to be using 918386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 919386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->rtp_cipher->type == &aes_icm) { 920386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 921386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* aes counter mode */ 922386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[0] = 0; 923386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[1] = hdr->ssrc; /* still in network order */ 924386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH 925386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16), 926386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari low32(est) << 16)); 927386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else 928386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v64[1] = be64_to_cpu(est << 16); 929386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 930386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_icm_set_iv((aes_icm_ctx_t*)stream->rtp_cipher->state, &iv); 931386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 932386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 933386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* no particular format - set the iv to the pakcet index */ 934386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH 935386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[0] = 0; 936386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[1] = 0; 937386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else 938386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v64[0] = 0; 939386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 940386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v64[1] = be64_to_cpu(est); 941386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_set_iv(stream->rtp_cipher, &iv); 942386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 943386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 944386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 945386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 946386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* shift est, put into network byte order */ 947386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH 948386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari est = be64_to_cpu(make64((high32(est) << 16) | 949386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari (low32(est) >> 16), 950386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari low32(est) << 16)); 951386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else 952386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari est = be64_to_cpu(est << 16); 953386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 954386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 955386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 956386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * find starting point for decryption and length of data to be 957386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * decrypted - the encrypted portion starts after the rtp header 958386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * extension, if present; otherwise, it starts after the last csrc, 959386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if any are present 960386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 961386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're not providing confidentiality, set enc_start to NULL 962386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 963386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->rtp_services & sec_serv_conf) { 964386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; 965386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (hdr->x == 1) { 966386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start; 967386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_start += (ntohs(xtn_hdr->length) + 1); 968386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 969386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len 970386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari - ((enc_start - (uint32_t *)hdr) << 2)); 971386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 972386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_start = NULL; 973386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 974386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 975386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 976386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're providing authentication, set the auth_start and auth_tag 977386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * pointers to the proper locations; otherwise, set auth_start to NULL 978386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * to indicate that no authentication is needed 979386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 980386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->rtp_services & sec_serv_auth) { 981386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_start = (uint32_t *)hdr; 982386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len; 983386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 984386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_start = NULL; 985386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag = NULL; 986386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 987386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 988386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 989386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we expect message authentication, run the authentication 990386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * function and compare the result with the value of the auth_tag 991386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 992386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (auth_start) { 993386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 994386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 995386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're using a universal hash, then we need to compute the 996386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * keystream prefix for encrypting the universal hash output 997386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 998386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if the keystream prefix length is zero, then we know that 999386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the authenticator isn't using a universal hash function 1000386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1001386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->rtp_auth->prefix_len != 0) { 1002386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1003386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari prefix_len = auth_get_prefix_length(stream->rtp_auth); 1004386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_output(stream->rtp_cipher, tmp_tag, prefix_len); 1005386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "keystream prefix: %s", 1006386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(tmp_tag, prefix_len)); 1007386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1008386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 1009386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1010386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1011386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize auth func context */ 1012386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = auth_start(stream->rtp_auth); 1013386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) return status; 1014386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1015386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* now compute auth function over packet */ 1016386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = auth_update(stream->rtp_auth, (uint8_t *)auth_start, 1017386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *pkt_octet_len - tag_len); 1018386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1019386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* run auth func over ROC, then write tmp tag */ 1020386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag); 1021386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1022386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "computed auth tag: %s", 1023386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(tmp_tag, tag_len)); 1024386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "packet auth tag: %s", 1025386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(auth_tag, tag_len)); 1026386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1027386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_auth_fail; 1028386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1029386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (octet_string_is_eq(tmp_tag, auth_tag, tag_len)) 1030386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_auth_fail; 1031386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1032386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1033386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1034386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * update the key usage limit, and check it to make sure that we 1035386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * didn't just hit either the soft limit or the hard limit, and call 1036386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the event handler if we hit either. 1037386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1038386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari switch(key_limit_update(stream->limit)) { 1039386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case key_event_normal: 1040386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1041386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case key_event_soft_limit: 1042386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_handle_event(ctx, stream, event_key_soft_limit); 1043386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1044386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case key_event_hard_limit: 1045386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_handle_event(ctx, stream, event_key_hard_limit); 1046386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_key_expired; 1047386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari default: 1048386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1049386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1050386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1051386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* if we're encrypting, add keystream into ciphertext */ 1052386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (enc_start) { 1053386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_encrypt(stream->rtp_cipher, 1054386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari (uint8_t *)enc_start, &enc_octet_len); 1055386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1056386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 1057386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1058386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1059386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1060386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * verify that stream is for received traffic - this check will 1061386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * detect SSRC collisions, since a stream that appears in both 1062386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_protect() and srtp_unprotect() will fail this test in one of 1063386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * those functions. 1064386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1065386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * we do this check *after* the authentication check, so that the 1066386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * latter check will catch any attempts to fool us into thinking 1067386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * that we've got a collision 1068386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1069386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->direction != dir_srtp_receiver) { 1070386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->direction == dir_unknown) { 1071386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream->direction = dir_srtp_receiver; 1072386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 1073386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_handle_event(ctx, stream, event_ssrc_collision); 1074386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1075386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1076386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1077386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1078386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if the stream is a 'provisional' one, in which the template context 1079386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * is used, then we need to allocate a new stream at this point, since 1080386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the authentication passed 1081386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1082386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream == ctx->stream_template) { 1083386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *new_stream; 1084386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1085386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1086386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * allocate and initialize a new stream 1087386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1088386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * note that we indicate failure if we can't allocate the new 1089386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * stream, and some implementations will want to not return 1090386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * failure here 1091386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1092386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); 1093386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1094386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1095386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1096386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* add new stream to the head of the stream_list */ 1097386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari new_stream->next = ctx->stream_list; 1098386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari ctx->stream_list = new_stream; 1099386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1100386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set stream (the pointer used in this function) */ 1101386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = new_stream; 1102386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1103386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1104386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1105386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the message authentication function passed, so add the packet 1106386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * index into the replay database 1107386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1108386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari rdbx_add_index(&stream->rtp_rdbx, delta); 1109386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1110386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* decrease the packet length by the length of the auth tag */ 1111386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *pkt_octet_len -= tag_len; 1112386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1113386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 1114386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1115386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1116386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 1117386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_init() { 1118386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 1119386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1120386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize crypto kernel */ 1121386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = crypto_kernel_init(); 1122386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1123386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1124386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1125386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* load srtp debug module into the kernel */ 1126386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = crypto_kernel_load_debug_module(&mod_srtp); 1127386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1128386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1129386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1130386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 1131386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1132386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1133386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 1134386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * The following code is under consideration for removal. See 1135386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * SRTP_MAX_TRAILER_LEN 1136386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1137386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if 0 1138386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1139386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 1140386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_get_trailer_length(&a) returns the number of octets that will 1141386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * be added to an RTP packet by the SRTP processing. This value 1142386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * is constant for a given srtp_stream_t (i.e. between initializations). 1143386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1144386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1145386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariint 1146386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_get_trailer_length(const srtp_stream_t s) { 1147386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return auth_get_tag_length(s->rtp_auth); 1148386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1149386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1150386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif 1151386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1152386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 1153386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_get_stream(ssrc) returns a pointer to the stream corresponding 1154386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * to ssrc, or NULL if no stream exists for that ssrc 1155386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1156386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * this is an internal function 1157386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1158386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1159386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_stream_ctx_t * 1160386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_get_stream(srtp_t srtp, uint32_t ssrc) { 1161386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *stream; 1162386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1163386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* walk down list until ssrc is found */ 1164386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = srtp->stream_list; 1165386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari while (stream != NULL) { 1166386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->ssrc == ssrc) 1167386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return stream; 1168386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = stream->next; 1169386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1170386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1171386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* we haven't found our ssrc, so return a null */ 1172386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return NULL; 1173386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1174386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1175386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 1176386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_dealloc(srtp_t session) { 1177386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *stream; 1178386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 1179386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1180386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1181386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * we take a conservative deallocation strategy - if we encounter an 1182386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * error deallocating a stream, then we stop trying to deallocate 1183386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * memory and just return an error 1184386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1185386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1186386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* walk list of streams, deallocating as we go */ 1187386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = session->stream_list; 1188386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari while (stream != NULL) { 1189386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_t next = stream->next; 1190386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = srtp_stream_uninit_and_dealloc(stream, session->stream_template); 1191386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) { 1192386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1193386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1194386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = next; 1195386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1196386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1197386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* deallocate stream template, if there is one */ 1198386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (session->stream_template != NULL) { 1199386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = srtp_stream_uninit_and_dealloc(session->stream_template, NULL); 1200386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1201386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1202386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* deallocate session context */ 1203386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_free(session); 1204386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1205386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 1206386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1207386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1208386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1209386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 1210386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_add_stream(srtp_t session, 1211386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari const srtp_policy_t *policy) { 1212386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 1213386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_t tmp; 1214386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1215386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* sanity check arguments */ 1216386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if ((session == NULL) || (policy == NULL) || (policy->key == NULL)) 1217386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_bad_param; 1218386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1219386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* allocate stream */ 1220386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = srtp_stream_alloc(&tmp, policy); 1221386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) { 1222386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1223386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1224386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1225386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize stream */ 1226386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = srtp_stream_init(tmp, policy); 1227386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) { 1228386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_free(tmp); 1229386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1230386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1231386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1232386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1233386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * set the head of the stream list or the template to point to the 1234386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * stream that we've just alloced and init'ed, depending on whether 1235386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * or not it has a wildcard SSRC value or not 1236386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1237386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if the template stream has already been set, then the policy is 1238386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * inconsistent, so we return a bad_param error code 1239386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1240386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari switch (policy->ssrc.type) { 1241386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case (ssrc_any_outbound): 1242386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (session->stream_template) { 1243386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_bad_param; 1244386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1245386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari session->stream_template = tmp; 1246386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari session->stream_template->direction = dir_srtp_sender; 1247386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1248386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case (ssrc_any_inbound): 1249386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (session->stream_template) { 1250386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_bad_param; 1251386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1252386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari session->stream_template = tmp; 1253386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari session->stream_template->direction = dir_srtp_receiver; 1254386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1255386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case (ssrc_specific): 1256386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari tmp->next = session->stream_list; 1257386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari session->stream_list = tmp; 1258386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1259386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case (ssrc_undefined): 1260386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari default: 1261386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_free(tmp); 1262386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_bad_param; 1263386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1264386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 1265386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1266386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1267386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1268386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 1269386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_create(srtp_t *session, /* handle for session */ 1270386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari const srtp_policy_t *policy) { /* SRTP policy (list) */ 1271386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t stat; 1272386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_ctx_t *ctx; 1273386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1274386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* sanity check arguments */ 1275386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (session == NULL) 1276386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_bad_param; 1277386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1278386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* allocate srtp context and set ctx_ptr */ 1279386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari ctx = (srtp_ctx_t *) crypto_alloc(sizeof(srtp_ctx_t)); 1280386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (ctx == NULL) 1281386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_alloc_fail; 1282386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *session = ctx; 1283386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1284386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1285386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * loop over elements in the policy list, allocating and 1286386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * initializing a stream for each element 1287386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1288386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari ctx->stream_template = NULL; 1289386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari ctx->stream_list = NULL; 1290386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari while (policy != NULL) { 1291386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1292386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stat = srtp_add_stream(ctx, policy); 1293386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stat) { 1294386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* clean up everything */ 1295386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_dealloc(*session); 1296386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return stat; 1297386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1298386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1299386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set policy to next item in list */ 1300386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari policy = policy->next; 1301386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1302386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1303386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 1304386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1305386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1306386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1307386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 1308386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_remove_stream(srtp_t session, uint32_t ssrc) { 1309386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *stream, *last_stream; 1310386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1311386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* sanity check arguments */ 1312386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (session == NULL) 1313386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_bad_param; 1314386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1315386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* find stream in list; complain if not found */ 1316386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari last_stream = stream = session->stream_list; 1317386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari while ((stream != NULL) && (ssrc != stream->ssrc)) { 1318386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari last_stream = stream; 1319386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = stream->next; 1320386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1321386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream == NULL) 1322386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_no_ctx; 1323386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1324386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* remove stream from the list */ 1325386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari last_stream->next = stream->next; 1326386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1327386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return srtp_stream_uninit_and_dealloc(stream, session->stream_template); 1328386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1329386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1330386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 1331386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_stream_uninit_and_dealloc(srtp_stream_ctx_t *stream, 1332386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *stream_template) { 1333386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 1334386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* deallocate rdbx data */ 1335386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = srtp_stream_uninit(stream); 1336386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1337386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1338386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1339386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* deallocate the stream */ 1340386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = srtp_stream_dealloc(stream, stream_template); 1341386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1342386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1343386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1344386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 1345386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1346386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1347386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1348386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 1349386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the default policy - provides a convenient way for callers to use 1350386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the default security policy 1351386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1352386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * this policy is that defined in the current SRTP internet draft. 1353386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1354386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1355386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1356386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 1357386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * NOTE: cipher_key_len is really key len (128 bits) plus salt len 1358386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * (112 bits) 1359386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1360386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* There are hard-coded 16's for base_key_len in the key generation code */ 1361386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1362386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarivoid 1363386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricrypto_policy_set_rtp_default(crypto_policy_t *p) { 1364386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1365386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->cipher_type = AES_128_ICM; 1366386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */ 1367386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_type = HMAC_SHA1; 1368386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_key_len = 20; /* default 160 bits per RFC 3711 */ 1369386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */ 1370386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->sec_serv = sec_serv_conf_and_auth; 1371386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1372386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1373386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1374386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarivoid 1375386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricrypto_policy_set_rtcp_default(crypto_policy_t *p) { 1376386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1377386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->cipher_type = AES_128_ICM; 1378386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->cipher_key_len = 30; /* default 128 bits per RFC 3711 */ 1379386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_type = HMAC_SHA1; 1380386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_key_len = 20; /* default 160 bits per RFC 3711 */ 1381386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */ 1382386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->sec_serv = sec_serv_conf_and_auth; 1383386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1384386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1385386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1386386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarivoid 1387386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricrypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p) { 1388386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1389386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1390386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * corresponds to draft-ietf-mmusic-sdescriptions-12.txt 1391386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1392386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * note that this crypto policy is intended for SRTP, but not SRTCP 1393386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1394386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1395386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->cipher_type = AES_128_ICM; 1396386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */ 1397386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_type = HMAC_SHA1; 1398386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_key_len = 20; /* 160 bit key */ 1399386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_tag_len = 4; /* 32 bit tag */ 1400386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->sec_serv = sec_serv_conf_and_auth; 1401386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1402386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1403386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1404386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1405386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarivoid 1406386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricrypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p) { 1407386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1408386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1409386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * corresponds to draft-ietf-mmusic-sdescriptions-12.txt 1410386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1411386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * note that this crypto policy is intended for SRTP, but not SRTCP 1412386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1413386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1414386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->cipher_type = AES_128_ICM; 1415386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->cipher_key_len = 30; /* 128 bit key, 112 bit salt */ 1416386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_type = NULL_AUTH; 1417386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_key_len = 0; 1418386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_tag_len = 0; 1419386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->sec_serv = sec_serv_conf; 1420386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1421386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1422386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1423386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1424386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarivoid 1425386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricrypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p) { 1426386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1427386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1428386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * corresponds to draft-ietf-mmusic-sdescriptions-12.txt 1429386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1430386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1431386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->cipher_type = NULL_CIPHER; 1432386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->cipher_key_len = 0; 1433386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_type = HMAC_SHA1; 1434386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_key_len = 20; 1435386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->auth_tag_len = 10; 1436386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari p->sec_serv = sec_serv_auth; 1437386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1438386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1439386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1440386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1441386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 1442386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * secure rtcp functions 1443386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1444386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1445386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 1446386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) { 1447386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr; 1448386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t *enc_start; /* pointer to start of encrypted portion */ 1449386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t *auth_start; /* pointer to start of auth. portion */ 1450386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t *trailer; /* pointer to start of trailer */ 1451386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned enc_octet_len = 0;/* number of octets in encrypted portion */ 1452386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ 1453386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 1454386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int tag_len; 1455386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *stream; 1456386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int prefix_len; 1457386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t seq_num; 1458386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1459386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* we assume the hdr is 32-bit aligned to start */ 1460386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1461386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * look up ssrc in srtp_stream list, and process the packet with 1462386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the appropriate stream. if we haven't seen this stream before, 1463386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * there's only one key for this srtp_session, and the cipher 1464386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * supports key-sharing, then we assume that a new stream using 1465386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * that key has just started up 1466386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1467386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = srtp_get_stream(ctx, hdr->ssrc); 1468386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream == NULL) { 1469386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (ctx->stream_template != NULL) { 1470386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *new_stream; 1471386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1472386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* allocate and initialize a new stream */ 1473386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = srtp_stream_clone(ctx->stream_template, 1474386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari hdr->ssrc, &new_stream); 1475386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1476386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1477386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1478386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* add new stream to the head of the stream_list */ 1479386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari new_stream->next = ctx->stream_list; 1480386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari ctx->stream_list = new_stream; 1481386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1482386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set stream (the pointer used in this function) */ 1483386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = new_stream; 1484386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 1485386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* no template stream, so we return an error */ 1486386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_no_ctx; 1487386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1488386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1489386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1490386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1491386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * verify that stream is for sending traffic - this check will 1492386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * detect SSRC collisions, since a stream that appears in both 1493386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_protect() and srtp_unprotect() will fail this test in one of 1494386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * those functions. 1495386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1496386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->direction != dir_srtp_sender) { 1497386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->direction == dir_unknown) { 1498386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream->direction = dir_srtp_sender; 1499386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 1500386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_handle_event(ctx, stream, event_ssrc_collision); 1501386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1502386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1503386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1504386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* get tag length from stream context */ 1505386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari tag_len = auth_get_tag_length(stream->rtcp_auth); 1506386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1507386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1508386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * set encryption start and encryption length - if we're not 1509386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * providing confidentiality, set enc_start to NULL 1510386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1511386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header; 1512386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_octet_len = *pkt_octet_len - octets_in_rtcp_header; 1513386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1514386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* all of the packet, except the header, gets encrypted */ 1515386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* NOTE: hdr->length is not usable - it refers to only the first 1516386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari RTCP report in the compound packet! */ 1517386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always 1518386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari multiples of 32-bits (RFC 3550 6.1) */ 1519386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari trailer = (uint32_t *) ((char *)enc_start + enc_octet_len); 1520386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1521386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->rtcp_services & sec_serv_conf) { 1522386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */ 1523386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 1524386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_start = NULL; 1525386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_octet_len = 0; 1526386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 0 is network-order independant */ 1527386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *trailer = 0x00000000; /* set encrypt bit */ 1528386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1529386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1530386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1531386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * set the auth_start and auth_tag pointers to the proper locations 1532386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * (note that srtpc *always* provides authentication, unlike srtp) 1533386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1534386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* Note: This would need to change for optional mikey data */ 1535386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_start = (uint32_t *)hdr; 1536386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t); 1537386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1538386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* perform EKT processing if needed */ 1539386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len, 1540386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari rdbx_get_packet_index(&stream->rtp_rdbx)); 1541386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1542386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1543386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * check sequence number for overruns, and copy it into the packet 1544386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if its value isn't too big 1545386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1546386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = rdb_increment(&stream->rtcp_rdb); 1547386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1548386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1549386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari seq_num = rdb_get_value(&stream->rtcp_rdb); 1550386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *trailer |= htonl(seq_num); 1551386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "srtcp index: %x", seq_num); 1552386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1553386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1554386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're using rindael counter mode, set nonce and seq 1555386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1556386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->rtcp_cipher->type == &aes_icm) { 1557386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari v128_t iv; 1558386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1559386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[0] = 0; 1560386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[1] = hdr->ssrc; /* still in network order! */ 1561386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[2] = htonl(seq_num >> 16); 1562386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[3] = htonl(seq_num << 16); 1563386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_icm_set_iv((aes_icm_ctx_t*)stream->rtcp_cipher->state, &iv); 1564386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1565386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 1566386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari v128_t iv; 1567386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1568386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* otherwise, just set the index to seq_num */ 1569386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[0] = 0; 1570386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[1] = 0; 1571386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[2] = 0; 1572386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[3] = htonl(seq_num); 1573386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_set_iv(stream->rtcp_cipher, &iv); 1574386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1575386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1576386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 1577386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1578386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1579386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're authenticating using a universal hash, put the keystream 1580386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * prefix into the authentication tag 1581386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1582386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1583386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* if auth_start is non-null, then put keystream into tag */ 1584386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (auth_start) { 1585386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1586386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* put keystream prefix into auth_tag */ 1587386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari prefix_len = auth_get_prefix_length(stream->rtcp_auth); 1588386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len); 1589386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1590386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "keystream prefix: %s", 1591386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(auth_tag, prefix_len)); 1592386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1593386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1594386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 1595386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1596386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1597386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* if we're encrypting, exor keystream into the message */ 1598386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (enc_start) { 1599386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_encrypt(stream->rtcp_cipher, 1600386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari (uint8_t *)enc_start, &enc_octet_len); 1601386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1602386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 1603386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1604386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1605386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize auth func context */ 1606386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_start(stream->rtcp_auth); 1607386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1608386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1609386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * run auth func over packet (including trailer), and write the 1610386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * result at auth_tag 1611386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1612386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = auth_compute(stream->rtcp_auth, 1613386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari (uint8_t *)auth_start, 1614386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari (*pkt_octet_len) + sizeof(srtcp_trailer_t), 1615386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag); 1616386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "srtcp auth tag: %s", 1617386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(auth_tag, tag_len)); 1618386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1619386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_auth_fail; 1620386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1621386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* increase the packet length by the length of the auth tag and seq_num*/ 1622386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t)); 1623386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1624386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 1625386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1626386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1627386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1628386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 1629386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) { 1630386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr; 1631386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t *enc_start; /* pointer to start of encrypted portion */ 1632386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t *auth_start; /* pointer to start of auth. portion */ 1633386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t *trailer; /* pointer to start of trailer */ 1634386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned enc_octet_len = 0;/* number of octets in encrypted portion */ 1635386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint8_t *auth_tag = NULL; /* location of auth_tag within packet */ 1636386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint8_t tmp_tag[SRTP_MAX_TAG_LEN]; 1637386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint8_t tag_copy[SRTP_MAX_TAG_LEN]; 1638386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari err_status_t status; 1639386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari unsigned auth_len; 1640386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int tag_len; 1641386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *stream; 1642386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int prefix_len; 1643386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint32_t seq_num; 1644386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int e_bit_in_packet; /* whether the E-bit was found in the packet */ 1645386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari int sec_serv_confidentiality; /* whether confidentiality was requested */ 1646386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1647386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* we assume the hdr is 32-bit aligned to start */ 1648386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1649386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * look up ssrc in srtp_stream list, and process the packet with 1650386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the appropriate stream. if we haven't seen this stream before, 1651386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * there's only one key for this srtp_session, and the cipher 1652386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * supports key-sharing, then we assume that a new stream using 1653386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * that key has just started up 1654386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1655386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = srtp_get_stream(ctx, hdr->ssrc); 1656386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream == NULL) { 1657386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (ctx->stream_template != NULL) { 1658386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = ctx->stream_template; 1659386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1660386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1661386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * check to see if stream_template has an EKT data structure, in 1662386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * which case we initialize the template using the EKT policy 1663386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * referenced by that data (which consists of decrypting the 1664386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * master key from the EKT field) 1665386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1666386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * this function initializes a *provisional* stream, and this 1667386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * stream should not be accepted until and unless the packet 1668386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * passes its authentication check 1669386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1670386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->ekt != NULL) { 1671386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = srtp_stream_init_from_ekt(stream, srtcp_hdr, *pkt_octet_len); 1672386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1673386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1674386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1675386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1676386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)", 1677386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari hdr->ssrc); 1678386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 1679386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* no template stream, so we return an error */ 1680386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_no_ctx; 1681386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1682386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1683386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1684386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari sec_serv_confidentiality = stream->rtcp_services == sec_serv_conf || 1685386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream->rtcp_services == sec_serv_conf_and_auth; 1686386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1687386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* get tag length from stream context */ 1688386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari tag_len = auth_get_tag_length(stream->rtcp_auth); 1689386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1690386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1691386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * set encryption start, encryption length, and trailer 1692386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1693386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_octet_len = *pkt_octet_len - 1694386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t)); 1695386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* index & E (encryption) bit follow normal data. hdr->len 1696386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari is the number of words (32-bit) in the normal packet minus 1 */ 1697386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* This should point trailer to the word past the end of the 1698386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari normal data. */ 1699386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* This would need to be modified for optional mikey data */ 1700386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1701386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always 1702386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * multiples of 32-bits (RFC 3550 6.1) 1703386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1704386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari trailer = (uint32_t *) ((char *) hdr + 1705386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t))); 1706386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari e_bit_in_packet = (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) == SRTCP_E_BYTE_BIT; 1707386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (e_bit_in_packet != sec_serv_confidentiality) { 1708386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cant_check; 1709386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1710386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (sec_serv_confidentiality) { 1711386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header; 1712386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 1713386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_octet_len = 0; 1714386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari enc_start = NULL; /* this indicates that there's no encryption */ 1715386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1716386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1717386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1718386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * set the auth_start and auth_tag pointers to the proper locations 1719386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * (note that srtcp *always* uses authentication, unlike srtp) 1720386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1721386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_start = (uint32_t *)hdr; 1722386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_len = *pkt_octet_len - tag_len; 1723386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag = (uint8_t *)hdr + auth_len; 1724386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1725386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1726386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if EKT is in use, then we make a copy of the tag from the packet, 1727386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * and then zeroize the location of the base tag 1728386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1729386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * we first re-position the auth_tag pointer so that it points to 1730386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the base tag 1731386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1732386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->ekt) { 1733386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag -= ekt_octets_after_base_tag(stream->ekt); 1734386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari memcpy(tag_copy, auth_tag, tag_len); 1735386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_set_to_zero(auth_tag, tag_len); 1736386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_tag = tag_copy; 1737386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_len += tag_len; 1738386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1739386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1740386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1741386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * check the sequence number for replays 1742386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1743386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* this is easier than dealing with bitfield access */ 1744386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK; 1745386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "srtcp index: %x", seq_num); 1746386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = rdb_check(&stream->rtcp_rdb, seq_num); 1747386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1748386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1749386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1750386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1751386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're using aes counter mode, set nonce and seq 1752386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1753386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->rtcp_cipher->type == &aes_icm) { 1754386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari v128_t iv; 1755386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1756386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[0] = 0; 1757386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[1] = hdr->ssrc; /* still in network order! */ 1758386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[2] = htonl(seq_num >> 16); 1759386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[3] = htonl(seq_num << 16); 1760386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = aes_icm_set_iv((aes_icm_ctx_t*)stream->rtcp_cipher->state, &iv); 1761386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1762386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 1763386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari v128_t iv; 1764386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1765386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* otherwise, just set the index to seq_num */ 1766386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[0] = 0; 1767386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[1] = 0; 1768386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[2] = 0; 1769386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari iv.v32[3] = htonl(seq_num); 1770386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_set_iv(stream->rtcp_cipher, &iv); 1771386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1772386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1773386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1774386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 1775386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1776386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* initialize auth func context */ 1777386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_start(stream->rtcp_auth); 1778386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1779386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* run auth func over packet, put result into tmp_tag */ 1780386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start, 1781386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari auth_len, tmp_tag); 1782386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "srtcp computed tag: %s", 1783386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(tmp_tag, tag_len)); 1784386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1785386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_auth_fail; 1786386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1787386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* compare the tag just computed with the one in the packet */ 1788386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "srtcp tag from packet: %s", 1789386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(auth_tag, tag_len)); 1790386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (octet_string_is_eq(tmp_tag, auth_tag, tag_len)) 1791386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_auth_fail; 1792386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1793386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1794386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if we're authenticating using a universal hash, put the keystream 1795386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * prefix into the authentication tag 1796386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1797386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari prefix_len = auth_get_prefix_length(stream->rtcp_auth); 1798386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (prefix_len) { 1799386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len); 1800386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_srtp, "keystream prefix: %s", 1801386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari octet_string_hex_string(auth_tag, prefix_len)); 1802386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1803386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 1804386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1805386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1806386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* if we're decrypting, exor keystream into the message */ 1807386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (enc_start) { 1808386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = cipher_encrypt(stream->rtcp_cipher, 1809386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari (uint8_t *)enc_start, &enc_octet_len); 1810386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1811386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_cipher_fail; 1812386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1813386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1814386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* decrease the packet length by the length of the auth tag and seq_num */ 1815386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t)); 1816386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1817386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1818386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if EKT is in effect, subtract the EKT data out of the packet 1819386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * length 1820386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1821386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *pkt_octet_len -= ekt_octets_after_base_tag(stream->ekt); 1822386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1823386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1824386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * verify that stream is for received traffic - this check will 1825386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * detect SSRC collisions, since a stream that appears in both 1826386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * srtp_protect() and srtp_unprotect() will fail this test in one of 1827386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * those functions. 1828386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1829386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * we do this check *after* the authentication check, so that the 1830386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * latter check will catch any attempts to fool us into thinking 1831386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * that we've got a collision 1832386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1833386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->direction != dir_srtp_receiver) { 1834386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream->direction == dir_unknown) { 1835386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream->direction = dir_srtp_receiver; 1836386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } else { 1837386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_handle_event(ctx, stream, event_ssrc_collision); 1838386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1839386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1840386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1841386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1842386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * if the stream is a 'provisional' one, in which the template context 1843386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * is used, then we need to allocate a new stream at this point, since 1844386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the authentication passed 1845386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1846386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (stream == ctx->stream_template) { 1847386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_stream_ctx_t *new_stream; 1848386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1849386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* 1850386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * allocate and initialize a new stream 1851386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 1852386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * note that we indicate failure if we can't allocate the new 1853386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * stream, and some implementations will want to not return 1854386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * failure here 1855386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1856386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); 1857386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari if (status) 1858386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return status; 1859386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1860386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* add new stream to the head of the stream_list */ 1861386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari new_stream->next = ctx->stream_list; 1862386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari ctx->stream_list = new_stream; 1863386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1864386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set stream (the pointer used in this function) */ 1865386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari stream = new_stream; 1866386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1867386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1868386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* we've passed the authentication check, so add seq_num to the rdb */ 1869386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari rdb_add_index(&stream->rtcp_rdb, seq_num); 1870386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1871386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1872386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 1873386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1874386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1875386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1876386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1877386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/* 1878386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * dtls keying for srtp 1879386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */ 1880386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1881386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 1882386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricrypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy, 1883386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_profile_t profile) { 1884386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1885386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set SRTP policy from the SRTP profile in the key set */ 1886386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari switch(profile) { 1887386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes128_cm_sha1_80: 1888386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); 1889386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); 1890386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1891386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes128_cm_sha1_32: 1892386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_policy_set_aes_cm_128_hmac_sha1_32(policy); 1893386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); 1894386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1895386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_null_sha1_80: 1896386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_policy_set_null_cipher_hmac_sha1_80(policy); 1897386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_policy_set_null_cipher_hmac_sha1_80(policy); 1898386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1899386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* the following profiles are not (yet) supported */ 1900386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_null_sha1_32: 1901386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes256_cm_sha1_80: 1902386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes256_cm_sha1_32: 1903386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari default: 1904386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_bad_param; 1905386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1906386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1907386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 1908386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1909386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1910386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t 1911386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricrypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy, 1912386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari srtp_profile_t profile) { 1913386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1914386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* set SRTP policy from the SRTP profile in the key set */ 1915386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari switch(profile) { 1916386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes128_cm_sha1_80: 1917386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); 1918386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1919386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes128_cm_sha1_32: 1920386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_policy_set_aes_cm_128_hmac_sha1_80(policy); 1921386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1922386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_null_sha1_80: 1923386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari crypto_policy_set_null_cipher_hmac_sha1_80(policy); 1924386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1925386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* the following profiles are not (yet) supported */ 1926386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_null_sha1_32: 1927386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes256_cm_sha1_80: 1928386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes256_cm_sha1_32: 1929386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari default: 1930386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_bad_param; 1931386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1932386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1933386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return err_status_ok; 1934386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1935386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1936386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarivoid 1937386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariappend_salt_to_key(uint8_t *key, unsigned int bytes_in_key, 1938386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari uint8_t *salt, unsigned int bytes_in_salt) { 1939386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1940386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari memcpy(key + bytes_in_key, salt, bytes_in_salt); 1941386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1942386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1943386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1944386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariunsigned int 1945386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_profile_get_master_key_length(srtp_profile_t profile) { 1946386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1947386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari switch(profile) { 1948386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes128_cm_sha1_80: 1949386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return 16; 1950386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1951386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes128_cm_sha1_32: 1952386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return 16; 1953386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1954386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_null_sha1_80: 1955386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return 16; 1956386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1957386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* the following profiles are not (yet) supported */ 1958386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_null_sha1_32: 1959386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes256_cm_sha1_80: 1960386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes256_cm_sha1_32: 1961386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari default: 1962386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return 0; /* indicate error by returning a zero */ 1963386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1964386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1965386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1966386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariunsigned int 1967386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarisrtp_profile_get_master_salt_length(srtp_profile_t profile) { 1968386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari 1969386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari switch(profile) { 1970386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes128_cm_sha1_80: 1971386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return 14; 1972386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1973386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes128_cm_sha1_32: 1974386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return 14; 1975386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1976386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_null_sha1_80: 1977386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return 14; 1978386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari break; 1979386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari /* the following profiles are not (yet) supported */ 1980386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_null_sha1_32: 1981386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes256_cm_sha1_80: 1982386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari case srtp_profile_aes256_cm_sha1_32: 1983386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari default: 1984386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari return 0; /* indicate error by returning a zero */ 1985386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari } 1986386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari} 1987