1 | #include <machine/rtems-bsd-user-space.h> |
---|
2 | |
---|
3 | /* |
---|
4 | * MSCHAPV2 (RFC 2759) |
---|
5 | * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> |
---|
6 | * |
---|
7 | * This software may be distributed under the terms of the BSD license. |
---|
8 | * See README for more details. |
---|
9 | */ |
---|
10 | |
---|
11 | #include "includes.h" |
---|
12 | |
---|
13 | #include "common.h" |
---|
14 | #include "crypto/ms_funcs.h" |
---|
15 | #include "mschapv2.h" |
---|
16 | |
---|
17 | const u8 * mschapv2_remove_domain(const u8 *username, size_t *len) |
---|
18 | { |
---|
19 | size_t i; |
---|
20 | |
---|
21 | /* |
---|
22 | * MSCHAPv2 does not include optional domain name in the |
---|
23 | * challenge-response calculation, so remove domain prefix |
---|
24 | * (if present). |
---|
25 | */ |
---|
26 | |
---|
27 | for (i = 0; i < *len; i++) { |
---|
28 | if (username[i] == '\\') { |
---|
29 | *len -= i + 1; |
---|
30 | return username + i + 1; |
---|
31 | } |
---|
32 | } |
---|
33 | |
---|
34 | return username; |
---|
35 | } |
---|
36 | |
---|
37 | |
---|
38 | int mschapv2_derive_response(const u8 *identity, size_t identity_len, |
---|
39 | const u8 *password, size_t password_len, |
---|
40 | int pwhash, |
---|
41 | const u8 *auth_challenge, |
---|
42 | const u8 *peer_challenge, |
---|
43 | u8 *nt_response, u8 *auth_response, |
---|
44 | u8 *master_key) |
---|
45 | { |
---|
46 | const u8 *username; |
---|
47 | size_t username_len; |
---|
48 | u8 password_hash[16], password_hash_hash[16]; |
---|
49 | |
---|
50 | wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Identity", |
---|
51 | identity, identity_len); |
---|
52 | username_len = identity_len; |
---|
53 | username = mschapv2_remove_domain(identity, &username_len); |
---|
54 | wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Username", |
---|
55 | username, username_len); |
---|
56 | |
---|
57 | wpa_hexdump(MSG_DEBUG, "MSCHAPV2: auth_challenge", |
---|
58 | auth_challenge, MSCHAPV2_CHAL_LEN); |
---|
59 | wpa_hexdump(MSG_DEBUG, "MSCHAPV2: peer_challenge", |
---|
60 | peer_challenge, MSCHAPV2_CHAL_LEN); |
---|
61 | wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: username", |
---|
62 | username, username_len); |
---|
63 | /* Authenticator response is not really needed yet, but calculate it |
---|
64 | * here so that challenges need not be saved. */ |
---|
65 | if (pwhash) { |
---|
66 | wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: password hash", |
---|
67 | password, password_len); |
---|
68 | if (generate_nt_response_pwhash(auth_challenge, peer_challenge, |
---|
69 | username, username_len, |
---|
70 | password, nt_response) || |
---|
71 | generate_authenticator_response_pwhash( |
---|
72 | password, peer_challenge, auth_challenge, |
---|
73 | username, username_len, nt_response, |
---|
74 | auth_response)) |
---|
75 | return -1; |
---|
76 | } else { |
---|
77 | wpa_hexdump_ascii_key(MSG_DEBUG, "MSCHAPV2: password", |
---|
78 | password, password_len); |
---|
79 | if (generate_nt_response(auth_challenge, peer_challenge, |
---|
80 | username, username_len, |
---|
81 | password, password_len, |
---|
82 | nt_response) || |
---|
83 | generate_authenticator_response(password, password_len, |
---|
84 | peer_challenge, |
---|
85 | auth_challenge, |
---|
86 | username, username_len, |
---|
87 | nt_response, |
---|
88 | auth_response)) |
---|
89 | return -1; |
---|
90 | } |
---|
91 | wpa_hexdump(MSG_DEBUG, "MSCHAPV2: NT Response", |
---|
92 | nt_response, MSCHAPV2_NT_RESPONSE_LEN); |
---|
93 | wpa_hexdump(MSG_DEBUG, "MSCHAPV2: Auth Response", |
---|
94 | auth_response, MSCHAPV2_AUTH_RESPONSE_LEN); |
---|
95 | |
---|
96 | /* Generate master_key here since we have the needed data available. */ |
---|
97 | if (pwhash) { |
---|
98 | if (hash_nt_password_hash(password, password_hash_hash)) |
---|
99 | return -1; |
---|
100 | } else { |
---|
101 | if (nt_password_hash(password, password_len, password_hash) || |
---|
102 | hash_nt_password_hash(password_hash, password_hash_hash)) |
---|
103 | return -1; |
---|
104 | } |
---|
105 | if (get_master_key(password_hash_hash, nt_response, master_key)) |
---|
106 | return -1; |
---|
107 | wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: Master Key", |
---|
108 | master_key, MSCHAPV2_MASTER_KEY_LEN); |
---|
109 | |
---|
110 | return 0; |
---|
111 | } |
---|
112 | |
---|
113 | |
---|
114 | int mschapv2_verify_auth_response(const u8 *auth_response, |
---|
115 | const u8 *buf, size_t buf_len) |
---|
116 | { |
---|
117 | u8 recv_response[MSCHAPV2_AUTH_RESPONSE_LEN]; |
---|
118 | if (buf_len < 2 + 2 * MSCHAPV2_AUTH_RESPONSE_LEN || |
---|
119 | buf[0] != 'S' || buf[1] != '=' || |
---|
120 | hexstr2bin((char *) (buf + 2), recv_response, |
---|
121 | MSCHAPV2_AUTH_RESPONSE_LEN) || |
---|
122 | os_memcmp_const(auth_response, recv_response, |
---|
123 | MSCHAPV2_AUTH_RESPONSE_LEN) != 0) |
---|
124 | return -1; |
---|
125 | return 0; |
---|
126 | } |
---|