Branch data Line data Source code
1 : : /*
2 : : * SHA1-based PRF
3 : : * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
4 : : *
5 : : * This software may be distributed under the terms of the BSD license.
6 : : * See README for more details.
7 : : */
8 : :
9 : : #include "includes.h"
10 : :
11 : : #include "common.h"
12 : : #include "sha1.h"
13 : : #include "crypto.h"
14 : :
15 : :
16 : : /**
17 : : * sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1)
18 : : * @key: Key for PRF
19 : : * @key_len: Length of the key in bytes
20 : : * @label: A unique label for each purpose of the PRF
21 : : * @data: Extra data to bind into the key
22 : : * @data_len: Length of the data
23 : : * @buf: Buffer for the generated pseudo-random key
24 : : * @buf_len: Number of bytes of key to generate
25 : : * Returns: 0 on success, -1 of failure
26 : : *
27 : : * This function is used to derive new, cryptographically separate keys from a
28 : : * given key (e.g., PMK in IEEE 802.11i).
29 : : */
30 : 1478 : int sha1_prf(const u8 *key, size_t key_len, const char *label,
31 : : const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
32 : : {
33 : 1478 : u8 counter = 0;
34 : : size_t pos, plen;
35 : : u8 hash[SHA1_MAC_LEN];
36 : 1478 : size_t label_len = os_strlen(label) + 1;
37 : : const unsigned char *addr[3];
38 : : size_t len[3];
39 : :
40 : 1478 : addr[0] = (u8 *) label;
41 : 1478 : len[0] = label_len;
42 : 1478 : addr[1] = data;
43 : 1478 : len[1] = data_len;
44 : 1478 : addr[2] = &counter;
45 : 1478 : len[2] = 1;
46 : :
47 : 1478 : pos = 0;
48 [ + - ]: 3819 : while (pos < buf_len) {
49 : 3819 : plen = buf_len - pos;
50 [ + + ]: 3819 : if (plen >= SHA1_MAC_LEN) {
51 [ - + ]: 2341 : if (hmac_sha1_vector(key, key_len, 3, addr, len,
52 : : &buf[pos]))
53 : 0 : return -1;
54 : 2341 : pos += SHA1_MAC_LEN;
55 : : } else {
56 [ - + ]: 1478 : if (hmac_sha1_vector(key, key_len, 3, addr, len,
57 : : hash))
58 : 0 : return -1;
59 : 1478 : os_memcpy(&buf[pos], hash, plen);
60 : 1478 : break;
61 : : }
62 : 2341 : counter++;
63 : : }
64 : :
65 : 1478 : return 0;
66 : : }
|