Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/modes/cbc/cbc_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
@file cbc_decrypt.c
13
CBC implementation, encrypt block, Tom St Denis
14
*/
15
16
17
#ifdef LTC_CBC_MODE
18
19
/**
20
CBC decrypt
21
@param ct Ciphertext
22
@param pt [out] Plaintext
23
@param len The number of bytes to process (must be multiple of block length)
24
@param cbc CBC state
25
@return CRYPT_OK if successful
26
*/
27
int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc)
28
{
29
int x, err;
30
unsigned char tmp[16];
31
#ifdef LTC_FAST
32
LTC_FAST_TYPE tmpy;
33
#else
34
unsigned char tmpy;
35
#endif
36
37
LTC_ARGCHK(pt != NULL);
38
LTC_ARGCHK(ct != NULL);
39
LTC_ARGCHK(cbc != NULL);
40
41
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
42
return err;
43
}
44
45
/* is blocklen valid? */
46
if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV) || cbc->blocklen > (int)sizeof(tmp)) {
47
return CRYPT_INVALID_ARG;
48
}
49
50
if (len % cbc->blocklen) {
51
return CRYPT_INVALID_ARG;
52
}
53
#ifdef LTC_FAST
54
if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
55
return CRYPT_INVALID_ARG;
56
}
57
#endif
58
59
if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {
60
return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
61
} else {
62
while (len) {
63
/* decrypt */
64
if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) {
65
return err;
66
}
67
68
/* xor IV against plaintext */
69
#if defined(LTC_FAST)
70
for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
71
tmpy = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)tmp + x));
72
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x));
73
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) = tmpy;
74
}
75
#else
76
for (x = 0; x < cbc->blocklen; x++) {
77
tmpy = tmp[x] ^ cbc->IV[x];
78
cbc->IV[x] = ct[x];
79
pt[x] = tmpy;
80
}
81
#endif
82
83
ct += cbc->blocklen;
84
pt += cbc->blocklen;
85
len -= cbc->blocklen;
86
}
87
}
88
return CRYPT_OK;
89
}
90
91
#endif
92
93