1/* $NetBSD: salt-aes-sha2.c,v 1.3 2023/06/19 21:41:44 christos Exp $ */ 2 3/* 4 * Copyright (c) 1997 - 2008 Kungliga Tekniska H��gskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include "krb5_locl.h" 37 38int _krb5_AES_SHA2_string_to_default_iterator = 32768; 39 40static krb5_error_code 41AES_SHA2_string_to_key(krb5_context context, 42 krb5_enctype enctype, 43 krb5_data password, 44 krb5_salt salt, 45 krb5_data opaque, 46 krb5_keyblock *key) 47{ 48 krb5_error_code ret; 49 uint32_t iter; 50 struct _krb5_encryption_type *et = NULL; 51 struct _krb5_key_data kd; 52 krb5_data saltp; 53 size_t enctypesz; 54 const EVP_MD *md = NULL; 55 56 krb5_data_zero(&saltp); 57 kd.key = NULL; 58 kd.schedule = NULL; 59 60 if (opaque.length == 0) { 61 iter = _krb5_AES_SHA2_string_to_default_iterator; 62 } else if (opaque.length == 4) { 63 unsigned long v; 64 _krb5_get_int(opaque.data, &v, 4); 65 iter = ((uint32_t)v); 66 } else { 67 ret = KRB5_PROG_KEYTYPE_NOSUPP; /* XXX */ 68 goto cleanup; 69 } 70 71 et = _krb5_find_enctype(enctype); 72 if (et == NULL) { 73 ret = KRB5_PROG_KEYTYPE_NOSUPP; 74 goto cleanup; 75 } 76 77 kd.schedule = NULL; 78 ALLOC(kd.key, 1); 79 if (kd.key == NULL) { 80 ret = krb5_enomem(context); 81 goto cleanup; 82 } 83 kd.key->keytype = enctype; 84 ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size); 85 if (ret) { 86 ret = krb5_enomem(context); 87 goto cleanup; 88 } 89 90 enctypesz = strlen(et->name) + 1; 91 ret = krb5_data_alloc(&saltp, enctypesz + salt.saltvalue.length); 92 if (ret) { 93 ret = krb5_enomem(context); 94 goto cleanup; 95 } 96 memcpy(saltp.data, et->name, enctypesz); 97 if (salt.saltvalue.length) 98 memcpy((unsigned char *)saltp.data + enctypesz, 99 salt.saltvalue.data, salt.saltvalue.length); 100 101 ret = _krb5_aes_sha2_md_for_enctype(context, enctype, &md); 102 if (ret) 103 goto cleanup; 104 105 ret = PKCS5_PBKDF2_HMAC(password.data, password.length, 106 saltp.data, saltp.length, 107 iter, md, 108 et->keytype->size, kd.key->keyvalue.data); 109 if (ret != 1) { 110 krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP, 111 "Error calculating s2k"); 112 ret = KRB5_PROG_KEYTYPE_NOSUPP; 113 goto cleanup; 114 } 115 116 ret = _krb5_derive_key(context, et, &kd, "kerberos", strlen("kerberos")); 117 if (ret) 118 goto cleanup; 119 120 ret = krb5_copy_keyblock_contents(context, kd.key, key); 121 if (ret) 122 goto cleanup; 123 124cleanup: 125 krb5_data_free(&saltp); 126 _krb5_free_key_data(context, &kd, et); 127 128 return ret; 129} 130 131struct salt_type _krb5_AES_SHA2_salt[] = { 132 { 133 KRB5_PW_SALT, 134 "pw-salt", 135 AES_SHA2_string_to_key 136 }, 137 { 0, NULL, NULL } 138}; 139