blob: 5410bd39beb9353615818539f133afbebe7563fa [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
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker5121ce52009-01-03 21:22:43 +00006 */
7/*
8 * DES, on which TDES is based, was originally designed by Horst Feistel
9 * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
10 *
11 * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
12 */
13
Gilles Peskinedb09ef62020-06-03 01:43:33 +020014#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000015
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020016#if defined(MBEDTLS_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000017
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000018#include "mbedtls/des.h"
Gilles Peskine7820a572021-07-07 21:08:28 +020019#include "mbedtls/error.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050020#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000021
Rich Evans00ab4702015-02-06 13:43:58 +000022#include <string.h>
23
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000024#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010025
Paul Bakker5121ce52009-01-03 21:22:43 +000026/*
Paul Bakker5121ce52009-01-03 21:22:43 +000027 * Expanded DES S-boxes
28 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000029static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000030{
31 0x01010400, 0x00000000, 0x00010000, 0x01010404,
32 0x01010004, 0x00010404, 0x00000004, 0x00010000,
33 0x00000400, 0x01010400, 0x01010404, 0x00000400,
34 0x01000404, 0x01010004, 0x01000000, 0x00000004,
35 0x00000404, 0x01000400, 0x01000400, 0x00010400,
36 0x00010400, 0x01010000, 0x01010000, 0x01000404,
37 0x00010004, 0x01000004, 0x01000004, 0x00010004,
38 0x00000000, 0x00000404, 0x00010404, 0x01000000,
39 0x00010000, 0x01010404, 0x00000004, 0x01010000,
40 0x01010400, 0x01000000, 0x01000000, 0x00000400,
41 0x01010004, 0x00010000, 0x00010400, 0x01000004,
42 0x00000400, 0x00000004, 0x01000404, 0x00010404,
43 0x01010404, 0x00010004, 0x01010000, 0x01000404,
44 0x01000004, 0x00000404, 0x00010404, 0x01010400,
45 0x00000404, 0x01000400, 0x01000400, 0x00000000,
46 0x00010004, 0x00010400, 0x00000000, 0x01010004
47};
48
Paul Bakker5c2364c2012-10-01 14:41:15 +000049static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000050{
51 0x80108020, 0x80008000, 0x00008000, 0x00108020,
52 0x00100000, 0x00000020, 0x80100020, 0x80008020,
53 0x80000020, 0x80108020, 0x80108000, 0x80000000,
54 0x80008000, 0x00100000, 0x00000020, 0x80100020,
55 0x00108000, 0x00100020, 0x80008020, 0x00000000,
56 0x80000000, 0x00008000, 0x00108020, 0x80100000,
57 0x00100020, 0x80000020, 0x00000000, 0x00108000,
58 0x00008020, 0x80108000, 0x80100000, 0x00008020,
59 0x00000000, 0x00108020, 0x80100020, 0x00100000,
60 0x80008020, 0x80100000, 0x80108000, 0x00008000,
61 0x80100000, 0x80008000, 0x00000020, 0x80108020,
62 0x00108020, 0x00000020, 0x00008000, 0x80000000,
63 0x00008020, 0x80108000, 0x00100000, 0x80000020,
64 0x00100020, 0x80008020, 0x80000020, 0x00100020,
65 0x00108000, 0x00000000, 0x80008000, 0x00008020,
66 0x80000000, 0x80100020, 0x80108020, 0x00108000
67};
68
Paul Bakker5c2364c2012-10-01 14:41:15 +000069static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000070{
71 0x00000208, 0x08020200, 0x00000000, 0x08020008,
72 0x08000200, 0x00000000, 0x00020208, 0x08000200,
73 0x00020008, 0x08000008, 0x08000008, 0x00020000,
74 0x08020208, 0x00020008, 0x08020000, 0x00000208,
75 0x08000000, 0x00000008, 0x08020200, 0x00000200,
76 0x00020200, 0x08020000, 0x08020008, 0x00020208,
77 0x08000208, 0x00020200, 0x00020000, 0x08000208,
78 0x00000008, 0x08020208, 0x00000200, 0x08000000,
79 0x08020200, 0x08000000, 0x00020008, 0x00000208,
80 0x00020000, 0x08020200, 0x08000200, 0x00000000,
81 0x00000200, 0x00020008, 0x08020208, 0x08000200,
82 0x08000008, 0x00000200, 0x00000000, 0x08020008,
83 0x08000208, 0x00020000, 0x08000000, 0x08020208,
84 0x00000008, 0x00020208, 0x00020200, 0x08000008,
85 0x08020000, 0x08000208, 0x00000208, 0x08020000,
86 0x00020208, 0x00000008, 0x08020008, 0x00020200
87};
88
Paul Bakker5c2364c2012-10-01 14:41:15 +000089static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000090{
91 0x00802001, 0x00002081, 0x00002081, 0x00000080,
92 0x00802080, 0x00800081, 0x00800001, 0x00002001,
93 0x00000000, 0x00802000, 0x00802000, 0x00802081,
94 0x00000081, 0x00000000, 0x00800080, 0x00800001,
95 0x00000001, 0x00002000, 0x00800000, 0x00802001,
96 0x00000080, 0x00800000, 0x00002001, 0x00002080,
97 0x00800081, 0x00000001, 0x00002080, 0x00800080,
98 0x00002000, 0x00802080, 0x00802081, 0x00000081,
99 0x00800080, 0x00800001, 0x00802000, 0x00802081,
100 0x00000081, 0x00000000, 0x00000000, 0x00802000,
101 0x00002080, 0x00800080, 0x00800081, 0x00000001,
102 0x00802001, 0x00002081, 0x00002081, 0x00000080,
103 0x00802081, 0x00000081, 0x00000001, 0x00002000,
104 0x00800001, 0x00002001, 0x00802080, 0x00800081,
105 0x00002001, 0x00002080, 0x00800000, 0x00802001,
106 0x00000080, 0x00800000, 0x00002000, 0x00802080
107};
108
Paul Bakker5c2364c2012-10-01 14:41:15 +0000109static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000110{
111 0x00000100, 0x02080100, 0x02080000, 0x42000100,
112 0x00080000, 0x00000100, 0x40000000, 0x02080000,
113 0x40080100, 0x00080000, 0x02000100, 0x40080100,
114 0x42000100, 0x42080000, 0x00080100, 0x40000000,
115 0x02000000, 0x40080000, 0x40080000, 0x00000000,
116 0x40000100, 0x42080100, 0x42080100, 0x02000100,
117 0x42080000, 0x40000100, 0x00000000, 0x42000000,
118 0x02080100, 0x02000000, 0x42000000, 0x00080100,
119 0x00080000, 0x42000100, 0x00000100, 0x02000000,
120 0x40000000, 0x02080000, 0x42000100, 0x40080100,
121 0x02000100, 0x40000000, 0x42080000, 0x02080100,
122 0x40080100, 0x00000100, 0x02000000, 0x42080000,
123 0x42080100, 0x00080100, 0x42000000, 0x42080100,
124 0x02080000, 0x00000000, 0x40080000, 0x42000000,
125 0x00080100, 0x02000100, 0x40000100, 0x00080000,
126 0x00000000, 0x40080000, 0x02080100, 0x40000100
127};
128
Paul Bakker5c2364c2012-10-01 14:41:15 +0000129static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000130{
131 0x20000010, 0x20400000, 0x00004000, 0x20404010,
132 0x20400000, 0x00000010, 0x20404010, 0x00400000,
133 0x20004000, 0x00404010, 0x00400000, 0x20000010,
134 0x00400010, 0x20004000, 0x20000000, 0x00004010,
135 0x00000000, 0x00400010, 0x20004010, 0x00004000,
136 0x00404000, 0x20004010, 0x00000010, 0x20400010,
137 0x20400010, 0x00000000, 0x00404010, 0x20404000,
138 0x00004010, 0x00404000, 0x20404000, 0x20000000,
139 0x20004000, 0x00000010, 0x20400010, 0x00404000,
140 0x20404010, 0x00400000, 0x00004010, 0x20000010,
141 0x00400000, 0x20004000, 0x20000000, 0x00004010,
142 0x20000010, 0x20404010, 0x00404000, 0x20400000,
143 0x00404010, 0x20404000, 0x00000000, 0x20400010,
144 0x00000010, 0x00004000, 0x20400000, 0x00404010,
145 0x00004000, 0x00400010, 0x20004010, 0x00000000,
146 0x20404000, 0x20000000, 0x00400010, 0x20004010
147};
148
Paul Bakker5c2364c2012-10-01 14:41:15 +0000149static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000150{
151 0x00200000, 0x04200002, 0x04000802, 0x00000000,
152 0x00000800, 0x04000802, 0x00200802, 0x04200800,
153 0x04200802, 0x00200000, 0x00000000, 0x04000002,
154 0x00000002, 0x04000000, 0x04200002, 0x00000802,
155 0x04000800, 0x00200802, 0x00200002, 0x04000800,
156 0x04000002, 0x04200000, 0x04200800, 0x00200002,
157 0x04200000, 0x00000800, 0x00000802, 0x04200802,
158 0x00200800, 0x00000002, 0x04000000, 0x00200800,
159 0x04000000, 0x00200800, 0x00200000, 0x04000802,
160 0x04000802, 0x04200002, 0x04200002, 0x00000002,
161 0x00200002, 0x04000000, 0x04000800, 0x00200000,
162 0x04200800, 0x00000802, 0x00200802, 0x04200800,
163 0x00000802, 0x04000002, 0x04200802, 0x04200000,
164 0x00200800, 0x00000000, 0x00000002, 0x04200802,
165 0x00000000, 0x00200802, 0x04200000, 0x00000800,
166 0x04000002, 0x04000800, 0x00000800, 0x00200002
167};
168
Paul Bakker5c2364c2012-10-01 14:41:15 +0000169static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000170{
171 0x10001040, 0x00001000, 0x00040000, 0x10041040,
172 0x10000000, 0x10001040, 0x00000040, 0x10000000,
173 0x00040040, 0x10040000, 0x10041040, 0x00041000,
174 0x10041000, 0x00041040, 0x00001000, 0x00000040,
175 0x10040000, 0x10000040, 0x10001000, 0x00001040,
176 0x00041000, 0x00040040, 0x10040040, 0x10041000,
177 0x00001040, 0x00000000, 0x00000000, 0x10040040,
178 0x10000040, 0x10001000, 0x00041040, 0x00040000,
179 0x00041040, 0x00040000, 0x10041000, 0x00001000,
180 0x00000040, 0x10040040, 0x00001000, 0x00041040,
181 0x10001000, 0x00000040, 0x10000040, 0x10040000,
182 0x10040040, 0x10000000, 0x00040000, 0x10001040,
183 0x00000000, 0x10041040, 0x00040040, 0x10000040,
184 0x10040000, 0x10001000, 0x10001040, 0x00000000,
185 0x10041040, 0x00041000, 0x00041000, 0x00001040,
186 0x00001040, 0x00040040, 0x10000000, 0x10041000
187};
188
189/*
190 * PC1: left and right halves bit-swap
191 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000192static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000193{
194 0x00000000, 0x00000001, 0x00000100, 0x00000101,
195 0x00010000, 0x00010001, 0x00010100, 0x00010101,
196 0x01000000, 0x01000001, 0x01000100, 0x01000101,
197 0x01010000, 0x01010001, 0x01010100, 0x01010101
198};
199
Paul Bakker5c2364c2012-10-01 14:41:15 +0000200static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000201{
202 0x00000000, 0x01000000, 0x00010000, 0x01010000,
203 0x00000100, 0x01000100, 0x00010100, 0x01010100,
204 0x00000001, 0x01000001, 0x00010001, 0x01010001,
205 0x00000101, 0x01000101, 0x00010101, 0x01010101,
206};
207
208/*
209 * Initial Permutation macro
210 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100211#define DES_IP(X, Y) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100212 do \
213 { \
214 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
215 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
216 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
217 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
218 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
219 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
220 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000222
223/*
224 * Final Permutation macro
225 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100226#define DES_FP(X, Y) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100227 do \
228 { \
229 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
230 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
231 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
232 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
233 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
234 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
235 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000237
238/*
239 * DES round macro
240 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100241#define DES_ROUND(X, Y) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100242 do \
243 { \
244 T = *SK++ ^ (X); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 (Y) ^= SB8[(T) & 0x3F] ^ \
246 SB6[(T >> 8) & 0x3F] ^ \
247 SB4[(T >> 16) & 0x3F] ^ \
248 SB2[(T >> 24) & 0x3F]; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100249 \
250 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 (Y) ^= SB7[(T) & 0x3F] ^ \
252 SB5[(T >> 8) & 0x3F] ^ \
253 SB3[(T >> 16) & 0x3F] ^ \
254 SB1[(T >> 24) & 0x3F]; \
255 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000256
Gilles Peskine449bd832023-01-11 14:50:10 +0100257#define SWAP(a, b) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100258 do \
259 { \
260 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263void mbedtls_des_init(mbedtls_des_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200264{
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 memset(ctx, 0, sizeof(mbedtls_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200266}
267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268void mbedtls_des_free(mbedtls_des_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200269{
Gilles Peskine449bd832023-01-11 14:50:10 +0100270 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200271 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100272 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200275}
276
Gilles Peskine449bd832023-01-11 14:50:10 +0100277void mbedtls_des3_init(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200278{
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 memset(ctx, 0, sizeof(mbedtls_des3_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200280}
281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282void mbedtls_des3_free(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200283{
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200285 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200287
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des3_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200289}
290
Paul Bakker1f87fb62011-01-15 17:32:24 +0000291static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32,
293 35, 37, 38, 41, 42, 44,
294 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69,
295 70, 73, 74, 76, 79, 81,
296 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103,
297 104, 107, 109, 110, 112,
298 115, 117, 118, 121, 122, 124, 127, 128, 131,
299 133, 134, 137, 138, 140,
300 143, 145, 146, 148, 151, 152, 155, 157, 158,
301 161, 162, 164, 167, 168,
302 171, 173, 174, 176, 179, 181, 182, 185, 186,
303 188, 191, 193, 194, 196,
304 199, 200, 203, 205, 206, 208, 211, 213, 214,
305 217, 218, 220, 223, 224,
306 227, 229, 230, 233, 234, 236, 239, 241, 242,
307 244, 247, 248, 251, 253,
308 254 };
Paul Bakker1f87fb62011-01-15 17:32:24 +0000309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker1f87fb62011-01-15 17:32:24 +0000311{
312 int i;
313
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) {
Paul Bakker1f87fb62011-01-15 17:32:24 +0000315 key[i] = odd_parity_table[key[i] / 2];
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 }
Paul Bakker1f87fb62011-01-15 17:32:24 +0000317}
318
319/*
320 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
321 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100322int mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker1f87fb62011-01-15 17:32:24 +0000323{
324 int i;
325
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) {
327 if (key[i] != odd_parity_table[key[i] / 2]) {
328 return 1;
329 }
330 }
Paul Bakker1f87fb62011-01-15 17:32:24 +0000331
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 return 0;
Paul Bakker1f87fb62011-01-15 17:32:24 +0000333}
334
335/*
336 * Table of weak and semi-weak keys
337 *
338 * Source: http://en.wikipedia.org/wiki/Weak_key
339 *
340 * Weak:
341 * Alternating ones + zeros (0x0101010101010101)
342 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
343 * '0xE0E0E0E0F1F1F1F1'
344 * '0x1F1F1F1F0E0E0E0E'
345 *
346 * Semi-weak:
347 * 0x011F011F010E010E and 0x1F011F010E010E01
348 * 0x01E001E001F101F1 and 0xE001E001F101F101
349 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
350 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
351 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
352 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
353 *
354 */
355
356#define WEAK_KEY_COUNT 16
357
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000359{
360 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
361 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
362 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
363 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
364
365 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
366 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
367 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
368 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
369 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
370 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
371 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
372 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
373 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
374 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
375 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
376 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
377};
378
Gilles Peskine449bd832023-01-11 14:50:10 +0100379int mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker1f87fb62011-01-15 17:32:24 +0000380{
381 int i;
382
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 for (i = 0; i < WEAK_KEY_COUNT; i++) {
384 if (memcmp(weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0) {
385 return 1;
386 }
387 }
Paul Bakker1f87fb62011-01-15 17:32:24 +0000388
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 return 0;
Paul Bakker1f87fb62011-01-15 17:32:24 +0000390}
391
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200392#if !defined(MBEDTLS_DES_SETKEY_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100393void mbedtls_des_setkey(uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000394{
395 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000396 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 X = MBEDTLS_GET_UINT32_BE(key, 0);
399 Y = MBEDTLS_GET_UINT32_BE(key, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000400
401 /*
402 * Permuted Choice 1
403 */
404 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 T = ((Y) ^ X) & 0x10101010; X ^= T; Y ^= (T);
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 X = (LHs[(X) & 0xF] << 3) | (LHs[(X >> 8) & 0xF] << 2)
408 | (LHs[(X >> 16) & 0xF] << 1) | (LHs[(X >> 24) & 0xF])
409 | (LHs[(X >> 5) & 0xF] << 7) | (LHs[(X >> 13) & 0xF] << 6)
410 | (LHs[(X >> 21) & 0xF] << 5) | (LHs[(X >> 29) & 0xF] << 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 Y = (RHs[(Y >> 1) & 0xF] << 3) | (RHs[(Y >> 9) & 0xF] << 2)
413 | (RHs[(Y >> 17) & 0xF] << 1) | (RHs[(Y >> 25) & 0xF])
414 | (RHs[(Y >> 4) & 0xF] << 7) | (RHs[(Y >> 12) & 0xF] << 6)
415 | (RHs[(Y >> 20) & 0xF] << 5) | (RHs[(Y >> 28) & 0xF] << 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
417 X &= 0x0FFFFFFF;
418 Y &= 0x0FFFFFFF;
419
420 /*
421 * calculate subkeys
422 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 for (i = 0; i < 16; i++) {
424 if (i < 2 || i == 8 || i == 15) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000425 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
426 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 } else {
Paul Bakker5121ce52009-01-03 21:22:43 +0000428 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
429 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
430 }
431
432 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
433 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
434 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
435 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
436 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
437 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
438 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 | ((Y >> 14) & 0x00000200) | ((Y) & 0x00000100)
Paul Bakker5121ce52009-01-03 21:22:43 +0000440 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
441 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
442 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
443
444 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
445 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
446 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
447 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
448 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
449 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
450 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
451 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 | ((Y) & 0x00000200) | ((Y << 7) & 0x00000100)
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
454 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
455 }
456}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200457#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000458
459/*
460 * DES key schedule (56-bit, encryption)
461 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100462int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000463{
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000467}
468
469/*
470 * DES key schedule (56-bit, decryption)
471 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100472int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000473{
474 int i;
475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 for (i = 0; i < 16; i += 2) {
479 SWAP(ctx->sk[i], ctx->sk[30 - i]);
480 SWAP(ctx->sk[i + 1], ctx->sk[31 - i]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000481 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000482
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000484}
485
Gilles Peskine449bd832023-01-11 14:50:10 +0100486static void des3_set2key(uint32_t esk[96],
487 uint32_t dsk[96],
488 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000489{
490 int i;
491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 mbedtls_des_setkey(esk, key);
493 mbedtls_des_setkey(dsk + 32, key + 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 for (i = 0; i < 32; i += 2) {
496 dsk[i] = esk[30 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000497 dsk[i + 1] = esk[31 - i];
498
499 esk[i + 32] = dsk[62 - i];
500 esk[i + 33] = dsk[63 - i];
501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 esk[i + 64] = esk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000503 esk[i + 65] = esk[i + 1];
504
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 dsk[i + 64] = dsk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000506 dsk[i + 65] = dsk[i + 1];
507 }
508}
509
510/*
511 * Triple-DES key schedule (112-bit, encryption)
512 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100513int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx,
514 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000515{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000516 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000517
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 des3_set2key(ctx->sk, sk, key);
519 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000520
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000522}
523
524/*
525 * Triple-DES key schedule (112-bit, decryption)
526 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100527int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx,
528 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000529{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000530 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000531
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 des3_set2key(sk, ctx->sk, key);
533 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000534
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000536}
537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538static void des3_set3key(uint32_t esk[96],
539 uint32_t dsk[96],
540 const unsigned char key[24])
Paul Bakker5121ce52009-01-03 21:22:43 +0000541{
542 int i;
543
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 mbedtls_des_setkey(esk, key);
545 mbedtls_des_setkey(dsk + 32, key + 8);
546 mbedtls_des_setkey(esk + 64, key + 16);
Paul Bakker5121ce52009-01-03 21:22:43 +0000547
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 for (i = 0; i < 32; i += 2) {
549 dsk[i] = esk[94 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000550 dsk[i + 1] = esk[95 - i];
551
552 esk[i + 32] = dsk[62 - i];
553 esk[i + 33] = dsk[63 - i];
554
555 dsk[i + 64] = esk[30 - i];
556 dsk[i + 65] = esk[31 - i];
557 }
558}
559
560/*
561 * Triple-DES key schedule (168-bit, encryption)
562 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100563int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx,
564 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000565{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000566 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000567
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 des3_set3key(ctx->sk, sk, key);
569 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000570
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000572}
573
574/*
575 * Triple-DES key schedule (168-bit, decryption)
576 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100577int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx,
578 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000579{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000580 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 des3_set3key(sk, ctx->sk, key);
583 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000584
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000586}
587
588/*
589 * DES-ECB block encryption/decryption
590 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200591#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100592int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx,
593 const unsigned char input[8],
594 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000595{
596 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000597 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000598
599 SK = ctx->sk;
600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 X = MBEDTLS_GET_UINT32_BE(input, 0);
602 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 for (i = 0; i < 8; i++) {
607 DES_ROUND(Y, X);
608 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000609 }
610
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
614 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000617}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200618#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000621/*
622 * DES-CBC buffer encryption/decryption
623 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100624int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
625 int mode,
626 size_t length,
627 unsigned char iv[8],
628 const unsigned char *input,
629 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000630{
Gilles Peskine7820a572021-07-07 21:08:28 +0200631 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 unsigned char temp[8];
633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 if (length % 8) {
635 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
636 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 if (mode == MBEDTLS_DES_ENCRYPT) {
639 while (length > 0) {
640 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 ret = mbedtls_des_crypt_ecb(ctx, output, output);
643 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200644 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 }
646 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000647
648 input += 8;
649 output += 8;
650 length -= 8;
651 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 } else { /* MBEDTLS_DES_DECRYPT */
653 while (length > 0) {
654 memcpy(temp, input, 8);
655 ret = mbedtls_des_crypt_ecb(ctx, input, output);
656 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200657 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000659
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000663
664 input += 8;
665 output += 8;
666 length -= 8;
667 }
668 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200669 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000670
Gilles Peskine7820a572021-07-07 21:08:28 +0200671exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000673}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200674#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
676/*
677 * 3DES-ECB block encryption/decryption
678 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200679#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100680int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
681 const unsigned char input[8],
682 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000683{
684 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000685 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000686
687 SK = ctx->sk;
688
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 X = MBEDTLS_GET_UINT32_BE(input, 0);
690 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 for (i = 0; i < 8; i++) {
695 DES_ROUND(Y, X);
696 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000697 }
698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 for (i = 0; i < 8; i++) {
700 DES_ROUND(X, Y);
701 DES_ROUND(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000702 }
703
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 for (i = 0; i < 8; i++) {
705 DES_ROUND(Y, X);
706 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000707 }
708
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
712 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000713
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000715}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200716#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200718#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000719/*
720 * 3DES-CBC buffer encryption/decryption
721 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100722int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
723 int mode,
724 size_t length,
725 unsigned char iv[8],
726 const unsigned char *input,
727 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000728{
Gilles Peskine7820a572021-07-07 21:08:28 +0200729 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000730 unsigned char temp[8];
731
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 if (length % 8) {
733 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
734 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000735
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 if (mode == MBEDTLS_DES_ENCRYPT) {
737 while (length > 0) {
738 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000739
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 ret = mbedtls_des3_crypt_ecb(ctx, output, output);
741 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200742 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 }
744 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000745
746 input += 8;
747 output += 8;
748 length -= 8;
749 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 } else { /* MBEDTLS_DES_DECRYPT */
751 while (length > 0) {
752 memcpy(temp, input, 8);
753 ret = mbedtls_des3_crypt_ecb(ctx, input, output);
754 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200755 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000757
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000759
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000761
762 input += 8;
763 output += 8;
764 length -= 8;
765 }
766 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200767 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000768
Gilles Peskine7820a572021-07-07 21:08:28 +0200769exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000771}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200772#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000773
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000775/*
776 * DES and 3DES test vectors from:
777 *
778 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
779 */
780static const unsigned char des3_test_keys[24] =
781{
782 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
783 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
784 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
785};
786
Paul Bakker5121ce52009-01-03 21:22:43 +0000787static const unsigned char des3_test_buf[8] =
788{
789 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
790};
791
792static const unsigned char des3_test_ecb_dec[3][8] =
793{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100794 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
795 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
796 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000797};
798
799static const unsigned char des3_test_ecb_enc[3][8] =
800{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100801 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
802 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
803 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000804};
805
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200806#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100807static const unsigned char des3_test_iv[8] =
808{
809 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
810};
811
Paul Bakker5121ce52009-01-03 21:22:43 +0000812static const unsigned char des3_test_cbc_dec[3][8] =
813{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100814 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
815 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
816 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000817};
818
819static const unsigned char des3_test_cbc_enc[3][8] =
820{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100821 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
822 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
823 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000824};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200825#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000826
827/*
828 * Checkup routine
829 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100830int mbedtls_des_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000831{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200832 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200833 mbedtls_des_context ctx;
834 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000835 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200836#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000837 unsigned char prv[8];
838 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200839#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000840
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 mbedtls_des_init(&ctx);
842 mbedtls_des3_init(&ctx3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000843 /*
844 * ECB mode
845 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000847 u = i >> 1;
848 v = i & 1;
849
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 if (verbose != 0) {
851 mbedtls_printf(" DES%c-ECB-%3d (%s): ",
852 (u == 0) ? ' ' : '3', 56 + u * 56,
853 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000854 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100855
856 memcpy(buf, des3_test_buf, 8);
857
858 switch (i) {
859 case 0:
860 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
861 break;
862
863 case 1:
864 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
865 break;
866
867 case 2:
868 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
869 break;
870
871 case 3:
872 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
873 break;
874
875 case 4:
876 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
877 break;
878
879 case 5:
880 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
881 break;
882
883 default:
884 return 1;
885 }
886 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200887 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000888 }
889
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 for (j = 0; j < 100; j++) {
891 if (u == 0) {
892 ret = mbedtls_des_crypt_ecb(&ctx, buf, buf);
893 } else {
894 ret = mbedtls_des3_crypt_ecb(&ctx3, buf, buf);
895 }
896 if (ret != 0) {
897 goto exit;
898 }
899 }
900
901 if ((v == MBEDTLS_DES_DECRYPT &&
902 memcmp(buf, des3_test_ecb_dec[u], 8) != 0) ||
903 (v != MBEDTLS_DES_DECRYPT &&
904 memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) {
905 if (verbose != 0) {
906 mbedtls_printf("failed\n");
907 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000908
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200909 ret = 1;
910 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000911 }
912
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 if (verbose != 0) {
914 mbedtls_printf("passed\n");
915 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000916 }
917
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 if (verbose != 0) {
919 mbedtls_printf("\n");
920 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000921
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000923 /*
924 * CBC mode
925 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000927 u = i >> 1;
928 v = i & 1;
929
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 if (verbose != 0) {
931 mbedtls_printf(" DES%c-CBC-%3d (%s): ",
932 (u == 0) ? ' ' : '3', 56 + u * 56,
933 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000934 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100935
936 memcpy(iv, des3_test_iv, 8);
937 memcpy(prv, des3_test_iv, 8);
938 memcpy(buf, des3_test_buf, 8);
939
940 switch (i) {
941 case 0:
942 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
943 break;
944
945 case 1:
946 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
947 break;
948
949 case 2:
950 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
951 break;
952
953 case 3:
954 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
955 break;
956
957 case 4:
958 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
959 break;
960
961 case 5:
962 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
963 break;
964
965 default:
966 return 1;
967 }
968 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200969 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000970 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100971
972 if (v == MBEDTLS_DES_DECRYPT) {
973 for (j = 0; j < 100; j++) {
974 if (u == 0) {
975 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
976 } else {
977 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
978 }
979 if (ret != 0) {
980 goto exit;
981 }
982 }
983 } else {
984 for (j = 0; j < 100; j++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000985 unsigned char tmp[8];
986
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 if (u == 0) {
988 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
989 } else {
990 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
991 }
992 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200993 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000995
Gilles Peskine449bd832023-01-11 14:50:10 +0100996 memcpy(tmp, prv, 8);
997 memcpy(prv, buf, 8);
998 memcpy(buf, tmp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000999 }
1000
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 memcpy(buf, prv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001002 }
1003
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 if ((v == MBEDTLS_DES_DECRYPT &&
1005 memcmp(buf, des3_test_cbc_dec[u], 8) != 0) ||
1006 (v != MBEDTLS_DES_DECRYPT &&
1007 memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) {
1008 if (verbose != 0) {
1009 mbedtls_printf("failed\n");
1010 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001011
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001012 ret = 1;
1013 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001014 }
1015
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 if (verbose != 0) {
1017 mbedtls_printf("passed\n");
1018 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001019 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001021
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 if (verbose != 0) {
1023 mbedtls_printf("\n");
1024 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001025
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001026exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 mbedtls_des_free(&ctx);
1028 mbedtls_des3_free(&ctx3);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001029
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001031 ret = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 }
1033 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001034}
1035
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038#endif /* MBEDTLS_DES_C */