/*
 * ekt.c
 *
 * Encrypted Key Transport for SRTP
 * 
 * David 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 "err.h"
#include "srtp_priv.h"
#include "ekt.h"

extern debug_module_t mod_srtp;

/*
 *  The EKT Authentication Tag format.
 *
 *    0                   1                   2                   3
 *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *   :                   Base Authentication Tag                     :
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *   :                     Encrypted Master Key                      :
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *   |                       Rollover Counter                        |
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *   |    Initial Sequence Number    |   Security Parameter Index    |
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 */			 

#define EKT_OCTETS_AFTER_BASE_TAG 24
#define EKT_OCTETS_AFTER_EMK       8
#define EKT_OCTETS_AFTER_ROC       4
#define EKT_SPI_LEN                2

unsigned
ekt_octets_after_base_tag(ekt_stream_t ekt) {
  /*
   * if the pointer ekt is NULL, then EKT is not in effect, so we
   * indicate this by returning zero
   */
  if (!ekt)
    return 0;

  switch(ekt->data->ekt_cipher_type) {
  case EKT_CIPHER_AES_128_ECB:
    return 16 + EKT_OCTETS_AFTER_EMK;
    break;
  default:
    break;
  }
  return 0;
}

static inline ekt_spi_t
srtcp_packet_get_ekt_spi(const uint8_t *packet_start, unsigned pkt_octet_len) {
  const uint8_t *spi_location;
  
  spi_location = packet_start + (pkt_octet_len - EKT_SPI_LEN);
  
  return *((const ekt_spi_t *)spi_location);
}

static inline uint32_t
srtcp_packet_get_ekt_roc(const uint8_t *packet_start, unsigned pkt_octet_len) {
  const uint8_t *roc_location;
  
  roc_location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_ROC);
  
  return *((const uint32_t *)roc_location);
}

static inline const uint8_t *
srtcp_packet_get_emk_location(const uint8_t *packet_start, 
			      unsigned pkt_octet_len) {
  const uint8_t *location;
  
  location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_BASE_TAG);

  return location;
}


err_status_t 
ekt_alloc(ekt_stream_t *stream_data, ekt_policy_t policy) {

  /*
   * if the policy pointer is NULL, then EKT is not in use
   * so we just set the EKT stream data pointer to NULL
   */
  if (!policy) {
    *stream_data = NULL;
    return err_status_ok;
  }

  /* TODO */
  *stream_data = NULL;

  return err_status_ok;
}

err_status_t
ekt_stream_init_from_policy(ekt_stream_t stream_data, ekt_policy_t policy) {
  if (!stream_data)
    return err_status_ok;

  return err_status_ok;
}


void
aes_decrypt_with_raw_key(void *ciphertext, const void *key) {
  aes_expanded_key_t expanded_key;

  aes_expand_decryption_key(key, expanded_key);
  aes_decrypt(ciphertext, expanded_key);
}

/*
 * The function srtp_stream_init_from_ekt() initializes a stream using
 * the EKT data from an SRTCP trailer.  
 */

err_status_t
srtp_stream_init_from_ekt(srtp_stream_t stream,			  
			  const void *srtcp_hdr,
			  unsigned pkt_octet_len) {
  err_status_t err;
  const uint8_t *master_key;
  srtp_policy_t srtp_policy;
  unsigned master_key_len;
  uint32_t roc;

  /*
   * NOTE: at present, we only support a single ekt_policy at a time.  
   */
  if (stream->ekt->data->spi != 
      srtcp_packet_get_ekt_spi(srtcp_hdr, pkt_octet_len))
    return err_status_no_ctx;

  if (stream->ekt->data->ekt_cipher_type != EKT_CIPHER_AES_128_ECB)
    return err_status_bad_param;
  master_key_len = 16;

  /* decrypt the Encrypted Master Key field */
  master_key = srtcp_packet_get_emk_location(srtcp_hdr, pkt_octet_len);
  aes_decrypt_with_raw_key((void*)master_key, stream->ekt->data->ekt_dec_key);

  /* set the SRTP ROC */
  roc = srtcp_packet_get_ekt_roc(srtcp_hdr, pkt_octet_len);
  err = rdbx_set_roc(&stream->rtp_rdbx, roc);
  if (err) return err;

  err = srtp_stream_init(stream, &srtp_policy);
  if (err) return err;

  return err_status_ok;
}

void
ekt_write_data(ekt_stream_t ekt,
	       void *base_tag, 
	       unsigned base_tag_len, 
	       int *packet_len,
	       xtd_seq_num_t pkt_index) {
  uint32_t roc;
  uint16_t isn;
  unsigned emk_len;
  uint8_t *packet;

  /* if the pointer ekt is NULL, then EKT is not in effect */
  if (!ekt) {
    debug_print(mod_srtp, "EKT not in use", NULL);
    return;
  }

  /* write zeros into the location of the base tag */
  octet_string_set_to_zero(base_tag, base_tag_len);
  packet = (uint8_t*)base_tag + base_tag_len;

  /* copy encrypted master key into packet */
  emk_len = ekt_octets_after_base_tag(ekt);
  memcpy(packet, ekt->encrypted_master_key, emk_len);
  debug_print(mod_srtp, "writing EKT EMK: %s,", 
	      octet_string_hex_string(packet, emk_len));
  packet += emk_len;

  /* copy ROC into packet */
  roc = (uint32_t)(pkt_index >> 16);
  *((uint32_t *)packet) = be32_to_cpu(roc);
  debug_print(mod_srtp, "writing EKT ROC: %s,", 
	      octet_string_hex_string(packet, sizeof(roc)));
  packet += sizeof(roc);

  /* copy ISN into packet */
  isn = (uint16_t)pkt_index;
  *((uint16_t *)packet) = htons(isn);
  debug_print(mod_srtp, "writing EKT ISN: %s,", 
	      octet_string_hex_string(packet, sizeof(isn)));
  packet += sizeof(isn);

  /* copy SPI into packet */
  *((uint16_t *)packet) = htons(ekt->data->spi);
  debug_print(mod_srtp, "writing EKT SPI: %s,", 
	      octet_string_hex_string(packet, sizeof(ekt->data->spi)));

  /* increase packet length appropriately */
  *packet_len += EKT_OCTETS_AFTER_EMK + emk_len;
}


/*
 * The function call srtcp_ekt_trailer(ekt, auth_len, auth_tag   )
 * 
 * If the pointer ekt is NULL, then the other inputs are unaffected.
 *
 * auth_tag is a pointer to the pointer to the location of the
 * authentication tag in the packet.  If EKT is in effect, then the
 * auth_tag pointer is set to the location 
 */

void
srtcp_ekt_trailer(ekt_stream_t ekt,
		  unsigned *auth_len,
		  void **auth_tag,
		  void *tag_copy) {
  
  /* 
   * if there is no EKT policy, then the other inputs are unaffected
   */
  if (!ekt) 
    return;
      
  /* copy auth_tag into temporary location */
  
}

