blob: eaddf282a9d48c806f6b419ce09305bd5755d45c [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
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * DES, on which TDES is based, was originally designed by Horst Feistel
21 * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
22 *
23 * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/des.h"
Gilles Peskine7820a572021-07-07 21:08:28 +020031#include "mbedtls/error.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050032#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020039
Paul Bakker5121ce52009-01-03 21:22:43 +000040/*
Paul Bakker5121ce52009-01-03 21:22:43 +000041 * Expanded DES S-boxes
42 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000043static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000044{
45 0x01010400, 0x00000000, 0x00010000, 0x01010404,
46 0x01010004, 0x00010404, 0x00000004, 0x00010000,
47 0x00000400, 0x01010400, 0x01010404, 0x00000400,
48 0x01000404, 0x01010004, 0x01000000, 0x00000004,
49 0x00000404, 0x01000400, 0x01000400, 0x00010400,
50 0x00010400, 0x01010000, 0x01010000, 0x01000404,
51 0x00010004, 0x01000004, 0x01000004, 0x00010004,
52 0x00000000, 0x00000404, 0x00010404, 0x01000000,
53 0x00010000, 0x01010404, 0x00000004, 0x01010000,
54 0x01010400, 0x01000000, 0x01000000, 0x00000400,
55 0x01010004, 0x00010000, 0x00010400, 0x01000004,
56 0x00000400, 0x00000004, 0x01000404, 0x00010404,
57 0x01010404, 0x00010004, 0x01010000, 0x01000404,
58 0x01000004, 0x00000404, 0x00010404, 0x01010400,
59 0x00000404, 0x01000400, 0x01000400, 0x00000000,
60 0x00010004, 0x00010400, 0x00000000, 0x01010004
61};
62
Paul Bakker5c2364c2012-10-01 14:41:15 +000063static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000064{
65 0x80108020, 0x80008000, 0x00008000, 0x00108020,
66 0x00100000, 0x00000020, 0x80100020, 0x80008020,
67 0x80000020, 0x80108020, 0x80108000, 0x80000000,
68 0x80008000, 0x00100000, 0x00000020, 0x80100020,
69 0x00108000, 0x00100020, 0x80008020, 0x00000000,
70 0x80000000, 0x00008000, 0x00108020, 0x80100000,
71 0x00100020, 0x80000020, 0x00000000, 0x00108000,
72 0x00008020, 0x80108000, 0x80100000, 0x00008020,
73 0x00000000, 0x00108020, 0x80100020, 0x00100000,
74 0x80008020, 0x80100000, 0x80108000, 0x00008000,
75 0x80100000, 0x80008000, 0x00000020, 0x80108020,
76 0x00108020, 0x00000020, 0x00008000, 0x80000000,
77 0x00008020, 0x80108000, 0x00100000, 0x80000020,
78 0x00100020, 0x80008020, 0x80000020, 0x00100020,
79 0x00108000, 0x00000000, 0x80008000, 0x00008020,
80 0x80000000, 0x80100020, 0x80108020, 0x00108000
81};
82
Paul Bakker5c2364c2012-10-01 14:41:15 +000083static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000084{
85 0x00000208, 0x08020200, 0x00000000, 0x08020008,
86 0x08000200, 0x00000000, 0x00020208, 0x08000200,
87 0x00020008, 0x08000008, 0x08000008, 0x00020000,
88 0x08020208, 0x00020008, 0x08020000, 0x00000208,
89 0x08000000, 0x00000008, 0x08020200, 0x00000200,
90 0x00020200, 0x08020000, 0x08020008, 0x00020208,
91 0x08000208, 0x00020200, 0x00020000, 0x08000208,
92 0x00000008, 0x08020208, 0x00000200, 0x08000000,
93 0x08020200, 0x08000000, 0x00020008, 0x00000208,
94 0x00020000, 0x08020200, 0x08000200, 0x00000000,
95 0x00000200, 0x00020008, 0x08020208, 0x08000200,
96 0x08000008, 0x00000200, 0x00000000, 0x08020008,
97 0x08000208, 0x00020000, 0x08000000, 0x08020208,
98 0x00000008, 0x00020208, 0x00020200, 0x08000008,
99 0x08020000, 0x08000208, 0x00000208, 0x08020000,
100 0x00020208, 0x00000008, 0x08020008, 0x00020200
101};
102
Paul Bakker5c2364c2012-10-01 14:41:15 +0000103static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000104{
105 0x00802001, 0x00002081, 0x00002081, 0x00000080,
106 0x00802080, 0x00800081, 0x00800001, 0x00002001,
107 0x00000000, 0x00802000, 0x00802000, 0x00802081,
108 0x00000081, 0x00000000, 0x00800080, 0x00800001,
109 0x00000001, 0x00002000, 0x00800000, 0x00802001,
110 0x00000080, 0x00800000, 0x00002001, 0x00002080,
111 0x00800081, 0x00000001, 0x00002080, 0x00800080,
112 0x00002000, 0x00802080, 0x00802081, 0x00000081,
113 0x00800080, 0x00800001, 0x00802000, 0x00802081,
114 0x00000081, 0x00000000, 0x00000000, 0x00802000,
115 0x00002080, 0x00800080, 0x00800081, 0x00000001,
116 0x00802001, 0x00002081, 0x00002081, 0x00000080,
117 0x00802081, 0x00000081, 0x00000001, 0x00002000,
118 0x00800001, 0x00002001, 0x00802080, 0x00800081,
119 0x00002001, 0x00002080, 0x00800000, 0x00802001,
120 0x00000080, 0x00800000, 0x00002000, 0x00802080
121};
122
Paul Bakker5c2364c2012-10-01 14:41:15 +0000123static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000124{
125 0x00000100, 0x02080100, 0x02080000, 0x42000100,
126 0x00080000, 0x00000100, 0x40000000, 0x02080000,
127 0x40080100, 0x00080000, 0x02000100, 0x40080100,
128 0x42000100, 0x42080000, 0x00080100, 0x40000000,
129 0x02000000, 0x40080000, 0x40080000, 0x00000000,
130 0x40000100, 0x42080100, 0x42080100, 0x02000100,
131 0x42080000, 0x40000100, 0x00000000, 0x42000000,
132 0x02080100, 0x02000000, 0x42000000, 0x00080100,
133 0x00080000, 0x42000100, 0x00000100, 0x02000000,
134 0x40000000, 0x02080000, 0x42000100, 0x40080100,
135 0x02000100, 0x40000000, 0x42080000, 0x02080100,
136 0x40080100, 0x00000100, 0x02000000, 0x42080000,
137 0x42080100, 0x00080100, 0x42000000, 0x42080100,
138 0x02080000, 0x00000000, 0x40080000, 0x42000000,
139 0x00080100, 0x02000100, 0x40000100, 0x00080000,
140 0x00000000, 0x40080000, 0x02080100, 0x40000100
141};
142
Paul Bakker5c2364c2012-10-01 14:41:15 +0000143static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000144{
145 0x20000010, 0x20400000, 0x00004000, 0x20404010,
146 0x20400000, 0x00000010, 0x20404010, 0x00400000,
147 0x20004000, 0x00404010, 0x00400000, 0x20000010,
148 0x00400010, 0x20004000, 0x20000000, 0x00004010,
149 0x00000000, 0x00400010, 0x20004010, 0x00004000,
150 0x00404000, 0x20004010, 0x00000010, 0x20400010,
151 0x20400010, 0x00000000, 0x00404010, 0x20404000,
152 0x00004010, 0x00404000, 0x20404000, 0x20000000,
153 0x20004000, 0x00000010, 0x20400010, 0x00404000,
154 0x20404010, 0x00400000, 0x00004010, 0x20000010,
155 0x00400000, 0x20004000, 0x20000000, 0x00004010,
156 0x20000010, 0x20404010, 0x00404000, 0x20400000,
157 0x00404010, 0x20404000, 0x00000000, 0x20400010,
158 0x00000010, 0x00004000, 0x20400000, 0x00404010,
159 0x00004000, 0x00400010, 0x20004010, 0x00000000,
160 0x20404000, 0x20000000, 0x00400010, 0x20004010
161};
162
Paul Bakker5c2364c2012-10-01 14:41:15 +0000163static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000164{
165 0x00200000, 0x04200002, 0x04000802, 0x00000000,
166 0x00000800, 0x04000802, 0x00200802, 0x04200800,
167 0x04200802, 0x00200000, 0x00000000, 0x04000002,
168 0x00000002, 0x04000000, 0x04200002, 0x00000802,
169 0x04000800, 0x00200802, 0x00200002, 0x04000800,
170 0x04000002, 0x04200000, 0x04200800, 0x00200002,
171 0x04200000, 0x00000800, 0x00000802, 0x04200802,
172 0x00200800, 0x00000002, 0x04000000, 0x00200800,
173 0x04000000, 0x00200800, 0x00200000, 0x04000802,
174 0x04000802, 0x04200002, 0x04200002, 0x00000002,
175 0x00200002, 0x04000000, 0x04000800, 0x00200000,
176 0x04200800, 0x00000802, 0x00200802, 0x04200800,
177 0x00000802, 0x04000002, 0x04200802, 0x04200000,
178 0x00200800, 0x00000000, 0x00000002, 0x04200802,
179 0x00000000, 0x00200802, 0x04200000, 0x00000800,
180 0x04000002, 0x04000800, 0x00000800, 0x00200002
181};
182
Paul Bakker5c2364c2012-10-01 14:41:15 +0000183static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000184{
185 0x10001040, 0x00001000, 0x00040000, 0x10041040,
186 0x10000000, 0x10001040, 0x00000040, 0x10000000,
187 0x00040040, 0x10040000, 0x10041040, 0x00041000,
188 0x10041000, 0x00041040, 0x00001000, 0x00000040,
189 0x10040000, 0x10000040, 0x10001000, 0x00001040,
190 0x00041000, 0x00040040, 0x10040040, 0x10041000,
191 0x00001040, 0x00000000, 0x00000000, 0x10040040,
192 0x10000040, 0x10001000, 0x00041040, 0x00040000,
193 0x00041040, 0x00040000, 0x10041000, 0x00001000,
194 0x00000040, 0x10040040, 0x00001000, 0x00041040,
195 0x10001000, 0x00000040, 0x10000040, 0x10040000,
196 0x10040040, 0x10000000, 0x00040000, 0x10001040,
197 0x00000000, 0x10041040, 0x00040040, 0x10000040,
198 0x10040000, 0x10001000, 0x10001040, 0x00000000,
199 0x10041040, 0x00041000, 0x00041000, 0x00001040,
200 0x00001040, 0x00040040, 0x10000000, 0x10041000
201};
202
203/*
204 * PC1: left and right halves bit-swap
205 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000206static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000207{
208 0x00000000, 0x00000001, 0x00000100, 0x00000101,
209 0x00010000, 0x00010001, 0x00010100, 0x00010101,
210 0x01000000, 0x01000001, 0x01000100, 0x01000101,
211 0x01010000, 0x01010001, 0x01010100, 0x01010101
212};
213
Paul Bakker5c2364c2012-10-01 14:41:15 +0000214static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000215{
216 0x00000000, 0x01000000, 0x00010000, 0x01010000,
217 0x00000100, 0x01000100, 0x00010100, 0x01010100,
218 0x00000001, 0x01000001, 0x00010001, 0x01010001,
219 0x00000101, 0x01000101, 0x00010101, 0x01010101,
220};
221
222/*
223 * Initial Permutation macro
224 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100225#define DES_IP(X, Y) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100226 do \
227 { \
228 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
229 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
230 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
231 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
232 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
233 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
234 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000236
237/*
238 * Final Permutation macro
239 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100240#define DES_FP(X, Y) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100241 do \
242 { \
243 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
244 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
245 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
246 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
247 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
248 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
249 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000251
252/*
253 * DES round macro
254 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100255#define DES_ROUND(X, Y) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100256 do \
257 { \
258 T = *SK++ ^ (X); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 (Y) ^= SB8[(T) & 0x3F] ^ \
260 SB6[(T >> 8) & 0x3F] ^ \
261 SB4[(T >> 16) & 0x3F] ^ \
262 SB2[(T >> 24) & 0x3F]; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100263 \
264 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 (Y) ^= SB7[(T) & 0x3F] ^ \
266 SB5[(T >> 8) & 0x3F] ^ \
267 SB3[(T >> 16) & 0x3F] ^ \
268 SB1[(T >> 24) & 0x3F]; \
269 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000270
Gilles Peskine449bd832023-01-11 14:50:10 +0100271#define SWAP(a, b) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100272 do \
273 { \
274 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
Gilles Peskine449bd832023-01-11 14:50:10 +0100277void mbedtls_des_init(mbedtls_des_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200278{
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 memset(ctx, 0, sizeof(mbedtls_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200280}
281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282void mbedtls_des_free(mbedtls_des_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_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200289}
290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291void mbedtls_des3_init(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200292{
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 memset(ctx, 0, sizeof(mbedtls_des3_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200294}
295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296void mbedtls_des3_free(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200297{
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200299 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des3_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200303}
304
Paul Bakker1f87fb62011-01-15 17:32:24 +0000305static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32,
307 35, 37, 38, 41, 42, 44,
308 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69,
309 70, 73, 74, 76, 79, 81,
310 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103,
311 104, 107, 109, 110, 112,
312 115, 117, 118, 121, 122, 124, 127, 128, 131,
313 133, 134, 137, 138, 140,
314 143, 145, 146, 148, 151, 152, 155, 157, 158,
315 161, 162, 164, 167, 168,
316 171, 173, 174, 176, 179, 181, 182, 185, 186,
317 188, 191, 193, 194, 196,
318 199, 200, 203, 205, 206, 208, 211, 213, 214,
319 217, 218, 220, 223, 224,
320 227, 229, 230, 233, 234, 236, 239, 241, 242,
321 244, 247, 248, 251, 253,
322 254 };
Paul Bakker1f87fb62011-01-15 17:32:24 +0000323
Gilles Peskine449bd832023-01-11 14:50:10 +0100324void mbedtls_des_key_set_parity(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++) {
Paul Bakker1f87fb62011-01-15 17:32:24 +0000329 key[i] = odd_parity_table[key[i] / 2];
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 }
Paul Bakker1f87fb62011-01-15 17:32:24 +0000331}
332
333/*
334 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
335 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100336int mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker1f87fb62011-01-15 17:32:24 +0000337{
338 int i;
339
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) {
341 if (key[i] != odd_parity_table[key[i] / 2]) {
342 return 1;
343 }
344 }
Paul Bakker1f87fb62011-01-15 17:32:24 +0000345
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 return 0;
Paul Bakker1f87fb62011-01-15 17:32:24 +0000347}
348
349/*
350 * Table of weak and semi-weak keys
351 *
352 * Source: http://en.wikipedia.org/wiki/Weak_key
353 *
354 * Weak:
355 * Alternating ones + zeros (0x0101010101010101)
356 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
357 * '0xE0E0E0E0F1F1F1F1'
358 * '0x1F1F1F1F0E0E0E0E'
359 *
360 * Semi-weak:
361 * 0x011F011F010E010E and 0x1F011F010E010E01
362 * 0x01E001E001F101F1 and 0xE001E001F101F101
363 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
364 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
365 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
366 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
367 *
368 */
369
370#define WEAK_KEY_COUNT 16
371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000373{
374 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
375 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
376 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
377 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
378
379 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
380 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
381 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
382 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
383 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
384 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
385 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
386 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
387 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
388 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
389 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
390 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
391};
392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393int mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker1f87fb62011-01-15 17:32:24 +0000394{
395 int i;
396
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 for (i = 0; i < WEAK_KEY_COUNT; i++) {
398 if (memcmp(weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0) {
399 return 1;
400 }
401 }
Paul Bakker1f87fb62011-01-15 17:32:24 +0000402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 return 0;
Paul Bakker1f87fb62011-01-15 17:32:24 +0000404}
405
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200406#if !defined(MBEDTLS_DES_SETKEY_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100407void mbedtls_des_setkey(uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000408{
409 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000410 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 X = MBEDTLS_GET_UINT32_BE(key, 0);
413 Y = MBEDTLS_GET_UINT32_BE(key, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
415 /*
416 * Permuted Choice 1
417 */
418 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 T = ((Y) ^ X) & 0x10101010; X ^= T; Y ^= (T);
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 X = (LHs[(X) & 0xF] << 3) | (LHs[(X >> 8) & 0xF] << 2)
422 | (LHs[(X >> 16) & 0xF] << 1) | (LHs[(X >> 24) & 0xF])
423 | (LHs[(X >> 5) & 0xF] << 7) | (LHs[(X >> 13) & 0xF] << 6)
424 | (LHs[(X >> 21) & 0xF] << 5) | (LHs[(X >> 29) & 0xF] << 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 Y = (RHs[(Y >> 1) & 0xF] << 3) | (RHs[(Y >> 9) & 0xF] << 2)
427 | (RHs[(Y >> 17) & 0xF] << 1) | (RHs[(Y >> 25) & 0xF])
428 | (RHs[(Y >> 4) & 0xF] << 7) | (RHs[(Y >> 12) & 0xF] << 6)
429 | (RHs[(Y >> 20) & 0xF] << 5) | (RHs[(Y >> 28) & 0xF] << 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
431 X &= 0x0FFFFFFF;
432 Y &= 0x0FFFFFFF;
433
434 /*
435 * calculate subkeys
436 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 for (i = 0; i < 16; i++) {
438 if (i < 2 || i == 8 || i == 15) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
440 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 } else {
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
443 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
444 }
445
446 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
447 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
448 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
449 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
450 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
451 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
452 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 | ((Y >> 14) & 0x00000200) | ((Y) & 0x00000100)
Paul Bakker5121ce52009-01-03 21:22:43 +0000454 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
455 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
456 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
457
458 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
459 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
460 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
461 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
462 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
463 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
464 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
465 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 | ((Y) & 0x00000200) | ((Y << 7) & 0x00000100)
Paul Bakker5121ce52009-01-03 21:22:43 +0000467 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
468 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
469 }
470}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200471#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
473/*
474 * DES key schedule (56-bit, encryption)
475 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100476int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000477{
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000481}
482
483/*
484 * DES key schedule (56-bit, decryption)
485 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100486int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000487{
488 int i;
489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 for (i = 0; i < 16; i += 2) {
493 SWAP(ctx->sk[i], ctx->sk[30 - i]);
494 SWAP(ctx->sk[i + 1], ctx->sk[31 - i]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000495 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000498}
499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500static void des3_set2key(uint32_t esk[96],
501 uint32_t dsk[96],
502 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000503{
504 int i;
505
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 mbedtls_des_setkey(esk, key);
507 mbedtls_des_setkey(dsk + 32, key + 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 for (i = 0; i < 32; i += 2) {
510 dsk[i] = esk[30 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000511 dsk[i + 1] = esk[31 - i];
512
513 esk[i + 32] = dsk[62 - i];
514 esk[i + 33] = dsk[63 - i];
515
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 esk[i + 64] = esk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000517 esk[i + 65] = esk[i + 1];
518
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 dsk[i + 64] = dsk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000520 dsk[i + 65] = dsk[i + 1];
521 }
522}
523
524/*
525 * Triple-DES key schedule (112-bit, encryption)
526 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100527int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx,
528 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000529{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000530 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000531
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 des3_set2key(ctx->sk, sk, key);
533 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000534
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000536}
537
538/*
539 * Triple-DES key schedule (112-bit, decryption)
540 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100541int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx,
542 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000543{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000544 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 des3_set2key(sk, ctx->sk, key);
547 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000550}
551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552static void des3_set3key(uint32_t esk[96],
553 uint32_t dsk[96],
554 const unsigned char key[24])
Paul Bakker5121ce52009-01-03 21:22:43 +0000555{
556 int i;
557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 mbedtls_des_setkey(esk, key);
559 mbedtls_des_setkey(dsk + 32, key + 8);
560 mbedtls_des_setkey(esk + 64, key + 16);
Paul Bakker5121ce52009-01-03 21:22:43 +0000561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 for (i = 0; i < 32; i += 2) {
563 dsk[i] = esk[94 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000564 dsk[i + 1] = esk[95 - i];
565
566 esk[i + 32] = dsk[62 - i];
567 esk[i + 33] = dsk[63 - i];
568
569 dsk[i + 64] = esk[30 - i];
570 dsk[i + 65] = esk[31 - i];
571 }
572}
573
574/*
575 * Triple-DES key schedule (168-bit, encryption)
576 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100577int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx,
578 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000579{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000580 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 des3_set3key(ctx->sk, sk, key);
583 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000584
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000586}
587
588/*
589 * Triple-DES key schedule (168-bit, decryption)
590 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100591int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx,
592 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000593{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000594 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 des3_set3key(sk, ctx->sk, key);
597 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000598
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000600}
601
602/*
603 * DES-ECB block encryption/decryption
604 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200605#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100606int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx,
607 const unsigned char input[8],
608 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000609{
610 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000611 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
613 SK = ctx->sk;
614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 X = MBEDTLS_GET_UINT32_BE(input, 0);
616 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 for (i = 0; i < 8; i++) {
621 DES_ROUND(Y, X);
622 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000623 }
624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
628 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000631}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200632#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000635/*
636 * DES-CBC buffer encryption/decryption
637 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100638int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
639 int mode,
640 size_t length,
641 unsigned char iv[8],
642 const unsigned char *input,
643 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000644{
Gilles Peskine7820a572021-07-07 21:08:28 +0200645 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000646 unsigned char temp[8];
647
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 if (length % 8) {
649 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
650 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 if (mode == MBEDTLS_DES_ENCRYPT) {
653 while (length > 0) {
654 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 ret = mbedtls_des_crypt_ecb(ctx, output, output);
657 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200658 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 }
660 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
662 input += 8;
663 output += 8;
664 length -= 8;
665 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 } else { /* MBEDTLS_DES_DECRYPT */
667 while (length > 0) {
668 memcpy(temp, input, 8);
669 ret = mbedtls_des_crypt_ecb(ctx, input, output);
670 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200671 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000673
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000677
678 input += 8;
679 output += 8;
680 length -= 8;
681 }
682 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200683 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000684
Gilles Peskine7820a572021-07-07 21:08:28 +0200685exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000687}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200688#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000689
690/*
691 * 3DES-ECB block encryption/decryption
692 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200693#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100694int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
695 const unsigned char input[8],
696 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000697{
698 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000699 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
701 SK = ctx->sk;
702
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 X = MBEDTLS_GET_UINT32_BE(input, 0);
704 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000705
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000707
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 for (i = 0; i < 8; i++) {
709 DES_ROUND(Y, X);
710 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000711 }
712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 for (i = 0; i < 8; i++) {
714 DES_ROUND(X, Y);
715 DES_ROUND(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000716 }
717
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 for (i = 0; i < 8; i++) {
719 DES_ROUND(Y, X);
720 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000721 }
722
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000724
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
726 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000727
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000729}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200730#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000731
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200732#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000733/*
734 * 3DES-CBC buffer encryption/decryption
735 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100736int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
737 int mode,
738 size_t length,
739 unsigned char iv[8],
740 const unsigned char *input,
741 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000742{
Gilles Peskine7820a572021-07-07 21:08:28 +0200743 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000744 unsigned char temp[8];
745
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 if (length % 8) {
747 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
748 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000749
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 if (mode == MBEDTLS_DES_ENCRYPT) {
751 while (length > 0) {
752 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 ret = mbedtls_des3_crypt_ecb(ctx, output, output);
755 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200756 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 }
758 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000759
760 input += 8;
761 output += 8;
762 length -= 8;
763 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 } else { /* MBEDTLS_DES_DECRYPT */
765 while (length > 0) {
766 memcpy(temp, input, 8);
767 ret = mbedtls_des3_crypt_ecb(ctx, input, output);
768 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200769 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000773
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000775
776 input += 8;
777 output += 8;
778 length -= 8;
779 }
780 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200781 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000782
Gilles Peskine7820a572021-07-07 21:08:28 +0200783exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000785}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000787
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200789
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000791/*
792 * DES and 3DES test vectors from:
793 *
794 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
795 */
796static const unsigned char des3_test_keys[24] =
797{
798 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
799 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
800 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
801};
802
Paul Bakker5121ce52009-01-03 21:22:43 +0000803static const unsigned char des3_test_buf[8] =
804{
805 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
806};
807
808static const unsigned char des3_test_ecb_dec[3][8] =
809{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100810 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
811 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
812 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000813};
814
815static const unsigned char des3_test_ecb_enc[3][8] =
816{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100817 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
818 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
819 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000820};
821
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200822#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100823static const unsigned char des3_test_iv[8] =
824{
825 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
826};
827
Paul Bakker5121ce52009-01-03 21:22:43 +0000828static const unsigned char des3_test_cbc_dec[3][8] =
829{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100830 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
831 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
832 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000833};
834
835static const unsigned char des3_test_cbc_enc[3][8] =
836{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100837 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
838 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
839 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000840};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000842
843/*
844 * Checkup routine
845 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100846int mbedtls_des_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000847{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200848 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849 mbedtls_des_context ctx;
850 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000851 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000853 unsigned char prv[8];
854 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200855#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000856
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 mbedtls_des_init(&ctx);
858 mbedtls_des3_init(&ctx3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000859 /*
860 * ECB mode
861 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000863 u = i >> 1;
864 v = i & 1;
865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 if (verbose != 0) {
867 mbedtls_printf(" DES%c-ECB-%3d (%s): ",
868 (u == 0) ? ' ' : '3', 56 + u * 56,
869 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000870 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100871
872 memcpy(buf, des3_test_buf, 8);
873
874 switch (i) {
875 case 0:
876 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
877 break;
878
879 case 1:
880 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
881 break;
882
883 case 2:
884 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
885 break;
886
887 case 3:
888 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
889 break;
890
891 case 4:
892 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
893 break;
894
895 case 5:
896 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
897 break;
898
899 default:
900 return 1;
901 }
902 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200903 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000904 }
905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 for (j = 0; j < 100; j++) {
907 if (u == 0) {
908 ret = mbedtls_des_crypt_ecb(&ctx, buf, buf);
909 } else {
910 ret = mbedtls_des3_crypt_ecb(&ctx3, buf, buf);
911 }
912 if (ret != 0) {
913 goto exit;
914 }
915 }
916
917 if ((v == MBEDTLS_DES_DECRYPT &&
918 memcmp(buf, des3_test_ecb_dec[u], 8) != 0) ||
919 (v != MBEDTLS_DES_DECRYPT &&
920 memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) {
921 if (verbose != 0) {
922 mbedtls_printf("failed\n");
923 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000924
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200925 ret = 1;
926 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000927 }
928
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 if (verbose != 0) {
930 mbedtls_printf("passed\n");
931 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000932 }
933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 if (verbose != 0) {
935 mbedtls_printf("\n");
936 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000937
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000939 /*
940 * CBC mode
941 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000943 u = i >> 1;
944 v = i & 1;
945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 if (verbose != 0) {
947 mbedtls_printf(" DES%c-CBC-%3d (%s): ",
948 (u == 0) ? ' ' : '3', 56 + u * 56,
949 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000950 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100951
952 memcpy(iv, des3_test_iv, 8);
953 memcpy(prv, des3_test_iv, 8);
954 memcpy(buf, des3_test_buf, 8);
955
956 switch (i) {
957 case 0:
958 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
959 break;
960
961 case 1:
962 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
963 break;
964
965 case 2:
966 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
967 break;
968
969 case 3:
970 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
971 break;
972
973 case 4:
974 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
975 break;
976
977 case 5:
978 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
979 break;
980
981 default:
982 return 1;
983 }
984 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200985 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100987
988 if (v == MBEDTLS_DES_DECRYPT) {
989 for (j = 0; j < 100; j++) {
990 if (u == 0) {
991 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
992 } else {
993 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
994 }
995 if (ret != 0) {
996 goto exit;
997 }
998 }
999 } else {
1000 for (j = 0; j < 100; j++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001001 unsigned char tmp[8];
1002
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 if (u == 0) {
1004 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
1005 } else {
1006 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
1007 }
1008 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001009 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 memcpy(tmp, prv, 8);
1013 memcpy(prv, buf, 8);
1014 memcpy(buf, tmp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001015 }
1016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 memcpy(buf, prv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001018 }
1019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 if ((v == MBEDTLS_DES_DECRYPT &&
1021 memcmp(buf, des3_test_cbc_dec[u], 8) != 0) ||
1022 (v != MBEDTLS_DES_DECRYPT &&
1023 memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) {
1024 if (verbose != 0) {
1025 mbedtls_printf("failed\n");
1026 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001027
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001028 ret = 1;
1029 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001030 }
1031
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 if (verbose != 0) {
1033 mbedtls_printf("passed\n");
1034 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001035 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 if (verbose != 0) {
1039 mbedtls_printf("\n");
1040 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001041
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001042exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 mbedtls_des_free(&ctx);
1044 mbedtls_des3_free(&ctx3);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001047 ret = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 }
1049 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001050}
1051
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001052#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001053
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001054#endif /* MBEDTLS_DES_C */