161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/* 261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * SHA256-based PRF (IEEE 802.11r) 3a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi> 461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * 561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * See README for more details. 761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "includes.h" 1061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "common.h" 1261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "sha256.h" 1361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "crypto.h" 1461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/** 1761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2) 1861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @key: Key for PRF 1961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @key_len: Length of the key in bytes 2061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @label: A unique label for each purpose of the PRF 2161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @data: Extra data to bind into the key 2261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @data_len: Length of the data 2361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @buf: Buffer for the generated pseudo-random key 2461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @buf_len: Number of bytes of key to generate 2561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * 2661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * This function is used to derive new, cryptographically separate keys from a 2761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * given key. 2861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 2961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid sha256_prf(const u8 *key, size_t key_len, const char *label, 3061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *data, size_t data_len, u8 *buf, size_t buf_len) 3161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 32a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sha256_prf_bits(key, key_len, label, data, data_len, buf, buf_len * 8); 33a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 34a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 35a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 36a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 37a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * sha256_prf_bits - IEEE Std 802.11-2012, 11.6.1.7.2 Key derivation function 38a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @key: Key for KDF 39a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @key_len: Length of the key in bytes 40a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @label: A unique label for each purpose of the PRF 41a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @data: Extra data to bind into the key 42a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @data_len: Length of the data 43a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @buf: Buffer for the generated pseudo-random key 44a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @buf_len: Number of bits of key to generate 45a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 46a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function is used to derive new, cryptographically separate keys from a 47a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * given key. If the requested buf_len is not divisible by eight, the least 48a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * significant 1-7 bits of the last octet in the output are not part of the 49a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * requested output. 50a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 51a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtvoid sha256_prf_bits(const u8 *key, size_t key_len, const char *label, 52a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt const u8 *data, size_t data_len, u8 *buf, 53a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t buf_len_bits) 54a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 5561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u16 counter = 1; 5661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t pos, plen; 5761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 hash[SHA256_MAC_LEN]; 5861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *addr[4]; 5961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len[4]; 6061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 counter_le[2], length_le[2]; 61a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t buf_len = (buf_len_bits + 7) / 8; 6261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt addr[0] = counter_le; 6461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len[0] = 2; 6561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt addr[1] = (u8 *) label; 6661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len[1] = os_strlen(label); 6761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt addr[2] = data; 6861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len[2] = data_len; 6961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt addr[3] = length_le; 7061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len[3] = sizeof(length_le); 7161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 72a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt WPA_PUT_LE16(length_le, buf_len_bits); 7361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = 0; 7461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (pos < buf_len) { 7561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt plen = buf_len - pos; 7661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WPA_PUT_LE16(counter_le, counter); 7761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (plen >= SHA256_MAC_LEN) { 7861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hmac_sha256_vector(key, key_len, 4, addr, len, 7961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &buf[pos]); 8061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += SHA256_MAC_LEN; 8161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 8261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hmac_sha256_vector(key, key_len, 4, addr, len, hash); 8361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(&buf[pos], hash, plen); 84a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt pos += plen; 8561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 8661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 8761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt counter++; 8861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 89a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 90a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 91a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Mask out unused bits in the last octet if it does not use all the 92a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * bits. 93a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 94a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (buf_len_bits % 8) { 95a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 mask = 0xff << (8 - buf_len_bits % 8); 96a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt buf[pos - 1] &= mask; 97a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 9861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 99