1e28a4053SRui Paulo /* 2e28a4053SRui Paulo * SHA1 T-PRF for EAP-FAST 3e28a4053SRui Paulo * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> 4e28a4053SRui Paulo * 5f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6f05cddf9SRui Paulo * See README for more details. 7e28a4053SRui Paulo */ 8e28a4053SRui Paulo 9e28a4053SRui Paulo #include "includes.h" 10e28a4053SRui Paulo 11e28a4053SRui Paulo #include "common.h" 12e28a4053SRui Paulo #include "sha1.h" 13e28a4053SRui Paulo #include "crypto.h" 14e28a4053SRui Paulo 15e28a4053SRui Paulo /** 16e28a4053SRui Paulo * sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF) 17e28a4053SRui Paulo * @key: Key for PRF 18e28a4053SRui Paulo * @key_len: Length of the key in bytes 19e28a4053SRui Paulo * @label: A unique label for each purpose of the PRF 20e28a4053SRui Paulo * @seed: Seed value to bind into the key 21e28a4053SRui Paulo * @seed_len: Length of the seed 22e28a4053SRui Paulo * @buf: Buffer for the generated pseudo-random key 23e28a4053SRui Paulo * @buf_len: Number of bytes of key to generate 24e28a4053SRui Paulo * Returns: 0 on success, -1 of failure 25e28a4053SRui Paulo * 26e28a4053SRui Paulo * This function is used to derive new, cryptographically separate keys from a 27e28a4053SRui Paulo * given key for EAP-FAST. T-PRF is defined in RFC 4851, Section 5.5. 28e28a4053SRui Paulo */ 29e28a4053SRui Paulo int sha1_t_prf(const u8 *key, size_t key_len, const char *label, 30e28a4053SRui Paulo const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len) 31e28a4053SRui Paulo { 32e28a4053SRui Paulo unsigned char counter = 0; 33e28a4053SRui Paulo size_t pos, plen; 34e28a4053SRui Paulo u8 hash[SHA1_MAC_LEN]; 35e28a4053SRui Paulo size_t label_len = os_strlen(label); 36e28a4053SRui Paulo u8 output_len[2]; 37e28a4053SRui Paulo const unsigned char *addr[5]; 38e28a4053SRui Paulo size_t len[5]; 39e28a4053SRui Paulo 40e28a4053SRui Paulo addr[0] = hash; 41e28a4053SRui Paulo len[0] = 0; 42e28a4053SRui Paulo addr[1] = (unsigned char *) label; 43e28a4053SRui Paulo len[1] = label_len + 1; 44e28a4053SRui Paulo addr[2] = seed; 45e28a4053SRui Paulo len[2] = seed_len; 46e28a4053SRui Paulo addr[3] = output_len; 47e28a4053SRui Paulo len[3] = 2; 48e28a4053SRui Paulo addr[4] = &counter; 49e28a4053SRui Paulo len[4] = 1; 50e28a4053SRui Paulo 51e28a4053SRui Paulo output_len[0] = (buf_len >> 8) & 0xff; 52e28a4053SRui Paulo output_len[1] = buf_len & 0xff; 53e28a4053SRui Paulo pos = 0; 54e28a4053SRui Paulo while (pos < buf_len) { 55e28a4053SRui Paulo counter++; 56e28a4053SRui Paulo plen = buf_len - pos; 57e28a4053SRui Paulo if (hmac_sha1_vector(key, key_len, 5, addr, len, hash)) 58e28a4053SRui Paulo return -1; 59e28a4053SRui Paulo if (plen >= SHA1_MAC_LEN) { 60e28a4053SRui Paulo os_memcpy(&buf[pos], hash, SHA1_MAC_LEN); 61e28a4053SRui Paulo pos += SHA1_MAC_LEN; 62e28a4053SRui Paulo } else { 63e28a4053SRui Paulo os_memcpy(&buf[pos], hash, plen); 64e28a4053SRui Paulo break; 65e28a4053SRui Paulo } 66e28a4053SRui Paulo len[0] = SHA1_MAC_LEN; 67e28a4053SRui Paulo } 68e28a4053SRui Paulo 69*325151a3SRui Paulo os_memset(hash, 0, SHA1_MAC_LEN); 70*325151a3SRui Paulo 71e28a4053SRui Paulo return 0; 72e28a4053SRui Paulo } 73