blob: c56d4d4fe3c1690d9bfcb3e63d0d9da8aeabd784 [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é-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020039
Paul Bakker5121ce52009-01-03 21:22:43 +000040/*
Paul Bakker5121ce52009-01-03 21:22:43 +000041 * Expanded DES S-boxes
42 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000043static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000044{
45 0x01010400, 0x00000000, 0x00010000, 0x01010404,
46 0x01010004, 0x00010404, 0x00000004, 0x00010000,
47 0x00000400, 0x01010400, 0x01010404, 0x00000400,
48 0x01000404, 0x01010004, 0x01000000, 0x00000004,
49 0x00000404, 0x01000400, 0x01000400, 0x00010400,
50 0x00010400, 0x01010000, 0x01010000, 0x01000404,
51 0x00010004, 0x01000004, 0x01000004, 0x00010004,
52 0x00000000, 0x00000404, 0x00010404, 0x01000000,
53 0x00010000, 0x01010404, 0x00000004, 0x01010000,
54 0x01010400, 0x01000000, 0x01000000, 0x00000400,
55 0x01010004, 0x00010000, 0x00010400, 0x01000004,
56 0x00000400, 0x00000004, 0x01000404, 0x00010404,
57 0x01010404, 0x00010004, 0x01010000, 0x01000404,
58 0x01000004, 0x00000404, 0x00010404, 0x01010400,
59 0x00000404, 0x01000400, 0x01000400, 0x00000000,
60 0x00010004, 0x00010400, 0x00000000, 0x01010004
61};
62
Paul Bakker5c2364c2012-10-01 14:41:15 +000063static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000064{
65 0x80108020, 0x80008000, 0x00008000, 0x00108020,
66 0x00100000, 0x00000020, 0x80100020, 0x80008020,
67 0x80000020, 0x80108020, 0x80108000, 0x80000000,
68 0x80008000, 0x00100000, 0x00000020, 0x80100020,
69 0x00108000, 0x00100020, 0x80008020, 0x00000000,
70 0x80000000, 0x00008000, 0x00108020, 0x80100000,
71 0x00100020, 0x80000020, 0x00000000, 0x00108000,
72 0x00008020, 0x80108000, 0x80100000, 0x00008020,
73 0x00000000, 0x00108020, 0x80100020, 0x00100000,
74 0x80008020, 0x80100000, 0x80108000, 0x00008000,
75 0x80100000, 0x80008000, 0x00000020, 0x80108020,
76 0x00108020, 0x00000020, 0x00008000, 0x80000000,
77 0x00008020, 0x80108000, 0x00100000, 0x80000020,
78 0x00100020, 0x80008020, 0x80000020, 0x00100020,
79 0x00108000, 0x00000000, 0x80008000, 0x00008020,
80 0x80000000, 0x80100020, 0x80108020, 0x00108000
81};
82
Paul Bakker5c2364c2012-10-01 14:41:15 +000083static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000084{
85 0x00000208, 0x08020200, 0x00000000, 0x08020008,
86 0x08000200, 0x00000000, 0x00020208, 0x08000200,
87 0x00020008, 0x08000008, 0x08000008, 0x00020000,
88 0x08020208, 0x00020008, 0x08020000, 0x00000208,
89 0x08000000, 0x00000008, 0x08020200, 0x00000200,
90 0x00020200, 0x08020000, 0x08020008, 0x00020208,
91 0x08000208, 0x00020200, 0x00020000, 0x08000208,
92 0x00000008, 0x08020208, 0x00000200, 0x08000000,
93 0x08020200, 0x08000000, 0x00020008, 0x00000208,
94 0x00020000, 0x08020200, 0x08000200, 0x00000000,
95 0x00000200, 0x00020008, 0x08020208, 0x08000200,
96 0x08000008, 0x00000200, 0x00000000, 0x08020008,
97 0x08000208, 0x00020000, 0x08000000, 0x08020208,
98 0x00000008, 0x00020208, 0x00020200, 0x08000008,
99 0x08020000, 0x08000208, 0x00000208, 0x08020000,
100 0x00020208, 0x00000008, 0x08020008, 0x00020200
101};
102
Paul Bakker5c2364c2012-10-01 14:41:15 +0000103static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000104{
105 0x00802001, 0x00002081, 0x00002081, 0x00000080,
106 0x00802080, 0x00800081, 0x00800001, 0x00002001,
107 0x00000000, 0x00802000, 0x00802000, 0x00802081,
108 0x00000081, 0x00000000, 0x00800080, 0x00800001,
109 0x00000001, 0x00002000, 0x00800000, 0x00802001,
110 0x00000080, 0x00800000, 0x00002001, 0x00002080,
111 0x00800081, 0x00000001, 0x00002080, 0x00800080,
112 0x00002000, 0x00802080, 0x00802081, 0x00000081,
113 0x00800080, 0x00800001, 0x00802000, 0x00802081,
114 0x00000081, 0x00000000, 0x00000000, 0x00802000,
115 0x00002080, 0x00800080, 0x00800081, 0x00000001,
116 0x00802001, 0x00002081, 0x00002081, 0x00000080,
117 0x00802081, 0x00000081, 0x00000001, 0x00002000,
118 0x00800001, 0x00002001, 0x00802080, 0x00800081,
119 0x00002001, 0x00002080, 0x00800000, 0x00802001,
120 0x00000080, 0x00800000, 0x00002000, 0x00802080
121};
122
Paul Bakker5c2364c2012-10-01 14:41:15 +0000123static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000124{
125 0x00000100, 0x02080100, 0x02080000, 0x42000100,
126 0x00080000, 0x00000100, 0x40000000, 0x02080000,
127 0x40080100, 0x00080000, 0x02000100, 0x40080100,
128 0x42000100, 0x42080000, 0x00080100, 0x40000000,
129 0x02000000, 0x40080000, 0x40080000, 0x00000000,
130 0x40000100, 0x42080100, 0x42080100, 0x02000100,
131 0x42080000, 0x40000100, 0x00000000, 0x42000000,
132 0x02080100, 0x02000000, 0x42000000, 0x00080100,
133 0x00080000, 0x42000100, 0x00000100, 0x02000000,
134 0x40000000, 0x02080000, 0x42000100, 0x40080100,
135 0x02000100, 0x40000000, 0x42080000, 0x02080100,
136 0x40080100, 0x00000100, 0x02000000, 0x42080000,
137 0x42080100, 0x00080100, 0x42000000, 0x42080100,
138 0x02080000, 0x00000000, 0x40080000, 0x42000000,
139 0x00080100, 0x02000100, 0x40000100, 0x00080000,
140 0x00000000, 0x40080000, 0x02080100, 0x40000100
141};
142
Paul Bakker5c2364c2012-10-01 14:41:15 +0000143static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000144{
145 0x20000010, 0x20400000, 0x00004000, 0x20404010,
146 0x20400000, 0x00000010, 0x20404010, 0x00400000,
147 0x20004000, 0x00404010, 0x00400000, 0x20000010,
148 0x00400010, 0x20004000, 0x20000000, 0x00004010,
149 0x00000000, 0x00400010, 0x20004010, 0x00004000,
150 0x00404000, 0x20004010, 0x00000010, 0x20400010,
151 0x20400010, 0x00000000, 0x00404010, 0x20404000,
152 0x00004010, 0x00404000, 0x20404000, 0x20000000,
153 0x20004000, 0x00000010, 0x20400010, 0x00404000,
154 0x20404010, 0x00400000, 0x00004010, 0x20000010,
155 0x00400000, 0x20004000, 0x20000000, 0x00004010,
156 0x20000010, 0x20404010, 0x00404000, 0x20400000,
157 0x00404010, 0x20404000, 0x00000000, 0x20400010,
158 0x00000010, 0x00004000, 0x20400000, 0x00404010,
159 0x00004000, 0x00400010, 0x20004010, 0x00000000,
160 0x20404000, 0x20000000, 0x00400010, 0x20004010
161};
162
Paul Bakker5c2364c2012-10-01 14:41:15 +0000163static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000164{
165 0x00200000, 0x04200002, 0x04000802, 0x00000000,
166 0x00000800, 0x04000802, 0x00200802, 0x04200800,
167 0x04200802, 0x00200000, 0x00000000, 0x04000002,
168 0x00000002, 0x04000000, 0x04200002, 0x00000802,
169 0x04000800, 0x00200802, 0x00200002, 0x04000800,
170 0x04000002, 0x04200000, 0x04200800, 0x00200002,
171 0x04200000, 0x00000800, 0x00000802, 0x04200802,
172 0x00200800, 0x00000002, 0x04000000, 0x00200800,
173 0x04000000, 0x00200800, 0x00200000, 0x04000802,
174 0x04000802, 0x04200002, 0x04200002, 0x00000002,
175 0x00200002, 0x04000000, 0x04000800, 0x00200000,
176 0x04200800, 0x00000802, 0x00200802, 0x04200800,
177 0x00000802, 0x04000002, 0x04200802, 0x04200000,
178 0x00200800, 0x00000000, 0x00000002, 0x04200802,
179 0x00000000, 0x00200802, 0x04200000, 0x00000800,
180 0x04000002, 0x04000800, 0x00000800, 0x00200002
181};
182
Paul Bakker5c2364c2012-10-01 14:41:15 +0000183static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000184{
185 0x10001040, 0x00001000, 0x00040000, 0x10041040,
186 0x10000000, 0x10001040, 0x00000040, 0x10000000,
187 0x00040040, 0x10040000, 0x10041040, 0x00041000,
188 0x10041000, 0x00041040, 0x00001000, 0x00000040,
189 0x10040000, 0x10000040, 0x10001000, 0x00001040,
190 0x00041000, 0x00040040, 0x10040040, 0x10041000,
191 0x00001040, 0x00000000, 0x00000000, 0x10040040,
192 0x10000040, 0x10001000, 0x00041040, 0x00040000,
193 0x00041040, 0x00040000, 0x10041000, 0x00001000,
194 0x00000040, 0x10040040, 0x00001000, 0x00041040,
195 0x10001000, 0x00000040, 0x10000040, 0x10040000,
196 0x10040040, 0x10000000, 0x00040000, 0x10001040,
197 0x00000000, 0x10041040, 0x00040040, 0x10000040,
198 0x10040000, 0x10001000, 0x10001040, 0x00000000,
199 0x10041040, 0x00041000, 0x00041000, 0x00001040,
200 0x00001040, 0x00040040, 0x10000000, 0x10041000
201};
202
203/*
204 * PC1: left and right halves bit-swap
205 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000206static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000207{
208 0x00000000, 0x00000001, 0x00000100, 0x00000101,
209 0x00010000, 0x00010001, 0x00010100, 0x00010101,
210 0x01000000, 0x01000001, 0x01000100, 0x01000101,
211 0x01010000, 0x01010001, 0x01010100, 0x01010101
212};
213
Paul Bakker5c2364c2012-10-01 14:41:15 +0000214static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000215{
216 0x00000000, 0x01000000, 0x00010000, 0x01010000,
217 0x00000100, 0x01000100, 0x00010100, 0x01010100,
218 0x00000001, 0x01000001, 0x00010001, 0x01010001,
219 0x00000101, 0x01000101, 0x00010101, 0x01010101,
220};
221
222/*
223 * Initial Permutation macro
224 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100225#define DES_IP(X,Y) \
226 do \
227 { \
228 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
229 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
230 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
231 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
232 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
233 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
234 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
235 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000236
237/*
238 * Final Permutation macro
239 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100240#define DES_FP(X,Y) \
241 do \
242 { \
243 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
244 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
245 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
246 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
247 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
248 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
249 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
250 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000251
252/*
253 * DES round macro
254 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100255#define DES_ROUND(X,Y) \
256 do \
257 { \
258 T = *SK++ ^ (X); \
259 (Y) ^= SB8[ (T ) & 0x3F ] ^ \
260 SB6[ (T >> 8) & 0x3F ] ^ \
261 SB4[ (T >> 16) & 0x3F ] ^ \
262 SB2[ (T >> 24) & 0x3F ]; \
263 \
264 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
265 (Y) ^= SB7[ (T ) & 0x3F ] ^ \
266 SB5[ (T >> 8) & 0x3F ] ^ \
267 SB3[ (T >> 16) & 0x3F ] ^ \
268 SB1[ (T >> 24) & 0x3F ]; \
269 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000270
Hanno Becker1eeca412018-10-15 12:01:35 +0100271#define SWAP(a,b) \
272 do \
273 { \
274 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
275 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200277void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200278{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200279 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200280}
281
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200282void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200283{
284 if( ctx == NULL )
285 return;
286
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500287 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200288}
289
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200290void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200291{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200293}
294
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200296{
297 if( ctx == NULL )
298 return;
299
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500300 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200301}
302
Paul Bakker1f87fb62011-01-15 17:32:24 +0000303static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
304 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
305 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
306 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
307 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
308 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
309 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
310 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
311 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
312 254 };
313
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000315{
316 int i;
317
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000319 key[i] = odd_parity_table[key[i] / 2];
320}
321
322/*
323 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
324 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000326{
327 int i;
328
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200330 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000331 return( 1 );
332
333 return( 0 );
334}
335
336/*
337 * Table of weak and semi-weak keys
338 *
339 * Source: http://en.wikipedia.org/wiki/Weak_key
340 *
341 * Weak:
342 * Alternating ones + zeros (0x0101010101010101)
343 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
344 * '0xE0E0E0E0F1F1F1F1'
345 * '0x1F1F1F1F0E0E0E0E'
346 *
347 * Semi-weak:
348 * 0x011F011F010E010E and 0x1F011F010E010E01
349 * 0x01E001E001F101F1 and 0xE001E001F101F101
350 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
351 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
352 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
353 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
354 *
355 */
356
357#define WEAK_KEY_COUNT 16
358
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000360{
361 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
362 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
363 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
364 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
365
366 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
367 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
368 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
369 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
370 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
371 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
372 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
373 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
374 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
375 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
376 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
377 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
378};
379
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200380int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000381{
382 int i;
383
384 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000386 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000387
Paul Bakker73206952011-07-06 14:37:33 +0000388 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000389}
390
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200391#if !defined(MBEDTLS_DES_SETKEY_ALT)
392void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000393{
394 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000395 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
Joe Subbiani6a506312021-07-07 16:56:29 +0100397 X = MBEDTLS_GET_UINT32_BE( key, 0 );
398 Y = MBEDTLS_GET_UINT32_BE( key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
400 /*
401 * Permuted Choice 1
402 */
403 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
404 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
405
406 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
407 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
408 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
409 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
410
411 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
412 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
413 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
414 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
415
416 X &= 0x0FFFFFFF;
417 Y &= 0x0FFFFFFF;
418
419 /*
420 * calculate subkeys
421 */
422 for( i = 0; i < 16; i++ )
423 {
424 if( i < 2 || i == 8 || i == 15 )
425 {
426 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
427 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
428 }
429 else
430 {
431 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
432 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
433 }
434
435 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
436 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
437 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
438 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
439 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
440 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
441 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
442 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
443 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
444 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
445 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
446
447 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
448 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
449 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
450 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
451 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
452 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
453 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
454 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
455 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
456 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
457 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
458 }
459}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200460#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
462/*
463 * DES key schedule (56-bit, encryption)
464 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000466{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200467 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000468
469 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000470}
471
472/*
473 * DES key schedule (56-bit, decryption)
474 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000476{
477 int i;
478
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200479 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
481 for( i = 0; i < 16; i += 2 )
482 {
483 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
484 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
485 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000486
487 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000488}
489
Paul Bakker5c2364c2012-10-01 14:41:15 +0000490static void des3_set2key( uint32_t esk[96],
491 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000493{
494 int i;
495
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200496 mbedtls_des_setkey( esk, key );
497 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000498
499 for( i = 0; i < 32; i += 2 )
500 {
501 dsk[i ] = esk[30 - i];
502 dsk[i + 1] = esk[31 - i];
503
504 esk[i + 32] = dsk[62 - i];
505 esk[i + 33] = dsk[63 - i];
506
507 esk[i + 64] = esk[i ];
508 esk[i + 65] = esk[i + 1];
509
510 dsk[i + 64] = dsk[i ];
511 dsk[i + 65] = dsk[i + 1];
512 }
513}
514
515/*
516 * Triple-DES key schedule (112-bit, encryption)
517 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
519 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000520{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000521 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000522
523 des3_set2key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500524 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000525
526 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000527}
528
529/*
530 * Triple-DES key schedule (112-bit, decryption)
531 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
533 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000534{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000535 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000536
537 des3_set2key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500538 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000539
540 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000541}
542
Paul Bakker5c2364c2012-10-01 14:41:15 +0000543static void des3_set3key( uint32_t esk[96],
544 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000545 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000546{
547 int i;
548
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200549 mbedtls_des_setkey( esk, key );
550 mbedtls_des_setkey( dsk + 32, key + 8 );
551 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
553 for( i = 0; i < 32; i += 2 )
554 {
555 dsk[i ] = esk[94 - i];
556 dsk[i + 1] = esk[95 - i];
557
558 esk[i + 32] = dsk[62 - i];
559 esk[i + 33] = dsk[63 - i];
560
561 dsk[i + 64] = esk[30 - i];
562 dsk[i + 65] = esk[31 - i];
563 }
564}
565
566/*
567 * Triple-DES key schedule (168-bit, encryption)
568 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
570 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000571{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000572 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
574 des3_set3key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500575 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000576
577 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000578}
579
580/*
581 * Triple-DES key schedule (168-bit, decryption)
582 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
584 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000585{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000586 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
588 des3_set3key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500589 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000590
591 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000592}
593
594/*
595 * DES-ECB block encryption/decryption
596 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200597#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000599 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000600 unsigned char output[8] )
601{
602 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000603 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
605 SK = ctx->sk;
606
Joe Subbiani6a506312021-07-07 16:56:29 +0100607 X = MBEDTLS_GET_UINT32_BE( input, 0 );
608 Y = MBEDTLS_GET_UINT32_BE( input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
610 DES_IP( X, Y );
611
612 for( i = 0; i < 8; i++ )
613 {
614 DES_ROUND( Y, X );
615 DES_ROUND( X, Y );
616 }
617
618 DES_FP( Y, X );
619
Joe Subbiani5ecac212021-06-24 13:00:03 +0100620 MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
621 MBEDTLS_PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000622
623 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000624}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200625#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000628/*
629 * DES-CBC buffer encryption/decryption
630 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000633 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000635 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 unsigned char *output )
637{
Gilles Peskine7820a572021-07-07 21:08:28 +0200638 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000639 unsigned char temp[8];
640
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000641 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000643
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000645 {
646 while( length > 0 )
647 {
Dave Rodgman2e9db8e2022-11-22 16:43:29 +0000648 mbedtls_xor( output, input, iv, 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
Gilles Peskine7820a572021-07-07 21:08:28 +0200650 ret = mbedtls_des_crypt_ecb( ctx, output, output );
651 if( ret != 0 )
652 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000653 memcpy( iv, output, 8 );
654
655 input += 8;
656 output += 8;
657 length -= 8;
658 }
659 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 {
662 while( length > 0 )
663 {
664 memcpy( temp, input, 8 );
Gilles Peskine7820a572021-07-07 21:08:28 +0200665 ret = mbedtls_des_crypt_ecb( ctx, input, output );
666 if( ret != 0 )
667 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
Dave Rodgman2e9db8e2022-11-22 16:43:29 +0000669 mbedtls_xor( output, output, iv, 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000670
671 memcpy( iv, temp, 8 );
672
673 input += 8;
674 output += 8;
675 length -= 8;
676 }
677 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200678 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000679
Gilles Peskine7820a572021-07-07 21:08:28 +0200680exit:
681 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000682}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200683#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
685/*
686 * 3DES-ECB block encryption/decryption
687 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200688#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000690 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000691 unsigned char output[8] )
692{
693 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000694 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000695
696 SK = ctx->sk;
697
Joe Subbiani6a506312021-07-07 16:56:29 +0100698 X = MBEDTLS_GET_UINT32_BE( input, 0 );
699 Y = MBEDTLS_GET_UINT32_BE( input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
701 DES_IP( X, Y );
702
703 for( i = 0; i < 8; i++ )
704 {
705 DES_ROUND( Y, X );
706 DES_ROUND( X, Y );
707 }
708
709 for( i = 0; i < 8; i++ )
710 {
711 DES_ROUND( X, Y );
712 DES_ROUND( Y, X );
713 }
714
715 for( i = 0; i < 8; i++ )
716 {
717 DES_ROUND( Y, X );
718 DES_ROUND( X, Y );
719 }
720
721 DES_FP( Y, X );
722
Joe Subbiani5ecac212021-06-24 13:00:03 +0100723 MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
724 MBEDTLS_PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000725
726 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000727}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200728#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000729
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200730#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000731/*
732 * 3DES-CBC buffer encryption/decryption
733 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200734int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000735 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000736 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000737 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000738 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000739 unsigned char *output )
740{
Gilles Peskine7820a572021-07-07 21:08:28 +0200741 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000742 unsigned char temp[8];
743
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000744 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200745 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000746
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200747 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000748 {
749 while( length > 0 )
750 {
Dave Rodgman2e9db8e2022-11-22 16:43:29 +0000751 mbedtls_xor( output, input, iv, 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000752
Gilles Peskine7820a572021-07-07 21:08:28 +0200753 ret = mbedtls_des3_crypt_ecb( ctx, output, output );
754 if( ret != 0 )
755 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000756 memcpy( iv, output, 8 );
757
758 input += 8;
759 output += 8;
760 length -= 8;
761 }
762 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200763 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000764 {
765 while( length > 0 )
766 {
767 memcpy( temp, input, 8 );
Gilles Peskine7820a572021-07-07 21:08:28 +0200768 ret = mbedtls_des3_crypt_ecb( ctx, input, output );
769 if( ret != 0 )
770 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Dave Rodgman2e9db8e2022-11-22 16:43:29 +0000772 mbedtls_xor( output, output, iv, 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000773
774 memcpy( iv, temp, 8 );
775
776 input += 8;
777 output += 8;
778 length -= 8;
779 }
780 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200781 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000782
Gilles Peskine7820a572021-07-07 21:08:28 +0200783exit:
784 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000785}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000787
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200789
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000791/*
792 * DES and 3DES test vectors from:
793 *
794 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
795 */
796static const unsigned char des3_test_keys[24] =
797{
798 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
799 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
800 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
801};
802
Paul Bakker5121ce52009-01-03 21:22:43 +0000803static const unsigned char des3_test_buf[8] =
804{
805 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
806};
807
808static const unsigned char des3_test_ecb_dec[3][8] =
809{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100810 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
811 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
812 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000813};
814
815static const unsigned char des3_test_ecb_enc[3][8] =
816{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100817 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
818 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
819 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000820};
821
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200822#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100823static const unsigned char des3_test_iv[8] =
824{
825 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
826};
827
Paul Bakker5121ce52009-01-03 21:22:43 +0000828static const unsigned char des3_test_cbc_dec[3][8] =
829{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100830 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
831 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
832 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000833};
834
835static const unsigned char des3_test_cbc_enc[3][8] =
836{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100837 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
838 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
839 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000840};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000842
843/*
844 * Checkup routine
845 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000847{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200848 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849 mbedtls_des_context ctx;
850 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000851 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000853 unsigned char prv[8];
854 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200855#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000856
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857 mbedtls_des_init( &ctx );
858 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000859 /*
860 * ECB mode
861 */
862 for( i = 0; i < 6; i++ )
863 {
864 u = i >> 1;
865 v = i & 1;
866
867 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100869 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000871
872 memcpy( buf, des3_test_buf, 8 );
873
874 switch( i )
875 {
876 case 0:
Gilles Peskine7820a572021-07-07 21:08:28 +0200877 ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000878 break;
879
880 case 1:
Gilles Peskine7820a572021-07-07 21:08:28 +0200881 ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000882 break;
883
884 case 2:
Gilles Peskine7820a572021-07-07 21:08:28 +0200885 ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000886 break;
887
888 case 3:
Gilles Peskine7820a572021-07-07 21:08:28 +0200889 ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000890 break;
891
892 case 4:
Gilles Peskine7820a572021-07-07 21:08:28 +0200893 ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000894 break;
895
896 case 5:
Gilles Peskine7820a572021-07-07 21:08:28 +0200897 ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000898 break;
899
900 default:
901 return( 1 );
902 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200903 if( ret != 0 )
904 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000905
Jaeden Amero355b4b02019-05-29 10:13:23 +0100906 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000907 {
908 if( u == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +0200909 ret = mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000910 else
Gilles Peskine7820a572021-07-07 21:08:28 +0200911 ret = mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
912 if( ret != 0 )
913 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000914 }
915
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000917 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000919 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
920 {
921 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000923
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200924 ret = 1;
925 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000926 }
927
928 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000930 }
931
932 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000934
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000936 /*
937 * CBC mode
938 */
939 for( i = 0; i < 6; i++ )
940 {
941 u = i >> 1;
942 v = i & 1;
943
944 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200945 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100946 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000948
949 memcpy( iv, des3_test_iv, 8 );
950 memcpy( prv, des3_test_iv, 8 );
951 memcpy( buf, des3_test_buf, 8 );
952
953 switch( i )
954 {
955 case 0:
Gilles Peskine7820a572021-07-07 21:08:28 +0200956 ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000957 break;
958
959 case 1:
Gilles Peskine7820a572021-07-07 21:08:28 +0200960 ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000961 break;
962
963 case 2:
Gilles Peskine7820a572021-07-07 21:08:28 +0200964 ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000965 break;
966
967 case 3:
Gilles Peskine7820a572021-07-07 21:08:28 +0200968 ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000969 break;
970
971 case 4:
Gilles Peskine7820a572021-07-07 21:08:28 +0200972 ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000973 break;
974
975 case 5:
Gilles Peskine7820a572021-07-07 21:08:28 +0200976 ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000977 break;
978
979 default:
980 return( 1 );
981 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200982 if( ret != 0 )
983 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000984
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 {
Jaeden Amero355b4b02019-05-29 10:13:23 +0100987 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000988 {
989 if( u == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +0200990 ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000991 else
Gilles Peskine7820a572021-07-07 21:08:28 +0200992 ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
993 if( ret != 0 )
994 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000995 }
996 }
997 else
998 {
Jaeden Amero355b4b02019-05-29 10:13:23 +0100999 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001000 {
1001 unsigned char tmp[8];
1002
1003 if( u == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +02001004 ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 else
Gilles Peskine7820a572021-07-07 21:08:28 +02001006 ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
1007 if( ret != 0 )
1008 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001009
1010 memcpy( tmp, prv, 8 );
1011 memcpy( prv, buf, 8 );
1012 memcpy( buf, tmp, 8 );
1013 }
1014
1015 memcpy( buf, prv, 8 );
1016 }
1017
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001018 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001019 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001021 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1022 {
1023 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001025
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001026 ret = 1;
1027 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001028 }
1029
1030 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001031 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001032 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001034
1035 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001038exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001039 mbedtls_des_free( &ctx );
1040 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001041
Gilles Peskine7820a572021-07-07 21:08:28 +02001042 if( ret != 0 )
1043 ret = 1;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001044 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001045}
1046
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049#endif /* MBEDTLS_DES_C */