blob: 7f90faa044c124f8cde53f5724ba28d2997d5110 [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"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050031#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Rich Evans00ab4702015-02-06 13:43:58 +000033#include <string.h>
34
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#if defined(MBEDTLS_SELF_TEST)
36#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010038#else
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#define mbedtls_printf printf
41#endif /* MBEDTLS_PLATFORM_C */
42#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010043
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020045
Paul Bakker5121ce52009-01-03 21:22:43 +000046/*
Paul Bakker5121ce52009-01-03 21:22:43 +000047 * Expanded DES S-boxes
48 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000049static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000050{
51 0x01010400, 0x00000000, 0x00010000, 0x01010404,
52 0x01010004, 0x00010404, 0x00000004, 0x00010000,
53 0x00000400, 0x01010400, 0x01010404, 0x00000400,
54 0x01000404, 0x01010004, 0x01000000, 0x00000004,
55 0x00000404, 0x01000400, 0x01000400, 0x00010400,
56 0x00010400, 0x01010000, 0x01010000, 0x01000404,
57 0x00010004, 0x01000004, 0x01000004, 0x00010004,
58 0x00000000, 0x00000404, 0x00010404, 0x01000000,
59 0x00010000, 0x01010404, 0x00000004, 0x01010000,
60 0x01010400, 0x01000000, 0x01000000, 0x00000400,
61 0x01010004, 0x00010000, 0x00010400, 0x01000004,
62 0x00000400, 0x00000004, 0x01000404, 0x00010404,
63 0x01010404, 0x00010004, 0x01010000, 0x01000404,
64 0x01000004, 0x00000404, 0x00010404, 0x01010400,
65 0x00000404, 0x01000400, 0x01000400, 0x00000000,
66 0x00010004, 0x00010400, 0x00000000, 0x01010004
67};
68
Paul Bakker5c2364c2012-10-01 14:41:15 +000069static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000070{
71 0x80108020, 0x80008000, 0x00008000, 0x00108020,
72 0x00100000, 0x00000020, 0x80100020, 0x80008020,
73 0x80000020, 0x80108020, 0x80108000, 0x80000000,
74 0x80008000, 0x00100000, 0x00000020, 0x80100020,
75 0x00108000, 0x00100020, 0x80008020, 0x00000000,
76 0x80000000, 0x00008000, 0x00108020, 0x80100000,
77 0x00100020, 0x80000020, 0x00000000, 0x00108000,
78 0x00008020, 0x80108000, 0x80100000, 0x00008020,
79 0x00000000, 0x00108020, 0x80100020, 0x00100000,
80 0x80008020, 0x80100000, 0x80108000, 0x00008000,
81 0x80100000, 0x80008000, 0x00000020, 0x80108020,
82 0x00108020, 0x00000020, 0x00008000, 0x80000000,
83 0x00008020, 0x80108000, 0x00100000, 0x80000020,
84 0x00100020, 0x80008020, 0x80000020, 0x00100020,
85 0x00108000, 0x00000000, 0x80008000, 0x00008020,
86 0x80000000, 0x80100020, 0x80108020, 0x00108000
87};
88
Paul Bakker5c2364c2012-10-01 14:41:15 +000089static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000090{
91 0x00000208, 0x08020200, 0x00000000, 0x08020008,
92 0x08000200, 0x00000000, 0x00020208, 0x08000200,
93 0x00020008, 0x08000008, 0x08000008, 0x00020000,
94 0x08020208, 0x00020008, 0x08020000, 0x00000208,
95 0x08000000, 0x00000008, 0x08020200, 0x00000200,
96 0x00020200, 0x08020000, 0x08020008, 0x00020208,
97 0x08000208, 0x00020200, 0x00020000, 0x08000208,
98 0x00000008, 0x08020208, 0x00000200, 0x08000000,
99 0x08020200, 0x08000000, 0x00020008, 0x00000208,
100 0x00020000, 0x08020200, 0x08000200, 0x00000000,
101 0x00000200, 0x00020008, 0x08020208, 0x08000200,
102 0x08000008, 0x00000200, 0x00000000, 0x08020008,
103 0x08000208, 0x00020000, 0x08000000, 0x08020208,
104 0x00000008, 0x00020208, 0x00020200, 0x08000008,
105 0x08020000, 0x08000208, 0x00000208, 0x08020000,
106 0x00020208, 0x00000008, 0x08020008, 0x00020200
107};
108
Paul Bakker5c2364c2012-10-01 14:41:15 +0000109static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000110{
111 0x00802001, 0x00002081, 0x00002081, 0x00000080,
112 0x00802080, 0x00800081, 0x00800001, 0x00002001,
113 0x00000000, 0x00802000, 0x00802000, 0x00802081,
114 0x00000081, 0x00000000, 0x00800080, 0x00800001,
115 0x00000001, 0x00002000, 0x00800000, 0x00802001,
116 0x00000080, 0x00800000, 0x00002001, 0x00002080,
117 0x00800081, 0x00000001, 0x00002080, 0x00800080,
118 0x00002000, 0x00802080, 0x00802081, 0x00000081,
119 0x00800080, 0x00800001, 0x00802000, 0x00802081,
120 0x00000081, 0x00000000, 0x00000000, 0x00802000,
121 0x00002080, 0x00800080, 0x00800081, 0x00000001,
122 0x00802001, 0x00002081, 0x00002081, 0x00000080,
123 0x00802081, 0x00000081, 0x00000001, 0x00002000,
124 0x00800001, 0x00002001, 0x00802080, 0x00800081,
125 0x00002001, 0x00002080, 0x00800000, 0x00802001,
126 0x00000080, 0x00800000, 0x00002000, 0x00802080
127};
128
Paul Bakker5c2364c2012-10-01 14:41:15 +0000129static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000130{
131 0x00000100, 0x02080100, 0x02080000, 0x42000100,
132 0x00080000, 0x00000100, 0x40000000, 0x02080000,
133 0x40080100, 0x00080000, 0x02000100, 0x40080100,
134 0x42000100, 0x42080000, 0x00080100, 0x40000000,
135 0x02000000, 0x40080000, 0x40080000, 0x00000000,
136 0x40000100, 0x42080100, 0x42080100, 0x02000100,
137 0x42080000, 0x40000100, 0x00000000, 0x42000000,
138 0x02080100, 0x02000000, 0x42000000, 0x00080100,
139 0x00080000, 0x42000100, 0x00000100, 0x02000000,
140 0x40000000, 0x02080000, 0x42000100, 0x40080100,
141 0x02000100, 0x40000000, 0x42080000, 0x02080100,
142 0x40080100, 0x00000100, 0x02000000, 0x42080000,
143 0x42080100, 0x00080100, 0x42000000, 0x42080100,
144 0x02080000, 0x00000000, 0x40080000, 0x42000000,
145 0x00080100, 0x02000100, 0x40000100, 0x00080000,
146 0x00000000, 0x40080000, 0x02080100, 0x40000100
147};
148
Paul Bakker5c2364c2012-10-01 14:41:15 +0000149static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000150{
151 0x20000010, 0x20400000, 0x00004000, 0x20404010,
152 0x20400000, 0x00000010, 0x20404010, 0x00400000,
153 0x20004000, 0x00404010, 0x00400000, 0x20000010,
154 0x00400010, 0x20004000, 0x20000000, 0x00004010,
155 0x00000000, 0x00400010, 0x20004010, 0x00004000,
156 0x00404000, 0x20004010, 0x00000010, 0x20400010,
157 0x20400010, 0x00000000, 0x00404010, 0x20404000,
158 0x00004010, 0x00404000, 0x20404000, 0x20000000,
159 0x20004000, 0x00000010, 0x20400010, 0x00404000,
160 0x20404010, 0x00400000, 0x00004010, 0x20000010,
161 0x00400000, 0x20004000, 0x20000000, 0x00004010,
162 0x20000010, 0x20404010, 0x00404000, 0x20400000,
163 0x00404010, 0x20404000, 0x00000000, 0x20400010,
164 0x00000010, 0x00004000, 0x20400000, 0x00404010,
165 0x00004000, 0x00400010, 0x20004010, 0x00000000,
166 0x20404000, 0x20000000, 0x00400010, 0x20004010
167};
168
Paul Bakker5c2364c2012-10-01 14:41:15 +0000169static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000170{
171 0x00200000, 0x04200002, 0x04000802, 0x00000000,
172 0x00000800, 0x04000802, 0x00200802, 0x04200800,
173 0x04200802, 0x00200000, 0x00000000, 0x04000002,
174 0x00000002, 0x04000000, 0x04200002, 0x00000802,
175 0x04000800, 0x00200802, 0x00200002, 0x04000800,
176 0x04000002, 0x04200000, 0x04200800, 0x00200002,
177 0x04200000, 0x00000800, 0x00000802, 0x04200802,
178 0x00200800, 0x00000002, 0x04000000, 0x00200800,
179 0x04000000, 0x00200800, 0x00200000, 0x04000802,
180 0x04000802, 0x04200002, 0x04200002, 0x00000002,
181 0x00200002, 0x04000000, 0x04000800, 0x00200000,
182 0x04200800, 0x00000802, 0x00200802, 0x04200800,
183 0x00000802, 0x04000002, 0x04200802, 0x04200000,
184 0x00200800, 0x00000000, 0x00000002, 0x04200802,
185 0x00000000, 0x00200802, 0x04200000, 0x00000800,
186 0x04000002, 0x04000800, 0x00000800, 0x00200002
187};
188
Paul Bakker5c2364c2012-10-01 14:41:15 +0000189static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000190{
191 0x10001040, 0x00001000, 0x00040000, 0x10041040,
192 0x10000000, 0x10001040, 0x00000040, 0x10000000,
193 0x00040040, 0x10040000, 0x10041040, 0x00041000,
194 0x10041000, 0x00041040, 0x00001000, 0x00000040,
195 0x10040000, 0x10000040, 0x10001000, 0x00001040,
196 0x00041000, 0x00040040, 0x10040040, 0x10041000,
197 0x00001040, 0x00000000, 0x00000000, 0x10040040,
198 0x10000040, 0x10001000, 0x00041040, 0x00040000,
199 0x00041040, 0x00040000, 0x10041000, 0x00001000,
200 0x00000040, 0x10040040, 0x00001000, 0x00041040,
201 0x10001000, 0x00000040, 0x10000040, 0x10040000,
202 0x10040040, 0x10000000, 0x00040000, 0x10001040,
203 0x00000000, 0x10041040, 0x00040040, 0x10000040,
204 0x10040000, 0x10001000, 0x10001040, 0x00000000,
205 0x10041040, 0x00041000, 0x00041000, 0x00001040,
206 0x00001040, 0x00040040, 0x10000000, 0x10041000
207};
208
209/*
210 * PC1: left and right halves bit-swap
211 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000212static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000213{
214 0x00000000, 0x00000001, 0x00000100, 0x00000101,
215 0x00010000, 0x00010001, 0x00010100, 0x00010101,
216 0x01000000, 0x01000001, 0x01000100, 0x01000101,
217 0x01010000, 0x01010001, 0x01010100, 0x01010101
218};
219
Paul Bakker5c2364c2012-10-01 14:41:15 +0000220static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000221{
222 0x00000000, 0x01000000, 0x00010000, 0x01010000,
223 0x00000100, 0x01000100, 0x00010100, 0x01010100,
224 0x00000001, 0x01000001, 0x00010001, 0x01010001,
225 0x00000101, 0x01000101, 0x00010101, 0x01010101,
226};
227
228/*
229 * Initial Permutation macro
230 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100231#define DES_IP(X,Y) \
232 do \
233 { \
234 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
235 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
236 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
237 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
238 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
239 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
240 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
241 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
243/*
244 * Final Permutation macro
245 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100246#define DES_FP(X,Y) \
247 do \
248 { \
249 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
250 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
251 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
252 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
253 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
254 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
255 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
256 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000257
258/*
259 * DES round macro
260 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100261#define DES_ROUND(X,Y) \
262 do \
263 { \
264 T = *SK++ ^ (X); \
265 (Y) ^= SB8[ (T ) & 0x3F ] ^ \
266 SB6[ (T >> 8) & 0x3F ] ^ \
267 SB4[ (T >> 16) & 0x3F ] ^ \
268 SB2[ (T >> 24) & 0x3F ]; \
269 \
270 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
271 (Y) ^= SB7[ (T ) & 0x3F ] ^ \
272 SB5[ (T >> 8) & 0x3F ] ^ \
273 SB3[ (T >> 16) & 0x3F ] ^ \
274 SB1[ (T >> 24) & 0x3F ]; \
275 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
Hanno Becker1eeca412018-10-15 12:01:35 +0100277#define SWAP(a,b) \
278 do \
279 { \
280 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
281 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000282
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200284{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200285 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200286}
287
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200289{
290 if( ctx == NULL )
291 return;
292
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500293 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200294}
295
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200296void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200297{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200298 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200299}
300
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200302{
303 if( ctx == NULL )
304 return;
305
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500306 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200307}
308
Paul Bakker1f87fb62011-01-15 17:32:24 +0000309static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
310 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
311 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
312 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
313 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
314 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
315 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
316 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
317 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
318 254 };
319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000321{
322 int i;
323
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200324 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000325 key[i] = odd_parity_table[key[i] / 2];
326}
327
328/*
329 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
330 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000332{
333 int i;
334
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200336 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000337 return( 1 );
338
339 return( 0 );
340}
341
342/*
343 * Table of weak and semi-weak keys
344 *
345 * Source: http://en.wikipedia.org/wiki/Weak_key
346 *
347 * Weak:
348 * Alternating ones + zeros (0x0101010101010101)
349 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
350 * '0xE0E0E0E0F1F1F1F1'
351 * '0x1F1F1F1F0E0E0E0E'
352 *
353 * Semi-weak:
354 * 0x011F011F010E010E and 0x1F011F010E010E01
355 * 0x01E001E001F101F1 and 0xE001E001F101F101
356 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
357 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
358 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
359 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
360 *
361 */
362
363#define WEAK_KEY_COUNT 16
364
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000366{
367 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
368 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
369 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
370 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
371
372 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
373 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
374 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
375 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
376 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
377 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
378 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
379 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
380 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
381 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
382 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
383 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
384};
385
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000387{
388 int i;
389
390 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000392 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000393
Paul Bakker73206952011-07-06 14:37:33 +0000394 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000395}
396
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200397#if !defined(MBEDTLS_DES_SETKEY_ALT)
398void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000399{
400 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000401 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000402
Joe Subbiani6a506312021-07-07 16:56:29 +0100403 X = MBEDTLS_GET_UINT32_BE( key, 0 );
404 Y = MBEDTLS_GET_UINT32_BE( key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
406 /*
407 * Permuted Choice 1
408 */
409 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
410 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
411
412 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
413 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
414 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
415 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
416
417 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
418 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
419 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
420 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
421
422 X &= 0x0FFFFFFF;
423 Y &= 0x0FFFFFFF;
424
425 /*
426 * calculate subkeys
427 */
428 for( i = 0; i < 16; i++ )
429 {
430 if( i < 2 || i == 8 || i == 15 )
431 {
432 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
433 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
434 }
435 else
436 {
437 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
438 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
439 }
440
441 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
442 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
443 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
444 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
445 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
446 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
447 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
448 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
449 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
450 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
451 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
452
453 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
454 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
455 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
456 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
457 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
458 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
459 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
460 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
461 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
462 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
463 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
464 }
465}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200466#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
468/*
469 * DES key schedule (56-bit, encryption)
470 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000472{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200473 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000474
475 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000476}
477
478/*
479 * DES key schedule (56-bit, decryption)
480 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000482{
483 int i;
484
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200485 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
487 for( i = 0; i < 16; i += 2 )
488 {
489 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
490 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
491 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000492
493 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000494}
495
Paul Bakker5c2364c2012-10-01 14:41:15 +0000496static void des3_set2key( uint32_t esk[96],
497 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000499{
500 int i;
501
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200502 mbedtls_des_setkey( esk, key );
503 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000504
505 for( i = 0; i < 32; i += 2 )
506 {
507 dsk[i ] = esk[30 - i];
508 dsk[i + 1] = esk[31 - i];
509
510 esk[i + 32] = dsk[62 - i];
511 esk[i + 33] = dsk[63 - i];
512
513 esk[i + 64] = esk[i ];
514 esk[i + 65] = esk[i + 1];
515
516 dsk[i + 64] = dsk[i ];
517 dsk[i + 65] = dsk[i + 1];
518 }
519}
520
521/*
522 * Triple-DES key schedule (112-bit, encryption)
523 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200524int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
525 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000526{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000527 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000528
529 des3_set2key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500530 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000531
532 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000533}
534
535/*
536 * Triple-DES key schedule (112-bit, decryption)
537 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
539 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000540{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000541 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000542
543 des3_set2key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500544 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000545
546 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000547}
548
Paul Bakker5c2364c2012-10-01 14:41:15 +0000549static void des3_set3key( uint32_t esk[96],
550 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000551 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000552{
553 int i;
554
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200555 mbedtls_des_setkey( esk, key );
556 mbedtls_des_setkey( dsk + 32, key + 8 );
557 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000558
559 for( i = 0; i < 32; i += 2 )
560 {
561 dsk[i ] = esk[94 - i];
562 dsk[i + 1] = esk[95 - i];
563
564 esk[i + 32] = dsk[62 - i];
565 esk[i + 33] = dsk[63 - i];
566
567 dsk[i + 64] = esk[30 - i];
568 dsk[i + 65] = esk[31 - i];
569 }
570}
571
572/*
573 * Triple-DES key schedule (168-bit, encryption)
574 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
576 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000577{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000578 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
580 des3_set3key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500581 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000582
583 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000584}
585
586/*
587 * Triple-DES key schedule (168-bit, decryption)
588 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
590 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000591{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000592 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
594 des3_set3key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500595 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000596
597 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000598}
599
600/*
601 * DES-ECB block encryption/decryption
602 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200603#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000605 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000606 unsigned char output[8] )
607{
608 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000609 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
611 SK = ctx->sk;
612
Joe Subbiani6a506312021-07-07 16:56:29 +0100613 X = MBEDTLS_GET_UINT32_BE( input, 0 );
614 Y = MBEDTLS_GET_UINT32_BE( input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
616 DES_IP( X, Y );
617
618 for( i = 0; i < 8; i++ )
619 {
620 DES_ROUND( Y, X );
621 DES_ROUND( X, Y );
622 }
623
624 DES_FP( Y, X );
625
Joe Subbiani5ecac212021-06-24 13:00:03 +0100626 MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
627 MBEDTLS_PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000628
629 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000630}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200631#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000634/*
635 * DES-CBC buffer encryption/decryption
636 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000638 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000639 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000640 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000641 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000642 unsigned char *output )
643{
644 int i;
645 unsigned char temp[8];
646
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000647 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000651 {
652 while( length > 0 )
653 {
654 for( i = 0; i < 8; i++ )
655 output[i] = (unsigned char)( input[i] ^ iv[i] );
656
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657 mbedtls_des_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000658 memcpy( iv, output, 8 );
659
660 input += 8;
661 output += 8;
662 length -= 8;
663 }
664 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200665 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 {
667 while( length > 0 )
668 {
669 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200670 mbedtls_des_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
672 for( i = 0; i < 8; i++ )
673 output[i] = (unsigned char)( output[i] ^ iv[i] );
674
675 memcpy( iv, temp, 8 );
676
677 input += 8;
678 output += 8;
679 length -= 8;
680 }
681 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000682
683 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000684}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200685#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000686
687/*
688 * 3DES-ECB block encryption/decryption
689 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200690#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200691int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000692 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000693 unsigned char output[8] )
694{
695 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000696 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000697
698 SK = ctx->sk;
699
Joe Subbiani6a506312021-07-07 16:56:29 +0100700 X = MBEDTLS_GET_UINT32_BE( input, 0 );
701 Y = MBEDTLS_GET_UINT32_BE( input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000702
703 DES_IP( X, Y );
704
705 for( i = 0; i < 8; i++ )
706 {
707 DES_ROUND( Y, X );
708 DES_ROUND( X, Y );
709 }
710
711 for( i = 0; i < 8; i++ )
712 {
713 DES_ROUND( X, Y );
714 DES_ROUND( Y, X );
715 }
716
717 for( i = 0; i < 8; i++ )
718 {
719 DES_ROUND( Y, X );
720 DES_ROUND( X, Y );
721 }
722
723 DES_FP( Y, X );
724
Joe Subbiani5ecac212021-06-24 13:00:03 +0100725 MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
726 MBEDTLS_PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000727
728 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000729}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200730#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000731
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200732#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000733/*
734 * 3DES-CBC buffer encryption/decryption
735 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200736int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000737 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000738 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000739 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000740 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000741 unsigned char *output )
742{
743 int i;
744 unsigned char temp[8];
745
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000746 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200747 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000748
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000750 {
751 while( length > 0 )
752 {
753 for( i = 0; i < 8; i++ )
754 output[i] = (unsigned char)( input[i] ^ iv[i] );
755
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200756 mbedtls_des3_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000757 memcpy( iv, output, 8 );
758
759 input += 8;
760 output += 8;
761 length -= 8;
762 }
763 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200764 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000765 {
766 while( length > 0 )
767 {
768 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200769 mbedtls_des3_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000770
771 for( i = 0; i < 8; i++ )
772 output[i] = (unsigned char)( output[i] ^ iv[i] );
773
774 memcpy( iv, temp, 8 );
775
776 input += 8;
777 output += 8;
778 length -= 8;
779 }
780 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000781
782 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000783}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200784#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000785
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200787
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000789/*
790 * DES and 3DES test vectors from:
791 *
792 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
793 */
794static const unsigned char des3_test_keys[24] =
795{
796 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
797 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
798 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
799};
800
Paul Bakker5121ce52009-01-03 21:22:43 +0000801static const unsigned char des3_test_buf[8] =
802{
803 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
804};
805
806static const unsigned char des3_test_ecb_dec[3][8] =
807{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100808 { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
809 { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
810 { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
Paul Bakker5121ce52009-01-03 21:22:43 +0000811};
812
813static const unsigned char des3_test_ecb_enc[3][8] =
814{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100815 { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
816 { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
817 { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
Paul Bakker5121ce52009-01-03 21:22:43 +0000818};
819
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100821static const unsigned char des3_test_iv[8] =
822{
823 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
824};
825
Paul Bakker5121ce52009-01-03 21:22:43 +0000826static const unsigned char des3_test_cbc_dec[3][8] =
827{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100828 { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
829 { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
830 { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
Paul Bakker5121ce52009-01-03 21:22:43 +0000831};
832
833static const unsigned char des3_test_cbc_enc[3][8] =
834{
Jaeden Amero355b4b02019-05-29 10:13:23 +0100835 { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
836 { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
837 { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000838};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000840
841/*
842 * Checkup routine
843 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200844int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000845{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200846 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847 mbedtls_des_context ctx;
848 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000849 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200850#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000851 unsigned char prv[8];
852 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200853#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000854
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855 mbedtls_des_init( &ctx );
856 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000857 /*
858 * ECB mode
859 */
860 for( i = 0; i < 6; i++ )
861 {
862 u = i >> 1;
863 v = i & 1;
864
865 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100867 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000869
870 memcpy( buf, des3_test_buf, 8 );
871
872 switch( i )
873 {
874 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000876 break;
877
878 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000880 break;
881
882 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000884 break;
885
886 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200887 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000888 break;
889
890 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000892 break;
893
894 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000896 break;
897
898 default:
899 return( 1 );
900 }
901
Jaeden Amero355b4b02019-05-29 10:13:23 +0100902 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000903 {
904 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905 mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000906 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200907 mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000908 }
909
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000911 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200912 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000913 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
914 {
915 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000917
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200918 ret = 1;
919 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000920 }
921
922 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200923 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000924 }
925
926 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000928
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000930 /*
931 * CBC mode
932 */
933 for( i = 0; i < 6; i++ )
934 {
935 u = i >> 1;
936 v = i & 1;
937
938 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100940 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000942
943 memcpy( iv, des3_test_iv, 8 );
944 memcpy( prv, des3_test_iv, 8 );
945 memcpy( buf, des3_test_buf, 8 );
946
947 switch( i )
948 {
949 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000951 break;
952
953 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000955 break;
956
957 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 break;
960
961 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200962 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000963 break;
964
965 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000967 break;
968
969 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200970 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000971 break;
972
973 default:
974 return( 1 );
975 }
976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 if( v == MBEDTLS_DES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000978 {
Jaeden Amero355b4b02019-05-29 10:13:23 +0100979 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000980 {
981 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200982 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000983 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200984 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000985 }
986 }
987 else
988 {
Jaeden Amero355b4b02019-05-29 10:13:23 +0100989 for( j = 0; j < 100; j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000990 {
991 unsigned char tmp[8];
992
993 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200994 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000995 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200996 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000997
998 memcpy( tmp, prv, 8 );
999 memcpy( prv, buf, 8 );
1000 memcpy( buf, tmp, 8 );
1001 }
1002
1003 memcpy( buf, prv, 8 );
1004 }
1005
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001007 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001008 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001009 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1010 {
1011 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001012 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001013
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001014 ret = 1;
1015 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001016 }
1017
1018 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001020 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001022
1023 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001025
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001026exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001027 mbedtls_des_free( &ctx );
1028 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001029
1030 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001031}
1032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001034
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035#endif /* MBEDTLS_DES_C */