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