xref: /freebsd/crypto/libecc/src/examples/hash/tdes.c (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
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