blob: aec027da901fa575ef8e9a45de3b00fb3343a099 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-46-3 compliant Triple-DES implementation
3 *
4 * Copyright (C) 2006-2007 Christophe Devine
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20/*
21 * DES, on which TDES is based, was originally designed by Horst Feistel
22 * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
23 *
24 * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
25 */
26
27#include "xyssl/config.h"
28
29#if defined(XYSSL_DES_C)
30
31#include "xyssl/des.h"
32
33#include <string.h>
34
35/*
36 * 32-bit integer manipulation macros (big endian)
37 */
38#ifndef GET_ULONG_BE
39#define GET_ULONG_BE(n,b,i) \
40{ \
41 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
42 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
43 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
44 | ( (unsigned long) (b)[(i) + 3] ); \
45}
46#endif
47
48#ifndef PUT_ULONG_BE
49#define PUT_ULONG_BE(n,b,i) \
50{ \
51 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
52 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
53 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
54 (b)[(i) + 3] = (unsigned char) ( (n) ); \
55}
56#endif
57
58/*
59 * Expanded DES S-boxes
60 */
61static const unsigned long SB1[64] =
62{
63 0x01010400, 0x00000000, 0x00010000, 0x01010404,
64 0x01010004, 0x00010404, 0x00000004, 0x00010000,
65 0x00000400, 0x01010400, 0x01010404, 0x00000400,
66 0x01000404, 0x01010004, 0x01000000, 0x00000004,
67 0x00000404, 0x01000400, 0x01000400, 0x00010400,
68 0x00010400, 0x01010000, 0x01010000, 0x01000404,
69 0x00010004, 0x01000004, 0x01000004, 0x00010004,
70 0x00000000, 0x00000404, 0x00010404, 0x01000000,
71 0x00010000, 0x01010404, 0x00000004, 0x01010000,
72 0x01010400, 0x01000000, 0x01000000, 0x00000400,
73 0x01010004, 0x00010000, 0x00010400, 0x01000004,
74 0x00000400, 0x00000004, 0x01000404, 0x00010404,
75 0x01010404, 0x00010004, 0x01010000, 0x01000404,
76 0x01000004, 0x00000404, 0x00010404, 0x01010400,
77 0x00000404, 0x01000400, 0x01000400, 0x00000000,
78 0x00010004, 0x00010400, 0x00000000, 0x01010004
79};
80
81static const unsigned long SB2[64] =
82{
83 0x80108020, 0x80008000, 0x00008000, 0x00108020,
84 0x00100000, 0x00000020, 0x80100020, 0x80008020,
85 0x80000020, 0x80108020, 0x80108000, 0x80000000,
86 0x80008000, 0x00100000, 0x00000020, 0x80100020,
87 0x00108000, 0x00100020, 0x80008020, 0x00000000,
88 0x80000000, 0x00008000, 0x00108020, 0x80100000,
89 0x00100020, 0x80000020, 0x00000000, 0x00108000,
90 0x00008020, 0x80108000, 0x80100000, 0x00008020,
91 0x00000000, 0x00108020, 0x80100020, 0x00100000,
92 0x80008020, 0x80100000, 0x80108000, 0x00008000,
93 0x80100000, 0x80008000, 0x00000020, 0x80108020,
94 0x00108020, 0x00000020, 0x00008000, 0x80000000,
95 0x00008020, 0x80108000, 0x00100000, 0x80000020,
96 0x00100020, 0x80008020, 0x80000020, 0x00100020,
97 0x00108000, 0x00000000, 0x80008000, 0x00008020,
98 0x80000000, 0x80100020, 0x80108020, 0x00108000
99};
100
101static const unsigned long SB3[64] =
102{
103 0x00000208, 0x08020200, 0x00000000, 0x08020008,
104 0x08000200, 0x00000000, 0x00020208, 0x08000200,
105 0x00020008, 0x08000008, 0x08000008, 0x00020000,
106 0x08020208, 0x00020008, 0x08020000, 0x00000208,
107 0x08000000, 0x00000008, 0x08020200, 0x00000200,
108 0x00020200, 0x08020000, 0x08020008, 0x00020208,
109 0x08000208, 0x00020200, 0x00020000, 0x08000208,
110 0x00000008, 0x08020208, 0x00000200, 0x08000000,
111 0x08020200, 0x08000000, 0x00020008, 0x00000208,
112 0x00020000, 0x08020200, 0x08000200, 0x00000000,
113 0x00000200, 0x00020008, 0x08020208, 0x08000200,
114 0x08000008, 0x00000200, 0x00000000, 0x08020008,
115 0x08000208, 0x00020000, 0x08000000, 0x08020208,
116 0x00000008, 0x00020208, 0x00020200, 0x08000008,
117 0x08020000, 0x08000208, 0x00000208, 0x08020000,
118 0x00020208, 0x00000008, 0x08020008, 0x00020200
119};
120
121static const unsigned long SB4[64] =
122{
123 0x00802001, 0x00002081, 0x00002081, 0x00000080,
124 0x00802080, 0x00800081, 0x00800001, 0x00002001,
125 0x00000000, 0x00802000, 0x00802000, 0x00802081,
126 0x00000081, 0x00000000, 0x00800080, 0x00800001,
127 0x00000001, 0x00002000, 0x00800000, 0x00802001,
128 0x00000080, 0x00800000, 0x00002001, 0x00002080,
129 0x00800081, 0x00000001, 0x00002080, 0x00800080,
130 0x00002000, 0x00802080, 0x00802081, 0x00000081,
131 0x00800080, 0x00800001, 0x00802000, 0x00802081,
132 0x00000081, 0x00000000, 0x00000000, 0x00802000,
133 0x00002080, 0x00800080, 0x00800081, 0x00000001,
134 0x00802001, 0x00002081, 0x00002081, 0x00000080,
135 0x00802081, 0x00000081, 0x00000001, 0x00002000,
136 0x00800001, 0x00002001, 0x00802080, 0x00800081,
137 0x00002001, 0x00002080, 0x00800000, 0x00802001,
138 0x00000080, 0x00800000, 0x00002000, 0x00802080
139};
140
141static const unsigned long SB5[64] =
142{
143 0x00000100, 0x02080100, 0x02080000, 0x42000100,
144 0x00080000, 0x00000100, 0x40000000, 0x02080000,
145 0x40080100, 0x00080000, 0x02000100, 0x40080100,
146 0x42000100, 0x42080000, 0x00080100, 0x40000000,
147 0x02000000, 0x40080000, 0x40080000, 0x00000000,
148 0x40000100, 0x42080100, 0x42080100, 0x02000100,
149 0x42080000, 0x40000100, 0x00000000, 0x42000000,
150 0x02080100, 0x02000000, 0x42000000, 0x00080100,
151 0x00080000, 0x42000100, 0x00000100, 0x02000000,
152 0x40000000, 0x02080000, 0x42000100, 0x40080100,
153 0x02000100, 0x40000000, 0x42080000, 0x02080100,
154 0x40080100, 0x00000100, 0x02000000, 0x42080000,
155 0x42080100, 0x00080100, 0x42000000, 0x42080100,
156 0x02080000, 0x00000000, 0x40080000, 0x42000000,
157 0x00080100, 0x02000100, 0x40000100, 0x00080000,
158 0x00000000, 0x40080000, 0x02080100, 0x40000100
159};
160
161static const unsigned long SB6[64] =
162{
163 0x20000010, 0x20400000, 0x00004000, 0x20404010,
164 0x20400000, 0x00000010, 0x20404010, 0x00400000,
165 0x20004000, 0x00404010, 0x00400000, 0x20000010,
166 0x00400010, 0x20004000, 0x20000000, 0x00004010,
167 0x00000000, 0x00400010, 0x20004010, 0x00004000,
168 0x00404000, 0x20004010, 0x00000010, 0x20400010,
169 0x20400010, 0x00000000, 0x00404010, 0x20404000,
170 0x00004010, 0x00404000, 0x20404000, 0x20000000,
171 0x20004000, 0x00000010, 0x20400010, 0x00404000,
172 0x20404010, 0x00400000, 0x00004010, 0x20000010,
173 0x00400000, 0x20004000, 0x20000000, 0x00004010,
174 0x20000010, 0x20404010, 0x00404000, 0x20400000,
175 0x00404010, 0x20404000, 0x00000000, 0x20400010,
176 0x00000010, 0x00004000, 0x20400000, 0x00404010,
177 0x00004000, 0x00400010, 0x20004010, 0x00000000,
178 0x20404000, 0x20000000, 0x00400010, 0x20004010
179};
180
181static const unsigned long SB7[64] =
182{
183 0x00200000, 0x04200002, 0x04000802, 0x00000000,
184 0x00000800, 0x04000802, 0x00200802, 0x04200800,
185 0x04200802, 0x00200000, 0x00000000, 0x04000002,
186 0x00000002, 0x04000000, 0x04200002, 0x00000802,
187 0x04000800, 0x00200802, 0x00200002, 0x04000800,
188 0x04000002, 0x04200000, 0x04200800, 0x00200002,
189 0x04200000, 0x00000800, 0x00000802, 0x04200802,
190 0x00200800, 0x00000002, 0x04000000, 0x00200800,
191 0x04000000, 0x00200800, 0x00200000, 0x04000802,
192 0x04000802, 0x04200002, 0x04200002, 0x00000002,
193 0x00200002, 0x04000000, 0x04000800, 0x00200000,
194 0x04200800, 0x00000802, 0x00200802, 0x04200800,
195 0x00000802, 0x04000002, 0x04200802, 0x04200000,
196 0x00200800, 0x00000000, 0x00000002, 0x04200802,
197 0x00000000, 0x00200802, 0x04200000, 0x00000800,
198 0x04000002, 0x04000800, 0x00000800, 0x00200002
199};
200
201static const unsigned long SB8[64] =
202{
203 0x10001040, 0x00001000, 0x00040000, 0x10041040,
204 0x10000000, 0x10001040, 0x00000040, 0x10000000,
205 0x00040040, 0x10040000, 0x10041040, 0x00041000,
206 0x10041000, 0x00041040, 0x00001000, 0x00000040,
207 0x10040000, 0x10000040, 0x10001000, 0x00001040,
208 0x00041000, 0x00040040, 0x10040040, 0x10041000,
209 0x00001040, 0x00000000, 0x00000000, 0x10040040,
210 0x10000040, 0x10001000, 0x00041040, 0x00040000,
211 0x00041040, 0x00040000, 0x10041000, 0x00001000,
212 0x00000040, 0x10040040, 0x00001000, 0x00041040,
213 0x10001000, 0x00000040, 0x10000040, 0x10040000,
214 0x10040040, 0x10000000, 0x00040000, 0x10001040,
215 0x00000000, 0x10041040, 0x00040040, 0x10000040,
216 0x10040000, 0x10001000, 0x10001040, 0x00000000,
217 0x10041040, 0x00041000, 0x00041000, 0x00001040,
218 0x00001040, 0x00040040, 0x10000000, 0x10041000
219};
220
221/*
222 * PC1: left and right halves bit-swap
223 */
224static const unsigned long LHs[16] =
225{
226 0x00000000, 0x00000001, 0x00000100, 0x00000101,
227 0x00010000, 0x00010001, 0x00010100, 0x00010101,
228 0x01000000, 0x01000001, 0x01000100, 0x01000101,
229 0x01010000, 0x01010001, 0x01010100, 0x01010101
230};
231
232static const unsigned long RHs[16] =
233{
234 0x00000000, 0x01000000, 0x00010000, 0x01010000,
235 0x00000100, 0x01000100, 0x00010100, 0x01010100,
236 0x00000001, 0x01000001, 0x00010001, 0x01010001,
237 0x00000101, 0x01000101, 0x00010101, 0x01010101,
238};
239
240/*
241 * Initial Permutation macro
242 */
243#define DES_IP(X,Y) \
244{ \
245 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
246 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
247 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
248 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
249 Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
250 T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
251 X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
252}
253
254/*
255 * Final Permutation macro
256 */
257#define DES_FP(X,Y) \
258{ \
259 X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
260 T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
261 Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
262 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
263 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
264 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
265 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
266}
267
268/*
269 * DES round macro
270 */
271#define DES_ROUND(X,Y) \
272{ \
273 T = *SK++ ^ X; \
274 Y ^= SB8[ (T ) & 0x3F ] ^ \
275 SB6[ (T >> 8) & 0x3F ] ^ \
276 SB4[ (T >> 16) & 0x3F ] ^ \
277 SB2[ (T >> 24) & 0x3F ]; \
278 \
279 T = *SK++ ^ ((X << 28) | (X >> 4)); \
280 Y ^= SB7[ (T ) & 0x3F ] ^ \
281 SB5[ (T >> 8) & 0x3F ] ^ \
282 SB3[ (T >> 16) & 0x3F ] ^ \
283 SB1[ (T >> 24) & 0x3F ]; \
284}
285
286#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }
287
288static void des_setkey( unsigned long SK[32], unsigned char key[8] )
289{
290 int i;
291 unsigned long X, Y, T;
292
293 GET_ULONG_BE( X, key, 0 );
294 GET_ULONG_BE( Y, key, 4 );
295
296 /*
297 * Permuted Choice 1
298 */
299 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
300 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
301
302 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
303 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
304 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
305 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
306
307 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
308 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
309 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
310 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
311
312 X &= 0x0FFFFFFF;
313 Y &= 0x0FFFFFFF;
314
315 /*
316 * calculate subkeys
317 */
318 for( i = 0; i < 16; i++ )
319 {
320 if( i < 2 || i == 8 || i == 15 )
321 {
322 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
323 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
324 }
325 else
326 {
327 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
328 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
329 }
330
331 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
332 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
333 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
334 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
335 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
336 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
337 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
338 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
339 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
340 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
341 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
342
343 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
344 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
345 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
346 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
347 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
348 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
349 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
350 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
351 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
352 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
353 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
354 }
355}
356
357/*
358 * DES key schedule (56-bit, encryption)
359 */
360void des_setkey_enc( des_context *ctx, unsigned char key[8] )
361{
362 des_setkey( ctx->sk, key );
363}
364
365/*
366 * DES key schedule (56-bit, decryption)
367 */
368void des_setkey_dec( des_context *ctx, unsigned char key[8] )
369{
370 int i;
371
372 des_setkey( ctx->sk, key );
373
374 for( i = 0; i < 16; i += 2 )
375 {
376 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
377 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
378 }
379}
380
381static void des3_set2key( unsigned long esk[96],
382 unsigned long dsk[96],
383 unsigned char key[16] )
384{
385 int i;
386
387 des_setkey( esk, key );
388 des_setkey( dsk + 32, key + 8 );
389
390 for( i = 0; i < 32; i += 2 )
391 {
392 dsk[i ] = esk[30 - i];
393 dsk[i + 1] = esk[31 - i];
394
395 esk[i + 32] = dsk[62 - i];
396 esk[i + 33] = dsk[63 - i];
397
398 esk[i + 64] = esk[i ];
399 esk[i + 65] = esk[i + 1];
400
401 dsk[i + 64] = dsk[i ];
402 dsk[i + 65] = dsk[i + 1];
403 }
404}
405
406/*
407 * Triple-DES key schedule (112-bit, encryption)
408 */
409void des3_set2key_enc( des3_context *ctx, unsigned char key[16] )
410{
411 unsigned long sk[96];
412
413 des3_set2key( ctx->sk, sk, key );
414 memset( sk, 0, sizeof( sk ) );
415}
416
417/*
418 * Triple-DES key schedule (112-bit, decryption)
419 */
420void des3_set2key_dec( des3_context *ctx, unsigned char key[16] )
421{
422 unsigned long sk[96];
423
424 des3_set2key( sk, ctx->sk, key );
425 memset( sk, 0, sizeof( sk ) );
426}
427
428static void des3_set3key( unsigned long esk[96],
429 unsigned long dsk[96],
430 unsigned char key[24] )
431{
432 int i;
433
434 des_setkey( esk, key );
435 des_setkey( dsk + 32, key + 8 );
436 des_setkey( esk + 64, key + 16 );
437
438 for( i = 0; i < 32; i += 2 )
439 {
440 dsk[i ] = esk[94 - i];
441 dsk[i + 1] = esk[95 - i];
442
443 esk[i + 32] = dsk[62 - i];
444 esk[i + 33] = dsk[63 - i];
445
446 dsk[i + 64] = esk[30 - i];
447 dsk[i + 65] = esk[31 - i];
448 }
449}
450
451/*
452 * Triple-DES key schedule (168-bit, encryption)
453 */
454void des3_set3key_enc( des3_context *ctx, unsigned char key[24] )
455{
456 unsigned long sk[96];
457
458 des3_set3key( ctx->sk, sk, key );
459 memset( sk, 0, sizeof( sk ) );
460}
461
462/*
463 * Triple-DES key schedule (168-bit, decryption)
464 */
465void des3_set3key_dec( des3_context *ctx, unsigned char key[24] )
466{
467 unsigned long sk[96];
468
469 des3_set3key( sk, ctx->sk, key );
470 memset( sk, 0, sizeof( sk ) );
471}
472
473/*
474 * DES-ECB block encryption/decryption
475 */
476void des_crypt_ecb( des_context *ctx,
477 unsigned char input[8],
478 unsigned char output[8] )
479{
480 int i;
481 unsigned long X, Y, T, *SK;
482
483 SK = ctx->sk;
484
485 GET_ULONG_BE( X, input, 0 );
486 GET_ULONG_BE( Y, input, 4 );
487
488 DES_IP( X, Y );
489
490 for( i = 0; i < 8; i++ )
491 {
492 DES_ROUND( Y, X );
493 DES_ROUND( X, Y );
494 }
495
496 DES_FP( Y, X );
497
498 PUT_ULONG_BE( Y, output, 0 );
499 PUT_ULONG_BE( X, output, 4 );
500}
501
502/*
503 * DES-CBC buffer encryption/decryption
504 */
505void des_crypt_cbc( des_context *ctx,
506 int mode,
507 int length,
508 unsigned char iv[8],
509 unsigned char *input,
510 unsigned char *output )
511{
512 int i;
513 unsigned char temp[8];
514
515 if( mode == DES_ENCRYPT )
516 {
517 while( length > 0 )
518 {
519 for( i = 0; i < 8; i++ )
520 output[i] = (unsigned char)( input[i] ^ iv[i] );
521
522 des_crypt_ecb( ctx, output, output );
523 memcpy( iv, output, 8 );
524
525 input += 8;
526 output += 8;
527 length -= 8;
528 }
529 }
530 else /* DES_DECRYPT */
531 {
532 while( length > 0 )
533 {
534 memcpy( temp, input, 8 );
535 des_crypt_ecb( ctx, input, output );
536
537 for( i = 0; i < 8; i++ )
538 output[i] = (unsigned char)( output[i] ^ iv[i] );
539
540 memcpy( iv, temp, 8 );
541
542 input += 8;
543 output += 8;
544 length -= 8;
545 }
546 }
547}
548
549/*
550 * 3DES-ECB block encryption/decryption
551 */
552void des3_crypt_ecb( des3_context *ctx,
553 unsigned char input[8],
554 unsigned char output[8] )
555{
556 int i;
557 unsigned long X, Y, T, *SK;
558
559 SK = ctx->sk;
560
561 GET_ULONG_BE( X, input, 0 );
562 GET_ULONG_BE( Y, input, 4 );
563
564 DES_IP( X, Y );
565
566 for( i = 0; i < 8; i++ )
567 {
568 DES_ROUND( Y, X );
569 DES_ROUND( X, Y );
570 }
571
572 for( i = 0; i < 8; i++ )
573 {
574 DES_ROUND( X, Y );
575 DES_ROUND( Y, X );
576 }
577
578 for( i = 0; i < 8; i++ )
579 {
580 DES_ROUND( Y, X );
581 DES_ROUND( X, Y );
582 }
583
584 DES_FP( Y, X );
585
586 PUT_ULONG_BE( Y, output, 0 );
587 PUT_ULONG_BE( X, output, 4 );
588}
589
590/*
591 * 3DES-CBC buffer encryption/decryption
592 */
593void des3_crypt_cbc( des3_context *ctx,
594 int mode,
595 int length,
596 unsigned char iv[8],
597 unsigned char *input,
598 unsigned char *output )
599{
600 int i;
601 unsigned char temp[8];
602
603 if( mode == DES_ENCRYPT )
604 {
605 while( length > 0 )
606 {
607 for( i = 0; i < 8; i++ )
608 output[i] = (unsigned char)( input[i] ^ iv[i] );
609
610 des3_crypt_ecb( ctx, output, output );
611 memcpy( iv, output, 8 );
612
613 input += 8;
614 output += 8;
615 length -= 8;
616 }
617 }
618 else /* DES_DECRYPT */
619 {
620 while( length > 0 )
621 {
622 memcpy( temp, input, 8 );
623 des3_crypt_ecb( ctx, input, output );
624
625 for( i = 0; i < 8; i++ )
626 output[i] = (unsigned char)( output[i] ^ iv[i] );
627
628 memcpy( iv, temp, 8 );
629
630 input += 8;
631 output += 8;
632 length -= 8;
633 }
634 }
635}
636
637#if defined(XYSSL_SELF_TEST)
638
639#include <stdio.h>
640
641/*
642 * DES and 3DES test vectors from:
643 *
644 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
645 */
646static const unsigned char des3_test_keys[24] =
647{
648 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
649 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
650 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
651};
652
653static const unsigned char des3_test_iv[8] =
654{
655 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
656};
657
658static const unsigned char des3_test_buf[8] =
659{
660 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
661};
662
663static const unsigned char des3_test_ecb_dec[3][8] =
664{
665 { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
666 { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
667 { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
668};
669
670static const unsigned char des3_test_ecb_enc[3][8] =
671{
672 { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
673 { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
674 { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
675};
676
677static const unsigned char des3_test_cbc_dec[3][8] =
678{
679 { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
680 { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
681 { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
682};
683
684static const unsigned char des3_test_cbc_enc[3][8] =
685{
686 { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
687 { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
688 { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
689};
690
691/*
692 * Checkup routine
693 */
694int des_self_test( int verbose )
695{
696 int i, j, u, v;
697 des_context ctx;
698 des3_context ctx3;
699 unsigned char key[24];
700 unsigned char buf[8];
701 unsigned char prv[8];
702 unsigned char iv[8];
703
704 memset( key, 0, 24 );
705
706 /*
707 * ECB mode
708 */
709 for( i = 0; i < 6; i++ )
710 {
711 u = i >> 1;
712 v = i & 1;
713
714 if( verbose != 0 )
715 printf( " DES%c-ECB-%3d (%s): ",
716 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
717 ( v == DES_DECRYPT ) ? "dec" : "enc" );
718
719 memcpy( buf, des3_test_buf, 8 );
720
721 switch( i )
722 {
723 case 0:
724 des_setkey_dec( &ctx, (unsigned char *) des3_test_keys );
725 break;
726
727 case 1:
728 des_setkey_enc( &ctx, (unsigned char *) des3_test_keys );
729 break;
730
731 case 2:
732 des3_set2key_dec( &ctx3, (unsigned char *) des3_test_keys );
733 break;
734
735 case 3:
736 des3_set2key_enc( &ctx3, (unsigned char *) des3_test_keys );
737 break;
738
739 case 4:
740 des3_set3key_dec( &ctx3, (unsigned char *) des3_test_keys );
741 break;
742
743 case 5:
744 des3_set3key_enc( &ctx3, (unsigned char *) des3_test_keys );
745 break;
746
747 default:
748 return( 1 );
749 }
750
751 for( j = 0; j < 10000; j++ )
752 {
753 if( u == 0 )
754 des_crypt_ecb( &ctx, buf, buf );
755 else
756 des3_crypt_ecb( &ctx3, buf, buf );
757 }
758
759 if( ( v == DES_DECRYPT &&
760 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
761 ( v != DES_DECRYPT &&
762 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
763 {
764 if( verbose != 0 )
765 printf( "failed\n" );
766
767 return( 1 );
768 }
769
770 if( verbose != 0 )
771 printf( "passed\n" );
772 }
773
774 if( verbose != 0 )
775 printf( "\n" );
776
777 /*
778 * CBC mode
779 */
780 for( i = 0; i < 6; i++ )
781 {
782 u = i >> 1;
783 v = i & 1;
784
785 if( verbose != 0 )
786 printf( " DES%c-CBC-%3d (%s): ",
787 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
788 ( v == DES_DECRYPT ) ? "dec" : "enc" );
789
790 memcpy( iv, des3_test_iv, 8 );
791 memcpy( prv, des3_test_iv, 8 );
792 memcpy( buf, des3_test_buf, 8 );
793
794 switch( i )
795 {
796 case 0:
797 des_setkey_dec( &ctx, (unsigned char *) des3_test_keys );
798 break;
799
800 case 1:
801 des_setkey_enc( &ctx, (unsigned char *) des3_test_keys );
802 break;
803
804 case 2:
805 des3_set2key_dec( &ctx3, (unsigned char *) des3_test_keys );
806 break;
807
808 case 3:
809 des3_set2key_enc( &ctx3, (unsigned char *) des3_test_keys );
810 break;
811
812 case 4:
813 des3_set3key_dec( &ctx3, (unsigned char *) des3_test_keys );
814 break;
815
816 case 5:
817 des3_set3key_enc( &ctx3, (unsigned char *) des3_test_keys );
818 break;
819
820 default:
821 return( 1 );
822 }
823
824 if( v == DES_DECRYPT )
825 {
826 for( j = 0; j < 10000; j++ )
827 {
828 if( u == 0 )
829 des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
830 else
831 des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
832 }
833 }
834 else
835 {
836 for( j = 0; j < 10000; j++ )
837 {
838 unsigned char tmp[8];
839
840 if( u == 0 )
841 des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
842 else
843 des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
844
845 memcpy( tmp, prv, 8 );
846 memcpy( prv, buf, 8 );
847 memcpy( buf, tmp, 8 );
848 }
849
850 memcpy( buf, prv, 8 );
851 }
852
853 if( ( v == DES_DECRYPT &&
854 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
855 ( v != DES_DECRYPT &&
856 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
857 {
858 if( verbose != 0 )
859 printf( "failed\n" );
860
861 return( 1 );
862 }
863
864 if( verbose != 0 )
865 printf( "passed\n" );
866 }
867
868 if( verbose != 0 )
869 printf( "\n" );
870
871 return( 0 );
872}
873
874#endif
875
876#endif