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