Coverage Report

Created: 2021-02-21 07:20

/src/botan/src/lib/block/des/des.cpp
Line
Count
Source (jump to first uncovered line)
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
#include <botan/internal/cpuid.h>
15
16
namespace Botan {
17
18
namespace {
19
20
alignas(256) const uint32_t DES_SPBOX[64*8] = {
21
   0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404,
22
   0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,
23
   0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,
24
   0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
25
   0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404,
26
   0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000,
27
   0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000,
28
   0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
29
   0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404,
30
   0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,
31
   0x00010004, 0x00010400, 0x00000000, 0x01010004,
32
33
   0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020,
34
   0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,
35
   0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,
36
   0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
37
   0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000,
38
   0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000,
39
   0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000,
40
   0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
41
   0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020,
42
   0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,
43
   0x80000000, 0x80100020, 0x80108020, 0x00108000,
44
45
   0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000,
46
   0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,
47
   0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,
48
   0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
49
   0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208,
50
   0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208,
51
   0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008,
52
   0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
53
   0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208,
54
   0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,
55
   0x00020208, 0x00000008, 0x08020008, 0x00020200,
56
57
   0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081,
58
   0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,
59
   0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,
60
   0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
61
   0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080,
62
   0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081,
63
   0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080,
64
   0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
65
   0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001,
66
   0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,
67
   0x00000080, 0x00800000, 0x00002000, 0x00802080,
68
69
   0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100,
70
   0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,
71
   0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,
72
   0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
73
   0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000,
74
   0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000,
75
   0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000,
76
   0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
77
   0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000,
78
   0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,
79
   0x00000000, 0x40080000, 0x02080100, 0x40000100,
80
81
   0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010,
82
   0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,
83
   0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,
84
   0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
85
   0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000,
86
   0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000,
87
   0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000,
88
   0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
89
   0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000,
90
   0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,
91
   0x20404000, 0x20000000, 0x00400010, 0x20004010,
92
93
   0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802,
94
   0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,
95
   0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,
96
   0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
97
   0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002,
98
   0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802,
99
   0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000,
100
   0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
101
   0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000,
102
   0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,
103
   0x04000002, 0x04000800, 0x00000800, 0x00200002,
104
105
   0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040,
106
   0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,
107
   0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
108
   0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
109
   0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000,
110
   0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000,
111
   0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040,
112
   0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
113
   0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000,
114
   0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040,
115
   0x00001040, 0x00040040, 0x10000000, 0x10041000 };
116
117
/*
118
* DES Key Schedule
119
*/
120
void des_key_schedule(uint32_t round_key[32], const uint8_t key[8])
121
1.44k
   {
122
1.44k
   static const uint8_t ROT[16] = { 1, 1, 2, 2, 2, 2, 2, 2,
123
1.44k
                                 1, 2, 2, 2, 2, 2, 2, 1 };
124
125
1.44k
   uint32_t C = ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) |
126
1.44k
                ((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) |
127
1.44k
                ((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) |
128
1.44k
                ((key[1] & 0x80) << 14) | ((key[0] & 0x80) << 13) |
129
1.44k
                ((key[7] & 0x40) << 13) | ((key[6] & 0x40) << 12) |
130
1.44k
                ((key[5] & 0x40) << 11) | ((key[4] & 0x40) << 10) |
131
1.44k
                ((key[3] & 0x40) <<  9) | ((key[2] & 0x40) <<  8) |
132
1.44k
                ((key[1] & 0x40) <<  7) | ((key[0] & 0x40) <<  6) |
133
1.44k
                ((key[7] & 0x20) <<  6) | ((key[6] & 0x20) <<  5) |
134
1.44k
                ((key[5] & 0x20) <<  4) | ((key[4] & 0x20) <<  3) |
135
1.44k
                ((key[3] & 0x20) <<  2) | ((key[2] & 0x20) <<  1) |
136
1.44k
                ((key[1] & 0x20)      ) | ((key[0] & 0x20) >>  1) |
137
1.44k
                ((key[7] & 0x10) >>  1) | ((key[6] & 0x10) >>  2) |
138
1.44k
                ((key[5] & 0x10) >>  3) | ((key[4] & 0x10) >>  4);
139
1.44k
   uint32_t D = ((key[7] & 0x02) << 26) | ((key[6] & 0x02) << 25) |
140
1.44k
                ((key[5] & 0x02) << 24) | ((key[4] & 0x02) << 23) |
141
1.44k
                ((key[3] & 0x02) << 22) | ((key[2] & 0x02) << 21) |
142
1.44k
                ((key[1] & 0x02) << 20) | ((key[0] & 0x02) << 19) |
143
1.44k
                ((key[7] & 0x04) << 17) | ((key[6] & 0x04) << 16) |
144
1.44k
                ((key[5] & 0x04) << 15) | ((key[4] & 0x04) << 14) |
145
1.44k
                ((key[3] & 0x04) << 13) | ((key[2] & 0x04) << 12) |
146
1.44k
                ((key[1] & 0x04) << 11) | ((key[0] & 0x04) << 10) |
147
1.44k
                ((key[7] & 0x08) <<  8) | ((key[6] & 0x08) <<  7) |
148
1.44k
                ((key[5] & 0x08) <<  6) | ((key[4] & 0x08) <<  5) |
149
1.44k
                ((key[3] & 0x08) <<  4) | ((key[2] & 0x08) <<  3) |
150
1.44k
                ((key[1] & 0x08) <<  2) | ((key[0] & 0x08) <<  1) |
151
1.44k
                ((key[3] & 0x10) >>  1) | ((key[2] & 0x10) >>  2) |
152
1.44k
                ((key[1] & 0x10) >>  3) | ((key[0] & 0x10) >>  4);
153
154
24.6k
   for(size_t i = 0; i != 16; ++i)
155
23.1k
      {
156
23.1k
      C = ((C << ROT[i]) | (C >> (28-ROT[i]))) & 0x0FFFFFFF;
157
23.1k
      D = ((D << ROT[i]) | (D >> (28-ROT[i]))) & 0x0FFFFFFF;
158
23.1k
      round_key[2*i  ] = ((C & 0x00000010) << 22) | ((C & 0x00000800) << 17) |
159
23.1k
                         ((C & 0x00000020) << 16) | ((C & 0x00004004) << 15) |
160
23.1k
                         ((C & 0x00000200) << 11) | ((C & 0x00020000) << 10) |
161
23.1k
                         ((C & 0x01000000) >>  6) | ((C & 0x00100000) >>  4) |
162
23.1k
                         ((C & 0x00010000) <<  3) | ((C & 0x08000000) >>  2) |
163
23.1k
                         ((C & 0x00800000) <<  1) | ((D & 0x00000010) <<  8) |
164
23.1k
                         ((D & 0x00000002) <<  7) | ((D & 0x00000001) <<  2) |
165
23.1k
                         ((D & 0x00000200)      ) | ((D & 0x00008000) >>  2) |
166
23.1k
                         ((D & 0x00000088) >>  3) | ((D & 0x00001000) >>  7) |
167
23.1k
                         ((D & 0x00080000) >>  9) | ((D & 0x02020000) >> 14) |
168
23.1k
                         ((D & 0x00400000) >> 21);
169
23.1k
      round_key[2*i+1] = ((C & 0x00000001) << 28) | ((C & 0x00000082) << 18) |
170
23.1k
                         ((C & 0x00002000) << 14) | ((C & 0x00000100) << 10) |
171
23.1k
                         ((C & 0x00001000) <<  9) | ((C & 0x00040000) <<  6) |
172
23.1k
                         ((C & 0x02400000) <<  4) | ((C & 0x00008000) <<  2) |
173
23.1k
                         ((C & 0x00200000) >>  1) | ((C & 0x04000000) >> 10) |
174
23.1k
                         ((D & 0x00000020) <<  6) | ((D & 0x00000100)      ) |
175
23.1k
                         ((D & 0x00000800) >>  1) | ((D & 0x00000040) >>  3) |
176
23.1k
                         ((D & 0x00010000) >>  4) | ((D & 0x00000400) >>  5) |
177
23.1k
                         ((D & 0x00004000) >> 10) | ((D & 0x04000000) >> 13) |
178
23.1k
                         ((D & 0x00800000) >> 14) | ((D & 0x00100000) >> 18) |
179
23.1k
                         ((D & 0x01000000) >> 24) | ((D & 0x08000000) >> 26);
180
23.1k
      }
181
1.44k
   }
182
183
inline uint32_t spbox(uint32_t T0, uint32_t T1)
184
0
   {
185
0
   return
186
0
      DES_SPBOX[64*0+((T0 >> 24) & 0x3F)] ^
187
0
      DES_SPBOX[64*1+((T1 >> 24) & 0x3F)] ^
188
0
      DES_SPBOX[64*2+((T0 >> 16) & 0x3F)] ^
189
0
      DES_SPBOX[64*3+((T1 >> 16) & 0x3F)] ^
190
0
      DES_SPBOX[64*4+((T0 >>  8) & 0x3F)] ^
191
0
      DES_SPBOX[64*5+((T1 >>  8) & 0x3F)] ^
192
0
      DES_SPBOX[64*6+((T0 >>  0) & 0x3F)] ^
193
0
      DES_SPBOX[64*7+((T1 >>  0) & 0x3F)];
194
0
   }
195
196
/*
197
* DES Encryption
198
*/
199
inline void des_encrypt(uint32_t& Lr, uint32_t& Rr,
200
                        const uint32_t round_key[32])
201
0
   {
202
0
   uint32_t L = Lr;
203
0
   uint32_t R = Rr;
204
0
   for(size_t i = 0; i != 16; i += 2)
205
0
      {
206
0
      L ^= spbox(rotr<4>(R) ^ round_key[2*i  ], R ^ round_key[2*i+1]);
207
0
      R ^= spbox(rotr<4>(L) ^ round_key[2*i+2], L ^ round_key[2*i+3]);
208
0
      }
209
210
0
   Lr = L;
211
0
   Rr = R;
212
0
   }
213
214
inline void des_encrypt_x2(uint32_t& L0r, uint32_t& R0r,
215
                           uint32_t& L1r, uint32_t& R1r,
216
                           const uint32_t round_key[32])
217
0
   {
218
0
   uint32_t L0 = L0r;
219
0
   uint32_t R0 = R0r;
220
0
   uint32_t L1 = L1r;
221
0
   uint32_t R1 = R1r;
222
223
0
   for(size_t i = 0; i != 16; i += 2)
224
0
      {
225
0
      L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i  ], R0 ^ round_key[2*i+1]);
226
0
      L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i  ], R1 ^ round_key[2*i+1]);
227
228
0
      R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i+2], L0 ^ round_key[2*i+3]);
229
0
      R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i+2], L1 ^ round_key[2*i+3]);
230
0
      }
231
232
0
   L0r = L0;
233
0
   R0r = R0;
234
0
   L1r = L1;
235
0
   R1r = R1;
236
0
   }
237
238
/*
239
* DES Decryption
240
*/
241
inline void des_decrypt(uint32_t& Lr, uint32_t& Rr,
242
                        const uint32_t round_key[32])
243
0
   {
244
0
   uint32_t L = Lr;
245
0
   uint32_t R = Rr;
246
0
   for(size_t i = 16; i != 0; i -= 2)
247
0
      {
248
0
      L ^= spbox(rotr<4>(R) ^ round_key[2*i - 2], R  ^ round_key[2*i - 1]);
249
0
      R ^= spbox(rotr<4>(L) ^ round_key[2*i - 4], L  ^ round_key[2*i - 3]);
250
0
      }
251
0
   Lr = L;
252
0
   Rr = R;
253
0
   }
254
255
inline void des_decrypt_x2(uint32_t& L0r, uint32_t& R0r,
256
                           uint32_t& L1r, uint32_t& R1r,
257
                           const uint32_t round_key[32])
258
0
   {
259
0
   uint32_t L0 = L0r;
260
0
   uint32_t R0 = R0r;
261
0
   uint32_t L1 = L1r;
262
0
   uint32_t R1 = R1r;
263
264
0
   for(size_t i = 16; i != 0; i -= 2)
265
0
      {
266
0
      L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i - 2], R0  ^ round_key[2*i - 1]);
267
0
      L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i - 2], R1  ^ round_key[2*i - 1]);
268
269
0
      R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i - 4], L0  ^ round_key[2*i - 3]);
270
0
      R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i - 4], L1  ^ round_key[2*i - 3]);
271
0
      }
272
273
0
   L0r = L0;
274
0
   R0r = R0;
275
0
   L1r = L1;
276
0
   R1r = R1;
277
0
   }
278
279
inline void des_IP(uint32_t& L, uint32_t& R)
280
0
   {
281
   // IP sequence by Wei Dai, taken from public domain Crypto++
282
0
   uint32_t T;
283
0
   R = rotl<4>(R);
284
0
   T = (L ^ R) & 0xF0F0F0F0;
285
0
   L ^= T;
286
0
   R = rotr<20>(R ^ T);
287
0
   T = (L ^ R) & 0xFFFF0000;
288
0
   L ^= T;
289
0
   R = rotr<18>(R ^ T);
290
0
   T = (L ^ R) & 0x33333333;
291
0
   L ^= T;
292
0
   R = rotr<6>(R ^ T);
293
0
   T = (L ^ R) & 0x00FF00FF;
294
0
   L ^= T;
295
0
   R = rotl<9>(R ^ T);
296
0
   T = (L ^ R) & 0xAAAAAAAA;
297
0
   L = rotl<1>(L ^ T);
298
0
   R ^= T;
299
0
   }
300
301
inline void des_FP(uint32_t& L, uint32_t& R)
302
0
   {
303
   // FP sequence by Wei Dai, taken from public domain Crypto++
304
0
   uint32_t T;
305
306
0
   R = rotr<1>(R);
307
0
   T = (L ^ R) & 0xAAAAAAAA;
308
0
   R ^= T;
309
0
   L = rotr<9>(L ^ T);
310
0
   T = (L ^ R) & 0x00FF00FF;
311
0
   R ^= T;
312
0
   L = rotl<6>(L ^ T);
313
0
   T = (L ^ R) & 0x33333333;
314
0
   R ^= T;
315
0
   L = rotl<18>(L ^ T);
316
0
   T = (L ^ R) & 0xFFFF0000;
317
0
   R ^= T;
318
0
   L = rotl<20>(L ^ T);
319
0
   T = (L ^ R) & 0xF0F0F0F0;
320
0
   R ^= T;
321
0
   L = rotr<4>(L ^ T);
322
0
   }
323
324
}
325
326
/*
327
* DES Encryption
328
*/
329
void DES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
330
0
   {
331
0
   verify_key_set(m_round_key.empty() == false);
332
333
0
   while(blocks >= 2)
334
0
      {
335
0
      uint32_t L0 = load_be<uint32_t>(in, 0);
336
0
      uint32_t R0 = load_be<uint32_t>(in, 1);
337
0
      uint32_t L1 = load_be<uint32_t>(in, 2);
338
0
      uint32_t R1 = load_be<uint32_t>(in, 3);
339
340
0
      des_IP(L0, R0);
341
0
      des_IP(L1, R1);
342
343
0
      des_encrypt_x2(L0, R0, L1, R1, m_round_key.data());
344
345
0
      des_FP(L0, R0);
346
0
      des_FP(L1, R1);
347
348
0
      store_be(out, R0, L0, R1, L1);
349
350
0
      in += 2*BLOCK_SIZE;
351
0
      out += 2*BLOCK_SIZE;
352
0
      blocks -= 2;
353
0
      }
354
355
0
   while(blocks > 0)
356
0
      {
357
0
      uint32_t L0 = load_be<uint32_t>(in, 0);
358
0
      uint32_t R0 = load_be<uint32_t>(in, 1);
359
0
      des_IP(L0, R0);
360
0
      des_encrypt(L0, R0, m_round_key.data());
361
0
      des_FP(L0, R0);
362
0
      store_be(out, R0, L0);
363
364
0
      in += BLOCK_SIZE;
365
0
      out += BLOCK_SIZE;
366
0
      blocks -= 1;
367
0
      }
368
0
   }
369
370
/*
371
* DES Decryption
372
*/
373
void DES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
374
0
   {
375
0
   verify_key_set(m_round_key.empty() == false);
376
377
0
   while(blocks >= 2)
378
0
      {
379
0
      uint32_t L0 = load_be<uint32_t>(in, 0);
380
0
      uint32_t R0 = load_be<uint32_t>(in, 1);
381
0
      uint32_t L1 = load_be<uint32_t>(in, 2);
382
0
      uint32_t R1 = load_be<uint32_t>(in, 3);
383
384
0
      des_IP(L0, R0);
385
0
      des_IP(L1, R1);
386
387
0
      des_decrypt_x2(L0, R0, L1, R1, m_round_key.data());
388
389
0
      des_FP(L0, R0);
390
0
      des_FP(L1, R1);
391
392
0
      store_be(out, R0, L0, R1, L1);
393
394
0
      in += 2*BLOCK_SIZE;
395
0
      out += 2*BLOCK_SIZE;
396
0
      blocks -= 2;
397
0
      }
398
399
0
   while(blocks > 0)
400
0
      {
401
0
      uint32_t L0 = load_be<uint32_t>(in, 0);
402
0
      uint32_t R0 = load_be<uint32_t>(in, 1);
403
0
      des_IP(L0, R0);
404
0
      des_decrypt(L0, R0, m_round_key.data());
405
0
      des_FP(L0, R0);
406
0
      store_be(out, R0, L0);
407
408
0
      in += BLOCK_SIZE;
409
0
      out += BLOCK_SIZE;
410
0
      blocks -= 1;
411
0
      }
412
0
   }
413
414
/*
415
* DES Key Schedule
416
*/
417
void DES::key_schedule(const uint8_t key[], size_t)
418
0
   {
419
0
   m_round_key.resize(32);
420
0
   des_key_schedule(m_round_key.data(), key);
421
0
   }
422
423
void DES::clear()
424
0
   {
425
0
   zap(m_round_key);
426
0
   }
427
428
/*
429
* TripleDES Encryption
430
*/
431
void TripleDES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
432
1.83k
   {
433
1.83k
   verify_key_set(m_round_key.empty() == false);
434
435
1.83k
#if defined(BOTAN_HAS_DES_BMI2)
436
1.83k
   if(CPUID::has_bmi2() && CPUID::has_fast_pdep())
437
1.83k
      {
438
1.83k
      return bmi2_encrypt_n(in, out, blocks, &m_round_key[0]);
439
1.83k
      }
440
0
#endif
441
442
0
   while(blocks >= 2)
443
0
      {
444
0
      uint32_t L0 = load_be<uint32_t>(in, 0);
445
0
      uint32_t R0 = load_be<uint32_t>(in, 1);
446
0
      uint32_t L1 = load_be<uint32_t>(in, 2);
447
0
      uint32_t R1 = load_be<uint32_t>(in, 3);
448
449
0
      des_IP(L0, R0);
450
0
      des_IP(L1, R1);
451
452
0
      des_encrypt_x2(L0, R0, L1, R1, &m_round_key[0]);
453
0
      des_decrypt_x2(R0, L0, R1, L1, &m_round_key[32]);
454
0
      des_encrypt_x2(L0, R0, L1, R1, &m_round_key[64]);
455
456
0
      des_FP(L0, R0);
457
0
      des_FP(L1, R1);
458
459
0
      store_be(out, R0, L0, R1, L1);
460
461
0
      in += 2*BLOCK_SIZE;
462
0
      out += 2*BLOCK_SIZE;
463
0
      blocks -= 2;
464
0
      }
465
466
0
   while(blocks > 0)
467
0
      {
468
0
      uint32_t L0 = load_be<uint32_t>(in, 0);
469
0
      uint32_t R0 = load_be<uint32_t>(in, 1);
470
471
0
      des_IP(L0, R0);
472
0
      des_encrypt(L0, R0, &m_round_key[0]);
473
0
      des_decrypt(R0, L0, &m_round_key[32]);
474
0
      des_encrypt(L0, R0, &m_round_key[64]);
475
0
      des_FP(L0, R0);
476
477
0
      store_be(out, R0, L0);
478
479
0
      in += BLOCK_SIZE;
480
0
      out += BLOCK_SIZE;
481
0
      blocks -= 1;
482
0
      }
483
0
   }
484
485
/*
486
* TripleDES Decryption
487
*/
488
void TripleDES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
489
4.59k
   {
490
4.59k
   verify_key_set(m_round_key.empty() == false);
491
492
4.59k
#if defined(BOTAN_HAS_DES_BMI2)
493
4.59k
   if(CPUID::has_bmi2() && CPUID::has_fast_pdep())
494
4.59k
      {
495
4.59k
      return bmi2_decrypt_n(in, out, blocks, &m_round_key[0]);
496
4.59k
      }
497
0
#endif
498
499
0
   while(blocks >= 2)
500
0
      {
501
0
      uint32_t L0 = load_be<uint32_t>(in, 0);
502
0
      uint32_t R0 = load_be<uint32_t>(in, 1);
503
0
      uint32_t L1 = load_be<uint32_t>(in, 2);
504
0
      uint32_t R1 = load_be<uint32_t>(in, 3);
505
506
0
      des_IP(L0, R0);
507
0
      des_IP(L1, R1);
508
509
0
      des_decrypt_x2(L0, R0, L1, R1, &m_round_key[64]);
510
0
      des_encrypt_x2(R0, L0, R1, L1, &m_round_key[32]);
511
0
      des_decrypt_x2(L0, R0, L1, R1, &m_round_key[0]);
512
513
0
      des_FP(L0, R0);
514
0
      des_FP(L1, R1);
515
516
0
      store_be(out, R0, L0, R1, L1);
517
518
0
      in += 2*BLOCK_SIZE;
519
0
      out += 2*BLOCK_SIZE;
520
0
      blocks -= 2;
521
0
      }
522
523
0
   while(blocks > 0)
524
0
      {
525
0
      uint32_t L0 = load_be<uint32_t>(in, 0);
526
0
      uint32_t R0 = load_be<uint32_t>(in, 1);
527
528
0
      des_IP(L0, R0);
529
0
      des_decrypt(L0, R0, &m_round_key[64]);
530
0
      des_encrypt(R0, L0, &m_round_key[32]);
531
0
      des_decrypt(L0, R0, &m_round_key[0]);
532
0
      des_FP(L0, R0);
533
534
0
      store_be(out, R0, L0);
535
536
0
      in += BLOCK_SIZE;
537
0
      out += BLOCK_SIZE;
538
0
      blocks -= 1;
539
0
      }
540
0
   }
541
542
/*
543
* TripleDES Key Schedule
544
*/
545
void TripleDES::key_schedule(const uint8_t key[], size_t length)
546
483
   {
547
483
   m_round_key.resize(3*32);
548
483
   des_key_schedule(&m_round_key[0], key);
549
483
   des_key_schedule(&m_round_key[32], key + 8);
550
551
483
   if(length == 24)
552
483
      des_key_schedule(&m_round_key[64], key + 16);
553
0
   else
554
0
      copy_mem(&m_round_key[64], &m_round_key[0], 32);
555
483
   }
556
557
void TripleDES::clear()
558
0
   {
559
0
   zap(m_round_key);
560
0
   }
561
562
}