blob: f68dba0b3afdbe6eec69d9b11953967ec61716d9 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-46-3 compliant Triple-DES implementation
3 *
Bence Szépkúti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
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 * **********
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"
Paul Bakker5121ce52009-01-03 21:22:43 +000062
Rich Evans00ab4702015-02-06 13:43:58 +000063#include <string.h>
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_SELF_TEST)
66#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000067#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010068#else
Rich Evans00ab4702015-02-06 13:43:58 +000069#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070#define mbedtls_printf printf
71#endif /* MBEDTLS_PLATFORM_C */
72#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010073
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020075
Paul Bakker34617722014-06-13 17:20:13 +020076/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077static void mbedtls_zeroize( void *v, size_t n ) {
Simon Butcher88ffc082016-05-20 00:00:37 +010078 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
Paul Bakker34617722014-06-13 17:20:13 +020079}
80
Paul Bakker5121ce52009-01-03 21:22:43 +000081/*
82 * 32-bit integer manipulation macros (big endian)
83 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000084#ifndef GET_UINT32_BE
85#define GET_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000086{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000087 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
88 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
89 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
90 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000091}
92#endif
93
Paul Bakker5c2364c2012-10-01 14:41:15 +000094#ifndef PUT_UINT32_BE
95#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000096{ \
97 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
98 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
99 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
100 (b)[(i) + 3] = (unsigned char) ( (n) ); \
101}
102#endif
103
104/*
105 * Expanded DES S-boxes
106 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000107static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000108{
109 0x01010400, 0x00000000, 0x00010000, 0x01010404,
110 0x01010004, 0x00010404, 0x00000004, 0x00010000,
111 0x00000400, 0x01010400, 0x01010404, 0x00000400,
112 0x01000404, 0x01010004, 0x01000000, 0x00000004,
113 0x00000404, 0x01000400, 0x01000400, 0x00010400,
114 0x00010400, 0x01010000, 0x01010000, 0x01000404,
115 0x00010004, 0x01000004, 0x01000004, 0x00010004,
116 0x00000000, 0x00000404, 0x00010404, 0x01000000,
117 0x00010000, 0x01010404, 0x00000004, 0x01010000,
118 0x01010400, 0x01000000, 0x01000000, 0x00000400,
119 0x01010004, 0x00010000, 0x00010400, 0x01000004,
120 0x00000400, 0x00000004, 0x01000404, 0x00010404,
121 0x01010404, 0x00010004, 0x01010000, 0x01000404,
122 0x01000004, 0x00000404, 0x00010404, 0x01010400,
123 0x00000404, 0x01000400, 0x01000400, 0x00000000,
124 0x00010004, 0x00010400, 0x00000000, 0x01010004
125};
126
Paul Bakker5c2364c2012-10-01 14:41:15 +0000127static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000128{
129 0x80108020, 0x80008000, 0x00008000, 0x00108020,
130 0x00100000, 0x00000020, 0x80100020, 0x80008020,
131 0x80000020, 0x80108020, 0x80108000, 0x80000000,
132 0x80008000, 0x00100000, 0x00000020, 0x80100020,
133 0x00108000, 0x00100020, 0x80008020, 0x00000000,
134 0x80000000, 0x00008000, 0x00108020, 0x80100000,
135 0x00100020, 0x80000020, 0x00000000, 0x00108000,
136 0x00008020, 0x80108000, 0x80100000, 0x00008020,
137 0x00000000, 0x00108020, 0x80100020, 0x00100000,
138 0x80008020, 0x80100000, 0x80108000, 0x00008000,
139 0x80100000, 0x80008000, 0x00000020, 0x80108020,
140 0x00108020, 0x00000020, 0x00008000, 0x80000000,
141 0x00008020, 0x80108000, 0x00100000, 0x80000020,
142 0x00100020, 0x80008020, 0x80000020, 0x00100020,
143 0x00108000, 0x00000000, 0x80008000, 0x00008020,
144 0x80000000, 0x80100020, 0x80108020, 0x00108000
145};
146
Paul Bakker5c2364c2012-10-01 14:41:15 +0000147static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000148{
149 0x00000208, 0x08020200, 0x00000000, 0x08020008,
150 0x08000200, 0x00000000, 0x00020208, 0x08000200,
151 0x00020008, 0x08000008, 0x08000008, 0x00020000,
152 0x08020208, 0x00020008, 0x08020000, 0x00000208,
153 0x08000000, 0x00000008, 0x08020200, 0x00000200,
154 0x00020200, 0x08020000, 0x08020008, 0x00020208,
155 0x08000208, 0x00020200, 0x00020000, 0x08000208,
156 0x00000008, 0x08020208, 0x00000200, 0x08000000,
157 0x08020200, 0x08000000, 0x00020008, 0x00000208,
158 0x00020000, 0x08020200, 0x08000200, 0x00000000,
159 0x00000200, 0x00020008, 0x08020208, 0x08000200,
160 0x08000008, 0x00000200, 0x00000000, 0x08020008,
161 0x08000208, 0x00020000, 0x08000000, 0x08020208,
162 0x00000008, 0x00020208, 0x00020200, 0x08000008,
163 0x08020000, 0x08000208, 0x00000208, 0x08020000,
164 0x00020208, 0x00000008, 0x08020008, 0x00020200
165};
166
Paul Bakker5c2364c2012-10-01 14:41:15 +0000167static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000168{
169 0x00802001, 0x00002081, 0x00002081, 0x00000080,
170 0x00802080, 0x00800081, 0x00800001, 0x00002001,
171 0x00000000, 0x00802000, 0x00802000, 0x00802081,
172 0x00000081, 0x00000000, 0x00800080, 0x00800001,
173 0x00000001, 0x00002000, 0x00800000, 0x00802001,
174 0x00000080, 0x00800000, 0x00002001, 0x00002080,
175 0x00800081, 0x00000001, 0x00002080, 0x00800080,
176 0x00002000, 0x00802080, 0x00802081, 0x00000081,
177 0x00800080, 0x00800001, 0x00802000, 0x00802081,
178 0x00000081, 0x00000000, 0x00000000, 0x00802000,
179 0x00002080, 0x00800080, 0x00800081, 0x00000001,
180 0x00802001, 0x00002081, 0x00002081, 0x00000080,
181 0x00802081, 0x00000081, 0x00000001, 0x00002000,
182 0x00800001, 0x00002001, 0x00802080, 0x00800081,
183 0x00002001, 0x00002080, 0x00800000, 0x00802001,
184 0x00000080, 0x00800000, 0x00002000, 0x00802080
185};
186
Paul Bakker5c2364c2012-10-01 14:41:15 +0000187static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000188{
189 0x00000100, 0x02080100, 0x02080000, 0x42000100,
190 0x00080000, 0x00000100, 0x40000000, 0x02080000,
191 0x40080100, 0x00080000, 0x02000100, 0x40080100,
192 0x42000100, 0x42080000, 0x00080100, 0x40000000,
193 0x02000000, 0x40080000, 0x40080000, 0x00000000,
194 0x40000100, 0x42080100, 0x42080100, 0x02000100,
195 0x42080000, 0x40000100, 0x00000000, 0x42000000,
196 0x02080100, 0x02000000, 0x42000000, 0x00080100,
197 0x00080000, 0x42000100, 0x00000100, 0x02000000,
198 0x40000000, 0x02080000, 0x42000100, 0x40080100,
199 0x02000100, 0x40000000, 0x42080000, 0x02080100,
200 0x40080100, 0x00000100, 0x02000000, 0x42080000,
201 0x42080100, 0x00080100, 0x42000000, 0x42080100,
202 0x02080000, 0x00000000, 0x40080000, 0x42000000,
203 0x00080100, 0x02000100, 0x40000100, 0x00080000,
204 0x00000000, 0x40080000, 0x02080100, 0x40000100
205};
206
Paul Bakker5c2364c2012-10-01 14:41:15 +0000207static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000208{
209 0x20000010, 0x20400000, 0x00004000, 0x20404010,
210 0x20400000, 0x00000010, 0x20404010, 0x00400000,
211 0x20004000, 0x00404010, 0x00400000, 0x20000010,
212 0x00400010, 0x20004000, 0x20000000, 0x00004010,
213 0x00000000, 0x00400010, 0x20004010, 0x00004000,
214 0x00404000, 0x20004010, 0x00000010, 0x20400010,
215 0x20400010, 0x00000000, 0x00404010, 0x20404000,
216 0x00004010, 0x00404000, 0x20404000, 0x20000000,
217 0x20004000, 0x00000010, 0x20400010, 0x00404000,
218 0x20404010, 0x00400000, 0x00004010, 0x20000010,
219 0x00400000, 0x20004000, 0x20000000, 0x00004010,
220 0x20000010, 0x20404010, 0x00404000, 0x20400000,
221 0x00404010, 0x20404000, 0x00000000, 0x20400010,
222 0x00000010, 0x00004000, 0x20400000, 0x00404010,
223 0x00004000, 0x00400010, 0x20004010, 0x00000000,
224 0x20404000, 0x20000000, 0x00400010, 0x20004010
225};
226
Paul Bakker5c2364c2012-10-01 14:41:15 +0000227static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000228{
229 0x00200000, 0x04200002, 0x04000802, 0x00000000,
230 0x00000800, 0x04000802, 0x00200802, 0x04200800,
231 0x04200802, 0x00200000, 0x00000000, 0x04000002,
232 0x00000002, 0x04000000, 0x04200002, 0x00000802,
233 0x04000800, 0x00200802, 0x00200002, 0x04000800,
234 0x04000002, 0x04200000, 0x04200800, 0x00200002,
235 0x04200000, 0x00000800, 0x00000802, 0x04200802,
236 0x00200800, 0x00000002, 0x04000000, 0x00200800,
237 0x04000000, 0x00200800, 0x00200000, 0x04000802,
238 0x04000802, 0x04200002, 0x04200002, 0x00000002,
239 0x00200002, 0x04000000, 0x04000800, 0x00200000,
240 0x04200800, 0x00000802, 0x00200802, 0x04200800,
241 0x00000802, 0x04000002, 0x04200802, 0x04200000,
242 0x00200800, 0x00000000, 0x00000002, 0x04200802,
243 0x00000000, 0x00200802, 0x04200000, 0x00000800,
244 0x04000002, 0x04000800, 0x00000800, 0x00200002
245};
246
Paul Bakker5c2364c2012-10-01 14:41:15 +0000247static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000248{
249 0x10001040, 0x00001000, 0x00040000, 0x10041040,
250 0x10000000, 0x10001040, 0x00000040, 0x10000000,
251 0x00040040, 0x10040000, 0x10041040, 0x00041000,
252 0x10041000, 0x00041040, 0x00001000, 0x00000040,
253 0x10040000, 0x10000040, 0x10001000, 0x00001040,
254 0x00041000, 0x00040040, 0x10040040, 0x10041000,
255 0x00001040, 0x00000000, 0x00000000, 0x10040040,
256 0x10000040, 0x10001000, 0x00041040, 0x00040000,
257 0x00041040, 0x00040000, 0x10041000, 0x00001000,
258 0x00000040, 0x10040040, 0x00001000, 0x00041040,
259 0x10001000, 0x00000040, 0x10000040, 0x10040000,
260 0x10040040, 0x10000000, 0x00040000, 0x10001040,
261 0x00000000, 0x10041040, 0x00040040, 0x10000040,
262 0x10040000, 0x10001000, 0x10001040, 0x00000000,
263 0x10041040, 0x00041000, 0x00041000, 0x00001040,
264 0x00001040, 0x00040040, 0x10000000, 0x10041000
265};
266
267/*
268 * PC1: left and right halves bit-swap
269 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000270static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000271{
272 0x00000000, 0x00000001, 0x00000100, 0x00000101,
273 0x00010000, 0x00010001, 0x00010100, 0x00010101,
274 0x01000000, 0x01000001, 0x01000100, 0x01000101,
275 0x01010000, 0x01010001, 0x01010100, 0x01010101
276};
277
Paul Bakker5c2364c2012-10-01 14:41:15 +0000278static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000279{
280 0x00000000, 0x01000000, 0x00010000, 0x01010000,
281 0x00000100, 0x01000100, 0x00010100, 0x01010100,
282 0x00000001, 0x01000001, 0x00010001, 0x01010001,
283 0x00000101, 0x01000101, 0x00010101, 0x01010101,
284};
285
286/*
287 * Initial Permutation macro
288 */
289#define DES_IP(X,Y) \
290{ \
291 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
292 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
293 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
294 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
295 Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
296 T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
297 X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
298}
299
300/*
301 * Final Permutation macro
302 */
303#define DES_FP(X,Y) \
304{ \
305 X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
306 T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
307 Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
308 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
309 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
310 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
311 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
312}
313
314/*
315 * DES round macro
316 */
317#define DES_ROUND(X,Y) \
318{ \
319 T = *SK++ ^ X; \
320 Y ^= SB8[ (T ) & 0x3F ] ^ \
321 SB6[ (T >> 8) & 0x3F ] ^ \
322 SB4[ (T >> 16) & 0x3F ] ^ \
323 SB2[ (T >> 24) & 0x3F ]; \
324 \
325 T = *SK++ ^ ((X << 28) | (X >> 4)); \
326 Y ^= SB7[ (T ) & 0x3F ] ^ \
327 SB5[ (T >> 8) & 0x3F ] ^ \
328 SB3[ (T >> 16) & 0x3F ] ^ \
329 SB1[ (T >> 24) & 0x3F ]; \
330}
331
Paul Bakker5c2364c2012-10-01 14:41:15 +0000332#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; }
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200334void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200335{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200337}
338
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200340{
341 if( ctx == NULL )
342 return;
343
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344 mbedtls_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200345}
346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200348{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200350}
351
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200353{
354 if( ctx == NULL )
355 return;
356
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357 mbedtls_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200358}
359
Paul Bakker1f87fb62011-01-15 17:32:24 +0000360static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
361 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
362 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
363 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
364 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
365 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
366 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
367 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
368 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
369 254 };
370
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000372{
373 int i;
374
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000376 key[i] = odd_parity_table[key[i] / 2];
377}
378
379/*
380 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
381 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200382int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000383{
384 int i;
385
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200387 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000388 return( 1 );
389
390 return( 0 );
391}
392
393/*
394 * Table of weak and semi-weak keys
395 *
396 * Source: http://en.wikipedia.org/wiki/Weak_key
397 *
398 * Weak:
399 * Alternating ones + zeros (0x0101010101010101)
400 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
401 * '0xE0E0E0E0F1F1F1F1'
402 * '0x1F1F1F1F0E0E0E0E'
403 *
404 * Semi-weak:
405 * 0x011F011F010E010E and 0x1F011F010E010E01
406 * 0x01E001E001F101F1 and 0xE001E001F101F101
407 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
408 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
409 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
410 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
411 *
412 */
413
414#define WEAK_KEY_COUNT 16
415
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000417{
418 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
419 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
420 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
421 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
422
423 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
424 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
425 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
426 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
427 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
428 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
429 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
430 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
431 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
432 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
433 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
434 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
435};
436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000438{
439 int i;
440
441 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000443 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000444
Paul Bakker73206952011-07-06 14:37:33 +0000445 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000446}
447
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200448#if !defined(MBEDTLS_DES_SETKEY_ALT)
449void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000450{
451 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000452 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000453
Paul Bakker5c2364c2012-10-01 14:41:15 +0000454 GET_UINT32_BE( X, key, 0 );
455 GET_UINT32_BE( Y, key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
457 /*
458 * Permuted Choice 1
459 */
460 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
461 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
462
463 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
464 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
465 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
466 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
467
468 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
469 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
470 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
471 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
472
473 X &= 0x0FFFFFFF;
474 Y &= 0x0FFFFFFF;
475
476 /*
477 * calculate subkeys
478 */
479 for( i = 0; i < 16; i++ )
480 {
481 if( i < 2 || i == 8 || i == 15 )
482 {
483 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
484 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
485 }
486 else
487 {
488 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
489 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
490 }
491
492 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
493 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
494 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
495 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
496 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
497 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
498 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
499 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
500 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
501 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
502 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
503
504 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
505 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
506 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
507 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
508 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
509 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
510 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
511 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
512 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
513 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
514 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
515 }
516}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200517#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000518
519/*
520 * DES key schedule (56-bit, encryption)
521 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200522int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000523{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200524 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000525
526 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000527}
528
529/*
530 * DES key schedule (56-bit, decryption)
531 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000533{
534 int i;
535
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200536 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000537
538 for( i = 0; i < 16; i += 2 )
539 {
540 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
541 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
542 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000543
544 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000545}
546
Paul Bakker5c2364c2012-10-01 14:41:15 +0000547static void des3_set2key( uint32_t esk[96],
548 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000550{
551 int i;
552
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200553 mbedtls_des_setkey( esk, key );
554 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
556 for( i = 0; i < 32; i += 2 )
557 {
558 dsk[i ] = esk[30 - i];
559 dsk[i + 1] = esk[31 - i];
560
561 esk[i + 32] = dsk[62 - i];
562 esk[i + 33] = dsk[63 - i];
563
564 esk[i + 64] = esk[i ];
565 esk[i + 65] = esk[i + 1];
566
567 dsk[i + 64] = dsk[i ];
568 dsk[i + 65] = dsk[i + 1];
569 }
570}
571
572/*
573 * Triple-DES key schedule (112-bit, encryption)
574 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
576 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000577{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000578 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
580 des3_set2key( ctx->sk, sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000582
583 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000584}
585
586/*
587 * Triple-DES key schedule (112-bit, decryption)
588 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
590 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000591{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000592 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
594 des3_set2key( sk, ctx->sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000596
597 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000598}
599
Paul Bakker5c2364c2012-10-01 14:41:15 +0000600static void des3_set3key( uint32_t esk[96],
601 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000602 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000603{
604 int i;
605
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200606 mbedtls_des_setkey( esk, key );
607 mbedtls_des_setkey( dsk + 32, key + 8 );
608 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
610 for( i = 0; i < 32; i += 2 )
611 {
612 dsk[i ] = esk[94 - i];
613 dsk[i + 1] = esk[95 - i];
614
615 esk[i + 32] = dsk[62 - i];
616 esk[i + 33] = dsk[63 - i];
617
618 dsk[i + 64] = esk[30 - i];
619 dsk[i + 65] = esk[31 - i];
620 }
621}
622
623/*
624 * Triple-DES key schedule (168-bit, encryption)
625 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
627 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000628{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000629 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
631 des3_set3key( ctx->sk, sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000633
634 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000635}
636
637/*
638 * Triple-DES key schedule (168-bit, decryption)
639 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
641 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000642{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000643 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
645 des3_set3key( sk, ctx->sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200646 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000647
648 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000649}
650
651/*
652 * DES-ECB block encryption/decryption
653 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200654#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000656 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000657 unsigned char output[8] )
658{
659 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000660 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
662 SK = ctx->sk;
663
Paul Bakker5c2364c2012-10-01 14:41:15 +0000664 GET_UINT32_BE( X, input, 0 );
665 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
667 DES_IP( X, Y );
668
669 for( i = 0; i < 8; i++ )
670 {
671 DES_ROUND( Y, X );
672 DES_ROUND( X, Y );
673 }
674
675 DES_FP( Y, X );
676
Paul Bakker5c2364c2012-10-01 14:41:15 +0000677 PUT_UINT32_BE( Y, output, 0 );
678 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000679
680 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000681}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200682#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000683
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000685/*
686 * DES-CBC buffer encryption/decryption
687 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200688int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000689 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000690 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000691 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000692 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000693 unsigned char *output )
694{
695 int i;
696 unsigned char temp[8];
697
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000698 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200699 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000700
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200701 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000702 {
703 while( length > 0 )
704 {
705 for( i = 0; i < 8; i++ )
706 output[i] = (unsigned char)( input[i] ^ iv[i] );
707
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200708 mbedtls_des_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000709 memcpy( iv, output, 8 );
710
711 input += 8;
712 output += 8;
713 length -= 8;
714 }
715 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000717 {
718 while( length > 0 )
719 {
720 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200721 mbedtls_des_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000722
723 for( i = 0; i < 8; i++ )
724 output[i] = (unsigned char)( output[i] ^ iv[i] );
725
726 memcpy( iv, temp, 8 );
727
728 input += 8;
729 output += 8;
730 length -= 8;
731 }
732 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000733
734 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000735}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200736#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000737
738/*
739 * 3DES-ECB block encryption/decryption
740 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200741#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200742int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000743 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000744 unsigned char output[8] )
745{
746 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000747 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
749 SK = ctx->sk;
750
Paul Bakker5c2364c2012-10-01 14:41:15 +0000751 GET_UINT32_BE( X, input, 0 );
752 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
754 DES_IP( X, Y );
755
756 for( i = 0; i < 8; i++ )
757 {
758 DES_ROUND( Y, X );
759 DES_ROUND( X, Y );
760 }
761
762 for( i = 0; i < 8; i++ )
763 {
764 DES_ROUND( X, Y );
765 DES_ROUND( Y, X );
766 }
767
768 for( i = 0; i < 8; i++ )
769 {
770 DES_ROUND( Y, X );
771 DES_ROUND( X, Y );
772 }
773
774 DES_FP( Y, X );
775
Paul Bakker5c2364c2012-10-01 14:41:15 +0000776 PUT_UINT32_BE( Y, output, 0 );
777 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000778
779 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000780}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200781#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000782
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000784/*
785 * 3DES-CBC buffer encryption/decryption
786 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200787int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000788 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000789 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000790 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000791 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000792 unsigned char *output )
793{
794 int i;
795 unsigned char temp[8];
796
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000797 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000799
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200800 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000801 {
802 while( length > 0 )
803 {
804 for( i = 0; i < 8; i++ )
805 output[i] = (unsigned char)( input[i] ^ iv[i] );
806
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807 mbedtls_des3_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000808 memcpy( iv, output, 8 );
809
810 input += 8;
811 output += 8;
812 length -= 8;
813 }
814 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000816 {
817 while( length > 0 )
818 {
819 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820 mbedtls_des3_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000821
822 for( i = 0; i < 8; i++ )
823 output[i] = (unsigned char)( output[i] ^ iv[i] );
824
825 memcpy( iv, temp, 8 );
826
827 input += 8;
828 output += 8;
829 length -= 8;
830 }
831 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000832
833 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000834}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200835#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000836
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200838
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000840/*
841 * DES and 3DES test vectors from:
842 *
843 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
844 */
845static const unsigned char des3_test_keys[24] =
846{
847 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
848 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
849 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
850};
851
Paul Bakker5121ce52009-01-03 21:22:43 +0000852static const unsigned char des3_test_buf[8] =
853{
854 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
855};
856
857static const unsigned char des3_test_ecb_dec[3][8] =
858{
859 { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
860 { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
861 { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
862};
863
864static const unsigned char des3_test_ecb_enc[3][8] =
865{
866 { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
867 { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
868 { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
869};
870
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100872static const unsigned char des3_test_iv[8] =
873{
874 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
875};
876
Paul Bakker5121ce52009-01-03 21:22:43 +0000877static const unsigned char des3_test_cbc_dec[3][8] =
878{
879 { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
880 { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
881 { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
882};
883
884static const unsigned char des3_test_cbc_enc[3][8] =
885{
886 { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
887 { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
888 { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
889};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000891
892/*
893 * Checkup routine
894 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000896{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200897 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200898 mbedtls_des_context ctx;
899 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000900 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000902 unsigned char prv[8];
903 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200904#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000905
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906 mbedtls_des_init( &ctx );
907 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000908 /*
909 * ECB mode
910 */
911 for( i = 0; i < 6; i++ )
912 {
913 u = i >> 1;
914 v = i & 1;
915
916 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200917 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100918 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000920
921 memcpy( buf, des3_test_buf, 8 );
922
923 switch( i )
924 {
925 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000927 break;
928
929 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000931 break;
932
933 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000935 break;
936
937 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000939 break;
940
941 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200942 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000943 break;
944
945 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000947 break;
948
949 default:
950 return( 1 );
951 }
952
953 for( j = 0; j < 10000; j++ )
954 {
955 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956 mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000957 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 }
960
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000962 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000964 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
965 {
966 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200967 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000968
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200969 ret = 1;
970 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000971 }
972
973 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000975 }
976
977 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200978 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000979
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200980#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000981 /*
982 * CBC mode
983 */
984 for( i = 0; i < 6; i++ )
985 {
986 u = i >> 1;
987 v = i & 1;
988
989 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200990 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100991 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200992 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000993
994 memcpy( iv, des3_test_iv, 8 );
995 memcpy( prv, des3_test_iv, 8 );
996 memcpy( buf, des3_test_buf, 8 );
997
998 switch( i )
999 {
1000 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001001 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001002 break;
1003
1004 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001005 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001006 break;
1007
1008 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001009 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001010 break;
1011
1012 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001013 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001014 break;
1015
1016 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001018 break;
1019
1020 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 break;
1023
1024 default:
1025 return( 1 );
1026 }
1027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001029 {
1030 for( j = 0; j < 10000; j++ )
1031 {
1032 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001034 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001036 }
1037 }
1038 else
1039 {
1040 for( j = 0; j < 10000; j++ )
1041 {
1042 unsigned char tmp[8];
1043
1044 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001045 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001046 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001048
1049 memcpy( tmp, prv, 8 );
1050 memcpy( prv, buf, 8 );
1051 memcpy( buf, tmp, 8 );
1052 }
1053
1054 memcpy( buf, prv, 8 );
1055 }
1056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001058 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001059 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001060 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1061 {
1062 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001063 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001064
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001065 ret = 1;
1066 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001067 }
1068
1069 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001070 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001071 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001072#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001073
1074 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001075 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001076
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001077exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078 mbedtls_des_free( &ctx );
1079 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001080
1081 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001082}
1083
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001084#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001085
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086#endif /* MBEDTLS_DES_C */