From 4f88fc0464ad457867fef27f424e2517e3cedce9 Mon Sep 17 00:00:00 2001 From: Brian Gix Date: Thu, 11 Sep 2014 18:27:44 +0300 Subject: [PATCH] P2PS: WPS changes needed for P2PS default PIN This provides additional WPS definitions and rules for negotiating use of P2PS default PIN configuration method. Signed-off-by: Jouni Malinen --- src/p2p/p2p.c | 2 ++ src/p2p/p2p.h | 3 ++- src/p2p/p2p_build.c | 7 +++++-- src/p2p/p2p_go_neg.c | 25 +++++++++++++++++++++++++ src/wps/wps_common.c | 5 +++++ src/wps/wps_defs.h | 4 +++- src/wps/wps_registrar.c | 1 + wpa_supplicant/ctrl_iface.c | 4 +++- wpa_supplicant/p2p_supplicant.c | 2 ++ 9 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 2f62bf7d7..0fb41f88e 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -3723,6 +3723,8 @@ const char * p2p_wps_method_text(enum p2p_wps_method method) return "PBC"; case WPS_NFC: return "NFC"; + case WPS_P2PS: + return "P2PS"; } return "??"; diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 047d3fa6a..9d76032de 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -56,7 +56,8 @@ struct p2p_channels { }; enum p2p_wps_method { - WPS_NOT_READY, WPS_PIN_DISPLAY, WPS_PIN_KEYPAD, WPS_PBC, WPS_NFC + WPS_NOT_READY, WPS_PIN_DISPLAY, WPS_PIN_KEYPAD, WPS_PBC, WPS_NFC, + WPS_P2PS }; /** diff --git a/src/p2p/p2p_build.c b/src/p2p/p2p_build.c index bb77f1814..0789f9943 100644 --- a/src/p2p/p2p_build.c +++ b/src/p2p/p2p_build.c @@ -164,15 +164,18 @@ void p2p_buf_add_device_info(struct wpabuf *buf, struct p2p_data *p2p, if (peer->wps_method == WPS_PBC) methods |= WPS_CONFIG_PUSHBUTTON; else if (peer->wps_method == WPS_PIN_DISPLAY || - peer->wps_method == WPS_PIN_KEYPAD) + peer->wps_method == WPS_PIN_KEYPAD) { methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD; + methods |= WPS_CONFIG_P2PS; + } } else if (p2p->cfg->config_methods) { methods |= p2p->cfg->config_methods & (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_DISPLAY | - WPS_CONFIG_KEYPAD); + WPS_CONFIG_KEYPAD | WPS_CONFIG_P2PS); } else { methods |= WPS_CONFIG_PUSHBUTTON; methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD; + methods |= WPS_CONFIG_P2PS; } wpabuf_put_be16(buf, methods); diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index c654c5a86..fad779186 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -107,6 +107,8 @@ u16 p2p_wps_method_pw_id(enum p2p_wps_method wps_method) return DEV_PW_PUSHBUTTON; case WPS_NFC: return DEV_PW_NFC_CONNECTION_HANDOVER; + case WPS_P2PS: + return DEV_PW_P2PS_DEFAULT; default: return DEV_PW_DEFAULT; } @@ -124,6 +126,8 @@ static const char * p2p_wps_method_str(enum p2p_wps_method wps_method) return "PBC"; case WPS_NFC: return "NFC"; + case WPS_P2PS: + return "P2PS"; default: return "??"; } @@ -218,6 +222,8 @@ int p2p_connect_send(struct p2p_data *p2p, struct p2p_device *dev) config_method = WPS_CONFIG_DISPLAY; else if (dev->wps_method == WPS_PBC) config_method = WPS_CONFIG_PUSHBUTTON; + else if (dev->wps_method == WPS_P2PS) + config_method = WPS_CONFIG_P2PS; else return -1; return p2p_prov_disc_req(p2p, dev->info.p2p_device_addr, @@ -743,6 +749,16 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa, goto fail; } break; + case DEV_PW_P2PS_DEFAULT: + p2p_dbg(p2p, "Peer using P2PS pin"); + if (dev->wps_method != WPS_P2PS) { + p2p_dbg(p2p, + "We have wps_method=%s -> incompatible", + p2p_wps_method_str(dev->wps_method)); + status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD; + goto fail; + } + break; default: if (msg.dev_password_id && msg.dev_password_id == dev->oob_pw_id) { @@ -1102,6 +1118,15 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, goto fail; } break; + case DEV_PW_P2PS_DEFAULT: + p2p_dbg(p2p, "P2P: Peer using P2PS default pin"); + if (dev->wps_method != WPS_P2PS) { + p2p_dbg(p2p, "We have wps_method=%s -> incompatible", + p2p_wps_method_str(dev->wps_method)); + status = P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD; + goto fail; + } + break; default: if (msg.dev_password_id && msg.dev_password_id == dev->oob_pw_id) { diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c index 222d48559..c1ede6a9e 100644 --- a/src/wps/wps_common.c +++ b/src/wps/wps_common.c @@ -535,6 +535,9 @@ u16 wps_config_methods_str2bin(const char *str) #ifdef CONFIG_WPS_NFC methods |= WPS_CONFIG_NFC_INTERFACE; #endif /* CONFIG_WPS_NFC */ +#ifdef CONFIG_P2P + methods |= WPS_CONFIG_P2PS; +#endif /* CONFIG_P2P */ } else { if (os_strstr(str, "ethernet")) methods |= WPS_CONFIG_ETHERNET; @@ -560,6 +563,8 @@ u16 wps_config_methods_str2bin(const char *str) methods |= WPS_CONFIG_VIRT_PUSHBUTTON; if (os_strstr(str, "physical_push_button")) methods |= WPS_CONFIG_PHY_PUSHBUTTON; + if (os_strstr(str, "p2ps")) + methods |= WPS_CONFIG_P2PS; } return methods; diff --git a/src/wps/wps_defs.h b/src/wps/wps_defs.h index da005a41a..25cd14a0b 100644 --- a/src/wps/wps_defs.h +++ b/src/wps/wps_defs.h @@ -154,7 +154,8 @@ enum wps_dev_password_id { DEV_PW_REKEY = 0x0003, DEV_PW_PUSHBUTTON = 0x0004, DEV_PW_REGISTRAR_SPECIFIED = 0x0005, - DEV_PW_NFC_CONNECTION_HANDOVER = 0x0007 + DEV_PW_NFC_CONNECTION_HANDOVER = 0x0007, + DEV_PW_P2PS_DEFAULT = 0x0008 }; /* Message Type */ @@ -244,6 +245,7 @@ enum wps_error_indication { #define WPS_CONFIG_KEYPAD 0x0100 #define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280 #define WPS_CONFIG_PHY_PUSHBUTTON 0x0480 +#define WPS_CONFIG_P2PS 0x1000 #define WPS_CONFIG_VIRT_DISPLAY 0x2008 #define WPS_CONFIG_PHY_DISPLAY 0x4008 diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index 8ee1ea984..48b7e1288 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -2578,6 +2578,7 @@ static enum wps_process_res wps_process_m1(struct wps_data *wps, if (wps->dev_pw_id < 0x10 && wps->dev_pw_id != DEV_PW_DEFAULT && + wps->dev_pw_id != DEV_PW_P2PS_DEFAULT && wps->dev_pw_id != DEV_PW_USER_SPECIFIED && wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED && wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED && diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index ec6d690a4..80481938c 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -4567,7 +4567,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, int pd; int ht40, vht; - /* <"pbc" | "pin" | PIN> [label|display|keypad] + /* <"pbc" | "pin" | PIN> [label|display|keypad|p2ps] * [persistent|persistent=] * [join] [auth] [go_intent=<0..15>] [freq=] [provdisc] * [ht40] [vht] */ @@ -4631,6 +4631,8 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, *pos++ = '\0'; if (os_strncmp(pos, "display", 7) == 0) wps_method = WPS_PIN_DISPLAY; + else if (os_strncmp(pos, "p2ps", 4) == 0) + wps_method = WPS_P2PS; } if (!wps_pin_str_valid(pin)) { os_memcpy(buf, "FAIL-INVALID-PIN\n", 17); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 5fc401ba9..4ae4956bc 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -1268,6 +1268,8 @@ static void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s, #endif /* CONFIG_WPS_NFC */ } else { u16 dev_pw_id = DEV_PW_DEFAULT; + if (wpa_s->p2p_wps_method == WPS_P2PS) + dev_pw_id = DEV_PW_P2PS_DEFAULT; if (wpa_s->p2p_wps_method == WPS_PIN_KEYPAD) dev_pw_id = DEV_PW_REGISTRAR_SPECIFIED; wpas_wps_start_pin(wpa_s, res->peer_interface_addr,