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