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