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