mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2025-01-03 10:32:33 +01:00
crypto/handshake/eapol: Allow other PTK lengths
The crypto_ptk was hard coded for 16 byte KCK/KEK. Depending on the AKM these can be up to 32 bytes. This changes completely removes the crypto_ptk struct and adds getters to the handshake object for the kck and kek. Like before the PTK is derived into a continuous buffer, and the kck/kek getters take care of returning the proper key offset depending on AKM. To allow for larger than 16 byte keys aes_unwrap needed to be modified to take the kek length.
This commit is contained in:
parent
3b801526f0
commit
6771a06463
11
src/crypto.c
11
src/crypto.c
@ -129,7 +129,7 @@ bool cmac_aes(const void *key, size_t key_len,
|
||||
*
|
||||
* NOTE: Buffers @in and @out can overlap
|
||||
*/
|
||||
bool aes_unwrap(const uint8_t *kek, const uint8_t *in, size_t len,
|
||||
bool aes_unwrap(const uint8_t *kek, size_t kek_len, const uint8_t *in, size_t len,
|
||||
uint8_t *out)
|
||||
{
|
||||
uint64_t b[2];
|
||||
@ -139,7 +139,7 @@ bool aes_unwrap(const uint8_t *kek, const uint8_t *in, size_t len,
|
||||
struct l_cipher *cipher;
|
||||
uint64_t t = n * 6;
|
||||
|
||||
cipher = l_cipher_new(L_CIPHER_AES, kek, 16);
|
||||
cipher = l_cipher_new(L_CIPHER_AES, kek, kek_len);
|
||||
if (!cipher)
|
||||
return false;
|
||||
|
||||
@ -552,7 +552,6 @@ static bool crypto_derive_ptk(const uint8_t *pmk, size_t pmk_len,
|
||||
}
|
||||
|
||||
pos += 64;
|
||||
|
||||
if (use_sha256)
|
||||
return kdf_sha256(pmk, pmk_len, label, strlen(label),
|
||||
data, sizeof(data), out_ptk, ptk_len);
|
||||
@ -564,12 +563,12 @@ static bool crypto_derive_ptk(const uint8_t *pmk, size_t pmk_len,
|
||||
bool crypto_derive_pairwise_ptk(const uint8_t *pmk,
|
||||
const uint8_t *addr1, const uint8_t *addr2,
|
||||
const uint8_t *nonce1, const uint8_t *nonce2,
|
||||
struct crypto_ptk *out_ptk, size_t ptk_len,
|
||||
uint8_t *out_ptk, size_t ptk_len,
|
||||
bool use_sha256)
|
||||
{
|
||||
return crypto_derive_ptk(pmk, 32, "Pairwise key expansion",
|
||||
addr1, addr2, nonce1, nonce2,
|
||||
(uint8_t *) out_ptk, ptk_len,
|
||||
out_ptk, ptk_len,
|
||||
use_sha256);
|
||||
}
|
||||
|
||||
@ -677,7 +676,7 @@ exit:
|
||||
bool crypto_derive_ft_ptk(const uint8_t *pmk_r1, const uint8_t *pmk_r1_name,
|
||||
const uint8_t *addr1, const uint8_t *addr2,
|
||||
const uint8_t *nonce1, const uint8_t *nonce2,
|
||||
struct crypto_ptk *out_ptk, size_t ptk_len,
|
||||
uint8_t *out_ptk, size_t ptk_len,
|
||||
uint8_t *out_ptk_name)
|
||||
{
|
||||
uint8_t context[ETH_ALEN * 2 + 64];
|
||||
|
12
src/crypto.h
12
src/crypto.h
@ -54,12 +54,6 @@ enum crypto_akm {
|
||||
#define CRYPTO_MIN_IGTK_LEN 16
|
||||
#define CRYPTO_MAX_IGTK_LEN 32
|
||||
|
||||
struct crypto_ptk {
|
||||
uint8_t kck[16];
|
||||
uint8_t kek[16];
|
||||
uint8_t tk[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
extern const unsigned char crypto_dh5_prime[];
|
||||
extern size_t crypto_dh5_prime_size;
|
||||
extern const unsigned char crypto_dh5_generator[];
|
||||
@ -76,7 +70,7 @@ bool hmac_sha384(const void *key, size_t key_len,
|
||||
bool cmac_aes(const void *key, size_t key_len,
|
||||
const void *data, size_t data_len, void *output, size_t size);
|
||||
|
||||
bool aes_unwrap(const uint8_t *kek, const uint8_t *in, size_t len,
|
||||
bool aes_unwrap(const uint8_t *kek, size_t kek_len, const uint8_t *in, size_t len,
|
||||
uint8_t *out);
|
||||
bool aes_wrap(const uint8_t *kek, const uint8_t *in, size_t len, uint8_t *out);
|
||||
bool arc4_skip(const uint8_t *key, size_t key_len, size_t skip,
|
||||
@ -104,7 +98,7 @@ bool hkdf_expand_sha256(const uint8_t *key, size_t key_len, const char *info,
|
||||
bool crypto_derive_pairwise_ptk(const uint8_t *pmk,
|
||||
const uint8_t *addr1, const uint8_t *addr2,
|
||||
const uint8_t *nonce1, const uint8_t *nonce2,
|
||||
struct crypto_ptk *out_ptk, size_t ptk_len,
|
||||
uint8_t *out_ptk, size_t ptk_len,
|
||||
bool use_sha256);
|
||||
|
||||
bool crypto_derive_pmk_r0(const uint8_t *xxkey,
|
||||
@ -121,7 +115,7 @@ bool crypto_derive_pmk_r1(const uint8_t *pmk_r0,
|
||||
bool crypto_derive_ft_ptk(const uint8_t *pmk_r1, const uint8_t *pmk_r1_name,
|
||||
const uint8_t *addr1, const uint8_t *addr2,
|
||||
const uint8_t *nonce1, const uint8_t *nonce2,
|
||||
struct crypto_ptk *out_ptk, size_t ptk_len,
|
||||
uint8_t *out_ptk, size_t ptk_len,
|
||||
uint8_t *out_ptk_name);
|
||||
|
||||
bool crypto_derive_pmkid(const uint8_t *pmk,
|
||||
|
71
src/eapol.c
71
src/eapol.c
@ -226,7 +226,7 @@ uint8_t *eapol_decrypt_key_data(enum ie_rsn_akm_suite akm, const uint8_t *kek,
|
||||
case EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES:
|
||||
case EAPOL_KEY_DESCRIPTOR_VERSION_AES_128_CMAC_AES:
|
||||
case EAPOL_KEY_DESCRIPTOR_VERSION_AKM_DEFINED:
|
||||
if (!aes_unwrap(kek, key_data, key_data_len, buf))
|
||||
if (!aes_unwrap(kek, 16, key_data, key_data_len, buf))
|
||||
goto error;
|
||||
|
||||
break;
|
||||
@ -960,7 +960,7 @@ static void eapol_ptk_1_of_4_retry(struct l_timeout *timeout, void *user_data)
|
||||
static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm,
|
||||
const struct eapol_key *ek)
|
||||
{
|
||||
const struct crypto_ptk *ptk;
|
||||
const uint8_t *kck;
|
||||
struct eapol_key *step2;
|
||||
uint8_t mic[MIC_MAXLEN];
|
||||
uint8_t *ies;
|
||||
@ -1084,9 +1084,9 @@ static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm,
|
||||
sm->handshake->snonce, ies_len, ies,
|
||||
sm->handshake->wpa_ie, sm->mic_len);
|
||||
|
||||
ptk = handshake_state_get_ptk(sm->handshake);
|
||||
kck = handshake_state_get_kck(sm->handshake);
|
||||
|
||||
if (!eapol_calculate_mic(sm->handshake->akm_suite, ptk->kck,
|
||||
if (!eapol_calculate_mic(sm->handshake->akm_suite, kck,
|
||||
step2, mic, sm->mic_len)) {
|
||||
l_info("MIC calculation failed. "
|
||||
"Ensure Kernel Crypto is available.");
|
||||
@ -1123,7 +1123,8 @@ static void eapol_send_ptk_3_of_4(struct eapol_sm *sm)
|
||||
sm->handshake->pairwise_cipher);
|
||||
enum crypto_cipher group_cipher = ie_rsn_cipher_suite_to_cipher(
|
||||
sm->handshake->group_cipher);
|
||||
const struct crypto_ptk *ptk = (struct crypto_ptk *) sm->handshake->ptk;
|
||||
const uint8_t *kck;
|
||||
const uint8_t *kek;
|
||||
struct ie_rsn_info rsn;
|
||||
uint8_t *rsne;
|
||||
|
||||
@ -1174,7 +1175,9 @@ static void eapol_send_ptk_3_of_4(struct eapol_sm *sm)
|
||||
key_data_len += gtk_kde[1] + 2;
|
||||
}
|
||||
|
||||
if (!eapol_encrypt_key_data(ptk->kek, key_data_buf,
|
||||
kek = handshake_state_get_kek(sm->handshake);
|
||||
|
||||
if (!eapol_encrypt_key_data(kek, key_data_buf,
|
||||
key_data_len, ek, sm->mic_len))
|
||||
return;
|
||||
|
||||
@ -1183,7 +1186,9 @@ static void eapol_send_ptk_3_of_4(struct eapol_sm *sm)
|
||||
ek->header.packet_len = L_CPU_TO_BE16(EAPOL_FRAME_LEN(sm->mic_len) +
|
||||
key_data_len - 4);
|
||||
|
||||
if (!eapol_calculate_mic(sm->handshake->akm_suite, ptk->kck, ek,
|
||||
kck = handshake_state_get_kck(sm->handshake);
|
||||
|
||||
if (!eapol_calculate_mic(sm->handshake->akm_suite, kck, ek,
|
||||
EAPOL_KEY_MIC(ek), sm->mic_len))
|
||||
return;
|
||||
|
||||
@ -1242,10 +1247,8 @@ static void eapol_handle_ptk_2_of_4(struct eapol_sm *sm,
|
||||
const struct eapol_key *ek)
|
||||
{
|
||||
const uint8_t *rsne;
|
||||
enum crypto_cipher cipher;
|
||||
size_t ptk_size;
|
||||
uint8_t ptk_buf[64];
|
||||
struct crypto_ptk *ptk = (struct crypto_ptk *) ptk_buf;
|
||||
const uint8_t *kck;
|
||||
const uint8_t *aa = sm->handshake->aa;
|
||||
|
||||
l_debug("ifindex=%u", sm->handshake->ifindex);
|
||||
@ -1256,15 +1259,17 @@ static void eapol_handle_ptk_2_of_4(struct eapol_sm *sm,
|
||||
if (L_BE64_TO_CPU(ek->key_replay_counter) != sm->replay_counter)
|
||||
return;
|
||||
|
||||
cipher = ie_rsn_cipher_suite_to_cipher(sm->handshake->pairwise_cipher);
|
||||
ptk_size = sizeof(struct crypto_ptk) + crypto_cipher_key_len(cipher);
|
||||
ptk_size = handshake_state_get_ptk_size(sm->handshake);
|
||||
|
||||
if (!crypto_derive_pairwise_ptk(sm->handshake->pmk, sm->handshake->spa,
|
||||
aa, sm->handshake->anonce,
|
||||
ek->key_nonce, ptk, ptk_size, false))
|
||||
if (!crypto_derive_pairwise_ptk(sm->handshake->pmk,
|
||||
sm->handshake->spa, aa,
|
||||
sm->handshake->anonce, ek->key_nonce,
|
||||
sm->handshake->ptk, ptk_size, false))
|
||||
return;
|
||||
|
||||
if (!eapol_verify_mic(sm->handshake->akm_suite, ptk->kck, ek,
|
||||
kck = handshake_state_get_kck(sm->handshake);
|
||||
|
||||
if (!eapol_verify_mic(sm->handshake->akm_suite, kck, ek,
|
||||
sm->mic_len))
|
||||
return;
|
||||
|
||||
@ -1282,7 +1287,6 @@ static void eapol_handle_ptk_2_of_4(struct eapol_sm *sm,
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(sm->handshake->ptk, ptk_buf, ptk_size);
|
||||
memcpy(sm->handshake->snonce, ek->key_nonce,
|
||||
sizeof(sm->handshake->snonce));
|
||||
sm->handshake->have_snonce = true;
|
||||
@ -1316,7 +1320,8 @@ static void eapol_handle_ptk_3_of_4(struct eapol_sm *sm,
|
||||
const uint8_t *decrypted_key_data,
|
||||
size_t decrypted_key_data_size)
|
||||
{
|
||||
const struct crypto_ptk *ptk;
|
||||
const uint8_t *kck;
|
||||
const uint8_t *kek;
|
||||
struct eapol_key *step4;
|
||||
uint8_t mic[MIC_MAXLEN];
|
||||
const uint8_t *gtk = NULL;
|
||||
@ -1516,9 +1521,10 @@ retransmit:
|
||||
sm->replay_counter,
|
||||
sm->handshake->wpa_ie, sm->mic_len);
|
||||
|
||||
ptk = handshake_state_get_ptk(sm->handshake);
|
||||
kck = handshake_state_get_kck(sm->handshake);
|
||||
kek = handshake_state_get_kek(sm->handshake);
|
||||
|
||||
if (!eapol_calculate_mic(sm->handshake->akm_suite, ptk->kck,
|
||||
if (!eapol_calculate_mic(sm->handshake->akm_suite, kck,
|
||||
step4, mic, sm->mic_len)) {
|
||||
l_free(step4);
|
||||
handshake_failed(sm, MMPDU_REASON_CODE_UNSPECIFIED);
|
||||
@ -1550,7 +1556,7 @@ retransmit:
|
||||
handshake_state_install_ptk(sm->handshake);
|
||||
|
||||
if (rekey_offload)
|
||||
rekey_offload(sm->handshake->ifindex, ptk->kek, ptk->kck,
|
||||
rekey_offload(sm->handshake->ifindex, kek, kck,
|
||||
sm->replay_counter, sm->user_data);
|
||||
|
||||
l_timeout_remove(sm->timeout);
|
||||
@ -1566,7 +1572,7 @@ error_ie_different:
|
||||
static void eapol_handle_ptk_4_of_4(struct eapol_sm *sm,
|
||||
const struct eapol_key *ek)
|
||||
{
|
||||
const struct crypto_ptk *ptk = (struct crypto_ptk *) sm->handshake->ptk;
|
||||
const uint8_t *kck;
|
||||
|
||||
l_debug("ifindex=%u", sm->handshake->ifindex);
|
||||
|
||||
@ -1576,7 +1582,9 @@ static void eapol_handle_ptk_4_of_4(struct eapol_sm *sm,
|
||||
if (L_BE64_TO_CPU(ek->key_replay_counter) != sm->replay_counter)
|
||||
return;
|
||||
|
||||
if (!eapol_verify_mic(sm->handshake->akm_suite, ptk->kck, ek,
|
||||
kck = handshake_state_get_kck(sm->handshake);
|
||||
|
||||
if (!eapol_verify_mic(sm->handshake->akm_suite, kck, ek,
|
||||
sm->mic_len))
|
||||
return;
|
||||
|
||||
@ -1591,7 +1599,7 @@ static void eapol_handle_gtk_1_of_2(struct eapol_sm *sm,
|
||||
const uint8_t *decrypted_key_data,
|
||||
size_t decrypted_key_data_size)
|
||||
{
|
||||
const struct crypto_ptk *ptk;
|
||||
const uint8_t *kck;
|
||||
struct eapol_key *step2;
|
||||
uint8_t mic[MIC_MAXLEN];
|
||||
const uint8_t *gtk;
|
||||
@ -1664,9 +1672,9 @@ static void eapol_handle_gtk_1_of_2(struct eapol_sm *sm,
|
||||
sm->handshake->wpa_ie, ek->wpa_key_id,
|
||||
sm->mic_len);
|
||||
|
||||
ptk = handshake_state_get_ptk(sm->handshake);
|
||||
kck = handshake_state_get_kck(sm->handshake);
|
||||
|
||||
if (!eapol_calculate_mic(sm->handshake->akm_suite, ptk->kck,
|
||||
if (!eapol_calculate_mic(sm->handshake->akm_suite, kck,
|
||||
step2, mic, sm->mic_len)) {
|
||||
l_free(step2);
|
||||
handshake_failed(sm, MMPDU_REASON_CODE_UNSPECIFIED);
|
||||
@ -1708,7 +1716,8 @@ static void eapol_key_handle(struct eapol_sm *sm,
|
||||
const struct eapol_frame *frame)
|
||||
{
|
||||
const struct eapol_key *ek;
|
||||
const struct crypto_ptk *ptk;
|
||||
const uint8_t *kck;
|
||||
const uint8_t *kek;
|
||||
uint8_t *decrypted_key_data = NULL;
|
||||
size_t key_data_len = 0;
|
||||
uint64_t replay_counter;
|
||||
@ -1761,14 +1770,14 @@ static void eapol_key_handle(struct eapol_sm *sm,
|
||||
if (sm->have_replay && sm->replay_counter >= replay_counter)
|
||||
return;
|
||||
|
||||
ptk = handshake_state_get_ptk(sm->handshake);
|
||||
kck = handshake_state_get_kck(sm->handshake);
|
||||
|
||||
if (ek->key_mic) {
|
||||
/* Haven't received step 1 yet, so no ptk */
|
||||
if (!sm->handshake->have_snonce)
|
||||
return;
|
||||
|
||||
if (!eapol_verify_mic(sm->handshake->akm_suite, ptk->kck, ek,
|
||||
if (!eapol_verify_mic(sm->handshake->akm_suite, kck, ek,
|
||||
sm->mic_len))
|
||||
return;
|
||||
}
|
||||
@ -1779,8 +1788,10 @@ static void eapol_key_handle(struct eapol_sm *sm,
|
||||
if (!sm->handshake->have_snonce)
|
||||
return;
|
||||
|
||||
kek = handshake_state_get_kek(sm->handshake);
|
||||
|
||||
decrypted_key_data = eapol_decrypt_key_data(
|
||||
sm->handshake->akm_suite, ptk->kek,
|
||||
sm->handshake->akm_suite, kek,
|
||||
ek, &key_data_len, sm->mic_len);
|
||||
if (!decrypted_key_data)
|
||||
return;
|
||||
|
@ -44,7 +44,7 @@ bool ft_calculate_fte_mic(struct handshake_state *hs, uint8_t seq_num,
|
||||
struct iovec iov[10];
|
||||
int iov_elems = 0;
|
||||
struct l_checksum *checksum;
|
||||
const struct crypto_ptk *ptk = handshake_state_get_ptk(hs);
|
||||
const uint8_t *kck = handshake_state_get_kck(hs);
|
||||
uint8_t zero_mic[16] = {};
|
||||
|
||||
iov[iov_elems].iov_base = hs->spa;
|
||||
@ -80,7 +80,7 @@ bool ft_calculate_fte_mic(struct handshake_state *hs, uint8_t seq_num,
|
||||
iov[iov_elems++].iov_len = ric[1] + 2;
|
||||
}
|
||||
|
||||
checksum = l_checksum_new_cmac_aes(ptk->kck, 16);
|
||||
checksum = l_checksum_new_cmac_aes(kck, 16);
|
||||
if (!checksum)
|
||||
return false;
|
||||
|
||||
|
@ -278,10 +278,51 @@ void handshake_state_set_anonce(struct handshake_state *s,
|
||||
memcpy(s->anonce, anonce, 32);
|
||||
}
|
||||
|
||||
/* A multi-purpose getter for key sizes */
|
||||
static bool handshake_get_key_sizes(struct handshake_state *s, size_t *ptk_size,
|
||||
size_t *kck_size, size_t *kek_size)
|
||||
{
|
||||
size_t kck;
|
||||
size_t kek;
|
||||
size_t tk;
|
||||
enum crypto_cipher cipher =
|
||||
ie_rsn_cipher_suite_to_cipher(s->pairwise_cipher);
|
||||
|
||||
tk = crypto_cipher_key_len(cipher);
|
||||
|
||||
/*
|
||||
* IEEE 802.11-2016 Table 12-8: Integrity and key-wrap algorithms
|
||||
*
|
||||
* From the table, only 00-0F-AC:12 and 00-0F-AC:13 use longer KCK and
|
||||
* KEK keys, which are 24 and 32 bytes respectively. The remainder use
|
||||
* 16 and 16 respectively.
|
||||
*/
|
||||
switch (s->akm_suite) {
|
||||
case IE_RSN_AKM_SUITE_8021X_SUITE_B_SHA256:
|
||||
case IE_RSN_AKM_SUITE_FT_OVER_8021X_SHA384:
|
||||
kck = 24;
|
||||
kek = 32;
|
||||
break;
|
||||
default:
|
||||
kck = 16;
|
||||
kek = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ptk_size)
|
||||
*ptk_size = kck + kek + tk;
|
||||
|
||||
if (kck_size)
|
||||
*kck_size = kck;
|
||||
|
||||
if (kek_size)
|
||||
*kek_size = kek;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool handshake_state_derive_ptk(struct handshake_state *s)
|
||||
{
|
||||
struct crypto_ptk *ptk = (struct crypto_ptk *) s->ptk;
|
||||
enum crypto_cipher cipher;
|
||||
size_t ptk_size;
|
||||
bool use_sha256;
|
||||
|
||||
@ -305,9 +346,7 @@ bool handshake_state_derive_ptk(struct handshake_state *s)
|
||||
else
|
||||
use_sha256 = false;
|
||||
|
||||
cipher = ie_rsn_cipher_suite_to_cipher(s->pairwise_cipher);
|
||||
|
||||
ptk_size = sizeof(struct crypto_ptk) + crypto_cipher_key_len(cipher);
|
||||
ptk_size = handshake_state_get_ptk_size(s);
|
||||
|
||||
if (s->akm_suite & (IE_RSN_AKM_SUITE_FT_OVER_8021X |
|
||||
IE_RSN_AKM_SUITE_FT_USING_PSK |
|
||||
@ -344,26 +383,54 @@ bool handshake_state_derive_ptk(struct handshake_state *s)
|
||||
|
||||
if (!crypto_derive_ft_ptk(s->pmk_r1, s->pmk_r1_name, s->aa,
|
||||
s->spa, s->snonce, s->anonce,
|
||||
ptk, ptk_size, ptk_name))
|
||||
s->ptk, ptk_size, ptk_name))
|
||||
return false;
|
||||
} else
|
||||
if (!crypto_derive_pairwise_ptk(s->pmk, s->spa, s->aa,
|
||||
s->anonce, s->snonce,
|
||||
ptk, ptk_size, use_sha256))
|
||||
if (!crypto_derive_pairwise_ptk(s->pmk, s->spa,
|
||||
s->aa, s->anonce, s->snonce,
|
||||
s->ptk, ptk_size, use_sha256))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct crypto_ptk *handshake_state_get_ptk(struct handshake_state *s)
|
||||
size_t handshake_state_get_ptk_size(struct handshake_state *s)
|
||||
{
|
||||
return (struct crypto_ptk *) s->ptk;
|
||||
size_t ptk_size;
|
||||
|
||||
if (!handshake_get_key_sizes(s, &ptk_size, NULL, NULL))
|
||||
return 0;
|
||||
|
||||
return ptk_size;
|
||||
}
|
||||
|
||||
const uint8_t *handshake_state_get_kck(struct handshake_state *s)
|
||||
{
|
||||
return s->ptk;
|
||||
}
|
||||
|
||||
const uint8_t *handshake_state_get_kek(struct handshake_state *s)
|
||||
{
|
||||
size_t kck_size;
|
||||
|
||||
if (!handshake_get_key_sizes(s, NULL, &kck_size, NULL))
|
||||
return NULL;
|
||||
|
||||
return s->ptk + kck_size;
|
||||
}
|
||||
|
||||
static const uint8_t *handshake_get_tk(struct handshake_state *s)
|
||||
{
|
||||
size_t kck_size, kek_size;
|
||||
|
||||
if (!handshake_get_key_sizes(s, NULL, &kck_size, &kek_size))
|
||||
return NULL;
|
||||
|
||||
return s->ptk + kck_size + kek_size;
|
||||
}
|
||||
|
||||
void handshake_state_install_ptk(struct handshake_state *s)
|
||||
{
|
||||
struct crypto_ptk *ptk = (struct crypto_ptk *) s->ptk;
|
||||
|
||||
s->ptk_complete = true;
|
||||
|
||||
if (install_tk) {
|
||||
@ -372,7 +439,7 @@ void handshake_state_install_ptk(struct handshake_state *s)
|
||||
|
||||
handshake_event(s, HANDSHAKE_EVENT_SETTING_KEYS, NULL);
|
||||
|
||||
install_tk(s, ptk->tk, cipher);
|
||||
install_tk(s, handshake_get_tk(s), cipher);
|
||||
}
|
||||
}
|
||||
|
||||
@ -684,10 +751,10 @@ void handshake_util_build_gtk_kde(enum crypto_cipher cipher, const uint8_t *key,
|
||||
bool handshake_decode_fte_key(struct handshake_state *s, const uint8_t *wrapped,
|
||||
size_t key_len, uint8_t *key_out)
|
||||
{
|
||||
const struct crypto_ptk *ptk = handshake_state_get_ptk(s);
|
||||
const uint8_t *kek = handshake_state_get_kek(s);
|
||||
size_t padded_len = key_len < 16 ? 16 : align_len(key_len, 8);
|
||||
|
||||
if (!aes_unwrap(ptk->kek, wrapped, padded_len + 8, key_out))
|
||||
if (!aes_unwrap(kek, 16, wrapped, padded_len + 8, key_out))
|
||||
return false;
|
||||
|
||||
if (key_len < padded_len && key_out[key_len++] != 0xdd)
|
||||
|
@ -90,7 +90,7 @@ struct handshake_state {
|
||||
size_t pmk_len;
|
||||
uint8_t snonce[32];
|
||||
uint8_t anonce[32];
|
||||
uint8_t ptk[64];
|
||||
uint8_t ptk[80];
|
||||
uint8_t pmk_r0[32];
|
||||
uint8_t pmk_r0_name[16];
|
||||
uint8_t pmk_r1[32];
|
||||
@ -164,7 +164,9 @@ void handshake_state_set_anonce(struct handshake_state *s,
|
||||
const uint8_t *anonce);
|
||||
void handshake_state_set_pmkid(struct handshake_state *s, const uint8_t *pmkid);
|
||||
bool handshake_state_derive_ptk(struct handshake_state *s);
|
||||
const struct crypto_ptk *handshake_state_get_ptk(struct handshake_state *s);
|
||||
size_t handshake_state_get_ptk_size(struct handshake_state *s);
|
||||
const uint8_t *handshake_state_get_kck(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_gtk(struct handshake_state *s,
|
||||
|
Loading…
Reference in New Issue
Block a user