|
@@ -10,6 +10,7 @@
|
|
|
|
|
|
#include "common.h"
|
|
|
#include "crypto/sha256.h"
|
|
|
+#include "crypto/ms_funcs.h"
|
|
|
#include "eap_peer/eap_i.h"
|
|
|
#include "eap_common/eap_pwd_common.h"
|
|
|
|
|
@@ -25,6 +26,7 @@ struct eap_pwd_data {
|
|
|
size_t id_server_len;
|
|
|
u8 *password;
|
|
|
size_t password_len;
|
|
|
+ int password_hash;
|
|
|
u16 group_num;
|
|
|
EAP_PWD_group *grp;
|
|
|
|
|
@@ -86,8 +88,9 @@ static void * eap_pwd_init(struct eap_sm *sm)
|
|
|
const u8 *identity, *password;
|
|
|
size_t identity_len, password_len;
|
|
|
int fragment_size;
|
|
|
+ int pwhash;
|
|
|
|
|
|
- password = eap_get_config_password(sm, &password_len);
|
|
|
+ password = eap_get_config_password2(sm, &password_len, &pwhash);
|
|
|
if (password == NULL) {
|
|
|
wpa_printf(MSG_INFO, "EAP-PWD: No password configured!");
|
|
|
return NULL;
|
|
@@ -129,6 +132,7 @@ static void * eap_pwd_init(struct eap_sm *sm)
|
|
|
}
|
|
|
os_memcpy(data->password, password, password_len);
|
|
|
data->password_len = password_len;
|
|
|
+ data->password_hash = pwhash;
|
|
|
|
|
|
data->out_frag_pos = data->in_frag_pos = 0;
|
|
|
data->inbuf = data->outbuf = NULL;
|
|
@@ -216,6 +220,10 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
|
|
|
const u8 *payload, size_t payload_len)
|
|
|
{
|
|
|
struct eap_pwd_id *id;
|
|
|
+ const u8 *password;
|
|
|
+ size_t password_len;
|
|
|
+ u8 pwhashhash[16];
|
|
|
+ int res;
|
|
|
|
|
|
if (data->state != PWD_ID_Req) {
|
|
|
ret->ignore = TRUE;
|
|
@@ -231,6 +239,9 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
|
|
|
|
|
|
id = (struct eap_pwd_id *) payload;
|
|
|
data->group_num = be_to_host16(id->group_num);
|
|
|
+ wpa_printf(MSG_DEBUG,
|
|
|
+ "EAP-PWD: Server EAP-pwd-ID proposal: group=%u random=%u prf=%u prep=%u",
|
|
|
+ data->group_num, id->random_function, id->prf, id->prep);
|
|
|
if ((id->random_function != EAP_PWD_DEFAULT_RAND_FUNC) ||
|
|
|
(id->prf != EAP_PWD_DEFAULT_PRF)) {
|
|
|
ret->ignore = TRUE;
|
|
@@ -238,6 +249,22 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ if (id->prep != EAP_PWD_PREP_NONE &&
|
|
|
+ id->prep != EAP_PWD_PREP_MS) {
|
|
|
+ wpa_printf(MSG_DEBUG,
|
|
|
+ "EAP-PWD: Unsupported password pre-processing technique (Prep=%u)",
|
|
|
+ id->prep);
|
|
|
+ eap_pwd_state(data, FAILURE);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (id->prep == EAP_PWD_PREP_NONE && data->password_hash) {
|
|
|
+ wpa_printf(MSG_DEBUG,
|
|
|
+ "EAP-PWD: Unhashed password not available");
|
|
|
+ eap_pwd_state(data, FAILURE);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
wpa_printf(MSG_DEBUG, "EAP-PWD (peer): using group %d",
|
|
|
data->group_num);
|
|
|
|
|
@@ -260,12 +287,39 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ if (id->prep == EAP_PWD_PREP_MS) {
|
|
|
+ if (data->password_hash) {
|
|
|
+ res = hash_nt_password_hash(data->password, pwhashhash);
|
|
|
+ } else {
|
|
|
+ u8 pwhash[16];
|
|
|
+
|
|
|
+ res = nt_password_hash(data->password,
|
|
|
+ data->password_len, pwhash);
|
|
|
+ if (res == 0)
|
|
|
+ res = hash_nt_password_hash(pwhash, pwhashhash);
|
|
|
+ os_memset(pwhash, 0, sizeof(pwhash));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (res) {
|
|
|
+ eap_pwd_state(data, FAILURE);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ password = pwhashhash;
|
|
|
+ password_len = sizeof(pwhashhash);
|
|
|
+ } else {
|
|
|
+ password = data->password;
|
|
|
+ password_len = data->password_len;
|
|
|
+ }
|
|
|
+
|
|
|
/* compute PWE */
|
|
|
- if (compute_password_element(data->grp, data->group_num,
|
|
|
- data->password, data->password_len,
|
|
|
- data->id_server, data->id_server_len,
|
|
|
- data->id_peer, data->id_peer_len,
|
|
|
- id->token)) {
|
|
|
+ res = compute_password_element(data->grp, data->group_num,
|
|
|
+ password, password_len,
|
|
|
+ data->id_server, data->id_server_len,
|
|
|
+ data->id_peer, data->id_peer_len,
|
|
|
+ id->token);
|
|
|
+ os_memset(pwhashhash, 0, sizeof(pwhashhash));
|
|
|
+ if (res) {
|
|
|
wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to compute PWE");
|
|
|
eap_pwd_state(data, FAILURE);
|
|
|
return;
|