/*
 * aes_icm.c
 *
 * AES Integer Counter Mode
 *
 * 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.
 *
 */


#define ALIGN_32 0

#include "aes_icm.h"
#include "alloc.h"


debug_module_t mod_aes_icm = {
  0,                 /* debugging is off by default */
  "aes icm"          /* printable module name       */
};

/*
 * integer counter mode works as follows:
 *
 * 16 bits
 * <----->
 * +------+------+------+------+------+------+------+------+ 
 * |           nonce           |    pakcet index    |  ctr |---+
 * +------+------+------+------+------+------+------+------+   |
 *                                                             |
 * +------+------+------+------+------+------+------+------+   v
 * |                      salt                      |000000|->(+)
 * +------+------+------+------+------+------+------+------+   |
 *                                                             |
 *                                                        +---------+
 *							  | encrypt |
 *							  +---------+
 *							       | 
 * +------+------+------+------+------+------+------+------+   |
 * |                    keystream block                    |<--+ 
 * +------+------+------+------+------+------+------+------+   
 *
 * All fields are big-endian
 *
 * ctr is the block counter, which increments from zero for
 * each packet (16 bits wide)
 * 
 * packet index is distinct for each packet (48 bits wide)
 *
 * nonce can be distinct across many uses of the same key, or
 * can be a fixed value per key, or can be per-packet randomness
 * (64 bits)
 *
 */

err_status_t
aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) {
  extern cipher_type_t aes_icm;
  uint8_t *pointer;
  int tmp;

  debug_print(mod_aes_icm, 
            "allocating cipher with key length %d", key_len);

  /*
   * Ismacryp, for example, uses 16 byte key + 8 byte 
   * salt  so this function is called with key_len = 24.
   * The check for key_len = 30 does not apply. Our usage
   * of aes functions with key_len = values other than 30
   * has not broken anything. Don't know what would be the
   * effect of skipping this check for srtp in general.
   */
  if (!forIsmacryp && key_len != 30)
    return err_status_bad_param;

  /* allocate memory a cipher of type aes_icm */
  tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
  pointer = (uint8_t*)crypto_alloc(tmp);
  if (pointer == NULL) 
    return err_status_alloc_fail;

  /* set pointers */
  *c = (cipher_t *)pointer;
  (*c)->type = &aes_icm;
  (*c)->state = pointer + sizeof(cipher_t);

  /* increment ref_count */
  aes_icm.ref_count++;

  /* set key size        */
  (*c)->key_len = key_len;

  return err_status_ok;  
}

err_status_t aes_icm_alloc(cipher_t **c, int key_len, int forIsmacryp) {
  return aes_icm_alloc_ismacryp(c, key_len, 0);
}

err_status_t
aes_icm_dealloc(cipher_t *c) {
  extern cipher_type_t aes_icm;

  /* zeroize entire state*/
  octet_string_set_to_zero((uint8_t *)c, 
			   sizeof(aes_icm_ctx_t) + sizeof(cipher_t));

  /* free memory */
  crypto_free(c);

  /* decrement ref_count */
  aes_icm.ref_count--;
  
  return err_status_ok;  
}


/*
 * aes_icm_context_init(...) initializes the aes_icm_context
 * using the value in key[].
 *
 * the key is the secret key 
 *
 * the salt is unpredictable (but not necessarily secret) data which
 * randomizes the starting point in the keystream
 */

err_status_t
aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key) {
  v128_t tmp_key;

  /* set counter and initial values to 'offset' value */
  /* FIX!!! this assumes the salt is at key + 16, and thus that the */
  /* FIX!!! cipher key length is 16!  Also note this copies past the
            end of the 'key' array by 2 bytes! */
  v128_copy_octet_string(&c->counter, key + 16);
  v128_copy_octet_string(&c->offset, key + 16);

  /* force last two octets of the offset to zero (for srtp compatibility) */
  c->offset.v8[14] = c->offset.v8[15] = 0;
  c->counter.v8[14] = c->counter.v8[15] = 0;
  
  /* set tmp_key (for alignment) */
  v128_copy_octet_string(&tmp_key, key);

  debug_print(mod_aes_icm, 
	      "key:  %s", v128_hex_string(&tmp_key)); 
  debug_print(mod_aes_icm, 
	      "offset: %s", v128_hex_string(&c->offset)); 

  /* expand key */
  aes_expand_encryption_key(&tmp_key, c->expanded_key);

  /* indicate that the keystream_buffer is empty */
  c->bytes_in_buffer = 0;

  return err_status_ok;
}

/*
 * aes_icm_set_octet(c, i) sets the counter of the context which it is
 * passed so that the next octet of keystream that will be generated
 * is the ith octet
 */

err_status_t
aes_icm_set_octet(aes_icm_ctx_t *c,
		  uint64_t octet_num) {

#ifdef NO_64BIT_MATH
  int tail_num       = low32(octet_num) & 0x0f;
  /* 64-bit right-shift 4 */
  uint64_t block_num = make64(high32(octet_num) >> 4,
							  ((high32(octet_num) & 0x0f)<<(32-4)) |
							   (low32(octet_num) >> 4));
#else
  int tail_num       = octet_num % 16;
  uint64_t block_num = octet_num / 16;
#endif
  

  /* set counter value */
  /* FIX - There's no way this is correct */
  c->counter.v64[0] = c->offset.v64[0];
#ifdef NO_64BIT_MATH
  c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num),
							 low32(c->offset.v64[0])  ^ low32(block_num));
#else
  c->counter.v64[0] = c->offset.v64[0] ^ block_num;
#endif

  debug_print(mod_aes_icm, 
	      "set_octet: %s", v128_hex_string(&c->counter)); 

  /* fill keystream buffer, if needed */
  if (tail_num) {
    v128_copy(&c->keystream_buffer, &c->counter);
    aes_encrypt(&c->keystream_buffer, c->expanded_key);
    c->bytes_in_buffer = sizeof(v128_t);

    debug_print(mod_aes_icm, "counter:    %s", 
	      v128_hex_string(&c->counter));
    debug_print(mod_aes_icm, "ciphertext: %s", 
	      v128_hex_string(&c->keystream_buffer));    
    
    /*  indicate number of bytes in keystream_buffer  */
    c->bytes_in_buffer = sizeof(v128_t) - tail_num;
  
  } else {
    
    /* indicate that keystream_buffer is empty */
    c->bytes_in_buffer = 0;
  }

  return err_status_ok;
}

/*
 * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
 * the offset
 */

err_status_t
aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {
  v128_t *nonce = (v128_t *) iv;

  debug_print(mod_aes_icm, 
	      "setting iv: %s", v128_hex_string(nonce)); 
 
  v128_xor(&c->counter, &c->offset, nonce);
  
  debug_print(mod_aes_icm, 
	      "set_counter: %s", v128_hex_string(&c->counter)); 

  /* indicate that the keystream_buffer is empty */
  c->bytes_in_buffer = 0;

  return err_status_ok;
}



/*
 * aes_icm_advance(...) refills the keystream_buffer and
 * advances the block index of the sicm_context forward by one
 *
 * this is an internal, hopefully inlined function
 */
  
static inline void
aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) {
  /* fill buffer with new keystream */
  v128_copy(&c->keystream_buffer, &c->counter);
  aes_encrypt(&c->keystream_buffer, c->expanded_key);
  c->bytes_in_buffer = sizeof(v128_t);

  debug_print(mod_aes_icm, "counter:    %s", 
	      v128_hex_string(&c->counter));
  debug_print(mod_aes_icm, "ciphertext: %s", 
	      v128_hex_string(&c->keystream_buffer));    
  
  /* clock counter forward */

  if (forIsmacryp) {
    uint32_t temp;    
    //alex's clock counter forward
    temp = ntohl(c->counter.v32[3]);
    c->counter.v32[3] = htonl(++temp);
  } else {
    if (!++(c->counter.v8[15])) 
      ++(c->counter.v8[14]);
  }
}

inline void aes_icm_advance(aes_icm_ctx_t *c) {
  aes_icm_advance_ismacryp(c, 0);
}


/*e
 * icm_encrypt deals with the following cases:
 *
 * bytes_to_encr < bytes_in_buffer
 *  - add keystream into data
 *
 * bytes_to_encr > bytes_in_buffer
 *  - add keystream into data until keystream_buffer is depleted
 *  - loop over blocks, filling keystream_buffer and then
 *    adding keystream into data
 *  - fill buffer then add in remaining (< 16) bytes of keystream 
 */

err_status_t
aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,
              unsigned char *buf, unsigned int *enc_len, 
              int forIsmacryp) {
  unsigned int bytes_to_encr = *enc_len;
  unsigned int i;
  uint32_t *b;

  /* check that there's enough segment left but not for ismacryp*/
  if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff)
    return err_status_terminus;

 debug_print(mod_aes_icm, "block index: %d", 
           htons(c->counter.v16[7]));
  if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
    
    /* deal with odd case of small bytes_to_encr */
    for (i = (sizeof(v128_t) - c->bytes_in_buffer);
		 i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++) 
	{
      *buf++ ^= c->keystream_buffer.v8[i];
	}

    c->bytes_in_buffer -= bytes_to_encr;

    /* return now to avoid the main loop */
    return err_status_ok;

  } else {
    
    /* encrypt bytes until the remaining data is 16-byte aligned */    
    for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++) 
      *buf++ ^= c->keystream_buffer.v8[i];

    bytes_to_encr -= c->bytes_in_buffer;
    c->bytes_in_buffer = 0;

  }
  
  /* now loop over entire 16-byte blocks of keystream */
  for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) {

    /* fill buffer with new keystream */
    aes_icm_advance_ismacryp(c, forIsmacryp);

    /*
     * add keystream into the data buffer (this would be a lot faster
     * if we could assume 32-bit alignment!)
     */

#if ALIGN_32
    b = (uint32_t *)buf;
    *b++ ^= c->keystream_buffer.v32[0];
    *b++ ^= c->keystream_buffer.v32[1];
    *b++ ^= c->keystream_buffer.v32[2];
    *b++ ^= c->keystream_buffer.v32[3];
    buf = (uint8_t *)b;
#else    
    if ((((unsigned long) buf) & 0x03) != 0) {
      *buf++ ^= c->keystream_buffer.v8[0];
      *buf++ ^= c->keystream_buffer.v8[1];
      *buf++ ^= c->keystream_buffer.v8[2];
      *buf++ ^= c->keystream_buffer.v8[3];
      *buf++ ^= c->keystream_buffer.v8[4];
      *buf++ ^= c->keystream_buffer.v8[5];
      *buf++ ^= c->keystream_buffer.v8[6];
      *buf++ ^= c->keystream_buffer.v8[7];
      *buf++ ^= c->keystream_buffer.v8[8];
      *buf++ ^= c->keystream_buffer.v8[9];
      *buf++ ^= c->keystream_buffer.v8[10];
      *buf++ ^= c->keystream_buffer.v8[11];
      *buf++ ^= c->keystream_buffer.v8[12];
      *buf++ ^= c->keystream_buffer.v8[13];
      *buf++ ^= c->keystream_buffer.v8[14];
      *buf++ ^= c->keystream_buffer.v8[15];
    } else {
      b = (uint32_t *)buf;
      *b++ ^= c->keystream_buffer.v32[0];
      *b++ ^= c->keystream_buffer.v32[1];
      *b++ ^= c->keystream_buffer.v32[2];
      *b++ ^= c->keystream_buffer.v32[3];
      buf = (uint8_t *)b;
    }
#endif /* #if ALIGN_32 */

  }
  
  /* if there is a tail end of the data, process it */
  if ((bytes_to_encr & 0xf) != 0) {
    
    /* fill buffer with new keystream */
    aes_icm_advance_ismacryp(c, forIsmacryp);
    
    for (i=0; i < (bytes_to_encr & 0xf); i++)
      *buf++ ^= c->keystream_buffer.v8[i];
    
    /* reset the keystream buffer size to right value */
    c->bytes_in_buffer = sizeof(v128_t) - i;  
  } else {

    /* no tail, so just reset the keystream buffer size to zero */
    c->bytes_in_buffer = 0;

  }

  return err_status_ok;
}

err_status_t
aes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) {
  return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0);
}

err_status_t
aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) {
  unsigned int len = num_octets_to_output;
  
  /* zeroize the buffer */
  octet_string_set_to_zero(buffer, num_octets_to_output);
  
  /* exor keystream into buffer */
  return aes_icm_encrypt(c, buffer, &len);
}


char 
aes_icm_description[] = "aes integer counter mode";

uint8_t aes_icm_test_case_0_key[30] = {
  0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
};

uint8_t aes_icm_test_case_0_nonce[16] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

uint8_t aes_icm_test_case_0_plaintext[32] =  {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
};

uint8_t aes_icm_test_case_0_ciphertext[32] = {
  0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
  0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
  0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
  0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
};

cipher_test_case_t aes_icm_test_case_0 = {
  30,                                    /* octets in key            */
  aes_icm_test_case_0_key,               /* key                      */
  aes_icm_test_case_0_nonce,             /* packet index             */
  32,                                    /* octets in plaintext      */
  aes_icm_test_case_0_plaintext,         /* plaintext                */
  32,                                    /* octets in ciphertext     */
  aes_icm_test_case_0_ciphertext,        /* ciphertext               */
  NULL                                   /* pointer to next testcase */
};


/*
 * note: the encrypt function is identical to the decrypt function
 */

cipher_type_t aes_icm = {
  (cipher_alloc_func_t)          aes_icm_alloc,
  (cipher_dealloc_func_t)        aes_icm_dealloc,  
  (cipher_init_func_t)           aes_icm_context_init,
  (cipher_encrypt_func_t)        aes_icm_encrypt,
  (cipher_decrypt_func_t)        aes_icm_encrypt,
  (cipher_set_iv_func_t)         aes_icm_set_iv,
  (char *)                       aes_icm_description,
  (int)                          0,   /* instance count */
  (cipher_test_case_t *)        &aes_icm_test_case_0,
  (debug_module_t *)            &mod_aes_icm
};

