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_encrypt.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_crypt(const unsigned char *P, unsigned char *C, 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(&C[x])) = *(LTC_FAST_TYPE_PTR_CAST(&P[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&T[x]));
26
}
27
#else
28
for (x = 0; x < 16; x++) {
29
C[x] = P[x] ^ T[x];
30
}
31
#endif
32
33
if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(C, C, &xts->key1)) != CRYPT_OK) {
34
return err;
35
}
36
37
#ifdef LTC_FAST
38
for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
39
*(LTC_FAST_TYPE_PTR_CAST(&C[x])) ^= *(LTC_FAST_TYPE_PTR_CAST(&T[x]));
40
}
41
#else
42
for (x = 0; x < 16; x++) {
43
C[x] = C[x] ^ T[x];
44
}
45
#endif
46
47
/* LFSR the tweak */
48
xts_mult_x(T);
49
50
return CRYPT_OK;
51
}
52
53
/** XTS Encryption
54
@param pt [in] Plaintext
55
@param ptlen Length of plaintext (and ciphertext)
56
@param ct [out] Ciphertext
57
@param tweak [in] The 128--bit encryption tweak (e.g. sector number)
58
@param xts The XTS structure
59
Returns CRYPT_OK upon success
60
*/
61
int xts_encrypt(const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tweak,
62
symmetric_xts *xts)
63
{
64
unsigned char PP[16], CC[16], T[16];
65
unsigned long i, m, mo, lim;
66
int err;
67
68
/* check inputs */
69
LTC_ARGCHK(pt != NULL);
70
LTC_ARGCHK(ct != NULL);
71
LTC_ARGCHK(tweak != NULL);
72
LTC_ARGCHK(xts != NULL);
73
74
/* check if valid */
75
if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) {
76
return err;
77
}
78
79
/* get number of blocks */
80
m = ptlen >> 4;
81
mo = ptlen & 15;
82
83
/* must have at least one full block */
84
if (m == 0) {
85
return CRYPT_INVALID_ARG;
86
}
87
88
if (mo == 0) {
89
lim = m;
90
} else {
91
lim = m - 1;
92
}
93
94
if (cipher_descriptor[xts->cipher].accel_xts_encrypt && lim > 0) {
95
96
/* use accelerated encryption for whole blocks */
97
if ((err = cipher_descriptor[xts->cipher].accel_xts_encrypt(pt, ct, lim, tweak, &xts->key1, &xts->key2)) !=
98
CRYPT_OK) {
99
return err;
100
}
101
ct += lim * 16;
102
pt += lim * 16;
103
104
/* tweak is encrypted on output */
105
XMEMCPY(T, tweak, sizeof(T));
106
} else {
107
108
/* encrypt the tweak */
109
if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) {
110
return err;
111
}
112
113
for (i = 0; i < lim; i++) {
114
if ((err = _tweak_crypt(pt, ct, T, xts)) != CRYPT_OK) {
115
return err;
116
}
117
ct += 16;
118
pt += 16;
119
}
120
}
121
122
/* if ptlen not divide 16 then */
123
if (mo > 0) {
124
/* CC = tweak encrypt block m-1 */
125
if ((err = _tweak_crypt(pt, CC, T, xts)) != CRYPT_OK) {
126
return err;
127
}
128
129
/* Cm = first ptlen % 16 bytes of CC */
130
for (i = 0; i < mo; i++) {
131
PP[i] = pt[16 + i];
132
ct[16 + i] = CC[i];
133
}
134
135
for (; i < 16; i++) {
136
PP[i] = CC[i];
137
}
138
139
/* Cm-1 = Tweak encrypt PP */
140
if ((err = _tweak_crypt(PP, ct, T, xts)) != CRYPT_OK) {
141
return err;
142
}
143
}
144
145
/* Decrypt the tweak back */
146
if ((err = cipher_descriptor[xts->cipher].ecb_decrypt(T, tweak, &xts->key2)) != CRYPT_OK) {
147
return err;
148
}
149
150
return err;
151
}
152
153
#endif
154
155