4 #include "crypto/sha1.h"
5 #include "crypto/aes128.h"
7 #define byte unsigned char
8 #define memzero(a, b) memset(a, 0, b)
10 static void* memadd(void* p
, void* src
, unsigned len
)
16 static int memxcmp(const void* av
, const void* bv
, size_t len
)
18 const uint8_t* a
= (const uint8_t*) av
;
19 const uint8_t* b
= (const uint8_t*) bv
;
28 /* Supplementary crypto routines for EAPOL negotiations.
29 Ref. IEEE 802.11-2012 11.6.1.2 PRF
31 The standard calls for PRF384 but that's just the same code
32 that truncates the result to 48 bytes. In their terms:
34 PRF-384(K, A, B) = L(PRF-480(K, A, B), 0, 384)
36 To make things a bit easier, K is made 60 bytes (480 bits)
37 long and no explicit truncation is preformed. In the caller,
38 K is a temporary buffer anyway, the useful stuff gets copied
41 This function also handles concatenation:
44 B = mac1 | mac2 | nonce1 | nonce2
50 so there's no point in a dedicated buffer for B. */
52 void PRF480(byte out
[60], byte key
[32], const char* str
,
53 byte mac1
[6], byte mac2
[6],
54 byte nonce1
[32], byte nonce2
[32])
56 int slen
= strlen(str
);
57 int ilen
= slen
+ 1 + 2*6 + 2*32 + 1; /* exact input len */
58 int xlen
= ilen
+ 10; /* guarded buffer len */
63 p
= memadd(p
, str
, slen
+ 1);
64 p
= memadd(p
, mac1
, 6);
65 p
= memadd(p
, mac2
, 6);
66 p
= memadd(p
, nonce1
, 32);
67 p
= memadd(p
, nonce2
, 32);
69 for(int i
= 0; i
< 3; i
++) {
71 hmac_sha1(out
+ i
*20, key
, 32, ibuf
, ilen
);
75 /* SHA-1 based message integrity code (MIC) for auth and key management
76 scheme (AKM) 00-0F-AC:2, which we requested in association IEs and
77 probably checked in packet 1 payload.
79 Ref. IEEE 802.11-2012 11.6.3 EAPOL-Key frame construction and processing. */
81 void make_mic(byte mic
[16], byte kck
[16], void* buf
, int len
)
87 hmac_sha1(hash
, kck
, kcklen
, buf
, len
);
89 memcpy(mic
, hash
, miclen
);
92 int check_mic(byte mic
[16], byte kck
[16], void* buf
, int len
)
99 memcpy(copy
, mic
, miclen
);
100 memzero(mic
, miclen
);
102 hmac_sha1(hash
, kck
, kcklen
, buf
, len
);
104 int ret
= memxcmp(hash
, copy
, miclen
);
109 /* Packet 3 payload (GTK) is wrapped with standard RFC3394 0xA6
110 checkblock. We unwrap it in place, and start parsing 8 bytes
113 static const byte iv
[8] = {
114 0xA6, 0xA6, 0xA6, 0xA6,
115 0xA6, 0xA6, 0xA6, 0xA6
118 int unwrap_key(uint8_t kek
[16], void* buf
, int len
)
120 if(len
% 8 || len
< 16)
123 aes128_unwrap(kek
, buf
, len
);
125 return memxcmp(buf
, iv
, 8);