blob: 8cf346f81be43b63eb4eabf6b110e04c8ca9fdb0 [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 Peskine377a3102021-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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100235 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000236
237/*
238 * Final Permutation macro
239 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100250 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000251
252/*
253 * DES round macro
254 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100255#define DES_ROUND(X, Y) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100256 do \
257 { \
258 T = *SK++ ^ (X); \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100275 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100277void mbedtls_des_init(mbedtls_des_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200278{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100279 memset(ctx, 0, sizeof(mbedtls_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200280}
281
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100282void mbedtls_des_free(mbedtls_des_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200283{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100284 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200285 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100286 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200287
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100288 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200289}
290
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100291void mbedtls_des3_init(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200292{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100293 memset(ctx, 0, sizeof(mbedtls_des3_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200294}
295
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100296void mbedtls_des3_free(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200297{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200299 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100300 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200301
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100419 T = ((Y) ^ X) & 0x10101010; X ^= T; Y ^= (T);
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100478 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000479
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100480 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000481}
482
483/*
484 * DES key schedule (56-bit, decryption)
485 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100490 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100497 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000498}
499
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100506 mbedtls_des_setkey(esk, key);
507 mbedtls_des_setkey(dsk + 32, key + 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100516 esk[i + 64] = esk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000517 esk[i + 65] = esk[i + 1];
518
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100532 des3_set2key(ctx->sk, sk, key);
533 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000534
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100535 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000536}
537
538/*
539 * Triple-DES key schedule (112-bit, decryption)
540 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100546 des3_set2key(sk, ctx->sk, key);
547 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000548
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100549 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000550}
551
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100582 des3_set3key(ctx->sk, sk, key);
583 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000584
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100585 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000586}
587
588/*
589 * Triple-DES key schedule (168-bit, decryption)
590 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100596 des3_set3key(sk, ctx->sk, key);
597 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000598
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100618 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100625 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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{
645 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +0200646 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000647 unsigned char temp[8];
648
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100649 if (length % 8) {
650 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
651 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000652
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100653 if (mode == MBEDTLS_DES_ENCRYPT) {
654 while (length > 0) {
655 for (i = 0; i < 8; i++) {
656 output[i] = (unsigned char) (input[i] ^ iv[i]);
657 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000658
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100659 ret = mbedtls_des_crypt_ecb(ctx, output, output);
660 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200661 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100662 }
663 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000664
665 input += 8;
666 output += 8;
667 length -= 8;
668 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100669 } else { /* MBEDTLS_DES_DECRYPT */
670 while (length > 0) {
671 memcpy(temp, input, 8);
672 ret = mbedtls_des_crypt_ecb(ctx, input, output);
673 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200674 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100675 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000676
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100677 for (i = 0; i < 8; i++) {
678 output[i] = (unsigned char) (output[i] ^ iv[i]);
679 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000680
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100681 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
683 input += 8;
684 output += 8;
685 length -= 8;
686 }
687 }
Gilles Peskine377a3102021-07-07 21:08:28 +0200688 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000689
Gilles Peskine377a3102021-07-07 21:08:28 +0200690exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100691 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000692}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
695/*
696 * 3DES-ECB block encryption/decryption
697 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200698#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100699int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
700 const unsigned char input[8],
701 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000702{
703 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000704 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000705
706 SK = ctx->sk;
707
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100708 X = MBEDTLS_GET_UINT32_BE(input, 0);
709 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100711 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000712
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100713 for (i = 0; i < 8; i++) {
714 DES_ROUND(Y, X);
715 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000716 }
717
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100718 for (i = 0; i < 8; i++) {
719 DES_ROUND(X, Y);
720 DES_ROUND(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000721 }
722
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100723 for (i = 0; i < 8; i++) {
724 DES_ROUND(Y, X);
725 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000726 }
727
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100728 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000729
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100730 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
731 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000732
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100733 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000734}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200735#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000736
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200737#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000738/*
739 * 3DES-CBC buffer encryption/decryption
740 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100741int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
742 int mode,
743 size_t length,
744 unsigned char iv[8],
745 const unsigned char *input,
746 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000747{
748 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +0200749 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000750 unsigned char temp[8];
751
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100752 if (length % 8) {
753 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
754 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000755
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100756 if (mode == MBEDTLS_DES_ENCRYPT) {
757 while (length > 0) {
758 for (i = 0; i < 8; i++) {
759 output[i] = (unsigned char) (input[i] ^ iv[i]);
760 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000761
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100762 ret = mbedtls_des3_crypt_ecb(ctx, output, output);
763 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200764 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100765 }
766 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000767
768 input += 8;
769 output += 8;
770 length -= 8;
771 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100772 } else { /* MBEDTLS_DES_DECRYPT */
773 while (length > 0) {
774 memcpy(temp, input, 8);
775 ret = mbedtls_des3_crypt_ecb(ctx, input, output);
776 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200777 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100778 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000779
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100780 for (i = 0; i < 8; i++) {
781 output[i] = (unsigned char) (output[i] ^ iv[i]);
782 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000783
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100784 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000785
786 input += 8;
787 output += 8;
788 length -= 8;
789 }
790 }
Gilles Peskine377a3102021-07-07 21:08:28 +0200791 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000792
Gilles Peskine377a3102021-07-07 21:08:28 +0200793exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100794 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000795}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000797
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200799
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200800#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000801/*
802 * DES and 3DES test vectors from:
803 *
804 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
805 */
806static const unsigned char des3_test_keys[24] =
807{
808 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
809 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
810 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
811};
812
Paul Bakker5121ce52009-01-03 21:22:43 +0000813static const unsigned char des3_test_buf[8] =
814{
815 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
816};
817
818static const unsigned char des3_test_ecb_dec[3][8] =
819{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100820 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
821 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
822 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000823};
824
825static const unsigned char des3_test_ecb_enc[3][8] =
826{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100827 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
828 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
829 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000830};
831
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100833static const unsigned char des3_test_iv[8] =
834{
835 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
836};
837
Paul Bakker5121ce52009-01-03 21:22:43 +0000838static const unsigned char des3_test_cbc_dec[3][8] =
839{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100840 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
841 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
842 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000843};
844
845static const unsigned char des3_test_cbc_enc[3][8] =
846{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100847 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
848 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
849 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000850};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000852
853/*
854 * Checkup routine
855 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100856int mbedtls_des_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000857{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200858 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859 mbedtls_des_context ctx;
860 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000861 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000863 unsigned char prv[8];
864 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200865#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000866
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100867 mbedtls_des_init(&ctx);
868 mbedtls_des3_init(&ctx3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000869 /*
870 * ECB mode
871 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100872 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000873 u = i >> 1;
874 v = i & 1;
875
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100876 if (verbose != 0) {
877 mbedtls_printf(" DES%c-ECB-%3d (%s): ",
878 (u == 0) ? ' ' : '3', 56 + u * 56,
879 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000880 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100881
882 memcpy(buf, des3_test_buf, 8);
883
884 switch (i) {
885 case 0:
886 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
887 break;
888
889 case 1:
890 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
891 break;
892
893 case 2:
894 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
895 break;
896
897 case 3:
898 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
899 break;
900
901 case 4:
902 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
903 break;
904
905 case 5:
906 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
907 break;
908
909 default:
910 return 1;
911 }
912 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200913 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000914 }
915
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100916 for (j = 0; j < 100; j++) {
917 if (u == 0) {
918 ret = mbedtls_des_crypt_ecb(&ctx, buf, buf);
919 } else {
920 ret = mbedtls_des3_crypt_ecb(&ctx3, buf, buf);
921 }
922 if (ret != 0) {
923 goto exit;
924 }
925 }
926
927 if ((v == MBEDTLS_DES_DECRYPT &&
928 memcmp(buf, des3_test_ecb_dec[u], 8) != 0) ||
929 (v != MBEDTLS_DES_DECRYPT &&
930 memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) {
931 if (verbose != 0) {
932 mbedtls_printf("failed\n");
933 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000934
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200935 ret = 1;
936 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000937 }
938
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100939 if (verbose != 0) {
940 mbedtls_printf("passed\n");
941 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000942 }
943
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100944 if (verbose != 0) {
945 mbedtls_printf("\n");
946 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000947
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200948#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 /*
950 * CBC mode
951 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100952 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 u = i >> 1;
954 v = i & 1;
955
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100956 if (verbose != 0) {
957 mbedtls_printf(" DES%c-CBC-%3d (%s): ",
958 (u == 0) ? ' ' : '3', 56 + u * 56,
959 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000960 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100961
962 memcpy(iv, des3_test_iv, 8);
963 memcpy(prv, des3_test_iv, 8);
964 memcpy(buf, des3_test_buf, 8);
965
966 switch (i) {
967 case 0:
968 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
969 break;
970
971 case 1:
972 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
973 break;
974
975 case 2:
976 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
977 break;
978
979 case 3:
980 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
981 break;
982
983 case 4:
984 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
985 break;
986
987 case 5:
988 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
989 break;
990
991 default:
992 return 1;
993 }
994 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +0200995 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000996 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100997
998 if (v == MBEDTLS_DES_DECRYPT) {
999 for (j = 0; j < 100; j++) {
1000 if (u == 0) {
1001 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
1002 } else {
1003 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
1004 }
1005 if (ret != 0) {
1006 goto exit;
1007 }
1008 }
1009 } else {
1010 for (j = 0; j < 100; j++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001011 unsigned char tmp[8];
1012
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001013 if (u == 0) {
1014 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
1015 } else {
1016 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
1017 }
1018 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001019 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001020 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001021
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001022 memcpy(tmp, prv, 8);
1023 memcpy(prv, buf, 8);
1024 memcpy(buf, tmp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001025 }
1026
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001027 memcpy(buf, prv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001028 }
1029
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001030 if ((v == MBEDTLS_DES_DECRYPT &&
1031 memcmp(buf, des3_test_cbc_dec[u], 8) != 0) ||
1032 (v != MBEDTLS_DES_DECRYPT &&
1033 memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) {
1034 if (verbose != 0) {
1035 mbedtls_printf("failed\n");
1036 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001038 ret = 1;
1039 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001040 }
1041
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001042 if (verbose != 0) {
1043 mbedtls_printf("passed\n");
1044 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001045 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001047
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001048 if (verbose != 0) {
1049 mbedtls_printf("\n");
1050 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001052exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001053 mbedtls_des_free(&ctx);
1054 mbedtls_des3_free(&ctx3);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001055
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001056 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001057 ret = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001058 }
1059 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001060}
1061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001063
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064#endif /* MBEDTLS_DES_C */