/*
 * 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;
}

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);
}

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);
}

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, int key_len) {
  aes_expanded_key_t expanded_key;

  aes_expand_decryption_key(key, key_len, &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);
  /* FIX!? This decrypts the master key in-place, and never uses it */
  /* FIX!? It's also passing to ekt_dec_key (which is an aes_expanded_key_t)
   * to a function which expects a raw (unexpanded) key */
  aes_decrypt_with_raw_key((void*)master_key, &stream->ekt->data->ekt_dec_key, 16);

  /* 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,
	       uint8_t *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 = 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 */
  
}

