Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/modes/xts/xts_decrypt.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
#include "tomcrypt.h"
10
11
/**
12
Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects
13
*/
14
15
#ifdef LTC_XTS_MODE
16
17
static int _tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char *T, symmetric_xts *xts)
18
{
19
unsigned long x;
20
int err;
21
22
/* tweak encrypt block i */
23
#ifdef LTC_FAST
24
for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
25
*(LTC_FAST_TYPE_PTR_CAST(&P[x])) = *(LTC_FAST_TYPE_PTR_CAST(&C[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&T[x]));
26
}
27
#else
28
for (x = 0; x < 16; x++) {
29
P[x] = C[x] ^ T[x];
30
}
31
#endif
32
33
err = cipher_descriptor[xts->cipher].ecb_decrypt(P, P, &xts->key1);
34
35
#ifdef LTC_FAST
36
for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
37
*(LTC_FAST_TYPE_PTR_CAST(&P[x])) ^= *(LTC_FAST_TYPE_PTR_CAST(&T[x]));
38
}
39
#else
40
for (x = 0; x < 16; x++) {
41
P[x] = P[x] ^ T[x];
42
}
43
#endif
44
45
/* LFSR the tweak */
46
xts_mult_x(T);
47
48
return err;
49
}
50
51
/** XTS Decryption
52
@param ct [in] Ciphertext
53
@param ptlen Length of plaintext (and ciphertext)
54
@param pt [out] Plaintext
55
@param tweak [in] The 128--bit encryption tweak (e.g. sector number)
56
@param xts The XTS structure
57
Returns CRYPT_OK upon success
58
*/
59
int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt, unsigned char *tweak,
60
symmetric_xts *xts)
61
{
62
unsigned char PP[16], CC[16], T[16];
63
unsigned long i, m, mo, lim;
64
int err;
65
66
/* check inputs */
67
LTC_ARGCHK(pt != NULL);
68
LTC_ARGCHK(ct != NULL);
69
LTC_ARGCHK(tweak != NULL);
70
LTC_ARGCHK(xts != NULL);
71
72
/* check if valid */
73
if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) {
74
return err;
75
}
76
77
/* get number of blocks */
78
m = ptlen >> 4;
79
mo = ptlen & 15;
80
81
/* must have at least one full block */
82
if (m == 0) {
83
return CRYPT_INVALID_ARG;
84
}
85
86
if (mo == 0) {
87
lim = m;
88
} else {
89
lim = m - 1;
90
}
91
92
if (cipher_descriptor[xts->cipher].accel_xts_decrypt && lim > 0) {
93
94
/* use accelerated decryption for whole blocks */
95
if ((err = cipher_descriptor[xts->cipher].accel_xts_decrypt(ct, pt, lim, tweak, &xts->key1, &xts->key2)) !=
96
CRYPT_OK) {
97
return err;
98
}
99
ct += lim * 16;
100
pt += lim * 16;
101
102
/* tweak is encrypted on output */
103
XMEMCPY(T, tweak, sizeof(T));
104
} else {
105
/* encrypt the tweak */
106
if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) {
107
return err;
108
}
109
110
for (i = 0; i < lim; i++) {
111
if ((err = _tweak_uncrypt(ct, pt, T, xts)) != CRYPT_OK) {
112
return err;
113
}
114
ct += 16;
115
pt += 16;
116
}
117
}
118
119
/* if ptlen not divide 16 then */
120
if (mo > 0) {
121
XMEMCPY(CC, T, 16);
122
xts_mult_x(CC);
123
124
/* PP = tweak decrypt block m-1 */
125
if ((err = _tweak_uncrypt(ct, PP, CC, xts)) != CRYPT_OK) {
126
return err;
127
}
128
129
/* Pm = first ptlen % 16 bytes of PP */
130
for (i = 0; i < mo; i++) {
131
CC[i] = ct[16 + i];
132
pt[16 + i] = PP[i];
133
}
134
for (; i < 16; i++) {
135
CC[i] = PP[i];
136
}
137
138
/* Pm-1 = Tweak uncrypt CC */
139
if ((err = _tweak_uncrypt(CC, pt, T, xts)) != CRYPT_OK) {
140
return err;
141
}
142
}
143
144
/* Decrypt the tweak back */
145
if ((err = cipher_descriptor[xts->cipher].ecb_decrypt(T, tweak, &xts->key2)) != CRYPT_OK) {
146
return err;
147
}
148
149
return CRYPT_OK;
150
}
151
152
#endif
153
154