Botan 3.9.0
Crypto and TLS for C&
des.cpp
Go to the documentation of this file.
1/*
2* DES
3* (C) 1999-2008,2018,2020 Jack Lloyd
4*
5* Based on a public domain implemenation by Phil Karn (who in turn
6* credited Richard Outerbridge and Jim Gillogly)
7*
8* Botan is released under the Simplified BSD License (see license.txt)
9*/
10
11#include <botan/internal/des.h>
12
13#include <botan/internal/loadstor.h>
14#include <botan/internal/rotate.h>
15#include <span>
16
17namespace Botan {
18
19namespace {
20
21/*
22* Constant time DES [with assumptions on the cache]
23*
24* Each SBOX lookup (in function spbox below) examines just a single 64 byte range of this table,
25* converting it to the appropriate value using a multiplication and AND. Typically these tables
26* are otherwise 256 bytes, and thus the lookups leak information about the data being processed.
27* In constrast lookups within a single 64 byte cache line do not leak information [*] and we
28* can use alignas to ensure that the table entries are cache line aligned.
29*
30* [*] Assuming that the cache lines are at least 64 bytes long, and that the machine does not
31* suffer from cache bank conflicts. This is true for all Intel processors after Sandy Bridge,
32* and many other modern processors.
33*/
34alignas(256) const uint8_t SPBOX_CATS[64 * 8] = {
35 0x54, 0x00, 0x10, 0x55, 0x51, 0x15, 0x01, 0x10, 0x04, 0x54, 0x55, 0x04, 0x45, 0x51, 0x40, 0x01,
36 0x05, 0x44, 0x44, 0x14, 0x14, 0x50, 0x50, 0x45, 0x11, 0x41, 0x41, 0x11, 0x00, 0x05, 0x15, 0x40,
37 0x10, 0x55, 0x01, 0x50, 0x54, 0x40, 0x40, 0x04, 0x51, 0x10, 0x14, 0x41, 0x04, 0x01, 0x45, 0x15,
38 0x55, 0x11, 0x50, 0x45, 0x41, 0x05, 0x15, 0x54, 0x05, 0x44, 0x44, 0x00, 0x11, 0x14, 0x00, 0x51,
39
40 0x55, 0x44, 0x04, 0x15, 0x10, 0x01, 0x51, 0x45, 0x41, 0x55, 0x54, 0x40, 0x44, 0x10, 0x01, 0x51,
41 0x14, 0x11, 0x45, 0x00, 0x40, 0x04, 0x15, 0x50, 0x11, 0x41, 0x00, 0x14, 0x05, 0x54, 0x50, 0x05,
42 0x00, 0x15, 0x51, 0x10, 0x45, 0x50, 0x54, 0x04, 0x50, 0x44, 0x01, 0x55, 0x15, 0x01, 0x04, 0x40,
43 0x05, 0x54, 0x10, 0x41, 0x11, 0x45, 0x41, 0x11, 0x14, 0x00, 0x44, 0x05, 0x40, 0x51, 0x55, 0x14,
44
45 0x09, 0xA8, 0x00, 0xA1, 0x88, 0x00, 0x29, 0x88, 0x21, 0x81, 0x81, 0x20, 0xA9, 0x21, 0xA0, 0x09,
46 0x80, 0x01, 0xA8, 0x08, 0x28, 0xA0, 0xA1, 0x29, 0x89, 0x28, 0x20, 0x89, 0x01, 0xA9, 0x08, 0x80,
47 0xA8, 0x80, 0x21, 0x09, 0x20, 0xA8, 0x88, 0x00, 0x08, 0x21, 0xA9, 0x88, 0x81, 0x08, 0x00, 0xA1,
48 0x89, 0x20, 0x80, 0xA9, 0x01, 0x29, 0x28, 0x81, 0xA0, 0x89, 0x09, 0xA0, 0x29, 0x01, 0xA1, 0x28,
49
50 0x51, 0x15, 0x15, 0x04, 0x54, 0x45, 0x41, 0x11, 0x00, 0x50, 0x50, 0x55, 0x05, 0x00, 0x44, 0x41,
51 0x01, 0x10, 0x40, 0x51, 0x04, 0x40, 0x11, 0x14, 0x45, 0x01, 0x14, 0x44, 0x10, 0x54, 0x55, 0x05,
52 0x44, 0x41, 0x50, 0x55, 0x05, 0x00, 0x00, 0x50, 0x14, 0x44, 0x45, 0x01, 0x51, 0x15, 0x15, 0x04,
53 0x55, 0x05, 0x01, 0x10, 0x41, 0x11, 0x54, 0x45, 0x11, 0x14, 0x40, 0x51, 0x04, 0x40, 0x10, 0x54,
54
55 0x01, 0x29, 0x28, 0xA1, 0x08, 0x01, 0x80, 0x28, 0x89, 0x08, 0x21, 0x89, 0xA1, 0xA8, 0x09, 0x80,
56 0x20, 0x88, 0x88, 0x00, 0x81, 0xA9, 0xA9, 0x21, 0xA8, 0x81, 0x00, 0xA0, 0x29, 0x20, 0xA0, 0x09,
57 0x08, 0xA1, 0x01, 0x20, 0x80, 0x28, 0xA1, 0x89, 0x21, 0x80, 0xA8, 0x29, 0x89, 0x01, 0x20, 0xA8,
58 0xA9, 0x09, 0xA0, 0xA9, 0x28, 0x00, 0x88, 0xA0, 0x09, 0x21, 0x81, 0x08, 0x00, 0x88, 0x29, 0x81,
59
60 0x41, 0x50, 0x04, 0x55, 0x50, 0x01, 0x55, 0x10, 0x44, 0x15, 0x10, 0x41, 0x11, 0x44, 0x40, 0x05,
61 0x00, 0x11, 0x45, 0x04, 0x14, 0x45, 0x01, 0x51, 0x51, 0x00, 0x15, 0x54, 0x05, 0x14, 0x54, 0x40,
62 0x44, 0x01, 0x51, 0x14, 0x55, 0x10, 0x05, 0x41, 0x10, 0x44, 0x40, 0x05, 0x41, 0x55, 0x14, 0x50,
63 0x15, 0x54, 0x00, 0x51, 0x01, 0x04, 0x50, 0x15, 0x04, 0x11, 0x45, 0x00, 0x54, 0x40, 0x11, 0x45,
64
65 0x10, 0x51, 0x45, 0x00, 0x04, 0x45, 0x15, 0x54, 0x55, 0x10, 0x00, 0x41, 0x01, 0x40, 0x51, 0x05,
66 0x44, 0x15, 0x11, 0x44, 0x41, 0x50, 0x54, 0x11, 0x50, 0x04, 0x05, 0x55, 0x14, 0x01, 0x40, 0x14,
67 0x40, 0x14, 0x10, 0x45, 0x45, 0x51, 0x51, 0x01, 0x11, 0x40, 0x44, 0x10, 0x54, 0x05, 0x15, 0x54,
68 0x05, 0x41, 0x55, 0x50, 0x14, 0x00, 0x01, 0x55, 0x00, 0x15, 0x50, 0x04, 0x41, 0x44, 0x04, 0x11,
69
70 0x89, 0x08, 0x20, 0xA9, 0x80, 0x89, 0x01, 0x80, 0x21, 0xA0, 0xA9, 0x28, 0xA8, 0x29, 0x08, 0x01,
71 0xA0, 0x81, 0x88, 0x09, 0x28, 0x21, 0xA1, 0xA8, 0x09, 0x00, 0x00, 0xA1, 0x81, 0x88, 0x29, 0x20,
72 0x29, 0x20, 0xa8, 0x08, 0x01, 0xA1, 0x08, 0x29, 0x88, 0x01, 0x81, 0xA0, 0xA1, 0x80, 0x20, 0x89,
73 0x00, 0xA9, 0x21, 0x81, 0xA0, 0x88, 0x89, 0x00, 0xA9, 0x28, 0x28, 0x09, 0x09, 0x21, 0x80, 0xA8,
74};
75
76const uint32_t SPBOX_CAT_0_MUL = 0x70041106;
77const uint32_t SPBOX_CAT_1_MUL = 0x02012020;
78const uint32_t SPBOX_CAT_2_MUL = 0x00901048;
79const uint32_t SPBOX_CAT_3_MUL = 0x8e060221;
80const uint32_t SPBOX_CAT_4_MUL = 0x00912140;
81const uint32_t SPBOX_CAT_5_MUL = 0x80841018;
82const uint32_t SPBOX_CAT_6_MUL = 0xe0120202;
83const uint32_t SPBOX_CAT_7_MUL = 0x00212240;
84
85const uint32_t SPBOX_CAT_0_MASK = 0x01010404;
86const uint32_t SPBOX_CAT_1_MASK = 0x80108020;
87const uint32_t SPBOX_CAT_2_MASK = 0x08020208;
88const uint32_t SPBOX_CAT_3_MASK = 0x00802081;
89const uint32_t SPBOX_CAT_4_MASK = 0x42080100;
90const uint32_t SPBOX_CAT_5_MASK = 0x20404010;
91const uint32_t SPBOX_CAT_6_MASK = 0x04200802;
92const uint32_t SPBOX_CAT_7_MASK = 0x10041040;
93
94/*
95* DES Key Schedule
96*/
97void des_key_schedule(std::span<uint32_t, 32> round_key, const uint8_t key[8]) {
98 static const uint8_t ROT[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
99
100 uint32_t C = ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) | ((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) |
101 ((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) | ((key[1] & 0x80) << 14) | ((key[0] & 0x80) << 13) |
102 ((key[7] & 0x40) << 13) | ((key[6] & 0x40) << 12) | ((key[5] & 0x40) << 11) | ((key[4] & 0x40) << 10) |
103 ((key[3] & 0x40) << 9) | ((key[2] & 0x40) << 8) | ((key[1] & 0x40) << 7) | ((key[0] & 0x40) << 6) |
104 ((key[7] & 0x20) << 6) | ((key[6] & 0x20) << 5) | ((key[5] & 0x20) << 4) | ((key[4] & 0x20) << 3) |
105 ((key[3] & 0x20) << 2) | ((key[2] & 0x20) << 1) | ((key[1] & 0x20)) | ((key[0] & 0x20) >> 1) |
106 ((key[7] & 0x10) >> 1) | ((key[6] & 0x10) >> 2) | ((key[5] & 0x10) >> 3) | ((key[4] & 0x10) >> 4);
107 uint32_t D = ((key[7] & 0x02) << 26) | ((key[6] & 0x02) << 25) | ((key[5] & 0x02) << 24) | ((key[4] & 0x02) << 23) |
108 ((key[3] & 0x02) << 22) | ((key[2] & 0x02) << 21) | ((key[1] & 0x02) << 20) | ((key[0] & 0x02) << 19) |
109 ((key[7] & 0x04) << 17) | ((key[6] & 0x04) << 16) | ((key[5] & 0x04) << 15) | ((key[4] & 0x04) << 14) |
110 ((key[3] & 0x04) << 13) | ((key[2] & 0x04) << 12) | ((key[1] & 0x04) << 11) | ((key[0] & 0x04) << 10) |
111 ((key[7] & 0x08) << 8) | ((key[6] & 0x08) << 7) | ((key[5] & 0x08) << 6) | ((key[4] & 0x08) << 5) |
112 ((key[3] & 0x08) << 4) | ((key[2] & 0x08) << 3) | ((key[1] & 0x08) << 2) | ((key[0] & 0x08) << 1) |
113 ((key[3] & 0x10) >> 1) | ((key[2] & 0x10) >> 2) | ((key[1] & 0x10) >> 3) | ((key[0] & 0x10) >> 4);
114
115 for(size_t i = 0; i != 16; ++i) {
116 C = ((C << ROT[i]) | (C >> (28 - ROT[i]))) & 0x0FFFFFFF;
117 D = ((D << ROT[i]) | (D >> (28 - ROT[i]))) & 0x0FFFFFFF;
118 round_key[2 * i] = ((C & 0x00000010) << 22) | ((C & 0x00000800) << 17) | ((C & 0x00000020) << 16) |
119 ((C & 0x00004004) << 15) | ((C & 0x00000200) << 11) | ((C & 0x00020000) << 10) |
120 ((C & 0x01000000) >> 6) | ((C & 0x00100000) >> 4) | ((C & 0x00010000) << 3) |
121 ((C & 0x08000000) >> 2) | ((C & 0x00800000) << 1) | ((D & 0x00000010) << 8) |
122 ((D & 0x00000002) << 7) | ((D & 0x00000001) << 2) | ((D & 0x00000200)) |
123 ((D & 0x00008000) >> 2) | ((D & 0x00000088) >> 3) | ((D & 0x00001000) >> 7) |
124 ((D & 0x00080000) >> 9) | ((D & 0x02020000) >> 14) | ((D & 0x00400000) >> 21);
125 round_key[2 * i + 1] =
126 ((C & 0x00000001) << 28) | ((C & 0x00000082) << 18) | ((C & 0x00002000) << 14) | ((C & 0x00000100) << 10) |
127 ((C & 0x00001000) << 9) | ((C & 0x00040000) << 6) | ((C & 0x02400000) << 4) | ((C & 0x00008000) << 2) |
128 ((C & 0x00200000) >> 1) | ((C & 0x04000000) >> 10) | ((D & 0x00000020) << 6) | ((D & 0x00000100)) |
129 ((D & 0x00000800) >> 1) | ((D & 0x00000040) >> 3) | ((D & 0x00010000) >> 4) | ((D & 0x00000400) >> 5) |
130 ((D & 0x00004000) >> 10) | ((D & 0x04000000) >> 13) | ((D & 0x00800000) >> 14) | ((D & 0x00100000) >> 18) |
131 ((D & 0x01000000) >> 24) | ((D & 0x08000000) >> 26);
132 }
133}
134
135inline uint32_t spbox(uint32_t T0, uint32_t T1) {
136 return ((SPBOX_CATS[0 * 64 + ((T0 >> 24) & 0x3F)] * SPBOX_CAT_0_MUL) & SPBOX_CAT_0_MASK) ^
137 ((SPBOX_CATS[1 * 64 + ((T1 >> 24) & 0x3F)] * SPBOX_CAT_1_MUL) & SPBOX_CAT_1_MASK) ^
138 ((SPBOX_CATS[2 * 64 + ((T0 >> 16) & 0x3F)] * SPBOX_CAT_2_MUL) & SPBOX_CAT_2_MASK) ^
139 ((SPBOX_CATS[3 * 64 + ((T1 >> 16) & 0x3F)] * SPBOX_CAT_3_MUL) & SPBOX_CAT_3_MASK) ^
140 ((SPBOX_CATS[4 * 64 + ((T0 >> 8) & 0x3F)] * SPBOX_CAT_4_MUL) & SPBOX_CAT_4_MASK) ^
141 ((SPBOX_CATS[5 * 64 + ((T1 >> 8) & 0x3F)] * SPBOX_CAT_5_MUL) & SPBOX_CAT_5_MASK) ^
142 ((SPBOX_CATS[6 * 64 + ((T0 >> 0) & 0x3F)] * SPBOX_CAT_6_MUL) & SPBOX_CAT_6_MASK) ^
143 ((SPBOX_CATS[7 * 64 + ((T1 >> 0) & 0x3F)] * SPBOX_CAT_7_MUL) & SPBOX_CAT_7_MASK);
144}
145
146/*
147* DES Encryption
148*/
149inline void des_encrypt(uint32_t& Lr, uint32_t& Rr, std::span<const uint32_t, 32> round_key) {
150 uint32_t L = Lr;
151 uint32_t R = Rr;
152 for(size_t i = 0; i != 16; i += 2) {
153 L ^= spbox(rotr<4>(R) ^ round_key[2 * i], R ^ round_key[2 * i + 1]);
154 R ^= spbox(rotr<4>(L) ^ round_key[2 * i + 2], L ^ round_key[2 * i + 3]);
155 }
156
157 Lr = L;
158 Rr = R;
159}
160
161inline void des_encrypt_x2(
162 uint32_t& L0r, uint32_t& R0r, uint32_t& L1r, uint32_t& R1r, std::span<const uint32_t, 32> round_key) {
163 uint32_t L0 = L0r;
164 uint32_t R0 = R0r;
165 uint32_t L1 = L1r;
166 uint32_t R1 = R1r;
167
168 for(size_t i = 0; i != 16; i += 2) {
169 L0 ^= spbox(rotr<4>(R0) ^ round_key[2 * i], R0 ^ round_key[2 * i + 1]);
170 L1 ^= spbox(rotr<4>(R1) ^ round_key[2 * i], R1 ^ round_key[2 * i + 1]);
171
172 R0 ^= spbox(rotr<4>(L0) ^ round_key[2 * i + 2], L0 ^ round_key[2 * i + 3]);
173 R1 ^= spbox(rotr<4>(L1) ^ round_key[2 * i + 2], L1 ^ round_key[2 * i + 3]);
174 }
175
176 L0r = L0;
177 R0r = R0;
178 L1r = L1;
179 R1r = R1;
180}
181
182/*
183* DES Decryption
184*/
185inline void des_decrypt(uint32_t& Lr, uint32_t& Rr, std::span<const uint32_t, 32> round_key) {
186 uint32_t L = Lr;
187 uint32_t R = Rr;
188 for(size_t i = 16; i != 0; i -= 2) {
189 L ^= spbox(rotr<4>(R) ^ round_key[2 * i - 2], R ^ round_key[2 * i - 1]);
190 R ^= spbox(rotr<4>(L) ^ round_key[2 * i - 4], L ^ round_key[2 * i - 3]);
191 }
192 Lr = L;
193 Rr = R;
194}
195
196inline void des_decrypt_x2(
197 uint32_t& L0r, uint32_t& R0r, uint32_t& L1r, uint32_t& R1r, std::span<const uint32_t, 32> round_key) {
198 uint32_t L0 = L0r;
199 uint32_t R0 = R0r;
200 uint32_t L1 = L1r;
201 uint32_t R1 = R1r;
202
203 for(size_t i = 16; i != 0; i -= 2) {
204 L0 ^= spbox(rotr<4>(R0) ^ round_key[2 * i - 2], R0 ^ round_key[2 * i - 1]);
205 L1 ^= spbox(rotr<4>(R1) ^ round_key[2 * i - 2], R1 ^ round_key[2 * i - 1]);
206
207 R0 ^= spbox(rotr<4>(L0) ^ round_key[2 * i - 4], L0 ^ round_key[2 * i - 3]);
208 R1 ^= spbox(rotr<4>(L1) ^ round_key[2 * i - 4], L1 ^ round_key[2 * i - 3]);
209 }
210
211 L0r = L0;
212 R0r = R0;
213 L1r = L1;
214 R1r = R1;
215}
216
217inline void des_IP(uint32_t& L, uint32_t& R) {
218 // IP sequence by Wei Dai, taken from public domain Crypto++
219 R = rotl<4>(R);
220 uint32_t T = (L ^ R) & 0xF0F0F0F0;
221 L ^= T;
222 R = rotr<20>(R ^ T);
223 T = (L ^ R) & 0xFFFF0000;
224 L ^= T;
225 R = rotr<18>(R ^ T);
226 T = (L ^ R) & 0x33333333;
227 L ^= T;
228 R = rotr<6>(R ^ T);
229 T = (L ^ R) & 0x00FF00FF;
230 L ^= T;
231 R = rotl<9>(R ^ T);
232 T = (L ^ R) & 0xAAAAAAAA;
233 L = rotl<1>(L ^ T);
234 R ^= T;
235}
236
237inline void des_FP(uint32_t& L, uint32_t& R) {
238 // FP sequence by Wei Dai, taken from public domain Crypto++
239
240 R = rotr<1>(R);
241 uint32_t T = (L ^ R) & 0xAAAAAAAA;
242 R ^= T;
243 L = rotr<9>(L ^ T);
244 T = (L ^ R) & 0x00FF00FF;
245 R ^= T;
246 L = rotl<6>(L ^ T);
247 T = (L ^ R) & 0x33333333;
248 R ^= T;
249 L = rotl<18>(L ^ T);
250 T = (L ^ R) & 0xFFFF0000;
251 R ^= T;
252 L = rotl<20>(L ^ T);
253 T = (L ^ R) & 0xF0F0F0F0;
254 R ^= T;
255 L = rotr<4>(L ^ T);
256}
257
258} // namespace
259
260/*
261* DES Encryption
262*/
263void DES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
265
266 while(blocks >= 2) {
267 uint32_t L0 = load_be<uint32_t>(in, 0);
268 uint32_t R0 = load_be<uint32_t>(in, 1);
269 uint32_t L1 = load_be<uint32_t>(in, 2);
270 uint32_t R1 = load_be<uint32_t>(in, 3);
271
272 des_IP(L0, R0);
273 des_IP(L1, R1);
274
275 des_encrypt_x2(L0, R0, L1, R1, std::span<const uint32_t, 32>{m_round_key});
276
277 des_FP(L0, R0);
278 des_FP(L1, R1);
279
280 store_be(out, R0, L0, R1, L1);
281
282 in += 2 * BLOCK_SIZE;
283 out += 2 * BLOCK_SIZE;
284 blocks -= 2;
285 }
286
287 while(blocks > 0) {
288 uint32_t L0 = load_be<uint32_t>(in, 0);
289 uint32_t R0 = load_be<uint32_t>(in, 1);
290 des_IP(L0, R0);
291 des_encrypt(L0, R0, std::span<const uint32_t, 32>{m_round_key});
292 des_FP(L0, R0);
293 store_be(out, R0, L0);
294
295 in += BLOCK_SIZE;
296 out += BLOCK_SIZE;
297 blocks -= 1;
298 }
299}
300
301/*
302* DES Decryption
303*/
304void DES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
306
307 const auto KS = std::span<const uint32_t, 32>{m_round_key};
308
309 while(blocks >= 2) {
310 uint32_t L0 = load_be<uint32_t>(in, 0);
311 uint32_t R0 = load_be<uint32_t>(in, 1);
312 uint32_t L1 = load_be<uint32_t>(in, 2);
313 uint32_t R1 = load_be<uint32_t>(in, 3);
314
315 des_IP(L0, R0);
316 des_IP(L1, R1);
317
318 des_decrypt_x2(L0, R0, L1, R1, KS);
319
320 des_FP(L0, R0);
321 des_FP(L1, R1);
322
323 store_be(out, R0, L0, R1, L1);
324
325 in += 2 * BLOCK_SIZE;
326 out += 2 * BLOCK_SIZE;
327 blocks -= 2;
328 }
329
330 while(blocks > 0) {
331 uint32_t L0 = load_be<uint32_t>(in, 0);
332 uint32_t R0 = load_be<uint32_t>(in, 1);
333 des_IP(L0, R0);
334 des_decrypt(L0, R0, KS);
335 des_FP(L0, R0);
336 store_be(out, R0, L0);
337
338 in += BLOCK_SIZE;
339 out += BLOCK_SIZE;
340 blocks -= 1;
341 }
342}
343
345 return !m_round_key.empty();
346}
347
348/*
349* DES Key Schedule
350*/
351void DES::key_schedule(std::span<const uint8_t> key) {
352 m_round_key.resize(32);
353 const auto KS = std::span<uint32_t, 32>{m_round_key};
354 des_key_schedule(KS, key.data());
355}
356
358 zap(m_round_key);
359}
360
361/*
362* TripleDES Encryption
363*/
364void TripleDES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
366
367 const auto KS = std::span<const uint32_t, 3 * 32>{m_round_key};
368 const auto K1 = KS.subspan<0, 32>();
369 const auto K2 = KS.subspan<32, 32>();
370 const auto K3 = KS.subspan<64, 32>();
371
372 while(blocks >= 2) {
373 uint32_t L0 = load_be<uint32_t>(in, 0);
374 uint32_t R0 = load_be<uint32_t>(in, 1);
375 uint32_t L1 = load_be<uint32_t>(in, 2);
376 uint32_t R1 = load_be<uint32_t>(in, 3);
377
378 des_IP(L0, R0);
379 des_IP(L1, R1);
380
381 des_encrypt_x2(L0, R0, L1, R1, K1);
382 des_decrypt_x2(R0, L0, R1, L1, K2);
383 des_encrypt_x2(L0, R0, L1, R1, K3);
384
385 des_FP(L0, R0);
386 des_FP(L1, R1);
387
388 store_be(out, R0, L0, R1, L1);
389
390 in += 2 * BLOCK_SIZE;
391 out += 2 * BLOCK_SIZE;
392 blocks -= 2;
393 }
394
395 while(blocks > 0) {
396 uint32_t L0 = load_be<uint32_t>(in, 0);
397 uint32_t R0 = load_be<uint32_t>(in, 1);
398
399 des_IP(L0, R0);
400 des_encrypt(L0, R0, K1);
401 des_decrypt(R0, L0, K2);
402 des_encrypt(L0, R0, K3);
403 des_FP(L0, R0);
404
405 store_be(out, R0, L0);
406
407 in += BLOCK_SIZE;
408 out += BLOCK_SIZE;
409 blocks -= 1;
410 }
411}
412
413/*
414* TripleDES Decryption
415*/
416void TripleDES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
418
419 const auto KS = std::span<const uint32_t, 3 * 32>{m_round_key};
420 const auto K1 = KS.subspan<0, 32>();
421 const auto K2 = KS.subspan<32, 32>();
422 const auto K3 = KS.subspan<64, 32>();
423
424 while(blocks >= 2) {
425 uint32_t L0 = load_be<uint32_t>(in, 0);
426 uint32_t R0 = load_be<uint32_t>(in, 1);
427 uint32_t L1 = load_be<uint32_t>(in, 2);
428 uint32_t R1 = load_be<uint32_t>(in, 3);
429
430 des_IP(L0, R0);
431 des_IP(L1, R1);
432
433 des_decrypt_x2(L0, R0, L1, R1, K3);
434 des_encrypt_x2(R0, L0, R1, L1, K2);
435 des_decrypt_x2(L0, R0, L1, R1, K1);
436
437 des_FP(L0, R0);
438 des_FP(L1, R1);
439
440 store_be(out, R0, L0, R1, L1);
441
442 in += 2 * BLOCK_SIZE;
443 out += 2 * BLOCK_SIZE;
444 blocks -= 2;
445 }
446
447 while(blocks > 0) {
448 uint32_t L0 = load_be<uint32_t>(in, 0);
449 uint32_t R0 = load_be<uint32_t>(in, 1);
450
451 des_IP(L0, R0);
452 des_decrypt(L0, R0, K3);
453 des_encrypt(R0, L0, K2);
454 des_decrypt(L0, R0, K1);
455 des_FP(L0, R0);
456
457 store_be(out, R0, L0);
458
459 in += BLOCK_SIZE;
460 out += BLOCK_SIZE;
461 blocks -= 1;
462 }
463}
464
466 return !m_round_key.empty();
467}
468
469/*
470* TripleDES Key Schedule
471*/
472void TripleDES::key_schedule(std::span<const uint8_t> key) {
473 m_round_key.resize(3 * 32);
474
475 auto KS = std::span<uint32_t, 3 * 32>{m_round_key};
476 auto K1 = KS.subspan<0, 32>();
477 auto K2 = KS.subspan<32, 32>();
478 auto K3 = KS.subspan<64, 32>();
479
480 des_key_schedule(K1, key.first(8).data());
481 des_key_schedule(K2, key.subspan(8, 8).data());
482
483 if(key.size() == 24) {
484 des_key_schedule(K3, key.last(8).data());
485 } else {
486 copy_mem(&m_round_key[64], K1.data(), 32);
487 }
488}
489
491 zap(m_round_key);
492}
493
494} // namespace Botan
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition des.cpp:263
void clear() override
Definition des.cpp:357
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition des.cpp:304
bool has_keying_material() const override
Definition des.cpp:344
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition des.cpp:416
void clear() override
Definition des.cpp:490
bool has_keying_material() const override
Definition des.cpp:465
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition des.cpp:364
constexpr uint32_t K1
Definition sha1_f.h:16
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:145
void zap(std::vector< T, Alloc > &vec)
Definition secmem.h:134
BOTAN_FORCE_INLINE constexpr T rotr(T input)
Definition rotate.h:35
BOTAN_FORCE_INLINE constexpr T rotl(T input)
Definition rotate.h:23
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:745
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504