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