1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 /**
5    @file ocb3_done.c
6    OCB implementation, INTERNAL ONLY helper, by Tom St Denis
7 */
8 #include "tomcrypt_private.h"
9 
10 #ifdef LTC_OCB3_MODE
11 
12 /**
13    Finish OCB processing and compute the tag
14    @param ocb     The OCB state
15    @param tag     [out] The destination for the authentication tag
16    @param taglen  [in/out] The max size and resulting size of the authentication tag
17    @return CRYPT_OK if successful
18 */
ocb3_done(ocb3_state * ocb,unsigned char * tag,unsigned long * taglen)19 int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen)
20 {
21    unsigned char tmp[MAXBLOCKSIZE];
22    int err, x;
23 
24    LTC_ARGCHK(ocb    != NULL);
25    LTC_ARGCHK(tag    != NULL);
26    LTC_ARGCHK(taglen != NULL);
27    if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
28       goto LBL_ERR;
29    }
30 
31    /* check taglen */
32    if ((int)*taglen < ocb->tag_len) {
33       *taglen = (unsigned long)ocb->tag_len;
34       return CRYPT_BUFFER_OVERFLOW;
35    }
36 
37    /* finalize AAD processing */
38 
39    if (ocb->adata_buffer_bytes>0) {
40      /* Offset_* = Offset_m xor L_* */
41      ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_star, ocb->block_len);
42 
43      /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
44      ocb3_int_xor_blocks(tmp, ocb->adata_buffer, ocb->aOffset_current, ocb->adata_buffer_bytes);
45      for(x=ocb->adata_buffer_bytes; x<ocb->block_len; x++) {
46        if (x == ocb->adata_buffer_bytes) {
47          tmp[x] = 0x80 ^ ocb->aOffset_current[x];
48        }
49        else {
50          tmp[x] = 0x00 ^ ocb->aOffset_current[x];
51        }
52      }
53 
54      /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
55      if ((err = cipher_descriptor[ocb->cipher]->ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
56        goto LBL_ERR;
57      }
58      ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);
59    }
60 
61    /* finalize TAG computing */
62 
63    /* at this point ocb->aSum_current = HASH(K, A) */
64    /* tag = tag ^ HASH(K, A) */
65    ocb3_int_xor_blocks(tmp, ocb->tag_part, ocb->aSum_current, ocb->block_len);
66 
67    /* copy tag bytes */
68    for(x = 0; x < ocb->tag_len; x++) tag[x] = tmp[x];
69    *taglen = (unsigned long)ocb->tag_len;
70 
71    err = CRYPT_OK;
72 
73 LBL_ERR:
74 #ifdef LTC_CLEAN_STACK
75    zeromem(tmp, MAXBLOCKSIZE);
76    zeromem(ocb, sizeof(*ocb));
77 #endif
78 
79    return err;
80 }
81 
82 #endif
83