blob: 0867064403462dfc0a390bd84ea52340eb59d0c3 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-46-3 compliant Triple-DES implementation
3 *
Bence Szépkútia2947ac2020-08-19 16:37:36 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Paul Bakker5121ce52009-01-03 21:22:43 +000045 */
46/*
47 * DES, on which TDES is based, was originally designed by Horst Feistel
48 * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
49 *
50 * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
51 */
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000054#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020055#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000060
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000061#include "mbedtls/des.h"
Gilles Peskine621333f2021-07-07 21:08:28 +020062#include "mbedtls/error.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050063#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000064
Rich Evans00ab4702015-02-06 13:43:58 +000065#include <string.h>
66
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067#if defined(MBEDTLS_SELF_TEST)
68#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000069#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010070#else
Rich Evans00ab4702015-02-06 13:43:58 +000071#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072#define mbedtls_printf printf
73#endif /* MBEDTLS_PLATFORM_C */
74#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010075
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020077
Paul Bakker5121ce52009-01-03 21:22:43 +000078/*
79 * 32-bit integer manipulation macros (big endian)
80 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000081#ifndef GET_UINT32_BE
82#define GET_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000083{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000084 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
85 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
86 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
87 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000088}
89#endif
90
Paul Bakker5c2364c2012-10-01 14:41:15 +000091#ifndef PUT_UINT32_BE
92#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000093{ \
94 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
95 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
96 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
97 (b)[(i) + 3] = (unsigned char) ( (n) ); \
98}
99#endif
100
101/*
102 * Expanded DES S-boxes
103 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000104static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000105{
106 0x01010400, 0x00000000, 0x00010000, 0x01010404,
107 0x01010004, 0x00010404, 0x00000004, 0x00010000,
108 0x00000400, 0x01010400, 0x01010404, 0x00000400,
109 0x01000404, 0x01010004, 0x01000000, 0x00000004,
110 0x00000404, 0x01000400, 0x01000400, 0x00010400,
111 0x00010400, 0x01010000, 0x01010000, 0x01000404,
112 0x00010004, 0x01000004, 0x01000004, 0x00010004,
113 0x00000000, 0x00000404, 0x00010404, 0x01000000,
114 0x00010000, 0x01010404, 0x00000004, 0x01010000,
115 0x01010400, 0x01000000, 0x01000000, 0x00000400,
116 0x01010004, 0x00010000, 0x00010400, 0x01000004,
117 0x00000400, 0x00000004, 0x01000404, 0x00010404,
118 0x01010404, 0x00010004, 0x01010000, 0x01000404,
119 0x01000004, 0x00000404, 0x00010404, 0x01010400,
120 0x00000404, 0x01000400, 0x01000400, 0x00000000,
121 0x00010004, 0x00010400, 0x00000000, 0x01010004
122};
123
Paul Bakker5c2364c2012-10-01 14:41:15 +0000124static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000125{
126 0x80108020, 0x80008000, 0x00008000, 0x00108020,
127 0x00100000, 0x00000020, 0x80100020, 0x80008020,
128 0x80000020, 0x80108020, 0x80108000, 0x80000000,
129 0x80008000, 0x00100000, 0x00000020, 0x80100020,
130 0x00108000, 0x00100020, 0x80008020, 0x00000000,
131 0x80000000, 0x00008000, 0x00108020, 0x80100000,
132 0x00100020, 0x80000020, 0x00000000, 0x00108000,
133 0x00008020, 0x80108000, 0x80100000, 0x00008020,
134 0x00000000, 0x00108020, 0x80100020, 0x00100000,
135 0x80008020, 0x80100000, 0x80108000, 0x00008000,
136 0x80100000, 0x80008000, 0x00000020, 0x80108020,
137 0x00108020, 0x00000020, 0x00008000, 0x80000000,
138 0x00008020, 0x80108000, 0x00100000, 0x80000020,
139 0x00100020, 0x80008020, 0x80000020, 0x00100020,
140 0x00108000, 0x00000000, 0x80008000, 0x00008020,
141 0x80000000, 0x80100020, 0x80108020, 0x00108000
142};
143
Paul Bakker5c2364c2012-10-01 14:41:15 +0000144static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000145{
146 0x00000208, 0x08020200, 0x00000000, 0x08020008,
147 0x08000200, 0x00000000, 0x00020208, 0x08000200,
148 0x00020008, 0x08000008, 0x08000008, 0x00020000,
149 0x08020208, 0x00020008, 0x08020000, 0x00000208,
150 0x08000000, 0x00000008, 0x08020200, 0x00000200,
151 0x00020200, 0x08020000, 0x08020008, 0x00020208,
152 0x08000208, 0x00020200, 0x00020000, 0x08000208,
153 0x00000008, 0x08020208, 0x00000200, 0x08000000,
154 0x08020200, 0x08000000, 0x00020008, 0x00000208,
155 0x00020000, 0x08020200, 0x08000200, 0x00000000,
156 0x00000200, 0x00020008, 0x08020208, 0x08000200,
157 0x08000008, 0x00000200, 0x00000000, 0x08020008,
158 0x08000208, 0x00020000, 0x08000000, 0x08020208,
159 0x00000008, 0x00020208, 0x00020200, 0x08000008,
160 0x08020000, 0x08000208, 0x00000208, 0x08020000,
161 0x00020208, 0x00000008, 0x08020008, 0x00020200
162};
163
Paul Bakker5c2364c2012-10-01 14:41:15 +0000164static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000165{
166 0x00802001, 0x00002081, 0x00002081, 0x00000080,
167 0x00802080, 0x00800081, 0x00800001, 0x00002001,
168 0x00000000, 0x00802000, 0x00802000, 0x00802081,
169 0x00000081, 0x00000000, 0x00800080, 0x00800001,
170 0x00000001, 0x00002000, 0x00800000, 0x00802001,
171 0x00000080, 0x00800000, 0x00002001, 0x00002080,
172 0x00800081, 0x00000001, 0x00002080, 0x00800080,
173 0x00002000, 0x00802080, 0x00802081, 0x00000081,
174 0x00800080, 0x00800001, 0x00802000, 0x00802081,
175 0x00000081, 0x00000000, 0x00000000, 0x00802000,
176 0x00002080, 0x00800080, 0x00800081, 0x00000001,
177 0x00802001, 0x00002081, 0x00002081, 0x00000080,
178 0x00802081, 0x00000081, 0x00000001, 0x00002000,
179 0x00800001, 0x00002001, 0x00802080, 0x00800081,
180 0x00002001, 0x00002080, 0x00800000, 0x00802001,
181 0x00000080, 0x00800000, 0x00002000, 0x00802080
182};
183
Paul Bakker5c2364c2012-10-01 14:41:15 +0000184static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000185{
186 0x00000100, 0x02080100, 0x02080000, 0x42000100,
187 0x00080000, 0x00000100, 0x40000000, 0x02080000,
188 0x40080100, 0x00080000, 0x02000100, 0x40080100,
189 0x42000100, 0x42080000, 0x00080100, 0x40000000,
190 0x02000000, 0x40080000, 0x40080000, 0x00000000,
191 0x40000100, 0x42080100, 0x42080100, 0x02000100,
192 0x42080000, 0x40000100, 0x00000000, 0x42000000,
193 0x02080100, 0x02000000, 0x42000000, 0x00080100,
194 0x00080000, 0x42000100, 0x00000100, 0x02000000,
195 0x40000000, 0x02080000, 0x42000100, 0x40080100,
196 0x02000100, 0x40000000, 0x42080000, 0x02080100,
197 0x40080100, 0x00000100, 0x02000000, 0x42080000,
198 0x42080100, 0x00080100, 0x42000000, 0x42080100,
199 0x02080000, 0x00000000, 0x40080000, 0x42000000,
200 0x00080100, 0x02000100, 0x40000100, 0x00080000,
201 0x00000000, 0x40080000, 0x02080100, 0x40000100
202};
203
Paul Bakker5c2364c2012-10-01 14:41:15 +0000204static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000205{
206 0x20000010, 0x20400000, 0x00004000, 0x20404010,
207 0x20400000, 0x00000010, 0x20404010, 0x00400000,
208 0x20004000, 0x00404010, 0x00400000, 0x20000010,
209 0x00400010, 0x20004000, 0x20000000, 0x00004010,
210 0x00000000, 0x00400010, 0x20004010, 0x00004000,
211 0x00404000, 0x20004010, 0x00000010, 0x20400010,
212 0x20400010, 0x00000000, 0x00404010, 0x20404000,
213 0x00004010, 0x00404000, 0x20404000, 0x20000000,
214 0x20004000, 0x00000010, 0x20400010, 0x00404000,
215 0x20404010, 0x00400000, 0x00004010, 0x20000010,
216 0x00400000, 0x20004000, 0x20000000, 0x00004010,
217 0x20000010, 0x20404010, 0x00404000, 0x20400000,
218 0x00404010, 0x20404000, 0x00000000, 0x20400010,
219 0x00000010, 0x00004000, 0x20400000, 0x00404010,
220 0x00004000, 0x00400010, 0x20004010, 0x00000000,
221 0x20404000, 0x20000000, 0x00400010, 0x20004010
222};
223
Paul Bakker5c2364c2012-10-01 14:41:15 +0000224static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000225{
226 0x00200000, 0x04200002, 0x04000802, 0x00000000,
227 0x00000800, 0x04000802, 0x00200802, 0x04200800,
228 0x04200802, 0x00200000, 0x00000000, 0x04000002,
229 0x00000002, 0x04000000, 0x04200002, 0x00000802,
230 0x04000800, 0x00200802, 0x00200002, 0x04000800,
231 0x04000002, 0x04200000, 0x04200800, 0x00200002,
232 0x04200000, 0x00000800, 0x00000802, 0x04200802,
233 0x00200800, 0x00000002, 0x04000000, 0x00200800,
234 0x04000000, 0x00200800, 0x00200000, 0x04000802,
235 0x04000802, 0x04200002, 0x04200002, 0x00000002,
236 0x00200002, 0x04000000, 0x04000800, 0x00200000,
237 0x04200800, 0x00000802, 0x00200802, 0x04200800,
238 0x00000802, 0x04000002, 0x04200802, 0x04200000,
239 0x00200800, 0x00000000, 0x00000002, 0x04200802,
240 0x00000000, 0x00200802, 0x04200000, 0x00000800,
241 0x04000002, 0x04000800, 0x00000800, 0x00200002
242};
243
Paul Bakker5c2364c2012-10-01 14:41:15 +0000244static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000245{
246 0x10001040, 0x00001000, 0x00040000, 0x10041040,
247 0x10000000, 0x10001040, 0x00000040, 0x10000000,
248 0x00040040, 0x10040000, 0x10041040, 0x00041000,
249 0x10041000, 0x00041040, 0x00001000, 0x00000040,
250 0x10040000, 0x10000040, 0x10001000, 0x00001040,
251 0x00041000, 0x00040040, 0x10040040, 0x10041000,
252 0x00001040, 0x00000000, 0x00000000, 0x10040040,
253 0x10000040, 0x10001000, 0x00041040, 0x00040000,
254 0x00041040, 0x00040000, 0x10041000, 0x00001000,
255 0x00000040, 0x10040040, 0x00001000, 0x00041040,
256 0x10001000, 0x00000040, 0x10000040, 0x10040000,
257 0x10040040, 0x10000000, 0x00040000, 0x10001040,
258 0x00000000, 0x10041040, 0x00040040, 0x10000040,
259 0x10040000, 0x10001000, 0x10001040, 0x00000000,
260 0x10041040, 0x00041000, 0x00041000, 0x00001040,
261 0x00001040, 0x00040040, 0x10000000, 0x10041000
262};
263
264/*
265 * PC1: left and right halves bit-swap
266 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000267static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000268{
269 0x00000000, 0x00000001, 0x00000100, 0x00000101,
270 0x00010000, 0x00010001, 0x00010100, 0x00010101,
271 0x01000000, 0x01000001, 0x01000100, 0x01000101,
272 0x01010000, 0x01010001, 0x01010100, 0x01010101
273};
274
Paul Bakker5c2364c2012-10-01 14:41:15 +0000275static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000276{
277 0x00000000, 0x01000000, 0x00010000, 0x01010000,
278 0x00000100, 0x01000100, 0x00010100, 0x01010100,
279 0x00000001, 0x01000001, 0x00010001, 0x01010001,
280 0x00000101, 0x01000101, 0x00010101, 0x01010101,
281};
282
283/*
284 * Initial Permutation macro
285 */
Hanno Beckerd6028a12018-10-15 12:01:35 +0100286#define DES_IP(X,Y) \
287 do \
288 { \
289 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
290 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
291 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
292 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
293 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
294 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
295 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
296 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000297
298/*
299 * Final Permutation macro
300 */
Hanno Beckerd6028a12018-10-15 12:01:35 +0100301#define DES_FP(X,Y) \
302 do \
303 { \
304 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
305 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
306 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
307 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
308 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
309 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
310 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
311 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000312
313/*
314 * DES round macro
315 */
Hanno Beckerd6028a12018-10-15 12:01:35 +0100316#define DES_ROUND(X,Y) \
317 do \
318 { \
319 T = *SK++ ^ (X); \
320 (Y) ^= SB8[ (T ) & 0x3F ] ^ \
321 SB6[ (T >> 8) & 0x3F ] ^ \
322 SB4[ (T >> 16) & 0x3F ] ^ \
323 SB2[ (T >> 24) & 0x3F ]; \
324 \
325 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
326 (Y) ^= SB7[ (T ) & 0x3F ] ^ \
327 SB5[ (T >> 8) & 0x3F ] ^ \
328 SB3[ (T >> 16) & 0x3F ] ^ \
329 SB1[ (T >> 24) & 0x3F ]; \
330 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000331
Hanno Beckerd6028a12018-10-15 12:01:35 +0100332#define SWAP(a,b) \
333 do \
334 { \
335 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
336 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000337
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200339{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200341}
342
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200344{
345 if( ctx == NULL )
346 return;
347
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500348 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200349}
350
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200352{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200354}
355
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200357{
358 if( ctx == NULL )
359 return;
360
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500361 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200362}
363
Paul Bakker1f87fb62011-01-15 17:32:24 +0000364static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
365 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
366 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
367 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
368 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
369 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
370 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
371 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
372 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
373 254 };
374
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000376{
377 int i;
378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000380 key[i] = odd_parity_table[key[i] / 2];
381}
382
383/*
384 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
385 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000387{
388 int i;
389
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200391 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000392 return( 1 );
393
394 return( 0 );
395}
396
397/*
398 * Table of weak and semi-weak keys
399 *
400 * Source: http://en.wikipedia.org/wiki/Weak_key
401 *
402 * Weak:
403 * Alternating ones + zeros (0x0101010101010101)
404 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
405 * '0xE0E0E0E0F1F1F1F1'
406 * '0x1F1F1F1F0E0E0E0E'
407 *
408 * Semi-weak:
409 * 0x011F011F010E010E and 0x1F011F010E010E01
410 * 0x01E001E001F101F1 and 0xE001E001F101F101
411 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
412 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
413 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
414 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
415 *
416 */
417
418#define WEAK_KEY_COUNT 16
419
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000421{
422 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
423 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
424 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
425 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
426
427 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
428 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
429 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
430 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
431 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
432 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
433 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
434 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
435 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
436 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
437 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
438 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
439};
440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000442{
443 int i;
444
445 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000447 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000448
Paul Bakker73206952011-07-06 14:37:33 +0000449 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000450}
451
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200452#if !defined(MBEDTLS_DES_SETKEY_ALT)
453void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000454{
455 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000456 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000457
Paul Bakker5c2364c2012-10-01 14:41:15 +0000458 GET_UINT32_BE( X, key, 0 );
459 GET_UINT32_BE( Y, key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
461 /*
462 * Permuted Choice 1
463 */
464 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
465 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
466
467 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
468 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
469 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
470 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
471
472 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
473 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
474 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
475 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
476
477 X &= 0x0FFFFFFF;
478 Y &= 0x0FFFFFFF;
479
480 /*
481 * calculate subkeys
482 */
483 for( i = 0; i < 16; i++ )
484 {
485 if( i < 2 || i == 8 || i == 15 )
486 {
487 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
488 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
489 }
490 else
491 {
492 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
493 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
494 }
495
496 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
497 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
498 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
499 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
500 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
501 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
502 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
503 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
504 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
505 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
506 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
507
508 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
509 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
510 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
511 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
512 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
513 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
514 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
515 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
516 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
517 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
518 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
519 }
520}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200521#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000522
523/*
524 * DES key schedule (56-bit, encryption)
525 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000527{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200528 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000529
530 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000531}
532
533/*
534 * DES key schedule (56-bit, decryption)
535 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000537{
538 int i;
539
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200540 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000541
542 for( i = 0; i < 16; i += 2 )
543 {
544 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
545 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
546 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000547
548 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000549}
550
Paul Bakker5c2364c2012-10-01 14:41:15 +0000551static void des3_set2key( uint32_t esk[96],
552 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000554{
555 int i;
556
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200557 mbedtls_des_setkey( esk, key );
558 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000559
560 for( i = 0; i < 32; i += 2 )
561 {
562 dsk[i ] = esk[30 - i];
563 dsk[i + 1] = esk[31 - i];
564
565 esk[i + 32] = dsk[62 - i];
566 esk[i + 33] = dsk[63 - i];
567
568 esk[i + 64] = esk[i ];
569 esk[i + 65] = esk[i + 1];
570
571 dsk[i + 64] = dsk[i ];
572 dsk[i + 65] = dsk[i + 1];
573 }
574}
575
576/*
577 * Triple-DES key schedule (112-bit, encryption)
578 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
580 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000581{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000582 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000583
584 des3_set2key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500585 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000586
587 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000588}
589
590/*
591 * Triple-DES key schedule (112-bit, decryption)
592 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
594 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000595{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000596 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
598 des3_set2key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500599 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000600
601 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000602}
603
Paul Bakker5c2364c2012-10-01 14:41:15 +0000604static void des3_set3key( uint32_t esk[96],
605 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000606 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000607{
608 int i;
609
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200610 mbedtls_des_setkey( esk, key );
611 mbedtls_des_setkey( dsk + 32, key + 8 );
612 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
614 for( i = 0; i < 32; i += 2 )
615 {
616 dsk[i ] = esk[94 - i];
617 dsk[i + 1] = esk[95 - i];
618
619 esk[i + 32] = dsk[62 - i];
620 esk[i + 33] = dsk[63 - i];
621
622 dsk[i + 64] = esk[30 - i];
623 dsk[i + 65] = esk[31 - i];
624 }
625}
626
627/*
628 * Triple-DES key schedule (168-bit, encryption)
629 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200630int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
631 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000632{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000633 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
635 des3_set3key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500636 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000637
638 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000639}
640
641/*
642 * Triple-DES key schedule (168-bit, decryption)
643 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
645 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000646{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000647 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
649 des3_set3key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500650 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000651
652 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000653}
654
655/*
656 * DES-ECB block encryption/decryption
657 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200658#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200659int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000660 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 unsigned char output[8] )
662{
663 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000664 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
666 SK = ctx->sk;
667
Paul Bakker5c2364c2012-10-01 14:41:15 +0000668 GET_UINT32_BE( X, input, 0 );
669 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000670
671 DES_IP( X, Y );
672
673 for( i = 0; i < 8; i++ )
674 {
675 DES_ROUND( Y, X );
676 DES_ROUND( X, Y );
677 }
678
679 DES_FP( Y, X );
680
Paul Bakker5c2364c2012-10-01 14:41:15 +0000681 PUT_UINT32_BE( Y, output, 0 );
682 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000683
684 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000685}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200686#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000687
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200688#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000689/*
690 * DES-CBC buffer encryption/decryption
691 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000693 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000694 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000695 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000696 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000697 unsigned char *output )
698{
699 int i;
Gilles Peskine621333f2021-07-07 21:08:28 +0200700 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000701 unsigned char temp[8];
702
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000703 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200704 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000705
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200706 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000707 {
708 while( length > 0 )
709 {
710 for( i = 0; i < 8; i++ )
711 output[i] = (unsigned char)( input[i] ^ iv[i] );
712
Gilles Peskine621333f2021-07-07 21:08:28 +0200713 ret = mbedtls_des_crypt_ecb( ctx, output, output );
714 if( ret != 0 )
715 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000716 memcpy( iv, output, 8 );
717
718 input += 8;
719 output += 8;
720 length -= 8;
721 }
722 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200723 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000724 {
725 while( length > 0 )
726 {
727 memcpy( temp, input, 8 );
Gilles Peskine621333f2021-07-07 21:08:28 +0200728 ret = mbedtls_des_crypt_ecb( ctx, input, output );
729 if( ret != 0 )
730 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000731
732 for( i = 0; i < 8; i++ )
733 output[i] = (unsigned char)( output[i] ^ iv[i] );
734
735 memcpy( iv, temp, 8 );
736
737 input += 8;
738 output += 8;
739 length -= 8;
740 }
741 }
Gilles Peskine621333f2021-07-07 21:08:28 +0200742 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000743
Gilles Peskine621333f2021-07-07 21:08:28 +0200744exit:
745 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000746}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200747#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
749/*
750 * 3DES-ECB block encryption/decryption
751 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200752#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200753int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000754 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000755 unsigned char output[8] )
756{
757 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000758 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000759
760 SK = ctx->sk;
761
Paul Bakker5c2364c2012-10-01 14:41:15 +0000762 GET_UINT32_BE( X, input, 0 );
763 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000764
765 DES_IP( X, Y );
766
767 for( i = 0; i < 8; i++ )
768 {
769 DES_ROUND( Y, X );
770 DES_ROUND( X, Y );
771 }
772
773 for( i = 0; i < 8; i++ )
774 {
775 DES_ROUND( X, Y );
776 DES_ROUND( Y, X );
777 }
778
779 for( i = 0; i < 8; i++ )
780 {
781 DES_ROUND( Y, X );
782 DES_ROUND( X, Y );
783 }
784
785 DES_FP( Y, X );
786
Paul Bakker5c2364c2012-10-01 14:41:15 +0000787 PUT_UINT32_BE( Y, output, 0 );
788 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000789
790 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000791}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200792#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000793
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000795/*
796 * 3DES-CBC buffer encryption/decryption
797 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000799 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000800 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000801 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000802 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000803 unsigned char *output )
804{
805 int i;
Gilles Peskine621333f2021-07-07 21:08:28 +0200806 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000807 unsigned char temp[8];
808
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000809 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200810 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000811
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000813 {
814 while( length > 0 )
815 {
816 for( i = 0; i < 8; i++ )
817 output[i] = (unsigned char)( input[i] ^ iv[i] );
818
Gilles Peskine621333f2021-07-07 21:08:28 +0200819 ret = mbedtls_des3_crypt_ecb( ctx, output, output );
820 if( ret != 0 )
821 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000822 memcpy( iv, output, 8 );
823
824 input += 8;
825 output += 8;
826 length -= 8;
827 }
828 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000830 {
831 while( length > 0 )
832 {
833 memcpy( temp, input, 8 );
Gilles Peskine621333f2021-07-07 21:08:28 +0200834 ret = mbedtls_des3_crypt_ecb( ctx, input, output );
835 if( ret != 0 )
836 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000837
838 for( i = 0; i < 8; i++ )
839 output[i] = (unsigned char)( output[i] ^ iv[i] );
840
841 memcpy( iv, temp, 8 );
842
843 input += 8;
844 output += 8;
845 length -= 8;
846 }
847 }
Gilles Peskine621333f2021-07-07 21:08:28 +0200848 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000849
Gilles Peskine621333f2021-07-07 21:08:28 +0200850exit:
851 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000852}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000854
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200856
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000858/*
859 * DES and 3DES test vectors from:
860 *
861 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
862 */
863static const unsigned char des3_test_keys[24] =
864{
865 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
866 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
867 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
868};
869
Paul Bakker5121ce52009-01-03 21:22:43 +0000870static const unsigned char des3_test_buf[8] =
871{
872 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
873};
874
875static const unsigned char des3_test_ecb_dec[3][8] =
876{
877 { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
878 { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
879 { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
880};
881
882static const unsigned char des3_test_ecb_enc[3][8] =
883{
884 { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
885 { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
886 { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
887};
888
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100890static const unsigned char des3_test_iv[8] =
891{
892 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
893};
894
Paul Bakker5121ce52009-01-03 21:22:43 +0000895static const unsigned char des3_test_cbc_dec[3][8] =
896{
897 { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
898 { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
899 { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
900};
901
902static const unsigned char des3_test_cbc_enc[3][8] =
903{
904 { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
905 { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
906 { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
907};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000909
910/*
911 * Checkup routine
912 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000914{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200915 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 mbedtls_des_context ctx;
917 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000918 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000920 unsigned char prv[8];
921 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200922#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000923
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 mbedtls_des_init( &ctx );
925 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000926 /*
927 * ECB mode
928 */
929 for( i = 0; i < 6; i++ )
930 {
931 u = i >> 1;
932 v = i & 1;
933
934 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100936 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000938
939 memcpy( buf, des3_test_buf, 8 );
940
941 switch( i )
942 {
943 case 0:
Gilles Peskine621333f2021-07-07 21:08:28 +0200944 ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000945 break;
946
947 case 1:
Gilles Peskine621333f2021-07-07 21:08:28 +0200948 ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 break;
950
951 case 2:
Gilles Peskine621333f2021-07-07 21:08:28 +0200952 ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 break;
954
955 case 3:
Gilles Peskine621333f2021-07-07 21:08:28 +0200956 ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000957 break;
958
959 case 4:
Gilles Peskine621333f2021-07-07 21:08:28 +0200960 ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000961 break;
962
963 case 5:
Gilles Peskine621333f2021-07-07 21:08:28 +0200964 ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000965 break;
966
967 default:
968 return( 1 );
969 }
Gilles Peskine621333f2021-07-07 21:08:28 +0200970 if( ret != 0 )
971 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000972
973 for( j = 0; j < 10000; j++ )
974 {
975 if( u == 0 )
Gilles Peskine621333f2021-07-07 21:08:28 +0200976 ret = mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000977 else
Gilles Peskine621333f2021-07-07 21:08:28 +0200978 ret = mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
979 if( ret != 0 )
980 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000981 }
982
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000984 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
987 {
988 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000990
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200991 ret = 1;
992 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000993 }
994
995 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200996 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000997 }
998
999 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001000 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001001
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001003 /*
1004 * CBC mode
1005 */
1006 for( i = 0; i < 6; i++ )
1007 {
1008 u = i >> 1;
1009 v = i & 1;
1010
1011 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001012 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +01001013 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001014 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001015
1016 memcpy( iv, des3_test_iv, 8 );
1017 memcpy( prv, des3_test_iv, 8 );
1018 memcpy( buf, des3_test_buf, 8 );
1019
1020 switch( i )
1021 {
1022 case 0:
Gilles Peskine621333f2021-07-07 21:08:28 +02001023 ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001024 break;
1025
1026 case 1:
Gilles Peskine621333f2021-07-07 21:08:28 +02001027 ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001028 break;
1029
1030 case 2:
Gilles Peskine621333f2021-07-07 21:08:28 +02001031 ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001032 break;
1033
1034 case 3:
Gilles Peskine621333f2021-07-07 21:08:28 +02001035 ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001036 break;
1037
1038 case 4:
Gilles Peskine621333f2021-07-07 21:08:28 +02001039 ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001040 break;
1041
1042 case 5:
Gilles Peskine621333f2021-07-07 21:08:28 +02001043 ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001044 break;
1045
1046 default:
1047 return( 1 );
1048 }
Gilles Peskine621333f2021-07-07 21:08:28 +02001049 if( ret != 0 )
1050 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001052 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001053 {
1054 for( j = 0; j < 10000; j++ )
1055 {
1056 if( u == 0 )
Gilles Peskine621333f2021-07-07 21:08:28 +02001057 ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001058 else
Gilles Peskine621333f2021-07-07 21:08:28 +02001059 ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
1060 if( ret != 0 )
1061 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001062 }
1063 }
1064 else
1065 {
1066 for( j = 0; j < 10000; j++ )
1067 {
1068 unsigned char tmp[8];
1069
1070 if( u == 0 )
Gilles Peskine621333f2021-07-07 21:08:28 +02001071 ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001072 else
Gilles Peskine621333f2021-07-07 21:08:28 +02001073 ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
1074 if( ret != 0 )
1075 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001076
1077 memcpy( tmp, prv, 8 );
1078 memcpy( prv, buf, 8 );
1079 memcpy( buf, tmp, 8 );
1080 }
1081
1082 memcpy( buf, prv, 8 );
1083 }
1084
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001086 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001087 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001088 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1089 {
1090 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001092
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001093 ret = 1;
1094 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001095 }
1096
1097 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001098 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001099 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001100#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001101
1102 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001103 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001104
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001105exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001106 mbedtls_des_free( &ctx );
1107 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001108
Gilles Peskine621333f2021-07-07 21:08:28 +02001109 if( ret != 0 )
1110 ret = 1;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001111 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001112}
1113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001114#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001116#endif /* MBEDTLS_DES_C */