blob: 9ff419046251619e5ddda49d6802bbc3cd188dd3 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-46-3 compliant Triple-DES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
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 Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * DES, on which TDES is based, was originally designed by Horst Feistel
21 * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
22 *
23 * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/des.h"
Gilles Peskine377a3102021-07-07 21:08:28 +020031#include "mbedtls/error.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050032#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_SELF_TEST)
37#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000038#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010039#else
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#define mbedtls_printf printf
42#endif /* MBEDTLS_PLATFORM_C */
43#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010044
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020046
Paul Bakker5121ce52009-01-03 21:22:43 +000047/*
48 * 32-bit integer manipulation macros (big endian)
49 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000050#ifndef GET_UINT32_BE
51#define GET_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000052{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000053 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
54 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
55 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
56 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000057}
58#endif
59
Paul Bakker5c2364c2012-10-01 14:41:15 +000060#ifndef PUT_UINT32_BE
61#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000062{ \
63 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
64 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
65 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
66 (b)[(i) + 3] = (unsigned char) ( (n) ); \
67}
68#endif
69
70/*
71 * Expanded DES S-boxes
72 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000073static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000074{
75 0x01010400, 0x00000000, 0x00010000, 0x01010404,
76 0x01010004, 0x00010404, 0x00000004, 0x00010000,
77 0x00000400, 0x01010400, 0x01010404, 0x00000400,
78 0x01000404, 0x01010004, 0x01000000, 0x00000004,
79 0x00000404, 0x01000400, 0x01000400, 0x00010400,
80 0x00010400, 0x01010000, 0x01010000, 0x01000404,
81 0x00010004, 0x01000004, 0x01000004, 0x00010004,
82 0x00000000, 0x00000404, 0x00010404, 0x01000000,
83 0x00010000, 0x01010404, 0x00000004, 0x01010000,
84 0x01010400, 0x01000000, 0x01000000, 0x00000400,
85 0x01010004, 0x00010000, 0x00010400, 0x01000004,
86 0x00000400, 0x00000004, 0x01000404, 0x00010404,
87 0x01010404, 0x00010004, 0x01010000, 0x01000404,
88 0x01000004, 0x00000404, 0x00010404, 0x01010400,
89 0x00000404, 0x01000400, 0x01000400, 0x00000000,
90 0x00010004, 0x00010400, 0x00000000, 0x01010004
91};
92
Paul Bakker5c2364c2012-10-01 14:41:15 +000093static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000094{
95 0x80108020, 0x80008000, 0x00008000, 0x00108020,
96 0x00100000, 0x00000020, 0x80100020, 0x80008020,
97 0x80000020, 0x80108020, 0x80108000, 0x80000000,
98 0x80008000, 0x00100000, 0x00000020, 0x80100020,
99 0x00108000, 0x00100020, 0x80008020, 0x00000000,
100 0x80000000, 0x00008000, 0x00108020, 0x80100000,
101 0x00100020, 0x80000020, 0x00000000, 0x00108000,
102 0x00008020, 0x80108000, 0x80100000, 0x00008020,
103 0x00000000, 0x00108020, 0x80100020, 0x00100000,
104 0x80008020, 0x80100000, 0x80108000, 0x00008000,
105 0x80100000, 0x80008000, 0x00000020, 0x80108020,
106 0x00108020, 0x00000020, 0x00008000, 0x80000000,
107 0x00008020, 0x80108000, 0x00100000, 0x80000020,
108 0x00100020, 0x80008020, 0x80000020, 0x00100020,
109 0x00108000, 0x00000000, 0x80008000, 0x00008020,
110 0x80000000, 0x80100020, 0x80108020, 0x00108000
111};
112
Paul Bakker5c2364c2012-10-01 14:41:15 +0000113static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000114{
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
131};
132
Paul Bakker5c2364c2012-10-01 14:41:15 +0000133static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000134{
135 0x00802001, 0x00002081, 0x00002081, 0x00000080,
136 0x00802080, 0x00800081, 0x00800001, 0x00002001,
137 0x00000000, 0x00802000, 0x00802000, 0x00802081,
138 0x00000081, 0x00000000, 0x00800080, 0x00800001,
139 0x00000001, 0x00002000, 0x00800000, 0x00802001,
140 0x00000080, 0x00800000, 0x00002001, 0x00002080,
141 0x00800081, 0x00000001, 0x00002080, 0x00800080,
142 0x00002000, 0x00802080, 0x00802081, 0x00000081,
143 0x00800080, 0x00800001, 0x00802000, 0x00802081,
144 0x00000081, 0x00000000, 0x00000000, 0x00802000,
145 0x00002080, 0x00800080, 0x00800081, 0x00000001,
146 0x00802001, 0x00002081, 0x00002081, 0x00000080,
147 0x00802081, 0x00000081, 0x00000001, 0x00002000,
148 0x00800001, 0x00002001, 0x00802080, 0x00800081,
149 0x00002001, 0x00002080, 0x00800000, 0x00802001,
150 0x00000080, 0x00800000, 0x00002000, 0x00802080
151};
152
Paul Bakker5c2364c2012-10-01 14:41:15 +0000153static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000154{
155 0x00000100, 0x02080100, 0x02080000, 0x42000100,
156 0x00080000, 0x00000100, 0x40000000, 0x02080000,
157 0x40080100, 0x00080000, 0x02000100, 0x40080100,
158 0x42000100, 0x42080000, 0x00080100, 0x40000000,
159 0x02000000, 0x40080000, 0x40080000, 0x00000000,
160 0x40000100, 0x42080100, 0x42080100, 0x02000100,
161 0x42080000, 0x40000100, 0x00000000, 0x42000000,
162 0x02080100, 0x02000000, 0x42000000, 0x00080100,
163 0x00080000, 0x42000100, 0x00000100, 0x02000000,
164 0x40000000, 0x02080000, 0x42000100, 0x40080100,
165 0x02000100, 0x40000000, 0x42080000, 0x02080100,
166 0x40080100, 0x00000100, 0x02000000, 0x42080000,
167 0x42080100, 0x00080100, 0x42000000, 0x42080100,
168 0x02080000, 0x00000000, 0x40080000, 0x42000000,
169 0x00080100, 0x02000100, 0x40000100, 0x00080000,
170 0x00000000, 0x40080000, 0x02080100, 0x40000100
171};
172
Paul Bakker5c2364c2012-10-01 14:41:15 +0000173static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000174{
175 0x20000010, 0x20400000, 0x00004000, 0x20404010,
176 0x20400000, 0x00000010, 0x20404010, 0x00400000,
177 0x20004000, 0x00404010, 0x00400000, 0x20000010,
178 0x00400010, 0x20004000, 0x20000000, 0x00004010,
179 0x00000000, 0x00400010, 0x20004010, 0x00004000,
180 0x00404000, 0x20004010, 0x00000010, 0x20400010,
181 0x20400010, 0x00000000, 0x00404010, 0x20404000,
182 0x00004010, 0x00404000, 0x20404000, 0x20000000,
183 0x20004000, 0x00000010, 0x20400010, 0x00404000,
184 0x20404010, 0x00400000, 0x00004010, 0x20000010,
185 0x00400000, 0x20004000, 0x20000000, 0x00004010,
186 0x20000010, 0x20404010, 0x00404000, 0x20400000,
187 0x00404010, 0x20404000, 0x00000000, 0x20400010,
188 0x00000010, 0x00004000, 0x20400000, 0x00404010,
189 0x00004000, 0x00400010, 0x20004010, 0x00000000,
190 0x20404000, 0x20000000, 0x00400010, 0x20004010
191};
192
Paul Bakker5c2364c2012-10-01 14:41:15 +0000193static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000194{
195 0x00200000, 0x04200002, 0x04000802, 0x00000000,
196 0x00000800, 0x04000802, 0x00200802, 0x04200800,
197 0x04200802, 0x00200000, 0x00000000, 0x04000002,
198 0x00000002, 0x04000000, 0x04200002, 0x00000802,
199 0x04000800, 0x00200802, 0x00200002, 0x04000800,
200 0x04000002, 0x04200000, 0x04200800, 0x00200002,
201 0x04200000, 0x00000800, 0x00000802, 0x04200802,
202 0x00200800, 0x00000002, 0x04000000, 0x00200800,
203 0x04000000, 0x00200800, 0x00200000, 0x04000802,
204 0x04000802, 0x04200002, 0x04200002, 0x00000002,
205 0x00200002, 0x04000000, 0x04000800, 0x00200000,
206 0x04200800, 0x00000802, 0x00200802, 0x04200800,
207 0x00000802, 0x04000002, 0x04200802, 0x04200000,
208 0x00200800, 0x00000000, 0x00000002, 0x04200802,
209 0x00000000, 0x00200802, 0x04200000, 0x00000800,
210 0x04000002, 0x04000800, 0x00000800, 0x00200002
211};
212
Paul Bakker5c2364c2012-10-01 14:41:15 +0000213static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000214{
215 0x10001040, 0x00001000, 0x00040000, 0x10041040,
216 0x10000000, 0x10001040, 0x00000040, 0x10000000,
217 0x00040040, 0x10040000, 0x10041040, 0x00041000,
218 0x10041000, 0x00041040, 0x00001000, 0x00000040,
219 0x10040000, 0x10000040, 0x10001000, 0x00001040,
220 0x00041000, 0x00040040, 0x10040040, 0x10041000,
221 0x00001040, 0x00000000, 0x00000000, 0x10040040,
222 0x10000040, 0x10001000, 0x00041040, 0x00040000,
223 0x00041040, 0x00040000, 0x10041000, 0x00001000,
224 0x00000040, 0x10040040, 0x00001000, 0x00041040,
225 0x10001000, 0x00000040, 0x10000040, 0x10040000,
226 0x10040040, 0x10000000, 0x00040000, 0x10001040,
227 0x00000000, 0x10041040, 0x00040040, 0x10000040,
228 0x10040000, 0x10001000, 0x10001040, 0x00000000,
229 0x10041040, 0x00041000, 0x00041000, 0x00001040,
230 0x00001040, 0x00040040, 0x10000000, 0x10041000
231};
232
233/*
234 * PC1: left and right halves bit-swap
235 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000236static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000237{
238 0x00000000, 0x00000001, 0x00000100, 0x00000101,
239 0x00010000, 0x00010001, 0x00010100, 0x00010101,
240 0x01000000, 0x01000001, 0x01000100, 0x01000101,
241 0x01010000, 0x01010001, 0x01010100, 0x01010101
242};
243
Paul Bakker5c2364c2012-10-01 14:41:15 +0000244static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000245{
246 0x00000000, 0x01000000, 0x00010000, 0x01010000,
247 0x00000100, 0x01000100, 0x00010100, 0x01010100,
248 0x00000001, 0x01000001, 0x00010001, 0x01010001,
249 0x00000101, 0x01000101, 0x00010101, 0x01010101,
250};
251
252/*
253 * Initial Permutation macro
254 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100255#define DES_IP(X,Y) \
256 do \
257 { \
258 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
259 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
260 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
261 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
262 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
263 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
264 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
265 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000266
267/*
268 * Final Permutation macro
269 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100270#define DES_FP(X,Y) \
271 do \
272 { \
273 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
274 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
275 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
276 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
277 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
278 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
279 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
280 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000281
282/*
283 * DES round macro
284 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100285#define DES_ROUND(X,Y) \
286 do \
287 { \
288 T = *SK++ ^ (X); \
289 (Y) ^= SB8[ (T ) & 0x3F ] ^ \
290 SB6[ (T >> 8) & 0x3F ] ^ \
291 SB4[ (T >> 16) & 0x3F ] ^ \
292 SB2[ (T >> 24) & 0x3F ]; \
293 \
294 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
295 (Y) ^= SB7[ (T ) & 0x3F ] ^ \
296 SB5[ (T >> 8) & 0x3F ] ^ \
297 SB3[ (T >> 16) & 0x3F ] ^ \
298 SB1[ (T >> 24) & 0x3F ]; \
299 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000300
Hanno Becker1eeca412018-10-15 12:01:35 +0100301#define SWAP(a,b) \
302 do \
303 { \
304 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
305 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000306
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200307void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200308{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200310}
311
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200313{
314 if( ctx == NULL )
315 return;
316
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500317 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200318}
319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200321{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200322 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200323}
324
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200326{
327 if( ctx == NULL )
328 return;
329
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500330 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200331}
332
Paul Bakker1f87fb62011-01-15 17:32:24 +0000333static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
334 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
335 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
336 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
337 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
338 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
339 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
340 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
341 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
342 254 };
343
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000345{
346 int i;
347
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000349 key[i] = odd_parity_table[key[i] / 2];
350}
351
352/*
353 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
354 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000356{
357 int i;
358
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200360 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000361 return( 1 );
362
363 return( 0 );
364}
365
366/*
367 * Table of weak and semi-weak keys
368 *
369 * Source: http://en.wikipedia.org/wiki/Weak_key
370 *
371 * Weak:
372 * Alternating ones + zeros (0x0101010101010101)
373 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
374 * '0xE0E0E0E0F1F1F1F1'
375 * '0x1F1F1F1F0E0E0E0E'
376 *
377 * Semi-weak:
378 * 0x011F011F010E010E and 0x1F011F010E010E01
379 * 0x01E001E001F101F1 and 0xE001E001F101F101
380 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
381 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
382 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
383 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
384 *
385 */
386
387#define WEAK_KEY_COUNT 16
388
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000390{
391 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
392 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
393 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
394 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
395
396 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
397 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
398 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
399 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
400 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
401 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
402 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
403 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
404 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
405 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
406 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
407 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
408};
409
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200410int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000411{
412 int i;
413
414 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000416 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000417
Paul Bakker73206952011-07-06 14:37:33 +0000418 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000419}
420
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200421#if !defined(MBEDTLS_DES_SETKEY_ALT)
422void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000423{
424 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000425 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
Paul Bakker5c2364c2012-10-01 14:41:15 +0000427 GET_UINT32_BE( X, key, 0 );
428 GET_UINT32_BE( Y, key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
430 /*
431 * Permuted Choice 1
432 */
433 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
434 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
435
436 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
437 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
438 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
439 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
440
441 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
442 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
443 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
444 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
445
446 X &= 0x0FFFFFFF;
447 Y &= 0x0FFFFFFF;
448
449 /*
450 * calculate subkeys
451 */
452 for( i = 0; i < 16; i++ )
453 {
454 if( i < 2 || i == 8 || i == 15 )
455 {
456 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
457 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
458 }
459 else
460 {
461 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
462 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
463 }
464
465 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
466 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
467 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
468 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
469 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
470 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
471 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
472 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
473 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
474 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
475 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
476
477 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
478 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
479 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
480 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
481 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
482 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
483 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
484 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
485 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
486 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
487 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
488 }
489}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200490#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
492/*
493 * DES key schedule (56-bit, encryption)
494 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000496{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200497 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000498
499 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000500}
501
502/*
503 * DES key schedule (56-bit, decryption)
504 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000506{
507 int i;
508
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200509 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
511 for( i = 0; i < 16; i += 2 )
512 {
513 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
514 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
515 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000516
517 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000518}
519
Paul Bakker5c2364c2012-10-01 14:41:15 +0000520static void des3_set2key( uint32_t esk[96],
521 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200522 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000523{
524 int i;
525
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200526 mbedtls_des_setkey( esk, key );
527 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000528
529 for( i = 0; i < 32; i += 2 )
530 {
531 dsk[i ] = esk[30 - i];
532 dsk[i + 1] = esk[31 - i];
533
534 esk[i + 32] = dsk[62 - i];
535 esk[i + 33] = dsk[63 - i];
536
537 esk[i + 64] = esk[i ];
538 esk[i + 65] = esk[i + 1];
539
540 dsk[i + 64] = dsk[i ];
541 dsk[i + 65] = dsk[i + 1];
542 }
543}
544
545/*
546 * Triple-DES key schedule (112-bit, encryption)
547 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200548int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
549 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000550{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000551 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
553 des3_set2key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500554 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000555
556 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000557}
558
559/*
560 * Triple-DES key schedule (112-bit, decryption)
561 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
563 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000564{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000565 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
567 des3_set2key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500568 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000569
570 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000571}
572
Paul Bakker5c2364c2012-10-01 14:41:15 +0000573static void des3_set3key( uint32_t esk[96],
574 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000575 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000576{
577 int i;
578
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200579 mbedtls_des_setkey( esk, key );
580 mbedtls_des_setkey( dsk + 32, key + 8 );
581 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
583 for( i = 0; i < 32; i += 2 )
584 {
585 dsk[i ] = esk[94 - i];
586 dsk[i + 1] = esk[95 - i];
587
588 esk[i + 32] = dsk[62 - i];
589 esk[i + 33] = dsk[63 - i];
590
591 dsk[i + 64] = esk[30 - i];
592 dsk[i + 65] = esk[31 - i];
593 }
594}
595
596/*
597 * Triple-DES key schedule (168-bit, encryption)
598 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
600 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000601{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000602 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000603
604 des3_set3key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500605 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000606
607 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000608}
609
610/*
611 * Triple-DES key schedule (168-bit, decryption)
612 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
614 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000615{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000616 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000617
618 des3_set3key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500619 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000620
621 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000622}
623
624/*
625 * DES-ECB block encryption/decryption
626 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200627#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000629 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 unsigned char output[8] )
631{
632 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000633 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
635 SK = ctx->sk;
636
Paul Bakker5c2364c2012-10-01 14:41:15 +0000637 GET_UINT32_BE( X, input, 0 );
638 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000639
640 DES_IP( X, Y );
641
642 for( i = 0; i < 8; i++ )
643 {
644 DES_ROUND( Y, X );
645 DES_ROUND( X, Y );
646 }
647
648 DES_FP( Y, X );
649
Paul Bakker5c2364c2012-10-01 14:41:15 +0000650 PUT_UINT32_BE( Y, output, 0 );
651 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000652
653 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000654}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200655#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000658/*
659 * DES-CBC buffer encryption/decryption
660 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200661int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000662 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000663 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000665 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 unsigned char *output )
667{
668 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +0200669 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000670 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
Gilles Peskine377a3102021-07-07 21:08:28 +0200682 ret = mbedtls_des_crypt_ecb( ctx, output, output );
683 if( ret != 0 )
684 goto exit;
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 );
Gilles Peskine377a3102021-07-07 21:08:28 +0200697 ret = mbedtls_des_crypt_ecb( ctx, input, output );
698 if( ret != 0 )
699 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
701 for( i = 0; i < 8; i++ )
702 output[i] = (unsigned char)( output[i] ^ iv[i] );
703
704 memcpy( iv, temp, 8 );
705
706 input += 8;
707 output += 8;
708 length -= 8;
709 }
710 }
Gilles Peskine377a3102021-07-07 21:08:28 +0200711 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000712
Gilles Peskine377a3102021-07-07 21:08:28 +0200713exit:
714 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000715}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
718/*
719 * 3DES-ECB block encryption/decryption
720 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200721#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200722int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000723 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000724 unsigned char output[8] )
725{
726 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000727 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000728
729 SK = ctx->sk;
730
Paul Bakker5c2364c2012-10-01 14:41:15 +0000731 GET_UINT32_BE( X, input, 0 );
732 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000733
734 DES_IP( X, Y );
735
736 for( i = 0; i < 8; i++ )
737 {
738 DES_ROUND( Y, X );
739 DES_ROUND( X, Y );
740 }
741
742 for( i = 0; i < 8; i++ )
743 {
744 DES_ROUND( X, Y );
745 DES_ROUND( Y, X );
746 }
747
748 for( i = 0; i < 8; i++ )
749 {
750 DES_ROUND( Y, X );
751 DES_ROUND( X, Y );
752 }
753
754 DES_FP( Y, X );
755
Paul Bakker5c2364c2012-10-01 14:41:15 +0000756 PUT_UINT32_BE( Y, output, 0 );
757 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000758
759 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000760}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200761#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000762
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200763#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000764/*
765 * 3DES-CBC buffer encryption/decryption
766 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000768 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000769 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000770 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000771 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000772 unsigned char *output )
773{
774 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +0200775 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000776 unsigned char temp[8];
777
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000778 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200779 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000780
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200781 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000782 {
783 while( length > 0 )
784 {
785 for( i = 0; i < 8; i++ )
786 output[i] = (unsigned char)( input[i] ^ iv[i] );
787
Gilles Peskine377a3102021-07-07 21:08:28 +0200788 ret = mbedtls_des3_crypt_ecb( ctx, output, output );
789 if( ret != 0 )
790 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000791 memcpy( iv, output, 8 );
792
793 input += 8;
794 output += 8;
795 length -= 8;
796 }
797 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000799 {
800 while( length > 0 )
801 {
802 memcpy( temp, input, 8 );
Gilles Peskine377a3102021-07-07 21:08:28 +0200803 ret = mbedtls_des3_crypt_ecb( ctx, input, output );
804 if( ret != 0 )
805 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000806
807 for( i = 0; i < 8; i++ )
808 output[i] = (unsigned char)( output[i] ^ iv[i] );
809
810 memcpy( iv, temp, 8 );
811
812 input += 8;
813 output += 8;
814 length -= 8;
815 }
816 }
Gilles Peskine377a3102021-07-07 21:08:28 +0200817 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000818
Gilles Peskine377a3102021-07-07 21:08:28 +0200819exit:
820 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000821}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200822#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000823
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200825
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000827/*
828 * DES and 3DES test vectors from:
829 *
830 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
831 */
832static const unsigned char des3_test_keys[24] =
833{
834 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
835 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
836 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
837};
838
Paul Bakker5121ce52009-01-03 21:22:43 +0000839static const unsigned char des3_test_buf[8] =
840{
841 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
842};
843
844static const unsigned char des3_test_ecb_dec[3][8] =
845{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100846 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
847 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
848 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000849};
850
851static const unsigned char des3_test_ecb_enc[3][8] =
852{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100853 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
854 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
855 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000856};
857
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100859static const unsigned char des3_test_iv[8] =
860{
861 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
862};
863
Paul Bakker5121ce52009-01-03 21:22:43 +0000864static const unsigned char des3_test_cbc_dec[3][8] =
865{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100866 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
867 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
868 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000869};
870
871static const unsigned char des3_test_cbc_enc[3][8] =
872{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100873 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
874 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
875 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000876};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000878
879/*
880 * Checkup routine
881 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200882int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000883{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200884 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885 mbedtls_des_context ctx;
886 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000887 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000889 unsigned char prv[8];
890 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200891#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000892
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893 mbedtls_des_init( &ctx );
894 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000895 /*
896 * ECB mode
897 */
898 for( i = 0; i < 6; i++ )
899 {
900 u = i >> 1;
901 v = i & 1;
902
903 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100905 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000907
908 memcpy( buf, des3_test_buf, 8 );
909
910 switch( i )
911 {
912 case 0:
Gilles Peskine377a3102021-07-07 21:08:28 +0200913 ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000914 break;
915
916 case 1:
Gilles Peskine377a3102021-07-07 21:08:28 +0200917 ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000918 break;
919
920 case 2:
Gilles Peskine377a3102021-07-07 21:08:28 +0200921 ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000922 break;
923
924 case 3:
Gilles Peskine377a3102021-07-07 21:08:28 +0200925 ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000926 break;
927
928 case 4:
Gilles Peskine377a3102021-07-07 21:08:28 +0200929 ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000930 break;
931
932 case 5:
Gilles Peskine377a3102021-07-07 21:08:28 +0200933 ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000934 break;
935
936 default:
937 return( 1 );
938 }
Gilles Peskine377a3102021-07-07 21:08:28 +0200939 if( ret != 0 )
940 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000941
Jaeden Amero355b4b02019-05-29 10:13:23 +0100942 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000943 {
944 if( u == 0 )
Gilles Peskine377a3102021-07-07 21:08:28 +0200945 ret = mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946 else
Gilles Peskine377a3102021-07-07 21:08:28 +0200947 ret = mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
948 if( ret != 0 )
949 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000950 }
951
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000955 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
956 {
957 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000959
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200960 ret = 1;
961 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000962 }
963
964 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000966 }
967
968 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000970
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200971#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000972 /*
973 * CBC mode
974 */
975 for( i = 0; i < 6; i++ )
976 {
977 u = i >> 1;
978 v = i & 1;
979
980 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100982 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000984
985 memcpy( iv, des3_test_iv, 8 );
986 memcpy( prv, des3_test_iv, 8 );
987 memcpy( buf, des3_test_buf, 8 );
988
989 switch( i )
990 {
991 case 0:
Gilles Peskine377a3102021-07-07 21:08:28 +0200992 ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000993 break;
994
995 case 1:
Gilles Peskine377a3102021-07-07 21:08:28 +0200996 ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000997 break;
998
999 case 2:
Gilles Peskine377a3102021-07-07 21:08:28 +02001000 ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001001 break;
1002
1003 case 3:
Gilles Peskine377a3102021-07-07 21:08:28 +02001004 ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 break;
1006
1007 case 4:
Gilles Peskine377a3102021-07-07 21:08:28 +02001008 ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001009 break;
1010
1011 case 5:
Gilles Peskine377a3102021-07-07 21:08:28 +02001012 ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001013 break;
1014
1015 default:
1016 return( 1 );
1017 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001018 if( ret != 0 )
1019 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001020
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 {
Jaeden Amero355b4b02019-05-29 10:13:23 +01001023 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001024 {
1025 if( u == 0 )
Gilles Peskine377a3102021-07-07 21:08:28 +02001026 ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001027 else
Gilles Peskine377a3102021-07-07 21:08:28 +02001028 ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
1029 if( ret != 0 )
1030 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001031 }
1032 }
1033 else
1034 {
Jaeden Amero355b4b02019-05-29 10:13:23 +01001035 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001036 {
1037 unsigned char tmp[8];
1038
1039 if( u == 0 )
Gilles Peskine377a3102021-07-07 21:08:28 +02001040 ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001041 else
Gilles Peskine377a3102021-07-07 21:08:28 +02001042 ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
1043 if( ret != 0 )
1044 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001045
1046 memcpy( tmp, prv, 8 );
1047 memcpy( prv, buf, 8 );
1048 memcpy( buf, tmp, 8 );
1049 }
1050
1051 memcpy( buf, prv, 8 );
1052 }
1053
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001054 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001055 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001057 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1058 {
1059 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001060 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001061
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001062 ret = 1;
1063 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001064 }
1065
1066 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001068 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001069#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001070
1071 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001072 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001073
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001074exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001075 mbedtls_des_free( &ctx );
1076 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001077
Gilles Peskine377a3102021-07-07 21:08:28 +02001078 if( ret != 0 )
1079 ret = 1;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001080 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001081}
1082
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001083#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001084
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085#endif /* MBEDTLS_DES_C */