Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/encauth/ocb3/ocb3_decrypt_last.c
5972 views
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_decrypt_last.c
12
OCB implementation, internal helper, by Karel Miko
13
*/
14
#include "tomcrypt.h"
15
16
#ifdef LTC_OCB3_MODE
17
18
/**
19
Finish an OCB (decryption) stream
20
@param ocb The OCB state
21
@param ct The remaining ciphertext
22
@param ctlen The length of the ciphertext (octets)
23
@param pt [out] The output buffer
24
@return CRYPT_OK if successful
25
*/
26
int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt)
27
{
28
unsigned char iOffset_star[MAXBLOCKSIZE];
29
unsigned char iPad[MAXBLOCKSIZE];
30
int err, x, full_blocks, full_blocks_len, last_block_len;
31
32
LTC_ARGCHK(ocb != NULL);
33
if (ct == NULL) LTC_ARGCHK(ctlen == 0);
34
if (ctlen != 0) {
35
LTC_ARGCHK(ct != NULL);
36
LTC_ARGCHK(pt != NULL);
37
}
38
39
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
40
goto LBL_ERR;
41
}
42
43
full_blocks = ctlen/ocb->block_len;
44
full_blocks_len = full_blocks * ocb->block_len;
45
last_block_len = ctlen - full_blocks_len;
46
47
/* process full blocks first */
48
if (full_blocks>0) {
49
if ((err = ocb3_decrypt(ocb, ct, full_blocks_len, pt)) != CRYPT_OK) {
50
goto LBL_ERR;
51
}
52
}
53
54
if (last_block_len>0) {
55
/* Offset_* = Offset_m xor L_* */
56
ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len);
57
58
/* Pad = ENCIPHER(K, Offset_*) */
59
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) {
60
goto LBL_ERR;
61
}
62
63
/* P_* = C_* xor Pad[1..bitlen(C_*)] */
64
ocb3_int_xor_blocks(pt+full_blocks_len, (unsigned char *)ct+full_blocks_len, iPad, last_block_len);
65
66
/* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
67
ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len);
68
for(x=last_block_len; x<ocb->block_len; x++) {
69
if (x == last_block_len)
70
ocb->checksum[x] ^= 0x80;
71
else
72
ocb->checksum[x] ^= 0x00;
73
}
74
75
/* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */
76
/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */
77
for(x=0; x<ocb->block_len; x++) {
78
ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x];
79
}
80
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
81
goto LBL_ERR;
82
}
83
}
84
else {
85
/* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */
86
/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */
87
for(x=0; x<ocb->block_len; x++) {
88
ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x];
89
}
90
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
91
goto LBL_ERR;
92
}
93
}
94
95
err = CRYPT_OK;
96
97
LBL_ERR:
98
#ifdef LTC_CLEAN_STACK
99
zeromem(iOffset_star, MAXBLOCKSIZE);
100
zeromem(iPad, MAXBLOCKSIZE);
101
#endif
102
103
return err;
104
}
105
106
#endif
107
108