LCOV - code coverage report
Current view: top level - netwerk/srtp/src/srtp - srtp.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 762 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 34 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * srtp.c
       3             :  *
       4             :  * the secure real-time transport protocol
       5             :  *
       6             :  * David A. McGrew
       7             :  * Cisco Systems, Inc.
       8             :  */
       9             : /*
      10             :  *      
      11             :  * Copyright (c) 2001-2006, Cisco Systems, Inc.
      12             :  * All rights reserved.
      13             :  * 
      14             :  * Redistribution and use in source and binary forms, with or without
      15             :  * modification, are permitted provided that the following conditions
      16             :  * are met:
      17             :  * 
      18             :  *   Redistributions of source code must retain the above copyright
      19             :  *   notice, this list of conditions and the following disclaimer.
      20             :  * 
      21             :  *   Redistributions in binary form must reproduce the above
      22             :  *   copyright notice, this list of conditions and the following
      23             :  *   disclaimer in the documentation and/or other materials provided
      24             :  *   with the distribution.
      25             :  * 
      26             :  *   Neither the name of the Cisco Systems, Inc. nor the names of its
      27             :  *   contributors may be used to endorse or promote products derived
      28             :  *   from this software without specific prior written permission.
      29             :  * 
      30             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      31             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      32             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
      33             :  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
      34             :  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
      35             :  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      36             :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      37             :  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      38             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      39             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      40             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      41             :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      42             :  *
      43             :  */
      44             : 
      45             : 
      46             : #include "srtp.h"
      47             : #include "ekt.h"             /* for SRTP Encrypted Key Transport */
      48             : #include "alloc.h"           /* for crypto_alloc()          */
      49             : 
      50             : #ifndef SRTP_KERNEL
      51             : # include <limits.h>
      52             : # ifdef HAVE_NETINET_IN_H
      53             : #  include <netinet/in.h>
      54             : # elif defined(HAVE_WINSOCK2_H)
      55             : #  include <winsock2.h>
      56             : # endif
      57             : #endif /* ! SRTP_KERNEL */
      58             : 
      59             : 
      60             : /* the debug module for srtp */
      61             : 
      62             : debug_module_t mod_srtp = {
      63             :   0,                  /* debugging is off by default */
      64             :   "srtp"              /* printable name for module   */
      65             : };
      66             : 
      67             : #define octets_in_rtp_header   12
      68             : #define uint32s_in_rtp_header  3
      69             : #define octets_in_rtcp_header  8
      70             : #define uint32s_in_rtcp_header 2
      71             : 
      72             : 
      73             : err_status_t
      74           0 : srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
      75             :                   const srtp_policy_t *p) {
      76             :   srtp_stream_ctx_t *str;
      77             :   err_status_t stat;
      78             : 
      79             :   /*
      80             :    * This function allocates the stream context, rtp and rtcp ciphers
      81             :    * and auth functions, and key limit structure.  If there is a
      82             :    * failure during allocation, we free all previously allocated
      83             :    * memory and return a failure code.  The code could probably 
      84             :    * be improved, but it works and should be clear.
      85             :    */
      86             : 
      87             :   /* allocate srtp stream and set str_ptr */
      88           0 :   str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));
      89           0 :   if (str == NULL)
      90           0 :     return err_status_alloc_fail;
      91           0 :   *str_ptr = str;  
      92             :   
      93             :   /* allocate cipher */
      94           0 :   stat = crypto_kernel_alloc_cipher(p->rtp.cipher_type, 
      95           0 :                                     &str->rtp_cipher, 
      96             :                                     p->rtp.cipher_key_len); 
      97           0 :   if (stat) {
      98           0 :     crypto_free(str);
      99           0 :     return stat;
     100             :   }
     101             : 
     102             :   /* allocate auth function */
     103           0 :   stat = crypto_kernel_alloc_auth(p->rtp.auth_type, 
     104           0 :                                   &str->rtp_auth,
     105             :                                   p->rtp.auth_key_len, 
     106             :                                   p->rtp.auth_tag_len); 
     107           0 :   if (stat) {
     108           0 :     cipher_dealloc(str->rtp_cipher);
     109           0 :     crypto_free(str);
     110           0 :     return stat;
     111             :   }
     112             :   
     113             :   /* allocate key limit structure */
     114           0 :   str->limit = (key_limit_ctx_t*) crypto_alloc(sizeof(key_limit_ctx_t));
     115           0 :   if (str->limit == NULL) {
     116           0 :     auth_dealloc(str->rtp_auth);
     117           0 :     cipher_dealloc(str->rtp_cipher);
     118           0 :     crypto_free(str); 
     119           0 :     return err_status_alloc_fail;
     120             :   }
     121             : 
     122             :   /*
     123             :    * ...and now the RTCP-specific initialization - first, allocate
     124             :    * the cipher 
     125             :    */
     126           0 :   stat = crypto_kernel_alloc_cipher(p->rtcp.cipher_type, 
     127           0 :                                     &str->rtcp_cipher, 
     128             :                                     p->rtcp.cipher_key_len); 
     129           0 :   if (stat) {
     130           0 :     auth_dealloc(str->rtp_auth);
     131           0 :     cipher_dealloc(str->rtp_cipher);
     132           0 :     crypto_free(str->limit);
     133           0 :     crypto_free(str);
     134           0 :     return stat;
     135             :   }
     136             : 
     137             :   /* allocate auth function */
     138           0 :   stat = crypto_kernel_alloc_auth(p->rtcp.auth_type, 
     139           0 :                                   &str->rtcp_auth,
     140             :                                   p->rtcp.auth_key_len, 
     141             :                                   p->rtcp.auth_tag_len); 
     142           0 :   if (stat) {
     143           0 :     cipher_dealloc(str->rtcp_cipher);
     144           0 :     auth_dealloc(str->rtp_auth);
     145           0 :     cipher_dealloc(str->rtp_cipher);
     146           0 :     crypto_free(str->limit);
     147           0 :     crypto_free(str);
     148           0 :    return stat;
     149             :   }  
     150             : 
     151             :   /* allocate ekt data associated with stream */
     152           0 :   stat = ekt_alloc(&str->ekt, p->ekt);
     153           0 :   if (stat) {
     154           0 :     auth_dealloc(str->rtcp_auth);
     155           0 :     cipher_dealloc(str->rtcp_cipher);
     156           0 :     auth_dealloc(str->rtp_auth);
     157           0 :     cipher_dealloc(str->rtp_cipher);
     158           0 :     crypto_free(str->limit);
     159           0 :     crypto_free(str);
     160           0 :    return stat;    
     161             :   }
     162             : 
     163           0 :   return err_status_ok;
     164             : }
     165             : 
     166             : err_status_t
     167           0 : srtp_stream_dealloc(srtp_t session, srtp_stream_ctx_t *stream) { 
     168             :   err_status_t status;
     169             :   
     170             :   /*
     171             :    * we use a conservative deallocation strategy - if any deallocation
     172             :    * fails, then we report that fact without trying to deallocate
     173             :    * anything else
     174             :    */
     175             : 
     176             :   /* deallocate cipher, if it is not the same as that in template */
     177           0 :   if (session->stream_template
     178           0 :       && stream->rtp_cipher == session->stream_template->rtp_cipher) {
     179             :     /* do nothing */
     180             :   } else {
     181           0 :     status = cipher_dealloc(stream->rtp_cipher); 
     182           0 :     if (status) 
     183           0 :       return status;
     184             :   }
     185             : 
     186             :   /* deallocate auth function, if it is not the same as that in template */
     187           0 :   if (session->stream_template
     188           0 :       && stream->rtp_auth == session->stream_template->rtp_auth) {
     189             :     /* do nothing */
     190             :   } else {
     191           0 :     status = auth_dealloc(stream->rtp_auth);
     192           0 :     if (status)
     193           0 :       return status;
     194             :   }
     195             : 
     196             :   /* deallocate key usage limit, if it is not the same as that in template */
     197           0 :   if (session->stream_template
     198           0 :       && stream->limit == session->stream_template->limit) {
     199             :     /* do nothing */
     200             :   } else {
     201           0 :     crypto_free(stream->limit);
     202             :   }   
     203             : 
     204             :   /* 
     205             :    * deallocate rtcp cipher, if it is not the same as that in
     206             :    * template 
     207             :    */
     208           0 :   if (session->stream_template
     209           0 :       && stream->rtcp_cipher == session->stream_template->rtcp_cipher) {
     210             :     /* do nothing */
     211             :   } else {
     212           0 :     status = cipher_dealloc(stream->rtcp_cipher); 
     213           0 :     if (status) 
     214           0 :       return status;
     215             :   }
     216             : 
     217             :   /*
     218             :    * deallocate rtcp auth function, if it is not the same as that in
     219             :    * template 
     220             :    */
     221           0 :   if (session->stream_template
     222           0 :       && stream->rtcp_auth == session->stream_template->rtcp_auth) {
     223             :     /* do nothing */
     224             :   } else {
     225           0 :     status = auth_dealloc(stream->rtcp_auth);
     226           0 :     if (status)
     227           0 :       return status;
     228             :   }
     229             : 
     230           0 :   status = rdbx_dealloc(&stream->rtp_rdbx);
     231           0 :   if (status)
     232           0 :     return status;
     233             : 
     234             :   /* DAM - need to deallocate EKT here */
     235             :   
     236             :   /* deallocate srtp stream context */
     237           0 :   crypto_free(stream);
     238             : 
     239           0 :   return err_status_ok;
     240             : }
     241             : 
     242             : 
     243             : /*
     244             :  * srtp_stream_clone(stream_template, new) allocates a new stream and
     245             :  * initializes it using the cipher and auth of the stream_template
     246             :  * 
     247             :  * the only unique data in a cloned stream is the replay database and
     248             :  * the SSRC
     249             :  */
     250             : 
     251             : err_status_t
     252           0 : srtp_stream_clone(const srtp_stream_ctx_t *stream_template, 
     253             :                   uint32_t ssrc, 
     254             :                   srtp_stream_ctx_t **str_ptr) {
     255             :   err_status_t status;
     256             :   srtp_stream_ctx_t *str;
     257             : 
     258             :   debug_print(mod_srtp, "cloning stream (SSRC: 0x%08x)", ssrc);
     259             : 
     260             :   /* allocate srtp stream and set str_ptr */
     261           0 :   str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));
     262           0 :   if (str == NULL)
     263           0 :     return err_status_alloc_fail;
     264           0 :   *str_ptr = str;  
     265             : 
     266             :   /* set cipher and auth pointers to those of the template */
     267           0 :   str->rtp_cipher  = stream_template->rtp_cipher;
     268           0 :   str->rtp_auth    = stream_template->rtp_auth;
     269           0 :   str->rtcp_cipher = stream_template->rtcp_cipher;
     270           0 :   str->rtcp_auth   = stream_template->rtcp_auth;
     271             : 
     272             :   /* set key limit to point to that of the template */
     273           0 :   status = key_limit_clone(stream_template->limit, &str->limit);
     274           0 :   if (status) 
     275           0 :     return status;
     276             : 
     277             :   /* initialize replay databases */
     278           0 :   status = rdbx_init(&str->rtp_rdbx,
     279             :                      rdbx_get_window_size(&stream_template->rtp_rdbx));
     280           0 :   if (status)
     281           0 :     return status;
     282           0 :   rdb_init(&str->rtcp_rdb);
     283           0 :   str->allow_repeat_tx = stream_template->allow_repeat_tx;
     284             :   
     285             :   /* set ssrc to that provided */
     286           0 :   str->ssrc = ssrc;
     287             : 
     288             :   /* set direction and security services */
     289           0 :   str->direction     = stream_template->direction;
     290           0 :   str->rtp_services  = stream_template->rtp_services;
     291           0 :   str->rtcp_services = stream_template->rtcp_services;
     292             : 
     293             :   /* set pointer to EKT data associated with stream */
     294           0 :   str->ekt = stream_template->ekt;
     295             : 
     296             :   /* defensive coding */
     297           0 :   str->next = NULL;
     298             : 
     299           0 :   return err_status_ok;
     300             : }
     301             : 
     302             : 
     303             : /*
     304             :  * key derivation functions, internal to libSRTP
     305             :  *
     306             :  * srtp_kdf_t is a key derivation context
     307             :  *
     308             :  * srtp_kdf_init(&kdf, cipher_id, k, keylen) initializes kdf to use cipher
     309             :  * described by cipher_id, with the master key k with length in octets keylen.
     310             :  * 
     311             :  * srtp_kdf_generate(&kdf, l, kl, keylen) derives the key
     312             :  * corresponding to label l and puts it into kl; the length
     313             :  * of the key in octets is provided as keylen.  this function
     314             :  * should be called once for each subkey that is derived.
     315             :  *
     316             :  * srtp_kdf_clear(&kdf) zeroizes and deallocates the kdf state
     317             :  */
     318             : 
     319             : typedef enum {
     320             :   label_rtp_encryption  = 0x00,
     321             :   label_rtp_msg_auth    = 0x01,
     322             :   label_rtp_salt        = 0x02,
     323             :   label_rtcp_encryption = 0x03,
     324             :   label_rtcp_msg_auth   = 0x04,
     325             :   label_rtcp_salt       = 0x05
     326             : } srtp_prf_label;
     327             : 
     328             : 
     329             : /*
     330             :  * srtp_kdf_t represents a key derivation function.  The SRTP
     331             :  * default KDF is the only one implemented at present.
     332             :  */
     333             : 
     334             : typedef struct { 
     335             :   cipher_t *cipher;    /* cipher used for key derivation  */  
     336             : } srtp_kdf_t;
     337             : 
     338             : err_status_t
     339           0 : srtp_kdf_init(srtp_kdf_t *kdf, cipher_type_id_t cipher_id, const uint8_t *key, int length) {
     340             : 
     341             :   err_status_t stat;
     342           0 :   stat = crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, length);
     343           0 :   if (stat)
     344           0 :     return stat;
     345             : 
     346           0 :   stat = cipher_init(kdf->cipher, key, direction_encrypt);
     347           0 :   if (stat) {
     348           0 :     cipher_dealloc(kdf->cipher);
     349           0 :     return stat;
     350             :   }
     351             : 
     352           0 :   return err_status_ok;
     353             : }
     354             : 
     355             : err_status_t
     356           0 : srtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label,
     357             :                   uint8_t *key, unsigned length) {
     358             : 
     359             :   v128_t nonce;
     360             :   err_status_t status;
     361             :   
     362             :   /* set eigth octet of nonce to <label>, set the rest of it to zero */
     363           0 :   v128_set_to_zero(&nonce);
     364           0 :   nonce.v8[7] = label;
     365             :  
     366           0 :   status = cipher_set_iv(kdf->cipher, &nonce);
     367           0 :   if (status)
     368           0 :     return status;
     369             :   
     370             :   /* generate keystream output */
     371           0 :   octet_string_set_to_zero(key, length);
     372           0 :   status = cipher_encrypt(kdf->cipher, key, &length);
     373           0 :   if (status)
     374           0 :     return status;
     375             : 
     376           0 :   return err_status_ok;
     377             : }
     378             : 
     379             : err_status_t
     380           0 : srtp_kdf_clear(srtp_kdf_t *kdf) {
     381             :   err_status_t status;
     382           0 :   status = cipher_dealloc(kdf->cipher);
     383           0 :   if (status)
     384           0 :     return status;
     385           0 :   kdf->cipher = NULL;
     386             : 
     387           0 :   return err_status_ok;  
     388             : }
     389             : 
     390             : /*
     391             :  *  end of key derivation functions 
     392             :  */
     393             : 
     394             : #define MAX_SRTP_KEY_LEN 256
     395             : 
     396             : 
     397             : /* Get the base key length corresponding to a given combined key+salt
     398             :  * length for the given cipher.
     399             :  * Assumption is that for AES-ICM a key length < 30 is Ismacryp using
     400             :  * AES-128 and short salts; everything else uses a salt length of 14.
     401             :  * TODO: key and salt lengths should be separate fields in the policy.  */
     402           0 : static inline int base_key_length(const cipher_type_t *cipher, int key_length)
     403             : {
     404           0 :   if (cipher->id != AES_ICM)
     405           0 :     return key_length;
     406           0 :   else if (key_length > 16 && key_length < 30)
     407           0 :     return 16;
     408           0 :   return key_length - 14;
     409             : }
     410             : 
     411             : err_status_t
     412           0 : srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) {
     413             :   err_status_t stat;
     414             :   srtp_kdf_t kdf;
     415             :   uint8_t tmp_key[MAX_SRTP_KEY_LEN];
     416           0 :   int kdf_keylen = 30, rtp_keylen, rtcp_keylen;
     417             :   int rtp_base_key_len, rtp_salt_len;
     418             :   int rtcp_base_key_len, rtcp_salt_len;
     419             : 
     420             :   /* If RTP or RTCP have a key length > AES-128, assume matching kdf. */
     421             :   /* TODO: kdf algorithm, master key length, and master salt length should
     422             :    * be part of srtp_policy_t. */
     423           0 :   rtp_keylen = cipher_get_key_length(srtp->rtp_cipher);
     424           0 :   if (rtp_keylen > kdf_keylen)
     425           0 :     kdf_keylen = rtp_keylen;
     426             : 
     427           0 :   rtcp_keylen = cipher_get_key_length(srtp->rtcp_cipher);
     428           0 :   if (rtcp_keylen > kdf_keylen)
     429           0 :     kdf_keylen = rtcp_keylen;
     430             : 
     431             :   /* initialize KDF state     */
     432           0 :   stat = srtp_kdf_init(&kdf, AES_ICM, (const uint8_t *)key, kdf_keylen);
     433           0 :   if (stat) {
     434           0 :     return err_status_init_fail;
     435             :   }
     436             : 
     437           0 :   rtp_base_key_len = base_key_length(srtp->rtp_cipher->type, rtp_keylen);
     438           0 :   rtp_salt_len = rtp_keylen - rtp_base_key_len;
     439             :   
     440             :   /* generate encryption key  */
     441           0 :   stat = srtp_kdf_generate(&kdf, label_rtp_encryption, 
     442             :                            tmp_key, rtp_base_key_len);
     443           0 :   if (stat) {
     444             :     /* zeroize temp buffer */
     445           0 :     octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
     446           0 :     return err_status_init_fail;
     447             :   }
     448             : 
     449             :   /* 
     450             :    * if the cipher in the srtp context uses a salt, then we need
     451             :    * to generate the salt value
     452             :    */
     453           0 :   if (rtp_salt_len > 0) {
     454             :     debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL);
     455             : 
     456             :     /* generate encryption salt, put after encryption key */
     457           0 :     stat = srtp_kdf_generate(&kdf, label_rtp_salt, 
     458             :                              tmp_key + rtp_base_key_len, rtp_salt_len);
     459           0 :     if (stat) {
     460             :       /* zeroize temp buffer */
     461           0 :       octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
     462           0 :       return err_status_init_fail;
     463             :     }
     464             :   }
     465             :   debug_print(mod_srtp, "cipher key: %s", 
     466             :               octet_string_hex_string(tmp_key, rtp_keylen));
     467             : 
     468             :   /* initialize cipher */
     469           0 :   stat = cipher_init(srtp->rtp_cipher, tmp_key, direction_any);
     470           0 :   if (stat) {
     471             :     /* zeroize temp buffer */
     472           0 :     octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
     473           0 :     return err_status_init_fail;
     474             :   }
     475             : 
     476             :   /* generate authentication key */
     477           0 :   stat = srtp_kdf_generate(&kdf, label_rtp_msg_auth,
     478           0 :                            tmp_key, auth_get_key_length(srtp->rtp_auth));
     479           0 :   if (stat) {
     480             :     /* zeroize temp buffer */
     481           0 :     octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
     482           0 :     return err_status_init_fail;
     483             :   }
     484             :   debug_print(mod_srtp, "auth key:   %s",
     485             :               octet_string_hex_string(tmp_key, 
     486             :                                       auth_get_key_length(srtp->rtp_auth))); 
     487             : 
     488             :   /* initialize auth function */
     489           0 :   stat = auth_init(srtp->rtp_auth, tmp_key);
     490           0 :   if (stat) {
     491             :     /* zeroize temp buffer */
     492           0 :     octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
     493           0 :     return err_status_init_fail;
     494             :   }
     495             : 
     496             :   /*
     497             :    * ...now initialize SRTCP keys
     498             :    */
     499             : 
     500           0 :   rtcp_base_key_len = base_key_length(srtp->rtcp_cipher->type, rtcp_keylen);
     501           0 :   rtcp_salt_len = rtcp_keylen - rtcp_base_key_len;
     502             :   
     503             :   /* generate encryption key  */
     504           0 :   stat = srtp_kdf_generate(&kdf, label_rtcp_encryption, 
     505             :                            tmp_key, rtcp_base_key_len);
     506           0 :   if (stat) {
     507             :     /* zeroize temp buffer */
     508           0 :     octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
     509           0 :     return err_status_init_fail;
     510             :   }
     511             : 
     512             :   /* 
     513             :    * if the cipher in the srtp context uses a salt, then we need
     514             :    * to generate the salt value
     515             :    */
     516           0 :   if (rtcp_salt_len > 0) {
     517             :     debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt",
     518             :                 NULL);
     519             : 
     520             :     /* generate encryption salt, put after encryption key */
     521           0 :     stat = srtp_kdf_generate(&kdf, label_rtcp_salt, 
     522             :                              tmp_key + rtcp_base_key_len, rtcp_salt_len);
     523           0 :     if (stat) {
     524             :       /* zeroize temp buffer */
     525           0 :       octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
     526           0 :       return err_status_init_fail;
     527             :     }
     528             :   }
     529             :   debug_print(mod_srtp, "rtcp cipher key: %s", 
     530             :               octet_string_hex_string(tmp_key, rtcp_keylen));  
     531             : 
     532             :   /* initialize cipher */
     533           0 :   stat = cipher_init(srtp->rtcp_cipher, tmp_key, direction_any);
     534           0 :   if (stat) {
     535             :     /* zeroize temp buffer */
     536           0 :     octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
     537           0 :     return err_status_init_fail;
     538             :   }
     539             : 
     540             :   /* generate authentication key */
     541           0 :   stat = srtp_kdf_generate(&kdf, label_rtcp_msg_auth,
     542           0 :                            tmp_key, auth_get_key_length(srtp->rtcp_auth));
     543           0 :   if (stat) {
     544             :     /* zeroize temp buffer */
     545           0 :     octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
     546           0 :     return err_status_init_fail;
     547             :   }
     548             : 
     549             :   debug_print(mod_srtp, "rtcp auth key:   %s",
     550             :               octet_string_hex_string(tmp_key, 
     551             :                      auth_get_key_length(srtp->rtcp_auth))); 
     552             : 
     553             :   /* initialize auth function */
     554           0 :   stat = auth_init(srtp->rtcp_auth, tmp_key);
     555           0 :   if (stat) {
     556             :     /* zeroize temp buffer */
     557           0 :     octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
     558           0 :     return err_status_init_fail;
     559             :   }
     560             : 
     561             :   /* clear memory then return */
     562           0 :   stat = srtp_kdf_clear(&kdf);
     563           0 :   octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);  
     564           0 :   if (stat)
     565           0 :     return err_status_init_fail;
     566             : 
     567           0 :   return err_status_ok;
     568             : }
     569             : 
     570             : err_status_t
     571           0 : srtp_stream_init(srtp_stream_ctx_t *srtp, 
     572             :                   const srtp_policy_t *p) {
     573             :   err_status_t err;
     574             : 
     575             :    debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)", 
     576             :                p->ssrc.value);
     577             : 
     578             :    /* initialize replay database */
     579             :    /* window size MUST be at least 64.  MAY be larger.  Values more than
     580             :     * 2^15 aren't meaningful due to how extended sequence numbers are
     581             :     * calculated.   Let a window size of 0 imply the default value. */
     582             : 
     583           0 :    if (p->window_size != 0 && (p->window_size < 64 || p->window_size >= 0x8000))
     584           0 :      return err_status_bad_param;
     585             : 
     586           0 :    if (p->window_size != 0)
     587           0 :      err = rdbx_init(&srtp->rtp_rdbx, p->window_size);
     588             :    else
     589           0 :      err = rdbx_init(&srtp->rtp_rdbx, 128);
     590           0 :    if (err) return err;
     591             : 
     592             :    /* initialize key limit to maximum value */
     593             : #ifdef NO_64BIT_MATH
     594             : {
     595             :    uint64_t temp;
     596             :    temp = make64(UINT_MAX,UINT_MAX);
     597             :    key_limit_set(srtp->limit, temp);
     598             : }
     599             : #else
     600           0 :    key_limit_set(srtp->limit, 0xffffffffffffLL);
     601             : #endif
     602             : 
     603             :    /* set the SSRC value */
     604           0 :    srtp->ssrc = htonl(p->ssrc.value);
     605             : 
     606             :    /* set the security service flags */
     607           0 :    srtp->rtp_services  = p->rtp.sec_serv;
     608           0 :    srtp->rtcp_services = p->rtcp.sec_serv;
     609             : 
     610             :    /*
     611             :     * set direction to unknown - this flag gets checked in srtp_protect(),
     612             :     * srtp_unprotect(), srtp_protect_rtcp(), and srtp_unprotect_rtcp(), and 
     613             :     * gets set appropriately if it is set to unknown.
     614             :     */
     615           0 :    srtp->direction = dir_unknown;
     616             : 
     617             :    /* initialize SRTCP replay database */
     618           0 :    rdb_init(&srtp->rtcp_rdb);
     619             : 
     620             :    /* initialize allow_repeat_tx */
     621             :    /* guard against uninitialized memory: allow only 0 or 1 here */
     622           0 :    if (p->allow_repeat_tx != 0 && p->allow_repeat_tx != 1) {
     623           0 :      rdbx_dealloc(&srtp->rtp_rdbx);
     624           0 :      return err_status_bad_param;
     625             :    }
     626           0 :    srtp->allow_repeat_tx = p->allow_repeat_tx;
     627             : 
     628             :    /* DAM - no RTCP key limit at present */
     629             : 
     630             :    /* initialize keys */
     631           0 :    err = srtp_stream_init_keys(srtp, p->key);
     632           0 :    if (err) {
     633           0 :      rdbx_dealloc(&srtp->rtp_rdbx);
     634           0 :      return err;
     635             :    }
     636             : 
     637             :    /* 
     638             :     * if EKT is in use, then initialize the EKT data associated with
     639             :     * the stream
     640             :     */
     641           0 :    err = ekt_stream_init_from_policy(srtp->ekt, p->ekt);
     642           0 :    if (err) {
     643           0 :      rdbx_dealloc(&srtp->rtp_rdbx);
     644           0 :      return err;
     645             :    }
     646             : 
     647           0 :    return err_status_ok;  
     648             :  }
     649             : 
     650             : 
     651             :  /*
     652             :   * srtp_event_reporter is an event handler function that merely
     653             :   * reports the events that are reported by the callbacks
     654             :   */
     655             : 
     656             :  void
     657           0 :  srtp_event_reporter(srtp_event_data_t *data) {
     658             : 
     659           0 :    err_report(err_level_warning, "srtp: in stream 0x%x: ", 
     660           0 :               data->stream->ssrc);
     661             : 
     662           0 :    switch(data->event) {
     663             :    case event_ssrc_collision:
     664           0 :      err_report(err_level_warning, "\tSSRC collision\n");
     665           0 :      break;
     666             :    case event_key_soft_limit:
     667           0 :      err_report(err_level_warning, "\tkey usage soft limit reached\n");
     668           0 :      break;
     669             :    case event_key_hard_limit:
     670           0 :      err_report(err_level_warning, "\tkey usage hard limit reached\n");
     671           0 :      break;
     672             :    case event_packet_index_limit:
     673           0 :      err_report(err_level_warning, "\tpacket index limit reached\n");
     674           0 :      break;
     675             :    default:
     676           0 :      err_report(err_level_warning, "\tunknown event reported to handler\n");
     677             :    }
     678           0 :  }
     679             : 
     680             :  /*
     681             :   * srtp_event_handler is a global variable holding a pointer to the
     682             :   * event handler function; this function is called for any unexpected
     683             :   * event that needs to be handled out of the SRTP data path.  see
     684             :   * srtp_event_t in srtp.h for more info
     685             :   *
     686             :   * it is okay to set srtp_event_handler to NULL, but we set 
     687             :   * it to the srtp_event_reporter.
     688             :   */
     689             : 
     690             :  static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter;
     691             : 
     692             :  err_status_t
     693           0 :  srtp_install_event_handler(srtp_event_handler_func_t func) {
     694             : 
     695             :    /* 
     696             :     * note that we accept NULL arguments intentionally - calling this
     697             :     * function with a NULL arguments removes an event handler that's
     698             :     * been previously installed
     699             :     */
     700             : 
     701             :    /* set global event handling function */
     702           0 :    srtp_event_handler = func;
     703           0 :    return err_status_ok;
     704             :  }
     705             : 
     706             :  err_status_t
     707           0 :  srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) {
     708           0 :    srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
     709             :    uint32_t *enc_start;        /* pointer to start of encrypted portion  */
     710             :    uint32_t *auth_start;       /* pointer to start of auth. portion      */
     711           0 :    unsigned enc_octet_len = 0; /* number of octets in encrypted portion  */
     712             :    xtd_seq_num_t est;          /* estimated xtd_seq_num_t of *hdr        */
     713             :    int delta;                  /* delta of local pkt idx and that in hdr */
     714           0 :    uint8_t *auth_tag = NULL;   /* location of auth_tag within packet     */
     715             :    err_status_t status;   
     716             :    int tag_len;
     717             :    srtp_stream_ctx_t *stream;
     718             :    int prefix_len;
     719             : 
     720             :    debug_print(mod_srtp, "function srtp_protect", NULL);
     721             : 
     722             :   /* we assume the hdr is 32-bit aligned to start */
     723             : 
     724             :    /* check the packet length - it must at least contain a full header */
     725           0 :    if (*pkt_octet_len < octets_in_rtp_header)
     726           0 :      return err_status_bad_param;
     727             : 
     728             :    /*
     729             :     * look up ssrc in srtp_stream list, and process the packet with
     730             :     * the appropriate stream.  if we haven't seen this stream before,
     731             :     * there's a template key for this srtp_session, and the cipher
     732             :     * supports key-sharing, then we assume that a new stream using
     733             :     * that key has just started up
     734             :     */
     735           0 :    stream = srtp_get_stream(ctx, hdr->ssrc);
     736           0 :    if (stream == NULL) {
     737           0 :      if (ctx->stream_template != NULL) {
     738             :        srtp_stream_ctx_t *new_stream;
     739             : 
     740             :        /* allocate and initialize a new stream */
     741           0 :        status = srtp_stream_clone(ctx->stream_template, 
     742             :                                   hdr->ssrc, &new_stream); 
     743           0 :        if (status)
     744           0 :          return status;
     745             : 
     746             :        /* add new stream to the head of the stream_list */
     747           0 :        new_stream->next = ctx->stream_list;
     748           0 :        ctx->stream_list = new_stream;
     749             : 
     750             :        /* set direction to outbound */
     751           0 :        new_stream->direction = dir_srtp_sender;
     752             : 
     753             :        /* set stream (the pointer used in this function) */
     754           0 :        stream = new_stream;
     755             :      } else {
     756             :        /* no template stream, so we return an error */
     757           0 :        return err_status_no_ctx;
     758             :      } 
     759             :    }
     760             : 
     761             :    /* 
     762             :     * verify that stream is for sending traffic - this check will
     763             :     * detect SSRC collisions, since a stream that appears in both
     764             :     * srtp_protect() and srtp_unprotect() will fail this test in one of
     765             :     * those functions.
     766             :     */
     767           0 :    if (stream->direction != dir_srtp_sender) {
     768           0 :      if (stream->direction == dir_unknown) {
     769           0 :        stream->direction = dir_srtp_sender;
     770             :      } else {
     771           0 :        srtp_handle_event(ctx, stream, event_ssrc_collision);
     772             :      }
     773             :    }
     774             : 
     775             :   /* 
     776             :    * update the key usage limit, and check it to make sure that we
     777             :    * didn't just hit either the soft limit or the hard limit, and call
     778             :    * the event handler if we hit either.
     779             :    */
     780           0 :   switch(key_limit_update(stream->limit)) {
     781             :   case key_event_normal:
     782           0 :     break;
     783             :   case key_event_soft_limit: 
     784           0 :     srtp_handle_event(ctx, stream, event_key_soft_limit);
     785           0 :     break; 
     786             :   case key_event_hard_limit:
     787           0 :     srtp_handle_event(ctx, stream, event_key_hard_limit);
     788           0 :         return err_status_key_expired;
     789             :   default:
     790           0 :     break;
     791             :   }
     792             : 
     793             :    /* get tag length from stream */
     794           0 :    tag_len = auth_get_tag_length(stream->rtp_auth); 
     795             : 
     796             :    /*
     797             :     * find starting point for encryption and length of data to be
     798             :     * encrypted - the encrypted portion starts after the rtp header
     799             :     * extension, if present; otherwise, it starts after the last csrc,
     800             :     * if any are present
     801             :     *
     802             :     * if we're not providing confidentiality, set enc_start to NULL
     803             :     */
     804           0 :    if (stream->rtp_services & sec_serv_conf) {
     805           0 :      enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;  
     806           0 :      if (hdr->x == 1) {
     807           0 :        srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
     808           0 :        enc_start += (ntohs(xtn_hdr->length) + 1);
     809             :      }
     810           0 :      if (!((uint8_t*)enc_start <= (uint8_t*)hdr + *pkt_octet_len))
     811           0 :        return err_status_parse_err;
     812           0 :      enc_octet_len = (unsigned int)(*pkt_octet_len 
     813           0 :                                     - ((enc_start - (uint32_t *)hdr) << 2));
     814             :    } else {
     815           0 :      enc_start = NULL;
     816             :    }
     817             : 
     818             :    /* 
     819             :     * if we're providing authentication, set the auth_start and auth_tag
     820             :     * pointers to the proper locations; otherwise, set auth_start to NULL
     821             :     * to indicate that no authentication is needed
     822             :     */
     823           0 :    if (stream->rtp_services & sec_serv_auth) {
     824           0 :      auth_start = (uint32_t *)hdr;
     825           0 :      auth_tag = (uint8_t *)hdr + *pkt_octet_len;
     826             :    } else {
     827           0 :      auth_start = NULL;
     828           0 :      auth_tag = NULL;
     829             :    }
     830             : 
     831             :    /*
     832             :     * estimate the packet index using the start of the replay window   
     833             :     * and the sequence number from the header
     834             :     */
     835           0 :    delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
     836           0 :    status = rdbx_check(&stream->rtp_rdbx, delta);
     837           0 :    if (status) {
     838           0 :      if (status != err_status_replay_fail || !stream->allow_repeat_tx)
     839           0 :        return status;  /* we've been asked to reuse an index */
     840             :    }
     841             :    else
     842           0 :      rdbx_add_index(&stream->rtp_rdbx, delta);
     843             : 
     844             : #ifdef NO_64BIT_MATH
     845             :    debug_print2(mod_srtp, "estimated packet index: %08x%08x", 
     846             :                 high32(est),low32(est));
     847             : #else
     848             :    debug_print(mod_srtp, "estimated packet index: %016llx", est);
     849             : #endif
     850             : 
     851             :    /* 
     852             :     * if we're using rindael counter mode, set nonce and seq 
     853             :     */
     854           0 :    if (stream->rtp_cipher->type->id == AES_ICM) {
     855             :      v128_t iv;
     856             : 
     857           0 :      iv.v32[0] = 0;
     858           0 :      iv.v32[1] = hdr->ssrc;
     859             : #ifdef NO_64BIT_MATH
     860             :      iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
     861             :                                                                  low32(est) << 16));
     862             : #else
     863           0 :      iv.v64[1] = be64_to_cpu(est << 16);
     864             : #endif
     865           0 :      status = cipher_set_iv(stream->rtp_cipher, &iv);
     866             : 
     867             :    } else {  
     868             :      v128_t iv;
     869             : 
     870             :      /* otherwise, set the index to est */  
     871             : #ifdef NO_64BIT_MATH
     872             :      iv.v32[0] = 0;
     873             :      iv.v32[1] = 0;
     874             : #else
     875           0 :      iv.v64[0] = 0;
     876             : #endif
     877           0 :      iv.v64[1] = be64_to_cpu(est);
     878           0 :      status = cipher_set_iv(stream->rtp_cipher, &iv);
     879             :    }
     880           0 :    if (status)
     881           0 :      return err_status_cipher_fail;
     882             : 
     883             :    /* shift est, put into network byte order */
     884             : #ifdef NO_64BIT_MATH
     885             :    est = be64_to_cpu(make64((high32(est) << 16) |
     886             :                                                  (low32(est) >> 16),
     887             :                                                  low32(est) << 16));
     888             : #else
     889           0 :    est = be64_to_cpu(est << 16);
     890             : #endif
     891             :    
     892             :    /* 
     893             :     * if we're authenticating using a universal hash, put the keystream
     894             :     * prefix into the authentication tag
     895             :     */
     896           0 :    if (auth_start) {
     897             :      
     898           0 :     prefix_len = auth_get_prefix_length(stream->rtp_auth);    
     899           0 :     if (prefix_len) {
     900           0 :       status = cipher_output(stream->rtp_cipher, auth_tag, prefix_len);
     901           0 :       if (status)
     902           0 :         return err_status_cipher_fail;
     903             :       debug_print(mod_srtp, "keystream prefix: %s", 
     904             :                   octet_string_hex_string(auth_tag, prefix_len));
     905             :     }
     906             :   }
     907             : 
     908             :   /* if we're encrypting, exor keystream into the message */
     909           0 :   if (enc_start) {
     910           0 :     status = cipher_encrypt(stream->rtp_cipher, 
     911             :                             (uint8_t *)enc_start, &enc_octet_len);
     912           0 :     if (status)
     913           0 :       return err_status_cipher_fail;
     914             :   }
     915             : 
     916             :   /*
     917             :    *  if we're authenticating, run authentication function and put result
     918             :    *  into the auth_tag 
     919             :    */
     920           0 :   if (auth_start) {        
     921             : 
     922             :     /* initialize auth func context */
     923           0 :     status = auth_start(stream->rtp_auth);
     924           0 :     if (status) return status;
     925             : 
     926             :     /* run auth func over packet */
     927           0 :     status = auth_update(stream->rtp_auth, 
     928             :                          (uint8_t *)auth_start, *pkt_octet_len);
     929           0 :     if (status) return status;
     930             :     
     931             :     /* run auth func over ROC, put result into auth_tag */
     932             :     debug_print(mod_srtp, "estimated packet index: %016llx", est);
     933           0 :     status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag); 
     934             :     debug_print(mod_srtp, "srtp auth tag:    %s", 
     935             :                 octet_string_hex_string(auth_tag, tag_len));
     936           0 :     if (status)
     937           0 :       return err_status_auth_fail;   
     938             : 
     939             :   }
     940             : 
     941           0 :   if (auth_tag) {
     942             : 
     943             :     /* increase the packet length by the length of the auth tag */
     944           0 :     *pkt_octet_len += tag_len;
     945             :   }
     946             : 
     947           0 :   return err_status_ok;  
     948             : }
     949             : 
     950             : 
     951             : err_status_t
     952           0 : srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
     953           0 :   srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr;
     954             :   uint32_t *enc_start;      /* pointer to start of encrypted portion  */
     955             :   uint32_t *auth_start;     /* pointer to start of auth. portion      */
     956           0 :   unsigned enc_octet_len = 0;/* number of octets in encrypted portion */
     957           0 :   uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */
     958             :   xtd_seq_num_t est;        /* estimated xtd_seq_num_t of *hdr        */
     959             :   int delta;                /* delta of local pkt idx and that in hdr */
     960             :   v128_t iv;
     961             :   err_status_t status;
     962             :   srtp_stream_ctx_t *stream;
     963             :   uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
     964             :   int tag_len, prefix_len;
     965             : 
     966             :   debug_print(mod_srtp, "function srtp_unprotect", NULL);
     967             : 
     968             :   /* we assume the hdr is 32-bit aligned to start */
     969             : 
     970             :   /* check the packet length - it must at least contain a full header */
     971           0 :   if (*pkt_octet_len < octets_in_rtp_header)
     972           0 :     return err_status_bad_param;
     973             : 
     974             :   /*
     975             :    * look up ssrc in srtp_stream list, and process the packet with 
     976             :    * the appropriate stream.  if we haven't seen this stream before,
     977             :    * there's only one key for this srtp_session, and the cipher
     978             :    * supports key-sharing, then we assume that a new stream using
     979             :    * that key has just started up
     980             :    */
     981           0 :   stream = srtp_get_stream(ctx, hdr->ssrc);
     982           0 :   if (stream == NULL) {
     983           0 :     if (ctx->stream_template != NULL) {
     984           0 :       stream = ctx->stream_template;
     985             :       debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)",
     986             :                   hdr->ssrc);
     987             :       
     988             :       /* 
     989             :        * set estimated packet index to sequence number from header,
     990             :        * and set delta equal to the same value
     991             :        */
     992             : #ifdef NO_64BIT_MATH
     993             :       est = (xtd_seq_num_t) make64(0,ntohs(hdr->seq));
     994             :       delta = low32(est);
     995             : #else
     996           0 :       est = (xtd_seq_num_t) ntohs(hdr->seq);
     997           0 :       delta = (int)est;
     998             : #endif
     999             :     } else {
    1000             :       
    1001             :       /*
    1002             :        * no stream corresponding to SSRC found, and we don't do
    1003             :        * key-sharing, so return an error
    1004             :        */
    1005           0 :       return err_status_no_ctx;
    1006             :     }
    1007             :   } else {
    1008             :   
    1009             :     /* estimate packet index from seq. num. in header */
    1010           0 :     delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
    1011             :     
    1012             :     /* check replay database */
    1013           0 :     status = rdbx_check(&stream->rtp_rdbx, delta);
    1014           0 :     if (status)
    1015           0 :       return status;
    1016             :   }
    1017             : 
    1018             : #ifdef NO_64BIT_MATH
    1019             :   debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),low32(est));
    1020             : #else
    1021             :   debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
    1022             : #endif
    1023             : 
    1024             :   /* get tag length from stream */
    1025           0 :   tag_len = auth_get_tag_length(stream->rtp_auth); 
    1026             : 
    1027             :   /* 
    1028             :    * set the cipher's IV properly, depending on whatever cipher we
    1029             :    * happen to be using
    1030             :    */
    1031           0 :   if (stream->rtp_cipher->type->id == AES_ICM) {
    1032             : 
    1033             :     /* aes counter mode */
    1034           0 :     iv.v32[0] = 0;
    1035           0 :     iv.v32[1] = hdr->ssrc;  /* still in network order */
    1036             : #ifdef NO_64BIT_MATH
    1037             :     iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
    1038             :                                  low32(est) << 16));
    1039             : #else
    1040           0 :     iv.v64[1] = be64_to_cpu(est << 16);
    1041             : #endif
    1042           0 :     status = cipher_set_iv(stream->rtp_cipher, &iv);
    1043             :   } else {  
    1044             :     
    1045             :     /* no particular format - set the iv to the pakcet index */  
    1046             : #ifdef NO_64BIT_MATH
    1047             :     iv.v32[0] = 0;
    1048             :     iv.v32[1] = 0;
    1049             : #else
    1050           0 :     iv.v64[0] = 0;
    1051             : #endif
    1052           0 :     iv.v64[1] = be64_to_cpu(est);
    1053           0 :     status = cipher_set_iv(stream->rtp_cipher, &iv);
    1054             :   }
    1055           0 :   if (status)
    1056           0 :     return err_status_cipher_fail;
    1057             : 
    1058             :   /* shift est, put into network byte order */
    1059             : #ifdef NO_64BIT_MATH
    1060             :   est = be64_to_cpu(make64((high32(est) << 16) |
    1061             :                                             (low32(est) >> 16),
    1062             :                                             low32(est) << 16));
    1063             : #else
    1064           0 :   est = be64_to_cpu(est << 16);
    1065             : #endif
    1066             : 
    1067             :   /*
    1068             :    * find starting point for decryption and length of data to be
    1069             :    * decrypted - the encrypted portion starts after the rtp header
    1070             :    * extension, if present; otherwise, it starts after the last csrc,
    1071             :    * if any are present
    1072             :    *
    1073             :    * if we're not providing confidentiality, set enc_start to NULL
    1074             :    */
    1075           0 :   if (stream->rtp_services & sec_serv_conf) {
    1076           0 :     enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;  
    1077           0 :     if (hdr->x == 1) {
    1078           0 :       srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
    1079           0 :       enc_start += (ntohs(xtn_hdr->length) + 1);
    1080             :     }  
    1081           0 :     if (!((uint8_t*)enc_start < (uint8_t*)hdr + (*pkt_octet_len - tag_len)))
    1082           0 :       return err_status_parse_err;
    1083           0 :     enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len 
    1084           0 :                                - ((enc_start - (uint32_t *)hdr) << 2));
    1085             :   } else {
    1086           0 :     enc_start = NULL;
    1087             :   }
    1088             : 
    1089             :   /* 
    1090             :    * if we're providing authentication, set the auth_start and auth_tag
    1091             :    * pointers to the proper locations; otherwise, set auth_start to NULL
    1092             :    * to indicate that no authentication is needed
    1093             :    */
    1094           0 :   if (stream->rtp_services & sec_serv_auth) {
    1095           0 :     auth_start = (uint32_t *)hdr;
    1096           0 :     auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len;
    1097             :   } else {
    1098           0 :     auth_start = NULL;
    1099           0 :     auth_tag = NULL;
    1100             :   } 
    1101             : 
    1102             :   /*
    1103             :    * if we expect message authentication, run the authentication
    1104             :    * function and compare the result with the value of the auth_tag
    1105             :    */
    1106           0 :   if (auth_start) {        
    1107             : 
    1108             :     /* 
    1109             :      * if we're using a universal hash, then we need to compute the
    1110             :      * keystream prefix for encrypting the universal hash output
    1111             :      *
    1112             :      * if the keystream prefix length is zero, then we know that
    1113             :      * the authenticator isn't using a universal hash function
    1114             :      */  
    1115           0 :     if (stream->rtp_auth->prefix_len != 0) {
    1116             :       
    1117           0 :       prefix_len = auth_get_prefix_length(stream->rtp_auth);    
    1118           0 :       status = cipher_output(stream->rtp_cipher, tmp_tag, prefix_len);
    1119             :       debug_print(mod_srtp, "keystream prefix: %s", 
    1120             :                   octet_string_hex_string(tmp_tag, prefix_len));
    1121           0 :       if (status)
    1122           0 :         return err_status_cipher_fail;
    1123             :     } 
    1124             : 
    1125             :     /* initialize auth func context */
    1126           0 :     status = auth_start(stream->rtp_auth);
    1127           0 :     if (status) return status;
    1128             :  
    1129             :     /* now compute auth function over packet */
    1130           0 :     status = auth_update(stream->rtp_auth, (uint8_t *)auth_start,  
    1131             :                          *pkt_octet_len - tag_len);
    1132             : 
    1133             :     /* run auth func over ROC, then write tmp tag */
    1134           0 :     status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag);  
    1135             : 
    1136             :     debug_print(mod_srtp, "computed auth tag:    %s", 
    1137             :                 octet_string_hex_string(tmp_tag, tag_len));
    1138             :     debug_print(mod_srtp, "packet auth tag:      %s", 
    1139             :                 octet_string_hex_string(auth_tag, tag_len));
    1140           0 :     if (status)
    1141           0 :       return err_status_auth_fail;   
    1142             : 
    1143           0 :     if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
    1144           0 :       return err_status_auth_fail;
    1145             :   }
    1146             : 
    1147             :   /* 
    1148             :    * update the key usage limit, and check it to make sure that we
    1149             :    * didn't just hit either the soft limit or the hard limit, and call
    1150             :    * the event handler if we hit either.
    1151             :    */
    1152           0 :   switch(key_limit_update(stream->limit)) {
    1153             :   case key_event_normal:
    1154           0 :     break;
    1155             :   case key_event_soft_limit: 
    1156           0 :     srtp_handle_event(ctx, stream, event_key_soft_limit);
    1157           0 :     break; 
    1158             :   case key_event_hard_limit:
    1159           0 :     srtp_handle_event(ctx, stream, event_key_hard_limit);
    1160           0 :     return err_status_key_expired;
    1161             :   default:
    1162           0 :     break;
    1163             :   }
    1164             : 
    1165             :   /* if we're decrypting, add keystream into ciphertext */
    1166           0 :   if (enc_start) {
    1167           0 :     status = cipher_decrypt(stream->rtp_cipher, 
    1168             :                             (uint8_t *)enc_start, &enc_octet_len);
    1169           0 :     if (status)
    1170           0 :       return err_status_cipher_fail;
    1171             :   }
    1172             : 
    1173             :   /* 
    1174             :    * verify that stream is for received traffic - this check will
    1175             :    * detect SSRC collisions, since a stream that appears in both
    1176             :    * srtp_protect() and srtp_unprotect() will fail this test in one of
    1177             :    * those functions.
    1178             :    *
    1179             :    * we do this check *after* the authentication check, so that the
    1180             :    * latter check will catch any attempts to fool us into thinking
    1181             :    * that we've got a collision
    1182             :    */
    1183           0 :   if (stream->direction != dir_srtp_receiver) {
    1184           0 :     if (stream->direction == dir_unknown) {
    1185           0 :       stream->direction = dir_srtp_receiver;
    1186             :     } else {
    1187           0 :       srtp_handle_event(ctx, stream, event_ssrc_collision);
    1188             :     }
    1189             :   }
    1190             : 
    1191             :   /* 
    1192             :    * if the stream is a 'provisional' one, in which the template context
    1193             :    * is used, then we need to allocate a new stream at this point, since
    1194             :    * the authentication passed
    1195             :    */
    1196           0 :   if (stream == ctx->stream_template) {  
    1197             :     srtp_stream_ctx_t *new_stream;
    1198             : 
    1199             :     /* 
    1200             :      * allocate and initialize a new stream 
    1201             :      * 
    1202             :      * note that we indicate failure if we can't allocate the new
    1203             :      * stream, and some implementations will want to not return
    1204             :      * failure here
    1205             :      */
    1206           0 :     status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); 
    1207           0 :     if (status)
    1208           0 :       return status;
    1209             :     
    1210             :     /* add new stream to the head of the stream_list */
    1211           0 :     new_stream->next = ctx->stream_list;
    1212           0 :     ctx->stream_list = new_stream;
    1213             :     
    1214             :     /* set stream (the pointer used in this function) */
    1215           0 :     stream = new_stream;
    1216             :   }
    1217             :   
    1218             :   /* 
    1219             :    * the message authentication function passed, so add the packet
    1220             :    * index into the replay database 
    1221             :    */
    1222           0 :   rdbx_add_index(&stream->rtp_rdbx, delta);
    1223             : 
    1224             :   /* decrease the packet length by the length of the auth tag */
    1225           0 :   *pkt_octet_len -= tag_len;
    1226             : 
    1227           0 :   return err_status_ok;  
    1228             : }
    1229             : 
    1230             : err_status_t
    1231           0 : srtp_init() {
    1232             :   err_status_t status;
    1233             : 
    1234             :   /* initialize crypto kernel */
    1235           0 :   status = crypto_kernel_init();
    1236           0 :   if (status) 
    1237           0 :     return status;
    1238             : 
    1239             :   /* load srtp debug module into the kernel */
    1240           0 :   status = crypto_kernel_load_debug_module(&mod_srtp);
    1241           0 :   if (status)
    1242           0 :     return status;
    1243             : 
    1244           0 :   return err_status_ok;
    1245             : }
    1246             : 
    1247             : err_status_t
    1248           0 : srtp_shutdown() {
    1249             :   err_status_t status;
    1250             : 
    1251             :   /* shut down crypto kernel */
    1252           0 :   status = crypto_kernel_shutdown();
    1253           0 :   if (status) 
    1254           0 :     return status;
    1255             : 
    1256             :   /* shutting down crypto kernel frees the srtp debug module as well */
    1257             : 
    1258           0 :   return err_status_ok;
    1259             : }
    1260             : 
    1261             : 
    1262             : /* 
    1263             :  * The following code is under consideration for removal.  See
    1264             :  * SRTP_MAX_TRAILER_LEN 
    1265             :  */
    1266             : #if 0
    1267             : 
    1268             : /*
    1269             :  * srtp_get_trailer_length(&a) returns the number of octets that will
    1270             :  * be added to an RTP packet by the SRTP processing.  This value
    1271             :  * is constant for a given srtp_stream_t (i.e. between initializations).
    1272             :  */
    1273             : 
    1274             : int
    1275             : srtp_get_trailer_length(const srtp_stream_t s) {
    1276             :   return auth_get_tag_length(s->rtp_auth);
    1277             : }
    1278             : 
    1279             : #endif
    1280             : 
    1281             : /*
    1282             :  * srtp_get_stream(ssrc) returns a pointer to the stream corresponding
    1283             :  * to ssrc, or NULL if no stream exists for that ssrc
    1284             :  *
    1285             :  * this is an internal function 
    1286             :  */
    1287             : 
    1288             : srtp_stream_ctx_t *
    1289           0 : srtp_get_stream(srtp_t srtp, uint32_t ssrc) {
    1290             :   srtp_stream_ctx_t *stream;
    1291             : 
    1292             :   /* walk down list until ssrc is found */
    1293           0 :   stream = srtp->stream_list;
    1294           0 :   while (stream != NULL) {
    1295           0 :     if (stream->ssrc == ssrc)
    1296           0 :       return stream;
    1297           0 :     stream = stream->next;
    1298             :   }
    1299             :   
    1300             :   /* we haven't found our ssrc, so return a null */
    1301           0 :   return NULL;
    1302             : }
    1303             : 
    1304             : err_status_t
    1305           0 : srtp_dealloc(srtp_t session) {
    1306             :   srtp_stream_ctx_t *stream;
    1307             :   err_status_t status;
    1308             : 
    1309             :   /*
    1310             :    * we take a conservative deallocation strategy - if we encounter an
    1311             :    * error deallocating a stream, then we stop trying to deallocate
    1312             :    * memory and just return an error
    1313             :    */
    1314             : 
    1315             :   /* walk list of streams, deallocating as we go */
    1316           0 :   stream = session->stream_list;
    1317           0 :   while (stream != NULL) {
    1318           0 :     srtp_stream_t next = stream->next;
    1319           0 :     status = srtp_stream_dealloc(session, stream);
    1320           0 :     if (status)
    1321           0 :       return status;
    1322           0 :     stream = next;
    1323             :   }
    1324             :   
    1325             :   /* deallocate stream template, if there is one */
    1326           0 :   if (session->stream_template != NULL) {
    1327           0 :     status = auth_dealloc(session->stream_template->rtcp_auth); 
    1328           0 :     if (status) 
    1329           0 :       return status; 
    1330           0 :     status = cipher_dealloc(session->stream_template->rtcp_cipher); 
    1331           0 :     if (status) 
    1332           0 :       return status; 
    1333           0 :     crypto_free(session->stream_template->limit);
    1334           0 :     status = cipher_dealloc(session->stream_template->rtp_cipher); 
    1335           0 :     if (status) 
    1336           0 :       return status; 
    1337           0 :     status = auth_dealloc(session->stream_template->rtp_auth);
    1338           0 :     if (status)
    1339           0 :       return status;
    1340           0 :     status = rdbx_dealloc(&session->stream_template->rtp_rdbx);
    1341           0 :     if (status)
    1342           0 :       return status;
    1343           0 :     crypto_free(session->stream_template);
    1344             :   }
    1345             : 
    1346             :   /* deallocate session context */
    1347           0 :   crypto_free(session);
    1348             : 
    1349           0 :   return err_status_ok;
    1350             : }
    1351             : 
    1352             : 
    1353             : err_status_t
    1354           0 : srtp_add_stream(srtp_t session, 
    1355             :                 const srtp_policy_t *policy)  {
    1356             :   err_status_t status;
    1357             :   srtp_stream_t tmp;
    1358             : 
    1359             :   /* sanity check arguments */
    1360           0 :   if ((session == NULL) || (policy == NULL) || (policy->key == NULL))
    1361           0 :     return err_status_bad_param;
    1362             : 
    1363             :   /* allocate stream  */
    1364           0 :   status = srtp_stream_alloc(&tmp, policy);
    1365           0 :   if (status) {
    1366           0 :     return status;
    1367             :   }
    1368             :   
    1369             :   /* initialize stream  */
    1370           0 :   status = srtp_stream_init(tmp, policy);
    1371           0 :   if (status) {
    1372           0 :     crypto_free(tmp);
    1373           0 :     return status;
    1374             :   }
    1375             :   
    1376             :   /* 
    1377             :    * set the head of the stream list or the template to point to the
    1378             :    * stream that we've just alloced and init'ed, depending on whether
    1379             :    * or not it has a wildcard SSRC value or not
    1380             :    *
    1381             :    * if the template stream has already been set, then the policy is
    1382             :    * inconsistent, so we return a bad_param error code
    1383             :    */
    1384           0 :   switch (policy->ssrc.type) {
    1385             :   case (ssrc_any_outbound):
    1386           0 :     if (session->stream_template) {
    1387           0 :       return err_status_bad_param;
    1388             :     }
    1389           0 :     session->stream_template = tmp;
    1390           0 :     session->stream_template->direction = dir_srtp_sender;
    1391           0 :     break;
    1392             :   case (ssrc_any_inbound):
    1393           0 :     if (session->stream_template) {
    1394           0 :       return err_status_bad_param;
    1395             :     }
    1396           0 :     session->stream_template = tmp;
    1397           0 :     session->stream_template->direction = dir_srtp_receiver;
    1398           0 :     break;
    1399             :   case (ssrc_specific):
    1400           0 :     tmp->next = session->stream_list;
    1401           0 :     session->stream_list = tmp;
    1402           0 :     break;
    1403             :   case (ssrc_undefined):
    1404             :   default:
    1405           0 :     crypto_free(tmp);
    1406           0 :     return err_status_bad_param;
    1407             :   }
    1408             :     
    1409           0 :   return err_status_ok;
    1410             : }
    1411             : 
    1412             : 
    1413             : err_status_t
    1414           0 : srtp_create(srtp_t *session,               /* handle for session     */ 
    1415             :             const srtp_policy_t *policy) { /* SRTP policy (list)     */
    1416             :   err_status_t stat;
    1417             :   srtp_ctx_t *ctx;
    1418             : 
    1419             :   /* sanity check arguments */
    1420           0 :   if (session == NULL)
    1421           0 :     return err_status_bad_param;
    1422             : 
    1423             :   /* allocate srtp context and set ctx_ptr */
    1424           0 :   ctx = (srtp_ctx_t *) crypto_alloc(sizeof(srtp_ctx_t));
    1425           0 :   if (ctx == NULL)
    1426           0 :     return err_status_alloc_fail;
    1427           0 :   *session = ctx;
    1428             : 
    1429             :   /* 
    1430             :    * loop over elements in the policy list, allocating and
    1431             :    * initializing a stream for each element
    1432             :    */
    1433           0 :   ctx->stream_template = NULL;
    1434           0 :   ctx->stream_list = NULL;
    1435           0 :   while (policy != NULL) {    
    1436             : 
    1437           0 :     stat = srtp_add_stream(ctx, policy);
    1438           0 :     if (stat) {
    1439             :       /* clean up everything */
    1440           0 :       srtp_dealloc(*session);
    1441           0 :       return stat;
    1442             :     }    
    1443             : 
    1444             :     /* set policy to next item in list  */
    1445           0 :     policy = policy->next;
    1446             :   }
    1447             : 
    1448           0 :   return err_status_ok;
    1449             : }
    1450             : 
    1451             : 
    1452             : err_status_t
    1453           0 : srtp_remove_stream(srtp_t session, uint32_t ssrc) {
    1454             :   srtp_stream_ctx_t *stream, *last_stream;
    1455             :   err_status_t status;
    1456             : 
    1457             :   /* sanity check arguments */
    1458           0 :   if (session == NULL)
    1459           0 :     return err_status_bad_param;
    1460             :   
    1461             :   /* find stream in list; complain if not found */
    1462           0 :   last_stream = stream = session->stream_list;
    1463           0 :   while ((stream != NULL) && (ssrc != stream->ssrc)) {
    1464           0 :     last_stream = stream;
    1465           0 :     stream = stream->next;
    1466             :   }
    1467           0 :   if (stream == NULL)
    1468           0 :     return err_status_no_ctx;
    1469             : 
    1470             :   /* remove stream from the list */
    1471           0 :   if (last_stream == stream)
    1472             :     /* stream was first in list */
    1473           0 :     session->stream_list = stream->next;
    1474             :   else
    1475           0 :     last_stream->next = stream->next;
    1476             : 
    1477             :   /* deallocate the stream */
    1478           0 :   status = srtp_stream_dealloc(session, stream);
    1479           0 :   if (status)
    1480           0 :     return status;
    1481             : 
    1482           0 :   return err_status_ok;
    1483             : }
    1484             : 
    1485             : 
    1486             : /*
    1487             :  * the default policy - provides a convenient way for callers to use
    1488             :  * the default security policy
    1489             :  * 
    1490             :  * this policy is that defined in the current SRTP internet draft.
    1491             :  *
    1492             :  */
    1493             : 
    1494             : /* 
    1495             :  * NOTE: cipher_key_len is really key len (128 bits) plus salt len
    1496             :  *  (112 bits)
    1497             :  */
    1498             : /* There are hard-coded 16's for base_key_len in the key generation code */
    1499             : 
    1500             : void
    1501           0 : crypto_policy_set_rtp_default(crypto_policy_t *p) {
    1502             : 
    1503           0 :   p->cipher_type     = AES_ICM;           
    1504           0 :   p->cipher_key_len  = 30;                /* default 128 bits per RFC 3711 */
    1505           0 :   p->auth_type       = HMAC_SHA1;             
    1506           0 :   p->auth_key_len    = 20;                /* default 160 bits per RFC 3711 */
    1507           0 :   p->auth_tag_len    = 10;                /* default 80 bits per RFC 3711 */
    1508           0 :   p->sec_serv        = sec_serv_conf_and_auth;
    1509             :   
    1510           0 : }
    1511             : 
    1512             : void
    1513           0 : crypto_policy_set_rtcp_default(crypto_policy_t *p) {
    1514             : 
    1515           0 :   p->cipher_type     = AES_ICM;           
    1516           0 :   p->cipher_key_len  = 30;                 /* default 128 bits per RFC 3711 */
    1517           0 :   p->auth_type       = HMAC_SHA1;             
    1518           0 :   p->auth_key_len    = 20;                 /* default 160 bits per RFC 3711 */
    1519           0 :   p->auth_tag_len    = 10;                 /* default 80 bits per RFC 3711 */
    1520           0 :   p->sec_serv        = sec_serv_conf_and_auth;
    1521             :   
    1522           0 : }
    1523             : 
    1524             : void
    1525           0 : crypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p) {
    1526             : 
    1527             :   /*
    1528             :    * corresponds to RFC 4568
    1529             :    *
    1530             :    * note that this crypto policy is intended for SRTP, but not SRTCP
    1531             :    */
    1532             : 
    1533           0 :   p->cipher_type     = AES_ICM;           
    1534           0 :   p->cipher_key_len  = 30;                /* 128 bit key, 112 bit salt */
    1535           0 :   p->auth_type       = HMAC_SHA1;             
    1536           0 :   p->auth_key_len    = 20;                /* 160 bit key               */
    1537           0 :   p->auth_tag_len    = 4;                 /* 32 bit tag                */
    1538           0 :   p->sec_serv        = sec_serv_conf_and_auth;
    1539             :   
    1540           0 : }
    1541             : 
    1542             : 
    1543             : void
    1544           0 : crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p) {
    1545             : 
    1546             :   /*
    1547             :    * corresponds to RFC 4568
    1548             :    *
    1549             :    * note that this crypto policy is intended for SRTP, but not SRTCP
    1550             :    */
    1551             : 
    1552           0 :   p->cipher_type     = AES_ICM;           
    1553           0 :   p->cipher_key_len  = 30;                /* 128 bit key, 112 bit salt */
    1554           0 :   p->auth_type       = NULL_AUTH;             
    1555           0 :   p->auth_key_len    = 0; 
    1556           0 :   p->auth_tag_len    = 0; 
    1557           0 :   p->sec_serv        = sec_serv_conf;
    1558             :   
    1559           0 : }
    1560             : 
    1561             : 
    1562             : void
    1563           0 : crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p) {
    1564             : 
    1565             :   /*
    1566             :    * corresponds to RFC 4568
    1567             :    */
    1568             : 
    1569           0 :   p->cipher_type     = NULL_CIPHER;           
    1570           0 :   p->cipher_key_len  = 0;
    1571           0 :   p->auth_type       = HMAC_SHA1;             
    1572           0 :   p->auth_key_len    = 20; 
    1573           0 :   p->auth_tag_len    = 10; 
    1574           0 :   p->sec_serv        = sec_serv_auth;
    1575             :   
    1576           0 : }
    1577             : 
    1578             : 
    1579             : void
    1580           0 : crypto_policy_set_aes_cm_256_hmac_sha1_80(crypto_policy_t *p) {
    1581             : 
    1582             :   /*
    1583             :    * corresponds to draft-ietf-avt-big-aes-03.txt
    1584             :    */
    1585             : 
    1586           0 :   p->cipher_type     = AES_ICM;           
    1587           0 :   p->cipher_key_len  = 46;
    1588           0 :   p->auth_type       = HMAC_SHA1;             
    1589           0 :   p->auth_key_len    = 20;                /* default 160 bits per RFC 3711 */
    1590           0 :   p->auth_tag_len    = 10;                /* default 80 bits per RFC 3711 */
    1591           0 :   p->sec_serv        = sec_serv_conf_and_auth;
    1592           0 : }
    1593             : 
    1594             : 
    1595             : void
    1596           0 : crypto_policy_set_aes_cm_256_hmac_sha1_32(crypto_policy_t *p) {
    1597             : 
    1598             :   /*
    1599             :    * corresponds to draft-ietf-avt-big-aes-03.txt
    1600             :    *
    1601             :    * note that this crypto policy is intended for SRTP, but not SRTCP
    1602             :    */
    1603             : 
    1604           0 :   p->cipher_type     = AES_ICM;           
    1605           0 :   p->cipher_key_len  = 46;
    1606           0 :   p->auth_type       = HMAC_SHA1;             
    1607           0 :   p->auth_key_len    = 20;                /* default 160 bits per RFC 3711 */
    1608           0 :   p->auth_tag_len    = 4;                 /* default 80 bits per RFC 3711 */
    1609           0 :   p->sec_serv        = sec_serv_conf_and_auth;
    1610           0 : }
    1611             : 
    1612             : 
    1613             : /* 
    1614             :  * secure rtcp functions
    1615             :  */
    1616             : 
    1617             : err_status_t 
    1618           0 : srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {
    1619           0 :   srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
    1620             :   uint32_t *enc_start;      /* pointer to start of encrypted portion  */
    1621             :   uint32_t *auth_start;     /* pointer to start of auth. portion      */
    1622             :   uint32_t *trailer;        /* pointer to start of trailer            */
    1623           0 :   unsigned enc_octet_len = 0;/* number of octets in encrypted portion */
    1624           0 :   uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */
    1625             :   err_status_t status;   
    1626             :   int tag_len;
    1627             :   srtp_stream_ctx_t *stream;
    1628             :   int prefix_len;
    1629             :   uint32_t seq_num;
    1630             : 
    1631             :   /* we assume the hdr is 32-bit aligned to start */
    1632             :   /*
    1633             :    * look up ssrc in srtp_stream list, and process the packet with 
    1634             :    * the appropriate stream.  if we haven't seen this stream before,
    1635             :    * there's only one key for this srtp_session, and the cipher
    1636             :    * supports key-sharing, then we assume that a new stream using
    1637             :    * that key has just started up
    1638             :    */
    1639           0 :   stream = srtp_get_stream(ctx, hdr->ssrc);
    1640           0 :   if (stream == NULL) {
    1641           0 :     if (ctx->stream_template != NULL) {
    1642             :       srtp_stream_ctx_t *new_stream;
    1643             :       
    1644             :       /* allocate and initialize a new stream */
    1645           0 :       status = srtp_stream_clone(ctx->stream_template,
    1646             :                                  hdr->ssrc, &new_stream); 
    1647           0 :       if (status)
    1648           0 :         return status;
    1649             :       
    1650             :       /* add new stream to the head of the stream_list */
    1651           0 :       new_stream->next = ctx->stream_list;
    1652           0 :       ctx->stream_list = new_stream;
    1653             :       
    1654             :       /* set stream (the pointer used in this function) */
    1655           0 :       stream = new_stream;
    1656             :     } else {
    1657             :       /* no template stream, so we return an error */
    1658           0 :       return err_status_no_ctx;
    1659             :     } 
    1660             :   }
    1661             :   
    1662             :   /* 
    1663             :    * verify that stream is for sending traffic - this check will
    1664             :    * detect SSRC collisions, since a stream that appears in both
    1665             :    * srtp_protect() and srtp_unprotect() will fail this test in one of
    1666             :    * those functions.
    1667             :    */
    1668           0 :   if (stream->direction != dir_srtp_sender) {
    1669           0 :     if (stream->direction == dir_unknown) {
    1670           0 :       stream->direction = dir_srtp_sender;
    1671             :     } else {
    1672           0 :       srtp_handle_event(ctx, stream, event_ssrc_collision);
    1673             :     }
    1674             :   }  
    1675             : 
    1676             :   /* get tag length from stream context */
    1677           0 :   tag_len = auth_get_tag_length(stream->rtcp_auth); 
    1678             : 
    1679             :   /*
    1680             :    * set encryption start and encryption length - if we're not
    1681             :    * providing confidentiality, set enc_start to NULL
    1682             :    */
    1683           0 :   enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;  
    1684           0 :   enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
    1685             : 
    1686             :   /* all of the packet, except the header, gets encrypted */
    1687             :   /* NOTE: hdr->length is not usable - it refers to only the first
    1688             :          RTCP report in the compound packet! */
    1689             :   /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
    1690             :          multiples of 32-bits (RFC 3550 6.1) */
    1691           0 :   trailer = (uint32_t *) ((char *)enc_start + enc_octet_len);
    1692             : 
    1693           0 :   if (stream->rtcp_services & sec_serv_conf) {
    1694           0 :     *trailer = htonl(SRTCP_E_BIT);     /* set encrypt bit */    
    1695             :   } else {
    1696           0 :     enc_start = NULL;
    1697           0 :     enc_octet_len = 0;
    1698             :         /* 0 is network-order independant */
    1699           0 :     *trailer = 0x00000000;     /* set encrypt bit */    
    1700             :   }
    1701             : 
    1702             :   /* 
    1703             :    * set the auth_start and auth_tag pointers to the proper locations
    1704             :    * (note that srtpc *always* provides authentication, unlike srtp)
    1705             :    */
    1706             :   /* Note: This would need to change for optional mikey data */
    1707           0 :   auth_start = (uint32_t *)hdr;
    1708           0 :   auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t); 
    1709             : 
    1710             :   /* perform EKT processing if needed */
    1711           0 :   ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len, 
    1712           0 :                  rdbx_get_packet_index(&stream->rtp_rdbx));
    1713             : 
    1714             :   /* 
    1715             :    * check sequence number for overruns, and copy it into the packet
    1716             :    * if its value isn't too big
    1717             :    */
    1718           0 :   status = rdb_increment(&stream->rtcp_rdb);
    1719           0 :   if (status)
    1720           0 :     return status;
    1721           0 :   seq_num = rdb_get_value(&stream->rtcp_rdb);
    1722           0 :   *trailer |= htonl(seq_num);
    1723             :   debug_print(mod_srtp, "srtcp index: %x", seq_num);
    1724             : 
    1725             :   /* 
    1726             :    * if we're using rindael counter mode, set nonce and seq 
    1727             :    */
    1728           0 :   if (stream->rtcp_cipher->type->id == AES_ICM) {
    1729             :     v128_t iv;
    1730             :     
    1731           0 :     iv.v32[0] = 0;
    1732           0 :     iv.v32[1] = hdr->ssrc;  /* still in network order! */
    1733           0 :     iv.v32[2] = htonl(seq_num >> 16);
    1734           0 :     iv.v32[3] = htonl(seq_num << 16);
    1735           0 :     status = cipher_set_iv(stream->rtcp_cipher, &iv);
    1736             : 
    1737             :   } else {  
    1738             :     v128_t iv;
    1739             :     
    1740             :     /* otherwise, just set the index to seq_num */  
    1741           0 :     iv.v32[0] = 0;
    1742           0 :     iv.v32[1] = 0;
    1743           0 :     iv.v32[2] = 0;
    1744           0 :     iv.v32[3] = htonl(seq_num);
    1745           0 :     status = cipher_set_iv(stream->rtcp_cipher, &iv);
    1746             :   }
    1747           0 :   if (status)
    1748           0 :     return err_status_cipher_fail;
    1749             : 
    1750             :   /* 
    1751             :    * if we're authenticating using a universal hash, put the keystream
    1752             :    * prefix into the authentication tag
    1753             :    */
    1754             :   
    1755             :   /* if auth_start is non-null, then put keystream into tag  */
    1756           0 :   if (auth_start) {
    1757             : 
    1758             :     /* put keystream prefix into auth_tag */
    1759           0 :     prefix_len = auth_get_prefix_length(stream->rtcp_auth);    
    1760           0 :     status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
    1761             : 
    1762             :     debug_print(mod_srtp, "keystream prefix: %s", 
    1763             :                 octet_string_hex_string(auth_tag, prefix_len));
    1764             : 
    1765           0 :     if (status)
    1766           0 :       return err_status_cipher_fail;
    1767             :   }
    1768             : 
    1769             :   /* if we're encrypting, exor keystream into the message */
    1770           0 :   if (enc_start) {
    1771           0 :     status = cipher_encrypt(stream->rtcp_cipher, 
    1772             :                             (uint8_t *)enc_start, &enc_octet_len);
    1773           0 :     if (status)
    1774           0 :       return err_status_cipher_fail;
    1775             :   }
    1776             : 
    1777             :   /* initialize auth func context */
    1778           0 :   auth_start(stream->rtcp_auth);
    1779             : 
    1780             :   /* 
    1781             :    * run auth func over packet (including trailer), and write the
    1782             :    * result at auth_tag 
    1783             :    */
    1784           0 :   status = auth_compute(stream->rtcp_auth, 
    1785             :                         (uint8_t *)auth_start, 
    1786             :                         (*pkt_octet_len) + sizeof(srtcp_trailer_t), 
    1787             :                         auth_tag);
    1788             :   debug_print(mod_srtp, "srtcp auth tag:    %s", 
    1789             :               octet_string_hex_string(auth_tag, tag_len));
    1790           0 :   if (status)
    1791           0 :     return err_status_auth_fail;   
    1792             :     
    1793             :   /* increase the packet length by the length of the auth tag and seq_num*/
    1794           0 :   *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
    1795             :     
    1796           0 :   return err_status_ok;  
    1797             : }
    1798             : 
    1799             : 
    1800             : err_status_t 
    1801           0 : srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) {
    1802           0 :   srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
    1803             :   uint32_t *enc_start;      /* pointer to start of encrypted portion  */
    1804             :   uint32_t *auth_start;     /* pointer to start of auth. portion      */
    1805             :   uint32_t *trailer;        /* pointer to start of trailer            */
    1806           0 :   unsigned enc_octet_len = 0;/* number of octets in encrypted portion */
    1807           0 :   uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */
    1808             :   uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
    1809             :   uint8_t tag_copy[SRTP_MAX_TAG_LEN];
    1810             :   err_status_t status;   
    1811             :   unsigned auth_len;
    1812             :   int tag_len;
    1813             :   srtp_stream_ctx_t *stream;
    1814             :   int prefix_len;
    1815             :   uint32_t seq_num;
    1816             : 
    1817             :   /* we assume the hdr is 32-bit aligned to start */
    1818             :   /*
    1819             :    * look up ssrc in srtp_stream list, and process the packet with 
    1820             :    * the appropriate stream.  if we haven't seen this stream before,
    1821             :    * there's only one key for this srtp_session, and the cipher
    1822             :    * supports key-sharing, then we assume that a new stream using
    1823             :    * that key has just started up
    1824             :    */
    1825           0 :   stream = srtp_get_stream(ctx, hdr->ssrc);
    1826           0 :   if (stream == NULL) {
    1827           0 :     if (ctx->stream_template != NULL) {
    1828           0 :       stream = ctx->stream_template;
    1829             : 
    1830             :       /* 
    1831             :        * check to see if stream_template has an EKT data structure, in
    1832             :        * which case we initialize the template using the EKT policy
    1833             :        * referenced by that data (which consists of decrypting the
    1834             :        * master key from the EKT field)
    1835             :        *
    1836             :        * this function initializes a *provisional* stream, and this
    1837             :        * stream should not be accepted until and unless the packet
    1838             :        * passes its authentication check
    1839             :        */ 
    1840           0 :       if (stream->ekt != NULL) {
    1841           0 :         status = srtp_stream_init_from_ekt(stream, srtcp_hdr, *pkt_octet_len);
    1842           0 :         if (status)
    1843           0 :           return status;
    1844             :       }
    1845             : 
    1846             :       debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)", 
    1847             :                   hdr->ssrc);
    1848             :     } else {
    1849             :       /* no template stream, so we return an error */
    1850           0 :       return err_status_no_ctx;
    1851             :     } 
    1852             :   }
    1853             :   
    1854             :   /* get tag length from stream context */
    1855           0 :   tag_len = auth_get_tag_length(stream->rtcp_auth); 
    1856             : 
    1857             :   /*
    1858             :    * set encryption start, encryption length, and trailer
    1859             :    */
    1860           0 :   enc_octet_len = *pkt_octet_len - 
    1861             :                   (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t));
    1862             :   /* index & E (encryption) bit follow normal data.  hdr->len
    1863             :          is the number of words (32-bit) in the normal packet minus 1 */
    1864             :   /* This should point trailer to the word past the end of the
    1865             :          normal data. */
    1866             :   /* This would need to be modified for optional mikey data */
    1867             :   /*
    1868             :    * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
    1869             :    *     multiples of 32-bits (RFC 3550 6.1)
    1870             :    */
    1871           0 :   trailer = (uint32_t *) ((char *) hdr +
    1872           0 :                      *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t)));
    1873           0 :   if (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) {
    1874           0 :     enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;  
    1875             :   } else {
    1876           0 :     enc_octet_len = 0;
    1877           0 :     enc_start = NULL; /* this indicates that there's no encryption */
    1878             :   }
    1879             : 
    1880             :   /* 
    1881             :    * set the auth_start and auth_tag pointers to the proper locations
    1882             :    * (note that srtcp *always* uses authentication, unlike srtp)
    1883             :    */
    1884           0 :   auth_start = (uint32_t *)hdr;
    1885           0 :   auth_len = *pkt_octet_len - tag_len;
    1886           0 :   auth_tag = (uint8_t *)hdr + auth_len;
    1887             : 
    1888             :   /* 
    1889             :    * if EKT is in use, then we make a copy of the tag from the packet,
    1890             :    * and then zeroize the location of the base tag
    1891             :    *
    1892             :    * we first re-position the auth_tag pointer so that it points to
    1893             :    * the base tag
    1894             :    */
    1895           0 :   if (stream->ekt) {
    1896           0 :     auth_tag -= ekt_octets_after_base_tag(stream->ekt);
    1897           0 :     memcpy(tag_copy, auth_tag, tag_len);
    1898           0 :     octet_string_set_to_zero(auth_tag, tag_len);
    1899           0 :     auth_tag = tag_copy;
    1900           0 :     auth_len += tag_len;
    1901             :   }
    1902             : 
    1903             :   /* 
    1904             :    * check the sequence number for replays
    1905             :    */
    1906             :   /* this is easier than dealing with bitfield access */
    1907           0 :   seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
    1908             :   debug_print(mod_srtp, "srtcp index: %x", seq_num);
    1909           0 :   status = rdb_check(&stream->rtcp_rdb, seq_num);
    1910           0 :   if (status)
    1911           0 :     return status;
    1912             : 
    1913             :   /* 
    1914             :    * if we're using aes counter mode, set nonce and seq 
    1915             :    */
    1916           0 :   if (stream->rtcp_cipher->type->id == AES_ICM) {
    1917             :     v128_t iv;
    1918             : 
    1919           0 :     iv.v32[0] = 0;
    1920           0 :     iv.v32[1] = hdr->ssrc; /* still in network order! */
    1921           0 :     iv.v32[2] = htonl(seq_num >> 16);
    1922           0 :     iv.v32[3] = htonl(seq_num << 16);
    1923           0 :     status = cipher_set_iv(stream->rtcp_cipher, &iv);
    1924             : 
    1925             :   } else {  
    1926             :     v128_t iv;
    1927             :     
    1928             :     /* otherwise, just set the index to seq_num */  
    1929           0 :     iv.v32[0] = 0;
    1930           0 :     iv.v32[1] = 0;
    1931           0 :     iv.v32[2] = 0;
    1932           0 :     iv.v32[3] = htonl(seq_num);
    1933           0 :     status = cipher_set_iv(stream->rtcp_cipher, &iv);
    1934             : 
    1935             :   }
    1936           0 :   if (status)
    1937           0 :     return err_status_cipher_fail;
    1938             : 
    1939             :   /* initialize auth func context */
    1940           0 :   auth_start(stream->rtcp_auth);
    1941             : 
    1942             :   /* run auth func over packet, put result into tmp_tag */
    1943           0 :   status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start,  
    1944             :                         auth_len, tmp_tag);
    1945             :   debug_print(mod_srtp, "srtcp computed tag:       %s", 
    1946             :               octet_string_hex_string(tmp_tag, tag_len));
    1947           0 :   if (status)
    1948           0 :     return err_status_auth_fail;   
    1949             :   
    1950             :   /* compare the tag just computed with the one in the packet */
    1951             :   debug_print(mod_srtp, "srtcp tag from packet:    %s", 
    1952             :               octet_string_hex_string(auth_tag, tag_len));  
    1953           0 :   if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
    1954           0 :     return err_status_auth_fail;
    1955             : 
    1956             :   /* 
    1957             :    * if we're authenticating using a universal hash, put the keystream
    1958             :    * prefix into the authentication tag
    1959             :    */
    1960           0 :   prefix_len = auth_get_prefix_length(stream->rtcp_auth);    
    1961           0 :   if (prefix_len) {
    1962           0 :     status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
    1963             :     debug_print(mod_srtp, "keystream prefix: %s", 
    1964             :                 octet_string_hex_string(auth_tag, prefix_len));
    1965           0 :     if (status)
    1966           0 :       return err_status_cipher_fail;
    1967             :   }
    1968             : 
    1969             :   /* if we're decrypting, exor keystream into the message */
    1970           0 :   if (enc_start) {
    1971           0 :     status = cipher_decrypt(stream->rtcp_cipher, 
    1972             :                             (uint8_t *)enc_start, &enc_octet_len);
    1973           0 :     if (status)
    1974           0 :       return err_status_cipher_fail;
    1975             :   }
    1976             : 
    1977             :   /* decrease the packet length by the length of the auth tag and seq_num */
    1978           0 :   *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
    1979             : 
    1980             :   /*
    1981             :    * if EKT is in effect, subtract the EKT data out of the packet
    1982             :    * length
    1983             :    */
    1984           0 :   *pkt_octet_len -= ekt_octets_after_base_tag(stream->ekt);
    1985             : 
    1986             :   /* 
    1987             :    * verify that stream is for received traffic - this check will
    1988             :    * detect SSRC collisions, since a stream that appears in both
    1989             :    * srtp_protect() and srtp_unprotect() will fail this test in one of
    1990             :    * those functions.
    1991             :    *
    1992             :    * we do this check *after* the authentication check, so that the
    1993             :    * latter check will catch any attempts to fool us into thinking
    1994             :    * that we've got a collision
    1995             :    */
    1996           0 :   if (stream->direction != dir_srtp_receiver) {
    1997           0 :     if (stream->direction == dir_unknown) {
    1998           0 :       stream->direction = dir_srtp_receiver;
    1999             :     } else {
    2000           0 :       srtp_handle_event(ctx, stream, event_ssrc_collision);
    2001             :     }
    2002             :   }
    2003             : 
    2004             :   /* 
    2005             :    * if the stream is a 'provisional' one, in which the template context
    2006             :    * is used, then we need to allocate a new stream at this point, since
    2007             :    * the authentication passed
    2008             :    */
    2009           0 :   if (stream == ctx->stream_template) {  
    2010             :     srtp_stream_ctx_t *new_stream;
    2011             : 
    2012             :     /* 
    2013             :      * allocate and initialize a new stream 
    2014             :      * 
    2015             :      * note that we indicate failure if we can't allocate the new
    2016             :      * stream, and some implementations will want to not return
    2017             :      * failure here
    2018             :      */
    2019           0 :     status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); 
    2020           0 :     if (status)
    2021           0 :       return status;
    2022             :     
    2023             :     /* add new stream to the head of the stream_list */
    2024           0 :     new_stream->next = ctx->stream_list;
    2025           0 :     ctx->stream_list = new_stream;
    2026             :     
    2027             :     /* set stream (the pointer used in this function) */
    2028           0 :     stream = new_stream;
    2029             :   }
    2030             : 
    2031             :   /* we've passed the authentication check, so add seq_num to the rdb */
    2032           0 :   rdb_add_index(&stream->rtcp_rdb, seq_num);
    2033             :     
    2034             :     
    2035           0 :   return err_status_ok;  
    2036             : }
    2037             : 
    2038             : 
    2039             : 
    2040             : /*
    2041             :  * dtls keying for srtp 
    2042             :  */
    2043             : 
    2044             : err_status_t
    2045           0 : crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy, 
    2046             :                                        srtp_profile_t profile) {
    2047             : 
    2048             :   /* set SRTP policy from the SRTP profile in the key set */
    2049           0 :   switch(profile) {
    2050             :   case srtp_profile_aes128_cm_sha1_80:
    2051           0 :     crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
    2052           0 :     crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
    2053           0 :     break;
    2054             :   case srtp_profile_aes128_cm_sha1_32:
    2055           0 :     crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);
    2056           0 :     crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
    2057           0 :     break;
    2058             :   case srtp_profile_null_sha1_80:
    2059           0 :     crypto_policy_set_null_cipher_hmac_sha1_80(policy);
    2060           0 :     crypto_policy_set_null_cipher_hmac_sha1_80(policy);
    2061           0 :     break;
    2062             :   case srtp_profile_aes256_cm_sha1_80:
    2063           0 :     crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
    2064           0 :     crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
    2065           0 :     break;
    2066             :   case srtp_profile_aes256_cm_sha1_32:
    2067           0 :     crypto_policy_set_aes_cm_256_hmac_sha1_32(policy);
    2068           0 :     crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
    2069           0 :     break;
    2070             :     /* the following profiles are not (yet) supported */
    2071             :   case srtp_profile_null_sha1_32:
    2072             :   default:
    2073           0 :     return err_status_bad_param;
    2074             :   }
    2075             : 
    2076           0 :   return err_status_ok;
    2077             : }
    2078             : 
    2079             : err_status_t
    2080           0 : crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy, 
    2081             :                                         srtp_profile_t profile) {
    2082             : 
    2083             :   /* set SRTP policy from the SRTP profile in the key set */
    2084           0 :   switch(profile) {
    2085             :   case srtp_profile_aes128_cm_sha1_80:
    2086           0 :     crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
    2087           0 :     break;
    2088             :   case srtp_profile_aes128_cm_sha1_32:
    2089           0 :     crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
    2090           0 :     break;
    2091             :   case srtp_profile_null_sha1_80:
    2092           0 :     crypto_policy_set_null_cipher_hmac_sha1_80(policy);
    2093           0 :     break;
    2094             :   case srtp_profile_aes256_cm_sha1_80:
    2095           0 :     crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
    2096           0 :     break;
    2097             :   case srtp_profile_aes256_cm_sha1_32:
    2098           0 :     crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
    2099           0 :     break;
    2100             :     /* the following profiles are not (yet) supported */
    2101             :   case srtp_profile_null_sha1_32:
    2102             :   default:
    2103           0 :     return err_status_bad_param;
    2104             :   }
    2105             : 
    2106           0 :   return err_status_ok;
    2107             : }
    2108             : 
    2109             : void
    2110           0 : append_salt_to_key(uint8_t *key, unsigned int bytes_in_key,
    2111             :                    uint8_t *salt, unsigned int bytes_in_salt) {
    2112             : 
    2113           0 :   memcpy(key + bytes_in_key, salt, bytes_in_salt);
    2114             : 
    2115           0 : }
    2116             : 
    2117             : unsigned int
    2118           0 : srtp_profile_get_master_key_length(srtp_profile_t profile) {
    2119             : 
    2120           0 :   switch(profile) {
    2121             :   case srtp_profile_aes128_cm_sha1_80:
    2122           0 :     return 16;
    2123             :     break;
    2124             :   case srtp_profile_aes128_cm_sha1_32:
    2125           0 :     return 16;
    2126             :     break;
    2127             :   case srtp_profile_null_sha1_80:
    2128           0 :     return 16;
    2129             :     break;
    2130             :   case srtp_profile_aes256_cm_sha1_80:
    2131           0 :     return 32;
    2132             :     break;
    2133             :   case srtp_profile_aes256_cm_sha1_32:
    2134           0 :     return 32;
    2135             :     break;
    2136             :     /* the following profiles are not (yet) supported */
    2137             :   case srtp_profile_null_sha1_32:
    2138             :   default:
    2139           0 :     return 0;  /* indicate error by returning a zero */
    2140             :   }
    2141             : }
    2142             : 
    2143             : unsigned int
    2144           0 : srtp_profile_get_master_salt_length(srtp_profile_t profile) {
    2145             : 
    2146           0 :   switch(profile) {
    2147             :   case srtp_profile_aes128_cm_sha1_80:
    2148           0 :     return 14;
    2149             :     break;
    2150             :   case srtp_profile_aes128_cm_sha1_32:
    2151           0 :     return 14;
    2152             :     break;
    2153             :   case srtp_profile_null_sha1_80:
    2154           0 :     return 14;
    2155             :     break;
    2156             :   case srtp_profile_aes256_cm_sha1_80:
    2157           0 :     return 14;
    2158             :     break;
    2159             :   case srtp_profile_aes256_cm_sha1_32:
    2160           0 :     return 14;
    2161             :     break;
    2162             :     /* the following profiles are not (yet) supported */
    2163             :   case srtp_profile_null_sha1_32:
    2164             :   default:
    2165           0 :     return 0;  /* indicate error by returning a zero */
    2166             :   }
    2167             : }

Generated by: LCOV version 1.13