/* * Long passwords, i.e 9 characters or more. */ static void afs_transarc_StringToKey (char *str, char *cell, DES_cblock *key) { DES_key_schedule schedule; DES_cblock temp_key; DES_cblock ivec; char password[512]; int passlen; strncpy (password, str, sizeof(password)); password[sizeof(password)-1] = '\0'; if ((passlen = strlen (password)) < sizeof(password)-1) strncat (password, cell, sizeof(password)-passlen); if ((passlen = strlen(password)) > sizeof(password)) passlen = sizeof(password); memcpy(&ivec, "kerberos", 8); memcpy(&temp_key, "kerberos", 8); des_fixup_key_parity (&temp_key); DES_key_sched (&temp_key, &schedule); DES_cbc_cksum ((unsigned char *)password, &ivec, passlen, &schedule, &ivec); memcpy(&temp_key, &ivec, 8); des_fixup_key_parity (&temp_key); DES_key_sched (&temp_key, &schedule); DES_cbc_cksum ((unsigned char *)password, key, passlen, &schedule, &ivec); des_fixup_key_parity (key); }
/* * des_random_key: create a random des key * * You should call des_set_random_number_generater_seed at least * once before this routine is called. If you haven't, I'll try * to add a little randomness to the start point anyway. Yes, * it recurses. Deal with it. * * Notes: the returned key has correct parity and is guarenteed not * to be a weak des key. Des_generate_random_block is used to * provide the random bits. */ int des_random_key(des_cblock key) { LOCK_INIT; if (!is_inited) { des_init_random_number_generator(key); } UNLOCK_INIT; do { des_generate_random_block(key); des_fixup_key_parity(key); } while (des_is_weak_key(key)); return (0); }
/* * Short passwords, i.e 8 characters or less. */ static void afs_cmu_StringToKey (char *str, char *cell, DES_cblock *key) { char password[8+1]; /* crypt is limited to 8 chars anyway */ int i; int passlen; strncpy (password, cell, 8); password[8] = '\0'; passlen = strlen (str); if (passlen > 8) passlen = 8; for (i=0; i<passlen; i++) password[i] = str[i] ^ cell[i]; /* make sure cell is zero padded */ for (i=0; i<8; i++) if (password[i] == '\0') password[i] = 'X'; /* crypt only considers the first 8 characters of password but for some reason returns eleven characters of result (plus the two salt chars). */ #ifdef KRB4_USE_SYSTEM_CRYPT strncpy((char *)key, crypt(password, "p1") + 2, sizeof(DES_cblock)); #else /* Use OpenSSL's DES_crypt() */ strncpy((char *)key, DES_crypt(password, "p1") + 2, sizeof(DES_cblock)); #endif /* parity is inserted into the LSB so leftshift each byte up one bit. This allows ascii characters with a zero MSB to retain as much significance as possible. */ { char *keybytes = (char *)key; unsigned int temp; for (i = 0; i < 8; i++) { temp = (unsigned int) keybytes[i]; keybytes[i] = (unsigned char) (temp << 1); } } des_fixup_key_parity (key); }
/* * convert an arbitrary length string to a DES key */ void des_string_to_key(char *str, register des_cblock * key) { register char *in_str; register unsigned temp, i, j; register afs_int32 length; unsigned char *k_p; int forward; register char *p_char; char k_char[64]; des_key_schedule key_sked; in_str = str; forward = 1; p_char = k_char; length = strlen(str); /* init key array for bits */ memset(k_char, 0, sizeof(k_char)); #ifdef DEBUG if (des_debug) fprintf(stdout, "\n\ninput str length = %d string = %s\nstring = 0x ", length, str); #endif /* get next 8 bytes, strip parity, xor */ for (i = 1; i <= length; i++) { /* get next input key byte */ temp = (unsigned int)*str++; #ifdef DEBUG if (des_debug) fprintf(stdout, "%02x ", temp & 0xff); #endif /* loop through bits within byte, ignore parity */ for (j = 0; j <= 6; j++) { if (forward) *p_char++ ^= (int)temp & 01; else *--p_char ^= (int)temp & 01; temp = temp >> 1; } while (--j > 0); /* check and flip direction */ if ((i % 8) == 0) forward = !forward; } /* now stuff into the key des_cblock, and force odd parity */ p_char = k_char; k_p = (unsigned char *)key; for (i = 0; i <= 7; i++) { temp = 0; for (j = 0; j <= 6; j++) temp |= *p_char++ << (1 + j); *k_p++ = (unsigned char)temp; } /* fix key parity */ des_fixup_key_parity(key); /* Now one-way encrypt it with the folded key */ (void)des_key_sched(key, key_sked); (void)des_cbc_cksum((des_cblock *) in_str, key, length, key_sked, key); /* erase key_sked */ memset((char *)key_sked, 0, sizeof(key_sked)); /* now fix up key parity again */ des_fixup_key_parity(key); if (des_debug) fprintf(stdout, "\nResulting string_to_key = 0x%lx 0x%lx\n", *((afs_uint32 *) key), *((afs_uint32 *) key + 1)); }