The procedure for setting extended key IDs is different from the
single PTK key. The key ID is toggled between 0 and 1 and the new
key is set as RX only, then set to RX/TX after message 4/4 goes
out.
Since netdev needs to set this new key before sending message 4,
eapol can include a built message which netdev will store if
required (i.e. using PAE).
---
src/handshake.c | 21 +++++++++++++++++++++
src/handshake.h | 13 +++++++++++++
2 files changed, 34 insertions(+)
diff --git a/src/handshake.c b/src/handshake.c
index 642a25a7..bf50656b 100644
--- a/src/handshake.c
+++ b/src/handshake.c
@@ -76,6 +76,7 @@ static handshake_get_nonce_func_t get_nonce = handshake_get_nonce;
static handshake_install_tk_func_t install_tk = NULL;
static handshake_install_gtk_func_t install_gtk = NULL;
static handshake_install_igtk_func_t install_igtk = NULL;
+static handshake_install_ext_tk_func_t install_ext_tk = NULL;
void __handshake_set_get_nonce_func(handshake_get_nonce_func_t func)
{
@@ -97,6 +98,11 @@ void __handshake_set_install_igtk_func(handshake_install_igtk_func_t
func)
install_igtk = func;
}
+void __handshake_set_install_ext_tk_func(handshake_install_ext_tk_func_t func)
+{
+ install_ext_tk = func;
+}
+
void handshake_state_free(struct handshake_state *s)
{
__typeof__(s->free) destroy = s->free;
@@ -663,6 +669,21 @@ void handshake_state_install_ptk(struct handshake_state *s)
}
}
+void handshake_state_install_ext_ptk(struct handshake_state *s,
+ uint8_t key_idx,
+ struct eapol_frame *ek, uint16_t proto,
+ bool noencrypt)
+{
+ if (install_ext_tk) {
+ uint32_t cipher =
+ ie_rsn_cipher_suite_to_cipher(s->pairwise_cipher);
+
+ install_ext_tk(s, key_idx, handshake_get_tk(s), cipher, ek,
+ proto, noencrypt);
+ }
+}
+
+
void handshake_state_install_gtk(struct handshake_state *s,
uint16_t gtk_key_index,
const uint8_t *gtk, size_t gtk_len,
diff --git a/src/handshake.h b/src/handshake.h
index e67e2c20..449c8fb8 100644
--- a/src/handshake.h
+++ b/src/handshake.h
@@ -27,6 +27,7 @@
struct handshake_state;
enum crypto_cipher;
+struct eapol_frame;
enum handshake_kde {
/* 802.11-2020 Table 12-9 in section 12.7.2 */
@@ -78,11 +79,18 @@ typedef void (*handshake_install_igtk_func_t)(struct handshake_state
*hs,
const uint8_t *igtk, uint8_t igtk_len,
const uint8_t *ipn, uint8_t ipn_len,
uint32_t cipher);
+typedef void (*handshake_install_rx_tk_cb_t)(bool success, void *user_data);
+typedef void (*handshake_install_ext_tk_func_t)(struct handshake_state *hs,
+ uint8_t key_idx, const uint8_t *tk,
+ uint32_t cipher,
+ const struct eapol_frame *step4,
+ uint16_t proto, bool noencrypt);
void __handshake_set_get_nonce_func(handshake_get_nonce_func_t func);
void __handshake_set_install_tk_func(handshake_install_tk_func_t func);
void __handshake_set_install_gtk_func(handshake_install_gtk_func_t func);
void __handshake_set_install_igtk_func(handshake_install_igtk_func_t func);
+void __handshake_set_install_ext_tk_func(handshake_install_ext_tk_func_t func);
struct handshake_state {
uint32_t ifindex;
@@ -227,6 +235,11 @@ size_t handshake_state_get_kek_len(struct handshake_state *s);
const uint8_t *handshake_state_get_kek(struct handshake_state *s);
void handshake_state_install_ptk(struct handshake_state *s);
+void handshake_state_install_ext_ptk(struct handshake_state *s,
+ uint8_t key_idx,
+ struct eapol_frame *ek, uint16_t proto,
+ bool noencrypt);
+
void handshake_state_install_gtk(struct handshake_state *s,
uint16_t gtk_key_index,
const uint8_t *gtk, size_t gtk_len,
--
2.31.1