00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto/ms_funcs.h"
00019 #include "mschapv2.h"
00020
00021 const u8 * mschapv2_remove_domain(const u8 *username, size_t *len)
00022 {
00023 size_t i;
00024
00025
00026
00027
00028
00029
00030
00031 for (i = 0; i < *len; i++) {
00032 if (username[i] == '\\') {
00033 *len -= i + 1;
00034 return username + i + 1;
00035 }
00036 }
00037
00038 return username;
00039 }
00040
00041
00042 int mschapv2_derive_response(const u8 *identity, size_t identity_len,
00043 const u8 *password, size_t password_len,
00044 int pwhash,
00045 const u8 *auth_challenge,
00046 const u8 *peer_challenge,
00047 u8 *nt_response, u8 *auth_response,
00048 u8 *master_key)
00049 {
00050 const u8 *username;
00051 size_t username_len;
00052 u8 password_hash[16], password_hash_hash[16];
00053
00054 wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Identity",
00055 identity, identity_len);
00056 username_len = identity_len;
00057 username = mschapv2_remove_domain(identity, &username_len);
00058 wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Username",
00059 username, username_len);
00060
00061 wpa_hexdump(MSG_DEBUG, "MSCHAPV2: auth_challenge",
00062 auth_challenge, MSCHAPV2_CHAL_LEN);
00063 wpa_hexdump(MSG_DEBUG, "MSCHAPV2: peer_challenge",
00064 peer_challenge, MSCHAPV2_CHAL_LEN);
00065 wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: username",
00066 username, username_len);
00067
00068
00069 if (pwhash) {
00070 wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: password hash",
00071 password, password_len);
00072 generate_nt_response_pwhash(auth_challenge, peer_challenge,
00073 username, username_len,
00074 password, nt_response);
00075 generate_authenticator_response_pwhash(
00076 password, peer_challenge, auth_challenge,
00077 username, username_len, nt_response, auth_response);
00078 } else {
00079 wpa_hexdump_ascii_key(MSG_DEBUG, "MSCHAPV2: password",
00080 password, password_len);
00081 generate_nt_response(auth_challenge, peer_challenge,
00082 username, username_len,
00083 password, password_len, nt_response);
00084 generate_authenticator_response(password, password_len,
00085 peer_challenge, auth_challenge,
00086 username, username_len,
00087 nt_response, auth_response);
00088 }
00089 wpa_hexdump(MSG_DEBUG, "MSCHAPV2: NT Response",
00090 nt_response, MSCHAPV2_NT_RESPONSE_LEN);
00091 wpa_hexdump(MSG_DEBUG, "MSCHAPV2: Auth Response",
00092 auth_response, MSCHAPV2_AUTH_RESPONSE_LEN);
00093
00094
00095 if (pwhash) {
00096 if (hash_nt_password_hash(password, password_hash_hash))
00097 return -1;
00098 } else {
00099 if (nt_password_hash(password, password_len, password_hash) ||
00100 hash_nt_password_hash(password_hash, password_hash_hash))
00101 return -1;
00102 }
00103 get_master_key(password_hash_hash, nt_response, master_key);
00104 wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: Master Key",
00105 master_key, MSCHAPV2_MASTER_KEY_LEN);
00106
00107 return 0;
00108 }
00109
00110
00111 int mschapv2_verify_auth_response(const u8 *auth_response,
00112 const u8 *buf, size_t buf_len)
00113 {
00114 u8 recv_response[MSCHAPV2_AUTH_RESPONSE_LEN];
00115 if (buf_len < 2 + 2 * MSCHAPV2_AUTH_RESPONSE_LEN ||
00116 buf[0] != 'S' || buf[1] != '=' ||
00117 hexstr2bin((char *) (buf + 2), recv_response,
00118 MSCHAPV2_AUTH_RESPONSE_LEN) ||
00119 os_memcmp(auth_response, recv_response,
00120 MSCHAPV2_AUTH_RESPONSE_LEN) != 0)
00121 return -1;
00122 return 0;
00123 }