blob: 29f721555fcdaaeadfcc08ed8d68675d756f6d40 [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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020030# include "mbedtls/des.h"
31# include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020033# include <string.h>
Rich Evans00ab4702015-02-06 13:43:58 +000034
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020035# if defined(MBEDTLS_SELF_TEST)
36# if defined(MBEDTLS_PLATFORM_C)
37# include "mbedtls/platform.h"
38# else
39# include <stdio.h>
40# define mbedtls_printf printf
41# endif /* MBEDTLS_PLATFORM_C */
42# endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010043
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020044# if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020045
Paul Bakker5121ce52009-01-03 21:22:43 +000046/*
47 * 32-bit integer manipulation macros (big endian)
48 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020049# ifndef GET_UINT32_BE
50# define GET_UINT32_BE(n, b, i) \
51 { \
52 (n) = ((uint32_t)(b)[(i)] << 24) | \
53 ((uint32_t)(b)[(i) + 1] << 16) | \
54 ((uint32_t)(b)[(i) + 2] << 8) | \
55 ((uint32_t)(b)[(i) + 3]); \
56 }
57# endif
Paul Bakker5121ce52009-01-03 21:22:43 +000058
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020059# ifndef PUT_UINT32_BE
60# define PUT_UINT32_BE(n, b, i) \
61 { \
62 (b)[(i)] = (unsigned char)((n) >> 24); \
63 (b)[(i) + 1] = (unsigned char)((n) >> 16); \
64 (b)[(i) + 2] = (unsigned char)((n) >> 8); \
65 (b)[(i) + 3] = (unsigned char)((n)); \
66 }
67# endif
Paul Bakker5121ce52009-01-03 21:22:43 +000068
69/*
70 * Expanded DES S-boxes
71 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020072static const uint32_t SB1[64] = {
73 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404,
74 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,
75 0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,
76 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
77 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404,
78 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000,
79 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000,
80 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
81 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404,
82 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,
Paul Bakker5121ce52009-01-03 21:22:43 +000083 0x00010004, 0x00010400, 0x00000000, 0x01010004
84};
85
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020086static const uint32_t SB2[64] = {
87 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020,
88 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,
89 0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,
90 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
91 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000,
92 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000,
93 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000,
94 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
95 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020,
96 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,
Paul Bakker5121ce52009-01-03 21:22:43 +000097 0x80000000, 0x80100020, 0x80108020, 0x00108000
98};
99
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200100static const uint32_t SB3[64] = {
101 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000,
102 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,
103 0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,
104 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
105 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208,
106 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208,
107 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008,
108 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
109 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208,
110 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,
Paul Bakker5121ce52009-01-03 21:22:43 +0000111 0x00020208, 0x00000008, 0x08020008, 0x00020200
112};
113
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200114static const uint32_t SB4[64] = {
115 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081,
116 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,
117 0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,
118 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
119 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080,
120 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081,
121 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080,
122 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
123 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001,
124 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,
Paul Bakker5121ce52009-01-03 21:22:43 +0000125 0x00000080, 0x00800000, 0x00002000, 0x00802080
126};
127
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200128static const uint32_t SB5[64] = {
129 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100,
130 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,
131 0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,
132 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
133 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000,
134 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000,
135 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000,
136 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
137 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000,
138 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,
Paul Bakker5121ce52009-01-03 21:22:43 +0000139 0x00000000, 0x40080000, 0x02080100, 0x40000100
140};
141
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200142static const uint32_t SB6[64] = {
143 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010,
144 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,
145 0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,
146 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
147 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000,
148 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000,
149 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000,
150 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
151 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000,
152 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,
Paul Bakker5121ce52009-01-03 21:22:43 +0000153 0x20404000, 0x20000000, 0x00400010, 0x20004010
154};
155
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200156static const uint32_t SB7[64] = {
157 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802,
158 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,
159 0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,
160 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
161 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002,
162 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802,
163 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000,
164 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
165 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000,
166 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,
Paul Bakker5121ce52009-01-03 21:22:43 +0000167 0x04000002, 0x04000800, 0x00000800, 0x00200002
168};
169
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200170static const uint32_t SB8[64] = {
171 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040,
172 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,
173 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
174 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
175 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000,
176 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000,
177 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040,
178 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
179 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000,
180 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040,
Paul Bakker5121ce52009-01-03 21:22:43 +0000181 0x00001040, 0x00040040, 0x10000000, 0x10041000
182};
183
184/*
185 * PC1: left and right halves bit-swap
186 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200187static const uint32_t LHs[16] = {
188 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00010000, 0x00010001,
189 0x00010100, 0x00010101, 0x01000000, 0x01000001, 0x01000100, 0x01000101,
Paul Bakker5121ce52009-01-03 21:22:43 +0000190 0x01010000, 0x01010001, 0x01010100, 0x01010101
191};
192
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200193static const uint32_t RHs[16] = {
194 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100,
195 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001,
Paul Bakker5121ce52009-01-03 21:22:43 +0000196 0x00000101, 0x01000101, 0x00010101, 0x01010101,
197};
198
199/*
200 * Initial Permutation macro
201 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200202# define DES_IP(X, Y) \
203 do { \
204 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; \
205 (Y) ^= T; \
206 (X) ^= (T << 4); \
207 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; \
208 (Y) ^= T; \
209 (X) ^= (T << 16); \
210 T = (((Y) >> 2) ^ (X)) & 0x33333333; \
211 (X) ^= T; \
212 (Y) ^= (T << 2); \
213 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; \
214 (X) ^= T; \
215 (Y) ^= (T << 8); \
216 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
217 T = ((X) ^ (Y)) & 0xAAAAAAAA; \
218 (Y) ^= T; \
219 (X) ^= T; \
220 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
221 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000222
223/*
224 * Final Permutation macro
225 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200226# define DES_FP(X, Y) \
227 do { \
228 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
229 T = ((X) ^ (Y)) & 0xAAAAAAAA; \
230 (X) ^= T; \
231 (Y) ^= T; \
232 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
233 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; \
234 (X) ^= T; \
235 (Y) ^= (T << 8); \
236 T = (((Y) >> 2) ^ (X)) & 0x33333333; \
237 (X) ^= T; \
238 (Y) ^= (T << 2); \
239 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; \
240 (Y) ^= T; \
241 (X) ^= (T << 16); \
242 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; \
243 (Y) ^= T; \
244 (X) ^= (T << 4); \
245 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000246
247/*
248 * DES round macro
249 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200250# define DES_ROUND(X, Y) \
251 do { \
252 T = *SK++ ^ (X); \
253 (Y) ^= SB8[(T)&0x3F] ^ SB6[(T >> 8) & 0x3F] ^ \
254 SB4[(T >> 16) & 0x3F] ^ SB2[(T >> 24) & 0x3F]; \
255 \
256 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
257 (Y) ^= SB7[(T)&0x3F] ^ SB5[(T >> 8) & 0x3F] ^ \
258 SB3[(T >> 16) & 0x3F] ^ SB1[(T >> 24) & 0x3F]; \
259 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000260
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200261# define SWAP(a, b) \
262 do { \
263 uint32_t t = (a); \
264 (a) = (b); \
265 (b) = t; \
266 t = 0; \
267 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000268
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200269void mbedtls_des_init(mbedtls_des_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200270{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200271 memset(ctx, 0, sizeof(mbedtls_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200272}
273
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200274void mbedtls_des_free(mbedtls_des_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200275{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200276 if (ctx == NULL)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200277 return;
278
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200279 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200280}
281
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200282void mbedtls_des3_init(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200283{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200284 memset(ctx, 0, sizeof(mbedtls_des3_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200285}
286
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200287void mbedtls_des3_free(mbedtls_des3_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200288{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200289 if (ctx == NULL)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200290 return;
291
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200292 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des3_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200293}
294
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200295static const unsigned char odd_parity_table[128] = {
296 1, 2, 4, 7, 8, 11, 13, 14, 16, 19, 21, 22, 25, 26, 28,
297 31, 32, 35, 37, 38, 41, 42, 44, 47, 49, 50, 52, 55, 56, 59,
298 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81, 82, 84, 87, 88,
299 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112, 115, 117, 118,
300 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140, 143, 145, 146, 148,
301 151, 152, 155, 157, 158, 161, 162, 164, 167, 168, 171, 173, 174, 176, 179,
302 181, 182, 185, 186, 188, 191, 193, 194, 196, 199, 200, 203, 205, 206, 208,
303 211, 213, 214, 217, 218, 220, 223, 224, 227, 229, 230, 233, 234, 236, 239,
304 241, 242, 244, 247, 248, 251, 253, 254
305};
Paul Bakker1f87fb62011-01-15 17:32:24 +0000306
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200307void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker1f87fb62011-01-15 17:32:24 +0000308{
309 int i;
310
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200311 for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++)
Paul Bakker1f87fb62011-01-15 17:32:24 +0000312 key[i] = odd_parity_table[key[i] / 2];
313}
314
315/*
316 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
317 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200318int mbedtls_des_key_check_key_parity(
319 const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker1f87fb62011-01-15 17:32:24 +0000320{
321 int i;
322
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200323 for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++)
324 if (key[i] != odd_parity_table[key[i] / 2])
325 return 1;
Paul Bakker1f87fb62011-01-15 17:32:24 +0000326
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200327 return 0;
Paul Bakker1f87fb62011-01-15 17:32:24 +0000328}
329
330/*
331 * Table of weak and semi-weak keys
332 *
333 * Source: http://en.wikipedia.org/wiki/Weak_key
334 *
335 * Weak:
336 * Alternating ones + zeros (0x0101010101010101)
337 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
338 * '0xE0E0E0E0F1F1F1F1'
339 * '0x1F1F1F1F0E0E0E0E'
340 *
341 * Semi-weak:
342 * 0x011F011F010E010E and 0x1F011F010E010E01
343 * 0x01E001E001F101F1 and 0xE001E001F101F101
344 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
345 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
346 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
347 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
348 *
349 */
350
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200351# define WEAK_KEY_COUNT 16
Paul Bakker1f87fb62011-01-15 17:32:24 +0000352
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200353static const unsigned char
354 weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] = {
355 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
356 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
357 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
358 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
Paul Bakker1f87fb62011-01-15 17:32:24 +0000359
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200360 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
361 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
362 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
363 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
364 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
365 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
366 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
367 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
368 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
369 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
370 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
371 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
372 };
Paul Bakker1f87fb62011-01-15 17:32:24 +0000373
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200374int mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker1f87fb62011-01-15 17:32:24 +0000375{
376 int i;
377
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200378 for (i = 0; i < WEAK_KEY_COUNT; i++)
379 if (memcmp(weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0)
380 return 1;
Paul Bakker1f87fb62011-01-15 17:32:24 +0000381
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200382 return 0;
Paul Bakker1f87fb62011-01-15 17:32:24 +0000383}
384
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200385# if !defined(MBEDTLS_DES_SETKEY_ALT)
386void mbedtls_des_setkey(uint32_t SK[32],
387 const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000388{
389 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000390 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000391
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200392 GET_UINT32_BE(X, key, 0);
393 GET_UINT32_BE(Y, key, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000394
395 /*
396 * Permuted Choice 1
397 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200398 T = ((Y >> 4) ^ X) & 0x0F0F0F0F;
399 X ^= T;
400 Y ^= (T << 4);
401 T = ((Y) ^ X) & 0x10101010;
402 X ^= T;
403 Y ^= (T);
Paul Bakker5121ce52009-01-03 21:22:43 +0000404
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200405 X = (LHs[(X)&0xF] << 3) | (LHs[(X >> 8) & 0xF] << 2) |
406 (LHs[(X >> 16) & 0xF] << 1) | (LHs[(X >> 24) & 0xF]) |
407 (LHs[(X >> 5) & 0xF] << 7) | (LHs[(X >> 13) & 0xF] << 6) |
408 (LHs[(X >> 21) & 0xF] << 5) | (LHs[(X >> 29) & 0xF] << 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200410 Y = (RHs[(Y >> 1) & 0xF] << 3) | (RHs[(Y >> 9) & 0xF] << 2) |
411 (RHs[(Y >> 17) & 0xF] << 1) | (RHs[(Y >> 25) & 0xF]) |
412 (RHs[(Y >> 4) & 0xF] << 7) | (RHs[(Y >> 12) & 0xF] << 6) |
413 (RHs[(Y >> 20) & 0xF] << 5) | (RHs[(Y >> 28) & 0xF] << 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
415 X &= 0x0FFFFFFF;
416 Y &= 0x0FFFFFFF;
417
418 /*
419 * calculate subkeys
420 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200421 for (i = 0; i < 16; i++) {
422 if (i < 2 || i == 8 || i == 15) {
423 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
424 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
425 } else {
426 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
427 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000428 }
429
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200430 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) |
431 ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) |
432 ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) |
433 ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) |
434 ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) |
435 ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) |
436 ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) |
437 ((Y >> 14) & 0x00000200) | ((Y)&0x00000100) |
438 ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) |
439 ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) |
440 ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
Paul Bakker5121ce52009-01-03 21:22:43 +0000441
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200442 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) |
443 ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) |
444 ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) |
445 ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) |
446 ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) |
447 ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) |
448 ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) |
449 ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) |
450 ((Y)&0x00000200) | ((Y << 7) & 0x00000100) |
451 ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) |
452 ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 }
454}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200455# endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
457/*
458 * DES key schedule (56-bit, encryption)
459 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200460int mbedtls_des_setkey_enc(mbedtls_des_context *ctx,
461 const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000462{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200463 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker8123e9d2011-01-06 15:37:30 +0000464
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200465 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000466}
467
468/*
469 * DES key schedule (56-bit, decryption)
470 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200471int mbedtls_des_setkey_dec(mbedtls_des_context *ctx,
472 const unsigned char key[MBEDTLS_DES_KEY_SIZE])
Paul Bakker5121ce52009-01-03 21:22:43 +0000473{
474 int i;
475
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200476 mbedtls_des_setkey(ctx->sk, key);
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200478 for (i = 0; i < 16; i += 2) {
479 SWAP(ctx->sk[i], ctx->sk[30 - i]);
480 SWAP(ctx->sk[i + 1], ctx->sk[31 - i]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000481 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000482
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200483 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000484}
485
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200486static void des3_set2key(uint32_t esk[96],
487 uint32_t dsk[96],
488 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000489{
490 int i;
491
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200492 mbedtls_des_setkey(esk, key);
493 mbedtls_des_setkey(dsk + 32, key + 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200495 for (i = 0; i < 32; i += 2) {
496 dsk[i] = esk[30 - i];
497 dsk[i + 1] = esk[31 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000498
499 esk[i + 32] = dsk[62 - i];
500 esk[i + 33] = dsk[63 - i];
501
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200502 esk[i + 64] = esk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000503 esk[i + 65] = esk[i + 1];
504
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200505 dsk[i + 64] = dsk[i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000506 dsk[i + 65] = dsk[i + 1];
507 }
508}
509
510/*
511 * Triple-DES key schedule (112-bit, encryption)
512 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200513int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx,
514 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])
Paul Bakker5121ce52009-01-03 21:22:43 +0000515{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000516 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000517
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200518 des3_set2key(ctx->sk, sk, key);
519 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000520
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200521 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000522}
523
524/*
525 * Triple-DES key schedule (112-bit, decryption)
526 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200527int mbedtls_des3_set2key_dec(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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200532 des3_set2key(sk, ctx->sk, key);
533 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000534
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200535 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000536}
537
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200538static void
539des3_set3key(uint32_t esk[96], uint32_t dsk[96], const unsigned char key[24])
Paul Bakker5121ce52009-01-03 21:22:43 +0000540{
541 int i;
542
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200543 mbedtls_des_setkey(esk, key);
544 mbedtls_des_setkey(dsk + 32, key + 8);
545 mbedtls_des_setkey(esk + 64, key + 16);
Paul Bakker5121ce52009-01-03 21:22:43 +0000546
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200547 for (i = 0; i < 32; i += 2) {
548 dsk[i] = esk[94 - i];
549 dsk[i + 1] = esk[95 - i];
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
551 esk[i + 32] = dsk[62 - i];
552 esk[i + 33] = dsk[63 - i];
553
554 dsk[i + 64] = esk[30 - i];
555 dsk[i + 65] = esk[31 - i];
556 }
557}
558
559/*
560 * Triple-DES key schedule (168-bit, encryption)
561 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200562int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx,
563 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000564{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000565 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200567 des3_set3key(ctx->sk, sk, key);
568 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000569
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200570 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000571}
572
573/*
574 * Triple-DES key schedule (168-bit, decryption)
575 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200576int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx,
577 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])
Paul Bakker5121ce52009-01-03 21:22:43 +0000578{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000579 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200581 des3_set3key(sk, ctx->sk, key);
582 mbedtls_platform_zeroize(sk, sizeof(sk));
Paul Bakker8123e9d2011-01-06 15:37:30 +0000583
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200584 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000585}
586
587/*
588 * DES-ECB block encryption/decryption
589 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200590# if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
591int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx,
592 const unsigned char input[8],
593 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000594{
595 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000596 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
598 SK = ctx->sk;
599
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200600 GET_UINT32_BE(X, input, 0);
601 GET_UINT32_BE(Y, input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000602
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200603 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200605 for (i = 0; i < 8; i++) {
606 DES_ROUND(Y, X);
607 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 }
609
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200610 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200612 PUT_UINT32_BE(Y, output, 0);
613 PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000614
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200615 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000616}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200617# endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200619# if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000620/*
621 * DES-CBC buffer encryption/decryption
622 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200623int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
624 int mode,
625 size_t length,
626 unsigned char iv[8],
627 const unsigned char *input,
628 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000629{
630 int i;
631 unsigned char temp[8];
632
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200633 if (length % 8)
634 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000635
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200636 if (mode == MBEDTLS_DES_ENCRYPT) {
637 while (length > 0) {
638 for (i = 0; i < 8; i++)
639 output[i] = (unsigned char)(input[i] ^ iv[i]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000640
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200641 mbedtls_des_crypt_ecb(ctx, output, output);
642 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200644 input += 8;
Paul Bakker5121ce52009-01-03 21:22:43 +0000645 output += 8;
646 length -= 8;
647 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200648 } else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000649 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200650 while (length > 0) {
651 memcpy(temp, input, 8);
652 mbedtls_des_crypt_ecb(ctx, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +0000653
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200654 for (i = 0; i < 8; i++)
655 output[i] = (unsigned char)(output[i] ^ iv[i]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200657 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000658
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200659 input += 8;
Paul Bakker5121ce52009-01-03 21:22:43 +0000660 output += 8;
661 length -= 8;
662 }
663 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000664
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200665 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000666}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200667# endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
669/*
670 * 3DES-ECB block encryption/decryption
671 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200672# if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
673int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
674 const unsigned char input[8],
675 unsigned char output[8])
Paul Bakker5121ce52009-01-03 21:22:43 +0000676{
677 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000678 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000679
680 SK = ctx->sk;
681
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200682 GET_UINT32_BE(X, input, 0);
683 GET_UINT32_BE(Y, input, 4);
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200685 DES_IP(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000686
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200687 for (i = 0; i < 8; i++) {
688 DES_ROUND(Y, X);
689 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000690 }
691
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200692 for (i = 0; i < 8; i++) {
693 DES_ROUND(X, Y);
694 DES_ROUND(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000695 }
696
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200697 for (i = 0; i < 8; i++) {
698 DES_ROUND(Y, X);
699 DES_ROUND(X, Y);
Paul Bakker5121ce52009-01-03 21:22:43 +0000700 }
701
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200702 DES_FP(Y, X);
Paul Bakker5121ce52009-01-03 21:22:43 +0000703
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200704 PUT_UINT32_BE(Y, output, 0);
705 PUT_UINT32_BE(X, output, 4);
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000706
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200707 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000708}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200709# endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200711# if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000712/*
713 * 3DES-CBC buffer encryption/decryption
714 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200715int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
716 int mode,
717 size_t length,
718 unsigned char iv[8],
719 const unsigned char *input,
720 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000721{
722 int i;
723 unsigned char temp[8];
724
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200725 if (length % 8)
726 return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000727
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200728 if (mode == MBEDTLS_DES_ENCRYPT) {
729 while (length > 0) {
730 for (i = 0; i < 8; i++)
731 output[i] = (unsigned char)(input[i] ^ iv[i]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000732
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200733 mbedtls_des3_crypt_ecb(ctx, output, output);
734 memcpy(iv, output, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000735
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200736 input += 8;
Paul Bakker5121ce52009-01-03 21:22:43 +0000737 output += 8;
738 length -= 8;
739 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200740 } else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000741 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200742 while (length > 0) {
743 memcpy(temp, input, 8);
744 mbedtls_des3_crypt_ecb(ctx, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +0000745
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200746 for (i = 0; i < 8; i++)
747 output[i] = (unsigned char)(output[i] ^ iv[i]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200749 memcpy(iv, temp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000750
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200751 input += 8;
Paul Bakker5121ce52009-01-03 21:22:43 +0000752 output += 8;
753 length -= 8;
754 }
755 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000756
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200757 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000758}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200759# endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000760
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200761# endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200762
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200763# if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000764/*
765 * DES and 3DES test vectors from:
766 *
767 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
768 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200769static const unsigned char des3_test_keys[24] = {
770 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x23, 0x45, 0x67, 0x89,
771 0xAB, 0xCD, 0xEF, 0x01, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
Paul Bakker5121ce52009-01-03 21:22:43 +0000772};
773
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200774static const unsigned char des3_test_buf[8] = { 0x4E, 0x6F, 0x77, 0x20,
775 0x69, 0x73, 0x20, 0x74 };
Paul Bakker5121ce52009-01-03 21:22:43 +0000776
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200777static const unsigned char des3_test_ecb_dec[3][8] = {
Jaeden Amero355b4b02019-05-29 10:13:23 +0100778 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
779 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
780 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000781};
782
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200783static const unsigned char des3_test_ecb_enc[3][8] = {
Jaeden Amero355b4b02019-05-29 10:13:23 +0100784 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
785 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
786 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000787};
788
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200789# if defined(MBEDTLS_CIPHER_MODE_CBC)
790static const unsigned char des3_test_iv[8] = {
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100791 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
792};
793
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200794static const unsigned char des3_test_cbc_dec[3][8] = {
Jaeden Amero355b4b02019-05-29 10:13:23 +0100795 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
796 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
797 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000798};
799
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200800static const unsigned char des3_test_cbc_enc[3][8] = {
Jaeden Amero355b4b02019-05-29 10:13:23 +0100801 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
802 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
803 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000804};
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200805# endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000806
807/*
808 * Checkup routine
809 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200810int mbedtls_des_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000811{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200812 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813 mbedtls_des_context ctx;
814 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000815 unsigned char buf[8];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200816# if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000817 unsigned char prv[8];
818 unsigned char iv[8];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200819# endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000820
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200821 mbedtls_des_init(&ctx);
822 mbedtls_des3_init(&ctx3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000823 /*
824 * ECB mode
825 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200826 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000827 u = i >> 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200828 v = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000829
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200830 if (verbose != 0)
831 mbedtls_printf(" DES%c-ECB-%3d (%s): ", (u == 0) ? ' ' : '3',
832 56 + u * 56,
833 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000834
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200835 memcpy(buf, des3_test_buf, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000836
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200837 switch (i) {
838 case 0:
839 mbedtls_des_setkey_dec(&ctx, des3_test_keys);
840 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000841
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200842 case 1:
843 mbedtls_des_setkey_enc(&ctx, des3_test_keys);
844 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000845
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200846 case 2:
847 mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
848 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000849
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200850 case 3:
851 mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
852 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000853
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200854 case 4:
855 mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
856 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000857
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200858 case 5:
859 mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
860 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000861
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200862 default:
863 return 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000864 }
865
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200866 for (j = 0; j < 100; j++) {
867 if (u == 0)
868 mbedtls_des_crypt_ecb(&ctx, buf, buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000869 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200870 mbedtls_des3_crypt_ecb(&ctx3, buf, buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000871 }
872
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200873 if ((v == MBEDTLS_DES_DECRYPT &&
874 memcmp(buf, des3_test_ecb_dec[u], 8) != 0) ||
875 (v != MBEDTLS_DES_DECRYPT &&
876 memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) {
877 if (verbose != 0)
878 mbedtls_printf("failed\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000879
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200880 ret = 1;
881 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000882 }
883
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200884 if (verbose != 0)
885 mbedtls_printf("passed\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000886 }
887
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200888 if (verbose != 0)
889 mbedtls_printf("\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000890
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200891# if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000892 /*
893 * CBC mode
894 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200895 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000896 u = i >> 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200897 v = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000898
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200899 if (verbose != 0)
900 mbedtls_printf(" DES%c-CBC-%3d (%s): ", (u == 0) ? ' ' : '3',
901 56 + u * 56,
902 (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +0000903
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200904 memcpy(iv, des3_test_iv, 8);
905 memcpy(prv, des3_test_iv, 8);
906 memcpy(buf, des3_test_buf, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000907
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200908 switch (i) {
909 case 0:
910 mbedtls_des_setkey_dec(&ctx, des3_test_keys);
911 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000912
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200913 case 1:
914 mbedtls_des_setkey_enc(&ctx, des3_test_keys);
915 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000916
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200917 case 2:
918 mbedtls_des3_set2key_dec(&ctx3, des3_test_keys);
919 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000920
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200921 case 3:
922 mbedtls_des3_set2key_enc(&ctx3, des3_test_keys);
923 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000924
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200925 case 4:
926 mbedtls_des3_set3key_dec(&ctx3, des3_test_keys);
927 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000928
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200929 case 5:
930 mbedtls_des3_set3key_enc(&ctx3, des3_test_keys);
931 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000932
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200933 default:
934 return 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000935 }
936
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200937 if (v == MBEDTLS_DES_DECRYPT) {
938 for (j = 0; j < 100; j++) {
939 if (u == 0)
940 mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000941 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200942 mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000943 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200944 } else {
945 for (j = 0; j < 100; j++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000946 unsigned char tmp[8];
947
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200948 if (u == 0)
949 mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000950 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200951 mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000952
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200953 memcpy(tmp, prv, 8);
954 memcpy(prv, buf, 8);
955 memcpy(buf, tmp, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000956 }
957
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200958 memcpy(buf, prv, 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 }
960
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200961 if ((v == MBEDTLS_DES_DECRYPT &&
962 memcmp(buf, des3_test_cbc_dec[u], 8) != 0) ||
963 (v != MBEDTLS_DES_DECRYPT &&
964 memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) {
965 if (verbose != 0)
966 mbedtls_printf("failed\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000967
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200968 ret = 1;
969 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000970 }
971
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200972 if (verbose != 0)
973 mbedtls_printf("passed\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000974 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200975# endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000976
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200977 if (verbose != 0)
978 mbedtls_printf("\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000979
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200980exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200981 mbedtls_des_free(&ctx);
982 mbedtls_des3_free(&ctx3);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200983
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200984 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000985}
986
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200987# endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000988
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989#endif /* MBEDTLS_DES_C */