Botan 2.19.3
Crypto and TLS for C&
des.cpp
Go to the documentation of this file.
1/*
2* DES
3* (C) 1999-2008,2018 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/des.h>
12#include <botan/loadstor.h>
13#include <botan/rotate.h>
14
15namespace Botan {
16
17namespace {
18
19/*
20* DES Key Schedule
21*/
22void des_key_schedule(uint32_t round_key[32], const uint8_t key[8])
23 {
24 static const uint8_t ROT[16] = { 1, 1, 2, 2, 2, 2, 2, 2,
25 1, 2, 2, 2, 2, 2, 2, 1 };
26
27 uint32_t C = ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) |
28 ((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) |
29 ((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) |
30 ((key[1] & 0x80) << 14) | ((key[0] & 0x80) << 13) |
31 ((key[7] & 0x40) << 13) | ((key[6] & 0x40) << 12) |
32 ((key[5] & 0x40) << 11) | ((key[4] & 0x40) << 10) |
33 ((key[3] & 0x40) << 9) | ((key[2] & 0x40) << 8) |
34 ((key[1] & 0x40) << 7) | ((key[0] & 0x40) << 6) |
35 ((key[7] & 0x20) << 6) | ((key[6] & 0x20) << 5) |
36 ((key[5] & 0x20) << 4) | ((key[4] & 0x20) << 3) |
37 ((key[3] & 0x20) << 2) | ((key[2] & 0x20) << 1) |
38 ((key[1] & 0x20) ) | ((key[0] & 0x20) >> 1) |
39 ((key[7] & 0x10) >> 1) | ((key[6] & 0x10) >> 2) |
40 ((key[5] & 0x10) >> 3) | ((key[4] & 0x10) >> 4);
41 uint32_t D = ((key[7] & 0x02) << 26) | ((key[6] & 0x02) << 25) |
42 ((key[5] & 0x02) << 24) | ((key[4] & 0x02) << 23) |
43 ((key[3] & 0x02) << 22) | ((key[2] & 0x02) << 21) |
44 ((key[1] & 0x02) << 20) | ((key[0] & 0x02) << 19) |
45 ((key[7] & 0x04) << 17) | ((key[6] & 0x04) << 16) |
46 ((key[5] & 0x04) << 15) | ((key[4] & 0x04) << 14) |
47 ((key[3] & 0x04) << 13) | ((key[2] & 0x04) << 12) |
48 ((key[1] & 0x04) << 11) | ((key[0] & 0x04) << 10) |
49 ((key[7] & 0x08) << 8) | ((key[6] & 0x08) << 7) |
50 ((key[5] & 0x08) << 6) | ((key[4] & 0x08) << 5) |
51 ((key[3] & 0x08) << 4) | ((key[2] & 0x08) << 3) |
52 ((key[1] & 0x08) << 2) | ((key[0] & 0x08) << 1) |
53 ((key[3] & 0x10) >> 1) | ((key[2] & 0x10) >> 2) |
54 ((key[1] & 0x10) >> 3) | ((key[0] & 0x10) >> 4);
55
56 for(size_t i = 0; i != 16; ++i)
57 {
58 C = ((C << ROT[i]) | (C >> (28-ROT[i]))) & 0x0FFFFFFF;
59 D = ((D << ROT[i]) | (D >> (28-ROT[i]))) & 0x0FFFFFFF;
60 round_key[2*i ] = ((C & 0x00000010) << 22) | ((C & 0x00000800) << 17) |
61 ((C & 0x00000020) << 16) | ((C & 0x00004004) << 15) |
62 ((C & 0x00000200) << 11) | ((C & 0x00020000) << 10) |
63 ((C & 0x01000000) >> 6) | ((C & 0x00100000) >> 4) |
64 ((C & 0x00010000) << 3) | ((C & 0x08000000) >> 2) |
65 ((C & 0x00800000) << 1) | ((D & 0x00000010) << 8) |
66 ((D & 0x00000002) << 7) | ((D & 0x00000001) << 2) |
67 ((D & 0x00000200) ) | ((D & 0x00008000) >> 2) |
68 ((D & 0x00000088) >> 3) | ((D & 0x00001000) >> 7) |
69 ((D & 0x00080000) >> 9) | ((D & 0x02020000) >> 14) |
70 ((D & 0x00400000) >> 21);
71 round_key[2*i+1] = ((C & 0x00000001) << 28) | ((C & 0x00000082) << 18) |
72 ((C & 0x00002000) << 14) | ((C & 0x00000100) << 10) |
73 ((C & 0x00001000) << 9) | ((C & 0x00040000) << 6) |
74 ((C & 0x02400000) << 4) | ((C & 0x00008000) << 2) |
75 ((C & 0x00200000) >> 1) | ((C & 0x04000000) >> 10) |
76 ((D & 0x00000020) << 6) | ((D & 0x00000100) ) |
77 ((D & 0x00000800) >> 1) | ((D & 0x00000040) >> 3) |
78 ((D & 0x00010000) >> 4) | ((D & 0x00000400) >> 5) |
79 ((D & 0x00004000) >> 10) | ((D & 0x04000000) >> 13) |
80 ((D & 0x00800000) >> 14) | ((D & 0x00100000) >> 18) |
81 ((D & 0x01000000) >> 24) | ((D & 0x08000000) >> 26);
82 }
83 }
84
85inline uint32_t spbox(uint32_t T0, uint32_t T1)
86 {
87 return DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
88 DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
89 DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
90 DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
91 }
92
93/*
94* DES Encryption
95*/
96inline void des_encrypt(uint32_t& Lr, uint32_t& Rr,
97 const uint32_t round_key[32])
98 {
99 uint32_t L = Lr;
100 uint32_t R = Rr;
101 for(size_t i = 0; i != 16; i += 2)
102 {
103 L ^= spbox(rotr<4>(R) ^ round_key[2*i ], R ^ round_key[2*i+1]);
104 R ^= spbox(rotr<4>(L) ^ round_key[2*i+2], L ^ round_key[2*i+3]);
105 }
106
107 Lr = L;
108 Rr = R;
109 }
110
111inline void des_encrypt_x2(uint32_t& L0r, uint32_t& R0r,
112 uint32_t& L1r, uint32_t& R1r,
113 const uint32_t round_key[32])
114 {
115 uint32_t L0 = L0r;
116 uint32_t R0 = R0r;
117 uint32_t L1 = L1r;
118 uint32_t R1 = R1r;
119
120 for(size_t i = 0; i != 16; i += 2)
121 {
122 L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i ], R0 ^ round_key[2*i+1]);
123 L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i ], R1 ^ round_key[2*i+1]);
124
125 R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i+2], L0 ^ round_key[2*i+3]);
126 R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i+2], L1 ^ round_key[2*i+3]);
127 }
128
129 L0r = L0;
130 R0r = R0;
131 L1r = L1;
132 R1r = R1;
133 }
134
135/*
136* DES Decryption
137*/
138inline void des_decrypt(uint32_t& Lr, uint32_t& Rr,
139 const uint32_t round_key[32])
140 {
141 uint32_t L = Lr;
142 uint32_t R = Rr;
143 for(size_t i = 16; i != 0; i -= 2)
144 {
145 L ^= spbox(rotr<4>(R) ^ round_key[2*i - 2], R ^ round_key[2*i - 1]);
146 R ^= spbox(rotr<4>(L) ^ round_key[2*i - 4], L ^ round_key[2*i - 3]);
147 }
148 Lr = L;
149 Rr = R;
150 }
151
152inline void des_decrypt_x2(uint32_t& L0r, uint32_t& R0r,
153 uint32_t& L1r, uint32_t& R1r,
154 const uint32_t round_key[32])
155 {
156 uint32_t L0 = L0r;
157 uint32_t R0 = R0r;
158 uint32_t L1 = L1r;
159 uint32_t R1 = R1r;
160
161 for(size_t i = 16; i != 0; i -= 2)
162 {
163 L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i - 2], R0 ^ round_key[2*i - 1]);
164 L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i - 2], R1 ^ round_key[2*i - 1]);
165
166 R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i - 4], L0 ^ round_key[2*i - 3]);
167 R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i - 4], L1 ^ round_key[2*i - 3]);
168 }
169
170 L0r = L0;
171 R0r = R0;
172 L1r = L1;
173 R1r = R1;
174 }
175
176inline void des_IP(uint32_t& L, uint32_t& R, const uint8_t block[])
177 {
178 // IP sequence by Wei Dai, taken from public domain Crypto++
179 L = load_be<uint32_t>(block, 0);
180 R = load_be<uint32_t>(block, 1);
181
182 uint32_t T;
183 R = rotl<4>(R);
184 T = (L ^ R) & 0xF0F0F0F0;
185 L ^= T;
186 R = rotr<20>(R ^ T);
187 T = (L ^ R) & 0xFFFF0000;
188 L ^= T;
189 R = rotr<18>(R ^ T);
190 T = (L ^ R) & 0x33333333;
191 L ^= T;
192 R = rotr<6>(R ^ T);
193 T = (L ^ R) & 0x00FF00FF;
194 L ^= T;
195 R = rotl<9>(R ^ T);
196 T = (L ^ R) & 0xAAAAAAAA;
197 L = rotl<1>(L ^ T);
198 R ^= T;
199 }
200
201inline void des_FP(uint32_t L, uint32_t R, uint8_t out[])
202 {
203 // FP sequence by Wei Dai, taken from public domain Crypto++
204 uint32_t T;
205
206 R = rotr<1>(R);
207 T = (L ^ R) & 0xAAAAAAAA;
208 R ^= T;
209 L = rotr<9>(L ^ T);
210 T = (L ^ R) & 0x00FF00FF;
211 R ^= T;
212 L = rotl<6>(L ^ T);
213 T = (L ^ R) & 0x33333333;
214 R ^= T;
215 L = rotl<18>(L ^ T);
216 T = (L ^ R) & 0xFFFF0000;
217 R ^= T;
218 L = rotl<20>(L ^ T);
219 T = (L ^ R) & 0xF0F0F0F0;
220 R ^= T;
221 L = rotr<4>(L ^ T);
222
223 store_be(out, R, L);
224 }
225
226}
227
228/*
229* DES Encryption
230*/
231void DES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
232 {
233 verify_key_set(m_round_key.empty() == false);
234
235 while(blocks >= 2)
236 {
237 uint32_t L0, R0;
238 uint32_t L1, R1;
239
240 des_IP(L0, R0, in);
241 des_IP(L1, R1, in + BLOCK_SIZE);
242
243 des_encrypt_x2(L0, R0, L1, R1, m_round_key.data());
244
245 des_FP(L0, R0, out);
246 des_FP(L1, R1, out + BLOCK_SIZE);
247
248 in += 2*BLOCK_SIZE;
249 out += 2*BLOCK_SIZE;
250 blocks -= 2;
251 }
252
253 for(size_t i = 0; i < blocks; ++i)
254 {
255 uint32_t L, R;
256 des_IP(L, R, in + BLOCK_SIZE*i);
257 des_encrypt(L, R, m_round_key.data());
258 des_FP(L, R, out + BLOCK_SIZE*i);
259 }
260 }
261
262/*
263* DES Decryption
264*/
265void DES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
266 {
267 verify_key_set(m_round_key.empty() == false);
268
269 while(blocks >= 2)
270 {
271 uint32_t L0, R0;
272 uint32_t L1, R1;
273
274 des_IP(L0, R0, in);
275 des_IP(L1, R1, in + BLOCK_SIZE);
276
277 des_decrypt_x2(L0, R0, L1, R1, m_round_key.data());
278
279 des_FP(L0, R0, out);
280 des_FP(L1, R1, out + BLOCK_SIZE);
281
282 in += 2*BLOCK_SIZE;
283 out += 2*BLOCK_SIZE;
284 blocks -= 2;
285 }
286
287 for(size_t i = 0; i < blocks; ++i)
288 {
289 uint32_t L, R;
290 des_IP(L, R, in + BLOCK_SIZE*i);
291 des_decrypt(L, R, m_round_key.data());
292 des_FP(L, R, out + BLOCK_SIZE*i);
293 }
294 }
295
296/*
297* DES Key Schedule
298*/
299void DES::key_schedule(const uint8_t key[], size_t)
300 {
301 m_round_key.resize(32);
302 des_key_schedule(m_round_key.data(), key);
303 }
304
306 {
307 zap(m_round_key);
308 }
309
310/*
311* TripleDES Encryption
312*/
313void TripleDES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
314 {
315 verify_key_set(m_round_key.empty() == false);
316
317 while(blocks >= 2)
318 {
319 uint32_t L0, R0;
320 uint32_t L1, R1;
321
322 des_IP(L0, R0, in);
323 des_IP(L1, R1, in + BLOCK_SIZE);
324
325 des_encrypt_x2(L0, R0, L1, R1, &m_round_key[0]);
326 des_decrypt_x2(R0, L0, R1, L1, &m_round_key[32]);
327 des_encrypt_x2(L0, R0, L1, R1, &m_round_key[64]);
328
329 des_FP(L0, R0, out);
330 des_FP(L1, R1, out + BLOCK_SIZE);
331
332 in += 2*BLOCK_SIZE;
333 out += 2*BLOCK_SIZE;
334 blocks -= 2;
335 }
336
337 for(size_t i = 0; i != blocks; ++i)
338 {
339 uint32_t L, R;
340 des_IP(L, R, in + BLOCK_SIZE*i);
341
342 des_encrypt(L, R, &m_round_key[0]);
343 des_decrypt(R, L, &m_round_key[32]);
344 des_encrypt(L, R, &m_round_key[64]);
345
346 des_FP(L, R, out + BLOCK_SIZE*i);
347 }
348 }
349
350/*
351* TripleDES Decryption
352*/
353void TripleDES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
354 {
355 verify_key_set(m_round_key.empty() == false);
356
357 while(blocks >= 2)
358 {
359 uint32_t L0, R0;
360 uint32_t L1, R1;
361
362 des_IP(L0, R0, in);
363 des_IP(L1, R1, in + BLOCK_SIZE);
364
365 des_decrypt_x2(L0, R0, L1, R1, &m_round_key[64]);
366 des_encrypt_x2(R0, L0, R1, L1, &m_round_key[32]);
367 des_decrypt_x2(L0, R0, L1, R1, &m_round_key[0]);
368
369 des_FP(L0, R0, out);
370 des_FP(L1, R1, out + BLOCK_SIZE);
371
372 in += 2*BLOCK_SIZE;
373 out += 2*BLOCK_SIZE;
374 blocks -= 2;
375 }
376
377 for(size_t i = 0; i != blocks; ++i)
378 {
379 uint32_t L, R;
380 des_IP(L, R, in + BLOCK_SIZE*i);
381
382 des_decrypt(L, R, &m_round_key[64]);
383 des_encrypt(R, L, &m_round_key[32]);
384 des_decrypt(L, R, &m_round_key[0]);
385
386 des_FP(L, R, out + BLOCK_SIZE*i);
387 }
388 }
389
390/*
391* TripleDES Key Schedule
392*/
393void TripleDES::key_schedule(const uint8_t key[], size_t length)
394 {
395 m_round_key.resize(3*32);
396 des_key_schedule(&m_round_key[0], key);
397 des_key_schedule(&m_round_key[32], key + 8);
398
399 if(length == 24)
400 des_key_schedule(&m_round_key[64], key + 16);
401 else
402 copy_mem(&m_round_key[64], &m_round_key[0], 32);
403 }
404
406 {
407 zap(m_round_key);
408 }
409
410}
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition des.cpp:231
void clear() override
Definition des.cpp:305
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition des.cpp:265
void verify_key_set(bool cond) const
Definition sym_algo.h:171
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition des.cpp:353
void clear() override
Definition des.cpp:405
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition des.cpp:313
fe T
Definition ge.cpp:37
void zap(std::vector< T, Alloc > &vec)
Definition secmem.h:124
void store_be(uint16_t in, uint8_t out[2])
Definition loadstor.h:438
void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:133
uint32_t load_be< uint32_t >(const uint8_t in[], size_t off)
Definition loadstor.h:179
const uint32_t DES_SPBOX6[256]
Definition des_tab.cpp:237
const uint32_t DES_SPBOX7[256]
Definition des_tab.cpp:282
const uint32_t DES_SPBOX2[256]
Definition des_tab.cpp:57
const uint32_t DES_SPBOX4[256]
Definition des_tab.cpp:147
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition loadstor.h:41
const uint32_t DES_SPBOX1[256]
Definition des_tab.cpp:12
const uint32_t DES_SPBOX5[256]
Definition des_tab.cpp:192
const uint32_t DES_SPBOX3[256]
Definition des_tab.cpp:102
const uint32_t DES_SPBOX8[256]
Definition des_tab.cpp:327