xref: /aosp_15_r20/external/mbedtls/library/des.c (revision 62c56f9862f102b96d72393aff6076c951fb8148)
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