sha1-tprf.c revision c5ec7f57ead87efa365800228aa0b09a12d9e6c4
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SHA1 T-PRF for EAP-FAST 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sha1.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF) 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @key: Key for PRF 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @key_len: Length of the key in bytes 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @label: A unique label for each purpose of the PRF 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @seed: Seed value to bind into the key 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @seed_len: Length of the seed 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for the generated pseudo-random key 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf_len: Number of bytes of key to generate 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 of failure 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to derive new, cryptographically separate keys from a 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * given key for EAP-FAST. T-PRF is defined in RFC 4851, Section 5.5. 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint sha1_t_prf(const u8 *key, size_t key_len, const char *label, 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len) 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char counter = 0; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t pos, plen; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[SHA1_MAC_LEN]; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t label_len = os_strlen(label); 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 output_len[2]; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const unsigned char *addr[5]; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len[5]; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = hash; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = 0; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[1] = (unsigned char *) label; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[1] = label_len + 1; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[2] = seed; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[2] = seed_len; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[3] = output_len; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[3] = 2; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[4] = &counter; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[4] = 1; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt output_len[0] = (buf_len >> 8) & 0xff; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt output_len[1] = buf_len & 0xff; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = 0; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < buf_len) { 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter++; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = buf_len - pos; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hmac_sha1_vector(key, key_len, 5, addr, len, hash)) 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen >= SHA1_MAC_LEN) { 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&buf[pos], hash, SHA1_MAC_LEN); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += SHA1_MAC_LEN; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&buf[pos], hash, plen); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = SHA1_MAC_LEN; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 71