diff --git a/src/handshake.c b/src/handshake.c index ee23dbad..fc1978df 100644 --- a/src/handshake.c +++ b/src/handshake.c @@ -838,6 +838,21 @@ void handshake_state_set_gtk(struct handshake_state *s, const uint8_t *key, memcpy(s->gtk_rsc, rsc, 6); } +void handshake_state_set_igtk(struct handshake_state *s, const uint8_t *key, + unsigned int key_index, const uint8_t *rsc) +{ + enum crypto_cipher cipher = + ie_rsn_cipher_suite_to_cipher(s->group_management_cipher); + int key_len = crypto_cipher_key_len(cipher); + + if (!key_len) + return; + + memcpy(s->igtk, key, key_len); + s->igtk_index = key_index; + memcpy(s->igtk_rsc, rsc, 6); +} + /* * This function performs a match of the RSN/WPA IE obtained from the scan * results vs the RSN/WPA IE obtained as part of the 4-way handshake. If they @@ -1027,6 +1042,25 @@ void handshake_util_build_gtk_kde(enum crypto_cipher cipher, const uint8_t *key, memcpy(to, key, key_len); } +void handshake_util_build_igtk_kde(enum crypto_cipher cipher, const uint8_t *key, + unsigned int key_index, uint8_t *to) +{ + size_t key_len = crypto_cipher_key_len(cipher); + + *to++ = IE_TYPE_VENDOR_SPECIFIC; + *to++ = 12 + key_len; + l_put_be32(HANDSHAKE_KDE_IGTK, to); + to += 4; + *to++ = key_index; + *to++ = 0; + + /** Initialize PN to zero **/ + memset(to, 0, 6); + to += 6; + + memcpy(to, key, key_len); +} + static const uint8_t *handshake_state_get_ft_fils_kek(struct handshake_state *s, size_t *len) { diff --git a/src/handshake.h b/src/handshake.h index 62118fe2..8a356e6b 100644 --- a/src/handshake.h +++ b/src/handshake.h @@ -150,8 +150,11 @@ struct handshake_state { uint8_t r1khid[6]; uint8_t gtk[32]; uint8_t gtk_rsc[6]; + uint8_t igtk[32]; + uint8_t igtk_rsc[6]; uint8_t proto_version : 2; unsigned int gtk_index; + unsigned int igtk_index; uint8_t active_tk_index; struct erp_cache_entry *erp_cache; bool support_ip_allocation : 1; @@ -288,6 +291,9 @@ bool handshake_decode_fte_key(struct handshake_state *s, const uint8_t *wrapped, void handshake_state_set_gtk(struct handshake_state *s, const uint8_t *key, unsigned int key_index, const uint8_t *rsc); +void handshake_state_set_igtk(struct handshake_state *s, const uint8_t *key, + unsigned int key_index, const uint8_t *rsc); + void handshake_state_set_chandef(struct handshake_state *s, struct band_chandef *chandef); int handshake_state_verify_oci(struct handshake_state *s, const uint8_t *oci, @@ -307,5 +313,7 @@ const uint8_t *handshake_util_find_pmkid_kde(const uint8_t *data, size_t data_len); void handshake_util_build_gtk_kde(enum crypto_cipher cipher, const uint8_t *key, unsigned int key_index, uint8_t *to); +void handshake_util_build_igtk_kde(enum crypto_cipher cipher, const uint8_t *key, + unsigned int key_index, uint8_t *to); DEFINE_CLEANUP_FUNC(handshake_state_free);