1*f0865ec9SKyle Evans /*
2*f0865ec9SKyle Evans * Copyright (C) 2021 - This file is part of libecc project
3*f0865ec9SKyle Evans *
4*f0865ec9SKyle Evans * Authors:
5*f0865ec9SKyle Evans * Ryad BENADJILA <ryadbenadjila@gmail.com>
6*f0865ec9SKyle Evans * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
7*f0865ec9SKyle Evans *
8*f0865ec9SKyle Evans * This software is licensed under a dual BSD and GPL v2 license.
9*f0865ec9SKyle Evans * See LICENSE file at the root folder of the project.
10*f0865ec9SKyle Evans */
11*f0865ec9SKyle Evans
12*f0865ec9SKyle Evans #include "tdes.h"
13*f0865ec9SKyle Evans
14*f0865ec9SKyle Evans /* This is a very straightforward and basic implementation of DES and T-DES */
15*f0865ec9SKyle Evans
16*f0865ec9SKyle Evans /* platform-independant 32-bit integer manipulation macros */
17*f0865ec9SKyle Evans #ifndef GET_UINT32
18*f0865ec9SKyle Evans #define GET_UINT32(n,b,i) \
19*f0865ec9SKyle Evans do { \
20*f0865ec9SKyle Evans (n) = ( (u32) (b)[(i) ] << 24 ) \
21*f0865ec9SKyle Evans | ( (u32) (b)[(i) + 1] << 16 ) \
22*f0865ec9SKyle Evans | ( (u32) (b)[(i) + 2] << 8 ) \
23*f0865ec9SKyle Evans | ( (u32) (b)[(i) + 3] ); \
24*f0865ec9SKyle Evans } while( 0 )
25*f0865ec9SKyle Evans #endif
26*f0865ec9SKyle Evans
27*f0865ec9SKyle Evans #ifndef PUT_UINT32
28*f0865ec9SKyle Evans #define PUT_UINT32(n,b,i) \
29*f0865ec9SKyle Evans do { \
30*f0865ec9SKyle Evans (b)[(i) ] = (u8) ( (n) >> 24 ); \
31*f0865ec9SKyle Evans (b)[(i) + 1] = (u8) ( (n) >> 16 ); \
32*f0865ec9SKyle Evans (b)[(i) + 2] = (u8) ( (n) >> 8 ); \
33*f0865ec9SKyle Evans (b)[(i) + 3] = (u8) ( (n) ); \
34*f0865ec9SKyle Evans } while( 0 )
35*f0865ec9SKyle Evans #endif
36*f0865ec9SKyle Evans
37*f0865ec9SKyle Evans /* DES 8 S-Boxes */
38*f0865ec9SKyle Evans static const u32 SB[8][64] = {
39*f0865ec9SKyle Evans {
40*f0865ec9SKyle Evans 0x01010400, 0x00000000, 0x00010000, 0x01010404,
41*f0865ec9SKyle Evans 0x01010004, 0x00010404, 0x00000004, 0x00010000,
42*f0865ec9SKyle Evans 0x00000400, 0x01010400, 0x01010404, 0x00000400,
43*f0865ec9SKyle Evans 0x01000404, 0x01010004, 0x01000000, 0x00000004,
44*f0865ec9SKyle Evans 0x00000404, 0x01000400, 0x01000400, 0x00010400,
45*f0865ec9SKyle Evans 0x00010400, 0x01010000, 0x01010000, 0x01000404,
46*f0865ec9SKyle Evans 0x00010004, 0x01000004, 0x01000004, 0x00010004,
47*f0865ec9SKyle Evans 0x00000000, 0x00000404, 0x00010404, 0x01000000,
48*f0865ec9SKyle Evans 0x00010000, 0x01010404, 0x00000004, 0x01010000,
49*f0865ec9SKyle Evans 0x01010400, 0x01000000, 0x01000000, 0x00000400,
50*f0865ec9SKyle Evans 0x01010004, 0x00010000, 0x00010400, 0x01000004,
51*f0865ec9SKyle Evans 0x00000400, 0x00000004, 0x01000404, 0x00010404,
52*f0865ec9SKyle Evans 0x01010404, 0x00010004, 0x01010000, 0x01000404,
53*f0865ec9SKyle Evans 0x01000004, 0x00000404, 0x00010404, 0x01010400,
54*f0865ec9SKyle Evans 0x00000404, 0x01000400, 0x01000400, 0x00000000,
55*f0865ec9SKyle Evans 0x00010004, 0x00010400, 0x00000000, 0x01010004
56*f0865ec9SKyle Evans },
57*f0865ec9SKyle Evans {
58*f0865ec9SKyle Evans 0x80108020, 0x80008000, 0x00008000, 0x00108020,
59*f0865ec9SKyle Evans 0x00100000, 0x00000020, 0x80100020, 0x80008020,
60*f0865ec9SKyle Evans 0x80000020, 0x80108020, 0x80108000, 0x80000000,
61*f0865ec9SKyle Evans 0x80008000, 0x00100000, 0x00000020, 0x80100020,
62*f0865ec9SKyle Evans 0x00108000, 0x00100020, 0x80008020, 0x00000000,
63*f0865ec9SKyle Evans 0x80000000, 0x00008000, 0x00108020, 0x80100000,
64*f0865ec9SKyle Evans 0x00100020, 0x80000020, 0x00000000, 0x00108000,
65*f0865ec9SKyle Evans 0x00008020, 0x80108000, 0x80100000, 0x00008020,
66*f0865ec9SKyle Evans 0x00000000, 0x00108020, 0x80100020, 0x00100000,
67*f0865ec9SKyle Evans 0x80008020, 0x80100000, 0x80108000, 0x00008000,
68*f0865ec9SKyle Evans 0x80100000, 0x80008000, 0x00000020, 0x80108020,
69*f0865ec9SKyle Evans 0x00108020, 0x00000020, 0x00008000, 0x80000000,
70*f0865ec9SKyle Evans 0x00008020, 0x80108000, 0x00100000, 0x80000020,
71*f0865ec9SKyle Evans 0x00100020, 0x80008020, 0x80000020, 0x00100020,
72*f0865ec9SKyle Evans 0x00108000, 0x00000000, 0x80008000, 0x00008020,
73*f0865ec9SKyle Evans 0x80000000, 0x80100020, 0x80108020, 0x00108000
74*f0865ec9SKyle Evans },
75*f0865ec9SKyle Evans {
76*f0865ec9SKyle Evans 0x00000208, 0x08020200, 0x00000000, 0x08020008,
77*f0865ec9SKyle Evans 0x08000200, 0x00000000, 0x00020208, 0x08000200,
78*f0865ec9SKyle Evans 0x00020008, 0x08000008, 0x08000008, 0x00020000,
79*f0865ec9SKyle Evans 0x08020208, 0x00020008, 0x08020000, 0x00000208,
80*f0865ec9SKyle Evans 0x08000000, 0x00000008, 0x08020200, 0x00000200,
81*f0865ec9SKyle Evans 0x00020200, 0x08020000, 0x08020008, 0x00020208,
82*f0865ec9SKyle Evans 0x08000208, 0x00020200, 0x00020000, 0x08000208,
83*f0865ec9SKyle Evans 0x00000008, 0x08020208, 0x00000200, 0x08000000,
84*f0865ec9SKyle Evans 0x08020200, 0x08000000, 0x00020008, 0x00000208,
85*f0865ec9SKyle Evans 0x00020000, 0x08020200, 0x08000200, 0x00000000,
86*f0865ec9SKyle Evans 0x00000200, 0x00020008, 0x08020208, 0x08000200,
87*f0865ec9SKyle Evans 0x08000008, 0x00000200, 0x00000000, 0x08020008,
88*f0865ec9SKyle Evans 0x08000208, 0x00020000, 0x08000000, 0x08020208,
89*f0865ec9SKyle Evans 0x00000008, 0x00020208, 0x00020200, 0x08000008,
90*f0865ec9SKyle Evans 0x08020000, 0x08000208, 0x00000208, 0x08020000,
91*f0865ec9SKyle Evans 0x00020208, 0x00000008, 0x08020008, 0x00020200
92*f0865ec9SKyle Evans },
93*f0865ec9SKyle Evans {
94*f0865ec9SKyle Evans 0x00802001, 0x00002081, 0x00002081, 0x00000080,
95*f0865ec9SKyle Evans 0x00802080, 0x00800081, 0x00800001, 0x00002001,
96*f0865ec9SKyle Evans 0x00000000, 0x00802000, 0x00802000, 0x00802081,
97*f0865ec9SKyle Evans 0x00000081, 0x00000000, 0x00800080, 0x00800001,
98*f0865ec9SKyle Evans 0x00000001, 0x00002000, 0x00800000, 0x00802001,
99*f0865ec9SKyle Evans 0x00000080, 0x00800000, 0x00002001, 0x00002080,
100*f0865ec9SKyle Evans 0x00800081, 0x00000001, 0x00002080, 0x00800080,
101*f0865ec9SKyle Evans 0x00002000, 0x00802080, 0x00802081, 0x00000081,
102*f0865ec9SKyle Evans 0x00800080, 0x00800001, 0x00802000, 0x00802081,
103*f0865ec9SKyle Evans 0x00000081, 0x00000000, 0x00000000, 0x00802000,
104*f0865ec9SKyle Evans 0x00002080, 0x00800080, 0x00800081, 0x00000001,
105*f0865ec9SKyle Evans 0x00802001, 0x00002081, 0x00002081, 0x00000080,
106*f0865ec9SKyle Evans 0x00802081, 0x00000081, 0x00000001, 0x00002000,
107*f0865ec9SKyle Evans 0x00800001, 0x00002001, 0x00802080, 0x00800081,
108*f0865ec9SKyle Evans 0x00002001, 0x00002080, 0x00800000, 0x00802001,
109*f0865ec9SKyle Evans 0x00000080, 0x00800000, 0x00002000, 0x00802080
110*f0865ec9SKyle Evans },
111*f0865ec9SKyle Evans {
112*f0865ec9SKyle Evans 0x00000100, 0x02080100, 0x02080000, 0x42000100,
113*f0865ec9SKyle Evans 0x00080000, 0x00000100, 0x40000000, 0x02080000,
114*f0865ec9SKyle Evans 0x40080100, 0x00080000, 0x02000100, 0x40080100,
115*f0865ec9SKyle Evans 0x42000100, 0x42080000, 0x00080100, 0x40000000,
116*f0865ec9SKyle Evans 0x02000000, 0x40080000, 0x40080000, 0x00000000,
117*f0865ec9SKyle Evans 0x40000100, 0x42080100, 0x42080100, 0x02000100,
118*f0865ec9SKyle Evans 0x42080000, 0x40000100, 0x00000000, 0x42000000,
119*f0865ec9SKyle Evans 0x02080100, 0x02000000, 0x42000000, 0x00080100,
120*f0865ec9SKyle Evans 0x00080000, 0x42000100, 0x00000100, 0x02000000,
121*f0865ec9SKyle Evans 0x40000000, 0x02080000, 0x42000100, 0x40080100,
122*f0865ec9SKyle Evans 0x02000100, 0x40000000, 0x42080000, 0x02080100,
123*f0865ec9SKyle Evans 0x40080100, 0x00000100, 0x02000000, 0x42080000,
124*f0865ec9SKyle Evans 0x42080100, 0x00080100, 0x42000000, 0x42080100,
125*f0865ec9SKyle Evans 0x02080000, 0x00000000, 0x40080000, 0x42000000,
126*f0865ec9SKyle Evans 0x00080100, 0x02000100, 0x40000100, 0x00080000,
127*f0865ec9SKyle Evans 0x00000000, 0x40080000, 0x02080100, 0x40000100
128*f0865ec9SKyle Evans },
129*f0865ec9SKyle Evans {
130*f0865ec9SKyle Evans 0x20000010, 0x20400000, 0x00004000, 0x20404010,
131*f0865ec9SKyle Evans 0x20400000, 0x00000010, 0x20404010, 0x00400000,
132*f0865ec9SKyle Evans 0x20004000, 0x00404010, 0x00400000, 0x20000010,
133*f0865ec9SKyle Evans 0x00400010, 0x20004000, 0x20000000, 0x00004010,
134*f0865ec9SKyle Evans 0x00000000, 0x00400010, 0x20004010, 0x00004000,
135*f0865ec9SKyle Evans 0x00404000, 0x20004010, 0x00000010, 0x20400010,
136*f0865ec9SKyle Evans 0x20400010, 0x00000000, 0x00404010, 0x20404000,
137*f0865ec9SKyle Evans 0x00004010, 0x00404000, 0x20404000, 0x20000000,
138*f0865ec9SKyle Evans 0x20004000, 0x00000010, 0x20400010, 0x00404000,
139*f0865ec9SKyle Evans 0x20404010, 0x00400000, 0x00004010, 0x20000010,
140*f0865ec9SKyle Evans 0x00400000, 0x20004000, 0x20000000, 0x00004010,
141*f0865ec9SKyle Evans 0x20000010, 0x20404010, 0x00404000, 0x20400000,
142*f0865ec9SKyle Evans 0x00404010, 0x20404000, 0x00000000, 0x20400010,
143*f0865ec9SKyle Evans 0x00000010, 0x00004000, 0x20400000, 0x00404010,
144*f0865ec9SKyle Evans 0x00004000, 0x00400010, 0x20004010, 0x00000000,
145*f0865ec9SKyle Evans 0x20404000, 0x20000000, 0x00400010, 0x20004010
146*f0865ec9SKyle Evans },
147*f0865ec9SKyle Evans {
148*f0865ec9SKyle Evans 0x00200000, 0x04200002, 0x04000802, 0x00000000,
149*f0865ec9SKyle Evans 0x00000800, 0x04000802, 0x00200802, 0x04200800,
150*f0865ec9SKyle Evans 0x04200802, 0x00200000, 0x00000000, 0x04000002,
151*f0865ec9SKyle Evans 0x00000002, 0x04000000, 0x04200002, 0x00000802,
152*f0865ec9SKyle Evans 0x04000800, 0x00200802, 0x00200002, 0x04000800,
153*f0865ec9SKyle Evans 0x04000002, 0x04200000, 0x04200800, 0x00200002,
154*f0865ec9SKyle Evans 0x04200000, 0x00000800, 0x00000802, 0x04200802,
155*f0865ec9SKyle Evans 0x00200800, 0x00000002, 0x04000000, 0x00200800,
156*f0865ec9SKyle Evans 0x04000000, 0x00200800, 0x00200000, 0x04000802,
157*f0865ec9SKyle Evans 0x04000802, 0x04200002, 0x04200002, 0x00000002,
158*f0865ec9SKyle Evans 0x00200002, 0x04000000, 0x04000800, 0x00200000,
159*f0865ec9SKyle Evans 0x04200800, 0x00000802, 0x00200802, 0x04200800,
160*f0865ec9SKyle Evans 0x00000802, 0x04000002, 0x04200802, 0x04200000,
161*f0865ec9SKyle Evans 0x00200800, 0x00000000, 0x00000002, 0x04200802,
162*f0865ec9SKyle Evans 0x00000000, 0x00200802, 0x04200000, 0x00000800,
163*f0865ec9SKyle Evans 0x04000002, 0x04000800, 0x00000800, 0x00200002
164*f0865ec9SKyle Evans },
165*f0865ec9SKyle Evans {
166*f0865ec9SKyle Evans 0x10001040, 0x00001000, 0x00040000, 0x10041040,
167*f0865ec9SKyle Evans 0x10000000, 0x10001040, 0x00000040, 0x10000000,
168*f0865ec9SKyle Evans 0x00040040, 0x10040000, 0x10041040, 0x00041000,
169*f0865ec9SKyle Evans 0x10041000, 0x00041040, 0x00001000, 0x00000040,
170*f0865ec9SKyle Evans 0x10040000, 0x10000040, 0x10001000, 0x00001040,
171*f0865ec9SKyle Evans 0x00041000, 0x00040040, 0x10040040, 0x10041000,
172*f0865ec9SKyle Evans 0x00001040, 0x00000000, 0x00000000, 0x10040040,
173*f0865ec9SKyle Evans 0x10000040, 0x10001000, 0x00041040, 0x00040000,
174*f0865ec9SKyle Evans 0x00041040, 0x00040000, 0x10041000, 0x00001000,
175*f0865ec9SKyle Evans 0x00000040, 0x10040040, 0x00001000, 0x00041040,
176*f0865ec9SKyle Evans 0x10001000, 0x00000040, 0x10000040, 0x10040000,
177*f0865ec9SKyle Evans 0x10040040, 0x10000000, 0x00040000, 0x10001040,
178*f0865ec9SKyle Evans 0x00000000, 0x10041040, 0x00040040, 0x10000040,
179*f0865ec9SKyle Evans 0x10040000, 0x10001000, 0x10001040, 0x00000000,
180*f0865ec9SKyle Evans 0x10041040, 0x00041000, 0x00041000, 0x00001040,
181*f0865ec9SKyle Evans 0x00001040, 0x00040040, 0x10000000, 0x10041000
182*f0865ec9SKyle Evans }
183*f0865ec9SKyle Evans };
184*f0865ec9SKyle Evans
185*f0865ec9SKyle Evans /* PC1: left and right halves bit-swap */
186*f0865ec9SKyle Evans
187*f0865ec9SKyle Evans static const u32 LH[16] =
188*f0865ec9SKyle Evans {
189*f0865ec9SKyle Evans 0x00000000, 0x00000001, 0x00000100, 0x00000101,
190*f0865ec9SKyle Evans 0x00010000, 0x00010001, 0x00010100, 0x00010101,
191*f0865ec9SKyle Evans 0x01000000, 0x01000001, 0x01000100, 0x01000101,
192*f0865ec9SKyle Evans 0x01010000, 0x01010001, 0x01010100, 0x01010101
193*f0865ec9SKyle Evans };
194*f0865ec9SKyle Evans
195*f0865ec9SKyle Evans static const u32 RH[16] =
196*f0865ec9SKyle Evans {
197*f0865ec9SKyle Evans 0x00000000, 0x01000000, 0x00010000, 0x01010000,
198*f0865ec9SKyle Evans 0x00000100, 0x01000100, 0x00010100, 0x01010100,
199*f0865ec9SKyle Evans 0x00000001, 0x01000001, 0x00010001, 0x01010001,
200*f0865ec9SKyle Evans 0x00000101, 0x01000101, 0x00010101, 0x01010101,
201*f0865ec9SKyle Evans };
202*f0865ec9SKyle Evans
203*f0865ec9SKyle Evans /* DES Initial Permutation (IP) */
des_ip(u32 L[1],u32 R[1])204*f0865ec9SKyle Evans static inline void des_ip(u32 L[1], u32 R[1])
205*f0865ec9SKyle Evans {
206*f0865ec9SKyle Evans u32 T;
207*f0865ec9SKyle Evans
208*f0865ec9SKyle Evans T = ((L[0] >> 4) ^ R[0]) & 0x0F0F0F0F; R[0] ^= T; L[0] ^= (T << 4);
209*f0865ec9SKyle Evans T = ((L[0] >> 16) ^ R[0]) & 0x0000FFFF; R[0] ^= T; L[0] ^= (T << 16);
210*f0865ec9SKyle Evans T = ((R[0] >> 2) ^ L[0]) & 0x33333333; L[0] ^= T; R[0] ^= (T << 2);
211*f0865ec9SKyle Evans T = ((R[0] >> 8) ^ L[0]) & 0x00FF00FF; L[0] ^= T; R[0] ^= (T << 8);
212*f0865ec9SKyle Evans R[0] = ((R[0] << 1) | (R[0] >> 31)) & 0xFFFFFFFF;
213*f0865ec9SKyle Evans T = (L[0] ^ R[0]) & 0xAAAAAAAA; R[0] ^= T; L[0] ^= T;
214*f0865ec9SKyle Evans L[0] = ((L[0] << 1) | (L[0] >> 31)) & 0xFFFFFFFF;
215*f0865ec9SKyle Evans
216*f0865ec9SKyle Evans return;
217*f0865ec9SKyle Evans }
218*f0865ec9SKyle Evans
219*f0865ec9SKyle Evans /* DES Final Permutation (FP) */
des_fp(u32 L[1],u32 R[1])220*f0865ec9SKyle Evans static inline void des_fp(u32 L[1], u32 R[1])
221*f0865ec9SKyle Evans {
222*f0865ec9SKyle Evans u32 T;
223*f0865ec9SKyle Evans
224*f0865ec9SKyle Evans L[0] = ((L[0] << 31) | (L[0] >> 1)) & 0xFFFFFFFF;
225*f0865ec9SKyle Evans T = (L[0] ^ R[0]) & 0xAAAAAAAA; L[0] ^= T; R[0] ^= T;
226*f0865ec9SKyle Evans R[0] = ((R[0] << 31) | (R[0] >> 1)) & 0xFFFFFFFF;
227*f0865ec9SKyle Evans T = ((R[0] >> 8) ^ L[0]) & 0x00FF00FF; L[0] ^= T; R[0] ^= (T << 8);
228*f0865ec9SKyle Evans T = ((R[0] >> 2) ^ L[0]) & 0x33333333; L[0] ^= T; R[0] ^= (T << 2);
229*f0865ec9SKyle Evans T = ((L[0] >> 16) ^ R[0]) & 0x0000FFFF; R[0] ^= T; L[0] ^= (T << 16);
230*f0865ec9SKyle Evans T = ((L[0] >> 4) ^ R[0]) & 0x0F0F0F0F; R[0] ^= T; L[0] ^= (T << 4);
231*f0865ec9SKyle Evans
232*f0865ec9SKyle Evans return;
233*f0865ec9SKyle Evans }
234*f0865ec9SKyle Evans
235*f0865ec9SKyle Evans /* DES function: F(R, K) + L with inversion */
des_round(u32 L[1],u32 R[1],u64 K)236*f0865ec9SKyle Evans static inline void des_round(u32 L[1], u32 R[1], u64 K)
237*f0865ec9SKyle Evans {
238*f0865ec9SKyle Evans u32 T;
239*f0865ec9SKyle Evans u32 k1, k2;
240*f0865ec9SKyle Evans
241*f0865ec9SKyle Evans k1 = (u32)K;
242*f0865ec9SKyle Evans k2 = (u32)(K >> 32);
243*f0865ec9SKyle Evans
244*f0865ec9SKyle Evans T = k1 ^ L[0];
245*f0865ec9SKyle Evans R[0] ^= SB[7][ (T) & 0x3f] ^ SB[5][ (T >> 8) & 0x3f] ^ SB[3][ (T >> 16) & 0x3f] ^ SB[1][ (T >> 24) & 0x3f];
246*f0865ec9SKyle Evans T = k2 ^ ((L[0] << 28) | (L[0] >> 4));
247*f0865ec9SKyle Evans R[0] ^= SB[6][ (T) & 0x3f] ^ SB[4][ (T >> 8) & 0x3f] ^ SB[2][ (T >> 16) & 0x3f] ^ SB[0][ (T >> 24) & 0x3f];
248*f0865ec9SKyle Evans
249*f0865ec9SKyle Evans return;
250*f0865ec9SKyle Evans }
251*f0865ec9SKyle Evans
252*f0865ec9SKyle Evans /* DES key schedule */
des_set_key(des_context * ctx,const u8 k[8],des_direction dir)253*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET int des_set_key(des_context *ctx, const u8 k[8], des_direction dir)
254*f0865ec9SKyle Evans {
255*f0865ec9SKyle Evans u32 i;
256*f0865ec9SKyle Evans u32 C, D, T;
257*f0865ec9SKyle Evans int ret;
258*f0865ec9SKyle Evans
259*f0865ec9SKyle Evans if((ctx == NULL) || (k == NULL)){
260*f0865ec9SKyle Evans ret = -1;
261*f0865ec9SKyle Evans goto err;
262*f0865ec9SKyle Evans }
263*f0865ec9SKyle Evans
264*f0865ec9SKyle Evans ctx->dir = dir;
265*f0865ec9SKyle Evans
266*f0865ec9SKyle Evans GET_UINT32(C, k, 0);
267*f0865ec9SKyle Evans GET_UINT32(D, k, 4);
268*f0865ec9SKyle Evans
269*f0865ec9SKyle Evans /* Permuted choice 1 */
270*f0865ec9SKyle Evans T = ((D >> 4) ^ C) & 0x0F0F0F0F; C ^= T; D ^= (T << 4);
271*f0865ec9SKyle Evans T = ((D ) ^ C) & 0x10101010; C ^= T; D ^= (T );
272*f0865ec9SKyle Evans
273*f0865ec9SKyle Evans C = (LH[ (C ) & 0xF] << 3) | (LH[ (C >> 8) & 0xF ] << 2)
274*f0865ec9SKyle Evans | (LH[ (C >> 16) & 0xF] << 1) | (LH[ (C >> 24) & 0xF ] )
275*f0865ec9SKyle Evans | (LH[ (C >> 5) & 0xF] << 7) | (LH[ (C >> 13) & 0xF ] << 6)
276*f0865ec9SKyle Evans | (LH[ (C >> 21) & 0xF] << 5) | (LH[ (C >> 29) & 0xF ] << 4);
277*f0865ec9SKyle Evans
278*f0865ec9SKyle Evans D = (RH[ (D >> 1) & 0xF] << 3) | (RH[ (D >> 9) & 0xF ] << 2)
279*f0865ec9SKyle Evans | (RH[ (D >> 17) & 0xF] << 1) | (RH[ (D >> 25) & 0xF ] )
280*f0865ec9SKyle Evans | (RH[ (D >> 4) & 0xF] << 7) | (RH[ (D >> 12) & 0xF ] << 6)
281*f0865ec9SKyle Evans | (RH[ (D >> 20) & 0xF] << 5) | (RH[ (D >> 28) & 0xF ] << 4);
282*f0865ec9SKyle Evans
283*f0865ec9SKyle Evans C &= 0x0FFFFFFF;
284*f0865ec9SKyle Evans D &= 0x0FFFFFFF;
285*f0865ec9SKyle Evans
286*f0865ec9SKyle Evans /* Compute the subkeys */
287*f0865ec9SKyle Evans for( i = 0; i < 16; i++ ){
288*f0865ec9SKyle Evans u32 k1, k2;
289*f0865ec9SKyle Evans if((i < 2) || (i == 8) || (i == 15)){
290*f0865ec9SKyle Evans C = ((C << 1) | (C >> 27)) & 0x0FFFFFFF;
291*f0865ec9SKyle Evans D = ((D << 1) | (D >> 27)) & 0x0FFFFFFF;
292*f0865ec9SKyle Evans }
293*f0865ec9SKyle Evans else{
294*f0865ec9SKyle Evans C = ((C << 2) | (C >> 26)) & 0x0FFFFFFF;
295*f0865ec9SKyle Evans D = ((D << 2) | (D >> 26)) & 0x0FFFFFFF;
296*f0865ec9SKyle Evans }
297*f0865ec9SKyle Evans
298*f0865ec9SKyle Evans k1 = ((C << 4) & 0x24000000) | ((C << 28) & 0x10000000)
299*f0865ec9SKyle Evans | ((C << 14) & 0x08000000) | ((C << 18) & 0x02080000)
300*f0865ec9SKyle Evans | ((C << 6) & 0x01000000) | ((C << 9) & 0x00200000)
301*f0865ec9SKyle Evans | ((C >> 1) & 0x00100000) | ((C << 10) & 0x00040000)
302*f0865ec9SKyle Evans | ((C << 2) & 0x00020000) | ((C >> 10) & 0x00010000)
303*f0865ec9SKyle Evans | ((D >> 13) & 0x00002000) | ((D >> 4) & 0x00001000)
304*f0865ec9SKyle Evans | ((D << 6) & 0x00000800) | ((D >> 1) & 0x00000400)
305*f0865ec9SKyle Evans | ((D >> 14) & 0x00000200) | ((D ) & 0x00000100)
306*f0865ec9SKyle Evans | ((D >> 5) & 0x00000020) | ((D >> 10) & 0x00000010)
307*f0865ec9SKyle Evans | ((D >> 3) & 0x00000008) | ((D >> 18) & 0x00000004)
308*f0865ec9SKyle Evans | ((D >> 26) & 0x00000002) | ((D >> 24) & 0x00000001);
309*f0865ec9SKyle Evans
310*f0865ec9SKyle Evans k2 = ((C << 15) & 0x20000000) | ((C << 17) & 0x10000000)
311*f0865ec9SKyle Evans | ((C << 10) & 0x08000000) | ((C << 22) & 0x04000000)
312*f0865ec9SKyle Evans | ((C >> 2) & 0x02000000) | ((C << 1) & 0x01000000)
313*f0865ec9SKyle Evans | ((C << 16) & 0x00200000) | ((C << 11) & 0x00100000)
314*f0865ec9SKyle Evans | ((C << 3) & 0x00080000) | ((C >> 6) & 0x00040000)
315*f0865ec9SKyle Evans | ((C << 15) & 0x00020000) | ((C >> 4) & 0x00010000)
316*f0865ec9SKyle Evans | ((D >> 2) & 0x00002000) | ((D << 8) & 0x00001000)
317*f0865ec9SKyle Evans | ((D >> 14) & 0x00000808) | ((D >> 9) & 0x00000400)
318*f0865ec9SKyle Evans | ((D ) & 0x00000200) | ((D << 7) & 0x00000100)
319*f0865ec9SKyle Evans | ((D >> 7) & 0x00000020) | ((D >> 3) & 0x00000011)
320*f0865ec9SKyle Evans | ((D << 2) & 0x00000004) | ((D >> 21) & 0x00000002);
321*f0865ec9SKyle Evans
322*f0865ec9SKyle Evans if(dir == DES_ENCRYPTION){
323*f0865ec9SKyle Evans ctx->sk[i] = (((u64)k2) << 32) | (u64)k1;
324*f0865ec9SKyle Evans }
325*f0865ec9SKyle Evans else if(dir == DES_DECRYPTION){
326*f0865ec9SKyle Evans ctx->sk[15-i] = (((u64)k2) << 32) | (u64)k1;
327*f0865ec9SKyle Evans }
328*f0865ec9SKyle Evans else{
329*f0865ec9SKyle Evans ret = -1;
330*f0865ec9SKyle Evans goto err;
331*f0865ec9SKyle Evans }
332*f0865ec9SKyle Evans }
333*f0865ec9SKyle Evans
334*f0865ec9SKyle Evans ret = 0;
335*f0865ec9SKyle Evans
336*f0865ec9SKyle Evans err:
337*f0865ec9SKyle Evans return ret;
338*f0865ec9SKyle Evans }
339*f0865ec9SKyle Evans
340*f0865ec9SKyle Evans /* DES encryption core */
des_core(const des_context * ctx,const u8 input[8],u8 output[8])341*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static inline int des_core(const des_context *ctx, const u8 input[8], u8 output[8])
342*f0865ec9SKyle Evans {
343*f0865ec9SKyle Evans u32 L, R;
344*f0865ec9SKyle Evans u32 i;
345*f0865ec9SKyle Evans int ret;
346*f0865ec9SKyle Evans
347*f0865ec9SKyle Evans if((ctx == NULL) || (input == NULL) || (output == NULL)){
348*f0865ec9SKyle Evans ret = -1;
349*f0865ec9SKyle Evans goto err;
350*f0865ec9SKyle Evans }
351*f0865ec9SKyle Evans
352*f0865ec9SKyle Evans GET_UINT32(L, input, 0);
353*f0865ec9SKyle Evans GET_UINT32(R, input, 4);
354*f0865ec9SKyle Evans
355*f0865ec9SKyle Evans des_ip(&L, &R);
356*f0865ec9SKyle Evans
357*f0865ec9SKyle Evans for(i = 0; i < 16; i++){
358*f0865ec9SKyle Evans if((i % 2) == 0){
359*f0865ec9SKyle Evans des_round(&R, &L, ctx->sk[i]);
360*f0865ec9SKyle Evans }
361*f0865ec9SKyle Evans else{
362*f0865ec9SKyle Evans des_round(&L, &R, ctx->sk[i]);
363*f0865ec9SKyle Evans }
364*f0865ec9SKyle Evans }
365*f0865ec9SKyle Evans
366*f0865ec9SKyle Evans des_fp(&R, &L);
367*f0865ec9SKyle Evans
368*f0865ec9SKyle Evans PUT_UINT32(R, output, 0);
369*f0865ec9SKyle Evans PUT_UINT32(L, output, 4);
370*f0865ec9SKyle Evans
371*f0865ec9SKyle Evans ret = 0;
372*f0865ec9SKyle Evans err:
373*f0865ec9SKyle Evans return ret;
374*f0865ec9SKyle Evans }
375*f0865ec9SKyle Evans
376*f0865ec9SKyle Evans /* DES encryption/decryption */
des(const des_context * ctx,const u8 input[8],u8 output[8])377*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET int des(const des_context *ctx, const u8 input[8], u8 output[8])
378*f0865ec9SKyle Evans {
379*f0865ec9SKyle Evans return des_core(ctx, input, output);
380*f0865ec9SKyle Evans }
381*f0865ec9SKyle Evans
382*f0865ec9SKyle Evans /* TDES key schedules */
des3_set_keys(des3_context * ctx,const u8 k1[8],const u8 k2[8],const u8 k3[8],des_direction dir)383*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET int des3_set_keys(des3_context *ctx, const u8 k1[8], const u8 k2[8], const u8 k3[8], des_direction dir)
384*f0865ec9SKyle Evans {
385*f0865ec9SKyle Evans int ret;
386*f0865ec9SKyle Evans
387*f0865ec9SKyle Evans if((ctx == NULL) || (k1 == NULL) || (k2 == NULL)){
388*f0865ec9SKyle Evans ret = -1;
389*f0865ec9SKyle Evans goto err;
390*f0865ec9SKyle Evans }
391*f0865ec9SKyle Evans ctx->dir = dir;
392*f0865ec9SKyle Evans if(dir == DES_ENCRYPTION){
393*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[0]), k1, DES_ENCRYPTION)){
394*f0865ec9SKyle Evans ret = -1;
395*f0865ec9SKyle Evans goto err;
396*f0865ec9SKyle Evans }
397*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[1]), k2, DES_DECRYPTION)){
398*f0865ec9SKyle Evans ret = -1;
399*f0865ec9SKyle Evans goto err;
400*f0865ec9SKyle Evans }
401*f0865ec9SKyle Evans if(k3 == NULL){
402*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[2]), k1, DES_ENCRYPTION)){
403*f0865ec9SKyle Evans ret = -1;
404*f0865ec9SKyle Evans goto err;
405*f0865ec9SKyle Evans }
406*f0865ec9SKyle Evans }
407*f0865ec9SKyle Evans else{
408*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[2]), k3, DES_ENCRYPTION)){
409*f0865ec9SKyle Evans ret = -1;
410*f0865ec9SKyle Evans goto err;
411*f0865ec9SKyle Evans }
412*f0865ec9SKyle Evans }
413*f0865ec9SKyle Evans }
414*f0865ec9SKyle Evans else if(dir == DES_DECRYPTION){
415*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[0]), k1, DES_DECRYPTION)){
416*f0865ec9SKyle Evans ret = -1;
417*f0865ec9SKyle Evans goto err;
418*f0865ec9SKyle Evans }
419*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[1]), k2, DES_ENCRYPTION)){
420*f0865ec9SKyle Evans ret = -1;
421*f0865ec9SKyle Evans goto err;
422*f0865ec9SKyle Evans }
423*f0865ec9SKyle Evans if(k3 == NULL){
424*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[2]), k1, DES_DECRYPTION)){
425*f0865ec9SKyle Evans ret = -1;
426*f0865ec9SKyle Evans goto err;
427*f0865ec9SKyle Evans }
428*f0865ec9SKyle Evans }
429*f0865ec9SKyle Evans else{
430*f0865ec9SKyle Evans if(des_set_key(&(ctx->des[2]), k3, DES_DECRYPTION)){
431*f0865ec9SKyle Evans ret = -1;
432*f0865ec9SKyle Evans goto err;
433*f0865ec9SKyle Evans }
434*f0865ec9SKyle Evans }
435*f0865ec9SKyle Evans }
436*f0865ec9SKyle Evans else{
437*f0865ec9SKyle Evans ret = -1;
438*f0865ec9SKyle Evans goto err;
439*f0865ec9SKyle Evans }
440*f0865ec9SKyle Evans
441*f0865ec9SKyle Evans ret = 0;
442*f0865ec9SKyle Evans err:
443*f0865ec9SKyle Evans return ret;
444*f0865ec9SKyle Evans }
445*f0865ec9SKyle Evans
446*f0865ec9SKyle Evans /* TDES encryption/decryption */
des3(const des3_context * ctx,const u8 input[8],u8 output[8])447*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET int des3(const des3_context *ctx, const u8 input[8], u8 output[8])
448*f0865ec9SKyle Evans {
449*f0865ec9SKyle Evans int ret;
450*f0865ec9SKyle Evans u8 tmp[8];
451*f0865ec9SKyle Evans
452*f0865ec9SKyle Evans if(ctx == NULL){
453*f0865ec9SKyle Evans ret = -1;
454*f0865ec9SKyle Evans goto err;
455*f0865ec9SKyle Evans }
456*f0865ec9SKyle Evans if(ctx->dir == DES_ENCRYPTION){
457*f0865ec9SKyle Evans if(des_core(&(ctx->des[0]), input, output)){
458*f0865ec9SKyle Evans ret = -1;
459*f0865ec9SKyle Evans goto err;
460*f0865ec9SKyle Evans }
461*f0865ec9SKyle Evans if(des_core(&(ctx->des[1]), output, tmp)){
462*f0865ec9SKyle Evans ret = -1;
463*f0865ec9SKyle Evans goto err;
464*f0865ec9SKyle Evans }
465*f0865ec9SKyle Evans if(des_core(&(ctx->des[2]), tmp, output)){
466*f0865ec9SKyle Evans ret = -1;
467*f0865ec9SKyle Evans goto err;
468*f0865ec9SKyle Evans }
469*f0865ec9SKyle Evans }
470*f0865ec9SKyle Evans else if(ctx->dir == DES_DECRYPTION){
471*f0865ec9SKyle Evans if(des_core(&(ctx->des[2]), input, output)){
472*f0865ec9SKyle Evans ret = -1;
473*f0865ec9SKyle Evans goto err;
474*f0865ec9SKyle Evans }
475*f0865ec9SKyle Evans if(des_core(&(ctx->des[1]), output, tmp)){
476*f0865ec9SKyle Evans ret = -1;
477*f0865ec9SKyle Evans goto err;
478*f0865ec9SKyle Evans }
479*f0865ec9SKyle Evans if(des_core(&(ctx->des[0]), tmp, output)){
480*f0865ec9SKyle Evans ret = -1;
481*f0865ec9SKyle Evans goto err;
482*f0865ec9SKyle Evans }
483*f0865ec9SKyle Evans }
484*f0865ec9SKyle Evans else{
485*f0865ec9SKyle Evans ret = -1;
486*f0865ec9SKyle Evans goto err;
487*f0865ec9SKyle Evans }
488*f0865ec9SKyle Evans
489*f0865ec9SKyle Evans ret = 0;
490*f0865ec9SKyle Evans err:
491*f0865ec9SKyle Evans return ret;
492*f0865ec9SKyle Evans }
493