1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  *
9  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
10  */
11 
12 /**
13    @file eax_init.c
14    EAX implementation, initialized EAX state, by Tom St Denis
15 */
16 #include "tomcrypt.h"
17 
18 #ifdef LTC_EAX_MODE
19 
20 /**
21    Initialized an EAX state
22    @param eax       [out] The EAX state to initialize
23    @param cipher    The index of the desired cipher
24    @param key       The secret key
25    @param keylen    The length of the secret key (octets)
26    @param nonce     The use-once nonce for the session
27    @param noncelen  The length of the nonce (octets)
28    @param header    The header for the EAX state
29    @param headerlen The header length (octets)
30    @return CRYPT_OK if successful
31 */
eax_init(eax_state * eax,int cipher,const unsigned char * key,unsigned long keylen,const unsigned char * nonce,unsigned long noncelen,const unsigned char * header,unsigned long headerlen)32 int eax_init(eax_state *eax, int cipher,
33              const unsigned char *key,    unsigned long keylen,
34              const unsigned char *nonce,  unsigned long noncelen,
35              const unsigned char *header, unsigned long headerlen)
36 {
37    unsigned char *buf;
38    int           err, blklen;
39    omac_state    *omac;
40    unsigned long len;
41 
42 
43    LTC_ARGCHK(eax   != NULL);
44    LTC_ARGCHK(key   != NULL);
45    LTC_ARGCHK(nonce != NULL);
46    if (headerlen > 0) {
47       LTC_ARGCHK(header != NULL);
48    }
49 
50    if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
51       return err;
52    }
53    blklen = cipher_descriptor[cipher].block_length;
54 
55    /* allocate ram */
56    buf  = XMALLOC(MAXBLOCKSIZE);
57    omac = XMALLOC(sizeof(*omac));
58 
59    if (buf == NULL || omac == NULL) {
60       if (buf != NULL) {
61          XFREE(buf);
62       }
63       if (omac != NULL) {
64          XFREE(omac);
65       }
66       return CRYPT_MEM;
67    }
68 
69    /* N = LTC_OMAC_0K(nonce) */
70    zeromem(buf, MAXBLOCKSIZE);
71    if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) {
72       goto LBL_ERR;
73    }
74 
75    /* omac the [0]_n */
76    if ((err = omac_process(omac, buf, blklen)) != CRYPT_OK) {
77       goto LBL_ERR;
78    }
79    /* omac the nonce */
80    if ((err = omac_process(omac, nonce, noncelen)) != CRYPT_OK) {
81       goto LBL_ERR;
82    }
83    /* store result */
84    len = sizeof(eax->N);
85    if ((err = omac_done(omac, eax->N, &len)) != CRYPT_OK) {
86       goto LBL_ERR;
87    }
88 
89    /* H = LTC_OMAC_1K(header) */
90    zeromem(buf, MAXBLOCKSIZE);
91    buf[blklen - 1] = 1;
92 
93    if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) {
94       goto LBL_ERR;
95    }
96 
97    /* omac the [1]_n */
98    if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) {
99       goto LBL_ERR;
100    }
101    /* omac the header */
102    if (headerlen != 0) {
103       if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) {
104           goto LBL_ERR;
105       }
106    }
107 
108    /* note we don't finish the headeromac, this allows us to add more header later */
109 
110    /* setup the CTR mode */
111    if ((err = ctr_start(cipher, eax->N, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &eax->ctr)) != CRYPT_OK) {
112       goto LBL_ERR;
113    }
114 
115    /* setup the LTC_OMAC for the ciphertext */
116    if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) {
117       goto LBL_ERR;
118    }
119 
120    /* omac [2]_n */
121    zeromem(buf, MAXBLOCKSIZE);
122    buf[blklen-1] = 2;
123    if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) {
124       goto LBL_ERR;
125    }
126 
127    err = CRYPT_OK;
128 LBL_ERR:
129 #ifdef LTC_CLEAN_STACK
130    zeromem(buf,  MAXBLOCKSIZE);
131    zeromem(omac, sizeof(*omac));
132 #endif
133 
134    XFREE(omac);
135    XFREE(buf);
136 
137    return err;
138 }
139 
140 #endif
141 
142 /* $Source$ */
143 /* $Revision$ */
144 /* $Date$ */
145