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