blob: 863a80c48bdd3462e709c29c589f03cd90842005 [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
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
22 * DES, on which TDES is based, was originally designed by Horst Feistel
23 * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
24 *
25 * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
26 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/des.h"
Andres Amaya Garciae32df082017-10-25 09:37:04 +010037#include "mbedtls/utils.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_SELF_TEST)
42#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044#else
Rich Evans00ab4702015-02-06 13:43:58 +000045#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#define mbedtls_printf printf
47#endif /* MBEDTLS_PLATFORM_C */
48#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020051
Paul Bakker5121ce52009-01-03 21:22:43 +000052/*
53 * 32-bit integer manipulation macros (big endian)
54 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000055#ifndef GET_UINT32_BE
56#define GET_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000057{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000058 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
59 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
60 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
61 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000062}
63#endif
64
Paul Bakker5c2364c2012-10-01 14:41:15 +000065#ifndef PUT_UINT32_BE
66#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000067{ \
68 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
69 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
70 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
71 (b)[(i) + 3] = (unsigned char) ( (n) ); \
72}
73#endif
74
75/*
76 * Expanded DES S-boxes
77 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000078static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000079{
80 0x01010400, 0x00000000, 0x00010000, 0x01010404,
81 0x01010004, 0x00010404, 0x00000004, 0x00010000,
82 0x00000400, 0x01010400, 0x01010404, 0x00000400,
83 0x01000404, 0x01010004, 0x01000000, 0x00000004,
84 0x00000404, 0x01000400, 0x01000400, 0x00010400,
85 0x00010400, 0x01010000, 0x01010000, 0x01000404,
86 0x00010004, 0x01000004, 0x01000004, 0x00010004,
87 0x00000000, 0x00000404, 0x00010404, 0x01000000,
88 0x00010000, 0x01010404, 0x00000004, 0x01010000,
89 0x01010400, 0x01000000, 0x01000000, 0x00000400,
90 0x01010004, 0x00010000, 0x00010400, 0x01000004,
91 0x00000400, 0x00000004, 0x01000404, 0x00010404,
92 0x01010404, 0x00010004, 0x01010000, 0x01000404,
93 0x01000004, 0x00000404, 0x00010404, 0x01010400,
94 0x00000404, 0x01000400, 0x01000400, 0x00000000,
95 0x00010004, 0x00010400, 0x00000000, 0x01010004
96};
97
Paul Bakker5c2364c2012-10-01 14:41:15 +000098static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000099{
100 0x80108020, 0x80008000, 0x00008000, 0x00108020,
101 0x00100000, 0x00000020, 0x80100020, 0x80008020,
102 0x80000020, 0x80108020, 0x80108000, 0x80000000,
103 0x80008000, 0x00100000, 0x00000020, 0x80100020,
104 0x00108000, 0x00100020, 0x80008020, 0x00000000,
105 0x80000000, 0x00008000, 0x00108020, 0x80100000,
106 0x00100020, 0x80000020, 0x00000000, 0x00108000,
107 0x00008020, 0x80108000, 0x80100000, 0x00008020,
108 0x00000000, 0x00108020, 0x80100020, 0x00100000,
109 0x80008020, 0x80100000, 0x80108000, 0x00008000,
110 0x80100000, 0x80008000, 0x00000020, 0x80108020,
111 0x00108020, 0x00000020, 0x00008000, 0x80000000,
112 0x00008020, 0x80108000, 0x00100000, 0x80000020,
113 0x00100020, 0x80008020, 0x80000020, 0x00100020,
114 0x00108000, 0x00000000, 0x80008000, 0x00008020,
115 0x80000000, 0x80100020, 0x80108020, 0x00108000
116};
117
Paul Bakker5c2364c2012-10-01 14:41:15 +0000118static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000119{
120 0x00000208, 0x08020200, 0x00000000, 0x08020008,
121 0x08000200, 0x00000000, 0x00020208, 0x08000200,
122 0x00020008, 0x08000008, 0x08000008, 0x00020000,
123 0x08020208, 0x00020008, 0x08020000, 0x00000208,
124 0x08000000, 0x00000008, 0x08020200, 0x00000200,
125 0x00020200, 0x08020000, 0x08020008, 0x00020208,
126 0x08000208, 0x00020200, 0x00020000, 0x08000208,
127 0x00000008, 0x08020208, 0x00000200, 0x08000000,
128 0x08020200, 0x08000000, 0x00020008, 0x00000208,
129 0x00020000, 0x08020200, 0x08000200, 0x00000000,
130 0x00000200, 0x00020008, 0x08020208, 0x08000200,
131 0x08000008, 0x00000200, 0x00000000, 0x08020008,
132 0x08000208, 0x00020000, 0x08000000, 0x08020208,
133 0x00000008, 0x00020208, 0x00020200, 0x08000008,
134 0x08020000, 0x08000208, 0x00000208, 0x08020000,
135 0x00020208, 0x00000008, 0x08020008, 0x00020200
136};
137
Paul Bakker5c2364c2012-10-01 14:41:15 +0000138static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000139{
140 0x00802001, 0x00002081, 0x00002081, 0x00000080,
141 0x00802080, 0x00800081, 0x00800001, 0x00002001,
142 0x00000000, 0x00802000, 0x00802000, 0x00802081,
143 0x00000081, 0x00000000, 0x00800080, 0x00800001,
144 0x00000001, 0x00002000, 0x00800000, 0x00802001,
145 0x00000080, 0x00800000, 0x00002001, 0x00002080,
146 0x00800081, 0x00000001, 0x00002080, 0x00800080,
147 0x00002000, 0x00802080, 0x00802081, 0x00000081,
148 0x00800080, 0x00800001, 0x00802000, 0x00802081,
149 0x00000081, 0x00000000, 0x00000000, 0x00802000,
150 0x00002080, 0x00800080, 0x00800081, 0x00000001,
151 0x00802001, 0x00002081, 0x00002081, 0x00000080,
152 0x00802081, 0x00000081, 0x00000001, 0x00002000,
153 0x00800001, 0x00002001, 0x00802080, 0x00800081,
154 0x00002001, 0x00002080, 0x00800000, 0x00802001,
155 0x00000080, 0x00800000, 0x00002000, 0x00802080
156};
157
Paul Bakker5c2364c2012-10-01 14:41:15 +0000158static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000159{
160 0x00000100, 0x02080100, 0x02080000, 0x42000100,
161 0x00080000, 0x00000100, 0x40000000, 0x02080000,
162 0x40080100, 0x00080000, 0x02000100, 0x40080100,
163 0x42000100, 0x42080000, 0x00080100, 0x40000000,
164 0x02000000, 0x40080000, 0x40080000, 0x00000000,
165 0x40000100, 0x42080100, 0x42080100, 0x02000100,
166 0x42080000, 0x40000100, 0x00000000, 0x42000000,
167 0x02080100, 0x02000000, 0x42000000, 0x00080100,
168 0x00080000, 0x42000100, 0x00000100, 0x02000000,
169 0x40000000, 0x02080000, 0x42000100, 0x40080100,
170 0x02000100, 0x40000000, 0x42080000, 0x02080100,
171 0x40080100, 0x00000100, 0x02000000, 0x42080000,
172 0x42080100, 0x00080100, 0x42000000, 0x42080100,
173 0x02080000, 0x00000000, 0x40080000, 0x42000000,
174 0x00080100, 0x02000100, 0x40000100, 0x00080000,
175 0x00000000, 0x40080000, 0x02080100, 0x40000100
176};
177
Paul Bakker5c2364c2012-10-01 14:41:15 +0000178static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000179{
180 0x20000010, 0x20400000, 0x00004000, 0x20404010,
181 0x20400000, 0x00000010, 0x20404010, 0x00400000,
182 0x20004000, 0x00404010, 0x00400000, 0x20000010,
183 0x00400010, 0x20004000, 0x20000000, 0x00004010,
184 0x00000000, 0x00400010, 0x20004010, 0x00004000,
185 0x00404000, 0x20004010, 0x00000010, 0x20400010,
186 0x20400010, 0x00000000, 0x00404010, 0x20404000,
187 0x00004010, 0x00404000, 0x20404000, 0x20000000,
188 0x20004000, 0x00000010, 0x20400010, 0x00404000,
189 0x20404010, 0x00400000, 0x00004010, 0x20000010,
190 0x00400000, 0x20004000, 0x20000000, 0x00004010,
191 0x20000010, 0x20404010, 0x00404000, 0x20400000,
192 0x00404010, 0x20404000, 0x00000000, 0x20400010,
193 0x00000010, 0x00004000, 0x20400000, 0x00404010,
194 0x00004000, 0x00400010, 0x20004010, 0x00000000,
195 0x20404000, 0x20000000, 0x00400010, 0x20004010
196};
197
Paul Bakker5c2364c2012-10-01 14:41:15 +0000198static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000199{
200 0x00200000, 0x04200002, 0x04000802, 0x00000000,
201 0x00000800, 0x04000802, 0x00200802, 0x04200800,
202 0x04200802, 0x00200000, 0x00000000, 0x04000002,
203 0x00000002, 0x04000000, 0x04200002, 0x00000802,
204 0x04000800, 0x00200802, 0x00200002, 0x04000800,
205 0x04000002, 0x04200000, 0x04200800, 0x00200002,
206 0x04200000, 0x00000800, 0x00000802, 0x04200802,
207 0x00200800, 0x00000002, 0x04000000, 0x00200800,
208 0x04000000, 0x00200800, 0x00200000, 0x04000802,
209 0x04000802, 0x04200002, 0x04200002, 0x00000002,
210 0x00200002, 0x04000000, 0x04000800, 0x00200000,
211 0x04200800, 0x00000802, 0x00200802, 0x04200800,
212 0x00000802, 0x04000002, 0x04200802, 0x04200000,
213 0x00200800, 0x00000000, 0x00000002, 0x04200802,
214 0x00000000, 0x00200802, 0x04200000, 0x00000800,
215 0x04000002, 0x04000800, 0x00000800, 0x00200002
216};
217
Paul Bakker5c2364c2012-10-01 14:41:15 +0000218static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000219{
220 0x10001040, 0x00001000, 0x00040000, 0x10041040,
221 0x10000000, 0x10001040, 0x00000040, 0x10000000,
222 0x00040040, 0x10040000, 0x10041040, 0x00041000,
223 0x10041000, 0x00041040, 0x00001000, 0x00000040,
224 0x10040000, 0x10000040, 0x10001000, 0x00001040,
225 0x00041000, 0x00040040, 0x10040040, 0x10041000,
226 0x00001040, 0x00000000, 0x00000000, 0x10040040,
227 0x10000040, 0x10001000, 0x00041040, 0x00040000,
228 0x00041040, 0x00040000, 0x10041000, 0x00001000,
229 0x00000040, 0x10040040, 0x00001000, 0x00041040,
230 0x10001000, 0x00000040, 0x10000040, 0x10040000,
231 0x10040040, 0x10000000, 0x00040000, 0x10001040,
232 0x00000000, 0x10041040, 0x00040040, 0x10000040,
233 0x10040000, 0x10001000, 0x10001040, 0x00000000,
234 0x10041040, 0x00041000, 0x00041000, 0x00001040,
235 0x00001040, 0x00040040, 0x10000000, 0x10041000
236};
237
238/*
239 * PC1: left and right halves bit-swap
240 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000241static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000242{
243 0x00000000, 0x00000001, 0x00000100, 0x00000101,
244 0x00010000, 0x00010001, 0x00010100, 0x00010101,
245 0x01000000, 0x01000001, 0x01000100, 0x01000101,
246 0x01010000, 0x01010001, 0x01010100, 0x01010101
247};
248
Paul Bakker5c2364c2012-10-01 14:41:15 +0000249static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000250{
251 0x00000000, 0x01000000, 0x00010000, 0x01010000,
252 0x00000100, 0x01000100, 0x00010100, 0x01010100,
253 0x00000001, 0x01000001, 0x00010001, 0x01010001,
254 0x00000101, 0x01000101, 0x00010101, 0x01010101,
255};
256
257/*
258 * Initial Permutation macro
259 */
260#define DES_IP(X,Y) \
261{ \
262 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
263 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
264 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
265 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
266 Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
267 T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
268 X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
269}
270
271/*
272 * Final Permutation macro
273 */
274#define DES_FP(X,Y) \
275{ \
276 X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
277 T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
278 Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
279 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
280 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
281 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
282 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
283}
284
285/*
286 * DES round macro
287 */
288#define DES_ROUND(X,Y) \
289{ \
290 T = *SK++ ^ X; \
291 Y ^= SB8[ (T ) & 0x3F ] ^ \
292 SB6[ (T >> 8) & 0x3F ] ^ \
293 SB4[ (T >> 16) & 0x3F ] ^ \
294 SB2[ (T >> 24) & 0x3F ]; \
295 \
296 T = *SK++ ^ ((X << 28) | (X >> 4)); \
297 Y ^= SB7[ (T ) & 0x3F ] ^ \
298 SB5[ (T >> 8) & 0x3F ] ^ \
299 SB3[ (T >> 16) & 0x3F ] ^ \
300 SB1[ (T >> 24) & 0x3F ]; \
301}
302
Paul Bakker5c2364c2012-10-01 14:41:15 +0000303#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; }
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200306{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200307 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200308}
309
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200310void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200311{
312 if( ctx == NULL )
313 return;
314
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200315 mbedtls_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200316}
317
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200319{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200321}
322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200324{
325 if( ctx == NULL )
326 return;
327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328 mbedtls_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200329}
330
Paul Bakker1f87fb62011-01-15 17:32:24 +0000331static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
332 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
333 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
334 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
335 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
336 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
337 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
338 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
339 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
340 254 };
341
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000343{
344 int i;
345
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000347 key[i] = odd_parity_table[key[i] / 2];
348}
349
350/*
351 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
352 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000354{
355 int i;
356
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200358 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000359 return( 1 );
360
361 return( 0 );
362}
363
364/*
365 * Table of weak and semi-weak keys
366 *
367 * Source: http://en.wikipedia.org/wiki/Weak_key
368 *
369 * Weak:
370 * Alternating ones + zeros (0x0101010101010101)
371 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
372 * '0xE0E0E0E0F1F1F1F1'
373 * '0x1F1F1F1F0E0E0E0E'
374 *
375 * Semi-weak:
376 * 0x011F011F010E010E and 0x1F011F010E010E01
377 * 0x01E001E001F101F1 and 0xE001E001F101F101
378 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
379 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
380 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
381 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
382 *
383 */
384
385#define WEAK_KEY_COUNT 16
386
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000388{
389 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
390 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
391 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
392 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
393
394 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
395 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
396 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
397 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
398 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
399 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
400 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
401 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
402 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
403 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
404 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
405 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
406};
407
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000409{
410 int i;
411
412 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000414 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000415
Paul Bakker73206952011-07-06 14:37:33 +0000416 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000417}
418
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200419#if !defined(MBEDTLS_DES_SETKEY_ALT)
420void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000421{
422 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000423 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
Paul Bakker5c2364c2012-10-01 14:41:15 +0000425 GET_UINT32_BE( X, key, 0 );
426 GET_UINT32_BE( Y, key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
428 /*
429 * Permuted Choice 1
430 */
431 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
432 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
433
434 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
435 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
436 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
437 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
438
439 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
440 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
441 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
442 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
443
444 X &= 0x0FFFFFFF;
445 Y &= 0x0FFFFFFF;
446
447 /*
448 * calculate subkeys
449 */
450 for( i = 0; i < 16; i++ )
451 {
452 if( i < 2 || i == 8 || i == 15 )
453 {
454 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
455 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
456 }
457 else
458 {
459 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
460 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
461 }
462
463 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
464 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
465 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
466 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
467 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
468 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
469 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
470 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
471 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
472 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
473 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
474
475 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
476 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
477 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
478 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
479 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
480 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
481 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
482 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
483 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
484 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
485 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
486 }
487}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200488#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
490/*
491 * DES key schedule (56-bit, encryption)
492 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000494{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200495 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000496
497 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000498}
499
500/*
501 * DES key schedule (56-bit, decryption)
502 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000504{
505 int i;
506
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200507 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
509 for( i = 0; i < 16; i += 2 )
510 {
511 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
512 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
513 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000514
515 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000516}
517
Paul Bakker5c2364c2012-10-01 14:41:15 +0000518static void des3_set2key( uint32_t esk[96],
519 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200520 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000521{
522 int i;
523
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200524 mbedtls_des_setkey( esk, key );
525 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
527 for( i = 0; i < 32; i += 2 )
528 {
529 dsk[i ] = esk[30 - i];
530 dsk[i + 1] = esk[31 - i];
531
532 esk[i + 32] = dsk[62 - i];
533 esk[i + 33] = dsk[63 - i];
534
535 esk[i + 64] = esk[i ];
536 esk[i + 65] = esk[i + 1];
537
538 dsk[i + 64] = dsk[i ];
539 dsk[i + 65] = dsk[i + 1];
540 }
541}
542
543/*
544 * Triple-DES key schedule (112-bit, encryption)
545 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200546int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
547 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000548{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000549 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
551 des3_set2key( ctx->sk, sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000553
554 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000555}
556
557/*
558 * Triple-DES key schedule (112-bit, decryption)
559 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
561 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000562{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000563 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000564
565 des3_set2key( sk, ctx->sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000567
568 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000569}
570
Paul Bakker5c2364c2012-10-01 14:41:15 +0000571static void des3_set3key( uint32_t esk[96],
572 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000573 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000574{
575 int i;
576
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200577 mbedtls_des_setkey( esk, key );
578 mbedtls_des_setkey( dsk + 32, key + 8 );
579 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
581 for( i = 0; i < 32; i += 2 )
582 {
583 dsk[i ] = esk[94 - i];
584 dsk[i + 1] = esk[95 - i];
585
586 esk[i + 32] = dsk[62 - i];
587 esk[i + 33] = dsk[63 - i];
588
589 dsk[i + 64] = esk[30 - i];
590 dsk[i + 65] = esk[31 - i];
591 }
592}
593
594/*
595 * Triple-DES key schedule (168-bit, encryption)
596 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
598 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000599{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000600 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
602 des3_set3key( ctx->sk, sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200603 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000604
605 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000606}
607
608/*
609 * Triple-DES key schedule (168-bit, decryption)
610 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
612 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000613{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000614 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
616 des3_set3key( sk, ctx->sk, key );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 mbedtls_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000618
619 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000620}
621
622/*
623 * DES-ECB block encryption/decryption
624 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200625#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000627 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 unsigned char output[8] )
629{
630 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000631 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
633 SK = ctx->sk;
634
Paul Bakker5c2364c2012-10-01 14:41:15 +0000635 GET_UINT32_BE( X, input, 0 );
636 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
638 DES_IP( X, Y );
639
640 for( i = 0; i < 8; i++ )
641 {
642 DES_ROUND( Y, X );
643 DES_ROUND( X, Y );
644 }
645
646 DES_FP( Y, X );
647
Paul Bakker5c2364c2012-10-01 14:41:15 +0000648 PUT_UINT32_BE( Y, output, 0 );
649 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000650
651 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000652}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200653#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000656/*
657 * DES-CBC buffer encryption/decryption
658 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200659int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000660 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000661 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000662 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000663 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 unsigned char *output )
665{
666 int i;
667 unsigned char temp[8];
668
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000669 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200670 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000671
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000673 {
674 while( length > 0 )
675 {
676 for( i = 0; i < 8; i++ )
677 output[i] = (unsigned char)( input[i] ^ iv[i] );
678
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679 mbedtls_des_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000680 memcpy( iv, output, 8 );
681
682 input += 8;
683 output += 8;
684 length -= 8;
685 }
686 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200687 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000688 {
689 while( length > 0 )
690 {
691 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692 mbedtls_des_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000693
694 for( i = 0; i < 8; i++ )
695 output[i] = (unsigned char)( output[i] ^ iv[i] );
696
697 memcpy( iv, temp, 8 );
698
699 input += 8;
700 output += 8;
701 length -= 8;
702 }
703 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000704
705 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000706}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200707#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000708
709/*
710 * 3DES-ECB block encryption/decryption
711 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200712#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200713int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000714 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000715 unsigned char output[8] )
716{
717 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000718 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000719
720 SK = ctx->sk;
721
Paul Bakker5c2364c2012-10-01 14:41:15 +0000722 GET_UINT32_BE( X, input, 0 );
723 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000724
725 DES_IP( X, Y );
726
727 for( i = 0; i < 8; i++ )
728 {
729 DES_ROUND( Y, X );
730 DES_ROUND( X, Y );
731 }
732
733 for( i = 0; i < 8; i++ )
734 {
735 DES_ROUND( X, Y );
736 DES_ROUND( Y, X );
737 }
738
739 for( i = 0; i < 8; i++ )
740 {
741 DES_ROUND( Y, X );
742 DES_ROUND( X, Y );
743 }
744
745 DES_FP( Y, X );
746
Paul Bakker5c2364c2012-10-01 14:41:15 +0000747 PUT_UINT32_BE( Y, output, 0 );
748 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000749
750 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000751}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200752#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200754#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000755/*
756 * 3DES-CBC buffer encryption/decryption
757 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200758int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000759 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000760 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000761 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000762 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000763 unsigned char *output )
764{
765 int i;
766 unsigned char temp[8];
767
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000768 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200769 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000770
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200771 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000772 {
773 while( length > 0 )
774 {
775 for( i = 0; i < 8; i++ )
776 output[i] = (unsigned char)( input[i] ^ iv[i] );
777
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200778 mbedtls_des3_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000779 memcpy( iv, output, 8 );
780
781 input += 8;
782 output += 8;
783 length -= 8;
784 }
785 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000787 {
788 while( length > 0 )
789 {
790 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200791 mbedtls_des3_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000792
793 for( i = 0; i < 8; i++ )
794 output[i] = (unsigned char)( output[i] ^ iv[i] );
795
796 memcpy( iv, temp, 8 );
797
798 input += 8;
799 output += 8;
800 length -= 8;
801 }
802 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000803
804 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000805}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200806#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000807
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200809
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200810#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000811/*
812 * DES and 3DES test vectors from:
813 *
814 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
815 */
816static const unsigned char des3_test_keys[24] =
817{
818 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
819 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
820 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
821};
822
Paul Bakker5121ce52009-01-03 21:22:43 +0000823static const unsigned char des3_test_buf[8] =
824{
825 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
826};
827
828static const unsigned char des3_test_ecb_dec[3][8] =
829{
830 { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
831 { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
832 { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
833};
834
835static const unsigned char des3_test_ecb_enc[3][8] =
836{
837 { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
838 { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
839 { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
840};
841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100843static const unsigned char des3_test_iv[8] =
844{
845 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
846};
847
Paul Bakker5121ce52009-01-03 21:22:43 +0000848static const unsigned char des3_test_cbc_dec[3][8] =
849{
850 { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
851 { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
852 { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
853};
854
855static const unsigned char des3_test_cbc_enc[3][8] =
856{
857 { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
858 { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
859 { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
860};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000862
863/*
864 * Checkup routine
865 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000867{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200868 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869 mbedtls_des_context ctx;
870 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000871 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000873 unsigned char prv[8];
874 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200875#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000876
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877 mbedtls_des_init( &ctx );
878 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000879 /*
880 * ECB mode
881 */
882 for( i = 0; i < 6; i++ )
883 {
884 u = i >> 1;
885 v = i & 1;
886
887 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100889 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000891
892 memcpy( buf, des3_test_buf, 8 );
893
894 switch( i )
895 {
896 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000898 break;
899
900 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000902 break;
903
904 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000906 break;
907
908 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000910 break;
911
912 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000914 break;
915
916 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200917 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000918 break;
919
920 default:
921 return( 1 );
922 }
923
924 for( j = 0; j < 10000; j++ )
925 {
926 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000928 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929 mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000930 }
931
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000933 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000935 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
936 {
937 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000939
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200940 ret = 1;
941 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000942 }
943
944 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200945 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946 }
947
948 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000950
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200951#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000952 /*
953 * CBC mode
954 */
955 for( i = 0; i < 6; i++ )
956 {
957 u = i >> 1;
958 v = i & 1;
959
960 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100962 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000964
965 memcpy( iv, des3_test_iv, 8 );
966 memcpy( prv, des3_test_iv, 8 );
967 memcpy( buf, des3_test_buf, 8 );
968
969 switch( i )
970 {
971 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000973 break;
974
975 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000977 break;
978
979 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200980 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000981 break;
982
983 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200984 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000985 break;
986
987 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200988 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000989 break;
990
991 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200992 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000993 break;
994
995 default:
996 return( 1 );
997 }
998
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001000 {
1001 for( j = 0; j < 10000; j++ )
1002 {
1003 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001004 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001007 }
1008 }
1009 else
1010 {
1011 for( j = 0; j < 10000; j++ )
1012 {
1013 unsigned char tmp[8];
1014
1015 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001016 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001017 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001018 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001019
1020 memcpy( tmp, prv, 8 );
1021 memcpy( prv, buf, 8 );
1022 memcpy( buf, tmp, 8 );
1023 }
1024
1025 memcpy( buf, prv, 8 );
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 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001031 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1032 {
1033 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001034 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001035
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001036 ret = 1;
1037 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001038 }
1039
1040 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001041 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001042 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001043#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001044
1045 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001047
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001048exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049 mbedtls_des_free( &ctx );
1050 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001051
1052 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001053}
1054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057#endif /* MBEDTLS_DES_C */