/*
 * srtp.c
 *
 * the secure real-time transport protocol
 *
 * David A. McGrew
 * Cisco Systems, Inc.
 */
/*
 *	
 * Copyright (c) 2001-2006, Cisco Systems, Inc.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 *   Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * 
 *   Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 * 
 *   Neither the name of the Cisco Systems, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "srtp.h"
#include "srtp_priv.h"
#include "crypto_types.h"
#include "err.h"
#include "ekt.h"             /* for SRTP Encrypted Key Transport */
#include "alloc.h"           /* for srtp_crypto_alloc()          */
#ifdef OPENSSL
#include "aes_gcm_ossl.h"    /* for AES GCM mode  */
# ifdef OPENSSL_KDF
# include <openssl/kdf.h>
# include "aes_icm_ossl.h"    /* for AES GCM mode  */
# endif
#endif

#include <limits.h>
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#elif defined(HAVE_WINSOCK2_H)
# include <winsock2.h>
#endif


/* the debug module for srtp */

srtp_debug_module_t mod_srtp = {
  0,                  /* debugging is off by default */
  "srtp"              /* printable name for module   */
};

#define octets_in_rtp_header   12
#define uint32s_in_rtp_header  3
#define octets_in_rtcp_header  8
#define uint32s_in_rtcp_header 2
#define octets_in_rtp_extn_hdr 4

static srtp_err_status_t
srtp_validate_rtp_header(void *rtp_hdr, int *pkt_octet_len) {
  srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;

  /* Check RTP header length */
  int rtp_header_len = octets_in_rtp_header + 4 * hdr->cc;
  if (hdr->x == 1)
    rtp_header_len += octets_in_rtp_extn_hdr;

  if (*pkt_octet_len < rtp_header_len)
    return srtp_err_status_bad_param;

  /* Verifing profile length. */
  if (hdr->x == 1) {
    srtp_hdr_xtnd_t *xtn_hdr =
      (srtp_hdr_xtnd_t *)((uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc);
    int profile_len = ntohs(xtn_hdr->length);
    rtp_header_len += profile_len * 4;
    /* profile length counts the number of 32-bit words */
    if (*pkt_octet_len < rtp_header_len)
      return srtp_err_status_bad_param;
  }
  return srtp_err_status_ok;
}

const char *srtp_get_version_string ()
{
    /*
     * Simply return the autotools generated string
     */
    return SRTP_VER_STRING;
}

unsigned int srtp_get_version ()
{
    unsigned int major = 0, minor = 0, micro = 0;
    unsigned int rv = 0;
    int parse_rv;

    /*
     * Parse the autotools generated version 
     */
    parse_rv = sscanf(SRTP_VERSION, "%u.%u.%u", &major, &minor, &micro);
    if (parse_rv != 3) {
	/*
	 * We're expected to parse all 3 version levels.
	 * If not, then this must not be an official release.
	 * Return all zeros on the version
	 */
	return (0);
    }

    /* 
     * We allow 8 bits for the major and minor, while
     * allowing 16 bits for the micro.  16 bits for the micro
     * may be beneficial for a continuous delivery model 
     * in the future.
     */
    rv |= (major & 0xFF) << 24;
    rv |= (minor & 0xFF) << 16;
    rv |= micro & 0xFF;
    return rv;
}

/* Release (maybe partially allocated) stream. */
static void
srtp_stream_free(srtp_stream_ctx_t *str) {
  if (str->rtp_xtn_hdr_cipher) {
    srtp_cipher_dealloc(str->rtp_xtn_hdr_cipher);
  }
  if (str->enc_xtn_hdr) {
    srtp_crypto_free(str->enc_xtn_hdr);
  }
  if (str->rtcp_auth) {
    auth_dealloc(str->rtcp_auth);
  }
  if (str->rtcp_cipher) {
    srtp_cipher_dealloc(str->rtcp_cipher);
  }
  if (str->limit) {
    srtp_crypto_free(str->limit);
  }
  if (str->rtp_auth) {
    auth_dealloc(str->rtp_auth);
  }
  if (str->rtp_cipher) {
    srtp_cipher_dealloc(str->rtp_cipher);
  }
  srtp_crypto_free(str);
}

srtp_err_status_t
srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
		  const srtp_policy_t *p) {
  srtp_stream_ctx_t *str;
  srtp_err_status_t stat;

  /*
   * This function allocates the stream context, rtp and rtcp ciphers
   * and auth functions, and key limit structure.  If there is a
   * failure during allocation, we free all previously allocated
   * memory and return a failure code.  The code could probably 
   * be improved, but it works and should be clear.
   */

  /* allocate srtp stream and set str_ptr */
  str = (srtp_stream_ctx_t *) srtp_crypto_alloc(sizeof(srtp_stream_ctx_t));
  if (str == NULL)
    return srtp_err_status_alloc_fail;

  memset(str, 0, sizeof(srtp_stream_ctx_t));
  *str_ptr = str;

  /* allocate cipher */
  stat = srtp_crypto_kernel_alloc_cipher(p->rtp.cipher_type, 
				    &str->rtp_cipher, 
				    p->rtp.cipher_key_len,
				    p->rtp.auth_tag_len); 
  if (stat) {
    srtp_stream_free(str);
    return stat;
  }

  /* allocate auth function */
  stat = srtp_crypto_kernel_alloc_auth(p->rtp.auth_type, 
				  &str->rtp_auth,
				  p->rtp.auth_key_len, 
				  p->rtp.auth_tag_len); 
  if (stat) {
    srtp_stream_free(str);
    return stat;
  }
  
  /* allocate key limit structure */
  str->limit = (srtp_key_limit_ctx_t*) srtp_crypto_alloc(sizeof(srtp_key_limit_ctx_t));
  if (str->limit == NULL) {
    srtp_stream_free(str);
    return srtp_err_status_alloc_fail;
  }

  /*
   * ...and now the RTCP-specific initialization - first, allocate
   * the cipher 
   */
  stat = srtp_crypto_kernel_alloc_cipher(p->rtcp.cipher_type, 
				    &str->rtcp_cipher, 
				    p->rtcp.cipher_key_len, 
				    p->rtcp.auth_tag_len); 
  if (stat) {
    srtp_stream_free(str);
    return stat;
  }

  /* allocate auth function */
  stat = srtp_crypto_kernel_alloc_auth(p->rtcp.auth_type, 
				  &str->rtcp_auth,
				  p->rtcp.auth_key_len, 
				  p->rtcp.auth_tag_len); 
  if (stat) {
    srtp_stream_free(str);
    return stat;
  }  

  /* allocate ekt data associated with stream */
  stat = srtp_ekt_alloc(&str->ekt, p->ekt);
  if (stat) {
    srtp_stream_free(str);
    return stat;
  }

  if (p->enc_xtn_hdr && p->enc_xtn_hdr_count > 0) {
    srtp_cipher_type_id_t enc_xtn_hdr_cipher_type;
    int enc_xtn_hdr_cipher_key_len;

    str->enc_xtn_hdr = (int*) srtp_crypto_alloc(p->enc_xtn_hdr_count * sizeof(p->enc_xtn_hdr[0]));
    if (!str->enc_xtn_hdr) {
      srtp_stream_free(str);
      return srtp_err_status_alloc_fail;
    }
    memcpy(str->enc_xtn_hdr, p->enc_xtn_hdr, p->enc_xtn_hdr_count * sizeof(p->enc_xtn_hdr[0]));
    str->enc_xtn_hdr_count = p->enc_xtn_hdr_count;

    /* For GCM ciphers, the corresponding ICM cipher is used for header extensions encryption. */
    switch (p->rtp.cipher_type) {
    case SRTP_AES_128_GCM:
      enc_xtn_hdr_cipher_type = SRTP_AES_128_ICM;
      enc_xtn_hdr_cipher_key_len = 30;
      break;
    case SRTP_AES_256_GCM:
      enc_xtn_hdr_cipher_type = SRTP_AES_256_ICM;
      enc_xtn_hdr_cipher_key_len = 46;
      break;
    default:
      enc_xtn_hdr_cipher_type = p->rtp.cipher_type;
      enc_xtn_hdr_cipher_key_len = p->rtp.cipher_key_len;
      break;
    }

    /* allocate cipher for extensions header encryption */
    stat = srtp_crypto_kernel_alloc_cipher(enc_xtn_hdr_cipher_type,
              &str->rtp_xtn_hdr_cipher,
              enc_xtn_hdr_cipher_key_len,
              0);
    if (stat) {
      srtp_stream_free(str);
      return stat;
    }
  } else {
    str->rtp_xtn_hdr_cipher = NULL;
    str->enc_xtn_hdr = NULL;
    str->enc_xtn_hdr_count = 0;
  }

  return srtp_err_status_ok;
}

srtp_err_status_t
srtp_stream_dealloc(srtp_stream_ctx_t *stream, srtp_stream_ctx_t *stream_template) {
  srtp_err_status_t status;
  
  /*
   * we use a conservative deallocation strategy - if any deallocation
   * fails, then we report that fact without trying to deallocate
   * anything else
   */

  /* deallocate cipher, if it is not the same as that in template */
  if (stream_template
      && stream->rtp_cipher == stream_template->rtp_cipher) {
    /* do nothing */
  } else {
    status = srtp_cipher_dealloc(stream->rtp_cipher); 
    if (status) 
      return status;
  }

  /* deallocate auth function, if it is not the same as that in template */
  if (stream_template
      && stream->rtp_auth == stream_template->rtp_auth) {
    /* do nothing */
  } else {
    status = auth_dealloc(stream->rtp_auth);
    if (status)
      return status;
  }

  /* deallocate key usage limit, if it is not the same as that in template */
  if (stream_template
      && stream->limit == stream_template->limit) {
    /* do nothing */
  } else {
    srtp_crypto_free(stream->limit);
  }   

  if (stream_template
      && stream->rtp_xtn_hdr_cipher == stream_template->rtp_xtn_hdr_cipher) {
    /* do nothing */
  } else if (stream->rtp_xtn_hdr_cipher) {
    status = srtp_cipher_dealloc(stream->rtp_xtn_hdr_cipher);
    if (status)
      return status;
  }

  /* 
   * deallocate rtcp cipher, if it is not the same as that in
   * template 
   */
  if (stream_template
      && stream->rtcp_cipher == stream_template->rtcp_cipher) {
    /* do nothing */
  } else {
    status = srtp_cipher_dealloc(stream->rtcp_cipher); 
    if (status) 
      return status;
  }

  /*
   * deallocate rtcp auth function, if it is not the same as that in
   * template 
   */
  if (stream_template
      && stream->rtcp_auth == stream_template->rtcp_auth) {
    /* do nothing */
  } else {
    status = auth_dealloc(stream->rtcp_auth);
    if (status)
      return status;
  }

  status = srtp_rdbx_dealloc(&stream->rtp_rdbx);
  if (status)
    return status;

  /* DAM - need to deallocate EKT here */

  if (stream_template
      && stream->enc_xtn_hdr == stream_template->enc_xtn_hdr) {
    /* do nothing */
  } else if (stream->enc_xtn_hdr) {
    srtp_crypto_free(stream->enc_xtn_hdr);
  }

  /*
   * zeroize the salt value
   */
  memset(stream->salt, 0, SRTP_AEAD_SALT_LEN);
  memset(stream->c_salt, 0, SRTP_AEAD_SALT_LEN);

  
  /* deallocate srtp stream context */
  srtp_crypto_free(stream);

  return srtp_err_status_ok;
}


/*
 * srtp_stream_clone(stream_template, new) allocates a new stream and
 * initializes it using the cipher and auth of the stream_template
 * 
 * the only unique data in a cloned stream is the replay database and
 * the SSRC
 */

srtp_err_status_t
srtp_stream_clone(const srtp_stream_ctx_t *stream_template, 
		  uint32_t ssrc, 
		  srtp_stream_ctx_t **str_ptr) {
  srtp_err_status_t status;
  srtp_stream_ctx_t *str;

  debug_print(mod_srtp, "cloning stream (SSRC: 0x%08x)", ssrc);

  /* allocate srtp stream and set str_ptr */
  str = (srtp_stream_ctx_t *) srtp_crypto_alloc(sizeof(srtp_stream_ctx_t));
  if (str == NULL)
    return srtp_err_status_alloc_fail;
  *str_ptr = str;  

  /* set cipher and auth pointers to those of the template */
  str->rtp_cipher  = stream_template->rtp_cipher;
  str->rtp_auth    = stream_template->rtp_auth;
  str->rtp_xtn_hdr_cipher = stream_template->rtp_xtn_hdr_cipher;
  str->rtcp_cipher = stream_template->rtcp_cipher;
  str->rtcp_auth   = stream_template->rtcp_auth;

  /* set key limit to point to that of the template */
  status = srtp_key_limit_clone(stream_template->limit, &str->limit);
  if (status) { 
    srtp_crypto_free(*str_ptr);
    *str_ptr = NULL;
    return status;
  }

  /* initialize replay databases */
  status = srtp_rdbx_init(&str->rtp_rdbx,
		     srtp_rdbx_get_window_size(&stream_template->rtp_rdbx));
  if (status) {
    srtp_crypto_free(*str_ptr);
    *str_ptr = NULL;
    return status;
  }
  srtp_rdb_init(&str->rtcp_rdb);
  str->allow_repeat_tx = stream_template->allow_repeat_tx;
  
  /* set ssrc to that provided */
  str->ssrc = ssrc;

  /* set direction and security services */
  str->direction     = stream_template->direction;
  str->rtp_services  = stream_template->rtp_services;
  str->rtcp_services = stream_template->rtcp_services;

  /* set pointer to EKT data associated with stream */
  str->ekt = stream_template->ekt;

  /* Copy the salt values */
  memcpy(str->salt, stream_template->salt, SRTP_AEAD_SALT_LEN);
  memcpy(str->c_salt, stream_template->c_salt, SRTP_AEAD_SALT_LEN);

  /* copy information about extensions header encryption */
  str->enc_xtn_hdr = stream_template->enc_xtn_hdr;
  str->enc_xtn_hdr_count = stream_template->enc_xtn_hdr_count;

  /* defensive coding */
  str->next = NULL;

  return srtp_err_status_ok;
}


/*
 * key derivation functions, internal to libSRTP
 *
 * srtp_kdf_t is a key derivation context
 *
 * srtp_kdf_init(&kdf, cipher_id, k, keylen) initializes kdf to use cipher
 * described by cipher_id, with the master key k with length in octets keylen.
 * 
 * srtp_kdf_generate(&kdf, l, kl, keylen) derives the key
 * corresponding to label l and puts it into kl; the length
 * of the key in octets is provided as keylen.  this function
 * should be called once for each subkey that is derived.
 *
 * srtp_kdf_clear(&kdf) zeroizes and deallocates the kdf state
 */

typedef enum {
  label_rtp_encryption  = 0x00,
  label_rtp_msg_auth    = 0x01,
  label_rtp_salt        = 0x02,
  label_rtcp_encryption = 0x03,
  label_rtcp_msg_auth   = 0x04,
  label_rtcp_salt       = 0x05,
  label_rtp_header_encryption = 0x06,
  label_rtp_header_salt = 0x07
} srtp_prf_label;

#define MAX_SRTP_KEY_LEN 256

#if defined(OPENSSL) && defined(OPENSSL_KDF)
#define MAX_SRTP_AESKEY_LEN 32
#define MAX_SRTP_SALT_LEN 14 

/*
 * srtp_kdf_t represents a key derivation function.  The SRTP
 * default KDF is the only one implemented at present.
 */
typedef struct { 
    uint8_t master_key[MAX_SRTP_AESKEY_LEN];
    uint8_t master_salt[MAX_SRTP_SALT_LEN];
    const EVP_CIPHER *evp;
} srtp_kdf_t;


static srtp_err_status_t srtp_kdf_init(srtp_kdf_t *kdf, const uint8_t *key, int key_len, int salt_len) 
{
    memset(kdf, 0x0, sizeof(srtp_kdf_t));

    /* The NULL cipher has zero key length */
    if (key_len == 0) return srtp_err_status_ok;

    if ((key_len > MAX_SRTP_AESKEY_LEN) || (salt_len > MAX_SRTP_SALT_LEN)) {
        return srtp_err_status_bad_param;
    }
    switch (key_len) {
    case SRTP_AES_256_KEYSIZE:
        kdf->evp = EVP_aes_256_ctr();
        break;
    case SRTP_AES_192_KEYSIZE:
        kdf->evp = EVP_aes_192_ctr();
        break;
    case SRTP_AES_128_KEYSIZE:
        kdf->evp = EVP_aes_128_ctr();
        break;
    default:
        return srtp_err_status_bad_param;
        break;
    }
    memcpy(kdf->master_key, key, key_len); 
    memcpy(kdf->master_salt, key+key_len, salt_len); 
    return srtp_err_status_ok;
}

static srtp_err_status_t srtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label, uint8_t *key, unsigned int length) 
{
    int ret;

    /* The NULL cipher will not have an EVP */
    if (!kdf->evp) return srtp_err_status_ok;

    octet_string_set_to_zero(key, length);

    /*
     * Invoke the OpenSSL SRTP KDF function
     * This is useful if OpenSSL is in FIPS mode and FIP
     * compliance is required for SRTP.
     */
    ret = kdf_srtp(kdf->evp, (char *)&kdf->master_key, (char *)&kdf->master_salt, NULL, NULL, label, (char *)key);
    if (ret == -1) {
        return (srtp_err_status_algo_fail);
    }

    return srtp_err_status_ok;
}

static srtp_err_status_t srtp_kdf_clear(srtp_kdf_t *kdf) {
    memset(kdf->master_key, 0x0, MAX_SRTP_AESKEY_LEN);
    memset(kdf->master_salt, 0x0, MAX_SRTP_SALT_LEN);
    kdf->evp = NULL;

    return srtp_err_status_ok;  
}

#else /* if OPENSSL_KDF */

/*
 * srtp_kdf_t represents a key derivation function.  The SRTP
 * default KDF is the only one implemented at present.
 */
typedef struct { 
    srtp_cipher_t *cipher;    /* cipher used for key derivation  */  
} srtp_kdf_t;

static srtp_err_status_t srtp_kdf_init(srtp_kdf_t *kdf, srtp_cipher_type_id_t cipher_id, const uint8_t *key, int length) 
{
    srtp_err_status_t stat;
    stat = srtp_crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, length, 0);
    if (stat) return stat;

    stat = srtp_cipher_init(kdf->cipher, key);
    if (stat) {
        srtp_cipher_dealloc(kdf->cipher);
        return stat;
    }
    return srtp_err_status_ok;
}

static srtp_err_status_t srtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label, uint8_t *key, unsigned int length) 
{
    srtp_err_status_t status;
    v128_t nonce;
  
    /* set eigth octet of nonce to <label>, set the rest of it to zero */
    v128_set_to_zero(&nonce);
    nonce.v8[7] = label;
 
    status = srtp_cipher_set_iv(kdf->cipher, (uint8_t*)&nonce, direction_encrypt);
    if (status) return status;
  
    /* generate keystream output */
    octet_string_set_to_zero(key, length);
    status = srtp_cipher_encrypt(kdf->cipher, key, &length);
    if (status) return status;

    return srtp_err_status_ok;
}

static srtp_err_status_t srtp_kdf_clear(srtp_kdf_t *kdf) {
    srtp_err_status_t status;
    status = srtp_cipher_dealloc(kdf->cipher);
    if (status) return status;
    kdf->cipher = NULL;
    return srtp_err_status_ok;  
}
#endif /* else OPENSSL_KDF */

/*
 *  end of key derivation functions 
 */



/* Get the base key length corresponding to a given combined key+salt
 * length for the given cipher.
 * Assumption is that for AES-ICM a key length < 30 is Ismacryp using
 * AES-128 and short salts; everything else uses a salt length of 14.
 * TODO: key and salt lengths should be separate fields in the policy.  */
static inline int base_key_length(const srtp_cipher_type_t *cipher, int key_length)
{
  switch (cipher->id) {
  case SRTP_AES_128_ICM:
  case SRTP_AES_192_ICM:
  case SRTP_AES_256_ICM:
    /* The legacy modes are derived from
     * the configured key length on the policy */
    return key_length - 14;
    break;
  case SRTP_AES_128_GCM:
    return 16;
    break;
  case SRTP_AES_256_GCM:
    return 32;
    break;
  default:
    return key_length;
    break;
  }
}

srtp_err_status_t
srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) {
  srtp_err_status_t stat;
  srtp_kdf_t kdf;
  uint8_t tmp_key[MAX_SRTP_KEY_LEN];
  int kdf_keylen = 30, rtp_keylen, rtcp_keylen;
  int rtp_base_key_len, rtp_salt_len;
  int rtcp_base_key_len, rtcp_salt_len;

  /* If RTP or RTCP have a key length > AES-128, assume matching kdf. */
  /* TODO: kdf algorithm, master key length, and master salt length should
   * be part of srtp_policy_t. */
  rtp_keylen = srtp_cipher_get_key_length(srtp->rtp_cipher);
  rtcp_keylen = srtp_cipher_get_key_length(srtp->rtcp_cipher);
  rtp_base_key_len = base_key_length(srtp->rtp_cipher->type, rtp_keylen);
  rtp_salt_len = rtp_keylen - rtp_base_key_len;

  if (rtp_keylen > kdf_keylen) {
    kdf_keylen = 46;  /* AES-CTR mode is always used for KDF */
  }

  if (rtcp_keylen > kdf_keylen) {
    kdf_keylen = 46;  /* AES-CTR mode is always used for KDF */
  }

  debug_print(mod_srtp, "srtp key len: %d", rtp_keylen);
  debug_print(mod_srtp, "srtcp key len: %d", rtcp_keylen);
  debug_print(mod_srtp, "base key len: %d", rtp_base_key_len);
  debug_print(mod_srtp, "kdf key len: %d", kdf_keylen);
  debug_print(mod_srtp, "rtp salt len: %d", rtp_salt_len);

  /* 
   * Make sure the key given to us is 'zero' appended.  GCM
   * mode uses a shorter master SALT (96 bits), but still relies on 
   * the legacy CTR mode KDF, which uses a 112 bit master SALT.
   */
  memset(tmp_key, 0x0, MAX_SRTP_KEY_LEN);
  memcpy(tmp_key, key, (rtp_base_key_len + rtp_salt_len));

  /* initialize KDF state     */
#if defined(OPENSSL) && defined(OPENSSL_KDF)
  stat = srtp_kdf_init(&kdf, (const uint8_t *)tmp_key, rtp_base_key_len, rtp_salt_len); 
#else
  stat = srtp_kdf_init(&kdf, SRTP_AES_ICM, (const uint8_t *)tmp_key, kdf_keylen);
#endif
  if (stat) {
    return srtp_err_status_init_fail;
  }
  
  /* generate encryption key  */
  stat = srtp_kdf_generate(&kdf, label_rtp_encryption, 
			   tmp_key, rtp_base_key_len);
  if (stat) {
    /* zeroize temp buffer */
    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
    return srtp_err_status_init_fail;
  }
  debug_print(mod_srtp, "cipher key: %s", 
	      srtp_octet_string_hex_string(tmp_key, rtp_base_key_len));

  /* 
   * if the cipher in the srtp context uses a salt, then we need
   * to generate the salt value
   */
  if (rtp_salt_len > 0) {
    debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL);

    /* generate encryption salt, put after encryption key */
    stat = srtp_kdf_generate(&kdf, label_rtp_salt, 
			     tmp_key + rtp_base_key_len, rtp_salt_len);
    if (stat) {
      /* zeroize temp buffer */
      octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
      return srtp_err_status_init_fail;
    }
    memcpy(srtp->salt, tmp_key + rtp_base_key_len, SRTP_AEAD_SALT_LEN);
  }
  if (rtp_salt_len > 0) {
    debug_print(mod_srtp, "cipher salt: %s",
		srtp_octet_string_hex_string(tmp_key + rtp_base_key_len, rtp_salt_len));
  }

  /* initialize cipher */
  stat = srtp_cipher_init(srtp->rtp_cipher, tmp_key);
  if (stat) {
    /* zeroize temp buffer */
    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
    return srtp_err_status_init_fail;
  }

  if (srtp->rtp_xtn_hdr_cipher) {
    /* generate extensions header encryption key  */
    int rtp_xtn_hdr_keylen;
    int rtp_xtn_hdr_base_key_len;
    int rtp_xtn_hdr_salt_len;
    srtp_kdf_t tmp_kdf;
    srtp_kdf_t *xtn_hdr_kdf;

    if (srtp->rtp_xtn_hdr_cipher->type != srtp->rtp_cipher->type) {
      /* With GCM ciphers, the header extensions are still encrypted using the corresponding ICM cipher. */
      /* See https://tools.ietf.org/html/draft-ietf-avtcore-srtp-aes-gcm-17#section-8.3 */
      uint8_t tmp_xtn_hdr_key[MAX_SRTP_KEY_LEN];
      rtp_xtn_hdr_keylen = srtp_cipher_get_key_length(srtp->rtp_xtn_hdr_cipher);
      rtp_xtn_hdr_base_key_len = base_key_length(srtp->rtp_xtn_hdr_cipher->type, rtp_xtn_hdr_keylen);
      rtp_xtn_hdr_salt_len = rtp_xtn_hdr_keylen - rtp_xtn_hdr_base_key_len;
      memset(tmp_xtn_hdr_key, 0x0, MAX_SRTP_KEY_LEN);
      memcpy(tmp_xtn_hdr_key, key, (rtp_xtn_hdr_base_key_len + rtp_xtn_hdr_salt_len));
      xtn_hdr_kdf = &tmp_kdf;

      /* initialize KDF state     */
#if defined(OPENSSL) && defined(OPENSSL_KDF)
      stat = srtp_kdf_init(xtn_hdr_kdf, (const uint8_t *)tmp_xtn_hdr_key, rtp_xtn_hdr_base_key_len, rtp_xtn_hdr_salt_len);
#else
      stat = srtp_kdf_init(xtn_hdr_kdf, SRTP_AES_ICM, (const uint8_t *)tmp_xtn_hdr_key, kdf_keylen);
#endif
      octet_string_set_to_zero(tmp_xtn_hdr_key, MAX_SRTP_KEY_LEN);
      if (stat) {
        return srtp_err_status_init_fail;
      }
    } else {
      /* Reuse main KDF. */
      rtp_xtn_hdr_keylen = rtp_keylen;
      rtp_xtn_hdr_base_key_len = rtp_base_key_len;
      rtp_xtn_hdr_salt_len = rtp_salt_len;
      xtn_hdr_kdf = &kdf;
    }

    stat = srtp_kdf_generate(xtn_hdr_kdf, label_rtp_header_encryption,
           tmp_key, rtp_xtn_hdr_base_key_len);
    if (stat) {
      /* zeroize temp buffer */
      octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
      return srtp_err_status_init_fail;
    }
    debug_print(mod_srtp, "extensions cipher key: %s",
          srtp_octet_string_hex_string(tmp_key, rtp_xtn_hdr_base_key_len));

    /*
     * if the cipher in the srtp context uses a salt, then we need
     * to generate the salt value
     */
    if (rtp_xtn_hdr_salt_len > 0) {
      debug_print(mod_srtp, "found rtp_xtn_hdr_salt_len > 0, generating salt", NULL);

      /* generate encryption salt, put after encryption key */
      stat = srtp_kdf_generate(xtn_hdr_kdf, label_rtp_header_salt,
             tmp_key + rtp_xtn_hdr_base_key_len, rtp_xtn_hdr_salt_len);
      if (stat) {
        /* zeroize temp buffer */
        octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
        return srtp_err_status_init_fail;
      }
    }
    if (rtp_xtn_hdr_salt_len > 0) {
      debug_print(mod_srtp, "extensions cipher salt: %s",
      srtp_octet_string_hex_string(tmp_key + rtp_xtn_hdr_base_key_len, rtp_xtn_hdr_salt_len));
    }

    /* initialize extensions header cipher */
    stat = srtp_cipher_init(srtp->rtp_xtn_hdr_cipher, tmp_key);
    if (stat) {
      /* zeroize temp buffer */
      octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
      return srtp_err_status_init_fail;
    }

    if (xtn_hdr_kdf != &kdf) {
      /* release memory for custom header extension encryption kdf */
      stat = srtp_kdf_clear(xtn_hdr_kdf);
      if (stat) {
        octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
        return srtp_err_status_init_fail;
      }
    }
  }

  /* generate authentication key */
  stat = srtp_kdf_generate(&kdf, label_rtp_msg_auth,
			   tmp_key, srtp_auth_get_key_length(srtp->rtp_auth));
  if (stat) {
    /* zeroize temp buffer */
    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
    return srtp_err_status_init_fail;
  }
  debug_print(mod_srtp, "auth key:   %s",
	      srtp_octet_string_hex_string(tmp_key, 
				      srtp_auth_get_key_length(srtp->rtp_auth))); 

  /* initialize auth function */
  stat = auth_init(srtp->rtp_auth, tmp_key);
  if (stat) {
    /* zeroize temp buffer */
    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
    return srtp_err_status_init_fail;
  }

  /*
   * ...now initialize SRTCP keys
   */

  rtcp_base_key_len = base_key_length(srtp->rtcp_cipher->type, rtcp_keylen);
  rtcp_salt_len = rtcp_keylen - rtcp_base_key_len;
  debug_print(mod_srtp, "rtcp salt len: %d", rtcp_salt_len);
  
  /* generate encryption key  */
  stat = srtp_kdf_generate(&kdf, label_rtcp_encryption, 
			   tmp_key, rtcp_base_key_len);
  if (stat) {
    /* zeroize temp buffer */
    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
    return srtp_err_status_init_fail;
  }

  /* 
   * if the cipher in the srtp context uses a salt, then we need
   * to generate the salt value
   */
  if (rtcp_salt_len > 0) {
    debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt",
		NULL);

    /* generate encryption salt, put after encryption key */
    stat = srtp_kdf_generate(&kdf, label_rtcp_salt, 
			     tmp_key + rtcp_base_key_len, rtcp_salt_len);
    if (stat) {
      /* zeroize temp buffer */
      octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
      return srtp_err_status_init_fail;
    }
    memcpy(srtp->c_salt, tmp_key + rtcp_base_key_len, SRTP_AEAD_SALT_LEN);
  }
  debug_print(mod_srtp, "rtcp cipher key: %s", 
	      srtp_octet_string_hex_string(tmp_key, rtcp_base_key_len));  
  if (rtcp_salt_len > 0) {
    debug_print(mod_srtp, "rtcp cipher salt: %s",
		srtp_octet_string_hex_string(tmp_key + rtcp_base_key_len, rtcp_salt_len));
  }

  /* initialize cipher */
  stat = srtp_cipher_init(srtp->rtcp_cipher, tmp_key);
  if (stat) {
    /* zeroize temp buffer */
    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
    return srtp_err_status_init_fail;
  }

  /* generate authentication key */
  stat = srtp_kdf_generate(&kdf, label_rtcp_msg_auth,
			   tmp_key, srtp_auth_get_key_length(srtp->rtcp_auth));
  if (stat) {
    /* zeroize temp buffer */
    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
    return srtp_err_status_init_fail;
  }

  debug_print(mod_srtp, "rtcp auth key:   %s",
	      srtp_octet_string_hex_string(tmp_key, 
		     srtp_auth_get_key_length(srtp->rtcp_auth))); 

  /* initialize auth function */
  stat = auth_init(srtp->rtcp_auth, tmp_key);
  if (stat) {
    /* zeroize temp buffer */
    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
    return srtp_err_status_init_fail;
  }

  /* clear memory then return */
  stat = srtp_kdf_clear(&kdf);
  octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);  
  if (stat)
    return srtp_err_status_init_fail;

  return srtp_err_status_ok;
}

srtp_err_status_t
srtp_stream_init(srtp_stream_ctx_t *srtp, 
		  const srtp_policy_t *p) {
  srtp_err_status_t err;

   debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)", 
	       p->ssrc.value);

   /* initialize replay database */
   /* window size MUST be at least 64.  MAY be larger.  Values more than
    * 2^15 aren't meaningful due to how extended sequence numbers are
    * calculated.   Let a window size of 0 imply the default value. */

   if (p->window_size != 0 && (p->window_size < 64 || p->window_size >= 0x8000))
     return srtp_err_status_bad_param;

   if (p->window_size != 0)
     err = srtp_rdbx_init(&srtp->rtp_rdbx, p->window_size);
   else
     err = srtp_rdbx_init(&srtp->rtp_rdbx, 128);
   if (err) return err;

   /* initialize key limit to maximum value */
#ifdef NO_64BIT_MATH
{
   uint64_t temp;
   temp = make64(UINT_MAX,UINT_MAX);
   srtp_key_limit_set(srtp->limit, temp);
}
#else
   srtp_key_limit_set(srtp->limit, 0xffffffffffffLL);
#endif

   /* set the SSRC value */
   srtp->ssrc = htonl(p->ssrc.value);

   /* set the security service flags */
   srtp->rtp_services  = p->rtp.sec_serv;
   srtp->rtcp_services = p->rtcp.sec_serv;

   /*
    * set direction to unknown - this flag gets checked in srtp_protect(),
    * srtp_unprotect(), srtp_protect_rtcp(), and srtp_unprotect_rtcp(), and 
    * gets set appropriately if it is set to unknown.
    */
   srtp->direction = dir_unknown;

   /* initialize SRTCP replay database */
   srtp_rdb_init(&srtp->rtcp_rdb);

   /* initialize allow_repeat_tx */
   /* guard against uninitialized memory: allow only 0 or 1 here */
   if (p->allow_repeat_tx != 0 && p->allow_repeat_tx != 1) {
     srtp_rdbx_dealloc(&srtp->rtp_rdbx);
     return srtp_err_status_bad_param;
   }
   srtp->allow_repeat_tx = p->allow_repeat_tx;

   /* DAM - no RTCP key limit at present */

   /* initialize keys */
   err = srtp_stream_init_keys(srtp, p->key);
   if (err) {
     srtp_rdbx_dealloc(&srtp->rtp_rdbx);
     return err;
   }

   /* 
    * if EKT is in use, then initialize the EKT data associated with
    * the stream
    */
   err = srtp_ekt_stream_init_from_policy(srtp->ekt, p->ekt);
   if (err) {
     srtp_rdbx_dealloc(&srtp->rtp_rdbx);
     return err;
   }

   return srtp_err_status_ok;  
 }


 /*
  * srtp_event_reporter is an event handler function that merely
  * reports the events that are reported by the callbacks
  */

 void
 srtp_event_reporter(srtp_event_data_t *data) {

   srtp_err_report(srtp_err_level_warning, "srtp: in stream 0x%x: ", 
	      data->stream->ssrc);

   switch(data->event) {
   case event_ssrc_collision:
     srtp_err_report(srtp_err_level_warning, "\tSSRC collision\n");
     break;
   case event_key_soft_limit:
     srtp_err_report(srtp_err_level_warning, "\tkey usage soft limit reached\n");
     break;
   case event_key_hard_limit:
     srtp_err_report(srtp_err_level_warning, "\tkey usage hard limit reached\n");
     break;
   case event_packet_index_limit:
     srtp_err_report(srtp_err_level_warning, "\tpacket index limit reached\n");
     break;
   default:
     srtp_err_report(srtp_err_level_warning, "\tunknown event reported to handler\n");
   }
 }

 /*
  * srtp_event_handler is a global variable holding a pointer to the
  * event handler function; this function is called for any unexpected
  * event that needs to be handled out of the SRTP data path.  see
  * srtp_event_t in srtp.h for more info
  *
  * it is okay to set srtp_event_handler to NULL, but we set 
  * it to the srtp_event_reporter.
  */

 static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter;

 srtp_err_status_t
 srtp_install_event_handler(srtp_event_handler_func_t func) {

   /* 
    * note that we accept NULL arguments intentionally - calling this
    * function with a NULL arguments removes an event handler that's
    * been previously installed
    */

   /* set global event handling function */
   srtp_event_handler = func;
   return srtp_err_status_ok;
 }


/*
 * Check if the given extension header id is / should be encrypted.
 * Returns 1 if yes, otherwise 0.
 */
static int
srtp_protect_extension_header(srtp_stream_ctx_t *stream, int id) {
  int* enc_xtn_hdr = stream->enc_xtn_hdr;
  int count = stream->enc_xtn_hdr_count;

  if (!enc_xtn_hdr || count <= 0) {
    return 0;
  }

  while (count > 0) {
    if (*enc_xtn_hdr == id) {
      return 1;
    }

    enc_xtn_hdr++;
    count--;
  }
  return 0;
}


/*
 * extensions header encryption RFC 6904
 */
static srtp_err_status_t
srtp_process_header_encryption(srtp_stream_ctx_t *stream, srtp_hdr_xtnd_t *xtn_hdr) {
  srtp_err_status_t status;
  uint8_t keystream[257];  /* Maximum 2 bytes header + 255 bytes data. */
  int keystream_pos;
  uint8_t* xtn_hdr_data = ((uint8_t *)xtn_hdr) + octets_in_rtp_extn_hdr;
  uint8_t* xtn_hdr_end = xtn_hdr_data + (ntohs(xtn_hdr->length) * sizeof(uint32_t));

  if (ntohs(xtn_hdr->profile_specific) == 0xbede) {
    /* RFC 5285, section 4.2. One-Byte Header */
    while (xtn_hdr_data < xtn_hdr_end) {
      uint8_t xid = (*xtn_hdr_data & 0xf0) >> 4;
      unsigned int xlen = (*xtn_hdr_data & 0x0f) + 1;
      uint32_t xlen_with_header = 1+xlen;
      xtn_hdr_data++;

      if (xtn_hdr_data + xlen > xtn_hdr_end)
        return srtp_err_status_parse_err;

      if (xid == 15) {
        /* found header 15, stop further processing. */
        break;
      }

      status = srtp_cipher_output(stream->rtp_xtn_hdr_cipher, keystream, &xlen_with_header);
      if (status)
        return srtp_err_status_cipher_fail;

      if (srtp_protect_extension_header(stream, xid)) {
        keystream_pos = 1;
        while (xlen > 0) {
          *xtn_hdr_data ^= keystream[keystream_pos++];
          xtn_hdr_data++;
          xlen--;
        }
      } else {
        xtn_hdr_data += xlen;
      }

      /* skip padding bytes. */
      while (xtn_hdr_data < xtn_hdr_end && *xtn_hdr_data == 0) {
        xtn_hdr_data++;
      }
    }
  } else if ((ntohs(xtn_hdr->profile_specific) & 0x1fff) == 0x100) {
    /* RFC 5285, section 4.3. Two-Byte Header */
    while (xtn_hdr_data + 1 < xtn_hdr_end) {
      uint8_t xid = *xtn_hdr_data;
      unsigned int xlen = *(xtn_hdr_data+1);
      uint32_t xlen_with_header = 2+xlen;
      xtn_hdr_data += 2;

      if (xtn_hdr_data + xlen > xtn_hdr_end)
        return srtp_err_status_parse_err;

      status = srtp_cipher_output(stream->rtp_xtn_hdr_cipher, keystream, &xlen_with_header);
      if (status)
        return srtp_err_status_cipher_fail;

      if (xlen > 0 && srtp_protect_extension_header(stream, xid)) {
        keystream_pos = 2;
        while (xlen > 0) {
          *xtn_hdr_data ^= keystream[keystream_pos++];
          xtn_hdr_data++;
          xlen--;
        }
      } else {
        xtn_hdr_data += xlen;
      }

      /* skip padding bytes. */
      while (xtn_hdr_data < xtn_hdr_end && *xtn_hdr_data == 0) {
        xtn_hdr_data++;
      }
    }
  } else {
    /* unsupported extension header format. */
    return srtp_err_status_parse_err;
  }

  return srtp_err_status_ok;
}


/*
 * AEAD uses a new IV formation method.  This function implements
 * section 9.1 from draft-ietf-avtcore-srtp-aes-gcm-07.txt.  The
 * calculation is defined as, where (+) is the xor operation:
 *
 *
 *              0  0  0  0  0  0  0  0  0  0  1  1
 *              0  1  2  3  4  5  6  7  8  9  0  1
 *            +--+--+--+--+--+--+--+--+--+--+--+--+
 *            |00|00|    SSRC   |     ROC   | SEQ |---+
 *            +--+--+--+--+--+--+--+--+--+--+--+--+   |
 *                                                    |
 *            +--+--+--+--+--+--+--+--+--+--+--+--+   |
 *            |         Encryption Salt           |->(+)
 *            +--+--+--+--+--+--+--+--+--+--+--+--+   |
 *                                                    |
 *            +--+--+--+--+--+--+--+--+--+--+--+--+   |
 *            |       Initialization Vector       |<--+
 *            +--+--+--+--+--+--+--+--+--+--+--+--+*
 *
 * Input:  *stream - pointer to SRTP stream context, used to retrieve
 *                   the SALT 
 *         *iv     - Pointer to receive the calculated IV
 *         *seq    - The ROC and SEQ value to use for the
 *                   IV calculation.
 *         *hdr    - The RTP header, used to get the SSRC value
 *
 */
static void srtp_calc_aead_iv(srtp_stream_ctx_t *stream, v128_t *iv, 
	                      srtp_xtd_seq_num_t *seq, srtp_hdr_t *hdr)
{
    v128_t	in;
    v128_t	salt;

#ifdef NO_64BIT_MATH
    uint32_t local_roc = ((high32(*seq) << 16) |
                         (low32(*seq) >> 16));
    uint16_t local_seq = (uint16_t) (low32(*seq));
#else
    uint32_t local_roc = (uint32_t)(*seq >> 16);
    uint16_t local_seq = (uint16_t) *seq;
#endif

    memset(&in, 0, sizeof(v128_t));
    memset(&salt, 0, sizeof(v128_t));

    in.v16[5] = htons(local_seq);
    local_roc = htonl(local_roc);
    memcpy(&in.v16[3], &local_roc, sizeof(local_roc));

    /*
     * Copy in the RTP SSRC value
     */
    memcpy(&in.v8[2], &hdr->ssrc, 4);
    debug_print(mod_srtp, "Pre-salted RTP IV = %s\n", v128_hex_string(&in));

    /*
     * Get the SALT value from the context
     */
    memcpy(salt.v8, stream->salt, SRTP_AEAD_SALT_LEN);
    debug_print(mod_srtp, "RTP SALT = %s\n", v128_hex_string(&salt));

    /*
     * Finally, apply tyhe SALT to the input
     */
    v128_xor(iv, &in, &salt);
}


/*
 * This function handles outgoing SRTP packets while in AEAD mode,
 * which currently supports AES-GCM encryption.  All packets are
 * encrypted and authenticated.
 */
static srtp_err_status_t
srtp_protect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, 
	           void *rtp_hdr, unsigned int *pkt_octet_len)
{
    srtp_hdr_t *hdr = (srtp_hdr_t*)rtp_hdr;
    uint32_t *enc_start;        /* pointer to start of encrypted portion  */
    int enc_octet_len = 0; /* number of octets in encrypted portion  */
    srtp_xtd_seq_num_t est;          /* estimated xtd_seq_num_t of *hdr        */
    int delta;                  /* delta of local pkt idx and that in hdr */
    srtp_err_status_t status;
    uint32_t tag_len;
    v128_t iv;
    unsigned int aad_len;
    srtp_hdr_xtnd_t *xtn_hdr = NULL;

    debug_print(mod_srtp, "function srtp_protect_aead", NULL);

    /*
     * update the key usage limit, and check it to make sure that we
     * didn't just hit either the soft limit or the hard limit, and call
     * the event handler if we hit either.
     */
    switch (srtp_key_limit_update(stream->limit)) {
    case srtp_key_event_normal:
        break;
    case srtp_key_event_hard_limit:
        srtp_handle_event(ctx, stream, event_key_hard_limit);
        return srtp_err_status_key_expired;
    case srtp_key_event_soft_limit:
    default:
        srtp_handle_event(ctx, stream, event_key_soft_limit);
        break;
    }

    /* get tag length from stream */
    tag_len = srtp_auth_get_tag_length(stream->rtp_auth);

    /*
     * find starting point for encryption and length of data to be
     * encrypted - the encrypted portion starts after the rtp header
     * extension, if present; otherwise, it starts after the last csrc,
     * if any are present
     */
     enc_start = (uint32_t*)hdr + uint32s_in_rtp_header + hdr->cc;
     if (hdr->x == 1) {
         xtn_hdr = (srtp_hdr_xtnd_t*)enc_start;
         enc_start += (ntohs(xtn_hdr->length) + 1);
     }
     /* note: the passed size is without the auth tag */
     if (!((uint8_t*)enc_start <= (uint8_t*)hdr + *pkt_octet_len))
         return srtp_err_status_parse_err;
     enc_octet_len = (int)(*pkt_octet_len -
                                    ((uint8_t*)enc_start - (uint8_t*)hdr));
     if (enc_octet_len < 0) return srtp_err_status_parse_err;

    /*
     * estimate the packet index using the start of the replay window
     * and the sequence number from the header
     */
    delta = srtp_rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
    status = srtp_rdbx_check(&stream->rtp_rdbx, delta);
    if (status) {
	if (status != srtp_err_status_replay_fail || !stream->allow_repeat_tx) {
	    return status;  /* we've been asked to reuse an index */
	}
    } else {
	srtp_rdbx_add_index(&stream->rtp_rdbx, delta);
    }

#ifdef NO_64BIT_MATH
    debug_print2(mod_srtp, "estimated packet index: %08x%08x",
                 high32(est), low32(est));
#else
    debug_print(mod_srtp, "estimated packet index: %016llx", est);
#endif

    /*
     * AEAD uses a new IV formation method
     */
    srtp_calc_aead_iv(stream, &iv, &est, hdr);
    /* shift est, put into network byte order */
#ifdef NO_64BIT_MATH
    est = be64_to_cpu(make64((high32(est) << 16) |
                             (low32(est) >> 16),
                             low32(est) << 16));
#else
    est = be64_to_cpu(est << 16);
#endif

    status = srtp_cipher_set_iv(stream->rtp_cipher, (uint8_t*)&iv, direction_encrypt);
    if (!status && stream->rtp_xtn_hdr_cipher) {
      iv.v32[0] = 0;
      iv.v32[1] = hdr->ssrc;
      iv.v64[1] = est;
      status = srtp_cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_encrypt);
    }
    if (status) {
        return srtp_err_status_cipher_fail;
    }

    if (xtn_hdr && stream->rtp_xtn_hdr_cipher) {
      /*
       * extensions header encryption RFC 6904
       */
      status = srtp_process_header_encryption(stream, xtn_hdr);
      if (status) {
        return status;
      }
    }

    /*
     * Set the AAD over the RTP header 
     */
    aad_len = (uint8_t *)enc_start - (uint8_t *)hdr;
    status = srtp_cipher_set_aad(stream->rtp_cipher, (uint8_t*)hdr, aad_len);
    if (status) {
        return ( srtp_err_status_cipher_fail);
    }

    /* Encrypt the payload  */
    status = srtp_cipher_encrypt(stream->rtp_cipher,
                            (uint8_t*)enc_start, (unsigned int *)&enc_octet_len);
    if (status) {
        return srtp_err_status_cipher_fail;
    }
    /*
     * If we're doing GCM, we need to get the tag
     * and append that to the output
     */
    status = srtp_cipher_get_tag(stream->rtp_cipher, 
                            (uint8_t*)enc_start+enc_octet_len, &tag_len);
    if (status) {
	return ( srtp_err_status_cipher_fail);
    }

    /* increase the packet length by the length of the auth tag */
    *pkt_octet_len += tag_len;

    return srtp_err_status_ok;
}


/*
 * This function handles incoming SRTP packets while in AEAD mode,
 * which currently supports AES-GCM encryption.  All packets are
 * encrypted and authenticated.  Note, the auth tag is at the end
 * of the packet stream and is automatically checked by GCM
 * when decrypting the payload.
 */
static srtp_err_status_t
srtp_unprotect_aead (srtp_ctx_t *ctx, srtp_stream_ctx_t *stream, int delta, 
	             srtp_xtd_seq_num_t est, void *srtp_hdr, unsigned int *pkt_octet_len)
{
    srtp_hdr_t *hdr = (srtp_hdr_t*)srtp_hdr;
    uint32_t *enc_start;        /* pointer to start of encrypted portion  */
    unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
    v128_t iv;
    srtp_err_status_t status;
    int tag_len;
    unsigned int aad_len;
    srtp_hdr_xtnd_t *xtn_hdr = NULL;

    debug_print(mod_srtp, "function srtp_unprotect_aead", NULL);

#ifdef NO_64BIT_MATH
    debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est), low32(est));
#else
    debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
#endif

    /* get tag length from stream */
    tag_len = srtp_auth_get_tag_length(stream->rtp_auth);

    /*
     * AEAD uses a new IV formation method 
     */
    srtp_calc_aead_iv(stream, &iv, &est, hdr);
    status = srtp_cipher_set_iv(stream->rtp_cipher, (uint8_t*)&iv, direction_decrypt);
    if (!status && stream->rtp_xtn_hdr_cipher) {
      iv.v32[0] = 0;
      iv.v32[1] = hdr->ssrc;
#ifdef NO_64BIT_MATH
      iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
                  low32(est) << 16));
#else
      iv.v64[1] = be64_to_cpu(est << 16);
#endif
      status = srtp_cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_encrypt);
    }
    if (status) {
        return srtp_err_status_cipher_fail;
    }

    /*
     * find starting point for decryption and length of data to be
     * decrypted - the encrypted portion starts after the rtp header
     * extension, if present; otherwise, it starts after the last csrc,
     * if any are present
     */
    enc_start = (uint32_t*)hdr + uint32s_in_rtp_header + hdr->cc;
    if (hdr->x == 1) {
        xtn_hdr = (srtp_hdr_xtnd_t*)enc_start;
        enc_start += (ntohs(xtn_hdr->length) + 1);
    }
    if (!((uint8_t*)enc_start <= (uint8_t*)hdr + (*pkt_octet_len - tag_len)))
        return srtp_err_status_parse_err;
    /*
     * We pass the tag down to the cipher when doing GCM mode 
     */
    enc_octet_len = (unsigned int)(*pkt_octet_len - 
                                   ((uint8_t*)enc_start - (uint8_t*)hdr));

    /*
     * Sanity check the encrypted payload length against
     * the tag size.  It must always be at least as large
     * as the tag length.
     */
    if (enc_octet_len < (unsigned int) tag_len) {
        return srtp_err_status_cipher_fail;
    }

    /*
     * update the key usage limit, and check it to make sure that we
     * didn't just hit either the soft limit or the hard limit, and call
     * the event handler if we hit either.
     */
    switch (srtp_key_limit_update(stream->limit)) {
    case srtp_key_event_normal:
        break;
    case srtp_key_event_soft_limit:
        srtp_handle_event(ctx, stream, event_key_soft_limit);
        break;
    case srtp_key_event_hard_limit:
        srtp_handle_event(ctx, stream, event_key_hard_limit);
        return srtp_err_status_key_expired;
    default:
        break;
    }

    /*
     * Set the AAD for AES-GCM, which is the RTP header
     */
    aad_len = (uint8_t *)enc_start - (uint8_t *)hdr;
    status = srtp_cipher_set_aad(stream->rtp_cipher, (uint8_t*)hdr, aad_len);
    if (status) {
        return ( srtp_err_status_cipher_fail);
    }

    /* Decrypt the ciphertext.  This also checks the auth tag based
     * on the AAD we just specified above */
    status = srtp_cipher_decrypt(stream->rtp_cipher, (uint8_t*)enc_start, &enc_octet_len);
    if (status) {
        return status;
    }

    if (xtn_hdr && stream->rtp_xtn_hdr_cipher) {
      /*
       * extensions header encryption RFC 6904
       */
      status = srtp_process_header_encryption(stream, xtn_hdr);
      if (status) {
        return status;
      }
    }

    /*
     * verify that stream is for received traffic - this check will
     * detect SSRC collisions, since a stream that appears in both
     * srtp_protect() and srtp_unprotect() will fail this test in one of
     * those functions.
     *
     * we do this check *after* the authentication check, so that the
     * latter check will catch any attempts to fool us into thinking
     * that we've got a collision
     */
    if (stream->direction != dir_srtp_receiver) {
        if (stream->direction == dir_unknown) {
            stream->direction = dir_srtp_receiver;
        } else {
            srtp_handle_event(ctx, stream, event_ssrc_collision);
        }
    }

    /*
     * if the stream is a 'provisional' one, in which the template context
     * is used, then we need to allocate a new stream at this point, since
     * the authentication passed
     */
    if (stream == ctx->stream_template) {
        srtp_stream_ctx_t *new_stream;

        /*
         * allocate and initialize a new stream
         *
         * note that we indicate failure if we can't allocate the new
         * stream, and some implementations will want to not return
         * failure here
         */
        status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
        if (status) {
            return status;
        }

        /* add new stream to the head of the stream_list */
        new_stream->next = ctx->stream_list;
        ctx->stream_list = new_stream;

        /* set stream (the pointer used in this function) */
        stream = new_stream;
    }

    /*
     * the message authentication function passed, so add the packet
     * index into the replay database
     */
    srtp_rdbx_add_index(&stream->rtp_rdbx, delta);

    /* decrease the packet length by the length of the auth tag */
    *pkt_octet_len -= tag_len;

    return srtp_err_status_ok;
}


 srtp_err_status_t
 srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) {
   srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
   uint32_t *enc_start;        /* pointer to start of encrypted portion  */
   uint32_t *auth_start;       /* pointer to start of auth. portion      */
   int enc_octet_len = 0; /* number of octets in encrypted portion  */
   srtp_xtd_seq_num_t est;          /* estimated xtd_seq_num_t of *hdr        */
   int delta;                  /* delta of local pkt idx and that in hdr */
   uint8_t *auth_tag = NULL;   /* location of auth_tag within packet     */
   srtp_err_status_t status;   
   int tag_len;
   srtp_stream_ctx_t *stream;
   uint32_t prefix_len;
   srtp_hdr_xtnd_t *xtn_hdr = NULL;

   debug_print(mod_srtp, "function srtp_protect", NULL);

  /* we assume the hdr is 32-bit aligned to start */

  /* Verify RTP header */
  status = srtp_validate_rtp_header(rtp_hdr, pkt_octet_len);
  if (status)
    return status;

   /* check the packet length - it must at least contain a full header */
   if (*pkt_octet_len < octets_in_rtp_header)
     return srtp_err_status_bad_param;

   /*
    * look up ssrc in srtp_stream list, and process the packet with
    * the appropriate stream.  if we haven't seen this stream before,
    * there's a template key for this srtp_session, and the cipher
    * supports key-sharing, then we assume that a new stream using
    * that key has just started up
    */
   stream = srtp_get_stream(ctx, hdr->ssrc);
   if (stream == NULL) {
     if (ctx->stream_template != NULL) {
       srtp_stream_ctx_t *new_stream;

       /* allocate and initialize a new stream */
       status = srtp_stream_clone(ctx->stream_template, 
				  hdr->ssrc, &new_stream); 
       if (status)
	 return status;

       /* add new stream to the head of the stream_list */
       new_stream->next = ctx->stream_list;
       ctx->stream_list = new_stream;

       /* set direction to outbound */
       new_stream->direction = dir_srtp_sender;

       /* set stream (the pointer used in this function) */
       stream = new_stream;
     } else {
       /* no template stream, so we return an error */
       return srtp_err_status_no_ctx;
     } 
   }

   /* 
    * verify that stream is for sending traffic - this check will
    * detect SSRC collisions, since a stream that appears in both
    * srtp_protect() and srtp_unprotect() will fail this test in one of
    * those functions.
    */
  if (stream->direction != dir_srtp_sender) {
     if (stream->direction == dir_unknown) {
       stream->direction = dir_srtp_sender;
     } else {
       srtp_handle_event(ctx, stream, event_ssrc_collision);
     }
  }

   /*
    * Check if this is an AEAD stream (GCM mode).  If so, then dispatch
    * the request to our AEAD handler.
    */
  if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
      stream->rtp_cipher->algorithm == SRTP_AES_256_GCM) {
      return srtp_protect_aead(ctx, stream, rtp_hdr, (unsigned int*)pkt_octet_len);
  }

  /* 
   * update the key usage limit, and check it to make sure that we
   * didn't just hit either the soft limit or the hard limit, and call
   * the event handler if we hit either.
   */
  switch(srtp_key_limit_update(stream->limit)) {
  case srtp_key_event_normal:
    break;
  case srtp_key_event_soft_limit: 
    srtp_handle_event(ctx, stream, event_key_soft_limit);
    break; 
  case srtp_key_event_hard_limit:
    srtp_handle_event(ctx, stream, event_key_hard_limit);
	return srtp_err_status_key_expired;
  default:
    break;
  }

   /* get tag length from stream */
   tag_len = srtp_auth_get_tag_length(stream->rtp_auth); 

   /*
    * find starting point for encryption and length of data to be
    * encrypted - the encrypted portion starts after the rtp header
    * extension, if present; otherwise, it starts after the last csrc,
    * if any are present
    *
    * if we're not providing confidentiality, set enc_start to NULL
    */
   if (stream->rtp_services & sec_serv_conf) {
     enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;  
     if (hdr->x == 1) {
       xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
       enc_start += (ntohs(xtn_hdr->length) + 1);
     }
     /* note: the passed size is without the auth tag */
     if (!((uint8_t*)enc_start <= (uint8_t*)hdr + *pkt_octet_len))
       return srtp_err_status_parse_err;
     enc_octet_len = (int)(*pkt_octet_len -
                                    ((uint8_t*)enc_start - (uint8_t*)hdr));
     if (enc_octet_len < 0) return srtp_err_status_parse_err;
   } else {
     enc_start = NULL;
   }

   /* 
    * if we're providing authentication, set the auth_start and auth_tag
    * pointers to the proper locations; otherwise, set auth_start to NULL
    * to indicate that no authentication is needed
    */
   if (stream->rtp_services & sec_serv_auth) {
     auth_start = (uint32_t *)hdr;
     auth_tag = (uint8_t *)hdr + *pkt_octet_len;
   } else {
     auth_start = NULL;
     auth_tag = NULL;
   }

   /*
    * estimate the packet index using the start of the replay window   
    * and the sequence number from the header
    */
   delta = srtp_rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
   status = srtp_rdbx_check(&stream->rtp_rdbx, delta);
   if (status) {
     if (status != srtp_err_status_replay_fail || !stream->allow_repeat_tx)
       return status;  /* we've been asked to reuse an index */
   }
   else
     srtp_rdbx_add_index(&stream->rtp_rdbx, delta);

#ifdef NO_64BIT_MATH
   debug_print2(mod_srtp, "estimated packet index: %08x%08x", 
		high32(est),low32(est));
#else
   debug_print(mod_srtp, "estimated packet index: %016llx", est);
#endif

   /* 
    * if we're using rindael counter mode, set nonce and seq 
    */
   if (stream->rtp_cipher->type->id == SRTP_AES_ICM ||
       stream->rtp_cipher->type->id == SRTP_AES_256_ICM) {
     v128_t iv;

     iv.v32[0] = 0;
     iv.v32[1] = hdr->ssrc;
#ifdef NO_64BIT_MATH
     iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
								 low32(est) << 16));
#else
     iv.v64[1] = be64_to_cpu(est << 16);
#endif
     status = srtp_cipher_set_iv(stream->rtp_cipher, (uint8_t*)&iv, direction_encrypt);
     if (!status && stream->rtp_xtn_hdr_cipher) {
       status = srtp_cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_encrypt);
     }
   } else {  
     v128_t iv;

     /* otherwise, set the index to est */  
#ifdef NO_64BIT_MATH
     iv.v32[0] = 0;
     iv.v32[1] = 0;
#else
     iv.v64[0] = 0;
#endif
     iv.v64[1] = be64_to_cpu(est);
     status = srtp_cipher_set_iv(stream->rtp_cipher, (uint8_t*)&iv, direction_encrypt);
     if (!status && stream->rtp_xtn_hdr_cipher) {
       status = srtp_cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_encrypt);
     }
   }
   if (status)
     return srtp_err_status_cipher_fail;

   /* shift est, put into network byte order */
#ifdef NO_64BIT_MATH
   est = be64_to_cpu(make64((high32(est) << 16) |
						 (low32(est) >> 16),
						 low32(est) << 16));
#else
   est = be64_to_cpu(est << 16);
#endif
   
   /* 
    * if we're authenticating using a universal hash, put the keystream
    * prefix into the authentication tag
    */
   if (auth_start) {
     
    prefix_len = srtp_auth_get_prefix_length(stream->rtp_auth);    
    if (prefix_len) {
      status = srtp_cipher_output(stream->rtp_cipher, auth_tag, &prefix_len);
      if (status)
	return srtp_err_status_cipher_fail;
      debug_print(mod_srtp, "keystream prefix: %s", 
		  srtp_octet_string_hex_string(auth_tag, prefix_len));
    }
  }

  if (xtn_hdr && stream->rtp_xtn_hdr_cipher) {
    /*
     * extensions header encryption RFC 6904
     */
    status = srtp_process_header_encryption(stream, xtn_hdr);
    if (status) {
      return status;
    }
  }

  /* if we're encrypting, exor keystream into the message */
  if (enc_start) {
    status = srtp_cipher_encrypt(stream->rtp_cipher, 
			        (uint8_t *)enc_start, (unsigned int *)&enc_octet_len);
    if (status)
      return srtp_err_status_cipher_fail;
  }

  /*
   *  if we're authenticating, run authentication function and put result
   *  into the auth_tag 
   */
  if (auth_start) {        

    /* initialize auth func context */
    status = auth_start(stream->rtp_auth);
    if (status) return status;

    /* run auth func over packet */
    status = auth_update(stream->rtp_auth, 
			 (uint8_t *)auth_start, *pkt_octet_len);
    if (status) return status;
    
    /* run auth func over ROC, put result into auth_tag */
    debug_print(mod_srtp, "estimated packet index: %016llx", est);
    status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag); 
    debug_print(mod_srtp, "srtp auth tag:    %s", 
		srtp_octet_string_hex_string(auth_tag, tag_len));
    if (status)
      return srtp_err_status_auth_fail;   

  }

  if (auth_tag) {

    /* increase the packet length by the length of the auth tag */
    *pkt_octet_len += tag_len;
  }

  return srtp_err_status_ok;  
}


srtp_err_status_t
srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
  srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr;
  uint32_t *enc_start;      /* pointer to start of encrypted portion  */
  uint32_t *auth_start;     /* pointer to start of auth. portion      */
  unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
  uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */
  srtp_xtd_seq_num_t est;        /* estimated xtd_seq_num_t of *hdr        */
  int delta;                /* delta of local pkt idx and that in hdr */
  v128_t iv;
  srtp_err_status_t status;
  srtp_stream_ctx_t *stream;
  uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
  uint32_t tag_len, prefix_len;
  srtp_hdr_xtnd_t *xtn_hdr = NULL;

  debug_print(mod_srtp, "function srtp_unprotect", NULL);

  /* we assume the hdr is 32-bit aligned to start */

  /* Verify RTP header */
  status = srtp_validate_rtp_header(srtp_hdr, pkt_octet_len);
  if (status)
    return status;

  /* check the packet length - it must at least contain a full header */
  if (*pkt_octet_len < octets_in_rtp_header)
    return srtp_err_status_bad_param;

  /*
   * look up ssrc in srtp_stream list, and process the packet with 
   * the appropriate stream.  if we haven't seen this stream before,
   * there's only one key for this srtp_session, and the cipher
   * supports key-sharing, then we assume that a new stream using
   * that key has just started up
   */
  stream = srtp_get_stream(ctx, hdr->ssrc);
  if (stream == NULL) {
    if (ctx->stream_template != NULL) {
      stream = ctx->stream_template;
      debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)",
		  hdr->ssrc);
      
      /* 
       * set estimated packet index to sequence number from header,
       * and set delta equal to the same value
       */
#ifdef NO_64BIT_MATH
      est = (srtp_xtd_seq_num_t) make64(0,ntohs(hdr->seq));
      delta = low32(est);
#else
      est = (srtp_xtd_seq_num_t) ntohs(hdr->seq);
      delta = (int)est;
#endif
    } else {
      
      /*
       * no stream corresponding to SSRC found, and we don't do
       * key-sharing, so return an error
       */
      return srtp_err_status_no_ctx;
    }
  } else {
  
    /* estimate packet index from seq. num. in header */
    delta = srtp_rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
    
    /* check replay database */
    status = srtp_rdbx_check(&stream->rtp_rdbx, delta);
    if (status)
      return status;
  }

#ifdef NO_64BIT_MATH
  debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),low32(est));
#else
  debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
#endif

  /*
   * Check if this is an AEAD stream (GCM mode).  If so, then dispatch
   * the request to our AEAD handler.
   */
  if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
      stream->rtp_cipher->algorithm == SRTP_AES_256_GCM) {
      return srtp_unprotect_aead(ctx, stream, delta, est, srtp_hdr, (unsigned int*)pkt_octet_len);
  }

  /* get tag length from stream */
  tag_len = srtp_auth_get_tag_length(stream->rtp_auth); 

  /* 
   * set the cipher's IV properly, depending on whatever cipher we
   * happen to be using
   */
  if (stream->rtp_cipher->type->id == SRTP_AES_ICM ||
      stream->rtp_cipher->type->id == SRTP_AES_256_ICM) {

    /* aes counter mode */
    iv.v32[0] = 0;
    iv.v32[1] = hdr->ssrc;  /* still in network order */
#ifdef NO_64BIT_MATH
    iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
			         low32(est) << 16));
#else
    iv.v64[1] = be64_to_cpu(est << 16);
#endif
    status = srtp_cipher_set_iv(stream->rtp_cipher, (uint8_t*)&iv, direction_decrypt);
    if (!status && stream->rtp_xtn_hdr_cipher) {
      status = srtp_cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_decrypt);
    }
  } else {  
    
    /* no particular format - set the iv to the pakcet index */  
#ifdef NO_64BIT_MATH
    iv.v32[0] = 0;
    iv.v32[1] = 0;
#else
    iv.v64[0] = 0;
#endif
    iv.v64[1] = be64_to_cpu(est);
    status = srtp_cipher_set_iv(stream->rtp_cipher, (uint8_t*)&iv, direction_decrypt);
    if (!status && stream->rtp_xtn_hdr_cipher) {
      status = srtp_cipher_set_iv(stream->rtp_xtn_hdr_cipher, (uint8_t*)&iv, direction_decrypt);
    }
  }
  if (status)
    return srtp_err_status_cipher_fail;

  /* shift est, put into network byte order */
#ifdef NO_64BIT_MATH
  est = be64_to_cpu(make64((high32(est) << 16) |
					    (low32(est) >> 16),
					    low32(est) << 16));
#else
  est = be64_to_cpu(est << 16);
#endif

  /*
   * find starting point for decryption and length of data to be
   * decrypted - the encrypted portion starts after the rtp header
   * extension, if present; otherwise, it starts after the last csrc,
   * if any are present
   *
   * if we're not providing confidentiality, set enc_start to NULL
   */
  if (stream->rtp_services & sec_serv_conf) {
    enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;  
    if (hdr->x == 1) {
      xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
      enc_start += (ntohs(xtn_hdr->length) + 1);
    }  
    if (!((uint8_t*)enc_start <= (uint8_t*)hdr + (*pkt_octet_len - tag_len)))
      return srtp_err_status_parse_err;
    enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len -
                               ((uint8_t*)enc_start - (uint8_t*)hdr));
  } else {
    enc_start = NULL;
  }

  /* 
   * if we're providing authentication, set the auth_start and auth_tag
   * pointers to the proper locations; otherwise, set auth_start to NULL
   * to indicate that no authentication is needed
   */
  if (stream->rtp_services & sec_serv_auth) {
    auth_start = (uint32_t *)hdr;
    auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len;
  } else {
    auth_start = NULL;
    auth_tag = NULL;
  } 

  /*
   * if we expect message authentication, run the authentication
   * function and compare the result with the value of the auth_tag
   */
  if (auth_start) {        

    /* 
     * if we're using a universal hash, then we need to compute the
     * keystream prefix for encrypting the universal hash output
     *
     * if the keystream prefix length is zero, then we know that
     * the authenticator isn't using a universal hash function
     */  
    if (stream->rtp_auth->prefix_len != 0) {
      
      prefix_len = srtp_auth_get_prefix_length(stream->rtp_auth);    
      status = srtp_cipher_output(stream->rtp_cipher, tmp_tag, &prefix_len);
      debug_print(mod_srtp, "keystream prefix: %s", 
		  srtp_octet_string_hex_string(tmp_tag, prefix_len));
      if (status)
	return srtp_err_status_cipher_fail;
    } 

    /* initialize auth func context */
    status = auth_start(stream->rtp_auth);
    if (status) return status;
 
    /* now compute auth function over packet */
    status = auth_update(stream->rtp_auth, (uint8_t *)auth_start,  
			 *pkt_octet_len - tag_len);

    /* run auth func over ROC, then write tmp tag */
    status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag);  

    debug_print(mod_srtp, "computed auth tag:    %s", 
		srtp_octet_string_hex_string(tmp_tag, tag_len));
    debug_print(mod_srtp, "packet auth tag:      %s", 
		srtp_octet_string_hex_string(auth_tag, tag_len));
    if (status)
      return srtp_err_status_auth_fail;   

    if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
      return srtp_err_status_auth_fail;
  }

  /* 
   * update the key usage limit, and check it to make sure that we
   * didn't just hit either the soft limit or the hard limit, and call
   * the event handler if we hit either.
   */
  switch(srtp_key_limit_update(stream->limit)) {
  case srtp_key_event_normal:
    break;
  case srtp_key_event_soft_limit: 
    srtp_handle_event(ctx, stream, event_key_soft_limit);
    break; 
  case srtp_key_event_hard_limit:
    srtp_handle_event(ctx, stream, event_key_hard_limit);
    return srtp_err_status_key_expired;
  default:
    break;
  }

  if (xtn_hdr && stream->rtp_xtn_hdr_cipher) {
    /*
     * extensions header encryption RFC 6904
     */
    status = srtp_process_header_encryption(stream, xtn_hdr);
    if (status) {
      return status;
    }
  }

  /* if we're decrypting, add keystream into ciphertext */
  if (enc_start) {
    status = srtp_cipher_decrypt(stream->rtp_cipher, (uint8_t *)enc_start, &enc_octet_len);
    if (status)
      return srtp_err_status_cipher_fail;
  }

  /* 
   * verify that stream is for received traffic - this check will
   * detect SSRC collisions, since a stream that appears in both
   * srtp_protect() and srtp_unprotect() will fail this test in one of
   * those functions.
   *
   * we do this check *after* the authentication check, so that the
   * latter check will catch any attempts to fool us into thinking
   * that we've got a collision
   */
  if (stream->direction != dir_srtp_receiver) {
    if (stream->direction == dir_unknown) {
      stream->direction = dir_srtp_receiver;
    } else {
      srtp_handle_event(ctx, stream, event_ssrc_collision);
    }
  }

  /* 
   * if the stream is a 'provisional' one, in which the template context
   * is used, then we need to allocate a new stream at this point, since
   * the authentication passed
   */
  if (stream == ctx->stream_template) {  
    srtp_stream_ctx_t *new_stream;

    /* 
     * allocate and initialize a new stream 
     * 
     * note that we indicate failure if we can't allocate the new
     * stream, and some implementations will want to not return
     * failure here
     */
    status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); 
    if (status)
      return status;
    
    /* add new stream to the head of the stream_list */
    new_stream->next = ctx->stream_list;
    ctx->stream_list = new_stream;
    
    /* set stream (the pointer used in this function) */
    stream = new_stream;
  }
  
  /* 
   * the message authentication function passed, so add the packet
   * index into the replay database 
   */
  srtp_rdbx_add_index(&stream->rtp_rdbx, delta);

  /* decrease the packet length by the length of the auth tag */
  *pkt_octet_len -= tag_len;

  return srtp_err_status_ok;  
}

srtp_err_status_t
srtp_init() {
  srtp_err_status_t status;

  /* initialize crypto kernel */
  status = srtp_crypto_kernel_init();
  if (status) 
    return status;

  /* load srtp debug module into the kernel */
  status = srtp_crypto_kernel_load_debug_module(&mod_srtp);
  if (status)
    return status;

  return srtp_err_status_ok;
}

srtp_err_status_t
srtp_shutdown() {
  srtp_err_status_t status;

  /* shut down crypto kernel */
  status = srtp_crypto_kernel_shutdown();
  if (status) 
    return status;

  /* shutting down crypto kernel frees the srtp debug module as well */

  return srtp_err_status_ok;
}


/* 
 * The following code is under consideration for removal.  See
 * SRTP_MAX_TRAILER_LEN 
 */
#if 0

/*
 * srtp_get_trailer_length(&a) returns the number of octets that will
 * be added to an RTP packet by the SRTP processing.  This value
 * is constant for a given srtp_stream_t (i.e. between initializations).
 */

int
srtp_get_trailer_length(const srtp_stream_t s) {
  return srtp_auth_get_tag_length(s->rtp_auth);
}

#endif

/*
 * srtp_get_stream(ssrc) returns a pointer to the stream corresponding
 * to ssrc, or NULL if no stream exists for that ssrc
 *
 * this is an internal function 
 */

srtp_stream_ctx_t *
srtp_get_stream(srtp_t srtp, uint32_t ssrc) {
  srtp_stream_ctx_t *stream;

  /* walk down list until ssrc is found */
  stream = srtp->stream_list;
  while (stream != NULL) {
    if (stream->ssrc == ssrc)
      return stream;
    stream = stream->next;
  }
  
  /* we haven't found our ssrc, so return a null */
  return NULL;
}

srtp_err_status_t
srtp_dealloc(srtp_t session) {
  srtp_stream_ctx_t *stream;
  srtp_err_status_t status;

  /*
   * we take a conservative deallocation strategy - if we encounter an
   * error deallocating a stream, then we stop trying to deallocate
   * memory and just return an error
   */

  /* walk list of streams, deallocating as we go */
  stream = session->stream_list;
  while (stream != NULL) {
    srtp_stream_t next = stream->next;
    status = srtp_stream_dealloc(stream, session->stream_template);
    if (status)
      return status;
    stream = next;
  }
  
  /* deallocate stream template, if there is one */
  if (session->stream_template != NULL) {
    status = srtp_stream_dealloc(session->stream_template, NULL);
    if (status)
      return status;
  }

  /* deallocate session context */
  srtp_crypto_free(session);

  return srtp_err_status_ok;
}


srtp_err_status_t
srtp_add_stream(srtp_t session, 
		const srtp_policy_t *policy)  {
  srtp_err_status_t status;
  srtp_stream_t tmp;

  /* sanity check arguments */
  if ((session == NULL) || (policy == NULL) || (policy->key == NULL))
    return srtp_err_status_bad_param;

  /* allocate stream  */
  status = srtp_stream_alloc(&tmp, policy);
  if (status) {
    return status;
  }
  
  /* initialize stream  */
  status = srtp_stream_init(tmp, policy);
  if (status) {
    srtp_crypto_free(tmp);
    return status;
  }
  
  /* 
   * set the head of the stream list or the template to point to the
   * stream that we've just alloced and init'ed, depending on whether
   * or not it has a wildcard SSRC value or not
   *
   * if the template stream has already been set, then the policy is
   * inconsistent, so we return a bad_param error code
   */
  switch (policy->ssrc.type) {
  case (ssrc_any_outbound):
    if (session->stream_template) {
      return srtp_err_status_bad_param;
    }
    session->stream_template = tmp;
    session->stream_template->direction = dir_srtp_sender;
    break;
  case (ssrc_any_inbound):
    if (session->stream_template) {
      return srtp_err_status_bad_param;
    }
    session->stream_template = tmp;
    session->stream_template->direction = dir_srtp_receiver;
    break;
  case (ssrc_specific):
    tmp->next = session->stream_list;
    session->stream_list = tmp;
    break;
  case (ssrc_undefined):
  default:
    srtp_crypto_free(tmp);
    return srtp_err_status_bad_param;
  }
    
  return srtp_err_status_ok;
}


srtp_err_status_t
srtp_create(srtp_t *session,               /* handle for session     */ 
	    const srtp_policy_t *policy) { /* SRTP policy (list)     */
  srtp_err_status_t stat;
  srtp_ctx_t *ctx;

  /* sanity check arguments */
  if (session == NULL)
    return srtp_err_status_bad_param;

  /* allocate srtp context and set ctx_ptr */
  ctx = (srtp_ctx_t *) srtp_crypto_alloc(sizeof(srtp_ctx_t));
  if (ctx == NULL)
    return srtp_err_status_alloc_fail;
  *session = ctx;

  /* 
   * loop over elements in the policy list, allocating and
   * initializing a stream for each element
   */
  ctx->stream_template = NULL;
  ctx->stream_list = NULL;
  ctx->user_data = NULL;
  while (policy != NULL) {    

    stat = srtp_add_stream(ctx, policy);
    if (stat) {
      /* clean up everything */
      srtp_dealloc(*session);
      *session = NULL;
      return stat;
    }    

    /* set policy to next item in list  */
    policy = policy->next;
  }

  return srtp_err_status_ok;
}


srtp_err_status_t
srtp_remove_stream(srtp_t session, uint32_t ssrc) {
  srtp_stream_ctx_t *stream, *last_stream;
  srtp_err_status_t status;

  /* sanity check arguments */
  if (session == NULL)
    return srtp_err_status_bad_param;
  
  /* find stream in list; complain if not found */
  last_stream = stream = session->stream_list;
  while ((stream != NULL) && (ssrc != stream->ssrc)) {
    last_stream = stream;
    stream = stream->next;
  }
  if (stream == NULL)
    return srtp_err_status_no_ctx;

  /* remove stream from the list */
  if (last_stream == stream)
    /* stream was first in list */
    session->stream_list = stream->next;
  else
    last_stream->next = stream->next;

  /* deallocate the stream */
  status = srtp_stream_dealloc(stream, session->stream_template);
  if (status)
    return status;

  return srtp_err_status_ok;
}


srtp_err_status_t
srtp_update(srtp_t session, const srtp_policy_t *policy) {
  srtp_err_status_t stat;

  /* sanity check arguments */
  if ((session == NULL) || (policy == NULL) || (policy->key == NULL)) {
    return srtp_err_status_bad_param;
  }

  while (policy != NULL) {
    stat = srtp_update_stream(session, policy);
    if (stat) {
      return stat;
    }

    /* set policy to next item in list  */
    policy = policy->next;
  }
  return srtp_err_status_ok;
}


static srtp_err_status_t
update_template_streams(srtp_t session, const srtp_policy_t *policy) {
  srtp_err_status_t status;
  srtp_stream_t new_stream_template;
  srtp_stream_t new_stream_list = NULL;

  if (session->stream_template == NULL) {
    return srtp_err_status_bad_param;
  }

  /* allocate new template stream  */
  status = srtp_stream_alloc(&new_stream_template, policy);
  if (status) {
    return status;
  }

  /* initialize new template stream  */
  status = srtp_stream_init(new_stream_template, policy);
  if (status) {
    srtp_crypto_free(new_stream_template);
    return status;
  }

  /* for all old templated streams */
  for (;;) {
    srtp_stream_t stream;
    uint32_t ssrc;
    srtp_xtd_seq_num_t old_index;
    srtp_rdb_t old_rtcp_rdb;

    stream = session->stream_list;
    while ((stream != NULL) && (stream->rtp_auth != session->stream_template->rtp_auth)) {
      stream = stream->next;
    }
    if (stream == NULL) {
      /* no more templated streams */
      break;
    }

    /* save old extendard seq */
    ssrc = stream->ssrc;
    old_index = stream->rtp_rdbx.index;
    old_rtcp_rdb = stream->rtcp_rdb;

    /* remove stream */
    status = srtp_remove_stream(session, ssrc);
    if (status) {
      /* free new allocations */
      while (new_stream_list != NULL) {
        srtp_stream_t next = new_stream_list->next;
        srtp_stream_dealloc(new_stream_list, new_stream_template);
        new_stream_list = next;
      }
      srtp_stream_dealloc(new_stream_template, NULL);
      return status;
    }

    /* allocate and initialize a new stream */
    status = srtp_stream_clone(new_stream_template, ssrc, &stream);
    if (status) {
      /* free new allocations */
      while (new_stream_list != NULL) {
        srtp_stream_t next = new_stream_list->next;
        srtp_stream_dealloc(new_stream_list, new_stream_template);
        new_stream_list = next;
      }
      srtp_stream_dealloc(new_stream_template, NULL);
      return status;
    }

    /* add new stream to the head of the new_stream_list */
    stream->next = new_stream_list;
    new_stream_list = stream;

    /* restore old extended seq */
    stream->rtp_rdbx.index = old_index;
    stream->rtcp_rdb = old_rtcp_rdb;
  }
  /* dealloc old template */
  srtp_stream_dealloc(session->stream_template, NULL);
  /* set new template */
  session->stream_template = new_stream_template;
  /* add new list */
  if (new_stream_list) {
    srtp_stream_t tail = new_stream_list;
    while (tail->next) {
      tail = tail->next;
    }
    tail->next = session->stream_list;
    session->stream_list = new_stream_list;
  }
  return status;
}


static srtp_err_status_t
update_stream(srtp_t session, const srtp_policy_t *policy) {
  srtp_err_status_t status;
  srtp_xtd_seq_num_t old_index;
  srtp_rdb_t old_rtcp_rdb;
  srtp_stream_t stream;

  stream = srtp_get_stream(session, policy->ssrc.value);
  if (stream == NULL) {
    return srtp_err_status_bad_param;
  }

  /* save old extendard seq */
  old_index = stream->rtp_rdbx.index;
  old_rtcp_rdb = stream->rtcp_rdb;

  status = srtp_remove_stream(session, policy->ssrc.value);
  if (status) {
    return status;
  }

  status = srtp_add_stream(session, policy);
  if (status) {
    return status;
  }

  stream = srtp_get_stream(session, policy->ssrc.value);
  if (stream == NULL) {
    return srtp_err_status_fail;
  }

  /* restore old extended seq */
  stream->rtp_rdbx.index = old_index;
  stream->rtcp_rdb = old_rtcp_rdb;

  return srtp_err_status_ok;
}


srtp_err_status_t
srtp_update_stream(srtp_t session, const srtp_policy_t *policy) {
  srtp_err_status_t status;

  /* sanity check arguments */
  if ((session == NULL) || (policy == NULL) || (policy->key == NULL))
    return srtp_err_status_bad_param;

  switch (policy->ssrc.type) {
  case (ssrc_any_outbound):
  case (ssrc_any_inbound):
    status = update_template_streams(session, policy);
    break;
  case (ssrc_specific):
    status = update_stream(session, policy);
    break;
  case (ssrc_undefined):
  default:
    return srtp_err_status_bad_param;
  }

  return status;
}


/*
 * the default policy - provides a convenient way for callers to use
 * the default security policy
 * 
 * this policy is that defined in the current SRTP internet draft.
 *
 */

/* 
 * NOTE: cipher_key_len is really key len (128 bits) plus salt len
 *  (112 bits)
 */
/* There are hard-coded 16's for base_key_len in the key generation code */

void
srtp_crypto_policy_set_rtp_default(srtp_crypto_policy_t *p) {

  p->cipher_type     = SRTP_AES_ICM;           
  p->cipher_key_len  = 30;                /* default 128 bits per RFC 3711 */
  p->auth_type       = SRTP_HMAC_SHA1;             
  p->auth_key_len    = 20;                /* default 160 bits per RFC 3711 */
  p->auth_tag_len    = 10;                /* default 80 bits per RFC 3711 */
  p->sec_serv        = sec_serv_conf_and_auth;
  
}

void
srtp_crypto_policy_set_rtcp_default(srtp_crypto_policy_t *p) {

  p->cipher_type     = SRTP_AES_ICM;           
  p->cipher_key_len  = 30;                 /* default 128 bits per RFC 3711 */
  p->auth_type       = SRTP_HMAC_SHA1;             
  p->auth_key_len    = 20;                 /* default 160 bits per RFC 3711 */
  p->auth_tag_len    = 10;                 /* default 80 bits per RFC 3711 */
  p->sec_serv        = sec_serv_conf_and_auth;
  
}

void
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(srtp_crypto_policy_t *p) {

  /*
   * corresponds to RFC 4568
   *
   * note that this crypto policy is intended for SRTP, but not SRTCP
   */

  p->cipher_type     = SRTP_AES_ICM;           
  p->cipher_key_len  = 30;                /* 128 bit key, 112 bit salt */
  p->auth_type       = SRTP_HMAC_SHA1;             
  p->auth_key_len    = 20;                /* 160 bit key               */
  p->auth_tag_len    = 4;                 /* 32 bit tag                */
  p->sec_serv        = sec_serv_conf_and_auth;
  
}


void
srtp_crypto_policy_set_aes_cm_128_null_auth(srtp_crypto_policy_t *p) {

  /*
   * corresponds to RFC 4568
   *
   * note that this crypto policy is intended for SRTP, but not SRTCP
   */

  p->cipher_type     = SRTP_AES_ICM;           
  p->cipher_key_len  = 30;                /* 128 bit key, 112 bit salt */
  p->auth_type       = SRTP_NULL_AUTH;             
  p->auth_key_len    = 0; 
  p->auth_tag_len    = 0; 
  p->sec_serv        = sec_serv_conf;
  
}


void
srtp_crypto_policy_set_null_cipher_hmac_sha1_80(srtp_crypto_policy_t *p) {

  /*
   * corresponds to RFC 4568
   */

  p->cipher_type     = SRTP_NULL_CIPHER;           
  p->cipher_key_len  = 0;
  p->auth_type       = SRTP_HMAC_SHA1;             
  p->auth_key_len    = 20; 
  p->auth_tag_len    = 10; 
  p->sec_serv        = sec_serv_auth;
  
}

void
srtp_crypto_policy_set_null_cipher_hmac_null(srtp_crypto_policy_t *p) {

  /*
   * Should only be used for testing
   */

  p->cipher_type     = SRTP_NULL_CIPHER;           
  p->cipher_key_len  = 0;
  p->auth_type       = SRTP_NULL_AUTH;             
  p->auth_key_len    = 0; 
  p->auth_tag_len    = 0; 
  p->sec_serv        = sec_serv_none;
  
}


void
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(srtp_crypto_policy_t *p) {

  /*
   * corresponds to draft-ietf-avt-big-aes-03.txt
   */

  p->cipher_type     = SRTP_AES_ICM;           
  p->cipher_key_len  = 46;
  p->auth_type       = SRTP_HMAC_SHA1;             
  p->auth_key_len    = 20;                /* default 160 bits per RFC 3711 */
  p->auth_tag_len    = 10;                /* default 80 bits per RFC 3711 */
  p->sec_serv        = sec_serv_conf_and_auth;
}


void
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(srtp_crypto_policy_t *p) {

  /*
   * corresponds to draft-ietf-avt-big-aes-03.txt
   *
   * note that this crypto policy is intended for SRTP, but not SRTCP
   */

  p->cipher_type     = SRTP_AES_ICM;           
  p->cipher_key_len  = 46;
  p->auth_type       = SRTP_HMAC_SHA1;             
  p->auth_key_len    = 20;                /* default 160 bits per RFC 3711 */
  p->auth_tag_len    = 4;                 /* default 80 bits per RFC 3711 */
  p->sec_serv        = sec_serv_conf_and_auth;
}

/*
 * AES-256 with no authentication.
 */
void
srtp_crypto_policy_set_aes_cm_256_null_auth (srtp_crypto_policy_t *p)
{
    p->cipher_type     = SRTP_AES_ICM;
    p->cipher_key_len  = 46;
    p->auth_type       = SRTP_NULL_AUTH;
    p->auth_key_len    = 0;
    p->auth_tag_len    = 0;
    p->sec_serv        = sec_serv_conf;
}

#ifdef OPENSSL
/*
 * AES-128 GCM mode with 8 octet auth tag. 
 */
void
srtp_crypto_policy_set_aes_gcm_128_8_auth(srtp_crypto_policy_t *p) {
  p->cipher_type     = SRTP_AES_128_GCM;           
  p->cipher_key_len  = SRTP_AES_128_GCM_KEYSIZE_WSALT; 
  p->auth_type       = SRTP_NULL_AUTH; /* GCM handles the auth for us */            
  p->auth_key_len    = 0; 
  p->auth_tag_len    = 8;   /* 8 octet tag length */
  p->sec_serv        = sec_serv_conf_and_auth;
}

/*
 * AES-256 GCM mode with 8 octet auth tag. 
 */
void
srtp_crypto_policy_set_aes_gcm_256_8_auth(srtp_crypto_policy_t *p) {
  p->cipher_type     = SRTP_AES_256_GCM;           
  p->cipher_key_len  = SRTP_AES_256_GCM_KEYSIZE_WSALT; 
  p->auth_type       = SRTP_NULL_AUTH; /* GCM handles the auth for us */ 
  p->auth_key_len    = 0; 
  p->auth_tag_len    = 8;   /* 8 octet tag length */
  p->sec_serv        = sec_serv_conf_and_auth;
}

/*
 * AES-128 GCM mode with 8 octet auth tag, no RTCP encryption. 
 */
void
srtp_crypto_policy_set_aes_gcm_128_8_only_auth(srtp_crypto_policy_t *p) {
  p->cipher_type     = SRTP_AES_128_GCM;           
  p->cipher_key_len  = SRTP_AES_128_GCM_KEYSIZE_WSALT; 
  p->auth_type       = SRTP_NULL_AUTH; /* GCM handles the auth for us */ 
  p->auth_key_len    = 0; 
  p->auth_tag_len    = 8;   /* 8 octet tag length */
  p->sec_serv        = sec_serv_auth;  /* This only applies to RTCP */
}

/*
 * AES-256 GCM mode with 8 octet auth tag, no RTCP encryption. 
 */
void
srtp_crypto_policy_set_aes_gcm_256_8_only_auth(srtp_crypto_policy_t *p) {
  p->cipher_type     = SRTP_AES_256_GCM;           
  p->cipher_key_len  = SRTP_AES_256_GCM_KEYSIZE_WSALT; 
  p->auth_type       = SRTP_NULL_AUTH; /* GCM handles the auth for us */ 
  p->auth_key_len    = 0; 
  p->auth_tag_len    = 8;   /* 8 octet tag length */
  p->sec_serv        = sec_serv_auth;  /* This only applies to RTCP */
}

/*
 * AES-128 GCM mode with 16 octet auth tag. 
 */
void
srtp_crypto_policy_set_aes_gcm_128_16_auth(srtp_crypto_policy_t *p) {
  p->cipher_type     = SRTP_AES_128_GCM;           
  p->cipher_key_len  = SRTP_AES_128_GCM_KEYSIZE_WSALT; 
  p->auth_type       = SRTP_NULL_AUTH; /* GCM handles the auth for us */            
  p->auth_key_len    = 0; 
  p->auth_tag_len    = 16;   /* 16 octet tag length */
  p->sec_serv        = sec_serv_conf_and_auth;
}

/*
 * AES-256 GCM mode with 16 octet auth tag. 
 */
void
srtp_crypto_policy_set_aes_gcm_256_16_auth(srtp_crypto_policy_t *p) {
  p->cipher_type     = SRTP_AES_256_GCM;           
  p->cipher_key_len  = SRTP_AES_256_GCM_KEYSIZE_WSALT; 
  p->auth_type       = SRTP_NULL_AUTH; /* GCM handles the auth for us */ 
  p->auth_key_len    = 0; 
  p->auth_tag_len    = 16;   /* 16 octet tag length */
  p->sec_serv        = sec_serv_conf_and_auth;
}

#endif

/* 
 * secure rtcp functions
 */

/*
 * AEAD uses a new IV formation method.  This function implements
 * section 10.1 from draft-ietf-avtcore-srtp-aes-gcm-07.txt.  The
 * calculation is defined as, where (+) is the xor operation:
 *
 *                0  1  2  3  4  5  6  7  8  9 10 11
 *               +--+--+--+--+--+--+--+--+--+--+--+--+
 *               |00|00|    SSRC   |00|00|0+SRTCP Idx|---+
 *               +--+--+--+--+--+--+--+--+--+--+--+--+   |
 *                                                       |
 *               +--+--+--+--+--+--+--+--+--+--+--+--+   |
 *               |         Encryption Salt           |->(+)
 *               +--+--+--+--+--+--+--+--+--+--+--+--+   |
 *                                                       |
 *               +--+--+--+--+--+--+--+--+--+--+--+--+   |
 *               |       Initialization Vector       |<--+
 *               +--+--+--+--+--+--+--+--+--+--+--+--+*
 *
 * Input:  *stream - pointer to SRTP stream context, used to retrieve
 *                   the SALT 
 *         *iv     - Pointer to recieve the calculated IV
 *         seq_num - The SEQ value to use for the IV calculation.
 *         *hdr    - The RTP header, used to get the SSRC value
 *
 */
static void srtp_calc_aead_iv_srtcp(srtp_stream_ctx_t *stream, v128_t *iv, 
                                    uint32_t seq_num, srtcp_hdr_t *hdr)
{
    v128_t	in;
    v128_t	salt;

    memset(&in, 0, sizeof(v128_t));
    memset(&salt, 0, sizeof(v128_t));

    in.v16[0] = 0;
    memcpy(&in.v16[1], &hdr->ssrc, 4); /* still in network order! */
    in.v16[3] = 0;
    in.v32[2] = 0x7FFFFFFF & htonl(seq_num); /* bit 32 is suppose to be zero */

    debug_print(mod_srtp, "Pre-salted RTCP IV = %s\n", v128_hex_string(&in));

    /*
     * Get the SALT value from the context
     */
    memcpy(salt.v8, stream->c_salt, 12);
    debug_print(mod_srtp, "RTCP SALT = %s\n", v128_hex_string(&salt));

    /*
     * Finally, apply the SALT to the input
     */
    v128_xor(iv, &in, &salt);
}

/*
 * This code handles AEAD ciphers for outgoing RTCP.  We currently support
 * AES-GCM mode with 128 or 256 bit keys. 
 */
static srtp_err_status_t
srtp_protect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream, 
                        void *rtcp_hdr, unsigned int *pkt_octet_len)
{
    srtcp_hdr_t *hdr = (srtcp_hdr_t*)rtcp_hdr;
    uint32_t *enc_start;        /* pointer to start of encrypted portion  */
    uint32_t *trailer;          /* pointer to start of trailer            */
    unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
    uint8_t *auth_tag = NULL;   /* location of auth_tag within packet     */
    srtp_err_status_t status;
    uint32_t tag_len;
    uint32_t seq_num;
    v128_t iv;
    uint32_t tseq;

    /* get tag length from stream context */
    tag_len = srtp_auth_get_tag_length(stream->rtcp_auth);

    /*
     * set encryption start and encryption length - if we're not
     * providing confidentiality, set enc_start to NULL
     */
    enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header;
    enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;

    /* NOTE: hdr->length is not usable - it refers to only the first
           RTCP report in the compound packet! */
    /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
           multiples of 32-bits (RFC 3550 6.1) */
    trailer = (uint32_t*)((char*)enc_start + enc_octet_len + tag_len);

    if (stream->rtcp_services & sec_serv_conf) {
        *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
    } else {
        enc_start = NULL;
        enc_octet_len = 0;
        /* 0 is network-order independant */
        *trailer = 0x00000000; /* set encrypt bit */
    }

    /*
     * set the auth_tag pointer to the proper location, which is after
     * the payload, but before the trailer
     * (note that srtpc *always* provides authentication, unlike srtp)
     */
    /* Note: This would need to change for optional mikey data */
    auth_tag = (uint8_t*)hdr + *pkt_octet_len;

    /*
     * check sequence number for overruns, and copy it into the packet
     * if its value isn't too big
     */
    status = srtp_rdb_increment(&stream->rtcp_rdb);
    if (status) {
        return status;
    }
    seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
    *trailer |= htonl(seq_num);
    debug_print(mod_srtp, "srtcp index: %x", seq_num);

    /*
     * Calculating the IV and pass it down to the cipher 
     */
    srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
    status = srtp_cipher_set_iv(stream->rtcp_cipher, (uint8_t*)&iv, direction_encrypt);
    if (status) {
        return srtp_err_status_cipher_fail;
    }

    /*
     * Set the AAD for GCM mode
     */
    if (enc_start) {
	/*
	 * If payload encryption is enabled, then the AAD consist of
	 * the RTCP header and the seq# at the end of the packet
	 */
	status = srtp_cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr, octets_in_rtcp_header);
	if (status) {
	    return ( srtp_err_status_cipher_fail);
	}
    } else {
	/*
	 * Since payload encryption is not enabled, we must authenticate
	 * the entire packet as described in section 10.3 in revision 07
	 * of the draft.
	 */
	status = srtp_cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr, *pkt_octet_len);
	if (status) {
	    return ( srtp_err_status_cipher_fail);
	}
    }
    /* 
     * Process the sequence# as AAD
     */
    tseq = *trailer;
    status = srtp_cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq, sizeof(srtcp_trailer_t));
    if (status) {
        return ( srtp_err_status_cipher_fail);
    }

    /* if we're encrypting, exor keystream into the message */
    if (enc_start) {
        status = srtp_cipher_encrypt(stream->rtcp_cipher,
                                    (uint8_t*)enc_start, &enc_octet_len);
        if (status) {
            return srtp_err_status_cipher_fail;
        }
	/*
	 * Get the tag and append that to the output
	 */
	status = srtp_cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag, &tag_len);
	if (status) {
	    return ( srtp_err_status_cipher_fail);
	}
	enc_octet_len += tag_len;
    } else {
	/*
	 * Even though we're not encrypting the payload, we need
	 * to run the cipher to get the auth tag.
	 */
	unsigned int nolen = 0;
        status = srtp_cipher_encrypt(stream->rtcp_cipher, NULL, &nolen);
        if (status) {
            return srtp_err_status_cipher_fail;
        }
	/*
	 * Get the tag and append that to the output
	 */
	status = srtp_cipher_get_tag(stream->rtcp_cipher, (uint8_t*)auth_tag, &tag_len);
	if (status) {
	    return ( srtp_err_status_cipher_fail);
	}
	enc_octet_len += tag_len;
    }

    /* increase the packet length by the length of the auth tag and seq_num*/
    *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));

    return srtp_err_status_ok;
}

/*
 * This function handles incoming SRTCP packets while in AEAD mode,
 * which currently supports AES-GCM encryption.  Note, the auth tag is 
 * at the end of the packet stream and is automatically checked by GCM
 * when decrypting the payload.
 */
static srtp_err_status_t
srtp_unprotect_rtcp_aead (srtp_t ctx, srtp_stream_ctx_t *stream, 
                          void *srtcp_hdr, unsigned int *pkt_octet_len)
{
    srtcp_hdr_t *hdr = (srtcp_hdr_t*)srtcp_hdr;
    uint32_t *enc_start;        /* pointer to start of encrypted portion  */
    uint32_t *trailer;          /* pointer to start of trailer            */
    unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
    uint8_t *auth_tag = NULL;   /* location of auth_tag within packet     */
    srtp_err_status_t status;
    int tag_len;
    unsigned int tmp_len;
    uint32_t seq_num;
    v128_t iv;
    uint32_t tseq;

    /* get tag length from stream context */
    tag_len = srtp_auth_get_tag_length(stream->rtcp_auth);

    /*
     * set encryption start, encryption length, and trailer
     */
    /* index & E (encryption) bit follow normal data.  hdr->len
           is the number of words (32-bit) in the normal packet minus 1 */
    /* This should point trailer to the word past the end of the
           normal data. */
    /* This would need to be modified for optional mikey data */
    /*
     * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
     *	 multiples of 32-bits (RFC 3550 6.1)
     */
    trailer = (uint32_t*)((char*)hdr + *pkt_octet_len - sizeof(srtcp_trailer_t));
    /*
     * We pass the tag down to the cipher when doing GCM mode 
     */
    enc_octet_len = *pkt_octet_len - (octets_in_rtcp_header + 
                                      sizeof(srtcp_trailer_t));
    auth_tag = (uint8_t*)hdr + *pkt_octet_len - tag_len - sizeof(srtcp_trailer_t);

    if (*((unsigned char*)trailer) & SRTCP_E_BYTE_BIT) {
        enc_start = (uint32_t*)hdr + uint32s_in_rtcp_header;
    } else {
        enc_octet_len = 0;
        enc_start = NULL; /* this indicates that there's no encryption */
    }

    /*
     * check the sequence number for replays
     */
    /* this is easier than dealing with bitfield access */
    seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
    debug_print(mod_srtp, "srtcp index: %x", seq_num);
    status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
    if (status) {
        return status;
    }

    /*
     * Calculate and set the IV
     */
    srtp_calc_aead_iv_srtcp(stream, &iv, seq_num, hdr);
    status = srtp_cipher_set_iv(stream->rtcp_cipher, (uint8_t*)&iv, direction_decrypt);
    if (status) {
        return srtp_err_status_cipher_fail;
    }

    /*
     * Set the AAD for GCM mode
     */
    if (enc_start) {
	/*
	 * If payload encryption is enabled, then the AAD consist of
	 * the RTCP header and the seq# at the end of the packet
	 */
	status = srtp_cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr, octets_in_rtcp_header);
	if (status) {
	    return ( srtp_err_status_cipher_fail);
	}
    } else {
	/*
	 * Since payload encryption is not enabled, we must authenticate
	 * the entire packet as described in section 10.3 in revision 07
	 * of the draft.
	 */
	status = srtp_cipher_set_aad(stream->rtcp_cipher, (uint8_t*)hdr, 
			            (*pkt_octet_len - tag_len - sizeof(srtcp_trailer_t)));
	if (status) {
	    return ( srtp_err_status_cipher_fail);
	}
    }

    /* 
     * Process the sequence# as AAD 
     */
    tseq = *trailer;
    status = srtp_cipher_set_aad(stream->rtcp_cipher, (uint8_t*)&tseq, sizeof(srtcp_trailer_t));
    if (status) {
	return ( srtp_err_status_cipher_fail);
    }

    /* if we're decrypting, exor keystream into the message */
    if (enc_start) {
        status = srtp_cipher_decrypt(stream->rtcp_cipher, (uint8_t*)enc_start, &enc_octet_len);
        if (status) {
            return status;
        }
    } else {
	/*
	 * Still need to run the cipher to check the tag
	 */
	tmp_len = tag_len;
        status = srtp_cipher_decrypt(stream->rtcp_cipher, (uint8_t*)auth_tag, &tmp_len);
        if (status) {
            return status;
        }
    }

    /* decrease the packet length by the length of the auth tag and seq_num*/
    *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));

    /*
     * verify that stream is for received traffic - this check will
     * detect SSRC collisions, since a stream that appears in both
     * srtp_protect() and srtp_unprotect() will fail this test in one of
     * those functions.
     *
     * we do this check *after* the authentication check, so that the
     * latter check will catch any attempts to fool us into thinking
     * that we've got a collision
     */
    if (stream->direction != dir_srtp_receiver) {
        if (stream->direction == dir_unknown) {
            stream->direction = dir_srtp_receiver;
        } else {
            srtp_handle_event(ctx, stream, event_ssrc_collision);
        }
    }

    /*
     * if the stream is a 'provisional' one, in which the template context
     * is used, then we need to allocate a new stream at this point, since
     * the authentication passed
     */
    if (stream == ctx->stream_template) {
        srtp_stream_ctx_t *new_stream;

        /*
         * allocate and initialize a new stream
         *
         * note that we indicate failure if we can't allocate the new
         * stream, and some implementations will want to not return
         * failure here
         */
        status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
        if (status) {
            return status;
        }

        /* add new stream to the head of the stream_list */
        new_stream->next = ctx->stream_list;
        ctx->stream_list = new_stream;

        /* set stream (the pointer used in this function) */
        stream = new_stream;
    }

    /* we've passed the authentication check, so add seq_num to the rdb */
    srtp_rdb_add_index(&stream->rtcp_rdb, seq_num);

    return srtp_err_status_ok;
}

srtp_err_status_t 
srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {
  srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
  uint32_t *enc_start;      /* pointer to start of encrypted portion  */
  uint32_t *auth_start;     /* pointer to start of auth. portion      */
  uint32_t *trailer;        /* pointer to start of trailer            */
  unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
  uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */
  srtp_err_status_t status;   
  int tag_len;
  srtp_stream_ctx_t *stream;
  uint32_t prefix_len;
  uint32_t seq_num;

  /* we assume the hdr is 32-bit aligned to start */

  /* check the packet length - it must at least contain a full header */
  if (*pkt_octet_len < octets_in_rtcp_header)
    return srtp_err_status_bad_param;

  /*
   * look up ssrc in srtp_stream list, and process the packet with 
   * the appropriate stream.  if we haven't seen this stream before,
   * there's only one key for this srtp_session, and the cipher
   * supports key-sharing, then we assume that a new stream using
   * that key has just started up
   */
  stream = srtp_get_stream(ctx, hdr->ssrc);
  if (stream == NULL) {
    if (ctx->stream_template != NULL) {
      srtp_stream_ctx_t *new_stream;
      
      /* allocate and initialize a new stream */
      status = srtp_stream_clone(ctx->stream_template,
				 hdr->ssrc, &new_stream); 
      if (status)
	return status;
      
      /* add new stream to the head of the stream_list */
      new_stream->next = ctx->stream_list;
      ctx->stream_list = new_stream;
      
      /* set stream (the pointer used in this function) */
      stream = new_stream;
    } else {
      /* no template stream, so we return an error */
      return srtp_err_status_no_ctx;
    } 
  }
  
  /* 
   * verify that stream is for sending traffic - this check will
   * detect SSRC collisions, since a stream that appears in both
   * srtp_protect() and srtp_unprotect() will fail this test in one of
   * those functions.
   */
  if (stream->direction != dir_srtp_sender) {
    if (stream->direction == dir_unknown) {
      stream->direction = dir_srtp_sender;
    } else {
      srtp_handle_event(ctx, stream, event_ssrc_collision);
    }
  }  

  /*
   * Check if this is an AEAD stream (GCM mode).  If so, then dispatch
   * the request to our AEAD handler.
   */
  if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
      stream->rtp_cipher->algorithm == SRTP_AES_256_GCM) {
      return srtp_protect_rtcp_aead(ctx, stream, rtcp_hdr, (unsigned int*)pkt_octet_len);
  }

  /* get tag length from stream context */
  tag_len = srtp_auth_get_tag_length(stream->rtcp_auth); 

  /*
   * set encryption start and encryption length - if we're not
   * providing confidentiality, set enc_start to NULL
   */
  enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;  
  enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;

  /* all of the packet, except the header, gets encrypted */
  /* NOTE: hdr->length is not usable - it refers to only the first
	 RTCP report in the compound packet! */
  /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
	 multiples of 32-bits (RFC 3550 6.1) */
  trailer = (uint32_t *) ((char *)enc_start + enc_octet_len);

  if (stream->rtcp_services & sec_serv_conf) {
    *trailer = htonl(SRTCP_E_BIT);     /* set encrypt bit */    
  } else {
    enc_start = NULL;
    enc_octet_len = 0;
	/* 0 is network-order independant */
    *trailer = 0x00000000;     /* set encrypt bit */    
  }

  /* 
   * set the auth_start and auth_tag pointers to the proper locations
   * (note that srtpc *always* provides authentication, unlike srtp)
   */
  /* Note: This would need to change for optional mikey data */
  auth_start = (uint32_t *)hdr;
  auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t); 

  /* perform EKT processing if needed */
  srtp_ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len, 
		      srtp_rdbx_get_packet_index(&stream->rtp_rdbx));

  /* 
   * check sequence number for overruns, and copy it into the packet
   * if its value isn't too big
   */
  status = srtp_rdb_increment(&stream->rtcp_rdb);
  if (status)
    return status;
  seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
  *trailer |= htonl(seq_num);
  debug_print(mod_srtp, "srtcp index: %x", seq_num);

  /* 
   * if we're using rindael counter mode, set nonce and seq 
   */
  if (stream->rtcp_cipher->type->id == SRTP_AES_ICM) {
    v128_t iv;
    
    iv.v32[0] = 0;
    iv.v32[1] = hdr->ssrc;  /* still in network order! */
    iv.v32[2] = htonl(seq_num >> 16);
    iv.v32[3] = htonl(seq_num << 16);
    status = srtp_cipher_set_iv(stream->rtcp_cipher, (uint8_t*)&iv, direction_encrypt);

  } else {  
    v128_t iv;
    
    /* otherwise, just set the index to seq_num */  
    iv.v32[0] = 0;
    iv.v32[1] = 0;
    iv.v32[2] = 0;
    iv.v32[3] = htonl(seq_num);
    status = srtp_cipher_set_iv(stream->rtcp_cipher, (uint8_t*)&iv, direction_encrypt);
  }
  if (status)
    return srtp_err_status_cipher_fail;

  /* 
   * if we're authenticating using a universal hash, put the keystream
   * prefix into the authentication tag
   */
  
  /* if auth_start is non-null, then put keystream into tag  */
  if (auth_start) {

    /* put keystream prefix into auth_tag */
    prefix_len = srtp_auth_get_prefix_length(stream->rtcp_auth);    
    status = srtp_cipher_output(stream->rtcp_cipher, auth_tag, &prefix_len);

    debug_print(mod_srtp, "keystream prefix: %s", 
		srtp_octet_string_hex_string(auth_tag, prefix_len));

    if (status)
      return srtp_err_status_cipher_fail;
  }

  /* if we're encrypting, exor keystream into the message */
  if (enc_start) {
    status = srtp_cipher_encrypt(stream->rtcp_cipher, 
		  	        (uint8_t *)enc_start, &enc_octet_len);
    if (status)
      return srtp_err_status_cipher_fail;
  }

  /* initialize auth func context */
  auth_start(stream->rtcp_auth);

  /* 
   * run auth func over packet (including trailer), and write the
   * result at auth_tag 
   */
  status = auth_compute(stream->rtcp_auth, 
			(uint8_t *)auth_start, 
			(*pkt_octet_len) + sizeof(srtcp_trailer_t), 
			auth_tag);
  debug_print(mod_srtp, "srtcp auth tag:    %s", 
	      srtp_octet_string_hex_string(auth_tag, tag_len));
  if (status)
    return srtp_err_status_auth_fail;   
    
  /* increase the packet length by the length of the auth tag and seq_num*/
  *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
    
  return srtp_err_status_ok;  
}


srtp_err_status_t 
srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) {
  srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
  uint32_t *enc_start;      /* pointer to start of encrypted portion  */
  uint32_t *auth_start;     /* pointer to start of auth. portion      */
  uint32_t *trailer;        /* pointer to start of trailer            */
  unsigned int enc_octet_len = 0;/* number of octets in encrypted portion */
  uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */
  uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
  uint8_t tag_copy[SRTP_MAX_TAG_LEN];
  srtp_err_status_t status;   
  unsigned int auth_len;
  int tag_len;
  srtp_stream_ctx_t *stream;
  uint32_t prefix_len;
  uint32_t seq_num;
  int e_bit_in_packet;     /* whether the E-bit was found in the packet */
  int sec_serv_confidentiality; /* whether confidentiality was requested */

  /* we assume the hdr is 32-bit aligned to start */

  /* check that the length value is sane; we'll check again once we
     know the tag length, but we at least want to know that it is
     a positive value */
  if (*pkt_octet_len < octets_in_rtcp_header + sizeof(srtcp_trailer_t))
    return srtp_err_status_bad_param;

  /*
   * look up ssrc in srtp_stream list, and process the packet with 
   * the appropriate stream.  if we haven't seen this stream before,
   * there's only one key for this srtp_session, and the cipher
   * supports key-sharing, then we assume that a new stream using
   * that key has just started up
   */
  stream = srtp_get_stream(ctx, hdr->ssrc);
  if (stream == NULL) {
    if (ctx->stream_template != NULL) {
      stream = ctx->stream_template;

      /* 
       * check to see if stream_template has an EKT data structure, in
       * which case we initialize the template using the EKT policy
       * referenced by that data (which consists of decrypting the
       * master key from the EKT field)
       *
       * this function initializes a *provisional* stream, and this
       * stream should not be accepted until and unless the packet
       * passes its authentication check
       */ 
      if (stream->ekt != NULL) {
	status = srtp_stream_init_from_ekt(stream, srtcp_hdr, *pkt_octet_len);
	if (status)
	  return status;
      }

      debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)", 
		  hdr->ssrc);
    } else {
      /* no template stream, so we return an error */
      return srtp_err_status_no_ctx;
    } 
  }
  
  /* get tag length from stream context */
  tag_len = srtp_auth_get_tag_length(stream->rtcp_auth);

  /* check the packet length - it must contain at least a full RTCP
     header, an auth tag (if applicable), and the SRTCP encrypted flag
     and 31-bit index value */
  if (*pkt_octet_len < (int) (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t))) {
    return srtp_err_status_bad_param;
  }

  /*
   * Check if this is an AEAD stream (GCM mode).  If so, then dispatch
   * the request to our AEAD handler.
   */
  if (stream->rtp_cipher->algorithm == SRTP_AES_128_GCM ||
      stream->rtp_cipher->algorithm == SRTP_AES_256_GCM) {
      return srtp_unprotect_rtcp_aead(ctx, stream, srtcp_hdr, (unsigned int*)pkt_octet_len);
  }

  sec_serv_confidentiality = stream->rtcp_services == sec_serv_conf ||
      stream->rtcp_services == sec_serv_conf_and_auth;

  /*
   * set encryption start, encryption length, and trailer
   */
  enc_octet_len = *pkt_octet_len - 
                  (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t));
  /* index & E (encryption) bit follow normal data.  hdr->len
	 is the number of words (32-bit) in the normal packet minus 1 */
  /* This should point trailer to the word past the end of the
	 normal data. */
  /* This would need to be modified for optional mikey data */
  /*
   * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
   *	 multiples of 32-bits (RFC 3550 6.1)
   */
  trailer = (uint32_t *) ((char *) hdr +
      *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t)));
  e_bit_in_packet =
      (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) == SRTCP_E_BYTE_BIT;
  if (e_bit_in_packet != sec_serv_confidentiality) {
    return srtp_err_status_cant_check;
  }
  if (sec_serv_confidentiality) {
    enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;  
  } else {
    enc_octet_len = 0;
    enc_start = NULL; /* this indicates that there's no encryption */
  }

  /* 
   * set the auth_start and auth_tag pointers to the proper locations
   * (note that srtcp *always* uses authentication, unlike srtp)
   */
  auth_start = (uint32_t *)hdr;
  auth_len = *pkt_octet_len - tag_len;
  auth_tag = (uint8_t *)hdr + auth_len;

  /* 
   * if EKT is in use, then we make a copy of the tag from the packet,
   * and then zeroize the location of the base tag
   *
   * we first re-position the auth_tag pointer so that it points to
   * the base tag
   */
  if (stream->ekt) {
    auth_tag -= srtp_ekt_octets_after_base_tag(stream->ekt);
    memcpy(tag_copy, auth_tag, tag_len);
    octet_string_set_to_zero(auth_tag, tag_len);
    auth_tag = tag_copy;
    auth_len += tag_len;
  }

  /* 
   * check the sequence number for replays
   */
  /* this is easier than dealing with bitfield access */
  seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
  debug_print(mod_srtp, "srtcp index: %x", seq_num);
  status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
  if (status)
    return status;

  /* 
   * if we're using aes counter mode, set nonce and seq 
   */
  if (stream->rtcp_cipher->type->id == SRTP_AES_ICM) {
    v128_t iv;

    iv.v32[0] = 0;
    iv.v32[1] = hdr->ssrc; /* still in network order! */
    iv.v32[2] = htonl(seq_num >> 16);
    iv.v32[3] = htonl(seq_num << 16);
    status = srtp_cipher_set_iv(stream->rtcp_cipher, (uint8_t*)&iv, direction_decrypt);

  } else {  
    v128_t iv;
    
    /* otherwise, just set the index to seq_num */  
    iv.v32[0] = 0;
    iv.v32[1] = 0;
    iv.v32[2] = 0;
    iv.v32[3] = htonl(seq_num);
    status = srtp_cipher_set_iv(stream->rtcp_cipher, (uint8_t*)&iv, direction_decrypt);

  }
  if (status)
    return srtp_err_status_cipher_fail;

  /* initialize auth func context */
  auth_start(stream->rtcp_auth);

  /* run auth func over packet, put result into tmp_tag */
  status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start,  
			auth_len, tmp_tag);
  debug_print(mod_srtp, "srtcp computed tag:       %s", 
	      srtp_octet_string_hex_string(tmp_tag, tag_len));
  if (status)
    return srtp_err_status_auth_fail;   
  
  /* compare the tag just computed with the one in the packet */
  debug_print(mod_srtp, "srtcp tag from packet:    %s", 
	      srtp_octet_string_hex_string(auth_tag, tag_len));  
  if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
    return srtp_err_status_auth_fail;

  /* 
   * if we're authenticating using a universal hash, put the keystream
   * prefix into the authentication tag
   */
  prefix_len = srtp_auth_get_prefix_length(stream->rtcp_auth);    
  if (prefix_len) {
    status = srtp_cipher_output(stream->rtcp_cipher, auth_tag, &prefix_len);
    debug_print(mod_srtp, "keystream prefix: %s", 
		srtp_octet_string_hex_string(auth_tag, prefix_len));
    if (status)
      return srtp_err_status_cipher_fail;
  }

  /* if we're decrypting, exor keystream into the message */
  if (enc_start) {
    status = srtp_cipher_decrypt(stream->rtcp_cipher, (uint8_t *)enc_start, &enc_octet_len);
    if (status)
      return srtp_err_status_cipher_fail;
  }

  /* decrease the packet length by the length of the auth tag and seq_num */
  *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));

  /*
   * if EKT is in effect, subtract the EKT data out of the packet
   * length
   */
  *pkt_octet_len -= srtp_ekt_octets_after_base_tag(stream->ekt);

  /* 
   * verify that stream is for received traffic - this check will
   * detect SSRC collisions, since a stream that appears in both
   * srtp_protect() and srtp_unprotect() will fail this test in one of
   * those functions.
   *
   * we do this check *after* the authentication check, so that the
   * latter check will catch any attempts to fool us into thinking
   * that we've got a collision
   */
  if (stream->direction != dir_srtp_receiver) {
    if (stream->direction == dir_unknown) {
      stream->direction = dir_srtp_receiver;
    } else {
      srtp_handle_event(ctx, stream, event_ssrc_collision);
    }
  }

  /* 
   * if the stream is a 'provisional' one, in which the template context
   * is used, then we need to allocate a new stream at this point, since
   * the authentication passed
   */
  if (stream == ctx->stream_template) {  
    srtp_stream_ctx_t *new_stream;

    /* 
     * allocate and initialize a new stream 
     * 
     * note that we indicate failure if we can't allocate the new
     * stream, and some implementations will want to not return
     * failure here
     */
    status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); 
    if (status)
      return status;
    
    /* add new stream to the head of the stream_list */
    new_stream->next = ctx->stream_list;
    ctx->stream_list = new_stream;
    
    /* set stream (the pointer used in this function) */
    stream = new_stream;
  }

  /* we've passed the authentication check, so add seq_num to the rdb */
  srtp_rdb_add_index(&stream->rtcp_rdb, seq_num);
    
    
  return srtp_err_status_ok;  
}


/*
 * user data within srtp_t context
 */

void
srtp_set_user_data(srtp_t ctx, void *data) {
  ctx->user_data = data;
}

void*
srtp_get_user_data(srtp_t ctx) {
  return ctx->user_data;
}


/*
 * dtls keying for srtp 
 */

srtp_err_status_t
srtp_crypto_policy_set_from_profile_for_rtp(srtp_crypto_policy_t *policy, 
				            srtp_profile_t profile) {

  /* set SRTP policy from the SRTP profile in the key set */
  switch(profile) {
  case srtp_profile_aes128_cm_sha1_80:
    srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
    break;
  case srtp_profile_aes128_cm_sha1_32:
    srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);
    break;
  case srtp_profile_null_sha1_80:
    srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
    break;
  case srtp_profile_aes256_cm_sha1_80:
    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
    break;
  case srtp_profile_aes256_cm_sha1_32:
    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(policy);
    break;
    /* the following profiles are not (yet) supported */
  case srtp_profile_null_sha1_32:
  default:
    return srtp_err_status_bad_param;
  }

  return srtp_err_status_ok;
}

srtp_err_status_t
srtp_crypto_policy_set_from_profile_for_rtcp(srtp_crypto_policy_t *policy, 
					     srtp_profile_t profile) {

  /* set SRTP policy from the SRTP profile in the key set */
  switch(profile) {
  case srtp_profile_aes128_cm_sha1_80:
    srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
    break;
  case srtp_profile_aes128_cm_sha1_32:
    /* We do not honor the 32-bit auth tag request since
     * this is not compliant with RFC 3711 */
    srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
    break;
  case srtp_profile_null_sha1_80:
    srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
    break;
  case srtp_profile_aes256_cm_sha1_80:
    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
    break;
  case srtp_profile_aes256_cm_sha1_32:
    /* We do not honor the 32-bit auth tag request since
     * this is not compliant with RFC 3711 */
    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
    break;
    /* the following profiles are not (yet) supported */
  case srtp_profile_null_sha1_32:
  default:
    return srtp_err_status_bad_param;
  }

  return srtp_err_status_ok;
}

void srtp_append_salt_to_key(uint8_t *key, unsigned int bytes_in_key, uint8_t *salt, unsigned int bytes_in_salt) {
  memcpy(key + bytes_in_key, salt, bytes_in_salt);
}

unsigned int
srtp_profile_get_master_key_length(srtp_profile_t profile) {

  switch(profile) {
  case srtp_profile_aes128_cm_sha1_80:
    return 16;
    break;
  case srtp_profile_aes128_cm_sha1_32:
    return 16;
    break;
  case srtp_profile_null_sha1_80:
    return 16;
    break;
  case srtp_profile_aes256_cm_sha1_80:
    return 32;
    break;
  case srtp_profile_aes256_cm_sha1_32:
    return 32;
    break;
    /* the following profiles are not (yet) supported */
  case srtp_profile_null_sha1_32:
  default:
    return 0;  /* indicate error by returning a zero */
  }
}

unsigned int
srtp_profile_get_master_salt_length(srtp_profile_t profile) {

  switch(profile) {
  case srtp_profile_aes128_cm_sha1_80:
    return 14;
    break;
  case srtp_profile_aes128_cm_sha1_32:
    return 14;
    break;
  case srtp_profile_null_sha1_80:
    return 14;
    break;
  case srtp_profile_aes256_cm_sha1_80:
    return 14;
    break;
  case srtp_profile_aes256_cm_sha1_32:
    return 14;
    break;
    /* the following profiles are not (yet) supported */
  case srtp_profile_null_sha1_32:
  default:
    return 0;  /* indicate error by returning a zero */
  }
}

/*
 * SRTP debug interface
 */
srtp_err_status_t srtp_set_debug_module(char *mod_name, int v)
{
    return srtp_crypto_kernel_set_debug_module(mod_name, v);
}

srtp_err_status_t srtp_list_debug_modules(void)
{
    return srtp_crypto_kernel_list_debug_modules();
}

