Bell 32V development
[unix-history] / usr / src / libc / gen / crypt.c
CommitLineData
2eeb1188
TL
1/*
2 * This program implements the
3 * Proposed Federal Information Processing
4 * Data Encryption Standard.
5 * See Federal Register, March 17, 1975 (40FR12134)
6 */
7
8/*
9 * Initial permutation,
10 */
11static char IP[] = {
12 58,50,42,34,26,18,10, 2,
13 60,52,44,36,28,20,12, 4,
14 62,54,46,38,30,22,14, 6,
15 64,56,48,40,32,24,16, 8,
16 57,49,41,33,25,17, 9, 1,
17 59,51,43,35,27,19,11, 3,
18 61,53,45,37,29,21,13, 5,
19 63,55,47,39,31,23,15, 7,
20};
21
22/*
23 * Final permutation, FP = IP^(-1)
24 */
25static char FP[] = {
26 40, 8,48,16,56,24,64,32,
27 39, 7,47,15,55,23,63,31,
28 38, 6,46,14,54,22,62,30,
29 37, 5,45,13,53,21,61,29,
30 36, 4,44,12,52,20,60,28,
31 35, 3,43,11,51,19,59,27,
32 34, 2,42,10,50,18,58,26,
33 33, 1,41, 9,49,17,57,25,
34};
35
36/*
37 * Permuted-choice 1 from the key bits
38 * to yield C and D.
39 * Note that bits 8,16... are left out:
40 * They are intended for a parity check.
41 */
42static char PC1_C[] = {
43 57,49,41,33,25,17, 9,
44 1,58,50,42,34,26,18,
45 10, 2,59,51,43,35,27,
46 19,11, 3,60,52,44,36,
47};
48
49static char PC1_D[] = {
50 63,55,47,39,31,23,15,
51 7,62,54,46,38,30,22,
52 14, 6,61,53,45,37,29,
53 21,13, 5,28,20,12, 4,
54};
55
56/*
57 * Sequence of shifts used for the key schedule.
58*/
59static char shifts[] = {
60 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
61};
62
63/*
64 * Permuted-choice 2, to pick out the bits from
65 * the CD array that generate the key schedule.
66 */
67static char PC2_C[] = {
68 14,17,11,24, 1, 5,
69 3,28,15, 6,21,10,
70 23,19,12, 4,26, 8,
71 16, 7,27,20,13, 2,
72};
73
74static char PC2_D[] = {
75 41,52,31,37,47,55,
76 30,40,51,45,33,48,
77 44,49,39,56,34,53,
78 46,42,50,36,29,32,
79};
80
81/*
82 * The C and D arrays used to calculate the key schedule.
83 */
84
85static char C[28];
86static char D[28];
87/*
88 * The key schedule.
89 * Generated from the key.
90 */
91static char KS[16][48];
92
93/*
94 * Set up the key schedule from the key.
95 */
96
97setkey(key)
98char *key;
99{
100 register i, j, k;
101 int t;
102
103 /*
104 * First, generate C and D by permuting
105 * the key. The low order bit of each
106 * 8-bit char is not used, so C and D are only 28
107 * bits apiece.
108 */
109 for (i=0; i<28; i++) {
110 C[i] = key[PC1_C[i]-1];
111 D[i] = key[PC1_D[i]-1];
112 }
113 /*
114 * To generate Ki, rotate C and D according
115 * to schedule and pick up a permutation
116 * using PC2.
117 */
118 for (i=0; i<16; i++) {
119 /*
120 * rotate.
121 */
122 for (k=0; k<shifts[i]; k++) {
123 t = C[0];
124 for (j=0; j<28-1; j++)
125 C[j] = C[j+1];
126 C[27] = t;
127 t = D[0];
128 for (j=0; j<28-1; j++)
129 D[j] = D[j+1];
130 D[27] = t;
131 }
132 /*
133 * get Ki. Note C and D are concatenated.
134 */
135 for (j=0; j<24; j++) {
136 KS[i][j] = C[PC2_C[j]-1];
137 KS[i][j+24] = D[PC2_D[j]-28-1];
138 }
139 }
140}
141
142/*
143 * The E bit-selection table.
144 */
145static char E[48];
146static char e[] = {
147 32, 1, 2, 3, 4, 5,
148 4, 5, 6, 7, 8, 9,
149 8, 9,10,11,12,13,
150 12,13,14,15,16,17,
151 16,17,18,19,20,21,
152 20,21,22,23,24,25,
153 24,25,26,27,28,29,
154 28,29,30,31,32, 1,
155};
156
157/*
158 * The 8 selection functions.
159 * For some reason, they give a 0-origin
160 * index, unlike everything else.
161 */
162static char S[8][64] = {
163 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
164 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
165 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
166 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
167
168 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
169 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
170 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
171 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
172
173 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
174 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
175 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
176 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
177
178 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
179 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
180 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
181 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
182
183 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
184 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
185 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
186 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
187
188 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
189 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
190 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
191 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
192
193 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
194 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
195 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
196 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
197
198 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
199 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
200 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
201 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
202};
203
204/*
205 * P is a permutation on the selected combination
206 * of the current L and key.
207 */
208static char P[] = {
209 16, 7,20,21,
210 29,12,28,17,
211 1,15,23,26,
212 5,18,31,10,
213 2, 8,24,14,
214 32,27, 3, 9,
215 19,13,30, 6,
216 22,11, 4,25,
217};
218
219/*
220 * The current block, divided into 2 halves.
221 */
222static char L[32], R[32];
223static char tempL[32];
224static char f[32];
225
226/*
227 * The combination of the key and the input, before selection.
228 */
229static char preS[48];
230
231/*
232 * The payoff: encrypt a block.
233 */
234
235encrypt(block, edflag)
236char *block;
237{
238 int i, ii;
239 register t, j, k;
240
241 /*
242 * First, permute the bits in the input
243 */
244 for (j=0; j<64; j++)
245 L[j] = block[IP[j]-1];
246 /*
247 * Perform an encryption operation 16 times.
248 */
249 for (ii=0; ii<16; ii++) {
250 /*
251 * Set direction
252 */
253 if (edflag)
254 i = 15-ii;
255 else
256 i = ii;
257 /*
258 * Save the R array,
259 * which will be the new L.
260 */
261 for (j=0; j<32; j++)
262 tempL[j] = R[j];
263 /*
264 * Expand R to 48 bits using the E selector;
265 * exclusive-or with the current key bits.
266 */
267 for (j=0; j<48; j++)
268 preS[j] = R[E[j]-1] ^ KS[i][j];
269 /*
270 * The pre-select bits are now considered
271 * in 8 groups of 6 bits each.
272 * The 8 selection functions map these
273 * 6-bit quantities into 4-bit quantities
274 * and the results permuted
275 * to make an f(R, K).
276 * The indexing into the selection functions
277 * is peculiar; it could be simplified by
278 * rewriting the tables.
279 */
280 for (j=0; j<8; j++) {
281 t = 6*j;
282 k = S[j][(preS[t+0]<<5)+
283 (preS[t+1]<<3)+
284 (preS[t+2]<<2)+
285 (preS[t+3]<<1)+
286 (preS[t+4]<<0)+
287 (preS[t+5]<<4)];
288 t = 4*j;
289 f[t+0] = (k>>3)&01;
290 f[t+1] = (k>>2)&01;
291 f[t+2] = (k>>1)&01;
292 f[t+3] = (k>>0)&01;
293 }
294 /*
295 * The new R is L ^ f(R, K).
296 * The f here has to be permuted first, though.
297 */
298 for (j=0; j<32; j++)
299 R[j] = L[j] ^ f[P[j]-1];
300 /*
301 * Finally, the new L (the original R)
302 * is copied back.
303 */
304 for (j=0; j<32; j++)
305 L[j] = tempL[j];
306 }
307 /*
308 * The output L and R are reversed.
309 */
310 for (j=0; j<32; j++) {
311 t = L[j];
312 L[j] = R[j];
313 R[j] = t;
314 }
315 /*
316 * The final output
317 * gets the inverse permutation of the very original.
318 */
319 for (j=0; j<64; j++)
320 block[j] = L[FP[j]-1];
321}
322
323char *
324crypt(pw,salt)
325char *pw;
326char *salt;
327{
328 register i, j, c;
329 int temp;
330 static char block[66], iobuf[16];
331 for(i=0; i<66; i++)
332 block[i] = 0;
333 for(i=0; (c= *pw) && i<64; pw++){
334 for(j=0; j<7; j++, i++)
335 block[i] = (c>>(6-j)) & 01;
336 i++;
337 }
338
339 setkey(block);
340
341 for(i=0; i<66; i++)
342 block[i] = 0;
343
344 for(i=0;i<48;i++)
345 E[i] = e[i];
346
347 for(i=0;i<2;i++){
348 c = *salt++;
349 iobuf[i] = c;
350 if(c>'Z') c -= 6;
351 if(c>'9') c -= 7;
352 c -= '.';
353 for(j=0;j<6;j++){
354 if((c>>j) & 01){
355 temp = E[6*i+j];
356 E[6*i+j] = E[6*i+j+24];
357 E[6*i+j+24] = temp;
358 }
359 }
360 }
361
362 for(i=0; i<25; i++)
363 encrypt(block,0);
364
365 for(i=0; i<11; i++){
366 c = 0;
367 for(j=0; j<6; j++){
368 c <<= 1;
369 c |= block[6*i+j];
370 }
371 c += '.';
372 if(c>'9') c += 7;
373 if(c>'Z') c += 6;
374 iobuf[i+2] = c;
375 }
376 iobuf[i+2] = 0;
377 if(iobuf[1]==0)
378 iobuf[1] = iobuf[0];
379 return(iobuf);
380}