Commit c5931d59 authored by Chris Leech's avatar Chris Leech Committed by Keith Busch
Browse files

nvme-auth: use hkdf_expand_label()



When generating keying material during an authentication transaction
(secure channel concatenation), the HKDF-Expand-Label function is part
of the specified key derivation process.

The current open-coded implementation misses the length prefix
requirements on the HkdfLabel label and context variable-length vectors
(RFC 8446 Section 3.4).

Instead, use the hkdf_expand_label() function.

Signed-off-by: default avatarChris Leech <cleech@redhat.com>
Signed-off-by: default avatarHannes Reinecke <hare@kernel.org>
Signed-off-by: default avatarKeith Busch <kbusch@kernel.org>
parent 1cab50da
Loading
Loading
Loading
Loading
+13 −20
Original line number Diff line number Diff line
@@ -768,10 +768,10 @@ int nvme_auth_derive_tls_psk(int hmac_id, u8 *psk, size_t psk_len,
{
	struct crypto_shash *hmac_tfm;
	const char *hmac_name;
	const char *psk_prefix = "tls13 nvme-tls-psk";
	const char *label = "nvme-tls-psk";
	static const char default_salt[HKDF_MAX_HASHLEN];
	size_t info_len, prk_len;
	char *info;
	size_t prk_len;
	const char *ctx;
	unsigned char *prk, *tls_key;
	int ret;

@@ -811,36 +811,29 @@ int nvme_auth_derive_tls_psk(int hmac_id, u8 *psk, size_t psk_len,
	if (ret)
		goto out_free_prk;

	/*
	 * 2 additional bytes for the length field from HDKF-Expand-Label,
	 * 2 additional bytes for the HMAC ID, and one byte for the space
	 * separator.
	 */
	info_len = strlen(psk_digest) + strlen(psk_prefix) + 5;
	info = kzalloc(info_len + 1, GFP_KERNEL);
	if (!info) {
	ctx = kasprintf(GFP_KERNEL, "%02d %s", hmac_id, psk_digest);
	if (!ctx) {
		ret = -ENOMEM;
		goto out_free_prk;
	}

	put_unaligned_be16(psk_len, info);
	memcpy(info + 2, psk_prefix, strlen(psk_prefix));
	sprintf(info + 2 + strlen(psk_prefix), "%02d %s", hmac_id, psk_digest);

	tls_key = kzalloc(psk_len, GFP_KERNEL);
	if (!tls_key) {
		ret = -ENOMEM;
		goto out_free_info;
		goto out_free_ctx;
	}
	ret = hkdf_expand(hmac_tfm, info, info_len, tls_key, psk_len);
	ret = hkdf_expand_label(hmac_tfm,
				label, strlen(label),
				ctx, strlen(ctx),
				tls_key, psk_len);
	if (ret) {
		kfree(tls_key);
		goto out_free_info;
		goto out_free_ctx;
	}
	*ret_psk = tls_key;

out_free_info:
	kfree(info);
out_free_ctx:
	kfree(ctx);
out_free_prk:
	kfree(prk);
out_free_shash: