1 /* $NetBSD: pkcs5.c,v 1.2 2017/01/28 21:31:47 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2006 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 <config.h> 37 #include <krb5/roken.h> 38 39 #ifdef KRB5 40 #include <krb5/krb5-types.h> 41 #endif 42 43 #include <evp.h> 44 #include <hmac.h> 45 46 /** 47 * As descriped in PKCS5, convert a password, salt, and iteration counter into a crypto key. 48 * 49 * @param password Password. 50 * @param password_len Length of password. 51 * @param salt Salt 52 * @param salt_len Length of salt. 53 * @param iter iteration counter. 54 * @param md the digest function. 55 * @param keylen the output key length. 56 * @param key the output key. 57 * 58 * @return 1 on success, non 1 on failure. 59 * 60 * @ingroup hcrypto_misc 61 */ 62 63 int 64 PKCS5_PBKDF2_HMAC(const void * password, size_t password_len, 65 const void * salt, size_t salt_len, 66 unsigned long iter, 67 const EVP_MD *md, 68 size_t keylen, void *key) 69 { 70 size_t datalen, leftofkey, checksumsize; 71 char *data, *tmpcksum; 72 uint32_t keypart; 73 unsigned long i; 74 int j; 75 char *p; 76 unsigned int hmacsize; 77 78 if (md == NULL) 79 return 0; 80 81 checksumsize = EVP_MD_size(md); 82 datalen = salt_len + 4; 83 84 tmpcksum = malloc(checksumsize + datalen); 85 if (tmpcksum == NULL) 86 return 0; 87 88 data = &tmpcksum[checksumsize]; 89 90 memcpy(data, salt, salt_len); 91 92 keypart = 1; 93 leftofkey = keylen; 94 p = key; 95 96 while (leftofkey) { 97 int len; 98 99 if (leftofkey > checksumsize) 100 len = checksumsize; 101 else 102 len = leftofkey; 103 104 data[datalen - 4] = (keypart >> 24) & 0xff; 105 data[datalen - 3] = (keypart >> 16) & 0xff; 106 data[datalen - 2] = (keypart >> 8) & 0xff; 107 data[datalen - 1] = (keypart) & 0xff; 108 109 HMAC(md, password, password_len, data, datalen, 110 tmpcksum, &hmacsize); 111 112 memcpy(p, tmpcksum, len); 113 for (i = 1; i < iter; i++) { 114 HMAC(md, password, password_len, tmpcksum, checksumsize, 115 tmpcksum, &hmacsize); 116 117 for (j = 0; j < len; j++) 118 p[j] ^= tmpcksum[j]; 119 } 120 121 p += len; 122 leftofkey -= len; 123 keypart++; 124 } 125 126 free(tmpcksum); 127 128 return 1; 129 } 130 131 /** 132 * As descriped in PKCS5, convert a password, salt, and iteration counter into a crypto key. 133 * 134 * @param password Password. 135 * @param password_len Length of password. 136 * @param salt Salt 137 * @param salt_len Length of salt. 138 * @param iter iteration counter. 139 * @param keylen the output key length. 140 * @param key the output key. 141 * 142 * @return 1 on success, non 1 on failure. 143 * 144 * @ingroup hcrypto_misc 145 */ 146 int 147 PKCS5_PBKDF2_HMAC_SHA1(const void * password, size_t password_len, 148 const void * salt, size_t salt_len, 149 unsigned long iter, 150 size_t keylen, void *key) 151 { 152 return PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, iter, 153 EVP_sha1(), keylen, key); 154 } 155