]>
Commit | Line | Data |
---|---|---|
2eeaa5c9 JM |
1 | /* |
2 | * EAP-PEAP common routines | |
3724ddc0 | 3 | * Copyright (c) 2008-2011, Jouni Malinen <j@w1.fi> |
2eeaa5c9 | 4 | * |
0f3d578e JM |
5 | * This software may be distributed under the terms of the BSD license. |
6 | * See README for more details. | |
2eeaa5c9 JM |
7 | */ |
8 | ||
9 | #include "includes.h" | |
10 | ||
11 | #include "common.h" | |
03da66bd | 12 | #include "crypto/sha1.h" |
26d1dc96 | 13 | #include "eap_peap_common.h" |
2eeaa5c9 | 14 | |
3724ddc0 JM |
15 | int peap_prfplus(int version, const u8 *key, size_t key_len, |
16 | const char *label, const u8 *seed, size_t seed_len, | |
17 | u8 *buf, size_t buf_len) | |
2eeaa5c9 JM |
18 | { |
19 | unsigned char counter = 0; | |
20 | size_t pos, plen; | |
21 | u8 hash[SHA1_MAC_LEN]; | |
22 | size_t label_len = os_strlen(label); | |
23 | u8 extra[2]; | |
24 | const unsigned char *addr[5]; | |
25 | size_t len[5]; | |
26 | ||
27 | addr[0] = hash; | |
28 | len[0] = 0; | |
29 | addr[1] = (unsigned char *) label; | |
30 | len[1] = label_len; | |
31 | addr[2] = seed; | |
32 | len[2] = seed_len; | |
33 | ||
34 | if (version == 0) { | |
35 | /* | |
36 | * PRF+(K, S, LEN) = T1 | T2 | ... | Tn | |
37 | * T1 = HMAC-SHA1(K, S | 0x01 | 0x00 | 0x00) | |
38 | * T2 = HMAC-SHA1(K, T1 | S | 0x02 | 0x00 | 0x00) | |
39 | * ... | |
40 | * Tn = HMAC-SHA1(K, Tn-1 | S | n | 0x00 | 0x00) | |
41 | */ | |
42 | ||
43 | extra[0] = 0; | |
44 | extra[1] = 0; | |
45 | ||
46 | addr[3] = &counter; | |
47 | len[3] = 1; | |
48 | addr[4] = extra; | |
49 | len[4] = 2; | |
50 | } else { | |
51 | /* | |
52 | * PRF (K,S,LEN) = T1 | T2 | T3 | T4 | ... where: | |
53 | * T1 = HMAC-SHA1(K, S | LEN | 0x01) | |
54 | * T2 = HMAC-SHA1 (K, T1 | S | LEN | 0x02) | |
55 | * T3 = HMAC-SHA1 (K, T2 | S | LEN | 0x03) | |
56 | * T4 = HMAC-SHA1 (K, T3 | S | LEN | 0x04) | |
57 | * ... | |
58 | */ | |
59 | ||
60 | extra[0] = buf_len & 0xff; | |
61 | ||
62 | addr[3] = extra; | |
63 | len[3] = 1; | |
64 | addr[4] = &counter; | |
65 | len[4] = 1; | |
66 | } | |
67 | ||
68 | pos = 0; | |
69 | while (pos < buf_len) { | |
70 | counter++; | |
71 | plen = buf_len - pos; | |
3724ddc0 JM |
72 | if (hmac_sha1_vector(key, key_len, 5, addr, len, hash) < 0) |
73 | return -1; | |
2eeaa5c9 JM |
74 | if (plen >= SHA1_MAC_LEN) { |
75 | os_memcpy(&buf[pos], hash, SHA1_MAC_LEN); | |
76 | pos += SHA1_MAC_LEN; | |
77 | } else { | |
78 | os_memcpy(&buf[pos], hash, plen); | |
79 | break; | |
80 | } | |
81 | len[0] = SHA1_MAC_LEN; | |
82 | } | |
3724ddc0 JM |
83 | |
84 | return 0; | |
2eeaa5c9 | 85 | } |