blob: a5f73330b0e845d1c37b378dc6595665b6be0f17 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-46-3 compliant Triple-DES implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 * **********
45 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000046 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000047 */
48/*
49 * DES, on which TDES is based, was originally designed by Horst Feistel
50 * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
51 *
52 * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
53 */
54
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000056#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020059#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000060
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061#if defined(MBEDTLS_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000062
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000063#include "mbedtls/des.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050064#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000065
Rich Evans00ab4702015-02-06 13:43:58 +000066#include <string.h>
67
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068#if defined(MBEDTLS_SELF_TEST)
69#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000070#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010071#else
Rich Evans00ab4702015-02-06 13:43:58 +000072#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073#define mbedtls_printf printf
74#endif /* MBEDTLS_PLATFORM_C */
75#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010076
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020078
Paul Bakker5121ce52009-01-03 21:22:43 +000079/*
80 * 32-bit integer manipulation macros (big endian)
81 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000082#ifndef GET_UINT32_BE
83#define GET_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000084{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000085 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
86 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
87 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
88 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000089}
90#endif
91
Paul Bakker5c2364c2012-10-01 14:41:15 +000092#ifndef PUT_UINT32_BE
93#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000094{ \
95 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
96 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
97 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
98 (b)[(i) + 3] = (unsigned char) ( (n) ); \
99}
100#endif
101
102/*
103 * Expanded DES S-boxes
104 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000105static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000106{
107 0x01010400, 0x00000000, 0x00010000, 0x01010404,
108 0x01010004, 0x00010404, 0x00000004, 0x00010000,
109 0x00000400, 0x01010400, 0x01010404, 0x00000400,
110 0x01000404, 0x01010004, 0x01000000, 0x00000004,
111 0x00000404, 0x01000400, 0x01000400, 0x00010400,
112 0x00010400, 0x01010000, 0x01010000, 0x01000404,
113 0x00010004, 0x01000004, 0x01000004, 0x00010004,
114 0x00000000, 0x00000404, 0x00010404, 0x01000000,
115 0x00010000, 0x01010404, 0x00000004, 0x01010000,
116 0x01010400, 0x01000000, 0x01000000, 0x00000400,
117 0x01010004, 0x00010000, 0x00010400, 0x01000004,
118 0x00000400, 0x00000004, 0x01000404, 0x00010404,
119 0x01010404, 0x00010004, 0x01010000, 0x01000404,
120 0x01000004, 0x00000404, 0x00010404, 0x01010400,
121 0x00000404, 0x01000400, 0x01000400, 0x00000000,
122 0x00010004, 0x00010400, 0x00000000, 0x01010004
123};
124
Paul Bakker5c2364c2012-10-01 14:41:15 +0000125static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000126{
127 0x80108020, 0x80008000, 0x00008000, 0x00108020,
128 0x00100000, 0x00000020, 0x80100020, 0x80008020,
129 0x80000020, 0x80108020, 0x80108000, 0x80000000,
130 0x80008000, 0x00100000, 0x00000020, 0x80100020,
131 0x00108000, 0x00100020, 0x80008020, 0x00000000,
132 0x80000000, 0x00008000, 0x00108020, 0x80100000,
133 0x00100020, 0x80000020, 0x00000000, 0x00108000,
134 0x00008020, 0x80108000, 0x80100000, 0x00008020,
135 0x00000000, 0x00108020, 0x80100020, 0x00100000,
136 0x80008020, 0x80100000, 0x80108000, 0x00008000,
137 0x80100000, 0x80008000, 0x00000020, 0x80108020,
138 0x00108020, 0x00000020, 0x00008000, 0x80000000,
139 0x00008020, 0x80108000, 0x00100000, 0x80000020,
140 0x00100020, 0x80008020, 0x80000020, 0x00100020,
141 0x00108000, 0x00000000, 0x80008000, 0x00008020,
142 0x80000000, 0x80100020, 0x80108020, 0x00108000
143};
144
Paul Bakker5c2364c2012-10-01 14:41:15 +0000145static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000146{
147 0x00000208, 0x08020200, 0x00000000, 0x08020008,
148 0x08000200, 0x00000000, 0x00020208, 0x08000200,
149 0x00020008, 0x08000008, 0x08000008, 0x00020000,
150 0x08020208, 0x00020008, 0x08020000, 0x00000208,
151 0x08000000, 0x00000008, 0x08020200, 0x00000200,
152 0x00020200, 0x08020000, 0x08020008, 0x00020208,
153 0x08000208, 0x00020200, 0x00020000, 0x08000208,
154 0x00000008, 0x08020208, 0x00000200, 0x08000000,
155 0x08020200, 0x08000000, 0x00020008, 0x00000208,
156 0x00020000, 0x08020200, 0x08000200, 0x00000000,
157 0x00000200, 0x00020008, 0x08020208, 0x08000200,
158 0x08000008, 0x00000200, 0x00000000, 0x08020008,
159 0x08000208, 0x00020000, 0x08000000, 0x08020208,
160 0x00000008, 0x00020208, 0x00020200, 0x08000008,
161 0x08020000, 0x08000208, 0x00000208, 0x08020000,
162 0x00020208, 0x00000008, 0x08020008, 0x00020200
163};
164
Paul Bakker5c2364c2012-10-01 14:41:15 +0000165static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000166{
167 0x00802001, 0x00002081, 0x00002081, 0x00000080,
168 0x00802080, 0x00800081, 0x00800001, 0x00002001,
169 0x00000000, 0x00802000, 0x00802000, 0x00802081,
170 0x00000081, 0x00000000, 0x00800080, 0x00800001,
171 0x00000001, 0x00002000, 0x00800000, 0x00802001,
172 0x00000080, 0x00800000, 0x00002001, 0x00002080,
173 0x00800081, 0x00000001, 0x00002080, 0x00800080,
174 0x00002000, 0x00802080, 0x00802081, 0x00000081,
175 0x00800080, 0x00800001, 0x00802000, 0x00802081,
176 0x00000081, 0x00000000, 0x00000000, 0x00802000,
177 0x00002080, 0x00800080, 0x00800081, 0x00000001,
178 0x00802001, 0x00002081, 0x00002081, 0x00000080,
179 0x00802081, 0x00000081, 0x00000001, 0x00002000,
180 0x00800001, 0x00002001, 0x00802080, 0x00800081,
181 0x00002001, 0x00002080, 0x00800000, 0x00802001,
182 0x00000080, 0x00800000, 0x00002000, 0x00802080
183};
184
Paul Bakker5c2364c2012-10-01 14:41:15 +0000185static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000186{
187 0x00000100, 0x02080100, 0x02080000, 0x42000100,
188 0x00080000, 0x00000100, 0x40000000, 0x02080000,
189 0x40080100, 0x00080000, 0x02000100, 0x40080100,
190 0x42000100, 0x42080000, 0x00080100, 0x40000000,
191 0x02000000, 0x40080000, 0x40080000, 0x00000000,
192 0x40000100, 0x42080100, 0x42080100, 0x02000100,
193 0x42080000, 0x40000100, 0x00000000, 0x42000000,
194 0x02080100, 0x02000000, 0x42000000, 0x00080100,
195 0x00080000, 0x42000100, 0x00000100, 0x02000000,
196 0x40000000, 0x02080000, 0x42000100, 0x40080100,
197 0x02000100, 0x40000000, 0x42080000, 0x02080100,
198 0x40080100, 0x00000100, 0x02000000, 0x42080000,
199 0x42080100, 0x00080100, 0x42000000, 0x42080100,
200 0x02080000, 0x00000000, 0x40080000, 0x42000000,
201 0x00080100, 0x02000100, 0x40000100, 0x00080000,
202 0x00000000, 0x40080000, 0x02080100, 0x40000100
203};
204
Paul Bakker5c2364c2012-10-01 14:41:15 +0000205static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000206{
207 0x20000010, 0x20400000, 0x00004000, 0x20404010,
208 0x20400000, 0x00000010, 0x20404010, 0x00400000,
209 0x20004000, 0x00404010, 0x00400000, 0x20000010,
210 0x00400010, 0x20004000, 0x20000000, 0x00004010,
211 0x00000000, 0x00400010, 0x20004010, 0x00004000,
212 0x00404000, 0x20004010, 0x00000010, 0x20400010,
213 0x20400010, 0x00000000, 0x00404010, 0x20404000,
214 0x00004010, 0x00404000, 0x20404000, 0x20000000,
215 0x20004000, 0x00000010, 0x20400010, 0x00404000,
216 0x20404010, 0x00400000, 0x00004010, 0x20000010,
217 0x00400000, 0x20004000, 0x20000000, 0x00004010,
218 0x20000010, 0x20404010, 0x00404000, 0x20400000,
219 0x00404010, 0x20404000, 0x00000000, 0x20400010,
220 0x00000010, 0x00004000, 0x20400000, 0x00404010,
221 0x00004000, 0x00400010, 0x20004010, 0x00000000,
222 0x20404000, 0x20000000, 0x00400010, 0x20004010
223};
224
Paul Bakker5c2364c2012-10-01 14:41:15 +0000225static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000226{
227 0x00200000, 0x04200002, 0x04000802, 0x00000000,
228 0x00000800, 0x04000802, 0x00200802, 0x04200800,
229 0x04200802, 0x00200000, 0x00000000, 0x04000002,
230 0x00000002, 0x04000000, 0x04200002, 0x00000802,
231 0x04000800, 0x00200802, 0x00200002, 0x04000800,
232 0x04000002, 0x04200000, 0x04200800, 0x00200002,
233 0x04200000, 0x00000800, 0x00000802, 0x04200802,
234 0x00200800, 0x00000002, 0x04000000, 0x00200800,
235 0x04000000, 0x00200800, 0x00200000, 0x04000802,
236 0x04000802, 0x04200002, 0x04200002, 0x00000002,
237 0x00200002, 0x04000000, 0x04000800, 0x00200000,
238 0x04200800, 0x00000802, 0x00200802, 0x04200800,
239 0x00000802, 0x04000002, 0x04200802, 0x04200000,
240 0x00200800, 0x00000000, 0x00000002, 0x04200802,
241 0x00000000, 0x00200802, 0x04200000, 0x00000800,
242 0x04000002, 0x04000800, 0x00000800, 0x00200002
243};
244
Paul Bakker5c2364c2012-10-01 14:41:15 +0000245static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000246{
247 0x10001040, 0x00001000, 0x00040000, 0x10041040,
248 0x10000000, 0x10001040, 0x00000040, 0x10000000,
249 0x00040040, 0x10040000, 0x10041040, 0x00041000,
250 0x10041000, 0x00041040, 0x00001000, 0x00000040,
251 0x10040000, 0x10000040, 0x10001000, 0x00001040,
252 0x00041000, 0x00040040, 0x10040040, 0x10041000,
253 0x00001040, 0x00000000, 0x00000000, 0x10040040,
254 0x10000040, 0x10001000, 0x00041040, 0x00040000,
255 0x00041040, 0x00040000, 0x10041000, 0x00001000,
256 0x00000040, 0x10040040, 0x00001000, 0x00041040,
257 0x10001000, 0x00000040, 0x10000040, 0x10040000,
258 0x10040040, 0x10000000, 0x00040000, 0x10001040,
259 0x00000000, 0x10041040, 0x00040040, 0x10000040,
260 0x10040000, 0x10001000, 0x10001040, 0x00000000,
261 0x10041040, 0x00041000, 0x00041000, 0x00001040,
262 0x00001040, 0x00040040, 0x10000000, 0x10041000
263};
264
265/*
266 * PC1: left and right halves bit-swap
267 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000268static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000269{
270 0x00000000, 0x00000001, 0x00000100, 0x00000101,
271 0x00010000, 0x00010001, 0x00010100, 0x00010101,
272 0x01000000, 0x01000001, 0x01000100, 0x01000101,
273 0x01010000, 0x01010001, 0x01010100, 0x01010101
274};
275
Paul Bakker5c2364c2012-10-01 14:41:15 +0000276static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000277{
278 0x00000000, 0x01000000, 0x00010000, 0x01010000,
279 0x00000100, 0x01000100, 0x00010100, 0x01010100,
280 0x00000001, 0x01000001, 0x00010001, 0x01010001,
281 0x00000101, 0x01000101, 0x00010101, 0x01010101,
282};
283
284/*
285 * Initial Permutation macro
286 */
Hanno Beckerd6028a12018-10-15 12:01:35 +0100287#define DES_IP(X,Y) \
288 do \
289 { \
290 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
291 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
292 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
293 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
294 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
295 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
296 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
297 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
299/*
300 * Final Permutation macro
301 */
Hanno Beckerd6028a12018-10-15 12:01:35 +0100302#define DES_FP(X,Y) \
303 do \
304 { \
305 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
306 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
307 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
308 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
309 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
310 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
311 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
312 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
314/*
315 * DES round macro
316 */
Hanno Beckerd6028a12018-10-15 12:01:35 +0100317#define DES_ROUND(X,Y) \
318 do \
319 { \
320 T = *SK++ ^ (X); \
321 (Y) ^= SB8[ (T ) & 0x3F ] ^ \
322 SB6[ (T >> 8) & 0x3F ] ^ \
323 SB4[ (T >> 16) & 0x3F ] ^ \
324 SB2[ (T >> 24) & 0x3F ]; \
325 \
326 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
327 (Y) ^= SB7[ (T ) & 0x3F ] ^ \
328 SB5[ (T >> 8) & 0x3F ] ^ \
329 SB3[ (T >> 16) & 0x3F ] ^ \
330 SB1[ (T >> 24) & 0x3F ]; \
331 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
Hanno Beckerd6028a12018-10-15 12:01:35 +0100333#define SWAP(a,b) \
334 do \
335 { \
336 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
337 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000338
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200340{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200342}
343
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200345{
346 if( ctx == NULL )
347 return;
348
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500349 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200350}
351
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200353{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200355}
356
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200358{
359 if( ctx == NULL )
360 return;
361
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500362 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200363}
364
Paul Bakker1f87fb62011-01-15 17:32:24 +0000365static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
366 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
367 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
368 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
369 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
370 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
371 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
372 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
373 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
374 254 };
375
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000377{
378 int i;
379
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200380 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000381 key[i] = odd_parity_table[key[i] / 2];
382}
383
384/*
385 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
386 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000388{
389 int i;
390
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200392 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000393 return( 1 );
394
395 return( 0 );
396}
397
398/*
399 * Table of weak and semi-weak keys
400 *
401 * Source: http://en.wikipedia.org/wiki/Weak_key
402 *
403 * Weak:
404 * Alternating ones + zeros (0x0101010101010101)
405 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
406 * '0xE0E0E0E0F1F1F1F1'
407 * '0x1F1F1F1F0E0E0E0E'
408 *
409 * Semi-weak:
410 * 0x011F011F010E010E and 0x1F011F010E010E01
411 * 0x01E001E001F101F1 and 0xE001E001F101F101
412 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
413 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
414 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
415 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
416 *
417 */
418
419#define WEAK_KEY_COUNT 16
420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000422{
423 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
424 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
425 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
426 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
427
428 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
429 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
430 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
431 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
432 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
433 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
434 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
435 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
436 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
437 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
438 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
439 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
440};
441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000443{
444 int i;
445
446 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000448 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000449
Paul Bakker73206952011-07-06 14:37:33 +0000450 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000451}
452
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200453#if !defined(MBEDTLS_DES_SETKEY_ALT)
454void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000455{
456 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000457 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000458
Paul Bakker5c2364c2012-10-01 14:41:15 +0000459 GET_UINT32_BE( X, key, 0 );
460 GET_UINT32_BE( Y, key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
462 /*
463 * Permuted Choice 1
464 */
465 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
466 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
467
468 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
469 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
470 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
471 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
472
473 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
474 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
475 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
476 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
477
478 X &= 0x0FFFFFFF;
479 Y &= 0x0FFFFFFF;
480
481 /*
482 * calculate subkeys
483 */
484 for( i = 0; i < 16; i++ )
485 {
486 if( i < 2 || i == 8 || i == 15 )
487 {
488 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
489 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
490 }
491 else
492 {
493 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
494 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
495 }
496
497 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
498 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
499 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
500 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
501 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
502 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
503 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
504 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
505 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
506 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
507 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
508
509 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
510 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
511 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
512 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
513 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
514 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
515 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
516 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
517 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
518 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
519 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
520 }
521}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200522#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
524/*
525 * DES key schedule (56-bit, encryption)
526 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000528{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200529 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000530
531 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000532}
533
534/*
535 * DES key schedule (56-bit, decryption)
536 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200537int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000538{
539 int i;
540
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200541 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000542
543 for( i = 0; i < 16; i += 2 )
544 {
545 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
546 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
547 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000548
549 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000550}
551
Paul Bakker5c2364c2012-10-01 14:41:15 +0000552static void des3_set2key( uint32_t esk[96],
553 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000555{
556 int i;
557
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200558 mbedtls_des_setkey( esk, key );
559 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561 for( i = 0; i < 32; i += 2 )
562 {
563 dsk[i ] = esk[30 - i];
564 dsk[i + 1] = esk[31 - i];
565
566 esk[i + 32] = dsk[62 - i];
567 esk[i + 33] = dsk[63 - i];
568
569 esk[i + 64] = esk[i ];
570 esk[i + 65] = esk[i + 1];
571
572 dsk[i + 64] = dsk[i ];
573 dsk[i + 65] = dsk[i + 1];
574 }
575}
576
577/*
578 * Triple-DES key schedule (112-bit, encryption)
579 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
581 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000582{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000583 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
585 des3_set2key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500586 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000587
588 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000589}
590
591/*
592 * Triple-DES key schedule (112-bit, decryption)
593 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
595 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000596{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000597 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000598
599 des3_set2key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500600 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000601
602 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000603}
604
Paul Bakker5c2364c2012-10-01 14:41:15 +0000605static void des3_set3key( uint32_t esk[96],
606 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000607 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000608{
609 int i;
610
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200611 mbedtls_des_setkey( esk, key );
612 mbedtls_des_setkey( dsk + 32, key + 8 );
613 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000614
615 for( i = 0; i < 32; i += 2 )
616 {
617 dsk[i ] = esk[94 - i];
618 dsk[i + 1] = esk[95 - i];
619
620 esk[i + 32] = dsk[62 - i];
621 esk[i + 33] = dsk[63 - i];
622
623 dsk[i + 64] = esk[30 - i];
624 dsk[i + 65] = esk[31 - i];
625 }
626}
627
628/*
629 * Triple-DES key schedule (168-bit, encryption)
630 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
632 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000633{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000634 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000635
636 des3_set3key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500637 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000638
639 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000640}
641
642/*
643 * Triple-DES key schedule (168-bit, decryption)
644 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
646 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000647{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000648 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
650 des3_set3key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500651 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000652
653 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000654}
655
656/*
657 * DES-ECB block encryption/decryption
658 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200659#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000661 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000662 unsigned char output[8] )
663{
664 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000665 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
667 SK = ctx->sk;
668
Paul Bakker5c2364c2012-10-01 14:41:15 +0000669 GET_UINT32_BE( X, input, 0 );
670 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
672 DES_IP( X, Y );
673
674 for( i = 0; i < 8; i++ )
675 {
676 DES_ROUND( Y, X );
677 DES_ROUND( X, Y );
678 }
679
680 DES_FP( Y, X );
681
Paul Bakker5c2364c2012-10-01 14:41:15 +0000682 PUT_UINT32_BE( Y, output, 0 );
683 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000684
685 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000686}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200687#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000690/*
691 * DES-CBC buffer encryption/decryption
692 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000694 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000695 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000696 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000697 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000698 unsigned char *output )
699{
700 int i;
701 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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200713 mbedtls_des_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000714 memcpy( iv, output, 8 );
715
716 input += 8;
717 output += 8;
718 length -= 8;
719 }
720 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200721 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000722 {
723 while( length > 0 )
724 {
725 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200726 mbedtls_des_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000727
728 for( i = 0; i < 8; i++ )
729 output[i] = (unsigned char)( output[i] ^ iv[i] );
730
731 memcpy( iv, temp, 8 );
732
733 input += 8;
734 output += 8;
735 length -= 8;
736 }
737 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000738
739 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000740}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200741#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000742
743/*
744 * 3DES-ECB block encryption/decryption
745 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200746#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200747int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000748 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000749 unsigned char output[8] )
750{
751 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000752 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
754 SK = ctx->sk;
755
Paul Bakker5c2364c2012-10-01 14:41:15 +0000756 GET_UINT32_BE( X, input, 0 );
757 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000758
759 DES_IP( X, Y );
760
761 for( i = 0; i < 8; i++ )
762 {
763 DES_ROUND( Y, X );
764 DES_ROUND( X, Y );
765 }
766
767 for( i = 0; i < 8; i++ )
768 {
769 DES_ROUND( X, Y );
770 DES_ROUND( Y, X );
771 }
772
773 for( i = 0; i < 8; i++ )
774 {
775 DES_ROUND( Y, X );
776 DES_ROUND( X, Y );
777 }
778
779 DES_FP( Y, X );
780
Paul Bakker5c2364c2012-10-01 14:41:15 +0000781 PUT_UINT32_BE( Y, output, 0 );
782 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000783
784 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000785}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200786#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000787
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000789/*
790 * 3DES-CBC buffer encryption/decryption
791 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000793 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000794 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000795 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000796 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000797 unsigned char *output )
798{
799 int i;
800 unsigned char temp[8];
801
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000802 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200803 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000804
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000806 {
807 while( length > 0 )
808 {
809 for( i = 0; i < 8; i++ )
810 output[i] = (unsigned char)( input[i] ^ iv[i] );
811
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812 mbedtls_des3_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000813 memcpy( iv, output, 8 );
814
815 input += 8;
816 output += 8;
817 length -= 8;
818 }
819 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000821 {
822 while( length > 0 )
823 {
824 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200825 mbedtls_des3_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000826
827 for( i = 0; i < 8; i++ )
828 output[i] = (unsigned char)( output[i] ^ iv[i] );
829
830 memcpy( iv, temp, 8 );
831
832 input += 8;
833 output += 8;
834 length -= 8;
835 }
836 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000837
838 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000839}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200840#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200843
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200844#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000845/*
846 * DES and 3DES test vectors from:
847 *
848 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
849 */
850static const unsigned char des3_test_keys[24] =
851{
852 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
853 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
854 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
855};
856
Paul Bakker5121ce52009-01-03 21:22:43 +0000857static const unsigned char des3_test_buf[8] =
858{
859 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
860};
861
862static const unsigned char des3_test_ecb_dec[3][8] =
863{
864 { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
865 { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
866 { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
867};
868
869static const unsigned char des3_test_ecb_enc[3][8] =
870{
871 { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
872 { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
873 { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
874};
875
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200876#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100877static const unsigned char des3_test_iv[8] =
878{
879 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
880};
881
Paul Bakker5121ce52009-01-03 21:22:43 +0000882static const unsigned char des3_test_cbc_dec[3][8] =
883{
884 { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
885 { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
886 { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
887};
888
889static const unsigned char des3_test_cbc_enc[3][8] =
890{
891 { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
892 { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
893 { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
894};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000896
897/*
898 * Checkup routine
899 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000901{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200902 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 mbedtls_des_context ctx;
904 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000905 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000907 unsigned char prv[8];
908 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200909#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000910
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911 mbedtls_des_init( &ctx );
912 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000913 /*
914 * ECB mode
915 */
916 for( i = 0; i < 6; i++ )
917 {
918 u = i >> 1;
919 v = i & 1;
920
921 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100923 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000925
926 memcpy( buf, des3_test_buf, 8 );
927
928 switch( i )
929 {
930 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000932 break;
933
934 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000936 break;
937
938 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000940 break;
941
942 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200943 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000944 break;
945
946 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000948 break;
949
950 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200951 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000952 break;
953
954 default:
955 return( 1 );
956 }
957
958 for( j = 0; j < 10000; j++ )
959 {
960 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000962 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000964 }
965
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000967 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200968 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000969 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
970 {
971 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000973
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200974 ret = 1;
975 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000976 }
977
978 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000980 }
981
982 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000984
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 /*
987 * CBC mode
988 */
989 for( i = 0; i < 6; i++ )
990 {
991 u = i >> 1;
992 v = i & 1;
993
994 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100996 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200997 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000998
999 memcpy( iv, des3_test_iv, 8 );
1000 memcpy( prv, des3_test_iv, 8 );
1001 memcpy( buf, des3_test_buf, 8 );
1002
1003 switch( i )
1004 {
1005 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001007 break;
1008
1009 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001011 break;
1012
1013 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001014 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001015 break;
1016
1017 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001018 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001019 break;
1020
1021 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001022 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001023 break;
1024
1025 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001026 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001027 break;
1028
1029 default:
1030 return( 1 );
1031 }
1032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001034 {
1035 for( j = 0; j < 10000; j++ )
1036 {
1037 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001039 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001040 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001041 }
1042 }
1043 else
1044 {
1045 for( j = 0; j < 10000; j++ )
1046 {
1047 unsigned char tmp[8];
1048
1049 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001050 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001051 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001052 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001053
1054 memcpy( tmp, prv, 8 );
1055 memcpy( prv, buf, 8 );
1056 memcpy( buf, tmp, 8 );
1057 }
1058
1059 memcpy( buf, prv, 8 );
1060 }
1061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001063 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001065 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1066 {
1067 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001068 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001069
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001070 ret = 1;
1071 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001072 }
1073
1074 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001075 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001076 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001078
1079 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001081
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001082exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001083 mbedtls_des_free( &ctx );
1084 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001085
1086 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001087}
1088
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001089#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001090
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091#endif /* MBEDTLS_DES_C */