blob: e135219967e7aa09c1f480a9411e56560198a3be [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-46-3 compliant Triple-DES implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
22 * DES, on which TDES is based, was originally designed by Horst Feistel
23 * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
24 *
25 * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
26 */
27
Gilles Peskinedb09ef62020-06-03 01:43:33 +020028#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if defined(MBEDTLS_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/des.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050033#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Rich Evans00ab4702015-02-06 13:43:58 +000035#include <string.h>
36
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020037#if defined(MBEDTLS_SELF_TEST)
38#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000039#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010040#else
Rich Evans00ab4702015-02-06 13:43:58 +000041#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#define mbedtls_printf printf
43#endif /* MBEDTLS_PLATFORM_C */
44#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010045
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020047
Paul Bakker5121ce52009-01-03 21:22:43 +000048/*
49 * 32-bit integer manipulation macros (big endian)
50 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000051#ifndef GET_UINT32_BE
52#define GET_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000053{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000054 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
55 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
56 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
57 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000058}
59#endif
60
Paul Bakker5c2364c2012-10-01 14:41:15 +000061#ifndef PUT_UINT32_BE
62#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000063{ \
64 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
65 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
66 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
67 (b)[(i) + 3] = (unsigned char) ( (n) ); \
68}
69#endif
70
71/*
72 * Expanded DES S-boxes
73 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000074static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000075{
76 0x01010400, 0x00000000, 0x00010000, 0x01010404,
77 0x01010004, 0x00010404, 0x00000004, 0x00010000,
78 0x00000400, 0x01010400, 0x01010404, 0x00000400,
79 0x01000404, 0x01010004, 0x01000000, 0x00000004,
80 0x00000404, 0x01000400, 0x01000400, 0x00010400,
81 0x00010400, 0x01010000, 0x01010000, 0x01000404,
82 0x00010004, 0x01000004, 0x01000004, 0x00010004,
83 0x00000000, 0x00000404, 0x00010404, 0x01000000,
84 0x00010000, 0x01010404, 0x00000004, 0x01010000,
85 0x01010400, 0x01000000, 0x01000000, 0x00000400,
86 0x01010004, 0x00010000, 0x00010400, 0x01000004,
87 0x00000400, 0x00000004, 0x01000404, 0x00010404,
88 0x01010404, 0x00010004, 0x01010000, 0x01000404,
89 0x01000004, 0x00000404, 0x00010404, 0x01010400,
90 0x00000404, 0x01000400, 0x01000400, 0x00000000,
91 0x00010004, 0x00010400, 0x00000000, 0x01010004
92};
93
Paul Bakker5c2364c2012-10-01 14:41:15 +000094static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000095{
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
112};
113
Paul Bakker5c2364c2012-10-01 14:41:15 +0000114static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000115{
116 0x00000208, 0x08020200, 0x00000000, 0x08020008,
117 0x08000200, 0x00000000, 0x00020208, 0x08000200,
118 0x00020008, 0x08000008, 0x08000008, 0x00020000,
119 0x08020208, 0x00020008, 0x08020000, 0x00000208,
120 0x08000000, 0x00000008, 0x08020200, 0x00000200,
121 0x00020200, 0x08020000, 0x08020008, 0x00020208,
122 0x08000208, 0x00020200, 0x00020000, 0x08000208,
123 0x00000008, 0x08020208, 0x00000200, 0x08000000,
124 0x08020200, 0x08000000, 0x00020008, 0x00000208,
125 0x00020000, 0x08020200, 0x08000200, 0x00000000,
126 0x00000200, 0x00020008, 0x08020208, 0x08000200,
127 0x08000008, 0x00000200, 0x00000000, 0x08020008,
128 0x08000208, 0x00020000, 0x08000000, 0x08020208,
129 0x00000008, 0x00020208, 0x00020200, 0x08000008,
130 0x08020000, 0x08000208, 0x00000208, 0x08020000,
131 0x00020208, 0x00000008, 0x08020008, 0x00020200
132};
133
Paul Bakker5c2364c2012-10-01 14:41:15 +0000134static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000135{
136 0x00802001, 0x00002081, 0x00002081, 0x00000080,
137 0x00802080, 0x00800081, 0x00800001, 0x00002001,
138 0x00000000, 0x00802000, 0x00802000, 0x00802081,
139 0x00000081, 0x00000000, 0x00800080, 0x00800001,
140 0x00000001, 0x00002000, 0x00800000, 0x00802001,
141 0x00000080, 0x00800000, 0x00002001, 0x00002080,
142 0x00800081, 0x00000001, 0x00002080, 0x00800080,
143 0x00002000, 0x00802080, 0x00802081, 0x00000081,
144 0x00800080, 0x00800001, 0x00802000, 0x00802081,
145 0x00000081, 0x00000000, 0x00000000, 0x00802000,
146 0x00002080, 0x00800080, 0x00800081, 0x00000001,
147 0x00802001, 0x00002081, 0x00002081, 0x00000080,
148 0x00802081, 0x00000081, 0x00000001, 0x00002000,
149 0x00800001, 0x00002001, 0x00802080, 0x00800081,
150 0x00002001, 0x00002080, 0x00800000, 0x00802001,
151 0x00000080, 0x00800000, 0x00002000, 0x00802080
152};
153
Paul Bakker5c2364c2012-10-01 14:41:15 +0000154static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000155{
156 0x00000100, 0x02080100, 0x02080000, 0x42000100,
157 0x00080000, 0x00000100, 0x40000000, 0x02080000,
158 0x40080100, 0x00080000, 0x02000100, 0x40080100,
159 0x42000100, 0x42080000, 0x00080100, 0x40000000,
160 0x02000000, 0x40080000, 0x40080000, 0x00000000,
161 0x40000100, 0x42080100, 0x42080100, 0x02000100,
162 0x42080000, 0x40000100, 0x00000000, 0x42000000,
163 0x02080100, 0x02000000, 0x42000000, 0x00080100,
164 0x00080000, 0x42000100, 0x00000100, 0x02000000,
165 0x40000000, 0x02080000, 0x42000100, 0x40080100,
166 0x02000100, 0x40000000, 0x42080000, 0x02080100,
167 0x40080100, 0x00000100, 0x02000000, 0x42080000,
168 0x42080100, 0x00080100, 0x42000000, 0x42080100,
169 0x02080000, 0x00000000, 0x40080000, 0x42000000,
170 0x00080100, 0x02000100, 0x40000100, 0x00080000,
171 0x00000000, 0x40080000, 0x02080100, 0x40000100
172};
173
Paul Bakker5c2364c2012-10-01 14:41:15 +0000174static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000175{
176 0x20000010, 0x20400000, 0x00004000, 0x20404010,
177 0x20400000, 0x00000010, 0x20404010, 0x00400000,
178 0x20004000, 0x00404010, 0x00400000, 0x20000010,
179 0x00400010, 0x20004000, 0x20000000, 0x00004010,
180 0x00000000, 0x00400010, 0x20004010, 0x00004000,
181 0x00404000, 0x20004010, 0x00000010, 0x20400010,
182 0x20400010, 0x00000000, 0x00404010, 0x20404000,
183 0x00004010, 0x00404000, 0x20404000, 0x20000000,
184 0x20004000, 0x00000010, 0x20400010, 0x00404000,
185 0x20404010, 0x00400000, 0x00004010, 0x20000010,
186 0x00400000, 0x20004000, 0x20000000, 0x00004010,
187 0x20000010, 0x20404010, 0x00404000, 0x20400000,
188 0x00404010, 0x20404000, 0x00000000, 0x20400010,
189 0x00000010, 0x00004000, 0x20400000, 0x00404010,
190 0x00004000, 0x00400010, 0x20004010, 0x00000000,
191 0x20404000, 0x20000000, 0x00400010, 0x20004010
192};
193
Paul Bakker5c2364c2012-10-01 14:41:15 +0000194static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000195{
196 0x00200000, 0x04200002, 0x04000802, 0x00000000,
197 0x00000800, 0x04000802, 0x00200802, 0x04200800,
198 0x04200802, 0x00200000, 0x00000000, 0x04000002,
199 0x00000002, 0x04000000, 0x04200002, 0x00000802,
200 0x04000800, 0x00200802, 0x00200002, 0x04000800,
201 0x04000002, 0x04200000, 0x04200800, 0x00200002,
202 0x04200000, 0x00000800, 0x00000802, 0x04200802,
203 0x00200800, 0x00000002, 0x04000000, 0x00200800,
204 0x04000000, 0x00200800, 0x00200000, 0x04000802,
205 0x04000802, 0x04200002, 0x04200002, 0x00000002,
206 0x00200002, 0x04000000, 0x04000800, 0x00200000,
207 0x04200800, 0x00000802, 0x00200802, 0x04200800,
208 0x00000802, 0x04000002, 0x04200802, 0x04200000,
209 0x00200800, 0x00000000, 0x00000002, 0x04200802,
210 0x00000000, 0x00200802, 0x04200000, 0x00000800,
211 0x04000002, 0x04000800, 0x00000800, 0x00200002
212};
213
Paul Bakker5c2364c2012-10-01 14:41:15 +0000214static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000215{
216 0x10001040, 0x00001000, 0x00040000, 0x10041040,
217 0x10000000, 0x10001040, 0x00000040, 0x10000000,
218 0x00040040, 0x10040000, 0x10041040, 0x00041000,
219 0x10041000, 0x00041040, 0x00001000, 0x00000040,
220 0x10040000, 0x10000040, 0x10001000, 0x00001040,
221 0x00041000, 0x00040040, 0x10040040, 0x10041000,
222 0x00001040, 0x00000000, 0x00000000, 0x10040040,
223 0x10000040, 0x10001000, 0x00041040, 0x00040000,
224 0x00041040, 0x00040000, 0x10041000, 0x00001000,
225 0x00000040, 0x10040040, 0x00001000, 0x00041040,
226 0x10001000, 0x00000040, 0x10000040, 0x10040000,
227 0x10040040, 0x10000000, 0x00040000, 0x10001040,
228 0x00000000, 0x10041040, 0x00040040, 0x10000040,
229 0x10040000, 0x10001000, 0x10001040, 0x00000000,
230 0x10041040, 0x00041000, 0x00041000, 0x00001040,
231 0x00001040, 0x00040040, 0x10000000, 0x10041000
232};
233
234/*
235 * PC1: left and right halves bit-swap
236 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000237static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000238{
239 0x00000000, 0x00000001, 0x00000100, 0x00000101,
240 0x00010000, 0x00010001, 0x00010100, 0x00010101,
241 0x01000000, 0x01000001, 0x01000100, 0x01000101,
242 0x01010000, 0x01010001, 0x01010100, 0x01010101
243};
244
Paul Bakker5c2364c2012-10-01 14:41:15 +0000245static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000246{
247 0x00000000, 0x01000000, 0x00010000, 0x01010000,
248 0x00000100, 0x01000100, 0x00010100, 0x01010100,
249 0x00000001, 0x01000001, 0x00010001, 0x01010001,
250 0x00000101, 0x01000101, 0x00010101, 0x01010101,
251};
252
253/*
254 * Initial Permutation macro
255 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100256#define DES_IP(X,Y) \
257 do \
258 { \
259 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
260 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
261 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
262 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
263 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
264 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
265 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
266 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000267
268/*
269 * Final Permutation macro
270 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100271#define DES_FP(X,Y) \
272 do \
273 { \
274 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
275 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
276 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
277 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
278 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
279 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
280 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
281 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000282
283/*
284 * DES round macro
285 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100286#define DES_ROUND(X,Y) \
287 do \
288 { \
289 T = *SK++ ^ (X); \
290 (Y) ^= SB8[ (T ) & 0x3F ] ^ \
291 SB6[ (T >> 8) & 0x3F ] ^ \
292 SB4[ (T >> 16) & 0x3F ] ^ \
293 SB2[ (T >> 24) & 0x3F ]; \
294 \
295 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
296 (Y) ^= SB7[ (T ) & 0x3F ] ^ \
297 SB5[ (T >> 8) & 0x3F ] ^ \
298 SB3[ (T >> 16) & 0x3F ] ^ \
299 SB1[ (T >> 24) & 0x3F ]; \
300 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000301
Hanno Becker1eeca412018-10-15 12:01:35 +0100302#define SWAP(a,b) \
303 do \
304 { \
305 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
306 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000307
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200308void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200309{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200310 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200311}
312
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200314{
315 if( ctx == NULL )
316 return;
317
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500318 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200319}
320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200322{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200324}
325
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200327{
328 if( ctx == NULL )
329 return;
330
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500331 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200332}
333
Paul Bakker1f87fb62011-01-15 17:32:24 +0000334static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
335 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
336 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
337 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
338 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
339 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
340 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
341 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
342 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
343 254 };
344
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200345void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000346{
347 int i;
348
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000350 key[i] = odd_parity_table[key[i] / 2];
351}
352
353/*
354 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
355 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000357{
358 int i;
359
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200361 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000362 return( 1 );
363
364 return( 0 );
365}
366
367/*
368 * Table of weak and semi-weak keys
369 *
370 * Source: http://en.wikipedia.org/wiki/Weak_key
371 *
372 * Weak:
373 * Alternating ones + zeros (0x0101010101010101)
374 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
375 * '0xE0E0E0E0F1F1F1F1'
376 * '0x1F1F1F1F0E0E0E0E'
377 *
378 * Semi-weak:
379 * 0x011F011F010E010E and 0x1F011F010E010E01
380 * 0x01E001E001F101F1 and 0xE001E001F101F101
381 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
382 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
383 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
384 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
385 *
386 */
387
388#define WEAK_KEY_COUNT 16
389
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000391{
392 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
393 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
394 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
395 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
396
397 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
398 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
399 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
400 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
401 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
402 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
403 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
404 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
405 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
406 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
407 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
408 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
409};
410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000412{
413 int i;
414
415 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000417 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000418
Paul Bakker73206952011-07-06 14:37:33 +0000419 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000420}
421
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200422#if !defined(MBEDTLS_DES_SETKEY_ALT)
423void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000424{
425 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000426 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
Paul Bakker5c2364c2012-10-01 14:41:15 +0000428 GET_UINT32_BE( X, key, 0 );
429 GET_UINT32_BE( Y, key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
431 /*
432 * Permuted Choice 1
433 */
434 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
435 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
436
437 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
438 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
439 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
440 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
441
442 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
443 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
444 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
445 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
446
447 X &= 0x0FFFFFFF;
448 Y &= 0x0FFFFFFF;
449
450 /*
451 * calculate subkeys
452 */
453 for( i = 0; i < 16; i++ )
454 {
455 if( i < 2 || i == 8 || i == 15 )
456 {
457 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
458 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
459 }
460 else
461 {
462 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
463 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
464 }
465
466 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
467 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
468 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
469 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
470 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
471 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
472 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
473 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
474 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
475 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
476 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
477
478 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
479 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
480 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
481 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
482 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
483 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
484 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
485 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
486 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
487 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
488 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
489 }
490}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200491#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000492
493/*
494 * DES key schedule (56-bit, encryption)
495 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000497{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200498 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000499
500 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000501}
502
503/*
504 * DES key schedule (56-bit, decryption)
505 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000507{
508 int i;
509
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200510 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000511
512 for( i = 0; i < 16; i += 2 )
513 {
514 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
515 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
516 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000517
518 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000519}
520
Paul Bakker5c2364c2012-10-01 14:41:15 +0000521static void des3_set2key( uint32_t esk[96],
522 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000524{
525 int i;
526
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200527 mbedtls_des_setkey( esk, key );
528 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
530 for( i = 0; i < 32; i += 2 )
531 {
532 dsk[i ] = esk[30 - i];
533 dsk[i + 1] = esk[31 - i];
534
535 esk[i + 32] = dsk[62 - i];
536 esk[i + 33] = dsk[63 - i];
537
538 esk[i + 64] = esk[i ];
539 esk[i + 65] = esk[i + 1];
540
541 dsk[i + 64] = dsk[i ];
542 dsk[i + 65] = dsk[i + 1];
543 }
544}
545
546/*
547 * Triple-DES key schedule (112-bit, encryption)
548 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
550 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000551{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000552 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000553
554 des3_set2key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500555 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000556
557 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000558}
559
560/*
561 * Triple-DES key schedule (112-bit, decryption)
562 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
564 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000565{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000566 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000567
568 des3_set2key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500569 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000570
571 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000572}
573
Paul Bakker5c2364c2012-10-01 14:41:15 +0000574static void des3_set3key( uint32_t esk[96],
575 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000576 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000577{
578 int i;
579
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200580 mbedtls_des_setkey( esk, key );
581 mbedtls_des_setkey( dsk + 32, key + 8 );
582 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000583
584 for( i = 0; i < 32; i += 2 )
585 {
586 dsk[i ] = esk[94 - i];
587 dsk[i + 1] = esk[95 - i];
588
589 esk[i + 32] = dsk[62 - i];
590 esk[i + 33] = dsk[63 - i];
591
592 dsk[i + 64] = esk[30 - i];
593 dsk[i + 65] = esk[31 - i];
594 }
595}
596
597/*
598 * Triple-DES key schedule (168-bit, encryption)
599 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
601 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000602{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000603 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
605 des3_set3key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500606 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000607
608 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000609}
610
611/*
612 * Triple-DES key schedule (168-bit, decryption)
613 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
615 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000616{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000617 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
619 des3_set3key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500620 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000621
622 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000623}
624
625/*
626 * DES-ECB block encryption/decryption
627 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200628#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000630 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000631 unsigned char output[8] )
632{
633 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000634 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000635
636 SK = ctx->sk;
637
Paul Bakker5c2364c2012-10-01 14:41:15 +0000638 GET_UINT32_BE( X, input, 0 );
639 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000640
641 DES_IP( X, Y );
642
643 for( i = 0; i < 8; i++ )
644 {
645 DES_ROUND( Y, X );
646 DES_ROUND( X, Y );
647 }
648
649 DES_FP( Y, X );
650
Paul Bakker5c2364c2012-10-01 14:41:15 +0000651 PUT_UINT32_BE( Y, output, 0 );
652 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000653
654 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000655}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200656#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000657
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200658#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000659/*
660 * DES-CBC buffer encryption/decryption
661 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000663 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000664 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000665 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000666 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 unsigned char *output )
668{
669 int i;
670 unsigned char temp[8];
671
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000672 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000674
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200675 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000676 {
677 while( length > 0 )
678 {
679 for( i = 0; i < 8; i++ )
680 output[i] = (unsigned char)( input[i] ^ iv[i] );
681
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682 mbedtls_des_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000683 memcpy( iv, output, 8 );
684
685 input += 8;
686 output += 8;
687 length -= 8;
688 }
689 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200690 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000691 {
692 while( length > 0 )
693 {
694 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 mbedtls_des_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000696
697 for( i = 0; i < 8; i++ )
698 output[i] = (unsigned char)( output[i] ^ iv[i] );
699
700 memcpy( iv, temp, 8 );
701
702 input += 8;
703 output += 8;
704 length -= 8;
705 }
706 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000707
708 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000709}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
712/*
713 * 3DES-ECB block encryption/decryption
714 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200715#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000717 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000718 unsigned char output[8] )
719{
720 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000721 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000722
723 SK = ctx->sk;
724
Paul Bakker5c2364c2012-10-01 14:41:15 +0000725 GET_UINT32_BE( X, input, 0 );
726 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000727
728 DES_IP( X, Y );
729
730 for( i = 0; i < 8; i++ )
731 {
732 DES_ROUND( Y, X );
733 DES_ROUND( X, Y );
734 }
735
736 for( i = 0; i < 8; i++ )
737 {
738 DES_ROUND( X, Y );
739 DES_ROUND( Y, X );
740 }
741
742 for( i = 0; i < 8; i++ )
743 {
744 DES_ROUND( Y, X );
745 DES_ROUND( X, Y );
746 }
747
748 DES_FP( Y, X );
749
Paul Bakker5c2364c2012-10-01 14:41:15 +0000750 PUT_UINT32_BE( Y, output, 0 );
751 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000752
753 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000754}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200755#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000756
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200757#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000758/*
759 * 3DES-CBC buffer encryption/decryption
760 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000762 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000763 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000764 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000765 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000766 unsigned char *output )
767{
768 int i;
769 unsigned char temp[8];
770
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000771 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200772 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000773
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000775 {
776 while( length > 0 )
777 {
778 for( i = 0; i < 8; i++ )
779 output[i] = (unsigned char)( input[i] ^ iv[i] );
780
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200781 mbedtls_des3_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000782 memcpy( iv, output, 8 );
783
784 input += 8;
785 output += 8;
786 length -= 8;
787 }
788 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000790 {
791 while( length > 0 )
792 {
793 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794 mbedtls_des3_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000795
796 for( i = 0; i < 8; i++ )
797 output[i] = (unsigned char)( output[i] ^ iv[i] );
798
799 memcpy( iv, temp, 8 );
800
801 input += 8;
802 output += 8;
803 length -= 8;
804 }
805 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000806
807 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000808}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200809#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000810
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200811#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200812
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000814/*
815 * DES and 3DES test vectors from:
816 *
817 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
818 */
819static const unsigned char des3_test_keys[24] =
820{
821 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
822 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
823 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
824};
825
Paul Bakker5121ce52009-01-03 21:22:43 +0000826static const unsigned char des3_test_buf[8] =
827{
828 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
829};
830
831static const unsigned char des3_test_ecb_dec[3][8] =
832{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100833 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
834 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
835 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000836};
837
838static const unsigned char des3_test_ecb_enc[3][8] =
839{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100840 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
841 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
842 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000843};
844
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100846static const unsigned char des3_test_iv[8] =
847{
848 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
849};
850
Paul Bakker5121ce52009-01-03 21:22:43 +0000851static const unsigned char des3_test_cbc_dec[3][8] =
852{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100853 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
854 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
855 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000856};
857
858static const unsigned char des3_test_cbc_enc[3][8] =
859{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100860 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
861 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
862 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000863};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200864#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000865
866/*
867 * Checkup routine
868 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000870{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200871 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872 mbedtls_des_context ctx;
873 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000874 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000876 unsigned char prv[8];
877 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200878#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000879
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200880 mbedtls_des_init( &ctx );
881 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000882 /*
883 * ECB mode
884 */
885 for( i = 0; i < 6; i++ )
886 {
887 u = i >> 1;
888 v = i & 1;
889
890 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100892 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000894
895 memcpy( buf, des3_test_buf, 8 );
896
897 switch( i )
898 {
899 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000901 break;
902
903 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000905 break;
906
907 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000909 break;
910
911 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200912 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000913 break;
914
915 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000917 break;
918
919 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200920 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000921 break;
922
923 default:
924 return( 1 );
925 }
926
Jaeden Amero355b4b02019-05-29 10:13:23 +0100927 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000928 {
929 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930 mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000931 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932 mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000933 }
934
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000936 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000938 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
939 {
940 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000942
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200943 ret = 1;
944 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000945 }
946
947 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200948 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 }
950
951 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000953
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000955 /*
956 * CBC mode
957 */
958 for( i = 0; i < 6; i++ )
959 {
960 u = i >> 1;
961 v = i & 1;
962
963 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100965 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000967
968 memcpy( iv, des3_test_iv, 8 );
969 memcpy( prv, des3_test_iv, 8 );
970 memcpy( buf, des3_test_buf, 8 );
971
972 switch( i )
973 {
974 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200975 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000976 break;
977
978 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000980 break;
981
982 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000984 break;
985
986 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200987 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000988 break;
989
990 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200991 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000992 break;
993
994 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000996 break;
997
998 default:
999 return( 1 );
1000 }
1001
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001003 {
Jaeden Amero355b4b02019-05-29 10:13:23 +01001004 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 {
1006 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001008 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001009 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001010 }
1011 }
1012 else
1013 {
Jaeden Amero355b4b02019-05-29 10:13:23 +01001014 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001015 {
1016 unsigned char tmp[8];
1017
1018 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001020 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001022
1023 memcpy( tmp, prv, 8 );
1024 memcpy( prv, buf, 8 );
1025 memcpy( buf, tmp, 8 );
1026 }
1027
1028 memcpy( buf, prv, 8 );
1029 }
1030
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001031 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001032 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001034 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1035 {
1036 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001037 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001038
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001039 ret = 1;
1040 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001041 }
1042
1043 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001044 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001045 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001047
1048 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001050
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001051exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001052 mbedtls_des_free( &ctx );
1053 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001054
1055 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001056}
1057
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001058#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001060#endif /* MBEDTLS_DES_C */