Added WirelessManager, a port of wpa_supplicant.
[AROS.git] / workbench / network / WirelessManager / src / eap_peer / mschapv2.c
blobb8fb07502fd73d332b55a05a4cb9149c0506bc97
1 /*
2 * MSCHAPV2 (RFC 2759)
3 * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
12 * See README and COPYING for more details.
15 #include "includes.h"
17 #include "common.h"
18 #include "crypto/ms_funcs.h"
19 #include "mschapv2.h"
21 const u8 * mschapv2_remove_domain(const u8 *username, size_t *len)
23 size_t i;
26 * MSCHAPv2 does not include optional domain name in the
27 * challenge-response calculation, so remove domain prefix
28 * (if present).
31 for (i = 0; i < *len; i++) {
32 if (username[i] == '\\') {
33 *len -= i + 1;
34 return username + i + 1;
38 return username;
42 int mschapv2_derive_response(const u8 *identity, size_t identity_len,
43 const u8 *password, size_t password_len,
44 int pwhash,
45 const u8 *auth_challenge,
46 const u8 *peer_challenge,
47 u8 *nt_response, u8 *auth_response,
48 u8 *master_key)
50 const u8 *username;
51 size_t username_len;
52 u8 password_hash[16], password_hash_hash[16];
54 wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Identity",
55 identity, identity_len);
56 username_len = identity_len;
57 username = mschapv2_remove_domain(identity, &username_len);
58 wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Username",
59 username, username_len);
61 wpa_hexdump(MSG_DEBUG, "MSCHAPV2: auth_challenge",
62 auth_challenge, MSCHAPV2_CHAL_LEN);
63 wpa_hexdump(MSG_DEBUG, "MSCHAPV2: peer_challenge",
64 peer_challenge, MSCHAPV2_CHAL_LEN);
65 wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: username",
66 username, username_len);
67 /* Authenticator response is not really needed yet, but calculate it
68 * here so that challenges need not be saved. */
69 if (pwhash) {
70 wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: password hash",
71 password, password_len);
72 generate_nt_response_pwhash(auth_challenge, peer_challenge,
73 username, username_len,
74 password, nt_response);
75 generate_authenticator_response_pwhash(
76 password, peer_challenge, auth_challenge,
77 username, username_len, nt_response, auth_response);
78 } else {
79 wpa_hexdump_ascii_key(MSG_DEBUG, "MSCHAPV2: password",
80 password, password_len);
81 generate_nt_response(auth_challenge, peer_challenge,
82 username, username_len,
83 password, password_len, nt_response);
84 generate_authenticator_response(password, password_len,
85 peer_challenge, auth_challenge,
86 username, username_len,
87 nt_response, auth_response);
89 wpa_hexdump(MSG_DEBUG, "MSCHAPV2: NT Response",
90 nt_response, MSCHAPV2_NT_RESPONSE_LEN);
91 wpa_hexdump(MSG_DEBUG, "MSCHAPV2: Auth Response",
92 auth_response, MSCHAPV2_AUTH_RESPONSE_LEN);
94 /* Generate master_key here since we have the needed data available. */
95 if (pwhash) {
96 if (hash_nt_password_hash(password, password_hash_hash))
97 return -1;
98 } else {
99 if (nt_password_hash(password, password_len, password_hash) ||
100 hash_nt_password_hash(password_hash, password_hash_hash))
101 return -1;
103 get_master_key(password_hash_hash, nt_response, master_key);
104 wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: Master Key",
105 master_key, MSCHAPV2_MASTER_KEY_LEN);
107 return 0;
111 int mschapv2_verify_auth_response(const u8 *auth_response,
112 const u8 *buf, size_t buf_len)
114 u8 recv_response[MSCHAPV2_AUTH_RESPONSE_LEN];
115 if (buf_len < 2 + 2 * MSCHAPV2_AUTH_RESPONSE_LEN ||
116 buf[0] != 'S' || buf[1] != '=' ||
117 hexstr2bin((char *) (buf + 2), recv_response,
118 MSCHAPV2_AUTH_RESPONSE_LEN) ||
119 os_memcmp(auth_response, recv_response,
120 MSCHAPV2_AUTH_RESPONSE_LEN) != 0)
121 return -1;
122 return 0;