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