blob: 91d22b5d906f5f38d48373df003a555dc9c6659e [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 Peskine7820a572021-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/*
Paul Bakker5121ce52009-01-03 21:22:43 +000048 * Expanded DES S-boxes
49 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000050static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000051{
52 0x01010400, 0x00000000, 0x00010000, 0x01010404,
53 0x01010004, 0x00010404, 0x00000004, 0x00010000,
54 0x00000400, 0x01010400, 0x01010404, 0x00000400,
55 0x01000404, 0x01010004, 0x01000000, 0x00000004,
56 0x00000404, 0x01000400, 0x01000400, 0x00010400,
57 0x00010400, 0x01010000, 0x01010000, 0x01000404,
58 0x00010004, 0x01000004, 0x01000004, 0x00010004,
59 0x00000000, 0x00000404, 0x00010404, 0x01000000,
60 0x00010000, 0x01010404, 0x00000004, 0x01010000,
61 0x01010400, 0x01000000, 0x01000000, 0x00000400,
62 0x01010004, 0x00010000, 0x00010400, 0x01000004,
63 0x00000400, 0x00000004, 0x01000404, 0x00010404,
64 0x01010404, 0x00010004, 0x01010000, 0x01000404,
65 0x01000004, 0x00000404, 0x00010404, 0x01010400,
66 0x00000404, 0x01000400, 0x01000400, 0x00000000,
67 0x00010004, 0x00010400, 0x00000000, 0x01010004
68};
69
Paul Bakker5c2364c2012-10-01 14:41:15 +000070static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000071{
72 0x80108020, 0x80008000, 0x00008000, 0x00108020,
73 0x00100000, 0x00000020, 0x80100020, 0x80008020,
74 0x80000020, 0x80108020, 0x80108000, 0x80000000,
75 0x80008000, 0x00100000, 0x00000020, 0x80100020,
76 0x00108000, 0x00100020, 0x80008020, 0x00000000,
77 0x80000000, 0x00008000, 0x00108020, 0x80100000,
78 0x00100020, 0x80000020, 0x00000000, 0x00108000,
79 0x00008020, 0x80108000, 0x80100000, 0x00008020,
80 0x00000000, 0x00108020, 0x80100020, 0x00100000,
81 0x80008020, 0x80100000, 0x80108000, 0x00008000,
82 0x80100000, 0x80008000, 0x00000020, 0x80108020,
83 0x00108020, 0x00000020, 0x00008000, 0x80000000,
84 0x00008020, 0x80108000, 0x00100000, 0x80000020,
85 0x00100020, 0x80008020, 0x80000020, 0x00100020,
86 0x00108000, 0x00000000, 0x80008000, 0x00008020,
87 0x80000000, 0x80100020, 0x80108020, 0x00108000
88};
89
Paul Bakker5c2364c2012-10-01 14:41:15 +000090static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000091{
92 0x00000208, 0x08020200, 0x00000000, 0x08020008,
93 0x08000200, 0x00000000, 0x00020208, 0x08000200,
94 0x00020008, 0x08000008, 0x08000008, 0x00020000,
95 0x08020208, 0x00020008, 0x08020000, 0x00000208,
96 0x08000000, 0x00000008, 0x08020200, 0x00000200,
97 0x00020200, 0x08020000, 0x08020008, 0x00020208,
98 0x08000208, 0x00020200, 0x00020000, 0x08000208,
99 0x00000008, 0x08020208, 0x00000200, 0x08000000,
100 0x08020200, 0x08000000, 0x00020008, 0x00000208,
101 0x00020000, 0x08020200, 0x08000200, 0x00000000,
102 0x00000200, 0x00020008, 0x08020208, 0x08000200,
103 0x08000008, 0x00000200, 0x00000000, 0x08020008,
104 0x08000208, 0x00020000, 0x08000000, 0x08020208,
105 0x00000008, 0x00020208, 0x00020200, 0x08000008,
106 0x08020000, 0x08000208, 0x00000208, 0x08020000,
107 0x00020208, 0x00000008, 0x08020008, 0x00020200
108};
109
Paul Bakker5c2364c2012-10-01 14:41:15 +0000110static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000111{
112 0x00802001, 0x00002081, 0x00002081, 0x00000080,
113 0x00802080, 0x00800081, 0x00800001, 0x00002001,
114 0x00000000, 0x00802000, 0x00802000, 0x00802081,
115 0x00000081, 0x00000000, 0x00800080, 0x00800001,
116 0x00000001, 0x00002000, 0x00800000, 0x00802001,
117 0x00000080, 0x00800000, 0x00002001, 0x00002080,
118 0x00800081, 0x00000001, 0x00002080, 0x00800080,
119 0x00002000, 0x00802080, 0x00802081, 0x00000081,
120 0x00800080, 0x00800001, 0x00802000, 0x00802081,
121 0x00000081, 0x00000000, 0x00000000, 0x00802000,
122 0x00002080, 0x00800080, 0x00800081, 0x00000001,
123 0x00802001, 0x00002081, 0x00002081, 0x00000080,
124 0x00802081, 0x00000081, 0x00000001, 0x00002000,
125 0x00800001, 0x00002001, 0x00802080, 0x00800081,
126 0x00002001, 0x00002080, 0x00800000, 0x00802001,
127 0x00000080, 0x00800000, 0x00002000, 0x00802080
128};
129
Paul Bakker5c2364c2012-10-01 14:41:15 +0000130static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000131{
132 0x00000100, 0x02080100, 0x02080000, 0x42000100,
133 0x00080000, 0x00000100, 0x40000000, 0x02080000,
134 0x40080100, 0x00080000, 0x02000100, 0x40080100,
135 0x42000100, 0x42080000, 0x00080100, 0x40000000,
136 0x02000000, 0x40080000, 0x40080000, 0x00000000,
137 0x40000100, 0x42080100, 0x42080100, 0x02000100,
138 0x42080000, 0x40000100, 0x00000000, 0x42000000,
139 0x02080100, 0x02000000, 0x42000000, 0x00080100,
140 0x00080000, 0x42000100, 0x00000100, 0x02000000,
141 0x40000000, 0x02080000, 0x42000100, 0x40080100,
142 0x02000100, 0x40000000, 0x42080000, 0x02080100,
143 0x40080100, 0x00000100, 0x02000000, 0x42080000,
144 0x42080100, 0x00080100, 0x42000000, 0x42080100,
145 0x02080000, 0x00000000, 0x40080000, 0x42000000,
146 0x00080100, 0x02000100, 0x40000100, 0x00080000,
147 0x00000000, 0x40080000, 0x02080100, 0x40000100
148};
149
Paul Bakker5c2364c2012-10-01 14:41:15 +0000150static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000151{
152 0x20000010, 0x20400000, 0x00004000, 0x20404010,
153 0x20400000, 0x00000010, 0x20404010, 0x00400000,
154 0x20004000, 0x00404010, 0x00400000, 0x20000010,
155 0x00400010, 0x20004000, 0x20000000, 0x00004010,
156 0x00000000, 0x00400010, 0x20004010, 0x00004000,
157 0x00404000, 0x20004010, 0x00000010, 0x20400010,
158 0x20400010, 0x00000000, 0x00404010, 0x20404000,
159 0x00004010, 0x00404000, 0x20404000, 0x20000000,
160 0x20004000, 0x00000010, 0x20400010, 0x00404000,
161 0x20404010, 0x00400000, 0x00004010, 0x20000010,
162 0x00400000, 0x20004000, 0x20000000, 0x00004010,
163 0x20000010, 0x20404010, 0x00404000, 0x20400000,
164 0x00404010, 0x20404000, 0x00000000, 0x20400010,
165 0x00000010, 0x00004000, 0x20400000, 0x00404010,
166 0x00004000, 0x00400010, 0x20004010, 0x00000000,
167 0x20404000, 0x20000000, 0x00400010, 0x20004010
168};
169
Paul Bakker5c2364c2012-10-01 14:41:15 +0000170static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000171{
172 0x00200000, 0x04200002, 0x04000802, 0x00000000,
173 0x00000800, 0x04000802, 0x00200802, 0x04200800,
174 0x04200802, 0x00200000, 0x00000000, 0x04000002,
175 0x00000002, 0x04000000, 0x04200002, 0x00000802,
176 0x04000800, 0x00200802, 0x00200002, 0x04000800,
177 0x04000002, 0x04200000, 0x04200800, 0x00200002,
178 0x04200000, 0x00000800, 0x00000802, 0x04200802,
179 0x00200800, 0x00000002, 0x04000000, 0x00200800,
180 0x04000000, 0x00200800, 0x00200000, 0x04000802,
181 0x04000802, 0x04200002, 0x04200002, 0x00000002,
182 0x00200002, 0x04000000, 0x04000800, 0x00200000,
183 0x04200800, 0x00000802, 0x00200802, 0x04200800,
184 0x00000802, 0x04000002, 0x04200802, 0x04200000,
185 0x00200800, 0x00000000, 0x00000002, 0x04200802,
186 0x00000000, 0x00200802, 0x04200000, 0x00000800,
187 0x04000002, 0x04000800, 0x00000800, 0x00200002
188};
189
Paul Bakker5c2364c2012-10-01 14:41:15 +0000190static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000191{
192 0x10001040, 0x00001000, 0x00040000, 0x10041040,
193 0x10000000, 0x10001040, 0x00000040, 0x10000000,
194 0x00040040, 0x10040000, 0x10041040, 0x00041000,
195 0x10041000, 0x00041040, 0x00001000, 0x00000040,
196 0x10040000, 0x10000040, 0x10001000, 0x00001040,
197 0x00041000, 0x00040040, 0x10040040, 0x10041000,
198 0x00001040, 0x00000000, 0x00000000, 0x10040040,
199 0x10000040, 0x10001000, 0x00041040, 0x00040000,
200 0x00041040, 0x00040000, 0x10041000, 0x00001000,
201 0x00000040, 0x10040040, 0x00001000, 0x00041040,
202 0x10001000, 0x00000040, 0x10000040, 0x10040000,
203 0x10040040, 0x10000000, 0x00040000, 0x10001040,
204 0x00000000, 0x10041040, 0x00040040, 0x10000040,
205 0x10040000, 0x10001000, 0x10001040, 0x00000000,
206 0x10041040, 0x00041000, 0x00041000, 0x00001040,
207 0x00001040, 0x00040040, 0x10000000, 0x10041000
208};
209
210/*
211 * PC1: left and right halves bit-swap
212 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000213static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000214{
215 0x00000000, 0x00000001, 0x00000100, 0x00000101,
216 0x00010000, 0x00010001, 0x00010100, 0x00010101,
217 0x01000000, 0x01000001, 0x01000100, 0x01000101,
218 0x01010000, 0x01010001, 0x01010100, 0x01010101
219};
220
Paul Bakker5c2364c2012-10-01 14:41:15 +0000221static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000222{
223 0x00000000, 0x01000000, 0x00010000, 0x01010000,
224 0x00000100, 0x01000100, 0x00010100, 0x01010100,
225 0x00000001, 0x01000001, 0x00010001, 0x01010001,
226 0x00000101, 0x01000101, 0x00010101, 0x01010101,
227};
228
229/*
230 * Initial Permutation macro
231 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100232#define DES_IP(X,Y) \
233 do \
234 { \
235 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
236 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
237 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
238 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
239 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
240 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
241 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
242 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000243
244/*
245 * Final Permutation macro
246 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100247#define DES_FP(X,Y) \
248 do \
249 { \
250 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
251 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
252 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
253 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
254 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
255 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
256 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
257 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000258
259/*
260 * DES round macro
261 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100262#define DES_ROUND(X,Y) \
263 do \
264 { \
265 T = *SK++ ^ (X); \
266 (Y) ^= SB8[ (T ) & 0x3F ] ^ \
267 SB6[ (T >> 8) & 0x3F ] ^ \
268 SB4[ (T >> 16) & 0x3F ] ^ \
269 SB2[ (T >> 24) & 0x3F ]; \
270 \
271 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
272 (Y) ^= SB7[ (T ) & 0x3F ] ^ \
273 SB5[ (T >> 8) & 0x3F ] ^ \
274 SB3[ (T >> 16) & 0x3F ] ^ \
275 SB1[ (T >> 24) & 0x3F ]; \
276 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000277
Hanno Becker1eeca412018-10-15 12:01:35 +0100278#define SWAP(a,b) \
279 do \
280 { \
281 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
282 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200284void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200285{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200287}
288
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200290{
291 if( ctx == NULL )
292 return;
293
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500294 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200295}
296
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200298{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200299 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200300}
301
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200303{
304 if( ctx == NULL )
305 return;
306
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500307 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200308}
309
Paul Bakker1f87fb62011-01-15 17:32:24 +0000310static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
311 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
312 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
313 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
314 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
315 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
316 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
317 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
318 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
319 254 };
320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000322{
323 int i;
324
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000326 key[i] = odd_parity_table[key[i] / 2];
327}
328
329/*
330 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
331 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000333{
334 int i;
335
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200337 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000338 return( 1 );
339
340 return( 0 );
341}
342
343/*
344 * Table of weak and semi-weak keys
345 *
346 * Source: http://en.wikipedia.org/wiki/Weak_key
347 *
348 * Weak:
349 * Alternating ones + zeros (0x0101010101010101)
350 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
351 * '0xE0E0E0E0F1F1F1F1'
352 * '0x1F1F1F1F0E0E0E0E'
353 *
354 * Semi-weak:
355 * 0x011F011F010E010E and 0x1F011F010E010E01
356 * 0x01E001E001F101F1 and 0xE001E001F101F101
357 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
358 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
359 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
360 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
361 *
362 */
363
364#define WEAK_KEY_COUNT 16
365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000367{
368 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
369 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
370 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
371 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
372
373 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
374 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
375 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
376 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
377 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
378 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
379 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
380 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
381 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
382 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
383 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
384 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
385};
386
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000388{
389 int i;
390
391 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000393 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000394
Paul Bakker73206952011-07-06 14:37:33 +0000395 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000396}
397
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200398#if !defined(MBEDTLS_DES_SETKEY_ALT)
399void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000400{
401 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000402 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
Joe Subbiani6a506312021-07-07 16:56:29 +0100404 X = MBEDTLS_GET_UINT32_BE( key, 0 );
405 Y = MBEDTLS_GET_UINT32_BE( key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
407 /*
408 * Permuted Choice 1
409 */
410 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
411 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
412
413 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
414 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
415 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
416 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
417
418 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
419 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
420 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
421 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
422
423 X &= 0x0FFFFFFF;
424 Y &= 0x0FFFFFFF;
425
426 /*
427 * calculate subkeys
428 */
429 for( i = 0; i < 16; i++ )
430 {
431 if( i < 2 || i == 8 || i == 15 )
432 {
433 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
434 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
435 }
436 else
437 {
438 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
439 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
440 }
441
442 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
443 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
444 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
445 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
446 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
447 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
448 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
449 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
450 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
451 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
452 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
453
454 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
455 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
456 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
457 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
458 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
459 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
460 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
461 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
462 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
463 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
464 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
465 }
466}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200467#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
469/*
470 * DES key schedule (56-bit, encryption)
471 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000473{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200474 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000475
476 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000477}
478
479/*
480 * DES key schedule (56-bit, decryption)
481 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000483{
484 int i;
485
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200486 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000487
488 for( i = 0; i < 16; i += 2 )
489 {
490 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
491 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
492 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000493
494 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000495}
496
Paul Bakker5c2364c2012-10-01 14:41:15 +0000497static void des3_set2key( uint32_t esk[96],
498 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000500{
501 int i;
502
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200503 mbedtls_des_setkey( esk, key );
504 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000505
506 for( i = 0; i < 32; i += 2 )
507 {
508 dsk[i ] = esk[30 - i];
509 dsk[i + 1] = esk[31 - i];
510
511 esk[i + 32] = dsk[62 - i];
512 esk[i + 33] = dsk[63 - i];
513
514 esk[i + 64] = esk[i ];
515 esk[i + 65] = esk[i + 1];
516
517 dsk[i + 64] = dsk[i ];
518 dsk[i + 65] = dsk[i + 1];
519 }
520}
521
522/*
523 * Triple-DES key schedule (112-bit, encryption)
524 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
526 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000527{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000528 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
530 des3_set2key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500531 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000532
533 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000534}
535
536/*
537 * Triple-DES key schedule (112-bit, decryption)
538 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
540 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000541{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000542 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
544 des3_set2key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500545 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000546
547 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000548}
549
Paul Bakker5c2364c2012-10-01 14:41:15 +0000550static void des3_set3key( uint32_t esk[96],
551 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000552 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000553{
554 int i;
555
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200556 mbedtls_des_setkey( esk, key );
557 mbedtls_des_setkey( dsk + 32, key + 8 );
558 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000559
560 for( i = 0; i < 32; i += 2 )
561 {
562 dsk[i ] = esk[94 - i];
563 dsk[i + 1] = esk[95 - i];
564
565 esk[i + 32] = dsk[62 - i];
566 esk[i + 33] = dsk[63 - i];
567
568 dsk[i + 64] = esk[30 - i];
569 dsk[i + 65] = esk[31 - i];
570 }
571}
572
573/*
574 * Triple-DES key schedule (168-bit, encryption)
575 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200576int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
577 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000578{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000579 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
581 des3_set3key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500582 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000583
584 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000585}
586
587/*
588 * Triple-DES key schedule (168-bit, decryption)
589 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200590int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
591 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000592{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000593 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000594
595 des3_set3key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500596 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000597
598 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000599}
600
601/*
602 * DES-ECB block encryption/decryption
603 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200604#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000606 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000607 unsigned char output[8] )
608{
609 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000610 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612 SK = ctx->sk;
613
Joe Subbiani6a506312021-07-07 16:56:29 +0100614 X = MBEDTLS_GET_UINT32_BE( input, 0 );
615 Y = MBEDTLS_GET_UINT32_BE( input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
617 DES_IP( X, Y );
618
619 for( i = 0; i < 8; i++ )
620 {
621 DES_ROUND( Y, X );
622 DES_ROUND( X, Y );
623 }
624
625 DES_FP( Y, X );
626
Joe Subbiani5ecac212021-06-24 13:00:03 +0100627 MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
628 MBEDTLS_PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000629
630 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000631}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200632#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000635/*
636 * DES-CBC buffer encryption/decryption
637 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000639 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000640 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000641 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000642 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000643 unsigned char *output )
644{
645 int i;
Gilles Peskine7820a572021-07-07 21:08:28 +0200646 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000647 unsigned char temp[8];
648
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000649 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000651
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000653 {
654 while( length > 0 )
655 {
656 for( i = 0; i < 8; i++ )
657 output[i] = (unsigned char)( input[i] ^ iv[i] );
658
Gilles Peskine7820a572021-07-07 21:08:28 +0200659 ret = mbedtls_des_crypt_ecb( ctx, output, output );
660 if( ret != 0 )
661 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000662 memcpy( iv, output, 8 );
663
664 input += 8;
665 output += 8;
666 length -= 8;
667 }
668 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000670 {
671 while( length > 0 )
672 {
673 memcpy( temp, input, 8 );
Gilles Peskine7820a572021-07-07 21:08:28 +0200674 ret = mbedtls_des_crypt_ecb( ctx, input, output );
675 if( ret != 0 )
676 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000677
678 for( i = 0; i < 8; i++ )
679 output[i] = (unsigned char)( output[i] ^ iv[i] );
680
681 memcpy( iv, temp, 8 );
682
683 input += 8;
684 output += 8;
685 length -= 8;
686 }
687 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200688 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000689
Gilles Peskine7820a572021-07-07 21:08:28 +0200690exit:
691 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000692}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
695/*
696 * 3DES-ECB block encryption/decryption
697 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200698#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200699int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000700 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000701 unsigned char output[8] )
702{
703 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000704 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000705
706 SK = ctx->sk;
707
Joe Subbiani6a506312021-07-07 16:56:29 +0100708 X = MBEDTLS_GET_UINT32_BE( input, 0 );
709 Y = MBEDTLS_GET_UINT32_BE( input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
711 DES_IP( X, Y );
712
713 for( i = 0; i < 8; i++ )
714 {
715 DES_ROUND( Y, X );
716 DES_ROUND( X, Y );
717 }
718
719 for( i = 0; i < 8; i++ )
720 {
721 DES_ROUND( X, Y );
722 DES_ROUND( Y, X );
723 }
724
725 for( i = 0; i < 8; i++ )
726 {
727 DES_ROUND( Y, X );
728 DES_ROUND( X, Y );
729 }
730
731 DES_FP( Y, X );
732
Joe Subbiani5ecac212021-06-24 13:00:03 +0100733 MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
734 MBEDTLS_PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000735
736 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000737}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200738#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000739
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200740#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000741/*
742 * 3DES-CBC buffer encryption/decryption
743 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200744int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000745 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000746 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000747 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000748 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000749 unsigned char *output )
750{
751 int i;
Gilles Peskine7820a572021-07-07 21:08:28 +0200752 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000753 unsigned char temp[8];
754
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000755 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200756 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000757
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200758 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000759 {
760 while( length > 0 )
761 {
762 for( i = 0; i < 8; i++ )
763 output[i] = (unsigned char)( input[i] ^ iv[i] );
764
Gilles Peskine7820a572021-07-07 21:08:28 +0200765 ret = mbedtls_des3_crypt_ecb( ctx, output, output );
766 if( ret != 0 )
767 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000768 memcpy( iv, output, 8 );
769
770 input += 8;
771 output += 8;
772 length -= 8;
773 }
774 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200775 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000776 {
777 while( length > 0 )
778 {
779 memcpy( temp, input, 8 );
Gilles Peskine7820a572021-07-07 21:08:28 +0200780 ret = mbedtls_des3_crypt_ecb( ctx, input, output );
781 if( ret != 0 )
782 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000783
784 for( i = 0; i < 8; i++ )
785 output[i] = (unsigned char)( output[i] ^ iv[i] );
786
787 memcpy( iv, temp, 8 );
788
789 input += 8;
790 output += 8;
791 length -= 8;
792 }
793 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200794 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000795
Gilles Peskine7820a572021-07-07 21:08:28 +0200796exit:
797 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000798}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000800
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200801#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200802
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200803#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000804/*
805 * DES and 3DES test vectors from:
806 *
807 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
808 */
809static const unsigned char des3_test_keys[24] =
810{
811 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
812 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
813 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
814};
815
Paul Bakker5121ce52009-01-03 21:22:43 +0000816static const unsigned char des3_test_buf[8] =
817{
818 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
819};
820
821static const unsigned char des3_test_ecb_dec[3][8] =
822{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100823 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
824 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
825 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000826};
827
828static const unsigned char des3_test_ecb_enc[3][8] =
829{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100830 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
831 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
832 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000833};
834
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200835#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100836static const unsigned char des3_test_iv[8] =
837{
838 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
839};
840
Paul Bakker5121ce52009-01-03 21:22:43 +0000841static const unsigned char des3_test_cbc_dec[3][8] =
842{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100843 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
844 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
845 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000846};
847
848static const unsigned char des3_test_cbc_enc[3][8] =
849{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100850 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
851 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
852 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000853};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200854#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000855
856/*
857 * Checkup routine
858 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000860{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200861 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862 mbedtls_des_context ctx;
863 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000864 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200865#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000866 unsigned char prv[8];
867 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200868#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000869
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 mbedtls_des_init( &ctx );
871 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000872 /*
873 * ECB mode
874 */
875 for( i = 0; i < 6; i++ )
876 {
877 u = i >> 1;
878 v = i & 1;
879
880 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200881 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100882 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000884
885 memcpy( buf, des3_test_buf, 8 );
886
887 switch( i )
888 {
889 case 0:
Gilles Peskine7820a572021-07-07 21:08:28 +0200890 ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000891 break;
892
893 case 1:
Gilles Peskine7820a572021-07-07 21:08:28 +0200894 ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000895 break;
896
897 case 2:
Gilles Peskine7820a572021-07-07 21:08:28 +0200898 ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000899 break;
900
901 case 3:
Gilles Peskine7820a572021-07-07 21:08:28 +0200902 ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000903 break;
904
905 case 4:
Gilles Peskine7820a572021-07-07 21:08:28 +0200906 ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000907 break;
908
909 case 5:
Gilles Peskine7820a572021-07-07 21:08:28 +0200910 ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000911 break;
912
913 default:
914 return( 1 );
915 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200916 if( ret != 0 )
917 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000918
Jaeden Amero355b4b02019-05-29 10:13:23 +0100919 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000920 {
921 if( u == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +0200922 ret = mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000923 else
Gilles Peskine7820a572021-07-07 21:08:28 +0200924 ret = mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
925 if( ret != 0 )
926 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000927 }
928
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000930 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000932 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
933 {
934 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000936
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200937 ret = 1;
938 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000939 }
940
941 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200942 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000943 }
944
945 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000947
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200948#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 /*
950 * CBC mode
951 */
952 for( i = 0; i < 6; i++ )
953 {
954 u = i >> 1;
955 v = i & 1;
956
957 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100959 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200960 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000961
962 memcpy( iv, des3_test_iv, 8 );
963 memcpy( prv, des3_test_iv, 8 );
964 memcpy( buf, des3_test_buf, 8 );
965
966 switch( i )
967 {
968 case 0:
Gilles Peskine7820a572021-07-07 21:08:28 +0200969 ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000970 break;
971
972 case 1:
Gilles Peskine7820a572021-07-07 21:08:28 +0200973 ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000974 break;
975
976 case 2:
Gilles Peskine7820a572021-07-07 21:08:28 +0200977 ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000978 break;
979
980 case 3:
Gilles Peskine7820a572021-07-07 21:08:28 +0200981 ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000982 break;
983
984 case 4:
Gilles Peskine7820a572021-07-07 21:08:28 +0200985 ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 break;
987
988 case 5:
Gilles Peskine7820a572021-07-07 21:08:28 +0200989 ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000990 break;
991
992 default:
993 return( 1 );
994 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200995 if( ret != 0 )
996 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000997
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200998 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000999 {
Jaeden Amero355b4b02019-05-29 10:13:23 +01001000 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001001 {
1002 if( u == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +02001003 ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001004 else
Gilles Peskine7820a572021-07-07 21:08:28 +02001005 ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
1006 if( ret != 0 )
1007 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001008 }
1009 }
1010 else
1011 {
Jaeden Amero355b4b02019-05-29 10:13:23 +01001012 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001013 {
1014 unsigned char tmp[8];
1015
1016 if( u == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +02001017 ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001018 else
Gilles Peskine7820a572021-07-07 21:08:28 +02001019 ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
1020 if( ret != 0 )
1021 goto exit;
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
Gilles Peskine7820a572021-07-07 21:08:28 +02001055 if( ret != 0 )
1056 ret = 1;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001057 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001058}
1059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001060#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062#endif /* MBEDTLS_DES_C */