sha1-pbkdf2.c revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
1/* 2 * SHA1-based key derivation function (PBKDF2) for IEEE 802.11i 3 * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15#include "includes.h" 16 17#include "common.h" 18#include "sha1.h" 19 20static int pbkdf2_sha1_f(const char *passphrase, const char *ssid, 21 size_t ssid_len, int iterations, unsigned int count, 22 u8 *digest) 23{ 24 unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN]; 25 int i, j; 26 unsigned char count_buf[4]; 27 const u8 *addr[2]; 28 size_t len[2]; 29 size_t passphrase_len = os_strlen(passphrase); 30 31 addr[0] = (u8 *) ssid; 32 len[0] = ssid_len; 33 addr[1] = count_buf; 34 len[1] = 4; 35 36 /* F(P, S, c, i) = U1 xor U2 xor ... Uc 37 * U1 = PRF(P, S || i) 38 * U2 = PRF(P, U1) 39 * Uc = PRF(P, Uc-1) 40 */ 41 42 count_buf[0] = (count >> 24) & 0xff; 43 count_buf[1] = (count >> 16) & 0xff; 44 count_buf[2] = (count >> 8) & 0xff; 45 count_buf[3] = count & 0xff; 46 if (hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len, 47 tmp)) 48 return -1; 49 os_memcpy(digest, tmp, SHA1_MAC_LEN); 50 51 for (i = 1; i < iterations; i++) { 52 if (hmac_sha1((u8 *) passphrase, passphrase_len, tmp, 53 SHA1_MAC_LEN, tmp2)) 54 return -1; 55 os_memcpy(tmp, tmp2, SHA1_MAC_LEN); 56 for (j = 0; j < SHA1_MAC_LEN; j++) 57 digest[j] ^= tmp2[j]; 58 } 59 60 return 0; 61} 62 63 64/** 65 * pbkdf2_sha1 - SHA1-based key derivation function (PBKDF2) for IEEE 802.11i 66 * @passphrase: ASCII passphrase 67 * @ssid: SSID 68 * @ssid_len: SSID length in bytes 69 * @iterations: Number of iterations to run 70 * @buf: Buffer for the generated key 71 * @buflen: Length of the buffer in bytes 72 * Returns: 0 on success, -1 of failure 73 * 74 * This function is used to derive PSK for WPA-PSK. For this protocol, 75 * iterations is set to 4096 and buflen to 32. This function is described in 76 * IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0. 77 */ 78int pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, 79 int iterations, u8 *buf, size_t buflen) 80{ 81 unsigned int count = 0; 82 unsigned char *pos = buf; 83 size_t left = buflen, plen; 84 unsigned char digest[SHA1_MAC_LEN]; 85 86 while (left > 0) { 87 count++; 88 if (pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, 89 count, digest)) 90 return -1; 91 plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left; 92 os_memcpy(pos, digest, plen); 93 pos += plen; 94 left -= plen; 95 } 96 97 return 0; 98} 99