aboutsummaryrefslogtreecommitdiffstats
path: root/src/wps
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2013-04-02 15:30:58 (GMT)
committerJouni Malinen <j@w1.fi>2014-01-27 19:10:55 (GMT)
commit975491793b3b4a0bd33bf783773bed5abb85fea8 (patch)
tree966f1248eb9e6e0c279785d34c64657c53aaa1bb /src/wps
parent34b67950154b202a2a2753a08ed71d4706bcf027 (diff)
downloadhostap-975491793b3b4a0bd33bf783773bed5abb85fea8.zip
hostap-975491793b3b4a0bd33bf783773bed5abb85fea8.tar.gz
hostap-975491793b3b4a0bd33bf783773bed5abb85fea8.tar.bz2
WPS NFC: Update NFC connection handover design
The new Device Password ID 7 is used to indicate that NFC connection handover is used with DH public key hash from both devices being exchanged over the NFC connection handover messages. This allows an abbreviated M1-M2 handshake to be used since Device Password does not need to be used when DH is authenticated with the out-of-band information (validation of the public key against the hash). Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'src/wps')
-rw-r--r--src/wps/wps.c4
-rw-r--r--src/wps/wps.h4
-rw-r--r--src/wps/wps_attr_build.c15
-rw-r--r--src/wps/wps_attr_parse.c9
-rw-r--r--src/wps/wps_common.c86
-rw-r--r--src/wps/wps_defs.h3
-rw-r--r--src/wps/wps_registrar.c26
7 files changed, 131 insertions, 16 deletions
diff --git a/src/wps/wps.c b/src/wps/wps.c
index 80343c8..a38a6db 100644
--- a/src/wps/wps.c
+++ b/src/wps/wps.c
@@ -58,6 +58,10 @@ struct wps_data * wps_init(const struct wps_config *cfg)
}
#ifdef CONFIG_WPS_NFC
+ if (cfg->pin == NULL &&
+ cfg->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER)
+ data->dev_pw_id = cfg->dev_pw_id;
+
if (cfg->wps->ap && !cfg->registrar && cfg->wps->ap_nfc_dev_pw_id) {
/* Keep AP PIN as alternative Device Password */
data->alt_dev_pw_id = data->dev_pw_id;
diff --git a/src/wps/wps.h b/src/wps/wps.h
index c093b26..66242ca 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -859,6 +859,10 @@ struct wpabuf * wps_nfc_token_build(int ndef, int id, struct wpabuf *pubkey,
struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey,
struct wpabuf **privkey,
struct wpabuf **dev_pw);
+struct wpabuf * wps_build_nfc_handover_req(struct wps_context *ctx,
+ struct wpabuf *nfc_dh_pubkey);
+struct wpabuf * wps_build_nfc_handover_sel(struct wps_context *ctx,
+ struct wpabuf *nfc_dh_pubkey);
/* ndef.c */
struct wpabuf * ndef_parse_wifi(const struct wpabuf *buf);
diff --git a/src/wps/wps_attr_build.c b/src/wps/wps_attr_build.c
index 666c98d..2f0c47c 100644
--- a/src/wps/wps_attr_build.c
+++ b/src/wps/wps_attr_build.c
@@ -38,8 +38,11 @@ int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
wps->wps->dh_ctx = NULL;
pubkey = wpabuf_dup(wps->wps->dh_pubkey);
#ifdef CONFIG_WPS_NFC
- } else if (wps->dev_pw_id >= 0x10 && wps->wps->ap &&
- wps->dev_pw_id == wps->wps->ap_nfc_dev_pw_id) {
+ } else if ((wps->dev_pw_id >= 0x10 ||
+ wps->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) &&
+ wps->wps->ap &&
+ (wps->dev_pw_id == wps->wps->ap_nfc_dev_pw_id ||
+ wps->wps->ap_nfc_dh_pubkey)) {
wpa_printf(MSG_DEBUG, "WPS: Using NFC password token DH keys");
if (wps->wps->ap_nfc_dh_privkey == NULL) {
wpa_printf(MSG_DEBUG,
@@ -399,9 +402,11 @@ int wps_build_oob_dev_pw(struct wpabuf *msg, u16 dev_pw_id,
pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
wpabuf_put_data(msg, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
wpabuf_put_be16(msg, dev_pw_id);
- wpa_hexdump_key(MSG_DEBUG, "WPS: OOB Device Password",
- dev_pw, dev_pw_len);
- wpabuf_put_data(msg, dev_pw, dev_pw_len);
+ if (dev_pw) {
+ wpa_hexdump_key(MSG_DEBUG, "WPS: OOB Device Password",
+ dev_pw, dev_pw_len);
+ wpabuf_put_data(msg, dev_pw, dev_pw_len);
+ }
return 0;
}
diff --git a/src/wps/wps_attr_parse.c b/src/wps/wps_attr_parse.c
index 3999b1b..f4e2e38 100644
--- a/src/wps/wps_attr_parse.c
+++ b/src/wps/wps_attr_parse.c
@@ -263,10 +263,13 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
attr->dev_password_id = pos;
break;
case ATTR_OOB_DEVICE_PASSWORD:
- if (len < WPS_OOB_PUBKEY_HASH_LEN + 2 +
- WPS_OOB_DEVICE_PASSWORD_MIN_LEN ||
+ if (len < WPS_OOB_PUBKEY_HASH_LEN + 2 ||
len > WPS_OOB_PUBKEY_HASH_LEN + 2 +
- WPS_OOB_DEVICE_PASSWORD_LEN) {
+ WPS_OOB_DEVICE_PASSWORD_LEN ||
+ (len < WPS_OOB_PUBKEY_HASH_LEN + 2 +
+ WPS_OOB_DEVICE_PASSWORD_MIN_LEN &&
+ WPA_GET_BE16(pos + WPS_OOB_PUBKEY_HASH_LEN) !=
+ DEV_PW_NFC_CONNECTION_HANDOVER)) {
wpa_printf(MSG_DEBUG, "WPS: Invalid OOB Device "
"Password length %u", len);
return -1;
diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c
index b1eb682..1c0e3ed 100644
--- a/src/wps/wps_common.c
+++ b/src/wps/wps_common.c
@@ -671,4 +671,90 @@ struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey,
return wps_nfc_token_build(ndef, *id, *pubkey, *dev_pw);
}
+
+struct wpabuf * wps_build_nfc_handover_req(struct wps_context *ctx,
+ struct wpabuf *nfc_dh_pubkey)
+{
+ struct wpabuf *msg;
+ void *len;
+
+ if (ctx == NULL)
+ return NULL;
+
+ wpa_printf(MSG_DEBUG, "WPS: Building attributes for NFC connection "
+ "handover request");
+
+ if (nfc_dh_pubkey == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS: No NFC OOB Device Password "
+ "configured");
+ return NULL;
+ }
+
+ msg = wpabuf_alloc(1000);
+ if (msg == NULL)
+ return msg;
+ len = wpabuf_put(msg, 2);
+
+ if (wps_build_oob_dev_pw(msg, DEV_PW_NFC_CONNECTION_HANDOVER,
+ nfc_dh_pubkey, NULL, 0) ||
+ wps_build_uuid_e(msg, ctx->uuid) ||
+ wps_build_wfa_ext(msg, 0, NULL, 0)) {
+ wpabuf_free(msg);
+ return NULL;
+ }
+
+ WPA_PUT_BE16(len, wpabuf_len(msg) - 2);
+
+ return msg;
+}
+
+
+static int wps_build_ssid(struct wpabuf *msg, struct wps_context *wps)
+{
+ wpa_printf(MSG_DEBUG, "WPS: * SSID");
+ wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID in Connection Handover Select",
+ wps->ssid, wps->ssid_len);
+ wpabuf_put_be16(msg, ATTR_SSID);
+ wpabuf_put_be16(msg, wps->ssid_len);
+ wpabuf_put_data(msg, wps->ssid, wps->ssid_len);
+ return 0;
+}
+
+
+struct wpabuf * wps_build_nfc_handover_sel(struct wps_context *ctx,
+ struct wpabuf *nfc_dh_pubkey)
+{
+ struct wpabuf *msg;
+ void *len;
+
+ if (ctx == NULL)
+ return NULL;
+
+ wpa_printf(MSG_DEBUG, "WPS: Building attributes for NFC connection "
+ "handover select");
+
+ if (nfc_dh_pubkey == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS: No NFC OOB Device Password "
+ "configured");
+ return NULL;
+ }
+
+ msg = wpabuf_alloc(1000);
+ if (msg == NULL)
+ return msg;
+ len = wpabuf_put(msg, 2);
+
+ if (wps_build_oob_dev_pw(msg, DEV_PW_NFC_CONNECTION_HANDOVER,
+ nfc_dh_pubkey, NULL, 0) ||
+ wps_build_ssid(msg, ctx) ||
+ wps_build_wfa_ext(msg, 0, NULL, 0)) {
+ wpabuf_free(msg);
+ return NULL;
+ }
+
+ WPA_PUT_BE16(len, wpabuf_len(msg) - 2);
+
+ return msg;
+}
+
#endif /* CONFIG_WPS_NFC */
diff --git a/src/wps/wps_defs.h b/src/wps/wps_defs.h
index 1249606..a736f27 100644
--- a/src/wps/wps_defs.h
+++ b/src/wps/wps_defs.h
@@ -155,7 +155,8 @@ enum wps_dev_password_id {
DEV_PW_MACHINE_SPECIFIED = 0x0002,
DEV_PW_REKEY = 0x0003,
DEV_PW_PUSHBUTTON = 0x0004,
- DEV_PW_REGISTRAR_SPECIFIED = 0x0005
+ DEV_PW_REGISTRAR_SPECIFIED = 0x0005,
+ DEV_PW_NFC_CONNECTION_HANDOVER = 0x0007
};
/* Message Type */
diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c
index b8709b9..f8f2ae1 100644
--- a/src/wps/wps_registrar.c
+++ b/src/wps/wps_registrar.c
@@ -1361,6 +1361,13 @@ static int wps_get_dev_password(struct wps_data *wps)
pin_len = 8;
#ifdef CONFIG_WPS_NFC
} else if (wps->nfc_pw_token) {
+ if (wps->nfc_pw_token->pw_id == DEV_PW_NFC_CONNECTION_HANDOVER)
+ {
+ wpa_printf(MSG_DEBUG, "WPS: Using NFC connection "
+ "handover and abbreviated WPS handshake "
+ "without Device Password");
+ return 0;
+ }
wpa_printf(MSG_DEBUG, "WPS: Use OOB Device Password from NFC "
"Password Token");
pin = wps->nfc_pw_token->dev_pw;
@@ -2556,6 +2563,9 @@ static enum wps_process_res wps_process_m1(struct wps_data *wps,
wps->dev_pw_id != DEV_PW_USER_SPECIFIED &&
wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED &&
wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED &&
+#ifdef CONFIG_WPS_NFC
+ wps->dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER &&
+#endif /* CONFIG_WPS_NFC */
(wps->dev_pw_id != DEV_PW_PUSHBUTTON ||
!wps->wps->registrar->pbc)) {
wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d",
@@ -2565,7 +2575,8 @@ static enum wps_process_res wps_process_m1(struct wps_data *wps,
}
#ifdef CONFIG_WPS_NFC
- if (wps->dev_pw_id >= 0x10) {
+ if (wps->dev_pw_id >= 0x10 ||
+ wps->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) {
struct wps_nfc_pw_token *token;
const u8 *addr[1];
u8 hash[WPS_HASH_LEN];
@@ -3541,10 +3552,12 @@ 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);
- token->dev_pw_len = dev_pw_len * 2;
+ if (dev_pw) {
+ wpa_snprintf_hex_uppercase((char *) token->dev_pw,
+ sizeof(token->dev_pw),
+ dev_pw, dev_pw_len);
+ token->dev_pw_len = dev_pw_len * 2;
+ }
dl_list_add(&reg->nfc_pw_tokens, &token->list);
@@ -3573,8 +3586,7 @@ int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
u16 id;
size_t dev_pw_len;
- if (oob_dev_pw_len < WPS_OOB_PUBKEY_HASH_LEN + 2 +
- WPS_OOB_DEVICE_PASSWORD_MIN_LEN ||
+ if (oob_dev_pw_len < WPS_OOB_PUBKEY_HASH_LEN + 2 ||
oob_dev_pw_len > WPS_OOB_PUBKEY_HASH_LEN + 2 +
WPS_OOB_DEVICE_PASSWORD_LEN)
return -1;