blob: 4bb354af776bc20668155a607e1189383f92a5ad [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 +0100392static void 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
Gilles Peskine449bd832023-01-11 14:50:10 +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);
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 T = ((Y) ^ X) & 0x10101010; X ^= T; Y ^= (T);
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 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);
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 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);
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
416 X &= 0x0FFFFFFF;
417 Y &= 0x0FFFFFFF;
418
419 /*
420 * calculate subkeys
421 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 for (i = 0; i < 16; i++) {
423 if (i < 2 || i == 8 || i == 15) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
425 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 } else {
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
428 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
429 }
430
431 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
432 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
433 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
434 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
435 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
436 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
437 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 | ((Y >> 14) & 0x00000200) | ((Y) & 0x00000100)
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
440 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
441 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
442
443 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
444 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
445 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
446 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
447 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
448 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
449 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
450 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 | ((Y) & 0x00000200) | ((Y << 7) & 0x00000100)
Paul Bakker5121ce52009-01-03 21:22:43 +0000452 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
453 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
454 }
455}
456
457/*
458 * DES key schedule (56-bit, encryption)
459 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100460int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000461{
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000465}
466
467/*
468 * DES key schedule (56-bit, decryption)
469 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100470int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000471{
472 int i;
473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 for (i = 0; i < 16; i += 2) {
477 SWAP(ctx->sk[i], ctx->sk[30 - i]);
478 SWAP(ctx->sk[i + 1], ctx->sk[31 - i]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000479 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000480
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000482}
483
Gilles Peskine449bd832023-01-11 14:50:10 +0100484static void des3_set2key(uint32_t esk[96],
485 uint32_t dsk[96],
486 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000487{
488 int i;
489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 mbedtls_des_setkey(esk, key);
491 mbedtls_des_setkey(dsk + 32, key + 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000492
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 for (i = 0; i < 32; i += 2) {
494 dsk[i] = esk[30 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000495 dsk[i + 1] = esk[31 - i];
496
497 esk[i + 32] = dsk[62 - i];
498 esk[i + 33] = dsk[63 - i];
499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 esk[i + 64] = esk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000501 esk[i + 65] = esk[i + 1];
502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 dsk[i + 64] = dsk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000504 dsk[i + 65] = dsk[i + 1];
505 }
506}
507
508/*
509 * Triple-DES key schedule (112-bit, encryption)
510 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100511int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx,
512 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000513{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000514 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000515
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 des3_set2key(ctx->sk, sk, key);
517 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000518
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000520}
521
522/*
523 * Triple-DES key schedule (112-bit, decryption)
524 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100525int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx,
526 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000527{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000528 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 des3_set2key(sk, ctx->sk, key);
531 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000534}
535
Gilles Peskine449bd832023-01-11 14:50:10 +0100536static void des3_set3key(uint32_t esk[96],
537 uint32_t dsk[96],
538 const unsigned char key[24])
Paul Bakker5121ce52009-01-03 21:22:43 +0000539{
540 int i;
541
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 mbedtls_des_setkey(esk, key);
543 mbedtls_des_setkey(dsk + 32, key + 8);
544 mbedtls_des_setkey(esk + 64, key + 16);
Paul Bakker5121ce52009-01-03 21:22:43 +0000545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 for (i = 0; i < 32; i += 2) {
547 dsk[i] = esk[94 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000548 dsk[i + 1] = esk[95 - i];
549
550 esk[i + 32] = dsk[62 - i];
551 esk[i + 33] = dsk[63 - i];
552
553 dsk[i + 64] = esk[30 - i];
554 dsk[i + 65] = esk[31 - i];
555 }
556}
557
558/*
559 * Triple-DES key schedule (168-bit, encryption)
560 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100561int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx,
562 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000563{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000564 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 des3_set3key(ctx->sk, sk, key);
567 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000568
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000570}
571
572/*
573 * Triple-DES key schedule (168-bit, decryption)
574 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100575int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx,
576 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000577{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000578 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 des3_set3key(sk, ctx->sk, key);
581 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000584}
585
586/*
587 * DES-ECB block encryption/decryption
588 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100589int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx,
590 const unsigned char input[8],
591 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000592{
593 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000594 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
596 SK = ctx->sk;
597
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 X = MBEDTLS_GET_UINT32_BE(input, 0);
599 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 for (i = 0; i < 8; i++) {
604 DES_ROUND(Y, X);
605 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000606 }
607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
611 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000614}
615
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000617/*
618 * DES-CBC buffer encryption/decryption
619 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100620int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
621 int mode,
622 size_t length,
623 unsigned char iv[8],
624 const unsigned char *input,
625 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000626{
Gilles Peskine7820a572021-07-07 21:08:28 +0200627 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 unsigned char temp[8];
629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 if (length % 8) {
631 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
632 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 if (mode == MBEDTLS_DES_ENCRYPT) {
635 while (length > 0) {
636 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 ret = mbedtls_des_crypt_ecb(ctx, output, output);
639 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200640 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 }
642 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
644 input += 8;
645 output += 8;
646 length -= 8;
647 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 } else { /* MBEDTLS_DES_DECRYPT */
649 while (length > 0) {
650 memcpy(temp, input, 8);
651 ret = mbedtls_des_crypt_ecb(ctx, input, output);
652 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200653 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000657
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000659
660 input += 8;
661 output += 8;
662 length -= 8;
663 }
664 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200665 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000666
Gilles Peskine7820a572021-07-07 21:08:28 +0200667exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000669}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200670#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
672/*
673 * 3DES-ECB block encryption/decryption
674 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100675int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
676 const unsigned char input[8],
677 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000678{
679 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000680 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000681
682 SK = ctx->sk;
683
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 X = MBEDTLS_GET_UINT32_BE(input, 0);
685 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000686
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 for (i = 0; i < 8; i++) {
690 DES_ROUND(Y, X);
691 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000692 }
693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 for (i = 0; i < 8; i++) {
695 DES_ROUND(X, Y);
696 DES_ROUND(Y, X);
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(Y, X);
701 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000702 }
703
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000705
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
707 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000708
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000710}
711
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000713/*
714 * 3DES-CBC buffer encryption/decryption
715 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100716int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
717 int mode,
718 size_t length,
719 unsigned char iv[8],
720 const unsigned char *input,
721 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000722{
Gilles Peskine7820a572021-07-07 21:08:28 +0200723 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000724 unsigned char temp[8];
725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 if (length % 8) {
727 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
728 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 if (mode == MBEDTLS_DES_ENCRYPT) {
731 while (length > 0) {
732 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 ret = mbedtls_des3_crypt_ecb(ctx, output, output);
735 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200736 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 }
738 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000739
740 input += 8;
741 output += 8;
742 length -= 8;
743 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 } else { /* MBEDTLS_DES_DECRYPT */
745 while (length > 0) {
746 memcpy(temp, input, 8);
747 ret = mbedtls_des3_crypt_ecb(ctx, input, output);
748 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200749 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000751
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000755
756 input += 8;
757 output += 8;
758 length -= 8;
759 }
760 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200761 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000762
Gilles Peskine7820a572021-07-07 21:08:28 +0200763exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000765}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200766#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000767
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200768#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000769/*
770 * DES and 3DES test vectors from:
771 *
772 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
773 */
774static const unsigned char des3_test_keys[24] =
775{
776 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
777 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
778 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
779};
780
Paul Bakker5121ce52009-01-03 21:22:43 +0000781static const unsigned char des3_test_buf[8] =
782{
783 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
784};
785
786static const unsigned char des3_test_ecb_dec[3][8] =
787{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100788 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
789 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
790 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000791};
792
793static const unsigned char des3_test_ecb_enc[3][8] =
794{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100795 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
796 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
797 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000798};
799
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200800#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100801static const unsigned char des3_test_iv[8] =
802{
803 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
804};
805
Paul Bakker5121ce52009-01-03 21:22:43 +0000806static const unsigned char des3_test_cbc_dec[3][8] =
807{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100808 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
809 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
810 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000811};
812
813static const unsigned char des3_test_cbc_enc[3][8] =
814{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100815 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
816 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
817 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000818};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200819#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000820
821/*
822 * Checkup routine
823 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100824int mbedtls_des_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000825{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200826 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200827 mbedtls_des_context ctx;
828 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000829 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000831 unsigned char prv[8];
832 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200833#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000834
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 mbedtls_des_init(&ctx);
836 mbedtls_des3_init(&ctx3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000837 /*
838 * ECB mode
839 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000841 u = i >> 1;
842 v = i & 1;
843
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 if (verbose != 0) {
845 mbedtls_printf(" DES%c-ECB-%3d (%s): ",
846 (u == 0) ? ' ' : '3', 56 + u * 56,
847 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000848 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100849
850 memcpy(buf, des3_test_buf, 8);
851
852 switch (i) {
853 case 0:
854 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
855 break;
856
857 case 1:
858 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
859 break;
860
861 case 2:
862 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
863 break;
864
865 case 3:
866 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
867 break;
868
869 case 4:
870 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
871 break;
872
873 case 5:
874 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
875 break;
876
877 default:
878 return 1;
879 }
880 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200881 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000882 }
883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 for (j = 0; j < 100; j++) {
885 if (u == 0) {
886 ret = mbedtls_des_crypt_ecb(&ctx, buf, buf);
887 } else {
888 ret = mbedtls_des3_crypt_ecb(&ctx3, buf, buf);
889 }
890 if (ret != 0) {
891 goto exit;
892 }
893 }
894
895 if ((v == MBEDTLS_DES_DECRYPT &&
896 memcmp(buf, des3_test_ecb_dec[u], 8) != 0) ||
897 (v != MBEDTLS_DES_DECRYPT &&
898 memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) {
899 if (verbose != 0) {
900 mbedtls_printf("failed\n");
901 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000902
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200903 ret = 1;
904 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000905 }
906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 if (verbose != 0) {
908 mbedtls_printf("passed\n");
909 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000910 }
911
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 if (verbose != 0) {
913 mbedtls_printf("\n");
914 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000915
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000917 /*
918 * CBC mode
919 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000921 u = i >> 1;
922 v = i & 1;
923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 if (verbose != 0) {
925 mbedtls_printf(" DES%c-CBC-%3d (%s): ",
926 (u == 0) ? ' ' : '3', 56 + u * 56,
927 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000928 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100929
930 memcpy(iv, des3_test_iv, 8);
931 memcpy(prv, des3_test_iv, 8);
932 memcpy(buf, des3_test_buf, 8);
933
934 switch (i) {
935 case 0:
936 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
937 break;
938
939 case 1:
940 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
941 break;
942
943 case 2:
944 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
945 break;
946
947 case 3:
948 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
949 break;
950
951 case 4:
952 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
953 break;
954
955 case 5:
956 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
957 break;
958
959 default:
960 return 1;
961 }
962 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200963 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000964 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100965
966 if (v == MBEDTLS_DES_DECRYPT) {
967 for (j = 0; j < 100; j++) {
968 if (u == 0) {
969 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
970 } else {
971 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
972 }
973 if (ret != 0) {
974 goto exit;
975 }
976 }
977 } else {
978 for (j = 0; j < 100; j++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000979 unsigned char tmp[8];
980
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 if (u == 0) {
982 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
983 } else {
984 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
985 }
986 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200987 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000989
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 memcpy(tmp, prv, 8);
991 memcpy(prv, buf, 8);
992 memcpy(buf, tmp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000993 }
994
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 memcpy(buf, prv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000996 }
997
Gilles Peskine449bd832023-01-11 14:50:10 +0100998 if ((v == MBEDTLS_DES_DECRYPT &&
999 memcmp(buf, des3_test_cbc_dec[u], 8) != 0) ||
1000 (v != MBEDTLS_DES_DECRYPT &&
1001 memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) {
1002 if (verbose != 0) {
1003 mbedtls_printf("failed\n");
1004 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001005
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001006 ret = 1;
1007 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001008 }
1009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 if (verbose != 0) {
1011 mbedtls_printf("passed\n");
1012 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001013 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001014#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001015
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 if (verbose != 0) {
1017 mbedtls_printf("\n");
1018 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001019
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001020exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 mbedtls_des_free(&ctx);
1022 mbedtls_des3_free(&ctx3);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001023
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001025 ret = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 }
1027 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001028}
1029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032#endif /* MBEDTLS_DES_C */