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