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