xref: /reactos/dll/3rdparty/mbedtls/des.c (revision cbda039f)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  *  FIPS-46-3 compliant Triple-DES implementation
3c2c66affSColin Finck  *
4218e2596SThomas Faber  *  Copyright The Mbed TLS Contributors
5e57126f5SThomas Faber  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6e57126f5SThomas Faber  *
7e57126f5SThomas Faber  *  This file is provided under the Apache License 2.0, or the
8e57126f5SThomas Faber  *  GNU General Public License v2.0 or later.
9e57126f5SThomas Faber  *
10e57126f5SThomas Faber  *  **********
11e57126f5SThomas Faber  *  Apache License 2.0:
12e57126f5SThomas Faber  *
13e57126f5SThomas Faber  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
14e57126f5SThomas Faber  *  not use this file except in compliance with the License.
15e57126f5SThomas Faber  *  You may obtain a copy of the License at
16e57126f5SThomas Faber  *
17e57126f5SThomas Faber  *  http://www.apache.org/licenses/LICENSE-2.0
18e57126f5SThomas Faber  *
19e57126f5SThomas Faber  *  Unless required by applicable law or agreed to in writing, software
20e57126f5SThomas Faber  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21e57126f5SThomas Faber  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22e57126f5SThomas Faber  *  See the License for the specific language governing permissions and
23e57126f5SThomas Faber  *  limitations under the License.
24e57126f5SThomas Faber  *
25e57126f5SThomas Faber  *  **********
26e57126f5SThomas Faber  *
27e57126f5SThomas Faber  *  **********
28e57126f5SThomas Faber  *  GNU General Public License v2.0 or later:
29c2c66affSColin Finck  *
30c2c66affSColin Finck  *  This program is free software; you can redistribute it and/or modify
31c2c66affSColin Finck  *  it under the terms of the GNU General Public License as published by
32c2c66affSColin Finck  *  the Free Software Foundation; either version 2 of the License, or
33c2c66affSColin Finck  *  (at your option) any later version.
34c2c66affSColin Finck  *
35c2c66affSColin Finck  *  This program is distributed in the hope that it will be useful,
36c2c66affSColin Finck  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
37c2c66affSColin Finck  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38c2c66affSColin Finck  *  GNU General Public License for more details.
39c2c66affSColin Finck  *
40c2c66affSColin Finck  *  You should have received a copy of the GNU General Public License along
41c2c66affSColin Finck  *  with this program; if not, write to the Free Software Foundation, Inc.,
42c2c66affSColin Finck  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43c2c66affSColin Finck  *
44e57126f5SThomas Faber  *  **********
45c2c66affSColin Finck  */
46c2c66affSColin Finck /*
47c2c66affSColin Finck  *  DES, on which TDES is based, was originally designed by Horst Feistel
48c2c66affSColin Finck  *  at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
49c2c66affSColin Finck  *
50c2c66affSColin Finck  *  http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
51c2c66affSColin Finck  */
52c2c66affSColin Finck 
53c2c66affSColin Finck #if !defined(MBEDTLS_CONFIG_FILE)
54c2c66affSColin Finck #include "mbedtls/config.h"
55c2c66affSColin Finck #else
56c2c66affSColin Finck #include MBEDTLS_CONFIG_FILE
57c2c66affSColin Finck #endif
58c2c66affSColin Finck 
59c2c66affSColin Finck #if defined(MBEDTLS_DES_C)
60c2c66affSColin Finck 
61c2c66affSColin Finck #include "mbedtls/des.h"
62*cbda039fSThomas Faber #include "mbedtls/platform_util.h"
63c2c66affSColin Finck 
64c2c66affSColin Finck #include <string.h>
65c2c66affSColin Finck 
66c2c66affSColin Finck #if defined(MBEDTLS_SELF_TEST)
67c2c66affSColin Finck #if defined(MBEDTLS_PLATFORM_C)
68c2c66affSColin Finck #include "mbedtls/platform.h"
69c2c66affSColin Finck #else
70c2c66affSColin Finck #include <stdio.h>
71c2c66affSColin Finck #define mbedtls_printf printf
72c2c66affSColin Finck #endif /* MBEDTLS_PLATFORM_C */
73c2c66affSColin Finck #endif /* MBEDTLS_SELF_TEST */
74c2c66affSColin Finck 
75c2c66affSColin Finck #if !defined(MBEDTLS_DES_ALT)
76c2c66affSColin Finck 
77c2c66affSColin Finck /*
78c2c66affSColin Finck  * 32-bit integer manipulation macros (big endian)
79c2c66affSColin Finck  */
80c2c66affSColin Finck #ifndef GET_UINT32_BE
81c2c66affSColin Finck #define GET_UINT32_BE(n,b,i)                            \
82c2c66affSColin Finck {                                                       \
83c2c66affSColin Finck     (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
84c2c66affSColin Finck         | ( (uint32_t) (b)[(i) + 1] << 16 )             \
85c2c66affSColin Finck         | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
86c2c66affSColin Finck         | ( (uint32_t) (b)[(i) + 3]       );            \
87c2c66affSColin Finck }
88c2c66affSColin Finck #endif
89c2c66affSColin Finck 
90c2c66affSColin Finck #ifndef PUT_UINT32_BE
91c2c66affSColin Finck #define PUT_UINT32_BE(n,b,i)                            \
92c2c66affSColin Finck {                                                       \
93c2c66affSColin Finck     (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
94c2c66affSColin Finck     (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
95c2c66affSColin Finck     (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
96c2c66affSColin Finck     (b)[(i) + 3] = (unsigned char) ( (n)       );       \
97c2c66affSColin Finck }
98c2c66affSColin Finck #endif
99c2c66affSColin Finck 
100c2c66affSColin Finck /*
101c2c66affSColin Finck  * Expanded DES S-boxes
102c2c66affSColin Finck  */
103c2c66affSColin Finck static const uint32_t SB1[64] =
104c2c66affSColin Finck {
105c2c66affSColin Finck     0x01010400, 0x00000000, 0x00010000, 0x01010404,
106c2c66affSColin Finck     0x01010004, 0x00010404, 0x00000004, 0x00010000,
107c2c66affSColin Finck     0x00000400, 0x01010400, 0x01010404, 0x00000400,
108c2c66affSColin Finck     0x01000404, 0x01010004, 0x01000000, 0x00000004,
109c2c66affSColin Finck     0x00000404, 0x01000400, 0x01000400, 0x00010400,
110c2c66affSColin Finck     0x00010400, 0x01010000, 0x01010000, 0x01000404,
111c2c66affSColin Finck     0x00010004, 0x01000004, 0x01000004, 0x00010004,
112c2c66affSColin Finck     0x00000000, 0x00000404, 0x00010404, 0x01000000,
113c2c66affSColin Finck     0x00010000, 0x01010404, 0x00000004, 0x01010000,
114c2c66affSColin Finck     0x01010400, 0x01000000, 0x01000000, 0x00000400,
115c2c66affSColin Finck     0x01010004, 0x00010000, 0x00010400, 0x01000004,
116c2c66affSColin Finck     0x00000400, 0x00000004, 0x01000404, 0x00010404,
117c2c66affSColin Finck     0x01010404, 0x00010004, 0x01010000, 0x01000404,
118c2c66affSColin Finck     0x01000004, 0x00000404, 0x00010404, 0x01010400,
119c2c66affSColin Finck     0x00000404, 0x01000400, 0x01000400, 0x00000000,
120c2c66affSColin Finck     0x00010004, 0x00010400, 0x00000000, 0x01010004
121c2c66affSColin Finck };
122c2c66affSColin Finck 
123c2c66affSColin Finck static const uint32_t SB2[64] =
124c2c66affSColin Finck {
125c2c66affSColin Finck     0x80108020, 0x80008000, 0x00008000, 0x00108020,
126c2c66affSColin Finck     0x00100000, 0x00000020, 0x80100020, 0x80008020,
127c2c66affSColin Finck     0x80000020, 0x80108020, 0x80108000, 0x80000000,
128c2c66affSColin Finck     0x80008000, 0x00100000, 0x00000020, 0x80100020,
129c2c66affSColin Finck     0x00108000, 0x00100020, 0x80008020, 0x00000000,
130c2c66affSColin Finck     0x80000000, 0x00008000, 0x00108020, 0x80100000,
131c2c66affSColin Finck     0x00100020, 0x80000020, 0x00000000, 0x00108000,
132c2c66affSColin Finck     0x00008020, 0x80108000, 0x80100000, 0x00008020,
133c2c66affSColin Finck     0x00000000, 0x00108020, 0x80100020, 0x00100000,
134c2c66affSColin Finck     0x80008020, 0x80100000, 0x80108000, 0x00008000,
135c2c66affSColin Finck     0x80100000, 0x80008000, 0x00000020, 0x80108020,
136c2c66affSColin Finck     0x00108020, 0x00000020, 0x00008000, 0x80000000,
137c2c66affSColin Finck     0x00008020, 0x80108000, 0x00100000, 0x80000020,
138c2c66affSColin Finck     0x00100020, 0x80008020, 0x80000020, 0x00100020,
139c2c66affSColin Finck     0x00108000, 0x00000000, 0x80008000, 0x00008020,
140c2c66affSColin Finck     0x80000000, 0x80100020, 0x80108020, 0x00108000
141c2c66affSColin Finck };
142c2c66affSColin Finck 
143c2c66affSColin Finck static const uint32_t SB3[64] =
144c2c66affSColin Finck {
145c2c66affSColin Finck     0x00000208, 0x08020200, 0x00000000, 0x08020008,
146c2c66affSColin Finck     0x08000200, 0x00000000, 0x00020208, 0x08000200,
147c2c66affSColin Finck     0x00020008, 0x08000008, 0x08000008, 0x00020000,
148c2c66affSColin Finck     0x08020208, 0x00020008, 0x08020000, 0x00000208,
149c2c66affSColin Finck     0x08000000, 0x00000008, 0x08020200, 0x00000200,
150c2c66affSColin Finck     0x00020200, 0x08020000, 0x08020008, 0x00020208,
151c2c66affSColin Finck     0x08000208, 0x00020200, 0x00020000, 0x08000208,
152c2c66affSColin Finck     0x00000008, 0x08020208, 0x00000200, 0x08000000,
153c2c66affSColin Finck     0x08020200, 0x08000000, 0x00020008, 0x00000208,
154c2c66affSColin Finck     0x00020000, 0x08020200, 0x08000200, 0x00000000,
155c2c66affSColin Finck     0x00000200, 0x00020008, 0x08020208, 0x08000200,
156c2c66affSColin Finck     0x08000008, 0x00000200, 0x00000000, 0x08020008,
157c2c66affSColin Finck     0x08000208, 0x00020000, 0x08000000, 0x08020208,
158c2c66affSColin Finck     0x00000008, 0x00020208, 0x00020200, 0x08000008,
159c2c66affSColin Finck     0x08020000, 0x08000208, 0x00000208, 0x08020000,
160c2c66affSColin Finck     0x00020208, 0x00000008, 0x08020008, 0x00020200
161c2c66affSColin Finck };
162c2c66affSColin Finck 
163c2c66affSColin Finck static const uint32_t SB4[64] =
164c2c66affSColin Finck {
165c2c66affSColin Finck     0x00802001, 0x00002081, 0x00002081, 0x00000080,
166c2c66affSColin Finck     0x00802080, 0x00800081, 0x00800001, 0x00002001,
167c2c66affSColin Finck     0x00000000, 0x00802000, 0x00802000, 0x00802081,
168c2c66affSColin Finck     0x00000081, 0x00000000, 0x00800080, 0x00800001,
169c2c66affSColin Finck     0x00000001, 0x00002000, 0x00800000, 0x00802001,
170c2c66affSColin Finck     0x00000080, 0x00800000, 0x00002001, 0x00002080,
171c2c66affSColin Finck     0x00800081, 0x00000001, 0x00002080, 0x00800080,
172c2c66affSColin Finck     0x00002000, 0x00802080, 0x00802081, 0x00000081,
173c2c66affSColin Finck     0x00800080, 0x00800001, 0x00802000, 0x00802081,
174c2c66affSColin Finck     0x00000081, 0x00000000, 0x00000000, 0x00802000,
175c2c66affSColin Finck     0x00002080, 0x00800080, 0x00800081, 0x00000001,
176c2c66affSColin Finck     0x00802001, 0x00002081, 0x00002081, 0x00000080,
177c2c66affSColin Finck     0x00802081, 0x00000081, 0x00000001, 0x00002000,
178c2c66affSColin Finck     0x00800001, 0x00002001, 0x00802080, 0x00800081,
179c2c66affSColin Finck     0x00002001, 0x00002080, 0x00800000, 0x00802001,
180c2c66affSColin Finck     0x00000080, 0x00800000, 0x00002000, 0x00802080
181c2c66affSColin Finck };
182c2c66affSColin Finck 
183c2c66affSColin Finck static const uint32_t SB5[64] =
184c2c66affSColin Finck {
185c2c66affSColin Finck     0x00000100, 0x02080100, 0x02080000, 0x42000100,
186c2c66affSColin Finck     0x00080000, 0x00000100, 0x40000000, 0x02080000,
187c2c66affSColin Finck     0x40080100, 0x00080000, 0x02000100, 0x40080100,
188c2c66affSColin Finck     0x42000100, 0x42080000, 0x00080100, 0x40000000,
189c2c66affSColin Finck     0x02000000, 0x40080000, 0x40080000, 0x00000000,
190c2c66affSColin Finck     0x40000100, 0x42080100, 0x42080100, 0x02000100,
191c2c66affSColin Finck     0x42080000, 0x40000100, 0x00000000, 0x42000000,
192c2c66affSColin Finck     0x02080100, 0x02000000, 0x42000000, 0x00080100,
193c2c66affSColin Finck     0x00080000, 0x42000100, 0x00000100, 0x02000000,
194c2c66affSColin Finck     0x40000000, 0x02080000, 0x42000100, 0x40080100,
195c2c66affSColin Finck     0x02000100, 0x40000000, 0x42080000, 0x02080100,
196c2c66affSColin Finck     0x40080100, 0x00000100, 0x02000000, 0x42080000,
197c2c66affSColin Finck     0x42080100, 0x00080100, 0x42000000, 0x42080100,
198c2c66affSColin Finck     0x02080000, 0x00000000, 0x40080000, 0x42000000,
199c2c66affSColin Finck     0x00080100, 0x02000100, 0x40000100, 0x00080000,
200c2c66affSColin Finck     0x00000000, 0x40080000, 0x02080100, 0x40000100
201c2c66affSColin Finck };
202c2c66affSColin Finck 
203c2c66affSColin Finck static const uint32_t SB6[64] =
204c2c66affSColin Finck {
205c2c66affSColin Finck     0x20000010, 0x20400000, 0x00004000, 0x20404010,
206c2c66affSColin Finck     0x20400000, 0x00000010, 0x20404010, 0x00400000,
207c2c66affSColin Finck     0x20004000, 0x00404010, 0x00400000, 0x20000010,
208c2c66affSColin Finck     0x00400010, 0x20004000, 0x20000000, 0x00004010,
209c2c66affSColin Finck     0x00000000, 0x00400010, 0x20004010, 0x00004000,
210c2c66affSColin Finck     0x00404000, 0x20004010, 0x00000010, 0x20400010,
211c2c66affSColin Finck     0x20400010, 0x00000000, 0x00404010, 0x20404000,
212c2c66affSColin Finck     0x00004010, 0x00404000, 0x20404000, 0x20000000,
213c2c66affSColin Finck     0x20004000, 0x00000010, 0x20400010, 0x00404000,
214c2c66affSColin Finck     0x20404010, 0x00400000, 0x00004010, 0x20000010,
215c2c66affSColin Finck     0x00400000, 0x20004000, 0x20000000, 0x00004010,
216c2c66affSColin Finck     0x20000010, 0x20404010, 0x00404000, 0x20400000,
217c2c66affSColin Finck     0x00404010, 0x20404000, 0x00000000, 0x20400010,
218c2c66affSColin Finck     0x00000010, 0x00004000, 0x20400000, 0x00404010,
219c2c66affSColin Finck     0x00004000, 0x00400010, 0x20004010, 0x00000000,
220c2c66affSColin Finck     0x20404000, 0x20000000, 0x00400010, 0x20004010
221c2c66affSColin Finck };
222c2c66affSColin Finck 
223c2c66affSColin Finck static const uint32_t SB7[64] =
224c2c66affSColin Finck {
225c2c66affSColin Finck     0x00200000, 0x04200002, 0x04000802, 0x00000000,
226c2c66affSColin Finck     0x00000800, 0x04000802, 0x00200802, 0x04200800,
227c2c66affSColin Finck     0x04200802, 0x00200000, 0x00000000, 0x04000002,
228c2c66affSColin Finck     0x00000002, 0x04000000, 0x04200002, 0x00000802,
229c2c66affSColin Finck     0x04000800, 0x00200802, 0x00200002, 0x04000800,
230c2c66affSColin Finck     0x04000002, 0x04200000, 0x04200800, 0x00200002,
231c2c66affSColin Finck     0x04200000, 0x00000800, 0x00000802, 0x04200802,
232c2c66affSColin Finck     0x00200800, 0x00000002, 0x04000000, 0x00200800,
233c2c66affSColin Finck     0x04000000, 0x00200800, 0x00200000, 0x04000802,
234c2c66affSColin Finck     0x04000802, 0x04200002, 0x04200002, 0x00000002,
235c2c66affSColin Finck     0x00200002, 0x04000000, 0x04000800, 0x00200000,
236c2c66affSColin Finck     0x04200800, 0x00000802, 0x00200802, 0x04200800,
237c2c66affSColin Finck     0x00000802, 0x04000002, 0x04200802, 0x04200000,
238c2c66affSColin Finck     0x00200800, 0x00000000, 0x00000002, 0x04200802,
239c2c66affSColin Finck     0x00000000, 0x00200802, 0x04200000, 0x00000800,
240c2c66affSColin Finck     0x04000002, 0x04000800, 0x00000800, 0x00200002
241c2c66affSColin Finck };
242c2c66affSColin Finck 
243c2c66affSColin Finck static const uint32_t SB8[64] =
244c2c66affSColin Finck {
245c2c66affSColin Finck     0x10001040, 0x00001000, 0x00040000, 0x10041040,
246c2c66affSColin Finck     0x10000000, 0x10001040, 0x00000040, 0x10000000,
247c2c66affSColin Finck     0x00040040, 0x10040000, 0x10041040, 0x00041000,
248c2c66affSColin Finck     0x10041000, 0x00041040, 0x00001000, 0x00000040,
249c2c66affSColin Finck     0x10040000, 0x10000040, 0x10001000, 0x00001040,
250c2c66affSColin Finck     0x00041000, 0x00040040, 0x10040040, 0x10041000,
251c2c66affSColin Finck     0x00001040, 0x00000000, 0x00000000, 0x10040040,
252c2c66affSColin Finck     0x10000040, 0x10001000, 0x00041040, 0x00040000,
253c2c66affSColin Finck     0x00041040, 0x00040000, 0x10041000, 0x00001000,
254c2c66affSColin Finck     0x00000040, 0x10040040, 0x00001000, 0x00041040,
255c2c66affSColin Finck     0x10001000, 0x00000040, 0x10000040, 0x10040000,
256c2c66affSColin Finck     0x10040040, 0x10000000, 0x00040000, 0x10001040,
257c2c66affSColin Finck     0x00000000, 0x10041040, 0x00040040, 0x10000040,
258c2c66affSColin Finck     0x10040000, 0x10001000, 0x10001040, 0x00000000,
259c2c66affSColin Finck     0x10041040, 0x00041000, 0x00041000, 0x00001040,
260c2c66affSColin Finck     0x00001040, 0x00040040, 0x10000000, 0x10041000
261c2c66affSColin Finck };
262c2c66affSColin Finck 
263c2c66affSColin Finck /*
264c2c66affSColin Finck  * PC1: left and right halves bit-swap
265c2c66affSColin Finck  */
266c2c66affSColin Finck static const uint32_t LHs[16] =
267c2c66affSColin Finck {
268c2c66affSColin Finck     0x00000000, 0x00000001, 0x00000100, 0x00000101,
269c2c66affSColin Finck     0x00010000, 0x00010001, 0x00010100, 0x00010101,
270c2c66affSColin Finck     0x01000000, 0x01000001, 0x01000100, 0x01000101,
271c2c66affSColin Finck     0x01010000, 0x01010001, 0x01010100, 0x01010101
272c2c66affSColin Finck };
273c2c66affSColin Finck 
274c2c66affSColin Finck static const uint32_t RHs[16] =
275c2c66affSColin Finck {
276c2c66affSColin Finck     0x00000000, 0x01000000, 0x00010000, 0x01010000,
277c2c66affSColin Finck     0x00000100, 0x01000100, 0x00010100, 0x01010100,
278c2c66affSColin Finck     0x00000001, 0x01000001, 0x00010001, 0x01010001,
279c2c66affSColin Finck     0x00000101, 0x01000101, 0x00010101, 0x01010101,
280c2c66affSColin Finck };
281c2c66affSColin Finck 
282c2c66affSColin Finck /*
283c2c66affSColin Finck  * Initial Permutation macro
284c2c66affSColin Finck  */
285c2c66affSColin Finck #define DES_IP(X,Y)                                                       \
286*cbda039fSThomas Faber     do                                                                    \
287c2c66affSColin Finck     {                                                                     \
288*cbda039fSThomas Faber         T = (((X) >>  4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T <<  4); \
289*cbda039fSThomas Faber         T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
290*cbda039fSThomas Faber         T = (((Y) >>  2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T <<  2); \
291*cbda039fSThomas Faber         T = (((Y) >>  8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T <<  8); \
292*cbda039fSThomas Faber         (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF;                    \
293*cbda039fSThomas Faber         T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T;                 \
294*cbda039fSThomas Faber         (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF;                    \
295*cbda039fSThomas Faber     } while( 0 )
296c2c66affSColin Finck 
297c2c66affSColin Finck /*
298c2c66affSColin Finck  * Final Permutation macro
299c2c66affSColin Finck  */
300c2c66affSColin Finck #define DES_FP(X,Y)                                                       \
301*cbda039fSThomas Faber     do                                                                    \
302c2c66affSColin Finck     {                                                                     \
303*cbda039fSThomas Faber         (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF;                    \
304*cbda039fSThomas Faber         T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T;                 \
305*cbda039fSThomas Faber         (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF;                    \
306*cbda039fSThomas Faber         T = (((Y) >>  8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T <<  8); \
307*cbda039fSThomas Faber         T = (((Y) >>  2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T <<  2); \
308*cbda039fSThomas Faber         T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \
309*cbda039fSThomas Faber         T = (((X) >>  4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T <<  4); \
310*cbda039fSThomas Faber     } while( 0 )
311c2c66affSColin Finck 
312c2c66affSColin Finck /*
313c2c66affSColin Finck  * DES round macro
314c2c66affSColin Finck  */
315c2c66affSColin Finck #define DES_ROUND(X,Y)                              \
316*cbda039fSThomas Faber     do                                              \
317c2c66affSColin Finck     {                                               \
318*cbda039fSThomas Faber         T = *SK++ ^ (X);                            \
319*cbda039fSThomas Faber         (Y) ^= SB8[ (T      ) & 0x3F ] ^            \
320c2c66affSColin Finck                SB6[ (T >>  8) & 0x3F ] ^            \
321c2c66affSColin Finck                SB4[ (T >> 16) & 0x3F ] ^            \
322c2c66affSColin Finck                SB2[ (T >> 24) & 0x3F ];             \
323c2c66affSColin Finck                                                     \
324*cbda039fSThomas Faber         T = *SK++ ^ (((X) << 28) | ((X) >> 4));     \
325*cbda039fSThomas Faber         (Y) ^= SB7[ (T      ) & 0x3F ] ^            \
326c2c66affSColin Finck                SB5[ (T >>  8) & 0x3F ] ^            \
327c2c66affSColin Finck                SB3[ (T >> 16) & 0x3F ] ^            \
328c2c66affSColin Finck                SB1[ (T >> 24) & 0x3F ];             \
329*cbda039fSThomas Faber     } while( 0 )
330c2c66affSColin Finck 
331*cbda039fSThomas Faber #define SWAP(a,b)                                       \
332*cbda039fSThomas Faber     do                                                  \
333*cbda039fSThomas Faber     {                                                   \
334*cbda039fSThomas Faber         uint32_t t = (a); (a) = (b); (b) = t; t = 0;    \
335*cbda039fSThomas Faber     } while( 0 )
336c2c66affSColin Finck 
mbedtls_des_init(mbedtls_des_context * ctx)337c2c66affSColin Finck void mbedtls_des_init( mbedtls_des_context *ctx )
338c2c66affSColin Finck {
339c2c66affSColin Finck     memset( ctx, 0, sizeof( mbedtls_des_context ) );
340c2c66affSColin Finck }
341c2c66affSColin Finck 
mbedtls_des_free(mbedtls_des_context * ctx)342c2c66affSColin Finck void mbedtls_des_free( mbedtls_des_context *ctx )
343c2c66affSColin Finck {
344c2c66affSColin Finck     if( ctx == NULL )
345c2c66affSColin Finck         return;
346c2c66affSColin Finck 
347*cbda039fSThomas Faber     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
348c2c66affSColin Finck }
349c2c66affSColin Finck 
mbedtls_des3_init(mbedtls_des3_context * ctx)350c2c66affSColin Finck void mbedtls_des3_init( mbedtls_des3_context *ctx )
351c2c66affSColin Finck {
352c2c66affSColin Finck     memset( ctx, 0, sizeof( mbedtls_des3_context ) );
353c2c66affSColin Finck }
354c2c66affSColin Finck 
mbedtls_des3_free(mbedtls_des3_context * ctx)355c2c66affSColin Finck void mbedtls_des3_free( mbedtls_des3_context *ctx )
356c2c66affSColin Finck {
357c2c66affSColin Finck     if( ctx == NULL )
358c2c66affSColin Finck         return;
359c2c66affSColin Finck 
360*cbda039fSThomas Faber     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
361c2c66affSColin Finck }
362c2c66affSColin Finck 
363c2c66affSColin Finck static const unsigned char odd_parity_table[128] = { 1,  2,  4,  7,  8,
364c2c66affSColin Finck         11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
365c2c66affSColin Finck         47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
366c2c66affSColin Finck         82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
367c2c66affSColin Finck         115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
368c2c66affSColin Finck         143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
369c2c66affSColin Finck         171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
370c2c66affSColin Finck         199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
371c2c66affSColin Finck         227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
372c2c66affSColin Finck         254 };
373c2c66affSColin Finck 
mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE])374c2c66affSColin Finck void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
375c2c66affSColin Finck {
376c2c66affSColin Finck     int i;
377c2c66affSColin Finck 
378c2c66affSColin Finck     for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
379c2c66affSColin Finck         key[i] = odd_parity_table[key[i] / 2];
380c2c66affSColin Finck }
381c2c66affSColin Finck 
382c2c66affSColin Finck /*
383c2c66affSColin Finck  * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
384c2c66affSColin Finck  */
mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZE])385c2c66affSColin Finck int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
386c2c66affSColin Finck {
387c2c66affSColin Finck     int i;
388c2c66affSColin Finck 
389c2c66affSColin Finck     for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
390c2c66affSColin Finck         if( key[i] != odd_parity_table[key[i] / 2] )
391c2c66affSColin Finck             return( 1 );
392c2c66affSColin Finck 
393c2c66affSColin Finck     return( 0 );
394c2c66affSColin Finck }
395c2c66affSColin Finck 
396c2c66affSColin Finck /*
397c2c66affSColin Finck  * Table of weak and semi-weak keys
398c2c66affSColin Finck  *
399c2c66affSColin Finck  * Source: http://en.wikipedia.org/wiki/Weak_key
400c2c66affSColin Finck  *
401c2c66affSColin Finck  * Weak:
402c2c66affSColin Finck  * Alternating ones + zeros (0x0101010101010101)
403c2c66affSColin Finck  * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
404c2c66affSColin Finck  * '0xE0E0E0E0F1F1F1F1'
405c2c66affSColin Finck  * '0x1F1F1F1F0E0E0E0E'
406c2c66affSColin Finck  *
407c2c66affSColin Finck  * Semi-weak:
408c2c66affSColin Finck  * 0x011F011F010E010E and 0x1F011F010E010E01
409c2c66affSColin Finck  * 0x01E001E001F101F1 and 0xE001E001F101F101
410c2c66affSColin Finck  * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
411c2c66affSColin Finck  * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
412c2c66affSColin Finck  * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
413c2c66affSColin Finck  * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
414c2c66affSColin Finck  *
415c2c66affSColin Finck  */
416c2c66affSColin Finck 
417c2c66affSColin Finck #define WEAK_KEY_COUNT 16
418c2c66affSColin Finck 
419c2c66affSColin Finck static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
420c2c66affSColin Finck {
421c2c66affSColin Finck     { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
422c2c66affSColin Finck     { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
423c2c66affSColin Finck     { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
424c2c66affSColin Finck     { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
425c2c66affSColin Finck 
426c2c66affSColin Finck     { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
427c2c66affSColin Finck     { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
428c2c66affSColin Finck     { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
429c2c66affSColin Finck     { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
430c2c66affSColin Finck     { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
431c2c66affSColin Finck     { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
432c2c66affSColin Finck     { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
433c2c66affSColin Finck     { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
434c2c66affSColin Finck     { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
435c2c66affSColin Finck     { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
436c2c66affSColin Finck     { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
437c2c66affSColin Finck     { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
438c2c66affSColin Finck };
439c2c66affSColin Finck 
mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE])440c2c66affSColin Finck int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
441c2c66affSColin Finck {
442c2c66affSColin Finck     int i;
443c2c66affSColin Finck 
444c2c66affSColin Finck     for( i = 0; i < WEAK_KEY_COUNT; i++ )
445c2c66affSColin Finck         if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
446c2c66affSColin Finck             return( 1 );
447c2c66affSColin Finck 
448c2c66affSColin Finck     return( 0 );
449c2c66affSColin Finck }
450c2c66affSColin Finck 
451c2c66affSColin Finck #if !defined(MBEDTLS_DES_SETKEY_ALT)
mbedtls_des_setkey(uint32_t SK[32],const unsigned char key[MBEDTLS_DES_KEY_SIZE])452c2c66affSColin Finck void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
453c2c66affSColin Finck {
454c2c66affSColin Finck     int i;
455c2c66affSColin Finck     uint32_t X, Y, T;
456c2c66affSColin Finck 
457c2c66affSColin Finck     GET_UINT32_BE( X, key, 0 );
458c2c66affSColin Finck     GET_UINT32_BE( Y, key, 4 );
459c2c66affSColin Finck 
460c2c66affSColin Finck     /*
461c2c66affSColin Finck      * Permuted Choice 1
462c2c66affSColin Finck      */
463c2c66affSColin Finck     T =  ((Y >>  4) ^ X) & 0x0F0F0F0F;  X ^= T; Y ^= (T <<  4);
464c2c66affSColin Finck     T =  ((Y      ) ^ X) & 0x10101010;  X ^= T; Y ^= (T      );
465c2c66affSColin Finck 
466c2c66affSColin Finck     X =   (LHs[ (X      ) & 0xF] << 3) | (LHs[ (X >>  8) & 0xF ] << 2)
467c2c66affSColin Finck         | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ]     )
468c2c66affSColin Finck         | (LHs[ (X >>  5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
469c2c66affSColin Finck         | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
470c2c66affSColin Finck 
471c2c66affSColin Finck     Y =   (RHs[ (Y >>  1) & 0xF] << 3) | (RHs[ (Y >>  9) & 0xF ] << 2)
472c2c66affSColin Finck         | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ]     )
473c2c66affSColin Finck         | (RHs[ (Y >>  4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
474c2c66affSColin Finck         | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
475c2c66affSColin Finck 
476c2c66affSColin Finck     X &= 0x0FFFFFFF;
477c2c66affSColin Finck     Y &= 0x0FFFFFFF;
478c2c66affSColin Finck 
479c2c66affSColin Finck     /*
480c2c66affSColin Finck      * calculate subkeys
481c2c66affSColin Finck      */
482c2c66affSColin Finck     for( i = 0; i < 16; i++ )
483c2c66affSColin Finck     {
484c2c66affSColin Finck         if( i < 2 || i == 8 || i == 15 )
485c2c66affSColin Finck         {
486c2c66affSColin Finck             X = ((X <<  1) | (X >> 27)) & 0x0FFFFFFF;
487c2c66affSColin Finck             Y = ((Y <<  1) | (Y >> 27)) & 0x0FFFFFFF;
488c2c66affSColin Finck         }
489c2c66affSColin Finck         else
490c2c66affSColin Finck         {
491c2c66affSColin Finck             X = ((X <<  2) | (X >> 26)) & 0x0FFFFFFF;
492c2c66affSColin Finck             Y = ((Y <<  2) | (Y >> 26)) & 0x0FFFFFFF;
493c2c66affSColin Finck         }
494c2c66affSColin Finck 
495c2c66affSColin Finck         *SK++ =   ((X <<  4) & 0x24000000) | ((X << 28) & 0x10000000)
496c2c66affSColin Finck                 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
497c2c66affSColin Finck                 | ((X <<  6) & 0x01000000) | ((X <<  9) & 0x00200000)
498c2c66affSColin Finck                 | ((X >>  1) & 0x00100000) | ((X << 10) & 0x00040000)
499c2c66affSColin Finck                 | ((X <<  2) & 0x00020000) | ((X >> 10) & 0x00010000)
500c2c66affSColin Finck                 | ((Y >> 13) & 0x00002000) | ((Y >>  4) & 0x00001000)
501c2c66affSColin Finck                 | ((Y <<  6) & 0x00000800) | ((Y >>  1) & 0x00000400)
502c2c66affSColin Finck                 | ((Y >> 14) & 0x00000200) | ((Y      ) & 0x00000100)
503c2c66affSColin Finck                 | ((Y >>  5) & 0x00000020) | ((Y >> 10) & 0x00000010)
504c2c66affSColin Finck                 | ((Y >>  3) & 0x00000008) | ((Y >> 18) & 0x00000004)
505c2c66affSColin Finck                 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
506c2c66affSColin Finck 
507c2c66affSColin Finck         *SK++ =   ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
508c2c66affSColin Finck                 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
509c2c66affSColin Finck                 | ((X >>  2) & 0x02000000) | ((X <<  1) & 0x01000000)
510c2c66affSColin Finck                 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
511c2c66affSColin Finck                 | ((X <<  3) & 0x00080000) | ((X >>  6) & 0x00040000)
512c2c66affSColin Finck                 | ((X << 15) & 0x00020000) | ((X >>  4) & 0x00010000)
513c2c66affSColin Finck                 | ((Y >>  2) & 0x00002000) | ((Y <<  8) & 0x00001000)
514c2c66affSColin Finck                 | ((Y >> 14) & 0x00000808) | ((Y >>  9) & 0x00000400)
515c2c66affSColin Finck                 | ((Y      ) & 0x00000200) | ((Y <<  7) & 0x00000100)
516c2c66affSColin Finck                 | ((Y >>  7) & 0x00000020) | ((Y >>  3) & 0x00000011)
517c2c66affSColin Finck                 | ((Y <<  2) & 0x00000004) | ((Y >> 21) & 0x00000002);
518c2c66affSColin Finck     }
519c2c66affSColin Finck }
520c2c66affSColin Finck #endif /* !MBEDTLS_DES_SETKEY_ALT */
521c2c66affSColin Finck 
522c2c66affSColin Finck /*
523c2c66affSColin Finck  * DES key schedule (56-bit, encryption)
524c2c66affSColin Finck  */
mbedtls_des_setkey_enc(mbedtls_des_context * ctx,const unsigned char key[MBEDTLS_DES_KEY_SIZE])525c2c66affSColin Finck int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
526c2c66affSColin Finck {
527c2c66affSColin Finck     mbedtls_des_setkey( ctx->sk, key );
528c2c66affSColin Finck 
529c2c66affSColin Finck     return( 0 );
530c2c66affSColin Finck }
531c2c66affSColin Finck 
532c2c66affSColin Finck /*
533c2c66affSColin Finck  * DES key schedule (56-bit, decryption)
534c2c66affSColin Finck  */
mbedtls_des_setkey_dec(mbedtls_des_context * ctx,const unsigned char key[MBEDTLS_DES_KEY_SIZE])535c2c66affSColin Finck int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
536c2c66affSColin Finck {
537c2c66affSColin Finck     int i;
538c2c66affSColin Finck 
539c2c66affSColin Finck     mbedtls_des_setkey( ctx->sk, key );
540c2c66affSColin Finck 
541c2c66affSColin Finck     for( i = 0; i < 16; i += 2 )
542c2c66affSColin Finck     {
543c2c66affSColin Finck         SWAP( ctx->sk[i    ], ctx->sk[30 - i] );
544c2c66affSColin Finck         SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
545c2c66affSColin Finck     }
546c2c66affSColin Finck 
547c2c66affSColin Finck     return( 0 );
548c2c66affSColin Finck }
549c2c66affSColin Finck 
des3_set2key(uint32_t esk[96],uint32_t dsk[96],const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])550c2c66affSColin Finck static void des3_set2key( uint32_t esk[96],
551c2c66affSColin Finck                           uint32_t dsk[96],
552c2c66affSColin Finck                           const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
553c2c66affSColin Finck {
554c2c66affSColin Finck     int i;
555c2c66affSColin Finck 
556c2c66affSColin Finck     mbedtls_des_setkey( esk, key );
557c2c66affSColin Finck     mbedtls_des_setkey( dsk + 32, key + 8 );
558c2c66affSColin Finck 
559c2c66affSColin Finck     for( i = 0; i < 32; i += 2 )
560c2c66affSColin Finck     {
561c2c66affSColin Finck         dsk[i     ] = esk[30 - i];
562c2c66affSColin Finck         dsk[i +  1] = esk[31 - i];
563c2c66affSColin Finck 
564c2c66affSColin Finck         esk[i + 32] = dsk[62 - i];
565c2c66affSColin Finck         esk[i + 33] = dsk[63 - i];
566c2c66affSColin Finck 
567c2c66affSColin Finck         esk[i + 64] = esk[i    ];
568c2c66affSColin Finck         esk[i + 65] = esk[i + 1];
569c2c66affSColin Finck 
570c2c66affSColin Finck         dsk[i + 64] = dsk[i    ];
571c2c66affSColin Finck         dsk[i + 65] = dsk[i + 1];
572c2c66affSColin Finck     }
573c2c66affSColin Finck }
574c2c66affSColin Finck 
575c2c66affSColin Finck /*
576c2c66affSColin Finck  * Triple-DES key schedule (112-bit, encryption)
577c2c66affSColin Finck  */
mbedtls_des3_set2key_enc(mbedtls_des3_context * ctx,const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])578c2c66affSColin Finck int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
579c2c66affSColin Finck                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
580c2c66affSColin Finck {
581c2c66affSColin Finck     uint32_t sk[96];
582c2c66affSColin Finck 
583c2c66affSColin Finck     des3_set2key( ctx->sk, sk, key );
584*cbda039fSThomas Faber     mbedtls_platform_zeroize( sk,  sizeof( sk ) );
585c2c66affSColin Finck 
586c2c66affSColin Finck     return( 0 );
587c2c66affSColin Finck }
588c2c66affSColin Finck 
589c2c66affSColin Finck /*
590c2c66affSColin Finck  * Triple-DES key schedule (112-bit, decryption)
591c2c66affSColin Finck  */
mbedtls_des3_set2key_dec(mbedtls_des3_context * ctx,const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2])592c2c66affSColin Finck int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
593c2c66affSColin Finck                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
594c2c66affSColin Finck {
595c2c66affSColin Finck     uint32_t sk[96];
596c2c66affSColin Finck 
597c2c66affSColin Finck     des3_set2key( sk, ctx->sk, key );
598*cbda039fSThomas Faber     mbedtls_platform_zeroize( sk,  sizeof( sk ) );
599c2c66affSColin Finck 
600c2c66affSColin Finck     return( 0 );
601c2c66affSColin Finck }
602c2c66affSColin Finck 
des3_set3key(uint32_t esk[96],uint32_t dsk[96],const unsigned char key[24])603c2c66affSColin Finck static void des3_set3key( uint32_t esk[96],
604c2c66affSColin Finck                           uint32_t dsk[96],
605c2c66affSColin Finck                           const unsigned char key[24] )
606c2c66affSColin Finck {
607c2c66affSColin Finck     int i;
608c2c66affSColin Finck 
609c2c66affSColin Finck     mbedtls_des_setkey( esk, key );
610c2c66affSColin Finck     mbedtls_des_setkey( dsk + 32, key +  8 );
611c2c66affSColin Finck     mbedtls_des_setkey( esk + 64, key + 16 );
612c2c66affSColin Finck 
613c2c66affSColin Finck     for( i = 0; i < 32; i += 2 )
614c2c66affSColin Finck     {
615c2c66affSColin Finck         dsk[i     ] = esk[94 - i];
616c2c66affSColin Finck         dsk[i +  1] = esk[95 - i];
617c2c66affSColin Finck 
618c2c66affSColin Finck         esk[i + 32] = dsk[62 - i];
619c2c66affSColin Finck         esk[i + 33] = dsk[63 - i];
620c2c66affSColin Finck 
621c2c66affSColin Finck         dsk[i + 64] = esk[30 - i];
622c2c66affSColin Finck         dsk[i + 65] = esk[31 - i];
623c2c66affSColin Finck     }
624c2c66affSColin Finck }
625c2c66affSColin Finck 
626c2c66affSColin Finck /*
627c2c66affSColin Finck  * Triple-DES key schedule (168-bit, encryption)
628c2c66affSColin Finck  */
mbedtls_des3_set3key_enc(mbedtls_des3_context * ctx,const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])629c2c66affSColin Finck int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
630c2c66affSColin Finck                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
631c2c66affSColin Finck {
632c2c66affSColin Finck     uint32_t sk[96];
633c2c66affSColin Finck 
634c2c66affSColin Finck     des3_set3key( ctx->sk, sk, key );
635*cbda039fSThomas Faber     mbedtls_platform_zeroize( sk,  sizeof( sk ) );
636c2c66affSColin Finck 
637c2c66affSColin Finck     return( 0 );
638c2c66affSColin Finck }
639c2c66affSColin Finck 
640c2c66affSColin Finck /*
641c2c66affSColin Finck  * Triple-DES key schedule (168-bit, decryption)
642c2c66affSColin Finck  */
mbedtls_des3_set3key_dec(mbedtls_des3_context * ctx,const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3])643c2c66affSColin Finck int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
644c2c66affSColin Finck                       const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
645c2c66affSColin Finck {
646c2c66affSColin Finck     uint32_t sk[96];
647c2c66affSColin Finck 
648c2c66affSColin Finck     des3_set3key( sk, ctx->sk, key );
649*cbda039fSThomas Faber     mbedtls_platform_zeroize( sk,  sizeof( sk ) );
650c2c66affSColin Finck 
651c2c66affSColin Finck     return( 0 );
652c2c66affSColin Finck }
653c2c66affSColin Finck 
654c2c66affSColin Finck /*
655c2c66affSColin Finck  * DES-ECB block encryption/decryption
656c2c66affSColin Finck  */
657c2c66affSColin Finck #if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
mbedtls_des_crypt_ecb(mbedtls_des_context * ctx,const unsigned char input[8],unsigned char output[8])658c2c66affSColin Finck int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
659c2c66affSColin Finck                     const unsigned char input[8],
660c2c66affSColin Finck                     unsigned char output[8] )
661c2c66affSColin Finck {
662c2c66affSColin Finck     int i;
663c2c66affSColin Finck     uint32_t X, Y, T, *SK;
664c2c66affSColin Finck 
665c2c66affSColin Finck     SK = ctx->sk;
666c2c66affSColin Finck 
667c2c66affSColin Finck     GET_UINT32_BE( X, input, 0 );
668c2c66affSColin Finck     GET_UINT32_BE( Y, input, 4 );
669c2c66affSColin Finck 
670c2c66affSColin Finck     DES_IP( X, Y );
671c2c66affSColin Finck 
672c2c66affSColin Finck     for( i = 0; i < 8; i++ )
673c2c66affSColin Finck     {
674c2c66affSColin Finck         DES_ROUND( Y, X );
675c2c66affSColin Finck         DES_ROUND( X, Y );
676c2c66affSColin Finck     }
677c2c66affSColin Finck 
678c2c66affSColin Finck     DES_FP( Y, X );
679c2c66affSColin Finck 
680c2c66affSColin Finck     PUT_UINT32_BE( Y, output, 0 );
681c2c66affSColin Finck     PUT_UINT32_BE( X, output, 4 );
682c2c66affSColin Finck 
683c2c66affSColin Finck     return( 0 );
684c2c66affSColin Finck }
685c2c66affSColin Finck #endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
686c2c66affSColin Finck 
687c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CBC)
688c2c66affSColin Finck /*
689c2c66affSColin Finck  * DES-CBC buffer encryption/decryption
690c2c66affSColin Finck  */
mbedtls_des_crypt_cbc(mbedtls_des_context * ctx,int mode,size_t length,unsigned char iv[8],const unsigned char * input,unsigned char * output)691c2c66affSColin Finck int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
692c2c66affSColin Finck                     int mode,
693c2c66affSColin Finck                     size_t length,
694c2c66affSColin Finck                     unsigned char iv[8],
695c2c66affSColin Finck                     const unsigned char *input,
696c2c66affSColin Finck                     unsigned char *output )
697c2c66affSColin Finck {
698c2c66affSColin Finck     int i;
699c2c66affSColin Finck     unsigned char temp[8];
700c2c66affSColin Finck 
701c2c66affSColin Finck     if( length % 8 )
702c2c66affSColin Finck         return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
703c2c66affSColin Finck 
704c2c66affSColin Finck     if( mode == MBEDTLS_DES_ENCRYPT )
705c2c66affSColin Finck     {
706c2c66affSColin Finck         while( length > 0 )
707c2c66affSColin Finck         {
708c2c66affSColin Finck             for( i = 0; i < 8; i++ )
709c2c66affSColin Finck                 output[i] = (unsigned char)( input[i] ^ iv[i] );
710c2c66affSColin Finck 
711c2c66affSColin Finck             mbedtls_des_crypt_ecb( ctx, output, output );
712c2c66affSColin Finck             memcpy( iv, output, 8 );
713c2c66affSColin Finck 
714c2c66affSColin Finck             input  += 8;
715c2c66affSColin Finck             output += 8;
716c2c66affSColin Finck             length -= 8;
717c2c66affSColin Finck         }
718c2c66affSColin Finck     }
719c2c66affSColin Finck     else /* MBEDTLS_DES_DECRYPT */
720c2c66affSColin Finck     {
721c2c66affSColin Finck         while( length > 0 )
722c2c66affSColin Finck         {
723c2c66affSColin Finck             memcpy( temp, input, 8 );
724c2c66affSColin Finck             mbedtls_des_crypt_ecb( ctx, input, output );
725c2c66affSColin Finck 
726c2c66affSColin Finck             for( i = 0; i < 8; i++ )
727c2c66affSColin Finck                 output[i] = (unsigned char)( output[i] ^ iv[i] );
728c2c66affSColin Finck 
729c2c66affSColin Finck             memcpy( iv, temp, 8 );
730c2c66affSColin Finck 
731c2c66affSColin Finck             input  += 8;
732c2c66affSColin Finck             output += 8;
733c2c66affSColin Finck             length -= 8;
734c2c66affSColin Finck         }
735c2c66affSColin Finck     }
736c2c66affSColin Finck 
737c2c66affSColin Finck     return( 0 );
738c2c66affSColin Finck }
739c2c66affSColin Finck #endif /* MBEDTLS_CIPHER_MODE_CBC */
740c2c66affSColin Finck 
741c2c66affSColin Finck /*
742c2c66affSColin Finck  * 3DES-ECB block encryption/decryption
743c2c66affSColin Finck  */
744c2c66affSColin Finck #if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
mbedtls_des3_crypt_ecb(mbedtls_des3_context * ctx,const unsigned char input[8],unsigned char output[8])745c2c66affSColin Finck int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
746c2c66affSColin Finck                      const unsigned char input[8],
747c2c66affSColin Finck                      unsigned char output[8] )
748c2c66affSColin Finck {
749c2c66affSColin Finck     int i;
750c2c66affSColin Finck     uint32_t X, Y, T, *SK;
751c2c66affSColin Finck 
752c2c66affSColin Finck     SK = ctx->sk;
753c2c66affSColin Finck 
754c2c66affSColin Finck     GET_UINT32_BE( X, input, 0 );
755c2c66affSColin Finck     GET_UINT32_BE( Y, input, 4 );
756c2c66affSColin Finck 
757c2c66affSColin Finck     DES_IP( X, Y );
758c2c66affSColin Finck 
759c2c66affSColin Finck     for( i = 0; i < 8; i++ )
760c2c66affSColin Finck     {
761c2c66affSColin Finck         DES_ROUND( Y, X );
762c2c66affSColin Finck         DES_ROUND( X, Y );
763c2c66affSColin Finck     }
764c2c66affSColin Finck 
765c2c66affSColin Finck     for( i = 0; i < 8; i++ )
766c2c66affSColin Finck     {
767c2c66affSColin Finck         DES_ROUND( X, Y );
768c2c66affSColin Finck         DES_ROUND( Y, X );
769c2c66affSColin Finck     }
770c2c66affSColin Finck 
771c2c66affSColin Finck     for( i = 0; i < 8; i++ )
772c2c66affSColin Finck     {
773c2c66affSColin Finck         DES_ROUND( Y, X );
774c2c66affSColin Finck         DES_ROUND( X, Y );
775c2c66affSColin Finck     }
776c2c66affSColin Finck 
777c2c66affSColin Finck     DES_FP( Y, X );
778c2c66affSColin Finck 
779c2c66affSColin Finck     PUT_UINT32_BE( Y, output, 0 );
780c2c66affSColin Finck     PUT_UINT32_BE( X, output, 4 );
781c2c66affSColin Finck 
782c2c66affSColin Finck     return( 0 );
783c2c66affSColin Finck }
784c2c66affSColin Finck #endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
785c2c66affSColin Finck 
786c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CBC)
787c2c66affSColin Finck /*
788c2c66affSColin Finck  * 3DES-CBC buffer encryption/decryption
789c2c66affSColin Finck  */
mbedtls_des3_crypt_cbc(mbedtls_des3_context * ctx,int mode,size_t length,unsigned char iv[8],const unsigned char * input,unsigned char * output)790c2c66affSColin Finck int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
791c2c66affSColin Finck                      int mode,
792c2c66affSColin Finck                      size_t length,
793c2c66affSColin Finck                      unsigned char iv[8],
794c2c66affSColin Finck                      const unsigned char *input,
795c2c66affSColin Finck                      unsigned char *output )
796c2c66affSColin Finck {
797c2c66affSColin Finck     int i;
798c2c66affSColin Finck     unsigned char temp[8];
799c2c66affSColin Finck 
800c2c66affSColin Finck     if( length % 8 )
801c2c66affSColin Finck         return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
802c2c66affSColin Finck 
803c2c66affSColin Finck     if( mode == MBEDTLS_DES_ENCRYPT )
804c2c66affSColin Finck     {
805c2c66affSColin Finck         while( length > 0 )
806c2c66affSColin Finck         {
807c2c66affSColin Finck             for( i = 0; i < 8; i++ )
808c2c66affSColin Finck                 output[i] = (unsigned char)( input[i] ^ iv[i] );
809c2c66affSColin Finck 
810c2c66affSColin Finck             mbedtls_des3_crypt_ecb( ctx, output, output );
811c2c66affSColin Finck             memcpy( iv, output, 8 );
812c2c66affSColin Finck 
813c2c66affSColin Finck             input  += 8;
814c2c66affSColin Finck             output += 8;
815c2c66affSColin Finck             length -= 8;
816c2c66affSColin Finck         }
817c2c66affSColin Finck     }
818c2c66affSColin Finck     else /* MBEDTLS_DES_DECRYPT */
819c2c66affSColin Finck     {
820c2c66affSColin Finck         while( length > 0 )
821c2c66affSColin Finck         {
822c2c66affSColin Finck             memcpy( temp, input, 8 );
823c2c66affSColin Finck             mbedtls_des3_crypt_ecb( ctx, input, output );
824c2c66affSColin Finck 
825c2c66affSColin Finck             for( i = 0; i < 8; i++ )
826c2c66affSColin Finck                 output[i] = (unsigned char)( output[i] ^ iv[i] );
827c2c66affSColin Finck 
828c2c66affSColin Finck             memcpy( iv, temp, 8 );
829c2c66affSColin Finck 
830c2c66affSColin Finck             input  += 8;
831c2c66affSColin Finck             output += 8;
832c2c66affSColin Finck             length -= 8;
833c2c66affSColin Finck         }
834c2c66affSColin Finck     }
835c2c66affSColin Finck 
836c2c66affSColin Finck     return( 0 );
837c2c66affSColin Finck }
838c2c66affSColin Finck #endif /* MBEDTLS_CIPHER_MODE_CBC */
839c2c66affSColin Finck 
840c2c66affSColin Finck #endif /* !MBEDTLS_DES_ALT */
841c2c66affSColin Finck 
842c2c66affSColin Finck #if defined(MBEDTLS_SELF_TEST)
843c2c66affSColin Finck /*
844c2c66affSColin Finck  * DES and 3DES test vectors from:
845c2c66affSColin Finck  *
846c2c66affSColin Finck  * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
847c2c66affSColin Finck  */
848c2c66affSColin Finck static const unsigned char des3_test_keys[24] =
849c2c66affSColin Finck {
850c2c66affSColin Finck     0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
851c2c66affSColin Finck     0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
852c2c66affSColin Finck     0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
853c2c66affSColin Finck };
854c2c66affSColin Finck 
855c2c66affSColin Finck static const unsigned char des3_test_buf[8] =
856c2c66affSColin Finck {
857c2c66affSColin Finck     0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
858c2c66affSColin Finck };
859c2c66affSColin Finck 
860c2c66affSColin Finck static const unsigned char des3_test_ecb_dec[3][8] =
861c2c66affSColin Finck {
862c2c66affSColin Finck     { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
863c2c66affSColin Finck     { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
864c2c66affSColin Finck     { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
865c2c66affSColin Finck };
866c2c66affSColin Finck 
867c2c66affSColin Finck static const unsigned char des3_test_ecb_enc[3][8] =
868c2c66affSColin Finck {
869c2c66affSColin Finck     { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
870c2c66affSColin Finck     { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
871c2c66affSColin Finck     { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
872c2c66affSColin Finck };
873c2c66affSColin Finck 
874c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CBC)
875c2c66affSColin Finck static const unsigned char des3_test_iv[8] =
876c2c66affSColin Finck {
877c2c66affSColin Finck     0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
878c2c66affSColin Finck };
879c2c66affSColin Finck 
880c2c66affSColin Finck static const unsigned char des3_test_cbc_dec[3][8] =
881c2c66affSColin Finck {
882c2c66affSColin Finck     { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
883c2c66affSColin Finck     { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
884c2c66affSColin Finck     { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
885c2c66affSColin Finck };
886c2c66affSColin Finck 
887c2c66affSColin Finck static const unsigned char des3_test_cbc_enc[3][8] =
888c2c66affSColin Finck {
889c2c66affSColin Finck     { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
890c2c66affSColin Finck     { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
891c2c66affSColin Finck     { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
892c2c66affSColin Finck };
893c2c66affSColin Finck #endif /* MBEDTLS_CIPHER_MODE_CBC */
894c2c66affSColin Finck 
895c2c66affSColin Finck /*
896c2c66affSColin Finck  * Checkup routine
897c2c66affSColin Finck  */
mbedtls_des_self_test(int verbose)898c2c66affSColin Finck int mbedtls_des_self_test( int verbose )
899c2c66affSColin Finck {
900c2c66affSColin Finck     int i, j, u, v, ret = 0;
901c2c66affSColin Finck     mbedtls_des_context ctx;
902c2c66affSColin Finck     mbedtls_des3_context ctx3;
903c2c66affSColin Finck     unsigned char buf[8];
904c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CBC)
905c2c66affSColin Finck     unsigned char prv[8];
906c2c66affSColin Finck     unsigned char iv[8];
907c2c66affSColin Finck #endif
908c2c66affSColin Finck 
909c2c66affSColin Finck     mbedtls_des_init( &ctx );
910c2c66affSColin Finck     mbedtls_des3_init( &ctx3 );
911c2c66affSColin Finck     /*
912c2c66affSColin Finck      * ECB mode
913c2c66affSColin Finck      */
914c2c66affSColin Finck     for( i = 0; i < 6; i++ )
915c2c66affSColin Finck     {
916c2c66affSColin Finck         u = i >> 1;
917c2c66affSColin Finck         v = i  & 1;
918c2c66affSColin Finck 
919c2c66affSColin Finck         if( verbose != 0 )
920c2c66affSColin Finck             mbedtls_printf( "  DES%c-ECB-%3d (%s): ",
921c2c66affSColin Finck                              ( u == 0 ) ? ' ' : '3', 56 + u * 56,
922c2c66affSColin Finck                              ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
923c2c66affSColin Finck 
924c2c66affSColin Finck         memcpy( buf, des3_test_buf, 8 );
925c2c66affSColin Finck 
926c2c66affSColin Finck         switch( i )
927c2c66affSColin Finck         {
928c2c66affSColin Finck         case 0:
929c2c66affSColin Finck             mbedtls_des_setkey_dec( &ctx, des3_test_keys );
930c2c66affSColin Finck             break;
931c2c66affSColin Finck 
932c2c66affSColin Finck         case 1:
933c2c66affSColin Finck             mbedtls_des_setkey_enc( &ctx, des3_test_keys );
934c2c66affSColin Finck             break;
935c2c66affSColin Finck 
936c2c66affSColin Finck         case 2:
937c2c66affSColin Finck             mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
938c2c66affSColin Finck             break;
939c2c66affSColin Finck 
940c2c66affSColin Finck         case 3:
941c2c66affSColin Finck             mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
942c2c66affSColin Finck             break;
943c2c66affSColin Finck 
944c2c66affSColin Finck         case 4:
945c2c66affSColin Finck             mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
946c2c66affSColin Finck             break;
947c2c66affSColin Finck 
948c2c66affSColin Finck         case 5:
949c2c66affSColin Finck             mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
950c2c66affSColin Finck             break;
951c2c66affSColin Finck 
952c2c66affSColin Finck         default:
953c2c66affSColin Finck             return( 1 );
954c2c66affSColin Finck         }
955c2c66affSColin Finck 
956c2c66affSColin Finck         for( j = 0; j < 10000; j++ )
957c2c66affSColin Finck         {
958c2c66affSColin Finck             if( u == 0 )
959c2c66affSColin Finck                 mbedtls_des_crypt_ecb( &ctx, buf, buf );
960c2c66affSColin Finck             else
961c2c66affSColin Finck                 mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
962c2c66affSColin Finck         }
963c2c66affSColin Finck 
964c2c66affSColin Finck         if( ( v == MBEDTLS_DES_DECRYPT &&
965c2c66affSColin Finck                 memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
966c2c66affSColin Finck             ( v != MBEDTLS_DES_DECRYPT &&
967c2c66affSColin Finck                 memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
968c2c66affSColin Finck         {
969c2c66affSColin Finck             if( verbose != 0 )
970c2c66affSColin Finck                 mbedtls_printf( "failed\n" );
971c2c66affSColin Finck 
972c2c66affSColin Finck             ret = 1;
973c2c66affSColin Finck             goto exit;
974c2c66affSColin Finck         }
975c2c66affSColin Finck 
976c2c66affSColin Finck         if( verbose != 0 )
977c2c66affSColin Finck             mbedtls_printf( "passed\n" );
978c2c66affSColin Finck     }
979c2c66affSColin Finck 
980c2c66affSColin Finck     if( verbose != 0 )
981c2c66affSColin Finck         mbedtls_printf( "\n" );
982c2c66affSColin Finck 
983c2c66affSColin Finck #if defined(MBEDTLS_CIPHER_MODE_CBC)
984c2c66affSColin Finck     /*
985c2c66affSColin Finck      * CBC mode
986c2c66affSColin Finck      */
987c2c66affSColin Finck     for( i = 0; i < 6; i++ )
988c2c66affSColin Finck     {
989c2c66affSColin Finck         u = i >> 1;
990c2c66affSColin Finck         v = i  & 1;
991c2c66affSColin Finck 
992c2c66affSColin Finck         if( verbose != 0 )
993c2c66affSColin Finck             mbedtls_printf( "  DES%c-CBC-%3d (%s): ",
994c2c66affSColin Finck                              ( u == 0 ) ? ' ' : '3', 56 + u * 56,
995c2c66affSColin Finck                              ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
996c2c66affSColin Finck 
997c2c66affSColin Finck         memcpy( iv,  des3_test_iv,  8 );
998c2c66affSColin Finck         memcpy( prv, des3_test_iv,  8 );
999c2c66affSColin Finck         memcpy( buf, des3_test_buf, 8 );
1000c2c66affSColin Finck 
1001c2c66affSColin Finck         switch( i )
1002c2c66affSColin Finck         {
1003c2c66affSColin Finck         case 0:
1004c2c66affSColin Finck             mbedtls_des_setkey_dec( &ctx, des3_test_keys );
1005c2c66affSColin Finck             break;
1006c2c66affSColin Finck 
1007c2c66affSColin Finck         case 1:
1008c2c66affSColin Finck             mbedtls_des_setkey_enc( &ctx, des3_test_keys );
1009c2c66affSColin Finck             break;
1010c2c66affSColin Finck 
1011c2c66affSColin Finck         case 2:
1012c2c66affSColin Finck             mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
1013c2c66affSColin Finck             break;
1014c2c66affSColin Finck 
1015c2c66affSColin Finck         case 3:
1016c2c66affSColin Finck             mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
1017c2c66affSColin Finck             break;
1018c2c66affSColin Finck 
1019c2c66affSColin Finck         case 4:
1020c2c66affSColin Finck             mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
1021c2c66affSColin Finck             break;
1022c2c66affSColin Finck 
1023c2c66affSColin Finck         case 5:
1024c2c66affSColin Finck             mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
1025c2c66affSColin Finck             break;
1026c2c66affSColin Finck 
1027c2c66affSColin Finck         default:
1028c2c66affSColin Finck             return( 1 );
1029c2c66affSColin Finck         }
1030c2c66affSColin Finck 
1031c2c66affSColin Finck         if( v == MBEDTLS_DES_DECRYPT )
1032c2c66affSColin Finck         {
1033c2c66affSColin Finck             for( j = 0; j < 10000; j++ )
1034c2c66affSColin Finck             {
1035c2c66affSColin Finck                 if( u == 0 )
1036c2c66affSColin Finck                     mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
1037c2c66affSColin Finck                 else
1038c2c66affSColin Finck                     mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
1039c2c66affSColin Finck             }
1040c2c66affSColin Finck         }
1041c2c66affSColin Finck         else
1042c2c66affSColin Finck         {
1043c2c66affSColin Finck             for( j = 0; j < 10000; j++ )
1044c2c66affSColin Finck             {
1045c2c66affSColin Finck                 unsigned char tmp[8];
1046c2c66affSColin Finck 
1047c2c66affSColin Finck                 if( u == 0 )
1048c2c66affSColin Finck                     mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
1049c2c66affSColin Finck                 else
1050c2c66affSColin Finck                     mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
1051c2c66affSColin Finck 
1052c2c66affSColin Finck                 memcpy( tmp, prv, 8 );
1053c2c66affSColin Finck                 memcpy( prv, buf, 8 );
1054c2c66affSColin Finck                 memcpy( buf, tmp, 8 );
1055c2c66affSColin Finck             }
1056c2c66affSColin Finck 
1057c2c66affSColin Finck             memcpy( buf, prv, 8 );
1058c2c66affSColin Finck         }
1059c2c66affSColin Finck 
1060c2c66affSColin Finck         if( ( v == MBEDTLS_DES_DECRYPT &&
1061c2c66affSColin Finck                 memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
1062c2c66affSColin Finck             ( v != MBEDTLS_DES_DECRYPT &&
1063c2c66affSColin Finck                 memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
1064c2c66affSColin Finck         {
1065c2c66affSColin Finck             if( verbose != 0 )
1066c2c66affSColin Finck                 mbedtls_printf( "failed\n" );
1067c2c66affSColin Finck 
1068c2c66affSColin Finck             ret = 1;
1069c2c66affSColin Finck             goto exit;
1070c2c66affSColin Finck         }
1071c2c66affSColin Finck 
1072c2c66affSColin Finck         if( verbose != 0 )
1073c2c66affSColin Finck             mbedtls_printf( "passed\n" );
1074c2c66affSColin Finck     }
1075c2c66affSColin Finck #endif /* MBEDTLS_CIPHER_MODE_CBC */
1076c2c66affSColin Finck 
1077c2c66affSColin Finck     if( verbose != 0 )
1078c2c66affSColin Finck         mbedtls_printf( "\n" );
1079c2c66affSColin Finck 
1080c2c66affSColin Finck exit:
1081c2c66affSColin Finck     mbedtls_des_free( &ctx );
1082c2c66affSColin Finck     mbedtls_des3_free( &ctx3 );
1083c2c66affSColin Finck 
1084c2c66affSColin Finck     return( ret );
1085c2c66affSColin Finck }
1086c2c66affSColin Finck 
1087c2c66affSColin Finck #endif /* MBEDTLS_SELF_TEST */
1088c2c66affSColin Finck 
1089c2c66affSColin Finck #endif /* MBEDTLS_DES_C */
1090