blob: a6a6b2fb826af930db45086fce5aa12362379697 [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 */
Yanray Wang9141ad12023-08-24 14:53:16 +0800486#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100487int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000488{
489 int i;
490
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker5121ce52009-01-03 21:22:43 +0000492
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 for (i = 0; i < 16; i += 2) {
494 SWAP(ctx->sk[i], ctx->sk[30 - i]);
495 SWAP(ctx->sk[i + 1], ctx->sk[31 - i]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000496 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000497
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000499}
Yanray Wang9141ad12023-08-24 14:53:16 +0800500#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502static void des3_set2key(uint32_t esk[96],
503 uint32_t dsk[96],
504 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000505{
506 int i;
507
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 mbedtls_des_setkey(esk, key);
509 mbedtls_des_setkey(dsk + 32, key + 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 for (i = 0; i < 32; i += 2) {
512 dsk[i] = esk[30 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000513 dsk[i + 1] = esk[31 - i];
514
515 esk[i + 32] = dsk[62 - i];
516 esk[i + 33] = dsk[63 - i];
517
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 esk[i + 64] = esk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000519 esk[i + 65] = esk[i + 1];
520
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 dsk[i + 64] = dsk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000522 dsk[i + 65] = dsk[i + 1];
523 }
524}
525
526/*
527 * Triple-DES key schedule (112-bit, encryption)
528 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100529int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx,
530 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000531{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000532 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 des3_set2key(ctx->sk, sk, key);
535 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000538}
539
540/*
541 * Triple-DES key schedule (112-bit, decryption)
542 */
Yanray Wang9141ad12023-08-24 14:53:16 +0800543#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100544int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx,
545 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000546{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000547 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 des3_set2key(sk, ctx->sk, key);
550 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000553}
Yanray Wang9141ad12023-08-24 14:53:16 +0800554#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
Gilles Peskine449bd832023-01-11 14:50:10 +0100556static void des3_set3key(uint32_t esk[96],
557 uint32_t dsk[96],
558 const unsigned char key[24])
Paul Bakker5121ce52009-01-03 21:22:43 +0000559{
560 int i;
561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 mbedtls_des_setkey(esk, key);
563 mbedtls_des_setkey(dsk + 32, key + 8);
564 mbedtls_des_setkey(esk + 64, key + 16);
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 for (i = 0; i < 32; i += 2) {
567 dsk[i] = esk[94 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000568 dsk[i + 1] = esk[95 - i];
569
570 esk[i + 32] = dsk[62 - i];
571 esk[i + 33] = dsk[63 - i];
572
573 dsk[i + 64] = esk[30 - i];
574 dsk[i + 65] = esk[31 - i];
575 }
576}
577
578/*
579 * Triple-DES key schedule (168-bit, encryption)
580 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100581int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx,
582 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000583{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000584 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000585
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 des3_set3key(ctx->sk, sk, key);
587 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000588
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000590}
591
592/*
593 * Triple-DES key schedule (168-bit, decryption)
594 */
Yanray Wang9141ad12023-08-24 14:53:16 +0800595#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100596int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx,
597 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000598{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000599 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 des3_set3key(sk, ctx->sk, key);
602 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000605}
Yanray Wang9141ad12023-08-24 14:53:16 +0800606#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
608/*
609 * DES-ECB block encryption/decryption
610 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200611#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100612int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx,
613 const unsigned char input[8],
614 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000615{
616 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000617 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
619 SK = ctx->sk;
620
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 X = MBEDTLS_GET_UINT32_BE(input, 0);
622 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 for (i = 0; i < 8; i++) {
627 DES_ROUND(Y, X);
628 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 }
630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
634 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000637}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200638#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000639
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000641/*
642 * DES-CBC buffer encryption/decryption
643 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100644int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
645 int mode,
646 size_t length,
647 unsigned char iv[8],
648 const unsigned char *input,
649 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000650{
Gilles Peskine7820a572021-07-07 21:08:28 +0200651 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000652 unsigned char temp[8];
653
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 if (length % 8) {
655 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
656 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000657
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 if (mode == MBEDTLS_DES_ENCRYPT) {
659 while (length > 0) {
660 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 ret = mbedtls_des_crypt_ecb(ctx, output, output);
663 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200664 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 }
666 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000667
668 input += 8;
669 output += 8;
670 length -= 8;
671 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 } else { /* MBEDTLS_DES_DECRYPT */
673 while (length > 0) {
674 memcpy(temp, input, 8);
675 ret = mbedtls_des_crypt_ecb(ctx, input, output);
676 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200677 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000679
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000683
684 input += 8;
685 output += 8;
686 length -= 8;
687 }
688 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200689 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000690
Gilles Peskine7820a572021-07-07 21:08:28 +0200691exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000693}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000695
696/*
697 * 3DES-ECB block encryption/decryption
698 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200699#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100700int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
701 const unsigned char input[8],
702 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000703{
704 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000705 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000706
707 SK = ctx->sk;
708
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 X = MBEDTLS_GET_UINT32_BE(input, 0);
710 Y = MBEDTLS_GET_UINT32_BE(input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000713
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 for (i = 0; i < 8; i++) {
715 DES_ROUND(Y, X);
716 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000717 }
718
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 for (i = 0; i < 8; i++) {
720 DES_ROUND(X, Y);
721 DES_ROUND(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000722 }
723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 for (i = 0; i < 8; i++) {
725 DES_ROUND(Y, X);
726 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000727 }
728
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000730
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 MBEDTLS_PUT_UINT32_BE(Y, output, 0);
732 MBEDTLS_PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000735}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200736#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000737
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200738#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000739/*
740 * 3DES-CBC buffer encryption/decryption
741 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100742int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
743 int mode,
744 size_t length,
745 unsigned char iv[8],
746 const unsigned char *input,
747 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000748{
Gilles Peskine7820a572021-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 Peskine449bd832023-01-11 14:50:10 +0100752 if (length % 8) {
753 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
754 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000755
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 if (mode == MBEDTLS_DES_ENCRYPT) {
757 while (length > 0) {
758 mbedtls_xor(output, input, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000759
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 ret = mbedtls_des3_crypt_ecb(ctx, output, output);
761 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200762 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 }
764 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000765
766 input += 8;
767 output += 8;
768 length -= 8;
769 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 } else { /* MBEDTLS_DES_DECRYPT */
771 while (length > 0) {
772 memcpy(temp, input, 8);
773 ret = mbedtls_des3_crypt_ecb(ctx, input, output);
774 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200775 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000777
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 mbedtls_xor(output, output, iv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000781
782 input += 8;
783 output += 8;
784 length -= 8;
785 }
786 }
Gilles Peskine7820a572021-07-07 21:08:28 +0200787 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000788
Gilles Peskine7820a572021-07-07 21:08:28 +0200789exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000791}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000793
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200795
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000797/*
798 * DES and 3DES test vectors from:
799 *
800 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
801 */
802static const unsigned char des3_test_keys[24] =
803{
804 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
805 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
806 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
807};
808
Paul Bakker5121ce52009-01-03 21:22:43 +0000809static const unsigned char des3_test_buf[8] =
810{
811 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
812};
813
814static const unsigned char des3_test_ecb_dec[3][8] =
815{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100816 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
817 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
818 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000819};
820
821static const unsigned char des3_test_ecb_enc[3][8] =
822{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100823 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
824 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
825 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000826};
827
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200828#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100829static const unsigned char des3_test_iv[8] =
830{
831 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
832};
833
Paul Bakker5121ce52009-01-03 21:22:43 +0000834static const unsigned char des3_test_cbc_dec[3][8] =
835{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100836 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
837 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
838 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000839};
840
841static const unsigned char des3_test_cbc_enc[3][8] =
842{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100843 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
844 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
845 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000846};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000848
849/*
850 * Checkup routine
851 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100852int mbedtls_des_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000853{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200854 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855 mbedtls_des_context ctx;
856 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000857 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000859 unsigned char prv[8];
860 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200861#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 mbedtls_des_init(&ctx);
864 mbedtls_des3_init(&ctx3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000865 /*
866 * ECB mode
867 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000869 u = i >> 1;
870 v = i & 1;
871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 if (verbose != 0) {
873 mbedtls_printf(" DES%c-ECB-%3d (%s): ",
874 (u == 0) ? ' ' : '3', 56 + u * 56,
875 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000876 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100877
Yanray Wang9141ad12023-08-24 14:53:16 +0800878#if defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
879 if (v == MBEDTLS_DES_DECRYPT) {
880 if (verbose != 0) {
881 mbedtls_printf("skipped\n");
882 }
883 continue;
884 }
885#endif
886
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 memcpy(buf, des3_test_buf, 8);
888
889 switch (i) {
Yanray Wang9141ad12023-08-24 14:53:16 +0800890#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 case 0:
892 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
893 break;
Yanray Wang9141ad12023-08-24 14:53:16 +0800894#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100895
896 case 1:
897 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
898 break;
899
Yanray Wang9141ad12023-08-24 14:53:16 +0800900#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 case 2:
902 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
903 break;
Yanray Wang9141ad12023-08-24 14:53:16 +0800904#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100905
906 case 3:
907 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
908 break;
909
Yanray Wang9141ad12023-08-24 14:53:16 +0800910#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 case 4:
912 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
913 break;
Yanray Wang9141ad12023-08-24 14:53:16 +0800914#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100915
916 case 5:
917 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
918 break;
919
920 default:
921 return 1;
922 }
923 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +0200924 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000925 }
926
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 for (j = 0; j < 100; j++) {
928 if (u == 0) {
929 ret = mbedtls_des_crypt_ecb(&ctx, buf, buf);
930 } else {
931 ret = mbedtls_des3_crypt_ecb(&ctx3, buf, buf);
932 }
933 if (ret != 0) {
934 goto exit;
935 }
936 }
937
938 if ((v == MBEDTLS_DES_DECRYPT &&
939 memcmp(buf, des3_test_ecb_dec[u], 8) != 0) ||
940 (v != MBEDTLS_DES_DECRYPT &&
941 memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) {
942 if (verbose != 0) {
943 mbedtls_printf("failed\n");
944 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000945
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200946 ret = 1;
947 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000948 }
949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 if (verbose != 0) {
951 mbedtls_printf("passed\n");
952 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 }
954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 if (verbose != 0) {
956 mbedtls_printf("\n");
957 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000958
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000960 /*
961 * CBC mode
962 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000964 u = i >> 1;
965 v = i & 1;
966
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 if (verbose != 0) {
968 mbedtls_printf(" DES%c-CBC-%3d (%s): ",
969 (u == 0) ? ' ' : '3', 56 + u * 56,
970 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000971 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100972
973 memcpy(iv, des3_test_iv, 8);
974 memcpy(prv, des3_test_iv, 8);
975 memcpy(buf, des3_test_buf, 8);
976
977 switch (i) {
978 case 0:
979 ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys);
980 break;
981
982 case 1:
983 ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys);
984 break;
985
986 case 2:
987 ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
988 break;
989
990 case 3:
991 ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
992 break;
993
994 case 4:
995 ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
996 break;
997
998 case 5:
999 ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
1000 break;
1001
1002 default:
1003 return 1;
1004 }
1005 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001006 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001007 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001008
1009 if (v == MBEDTLS_DES_DECRYPT) {
1010 for (j = 0; j < 100; j++) {
1011 if (u == 0) {
1012 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
1013 } else {
1014 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
1015 }
1016 if (ret != 0) {
1017 goto exit;
1018 }
1019 }
1020 } else {
1021 for (j = 0; j < 100; j++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 unsigned char tmp[8];
1023
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 if (u == 0) {
1025 ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
1026 } else {
1027 ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
1028 }
1029 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001030 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001032
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 memcpy(tmp, prv, 8);
1034 memcpy(prv, buf, 8);
1035 memcpy(buf, tmp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001036 }
1037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 memcpy(buf, prv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001039 }
1040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 if ((v == MBEDTLS_DES_DECRYPT &&
1042 memcmp(buf, des3_test_cbc_dec[u], 8) != 0) ||
1043 (v != MBEDTLS_DES_DECRYPT &&
1044 memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) {
1045 if (verbose != 0) {
1046 mbedtls_printf("failed\n");
1047 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001048
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001049 ret = 1;
1050 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001051 }
1052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 if (verbose != 0) {
1054 mbedtls_printf("passed\n");
1055 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001056 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001058
Gilles Peskine449bd832023-01-11 14:50:10 +01001059 if (verbose != 0) {
1060 mbedtls_printf("\n");
1061 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001062
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001063exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 mbedtls_des_free(&ctx);
1065 mbedtls_des3_free(&ctx3);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001066
Gilles Peskine449bd832023-01-11 14:50:10 +01001067 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001068 ret = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001069 }
1070 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001071}
1072
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001074
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001075#endif /* MBEDTLS_DES_C */