From 34b67950154b202a2a2753a08ed71d4706bcf027 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 24 Feb 2013 17:30:18 +0200 Subject: [PATCH] WPS NFC: Use abbreviated handshake if both PK hashes delivered OOB When both the Registrar and Enrollee public key hashes are delivered out-of-band (in NFC connection handover), use abbreviated WPS handshake (skip M3-M8). Signed-hostap: Jouni Malinen --- src/wps/wps.h | 3 ++- src/wps/wps_enrollee.c | 32 ++++++++++++++++++++++++++++++++ src/wps/wps_registrar.c | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/wps/wps.h b/src/wps/wps.h index 7e609c831..c093b26d1 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -806,7 +806,8 @@ int wps_registrar_config_ap(struct wps_registrar *reg, struct wps_credential *cred); int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg, const u8 *pubkey_hash, u16 pw_id, - const u8 *dev_pw, size_t dev_pw_len); + const u8 *dev_pw, size_t dev_pw_len, + int pk_hash_provided_oob); int wps_registrar_add_nfc_password_token(struct wps_registrar *reg, const u8 *oob_dev_pw, size_t oob_dev_pw_len); diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c index 03005822c..5d63c4c08 100644 --- a/src/wps/wps_enrollee.c +++ b/src/wps/wps_enrollee.c @@ -946,6 +946,38 @@ static enum wps_process_res wps_process_m2(struct wps_data *wps, return WPS_CONTINUE; } +#ifdef CONFIG_WPS_NFC + if (wps->peer_pubkey_hash_set) { + struct wpabuf *decrypted; + struct wps_parse_attr eattr; + + decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings, + attr->encr_settings_len); + if (decrypted == NULL) { + wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt " + "Encrypted Settings attribute"); + wps->state = SEND_WSC_NACK; + return WPS_CONTINUE; + } + + wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted " + "Settings attribute"); + if (wps_parse_msg(decrypted, &eattr) < 0 || + wps_process_key_wrap_auth(wps, decrypted, + eattr.key_wrap_auth) || + wps_process_creds(wps, eattr.cred, eattr.cred_len, + eattr.num_cred, attr->version2 != NULL)) { + wpabuf_free(decrypted); + wps->state = SEND_WSC_NACK; + return WPS_CONTINUE; + } + wpabuf_free(decrypted); + + wps->state = WPS_MSG_DONE; + return WPS_CONTINUE; + } +#endif /* CONFIG_WPS_NFC */ + wps->state = SEND_M3; return WPS_CONTINUE; } diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index 61bb6415b..b8709b9f7 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -34,6 +34,7 @@ struct wps_nfc_pw_token { u16 pw_id; u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN * 2 + 1]; size_t dev_pw_len; + int pk_hash_provided_oob; /* whether own PK hash was provided OOB */ }; @@ -1777,6 +1778,7 @@ static struct wpabuf * wps_build_ap_cred(struct wps_data *wps) static struct wpabuf * wps_build_m2(struct wps_data *wps) { struct wpabuf *msg; + int config_in_m2 = 0; if (random_get_bytes(wps->nonce_r, WPS_NONCE_LEN) < 0) return NULL; @@ -1807,14 +1809,40 @@ static struct wpabuf * wps_build_m2(struct wps_data *wps) wps_build_config_error(msg, WPS_CFG_NO_ERROR) || wps_build_dev_password_id(msg, wps->dev_pw_id) || wps_build_os_version(&wps->wps->dev, msg) || - wps_build_wfa_ext(msg, 0, NULL, 0) || - wps_build_authenticator(wps, msg)) { + wps_build_wfa_ext(msg, 0, NULL, 0)) { + wpabuf_free(msg); + return NULL; + } + +#ifdef CONFIG_WPS_NFC + if (wps->nfc_pw_token && wps->nfc_pw_token->pk_hash_provided_oob) { + /* + * Use abbreviated handshake since public key hash allowed + * Enrollee to validate our public key similarly to how Enrollee + * public key was validated. There is no need to validate Device + * Password in this case. + */ + struct wpabuf *plain = wpabuf_alloc(500); + if (plain == NULL || + wps_build_cred(wps, plain) || + wps_build_key_wrap_auth(wps, plain) || + wps_build_encr_settings(wps, msg, plain)) { + wpabuf_free(msg); + wpabuf_free(plain); + return NULL; + } + wpabuf_free(plain); + config_in_m2 = 1; + } +#endif /* CONFIG_WPS_NFC */ + + if (wps_build_authenticator(wps, msg)) { wpabuf_free(msg); return NULL; } wps->int_reg = 1; - wps->state = RECV_M3; + wps->state = config_in_m2 ? RECV_DONE : RECV_M3; return msg; } @@ -3496,7 +3524,8 @@ int wps_registrar_config_ap(struct wps_registrar *reg, int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg, const u8 *pubkey_hash, u16 pw_id, - const u8 *dev_pw, size_t dev_pw_len) + const u8 *dev_pw, size_t dev_pw_len, + int pk_hash_provided_oob) { struct wps_nfc_pw_token *token; @@ -3511,6 +3540,7 @@ int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg, os_memcpy(token->pubkey_hash, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN); token->pw_id = pw_id; + token->pk_hash_provided_oob = pk_hash_provided_oob; wpa_snprintf_hex_uppercase((char *) token->dev_pw, sizeof(token->dev_pw), dev_pw, dev_pw_len); @@ -3563,7 +3593,7 @@ int wps_registrar_add_nfc_password_token(struct wps_registrar *reg, wpa_hexdump_key(MSG_DEBUG, "WPS: Device Password", dev_pw, dev_pw_len); return wps_registrar_add_nfc_pw_token(reg, hash, id, dev_pw, - dev_pw_len); + dev_pw_len, 0); }