xref: /aosp_15_r20/external/wpa_supplicant_8/src/crypto/sha1-prf.c (revision 03f9172ca588f91df233974f4258bab95191f931)
1*03f9172cSAndroid Build Coastguard Worker /*
2*03f9172cSAndroid Build Coastguard Worker  * SHA1-based PRF
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 /**
17*03f9172cSAndroid Build Coastguard Worker  * sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1)
18*03f9172cSAndroid Build Coastguard Worker  * @key: Key for PRF
19*03f9172cSAndroid Build Coastguard Worker  * @key_len: Length of the key in bytes
20*03f9172cSAndroid Build Coastguard Worker  * @label: A unique label for each purpose of the PRF
21*03f9172cSAndroid Build Coastguard Worker  * @data: Extra data to bind into the key
22*03f9172cSAndroid Build Coastguard Worker  * @data_len: Length of the data
23*03f9172cSAndroid Build Coastguard Worker  * @buf: Buffer for the generated pseudo-random key
24*03f9172cSAndroid Build Coastguard Worker  * @buf_len: Number of bytes of key to generate
25*03f9172cSAndroid Build Coastguard Worker  * Returns: 0 on success, -1 of failure
26*03f9172cSAndroid Build Coastguard Worker  *
27*03f9172cSAndroid Build Coastguard Worker  * This function is used to derive new, cryptographically separate keys from a
28*03f9172cSAndroid Build Coastguard Worker  * given key (e.g., PMK in IEEE 802.11i).
29*03f9172cSAndroid Build Coastguard Worker  */
sha1_prf(const u8 * key,size_t key_len,const char * label,const u8 * data,size_t data_len,u8 * buf,size_t buf_len)30*03f9172cSAndroid Build Coastguard Worker int sha1_prf(const u8 *key, size_t key_len, const char *label,
31*03f9172cSAndroid Build Coastguard Worker 	     const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
32*03f9172cSAndroid Build Coastguard Worker {
33*03f9172cSAndroid Build Coastguard Worker 	u8 counter = 0;
34*03f9172cSAndroid Build Coastguard Worker 	size_t pos, plen;
35*03f9172cSAndroid Build Coastguard Worker 	u8 hash[SHA1_MAC_LEN];
36*03f9172cSAndroid Build Coastguard Worker 	size_t label_len = os_strlen(label) + 1;
37*03f9172cSAndroid Build Coastguard Worker 	const unsigned char *addr[3];
38*03f9172cSAndroid Build Coastguard Worker 	size_t len[3];
39*03f9172cSAndroid Build Coastguard Worker 
40*03f9172cSAndroid Build Coastguard Worker 	addr[0] = (u8 *) label;
41*03f9172cSAndroid Build Coastguard Worker 	len[0] = label_len;
42*03f9172cSAndroid Build Coastguard Worker 	addr[1] = data;
43*03f9172cSAndroid Build Coastguard Worker 	len[1] = data_len;
44*03f9172cSAndroid Build Coastguard Worker 	addr[2] = &counter;
45*03f9172cSAndroid Build Coastguard Worker 	len[2] = 1;
46*03f9172cSAndroid Build Coastguard Worker 
47*03f9172cSAndroid Build Coastguard Worker 	pos = 0;
48*03f9172cSAndroid Build Coastguard Worker 	while (pos < buf_len) {
49*03f9172cSAndroid Build Coastguard Worker 		plen = buf_len - pos;
50*03f9172cSAndroid Build Coastguard Worker 		if (plen >= SHA1_MAC_LEN) {
51*03f9172cSAndroid Build Coastguard Worker 			if (hmac_sha1_vector(key, key_len, 3, addr, len,
52*03f9172cSAndroid Build Coastguard Worker 					     &buf[pos]))
53*03f9172cSAndroid Build Coastguard Worker 				return -1;
54*03f9172cSAndroid Build Coastguard Worker 			pos += SHA1_MAC_LEN;
55*03f9172cSAndroid Build Coastguard Worker 		} else {
56*03f9172cSAndroid Build Coastguard Worker 			if (hmac_sha1_vector(key, key_len, 3, addr, len,
57*03f9172cSAndroid Build Coastguard Worker 					     hash))
58*03f9172cSAndroid Build Coastguard Worker 				return -1;
59*03f9172cSAndroid Build Coastguard Worker 			os_memcpy(&buf[pos], hash, plen);
60*03f9172cSAndroid Build Coastguard Worker 			break;
61*03f9172cSAndroid Build Coastguard Worker 		}
62*03f9172cSAndroid Build Coastguard Worker 		counter++;
63*03f9172cSAndroid Build Coastguard Worker 	}
64*03f9172cSAndroid Build Coastguard Worker 	forced_memzero(hash, sizeof(hash));
65*03f9172cSAndroid Build Coastguard Worker 
66*03f9172cSAndroid Build Coastguard Worker 	return 0;
67*03f9172cSAndroid Build Coastguard Worker }
68