/*
 ---------------------------------------------------------------------------
 Copyright (c) 2003, 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: 1/05/2003

 This code implements the EAX combined encryption and authentication mode 
 specified M. Bellare, P. Rogaway and D. Wagner.

 This is a byte oriented version in which the nonce is of limited length
*/

#ifndef EAX_AES_H
#define EAX_AES_H

#include <memory.h>

#include "aes.h"

/* The EAX-AES	context  */

typedef struct
{   
	unsigned char	nce_cbc[AES_BLOCK_SIZE];	/* encrypt (0|nonce), nonce CBC start	*/
	unsigned char   hdr_cbc[AES_BLOCK_SIZE];	/* encrypt(1), header CBC start			*/
	unsigned char   txt_cbc[AES_BLOCK_SIZE];	/* encrypt(2), ciphertext CBC start		*/
	unsigned char   ctr_val[AES_BLOCK_SIZE];	/* CTR counter value					*/
	unsigned char   enc_ctr[AES_BLOCK_SIZE];	/* encrypted CTR block					*/
	unsigned char   pad_xvv[2*AES_BLOCK_SIZE];	/* {02} encrypt(0), padding start value	*/
	unsigned long	tag_len;					/* authentication tag length			*/
	unsigned long	hdr_cnt;					/* header bytes so far					*/
	unsigned long	txte_cnt;					/* text bytes so far (encrypt)			*/
	unsigned long	txta_cnt;					/* text bytes so far (authenticate)		*/
    aes_encrypt_ctx aes[1];						/* AES encryption context				*/
} eax_ctx;

/* initialise EAX-AES with key and nonce value									*/

void eax_initialise(	
			const unsigned char key[],		/* the encryption key				*/
			unsigned long key_len,			/* key length (bytes)				*/
			const unsigned char nonce[],	/* the nonce data					*/
			unsigned long nonce_len,		/* nonce data length (bytes)		*/
			unsigned long auth_tag_length,  /* authentication tag length		*/
			eax_ctx ctx[1]);                /* the CCM context					*/

/* authenticate the header														*/

void eax_authenticate_header(
			unsigned char hbuf[],			/* the header input buffer			*/
			unsigned long len,				/* the length of this block (bytes) */
			eax_ctx ctx[1]);				/* the eax context                  */

/* encrypt and authenticate message data										*/

void eax_encrypt_data(
			unsigned char buf[],			/* the data buffer					*/
			unsigned long len,				/* the length of this block (bytes) */
			eax_ctx ctx[1]);				/* the eax context                  */

/* authenticate ciphertext data													*/

void eax_authenticate_data(
			unsigned char buf[],			/* the data input buffer			*/
			unsigned long len,				/* the length of this block (bytes) */
			eax_ctx ctx[1]);				/* the eax context                  */

/* decrypt ciphertext data														*/

void eax_decrypt_data(
			unsigned char buf[],			/* the data buffer					*/
			unsigned long len,				/* the length of this block (bytes) */
			eax_ctx ctx[1]);				/* the eax context                  */

/* authenticate and decrypt ciphertext data										*/

void eax_authenticate_and_decrypt_data(
			unsigned char buf[],			/* the data buffer					*/
			unsigned long len,				/* the length of this block (bytes) */
			eax_ctx ctx[1]);				/* the eax context                  */

/* compute the authentication tag and return it (no comparison is done)			*/

void eax_compute_tag(	
			unsigned char auth_tag[],		/* the encryption key				*/
			eax_ctx ctx[1]);                /* the EAX context					*/

/* cleanup the context when finished											*/

void eax_end(eax_ctx ctx[1]);				/* cleanup the EAX context			*/

#endif
