1226031Sstas/* 2226031Sstas * Copyright (c) 1997 - 2008 Kungliga Tekniska H��gskolan 3226031Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4226031Sstas * All rights reserved. 5226031Sstas * 6226031Sstas * Redistribution and use in source and binary forms, with or without 7226031Sstas * modification, are permitted provided that the following conditions 8226031Sstas * are met: 9226031Sstas * 10226031Sstas * 1. Redistributions of source code must retain the above copyright 11226031Sstas * notice, this list of conditions and the following disclaimer. 12226031Sstas * 13226031Sstas * 2. Redistributions in binary form must reproduce the above copyright 14226031Sstas * notice, this list of conditions and the following disclaimer in the 15226031Sstas * documentation and/or other materials provided with the distribution. 16226031Sstas * 17226031Sstas * 3. Neither the name of the Institute nor the names of its contributors 18226031Sstas * may be used to endorse or promote products derived from this software 19226031Sstas * without specific prior written permission. 20226031Sstas * 21226031Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22226031Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24226031Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25226031Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26226031Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27226031Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28226031Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29226031Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30226031Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31226031Sstas * SUCH DAMAGE. 32226031Sstas */ 33226031Sstas 34226031Sstas#include "krb5_locl.h" 35226031Sstas 36226031Sstas#ifdef HEIM_WEAK_CRYPTO 37226031Sstas 38226031Sstas#ifdef ENABLE_AFS_STRING_TO_KEY 39226031Sstas 40226031Sstas/* This defines the Andrew string_to_key function. It accepts a password 41226031Sstas * string as input and converts it via a one-way encryption algorithm to a DES 42226031Sstas * encryption key. It is compatible with the original Andrew authentication 43226031Sstas * service password database. 44226031Sstas */ 45226031Sstas 46226031Sstas/* 47226031Sstas * Short passwords, i.e 8 characters or less. 48226031Sstas */ 49226031Sstasstatic void 50226031Sstaskrb5_DES_AFS3_CMU_string_to_key (krb5_data pw, 51226031Sstas krb5_data cell, 52226031Sstas DES_cblock *key) 53226031Sstas{ 54226031Sstas char password[8+1]; /* crypt is limited to 8 chars anyway */ 55226031Sstas size_t i; 56226031Sstas 57226031Sstas for(i = 0; i < 8; i++) { 58226031Sstas char c = ((i < pw.length) ? ((char*)pw.data)[i] : 0) ^ 59226031Sstas ((i < cell.length) ? 60226031Sstas tolower(((unsigned char*)cell.data)[i]) : 0); 61226031Sstas password[i] = c ? c : 'X'; 62226031Sstas } 63226031Sstas password[8] = '\0'; 64226031Sstas 65226031Sstas memcpy(key, crypt(password, "p1") + 2, sizeof(DES_cblock)); 66226031Sstas 67226031Sstas /* parity is inserted into the LSB so left shift each byte up one 68226031Sstas bit. This allows ascii characters with a zero MSB to retain as 69226031Sstas much significance as possible. */ 70226031Sstas for (i = 0; i < sizeof(DES_cblock); i++) 71226031Sstas ((unsigned char*)key)[i] <<= 1; 72226031Sstas DES_set_odd_parity (key); 73226031Sstas} 74226031Sstas 75226031Sstas/* 76226031Sstas * Long passwords, i.e 9 characters or more. 77226031Sstas */ 78226031Sstasstatic void 79226031Sstaskrb5_DES_AFS3_Transarc_string_to_key (krb5_data pw, 80226031Sstas krb5_data cell, 81226031Sstas DES_cblock *key) 82226031Sstas{ 83226031Sstas DES_key_schedule schedule; 84226031Sstas DES_cblock temp_key; 85226031Sstas DES_cblock ivec; 86226031Sstas char password[512]; 87226031Sstas size_t passlen; 88226031Sstas 89226031Sstas memcpy(password, pw.data, min(pw.length, sizeof(password))); 90226031Sstas if(pw.length < sizeof(password)) { 91226031Sstas int len = min(cell.length, sizeof(password) - pw.length); 92226031Sstas size_t i; 93226031Sstas 94226031Sstas memcpy(password + pw.length, cell.data, len); 95226031Sstas for (i = pw.length; i < pw.length + len; ++i) 96226031Sstas password[i] = tolower((unsigned char)password[i]); 97226031Sstas } 98226031Sstas passlen = min(sizeof(password), pw.length + cell.length); 99226031Sstas memcpy(&ivec, "kerberos", 8); 100226031Sstas memcpy(&temp_key, "kerberos", 8); 101226031Sstas DES_set_odd_parity (&temp_key); 102226031Sstas DES_set_key_unchecked (&temp_key, &schedule); 103226031Sstas DES_cbc_cksum ((void*)password, &ivec, passlen, &schedule, &ivec); 104226031Sstas 105226031Sstas memcpy(&temp_key, &ivec, 8); 106226031Sstas DES_set_odd_parity (&temp_key); 107226031Sstas DES_set_key_unchecked (&temp_key, &schedule); 108226031Sstas DES_cbc_cksum ((void*)password, key, passlen, &schedule, &ivec); 109226031Sstas memset(&schedule, 0, sizeof(schedule)); 110226031Sstas memset(&temp_key, 0, sizeof(temp_key)); 111226031Sstas memset(&ivec, 0, sizeof(ivec)); 112226031Sstas memset(password, 0, sizeof(password)); 113226031Sstas 114226031Sstas DES_set_odd_parity (key); 115226031Sstas} 116226031Sstas 117226031Sstasstatic krb5_error_code 118226031SstasDES_AFS3_string_to_key(krb5_context context, 119226031Sstas krb5_enctype enctype, 120226031Sstas krb5_data password, 121226031Sstas krb5_salt salt, 122226031Sstas krb5_data opaque, 123226031Sstas krb5_keyblock *key) 124226031Sstas{ 125226031Sstas DES_cblock tmp; 126226031Sstas if(password.length > 8) 127226031Sstas krb5_DES_AFS3_Transarc_string_to_key(password, salt.saltvalue, &tmp); 128226031Sstas else 129226031Sstas krb5_DES_AFS3_CMU_string_to_key(password, salt.saltvalue, &tmp); 130226031Sstas key->keytype = enctype; 131226031Sstas krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp)); 132226031Sstas memset(&key, 0, sizeof(key)); 133226031Sstas return 0; 134226031Sstas} 135226031Sstas#endif /* ENABLE_AFS_STRING_TO_KEY */ 136226031Sstas 137226031Sstasstatic void 138226031SstasDES_string_to_key_int(unsigned char *data, size_t length, DES_cblock *key) 139226031Sstas{ 140226031Sstas DES_key_schedule schedule; 141226031Sstas size_t i; 142226031Sstas int reverse = 0; 143226031Sstas unsigned char *p; 144226031Sstas 145226031Sstas unsigned char swap[] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 146226031Sstas 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf }; 147226031Sstas memset(key, 0, 8); 148226031Sstas 149226031Sstas p = (unsigned char*)key; 150226031Sstas for (i = 0; i < length; i++) { 151226031Sstas unsigned char tmp = data[i]; 152226031Sstas if (!reverse) 153226031Sstas *p++ ^= (tmp << 1); 154226031Sstas else 155226031Sstas *--p ^= (swap[tmp & 0xf] << 4) | swap[(tmp & 0xf0) >> 4]; 156226031Sstas if((i % 8) == 7) 157226031Sstas reverse = !reverse; 158226031Sstas } 159226031Sstas DES_set_odd_parity(key); 160226031Sstas if(DES_is_weak_key(key)) 161226031Sstas (*key)[7] ^= 0xF0; 162226031Sstas DES_set_key_unchecked(key, &schedule); 163226031Sstas DES_cbc_cksum((void*)data, key, length, &schedule, key); 164226031Sstas memset(&schedule, 0, sizeof(schedule)); 165226031Sstas DES_set_odd_parity(key); 166226031Sstas if(DES_is_weak_key(key)) 167226031Sstas (*key)[7] ^= 0xF0; 168226031Sstas} 169226031Sstas 170226031Sstasstatic krb5_error_code 171226031Sstaskrb5_DES_string_to_key(krb5_context context, 172226031Sstas krb5_enctype enctype, 173226031Sstas krb5_data password, 174226031Sstas krb5_salt salt, 175226031Sstas krb5_data opaque, 176226031Sstas krb5_keyblock *key) 177226031Sstas{ 178226031Sstas unsigned char *s; 179226031Sstas size_t len; 180226031Sstas DES_cblock tmp; 181226031Sstas 182226031Sstas#ifdef ENABLE_AFS_STRING_TO_KEY 183226031Sstas if (opaque.length == 1) { 184226031Sstas unsigned long v; 185226031Sstas _krb5_get_int(opaque.data, &v, 1); 186226031Sstas if (v == 1) 187226031Sstas return DES_AFS3_string_to_key(context, enctype, password, 188226031Sstas salt, opaque, key); 189226031Sstas } 190226031Sstas#endif 191226031Sstas 192226031Sstas len = password.length + salt.saltvalue.length; 193226031Sstas s = malloc(len); 194226031Sstas if(len > 0 && s == NULL) { 195226031Sstas krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 196226031Sstas return ENOMEM; 197226031Sstas } 198226031Sstas memcpy(s, password.data, password.length); 199226031Sstas memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length); 200226031Sstas DES_string_to_key_int(s, len, &tmp); 201226031Sstas key->keytype = enctype; 202226031Sstas krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp)); 203226031Sstas memset(&tmp, 0, sizeof(tmp)); 204226031Sstas memset(s, 0, len); 205226031Sstas free(s); 206226031Sstas return 0; 207226031Sstas} 208226031Sstas 209226031Sstasstruct salt_type _krb5_des_salt[] = { 210226031Sstas { 211226031Sstas KRB5_PW_SALT, 212226031Sstas "pw-salt", 213226031Sstas krb5_DES_string_to_key 214226031Sstas }, 215226031Sstas#ifdef ENABLE_AFS_STRING_TO_KEY 216226031Sstas { 217226031Sstas KRB5_AFS3_SALT, 218226031Sstas "afs3-salt", 219226031Sstas DES_AFS3_string_to_key 220226031Sstas }, 221226031Sstas#endif 222226031Sstas { 0 } 223226031Sstas}; 224226031Sstas#endif 225