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