blob: 7fd71002a44e5ecaa708e5c65396ce6a6f20c095 [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
Thomas Daubney43874e02024-07-16 17:45:52 +0100392/*
393 * Internal function for key expansion.
394 */
395static void mbedtls_des_setkey(uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000396{
397 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000398 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 X = MBEDTLS_GET_UINT32_BE(key, 0);
401 Y = MBEDTLS_GET_UINT32_BE(key, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000402
403 /*
404 * Permuted Choice 1
405 */
406 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 T = ((Y) ^ X) & 0x10101010; X ^= T; Y ^= (T);
Paul Bakker5121ce52009-01-03 21:22:43 +0000408
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 X = (LHs[(X) & 0xF] << 3) | (LHs[(X >> 8) & 0xF] << 2)
410 | (LHs[(X >> 16) & 0xF] << 1) | (LHs[(X >> 24) & 0xF])
411 | (LHs[(X >> 5) & 0xF] << 7) | (LHs[(X >> 13) & 0xF] << 6)
412 | (LHs[(X >> 21) & 0xF] << 5) | (LHs[(X >> 29) & 0xF] << 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 Y = (RHs[(Y >> 1) & 0xF] << 3) | (RHs[(Y >> 9) & 0xF] << 2)
415 | (RHs[(Y >> 17) & 0xF] << 1) | (RHs[(Y >> 25) & 0xF])
416 | (RHs[(Y >> 4) & 0xF] << 7) | (RHs[(Y >> 12) & 0xF] << 6)
417 | (RHs[(Y >> 20) & 0xF] << 5) | (RHs[(Y >> 28) & 0xF] << 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
419 X &= 0x0FFFFFFF;
420 Y &= 0x0FFFFFFF;
421
422 /*
423 * calculate subkeys
424 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 for (i = 0; i < 16; i++) {
426 if (i < 2 || i == 8 || i == 15) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
428 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 } else {
Paul Bakker5121ce52009-01-03 21:22:43 +0000430 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
431 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
432 }
433
434 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
435 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
436 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
437 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
438 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
439 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
440 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 | ((Y >> 14) & 0x00000200) | ((Y) & 0x00000100)
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
443 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
444 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
445
446 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
447 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
448 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
449 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
450 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
451 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
452 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
453 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 | ((Y) & 0x00000200) | ((Y << 7) & 0x00000100)
Paul Bakker5121ce52009-01-03 21:22:43 +0000455 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
456 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
457 }
458}
459
460/*
461 * DES key schedule (56-bit, encryption)
462 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100463int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000464{
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000468}
469
470/*
471 * DES key schedule (56-bit, decryption)
472 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100473int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000474{
475 int i;
476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 for (i = 0; i < 16; i += 2) {
480 SWAP(ctx->sk[i], ctx->sk[30 - i]);
481 SWAP(ctx->sk[i + 1], ctx->sk[31 - i]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000482 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000483
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000485}
486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487static void des3_set2key(uint32_t esk[96],
488 uint32_t dsk[96],
489 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000490{
491 int i;
492
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 mbedtls_des_setkey(esk, key);
494 mbedtls_des_setkey(dsk + 32, key + 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 for (i = 0; i < 32; i += 2) {
497 dsk[i] = esk[30 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000498 dsk[i + 1] = esk[31 - i];
499
500 esk[i + 32] = dsk[62 - i];
501 esk[i + 33] = dsk[63 - i];
502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 esk[i + 64] = esk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000504 esk[i + 65] = esk[i + 1];
505
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 dsk[i + 64] = dsk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000507 dsk[i + 65] = dsk[i + 1];
508 }
509}
510
511/*
512 * Triple-DES key schedule (112-bit, encryption)
513 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100514int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx,
515 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000516{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000517 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000518
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 des3_set2key(ctx->sk, sk, key);
520 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000521
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000523}
524
525/*
526 * Triple-DES key schedule (112-bit, decryption)
527 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100528int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx,
529 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000530{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000531 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 des3_set2key(sk, ctx->sk, key);
534 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000535
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000537}
538
Gilles Peskine449bd832023-01-11 14:50:10 +0100539static void des3_set3key(uint32_t esk[96],
540 uint32_t dsk[96],
541 const unsigned char key[24])
Paul Bakker5121ce52009-01-03 21:22:43 +0000542{
543 int i;
544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 mbedtls_des_setkey(esk, key);
546 mbedtls_des_setkey(dsk + 32, key + 8);
547 mbedtls_des_setkey(esk + 64, key + 16);
Paul Bakker5121ce52009-01-03 21:22:43 +0000548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 for (i = 0; i < 32; i += 2) {
550 dsk[i] = esk[94 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000551 dsk[i + 1] = esk[95 - i];
552
553 esk[i + 32] = dsk[62 - i];
554 esk[i + 33] = dsk[63 - i];
555
556 dsk[i + 64] = esk[30 - i];
557 dsk[i + 65] = esk[31 - i];
558 }
559}
560
561/*
562 * Triple-DES key schedule (168-bit, encryption)
563 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100564int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx,
565 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000566{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000567 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000568
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 des3_set3key(ctx->sk, sk, key);
570 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000571
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000573}
574
575/*
576 * Triple-DES key schedule (168-bit, decryption)
577 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100578int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx,
579 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000580{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000581 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 des3_set3key(sk, ctx->sk, key);
584 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000585
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000587}
588
589/*
590 * DES-ECB block encryption/decryption
591 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200592#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100593int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx,
594 const unsigned char input[8],
595 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000596{
597 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000598 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
600 SK = ctx->sk;
601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 X = MBEDTLS_GET_UINT32_BE(input, 0);
603 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 for (i = 0; i < 8; i++) {
608 DES_ROUND(Y, X);
609 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000610 }
611
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
615 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000618}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200619#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000622/*
623 * DES-CBC buffer encryption/decryption
624 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100625int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
626 int mode,
627 size_t length,
628 unsigned char iv[8],
629 const unsigned char *input,
630 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000631{
Gilles Peskine7820a572021-07-07 21:08:28 +0200632 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 unsigned char temp[8];
634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 if (length % 8) {
636 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
637 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 if (mode == MBEDTLS_DES_ENCRYPT) {
640 while (length > 0) {
641 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000642
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 ret = mbedtls_des_crypt_ecb(ctx, output, output);
644 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200645 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 }
647 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
649 input += 8;
650 output += 8;
651 length -= 8;
652 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 } else { /* MBEDTLS_DES_DECRYPT */
654 while (length > 0) {
655 memcpy(temp, input, 8);
656 ret = mbedtls_des_crypt_ecb(ctx, input, output);
657 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200658 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000660
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000662
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000664
665 input += 8;
666 output += 8;
667 length -= 8;
668 }
669 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200670 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000671
Gilles Peskine7820a572021-07-07 21:08:28 +0200672exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000674}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200675#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000676
677/*
678 * 3DES-ECB block encryption/decryption
679 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200680#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100681int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
682 const unsigned char input[8],
683 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000684{
685 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000686 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000687
688 SK = ctx->sk;
689
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 X = MBEDTLS_GET_UINT32_BE(input, 0);
691 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 for (i = 0; i < 8; i++) {
696 DES_ROUND(Y, X);
697 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000698 }
699
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 for (i = 0; i < 8; i++) {
701 DES_ROUND(X, Y);
702 DES_ROUND(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 }
704
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 for (i = 0; i < 8; i++) {
706 DES_ROUND(Y, X);
707 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000708 }
709
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
713 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000714
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000716}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200717#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000718
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000720/*
721 * 3DES-CBC buffer encryption/decryption
722 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100723int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
724 int mode,
725 size_t length,
726 unsigned char iv[8],
727 const unsigned char *input,
728 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000729{
Gilles Peskine7820a572021-07-07 21:08:28 +0200730 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000731 unsigned char temp[8];
732
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 if (length % 8) {
734 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
735 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000736
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 if (mode == MBEDTLS_DES_ENCRYPT) {
738 while (length > 0) {
739 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000740
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 ret = mbedtls_des3_crypt_ecb(ctx, output, output);
742 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200743 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 }
745 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000746
747 input += 8;
748 output += 8;
749 length -= 8;
750 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 } else { /* MBEDTLS_DES_DECRYPT */
752 while (length > 0) {
753 memcpy(temp, input, 8);
754 ret = mbedtls_des3_crypt_ecb(ctx, input, output);
755 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200756 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000758
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000760
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000762
763 input += 8;
764 output += 8;
765 length -= 8;
766 }
767 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200768 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000769
Gilles Peskine7820a572021-07-07 21:08:28 +0200770exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000772}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200773#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000774
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200775#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000776/*
777 * DES and 3DES test vectors from:
778 *
779 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
780 */
781static const unsigned char des3_test_keys[24] =
782{
783 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
784 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
785 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
786};
787
Paul Bakker5121ce52009-01-03 21:22:43 +0000788static const unsigned char des3_test_buf[8] =
789{
790 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
791};
792
793static const unsigned char des3_test_ecb_dec[3][8] =
794{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100795 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
796 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
797 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000798};
799
800static const unsigned char des3_test_ecb_enc[3][8] =
801{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100802 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
803 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
804 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000805};
806
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100808static const unsigned char des3_test_iv[8] =
809{
810 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
811};
812
Paul Bakker5121ce52009-01-03 21:22:43 +0000813static const unsigned char des3_test_cbc_dec[3][8] =
814{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100815 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
816 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
817 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000818};
819
820static const unsigned char des3_test_cbc_enc[3][8] =
821{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100822 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
823 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
824 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000825};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000827
828/*
829 * Checkup routine
830 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100831int mbedtls_des_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000832{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200833 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200834 mbedtls_des_context ctx;
835 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000836 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000838 unsigned char prv[8];
839 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200840#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 mbedtls_des_init(&ctx);
843 mbedtls_des3_init(&ctx3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000844 /*
845 * ECB mode
846 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000848 u = i >> 1;
849 v = i & 1;
850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 if (verbose != 0) {
852 mbedtls_printf(" DES%c-ECB-%3d (%s): ",
853 (u == 0) ? ' ' : '3', 56 + u * 56,
854 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000855 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100856
857 memcpy(buf, des3_test_buf, 8);
858
859 switch (i) {
860 case 0:
861 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
862 break;
863
864 case 1:
865 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
866 break;
867
868 case 2:
869 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
870 break;
871
872 case 3:
873 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
874 break;
875
876 case 4:
877 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
878 break;
879
880 case 5:
881 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
882 break;
883
884 default:
885 return 1;
886 }
887 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200888 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000889 }
890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 for (j = 0; j < 100; j++) {
892 if (u == 0) {
893 ret = mbedtls_des_crypt_ecb(&ctx, buf, buf);
894 } else {
895 ret = mbedtls_des3_crypt_ecb(&ctx3, buf, buf);
896 }
897 if (ret != 0) {
898 goto exit;
899 }
900 }
901
902 if ((v == MBEDTLS_DES_DECRYPT &&
903 memcmp(buf, des3_test_ecb_dec[u], 8) != 0) ||
904 (v != MBEDTLS_DES_DECRYPT &&
905 memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) {
906 if (verbose != 0) {
907 mbedtls_printf("failed\n");
908 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000909
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200910 ret = 1;
911 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000912 }
913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 if (verbose != 0) {
915 mbedtls_printf("passed\n");
916 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000917 }
918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 if (verbose != 0) {
920 mbedtls_printf("\n");
921 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000922
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200923#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000924 /*
925 * CBC mode
926 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000928 u = i >> 1;
929 v = i & 1;
930
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 if (verbose != 0) {
932 mbedtls_printf(" DES%c-CBC-%3d (%s): ",
933 (u == 0) ? ' ' : '3', 56 + u * 56,
934 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000935 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100936
937 memcpy(iv, des3_test_iv, 8);
938 memcpy(prv, des3_test_iv, 8);
939 memcpy(buf, des3_test_buf, 8);
940
941 switch (i) {
942 case 0:
943 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
944 break;
945
946 case 1:
947 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
948 break;
949
950 case 2:
951 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
952 break;
953
954 case 3:
955 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
956 break;
957
958 case 4:
959 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
960 break;
961
962 case 5:
963 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
964 break;
965
966 default:
967 return 1;
968 }
969 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200970 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000971 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100972
973 if (v == MBEDTLS_DES_DECRYPT) {
974 for (j = 0; j < 100; j++) {
975 if (u == 0) {
976 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
977 } else {
978 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
979 }
980 if (ret != 0) {
981 goto exit;
982 }
983 }
984 } else {
985 for (j = 0; j < 100; j++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 unsigned char tmp[8];
987
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 if (u == 0) {
989 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
990 } else {
991 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
992 }
993 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200994 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 memcpy(tmp, prv, 8);
998 memcpy(prv, buf, 8);
999 memcpy(buf, tmp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001000 }
1001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 memcpy(buf, prv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001003 }
1004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 if ((v == MBEDTLS_DES_DECRYPT &&
1006 memcmp(buf, des3_test_cbc_dec[u], 8) != 0) ||
1007 (v != MBEDTLS_DES_DECRYPT &&
1008 memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) {
1009 if (verbose != 0) {
1010 mbedtls_printf("failed\n");
1011 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001012
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001013 ret = 1;
1014 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001015 }
1016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 if (verbose != 0) {
1018 mbedtls_printf("passed\n");
1019 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001020 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001022
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 if (verbose != 0) {
1024 mbedtls_printf("\n");
1025 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001026
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001027exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 mbedtls_des_free(&ctx);
1029 mbedtls_des3_free(&ctx3);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001030
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001032 ret = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 }
1034 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001035}
1036
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001037#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001038
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001039#endif /* MBEDTLS_DES_C */