Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / wpa / src / eap_peer / mschapv2.c
blob01c22d89753f90700448c53529f67f620c959c1a
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 "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 void 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 hash_nt_password_hash(password, password_hash_hash);
97 } else {
98 nt_password_hash(password, password_len, password_hash);
99 hash_nt_password_hash(password_hash, password_hash_hash);
101 get_master_key(password_hash_hash, nt_response, master_key);
102 wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: Master Key",
103 master_key, MSCHAPV2_MASTER_KEY_LEN);
107 int mschapv2_verify_auth_response(const u8 *auth_response,
108 const u8 *buf, size_t buf_len)
110 u8 recv_response[MSCHAPV2_AUTH_RESPONSE_LEN];
111 if (buf_len < 2 + 2 * MSCHAPV2_AUTH_RESPONSE_LEN ||
112 buf[0] != 'S' || buf[1] != '=' ||
113 hexstr2bin((char *) (buf + 2), recv_response,
114 MSCHAPV2_AUTH_RESPONSE_LEN) ||
115 os_memcmp(auth_response, recv_response,
116 MSCHAPV2_AUTH_RESPONSE_LEN) != 0)
117 return -1;
118 return 0;