blob: afe72cec00e265bb6e23069e740202092d70a1d9 [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 Rodgman7ff79652023-11-03 12:04:52 +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 Peskine377a3102021-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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100223 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000224
225/*
226 * Final Permutation macro
227 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100238 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000239
240/*
241 * DES round macro
242 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100243#define DES_ROUND(X, Y) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100244 do \
245 { \
246 T = *SK++ ^ (X); \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100263 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000264
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100265void mbedtls_des_init(mbedtls_des_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200266{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100267 memset(ctx, 0, sizeof(mbedtls_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200268}
269
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100270void mbedtls_des_free(mbedtls_des_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200271{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100272 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200273 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100274 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200275
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100276 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200277}
278
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100279void mbedtls_des3_init(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200280{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100281 memset(ctx, 0, sizeof(mbedtls_des3_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200282}
283
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100284void mbedtls_des3_free(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200285{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100286 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200287 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100288 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200289
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100407 T = ((Y) ^ X) & 0x10101010; X ^= T; Y ^= (T);
Paul Bakker5121ce52009-01-03 21:22:43 +0000408
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100466 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000467
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100468 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000469}
470
471/*
472 * DES key schedule (56-bit, decryption)
473 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100478 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100485 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000486}
487
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100494 mbedtls_des_setkey(esk, key);
495 mbedtls_des_setkey(dsk + 32, key + 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000496
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100504 esk[i + 64] = esk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000505 esk[i + 65] = esk[i + 1];
506
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100520 des3_set2key(ctx->sk, sk, key);
521 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000522
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100523 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000524}
525
526/*
527 * Triple-DES key schedule (112-bit, decryption)
528 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100534 des3_set2key(sk, ctx->sk, key);
535 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000536
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100537 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000538}
539
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100570 des3_set3key(ctx->sk, sk, key);
571 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000572
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100573 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000574}
575
576/*
577 * Triple-DES key schedule (168-bit, decryption)
578 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100584 des3_set3key(sk, ctx->sk, key);
585 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000586
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100606 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100613 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000614
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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{
633 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +0200634 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 unsigned char temp[8];
636
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100637 if (length % 8) {
638 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
639 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000640
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100641 if (mode == MBEDTLS_DES_ENCRYPT) {
642 while (length > 0) {
643 for (i = 0; i < 8; i++) {
644 output[i] = (unsigned char) (input[i] ^ iv[i]);
645 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000646
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100647 ret = mbedtls_des_crypt_ecb(ctx, output, output);
648 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200649 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100650 }
651 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000652
653 input += 8;
654 output += 8;
655 length -= 8;
656 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100657 } else { /* MBEDTLS_DES_DECRYPT */
658 while (length > 0) {
659 memcpy(temp, input, 8);
660 ret = mbedtls_des_crypt_ecb(ctx, input, output);
661 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200662 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100663 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000664
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100665 for (i = 0; i < 8; i++) {
666 output[i] = (unsigned char) (output[i] ^ iv[i]);
667 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100669 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000670
671 input += 8;
672 output += 8;
673 length -= 8;
674 }
675 }
Gilles Peskine377a3102021-07-07 21:08:28 +0200676 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000677
Gilles Peskine377a3102021-07-07 21:08:28 +0200678exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100679 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000680}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200681#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
683/*
684 * 3DES-ECB block encryption/decryption
685 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200686#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100687int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
688 const unsigned char input[8],
689 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000690{
691 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000692 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000693
694 SK = ctx->sk;
695
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100696 X = MBEDTLS_GET_UINT32_BE(input, 0);
697 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100699 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100701 for (i = 0; i < 8; i++) {
702 DES_ROUND(Y, X);
703 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000704 }
705
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100706 for (i = 0; i < 8; i++) {
707 DES_ROUND(X, Y);
708 DES_ROUND(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000709 }
710
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100711 for (i = 0; i < 8; i++) {
712 DES_ROUND(Y, X);
713 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000714 }
715
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100716 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100718 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
719 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000720
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100721 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000722}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200723#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000724
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000726/*
727 * 3DES-CBC buffer encryption/decryption
728 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100729int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
730 int mode,
731 size_t length,
732 unsigned char iv[8],
733 const unsigned char *input,
734 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000735{
736 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +0200737 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000738 unsigned char temp[8];
739
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100740 if (length % 8) {
741 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
742 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000743
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100744 if (mode == MBEDTLS_DES_ENCRYPT) {
745 while (length > 0) {
746 for (i = 0; i < 8; i++) {
747 output[i] = (unsigned char) (input[i] ^ iv[i]);
748 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000749
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100750 ret = mbedtls_des3_crypt_ecb(ctx, output, output);
751 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200752 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100753 }
754 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000755
756 input += 8;
757 output += 8;
758 length -= 8;
759 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100760 } else { /* MBEDTLS_DES_DECRYPT */
761 while (length > 0) {
762 memcpy(temp, input, 8);
763 ret = mbedtls_des3_crypt_ecb(ctx, input, output);
764 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200765 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100766 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000767
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100768 for (i = 0; i < 8; i++) {
769 output[i] = (unsigned char) (output[i] ^ iv[i]);
770 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100772 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000773
774 input += 8;
775 output += 8;
776 length -= 8;
777 }
778 }
Gilles Peskine377a3102021-07-07 21:08:28 +0200779 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000780
Gilles Peskine377a3102021-07-07 21:08:28 +0200781exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100782 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000783}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200784#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000785
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200787
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000789/*
790 * DES and 3DES test vectors from:
791 *
792 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
793 */
794static const unsigned char des3_test_keys[24] =
795{
796 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
797 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
798 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
799};
800
Paul Bakker5121ce52009-01-03 21:22:43 +0000801static const unsigned char des3_test_buf[8] =
802{
803 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
804};
805
806static const unsigned char des3_test_ecb_dec[3][8] =
807{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100808 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
809 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
810 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000811};
812
813static const unsigned char des3_test_ecb_enc[3][8] =
814{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100815 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
816 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
817 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000818};
819
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100821static const unsigned char des3_test_iv[8] =
822{
823 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
824};
825
Paul Bakker5121ce52009-01-03 21:22:43 +0000826static const unsigned char des3_test_cbc_dec[3][8] =
827{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100828 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
829 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
830 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000831};
832
833static const unsigned char des3_test_cbc_enc[3][8] =
834{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100835 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
836 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
837 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000838};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000840
841/*
842 * Checkup routine
843 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100844int mbedtls_des_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000845{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200846 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847 mbedtls_des_context ctx;
848 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000849 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200850#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000851 unsigned char prv[8];
852 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200853#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000854
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100855 mbedtls_des_init(&ctx);
856 mbedtls_des3_init(&ctx3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000857 /*
858 * ECB mode
859 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100860 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000861 u = i >> 1;
862 v = i & 1;
863
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100864 if (verbose != 0) {
865 mbedtls_printf(" DES%c-ECB-%3d (%s): ",
866 (u == 0) ? ' ' : '3', 56 + u * 56,
867 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000868 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100869
870 memcpy(buf, des3_test_buf, 8);
871
872 switch (i) {
873 case 0:
874 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
875 break;
876
877 case 1:
878 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
879 break;
880
881 case 2:
882 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
883 break;
884
885 case 3:
886 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
887 break;
888
889 case 4:
890 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
891 break;
892
893 case 5:
894 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
895 break;
896
897 default:
898 return 1;
899 }
900 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200901 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000902 }
903
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100904 for (j = 0; j < 100; j++) {
905 if (u == 0) {
906 ret = mbedtls_des_crypt_ecb(&ctx, buf, buf);
907 } else {
908 ret = mbedtls_des3_crypt_ecb(&ctx3, buf, buf);
909 }
910 if (ret != 0) {
911 goto exit;
912 }
913 }
914
915 if ((v == MBEDTLS_DES_DECRYPT &&
916 memcmp(buf, des3_test_ecb_dec[u], 8) != 0) ||
917 (v != MBEDTLS_DES_DECRYPT &&
918 memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) {
919 if (verbose != 0) {
920 mbedtls_printf("failed\n");
921 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000922
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200923 ret = 1;
924 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000925 }
926
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100927 if (verbose != 0) {
928 mbedtls_printf("passed\n");
929 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000930 }
931
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100932 if (verbose != 0) {
933 mbedtls_printf("\n");
934 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000935
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000937 /*
938 * CBC mode
939 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100940 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000941 u = i >> 1;
942 v = i & 1;
943
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100944 if (verbose != 0) {
945 mbedtls_printf(" DES%c-CBC-%3d (%s): ",
946 (u == 0) ? ' ' : '3', 56 + u * 56,
947 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000948 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100949
950 memcpy(iv, des3_test_iv, 8);
951 memcpy(prv, des3_test_iv, 8);
952 memcpy(buf, des3_test_buf, 8);
953
954 switch (i) {
955 case 0:
956 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
957 break;
958
959 case 1:
960 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
961 break;
962
963 case 2:
964 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
965 break;
966
967 case 3:
968 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
969 break;
970
971 case 4:
972 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
973 break;
974
975 case 5:
976 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
977 break;
978
979 default:
980 return 1;
981 }
982 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200983 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000984 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100985
986 if (v == MBEDTLS_DES_DECRYPT) {
987 for (j = 0; j < 100; j++) {
988 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) {
994 goto exit;
995 }
996 }
997 } else {
998 for (j = 0; j < 100; j++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000999 unsigned char tmp[8];
1000
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001001 if (u == 0) {
1002 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
1003 } else {
1004 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
1005 }
1006 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001007 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001008 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001009
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001010 memcpy(tmp, prv, 8);
1011 memcpy(prv, buf, 8);
1012 memcpy(buf, tmp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001013 }
1014
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001015 memcpy(buf, prv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001016 }
1017
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001018 if ((v == MBEDTLS_DES_DECRYPT &&
1019 memcmp(buf, des3_test_cbc_dec[u], 8) != 0) ||
1020 (v != MBEDTLS_DES_DECRYPT &&
1021 memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) {
1022 if (verbose != 0) {
1023 mbedtls_printf("failed\n");
1024 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001025
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001026 ret = 1;
1027 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001028 }
1029
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001030 if (verbose != 0) {
1031 mbedtls_printf("passed\n");
1032 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001033 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001034#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001035
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001036 if (verbose != 0) {
1037 mbedtls_printf("\n");
1038 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001039
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001040exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001041 mbedtls_des_free(&ctx);
1042 mbedtls_des3_free(&ctx3);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001043
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001044 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001045 ret = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001046 }
1047 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001048}
1049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001050#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001052#endif /* MBEDTLS_DES_C */