1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 /**
5     @file eax_decrypt_verify_memory.c
6     EAX implementation, decrypt block of memory, by Tom St Denis
7 */
8 #include "tomcrypt_private.h"
9 
10 #ifdef LTC_EAX_MODE
11 
12 /**
13    Decrypt a block of memory and verify the provided MAC tag with EAX
14    @param cipher     The index of the cipher desired
15    @param key        The secret key
16    @param keylen     The length of the key (octets)
17    @param nonce      The nonce data (use once) for the session
18    @param noncelen   The length of the nonce data.
19    @param header     The session header data
20    @param headerlen  The length of the header (octets)
21    @param ct         The ciphertext
22    @param ctlen      The length of the ciphertext (octets)
23    @param pt         [out] The plaintext
24    @param tag        The authentication tag provided by the encoder
25    @param taglen     [in/out] The length of the tag (octets)
26    @param stat       [out] The result of the decryption (1==valid tag, 0==invalid)
27    @return CRYPT_OK if successful regardless of the resulting tag comparison
28 */
eax_decrypt_verify_memory(int cipher,const unsigned char * key,unsigned long keylen,const unsigned char * nonce,unsigned long noncelen,const unsigned char * header,unsigned long headerlen,const unsigned char * ct,unsigned long ctlen,unsigned char * pt,const unsigned char * tag,unsigned long taglen,int * stat)29 int eax_decrypt_verify_memory(int cipher,
30     const unsigned char *key,    unsigned long keylen,
31     const unsigned char *nonce,  unsigned long noncelen,
32     const unsigned char *header, unsigned long headerlen,
33     const unsigned char *ct,     unsigned long ctlen,
34           unsigned char *pt,
35     const unsigned char *tag,    unsigned long taglen,
36           int           *stat)
37 {
38    int            err;
39    eax_state     *eax;
40    unsigned char *buf;
41    unsigned long  buflen;
42 
43    LTC_ARGCHK(stat != NULL);
44    LTC_ARGCHK(key  != NULL);
45    LTC_ARGCHK(pt   != NULL);
46    LTC_ARGCHK(ct   != NULL);
47    LTC_ARGCHK(tag  != NULL);
48 
49    /* default to zero */
50    *stat = 0;
51 
52    /* limit taglen */
53    taglen = MIN(taglen, MAXBLOCKSIZE);
54 
55    /* allocate ram */
56    buf = XMALLOC(taglen);
57    eax = XMALLOC(sizeof(*eax));
58    if (eax == NULL || buf == NULL) {
59       if (eax != NULL) {
60          XFREE(eax);
61       }
62       if (buf != NULL) {
63          XFREE(buf);
64       }
65       return CRYPT_MEM;
66    }
67 
68    if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
69       goto LBL_ERR;
70    }
71 
72    if ((err = eax_decrypt(eax, ct, pt, ctlen)) != CRYPT_OK) {
73       goto LBL_ERR;
74    }
75 
76    buflen = taglen;
77    if ((err = eax_done(eax, buf, &buflen)) != CRYPT_OK) {
78       goto LBL_ERR;
79    }
80 
81    /* compare tags */
82    if (buflen >= taglen && XMEM_NEQ(buf, tag, taglen) == 0) {
83       *stat = 1;
84    }
85 
86    err = CRYPT_OK;
87 LBL_ERR:
88 #ifdef LTC_CLEAN_STACK
89    zeromem(buf, taglen);
90    zeromem(eax, sizeof(*eax));
91 #endif
92 
93    XFREE(eax);
94    XFREE(buf);
95 
96    return err;
97 }
98 
99 #endif
100