1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3
4 /**
5 @file ocb3_decrypt_verify_memory.c
6 OCB implementation, helper to decrypt block of memory, by Tom St Denis
7 */
8 #include "tomcrypt_private.h"
9
10 #ifdef LTC_OCB3_MODE
11
12 /**
13 Decrypt and compare the tag with OCB
14 @param cipher The index of the cipher desired
15 @param key The secret key
16 @param keylen The length of the secret key (octets)
17 @param nonce The session nonce (length of the block size of the block cipher)
18 @param noncelen The length of the nonce (octets)
19 @param adata The AAD - additional associated data
20 @param adatalen The length of AAD (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 tag to compare against
25 @param taglen The length of the tag (octets)
26 @param stat [out] The result of the tag comparison (1==valid, 0==invalid)
27 @return CRYPT_OK if successful regardless of the tag comparison
28 */
ocb3_decrypt_verify_memory(int cipher,const unsigned char * key,unsigned long keylen,const unsigned char * nonce,unsigned long noncelen,const unsigned char * adata,unsigned long adatalen,const unsigned char * ct,unsigned long ctlen,unsigned char * pt,const unsigned char * tag,unsigned long taglen,int * stat)29 int ocb3_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 *adata, unsigned long adatalen,
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 ocb3_state *ocb;
40 unsigned char *buf;
41 unsigned long buflen;
42
43 LTC_ARGCHK(stat != NULL);
44
45 /* default to zero */
46 *stat = 0;
47
48 /* limit taglen */
49 taglen = MIN(taglen, MAXBLOCKSIZE);
50
51 /* allocate memory */
52 buf = XMALLOC(taglen);
53 ocb = XMALLOC(sizeof(ocb3_state));
54 if (ocb == NULL || buf == NULL) {
55 if (ocb != NULL) {
56 XFREE(ocb);
57 }
58 if (buf != NULL) {
59 XFREE(buf);
60 }
61 return CRYPT_MEM;
62 }
63
64 if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen, taglen)) != CRYPT_OK) {
65 goto LBL_ERR;
66 }
67
68 if (adata != NULL || adatalen != 0) {
69 if ((err = ocb3_add_aad(ocb, adata, adatalen)) != CRYPT_OK) {
70 goto LBL_ERR;
71 }
72 }
73
74 if ((err = ocb3_decrypt_last(ocb, ct, ctlen, pt)) != CRYPT_OK) {
75 goto LBL_ERR;
76 }
77
78 buflen = taglen;
79 if ((err = ocb3_done(ocb, buf, &buflen)) != CRYPT_OK) {
80 goto LBL_ERR;
81 }
82
83 /* compare tags */
84 if (buflen >= taglen && XMEM_NEQ(buf, tag, taglen) == 0) {
85 *stat = 1;
86 }
87
88 err = CRYPT_OK;
89
90 LBL_ERR:
91 #ifdef LTC_CLEAN_STACK
92 zeromem(ocb, sizeof(ocb3_state));
93 #endif
94
95 XFREE(ocb);
96 XFREE(buf);
97 return err;
98 }
99
100 #endif
101