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