blob: 8a33d82e50e2df1973da8a2bcfe5a5e940878d4c [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-46-3 compliant Triple-DES implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
22 * DES, on which TDES is based, was originally designed by Horst Feistel
23 * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
24 *
25 * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
26 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_DES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/des.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050037#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_SELF_TEST)
42#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044#else
Rich Evans00ab4702015-02-06 13:43:58 +000045#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#define mbedtls_printf printf
47#endif /* MBEDTLS_PLATFORM_C */
48#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if !defined(MBEDTLS_DES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020051
Paul Bakker5121ce52009-01-03 21:22:43 +000052/*
53 * 32-bit integer manipulation macros (big endian)
54 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000055#ifndef GET_UINT32_BE
56#define GET_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000057{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000058 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
59 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
60 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
61 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000062}
63#endif
64
Paul Bakker5c2364c2012-10-01 14:41:15 +000065#ifndef PUT_UINT32_BE
66#define PUT_UINT32_BE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000067{ \
68 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
69 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
70 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
71 (b)[(i) + 3] = (unsigned char) ( (n) ); \
72}
73#endif
74
75/*
76 * Expanded DES S-boxes
77 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000078static const uint32_t SB1[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000079{
80 0x01010400, 0x00000000, 0x00010000, 0x01010404,
81 0x01010004, 0x00010404, 0x00000004, 0x00010000,
82 0x00000400, 0x01010400, 0x01010404, 0x00000400,
83 0x01000404, 0x01010004, 0x01000000, 0x00000004,
84 0x00000404, 0x01000400, 0x01000400, 0x00010400,
85 0x00010400, 0x01010000, 0x01010000, 0x01000404,
86 0x00010004, 0x01000004, 0x01000004, 0x00010004,
87 0x00000000, 0x00000404, 0x00010404, 0x01000000,
88 0x00010000, 0x01010404, 0x00000004, 0x01010000,
89 0x01010400, 0x01000000, 0x01000000, 0x00000400,
90 0x01010004, 0x00010000, 0x00010400, 0x01000004,
91 0x00000400, 0x00000004, 0x01000404, 0x00010404,
92 0x01010404, 0x00010004, 0x01010000, 0x01000404,
93 0x01000004, 0x00000404, 0x00010404, 0x01010400,
94 0x00000404, 0x01000400, 0x01000400, 0x00000000,
95 0x00010004, 0x00010400, 0x00000000, 0x01010004
96};
97
Paul Bakker5c2364c2012-10-01 14:41:15 +000098static const uint32_t SB2[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +000099{
100 0x80108020, 0x80008000, 0x00008000, 0x00108020,
101 0x00100000, 0x00000020, 0x80100020, 0x80008020,
102 0x80000020, 0x80108020, 0x80108000, 0x80000000,
103 0x80008000, 0x00100000, 0x00000020, 0x80100020,
104 0x00108000, 0x00100020, 0x80008020, 0x00000000,
105 0x80000000, 0x00008000, 0x00108020, 0x80100000,
106 0x00100020, 0x80000020, 0x00000000, 0x00108000,
107 0x00008020, 0x80108000, 0x80100000, 0x00008020,
108 0x00000000, 0x00108020, 0x80100020, 0x00100000,
109 0x80008020, 0x80100000, 0x80108000, 0x00008000,
110 0x80100000, 0x80008000, 0x00000020, 0x80108020,
111 0x00108020, 0x00000020, 0x00008000, 0x80000000,
112 0x00008020, 0x80108000, 0x00100000, 0x80000020,
113 0x00100020, 0x80008020, 0x80000020, 0x00100020,
114 0x00108000, 0x00000000, 0x80008000, 0x00008020,
115 0x80000000, 0x80100020, 0x80108020, 0x00108000
116};
117
Paul Bakker5c2364c2012-10-01 14:41:15 +0000118static const uint32_t SB3[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000119{
120 0x00000208, 0x08020200, 0x00000000, 0x08020008,
121 0x08000200, 0x00000000, 0x00020208, 0x08000200,
122 0x00020008, 0x08000008, 0x08000008, 0x00020000,
123 0x08020208, 0x00020008, 0x08020000, 0x00000208,
124 0x08000000, 0x00000008, 0x08020200, 0x00000200,
125 0x00020200, 0x08020000, 0x08020008, 0x00020208,
126 0x08000208, 0x00020200, 0x00020000, 0x08000208,
127 0x00000008, 0x08020208, 0x00000200, 0x08000000,
128 0x08020200, 0x08000000, 0x00020008, 0x00000208,
129 0x00020000, 0x08020200, 0x08000200, 0x00000000,
130 0x00000200, 0x00020008, 0x08020208, 0x08000200,
131 0x08000008, 0x00000200, 0x00000000, 0x08020008,
132 0x08000208, 0x00020000, 0x08000000, 0x08020208,
133 0x00000008, 0x00020208, 0x00020200, 0x08000008,
134 0x08020000, 0x08000208, 0x00000208, 0x08020000,
135 0x00020208, 0x00000008, 0x08020008, 0x00020200
136};
137
Paul Bakker5c2364c2012-10-01 14:41:15 +0000138static const uint32_t SB4[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000139{
140 0x00802001, 0x00002081, 0x00002081, 0x00000080,
141 0x00802080, 0x00800081, 0x00800001, 0x00002001,
142 0x00000000, 0x00802000, 0x00802000, 0x00802081,
143 0x00000081, 0x00000000, 0x00800080, 0x00800001,
144 0x00000001, 0x00002000, 0x00800000, 0x00802001,
145 0x00000080, 0x00800000, 0x00002001, 0x00002080,
146 0x00800081, 0x00000001, 0x00002080, 0x00800080,
147 0x00002000, 0x00802080, 0x00802081, 0x00000081,
148 0x00800080, 0x00800001, 0x00802000, 0x00802081,
149 0x00000081, 0x00000000, 0x00000000, 0x00802000,
150 0x00002080, 0x00800080, 0x00800081, 0x00000001,
151 0x00802001, 0x00002081, 0x00002081, 0x00000080,
152 0x00802081, 0x00000081, 0x00000001, 0x00002000,
153 0x00800001, 0x00002001, 0x00802080, 0x00800081,
154 0x00002001, 0x00002080, 0x00800000, 0x00802001,
155 0x00000080, 0x00800000, 0x00002000, 0x00802080
156};
157
Paul Bakker5c2364c2012-10-01 14:41:15 +0000158static const uint32_t SB5[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000159{
160 0x00000100, 0x02080100, 0x02080000, 0x42000100,
161 0x00080000, 0x00000100, 0x40000000, 0x02080000,
162 0x40080100, 0x00080000, 0x02000100, 0x40080100,
163 0x42000100, 0x42080000, 0x00080100, 0x40000000,
164 0x02000000, 0x40080000, 0x40080000, 0x00000000,
165 0x40000100, 0x42080100, 0x42080100, 0x02000100,
166 0x42080000, 0x40000100, 0x00000000, 0x42000000,
167 0x02080100, 0x02000000, 0x42000000, 0x00080100,
168 0x00080000, 0x42000100, 0x00000100, 0x02000000,
169 0x40000000, 0x02080000, 0x42000100, 0x40080100,
170 0x02000100, 0x40000000, 0x42080000, 0x02080100,
171 0x40080100, 0x00000100, 0x02000000, 0x42080000,
172 0x42080100, 0x00080100, 0x42000000, 0x42080100,
173 0x02080000, 0x00000000, 0x40080000, 0x42000000,
174 0x00080100, 0x02000100, 0x40000100, 0x00080000,
175 0x00000000, 0x40080000, 0x02080100, 0x40000100
176};
177
Paul Bakker5c2364c2012-10-01 14:41:15 +0000178static const uint32_t SB6[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000179{
180 0x20000010, 0x20400000, 0x00004000, 0x20404010,
181 0x20400000, 0x00000010, 0x20404010, 0x00400000,
182 0x20004000, 0x00404010, 0x00400000, 0x20000010,
183 0x00400010, 0x20004000, 0x20000000, 0x00004010,
184 0x00000000, 0x00400010, 0x20004010, 0x00004000,
185 0x00404000, 0x20004010, 0x00000010, 0x20400010,
186 0x20400010, 0x00000000, 0x00404010, 0x20404000,
187 0x00004010, 0x00404000, 0x20404000, 0x20000000,
188 0x20004000, 0x00000010, 0x20400010, 0x00404000,
189 0x20404010, 0x00400000, 0x00004010, 0x20000010,
190 0x00400000, 0x20004000, 0x20000000, 0x00004010,
191 0x20000010, 0x20404010, 0x00404000, 0x20400000,
192 0x00404010, 0x20404000, 0x00000000, 0x20400010,
193 0x00000010, 0x00004000, 0x20400000, 0x00404010,
194 0x00004000, 0x00400010, 0x20004010, 0x00000000,
195 0x20404000, 0x20000000, 0x00400010, 0x20004010
196};
197
Paul Bakker5c2364c2012-10-01 14:41:15 +0000198static const uint32_t SB7[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000199{
200 0x00200000, 0x04200002, 0x04000802, 0x00000000,
201 0x00000800, 0x04000802, 0x00200802, 0x04200800,
202 0x04200802, 0x00200000, 0x00000000, 0x04000002,
203 0x00000002, 0x04000000, 0x04200002, 0x00000802,
204 0x04000800, 0x00200802, 0x00200002, 0x04000800,
205 0x04000002, 0x04200000, 0x04200800, 0x00200002,
206 0x04200000, 0x00000800, 0x00000802, 0x04200802,
207 0x00200800, 0x00000002, 0x04000000, 0x00200800,
208 0x04000000, 0x00200800, 0x00200000, 0x04000802,
209 0x04000802, 0x04200002, 0x04200002, 0x00000002,
210 0x00200002, 0x04000000, 0x04000800, 0x00200000,
211 0x04200800, 0x00000802, 0x00200802, 0x04200800,
212 0x00000802, 0x04000002, 0x04200802, 0x04200000,
213 0x00200800, 0x00000000, 0x00000002, 0x04200802,
214 0x00000000, 0x00200802, 0x04200000, 0x00000800,
215 0x04000002, 0x04000800, 0x00000800, 0x00200002
216};
217
Paul Bakker5c2364c2012-10-01 14:41:15 +0000218static const uint32_t SB8[64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000219{
220 0x10001040, 0x00001000, 0x00040000, 0x10041040,
221 0x10000000, 0x10001040, 0x00000040, 0x10000000,
222 0x00040040, 0x10040000, 0x10041040, 0x00041000,
223 0x10041000, 0x00041040, 0x00001000, 0x00000040,
224 0x10040000, 0x10000040, 0x10001000, 0x00001040,
225 0x00041000, 0x00040040, 0x10040040, 0x10041000,
226 0x00001040, 0x00000000, 0x00000000, 0x10040040,
227 0x10000040, 0x10001000, 0x00041040, 0x00040000,
228 0x00041040, 0x00040000, 0x10041000, 0x00001000,
229 0x00000040, 0x10040040, 0x00001000, 0x00041040,
230 0x10001000, 0x00000040, 0x10000040, 0x10040000,
231 0x10040040, 0x10000000, 0x00040000, 0x10001040,
232 0x00000000, 0x10041040, 0x00040040, 0x10000040,
233 0x10040000, 0x10001000, 0x10001040, 0x00000000,
234 0x10041040, 0x00041000, 0x00041000, 0x00001040,
235 0x00001040, 0x00040040, 0x10000000, 0x10041000
236};
237
238/*
239 * PC1: left and right halves bit-swap
240 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000241static const uint32_t LHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000242{
243 0x00000000, 0x00000001, 0x00000100, 0x00000101,
244 0x00010000, 0x00010001, 0x00010100, 0x00010101,
245 0x01000000, 0x01000001, 0x01000100, 0x01000101,
246 0x01010000, 0x01010001, 0x01010100, 0x01010101
247};
248
Paul Bakker5c2364c2012-10-01 14:41:15 +0000249static const uint32_t RHs[16] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000250{
251 0x00000000, 0x01000000, 0x00010000, 0x01010000,
252 0x00000100, 0x01000100, 0x00010100, 0x01010100,
253 0x00000001, 0x01000001, 0x00010001, 0x01010001,
254 0x00000101, 0x01000101, 0x00010101, 0x01010101,
255};
256
257/*
258 * Initial Permutation macro
259 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100260#define DES_IP(X,Y) \
261 do \
262 { \
263 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
264 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
265 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
266 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
267 (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \
268 T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \
269 (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \
270 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000271
272/*
273 * Final Permutation macro
274 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100275#define DES_FP(X,Y) \
276 do \
277 { \
278 (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \
279 T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \
280 (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \
281 T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \
282 T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \
283 T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
284 T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \
285 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000286
287/*
288 * DES round macro
289 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100290#define DES_ROUND(X,Y) \
291 do \
292 { \
293 T = *SK++ ^ (X); \
294 (Y) ^= SB8[ (T ) & 0x3F ] ^ \
295 SB6[ (T >> 8) & 0x3F ] ^ \
296 SB4[ (T >> 16) & 0x3F ] ^ \
297 SB2[ (T >> 24) & 0x3F ]; \
298 \
299 T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \
300 (Y) ^= SB7[ (T ) & 0x3F ] ^ \
301 SB5[ (T >> 8) & 0x3F ] ^ \
302 SB3[ (T >> 16) & 0x3F ] ^ \
303 SB1[ (T >> 24) & 0x3F ]; \
304 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000305
Hanno Becker1eeca412018-10-15 12:01:35 +0100306#define SWAP(a,b) \
307 do \
308 { \
309 uint32_t t = (a); (a) = (b); (b) = t; t = 0; \
310 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000311
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312void mbedtls_des_init( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200313{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314 memset( ctx, 0, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200315}
316
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317void mbedtls_des_free( mbedtls_des_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200318{
319 if( ctx == NULL )
320 return;
321
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500322 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200323}
324
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325void mbedtls_des3_init( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200326{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327 memset( ctx, 0, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200328}
329
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330void mbedtls_des3_free( mbedtls_des3_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200331{
332 if( ctx == NULL )
333 return;
334
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500335 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200336}
337
Paul Bakker1f87fb62011-01-15 17:32:24 +0000338static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
339 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
340 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
341 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
342 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
343 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
344 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
345 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
346 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
347 254 };
348
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000350{
351 int i;
352
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000354 key[i] = odd_parity_table[key[i] / 2];
355}
356
357/*
358 * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
359 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000361{
362 int i;
363
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364 for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200365 if( key[i] != odd_parity_table[key[i] / 2] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000366 return( 1 );
367
368 return( 0 );
369}
370
371/*
372 * Table of weak and semi-weak keys
373 *
374 * Source: http://en.wikipedia.org/wiki/Weak_key
375 *
376 * Weak:
377 * Alternating ones + zeros (0x0101010101010101)
378 * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
379 * '0xE0E0E0E0F1F1F1F1'
380 * '0x1F1F1F1F0E0E0E0E'
381 *
382 * Semi-weak:
383 * 0x011F011F010E010E and 0x1F011F010E010E01
384 * 0x01E001E001F101F1 and 0xE001E001F101F101
385 * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
386 * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
387 * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
388 * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
389 *
390 */
391
392#define WEAK_KEY_COUNT 16
393
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
Paul Bakker1f87fb62011-01-15 17:32:24 +0000395{
396 { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
397 { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
398 { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
399 { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
400
401 { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
402 { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
403 { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
404 { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
405 { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
406 { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
407 { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
408 { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
409 { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
410 { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
411 { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
412 { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
413};
414
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker1f87fb62011-01-15 17:32:24 +0000416{
417 int i;
418
419 for( i = 0; i < WEAK_KEY_COUNT; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
Paul Bakker73206952011-07-06 14:37:33 +0000421 return( 1 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000422
Paul Bakker73206952011-07-06 14:37:33 +0000423 return( 0 );
Paul Bakker1f87fb62011-01-15 17:32:24 +0000424}
425
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200426#if !defined(MBEDTLS_DES_SETKEY_ALT)
427void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000428{
429 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000430 uint32_t X, Y, T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000431
Paul Bakker5c2364c2012-10-01 14:41:15 +0000432 GET_UINT32_BE( X, key, 0 );
433 GET_UINT32_BE( Y, key, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000434
435 /*
436 * Permuted Choice 1
437 */
438 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
439 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
440
441 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
442 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
443 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
444 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
445
446 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
447 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
448 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
449 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
450
451 X &= 0x0FFFFFFF;
452 Y &= 0x0FFFFFFF;
453
454 /*
455 * calculate subkeys
456 */
457 for( i = 0; i < 16; i++ )
458 {
459 if( i < 2 || i == 8 || i == 15 )
460 {
461 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
462 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
463 }
464 else
465 {
466 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
467 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
468 }
469
470 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
471 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
472 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
473 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
474 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
475 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
476 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
477 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
478 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
479 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
480 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
481
482 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
483 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
484 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
485 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
486 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
487 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
488 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
489 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
490 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
491 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
492 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
493 }
494}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200495#endif /* !MBEDTLS_DES_SETKEY_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000496
497/*
498 * DES key schedule (56-bit, encryption)
499 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000501{
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200502 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000503
504 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000505}
506
507/*
508 * DES key schedule (56-bit, decryption)
509 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000511{
512 int i;
513
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200514 mbedtls_des_setkey( ctx->sk, key );
Paul Bakker5121ce52009-01-03 21:22:43 +0000515
516 for( i = 0; i < 16; i += 2 )
517 {
518 SWAP( ctx->sk[i ], ctx->sk[30 - i] );
519 SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
520 }
Paul Bakker8123e9d2011-01-06 15:37:30 +0000521
522 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000523}
524
Paul Bakker5c2364c2012-10-01 14:41:15 +0000525static void des3_set2key( uint32_t esk[96],
526 uint32_t dsk[96],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527 const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000528{
529 int i;
530
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200531 mbedtls_des_setkey( esk, key );
532 mbedtls_des_setkey( dsk + 32, key + 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
534 for( i = 0; i < 32; i += 2 )
535 {
536 dsk[i ] = esk[30 - i];
537 dsk[i + 1] = esk[31 - i];
538
539 esk[i + 32] = dsk[62 - i];
540 esk[i + 33] = dsk[63 - i];
541
542 esk[i + 64] = esk[i ];
543 esk[i + 65] = esk[i + 1];
544
545 dsk[i + 64] = dsk[i ];
546 dsk[i + 65] = dsk[i + 1];
547 }
548}
549
550/*
551 * Triple-DES key schedule (112-bit, encryption)
552 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
554 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000555{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000556 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000557
558 des3_set2key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500559 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000560
561 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000562}
563
564/*
565 * Triple-DES key schedule (112-bit, decryption)
566 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
568 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000569{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000570 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
572 des3_set2key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500573 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000574
575 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000576}
577
Paul Bakker5c2364c2012-10-01 14:41:15 +0000578static void des3_set3key( uint32_t esk[96],
579 uint32_t dsk[96],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000580 const unsigned char key[24] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000581{
582 int i;
583
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200584 mbedtls_des_setkey( esk, key );
585 mbedtls_des_setkey( dsk + 32, key + 8 );
586 mbedtls_des_setkey( esk + 64, key + 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
588 for( i = 0; i < 32; i += 2 )
589 {
590 dsk[i ] = esk[94 - i];
591 dsk[i + 1] = esk[95 - i];
592
593 esk[i + 32] = dsk[62 - i];
594 esk[i + 33] = dsk[63 - i];
595
596 dsk[i + 64] = esk[30 - i];
597 dsk[i + 65] = esk[31 - i];
598 }
599}
600
601/*
602 * Triple-DES key schedule (168-bit, encryption)
603 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
605 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000606{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000607 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000608
609 des3_set3key( ctx->sk, sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500610 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000611
612 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000613}
614
615/*
616 * Triple-DES key schedule (168-bit, decryption)
617 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
619 const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000620{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000621 uint32_t sk[96];
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
623 des3_set3key( sk, ctx->sk, key );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500624 mbedtls_platform_zeroize( sk, sizeof( sk ) );
Paul Bakker8123e9d2011-01-06 15:37:30 +0000625
626 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000627}
628
629/*
630 * DES-ECB block encryption/decryption
631 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200632#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000634 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 unsigned char output[8] )
636{
637 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000638 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000639
640 SK = ctx->sk;
641
Paul Bakker5c2364c2012-10-01 14:41:15 +0000642 GET_UINT32_BE( X, input, 0 );
643 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
645 DES_IP( X, Y );
646
647 for( i = 0; i < 8; i++ )
648 {
649 DES_ROUND( Y, X );
650 DES_ROUND( X, Y );
651 }
652
653 DES_FP( Y, X );
654
Paul Bakker5c2364c2012-10-01 14:41:15 +0000655 PUT_UINT32_BE( Y, output, 0 );
656 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000657
658 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000659}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200660#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000663/*
664 * DES-CBC buffer encryption/decryption
665 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200666int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000668 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000669 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000670 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000671 unsigned char *output )
672{
673 int i;
674 unsigned char temp[8];
675
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000676 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200677 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000678
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000680 {
681 while( length > 0 )
682 {
683 for( i = 0; i < 8; i++ )
684 output[i] = (unsigned char)( input[i] ^ iv[i] );
685
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200686 mbedtls_des_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000687 memcpy( iv, output, 8 );
688
689 input += 8;
690 output += 8;
691 length -= 8;
692 }
693 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000695 {
696 while( length > 0 )
697 {
698 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200699 mbedtls_des_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
701 for( i = 0; i < 8; i++ )
702 output[i] = (unsigned char)( output[i] ^ iv[i] );
703
704 memcpy( iv, temp, 8 );
705
706 input += 8;
707 output += 8;
708 length -= 8;
709 }
710 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000711
712 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000713}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
716/*
717 * 3DES-ECB block encryption/decryption
718 */
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200719#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200720int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000721 const unsigned char input[8],
Paul Bakker5121ce52009-01-03 21:22:43 +0000722 unsigned char output[8] )
723{
724 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000725 uint32_t X, Y, T, *SK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000726
727 SK = ctx->sk;
728
Paul Bakker5c2364c2012-10-01 14:41:15 +0000729 GET_UINT32_BE( X, input, 0 );
730 GET_UINT32_BE( Y, input, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000731
732 DES_IP( X, Y );
733
734 for( i = 0; i < 8; i++ )
735 {
736 DES_ROUND( Y, X );
737 DES_ROUND( X, Y );
738 }
739
740 for( i = 0; i < 8; i++ )
741 {
742 DES_ROUND( X, Y );
743 DES_ROUND( Y, X );
744 }
745
746 for( i = 0; i < 8; i++ )
747 {
748 DES_ROUND( Y, X );
749 DES_ROUND( X, Y );
750 }
751
752 DES_FP( Y, X );
753
Paul Bakker5c2364c2012-10-01 14:41:15 +0000754 PUT_UINT32_BE( Y, output, 0 );
755 PUT_UINT32_BE( X, output, 4 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000756
757 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000758}
Manuel Pégourié-Gonnard70a50102015-05-12 15:02:45 +0200759#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000760
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000762/*
763 * 3DES-CBC buffer encryption/decryption
764 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200765int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000766 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +0000767 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +0000768 unsigned char iv[8],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000769 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000770 unsigned char *output )
771{
772 int i;
773 unsigned char temp[8];
774
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000775 if( length % 8 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200776 return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000777
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200778 if( mode == MBEDTLS_DES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +0000779 {
780 while( length > 0 )
781 {
782 for( i = 0; i < 8; i++ )
783 output[i] = (unsigned char)( input[i] ^ iv[i] );
784
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785 mbedtls_des3_crypt_ecb( ctx, output, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000786 memcpy( iv, output, 8 );
787
788 input += 8;
789 output += 8;
790 length -= 8;
791 }
792 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200793 else /* MBEDTLS_DES_DECRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000794 {
795 while( length > 0 )
796 {
797 memcpy( temp, input, 8 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798 mbedtls_des3_crypt_ecb( ctx, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +0000799
800 for( i = 0; i < 8; i++ )
801 output[i] = (unsigned char)( output[i] ^ iv[i] );
802
803 memcpy( iv, temp, 8 );
804
805 input += 8;
806 output += 8;
807 length -= 8;
808 }
809 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000810
811 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000812}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000814
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815#endif /* !MBEDTLS_DES_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200816
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200817#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000818/*
819 * DES and 3DES test vectors from:
820 *
821 * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
822 */
823static const unsigned char des3_test_keys[24] =
824{
825 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
826 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
827 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
828};
829
Paul Bakker5121ce52009-01-03 21:22:43 +0000830static const unsigned char des3_test_buf[8] =
831{
832 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
833};
834
835static const unsigned char des3_test_ecb_dec[3][8] =
836{
837 { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
838 { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
839 { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
840};
841
842static const unsigned char des3_test_ecb_enc[3][8] =
843{
844 { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
845 { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
846 { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
847};
848
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard29dcc0b2014-03-10 11:32:07 +0100850static const unsigned char des3_test_iv[8] =
851{
852 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
853};
854
Paul Bakker5121ce52009-01-03 21:22:43 +0000855static const unsigned char des3_test_cbc_dec[3][8] =
856{
857 { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
858 { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
859 { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
860};
861
862static const unsigned char des3_test_cbc_enc[3][8] =
863{
864 { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
865 { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
866 { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
867};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000869
870/*
871 * Checkup routine
872 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873int mbedtls_des_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000874{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200875 int i, j, u, v, ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200876 mbedtls_des_context ctx;
877 mbedtls_des3_context ctx3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000878 unsigned char buf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000880 unsigned char prv[8];
881 unsigned char iv[8];
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +0200882#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000883
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200884 mbedtls_des_init( &ctx );
885 mbedtls_des3_init( &ctx3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000886 /*
887 * ECB mode
888 */
889 for( i = 0; i < 6; i++ )
890 {
891 u = i >> 1;
892 v = i & 1;
893
894 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895 mbedtls_printf( " DES%c-ECB-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100896 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000898
899 memcpy( buf, des3_test_buf, 8 );
900
901 switch( i )
902 {
903 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000905 break;
906
907 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000909 break;
910
911 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200912 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000913 break;
914
915 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000917 break;
918
919 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200920 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000921 break;
922
923 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000925 break;
926
927 default:
928 return( 1 );
929 }
930
931 for( j = 0; j < 10000; j++ )
932 {
933 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934 mbedtls_des_crypt_ecb( &ctx, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000935 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936 mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000937 }
938
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000940 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +0000942 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
943 {
944 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200945 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200947 ret = 1;
948 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 }
950
951 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 }
954
955 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000957
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 /*
960 * CBC mode
961 */
962 for( i = 0; i < 6; i++ )
963 {
964 u = i >> 1;
965 v = i & 1;
966
967 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200968 mbedtls_printf( " DES%c-CBC-%3d (%s): ",
Paul Bakker7dc4c442014-02-01 22:50:26 +0100969 ( u == 0 ) ? ' ' : '3', 56 + u * 56,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200970 ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000971
972 memcpy( iv, des3_test_iv, 8 );
973 memcpy( prv, des3_test_iv, 8 );
974 memcpy( buf, des3_test_buf, 8 );
975
976 switch( i )
977 {
978 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979 mbedtls_des_setkey_dec( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000980 break;
981
982 case 1:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 mbedtls_des_setkey_enc( &ctx, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000984 break;
985
986 case 2:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200987 mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000988 break;
989
990 case 3:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200991 mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000992 break;
993
994 case 4:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +0000996 break;
997
998 case 5:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999 mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
Paul Bakker5121ce52009-01-03 21:22:43 +00001000 break;
1001
1002 default:
1003 return( 1 );
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 {
1008 for( j = 0; j < 10000; j++ )
1009 {
1010 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001011 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001012 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001013 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001014 }
1015 }
1016 else
1017 {
1018 for( j = 0; j < 10000; j++ )
1019 {
1020 unsigned char tmp[8];
1021
1022 if( u == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001023 mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001024 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001025 mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001026
1027 memcpy( tmp, prv, 8 );
1028 memcpy( prv, buf, 8 );
1029 memcpy( buf, tmp, 8 );
1030 }
1031
1032 memcpy( buf, prv, 8 );
1033 }
1034
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035 if( ( v == MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001036 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001037 ( v != MBEDTLS_DES_DECRYPT &&
Paul Bakker5121ce52009-01-03 21:22:43 +00001038 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1039 {
1040 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001041 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001042
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001043 ret = 1;
1044 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001045 }
1046
1047 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001048 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001049 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001050#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
1052 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001054
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001055exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056 mbedtls_des_free( &ctx );
1057 mbedtls_des3_free( &ctx3 );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001058
1059 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001060}
1061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001063
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064#endif /* MBEDTLS_DES_C */