2 * FIPS-46-3 compliant Triple-DES implementation
4 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
6 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * * Neither the names of PolarSSL or XySSL nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 * DES, on which TDES is based, was originally designed by Horst Feistel
37 * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
39 * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
42 #include "tropicssl/config.h"
44 #if defined(TROPICSSL_DES_C)
46 #include "tropicssl/des.h"
51 * 32-bit integer manipulation macros (big endian)
54 #define GET_ULONG_BE(n,b,i) \
56 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
57 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
58 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
59 | ( (unsigned long) (b)[(i) + 3] ); \
64 #define PUT_ULONG_BE(n,b,i) \
66 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
67 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
68 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
69 (b)[(i) + 3] = (unsigned char) ( (n) ); \
74 * Expanded DES S-boxes
76 static const unsigned long SB1
[64] = {
77 0x01010400, 0x00000000, 0x00010000, 0x01010404,
78 0x01010004, 0x00010404, 0x00000004, 0x00010000,
79 0x00000400, 0x01010400, 0x01010404, 0x00000400,
80 0x01000404, 0x01010004, 0x01000000, 0x00000004,
81 0x00000404, 0x01000400, 0x01000400, 0x00010400,
82 0x00010400, 0x01010000, 0x01010000, 0x01000404,
83 0x00010004, 0x01000004, 0x01000004, 0x00010004,
84 0x00000000, 0x00000404, 0x00010404, 0x01000000,
85 0x00010000, 0x01010404, 0x00000004, 0x01010000,
86 0x01010400, 0x01000000, 0x01000000, 0x00000400,
87 0x01010004, 0x00010000, 0x00010400, 0x01000004,
88 0x00000400, 0x00000004, 0x01000404, 0x00010404,
89 0x01010404, 0x00010004, 0x01010000, 0x01000404,
90 0x01000004, 0x00000404, 0x00010404, 0x01010400,
91 0x00000404, 0x01000400, 0x01000400, 0x00000000,
92 0x00010004, 0x00010400, 0x00000000, 0x01010004
95 static const unsigned long SB2
[64] = {
96 0x80108020, 0x80008000, 0x00008000, 0x00108020,
97 0x00100000, 0x00000020, 0x80100020, 0x80008020,
98 0x80000020, 0x80108020, 0x80108000, 0x80000000,
99 0x80008000, 0x00100000, 0x00000020, 0x80100020,
100 0x00108000, 0x00100020, 0x80008020, 0x00000000,
101 0x80000000, 0x00008000, 0x00108020, 0x80100000,
102 0x00100020, 0x80000020, 0x00000000, 0x00108000,
103 0x00008020, 0x80108000, 0x80100000, 0x00008020,
104 0x00000000, 0x00108020, 0x80100020, 0x00100000,
105 0x80008020, 0x80100000, 0x80108000, 0x00008000,
106 0x80100000, 0x80008000, 0x00000020, 0x80108020,
107 0x00108020, 0x00000020, 0x00008000, 0x80000000,
108 0x00008020, 0x80108000, 0x00100000, 0x80000020,
109 0x00100020, 0x80008020, 0x80000020, 0x00100020,
110 0x00108000, 0x00000000, 0x80008000, 0x00008020,
111 0x80000000, 0x80100020, 0x80108020, 0x00108000
114 static const unsigned long SB3
[64] = {
115 0x00000208, 0x08020200, 0x00000000, 0x08020008,
116 0x08000200, 0x00000000, 0x00020208, 0x08000200,
117 0x00020008, 0x08000008, 0x08000008, 0x00020000,
118 0x08020208, 0x00020008, 0x08020000, 0x00000208,
119 0x08000000, 0x00000008, 0x08020200, 0x00000200,
120 0x00020200, 0x08020000, 0x08020008, 0x00020208,
121 0x08000208, 0x00020200, 0x00020000, 0x08000208,
122 0x00000008, 0x08020208, 0x00000200, 0x08000000,
123 0x08020200, 0x08000000, 0x00020008, 0x00000208,
124 0x00020000, 0x08020200, 0x08000200, 0x00000000,
125 0x00000200, 0x00020008, 0x08020208, 0x08000200,
126 0x08000008, 0x00000200, 0x00000000, 0x08020008,
127 0x08000208, 0x00020000, 0x08000000, 0x08020208,
128 0x00000008, 0x00020208, 0x00020200, 0x08000008,
129 0x08020000, 0x08000208, 0x00000208, 0x08020000,
130 0x00020208, 0x00000008, 0x08020008, 0x00020200
133 static const unsigned long SB4
[64] = {
134 0x00802001, 0x00002081, 0x00002081, 0x00000080,
135 0x00802080, 0x00800081, 0x00800001, 0x00002001,
136 0x00000000, 0x00802000, 0x00802000, 0x00802081,
137 0x00000081, 0x00000000, 0x00800080, 0x00800001,
138 0x00000001, 0x00002000, 0x00800000, 0x00802001,
139 0x00000080, 0x00800000, 0x00002001, 0x00002080,
140 0x00800081, 0x00000001, 0x00002080, 0x00800080,
141 0x00002000, 0x00802080, 0x00802081, 0x00000081,
142 0x00800080, 0x00800001, 0x00802000, 0x00802081,
143 0x00000081, 0x00000000, 0x00000000, 0x00802000,
144 0x00002080, 0x00800080, 0x00800081, 0x00000001,
145 0x00802001, 0x00002081, 0x00002081, 0x00000080,
146 0x00802081, 0x00000081, 0x00000001, 0x00002000,
147 0x00800001, 0x00002001, 0x00802080, 0x00800081,
148 0x00002001, 0x00002080, 0x00800000, 0x00802001,
149 0x00000080, 0x00800000, 0x00002000, 0x00802080
152 static const unsigned long SB5
[64] = {
153 0x00000100, 0x02080100, 0x02080000, 0x42000100,
154 0x00080000, 0x00000100, 0x40000000, 0x02080000,
155 0x40080100, 0x00080000, 0x02000100, 0x40080100,
156 0x42000100, 0x42080000, 0x00080100, 0x40000000,
157 0x02000000, 0x40080000, 0x40080000, 0x00000000,
158 0x40000100, 0x42080100, 0x42080100, 0x02000100,
159 0x42080000, 0x40000100, 0x00000000, 0x42000000,
160 0x02080100, 0x02000000, 0x42000000, 0x00080100,
161 0x00080000, 0x42000100, 0x00000100, 0x02000000,
162 0x40000000, 0x02080000, 0x42000100, 0x40080100,
163 0x02000100, 0x40000000, 0x42080000, 0x02080100,
164 0x40080100, 0x00000100, 0x02000000, 0x42080000,
165 0x42080100, 0x00080100, 0x42000000, 0x42080100,
166 0x02080000, 0x00000000, 0x40080000, 0x42000000,
167 0x00080100, 0x02000100, 0x40000100, 0x00080000,
168 0x00000000, 0x40080000, 0x02080100, 0x40000100
171 static const unsigned long SB6
[64] = {
172 0x20000010, 0x20400000, 0x00004000, 0x20404010,
173 0x20400000, 0x00000010, 0x20404010, 0x00400000,
174 0x20004000, 0x00404010, 0x00400000, 0x20000010,
175 0x00400010, 0x20004000, 0x20000000, 0x00004010,
176 0x00000000, 0x00400010, 0x20004010, 0x00004000,
177 0x00404000, 0x20004010, 0x00000010, 0x20400010,
178 0x20400010, 0x00000000, 0x00404010, 0x20404000,
179 0x00004010, 0x00404000, 0x20404000, 0x20000000,
180 0x20004000, 0x00000010, 0x20400010, 0x00404000,
181 0x20404010, 0x00400000, 0x00004010, 0x20000010,
182 0x00400000, 0x20004000, 0x20000000, 0x00004010,
183 0x20000010, 0x20404010, 0x00404000, 0x20400000,
184 0x00404010, 0x20404000, 0x00000000, 0x20400010,
185 0x00000010, 0x00004000, 0x20400000, 0x00404010,
186 0x00004000, 0x00400010, 0x20004010, 0x00000000,
187 0x20404000, 0x20000000, 0x00400010, 0x20004010
190 static const unsigned long SB7
[64] = {
191 0x00200000, 0x04200002, 0x04000802, 0x00000000,
192 0x00000800, 0x04000802, 0x00200802, 0x04200800,
193 0x04200802, 0x00200000, 0x00000000, 0x04000002,
194 0x00000002, 0x04000000, 0x04200002, 0x00000802,
195 0x04000800, 0x00200802, 0x00200002, 0x04000800,
196 0x04000002, 0x04200000, 0x04200800, 0x00200002,
197 0x04200000, 0x00000800, 0x00000802, 0x04200802,
198 0x00200800, 0x00000002, 0x04000000, 0x00200800,
199 0x04000000, 0x00200800, 0x00200000, 0x04000802,
200 0x04000802, 0x04200002, 0x04200002, 0x00000002,
201 0x00200002, 0x04000000, 0x04000800, 0x00200000,
202 0x04200800, 0x00000802, 0x00200802, 0x04200800,
203 0x00000802, 0x04000002, 0x04200802, 0x04200000,
204 0x00200800, 0x00000000, 0x00000002, 0x04200802,
205 0x00000000, 0x00200802, 0x04200000, 0x00000800,
206 0x04000002, 0x04000800, 0x00000800, 0x00200002
209 static const unsigned long SB8
[64] = {
210 0x10001040, 0x00001000, 0x00040000, 0x10041040,
211 0x10000000, 0x10001040, 0x00000040, 0x10000000,
212 0x00040040, 0x10040000, 0x10041040, 0x00041000,
213 0x10041000, 0x00041040, 0x00001000, 0x00000040,
214 0x10040000, 0x10000040, 0x10001000, 0x00001040,
215 0x00041000, 0x00040040, 0x10040040, 0x10041000,
216 0x00001040, 0x00000000, 0x00000000, 0x10040040,
217 0x10000040, 0x10001000, 0x00041040, 0x00040000,
218 0x00041040, 0x00040000, 0x10041000, 0x00001000,
219 0x00000040, 0x10040040, 0x00001000, 0x00041040,
220 0x10001000, 0x00000040, 0x10000040, 0x10040000,
221 0x10040040, 0x10000000, 0x00040000, 0x10001040,
222 0x00000000, 0x10041040, 0x00040040, 0x10000040,
223 0x10040000, 0x10001000, 0x10001040, 0x00000000,
224 0x10041040, 0x00041000, 0x00041000, 0x00001040,
225 0x00001040, 0x00040040, 0x10000000, 0x10041000
229 * PC1: left and right halves bit-swap
231 static const unsigned long LHs
[16] = {
232 0x00000000, 0x00000001, 0x00000100, 0x00000101,
233 0x00010000, 0x00010001, 0x00010100, 0x00010101,
234 0x01000000, 0x01000001, 0x01000100, 0x01000101,
235 0x01010000, 0x01010001, 0x01010100, 0x01010101
238 static const unsigned long RHs
[16] = {
239 0x00000000, 0x01000000, 0x00010000, 0x01010000,
240 0x00000100, 0x01000100, 0x00010100, 0x01010100,
241 0x00000001, 0x01000001, 0x00010001, 0x01010001,
242 0x00000101, 0x01000101, 0x00010101, 0x01010101,
246 * Initial Permutation macro
248 #define DES_IP(X,Y) \
250 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
251 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
252 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
253 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
254 Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
255 T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
256 X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
260 * Final Permutation macro
262 #define DES_FP(X,Y) \
264 X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
265 T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
266 Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
267 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
268 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
269 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
270 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
276 #define DES_ROUND(X,Y) \
279 Y ^= SB8[ (T ) & 0x3F ] ^ \
280 SB6[ (T >> 8) & 0x3F ] ^ \
281 SB4[ (T >> 16) & 0x3F ] ^ \
282 SB2[ (T >> 24) & 0x3F ]; \
284 T = *SK++ ^ ((X << 28) | (X >> 4)); \
285 Y ^= SB7[ (T ) & 0x3F ] ^ \
286 SB5[ (T >> 8) & 0x3F ] ^ \
287 SB3[ (T >> 16) & 0x3F ] ^ \
288 SB1[ (T >> 24) & 0x3F ]; \
291 #define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }
293 static void des_setkey(unsigned long SK
[32], const unsigned char key
[8])
296 unsigned long X
, Y
, T
;
298 GET_ULONG_BE(X
, key
, 0);
299 GET_ULONG_BE(Y
, key
, 4);
304 T
= ((Y
>> 4) ^ X
) & 0x0F0F0F0F;
307 T
= ((Y
) ^ X
) & 0x10101010;
311 X
= (LHs
[(X
) & 0xF] << 3) | (LHs
[(X
>> 8) & 0xF] << 2)
312 | (LHs
[(X
>> 16) & 0xF] << 1) | (LHs
[(X
>> 24) & 0xF])
313 | (LHs
[(X
>> 5) & 0xF] << 7) | (LHs
[(X
>> 13) & 0xF] << 6)
314 | (LHs
[(X
>> 21) & 0xF] << 5) | (LHs
[(X
>> 29) & 0xF] << 4);
316 Y
= (RHs
[(Y
>> 1) & 0xF] << 3) | (RHs
[(Y
>> 9) & 0xF] << 2)
317 | (RHs
[(Y
>> 17) & 0xF] << 1) | (RHs
[(Y
>> 25) & 0xF])
318 | (RHs
[(Y
>> 4) & 0xF] << 7) | (RHs
[(Y
>> 12) & 0xF] << 6)
319 | (RHs
[(Y
>> 20) & 0xF] << 5) | (RHs
[(Y
>> 28) & 0xF] << 4);
327 for (i
= 0; i
< 16; i
++) {
328 if (i
< 2 || i
== 8 || i
== 15) {
329 X
= ((X
<< 1) | (X
>> 27)) & 0x0FFFFFFF;
330 Y
= ((Y
<< 1) | (Y
>> 27)) & 0x0FFFFFFF;
332 X
= ((X
<< 2) | (X
>> 26)) & 0x0FFFFFFF;
333 Y
= ((Y
<< 2) | (Y
>> 26)) & 0x0FFFFFFF;
336 *SK
++ = ((X
<< 4) & 0x24000000) | ((X
<< 28) & 0x10000000)
337 | ((X
<< 14) & 0x08000000) | ((X
<< 18) & 0x02080000)
338 | ((X
<< 6) & 0x01000000) | ((X
<< 9) & 0x00200000)
339 | ((X
>> 1) & 0x00100000) | ((X
<< 10) & 0x00040000)
340 | ((X
<< 2) & 0x00020000) | ((X
>> 10) & 0x00010000)
341 | ((Y
>> 13) & 0x00002000) | ((Y
>> 4) & 0x00001000)
342 | ((Y
<< 6) & 0x00000800) | ((Y
>> 1) & 0x00000400)
343 | ((Y
>> 14) & 0x00000200) | ((Y
) & 0x00000100)
344 | ((Y
>> 5) & 0x00000020) | ((Y
>> 10) & 0x00000010)
345 | ((Y
>> 3) & 0x00000008) | ((Y
>> 18) & 0x00000004)
346 | ((Y
>> 26) & 0x00000002) | ((Y
>> 24) & 0x00000001);
348 *SK
++ = ((X
<< 15) & 0x20000000) | ((X
<< 17) & 0x10000000)
349 | ((X
<< 10) & 0x08000000) | ((X
<< 22) & 0x04000000)
350 | ((X
>> 2) & 0x02000000) | ((X
<< 1) & 0x01000000)
351 | ((X
<< 16) & 0x00200000) | ((X
<< 11) & 0x00100000)
352 | ((X
<< 3) & 0x00080000) | ((X
>> 6) & 0x00040000)
353 | ((X
<< 15) & 0x00020000) | ((X
>> 4) & 0x00010000)
354 | ((Y
>> 2) & 0x00002000) | ((Y
<< 8) & 0x00001000)
355 | ((Y
>> 14) & 0x00000808) | ((Y
>> 9) & 0x00000400)
356 | ((Y
) & 0x00000200) | ((Y
<< 7) & 0x00000100)
357 | ((Y
>> 7) & 0x00000020) | ((Y
>> 3) & 0x00000011)
358 | ((Y
<< 2) & 0x00000004) | ((Y
>> 21) & 0x00000002);
363 * DES key schedule (56-bit, encryption)
365 void des_setkey_enc(des_context
* ctx
, const unsigned char key
[8])
367 des_setkey(ctx
->sk
, key
);
371 * DES key schedule (56-bit, decryption)
373 void des_setkey_dec(des_context
* ctx
, const unsigned char key
[8])
377 des_setkey(ctx
->sk
, key
);
379 for (i
= 0; i
< 16; i
+= 2) {
380 SWAP(ctx
->sk
[i
], ctx
->sk
[30 - i
]);
381 SWAP(ctx
->sk
[i
+ 1], ctx
->sk
[31 - i
]);
385 static void des3_set2key(unsigned long esk
[96],
386 unsigned long dsk
[96], const unsigned char key
[16])
390 des_setkey(esk
, key
);
391 des_setkey(dsk
+ 32, key
+ 8);
393 for (i
= 0; i
< 32; i
+= 2) {
394 dsk
[i
] = esk
[30 - i
];
395 dsk
[i
+ 1] = esk
[31 - i
];
397 esk
[i
+ 32] = dsk
[62 - i
];
398 esk
[i
+ 33] = dsk
[63 - i
];
400 esk
[i
+ 64] = esk
[i
];
401 esk
[i
+ 65] = esk
[i
+ 1];
403 dsk
[i
+ 64] = dsk
[i
];
404 dsk
[i
+ 65] = dsk
[i
+ 1];
409 * Triple-DES key schedule (112-bit, encryption)
411 void des3_set2key_enc(des3_context
* ctx
, const unsigned char key
[16])
413 unsigned long sk
[96];
415 des3_set2key(ctx
->sk
, sk
, key
);
416 memset(sk
, 0, sizeof(sk
));
420 * Triple-DES key schedule (112-bit, decryption)
422 void des3_set2key_dec(des3_context
* ctx
, const unsigned char key
[16])
424 unsigned long sk
[96];
426 des3_set2key(sk
, ctx
->sk
, key
);
427 memset(sk
, 0, sizeof(sk
));
430 static void des3_set3key(unsigned long esk
[96],
431 unsigned long dsk
[96], const unsigned char key
[24])
435 des_setkey(esk
, key
);
436 des_setkey(dsk
+ 32, key
+ 8);
437 des_setkey(esk
+ 64, key
+ 16);
439 for (i
= 0; i
< 32; i
+= 2) {
440 dsk
[i
] = esk
[94 - i
];
441 dsk
[i
+ 1] = esk
[95 - i
];
443 esk
[i
+ 32] = dsk
[62 - i
];
444 esk
[i
+ 33] = dsk
[63 - i
];
446 dsk
[i
+ 64] = esk
[30 - i
];
447 dsk
[i
+ 65] = esk
[31 - i
];
452 * Triple-DES key schedule (168-bit, encryption)
454 void des3_set3key_enc(des3_context
* ctx
, const unsigned char key
[24])
456 unsigned long sk
[96];
458 des3_set3key(ctx
->sk
, sk
, key
);
459 memset(sk
, 0, sizeof(sk
));
463 * Triple-DES key schedule (168-bit, decryption)
465 void des3_set3key_dec(des3_context
* ctx
, const unsigned char key
[24])
467 unsigned long sk
[96];
469 des3_set3key(sk
, ctx
->sk
, key
);
470 memset(sk
, 0, sizeof(sk
));
474 * DES-ECB block encryption/decryption
476 void des_crypt_ecb(des_context
* ctx
,
477 const unsigned char input
[8],
478 unsigned char output
[8])
481 unsigned long X
, Y
, T
, *SK
;
485 GET_ULONG_BE(X
, input
, 0);
486 GET_ULONG_BE(Y
, input
, 4);
490 for (i
= 0; i
< 8; i
++) {
497 PUT_ULONG_BE(Y
, output
, 0);
498 PUT_ULONG_BE(X
, output
, 4);
502 * DES-CBC buffer encryption/decryption
504 void des_crypt_cbc(des_context
* ctx
,
508 const unsigned char *input
,
509 unsigned char *output
)
512 unsigned char temp
[8];
514 if (mode
== DES_ENCRYPT
) {
516 for (i
= 0; i
< 8; i
++)
517 output
[i
] = (unsigned char)(input
[i
] ^ iv
[i
]);
519 des_crypt_ecb(ctx
, output
, output
);
520 memcpy(iv
, output
, 8);
526 } else { /* DES_DECRYPT */
528 memcpy(temp
, input
, 8);
529 des_crypt_ecb(ctx
, input
, output
);
531 for (i
= 0; i
< 8; i
++)
532 output
[i
] = (unsigned char)(output
[i
] ^ iv
[i
]);
544 * 3DES-ECB block encryption/decryption
546 void des3_crypt_ecb(des3_context
* ctx
,
547 const unsigned char input
[8],
548 unsigned char output
[8])
551 unsigned long X
, Y
, T
, *SK
;
555 GET_ULONG_BE(X
, input
, 0);
556 GET_ULONG_BE(Y
, input
, 4);
560 for (i
= 0; i
< 8; i
++) {
565 for (i
= 0; i
< 8; i
++) {
570 for (i
= 0; i
< 8; i
++) {
577 PUT_ULONG_BE(Y
, output
, 0);
578 PUT_ULONG_BE(X
, output
, 4);
582 * 3DES-CBC buffer encryption/decryption
584 void des3_crypt_cbc(des3_context
* ctx
,
588 const unsigned char *input
,
589 unsigned char *output
)
592 unsigned char temp
[8];
594 if (mode
== DES_ENCRYPT
) {
596 for (i
= 0; i
< 8; i
++)
597 output
[i
] = (unsigned char)(input
[i
] ^ iv
[i
]);
599 des3_crypt_ecb(ctx
, output
, output
);
600 memcpy(iv
, output
, 8);
606 } else { /* DES_DECRYPT */
608 memcpy(temp
, input
, 8);
609 des3_crypt_ecb(ctx
, input
, output
);
611 for (i
= 0; i
< 8; i
++)
612 output
[i
] = (unsigned char)(output
[i
] ^ iv
[i
]);
623 #if defined(TROPICSSL_SELF_TEST)
628 * DES and 3DES test vectors from:
630 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
632 static const unsigned char des3_test_keys
[24] = {
633 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
634 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
635 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
638 static const unsigned char des3_test_iv
[8] = {
639 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
642 static const unsigned char des3_test_buf
[8] = {
643 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
646 static const unsigned char des3_test_ecb_dec
[3][8] = {
647 {0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D},
648 {0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB},
649 {0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A}
652 static const unsigned char des3_test_ecb_enc
[3][8] = {
653 {0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B},
654 {0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42},
655 {0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32}
658 static const unsigned char des3_test_cbc_dec
[3][8] = {
659 {0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3},
660 {0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93},
661 {0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C}
664 static const unsigned char des3_test_cbc_enc
[3][8] = {
665 {0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4},
666 {0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D},
667 {0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39}
673 int des_self_test(int verbose
)
678 unsigned char key
[24];
679 unsigned char buf
[8];
680 unsigned char prv
[8];
688 for (i
= 0; i
< 6; i
++) {
693 printf(" DES%c-ECB-%3d (%s): ",
694 (u
== 0) ? ' ' : '3', 56 + u
* 56,
695 (v
== DES_DECRYPT
) ? "dec" : "enc");
697 memcpy(buf
, des3_test_buf
, 8);
701 des_setkey_dec(&ctx
, des3_test_keys
);
705 des_setkey_enc(&ctx
, des3_test_keys
);
709 des3_set2key_dec(&ctx3
, des3_test_keys
);
713 des3_set2key_enc(&ctx3
, des3_test_keys
);
717 des3_set3key_dec(&ctx3
, des3_test_keys
);
721 des3_set3key_enc(&ctx3
,
729 for (j
= 0; j
< 10000; j
++) {
731 des_crypt_ecb(&ctx
, buf
, buf
);
733 des3_crypt_ecb(&ctx3
, buf
, buf
);
736 if ((v
== DES_DECRYPT
&&
737 memcmp(buf
, des3_test_ecb_dec
[u
], 8) != 0) ||
739 memcmp(buf
, des3_test_ecb_enc
[u
], 8) != 0)) {
756 for (i
= 0; i
< 6; i
++) {
761 printf(" DES%c-CBC-%3d (%s): ",
762 (u
== 0) ? ' ' : '3', 56 + u
* 56,
763 (v
== DES_DECRYPT
) ? "dec" : "enc");
765 memcpy(iv
, des3_test_iv
, 8);
766 memcpy(prv
, des3_test_iv
, 8);
767 memcpy(buf
, des3_test_buf
, 8);
771 des_setkey_dec(&ctx
, des3_test_keys
);
775 des_setkey_enc(&ctx
, des3_test_keys
);
779 des3_set2key_dec(&ctx3
, des3_test_keys
);
783 des3_set2key_enc(&ctx3
, des3_test_keys
);
787 des3_set3key_dec(&ctx3
, des3_test_keys
);
791 des3_set3key_enc(&ctx3
, des3_test_keys
);
798 if (v
== DES_DECRYPT
) {
799 for (j
= 0; j
< 10000; j
++) {
801 des_crypt_cbc(&ctx
, v
, 8, iv
, buf
, buf
);
803 des3_crypt_cbc(&ctx3
, v
, 8, iv
, buf
,
807 for (j
= 0; j
< 10000; j
++) {
808 unsigned char tmp
[8];
811 des_crypt_cbc(&ctx
, v
, 8, iv
, buf
, buf
);
813 des3_crypt_cbc(&ctx3
, v
, 8, iv
, buf
,
824 if ((v
== DES_DECRYPT
&&
825 memcmp(buf
, des3_test_cbc_dec
[u
], 8) != 0) ||
827 memcmp(buf
, des3_test_cbc_enc
[u
], 8) != 0)) {