blob: eddf55e78957bc01b5270976c6823f046d727398 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-46-3 compliant Triple-DES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
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 Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * DES, on which TDES is based, was originally designed by Horst Feistel
21 * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
22 *
23 * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/des.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050031#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Rich Evans00ab4702015-02-06 13:43:58 +000033#include <string.h>
34
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#if defined(MBEDTLS_SELF_TEST)
36#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010038#else
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#define mbedtls_printf printf
41#endif /* MBEDTLS_PLATFORM_C */
42#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010043
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020045
Paul Bakker5121ce52009-01-03 21:22:43 +000046/*
47 * 32-bit integer manipulation macros (big endian)
48 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000049#ifndef GET_UINT32_BE
50#define GET_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000051{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000052 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
53 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
54 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
55 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000056}
57#endif
58
Paul Bakker5c2364c2012-10-01 14:41:15 +000059#ifndef PUT_UINT32_BE
60#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000061{ \
62 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
63 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
64 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
65 (b)[(i) + 3] = (unsigned char) ( (n) ); \
66}
67#endif
68
69/*
70 * Expanded DES S-boxes
71 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000072static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000073{
74 0x01010400, 0x00000000, 0x00010000, 0x01010404,
75 0x01010004, 0x00010404, 0x00000004, 0x00010000,
76 0x00000400, 0x01010400, 0x01010404, 0x00000400,
77 0x01000404, 0x01010004, 0x01000000, 0x00000004,
78 0x00000404, 0x01000400, 0x01000400, 0x00010400,
79 0x00010400, 0x01010000, 0x01010000, 0x01000404,
80 0x00010004, 0x01000004, 0x01000004, 0x00010004,
81 0x00000000, 0x00000404, 0x00010404, 0x01000000,
82 0x00010000, 0x01010404, 0x00000004, 0x01010000,
83 0x01010400, 0x01000000, 0x01000000, 0x00000400,
84 0x01010004, 0x00010000, 0x00010400, 0x01000004,
85 0x00000400, 0x00000004, 0x01000404, 0x00010404,
86 0x01010404, 0x00010004, 0x01010000, 0x01000404,
87 0x01000004, 0x00000404, 0x00010404, 0x01010400,
88 0x00000404, 0x01000400, 0x01000400, 0x00000000,
89 0x00010004, 0x00010400, 0x00000000, 0x01010004
90};
91
Paul Bakker5c2364c2012-10-01 14:41:15 +000092static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000093{
94 0x80108020, 0x80008000, 0x00008000, 0x00108020,
95 0x00100000, 0x00000020, 0x80100020, 0x80008020,
96 0x80000020, 0x80108020, 0x80108000, 0x80000000,
97 0x80008000, 0x00100000, 0x00000020, 0x80100020,
98 0x00108000, 0x00100020, 0x80008020, 0x00000000,
99 0x80000000, 0x00008000, 0x00108020, 0x80100000,
100 0x00100020, 0x80000020, 0x00000000, 0x00108000,
101 0x00008020, 0x80108000, 0x80100000, 0x00008020,
102 0x00000000, 0x00108020, 0x80100020, 0x00100000,
103 0x80008020, 0x80100000, 0x80108000, 0x00008000,
104 0x80100000, 0x80008000, 0x00000020, 0x80108020,
105 0x00108020, 0x00000020, 0x00008000, 0x80000000,
106 0x00008020, 0x80108000, 0x00100000, 0x80000020,
107 0x00100020, 0x80008020, 0x80000020, 0x00100020,
108 0x00108000, 0x00000000, 0x80008000, 0x00008020,
109 0x80000000, 0x80100020, 0x80108020, 0x00108000
110};
111
Paul Bakker5c2364c2012-10-01 14:41:15 +0000112static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000113{
114 0x00000208, 0x08020200, 0x00000000, 0x08020008,
115 0x08000200, 0x00000000, 0x00020208, 0x08000200,
116 0x00020008, 0x08000008, 0x08000008, 0x00020000,
117 0x08020208, 0x00020008, 0x08020000, 0x00000208,
118 0x08000000, 0x00000008, 0x08020200, 0x00000200,
119 0x00020200, 0x08020000, 0x08020008, 0x00020208,
120 0x08000208, 0x00020200, 0x00020000, 0x08000208,
121 0x00000008, 0x08020208, 0x00000200, 0x08000000,
122 0x08020200, 0x08000000, 0x00020008, 0x00000208,
123 0x00020000, 0x08020200, 0x08000200, 0x00000000,
124 0x00000200, 0x00020008, 0x08020208, 0x08000200,
125 0x08000008, 0x00000200, 0x00000000, 0x08020008,
126 0x08000208, 0x00020000, 0x08000000, 0x08020208,
127 0x00000008, 0x00020208, 0x00020200, 0x08000008,
128 0x08020000, 0x08000208, 0x00000208, 0x08020000,
129 0x00020208, 0x00000008, 0x08020008, 0x00020200
130};
131
Paul Bakker5c2364c2012-10-01 14:41:15 +0000132static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000133{
134 0x00802001, 0x00002081, 0x00002081, 0x00000080,
135 0x00802080, 0x00800081, 0x00800001, 0x00002001,
136 0x00000000, 0x00802000, 0x00802000, 0x00802081,
137 0x00000081, 0x00000000, 0x00800080, 0x00800001,
138 0x00000001, 0x00002000, 0x00800000, 0x00802001,
139 0x00000080, 0x00800000, 0x00002001, 0x00002080,
140 0x00800081, 0x00000001, 0x00002080, 0x00800080,
141 0x00002000, 0x00802080, 0x00802081, 0x00000081,
142 0x00800080, 0x00800001, 0x00802000, 0x00802081,
143 0x00000081, 0x00000000, 0x00000000, 0x00802000,
144 0x00002080, 0x00800080, 0x00800081, 0x00000001,
145 0x00802001, 0x00002081, 0x00002081, 0x00000080,
146 0x00802081, 0x00000081, 0x00000001, 0x00002000,
147 0x00800001, 0x00002001, 0x00802080, 0x00800081,
148 0x00002001, 0x00002080, 0x00800000, 0x00802001,
149 0x00000080, 0x00800000, 0x00002000, 0x00802080
150};
151
Paul Bakker5c2364c2012-10-01 14:41:15 +0000152static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000153{
154 0x00000100, 0x02080100, 0x02080000, 0x42000100,
155 0x00080000, 0x00000100, 0x40000000, 0x02080000,
156 0x40080100, 0x00080000, 0x02000100, 0x40080100,
157 0x42000100, 0x42080000, 0x00080100, 0x40000000,
158 0x02000000, 0x40080000, 0x40080000, 0x00000000,
159 0x40000100, 0x42080100, 0x42080100, 0x02000100,
160 0x42080000, 0x40000100, 0x00000000, 0x42000000,
161 0x02080100, 0x02000000, 0x42000000, 0x00080100,
162 0x00080000, 0x42000100, 0x00000100, 0x02000000,
163 0x40000000, 0x02080000, 0x42000100, 0x40080100,
164 0x02000100, 0x40000000, 0x42080000, 0x02080100,
165 0x40080100, 0x00000100, 0x02000000, 0x42080000,
166 0x42080100, 0x00080100, 0x42000000, 0x42080100,
167 0x02080000, 0x00000000, 0x40080000, 0x42000000,
168 0x00080100, 0x02000100, 0x40000100, 0x00080000,
169 0x00000000, 0x40080000, 0x02080100, 0x40000100
170};
171
Paul Bakker5c2364c2012-10-01 14:41:15 +0000172static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000173{
174 0x20000010, 0x20400000, 0x00004000, 0x20404010,
175 0x20400000, 0x00000010, 0x20404010, 0x00400000,
176 0x20004000, 0x00404010, 0x00400000, 0x20000010,
177 0x00400010, 0x20004000, 0x20000000, 0x00004010,
178 0x00000000, 0x00400010, 0x20004010, 0x00004000,
179 0x00404000, 0x20004010, 0x00000010, 0x20400010,
180 0x20400010, 0x00000000, 0x00404010, 0x20404000,
181 0x00004010, 0x00404000, 0x20404000, 0x20000000,
182 0x20004000, 0x00000010, 0x20400010, 0x00404000,
183 0x20404010, 0x00400000, 0x00004010, 0x20000010,
184 0x00400000, 0x20004000, 0x20000000, 0x00004010,
185 0x20000010, 0x20404010, 0x00404000, 0x20400000,
186 0x00404010, 0x20404000, 0x00000000, 0x20400010,
187 0x00000010, 0x00004000, 0x20400000, 0x00404010,
188 0x00004000, 0x00400010, 0x20004010, 0x00000000,
189 0x20404000, 0x20000000, 0x00400010, 0x20004010
190};
191
Paul Bakker5c2364c2012-10-01 14:41:15 +0000192static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000193{
194 0x00200000, 0x04200002, 0x04000802, 0x00000000,
195 0x00000800, 0x04000802, 0x00200802, 0x04200800,
196 0x04200802, 0x00200000, 0x00000000, 0x04000002,
197 0x00000002, 0x04000000, 0x04200002, 0x00000802,
198 0x04000800, 0x00200802, 0x00200002, 0x04000800,
199 0x04000002, 0x04200000, 0x04200800, 0x00200002,
200 0x04200000, 0x00000800, 0x00000802, 0x04200802,
201 0x00200800, 0x00000002, 0x04000000, 0x00200800,
202 0x04000000, 0x00200800, 0x00200000, 0x04000802,
203 0x04000802, 0x04200002, 0x04200002, 0x00000002,
204 0x00200002, 0x04000000, 0x04000800, 0x00200000,
205 0x04200800, 0x00000802, 0x00200802, 0x04200800,
206 0x00000802, 0x04000002, 0x04200802, 0x04200000,
207 0x00200800, 0x00000000, 0x00000002, 0x04200802,
208 0x00000000, 0x00200802, 0x04200000, 0x00000800,
209 0x04000002, 0x04000800, 0x00000800, 0x00200002
210};
211
Paul Bakker5c2364c2012-10-01 14:41:15 +0000212static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000213{
214 0x10001040, 0x00001000, 0x00040000, 0x10041040,
215 0x10000000, 0x10001040, 0x00000040, 0x10000000,
216 0x00040040, 0x10040000, 0x10041040, 0x00041000,
217 0x10041000, 0x00041040, 0x00001000, 0x00000040,
218 0x10040000, 0x10000040, 0x10001000, 0x00001040,
219 0x00041000, 0x00040040, 0x10040040, 0x10041000,
220 0x00001040, 0x00000000, 0x00000000, 0x10040040,
221 0x10000040, 0x10001000, 0x00041040, 0x00040000,
222 0x00041040, 0x00040000, 0x10041000, 0x00001000,
223 0x00000040, 0x10040040, 0x00001000, 0x00041040,
224 0x10001000, 0x00000040, 0x10000040, 0x10040000,
225 0x10040040, 0x10000000, 0x00040000, 0x10001040,
226 0x00000000, 0x10041040, 0x00040040, 0x10000040,
227 0x10040000, 0x10001000, 0x10001040, 0x00000000,
228 0x10041040, 0x00041000, 0x00041000, 0x00001040,
229 0x00001040, 0x00040040, 0x10000000, 0x10041000
230};
231
232/*
233 * PC1: left and right halves bit-swap
234 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000235static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000236{
237 0x00000000, 0x00000001, 0x00000100, 0x00000101,
238 0x00010000, 0x00010001, 0x00010100, 0x00010101,
239 0x01000000, 0x01000001, 0x01000100, 0x01000101,
240 0x01010000, 0x01010001, 0x01010100, 0x01010101
241};
242
Paul Bakker5c2364c2012-10-01 14:41:15 +0000243static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000244{
245 0x00000000, 0x01000000, 0x00010000, 0x01010000,
246 0x00000100, 0x01000100, 0x00010100, 0x01010100,
247 0x00000001, 0x01000001, 0x00010001, 0x01010001,
248 0x00000101, 0x01000101, 0x00010101, 0x01010101,
249};
250
251/*
252 * Initial Permutation macro
253 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100254#define DES_IP(X,Y) \
255 do \
256 { \
257 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
258 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
259 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
260 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
261 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
262 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
263 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
264 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000265
266/*
267 * Final Permutation macro
268 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100269#define DES_FP(X,Y) \
270 do \
271 { \
272 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
273 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
274 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
275 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
276 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
277 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
278 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
279 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000280
281/*
282 * DES round macro
283 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100284#define DES_ROUND(X,Y) \
285 do \
286 { \
287 T = *SK++ ^ (X); \
288 (Y) ^= SB8[ (T ) & 0x3F ] ^ \
289 SB6[ (T >> 8) & 0x3F ] ^ \
290 SB4[ (T >> 16) & 0x3F ] ^ \
291 SB2[ (T >> 24) & 0x3F ]; \
292 \
293 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
294 (Y) ^= SB7[ (T ) & 0x3F ] ^ \
295 SB5[ (T >> 8) & 0x3F ] ^ \
296 SB3[ (T >> 16) & 0x3F ] ^ \
297 SB1[ (T >> 24) & 0x3F ]; \
298 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000299
Hanno Becker1eeca412018-10-15 12:01:35 +0100300#define SWAP(a,b) \
301 do \
302 { \
303 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
304 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000305
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200307{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200308 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200309}
310
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200312{
313 if( ctx == NULL )
314 return;
315
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500316 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200317}
318
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200320{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200322}
323
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200324void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200325{
326 if( ctx == NULL )
327 return;
328
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500329 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200330}
331
Paul Bakker1f87fb62011-01-15 17:32:24 +0000332static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
333 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
334 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
335 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
336 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
337 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
338 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
339 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
340 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
341 254 };
342
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000344{
345 int i;
346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000348 key[i] = odd_parity_table[key[i] / 2];
349}
350
351/*
352 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
353 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000355{
356 int i;
357
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200359 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000360 return( 1 );
361
362 return( 0 );
363}
364
365/*
366 * Table of weak and semi-weak keys
367 *
368 * Source: http://en.wikipedia.org/wiki/Weak_key
369 *
370 * Weak:
371 * Alternating ones + zeros (0x0101010101010101)
372 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
373 * '0xE0E0E0E0F1F1F1F1'
374 * '0x1F1F1F1F0E0E0E0E'
375 *
376 * Semi-weak:
377 * 0x011F011F010E010E and 0x1F011F010E010E01
378 * 0x01E001E001F101F1 and 0xE001E001F101F101
379 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
380 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
381 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
382 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
383 *
384 */
385
386#define WEAK_KEY_COUNT 16
387
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000389{
390 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
391 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
392 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
393 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
394
395 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
396 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
397 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
398 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
399 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
400 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
401 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
402 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
403 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
404 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
405 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
406 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
407};
408
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000410{
411 int i;
412
413 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000415 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000416
Paul Bakker73206952011-07-06 14:37:33 +0000417 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000418}
419
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200420#if !defined(MBEDTLS_DES_SETKEY_ALT)
421void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000422{
423 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000424 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
Paul Bakker5c2364c2012-10-01 14:41:15 +0000426 GET_UINT32_BE( X, key, 0 );
427 GET_UINT32_BE( Y, key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
429 /*
430 * Permuted Choice 1
431 */
432 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
433 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
434
435 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
436 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
437 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
438 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
439
440 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
441 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
442 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
443 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
444
445 X &= 0x0FFFFFFF;
446 Y &= 0x0FFFFFFF;
447
448 /*
449 * calculate subkeys
450 */
451 for( i = 0; i < 16; i++ )
452 {
453 if( i < 2 || i == 8 || i == 15 )
454 {
455 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
456 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
457 }
458 else
459 {
460 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
461 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
462 }
463
464 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
465 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
466 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
467 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
468 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
469 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
470 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
471 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
472 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
473 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
474 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
475
476 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
477 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
478 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
479 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
480 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
481 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
482 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
483 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
484 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
485 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
486 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
487 }
488}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200489#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000490
491/*
492 * DES key schedule (56-bit, encryption)
493 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000495{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200496 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000497
498 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000499}
500
501/*
502 * DES key schedule (56-bit, decryption)
503 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000505{
506 int i;
507
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200508 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000509
510 for( i = 0; i < 16; i += 2 )
511 {
512 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
513 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
514 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000515
516 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000517}
518
Paul Bakker5c2364c2012-10-01 14:41:15 +0000519static void des3_set2key( uint32_t esk[96],
520 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000522{
523 int i;
524
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200525 mbedtls_des_setkey( esk, key );
526 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
528 for( i = 0; i < 32; i += 2 )
529 {
530 dsk[i ] = esk[30 - i];
531 dsk[i + 1] = esk[31 - i];
532
533 esk[i + 32] = dsk[62 - i];
534 esk[i + 33] = dsk[63 - i];
535
536 esk[i + 64] = esk[i ];
537 esk[i + 65] = esk[i + 1];
538
539 dsk[i + 64] = dsk[i ];
540 dsk[i + 65] = dsk[i + 1];
541 }
542}
543
544/*
545 * Triple-DES key schedule (112-bit, encryption)
546 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
548 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000549{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000550 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000551
552 des3_set2key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500553 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000554
555 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000556}
557
558/*
559 * Triple-DES key schedule (112-bit, decryption)
560 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
562 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000563{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000564 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
566 des3_set2key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500567 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000568
569 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000570}
571
Paul Bakker5c2364c2012-10-01 14:41:15 +0000572static void des3_set3key( uint32_t esk[96],
573 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000574 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000575{
576 int i;
577
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200578 mbedtls_des_setkey( esk, key );
579 mbedtls_des_setkey( dsk + 32, key + 8 );
580 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
582 for( i = 0; i < 32; i += 2 )
583 {
584 dsk[i ] = esk[94 - i];
585 dsk[i + 1] = esk[95 - i];
586
587 esk[i + 32] = dsk[62 - i];
588 esk[i + 33] = dsk[63 - i];
589
590 dsk[i + 64] = esk[30 - i];
591 dsk[i + 65] = esk[31 - i];
592 }
593}
594
595/*
596 * Triple-DES key schedule (168-bit, encryption)
597 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
599 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000600{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000601 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000602
603 des3_set3key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500604 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000605
606 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000607}
608
609/*
610 * Triple-DES key schedule (168-bit, decryption)
611 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
613 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000614{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000615 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
617 des3_set3key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500618 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000619
620 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000621}
622
623/*
624 * DES-ECB block encryption/decryption
625 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200626#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000628 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 unsigned char output[8] )
630{
631 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000632 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
634 SK = ctx->sk;
635
Paul Bakker5c2364c2012-10-01 14:41:15 +0000636 GET_UINT32_BE( X, input, 0 );
637 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
639 DES_IP( X, Y );
640
641 for( i = 0; i < 8; i++ )
642 {
643 DES_ROUND( Y, X );
644 DES_ROUND( X, Y );
645 }
646
647 DES_FP( Y, X );
648
Paul Bakker5c2364c2012-10-01 14:41:15 +0000649 PUT_UINT32_BE( Y, output, 0 );
650 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000651
652 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000653}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200654#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000655
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200656#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000657/*
658 * DES-CBC buffer encryption/decryption
659 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000662 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000663 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000664 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000665 unsigned char *output )
666{
667 int i;
668 unsigned char temp[8];
669
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000670 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200671 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000672
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000674 {
675 while( length > 0 )
676 {
677 for( i = 0; i < 8; i++ )
678 output[i] = (unsigned char)( input[i] ^ iv[i] );
679
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680 mbedtls_des_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000681 memcpy( iv, output, 8 );
682
683 input += 8;
684 output += 8;
685 length -= 8;
686 }
687 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200688 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000689 {
690 while( length > 0 )
691 {
692 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693 mbedtls_des_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
695 for( i = 0; i < 8; i++ )
696 output[i] = (unsigned char)( output[i] ^ iv[i] );
697
698 memcpy( iv, temp, 8 );
699
700 input += 8;
701 output += 8;
702 length -= 8;
703 }
704 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000705
706 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000707}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200708#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000709
710/*
711 * 3DES-ECB block encryption/decryption
712 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200713#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000715 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000716 unsigned char output[8] )
717{
718 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000719 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000720
721 SK = ctx->sk;
722
Paul Bakker5c2364c2012-10-01 14:41:15 +0000723 GET_UINT32_BE( X, input, 0 );
724 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000725
726 DES_IP( X, Y );
727
728 for( i = 0; i < 8; i++ )
729 {
730 DES_ROUND( Y, X );
731 DES_ROUND( X, Y );
732 }
733
734 for( i = 0; i < 8; i++ )
735 {
736 DES_ROUND( X, Y );
737 DES_ROUND( Y, X );
738 }
739
740 for( i = 0; i < 8; i++ )
741 {
742 DES_ROUND( Y, X );
743 DES_ROUND( X, Y );
744 }
745
746 DES_FP( Y, X );
747
Paul Bakker5c2364c2012-10-01 14:41:15 +0000748 PUT_UINT32_BE( Y, output, 0 );
749 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000750
751 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000752}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200753#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000754
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000756/*
757 * 3DES-CBC buffer encryption/decryption
758 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200759int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000760 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000761 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000762 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000763 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000764 unsigned char *output )
765{
766 int i;
767 unsigned char temp[8];
768
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000769 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200770 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000771
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200772 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000773 {
774 while( length > 0 )
775 {
776 for( i = 0; i < 8; i++ )
777 output[i] = (unsigned char)( input[i] ^ iv[i] );
778
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200779 mbedtls_des3_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000780 memcpy( iv, output, 8 );
781
782 input += 8;
783 output += 8;
784 length -= 8;
785 }
786 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200787 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000788 {
789 while( length > 0 )
790 {
791 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792 mbedtls_des3_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000793
794 for( i = 0; i < 8; i++ )
795 output[i] = (unsigned char)( output[i] ^ iv[i] );
796
797 memcpy( iv, temp, 8 );
798
799 input += 8;
800 output += 8;
801 length -= 8;
802 }
803 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000804
805 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000806}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000808
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200809#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200810
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200811#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000812/*
813 * DES and 3DES test vectors from:
814 *
815 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
816 */
817static const unsigned char des3_test_keys[24] =
818{
819 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
820 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
821 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
822};
823
Paul Bakker5121ce52009-01-03 21:22:43 +0000824static const unsigned char des3_test_buf[8] =
825{
826 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
827};
828
829static const unsigned char des3_test_ecb_dec[3][8] =
830{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100831 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
832 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
833 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000834};
835
836static const unsigned char des3_test_ecb_enc[3][8] =
837{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100838 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
839 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
840 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000841};
842
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100844static const unsigned char des3_test_iv[8] =
845{
846 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
847};
848
Paul Bakker5121ce52009-01-03 21:22:43 +0000849static const unsigned char des3_test_cbc_dec[3][8] =
850{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100851 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
852 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
853 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000854};
855
856static const unsigned char des3_test_cbc_enc[3][8] =
857{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100858 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
859 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
860 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000861};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000863
864/*
865 * Checkup routine
866 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000868{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200869 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 mbedtls_des_context ctx;
871 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000872 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000874 unsigned char prv[8];
875 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200876#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000877
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878 mbedtls_des_init( &ctx );
879 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000880 /*
881 * ECB mode
882 */
883 for( i = 0; i < 6; i++ )
884 {
885 u = i >> 1;
886 v = i & 1;
887
888 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100890 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000892
893 memcpy( buf, des3_test_buf, 8 );
894
895 switch( i )
896 {
897 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200898 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000899 break;
900
901 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200902 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000903 break;
904
905 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000907 break;
908
909 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000911 break;
912
913 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000915 break;
916
917 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000919 break;
920
921 default:
922 return( 1 );
923 }
924
Jaeden Amero355b4b02019-05-29 10:13:23 +0100925 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000926 {
927 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200928 mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000929 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930 mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000931 }
932
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000934 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000936 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
937 {
938 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000940
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200941 ret = 1;
942 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000943 }
944
945 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000947 }
948
949 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000951
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 /*
954 * CBC mode
955 */
956 for( i = 0; i < 6; i++ )
957 {
958 u = i >> 1;
959 v = i & 1;
960
961 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200962 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100963 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000965
966 memcpy( iv, des3_test_iv, 8 );
967 memcpy( prv, des3_test_iv, 8 );
968 memcpy( buf, des3_test_buf, 8 );
969
970 switch( i )
971 {
972 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200973 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000974 break;
975
976 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000978 break;
979
980 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000982 break;
983
984 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 break;
987
988 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000990 break;
991
992 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000994 break;
995
996 default:
997 return( 1 );
998 }
999
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001000 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001001 {
Jaeden Amero355b4b02019-05-29 10:13:23 +01001002 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001003 {
1004 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001005 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001006 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001008 }
1009 }
1010 else
1011 {
Jaeden Amero355b4b02019-05-29 10:13:23 +01001012 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001013 {
1014 unsigned char tmp[8];
1015
1016 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001018 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001020
1021 memcpy( tmp, prv, 8 );
1022 memcpy( prv, buf, 8 );
1023 memcpy( buf, tmp, 8 );
1024 }
1025
1026 memcpy( buf, prv, 8 );
1027 }
1028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001029 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001030 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001031 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001032 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1033 {
1034 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001036
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001037 ret = 1;
1038 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001039 }
1040
1041 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001042 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001043 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001044#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001045
1046 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001048
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001049exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001050 mbedtls_des_free( &ctx );
1051 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001052
1053 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001054}
1055
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001057
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001058#endif /* MBEDTLS_DES_C */