/*
 ---------------------------------------------------------------------------
 Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
 All rights reserved.

 LICENSE TERMS

 The free distribution and use of this software in both source and binary
 form is allowed (with or without changes) provided that:

   1. distributions of this source code include the above copyright
      notice, this list of conditions and the following disclaimer;

   2. distributions in binary form include the above copyright
      notice, this list of conditions and the following disclaimer
      in the documentation and/or other associated materials;

   3. the copyright holder's name is not used to endorse products
      built using this software without specific written permission.

 ALTERNATIVELY, provided that this notice is retained in full, this product
 may be distributed under the terms of the GNU General Public License (GPL),
 in which case the provisions of the GPL apply INSTEAD OF those given above.

 DISCLAIMER

 This software is provided 'as is' with no explicit or implied warranties
 in respect of its properties, including, but not limited to, correctness
 and/or fitness for purpose.
 ---------------------------------------------------------------------------
 Issue Date: 20/02/2003

 This file contains the code for implementing encryption and authentication
 using AES with a Carter-Wegamn hash function  
*/

#ifndef _AESCWC_H
#define _AESCWC_H

#include <memory.h>
#include "aes.h"

#if defined(__cplusplus)
extern "C"
{
#endif

#define	BLOCK_LEN	(AES_BLOCK_SIZE / 4)

typedef double cwc_ht[6];
typedef double cwc_zt[6];

typedef unsigned char	uchar;
typedef	unsigned short	ushrt;
typedef unsigned long	ulong;

typedef struct
{   uchar	nonce[4 * BLOCK_LEN];	/* nonce buffer					*/
    uchar	xor_buf[4 * BLOCK_LEN];	/* encrypted data buffer		*/
	ulong	cwc_buf[BLOCK_LEN];		/* authentication data buffer	*/
	cwc_zt	zval;					/* cwc z value					*/
	cwc_ht	hash;					/* running hash value			*/
	ulong	hlen_lo;				/* authenticated header length	*/
	ulong	hlen_hi;				/* authenticated header length	*/
	ulong	mlen_lo;				/* encrypted message length		*/
	ulong	mlen_hi;				/* encrypted message length		*/
	ulong	pos;					/* position in buffer			*/
    aes_encrypt_ctx	enc_ctx[1];		/* AES context                  */
} aes_cwc_ctx;

void aes_cwc_init(
    const unsigned char key[], unsigned int k_len,	/* the key value to be used         */
    const unsigned char nonce[], unsigned int n_len,/* the nonce value                  */
    const unsigned char auth[], unsigned int a_len,	/* authenticated data (len < 2^32)	*/
    aes_cwc_ctx ctx[1]);							/* the CWC context                  */

void aes_cwc_encrypt(unsigned char data[], unsigned int len, aes_cwc_ctx ctx[1]);
void aes_cwc_decrypt(unsigned char data[], unsigned int len, aes_cwc_ctx ctx[1]);
void aes_cwc_end(unsigned char data[], unsigned int a_len, aes_cwc_ctx ctx[1]);

#if defined(__cplusplus)
}
#endif

#endif
