-
Notifications
You must be signed in to change notification settings - Fork 0
/
fdes.c
158 lines (132 loc) · 4.77 KB
/
fdes.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
* Copyright (c) 1991 David G. Koontz.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms. Inclusion in a product or release
* as part of a package for sale is not agreed to. Storing this
* software in a nonvolatile storage device characterized as an
* integrated circuit providing read only memory (ROM), either as
* source code or machine executeable instructions is similarly not
* agreed to. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
* IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE
*/
#ifndef lint
char Copyright[]=
"@(#) Copyright (c) 1991 David G. Koontz\n All rights reserved.\n";
#endif
/*
* fdes.c - faster implementation of DES algorithm.
*/
#include "config.h"
#include "fdes.h"
#include "des_ip.h"
#include "des_iip.h"
#include "des_key.h"
#include "des_s_p.h"
/* Key Schedule permuted for S Box input: */
static union block_48 K_S[16];
static union block_48 *key_start;
static int des_mode;
#pragma weak tac_des
#pragma weak tac_des_loadkey
#pragma weak tac_set_des_mode
void
tac_set_des_mode(int encode)
{
if (encode) {
key_start = &K_S[0];
des_mode = SHIFT_FOR_ENCRYPT;
} else {
key_start = &K_S[15];
des_mode = SHIFT_FOR_DECRYPT;
}
}
void
tac_des_loadkey(unsigned char *key, int shift)
{
unsigned i,j;
union block_48 data;
if (!shift) /* key lookup table always shifts */
for (i = 0; i < 8; i++)
data.string[i] = key[i] >> 1;
else
for (i = 0; i < 8; i++)
data.string[i] = key[i];
for ( j = 0; j < 16; j++) /* key load must be re-entrant */
K_S[j].AB[0] = K_S[j].AB[1] = 0;
for (i = 0; i < 8; i++) { /* 8 bytes (56 bits) of key */
for(j = 0; j < 16;j++) { /* load K_S[0-16] byte at a time */
K_S[j].AB[0] |= KEY[i][data.string[i]][j][0];
K_S[j].AB[1] |= KEY[i][data.string[i]][j][1];
}
}
}
static void
no_ip_des(union LR_block *block)
{
unsigned int round;
int shift;
unsigned long temp_f;
union block_48 pre_S, *k_s;
k_s = key_start;
shift = des_mode;
for (round = 0; round < 8; round++) { /* f(R,K), 16 double rounds */
/* Expansion Permutation, E XOR K */
temp_f = block->LR[RR]; /* L/R reg. is R31,R0...R30 (D0-D31) format */
pre_S.AB[0] = temp_f & 0x3f3f3f3f ^ k_s->AB[0]; /* S1S3S5S7 */
pre_S.AB[1] = ((temp_f >> 4 | temp_f << 28) & 0x3f3f3f3f) ^ k_s->AB[1];
k_s += shift; /* S2S4S6S8 */
/* S Box and P lookup: temp_f = f(R,K) */
temp_f = S_P[0][pre_S.string[S1]] | S_P[1][pre_S.string[S2]]
| S_P[2][pre_S.string[S3]] | S_P[3][pre_S.string[S4]]
| S_P[4][pre_S.string[S5]] | S_P[5][pre_S.string[S6]]
| S_P[6][pre_S.string[S7]] | S_P[7][pre_S.string[S8]];
/* f(R,K) EXOR L */
temp_f ^= block->LR[LL]; /* temp_f is new R */
block->LR[LL] = temp_f; /* update L register */
/* Repeat round (temp_f carried through) */
pre_S.AB[0] = temp_f & 0x3f3f3f3f ^ k_s->AB[0];
pre_S.AB[1] = ((temp_f >> 4 | temp_f << 28) & 0x3f3f3f3f) ^ k_s->AB[1];
k_s += shift;
temp_f = S_P[0][pre_S.string[S1]] | S_P[1][pre_S.string[S2]]
| S_P[2][pre_S.string[S3]] | S_P[3][pre_S.string[S4]]
| S_P[4][pre_S.string[S5]] | S_P[5][pre_S.string[S6]]
| S_P[6][pre_S.string[S7]] | S_P[7][pre_S.string[S8]];
temp_f ^= block->LR[RR]; /* L is old R */
block->LR[RR] = temp_f; /* update R register */
}
/* had L/R swap here */
}
void
tac_des(union LR_block *block)
{
unsigned long temp;
union LR_block data;
data.LR[LL] = block->LR[LL];
data.LR[RR] = block->LR[RR];
temp = IP[ 0][data.string[0]] | IP[ 1][data.string[1]] |
IP[ 2][data.string[2]] | IP[ 3][data.string[3]] |
IP[ 4][data.string[4]] | IP[ 5][data.string[5]] |
IP[ 6][data.string[6]] | IP[ 7][data.string[7]];
data.LR[LL] =
IP[ 8][data.string[0]] | IP[ 9][data.string[1]] |
IP[10][data.string[2]] | IP[11][data.string[3]] |
IP[12][data.string[4]] | IP[13][data.string[5]] |
IP[14][data.string[6]] | IP[15][data.string[7]];
data.LR[RR] = temp;
no_ip_des(&data);
temp = IIP[ 0][data.string[0]] | IIP[ 1][data.string[1]] |
IIP[ 2][data.string[2]] | IIP[ 3][data.string[3]] |
IIP[ 4][data.string[4]] | IIP[ 5][data.string[5]] |
IIP[ 6][data.string[6]] | IIP[ 7][data.string[7]];
block->LR[AA] =
IIP[ 8][data.string[0]] | IIP[ 9][data.string[1]] |
IIP[10][data.string[2]] | IIP[11][data.string[3]] |
IIP[12][data.string[4]] | IIP[13][data.string[5]] |
IIP[14][data.string[6]] | IIP[15][data.string[7]];
block->LR[BB] = temp;
}