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://libtomcrypt.com
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 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*/
32int 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 = 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 = 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 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;
128LBL_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: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_init.c,v $ */
143/* $Revision: 1.5 $ */
144/* $Date: 2006/03/31 14:15:35 $ */
145