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