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 5184 : 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 5184 : u8 counter = 0;
34 : size_t pos, plen;
35 : u8 hash[SHA1_MAC_LEN];
36 5184 : size_t label_len = os_strlen(label) + 1;
37 : const unsigned char *addr[3];
38 : size_t len[3];
39 :
40 5184 : addr[0] = (u8 *) label;
41 5184 : len[0] = label_len;
42 5184 : addr[1] = data;
43 5184 : len[1] = data_len;
44 5184 : addr[2] = &counter;
45 5184 : len[2] = 1;
46 :
47 5184 : pos = 0;
48 18636 : while (pos < buf_len) {
49 13452 : plen = buf_len - pos;
50 13452 : if (plen >= SHA1_MAC_LEN) {
51 8268 : if (hmac_sha1_vector(key, key_len, 3, addr, len,
52 : &buf[pos]))
53 0 : return -1;
54 8268 : pos += SHA1_MAC_LEN;
55 : } else {
56 5184 : if (hmac_sha1_vector(key, key_len, 3, addr, len,
57 : hash))
58 0 : return -1;
59 5184 : os_memcpy(&buf[pos], hash, plen);
60 5184 : break;
61 : }
62 8268 : counter++;
63 : }
64 5184 : os_memset(hash, 0, sizeof(hash));
65 :
66 5184 : return 0;
67 : }
|