Botan  2.4.0
Crypto and TLS for C++11
des.cpp
Go to the documentation of this file.
1 /*
2 * DES
3 * (C) 1999-2008 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 
14 namespace Botan {
15 
16 namespace {
17 
18 /*
19 * DES Key Schedule
20 */
21 void des_key_schedule(uint32_t round_key[32], const uint8_t key[8])
22  {
23  static const uint8_t ROT[16] = { 1, 1, 2, 2, 2, 2, 2, 2,
24  1, 2, 2, 2, 2, 2, 2, 1 };
25 
26  uint32_t C = ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) |
27  ((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) |
28  ((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) |
29  ((key[1] & 0x80) << 14) | ((key[0] & 0x80) << 13) |
30  ((key[7] & 0x40) << 13) | ((key[6] & 0x40) << 12) |
31  ((key[5] & 0x40) << 11) | ((key[4] & 0x40) << 10) |
32  ((key[3] & 0x40) << 9) | ((key[2] & 0x40) << 8) |
33  ((key[1] & 0x40) << 7) | ((key[0] & 0x40) << 6) |
34  ((key[7] & 0x20) << 6) | ((key[6] & 0x20) << 5) |
35  ((key[5] & 0x20) << 4) | ((key[4] & 0x20) << 3) |
36  ((key[3] & 0x20) << 2) | ((key[2] & 0x20) << 1) |
37  ((key[1] & 0x20) ) | ((key[0] & 0x20) >> 1) |
38  ((key[7] & 0x10) >> 1) | ((key[6] & 0x10) >> 2) |
39  ((key[5] & 0x10) >> 3) | ((key[4] & 0x10) >> 4);
40  uint32_t D = ((key[7] & 0x02) << 26) | ((key[6] & 0x02) << 25) |
41  ((key[5] & 0x02) << 24) | ((key[4] & 0x02) << 23) |
42  ((key[3] & 0x02) << 22) | ((key[2] & 0x02) << 21) |
43  ((key[1] & 0x02) << 20) | ((key[0] & 0x02) << 19) |
44  ((key[7] & 0x04) << 17) | ((key[6] & 0x04) << 16) |
45  ((key[5] & 0x04) << 15) | ((key[4] & 0x04) << 14) |
46  ((key[3] & 0x04) << 13) | ((key[2] & 0x04) << 12) |
47  ((key[1] & 0x04) << 11) | ((key[0] & 0x04) << 10) |
48  ((key[7] & 0x08) << 8) | ((key[6] & 0x08) << 7) |
49  ((key[5] & 0x08) << 6) | ((key[4] & 0x08) << 5) |
50  ((key[3] & 0x08) << 4) | ((key[2] & 0x08) << 3) |
51  ((key[1] & 0x08) << 2) | ((key[0] & 0x08) << 1) |
52  ((key[3] & 0x10) >> 1) | ((key[2] & 0x10) >> 2) |
53  ((key[1] & 0x10) >> 3) | ((key[0] & 0x10) >> 4);
54 
55  for(size_t i = 0; i != 16; ++i)
56  {
57  C = ((C << ROT[i]) | (C >> (28-ROT[i]))) & 0x0FFFFFFF;
58  D = ((D << ROT[i]) | (D >> (28-ROT[i]))) & 0x0FFFFFFF;
59  round_key[2*i ] = ((C & 0x00000010) << 22) | ((C & 0x00000800) << 17) |
60  ((C & 0x00000020) << 16) | ((C & 0x00004004) << 15) |
61  ((C & 0x00000200) << 11) | ((C & 0x00020000) << 10) |
62  ((C & 0x01000000) >> 6) | ((C & 0x00100000) >> 4) |
63  ((C & 0x00010000) << 3) | ((C & 0x08000000) >> 2) |
64  ((C & 0x00800000) << 1) | ((D & 0x00000010) << 8) |
65  ((D & 0x00000002) << 7) | ((D & 0x00000001) << 2) |
66  ((D & 0x00000200) ) | ((D & 0x00008000) >> 2) |
67  ((D & 0x00000088) >> 3) | ((D & 0x00001000) >> 7) |
68  ((D & 0x00080000) >> 9) | ((D & 0x02020000) >> 14) |
69  ((D & 0x00400000) >> 21);
70  round_key[2*i+1] = ((C & 0x00000001) << 28) | ((C & 0x00000082) << 18) |
71  ((C & 0x00002000) << 14) | ((C & 0x00000100) << 10) |
72  ((C & 0x00001000) << 9) | ((C & 0x00040000) << 6) |
73  ((C & 0x02400000) << 4) | ((C & 0x00008000) << 2) |
74  ((C & 0x00200000) >> 1) | ((C & 0x04000000) >> 10) |
75  ((D & 0x00000020) << 6) | ((D & 0x00000100) ) |
76  ((D & 0x00000800) >> 1) | ((D & 0x00000040) >> 3) |
77  ((D & 0x00010000) >> 4) | ((D & 0x00000400) >> 5) |
78  ((D & 0x00004000) >> 10) | ((D & 0x04000000) >> 13) |
79  ((D & 0x00800000) >> 14) | ((D & 0x00100000) >> 18) |
80  ((D & 0x01000000) >> 24) | ((D & 0x08000000) >> 26);
81  }
82  }
83 
84 /*
85 * DES Encryption
86 */
87 void des_encrypt(uint32_t& L, uint32_t& R,
88  const uint32_t round_key[32])
89  {
90  for(size_t i = 0; i != 16; i += 2)
91  {
92  uint32_t T0, T1;
93 
94  T0 = rotr<4>(R) ^ round_key[2*i];
95  T1 = R ^ round_key[2*i + 1];
96 
97  L ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
98  DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
99  DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
100  DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
101 
102  T0 = rotr<4>(L) ^ round_key[2*i + 2];
103  T1 = L ^ round_key[2*i + 3];
104 
105  R ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
106  DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
107  DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
108  DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
109  }
110  }
111 
112 /*
113 * DES Decryption
114 */
115 void des_decrypt(uint32_t& L, uint32_t& R,
116  const uint32_t round_key[32])
117  {
118  for(size_t i = 16; i != 0; i -= 2)
119  {
120  uint32_t T0, T1;
121 
122  T0 = rotr<4>(R) ^ round_key[2*i - 2];
123  T1 = R ^ round_key[2*i - 1];
124 
125  L ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
126  DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
127  DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
128  DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
129 
130  T0 = rotr<4>(L) ^ round_key[2*i - 4];
131  T1 = L ^ round_key[2*i - 3];
132 
133  R ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
134  DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
135  DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
136  DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
137  }
138  }
139 
140 }
141 
142 /*
143 * DES Encryption
144 */
145 void DES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
146  {
147  verify_key_set(m_round_key.empty() == false);
148 
149  for(size_t i = 0; i < blocks; ++i)
150  {
151  uint64_t T = (DES_IPTAB1[in[8*i+0]] ) | (DES_IPTAB1[in[8*i+1]] << 1) |
152  (DES_IPTAB1[in[8*i+2]] << 2) | (DES_IPTAB1[in[8*i+3]] << 3) |
153  (DES_IPTAB1[in[8*i+4]] << 4) | (DES_IPTAB1[in[8*i+5]] << 5) |
154  (DES_IPTAB1[in[8*i+6]] << 6) | (DES_IPTAB2[in[8*i+7]] );
155 
156  uint32_t L = static_cast<uint32_t>(T >> 32);
157  uint32_t R = static_cast<uint32_t>(T);
158 
159  des_encrypt(L, R, m_round_key.data());
160 
161  T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
162  (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
163  (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
164  (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
165  T = rotl<32>(T);
166 
167  store_be(T, out + 8*i);
168  }
169  }
170 
171 /*
172 * DES Decryption
173 */
174 void DES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
175  {
176  verify_key_set(m_round_key.empty() == false);
177 
178  for(size_t i = 0; i < blocks; ++i)
179  {
180  uint64_t T = (DES_IPTAB1[in[BLOCK_SIZE*i+0]] ) | (DES_IPTAB1[in[BLOCK_SIZE*i+1]] << 1) |
181  (DES_IPTAB1[in[BLOCK_SIZE*i+2]] << 2) | (DES_IPTAB1[in[BLOCK_SIZE*i+3]] << 3) |
182  (DES_IPTAB1[in[BLOCK_SIZE*i+4]] << 4) | (DES_IPTAB1[in[BLOCK_SIZE*i+5]] << 5) |
183  (DES_IPTAB1[in[BLOCK_SIZE*i+6]] << 6) | (DES_IPTAB2[in[BLOCK_SIZE*i+7]] );
184 
185  uint32_t L = static_cast<uint32_t>(T >> 32);
186  uint32_t R = static_cast<uint32_t>(T);
187 
188  des_decrypt(L, R, m_round_key.data());
189 
190  T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
191  (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
192  (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
193  (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
194 
195  T = rotl<32>(T);
196 
197  store_be(T, out + BLOCK_SIZE*i);
198  }
199  }
200 
201 /*
202 * DES Key Schedule
203 */
204 void DES::key_schedule(const uint8_t key[], size_t)
205  {
206  m_round_key.resize(32);
207  des_key_schedule(m_round_key.data(), key);
208  }
209 
211  {
212  zap(m_round_key);
213  }
214 
215 /*
216 * TripleDES Encryption
217 */
218 void TripleDES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
219  {
220  verify_key_set(m_round_key.empty() == false);
221 
222  for(size_t i = 0; i != blocks; ++i)
223  {
224  uint64_t T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
225  (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
226  (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
227  (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
228 
229  uint32_t L = static_cast<uint32_t>(T >> 32);
230  uint32_t R = static_cast<uint32_t>(T);
231 
232  des_encrypt(L, R, &m_round_key[0]);
233  des_decrypt(R, L, &m_round_key[32]);
234  des_encrypt(L, R, &m_round_key[64]);
235 
236  T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
237  (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
238  (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
239  (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
240 
241  T = rotl<32>(T);
242 
243  store_be(T, out);
244 
245  in += BLOCK_SIZE;
246  out += BLOCK_SIZE;
247  }
248  }
249 
250 /*
251 * TripleDES Decryption
252 */
253 void TripleDES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
254  {
255  verify_key_set(m_round_key.empty() == false);
256 
257  for(size_t i = 0; i != blocks; ++i)
258  {
259  uint64_t T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
260  (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
261  (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
262  (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
263 
264  uint32_t L = static_cast<uint32_t>(T >> 32);
265  uint32_t R = static_cast<uint32_t>(T);
266 
267  des_decrypt(L, R, &m_round_key[64]);
268  des_encrypt(R, L, &m_round_key[32]);
269  des_decrypt(L, R, &m_round_key[0]);
270 
271  T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
272  (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
273  (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
274  (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
275 
276  T = rotl<32>(T);
277 
278  store_be(T, out);
279 
280  in += BLOCK_SIZE;
281  out += BLOCK_SIZE;
282  }
283  }
284 
285 /*
286 * TripleDES Key Schedule
287 */
288 void TripleDES::key_schedule(const uint8_t key[], size_t length)
289  {
290  m_round_key.resize(3*32);
291  des_key_schedule(&m_round_key[0], key);
292  des_key_schedule(&m_round_key[32], key + 8);
293 
294  if(length == 24)
295  des_key_schedule(&m_round_key[64], key + 16);
296  else
297  copy_mem(&m_round_key[64], &m_round_key[0], 32);
298  }
299 
301  {
302  zap(m_round_key);
303  }
304 
305 }
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:174
const uint64_t DES_IPTAB2[256]
Definition: des_tab.cpp:438
const uint32_t DES_SPBOX6[256]
Definition: des_tab.cpp:237
const uint32_t DES_SPBOX7[256]
Definition: des_tab.cpp:282
void verify_key_set(bool cond) const
Definition: sym_algo.h:95
void zap(std::vector< T, Alloc > &vec)
Definition: secmem.h:191
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:253
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:434
const uint64_t DES_IPTAB1[256]
Definition: des_tab.cpp:372
const uint32_t DES_SPBOX4[256]
Definition: des_tab.cpp:147
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:218
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:145
const uint32_t DES_SPBOX3[256]
Definition: des_tab.cpp:102
const uint32_t DES_SPBOX8[256]
Definition: des_tab.cpp:327
const uint32_t DES_SPBOX1[256]
Definition: des_tab.cpp:12
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:97
Definition: alg_id.cpp:13
const uint32_t DES_SPBOX5[256]
Definition: des_tab.cpp:192
const uint32_t DES_SPBOX2[256]
Definition: des_tab.cpp:57
fe T
Definition: ge.cpp:37
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:39
const uint64_t DES_FPTAB1[256]
Definition: des_tab.cpp:504
void clear() override
Definition: des.cpp:210
void clear() override
Definition: des.cpp:300
const uint64_t DES_FPTAB2[256]
Definition: des_tab.cpp:570