/* * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "krb5_locl.h" #ifdef DES3_OLD_ENCTYPE static krb5_error_code DES3_string_to_key(krb5_context context, krb5_enctype enctype, krb5_data password, krb5_salt salt, krb5_data opaque, krb5_keyblock *key) { char *str; size_t len; unsigned char tmp[24]; DES_cblock keys[3]; krb5_error_code ret; len = password.length + salt.saltvalue.length; str = malloc(len); if (len != 0 && str == NULL) return krb5_enomem(context); memcpy(str, password.data, password.length); memcpy(str + password.length, salt.saltvalue.data, salt.saltvalue.length); { DES_cblock ivec; DES_key_schedule s[3]; int i; ret = _krb5_n_fold(str, len, tmp, 24); if (ret) { memset_s(str, len, 0, len); free(str); krb5_set_error_message(context, ret, N_("malloc: out of memory", "")); return ret; } for(i = 0; i < 3; i++){ memcpy(keys + i, tmp + i * 8, sizeof(keys[i])); DES_set_odd_parity(keys + i); if(DES_is_weak_key(keys + i)) _krb5_xor8(*(keys + i), (const unsigned char*)"\0\0\0\0\0\0\0\xf0"); DES_set_key_unchecked(keys + i, &s[i]); } memset_s(&ivec, sizeof(ivec), 0, sizeof(ivec)); DES_ede3_cbc_encrypt(tmp, tmp, sizeof(tmp), &s[0], &s[1], &s[2], &ivec, DES_ENCRYPT); memset_s(s, sizeof(s), 0, sizeof(s)); memset_s(&ivec, sizeof(ivec), 0, sizeof(ivec)); for(i = 0; i < 3; i++){ memcpy(keys + i, tmp + i * 8, sizeof(keys[i])); DES_set_odd_parity(keys + i); if(DES_is_weak_key(keys + i)) _krb5_xor8(*(keys + i), (const unsigned char*)"\0\0\0\0\0\0\0\xf0"); } memset_s(tmp, sizeof(tmp), 0, sizeof(tmp)); } key->keytype = enctype; krb5_data_copy(&key->keyvalue, keys, sizeof(keys)); memset_s(keys, sizeof(keys), 0, sizeof(keys)); memset_s(str, len, 0, len); free(str); return 0; } #endif static krb5_error_code DES3_string_to_key_derived(krb5_context context, krb5_enctype enctype, krb5_data password, krb5_salt salt, krb5_data opaque, krb5_keyblock *key) { krb5_error_code ret; size_t len = password.length + salt.saltvalue.length; char *s; s = malloc(len); if (len != 0 && s == NULL) return krb5_enomem(context); memcpy(s, password.data, password.length); memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length); ret = krb5_string_to_key_derived(context, s, len, enctype, key); memset_s(s, len, 0, len); free(s); return ret; } #ifdef DES3_OLD_ENCTYPE struct salt_type _krb5_des3_salt[] = { { KRB5_PW_SALT, "pw-salt", DES3_string_to_key }, { 0, NULL, NULL } }; #endif struct salt_type _krb5_des3_salt_derived[] = { { KRB5_PW_SALT, "pw-salt", DES3_string_to_key_derived }, { 0, NULL, NULL } };