1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * lib/crypto/pbkdf2.c 8 * 9 * Copyright 2002 by the Massachusetts Institute of Technology. 10 * All Rights Reserved. 11 * 12 * Export of this software from the United States of America may 13 * require a specific license from the United States Government. 14 * It is the responsibility of any person or organization contemplating 15 * export to obtain such a license before exporting. 16 * 17 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 18 * distribute this software and its documentation for any purpose and 19 * without fee is hereby granted, provided that the above copyright 20 * notice appear in all copies and that both that copyright notice and 21 * this permission notice appear in supporting documentation, and that 22 * the name of M.I.T. not be used in advertising or publicity pertaining 23 * to distribution of the software without specific, written prior 24 * permission. Furthermore if you modify this software you must label 25 * your software as modified software and not distribute it in such a 26 * fashion that it might be confused with the original M.I.T. software. 27 * M.I.T. makes no representations about the suitability of 28 * this software for any purpose. It is provided "as is" without express 29 * or implied warranty. 30 * 31 * 32 * Implementation of PBKDF2 from RFC 2898. 33 * Not currently used; likely to be used when we get around to AES support. 34 */ 35 36 #ifndef _KERNEL 37 38 #include <ctype.h> 39 #include "k5-int.h" 40 #include "hash_provider.h" 41 42 /* 43 * Solaris Kerberos: 44 * MIT code ripped out, use PBKDF2 algorithm from PKCS#11 45 * provider. 46 */ 47 krb5_error_code 48 krb5int_pbkdf2_hmac_sha1( 49 krb5_context context, 50 const krb5_data *out, 51 unsigned long count, 52 krb5_enctype enctype, 53 const krb5_data *pass, const krb5_data *salt) 54 { 55 krb5_error_code ret = 0; 56 CK_RV rv; 57 CK_PKCS5_PBKD2_PARAMS params; 58 CK_MECHANISM mechanism; 59 CK_OBJECT_CLASS class = CKO_SECRET_KEY; 60 CK_ATTRIBUTE tmpl[3]; 61 CK_KEY_TYPE keytype; 62 CK_OBJECT_HANDLE hKey; 63 int attrs = 0; 64 CK_ULONG outlen, passlen; 65 66 mechanism.mechanism = CKM_PKCS5_PBKD2; 67 mechanism.pParameter = ¶ms; 68 mechanism.ulParameterLen = sizeof (params); 69 70 tmpl[attrs].type = CKA_CLASS; 71 tmpl[attrs].pValue = &class; 72 tmpl[attrs].ulValueLen = sizeof (class); 73 attrs++; 74 75 rv = get_key_type(enctype, &keytype); 76 if (rv != CKR_OK) 77 return (PKCS_ERR); 78 79 tmpl[attrs].type = CKA_KEY_TYPE; 80 tmpl[attrs].pValue = &keytype; 81 tmpl[attrs].ulValueLen = sizeof (keytype); 82 attrs++; 83 84 /* 85 * For DES key types, do not include the value len attr. 86 */ 87 if (out->length > 0 && 88 enctype != ENCTYPE_DES_CBC_CRC && 89 enctype != ENCTYPE_DES_CBC_MD5 && 90 enctype != ENCTYPE_DES_CBC_RAW && 91 enctype != ENCTYPE_DES_HMAC_SHA1 && 92 enctype != ENCTYPE_DES3_CBC_SHA1 && 93 enctype != ENCTYPE_DES3_CBC_RAW) { 94 tmpl[attrs].type = CKA_VALUE_LEN; 95 /* using outlen to avoid 64bit alignment issues */ 96 outlen = (CK_ULONG)out->length; 97 tmpl[attrs].pValue = &outlen; 98 tmpl[attrs].ulValueLen = sizeof (outlen); 99 attrs++; 100 } 101 102 params.saltSource = CKZ_SALT_SPECIFIED; 103 params.pSaltSourceData = (void *)salt->data; 104 params.ulSaltSourceDataLen = salt->length; 105 params.iterations = count; 106 params.prf = CKP_PKCS5_PBKD2_HMAC_SHA1; 107 params.pPrfData = NULL; 108 params.ulPrfDataLen = 0; 109 params.pPassword = (CK_UTF8CHAR_PTR)pass->data; 110 /* using passlen to avoid 64bit alignment issues */ 111 passlen = (CK_ULONG)pass->length; 112 params.ulPasswordLen = &passlen; 113 114 rv = C_GenerateKey(krb_ctx_hSession(context), &mechanism, tmpl, 115 attrs, &hKey); 116 117 if (rv != CKR_OK) 118 ret = PKCS_ERR; 119 else { 120 /* Get the value from the key object. */ 121 tmpl[0].type = CKA_VALUE; 122 tmpl[0].pValue = out->data; 123 tmpl[0].ulValueLen = out->length; 124 rv = C_GetAttributeValue(krb_ctx_hSession(context), hKey, 125 tmpl, 1); 126 if (rv != CKR_OK) 127 ret = PKCS_ERR; 128 (void) C_DestroyObject(krb_ctx_hSession(context), hKey); 129 } 130 131 return (ret); 132 } 133 #endif /* !_KERNEL */ 134