]> pd.if.org Git - zpackage/blob - libtomcrypt/src/encauth/ocb3/ocb3_done.c
b913d3a437532f5cbaf1e7154471ee43cb2fe2d6
[zpackage] / libtomcrypt / src / encauth / ocb3 / ocb3_done.c
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 ocb3_done.c
12    OCB implementation, INTERNAL ONLY helper, by Tom St Denis
13 */
14 #include "tomcrypt.h"
15
16 #ifdef LTC_OCB3_MODE
17
18 /**
19    Finish OCB processing and compute the tag
20    @param ocb     The OCB state
21    @param tag     [out] The destination for the authentication tag
22    @param taglen  [in/out] The max size and resulting size of the authentication tag
23    @return CRYPT_OK if successful
24 */
25 int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen)
26 {
27    unsigned char tmp[MAXBLOCKSIZE];
28    int err, x;
29
30    LTC_ARGCHK(ocb    != NULL);
31    LTC_ARGCHK(tag    != NULL);
32    LTC_ARGCHK(taglen != NULL);
33    if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
34       goto LBL_ERR;
35    }
36
37    /* check taglen */
38    if ((int)*taglen < ocb->tag_len) {
39       *taglen = (unsigned long)ocb->tag_len;
40       return CRYPT_BUFFER_OVERFLOW;
41    }
42
43    /* finalize AAD processing */
44
45    if (ocb->adata_buffer_bytes>0) {
46      /* Offset_* = Offset_m xor L_* */
47      ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_star, ocb->block_len);
48
49      /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
50      ocb3_int_xor_blocks(tmp, ocb->adata_buffer, ocb->aOffset_current, ocb->adata_buffer_bytes);
51      for(x=ocb->adata_buffer_bytes; x<ocb->block_len; x++) {
52        if (x == ocb->adata_buffer_bytes) {
53          tmp[x] = 0x80 ^ ocb->aOffset_current[x];
54        }
55        else {
56          tmp[x] = 0x00 ^ ocb->aOffset_current[x];
57        }
58      }
59
60      /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
61      if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
62        goto LBL_ERR;
63      }
64      ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);
65    }
66
67    /* finalize TAG computing */
68
69    /* at this point ocb->aSum_current = HASH(K, A) */
70    /* tag = tag ^ HASH(K, A) */
71    ocb3_int_xor_blocks(tmp, ocb->tag_part, ocb->aSum_current, ocb->block_len);
72
73    /* copy tag bytes */
74    for(x = 0; x < ocb->tag_len; x++) tag[x] = tmp[x];
75    *taglen = (unsigned long)ocb->tag_len;
76
77    err = CRYPT_OK;
78
79 LBL_ERR:
80 #ifdef LTC_CLEAN_STACK
81    zeromem(tmp, MAXBLOCKSIZE);
82    zeromem(ocb, sizeof(*ocb));
83 #endif
84
85    return err;
86 }
87
88 #endif
89
90 /* ref:         $Format:%D$ */
91 /* git commit:  $Format:%H$ */
92 /* commit time: $Format:%ai$ */