1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 * Copyright (C) 1998 by the FundsXpress, INC.
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.
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.
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.
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.
35 #include "crypto_int.h"
38 #define min(a,b) ((a)>(b)?(b):(a))
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)
49 krb5_crypto_iov iov[2];
50 unsigned char zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
51 krb5_data outd, ivecd;
53 /* Make a key from keybits. */
54 kb.magic = KV5M_KEYBLOCK;
55 kb.enctype = ENCTYPE_DES_CBC_CRC;
57 kb.contents = (unsigned char *)keybits;
58 ret = krb5_k_create_key(NULL, &kb, &key);
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);
68 /* Make krb5_data structures for the ivec and output. */
69 ivecd = make_data((unsigned char *)ivec, 8);
70 outd = make_data(out, 8);
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);
78 /*** AFS string-to-key constants ***/
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,
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,
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.
108 static const char PC1_C[] = {
109 57,49,41,33,25,17, 9,
111 10, 2,59,51,43,35,27,
112 19,11, 3,60,52,44,36,
115 static const char PC1_D[] = {
116 63,55,47,39,31,23,15,
118 14, 6,61,53,45,37,29,
119 21,13, 5,28,20,12, 4,
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,
127 /* Permuted-choice 2, to pick out the bits from the CD array that generate the
129 static const char PC2_C[] = {
136 static const char PC2_D[] = {
143 /* The E bit-selection table */
144 static const char e[] = {
155 /* P is a permutation on the selected combination of the current L and key. */
156 static const char P[] = {
168 * The 8 selection functions.
169 * For some reason, they give a 0-origin
170 * index, unlike everything else.
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},
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},
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},
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},
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},
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},
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},
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},
215 /* Set up the key schedule from the key. */
217 afs_crypt_setkey(char *key, char *E, char (*KS)[48])
220 char C[28], D[28]; /* Used to calculate key schedule. */
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
228 for (i = 0; i < 28; i++) {
229 C[i] = key[PC1_C[i] - 1];
230 D[i] = key[PC1_D[i] - 1];
233 * To generate Ki, rotate C and D according
234 * to schedule and pick up a permutation
237 for (i = 0; i < 16; i++) {
239 for (k = 0; k < shifts[i]; k++) {
241 for (j = 0; j < 28 - 1; j++)
245 for (j = 0; j < 28 - 1; j++)
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];
260 * The payoff: encrypt a block.
264 afs_encrypt_block(char *block, char *E, char (*KS)[48])
266 const long edflag = 0;
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. */
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++) {
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];
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.
296 for (j = 0; j < 8; j++) {
298 k = S[j][(preS[t + 0] << 5) +
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;
310 /* The new R is L ^ f(R, K). The f here has to be permuted first,
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);
317 /* The output L and R are reversed. */
318 for (j = 0; j < 32; j++) {
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];
328 /* iobuf must be at least 16 bytes */
330 afs_crypt(const char *pw, const char *salt, char *iobuf)
336 char KS[16][48]; /* Key schedule, generated from key */
338 for (i = 0; i < 66; i++)
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;
346 afs_crypt_setkey(block, E, KS);
348 for (i = 0; i < 66; i++)
351 for (i = 0; i < 2; i++) {
359 for (j = 0; j < 6; j++) {
362 E[6 * i + j] = E[6 * i + j + 24];
363 E[6 * i + j + 24] = temp;
368 for (i = 0; i < 25; i++)
369 afs_encrypt_block(block, E, KS);
371 for (i = 0; i < 11; i++) {
373 for (j = 0; j < 6; j++) {
375 c |= block[6 * i + j];
390 static krb5_error_code
391 afs_s2k_oneblock(const krb5_data *data, const krb5_data *salt,
392 unsigned char *key_out)
395 unsigned char password[9]; /* trailing nul for crypt() */
396 char afs_crypt_buf[16];
399 * Run afs_crypt and use the first eight returned bytes after the copy of
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.
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]);
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')
419 /* Out-of-bounds salt characters are equivalent to a salt string
421 strncpy((char *)key_out,
422 (char *)afs_crypt((char *)password, "#~", afs_crypt_buf) + 2, 8);
423 for (i = 0; i < 8; i++)
425 /* Fix up key parity again. */
426 k5_des_fixup_key_parity(key_out);
427 zap(password, sizeof(password));
431 static krb5_error_code
432 afs_s2k_multiblock(const krb5_data *data, const krb5_data *salt,
433 unsigned char *key_out)
436 unsigned char ivec[8], tkey[8], *password;
437 size_t pw_len = salt->length + data->length;
440 /* Do a CBC checksum, twice, and use the result as the new key. */
442 password = malloc(pw_len);
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]);
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);
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);
465 k5_des_fixup_key_parity(key_out);
468 zapfree(password, pw_len);
472 static krb5_error_code
473 afs_s2k(const krb5_data *data, const krb5_data *salt, unsigned char *key_out)
475 if (data->length <= 8)
476 return afs_s2k_oneblock(data, salt, key_out);
478 return afs_s2k_multiblock(data, salt, key_out);
481 static krb5_error_code
482 des_s2k(const krb5_data *pw, const krb5_data *salt, unsigned char *key_out)
485 /* 8 "forward" bytes, 8 "reverse" bytes */
486 unsigned char uc[16];
491 unsigned char *p, *copy;
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)))
507 #define FETCH4(VAR, IDX) VAR = temp.ui[IDX/4]
508 #define PUT4(VAR, IDX) temp.ui[IDX/4] = VAR
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);
516 memcpy(copy, pw->data, pw->length);
518 memcpy(copy + pw->length, salt->data, salt->length);
520 memset(&temp, 0, sizeof(temp));
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++) {
527 if (p == temp.uc+16) {
529 #ifdef PRINT_TEST_VECTORS
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);
544 #ifdef PRINT_TEST_VECTORS
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);
556 #define REVERSE(VAR) \
558 krb5_ui_4 old = VAR, temp1 = 0; \
560 for (j = 0; j < 32; j++) { \
561 temp1 = (temp1 << 1) | (old & 1); \
569 /* Ignore high bits of each input byte. */
572 /* Reverse the bit strings -- after this, y is "before" x. */
575 #ifdef PRINT_TEST_VECTORS
578 union { unsigned char uc[4]; krb5_ui_4 ui; } t2;
579 printf("after reversal, reversed block:\n\t\t");
581 for (j = 0; j < 4; j++)
582 printf(" %02x", t2.uc[j] & 0xff);
584 for (j = 0; j < 4; j++)
585 printf(" %02x", t2.uc[j] & 0xff);
589 /* Ignored bits are now at the bottom of each byte, where we'll
590 * put the parity bits. Good. */
593 /* Ignored bits for z are at the top of each byte; fix that. */
595 /* Finish the fan-fold xor for these four bytes. */
598 /* Now do the second four bytes. */
601 /* Ignored bits for z are at the top of each byte; fix that. */
603 /* Finish the fan-fold xor for these four bytes. */
607 #ifdef PRINT_TEST_VECTORS
610 printf("after reversal, combined block:\n\t\t");
611 for (j = 0; j < 8; j++)
612 printf(" %02x", temp.uc[j] & 0xff);
617 #define FIXUP(k) (k5_des_fixup_key_parity(k), \
618 k5_des_is_weak_key(k) ? (k[7] ^= 0xF0) : 0)
620 /* Now temp.cb is the temporary key, with invalid parity. */
623 #ifdef PRINT_TEST_VECTORS
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);
633 ret = des_cbc_mac(temp.uc, temp.uc, copy, copylen, temp.uc);
637 #ifdef PRINT_TEST_VECTORS
640 printf("cbc checksum:\n\t\t");
641 for (j = 0; j < 8; j++)
642 printf(" %02x", temp.uc[j] & 0xff);
649 #ifdef PRINT_TEST_VECTORS
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);
659 memcpy(key_out, temp.uc, 8);
662 zap(&temp, sizeof(temp));
663 zapfree(copy, copylen);
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)
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;
683 /* Use AFS string to key if we were told to. */
685 return afs_s2k(string, salt, keyblock->contents);
687 return des_s2k(string, salt, keyblock->contents);