Cumulative patch from commit 2e988392436227c51002b573ee27a8cee37f70e9
2e98839 P2P: Disable DNS server from dnsmasq
c07f261 P2P NFC: Add script for connection handover with nfcpy
12288d8 WPS NFC: Protect nfcpy pretty print calls against exceptions
c209dd1 WPS NFC: nfcpy script to use new connection handover design
6202500 WPS NFC: Logging level configuration to wps-nfc.py and wps-ap-nfc.py
1f1b5b3 WPS NFC: Clean up nfcpy script no-wait operations
79ede5a WPS NFC: Validate ctrl_iface response before decoding it
ab1db08 WPS NFC: Use argparse in the nfcpy scripts
6f8fa6e WPS NFC: Update wps-nfc.py and wps-ap-nfc.py to use new nfcpy API
b56f6c8 P2P NFC: Add support for freq option in NFC ctrl_iface commands
91a6501 WPS NFC: Use BSSID and AP Channel from handover select
91226e0 WPS: Add testing option to corrupt public key hash
7312776 WPS NFC: add more debug prints for connection handover report
5cd4f66 WPS NFC: Use AP Channel information from credential container
d2f1837 WPS NFC: Add BSSID and AP channel info to Configuration Token
75dbf98 WPS-STRICT: Update valid Device Password ID and Config Error range
5cd4740 P2P NFC: WPA state machine config with driver-based BSS selection
8e9f53c P2P NFC: Static handover with NFC Tag on client
dd87677 P2P NFC: Enable own NFC Tag on GO Registrar
abe44e3 P2P NFC: Add GO info into handover message when in client role
23318be P2P NFC: Optimize join-a-group operation based on NFC information
86e3208 P2P NFC: Copy DH parameters to a separate group interface
d4b4d7f WPS NFC: Update DH keys for ER operations
ac08752 WPS NFC: Use pubkey mismatch config error from Enrollee
59b45d1 P2P NFC: Add processing of P2P client while NFC handover case
74df9ec P2P NFC: Do not try to join peer if both devices are already GO
201b0f5 P2P: Add test option to disable IP address assignment request
25ef852 P2P: Add support for IP address assignment in 4-way handshake
fdd48ff P2P NFC: Optimize GO Negotiation retries
c4f87a7 P2P NFC: Add NFC tag enabling for static handover
dd37a93 P2P NFC: Report handover select from tag for static handover
db6ae69 P2P NFC: Report connection handover as trigger for P2P
9358878 P2P NFC: Build connection handover messages
c00ab85 P2P NFC: Define WPS_NFC config method
0deab08 P2P NFC: Allow separate WPS/P2P IES to be parsed
fca9958 P2P NFC: Pass OOB Dev Password through P2P parser
ab9e344 P2P NFC: Pass OOB Device Password ID to P2P
5154689 P2P NFC: Add WPS attribute building for P2P NFC
01afd8d P2P NFC: Add NDEF helpers for P2P connection handover messages
9e323a2 P2P NFC: Add OOB GO Negotiation Channel attribute
14d8645 WPS NFC: Allow BSSID and channel to be included in handover select
50d1f89 NFC: Update WPS ER to use the new connection handover design
d950793 WPS NFC: Add support for wpa_supplicant AP/GO mode to use handover
fa4c298 WPS NFC: Process new style handover select
068cdb1 WPS NFC: New style connection handover select from AP/Registrar
3189ca0 WPS NFC: Add AP mode connection handover report
41f9ffb WPS NFC: Build new style carrier record for connection handover request
3f1639d WPS NFC: Split DH key generation to a separate function
9754917 WPS NFC: Update NFC connection handover design
34b6795 WPS NFC: Use abbreviated handshake if both PK hashes delivered OOB
57630e6 WPS: Preparations for allowing SSID filtering for provisioning step
5f45455 WPS NFC: Validate peer public key hash on Enrollee
ff40cd6 WPS NFC: Send M2D with config error 20 on pkhash mismatch
e435417 WPS: Remove Version attribute from NFC messages
72403ec WPS: Add builder functions for AP Channel and RF Bands attributes
ea43ad9 P2P: Make group operating channel available
9f7cd9a P2P: Split add-group-info into a helper function
253f2e3 P2P: Apply unsafe frequency rules to available channels
1682c62 Add a header file defining QCA OUI and vendor extensions
Change-Id: Ia7604d018e1ffb25e06bdc01ce258fc4a0569245
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c
index 4b431ad..abf3a4f 100644
--- a/src/wps/wps_common.c
+++ b/src/wps/wps_common.c
@@ -9,6 +9,8 @@
#include "includes.h"
#include "common.h"
+#include "common/defs.h"
+#include "common/ieee802_11_common.h"
#include "crypto/aes_wrap.h"
#include "crypto/crypto.h"
#include "crypto/dh_group5.h"
@@ -16,6 +18,7 @@
#include "crypto/sha256.h"
#include "crypto/random.h"
#include "wps_i.h"
+#include "wps_dev_attr.h"
void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
@@ -349,7 +352,8 @@
#ifdef CONFIG_WPS_OOB
-struct wpabuf * wps_get_oob_cred(struct wps_context *wps)
+struct wpabuf * wps_get_oob_cred(struct wps_context *wps, int rf_band,
+ int channel)
{
struct wps_data data;
struct wpabuf *plain;
@@ -365,8 +369,10 @@
data.wps = wps;
data.auth_type = wps->auth_types;
data.encr_type = wps->encr_types;
- if (wps_build_version(plain) ||
- wps_build_cred(&data, plain) ||
+ if (wps_build_cred(&data, plain) ||
+ (rf_band && wps_build_rf_bands_attr(plain, rf_band)) ||
+ (channel && wps_build_ap_channel(plain, channel)) ||
+ wps_build_mac_addr(plain, wps->dev.mac_addr) ||
wps_build_wfa_ext(plain, 0, NULL, 0)) {
os_free(data.new_psk);
wpabuf_free(plain);
@@ -412,8 +418,7 @@
if (data == NULL)
return NULL;
- if (wps_build_version(data) ||
- wps_build_oob_dev_pw(data, dev_pw_id, pubkey,
+ if (wps_build_oob_dev_pw(data, dev_pw_id, pubkey,
wpabuf_head(dev_pw), wpabuf_len(dev_pw)) ||
wps_build_wfa_ext(data, 0, NULL, 0)) {
wpa_printf(MSG_ERROR, "WPS: Failed to build NFC password "
@@ -636,12 +641,36 @@
}
+int wps_nfc_gen_dh(struct wpabuf **pubkey, struct wpabuf **privkey)
+{
+ struct wpabuf *priv = NULL, *pub = NULL;
+ void *dh_ctx;
+
+ dh_ctx = dh5_init(&priv, &pub);
+ if (dh_ctx == NULL)
+ return -1;
+ pub = wpabuf_zeropad(pub, 192);
+ if (pub == NULL) {
+ wpabuf_free(priv);
+ return -1;
+ }
+ wpa_hexdump_buf(MSG_DEBUG, "WPS: Generated new DH pubkey", pub);
+ dh5_free(dh_ctx);
+
+ wpabuf_free(*pubkey);
+ *pubkey = pub;
+ wpabuf_free(*privkey);
+ *privkey = priv;
+
+ return 0;
+}
+
+
struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey,
struct wpabuf **privkey,
struct wpabuf **dev_pw)
{
- struct wpabuf *priv = NULL, *pub = NULL, *pw;
- void *dh_ctx;
+ struct wpabuf *pw;
u16 val;
pw = wpabuf_alloc(WPS_OOB_DEVICE_PASSWORD_LEN);
@@ -655,22 +684,223 @@
return NULL;
}
- dh_ctx = dh5_init(&priv, &pub);
- if (dh_ctx == NULL) {
+ if (wps_nfc_gen_dh(pubkey, privkey) < 0) {
wpabuf_free(pw);
return NULL;
}
- dh5_free(dh_ctx);
*id = 0x10 + val % 0xfff0;
- wpabuf_free(*pubkey);
- *pubkey = pub;
- wpabuf_free(*privkey);
- *privkey = priv;
wpabuf_free(*dev_pw);
*dev_pw = pw;
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;
+}
+
+
+static int wps_build_ap_freq(struct wpabuf *msg, int freq)
+{
+ enum hostapd_hw_mode mode;
+ u8 channel, rf_band;
+ u16 ap_channel;
+
+ if (freq <= 0)
+ return 0;
+
+ mode = ieee80211_freq_to_chan(freq, &channel);
+ if (mode == NUM_HOSTAPD_MODES)
+ return 0; /* Unknown channel */
+
+ if (mode == HOSTAPD_MODE_IEEE80211G || mode == HOSTAPD_MODE_IEEE80211B)
+ rf_band = WPS_RF_24GHZ;
+ else if (mode == HOSTAPD_MODE_IEEE80211A)
+ rf_band = WPS_RF_50GHZ;
+ else
+ return 0; /* Unknown band */
+ ap_channel = channel;
+
+ if (wps_build_rf_bands_attr(msg, rf_band) ||
+ wps_build_ap_channel(msg, ap_channel))
+ return -1;
+
+ return 0;
+}
+
+
+struct wpabuf * wps_build_nfc_handover_sel(struct wps_context *ctx,
+ struct wpabuf *nfc_dh_pubkey,
+ const u8 *bssid, int freq)
+{
+ 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_ap_freq(msg, freq) ||
+ (bssid && wps_build_mac_addr(msg, bssid)) ||
+ wps_build_wfa_ext(msg, 0, NULL, 0)) {
+ wpabuf_free(msg);
+ return NULL;
+ }
+
+ WPA_PUT_BE16(len, wpabuf_len(msg) - 2);
+
+ return msg;
+}
+
+
+struct wpabuf * wps_build_nfc_handover_req_p2p(struct wps_context *ctx,
+ struct wpabuf *nfc_dh_pubkey)
+{
+ struct wpabuf *msg;
+
+ if (ctx == NULL)
+ return NULL;
+
+ wpa_printf(MSG_DEBUG, "WPS: Building attributes for NFC connection "
+ "handover request (P2P)");
+
+ if (nfc_dh_pubkey == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS: No NFC DH Public Key configured");
+ return NULL;
+ }
+
+ msg = wpabuf_alloc(1000);
+ if (msg == NULL)
+ return msg;
+
+ if (wps_build_manufacturer(&ctx->dev, msg) ||
+ wps_build_model_name(&ctx->dev, msg) ||
+ wps_build_model_number(&ctx->dev, msg) ||
+ wps_build_oob_dev_pw(msg, DEV_PW_NFC_CONNECTION_HANDOVER,
+ nfc_dh_pubkey, NULL, 0) ||
+ wps_build_rf_bands(&ctx->dev, msg, 0) ||
+ wps_build_serial_number(&ctx->dev, msg) ||
+ wps_build_uuid_e(msg, ctx->uuid) ||
+ wps_build_wfa_ext(msg, 0, NULL, 0)) {
+ wpabuf_free(msg);
+ return NULL;
+ }
+
+ return msg;
+}
+
+
+struct wpabuf * wps_build_nfc_handover_sel_p2p(struct wps_context *ctx,
+ int nfc_dev_pw_id,
+ struct wpabuf *nfc_dh_pubkey,
+ struct wpabuf *nfc_dev_pw)
+{
+ struct wpabuf *msg;
+ const u8 *dev_pw;
+ size_t dev_pw_len;
+
+ if (ctx == NULL)
+ return NULL;
+
+ wpa_printf(MSG_DEBUG, "WPS: Building attributes for NFC connection "
+ "handover select (P2P)");
+
+ if (nfc_dh_pubkey == NULL ||
+ (nfc_dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER &&
+ nfc_dev_pw == NULL)) {
+ wpa_printf(MSG_DEBUG, "WPS: No NFC OOB Device Password "
+ "configured");
+ return NULL;
+ }
+
+ msg = wpabuf_alloc(1000);
+ if (msg == NULL)
+ return msg;
+
+ if (nfc_dev_pw) {
+ dev_pw = wpabuf_head(nfc_dev_pw);
+ dev_pw_len = wpabuf_len(nfc_dev_pw);
+ } else {
+ dev_pw = NULL;
+ dev_pw_len = 0;
+ }
+
+ if (wps_build_manufacturer(&ctx->dev, msg) ||
+ wps_build_model_name(&ctx->dev, msg) ||
+ wps_build_model_number(&ctx->dev, msg) ||
+ wps_build_oob_dev_pw(msg, nfc_dev_pw_id, nfc_dh_pubkey,
+ dev_pw, dev_pw_len) ||
+ wps_build_rf_bands(&ctx->dev, msg, 0) ||
+ wps_build_serial_number(&ctx->dev, msg) ||
+ wps_build_uuid_e(msg, ctx->uuid) ||
+ wps_build_wfa_ext(msg, 0, NULL, 0)) {
+ wpabuf_free(msg);
+ return NULL;
+ }
+
+ return msg;
+}
+
#endif /* CONFIG_WPS_NFC */