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:         HEAD -> master, tag: v1.18.2 */
141 /* git commit:  7e7eb695d581782f04b24dc444cbfde86af59853 */
142 /* commit time: 2018-07-01 22:49:01 +0200 */
143