blob: 0576099ce8a7643062e2c94442d59ec795ba7503 [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"
Gilles Peskine7820a572021-07-07 21:08:28 +020031#include "mbedtls/error.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050032#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010039
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020041
Paul Bakker5121ce52009-01-03 21:22:43 +000042/*
Paul Bakker5121ce52009-01-03 21:22:43 +000043 * Expanded DES S-boxes
44 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000045static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000046{
47 0x01010400, 0x00000000, 0x00010000, 0x01010404,
48 0x01010004, 0x00010404, 0x00000004, 0x00010000,
49 0x00000400, 0x01010400, 0x01010404, 0x00000400,
50 0x01000404, 0x01010004, 0x01000000, 0x00000004,
51 0x00000404, 0x01000400, 0x01000400, 0x00010400,
52 0x00010400, 0x01010000, 0x01010000, 0x01000404,
53 0x00010004, 0x01000004, 0x01000004, 0x00010004,
54 0x00000000, 0x00000404, 0x00010404, 0x01000000,
55 0x00010000, 0x01010404, 0x00000004, 0x01010000,
56 0x01010400, 0x01000000, 0x01000000, 0x00000400,
57 0x01010004, 0x00010000, 0x00010400, 0x01000004,
58 0x00000400, 0x00000004, 0x01000404, 0x00010404,
59 0x01010404, 0x00010004, 0x01010000, 0x01000404,
60 0x01000004, 0x00000404, 0x00010404, 0x01010400,
61 0x00000404, 0x01000400, 0x01000400, 0x00000000,
62 0x00010004, 0x00010400, 0x00000000, 0x01010004
63};
64
Paul Bakker5c2364c2012-10-01 14:41:15 +000065static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000066{
67 0x80108020, 0x80008000, 0x00008000, 0x00108020,
68 0x00100000, 0x00000020, 0x80100020, 0x80008020,
69 0x80000020, 0x80108020, 0x80108000, 0x80000000,
70 0x80008000, 0x00100000, 0x00000020, 0x80100020,
71 0x00108000, 0x00100020, 0x80008020, 0x00000000,
72 0x80000000, 0x00008000, 0x00108020, 0x80100000,
73 0x00100020, 0x80000020, 0x00000000, 0x00108000,
74 0x00008020, 0x80108000, 0x80100000, 0x00008020,
75 0x00000000, 0x00108020, 0x80100020, 0x00100000,
76 0x80008020, 0x80100000, 0x80108000, 0x00008000,
77 0x80100000, 0x80008000, 0x00000020, 0x80108020,
78 0x00108020, 0x00000020, 0x00008000, 0x80000000,
79 0x00008020, 0x80108000, 0x00100000, 0x80000020,
80 0x00100020, 0x80008020, 0x80000020, 0x00100020,
81 0x00108000, 0x00000000, 0x80008000, 0x00008020,
82 0x80000000, 0x80100020, 0x80108020, 0x00108000
83};
84
Paul Bakker5c2364c2012-10-01 14:41:15 +000085static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000086{
87 0x00000208, 0x08020200, 0x00000000, 0x08020008,
88 0x08000200, 0x00000000, 0x00020208, 0x08000200,
89 0x00020008, 0x08000008, 0x08000008, 0x00020000,
90 0x08020208, 0x00020008, 0x08020000, 0x00000208,
91 0x08000000, 0x00000008, 0x08020200, 0x00000200,
92 0x00020200, 0x08020000, 0x08020008, 0x00020208,
93 0x08000208, 0x00020200, 0x00020000, 0x08000208,
94 0x00000008, 0x08020208, 0x00000200, 0x08000000,
95 0x08020200, 0x08000000, 0x00020008, 0x00000208,
96 0x00020000, 0x08020200, 0x08000200, 0x00000000,
97 0x00000200, 0x00020008, 0x08020208, 0x08000200,
98 0x08000008, 0x00000200, 0x00000000, 0x08020008,
99 0x08000208, 0x00020000, 0x08000000, 0x08020208,
100 0x00000008, 0x00020208, 0x00020200, 0x08000008,
101 0x08020000, 0x08000208, 0x00000208, 0x08020000,
102 0x00020208, 0x00000008, 0x08020008, 0x00020200
103};
104
Paul Bakker5c2364c2012-10-01 14:41:15 +0000105static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000106{
107 0x00802001, 0x00002081, 0x00002081, 0x00000080,
108 0x00802080, 0x00800081, 0x00800001, 0x00002001,
109 0x00000000, 0x00802000, 0x00802000, 0x00802081,
110 0x00000081, 0x00000000, 0x00800080, 0x00800001,
111 0x00000001, 0x00002000, 0x00800000, 0x00802001,
112 0x00000080, 0x00800000, 0x00002001, 0x00002080,
113 0x00800081, 0x00000001, 0x00002080, 0x00800080,
114 0x00002000, 0x00802080, 0x00802081, 0x00000081,
115 0x00800080, 0x00800001, 0x00802000, 0x00802081,
116 0x00000081, 0x00000000, 0x00000000, 0x00802000,
117 0x00002080, 0x00800080, 0x00800081, 0x00000001,
118 0x00802001, 0x00002081, 0x00002081, 0x00000080,
119 0x00802081, 0x00000081, 0x00000001, 0x00002000,
120 0x00800001, 0x00002001, 0x00802080, 0x00800081,
121 0x00002001, 0x00002080, 0x00800000, 0x00802001,
122 0x00000080, 0x00800000, 0x00002000, 0x00802080
123};
124
Paul Bakker5c2364c2012-10-01 14:41:15 +0000125static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000126{
127 0x00000100, 0x02080100, 0x02080000, 0x42000100,
128 0x00080000, 0x00000100, 0x40000000, 0x02080000,
129 0x40080100, 0x00080000, 0x02000100, 0x40080100,
130 0x42000100, 0x42080000, 0x00080100, 0x40000000,
131 0x02000000, 0x40080000, 0x40080000, 0x00000000,
132 0x40000100, 0x42080100, 0x42080100, 0x02000100,
133 0x42080000, 0x40000100, 0x00000000, 0x42000000,
134 0x02080100, 0x02000000, 0x42000000, 0x00080100,
135 0x00080000, 0x42000100, 0x00000100, 0x02000000,
136 0x40000000, 0x02080000, 0x42000100, 0x40080100,
137 0x02000100, 0x40000000, 0x42080000, 0x02080100,
138 0x40080100, 0x00000100, 0x02000000, 0x42080000,
139 0x42080100, 0x00080100, 0x42000000, 0x42080100,
140 0x02080000, 0x00000000, 0x40080000, 0x42000000,
141 0x00080100, 0x02000100, 0x40000100, 0x00080000,
142 0x00000000, 0x40080000, 0x02080100, 0x40000100
143};
144
Paul Bakker5c2364c2012-10-01 14:41:15 +0000145static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000146{
147 0x20000010, 0x20400000, 0x00004000, 0x20404010,
148 0x20400000, 0x00000010, 0x20404010, 0x00400000,
149 0x20004000, 0x00404010, 0x00400000, 0x20000010,
150 0x00400010, 0x20004000, 0x20000000, 0x00004010,
151 0x00000000, 0x00400010, 0x20004010, 0x00004000,
152 0x00404000, 0x20004010, 0x00000010, 0x20400010,
153 0x20400010, 0x00000000, 0x00404010, 0x20404000,
154 0x00004010, 0x00404000, 0x20404000, 0x20000000,
155 0x20004000, 0x00000010, 0x20400010, 0x00404000,
156 0x20404010, 0x00400000, 0x00004010, 0x20000010,
157 0x00400000, 0x20004000, 0x20000000, 0x00004010,
158 0x20000010, 0x20404010, 0x00404000, 0x20400000,
159 0x00404010, 0x20404000, 0x00000000, 0x20400010,
160 0x00000010, 0x00004000, 0x20400000, 0x00404010,
161 0x00004000, 0x00400010, 0x20004010, 0x00000000,
162 0x20404000, 0x20000000, 0x00400010, 0x20004010
163};
164
Paul Bakker5c2364c2012-10-01 14:41:15 +0000165static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000166{
167 0x00200000, 0x04200002, 0x04000802, 0x00000000,
168 0x00000800, 0x04000802, 0x00200802, 0x04200800,
169 0x04200802, 0x00200000, 0x00000000, 0x04000002,
170 0x00000002, 0x04000000, 0x04200002, 0x00000802,
171 0x04000800, 0x00200802, 0x00200002, 0x04000800,
172 0x04000002, 0x04200000, 0x04200800, 0x00200002,
173 0x04200000, 0x00000800, 0x00000802, 0x04200802,
174 0x00200800, 0x00000002, 0x04000000, 0x00200800,
175 0x04000000, 0x00200800, 0x00200000, 0x04000802,
176 0x04000802, 0x04200002, 0x04200002, 0x00000002,
177 0x00200002, 0x04000000, 0x04000800, 0x00200000,
178 0x04200800, 0x00000802, 0x00200802, 0x04200800,
179 0x00000802, 0x04000002, 0x04200802, 0x04200000,
180 0x00200800, 0x00000000, 0x00000002, 0x04200802,
181 0x00000000, 0x00200802, 0x04200000, 0x00000800,
182 0x04000002, 0x04000800, 0x00000800, 0x00200002
183};
184
Paul Bakker5c2364c2012-10-01 14:41:15 +0000185static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000186{
187 0x10001040, 0x00001000, 0x00040000, 0x10041040,
188 0x10000000, 0x10001040, 0x00000040, 0x10000000,
189 0x00040040, 0x10040000, 0x10041040, 0x00041000,
190 0x10041000, 0x00041040, 0x00001000, 0x00000040,
191 0x10040000, 0x10000040, 0x10001000, 0x00001040,
192 0x00041000, 0x00040040, 0x10040040, 0x10041000,
193 0x00001040, 0x00000000, 0x00000000, 0x10040040,
194 0x10000040, 0x10001000, 0x00041040, 0x00040000,
195 0x00041040, 0x00040000, 0x10041000, 0x00001000,
196 0x00000040, 0x10040040, 0x00001000, 0x00041040,
197 0x10001000, 0x00000040, 0x10000040, 0x10040000,
198 0x10040040, 0x10000000, 0x00040000, 0x10001040,
199 0x00000000, 0x10041040, 0x00040040, 0x10000040,
200 0x10040000, 0x10001000, 0x10001040, 0x00000000,
201 0x10041040, 0x00041000, 0x00041000, 0x00001040,
202 0x00001040, 0x00040040, 0x10000000, 0x10041000
203};
204
205/*
206 * PC1: left and right halves bit-swap
207 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000208static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000209{
210 0x00000000, 0x00000001, 0x00000100, 0x00000101,
211 0x00010000, 0x00010001, 0x00010100, 0x00010101,
212 0x01000000, 0x01000001, 0x01000100, 0x01000101,
213 0x01010000, 0x01010001, 0x01010100, 0x01010101
214};
215
Paul Bakker5c2364c2012-10-01 14:41:15 +0000216static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000217{
218 0x00000000, 0x01000000, 0x00010000, 0x01010000,
219 0x00000100, 0x01000100, 0x00010100, 0x01010100,
220 0x00000001, 0x01000001, 0x00010001, 0x01010001,
221 0x00000101, 0x01000101, 0x00010101, 0x01010101,
222};
223
224/*
225 * Initial Permutation macro
226 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100227#define DES_IP(X,Y) \
228 do \
229 { \
230 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
231 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
232 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
233 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
234 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
235 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
236 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
237 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
239/*
240 * Final Permutation macro
241 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100242#define DES_FP(X,Y) \
243 do \
244 { \
245 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
246 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
247 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
248 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
249 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
250 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
251 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
252 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000253
254/*
255 * DES round macro
256 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100257#define DES_ROUND(X,Y) \
258 do \
259 { \
260 T = *SK++ ^ (X); \
261 (Y) ^= SB8[ (T ) & 0x3F ] ^ \
262 SB6[ (T >> 8) & 0x3F ] ^ \
263 SB4[ (T >> 16) & 0x3F ] ^ \
264 SB2[ (T >> 24) & 0x3F ]; \
265 \
266 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
267 (Y) ^= SB7[ (T ) & 0x3F ] ^ \
268 SB5[ (T >> 8) & 0x3F ] ^ \
269 SB3[ (T >> 16) & 0x3F ] ^ \
270 SB1[ (T >> 24) & 0x3F ]; \
271 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000272
Hanno Becker1eeca412018-10-15 12:01:35 +0100273#define SWAP(a,b) \
274 do \
275 { \
276 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
277 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000278
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200279void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200280{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200281 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200282}
283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200284void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200285{
286 if( ctx == NULL )
287 return;
288
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500289 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200290}
291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200293{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200295}
296
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200298{
299 if( ctx == NULL )
300 return;
301
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500302 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200303}
304
Paul Bakker1f87fb62011-01-15 17:32:24 +0000305static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
306 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
307 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
308 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
309 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
310 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
311 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
312 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
313 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
314 254 };
315
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200316void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000317{
318 int i;
319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000321 key[i] = odd_parity_table[key[i] / 2];
322}
323
324/*
325 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
326 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000328{
329 int i;
330
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200332 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000333 return( 1 );
334
335 return( 0 );
336}
337
338/*
339 * Table of weak and semi-weak keys
340 *
341 * Source: http://en.wikipedia.org/wiki/Weak_key
342 *
343 * Weak:
344 * Alternating ones + zeros (0x0101010101010101)
345 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
346 * '0xE0E0E0E0F1F1F1F1'
347 * '0x1F1F1F1F0E0E0E0E'
348 *
349 * Semi-weak:
350 * 0x011F011F010E010E and 0x1F011F010E010E01
351 * 0x01E001E001F101F1 and 0xE001E001F101F101
352 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
353 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
354 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
355 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
356 *
357 */
358
359#define WEAK_KEY_COUNT 16
360
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000362{
363 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
364 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
365 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
366 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
367
368 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
369 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
370 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
371 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
372 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
373 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
374 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
375 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
376 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
377 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
378 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
379 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
380};
381
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200382int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000383{
384 int i;
385
386 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000388 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000389
Paul Bakker73206952011-07-06 14:37:33 +0000390 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000391}
392
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200393#if !defined(MBEDTLS_DES_SETKEY_ALT)
394void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000395{
396 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000397 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000398
Joe Subbiani6a506312021-07-07 16:56:29 +0100399 X = MBEDTLS_GET_UINT32_BE( key, 0 );
400 Y = MBEDTLS_GET_UINT32_BE( key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000401
402 /*
403 * Permuted Choice 1
404 */
405 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
406 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
407
408 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
409 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
410 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
411 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
412
413 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
414 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
415 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
416 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
417
418 X &= 0x0FFFFFFF;
419 Y &= 0x0FFFFFFF;
420
421 /*
422 * calculate subkeys
423 */
424 for( i = 0; i < 16; i++ )
425 {
426 if( i < 2 || i == 8 || i == 15 )
427 {
428 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
429 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
430 }
431 else
432 {
433 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
434 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
435 }
436
437 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
438 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
439 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
440 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
441 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
442 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
443 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
444 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
445 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
446 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
447 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
448
449 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
450 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
451 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
452 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
453 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
454 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
455 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
456 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
457 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
458 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
459 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
460 }
461}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200462#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
464/*
465 * DES key schedule (56-bit, encryption)
466 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000468{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200469 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000470
471 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472}
473
474/*
475 * DES key schedule (56-bit, decryption)
476 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000478{
479 int i;
480
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200481 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
483 for( i = 0; i < 16; i += 2 )
484 {
485 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
486 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
487 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000488
489 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000490}
491
Paul Bakker5c2364c2012-10-01 14:41:15 +0000492static void des3_set2key( uint32_t esk[96],
493 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000495{
496 int i;
497
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200498 mbedtls_des_setkey( esk, key );
499 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
501 for( i = 0; i < 32; i += 2 )
502 {
503 dsk[i ] = esk[30 - i];
504 dsk[i + 1] = esk[31 - i];
505
506 esk[i + 32] = dsk[62 - i];
507 esk[i + 33] = dsk[63 - i];
508
509 esk[i + 64] = esk[i ];
510 esk[i + 65] = esk[i + 1];
511
512 dsk[i + 64] = dsk[i ];
513 dsk[i + 65] = dsk[i + 1];
514 }
515}
516
517/*
518 * Triple-DES key schedule (112-bit, encryption)
519 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200520int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
521 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000522{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000523 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000524
525 des3_set2key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500526 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000527
528 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000529}
530
531/*
532 * Triple-DES key schedule (112-bit, decryption)
533 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
535 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000536{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000537 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000538
539 des3_set2key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500540 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000541
542 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000543}
544
Paul Bakker5c2364c2012-10-01 14:41:15 +0000545static void des3_set3key( uint32_t esk[96],
546 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000547 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000548{
549 int i;
550
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200551 mbedtls_des_setkey( esk, key );
552 mbedtls_des_setkey( dsk + 32, key + 8 );
553 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000554
555 for( i = 0; i < 32; i += 2 )
556 {
557 dsk[i ] = esk[94 - i];
558 dsk[i + 1] = esk[95 - i];
559
560 esk[i + 32] = dsk[62 - i];
561 esk[i + 33] = dsk[63 - i];
562
563 dsk[i + 64] = esk[30 - i];
564 dsk[i + 65] = esk[31 - i];
565 }
566}
567
568/*
569 * Triple-DES key schedule (168-bit, encryption)
570 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200571int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
572 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000573{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000574 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
576 des3_set3key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500577 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000578
579 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000580}
581
582/*
583 * Triple-DES key schedule (168-bit, decryption)
584 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200585int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
586 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000587{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000588 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000589
590 des3_set3key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500591 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000592
593 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000594}
595
596/*
597 * DES-ECB block encryption/decryption
598 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200599#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000601 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000602 unsigned char output[8] )
603{
604 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000605 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
607 SK = ctx->sk;
608
Joe Subbiani6a506312021-07-07 16:56:29 +0100609 X = MBEDTLS_GET_UINT32_BE( input, 0 );
610 Y = MBEDTLS_GET_UINT32_BE( input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612 DES_IP( X, Y );
613
614 for( i = 0; i < 8; i++ )
615 {
616 DES_ROUND( Y, X );
617 DES_ROUND( X, Y );
618 }
619
620 DES_FP( Y, X );
621
Joe Subbiani5ecac212021-06-24 13:00:03 +0100622 MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
623 MBEDTLS_PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000624
625 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000626}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200627#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000628
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000630/*
631 * DES-CBC buffer encryption/decryption
632 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000635 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000637 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000638 unsigned char *output )
639{
640 int i;
Gilles Peskine7820a572021-07-07 21:08:28 +0200641 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000642 unsigned char temp[8];
643
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000644 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000646
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000648 {
649 while( length > 0 )
650 {
651 for( i = 0; i < 8; i++ )
652 output[i] = (unsigned char)( input[i] ^ iv[i] );
653
Gilles Peskine7820a572021-07-07 21:08:28 +0200654 ret = mbedtls_des_crypt_ecb( ctx, output, output );
655 if( ret != 0 )
656 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000657 memcpy( iv, output, 8 );
658
659 input += 8;
660 output += 8;
661 length -= 8;
662 }
663 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200664 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000665 {
666 while( length > 0 )
667 {
668 memcpy( temp, input, 8 );
Gilles Peskine7820a572021-07-07 21:08:28 +0200669 ret = mbedtls_des_crypt_ecb( ctx, input, output );
670 if( ret != 0 )
671 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000672
673 for( i = 0; i < 8; i++ )
674 output[i] = (unsigned char)( output[i] ^ iv[i] );
675
676 memcpy( iv, temp, 8 );
677
678 input += 8;
679 output += 8;
680 length -= 8;
681 }
682 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200683 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000684
Gilles Peskine7820a572021-07-07 21:08:28 +0200685exit:
686 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000687}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200688#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000689
690/*
691 * 3DES-ECB block encryption/decryption
692 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200693#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000695 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000696 unsigned char output[8] )
697{
698 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000699 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
701 SK = ctx->sk;
702
Joe Subbiani6a506312021-07-07 16:56:29 +0100703 X = MBEDTLS_GET_UINT32_BE( input, 0 );
704 Y = MBEDTLS_GET_UINT32_BE( input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000705
706 DES_IP( X, Y );
707
708 for( i = 0; i < 8; i++ )
709 {
710 DES_ROUND( Y, X );
711 DES_ROUND( X, Y );
712 }
713
714 for( i = 0; i < 8; i++ )
715 {
716 DES_ROUND( X, Y );
717 DES_ROUND( Y, X );
718 }
719
720 for( i = 0; i < 8; i++ )
721 {
722 DES_ROUND( Y, X );
723 DES_ROUND( X, Y );
724 }
725
726 DES_FP( Y, X );
727
Joe Subbiani5ecac212021-06-24 13:00:03 +0100728 MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
729 MBEDTLS_PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000730
731 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000732}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200733#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000734
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200735#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000736/*
737 * 3DES-CBC buffer encryption/decryption
738 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000740 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000741 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000742 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000743 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000744 unsigned char *output )
745{
746 int i;
Gilles Peskine7820a572021-07-07 21:08:28 +0200747 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000748 unsigned char temp[8];
749
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000750 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200751 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000752
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200753 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000754 {
755 while( length > 0 )
756 {
757 for( i = 0; i < 8; i++ )
758 output[i] = (unsigned char)( input[i] ^ iv[i] );
759
Gilles Peskine7820a572021-07-07 21:08:28 +0200760 ret = mbedtls_des3_crypt_ecb( ctx, output, output );
761 if( ret != 0 )
762 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000763 memcpy( iv, output, 8 );
764
765 input += 8;
766 output += 8;
767 length -= 8;
768 }
769 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200770 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000771 {
772 while( length > 0 )
773 {
774 memcpy( temp, input, 8 );
Gilles Peskine7820a572021-07-07 21:08:28 +0200775 ret = mbedtls_des3_crypt_ecb( ctx, input, output );
776 if( ret != 0 )
777 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000778
779 for( i = 0; i < 8; i++ )
780 output[i] = (unsigned char)( output[i] ^ iv[i] );
781
782 memcpy( iv, temp, 8 );
783
784 input += 8;
785 output += 8;
786 length -= 8;
787 }
788 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200789 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000790
Gilles Peskine7820a572021-07-07 21:08:28 +0200791exit:
792 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000793}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000795
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200797
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000799/*
800 * DES and 3DES test vectors from:
801 *
802 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
803 */
804static const unsigned char des3_test_keys[24] =
805{
806 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
807 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
808 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
809};
810
Paul Bakker5121ce52009-01-03 21:22:43 +0000811static const unsigned char des3_test_buf[8] =
812{
813 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
814};
815
816static const unsigned char des3_test_ecb_dec[3][8] =
817{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100818 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
819 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
820 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000821};
822
823static const unsigned char des3_test_ecb_enc[3][8] =
824{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100825 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
826 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
827 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000828};
829
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100831static const unsigned char des3_test_iv[8] =
832{
833 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
834};
835
Paul Bakker5121ce52009-01-03 21:22:43 +0000836static const unsigned char des3_test_cbc_dec[3][8] =
837{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100838 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
839 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
840 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000841};
842
843static const unsigned char des3_test_cbc_enc[3][8] =
844{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100845 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
846 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
847 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000848};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000850
851/*
852 * Checkup routine
853 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200854int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000855{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200856 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857 mbedtls_des_context ctx;
858 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000859 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200860#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000861 unsigned char prv[8];
862 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200863#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000864
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200865 mbedtls_des_init( &ctx );
866 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000867 /*
868 * ECB mode
869 */
870 for( i = 0; i < 6; i++ )
871 {
872 u = i >> 1;
873 v = i & 1;
874
875 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200876 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100877 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000879
880 memcpy( buf, des3_test_buf, 8 );
881
882 switch( i )
883 {
884 case 0:
Gilles Peskine7820a572021-07-07 21:08:28 +0200885 ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000886 break;
887
888 case 1:
Gilles Peskine7820a572021-07-07 21:08:28 +0200889 ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000890 break;
891
892 case 2:
Gilles Peskine7820a572021-07-07 21:08:28 +0200893 ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000894 break;
895
896 case 3:
Gilles Peskine7820a572021-07-07 21:08:28 +0200897 ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000898 break;
899
900 case 4:
Gilles Peskine7820a572021-07-07 21:08:28 +0200901 ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000902 break;
903
904 case 5:
Gilles Peskine7820a572021-07-07 21:08:28 +0200905 ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000906 break;
907
908 default:
909 return( 1 );
910 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200911 if( ret != 0 )
912 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000913
Jaeden Amero355b4b02019-05-29 10:13:23 +0100914 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000915 {
916 if( u == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +0200917 ret = mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000918 else
Gilles Peskine7820a572021-07-07 21:08:28 +0200919 ret = mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
920 if( ret != 0 )
921 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000922 }
923
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000925 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000927 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
928 {
929 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000931
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200932 ret = 1;
933 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000934 }
935
936 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000938 }
939
940 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000942
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200943#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000944 /*
945 * CBC mode
946 */
947 for( i = 0; i < 6; i++ )
948 {
949 u = i >> 1;
950 v = i & 1;
951
952 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100954 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000956
957 memcpy( iv, des3_test_iv, 8 );
958 memcpy( prv, des3_test_iv, 8 );
959 memcpy( buf, des3_test_buf, 8 );
960
961 switch( i )
962 {
963 case 0:
Gilles Peskine7820a572021-07-07 21:08:28 +0200964 ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000965 break;
966
967 case 1:
Gilles Peskine7820a572021-07-07 21:08:28 +0200968 ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000969 break;
970
971 case 2:
Gilles Peskine7820a572021-07-07 21:08:28 +0200972 ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000973 break;
974
975 case 3:
Gilles Peskine7820a572021-07-07 21:08:28 +0200976 ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000977 break;
978
979 case 4:
Gilles Peskine7820a572021-07-07 21:08:28 +0200980 ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000981 break;
982
983 case 5:
Gilles Peskine7820a572021-07-07 21:08:28 +0200984 ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000985 break;
986
987 default:
988 return( 1 );
989 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200990 if( ret != 0 )
991 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000992
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000994 {
Jaeden Amero355b4b02019-05-29 10:13:23 +0100995 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000996 {
997 if( u == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +0200998 ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000999 else
Gilles Peskine7820a572021-07-07 21:08:28 +02001000 ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
1001 if( ret != 0 )
1002 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001003 }
1004 }
1005 else
1006 {
Jaeden Amero355b4b02019-05-29 10:13:23 +01001007 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001008 {
1009 unsigned char tmp[8];
1010
1011 if( u == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +02001012 ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001013 else
Gilles Peskine7820a572021-07-07 21:08:28 +02001014 ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
1015 if( ret != 0 )
1016 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001017
1018 memcpy( tmp, prv, 8 );
1019 memcpy( prv, buf, 8 );
1020 memcpy( buf, tmp, 8 );
1021 }
1022
1023 memcpy( buf, prv, 8 );
1024 }
1025
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001026 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001027 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001029 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1030 {
1031 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001033
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001034 ret = 1;
1035 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001036 }
1037
1038 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001039 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001040 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001041#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001042
1043 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001044 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001045
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001046exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047 mbedtls_des_free( &ctx );
1048 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001049
Gilles Peskine7820a572021-07-07 21:08:28 +02001050 if( ret != 0 )
1051 ret = 1;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001052 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 */