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