blob: f0032b3b5699789389b289901031779b4f7d0bd3 [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020026#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020027
Paul Bakker5121ce52009-01-03 21:22:43 +000028/*
Paul Bakker5121ce52009-01-03 21:22:43 +000029 * Expanded DES S-boxes
30 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000031static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000032{
33 0x01010400, 0x00000000, 0x00010000, 0x01010404,
34 0x01010004, 0x00010404, 0x00000004, 0x00010000,
35 0x00000400, 0x01010400, 0x01010404, 0x00000400,
36 0x01000404, 0x01010004, 0x01000000, 0x00000004,
37 0x00000404, 0x01000400, 0x01000400, 0x00010400,
38 0x00010400, 0x01010000, 0x01010000, 0x01000404,
39 0x00010004, 0x01000004, 0x01000004, 0x00010004,
40 0x00000000, 0x00000404, 0x00010404, 0x01000000,
41 0x00010000, 0x01010404, 0x00000004, 0x01010000,
42 0x01010400, 0x01000000, 0x01000000, 0x00000400,
43 0x01010004, 0x00010000, 0x00010400, 0x01000004,
44 0x00000400, 0x00000004, 0x01000404, 0x00010404,
45 0x01010404, 0x00010004, 0x01010000, 0x01000404,
46 0x01000004, 0x00000404, 0x00010404, 0x01010400,
47 0x00000404, 0x01000400, 0x01000400, 0x00000000,
48 0x00010004, 0x00010400, 0x00000000, 0x01010004
49};
50
Paul Bakker5c2364c2012-10-01 14:41:15 +000051static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000052{
53 0x80108020, 0x80008000, 0x00008000, 0x00108020,
54 0x00100000, 0x00000020, 0x80100020, 0x80008020,
55 0x80000020, 0x80108020, 0x80108000, 0x80000000,
56 0x80008000, 0x00100000, 0x00000020, 0x80100020,
57 0x00108000, 0x00100020, 0x80008020, 0x00000000,
58 0x80000000, 0x00008000, 0x00108020, 0x80100000,
59 0x00100020, 0x80000020, 0x00000000, 0x00108000,
60 0x00008020, 0x80108000, 0x80100000, 0x00008020,
61 0x00000000, 0x00108020, 0x80100020, 0x00100000,
62 0x80008020, 0x80100000, 0x80108000, 0x00008000,
63 0x80100000, 0x80008000, 0x00000020, 0x80108020,
64 0x00108020, 0x00000020, 0x00008000, 0x80000000,
65 0x00008020, 0x80108000, 0x00100000, 0x80000020,
66 0x00100020, 0x80008020, 0x80000020, 0x00100020,
67 0x00108000, 0x00000000, 0x80008000, 0x00008020,
68 0x80000000, 0x80100020, 0x80108020, 0x00108000
69};
70
Paul Bakker5c2364c2012-10-01 14:41:15 +000071static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000072{
73 0x00000208, 0x08020200, 0x00000000, 0x08020008,
74 0x08000200, 0x00000000, 0x00020208, 0x08000200,
75 0x00020008, 0x08000008, 0x08000008, 0x00020000,
76 0x08020208, 0x00020008, 0x08020000, 0x00000208,
77 0x08000000, 0x00000008, 0x08020200, 0x00000200,
78 0x00020200, 0x08020000, 0x08020008, 0x00020208,
79 0x08000208, 0x00020200, 0x00020000, 0x08000208,
80 0x00000008, 0x08020208, 0x00000200, 0x08000000,
81 0x08020200, 0x08000000, 0x00020008, 0x00000208,
82 0x00020000, 0x08020200, 0x08000200, 0x00000000,
83 0x00000200, 0x00020008, 0x08020208, 0x08000200,
84 0x08000008, 0x00000200, 0x00000000, 0x08020008,
85 0x08000208, 0x00020000, 0x08000000, 0x08020208,
86 0x00000008, 0x00020208, 0x00020200, 0x08000008,
87 0x08020000, 0x08000208, 0x00000208, 0x08020000,
88 0x00020208, 0x00000008, 0x08020008, 0x00020200
89};
90
Paul Bakker5c2364c2012-10-01 14:41:15 +000091static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000092{
93 0x00802001, 0x00002081, 0x00002081, 0x00000080,
94 0x00802080, 0x00800081, 0x00800001, 0x00002001,
95 0x00000000, 0x00802000, 0x00802000, 0x00802081,
96 0x00000081, 0x00000000, 0x00800080, 0x00800001,
97 0x00000001, 0x00002000, 0x00800000, 0x00802001,
98 0x00000080, 0x00800000, 0x00002001, 0x00002080,
99 0x00800081, 0x00000001, 0x00002080, 0x00800080,
100 0x00002000, 0x00802080, 0x00802081, 0x00000081,
101 0x00800080, 0x00800001, 0x00802000, 0x00802081,
102 0x00000081, 0x00000000, 0x00000000, 0x00802000,
103 0x00002080, 0x00800080, 0x00800081, 0x00000001,
104 0x00802001, 0x00002081, 0x00002081, 0x00000080,
105 0x00802081, 0x00000081, 0x00000001, 0x00002000,
106 0x00800001, 0x00002001, 0x00802080, 0x00800081,
107 0x00002001, 0x00002080, 0x00800000, 0x00802001,
108 0x00000080, 0x00800000, 0x00002000, 0x00802080
109};
110
Paul Bakker5c2364c2012-10-01 14:41:15 +0000111static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000112{
113 0x00000100, 0x02080100, 0x02080000, 0x42000100,
114 0x00080000, 0x00000100, 0x40000000, 0x02080000,
115 0x40080100, 0x00080000, 0x02000100, 0x40080100,
116 0x42000100, 0x42080000, 0x00080100, 0x40000000,
117 0x02000000, 0x40080000, 0x40080000, 0x00000000,
118 0x40000100, 0x42080100, 0x42080100, 0x02000100,
119 0x42080000, 0x40000100, 0x00000000, 0x42000000,
120 0x02080100, 0x02000000, 0x42000000, 0x00080100,
121 0x00080000, 0x42000100, 0x00000100, 0x02000000,
122 0x40000000, 0x02080000, 0x42000100, 0x40080100,
123 0x02000100, 0x40000000, 0x42080000, 0x02080100,
124 0x40080100, 0x00000100, 0x02000000, 0x42080000,
125 0x42080100, 0x00080100, 0x42000000, 0x42080100,
126 0x02080000, 0x00000000, 0x40080000, 0x42000000,
127 0x00080100, 0x02000100, 0x40000100, 0x00080000,
128 0x00000000, 0x40080000, 0x02080100, 0x40000100
129};
130
Paul Bakker5c2364c2012-10-01 14:41:15 +0000131static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000132{
133 0x20000010, 0x20400000, 0x00004000, 0x20404010,
134 0x20400000, 0x00000010, 0x20404010, 0x00400000,
135 0x20004000, 0x00404010, 0x00400000, 0x20000010,
136 0x00400010, 0x20004000, 0x20000000, 0x00004010,
137 0x00000000, 0x00400010, 0x20004010, 0x00004000,
138 0x00404000, 0x20004010, 0x00000010, 0x20400010,
139 0x20400010, 0x00000000, 0x00404010, 0x20404000,
140 0x00004010, 0x00404000, 0x20404000, 0x20000000,
141 0x20004000, 0x00000010, 0x20400010, 0x00404000,
142 0x20404010, 0x00400000, 0x00004010, 0x20000010,
143 0x00400000, 0x20004000, 0x20000000, 0x00004010,
144 0x20000010, 0x20404010, 0x00404000, 0x20400000,
145 0x00404010, 0x20404000, 0x00000000, 0x20400010,
146 0x00000010, 0x00004000, 0x20400000, 0x00404010,
147 0x00004000, 0x00400010, 0x20004010, 0x00000000,
148 0x20404000, 0x20000000, 0x00400010, 0x20004010
149};
150
Paul Bakker5c2364c2012-10-01 14:41:15 +0000151static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000152{
153 0x00200000, 0x04200002, 0x04000802, 0x00000000,
154 0x00000800, 0x04000802, 0x00200802, 0x04200800,
155 0x04200802, 0x00200000, 0x00000000, 0x04000002,
156 0x00000002, 0x04000000, 0x04200002, 0x00000802,
157 0x04000800, 0x00200802, 0x00200002, 0x04000800,
158 0x04000002, 0x04200000, 0x04200800, 0x00200002,
159 0x04200000, 0x00000800, 0x00000802, 0x04200802,
160 0x00200800, 0x00000002, 0x04000000, 0x00200800,
161 0x04000000, 0x00200800, 0x00200000, 0x04000802,
162 0x04000802, 0x04200002, 0x04200002, 0x00000002,
163 0x00200002, 0x04000000, 0x04000800, 0x00200000,
164 0x04200800, 0x00000802, 0x00200802, 0x04200800,
165 0x00000802, 0x04000002, 0x04200802, 0x04200000,
166 0x00200800, 0x00000000, 0x00000002, 0x04200802,
167 0x00000000, 0x00200802, 0x04200000, 0x00000800,
168 0x04000002, 0x04000800, 0x00000800, 0x00200002
169};
170
Paul Bakker5c2364c2012-10-01 14:41:15 +0000171static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000172{
173 0x10001040, 0x00001000, 0x00040000, 0x10041040,
174 0x10000000, 0x10001040, 0x00000040, 0x10000000,
175 0x00040040, 0x10040000, 0x10041040, 0x00041000,
176 0x10041000, 0x00041040, 0x00001000, 0x00000040,
177 0x10040000, 0x10000040, 0x10001000, 0x00001040,
178 0x00041000, 0x00040040, 0x10040040, 0x10041000,
179 0x00001040, 0x00000000, 0x00000000, 0x10040040,
180 0x10000040, 0x10001000, 0x00041040, 0x00040000,
181 0x00041040, 0x00040000, 0x10041000, 0x00001000,
182 0x00000040, 0x10040040, 0x00001000, 0x00041040,
183 0x10001000, 0x00000040, 0x10000040, 0x10040000,
184 0x10040040, 0x10000000, 0x00040000, 0x10001040,
185 0x00000000, 0x10041040, 0x00040040, 0x10000040,
186 0x10040000, 0x10001000, 0x10001040, 0x00000000,
187 0x10041040, 0x00041000, 0x00041000, 0x00001040,
188 0x00001040, 0x00040040, 0x10000000, 0x10041000
189};
190
191/*
192 * PC1: left and right halves bit-swap
193 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000194static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000195{
196 0x00000000, 0x00000001, 0x00000100, 0x00000101,
197 0x00010000, 0x00010001, 0x00010100, 0x00010101,
198 0x01000000, 0x01000001, 0x01000100, 0x01000101,
199 0x01010000, 0x01010001, 0x01010100, 0x01010101
200};
201
Paul Bakker5c2364c2012-10-01 14:41:15 +0000202static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000203{
204 0x00000000, 0x01000000, 0x00010000, 0x01010000,
205 0x00000100, 0x01000100, 0x00010100, 0x01010100,
206 0x00000001, 0x01000001, 0x00010001, 0x01010001,
207 0x00000101, 0x01000101, 0x00010101, 0x01010101,
208};
209
210/*
211 * Initial Permutation macro
212 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100213#define DES_IP(X, Y) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100214 do \
215 { \
216 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
217 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
218 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
219 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
220 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
221 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
222 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000224
225/*
226 * Final Permutation macro
227 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100228#define DES_FP(X, Y) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100229 do \
230 { \
231 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
232 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
233 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
234 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
235 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
236 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
237 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000239
240/*
241 * DES round macro
242 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100243#define DES_ROUND(X, Y) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100244 do \
245 { \
246 T = *SK++ ^ (X); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 (Y) ^= SB8[(T) & 0x3F] ^ \
248 SB6[(T >> 8) & 0x3F] ^ \
249 SB4[(T >> 16) & 0x3F] ^ \
250 SB2[(T >> 24) & 0x3F]; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100251 \
252 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 (Y) ^= SB7[(T) & 0x3F] ^ \
254 SB5[(T >> 8) & 0x3F] ^ \
255 SB3[(T >> 16) & 0x3F] ^ \
256 SB1[(T >> 24) & 0x3F]; \
257 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000258
Gilles Peskine449bd832023-01-11 14:50:10 +0100259#define SWAP(a, b) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100260 do \
261 { \
262 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000264
Gilles Peskine449bd832023-01-11 14:50:10 +0100265void mbedtls_des_init(mbedtls_des_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200266{
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 memset(ctx, 0, sizeof(mbedtls_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200268}
269
Gilles Peskine449bd832023-01-11 14:50:10 +0100270void mbedtls_des_free(mbedtls_des_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200271{
Gilles Peskine449bd832023-01-11 14:50:10 +0100272 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200273 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200275
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200277}
278
Gilles Peskine449bd832023-01-11 14:50:10 +0100279void mbedtls_des3_init(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200280{
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 memset(ctx, 0, sizeof(mbedtls_des3_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200282}
283
Gilles Peskine449bd832023-01-11 14:50:10 +0100284void mbedtls_des3_free(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200285{
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200287 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200289
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des3_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200291}
292
Paul Bakker1f87fb62011-01-15 17:32:24 +0000293static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32,
295 35, 37, 38, 41, 42, 44,
296 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69,
297 70, 73, 74, 76, 79, 81,
298 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103,
299 104, 107, 109, 110, 112,
300 115, 117, 118, 121, 122, 124, 127, 128, 131,
301 133, 134, 137, 138, 140,
302 143, 145, 146, 148, 151, 152, 155, 157, 158,
303 161, 162, 164, 167, 168,
304 171, 173, 174, 176, 179, 181, 182, 185, 186,
305 188, 191, 193, 194, 196,
306 199, 200, 203, 205, 206, 208, 211, 213, 214,
307 217, 218, 220, 223, 224,
308 227, 229, 230, 233, 234, 236, 239, 241, 242,
309 244, 247, 248, 251, 253,
310 254 };
Paul Bakker1f87fb62011-01-15 17:32:24 +0000311
Gilles Peskine449bd832023-01-11 14:50:10 +0100312void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker1f87fb62011-01-15 17:32:24 +0000313{
314 int i;
315
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) {
Paul Bakker1f87fb62011-01-15 17:32:24 +0000317 key[i] = odd_parity_table[key[i] / 2];
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 }
Paul Bakker1f87fb62011-01-15 17:32:24 +0000319}
320
321/*
322 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
323 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100324int mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker1f87fb62011-01-15 17:32:24 +0000325{
326 int i;
327
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) {
329 if (key[i] != odd_parity_table[key[i] / 2]) {
330 return 1;
331 }
332 }
Paul Bakker1f87fb62011-01-15 17:32:24 +0000333
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 return 0;
Paul Bakker1f87fb62011-01-15 17:32:24 +0000335}
336
337/*
338 * Table of weak and semi-weak keys
339 *
340 * Source: http://en.wikipedia.org/wiki/Weak_key
341 *
342 * Weak:
343 * Alternating ones + zeros (0x0101010101010101)
344 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
345 * '0xE0E0E0E0F1F1F1F1'
346 * '0x1F1F1F1F0E0E0E0E'
347 *
348 * Semi-weak:
349 * 0x011F011F010E010E and 0x1F011F010E010E01
350 * 0x01E001E001F101F1 and 0xE001E001F101F101
351 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
352 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
353 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
354 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
355 *
356 */
357
358#define WEAK_KEY_COUNT 16
359
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000361{
362 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
363 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
364 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
365 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
366
367 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
368 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
369 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
370 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
371 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
372 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
373 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
374 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
375 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
376 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
377 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
378 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
379};
380
Gilles Peskine449bd832023-01-11 14:50:10 +0100381int mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker1f87fb62011-01-15 17:32:24 +0000382{
383 int i;
384
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 for (i = 0; i < WEAK_KEY_COUNT; i++) {
386 if (memcmp(weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0) {
387 return 1;
388 }
389 }
Paul Bakker1f87fb62011-01-15 17:32:24 +0000390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 return 0;
Paul Bakker1f87fb62011-01-15 17:32:24 +0000392}
393
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200394#if !defined(MBEDTLS_DES_SETKEY_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100395void 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}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200459#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
461/*
462 * DES key schedule (56-bit, encryption)
463 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100464int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000465{
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000467
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000469}
470
471/*
472 * DES key schedule (56-bit, decryption)
473 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100474int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000475{
476 int i;
477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 for (i = 0; i < 16; i += 2) {
481 SWAP(ctx->sk[i], ctx->sk[30 - i]);
482 SWAP(ctx->sk[i + 1], ctx->sk[31 - i]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000483 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000486}
487
Gilles Peskine449bd832023-01-11 14:50:10 +0100488static void des3_set2key(uint32_t esk[96],
489 uint32_t dsk[96],
490 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000491{
492 int i;
493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 mbedtls_des_setkey(esk, key);
495 mbedtls_des_setkey(dsk + 32, key + 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 for (i = 0; i < 32; i += 2) {
498 dsk[i] = esk[30 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000499 dsk[i + 1] = esk[31 - i];
500
501 esk[i + 32] = dsk[62 - i];
502 esk[i + 33] = dsk[63 - i];
503
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 esk[i + 64] = esk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000505 esk[i + 65] = esk[i + 1];
506
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 dsk[i + 64] = dsk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000508 dsk[i + 65] = dsk[i + 1];
509 }
510}
511
512/*
513 * Triple-DES key schedule (112-bit, encryption)
514 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100515int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx,
516 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000517{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000518 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000519
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 des3_set2key(ctx->sk, sk, key);
521 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000522
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000524}
525
526/*
527 * Triple-DES key schedule (112-bit, decryption)
528 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100529int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx,
530 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000531{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000532 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 des3_set2key(sk, ctx->sk, key);
535 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000538}
539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540static void des3_set3key(uint32_t esk[96],
541 uint32_t dsk[96],
542 const unsigned char key[24])
Paul Bakker5121ce52009-01-03 21:22:43 +0000543{
544 int i;
545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 mbedtls_des_setkey(esk, key);
547 mbedtls_des_setkey(dsk + 32, key + 8);
548 mbedtls_des_setkey(esk + 64, key + 16);
Paul Bakker5121ce52009-01-03 21:22:43 +0000549
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 for (i = 0; i < 32; i += 2) {
551 dsk[i] = esk[94 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000552 dsk[i + 1] = esk[95 - i];
553
554 esk[i + 32] = dsk[62 - i];
555 esk[i + 33] = dsk[63 - i];
556
557 dsk[i + 64] = esk[30 - i];
558 dsk[i + 65] = esk[31 - i];
559 }
560}
561
562/*
563 * Triple-DES key schedule (168-bit, encryption)
564 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100565int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx,
566 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000567{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000568 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000569
Gilles Peskine449bd832023-01-11 14:50:10 +0100570 des3_set3key(ctx->sk, sk, key);
571 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000572
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000574}
575
576/*
577 * Triple-DES key schedule (168-bit, decryption)
578 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100579int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx,
580 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000581{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000582 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000583
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 des3_set3key(sk, ctx->sk, key);
585 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000586
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000588}
589
590/*
591 * DES-ECB block encryption/decryption
592 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200593#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100594int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx,
595 const unsigned char input[8],
596 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000597{
598 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000599 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
601 SK = ctx->sk;
602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 X = MBEDTLS_GET_UINT32_BE(input, 0);
604 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 for (i = 0; i < 8; i++) {
609 DES_ROUND(Y, X);
610 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000611 }
612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
616 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000619}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200620#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000623/*
624 * DES-CBC buffer encryption/decryption
625 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100626int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
627 int mode,
628 size_t length,
629 unsigned char iv[8],
630 const unsigned char *input,
631 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000632{
Gilles Peskine7820a572021-07-07 21:08:28 +0200633 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 unsigned char temp[8];
635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 if (length % 8) {
637 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
638 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000639
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 if (mode == MBEDTLS_DES_ENCRYPT) {
641 while (length > 0) {
642 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 ret = mbedtls_des_crypt_ecb(ctx, output, output);
645 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200646 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 }
648 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
650 input += 8;
651 output += 8;
652 length -= 8;
653 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 } else { /* MBEDTLS_DES_DECRYPT */
655 while (length > 0) {
656 memcpy(temp, input, 8);
657 ret = mbedtls_des_crypt_ecb(ctx, input, output);
658 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200659 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000663
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
666 input += 8;
667 output += 8;
668 length -= 8;
669 }
670 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200671 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000672
Gilles Peskine7820a572021-07-07 21:08:28 +0200673exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000675}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200676#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000677
678/*
679 * 3DES-ECB block encryption/decryption
680 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200681#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100682int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
683 const unsigned char input[8],
684 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000685{
686 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000687 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
689 SK = ctx->sk;
690
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 X = MBEDTLS_GET_UINT32_BE(input, 0);
692 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000695
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 for (i = 0; i < 8; i++) {
697 DES_ROUND(Y, X);
698 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000699 }
700
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 for (i = 0; i < 8; i++) {
702 DES_ROUND(X, Y);
703 DES_ROUND(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000704 }
705
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 for (i = 0; i < 8; i++) {
707 DES_ROUND(Y, X);
708 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000709 }
710
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
714 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000715
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000717}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200718#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000719
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200720#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000721/*
722 * 3DES-CBC buffer encryption/decryption
723 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100724int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
725 int mode,
726 size_t length,
727 unsigned char iv[8],
728 const unsigned char *input,
729 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000730{
Gilles Peskine7820a572021-07-07 21:08:28 +0200731 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000732 unsigned char temp[8];
733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 if (length % 8) {
735 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
736 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000737
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 if (mode == MBEDTLS_DES_ENCRYPT) {
739 while (length > 0) {
740 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000741
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 ret = mbedtls_des3_crypt_ecb(ctx, output, output);
743 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200744 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 }
746 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000747
748 input += 8;
749 output += 8;
750 length -= 8;
751 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 } else { /* MBEDTLS_DES_DECRYPT */
753 while (length > 0) {
754 memcpy(temp, input, 8);
755 ret = mbedtls_des3_crypt_ecb(ctx, input, output);
756 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200757 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000759
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000761
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000763
764 input += 8;
765 output += 8;
766 length -= 8;
767 }
768 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200769 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000770
Gilles Peskine7820a572021-07-07 21:08:28 +0200771exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000773}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000775
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200776#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200777
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200778#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000779/*
780 * DES and 3DES test vectors from:
781 *
782 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
783 */
784static const unsigned char des3_test_keys[24] =
785{
786 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
787 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
788 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
789};
790
Paul Bakker5121ce52009-01-03 21:22:43 +0000791static const unsigned char des3_test_buf[8] =
792{
793 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
794};
795
796static const unsigned char des3_test_ecb_dec[3][8] =
797{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100798 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
799 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
800 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000801};
802
803static const unsigned char des3_test_ecb_enc[3][8] =
804{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100805 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
806 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
807 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000808};
809
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200810#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100811static const unsigned char des3_test_iv[8] =
812{
813 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
814};
815
Paul Bakker5121ce52009-01-03 21:22:43 +0000816static const unsigned char des3_test_cbc_dec[3][8] =
817{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100818 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
819 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
820 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000821};
822
823static const unsigned char des3_test_cbc_enc[3][8] =
824{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100825 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
826 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
827 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000828};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000830
831/*
832 * Checkup routine
833 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100834int mbedtls_des_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000835{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200836 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 mbedtls_des_context ctx;
838 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000839 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200840#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000841 unsigned char prv[8];
842 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200843#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 mbedtls_des_init(&ctx);
846 mbedtls_des3_init(&ctx3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000847 /*
848 * ECB mode
849 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000851 u = i >> 1;
852 v = i & 1;
853
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 if (verbose != 0) {
855 mbedtls_printf(" DES%c-ECB-%3d (%s): ",
856 (u == 0) ? ' ' : '3', 56 + u * 56,
857 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000858 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100859
860 memcpy(buf, des3_test_buf, 8);
861
862 switch (i) {
863 case 0:
864 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
865 break;
866
867 case 1:
868 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
869 break;
870
871 case 2:
872 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
873 break;
874
875 case 3:
876 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
877 break;
878
879 case 4:
880 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
881 break;
882
883 case 5:
884 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
885 break;
886
887 default:
888 return 1;
889 }
890 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200891 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000892 }
893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 for (j = 0; j < 100; j++) {
895 if (u == 0) {
896 ret = mbedtls_des_crypt_ecb(&ctx, buf, buf);
897 } else {
898 ret = mbedtls_des3_crypt_ecb(&ctx3, buf, buf);
899 }
900 if (ret != 0) {
901 goto exit;
902 }
903 }
904
905 if ((v == MBEDTLS_DES_DECRYPT &&
906 memcmp(buf, des3_test_ecb_dec[u], 8) != 0) ||
907 (v != MBEDTLS_DES_DECRYPT &&
908 memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) {
909 if (verbose != 0) {
910 mbedtls_printf("failed\n");
911 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000912
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200913 ret = 1;
914 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000915 }
916
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 if (verbose != 0) {
918 mbedtls_printf("passed\n");
919 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000920 }
921
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 if (verbose != 0) {
923 mbedtls_printf("\n");
924 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000925
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000927 /*
928 * CBC mode
929 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000931 u = i >> 1;
932 v = i & 1;
933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 if (verbose != 0) {
935 mbedtls_printf(" DES%c-CBC-%3d (%s): ",
936 (u == 0) ? ' ' : '3', 56 + u * 56,
937 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000938 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100939
940 memcpy(iv, des3_test_iv, 8);
941 memcpy(prv, des3_test_iv, 8);
942 memcpy(buf, des3_test_buf, 8);
943
944 switch (i) {
945 case 0:
946 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
947 break;
948
949 case 1:
950 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
951 break;
952
953 case 2:
954 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
955 break;
956
957 case 3:
958 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
959 break;
960
961 case 4:
962 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
963 break;
964
965 case 5:
966 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
967 break;
968
969 default:
970 return 1;
971 }
972 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200973 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000974 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100975
976 if (v == MBEDTLS_DES_DECRYPT) {
977 for (j = 0; j < 100; j++) {
978 if (u == 0) {
979 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
980 } else {
981 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
982 }
983 if (ret != 0) {
984 goto exit;
985 }
986 }
987 } else {
988 for (j = 0; j < 100; j++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000989 unsigned char tmp[8];
990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 if (u == 0) {
992 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
993 } else {
994 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
995 }
996 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200997 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100998 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000999
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 memcpy(tmp, prv, 8);
1001 memcpy(prv, buf, 8);
1002 memcpy(buf, tmp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001003 }
1004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 memcpy(buf, prv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001006 }
1007
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 if ((v == MBEDTLS_DES_DECRYPT &&
1009 memcmp(buf, des3_test_cbc_dec[u], 8) != 0) ||
1010 (v != MBEDTLS_DES_DECRYPT &&
1011 memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) {
1012 if (verbose != 0) {
1013 mbedtls_printf("failed\n");
1014 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001015
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001016 ret = 1;
1017 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001018 }
1019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 if (verbose != 0) {
1021 mbedtls_printf("passed\n");
1022 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001023 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001025
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 if (verbose != 0) {
1027 mbedtls_printf("\n");
1028 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001029
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001030exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 mbedtls_des_free(&ctx);
1032 mbedtls_des3_free(&ctx3);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001035 ret = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 }
1037 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001038}
1039
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001040#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001041
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001042#endif /* MBEDTLS_DES_C */