diff --git a/src/crypto/ms_funcs.c b/src/crypto/ms_funcs.c index d0d6a96af..aff7d33f4 100644 --- a/src/crypto/ms_funcs.c +++ b/src/crypto/ms_funcs.c @@ -140,17 +140,20 @@ int hash_nt_password_hash(const u8 *password_hash, u8 *password_hash_hash) * @challenge: 8-octet Challenge (IN) * @password_hash: 16-octet PasswordHash (IN) * @response: 24-octet Response (OUT) + * Returns: 0 on success, -1 on failure */ -void challenge_response(const u8 *challenge, const u8 *password_hash, - u8 *response) +int challenge_response(const u8 *challenge, const u8 *password_hash, + u8 *response) { u8 zpwd[7]; - des_encrypt(challenge, password_hash, response); - des_encrypt(challenge, password_hash + 7, response + 8); + + if (des_encrypt(challenge, password_hash, response) < 0 || + des_encrypt(challenge, password_hash + 7, response + 8) < 0) + return -1; zpwd[0] = password_hash[14]; zpwd[1] = password_hash[15]; os_memset(zpwd + 2, 0, 5); - des_encrypt(challenge, zpwd, response + 16); + return des_encrypt(challenge, zpwd, response + 16); } @@ -175,9 +178,9 @@ int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge, if (challenge_hash(peer_challenge, auth_challenge, username, username_len, challenge) || - nt_password_hash(password, password_len, password_hash)) + nt_password_hash(password, password_len, password_hash) || + challenge_response(challenge, password_hash, response)) return -1; - challenge_response(challenge, password_hash, response); return 0; } @@ -202,9 +205,9 @@ int generate_nt_response_pwhash(const u8 *auth_challenge, if (challenge_hash(peer_challenge, auth_challenge, username, username_len, - challenge)) + challenge) || + challenge_response(challenge, password_hash, response)) return -1; - challenge_response(challenge, password_hash, response); return 0; } @@ -304,9 +307,10 @@ int nt_challenge_response(const u8 *challenge, const u8 *password, size_t password_len, u8 *response) { u8 password_hash[16]; - if (nt_password_hash(password, password_len, password_hash)) + + if (nt_password_hash(password, password_len, password_hash) || + challenge_response(challenge, password_hash, response)) return -1; - challenge_response(challenge, password_hash, response); return 0; } @@ -487,12 +491,15 @@ int new_password_encrypted_with_old_nt_password_hash( * @password_hash: 16-octer PasswordHash (IN) * @block: 16-octet Block (IN) * @cypher: 16-octer Cypher (OUT) + * Returns: 0 on success, -1 on failure */ -void nt_password_hash_encrypted_with_block(const u8 *password_hash, - const u8 *block, u8 *cypher) +int nt_password_hash_encrypted_with_block(const u8 *password_hash, + const u8 *block, u8 *cypher) { - des_encrypt(password_hash, block, cypher); - des_encrypt(password_hash + 8, block + 7, cypher + 8); + if (des_encrypt(password_hash, block, cypher) < 0 || + des_encrypt(password_hash + 8, block + 7, cypher + 8) < 0) + return -1; + return 0; } @@ -515,10 +522,10 @@ int old_nt_password_hash_encrypted_with_new_nt_password_hash( if (nt_password_hash(old_password, old_password_len, old_password_hash) || nt_password_hash(new_password, new_password_len, - new_password_hash)) + new_password_hash) || + nt_password_hash_encrypted_with_block(old_password_hash, + new_password_hash, + encrypted_password_hash)) return -1; - nt_password_hash_encrypted_with_block(old_password_hash, - new_password_hash, - encrypted_password_hash); return 0; } diff --git a/src/crypto/ms_funcs.h b/src/crypto/ms_funcs.h index b5b5918e1..b8d55f053 100644 --- a/src/crypto/ms_funcs.h +++ b/src/crypto/ms_funcs.h @@ -31,8 +31,8 @@ int generate_authenticator_response_pwhash( int nt_challenge_response(const u8 *challenge, const u8 *password, size_t password_len, u8 *response); -void challenge_response(const u8 *challenge, const u8 *password_hash, - u8 *response); +int challenge_response(const u8 *challenge, const u8 *password_hash, + u8 *response); int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge, const u8 *username, size_t username_len, u8 *challenge); int nt_password_hash(const u8 *password, size_t password_len, @@ -50,8 +50,8 @@ int __must_check new_password_encrypted_with_old_nt_password_hash( const u8 *new_password, size_t new_password_len, const u8 *old_password, size_t old_password_len, u8 *encrypted_pw_block); -void nt_password_hash_encrypted_with_block(const u8 *password_hash, - const u8 *block, u8 *cypher); +int nt_password_hash_encrypted_with_block(const u8 *password_hash, + const u8 *block, u8 *cypher); int old_nt_password_hash_encrypted_with_new_nt_password_hash( const u8 *new_password, size_t new_password_len, const u8 *old_password, size_t old_password_len, diff --git a/src/eap_peer/eap_leap.c b/src/eap_peer/eap_leap.c index ff6fa4afd..7bb62e72d 100644 --- a/src/eap_peer/eap_leap.c +++ b/src/eap_peer/eap_leap.c @@ -115,10 +115,13 @@ static struct wpabuf * eap_leap_process_request(struct eap_sm *sm, void *priv, wpabuf_put_u8(resp, 0); /* unused */ wpabuf_put_u8(resp, LEAP_RESPONSE_LEN); rpos = wpabuf_put(resp, LEAP_RESPONSE_LEN); - if (pwhash) - challenge_response(challenge, password, rpos); - else - nt_challenge_response(challenge, password, password_len, rpos); + if ((pwhash && challenge_response(challenge, password, rpos)) || + (!pwhash && + nt_challenge_response(challenge, password, password_len, rpos))) { + wpa_printf(MSG_DEBUG, "EAP-LEAP: Failed to derive response"); + ret->ignore = TRUE; + return NULL; + } os_memcpy(data->peer_response, rpos, LEAP_RESPONSE_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-LEAP: Response", rpos, LEAP_RESPONSE_LEN); @@ -239,7 +242,10 @@ static struct wpabuf * eap_leap_process_response(struct eap_sm *sm, void *priv, return NULL; } } - challenge_response(data->ap_challenge, pw_hash_hash, expected); + if (challenge_response(data->ap_challenge, pw_hash_hash, expected)) { + ret->ignore = TRUE; + return NULL; + } ret->methodState = METHOD_DONE; ret->allowNotifications = FALSE; diff --git a/src/eap_peer/eap_mschapv2.c b/src/eap_peer/eap_mschapv2.c index ce2227d38..d346dccab 100644 --- a/src/eap_peer/eap_mschapv2.c +++ b/src/eap_peer/eap_mschapv2.c @@ -567,11 +567,11 @@ static struct wpabuf * eap_mschapv2_change_password( if (pwhash) { u8 new_password_hash[16]; if (nt_password_hash(new_password, new_password_len, - new_password_hash)) + new_password_hash) || + nt_password_hash_encrypted_with_block(password, + new_password_hash, + cp->encr_hash)) goto fail; - nt_password_hash_encrypted_with_block(password, - new_password_hash, - cp->encr_hash); } else { if (old_nt_password_hash_encrypted_with_new_nt_password_hash( new_password, new_password_len, diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c index 3354b2d3a..6714b903e 100644 --- a/src/eap_peer/eap_ttls.c +++ b/src/eap_peer/eap_ttls.c @@ -624,12 +624,16 @@ static int eap_ttls_phase2_request_mschap(struct eap_sm *sm, os_memset(pos, 0, 24); /* LM-Response */ pos += 24; if (pwhash) { - challenge_response(challenge, password, pos); /* NT-Response */ + /* NT-Response */ + if (challenge_response(challenge, password, pos)) + return -1; wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password hash", password, 16); } else { - nt_challenge_response(challenge, password, password_len, - pos); /* NT-Response */ + /* NT-Response */ + if (nt_challenge_response(challenge, password, password_len, + pos)) + return -1; wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password", password, password_len); } diff --git a/src/eap_server/eap_server_ttls.c b/src/eap_server/eap_server_ttls.c index a53633f8f..160462952 100644 --- a/src/eap_server/eap_server_ttls.c +++ b/src/eap_server/eap_server_ttls.c @@ -372,7 +372,7 @@ static void eap_ttls_reset(struct eap_sm *sm, void *priv) static struct wpabuf * eap_ttls_build_start(struct eap_sm *sm, struct eap_ttls_data *data, u8 id) -{ +{ struct wpabuf *req; req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1, @@ -666,11 +666,14 @@ static void eap_ttls_process_phase2_mschap(struct eap_sm *sm, } os_free(chal); - if (sm->user->password_hash) - challenge_response(challenge, sm->user->password, nt_response); - else - nt_challenge_response(challenge, sm->user->password, - sm->user->password_len, nt_response); + if ((sm->user->password_hash && + challenge_response(challenge, sm->user->password, nt_response)) || + (!sm->user->password_hash && + nt_challenge_response(challenge, sm->user->password, + sm->user->password_len, nt_response))) { + eap_ttls_state(data, FAILURE); + return; + } if (os_memcmp_const(nt_response, response + 2 + 24, 24) == 0) { wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");