ssl/tls: add proper const attributes to functions, context members
[tropicssl.git] / library / des.c
blob5be7056ac668877afb9b7113fe5c7cfef30782d8
1 /*
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>
8 * All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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"
48 #include <string.h>
51 * 32-bit integer manipulation macros (big endian)
53 #ifndef GET_ULONG_BE
54 #define GET_ULONG_BE(n,b,i) \
55 { \
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] ); \
61 #endif
63 #ifndef PUT_ULONG_BE
64 #define PUT_ULONG_BE(n,b,i) \
65 { \
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) ); \
71 #endif
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); \
274 * DES round macro
276 #define DES_ROUND(X,Y) \
278 T = *SK++ ^ X; \
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])
295 int i;
296 unsigned long X, Y, T;
298 GET_ULONG_BE(X, key, 0);
299 GET_ULONG_BE(Y, key, 4);
302 * Permuted Choice 1
304 T = ((Y >> 4) ^ X) & 0x0F0F0F0F;
305 X ^= T;
306 Y ^= (T << 4);
307 T = ((Y) ^ X) & 0x10101010;
308 X ^= T;
309 Y ^= (T);
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);
321 X &= 0x0FFFFFFF;
322 Y &= 0x0FFFFFFF;
325 * calculate subkeys
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;
331 } else {
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])
375 int i;
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])
388 int i;
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])
433 int i;
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])
480 int i;
481 unsigned long X, Y, T, *SK;
483 SK = ctx->sk;
485 GET_ULONG_BE(X, input, 0);
486 GET_ULONG_BE(Y, input, 4);
488 DES_IP(X, Y);
490 for (i = 0; i < 8; i++) {
491 DES_ROUND(Y, X);
492 DES_ROUND(X, Y);
495 DES_FP(Y, X);
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,
505 int mode,
506 int length,
507 unsigned char iv[8],
508 const unsigned char *input,
509 unsigned char *output)
511 int i;
512 unsigned char temp[8];
514 if (mode == DES_ENCRYPT) {
515 while (length > 0) {
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);
522 input += 8;
523 output += 8;
524 length -= 8;
526 } else { /* DES_DECRYPT */
527 while (length > 0) {
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]);
534 memcpy(iv, temp, 8);
536 input += 8;
537 output += 8;
538 length -= 8;
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])
550 int i;
551 unsigned long X, Y, T, *SK;
553 SK = ctx->sk;
555 GET_ULONG_BE(X, input, 0);
556 GET_ULONG_BE(Y, input, 4);
558 DES_IP(X, Y);
560 for (i = 0; i < 8; i++) {
561 DES_ROUND(Y, X);
562 DES_ROUND(X, Y);
565 for (i = 0; i < 8; i++) {
566 DES_ROUND(X, Y);
567 DES_ROUND(Y, X);
570 for (i = 0; i < 8; i++) {
571 DES_ROUND(Y, X);
572 DES_ROUND(X, Y);
575 DES_FP(Y, X);
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,
585 int mode,
586 int length,
587 unsigned char iv[8],
588 const unsigned char *input,
589 unsigned char *output)
591 int i;
592 unsigned char temp[8];
594 if (mode == DES_ENCRYPT) {
595 while (length > 0) {
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);
602 input += 8;
603 output += 8;
604 length -= 8;
606 } else { /* DES_DECRYPT */
607 while (length > 0) {
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]);
614 memcpy(iv, temp, 8);
616 input += 8;
617 output += 8;
618 length -= 8;
623 #if defined(TROPICSSL_SELF_TEST)
625 #include <stdio.h>
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}
671 * Checkup routine
673 int des_self_test(int verbose)
675 int i, j, u, v;
676 des_context ctx;
677 des3_context ctx3;
678 unsigned char key[24];
679 unsigned char buf[8];
680 unsigned char prv[8];
681 unsigned char iv[8];
683 memset(key, 0, 24);
686 * ECB mode
688 for (i = 0; i < 6; i++) {
689 u = i >> 1;
690 v = i & 1;
692 if (verbose != 0)
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);
699 switch (i) {
700 case 0:
701 des_setkey_dec(&ctx, des3_test_keys);
702 break;
704 case 1:
705 des_setkey_enc(&ctx, des3_test_keys);
706 break;
708 case 2:
709 des3_set2key_dec(&ctx3, des3_test_keys);
710 break;
712 case 3:
713 des3_set2key_enc(&ctx3, des3_test_keys);
714 break;
716 case 4:
717 des3_set3key_dec(&ctx3, des3_test_keys);
718 break;
720 case 5:
721 des3_set3key_enc(&ctx3,
722 des3_test_keys);
723 break;
725 default:
726 return (1);
729 for (j = 0; j < 10000; j++) {
730 if (u == 0)
731 des_crypt_ecb(&ctx, buf, buf);
732 else
733 des3_crypt_ecb(&ctx3, buf, buf);
736 if ((v == DES_DECRYPT &&
737 memcmp(buf, des3_test_ecb_dec[u], 8) != 0) ||
738 (v != DES_DECRYPT &&
739 memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) {
740 if (verbose != 0)
741 printf("failed\n");
743 return (1);
746 if (verbose != 0)
747 printf("passed\n");
750 if (verbose != 0)
751 printf("\n");
754 * CBC mode
756 for (i = 0; i < 6; i++) {
757 u = i >> 1;
758 v = i & 1;
760 if (verbose != 0)
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);
769 switch (i) {
770 case 0:
771 des_setkey_dec(&ctx, des3_test_keys);
772 break;
774 case 1:
775 des_setkey_enc(&ctx, des3_test_keys);
776 break;
778 case 2:
779 des3_set2key_dec(&ctx3, des3_test_keys);
780 break;
782 case 3:
783 des3_set2key_enc(&ctx3, des3_test_keys);
784 break;
786 case 4:
787 des3_set3key_dec(&ctx3, des3_test_keys);
788 break;
790 case 5:
791 des3_set3key_enc(&ctx3, des3_test_keys);
792 break;
794 default:
795 return (1);
798 if (v == DES_DECRYPT) {
799 for (j = 0; j < 10000; j++) {
800 if (u == 0)
801 des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
802 else
803 des3_crypt_cbc(&ctx3, v, 8, iv, buf,
804 buf);
806 } else {
807 for (j = 0; j < 10000; j++) {
808 unsigned char tmp[8];
810 if (u == 0)
811 des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
812 else
813 des3_crypt_cbc(&ctx3, v, 8, iv, buf,
814 buf);
816 memcpy(tmp, prv, 8);
817 memcpy(prv, buf, 8);
818 memcpy(buf, tmp, 8);
821 memcpy(buf, prv, 8);
824 if ((v == DES_DECRYPT &&
825 memcmp(buf, des3_test_cbc_dec[u], 8) != 0) ||
826 (v != DES_DECRYPT &&
827 memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) {
828 if (verbose != 0)
829 printf("failed\n");
831 return (1);
834 if (verbose != 0)
835 printf("passed\n");
838 if (verbose != 0)
839 printf("\n");
841 return (0);
844 #endif
846 #endif