mschapv2.c
Go to the documentation of this file.
00001 /*
00002  * MSCHAPV2 (RFC 2759)
00003  * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
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          * MSCHAPv2 does not include optional domain name in the
00027          * challenge-response calculation, so remove domain prefix
00028          * (if present).
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         /* Authenticator response is not really needed yet, but calculate it
00068          * here so that challenges need not be saved. */
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         /* Generate master_key here since we have the needed data available. */
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 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:35