blob: 623165d39180a102e2c1d2889093efbe3d78565e [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"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050062#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000063
Rich Evans00ab4702015-02-06 13:43:58 +000064#include <string.h>
65
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_SELF_TEST)
67#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000068#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010069#else
Rich Evans00ab4702015-02-06 13:43:58 +000070#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071#define mbedtls_printf printf
72#endif /* MBEDTLS_PLATFORM_C */
73#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010074
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020076
Paul Bakker5121ce52009-01-03 21:22:43 +000077/*
78 * 32-bit integer manipulation macros (big endian)
79 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000080#ifndef GET_UINT32_BE
81#define GET_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000082{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000083 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
84 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
85 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
86 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000087}
88#endif
89
Paul Bakker5c2364c2012-10-01 14:41:15 +000090#ifndef PUT_UINT32_BE
91#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000092{ \
93 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
94 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
95 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
96 (b)[(i) + 3] = (unsigned char) ( (n) ); \
97}
98#endif
99
100/*
101 * Expanded DES S-boxes
102 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000103static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000104{
105 0x01010400, 0x00000000, 0x00010000, 0x01010404,
106 0x01010004, 0x00010404, 0x00000004, 0x00010000,
107 0x00000400, 0x01010400, 0x01010404, 0x00000400,
108 0x01000404, 0x01010004, 0x01000000, 0x00000004,
109 0x00000404, 0x01000400, 0x01000400, 0x00010400,
110 0x00010400, 0x01010000, 0x01010000, 0x01000404,
111 0x00010004, 0x01000004, 0x01000004, 0x00010004,
112 0x00000000, 0x00000404, 0x00010404, 0x01000000,
113 0x00010000, 0x01010404, 0x00000004, 0x01010000,
114 0x01010400, 0x01000000, 0x01000000, 0x00000400,
115 0x01010004, 0x00010000, 0x00010400, 0x01000004,
116 0x00000400, 0x00000004, 0x01000404, 0x00010404,
117 0x01010404, 0x00010004, 0x01010000, 0x01000404,
118 0x01000004, 0x00000404, 0x00010404, 0x01010400,
119 0x00000404, 0x01000400, 0x01000400, 0x00000000,
120 0x00010004, 0x00010400, 0x00000000, 0x01010004
121};
122
Paul Bakker5c2364c2012-10-01 14:41:15 +0000123static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000124{
125 0x80108020, 0x80008000, 0x00008000, 0x00108020,
126 0x00100000, 0x00000020, 0x80100020, 0x80008020,
127 0x80000020, 0x80108020, 0x80108000, 0x80000000,
128 0x80008000, 0x00100000, 0x00000020, 0x80100020,
129 0x00108000, 0x00100020, 0x80008020, 0x00000000,
130 0x80000000, 0x00008000, 0x00108020, 0x80100000,
131 0x00100020, 0x80000020, 0x00000000, 0x00108000,
132 0x00008020, 0x80108000, 0x80100000, 0x00008020,
133 0x00000000, 0x00108020, 0x80100020, 0x00100000,
134 0x80008020, 0x80100000, 0x80108000, 0x00008000,
135 0x80100000, 0x80008000, 0x00000020, 0x80108020,
136 0x00108020, 0x00000020, 0x00008000, 0x80000000,
137 0x00008020, 0x80108000, 0x00100000, 0x80000020,
138 0x00100020, 0x80008020, 0x80000020, 0x00100020,
139 0x00108000, 0x00000000, 0x80008000, 0x00008020,
140 0x80000000, 0x80100020, 0x80108020, 0x00108000
141};
142
Paul Bakker5c2364c2012-10-01 14:41:15 +0000143static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000144{
145 0x00000208, 0x08020200, 0x00000000, 0x08020008,
146 0x08000200, 0x00000000, 0x00020208, 0x08000200,
147 0x00020008, 0x08000008, 0x08000008, 0x00020000,
148 0x08020208, 0x00020008, 0x08020000, 0x00000208,
149 0x08000000, 0x00000008, 0x08020200, 0x00000200,
150 0x00020200, 0x08020000, 0x08020008, 0x00020208,
151 0x08000208, 0x00020200, 0x00020000, 0x08000208,
152 0x00000008, 0x08020208, 0x00000200, 0x08000000,
153 0x08020200, 0x08000000, 0x00020008, 0x00000208,
154 0x00020000, 0x08020200, 0x08000200, 0x00000000,
155 0x00000200, 0x00020008, 0x08020208, 0x08000200,
156 0x08000008, 0x00000200, 0x00000000, 0x08020008,
157 0x08000208, 0x00020000, 0x08000000, 0x08020208,
158 0x00000008, 0x00020208, 0x00020200, 0x08000008,
159 0x08020000, 0x08000208, 0x00000208, 0x08020000,
160 0x00020208, 0x00000008, 0x08020008, 0x00020200
161};
162
Paul Bakker5c2364c2012-10-01 14:41:15 +0000163static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000164{
165 0x00802001, 0x00002081, 0x00002081, 0x00000080,
166 0x00802080, 0x00800081, 0x00800001, 0x00002001,
167 0x00000000, 0x00802000, 0x00802000, 0x00802081,
168 0x00000081, 0x00000000, 0x00800080, 0x00800001,
169 0x00000001, 0x00002000, 0x00800000, 0x00802001,
170 0x00000080, 0x00800000, 0x00002001, 0x00002080,
171 0x00800081, 0x00000001, 0x00002080, 0x00800080,
172 0x00002000, 0x00802080, 0x00802081, 0x00000081,
173 0x00800080, 0x00800001, 0x00802000, 0x00802081,
174 0x00000081, 0x00000000, 0x00000000, 0x00802000,
175 0x00002080, 0x00800080, 0x00800081, 0x00000001,
176 0x00802001, 0x00002081, 0x00002081, 0x00000080,
177 0x00802081, 0x00000081, 0x00000001, 0x00002000,
178 0x00800001, 0x00002001, 0x00802080, 0x00800081,
179 0x00002001, 0x00002080, 0x00800000, 0x00802001,
180 0x00000080, 0x00800000, 0x00002000, 0x00802080
181};
182
Paul Bakker5c2364c2012-10-01 14:41:15 +0000183static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000184{
185 0x00000100, 0x02080100, 0x02080000, 0x42000100,
186 0x00080000, 0x00000100, 0x40000000, 0x02080000,
187 0x40080100, 0x00080000, 0x02000100, 0x40080100,
188 0x42000100, 0x42080000, 0x00080100, 0x40000000,
189 0x02000000, 0x40080000, 0x40080000, 0x00000000,
190 0x40000100, 0x42080100, 0x42080100, 0x02000100,
191 0x42080000, 0x40000100, 0x00000000, 0x42000000,
192 0x02080100, 0x02000000, 0x42000000, 0x00080100,
193 0x00080000, 0x42000100, 0x00000100, 0x02000000,
194 0x40000000, 0x02080000, 0x42000100, 0x40080100,
195 0x02000100, 0x40000000, 0x42080000, 0x02080100,
196 0x40080100, 0x00000100, 0x02000000, 0x42080000,
197 0x42080100, 0x00080100, 0x42000000, 0x42080100,
198 0x02080000, 0x00000000, 0x40080000, 0x42000000,
199 0x00080100, 0x02000100, 0x40000100, 0x00080000,
200 0x00000000, 0x40080000, 0x02080100, 0x40000100
201};
202
Paul Bakker5c2364c2012-10-01 14:41:15 +0000203static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000204{
205 0x20000010, 0x20400000, 0x00004000, 0x20404010,
206 0x20400000, 0x00000010, 0x20404010, 0x00400000,
207 0x20004000, 0x00404010, 0x00400000, 0x20000010,
208 0x00400010, 0x20004000, 0x20000000, 0x00004010,
209 0x00000000, 0x00400010, 0x20004010, 0x00004000,
210 0x00404000, 0x20004010, 0x00000010, 0x20400010,
211 0x20400010, 0x00000000, 0x00404010, 0x20404000,
212 0x00004010, 0x00404000, 0x20404000, 0x20000000,
213 0x20004000, 0x00000010, 0x20400010, 0x00404000,
214 0x20404010, 0x00400000, 0x00004010, 0x20000010,
215 0x00400000, 0x20004000, 0x20000000, 0x00004010,
216 0x20000010, 0x20404010, 0x00404000, 0x20400000,
217 0x00404010, 0x20404000, 0x00000000, 0x20400010,
218 0x00000010, 0x00004000, 0x20400000, 0x00404010,
219 0x00004000, 0x00400010, 0x20004010, 0x00000000,
220 0x20404000, 0x20000000, 0x00400010, 0x20004010
221};
222
Paul Bakker5c2364c2012-10-01 14:41:15 +0000223static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000224{
225 0x00200000, 0x04200002, 0x04000802, 0x00000000,
226 0x00000800, 0x04000802, 0x00200802, 0x04200800,
227 0x04200802, 0x00200000, 0x00000000, 0x04000002,
228 0x00000002, 0x04000000, 0x04200002, 0x00000802,
229 0x04000800, 0x00200802, 0x00200002, 0x04000800,
230 0x04000002, 0x04200000, 0x04200800, 0x00200002,
231 0x04200000, 0x00000800, 0x00000802, 0x04200802,
232 0x00200800, 0x00000002, 0x04000000, 0x00200800,
233 0x04000000, 0x00200800, 0x00200000, 0x04000802,
234 0x04000802, 0x04200002, 0x04200002, 0x00000002,
235 0x00200002, 0x04000000, 0x04000800, 0x00200000,
236 0x04200800, 0x00000802, 0x00200802, 0x04200800,
237 0x00000802, 0x04000002, 0x04200802, 0x04200000,
238 0x00200800, 0x00000000, 0x00000002, 0x04200802,
239 0x00000000, 0x00200802, 0x04200000, 0x00000800,
240 0x04000002, 0x04000800, 0x00000800, 0x00200002
241};
242
Paul Bakker5c2364c2012-10-01 14:41:15 +0000243static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000244{
245 0x10001040, 0x00001000, 0x00040000, 0x10041040,
246 0x10000000, 0x10001040, 0x00000040, 0x10000000,
247 0x00040040, 0x10040000, 0x10041040, 0x00041000,
248 0x10041000, 0x00041040, 0x00001000, 0x00000040,
249 0x10040000, 0x10000040, 0x10001000, 0x00001040,
250 0x00041000, 0x00040040, 0x10040040, 0x10041000,
251 0x00001040, 0x00000000, 0x00000000, 0x10040040,
252 0x10000040, 0x10001000, 0x00041040, 0x00040000,
253 0x00041040, 0x00040000, 0x10041000, 0x00001000,
254 0x00000040, 0x10040040, 0x00001000, 0x00041040,
255 0x10001000, 0x00000040, 0x10000040, 0x10040000,
256 0x10040040, 0x10000000, 0x00040000, 0x10001040,
257 0x00000000, 0x10041040, 0x00040040, 0x10000040,
258 0x10040000, 0x10001000, 0x10001040, 0x00000000,
259 0x10041040, 0x00041000, 0x00041000, 0x00001040,
260 0x00001040, 0x00040040, 0x10000000, 0x10041000
261};
262
263/*
264 * PC1: left and right halves bit-swap
265 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000266static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000267{
268 0x00000000, 0x00000001, 0x00000100, 0x00000101,
269 0x00010000, 0x00010001, 0x00010100, 0x00010101,
270 0x01000000, 0x01000001, 0x01000100, 0x01000101,
271 0x01010000, 0x01010001, 0x01010100, 0x01010101
272};
273
Paul Bakker5c2364c2012-10-01 14:41:15 +0000274static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000275{
276 0x00000000, 0x01000000, 0x00010000, 0x01010000,
277 0x00000100, 0x01000100, 0x00010100, 0x01010100,
278 0x00000001, 0x01000001, 0x00010001, 0x01010001,
279 0x00000101, 0x01000101, 0x00010101, 0x01010101,
280};
281
282/*
283 * Initial Permutation macro
284 */
Hanno Beckerd6028a12018-10-15 12:01:35 +0100285#define DES_IP(X,Y) \
286 do \
287 { \
288 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
289 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
290 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
291 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
292 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
293 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
294 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
295 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000296
297/*
298 * Final Permutation macro
299 */
Hanno Beckerd6028a12018-10-15 12:01:35 +0100300#define DES_FP(X,Y) \
301 do \
302 { \
303 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
304 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
305 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
306 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
307 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
308 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
309 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
310 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000311
312/*
313 * DES round macro
314 */
Hanno Beckerd6028a12018-10-15 12:01:35 +0100315#define DES_ROUND(X,Y) \
316 do \
317 { \
318 T = *SK++ ^ (X); \
319 (Y) ^= SB8[ (T ) & 0x3F ] ^ \
320 SB6[ (T >> 8) & 0x3F ] ^ \
321 SB4[ (T >> 16) & 0x3F ] ^ \
322 SB2[ (T >> 24) & 0x3F ]; \
323 \
324 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
325 (Y) ^= SB7[ (T ) & 0x3F ] ^ \
326 SB5[ (T >> 8) & 0x3F ] ^ \
327 SB3[ (T >> 16) & 0x3F ] ^ \
328 SB1[ (T >> 24) & 0x3F ]; \
329 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000330
Hanno Beckerd6028a12018-10-15 12:01:35 +0100331#define SWAP(a,b) \
332 do \
333 { \
334 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
335 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000336
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200338{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200340}
341
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200343{
344 if( ctx == NULL )
345 return;
346
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500347 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200348}
349
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200351{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200353}
354
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200356{
357 if( ctx == NULL )
358 return;
359
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500360 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200361}
362
Paul Bakker1f87fb62011-01-15 17:32:24 +0000363static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
364 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
365 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
366 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
367 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
368 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
369 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
370 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
371 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
372 254 };
373
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200374void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000375{
376 int i;
377
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000379 key[i] = odd_parity_table[key[i] / 2];
380}
381
382/*
383 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
384 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000386{
387 int i;
388
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200390 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000391 return( 1 );
392
393 return( 0 );
394}
395
396/*
397 * Table of weak and semi-weak keys
398 *
399 * Source: http://en.wikipedia.org/wiki/Weak_key
400 *
401 * Weak:
402 * Alternating ones + zeros (0x0101010101010101)
403 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
404 * '0xE0E0E0E0F1F1F1F1'
405 * '0x1F1F1F1F0E0E0E0E'
406 *
407 * Semi-weak:
408 * 0x011F011F010E010E and 0x1F011F010E010E01
409 * 0x01E001E001F101F1 and 0xE001E001F101F101
410 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
411 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
412 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
413 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
414 *
415 */
416
417#define WEAK_KEY_COUNT 16
418
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000420{
421 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
422 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
423 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
424 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
425
426 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
427 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
428 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
429 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
430 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
431 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
432 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
433 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
434 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
435 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
436 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
437 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
438};
439
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000441{
442 int i;
443
444 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200445 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000446 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000447
Paul Bakker73206952011-07-06 14:37:33 +0000448 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000449}
450
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200451#if !defined(MBEDTLS_DES_SETKEY_ALT)
452void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000453{
454 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000455 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
Paul Bakker5c2364c2012-10-01 14:41:15 +0000457 GET_UINT32_BE( X, key, 0 );
458 GET_UINT32_BE( Y, key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
460 /*
461 * Permuted Choice 1
462 */
463 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
464 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
465
466 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
467 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
468 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
469 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
470
471 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
472 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
473 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
474 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
475
476 X &= 0x0FFFFFFF;
477 Y &= 0x0FFFFFFF;
478
479 /*
480 * calculate subkeys
481 */
482 for( i = 0; i < 16; i++ )
483 {
484 if( i < 2 || i == 8 || i == 15 )
485 {
486 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
487 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
488 }
489 else
490 {
491 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
492 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
493 }
494
495 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
496 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
497 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
498 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
499 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
500 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
501 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
502 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
503 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
504 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
505 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
506
507 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
508 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
509 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
510 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
511 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
512 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
513 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
514 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
515 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
516 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
517 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
518 }
519}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200520#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000521
522/*
523 * DES key schedule (56-bit, encryption)
524 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000526{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200527 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000528
529 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000530}
531
532/*
533 * DES key schedule (56-bit, decryption)
534 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000536{
537 int i;
538
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200539 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000540
541 for( i = 0; i < 16; i += 2 )
542 {
543 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
544 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
545 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000546
547 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000548}
549
Paul Bakker5c2364c2012-10-01 14:41:15 +0000550static void des3_set2key( uint32_t esk[96],
551 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000553{
554 int i;
555
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200556 mbedtls_des_setkey( esk, key );
557 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000558
559 for( i = 0; i < 32; i += 2 )
560 {
561 dsk[i ] = esk[30 - i];
562 dsk[i + 1] = esk[31 - i];
563
564 esk[i + 32] = dsk[62 - i];
565 esk[i + 33] = dsk[63 - i];
566
567 esk[i + 64] = esk[i ];
568 esk[i + 65] = esk[i + 1];
569
570 dsk[i + 64] = dsk[i ];
571 dsk[i + 65] = dsk[i + 1];
572 }
573}
574
575/*
576 * Triple-DES key schedule (112-bit, encryption)
577 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
579 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000580{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000581 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
583 des3_set2key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500584 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000585
586 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000587}
588
589/*
590 * Triple-DES key schedule (112-bit, decryption)
591 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
593 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000594{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000595 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000596
597 des3_set2key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500598 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000599
600 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000601}
602
Paul Bakker5c2364c2012-10-01 14:41:15 +0000603static void des3_set3key( uint32_t esk[96],
604 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000605 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000606{
607 int i;
608
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200609 mbedtls_des_setkey( esk, key );
610 mbedtls_des_setkey( dsk + 32, key + 8 );
611 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
613 for( i = 0; i < 32; i += 2 )
614 {
615 dsk[i ] = esk[94 - i];
616 dsk[i + 1] = esk[95 - i];
617
618 esk[i + 32] = dsk[62 - i];
619 esk[i + 33] = dsk[63 - i];
620
621 dsk[i + 64] = esk[30 - i];
622 dsk[i + 65] = esk[31 - i];
623 }
624}
625
626/*
627 * Triple-DES key schedule (168-bit, encryption)
628 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
630 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000631{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000632 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
634 des3_set3key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500635 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000636
637 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000638}
639
640/*
641 * Triple-DES key schedule (168-bit, decryption)
642 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
644 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000645{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000646 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000647
648 des3_set3key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500649 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000650
651 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000652}
653
654/*
655 * DES-ECB block encryption/decryption
656 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200657#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200658int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000659 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000660 unsigned char output[8] )
661{
662 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000663 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000664
665 SK = ctx->sk;
666
Paul Bakker5c2364c2012-10-01 14:41:15 +0000667 GET_UINT32_BE( X, input, 0 );
668 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000669
670 DES_IP( X, Y );
671
672 for( i = 0; i < 8; i++ )
673 {
674 DES_ROUND( Y, X );
675 DES_ROUND( X, Y );
676 }
677
678 DES_FP( Y, X );
679
Paul Bakker5c2364c2012-10-01 14:41:15 +0000680 PUT_UINT32_BE( Y, output, 0 );
681 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000682
683 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000684}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200685#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000686
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200687#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000688/*
689 * DES-CBC buffer encryption/decryption
690 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200691int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000692 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000693 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000694 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000695 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000696 unsigned char *output )
697{
698 int i;
699 unsigned char temp[8];
700
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000701 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200702 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000703
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200704 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000705 {
706 while( length > 0 )
707 {
708 for( i = 0; i < 8; i++ )
709 output[i] = (unsigned char)( input[i] ^ iv[i] );
710
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200711 mbedtls_des_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000712 memcpy( iv, output, 8 );
713
714 input += 8;
715 output += 8;
716 length -= 8;
717 }
718 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000720 {
721 while( length > 0 )
722 {
723 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200724 mbedtls_des_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000725
726 for( i = 0; i < 8; i++ )
727 output[i] = (unsigned char)( output[i] ^ iv[i] );
728
729 memcpy( iv, temp, 8 );
730
731 input += 8;
732 output += 8;
733 length -= 8;
734 }
735 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000736
737 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000738}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000740
741/*
742 * 3DES-ECB block encryption/decryption
743 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200744#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200745int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000746 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000747 unsigned char output[8] )
748{
749 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000750 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000751
752 SK = ctx->sk;
753
Paul Bakker5c2364c2012-10-01 14:41:15 +0000754 GET_UINT32_BE( X, input, 0 );
755 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000756
757 DES_IP( X, Y );
758
759 for( i = 0; i < 8; i++ )
760 {
761 DES_ROUND( Y, X );
762 DES_ROUND( X, Y );
763 }
764
765 for( i = 0; i < 8; i++ )
766 {
767 DES_ROUND( X, Y );
768 DES_ROUND( Y, X );
769 }
770
771 for( i = 0; i < 8; i++ )
772 {
773 DES_ROUND( Y, X );
774 DES_ROUND( X, Y );
775 }
776
777 DES_FP( Y, X );
778
Paul Bakker5c2364c2012-10-01 14:41:15 +0000779 PUT_UINT32_BE( Y, output, 0 );
780 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000781
782 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000783}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200784#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000785
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000787/*
788 * 3DES-CBC buffer encryption/decryption
789 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000791 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000792 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000793 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000794 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000795 unsigned char *output )
796{
797 int i;
798 unsigned char temp[8];
799
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000800 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200801 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000802
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200803 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000804 {
805 while( length > 0 )
806 {
807 for( i = 0; i < 8; i++ )
808 output[i] = (unsigned char)( input[i] ^ iv[i] );
809
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200810 mbedtls_des3_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000811 memcpy( iv, output, 8 );
812
813 input += 8;
814 output += 8;
815 length -= 8;
816 }
817 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000819 {
820 while( length > 0 )
821 {
822 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823 mbedtls_des3_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000824
825 for( i = 0; i < 8; i++ )
826 output[i] = (unsigned char)( output[i] ^ iv[i] );
827
828 memcpy( iv, temp, 8 );
829
830 input += 8;
831 output += 8;
832 length -= 8;
833 }
834 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000835
836 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000837}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000839
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200840#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000843/*
844 * DES and 3DES test vectors from:
845 *
846 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
847 */
848static const unsigned char des3_test_keys[24] =
849{
850 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
851 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
852 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
853};
854
Paul Bakker5121ce52009-01-03 21:22:43 +0000855static const unsigned char des3_test_buf[8] =
856{
857 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
858};
859
860static const unsigned char des3_test_ecb_dec[3][8] =
861{
862 { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
863 { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
864 { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
865};
866
867static const unsigned char des3_test_ecb_enc[3][8] =
868{
869 { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
870 { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
871 { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
872};
873
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200874#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100875static const unsigned char des3_test_iv[8] =
876{
877 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
878};
879
Paul Bakker5121ce52009-01-03 21:22:43 +0000880static const unsigned char des3_test_cbc_dec[3][8] =
881{
882 { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
883 { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
884 { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
885};
886
887static const unsigned char des3_test_cbc_enc[3][8] =
888{
889 { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
890 { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
891 { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
892};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000894
895/*
896 * Checkup routine
897 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200898int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000899{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200900 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901 mbedtls_des_context ctx;
902 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000903 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000905 unsigned char prv[8];
906 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200907#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000908
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909 mbedtls_des_init( &ctx );
910 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000911 /*
912 * ECB mode
913 */
914 for( i = 0; i < 6; i++ )
915 {
916 u = i >> 1;
917 v = i & 1;
918
919 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200920 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100921 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000923
924 memcpy( buf, des3_test_buf, 8 );
925
926 switch( i )
927 {
928 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000930 break;
931
932 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000934 break;
935
936 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000938 break;
939
940 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000942 break;
943
944 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200945 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946 break;
947
948 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000950 break;
951
952 default:
953 return( 1 );
954 }
955
956 for( j = 0; j < 10000; j++ )
957 {
958 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959 mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000960 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000962 }
963
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000965 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000967 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
968 {
969 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200970 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000971
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200972 ret = 1;
973 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000974 }
975
976 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000978 }
979
980 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000982
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000984 /*
985 * CBC mode
986 */
987 for( i = 0; i < 6; i++ )
988 {
989 u = i >> 1;
990 v = i & 1;
991
992 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100994 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000996
997 memcpy( iv, des3_test_iv, 8 );
998 memcpy( prv, des3_test_iv, 8 );
999 memcpy( buf, des3_test_buf, 8 );
1000
1001 switch( i )
1002 {
1003 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001004 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 break;
1006
1007 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001008 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001009 break;
1010
1011 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001012 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001013 break;
1014
1015 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001016 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001017 break;
1018
1019 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001021 break;
1022
1023 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001025 break;
1026
1027 default:
1028 return( 1 );
1029 }
1030
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001031 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001032 {
1033 for( j = 0; j < 10000; j++ )
1034 {
1035 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001037 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001039 }
1040 }
1041 else
1042 {
1043 for( j = 0; j < 10000; j++ )
1044 {
1045 unsigned char tmp[8];
1046
1047 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001048 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001049 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001050 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
1052 memcpy( tmp, prv, 8 );
1053 memcpy( prv, buf, 8 );
1054 memcpy( buf, tmp, 8 );
1055 }
1056
1057 memcpy( buf, prv, 8 );
1058 }
1059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001060 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001061 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001063 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1064 {
1065 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001067
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001068 ret = 1;
1069 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001070 }
1071
1072 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001074 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001075#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001076
1077 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001079
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001080exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081 mbedtls_des_free( &ctx );
1082 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001083
1084 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001085}
1086
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001087#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001088
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001089#endif /* MBEDTLS_DES_C */