1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 /**
5   @file ocb_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_OCB_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 ct         The ciphertext
19    @param ctlen      The length of the ciphertext (octets)
20    @param pt         [out] The plaintext
21    @param tag        The tag to compare against
22    @param taglen     The length of the tag (octets)
23    @param stat       [out] The result of the tag comparison (1==valid, 0==invalid)
24    @return CRYPT_OK if successful regardless of the tag comparison
25 */
ocb_decrypt_verify_memory(int cipher,const unsigned char * key,unsigned long keylen,const unsigned char * nonce,const unsigned char * ct,unsigned long ctlen,unsigned char * pt,const unsigned char * tag,unsigned long taglen,int * stat)26 int ocb_decrypt_verify_memory(int cipher,
27     const unsigned char *key,    unsigned long keylen,
28     const unsigned char *nonce,
29     const unsigned char *ct,     unsigned long ctlen,
30           unsigned char *pt,
31     const unsigned char *tag,    unsigned long taglen,
32           int           *stat)
33 {
34    int err;
35    ocb_state *ocb;
36 
37    LTC_ARGCHK(key    != NULL);
38    LTC_ARGCHK(nonce  != NULL);
39    LTC_ARGCHK(pt     != NULL);
40    LTC_ARGCHK(ct     != NULL);
41    LTC_ARGCHK(tag    != NULL);
42    LTC_ARGCHK(stat    != NULL);
43 
44    /* allocate memory */
45    ocb = XMALLOC(sizeof(ocb_state));
46    if (ocb == NULL) {
47       return CRYPT_MEM;
48    }
49 
50    if ((err = ocb_init(ocb, cipher, key, keylen, nonce)) != CRYPT_OK) {
51       goto LBL_ERR;
52    }
53 
54    while (ctlen > (unsigned long)ocb->block_len) {
55         if ((err = ocb_decrypt(ocb, ct, pt)) != CRYPT_OK) {
56             goto LBL_ERR;
57         }
58         ctlen   -= ocb->block_len;
59         pt      += ocb->block_len;
60         ct      += ocb->block_len;
61    }
62 
63    err = ocb_done_decrypt(ocb, ct, ctlen, pt, tag, taglen, stat);
64 LBL_ERR:
65 #ifdef LTC_CLEAN_STACK
66    zeromem(ocb, sizeof(ocb_state));
67 #endif
68 
69    XFREE(ocb);
70 
71    return err;
72 }
73 
74 #endif
75