Signed-off-by: Shivani Baranwal <quic_shivbara@xxxxxxxxxxx> --- src/common/wpa_common.c | 2 ++ src/common/wpa_common.h | 1 + src/p2p/p2p.c | 54 +++++++++++++++++++++++++++++++++++++++-- src/p2p/p2p.h | 8 ++++++ src/p2p/p2p_i.h | 10 ++++++++ wpa_supplicant/ctrl_iface.c | 23 ++++++++++++++++++ wpa_supplicant/p2p_supplicant.c | 11 +++++++++ wpa_supplicant/p2p_supplicant.h | 8 ++++++ 8 files changed, 115 insertions(+), 2 deletions(-) diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index 28f478c..ef8a0fa 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -582,6 +582,7 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label, ptk->kek2_len = 0; ptk->kck2_len = 0; + ptk->ptk_len = ptk_len; os_memset(tmp, 0, sizeof(tmp)); os_memset(data, 0, data_len); return 0; @@ -1555,6 +1556,7 @@ int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len, ptk->kdk, ptk->kdk_len); } + ptk->ptk_len = ptk_len; forced_memzero(tmp, sizeof(tmp)); ret = 0; err: diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index 8f77d38..63196bc 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -270,6 +270,7 @@ struct wpa_ptk { size_t kck2_len; size_t kek2_len; size_t kdk_len; + size_t ptk_len; size_t ltf_keyseed_len; int installed; /* 1 if key has already been installed to driver */ }; diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 2c81ec5..59a15a8 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -3064,6 +3064,11 @@ void p2p_group_formation_failed(struct p2p_data *p2p) p2p_clear_go_neg(p2p); } +void p2p_set_store_pasn_ptk(struct p2p_data *p2p, u8 val) +{ + p2p->cfg->store_pasn_ptk = val; +} + bool is_p2p_6ghz_disabled(struct p2p_data *p2p) { @@ -6875,6 +6880,7 @@ int p2p_handle_pasn_auth(struct p2p_data *p2p, struct p2p_device *dev, p2p_dbg(p2p, "P2P PASN Responder: Handle PASN Auth3 failed"); return -1; } + p2p_pasn_store_ptk(p2p, &pasn->ptk); if (p2p_pasn_handle_action_wrapper(p2p, dev, mgmt, len, freq, auth_transaction)) { p2p_dbg(p2p, "P2P PASN Responder: Handle Auth3 action wrapper failed"); @@ -6930,12 +6936,12 @@ int p2p_pasn_auth_rx(struct p2p_data *p2p, const struct ieee80211_mgmt *mgmt, return -1; } ret = wpa_pasn_auth_rx(pasn, (const u8 *)mgmt, len, &pasn_data); - forced_memzero(pasn_get_ptk(pasn), sizeof(pasn->ptk)); - if (ret < 0) { p2p_dbg(p2p, "P2P PASN: wpa_pasn_auth_rx failed"); dev->role = P2P_ROLE_IDLE; } + p2p_pasn_store_ptk(p2p, &pasn->ptk); + forced_memzero(pasn_get_ptk(pasn), sizeof(pasn->ptk)); } else { ret = p2p_handle_pasn_auth(p2p, dev, mgmt, len, freq); @@ -6952,4 +6958,48 @@ void p2p_pasn_pmksa_set_pmk(struct p2p_data *p2p, const u8 *src, const u8 *dst, pasn_responder_pmksa_cache_add(p2p->responder_pmksa, src, dst, pmk, pmk_len, pmkid); } + + +void p2p_pasn_store_ptk(struct p2p_data *p2p, struct wpa_ptk *ptk) +{ + u8 *pos; + + if (!p2p->cfg->store_pasn_ptk) + return; + + if (ptk->ptk_len > sizeof(p2p->pasn_ptk)) { + p2p_dbg(p2p, "P2P PASN PTK exceeds: (len=%ld)", ptk->ptk_len); + return; + } + + pos = p2p->pasn_ptk; + p2p->pasn_ptk_len = ptk->ptk_len; + if (ptk->kck_len) { + os_memcpy(pos, ptk->kck, ptk->kck_len); + pos += ptk->kck_len; + } + if (ptk->kek_len) { + os_memcpy(pos, ptk->kek, ptk->kek_len); + pos += ptk->kek_len; + } + if (ptk->tk_len) { + os_memcpy(pos, ptk->tk, ptk->tk_len); + pos += ptk->tk_len; + } + if (ptk->kdk_len) { + os_memcpy(pos, ptk->kdk, ptk->kdk_len); + pos += ptk->kdk_len; + } +} + + +int p2p_pasn_get_ptk(struct p2p_data *p2p, const u8 **buf, size_t *buf_len) +{ + if (!p2p || !p2p->cfg->store_pasn_ptk || !p2p->pasn_ptk_len) + return -1; + + *buf_len = p2p->pasn_ptk_len; + *buf = p2p->pasn_ptk; + return 0; +} #endif diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 6024370..5d798a0 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -752,6 +752,11 @@ struct p2p_config { void *cb_ctx; /** + * store pasn ptk, Used for certification mode + */ + bool store_pasn_ptk; + + /** * debug_print - Debug print * @ctx: Callback context from cb_ctx * @level: Debug verbosity level (MSG_*) @@ -2716,4 +2721,7 @@ int p2p_pasn_auth_tx_status(struct p2p_data *p2p, const u8 *data, size_t data_len, u8 acked, bool verify); void p2p_pasn_pmksa_set_pmk(struct p2p_data *p2p, const u8 *src, const u8 *dst, u8 *pmk, u16 pmk_len, u8 *pmkid); +void p2p_set_store_pasn_ptk(struct p2p_data *p2p, u8 val); +void p2p_pasn_store_ptk(struct p2p_data *p2p, struct wpa_ptk *ptk); +int p2p_pasn_get_ptk(struct p2p_data *p2p, const u8 **buf, size_t *buf_len); #endif /* P2P_H */ diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 3e9119b..32a8421 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -681,6 +681,16 @@ struct p2p_data { * Indicate that auto go is enabled for this device */ u8 auto_go; + + /** + * pasn ptk of recent auth when store_pasn_ptk enabled + */ + u8 pasn_ptk[128]; + + /** + * pasn ptk length + */ + size_t pasn_ptk_len; }; /** diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 5a5b9e4..9c9e9a7 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -7748,6 +7748,11 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd) return 0; } + if (os_strcmp(cmd, "store_pasn_ptk") == 0) { + p2p_set_store_pasn_ptk(wpa_s->global->p2p, atoi(param)); + return 0; + } + wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'", cmd); @@ -10905,6 +10910,20 @@ static void wpas_ctrl_iface_pmksa_flush(struct wpa_supplicant *wpa_s) #endif /* CONFIG_AP */ } +#ifdef CONFIG_PASN + +static int p2p_ctrl_get_pasn_ptk(struct wpa_supplicant *wpa_s, char *buf, + size_t buflen) +{ + const u8 *ptk; + size_t ptk_len; + + if (wpas_p2p_get_pasn_ptk(wpa_s, &ptk, &ptk_len)) + return -1; + return wpa_snprintf_hex(buf, buflen, ptk, ptk_len); +} + +#endif // CONFIG_PASN #ifdef CONFIG_PMKSA_CACHE_EXTERNAL @@ -12918,6 +12937,10 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, reply_len = -1; } else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) { reply_len = p2p_get_passphrase(wpa_s, reply, reply_size); +#ifdef CONFIG_PASN + } else if (os_strcmp(buf, "P2P_GET_PASNPTK") == 0) { + reply_len = p2p_ctrl_get_pasn_ptk(wpa_s, reply, reply_size); +#endif /* CONFIG_PASN */ } else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) { reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply, reply_size); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 249390b..394beef 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -11159,4 +11159,15 @@ int wpas_p2p_pasn_auth_rx(struct wpa_supplicant *wpa_s, return -2; return p2p_pasn_auth_rx(p2p, mgmt, len, freq); } + + +int wpas_p2p_get_pasn_ptk(struct wpa_supplicant *wpa_s, const u8 **ptk, + size_t *ptk_len) +{ + struct p2p_data *p2p = wpa_s->global->p2p; + + if (wpa_s->global->p2p_disabled || !p2p) + return -2; + return p2p_pasn_get_ptk(p2p, ptk, ptk_len); +} #endif /* CONFIG_PASN */ diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index c9e9c78..3dcc9e3 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -234,6 +234,8 @@ int wpas_p2p_pasn_auth_rx(struct wpa_supplicant *wpa_s, const struct ieee80211_mgmt *mgmt, size_t len, int freq); int wpas_p2p_remove_all_identity(struct wpa_supplicant *wpa_s); +int wpas_p2p_get_pasn_ptk(struct wpa_supplicant *wpa_s, const u8 **ptk, + size_t *ptk_len); #else /* CONFIG_P2P */ static inline int @@ -377,6 +379,12 @@ wpas_p2p_remove_all_identity(struct wpa_supplicant *wpa_s) return 0; } +static inline int wpas_p2p_get_pasn_ptk(struct wpa_supplicant *wpa_s, + const u8 **ptk, size_t *ptk_len) +{ + return 0; +} + #endif /* CONFIG_P2P */ #endif /* P2P_SUPPLICANT_H */ -- 2.7.4 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap