blob: 3dc925897d9c30016ad7ec80a00a7e0d0d75617e [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úti4e9f7122020-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úti4e9f7122020-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"
Paul Bakker5121ce52009-01-03 21:22:43 +000064
Rich Evans00ab4702015-02-06 13:43:58 +000065#include <string.h>
66
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067#if defined(MBEDTLS_SELF_TEST)
68#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000069#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010070#else
Rich Evans00ab4702015-02-06 13:43:58 +000071#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072#define mbedtls_printf printf
73#endif /* MBEDTLS_PLATFORM_C */
74#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010075
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020077
Paul Bakker34617722014-06-13 17:20:13 +020078/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079static void mbedtls_zeroize( void *v, size_t n ) {
Simon Butcher88ffc082016-05-20 00:00:37 +010080 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
Paul Bakker34617722014-06-13 17:20:13 +020081}
82
Paul Bakker5121ce52009-01-03 21:22:43 +000083/*
84 * 32-bit integer manipulation macros (big endian)
85 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000086#ifndef GET_UINT32_BE
87#define GET_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000088{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000089 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
90 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
91 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
92 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000093}
94#endif
95
Paul Bakker5c2364c2012-10-01 14:41:15 +000096#ifndef PUT_UINT32_BE
97#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000098{ \
99 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
100 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
101 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
102 (b)[(i) + 3] = (unsigned char) ( (n) ); \
103}
104#endif
105
106/*
107 * Expanded DES S-boxes
108 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000109static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000110{
111 0x01010400, 0x00000000, 0x00010000, 0x01010404,
112 0x01010004, 0x00010404, 0x00000004, 0x00010000,
113 0x00000400, 0x01010400, 0x01010404, 0x00000400,
114 0x01000404, 0x01010004, 0x01000000, 0x00000004,
115 0x00000404, 0x01000400, 0x01000400, 0x00010400,
116 0x00010400, 0x01010000, 0x01010000, 0x01000404,
117 0x00010004, 0x01000004, 0x01000004, 0x00010004,
118 0x00000000, 0x00000404, 0x00010404, 0x01000000,
119 0x00010000, 0x01010404, 0x00000004, 0x01010000,
120 0x01010400, 0x01000000, 0x01000000, 0x00000400,
121 0x01010004, 0x00010000, 0x00010400, 0x01000004,
122 0x00000400, 0x00000004, 0x01000404, 0x00010404,
123 0x01010404, 0x00010004, 0x01010000, 0x01000404,
124 0x01000004, 0x00000404, 0x00010404, 0x01010400,
125 0x00000404, 0x01000400, 0x01000400, 0x00000000,
126 0x00010004, 0x00010400, 0x00000000, 0x01010004
127};
128
Paul Bakker5c2364c2012-10-01 14:41:15 +0000129static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000130{
131 0x80108020, 0x80008000, 0x00008000, 0x00108020,
132 0x00100000, 0x00000020, 0x80100020, 0x80008020,
133 0x80000020, 0x80108020, 0x80108000, 0x80000000,
134 0x80008000, 0x00100000, 0x00000020, 0x80100020,
135 0x00108000, 0x00100020, 0x80008020, 0x00000000,
136 0x80000000, 0x00008000, 0x00108020, 0x80100000,
137 0x00100020, 0x80000020, 0x00000000, 0x00108000,
138 0x00008020, 0x80108000, 0x80100000, 0x00008020,
139 0x00000000, 0x00108020, 0x80100020, 0x00100000,
140 0x80008020, 0x80100000, 0x80108000, 0x00008000,
141 0x80100000, 0x80008000, 0x00000020, 0x80108020,
142 0x00108020, 0x00000020, 0x00008000, 0x80000000,
143 0x00008020, 0x80108000, 0x00100000, 0x80000020,
144 0x00100020, 0x80008020, 0x80000020, 0x00100020,
145 0x00108000, 0x00000000, 0x80008000, 0x00008020,
146 0x80000000, 0x80100020, 0x80108020, 0x00108000
147};
148
Paul Bakker5c2364c2012-10-01 14:41:15 +0000149static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000150{
151 0x00000208, 0x08020200, 0x00000000, 0x08020008,
152 0x08000200, 0x00000000, 0x00020208, 0x08000200,
153 0x00020008, 0x08000008, 0x08000008, 0x00020000,
154 0x08020208, 0x00020008, 0x08020000, 0x00000208,
155 0x08000000, 0x00000008, 0x08020200, 0x00000200,
156 0x00020200, 0x08020000, 0x08020008, 0x00020208,
157 0x08000208, 0x00020200, 0x00020000, 0x08000208,
158 0x00000008, 0x08020208, 0x00000200, 0x08000000,
159 0x08020200, 0x08000000, 0x00020008, 0x00000208,
160 0x00020000, 0x08020200, 0x08000200, 0x00000000,
161 0x00000200, 0x00020008, 0x08020208, 0x08000200,
162 0x08000008, 0x00000200, 0x00000000, 0x08020008,
163 0x08000208, 0x00020000, 0x08000000, 0x08020208,
164 0x00000008, 0x00020208, 0x00020200, 0x08000008,
165 0x08020000, 0x08000208, 0x00000208, 0x08020000,
166 0x00020208, 0x00000008, 0x08020008, 0x00020200
167};
168
Paul Bakker5c2364c2012-10-01 14:41:15 +0000169static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000170{
171 0x00802001, 0x00002081, 0x00002081, 0x00000080,
172 0x00802080, 0x00800081, 0x00800001, 0x00002001,
173 0x00000000, 0x00802000, 0x00802000, 0x00802081,
174 0x00000081, 0x00000000, 0x00800080, 0x00800001,
175 0x00000001, 0x00002000, 0x00800000, 0x00802001,
176 0x00000080, 0x00800000, 0x00002001, 0x00002080,
177 0x00800081, 0x00000001, 0x00002080, 0x00800080,
178 0x00002000, 0x00802080, 0x00802081, 0x00000081,
179 0x00800080, 0x00800001, 0x00802000, 0x00802081,
180 0x00000081, 0x00000000, 0x00000000, 0x00802000,
181 0x00002080, 0x00800080, 0x00800081, 0x00000001,
182 0x00802001, 0x00002081, 0x00002081, 0x00000080,
183 0x00802081, 0x00000081, 0x00000001, 0x00002000,
184 0x00800001, 0x00002001, 0x00802080, 0x00800081,
185 0x00002001, 0x00002080, 0x00800000, 0x00802001,
186 0x00000080, 0x00800000, 0x00002000, 0x00802080
187};
188
Paul Bakker5c2364c2012-10-01 14:41:15 +0000189static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000190{
191 0x00000100, 0x02080100, 0x02080000, 0x42000100,
192 0x00080000, 0x00000100, 0x40000000, 0x02080000,
193 0x40080100, 0x00080000, 0x02000100, 0x40080100,
194 0x42000100, 0x42080000, 0x00080100, 0x40000000,
195 0x02000000, 0x40080000, 0x40080000, 0x00000000,
196 0x40000100, 0x42080100, 0x42080100, 0x02000100,
197 0x42080000, 0x40000100, 0x00000000, 0x42000000,
198 0x02080100, 0x02000000, 0x42000000, 0x00080100,
199 0x00080000, 0x42000100, 0x00000100, 0x02000000,
200 0x40000000, 0x02080000, 0x42000100, 0x40080100,
201 0x02000100, 0x40000000, 0x42080000, 0x02080100,
202 0x40080100, 0x00000100, 0x02000000, 0x42080000,
203 0x42080100, 0x00080100, 0x42000000, 0x42080100,
204 0x02080000, 0x00000000, 0x40080000, 0x42000000,
205 0x00080100, 0x02000100, 0x40000100, 0x00080000,
206 0x00000000, 0x40080000, 0x02080100, 0x40000100
207};
208
Paul Bakker5c2364c2012-10-01 14:41:15 +0000209static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000210{
211 0x20000010, 0x20400000, 0x00004000, 0x20404010,
212 0x20400000, 0x00000010, 0x20404010, 0x00400000,
213 0x20004000, 0x00404010, 0x00400000, 0x20000010,
214 0x00400010, 0x20004000, 0x20000000, 0x00004010,
215 0x00000000, 0x00400010, 0x20004010, 0x00004000,
216 0x00404000, 0x20004010, 0x00000010, 0x20400010,
217 0x20400010, 0x00000000, 0x00404010, 0x20404000,
218 0x00004010, 0x00404000, 0x20404000, 0x20000000,
219 0x20004000, 0x00000010, 0x20400010, 0x00404000,
220 0x20404010, 0x00400000, 0x00004010, 0x20000010,
221 0x00400000, 0x20004000, 0x20000000, 0x00004010,
222 0x20000010, 0x20404010, 0x00404000, 0x20400000,
223 0x00404010, 0x20404000, 0x00000000, 0x20400010,
224 0x00000010, 0x00004000, 0x20400000, 0x00404010,
225 0x00004000, 0x00400010, 0x20004010, 0x00000000,
226 0x20404000, 0x20000000, 0x00400010, 0x20004010
227};
228
Paul Bakker5c2364c2012-10-01 14:41:15 +0000229static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000230{
231 0x00200000, 0x04200002, 0x04000802, 0x00000000,
232 0x00000800, 0x04000802, 0x00200802, 0x04200800,
233 0x04200802, 0x00200000, 0x00000000, 0x04000002,
234 0x00000002, 0x04000000, 0x04200002, 0x00000802,
235 0x04000800, 0x00200802, 0x00200002, 0x04000800,
236 0x04000002, 0x04200000, 0x04200800, 0x00200002,
237 0x04200000, 0x00000800, 0x00000802, 0x04200802,
238 0x00200800, 0x00000002, 0x04000000, 0x00200800,
239 0x04000000, 0x00200800, 0x00200000, 0x04000802,
240 0x04000802, 0x04200002, 0x04200002, 0x00000002,
241 0x00200002, 0x04000000, 0x04000800, 0x00200000,
242 0x04200800, 0x00000802, 0x00200802, 0x04200800,
243 0x00000802, 0x04000002, 0x04200802, 0x04200000,
244 0x00200800, 0x00000000, 0x00000002, 0x04200802,
245 0x00000000, 0x00200802, 0x04200000, 0x00000800,
246 0x04000002, 0x04000800, 0x00000800, 0x00200002
247};
248
Paul Bakker5c2364c2012-10-01 14:41:15 +0000249static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000250{
251 0x10001040, 0x00001000, 0x00040000, 0x10041040,
252 0x10000000, 0x10001040, 0x00000040, 0x10000000,
253 0x00040040, 0x10040000, 0x10041040, 0x00041000,
254 0x10041000, 0x00041040, 0x00001000, 0x00000040,
255 0x10040000, 0x10000040, 0x10001000, 0x00001040,
256 0x00041000, 0x00040040, 0x10040040, 0x10041000,
257 0x00001040, 0x00000000, 0x00000000, 0x10040040,
258 0x10000040, 0x10001000, 0x00041040, 0x00040000,
259 0x00041040, 0x00040000, 0x10041000, 0x00001000,
260 0x00000040, 0x10040040, 0x00001000, 0x00041040,
261 0x10001000, 0x00000040, 0x10000040, 0x10040000,
262 0x10040040, 0x10000000, 0x00040000, 0x10001040,
263 0x00000000, 0x10041040, 0x00040040, 0x10000040,
264 0x10040000, 0x10001000, 0x10001040, 0x00000000,
265 0x10041040, 0x00041000, 0x00041000, 0x00001040,
266 0x00001040, 0x00040040, 0x10000000, 0x10041000
267};
268
269/*
270 * PC1: left and right halves bit-swap
271 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000272static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000273{
274 0x00000000, 0x00000001, 0x00000100, 0x00000101,
275 0x00010000, 0x00010001, 0x00010100, 0x00010101,
276 0x01000000, 0x01000001, 0x01000100, 0x01000101,
277 0x01010000, 0x01010001, 0x01010100, 0x01010101
278};
279
Paul Bakker5c2364c2012-10-01 14:41:15 +0000280static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000281{
282 0x00000000, 0x01000000, 0x00010000, 0x01010000,
283 0x00000100, 0x01000100, 0x00010100, 0x01010100,
284 0x00000001, 0x01000001, 0x00010001, 0x01010001,
285 0x00000101, 0x01000101, 0x00010101, 0x01010101,
286};
287
288/*
289 * Initial Permutation macro
290 */
291#define DES_IP(X,Y) \
292{ \
293 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
294 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
295 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
296 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
297 Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
298 T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
299 X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
300}
301
302/*
303 * Final Permutation macro
304 */
305#define DES_FP(X,Y) \
306{ \
307 X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
308 T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
309 Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
310 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
311 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
312 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
313 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
314}
315
316/*
317 * DES round macro
318 */
319#define DES_ROUND(X,Y) \
320{ \
321 T = *SK++ ^ X; \
322 Y ^= SB8[ (T ) & 0x3F ] ^ \
323 SB6[ (T >> 8) & 0x3F ] ^ \
324 SB4[ (T >> 16) & 0x3F ] ^ \
325 SB2[ (T >> 24) & 0x3F ]; \
326 \
327 T = *SK++ ^ ((X << 28) | (X >> 4)); \
328 Y ^= SB7[ (T ) & 0x3F ] ^ \
329 SB5[ (T >> 8) & 0x3F ] ^ \
330 SB3[ (T >> 16) & 0x3F ] ^ \
331 SB1[ (T >> 24) & 0x3F ]; \
332}
333
Paul Bakker5c2364c2012-10-01 14:41:15 +0000334#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; }
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200337{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200339}
340
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200342{
343 if( ctx == NULL )
344 return;
345
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346 mbedtls_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200347}
348
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200350{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200352}
353
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200355{
356 if( ctx == NULL )
357 return;
358
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359 mbedtls_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200360}
361
Paul Bakker1f87fb62011-01-15 17:32:24 +0000362static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
363 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
364 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
365 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
366 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
367 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
368 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
369 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
370 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
371 254 };
372
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000374{
375 int i;
376
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000378 key[i] = odd_parity_table[key[i] / 2];
379}
380
381/*
382 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
383 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200384int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000385{
386 int i;
387
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200389 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000390 return( 1 );
391
392 return( 0 );
393}
394
395/*
396 * Table of weak and semi-weak keys
397 *
398 * Source: http://en.wikipedia.org/wiki/Weak_key
399 *
400 * Weak:
401 * Alternating ones + zeros (0x0101010101010101)
402 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
403 * '0xE0E0E0E0F1F1F1F1'
404 * '0x1F1F1F1F0E0E0E0E'
405 *
406 * Semi-weak:
407 * 0x011F011F010E010E and 0x1F011F010E010E01
408 * 0x01E001E001F101F1 and 0xE001E001F101F101
409 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
410 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
411 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
412 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
413 *
414 */
415
416#define WEAK_KEY_COUNT 16
417
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000419{
420 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
421 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
422 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
423 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
424
425 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
426 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
427 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
428 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
429 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
430 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
431 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
432 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
433 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
434 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
435 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
436 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
437};
438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000440{
441 int i;
442
443 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000445 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000446
Paul Bakker73206952011-07-06 14:37:33 +0000447 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000448}
449
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200450#if !defined(MBEDTLS_DES_SETKEY_ALT)
451void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000452{
453 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000454 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
Paul Bakker5c2364c2012-10-01 14:41:15 +0000456 GET_UINT32_BE( X, key, 0 );
457 GET_UINT32_BE( Y, key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000458
459 /*
460 * Permuted Choice 1
461 */
462 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
463 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
464
465 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
466 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
467 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
468 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
469
470 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
471 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
472 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
473 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
474
475 X &= 0x0FFFFFFF;
476 Y &= 0x0FFFFFFF;
477
478 /*
479 * calculate subkeys
480 */
481 for( i = 0; i < 16; i++ )
482 {
483 if( i < 2 || i == 8 || i == 15 )
484 {
485 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
486 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
487 }
488 else
489 {
490 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
491 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
492 }
493
494 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
495 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
496 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
497 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
498 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
499 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
500 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
501 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
502 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
503 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
504 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
505
506 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
507 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
508 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
509 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
510 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
511 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
512 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
513 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
514 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
515 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
516 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
517 }
518}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200519#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000520
521/*
522 * DES key schedule (56-bit, encryption)
523 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200524int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000525{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200526 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000527
528 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000529}
530
531/*
532 * DES key schedule (56-bit, decryption)
533 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000535{
536 int i;
537
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200538 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000539
540 for( i = 0; i < 16; i += 2 )
541 {
542 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
543 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
544 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000545
546 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000547}
548
Paul Bakker5c2364c2012-10-01 14:41:15 +0000549static void des3_set2key( uint32_t esk[96],
550 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000552{
553 int i;
554
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200555 mbedtls_des_setkey( esk, key );
556 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000557
558 for( i = 0; i < 32; i += 2 )
559 {
560 dsk[i ] = esk[30 - i];
561 dsk[i + 1] = esk[31 - i];
562
563 esk[i + 32] = dsk[62 - i];
564 esk[i + 33] = dsk[63 - i];
565
566 esk[i + 64] = esk[i ];
567 esk[i + 65] = esk[i + 1];
568
569 dsk[i + 64] = dsk[i ];
570 dsk[i + 65] = dsk[i + 1];
571 }
572}
573
574/*
575 * Triple-DES key schedule (112-bit, encryption)
576 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
578 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000579{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000580 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
582 des3_set2key( ctx->sk, sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000584
585 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000586}
587
588/*
589 * Triple-DES key schedule (112-bit, decryption)
590 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
592 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000593{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000594 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
596 des3_set2key( sk, ctx->sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000598
599 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000600}
601
Paul Bakker5c2364c2012-10-01 14:41:15 +0000602static void des3_set3key( uint32_t esk[96],
603 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000604 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000605{
606 int i;
607
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200608 mbedtls_des_setkey( esk, key );
609 mbedtls_des_setkey( dsk + 32, key + 8 );
610 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612 for( i = 0; i < 32; i += 2 )
613 {
614 dsk[i ] = esk[94 - i];
615 dsk[i + 1] = esk[95 - i];
616
617 esk[i + 32] = dsk[62 - i];
618 esk[i + 33] = dsk[63 - i];
619
620 dsk[i + 64] = esk[30 - i];
621 dsk[i + 65] = esk[31 - i];
622 }
623}
624
625/*
626 * Triple-DES key schedule (168-bit, encryption)
627 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
629 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000630{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000631 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
633 des3_set3key( ctx->sk, sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000635
636 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637}
638
639/*
640 * Triple-DES key schedule (168-bit, decryption)
641 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
643 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000644{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000645 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000646
647 des3_set3key( sk, ctx->sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000649
650 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000651}
652
653/*
654 * DES-ECB block encryption/decryption
655 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200656#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000658 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000659 unsigned char output[8] )
660{
661 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000662 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000663
664 SK = ctx->sk;
665
Paul Bakker5c2364c2012-10-01 14:41:15 +0000666 GET_UINT32_BE( X, input, 0 );
667 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
669 DES_IP( X, Y );
670
671 for( i = 0; i < 8; i++ )
672 {
673 DES_ROUND( Y, X );
674 DES_ROUND( X, Y );
675 }
676
677 DES_FP( Y, X );
678
Paul Bakker5c2364c2012-10-01 14:41:15 +0000679 PUT_UINT32_BE( Y, output, 0 );
680 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000681
682 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000683}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200684#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000685
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200686#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000687/*
688 * DES-CBC buffer encryption/decryption
689 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200690int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000691 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000692 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000693 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000694 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000695 unsigned char *output )
696{
697 int i;
698 unsigned char temp[8];
699
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000700 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200701 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000702
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200703 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000704 {
705 while( length > 0 )
706 {
707 for( i = 0; i < 8; i++ )
708 output[i] = (unsigned char)( input[i] ^ iv[i] );
709
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710 mbedtls_des_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000711 memcpy( iv, output, 8 );
712
713 input += 8;
714 output += 8;
715 length -= 8;
716 }
717 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200718 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000719 {
720 while( length > 0 )
721 {
722 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200723 mbedtls_des_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000724
725 for( i = 0; i < 8; i++ )
726 output[i] = (unsigned char)( output[i] ^ iv[i] );
727
728 memcpy( iv, temp, 8 );
729
730 input += 8;
731 output += 8;
732 length -= 8;
733 }
734 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000735
736 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000737}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200738#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000739
740/*
741 * 3DES-ECB block encryption/decryption
742 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200743#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200744int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000745 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000746 unsigned char output[8] )
747{
748 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000749 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000750
751 SK = ctx->sk;
752
Paul Bakker5c2364c2012-10-01 14:41:15 +0000753 GET_UINT32_BE( X, input, 0 );
754 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000755
756 DES_IP( X, Y );
757
758 for( i = 0; i < 8; i++ )
759 {
760 DES_ROUND( Y, X );
761 DES_ROUND( X, Y );
762 }
763
764 for( i = 0; i < 8; i++ )
765 {
766 DES_ROUND( X, Y );
767 DES_ROUND( Y, X );
768 }
769
770 for( i = 0; i < 8; i++ )
771 {
772 DES_ROUND( Y, X );
773 DES_ROUND( X, Y );
774 }
775
776 DES_FP( Y, X );
777
Paul Bakker5c2364c2012-10-01 14:41:15 +0000778 PUT_UINT32_BE( Y, output, 0 );
779 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000780
781 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000782}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200783#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000784
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000786/*
787 * 3DES-CBC buffer encryption/decryption
788 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000790 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000791 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000792 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000793 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000794 unsigned char *output )
795{
796 int i;
797 unsigned char temp[8];
798
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000799 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200800 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000801
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200802 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000803 {
804 while( length > 0 )
805 {
806 for( i = 0; i < 8; i++ )
807 output[i] = (unsigned char)( input[i] ^ iv[i] );
808
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200809 mbedtls_des3_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000810 memcpy( iv, output, 8 );
811
812 input += 8;
813 output += 8;
814 length -= 8;
815 }
816 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200817 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000818 {
819 while( length > 0 )
820 {
821 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200822 mbedtls_des3_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000823
824 for( i = 0; i < 8; i++ )
825 output[i] = (unsigned char)( output[i] ^ iv[i] );
826
827 memcpy( iv, temp, 8 );
828
829 input += 8;
830 output += 8;
831 length -= 8;
832 }
833 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000834
835 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000836}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000838
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200840
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000842/*
843 * DES and 3DES test vectors from:
844 *
845 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
846 */
847static const unsigned char des3_test_keys[24] =
848{
849 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
850 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
851 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
852};
853
Paul Bakker5121ce52009-01-03 21:22:43 +0000854static const unsigned char des3_test_buf[8] =
855{
856 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
857};
858
859static const unsigned char des3_test_ecb_dec[3][8] =
860{
861 { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
862 { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
863 { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
864};
865
866static const unsigned char des3_test_ecb_enc[3][8] =
867{
868 { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
869 { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
870 { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
871};
872
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100874static const unsigned char des3_test_iv[8] =
875{
876 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
877};
878
Paul Bakker5121ce52009-01-03 21:22:43 +0000879static const unsigned char des3_test_cbc_dec[3][8] =
880{
881 { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
882 { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
883 { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
884};
885
886static const unsigned char des3_test_cbc_enc[3][8] =
887{
888 { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
889 { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
890 { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
891};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000893
894/*
895 * Checkup routine
896 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000898{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200899 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 mbedtls_des_context ctx;
901 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000902 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000904 unsigned char prv[8];
905 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200906#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000907
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908 mbedtls_des_init( &ctx );
909 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000910 /*
911 * ECB mode
912 */
913 for( i = 0; i < 6; i++ )
914 {
915 u = i >> 1;
916 v = i & 1;
917
918 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100920 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000922
923 memcpy( buf, des3_test_buf, 8 );
924
925 switch( i )
926 {
927 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200928 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000929 break;
930
931 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000933 break;
934
935 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000937 break;
938
939 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200940 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000941 break;
942
943 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000945 break;
946
947 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200948 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 break;
950
951 default:
952 return( 1 );
953 }
954
955 for( j = 0; j < 10000; j++ )
956 {
957 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200960 mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000961 }
962
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000964 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000966 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
967 {
968 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000970
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200971 ret = 1;
972 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000973 }
974
975 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000977 }
978
979 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200980 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000981
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200982#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000983 /*
984 * CBC mode
985 */
986 for( i = 0; i < 6; i++ )
987 {
988 u = i >> 1;
989 v = i & 1;
990
991 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200992 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100993 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200994 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000995
996 memcpy( iv, des3_test_iv, 8 );
997 memcpy( prv, des3_test_iv, 8 );
998 memcpy( buf, des3_test_buf, 8 );
999
1000 switch( i )
1001 {
1002 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001003 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001004 break;
1005
1006 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001008 break;
1009
1010 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001011 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001012 break;
1013
1014 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001015 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001016 break;
1017
1018 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001020 break;
1021
1022 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001023 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001024 break;
1025
1026 default:
1027 return( 1 );
1028 }
1029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001031 {
1032 for( j = 0; j < 10000; j++ )
1033 {
1034 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001036 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001037 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001038 }
1039 }
1040 else
1041 {
1042 for( j = 0; j < 10000; j++ )
1043 {
1044 unsigned char tmp[8];
1045
1046 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001048 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001050
1051 memcpy( tmp, prv, 8 );
1052 memcpy( prv, buf, 8 );
1053 memcpy( buf, tmp, 8 );
1054 }
1055
1056 memcpy( buf, prv, 8 );
1057 }
1058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001059 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001060 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001061 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001062 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1063 {
1064 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001066
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001067 ret = 1;
1068 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001069 }
1070
1071 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001072 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001073 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001074#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001075
1076 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001078
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001079exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080 mbedtls_des_free( &ctx );
1081 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001082
1083 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001084}
1085
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001087
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088#endif /* MBEDTLS_DES_C */