diff --git a/src/crypto.c b/src/crypto.c index 34863753..198c024f 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -418,19 +418,24 @@ bool kdf_sha256(const void *key, size_t key_len, * * Null key equates to a zero key (makes calls in EAP-PWD more convenient) */ -bool hkdf_extract_sha256(const uint8_t *key, size_t key_len, uint8_t num_args, - uint8_t *out, ...) +bool hkdf_extract(enum l_checksum_type type, const uint8_t *key, + size_t key_len, uint8_t num_args, + uint8_t *out, ...) { struct l_checksum *hmac; struct iovec iov[num_args]; - const uint8_t zero_key[32] = { 0 }; + const uint8_t zero_key[64] = { 0 }; + size_t dlen = l_checksum_digest_length(type); const uint8_t *k = key ? key : zero_key; - size_t k_len = key ? key_len : 32; + size_t k_len = key ? key_len : dlen; va_list va; int i; int ret; - hmac = l_checksum_new_hmac(L_CHECKSUM_SHA256, k, k_len); + if (dlen <= 0) + return false; + + hmac = l_checksum_new_hmac(type, k, k_len); if (!hmac) return false; @@ -446,27 +451,32 @@ bool hkdf_extract_sha256(const uint8_t *key, size_t key_len, uint8_t num_args, return false; } - ret = l_checksum_get_digest(hmac, out, 32); + ret = l_checksum_get_digest(hmac, out, dlen); l_checksum_free(hmac); va_end(va); - return (ret == 32); + return (ret == (int) dlen); } -bool hkdf_expand_sha256(const uint8_t *key, size_t key_len, const char *info, - size_t info_len, void *out, size_t out_len) +bool hkdf_expand(enum l_checksum_type type, const uint8_t *key, size_t key_len, + const char *info, size_t info_len, void *out, + size_t out_len) { - uint8_t t[32]; + uint8_t t[64]; size_t t_len = 0; struct iovec iov[3]; struct l_checksum *hmac; uint8_t count = 1; uint8_t *out_ptr = out; + size_t dlen = l_checksum_digest_length(type); + + if (dlen <= 0) + return false; while (out_len > 0) { ssize_t ret; - hmac = l_checksum_new_hmac(L_CHECKSUM_SHA256, key, key_len); + hmac = l_checksum_new_hmac(type, key, key_len); iov[0].iov_base = t; iov[0].iov_len = t_len; @@ -481,7 +491,7 @@ bool hkdf_expand_sha256(const uint8_t *key, size_t key_len, const char *info, } ret = l_checksum_get_digest(hmac, t, - (out_len > 32) ? 32 : out_len); + (out_len > dlen) ? dlen : out_len); if (ret < 0) { l_checksum_free(hmac); return false; @@ -495,7 +505,7 @@ bool hkdf_expand_sha256(const uint8_t *key, size_t key_len, const char *info, * RFC specifies that T(0) = empty string, so after the first * iteration we update the length for T(1)...T(N) */ - t_len = 32; + t_len = dlen; count++; l_checksum_free(hmac); diff --git a/src/crypto.h b/src/crypto.h index 4fcc381b..165b192e 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -89,11 +89,12 @@ bool kdf_sha256(const void *key, size_t key_len, bool prf_sha1(const void *key, size_t key_len, const void *prefix, size_t prefix_len, const void *data, size_t data_len, void *output, size_t size); -bool hkdf_extract_sha256(const uint8_t *key, size_t key_len, uint8_t num_args, - uint8_t *out, ...); +bool hkdf_extract(enum l_checksum_type type, const uint8_t *key, size_t key_len, + uint8_t num_args, uint8_t *out, ...); -bool hkdf_expand_sha256(const uint8_t *key, size_t key_len, const char *info, - size_t info_len, void *out, size_t out_len); +bool hkdf_expand(enum l_checksum_type type, const uint8_t *key, size_t key_len, + const char *info, size_t info_len, void *out, + size_t out_len); bool crypto_derive_pairwise_ptk(const uint8_t *pmk, size_t pmk_len, const uint8_t *addr1, const uint8_t *addr2, diff --git a/src/eap-pwd.c b/src/eap-pwd.c index e549c62f..ed4722ae 100644 --- a/src/eap-pwd.c +++ b/src/eap-pwd.c @@ -293,7 +293,7 @@ static void eap_pwd_handle_id(struct eap_state *eap, while (counter < 20) { /* pwd-seed = H(token|peer-ID|server-ID|password|counter) */ - hkdf_extract_sha256(NULL, 0, 5, pwd_seed, &token, 4, + hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 5, pwd_seed, &token, 4, pwd->identity, strlen(pwd->identity), pkt + 9, len - 9, pwd->password, strlen(pwd->password), &counter, 1); @@ -488,13 +488,14 @@ static void eap_pwd_handle_confirm(struct eap_state *eap, * compute Confirm_P = H(kp | Element_P | Scalar_P | * Element_S | Scalar_S | Ciphersuite) */ - hkdf_extract_sha256(NULL, 0, 6, confirm_p, kpx, clen, element_p, plen, - scalar_p, clen, element_s, plen, scalar_s, - clen, &pwd->ciphersuite, 4); + hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 6, confirm_p, kpx, clen, + element_p, plen, scalar_p, clen, element_s, + plen, scalar_s, clen, &pwd->ciphersuite, 4); - hkdf_extract_sha256(NULL, 0, 6, expected_confirm_s, kpx, clen, - element_s, plen, scalar_s, clen, element_p, - plen, scalar_p, clen, &pwd->ciphersuite, 4); + hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 6, expected_confirm_s, kpx, + clen, element_s, plen, scalar_s, clen, + element_p, plen, scalar_p, clen, + &pwd->ciphersuite, 4); if (memcmp(confirm_s, expected_confirm_s, 32)) { l_error("Confirm_S did not verify"); @@ -507,7 +508,7 @@ static void eap_pwd_handle_confirm(struct eap_state *eap, pos += 32; /* derive MK = H(kp | Confirm_P | Confirm_S ) */ - hkdf_extract_sha256(NULL, 0, 3, mk, kpx, clen, confirm_p, + hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 3, mk, kpx, clen, confirm_p, 32, confirm_s, 32); eap_pwd_send_response(eap, resp, pos - resp); @@ -515,8 +516,8 @@ static void eap_pwd_handle_confirm(struct eap_state *eap, eap_method_success(eap); session_id[0] = 52; - hkdf_extract_sha256(NULL, 0, 3, session_id + 1, &pwd->ciphersuite, 4, - scalar_p, clen, scalar_s, clen); + hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 3, session_id + 1, + &pwd->ciphersuite, 4, scalar_p, clen, scalar_s, clen); kdf(mk, 32, (const char *) session_id, 33, msk_emsk, 128); eap_set_key_material(eap, msk_emsk, 64, msk_emsk + 64, 64, NULL, 0); diff --git a/src/owe.c b/src/owe.c index f7de944d..54d8834f 100644 --- a/src/owe.c +++ b/src/owe.c @@ -157,11 +157,11 @@ static bool owe_compute_keys(struct owe_sm *owe, const void *public_key, l_put_le16(OWE_DEFAULT_GROUP, key + 64); /* prk = HKDF-extract(C | A | group, z) */ - if (!hkdf_extract_sha256(key, 66, 1, prk, ss_buf, 32)) + if (!hkdf_extract(L_CHECKSUM_SHA256, key, 66, 1, prk, ss_buf, 32)) goto failed; /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */ - if (!hkdf_expand_sha256(prk, 32, "OWE Key Generation", + if (!hkdf_expand(L_CHECKSUM_SHA256, prk, 32, "OWE Key Generation", strlen("OWE Key Generation"), pmk, 32)) goto failed; diff --git a/src/sae.c b/src/sae.c index feaf5e45..f9e4a0e3 100644 --- a/src/sae.c +++ b/src/sae.c @@ -83,7 +83,7 @@ static bool sae_pwd_seed(const uint8_t *addr1, const uint8_t *addr2, memcpy(key + 6, addr1, 6); } - return hkdf_extract_sha256(key, 12, 2, out, base, base_len, + return hkdf_extract(L_CHECKSUM_SHA256, key, 12, 2, out, base, base_len, &counter, 1); }