blob: 68de7013daf273cc346944333c3c28f46e1d9dd6 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-46-3 compliant Triple-DES implementation
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkerb96f1542010-07-18 20:36:00 +00007 *
Paul Bakker5121ce52009-01-03 21:22:43 +00008 * 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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020033#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#if defined(MBEDTLS_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/des.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_SELF_TEST)
42#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044#else
Rich Evans00ab4702015-02-06 13:43:58 +000045#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#define mbedtls_printf printf
47#endif /* MBEDTLS_PLATFORM_C */
48#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020051
Paul Bakker34617722014-06-13 17:20:13 +020052/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020054 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
55}
56
Paul Bakker5121ce52009-01-03 21:22:43 +000057/*
58 * 32-bit integer manipulation macros (big endian)
59 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000060#ifndef GET_UINT32_BE
61#define GET_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000062{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000063 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
64 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
65 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
66 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000067}
68#endif
69
Paul Bakker5c2364c2012-10-01 14:41:15 +000070#ifndef PUT_UINT32_BE
71#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000072{ \
73 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
74 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
75 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
76 (b)[(i) + 3] = (unsigned char) ( (n) ); \
77}
78#endif
79
80/*
81 * Expanded DES S-boxes
82 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000083static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000084{
85 0x01010400, 0x00000000, 0x00010000, 0x01010404,
86 0x01010004, 0x00010404, 0x00000004, 0x00010000,
87 0x00000400, 0x01010400, 0x01010404, 0x00000400,
88 0x01000404, 0x01010004, 0x01000000, 0x00000004,
89 0x00000404, 0x01000400, 0x01000400, 0x00010400,
90 0x00010400, 0x01010000, 0x01010000, 0x01000404,
91 0x00010004, 0x01000004, 0x01000004, 0x00010004,
92 0x00000000, 0x00000404, 0x00010404, 0x01000000,
93 0x00010000, 0x01010404, 0x00000004, 0x01010000,
94 0x01010400, 0x01000000, 0x01000000, 0x00000400,
95 0x01010004, 0x00010000, 0x00010400, 0x01000004,
96 0x00000400, 0x00000004, 0x01000404, 0x00010404,
97 0x01010404, 0x00010004, 0x01010000, 0x01000404,
98 0x01000004, 0x00000404, 0x00010404, 0x01010400,
99 0x00000404, 0x01000400, 0x01000400, 0x00000000,
100 0x00010004, 0x00010400, 0x00000000, 0x01010004
101};
102
Paul Bakker5c2364c2012-10-01 14:41:15 +0000103static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000104{
105 0x80108020, 0x80008000, 0x00008000, 0x00108020,
106 0x00100000, 0x00000020, 0x80100020, 0x80008020,
107 0x80000020, 0x80108020, 0x80108000, 0x80000000,
108 0x80008000, 0x00100000, 0x00000020, 0x80100020,
109 0x00108000, 0x00100020, 0x80008020, 0x00000000,
110 0x80000000, 0x00008000, 0x00108020, 0x80100000,
111 0x00100020, 0x80000020, 0x00000000, 0x00108000,
112 0x00008020, 0x80108000, 0x80100000, 0x00008020,
113 0x00000000, 0x00108020, 0x80100020, 0x00100000,
114 0x80008020, 0x80100000, 0x80108000, 0x00008000,
115 0x80100000, 0x80008000, 0x00000020, 0x80108020,
116 0x00108020, 0x00000020, 0x00008000, 0x80000000,
117 0x00008020, 0x80108000, 0x00100000, 0x80000020,
118 0x00100020, 0x80008020, 0x80000020, 0x00100020,
119 0x00108000, 0x00000000, 0x80008000, 0x00008020,
120 0x80000000, 0x80100020, 0x80108020, 0x00108000
121};
122
Paul Bakker5c2364c2012-10-01 14:41:15 +0000123static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000124{
125 0x00000208, 0x08020200, 0x00000000, 0x08020008,
126 0x08000200, 0x00000000, 0x00020208, 0x08000200,
127 0x00020008, 0x08000008, 0x08000008, 0x00020000,
128 0x08020208, 0x00020008, 0x08020000, 0x00000208,
129 0x08000000, 0x00000008, 0x08020200, 0x00000200,
130 0x00020200, 0x08020000, 0x08020008, 0x00020208,
131 0x08000208, 0x00020200, 0x00020000, 0x08000208,
132 0x00000008, 0x08020208, 0x00000200, 0x08000000,
133 0x08020200, 0x08000000, 0x00020008, 0x00000208,
134 0x00020000, 0x08020200, 0x08000200, 0x00000000,
135 0x00000200, 0x00020008, 0x08020208, 0x08000200,
136 0x08000008, 0x00000200, 0x00000000, 0x08020008,
137 0x08000208, 0x00020000, 0x08000000, 0x08020208,
138 0x00000008, 0x00020208, 0x00020200, 0x08000008,
139 0x08020000, 0x08000208, 0x00000208, 0x08020000,
140 0x00020208, 0x00000008, 0x08020008, 0x00020200
141};
142
Paul Bakker5c2364c2012-10-01 14:41:15 +0000143static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000144{
145 0x00802001, 0x00002081, 0x00002081, 0x00000080,
146 0x00802080, 0x00800081, 0x00800001, 0x00002001,
147 0x00000000, 0x00802000, 0x00802000, 0x00802081,
148 0x00000081, 0x00000000, 0x00800080, 0x00800001,
149 0x00000001, 0x00002000, 0x00800000, 0x00802001,
150 0x00000080, 0x00800000, 0x00002001, 0x00002080,
151 0x00800081, 0x00000001, 0x00002080, 0x00800080,
152 0x00002000, 0x00802080, 0x00802081, 0x00000081,
153 0x00800080, 0x00800001, 0x00802000, 0x00802081,
154 0x00000081, 0x00000000, 0x00000000, 0x00802000,
155 0x00002080, 0x00800080, 0x00800081, 0x00000001,
156 0x00802001, 0x00002081, 0x00002081, 0x00000080,
157 0x00802081, 0x00000081, 0x00000001, 0x00002000,
158 0x00800001, 0x00002001, 0x00802080, 0x00800081,
159 0x00002001, 0x00002080, 0x00800000, 0x00802001,
160 0x00000080, 0x00800000, 0x00002000, 0x00802080
161};
162
Paul Bakker5c2364c2012-10-01 14:41:15 +0000163static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000164{
165 0x00000100, 0x02080100, 0x02080000, 0x42000100,
166 0x00080000, 0x00000100, 0x40000000, 0x02080000,
167 0x40080100, 0x00080000, 0x02000100, 0x40080100,
168 0x42000100, 0x42080000, 0x00080100, 0x40000000,
169 0x02000000, 0x40080000, 0x40080000, 0x00000000,
170 0x40000100, 0x42080100, 0x42080100, 0x02000100,
171 0x42080000, 0x40000100, 0x00000000, 0x42000000,
172 0x02080100, 0x02000000, 0x42000000, 0x00080100,
173 0x00080000, 0x42000100, 0x00000100, 0x02000000,
174 0x40000000, 0x02080000, 0x42000100, 0x40080100,
175 0x02000100, 0x40000000, 0x42080000, 0x02080100,
176 0x40080100, 0x00000100, 0x02000000, 0x42080000,
177 0x42080100, 0x00080100, 0x42000000, 0x42080100,
178 0x02080000, 0x00000000, 0x40080000, 0x42000000,
179 0x00080100, 0x02000100, 0x40000100, 0x00080000,
180 0x00000000, 0x40080000, 0x02080100, 0x40000100
181};
182
Paul Bakker5c2364c2012-10-01 14:41:15 +0000183static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000184{
185 0x20000010, 0x20400000, 0x00004000, 0x20404010,
186 0x20400000, 0x00000010, 0x20404010, 0x00400000,
187 0x20004000, 0x00404010, 0x00400000, 0x20000010,
188 0x00400010, 0x20004000, 0x20000000, 0x00004010,
189 0x00000000, 0x00400010, 0x20004010, 0x00004000,
190 0x00404000, 0x20004010, 0x00000010, 0x20400010,
191 0x20400010, 0x00000000, 0x00404010, 0x20404000,
192 0x00004010, 0x00404000, 0x20404000, 0x20000000,
193 0x20004000, 0x00000010, 0x20400010, 0x00404000,
194 0x20404010, 0x00400000, 0x00004010, 0x20000010,
195 0x00400000, 0x20004000, 0x20000000, 0x00004010,
196 0x20000010, 0x20404010, 0x00404000, 0x20400000,
197 0x00404010, 0x20404000, 0x00000000, 0x20400010,
198 0x00000010, 0x00004000, 0x20400000, 0x00404010,
199 0x00004000, 0x00400010, 0x20004010, 0x00000000,
200 0x20404000, 0x20000000, 0x00400010, 0x20004010
201};
202
Paul Bakker5c2364c2012-10-01 14:41:15 +0000203static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000204{
205 0x00200000, 0x04200002, 0x04000802, 0x00000000,
206 0x00000800, 0x04000802, 0x00200802, 0x04200800,
207 0x04200802, 0x00200000, 0x00000000, 0x04000002,
208 0x00000002, 0x04000000, 0x04200002, 0x00000802,
209 0x04000800, 0x00200802, 0x00200002, 0x04000800,
210 0x04000002, 0x04200000, 0x04200800, 0x00200002,
211 0x04200000, 0x00000800, 0x00000802, 0x04200802,
212 0x00200800, 0x00000002, 0x04000000, 0x00200800,
213 0x04000000, 0x00200800, 0x00200000, 0x04000802,
214 0x04000802, 0x04200002, 0x04200002, 0x00000002,
215 0x00200002, 0x04000000, 0x04000800, 0x00200000,
216 0x04200800, 0x00000802, 0x00200802, 0x04200800,
217 0x00000802, 0x04000002, 0x04200802, 0x04200000,
218 0x00200800, 0x00000000, 0x00000002, 0x04200802,
219 0x00000000, 0x00200802, 0x04200000, 0x00000800,
220 0x04000002, 0x04000800, 0x00000800, 0x00200002
221};
222
Paul Bakker5c2364c2012-10-01 14:41:15 +0000223static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000224{
225 0x10001040, 0x00001000, 0x00040000, 0x10041040,
226 0x10000000, 0x10001040, 0x00000040, 0x10000000,
227 0x00040040, 0x10040000, 0x10041040, 0x00041000,
228 0x10041000, 0x00041040, 0x00001000, 0x00000040,
229 0x10040000, 0x10000040, 0x10001000, 0x00001040,
230 0x00041000, 0x00040040, 0x10040040, 0x10041000,
231 0x00001040, 0x00000000, 0x00000000, 0x10040040,
232 0x10000040, 0x10001000, 0x00041040, 0x00040000,
233 0x00041040, 0x00040000, 0x10041000, 0x00001000,
234 0x00000040, 0x10040040, 0x00001000, 0x00041040,
235 0x10001000, 0x00000040, 0x10000040, 0x10040000,
236 0x10040040, 0x10000000, 0x00040000, 0x10001040,
237 0x00000000, 0x10041040, 0x00040040, 0x10000040,
238 0x10040000, 0x10001000, 0x10001040, 0x00000000,
239 0x10041040, 0x00041000, 0x00041000, 0x00001040,
240 0x00001040, 0x00040040, 0x10000000, 0x10041000
241};
242
243/*
244 * PC1: left and right halves bit-swap
245 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000246static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000247{
248 0x00000000, 0x00000001, 0x00000100, 0x00000101,
249 0x00010000, 0x00010001, 0x00010100, 0x00010101,
250 0x01000000, 0x01000001, 0x01000100, 0x01000101,
251 0x01010000, 0x01010001, 0x01010100, 0x01010101
252};
253
Paul Bakker5c2364c2012-10-01 14:41:15 +0000254static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000255{
256 0x00000000, 0x01000000, 0x00010000, 0x01010000,
257 0x00000100, 0x01000100, 0x00010100, 0x01010100,
258 0x00000001, 0x01000001, 0x00010001, 0x01010001,
259 0x00000101, 0x01000101, 0x00010101, 0x01010101,
260};
261
262/*
263 * Initial Permutation macro
264 */
265#define DES_IP(X,Y) \
266{ \
267 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
268 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
269 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
270 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
271 Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
272 T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
273 X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
274}
275
276/*
277 * Final Permutation macro
278 */
279#define DES_FP(X,Y) \
280{ \
281 X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
282 T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
283 Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
284 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
285 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
286 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
287 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
288}
289
290/*
291 * DES round macro
292 */
293#define DES_ROUND(X,Y) \
294{ \
295 T = *SK++ ^ X; \
296 Y ^= SB8[ (T ) & 0x3F ] ^ \
297 SB6[ (T >> 8) & 0x3F ] ^ \
298 SB4[ (T >> 16) & 0x3F ] ^ \
299 SB2[ (T >> 24) & 0x3F ]; \
300 \
301 T = *SK++ ^ ((X << 28) | (X >> 4)); \
302 Y ^= SB7[ (T ) & 0x3F ] ^ \
303 SB5[ (T >> 8) & 0x3F ] ^ \
304 SB3[ (T >> 16) & 0x3F ] ^ \
305 SB1[ (T >> 24) & 0x3F ]; \
306}
307
Paul Bakker5c2364c2012-10-01 14:41:15 +0000308#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; }
Paul Bakker5121ce52009-01-03 21:22:43 +0000309
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200310void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200311{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200313}
314
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200315void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200316{
317 if( ctx == NULL )
318 return;
319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320 mbedtls_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200321}
322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200324{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200326}
327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200329{
330 if( ctx == NULL )
331 return;
332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333 mbedtls_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200334}
335
Paul Bakker1f87fb62011-01-15 17:32:24 +0000336static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
337 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
338 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
339 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
340 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
341 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
342 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
343 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
344 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
345 254 };
346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000348{
349 int i;
350
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000352 key[i] = odd_parity_table[key[i] / 2];
353}
354
355/*
356 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
357 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000359{
360 int i;
361
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200363 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000364 return( 1 );
365
366 return( 0 );
367}
368
369/*
370 * Table of weak and semi-weak keys
371 *
372 * Source: http://en.wikipedia.org/wiki/Weak_key
373 *
374 * Weak:
375 * Alternating ones + zeros (0x0101010101010101)
376 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
377 * '0xE0E0E0E0F1F1F1F1'
378 * '0x1F1F1F1F0E0E0E0E'
379 *
380 * Semi-weak:
381 * 0x011F011F010E010E and 0x1F011F010E010E01
382 * 0x01E001E001F101F1 and 0xE001E001F101F101
383 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
384 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
385 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
386 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
387 *
388 */
389
390#define WEAK_KEY_COUNT 16
391
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000393{
394 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
395 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
396 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
397 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
398
399 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
400 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
401 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
402 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
403 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
404 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
405 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
406 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
407 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
408 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
409 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
410 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
411};
412
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000414{
415 int i;
416
417 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000419 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000420
Paul Bakker73206952011-07-06 14:37:33 +0000421 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000422}
423
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200424#if !defined(MBEDTLS_DES_SETKEY_ALT)
425void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000426{
427 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000428 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Paul Bakker5c2364c2012-10-01 14:41:15 +0000430 GET_UINT32_BE( X, key, 0 );
431 GET_UINT32_BE( Y, key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
433 /*
434 * Permuted Choice 1
435 */
436 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
437 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
438
439 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
440 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
441 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
442 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
443
444 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
445 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
446 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
447 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
448
449 X &= 0x0FFFFFFF;
450 Y &= 0x0FFFFFFF;
451
452 /*
453 * calculate subkeys
454 */
455 for( i = 0; i < 16; i++ )
456 {
457 if( i < 2 || i == 8 || i == 15 )
458 {
459 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
460 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
461 }
462 else
463 {
464 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
465 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
466 }
467
468 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
469 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
470 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
471 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
472 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
473 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
474 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
475 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
476 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
477 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
478 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
479
480 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
481 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
482 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
483 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
484 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
485 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
486 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
487 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
488 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
489 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
490 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
491 }
492}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200493#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
495/*
496 * DES key schedule (56-bit, encryption)
497 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000499{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200500 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000501
502 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000503}
504
505/*
506 * DES key schedule (56-bit, decryption)
507 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000509{
510 int i;
511
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200512 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000513
514 for( i = 0; i < 16; i += 2 )
515 {
516 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
517 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
518 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000519
520 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000521}
522
Paul Bakker5c2364c2012-10-01 14:41:15 +0000523static void des3_set2key( uint32_t esk[96],
524 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000526{
527 int i;
528
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200529 mbedtls_des_setkey( esk, key );
530 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000531
532 for( i = 0; i < 32; i += 2 )
533 {
534 dsk[i ] = esk[30 - i];
535 dsk[i + 1] = esk[31 - i];
536
537 esk[i + 32] = dsk[62 - i];
538 esk[i + 33] = dsk[63 - i];
539
540 esk[i + 64] = esk[i ];
541 esk[i + 65] = esk[i + 1];
542
543 dsk[i + 64] = dsk[i ];
544 dsk[i + 65] = dsk[i + 1];
545 }
546}
547
548/*
549 * Triple-DES key schedule (112-bit, encryption)
550 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
552 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000553{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000554 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
556 des3_set2key( ctx->sk, sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000558
559 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000560}
561
562/*
563 * Triple-DES key schedule (112-bit, decryption)
564 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
566 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000567{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000568 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000569
570 des3_set2key( sk, ctx->sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200571 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000572
573 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000574}
575
Paul Bakker5c2364c2012-10-01 14:41:15 +0000576static void des3_set3key( uint32_t esk[96],
577 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000578 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000579{
580 int i;
581
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200582 mbedtls_des_setkey( esk, key );
583 mbedtls_des_setkey( dsk + 32, key + 8 );
584 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000585
586 for( i = 0; i < 32; i += 2 )
587 {
588 dsk[i ] = esk[94 - i];
589 dsk[i + 1] = esk[95 - i];
590
591 esk[i + 32] = dsk[62 - i];
592 esk[i + 33] = dsk[63 - i];
593
594 dsk[i + 64] = esk[30 - i];
595 dsk[i + 65] = esk[31 - i];
596 }
597}
598
599/*
600 * Triple-DES key schedule (168-bit, encryption)
601 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
603 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000604{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000605 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
607 des3_set3key( ctx->sk, sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000609
610 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000611}
612
613/*
614 * Triple-DES key schedule (168-bit, decryption)
615 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
617 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000618{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000619 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
621 des3_set3key( sk, ctx->sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000623
624 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000625}
626
627/*
628 * DES-ECB block encryption/decryption
629 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200630#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000632 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 unsigned char output[8] )
634{
635 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000636 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
638 SK = ctx->sk;
639
Paul Bakker5c2364c2012-10-01 14:41:15 +0000640 GET_UINT32_BE( X, input, 0 );
641 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000642
643 DES_IP( X, Y );
644
645 for( i = 0; i < 8; i++ )
646 {
647 DES_ROUND( Y, X );
648 DES_ROUND( X, Y );
649 }
650
651 DES_FP( Y, X );
652
Paul Bakker5c2364c2012-10-01 14:41:15 +0000653 PUT_UINT32_BE( Y, output, 0 );
654 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000655
656 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000657}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200658#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000659
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000661/*
662 * DES-CBC buffer encryption/decryption
663 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200664int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000665 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000666 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000668 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000669 unsigned char *output )
670{
671 int i;
672 unsigned char temp[8];
673
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000674 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200675 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000676
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200677 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000678 {
679 while( length > 0 )
680 {
681 for( i = 0; i < 8; i++ )
682 output[i] = (unsigned char)( input[i] ^ iv[i] );
683
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684 mbedtls_des_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000685 memcpy( iv, output, 8 );
686
687 input += 8;
688 output += 8;
689 length -= 8;
690 }
691 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000693 {
694 while( length > 0 )
695 {
696 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200697 mbedtls_des_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
699 for( i = 0; i < 8; i++ )
700 output[i] = (unsigned char)( output[i] ^ iv[i] );
701
702 memcpy( iv, temp, 8 );
703
704 input += 8;
705 output += 8;
706 length -= 8;
707 }
708 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000709
710 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000711}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000713
714/*
715 * 3DES-ECB block encryption/decryption
716 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200717#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200718int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000719 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000720 unsigned char output[8] )
721{
722 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000723 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000724
725 SK = ctx->sk;
726
Paul Bakker5c2364c2012-10-01 14:41:15 +0000727 GET_UINT32_BE( X, input, 0 );
728 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000729
730 DES_IP( X, Y );
731
732 for( i = 0; i < 8; i++ )
733 {
734 DES_ROUND( Y, X );
735 DES_ROUND( X, Y );
736 }
737
738 for( i = 0; i < 8; i++ )
739 {
740 DES_ROUND( X, Y );
741 DES_ROUND( Y, X );
742 }
743
744 for( i = 0; i < 8; i++ )
745 {
746 DES_ROUND( Y, X );
747 DES_ROUND( X, Y );
748 }
749
750 DES_FP( Y, X );
751
Paul Bakker5c2364c2012-10-01 14:41:15 +0000752 PUT_UINT32_BE( Y, output, 0 );
753 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000754
755 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000756}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200757#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000758
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200759#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000760/*
761 * 3DES-CBC buffer encryption/decryption
762 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200763int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000764 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000765 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000766 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000767 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000768 unsigned char *output )
769{
770 int i;
771 unsigned char temp[8];
772
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000773 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000775
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200776 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000777 {
778 while( length > 0 )
779 {
780 for( i = 0; i < 8; i++ )
781 output[i] = (unsigned char)( input[i] ^ iv[i] );
782
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783 mbedtls_des3_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000784 memcpy( iv, output, 8 );
785
786 input += 8;
787 output += 8;
788 length -= 8;
789 }
790 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200791 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000792 {
793 while( length > 0 )
794 {
795 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796 mbedtls_des3_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000797
798 for( i = 0; i < 8; i++ )
799 output[i] = (unsigned char)( output[i] ^ iv[i] );
800
801 memcpy( iv, temp, 8 );
802
803 input += 8;
804 output += 8;
805 length -= 8;
806 }
807 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000808
809 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000810}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200811#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000812
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200814
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000816/*
817 * DES and 3DES test vectors from:
818 *
819 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
820 */
821static const unsigned char des3_test_keys[24] =
822{
823 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
824 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
825 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
826};
827
Paul Bakker5121ce52009-01-03 21:22:43 +0000828static const unsigned char des3_test_buf[8] =
829{
830 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
831};
832
833static const unsigned char des3_test_ecb_dec[3][8] =
834{
835 { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
836 { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
837 { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
838};
839
840static const unsigned char des3_test_ecb_enc[3][8] =
841{
842 { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
843 { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
844 { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
845};
846
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100848static const unsigned char des3_test_iv[8] =
849{
850 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
851};
852
Paul Bakker5121ce52009-01-03 21:22:43 +0000853static const unsigned char des3_test_cbc_dec[3][8] =
854{
855 { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
856 { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
857 { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
858};
859
860static const unsigned char des3_test_cbc_enc[3][8] =
861{
862 { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
863 { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
864 { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
865};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000867
868/*
869 * Checkup routine
870 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000872{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200873 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200874 mbedtls_des_context ctx;
875 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000876 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000878 unsigned char prv[8];
879 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200880#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000881
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200882 mbedtls_des_init( &ctx );
883 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000884 /*
885 * ECB mode
886 */
887 for( i = 0; i < 6; i++ )
888 {
889 u = i >> 1;
890 v = i & 1;
891
892 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100894 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000896
897 memcpy( buf, des3_test_buf, 8 );
898
899 switch( i )
900 {
901 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200902 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000903 break;
904
905 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000907 break;
908
909 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000911 break;
912
913 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000915 break;
916
917 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000919 break;
920
921 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000923 break;
924
925 default:
926 return( 1 );
927 }
928
929 for( j = 0; j < 10000; j++ )
930 {
931 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932 mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000933 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934 mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000935 }
936
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000938 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000940 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
941 {
942 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200943 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000944
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200945 ret = 1;
946 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000947 }
948
949 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000951 }
952
953 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000955
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000957 /*
958 * CBC mode
959 */
960 for( i = 0; i < 6; i++ )
961 {
962 u = i >> 1;
963 v = i & 1;
964
965 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100967 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200968 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000969
970 memcpy( iv, des3_test_iv, 8 );
971 memcpy( prv, des3_test_iv, 8 );
972 memcpy( buf, des3_test_buf, 8 );
973
974 switch( i )
975 {
976 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000978 break;
979
980 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000982 break;
983
984 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 break;
987
988 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000990 break;
991
992 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000994 break;
995
996 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200997 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000998 break;
999
1000 default:
1001 return( 1 );
1002 }
1003
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001004 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 {
1006 for( j = 0; j < 10000; j++ )
1007 {
1008 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001009 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001010 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001011 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001012 }
1013 }
1014 else
1015 {
1016 for( j = 0; j < 10000; j++ )
1017 {
1018 unsigned char tmp[8];
1019
1020 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001023 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001024
1025 memcpy( tmp, prv, 8 );
1026 memcpy( prv, buf, 8 );
1027 memcpy( buf, tmp, 8 );
1028 }
1029
1030 memcpy( buf, prv, 8 );
1031 }
1032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001034 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001036 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1037 {
1038 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001039 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001040
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001041 ret = 1;
1042 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001043 }
1044
1045 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001047 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001048#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001049
1050 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001051 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001052
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001053exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001054 mbedtls_des_free( &ctx );
1055 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001056
1057 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001058}
1059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001060#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062#endif /* MBEDTLS_DES_C */