Stop using SALT_TYPE_AFS_LENGTH
[krb5.git] / src / lib / crypto / krb / s2k_des.c
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  * Copyright (C) 1998 by the FundsXpress, INC.
4  *
5  * All rights reserved.
6  *
7  * Export of this software from the United States of America may require
8  * a specific license from the United States Government.  It is the
9  * responsibility of any person or organization contemplating export to
10  * obtain such a license before exporting.
11  *
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of FundsXpress. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  FundsXpress makes no representations about the suitability of
20  * this software for any purpose.  It is provided "as is" without express
21  * or implied warranty.
22  *
23  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
25  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26  */
27
28 /*
29  * RFC 3961 and AFS string to key.  These are not standard crypto primitives
30  * (RFC 3961 string-to-key is implemented in OpenSSL for historical reasons but
31  * it doesn't get weak keys right), so we have to implement them here.
32  */
33
34 #include <ctype.h>
35 #include "crypto_int.h"
36
37 #undef min
38 #define min(a,b) ((a)>(b)?(b):(a))
39
40 /* Compute a CBC checksum of in (with length len) using the specified key and
41  * ivec.  The result is written into out. */
42 static krb5_error_code
43 des_cbc_mac(const unsigned char *keybits, const unsigned char *ivec,
44             const unsigned char *in, size_t len, unsigned char *out)
45 {
46     krb5_error_code ret;
47     krb5_keyblock kb;
48     krb5_key key;
49     krb5_crypto_iov iov[2];
50     unsigned char zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
51     krb5_data outd, ivecd;
52
53     /* Make a key from keybits. */
54     kb.magic = KV5M_KEYBLOCK;
55     kb.enctype = ENCTYPE_DES_CBC_CRC;
56     kb.length = 8;
57     kb.contents = (unsigned char *)keybits;
58     ret = krb5_k_create_key(NULL, &kb, &key);
59     if (ret)
60         return ret;
61
62     /* Make iovs for the input data, padding it out to the block size. */
63     iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
64     iov[0].data = make_data((unsigned char *)in, len);
65     iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
66     iov[1].data = make_data(zero, krb5_roundup(len, 8) - len);
67
68     /* Make krb5_data structures for the ivec and output. */
69     ivecd = make_data((unsigned char *)ivec, 8);
70     outd = make_data(out, 8);
71
72     /* Call the cbc_mac operation of the module's DES enc-provider. */
73     ret = krb5int_enc_des.cbc_mac(key, iov, 2, &ivecd, &outd);
74     krb5_k_free_key(NULL, key);
75     return ret;
76 }
77
78 /*** AFS string-to-key constants ***/
79
80 /* Initial permutation */
81 static const char IP[] = {
82     58,50,42,34,26,18,10, 2,
83     60,52,44,36,28,20,12, 4,
84     62,54,46,38,30,22,14, 6,
85     64,56,48,40,32,24,16, 8,
86     57,49,41,33,25,17, 9, 1,
87     59,51,43,35,27,19,11, 3,
88     61,53,45,37,29,21,13, 5,
89     63,55,47,39,31,23,15, 7,
90 };
91
92 /* Final permutation, FP = IP^(-1) */
93 static const char FP[] = {
94     40, 8,48,16,56,24,64,32,
95     39, 7,47,15,55,23,63,31,
96     38, 6,46,14,54,22,62,30,
97     37, 5,45,13,53,21,61,29,
98     36, 4,44,12,52,20,60,28,
99     35, 3,43,11,51,19,59,27,
100     34, 2,42,10,50,18,58,26,
101     33, 1,41, 9,49,17,57,25,
102 };
103
104 /*
105  * Permuted-choice 1 from the key bits to yield C and D.
106  * Note that bits 8,16... are left out: They are intended for a parity check.
107  */
108 static const char PC1_C[] = {
109     57,49,41,33,25,17, 9,
110     1,58,50,42,34,26,18,
111     10, 2,59,51,43,35,27,
112     19,11, 3,60,52,44,36,
113 };
114
115 static const char PC1_D[] = {
116     63,55,47,39,31,23,15,
117     7,62,54,46,38,30,22,
118     14, 6,61,53,45,37,29,
119     21,13, 5,28,20,12, 4,
120 };
121
122 /* Sequence of shifts used for the key schedule */
123 static const char shifts[] = {
124     1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
125 };
126
127 /* Permuted-choice 2, to pick out the bits from the CD array that generate the
128  * key schedule */
129 static const char PC2_C[] = {
130     14,17,11,24, 1, 5,
131     3,28,15, 6,21,10,
132     23,19,12, 4,26, 8,
133     16, 7,27,20,13, 2,
134 };
135
136 static const char PC2_D[] = {
137     41,52,31,37,47,55,
138     30,40,51,45,33,48,
139     44,49,39,56,34,53,
140     46,42,50,36,29,32,
141 };
142
143 /* The E bit-selection table */
144 static const char e[] = {
145     32, 1, 2, 3, 4, 5,
146     4, 5, 6, 7, 8, 9,
147     8, 9,10,11,12,13,
148     12,13,14,15,16,17,
149     16,17,18,19,20,21,
150     20,21,22,23,24,25,
151     24,25,26,27,28,29,
152     28,29,30,31,32, 1,
153 };
154
155 /* P is a permutation on the selected combination of the current L and key. */
156 static const char P[] = {
157     16, 7,20,21,
158     29,12,28,17,
159     1,15,23,26,
160     5,18,31,10,
161     2, 8,24,14,
162     32,27, 3, 9,
163     19,13,30, 6,
164     22,11, 4,25,
165 };
166
167 /*
168  * The 8 selection functions.
169  * For some reason, they give a 0-origin
170  * index, unlike everything else.
171  */
172 static const char S[8][64] = {
173     {14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
174      0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
175      4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
176      15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13},
177
178     {15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
179      3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
180      0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
181      13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9},
182
183     {10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
184      13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
185      13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
186      1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12},
187
188     { 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
189       13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
190       10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
191       3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14},
192
193     { 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
194       14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
195       4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
196       11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3},
197
198     {12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
199      10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
200      9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
201      4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13},
202
203     { 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
204       13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
205       1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
206       6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12},
207
208     {13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
209      1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
210      7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
211      2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11},
212 };
213
214
215 /* Set up the key schedule from the key. */
216 static void
217 afs_crypt_setkey(char *key, char *E, char (*KS)[48])
218 {
219     int i, j, k, t;
220     char C[28], D[28];          /* Used to calculate key schedule. */
221
222     /*
223      * First, generate C and D by permuting
224      * the key.  The low order bit of each
225      * 8-bit char is not used, so C and D are only 28
226      * bits apiece.
227      */
228     for (i = 0; i < 28; i++) {
229         C[i] = key[PC1_C[i] - 1];
230         D[i] = key[PC1_D[i] - 1];
231     }
232     /*
233      * To generate Ki, rotate C and D according
234      * to schedule and pick up a permutation
235      * using PC2.
236      */
237     for (i = 0; i < 16; i++) {
238         /* Rotate. */
239         for (k = 0; k < shifts[i]; k++) {
240             t = C[0];
241             for (j = 0; j < 28 - 1; j++)
242                 C[j] = C[j + 1];
243             C[27] = t;
244             t = D[0];
245             for (j = 0; j < 28 - 1; j++)
246                 D[j] = D[j + 1];
247             D[27] = t;
248         }
249         /* Get Ki.  Note C and D are concatenated. */
250         for (j = 0; j < 24; j++) {
251             KS[i][j] = C[PC2_C[j]-1];
252             KS[i][j+24] = D[PC2_D[j]-28-1];
253         }
254     }
255
256     memcpy(E, e, 48);
257 }
258
259 /*
260  * The payoff: encrypt a block.
261  */
262
263 static void
264 afs_encrypt_block(char *block, char *E, char (*KS)[48])
265 {
266     const long edflag = 0;
267     int i, ii;
268     int t, j, k;
269     char tempL[32];
270     char f[32];
271     char L[64];                 /* Current block divided into two halves */
272     char *const R = &L[32];
273     /* The combination of the key and the input, before selection. */
274     char preS[48];
275
276     /* First, permute the bits in the input. */
277     for (j = 0; j < 64; j++)
278         L[j] = block[IP[j] - 1];
279     /* Perform an encryption operation 16 times. */
280     for (ii = 0; ii < 16; ii++) {
281         /* Set direction. */
282         i = (edflag) ? 15 - ii : ii;
283         /* Save the R array, which will be the new L. */
284         memcpy(tempL, R, 32);
285         /* Expand R to 48 bits using the E selector; exclusive-or with the
286          * current key bits. */
287         for (j = 0; j < 48; j++)
288             preS[j] = R[E[j] - 1] ^ KS[i][j];
289         /*
290          * The pre-select bits are now considered in 8 groups of 6 bits each.
291          * The 8 selection functions map these 6-bit quantities into 4-bit
292          * quantities and the results permuted to make an f(R, K).  The
293          * indexing into the selection functions is peculiar; it could be
294          * simplified by rewriting the tables.
295          */
296         for (j = 0; j < 8; j++) {
297             t = 6 * j;
298             k = S[j][(preS[t + 0] << 5) +
299                      (preS[t + 1] << 3) +
300                      (preS[t + 2] << 2) +
301                      (preS[t + 3] << 1) +
302                      (preS[t + 4] << 0) +
303                      (preS[t + 5] << 4)];
304             t = 4 * j;
305             f[t + 0] = (k >> 3) & 1;
306             f[t + 1] = (k >> 2) & 1;
307             f[t + 2] = (k >> 1) & 1;
308             f[t + 3] = (k >> 0) & 1;
309         }
310         /* The new R is L ^ f(R, K).  The f here has to be permuted first,
311          * though. */
312         for (j = 0; j < 32; j++)
313             R[j] = L[j] ^ f[P[j] - 1];
314         /* Finally, the new L (the original R) is copied back. */
315         memcpy(L, tempL, 32);
316     }
317     /* The output L and R are reversed. */
318     for (j = 0; j < 32; j++) {
319         t = L[j];
320         L[j] = R[j];
321         R[j] = t;
322     }
323     /* The final output gets the inverse permutation of the very original. */
324     for (j = 0; j < 64; j++)
325         block[j] = L[FP[j] - 1];
326 }
327
328 /* iobuf must be at least 16 bytes */
329 static char *
330 afs_crypt(const char *pw, const char *salt, char *iobuf)
331 {
332     int i, j, c;
333     int temp;
334     char block[66];
335     char E[48];
336     char KS[16][48];            /* Key schedule, generated from key */
337
338     for (i = 0; i < 66; i++)
339         block[i] = 0;
340     for (i = 0; (c = *pw) != '\0' && i < 64; pw++){
341         for(j = 0; j < 7; j++, i++)
342             block[i] = (c >> (6 - j)) & 01;
343         i++;
344     }
345
346     afs_crypt_setkey(block, E, KS);
347
348     for (i = 0; i < 66; i++)
349         block[i] = 0;
350
351     for (i = 0; i < 2; i++) {
352         c = *salt++;
353         iobuf[i] = c;
354         if (c > 'Z')
355             c -= 6;
356         if (c > '9')
357             c -= 7;
358         c -= '.';
359         for (j = 0; j < 6; j++) {
360             if ((c >> j) & 01) {
361                 temp = E[6 * i + j];
362                 E[6 * i + j] = E[6 * i + j + 24];
363                 E[6 * i + j + 24] = temp;
364             }
365         }
366     }
367
368     for (i = 0; i < 25; i++)
369         afs_encrypt_block(block, E, KS);
370
371     for (i = 0; i < 11; i++) {
372         c = 0;
373         for (j = 0; j < 6; j++) {
374             c <<= 1;
375             c |= block[6 * i + j];
376         }
377         c += '.';
378         if (c > '9')
379             c += 7;
380         if (c > 'Z')
381             c += 6;
382         iobuf[i + 2] = c;
383     }
384     iobuf[i + 2] = 0;
385     if (iobuf[1] == 0)
386         iobuf[1] = iobuf[0];
387     return iobuf;
388 }
389
390 static krb5_error_code
391 afs_s2k_oneblock(const krb5_data *data, const krb5_data *salt,
392                  unsigned char *key_out)
393 {
394     unsigned int i;
395     unsigned char password[9]; /* trailing nul for crypt() */
396     char afs_crypt_buf[16];
397
398     /*
399      * Run afs_crypt and use the first eight returned bytes after the copy of
400      * the (fixed) salt.
401      *
402      * Since the returned bytes are alphanumeric, the output is limited to
403      * 2**48 possibilities; for each byte, only 64 possible values can be used.
404      */
405
406     memset(password, 0, sizeof(password));
407     memcpy(password, salt->data, min(salt->length, 8));
408     for (i = 0; i < 8; i++) {
409         if (isupper(password[i]))
410             password[i] = tolower(password[i]);
411     }
412     for (i = 0; i < data->length; i++)
413         password[i] ^= data->data[i];
414     for (i = 0; i < 8; i++) {
415         if (password[i] == '\0')
416             password[i] = 'X';
417     }
418     password[8] = '\0';
419     /* Out-of-bounds salt characters are equivalent to a salt string
420      * of "p1". */
421     strncpy((char *)key_out,
422             (char *)afs_crypt((char *)password, "#~", afs_crypt_buf) + 2, 8);
423     for (i = 0; i < 8; i++)
424         key_out[i] <<= 1;
425     /* Fix up key parity again. */
426     k5_des_fixup_key_parity(key_out);
427     zap(password, sizeof(password));
428     return 0;
429 }
430
431 static krb5_error_code
432 afs_s2k_multiblock(const krb5_data *data, const krb5_data *salt,
433                    unsigned char *key_out)
434 {
435     krb5_error_code ret;
436     unsigned char ivec[8], tkey[8], *password;
437     size_t pw_len = salt->length + data->length;
438     unsigned int i, j;
439
440     /* Do a CBC checksum, twice, and use the result as the new key.  */
441
442     password = malloc(pw_len);
443     if (!password)
444         return ENOMEM;
445
446     memcpy(password, data->data, data->length);
447     for (i = data->length, j = 0; j < salt->length; i++, j++) {
448         password[i] = salt->data[j];
449         if (isupper(password[i]))
450             password[i] = tolower(password[i]);
451     }
452
453     memcpy(ivec, "kerberos", sizeof(ivec));
454     memcpy(tkey, ivec, sizeof(tkey));
455     k5_des_fixup_key_parity(tkey);
456     ret = des_cbc_mac(tkey, ivec, password, pw_len, tkey);
457     if (ret)
458         goto cleanup;
459
460     memcpy(ivec, tkey, sizeof(ivec));
461     k5_des_fixup_key_parity(tkey);
462     ret = des_cbc_mac(tkey, ivec, password, pw_len, key_out);
463     if (ret)
464         goto cleanup;
465     k5_des_fixup_key_parity(key_out);
466
467 cleanup:
468     zapfree(password, pw_len);
469     return ret;
470 }
471
472 static krb5_error_code
473 afs_s2k(const krb5_data *data, const krb5_data *salt, unsigned char *key_out)
474 {
475     if (data->length <= 8)
476         return afs_s2k_oneblock(data, salt, key_out);
477     else
478         return afs_s2k_multiblock(data, salt, key_out);
479 }
480
481 static krb5_error_code
482 des_s2k(const krb5_data *pw, const krb5_data *salt, unsigned char *key_out)
483 {
484     union {
485         /* 8 "forward" bytes, 8 "reverse" bytes */
486         unsigned char uc[16];
487         krb5_ui_4 ui[4];
488     } temp;
489     unsigned int i;
490     krb5_ui_4 x, y, z;
491     unsigned char *p, *copy;
492     size_t copylen;
493     krb5_error_code ret;
494
495     /* As long as the architecture is big-endian or little-endian, it
496        doesn't matter which it is.  Think of it as reversing the
497        bytes, and also reversing the bits within each byte.  But this
498        current algorithm is dependent on having four 8-bit char values
499        exactly overlay a 32-bit integral type.  */
500     if (sizeof(temp.uc) != sizeof(temp.ui)
501         || (unsigned char)~0 != 0xFF
502         || (krb5_ui_4)~(krb5_ui_4)0 != 0xFFFFFFFF
503         || (temp.uc[0] = 1, temp.uc[1] = 2, temp.uc[2] = 3, temp.uc[3] = 4,
504             !(temp.ui[0] == 0x01020304
505               || temp.ui[0] == 0x04030201)))
506         abort();
507 #define FETCH4(VAR, IDX)        VAR = temp.ui[IDX/4]
508 #define PUT4(VAR, IDX)          temp.ui[IDX/4] = VAR
509
510     copylen = pw->length + (salt ? salt->length : 0);
511     /* Don't need NUL termination, at this point we're treating it as
512        a byte array, not a string.  */
513     copy = malloc(copylen);
514     if (copy == NULL)
515         return ENOMEM;
516     memcpy(copy, pw->data, pw->length);
517     if (salt)
518         memcpy(copy + pw->length, salt->data, salt->length);
519
520     memset(&temp, 0, sizeof(temp));
521     p = temp.uc;
522     /* Handle the fan-fold xor operation by splitting the data into
523        forward and reverse sections, and combine them later, rather
524        than having to do the reversal over and over again.  */
525     for (i = 0; i < copylen; i++) {
526         *p++ ^= copy[i];
527         if (p == temp.uc+16) {
528             p = temp.uc;
529 #ifdef PRINT_TEST_VECTORS
530             {
531                 int j;
532                 printf("after %d input bytes:\nforward block:\t", i+1);
533                 for (j = 0; j < 8; j++)
534                     printf(" %02x", temp.uc[j] & 0xff);
535                 printf("\nreverse block:\t");
536                 for (j = 8; j < 16; j++)
537                     printf(" %02x", temp.uc[j] & 0xff);
538                 printf("\n");
539             }
540 #endif
541         }
542     }
543
544 #ifdef PRINT_TEST_VECTORS
545     if (p != temp.uc) {
546         int j;
547         printf("at end, after %d input bytes:\nforward block:\t", i);
548         for (j = 0; j < 8; j++)
549             printf(" %02x", temp.uc[j] & 0xff);
550         printf("\nreverse block:\t");
551         for (j = 8; j < 16; j++)
552             printf(" %02x", temp.uc[j] & 0xff);
553         printf("\n");
554     }
555 #endif
556 #define REVERSE(VAR)                            \
557     {                                           \
558         krb5_ui_4 old = VAR, temp1 = 0;         \
559         int j;                                  \
560         for (j = 0; j < 32; j++) {              \
561             temp1 = (temp1 << 1) | (old & 1);   \
562             old >>= 1;                          \
563         }                                       \
564         VAR = temp1;                            \
565     }
566
567     FETCH4 (x, 8);
568     FETCH4 (y, 12);
569     /* Ignore high bits of each input byte.  */
570     x &= 0x7F7F7F7F;
571     y &= 0x7F7F7F7F;
572     /* Reverse the bit strings -- after this, y is "before" x.  */
573     REVERSE (x);
574     REVERSE (y);
575 #ifdef PRINT_TEST_VECTORS
576     {
577         int j;
578         union { unsigned char uc[4]; krb5_ui_4 ui; } t2;
579         printf("after reversal, reversed block:\n\t\t");
580         t2.ui = y;
581         for (j = 0; j < 4; j++)
582             printf(" %02x", t2.uc[j] & 0xff);
583         t2.ui = x;
584         for (j = 0; j < 4; j++)
585             printf(" %02x", t2.uc[j] & 0xff);
586         printf("\n");
587     }
588 #endif
589     /* Ignored bits are now at the bottom of each byte, where we'll
590      * put the parity bits.  Good.  */
591     FETCH4 (z, 0);
592     z &= 0x7F7F7F7F;
593     /* Ignored bits for z are at the top of each byte; fix that.  */
594     z <<= 1;
595     /* Finish the fan-fold xor for these four bytes.  */
596     z ^= y;
597     PUT4 (z, 0);
598     /* Now do the second four bytes.  */
599     FETCH4 (z, 4);
600     z &= 0x7F7F7F7F;
601     /* Ignored bits for z are at the top of each byte; fix that.  */
602     z <<= 1;
603     /* Finish the fan-fold xor for these four bytes.  */
604     z ^= x;
605     PUT4 (z, 4);
606
607 #ifdef PRINT_TEST_VECTORS
608     {
609         int j;
610         printf("after reversal, combined block:\n\t\t");
611         for (j = 0; j < 8; j++)
612             printf(" %02x", temp.uc[j] & 0xff);
613         printf("\n");
614     }
615 #endif
616
617 #define FIXUP(k) (k5_des_fixup_key_parity(k),                   \
618                   k5_des_is_weak_key(k) ? (k[7] ^= 0xF0) : 0)
619
620     /* Now temp.cb is the temporary key, with invalid parity.  */
621     FIXUP(temp.uc);
622
623 #ifdef PRINT_TEST_VECTORS
624     {
625         int j;
626         printf("after fixing parity and weak keys:\n\t\t");
627         for (j = 0; j < 8; j++)
628             printf(" %02x", temp.uc[j] & 0xff);
629         printf("\n");
630     }
631 #endif
632
633     ret = des_cbc_mac(temp.uc, temp.uc, copy, copylen, temp.uc);
634     if (ret)
635         goto cleanup;
636
637 #ifdef PRINT_TEST_VECTORS
638     {
639         int j;
640         printf("cbc checksum:\n\t\t");
641         for (j = 0; j < 8; j++)
642             printf(" %02x", temp.uc[j] & 0xff);
643         printf("\n");
644     }
645 #endif
646
647     FIXUP(temp.uc);
648
649 #ifdef PRINT_TEST_VECTORS
650     {
651         int j;
652         printf("after fixing parity and weak keys:\n\t\t");
653         for (j = 0; j < 8; j++)
654             printf(" %02x", temp.uc[j] & 0xff);
655         printf("\n");
656     }
657 #endif
658
659     memcpy(key_out, temp.uc, 8);
660
661 cleanup:
662     zap(&temp, sizeof(temp));
663     zapfree(copy, copylen);
664     return ret;
665 }
666
667 krb5_error_code
668 krb5int_des_string_to_key(const struct krb5_keytypes *ktp,
669                           const krb5_data *string, const krb5_data *salt,
670                           const krb5_data *parm, krb5_keyblock *keyblock)
671 {
672     int type;
673
674     if (parm != NULL) {
675         if (parm->length != 1)
676             return KRB5_ERR_BAD_S2K_PARAMS;
677         type = parm->data[0];
678         if (type != 0 && type != 1)
679             return KRB5_ERR_BAD_S2K_PARAMS;
680     } else
681         type = 0;
682
683     /* Use AFS string to key if we were told to. */
684     if (type == 1)
685         return afs_s2k(string, salt, keyblock->contents);
686
687     return des_s2k(string, salt, keyblock->contents);
688 }