1*03f9172cSAndroid Build Coastguard Worker /*
2*03f9172cSAndroid Build Coastguard Worker * SHA1 T-PRF for EAP-FAST
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 * sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF)
17*03f9172cSAndroid Build Coastguard Worker * @key: Key for PRF
18*03f9172cSAndroid Build Coastguard Worker * @key_len: Length of the key in bytes
19*03f9172cSAndroid Build Coastguard Worker * @label: A unique label for each purpose of the PRF
20*03f9172cSAndroid Build Coastguard Worker * @seed: Seed value to bind into the key
21*03f9172cSAndroid Build Coastguard Worker * @seed_len: Length of the seed
22*03f9172cSAndroid Build Coastguard Worker * @buf: Buffer for the generated pseudo-random key
23*03f9172cSAndroid Build Coastguard Worker * @buf_len: Number of bytes of key to generate
24*03f9172cSAndroid Build Coastguard Worker * Returns: 0 on success, -1 of failure
25*03f9172cSAndroid Build Coastguard Worker *
26*03f9172cSAndroid Build Coastguard Worker * This function is used to derive new, cryptographically separate keys from a
27*03f9172cSAndroid Build Coastguard Worker * given key for EAP-FAST. T-PRF is defined in RFC 4851, Section 5.5.
28*03f9172cSAndroid Build Coastguard Worker */
sha1_t_prf(const u8 * key,size_t key_len,const char * label,const u8 * seed,size_t seed_len,u8 * buf,size_t buf_len)29*03f9172cSAndroid Build Coastguard Worker int sha1_t_prf(const u8 *key, size_t key_len, const char *label,
30*03f9172cSAndroid Build Coastguard Worker const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len)
31*03f9172cSAndroid Build Coastguard Worker {
32*03f9172cSAndroid Build Coastguard Worker unsigned char counter = 0;
33*03f9172cSAndroid Build Coastguard Worker size_t pos, plen;
34*03f9172cSAndroid Build Coastguard Worker u8 hash[SHA1_MAC_LEN];
35*03f9172cSAndroid Build Coastguard Worker size_t label_len = os_strlen(label);
36*03f9172cSAndroid Build Coastguard Worker u8 output_len[2];
37*03f9172cSAndroid Build Coastguard Worker const unsigned char *addr[5];
38*03f9172cSAndroid Build Coastguard Worker size_t len[5];
39*03f9172cSAndroid Build Coastguard Worker
40*03f9172cSAndroid Build Coastguard Worker addr[0] = hash;
41*03f9172cSAndroid Build Coastguard Worker len[0] = 0;
42*03f9172cSAndroid Build Coastguard Worker addr[1] = (unsigned char *) label;
43*03f9172cSAndroid Build Coastguard Worker len[1] = label_len + 1;
44*03f9172cSAndroid Build Coastguard Worker addr[2] = seed;
45*03f9172cSAndroid Build Coastguard Worker len[2] = seed_len;
46*03f9172cSAndroid Build Coastguard Worker addr[3] = output_len;
47*03f9172cSAndroid Build Coastguard Worker len[3] = 2;
48*03f9172cSAndroid Build Coastguard Worker addr[4] = &counter;
49*03f9172cSAndroid Build Coastguard Worker len[4] = 1;
50*03f9172cSAndroid Build Coastguard Worker
51*03f9172cSAndroid Build Coastguard Worker output_len[0] = (buf_len >> 8) & 0xff;
52*03f9172cSAndroid Build Coastguard Worker output_len[1] = buf_len & 0xff;
53*03f9172cSAndroid Build Coastguard Worker pos = 0;
54*03f9172cSAndroid Build Coastguard Worker while (pos < buf_len) {
55*03f9172cSAndroid Build Coastguard Worker counter++;
56*03f9172cSAndroid Build Coastguard Worker plen = buf_len - pos;
57*03f9172cSAndroid Build Coastguard Worker if (hmac_sha1_vector(key, key_len, 5, addr, len, hash))
58*03f9172cSAndroid Build Coastguard Worker return -1;
59*03f9172cSAndroid Build Coastguard Worker if (plen >= SHA1_MAC_LEN) {
60*03f9172cSAndroid Build Coastguard Worker os_memcpy(&buf[pos], hash, SHA1_MAC_LEN);
61*03f9172cSAndroid Build Coastguard Worker pos += SHA1_MAC_LEN;
62*03f9172cSAndroid Build Coastguard Worker } else {
63*03f9172cSAndroid Build Coastguard Worker os_memcpy(&buf[pos], hash, plen);
64*03f9172cSAndroid Build Coastguard Worker break;
65*03f9172cSAndroid Build Coastguard Worker }
66*03f9172cSAndroid Build Coastguard Worker len[0] = SHA1_MAC_LEN;
67*03f9172cSAndroid Build Coastguard Worker }
68*03f9172cSAndroid Build Coastguard Worker
69*03f9172cSAndroid Build Coastguard Worker forced_memzero(hash, SHA1_MAC_LEN);
70*03f9172cSAndroid Build Coastguard Worker
71*03f9172cSAndroid Build Coastguard Worker return 0;
72*03f9172cSAndroid Build Coastguard Worker }
73