1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 7 /* 8 * lib/crypto/aes/aes_s2k.c 9 * 10 * Copyright 2003 by the Massachusetts Institute of Technology. 11 * All Rights Reserved. 12 * 13 * Export of this software from the United States of America may 14 * require a specific license from the United States Government. 15 * It is the responsibility of any person or organization contemplating 16 * export to obtain such a license before exporting. 17 * 18 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 19 * distribute this software and its documentation for any purpose and 20 * without fee is hereby granted, provided that the above copyright 21 * notice appear in all copies and that both that copyright notice and 22 * this permission notice appear in supporting documentation, and that 23 * the name of M.I.T. not be used in advertising or publicity pertaining 24 * to distribution of the software without specific, written prior 25 * permission. Furthermore if you modify this software you must label 26 * your software as modified software and not distribute it in such a 27 * fashion that it might be confused with the original M.I.T. software. 28 * M.I.T. makes no representations about the suitability of 29 * this software for any purpose. It is provided "as is" without express 30 * or implied warranty. 31 * 32 * 33 * krb5int_aes_string_to_key 34 */ 35 36 #include "k5-int.h" 37 #include "dk.h" 38 #include "aes_s2k.h" 39 40 #define DEFAULT_ITERATION_COUNT 4096 /* was 0xb000L in earlier drafts */ 41 #define MAX_ITERATION_COUNT 0x1000000L 42 43 krb5_error_code 44 krb5int_aes_string_to_key(krb5_context context, 45 const struct krb5_enc_provider *enc, 46 const krb5_data *string, 47 const krb5_data *salt, 48 const krb5_data *params, 49 krb5_keyblock *key) 50 { 51 unsigned long iter_count; 52 krb5_data out; 53 static const krb5_data usage = { KV5M_DATA, 8, "kerberos" }; 54 krb5_error_code err; 55 /* Solaris Kerberos */ 56 krb5_keyblock *inkey = NULL; 57 58 if (params) { 59 unsigned char *p = (unsigned char *) params->data; 60 if (params->length != 4) 61 return KRB5_ERR_BAD_S2K_PARAMS; 62 /* The first two need casts in case 'int' is 16 bits. */ 63 iter_count = (((unsigned long)p[0] << 24) 64 | ((unsigned long)p[1] << 16) 65 | (p[2] << 8) 66 | (p[3])); 67 if (iter_count == 0) { 68 /* 69 iter_count = (1L << 16) << 16; 70 if (((iter_count >> 16) >> 16) != 1) 71 return KRB5_ERR_BAD_S2K_PARAMS; 72 */ 73 iter_count = DEFAULT_ITERATION_COUNT; 74 } 75 } else 76 iter_count = DEFAULT_ITERATION_COUNT; 77 78 /* This is not a protocol specification constraint; this is an 79 implementation limit, which should eventually be controlled by 80 a config file. */ 81 if (iter_count >= MAX_ITERATION_COUNT) 82 return KRB5_ERR_BAD_S2K_PARAMS; 83 84 /* 85 * Dense key space, no parity bits or anything, so take a shortcut 86 * and use the key contents buffer for the generated bytes. 87 */ 88 /* Solaris Kerberos */ 89 if (key->length != 16 && key->length != 32) 90 return KRB5_CRYPTO_INTERNAL; 91 out.data = (char *) key->contents; 92 out.length = key->length; 93 /* Solaris Kerberos */ 94 err = krb5int_pbkdf2_hmac_sha1 (context, &out, iter_count, key->enctype, 95 string, salt); 96 if (err) { 97 memset(out.data, 0, out.length); 98 return err; 99 } 100 101 /* 102 * Solaris Kerberos: 103 * The derive key operation below will not work correctly 104 * if the input and output key pointers are to the same 105 * data. This is because the key object handle (PKCS#11) 106 * gets out-of-sync with the original key when the contents 107 * are modified. We copy the original key here for use 108 * below in the derive_key step, then we free this key 109 * before exiting. 110 */ 111 err = krb5_copy_keyblock(context, key, &inkey); 112 if (err) { 113 memset(out.data, 0, out.length); 114 return err; 115 } 116 117 err = krb5_derive_key (context, enc, inkey, key, &usage); 118 if (err) { 119 memset(out.data, 0, out.length); 120 } 121 krb5_free_keyblock(context, inkey); 122 123 return (err); 124 } 125