sha256-tlsprf.c revision 252190
121308Sache/* 221308Sache * TLS PRF P_SHA256 3136644Sache * Copyright (c) 2011, Jouni Malinen <j@w1.fi> 421308Sache * 521308Sache * This software may be distributed under the terms of the BSD license. 621308Sache * See README for more details. 721308Sache */ 821308Sache 921308Sache#include "includes.h" 1058310Sache 1121308Sache#include "common.h" 1221308Sache#include "sha256.h" 1321308Sache 1421308Sache 1521308Sache/** 1621308Sache * tls_prf_sha256 - Pseudo-Random Function for TLS v1.2 (P_SHA256, RFC 5246) 1721308Sache * @secret: Key for PRF 1821308Sache * @secret_len: Length of the key in bytes 1921308Sache * @label: A unique label for each purpose of the PRF 2021308Sache * @seed: Seed value to bind into the key 2158310Sache * @seed_len: Length of the seed 2221308Sache * @out: Buffer for the generated pseudo-random key 2321308Sache * @outlen: Number of bytes of key to generate 2421308Sache * Returns: 0 on success, -1 on failure. 2521308Sache * 2621308Sache * This function is used to derive new, cryptographically separate keys from a 2721308Sache * given key in TLS. This PRF is defined in RFC 2246, Chapter 5. 2821308Sache */ 2921308Sachevoid tls_prf_sha256(const u8 *secret, size_t secret_len, const char *label, 3021308Sache const u8 *seed, size_t seed_len, u8 *out, size_t outlen) 3121308Sache{ 3221308Sache size_t clen; 3321308Sache u8 A[SHA256_MAC_LEN]; 3421308Sache u8 P[SHA256_MAC_LEN]; 3521308Sache size_t pos; 3621308Sache const unsigned char *addr[3]; 3721308Sache size_t len[3]; 3835486Sache 3935486Sache addr[0] = A; 4035486Sache len[0] = SHA256_MAC_LEN; 4121308Sache addr[1] = (unsigned char *) label; 4221308Sache len[1] = os_strlen(label); 4321308Sache addr[2] = seed; 44119610Sache len[2] = seed_len; 4521308Sache 4621308Sache /* 4721308Sache * RFC 5246, Chapter 5 4821308Sache * A(0) = seed, A(i) = HMAC(secret, A(i-1)) 4958310Sache * P_hash = HMAC(secret, A(1) + seed) + HMAC(secret, A(2) + seed) + .. 5058310Sache * PRF(secret, label, seed) = P_SHA256(secret, label + seed) 5158310Sache */ 5235486Sache 5335486Sache hmac_sha256_vector(secret, secret_len, 2, &addr[1], &len[1], A); 5435486Sache 55136644Sache pos = 0; 56136644Sache while (pos < outlen) { 57119610Sache hmac_sha256_vector(secret, secret_len, 3, addr, len, P); 5875406Sache hmac_sha256(secret, secret_len, A, SHA256_MAC_LEN, A); 5921308Sache 6021308Sache clen = outlen - pos; 6121308Sache if (clen > SHA256_MAC_LEN) 6221308Sache clen = SHA256_MAC_LEN; 6321308Sache os_memcpy(out + pos, P, clen); 6421308Sache pos += clen; 6521308Sache } 66119610Sache} 67119610Sache