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