Skip to content

Commit 0d6574e

Browse files
committed
linux: fix 'TLS PSK derivation fixes'
The patch 'TLS PSK derivation fixes' was a bit too eager in adding the 'length' field to the HKDF label. The NVMe TCP spec defines Retained PSK = HKDF-Expand-Label(PRK, “HostNQN”, NQNh, Length(Configured PSK)) which according to RFC 8446 translates to: HKDF-Expand(PRK, HkdfLabel, Length(Configured PSK)) and HkdfLabel { (u16) Length(Configured PSK) "tls13 HostNQN" NQNh } The previous patch would tread both the 'label' and the 'context' field as an HkdfLabel, which is wrong. Signed-off-by: Hannes Reinecke <[email protected]>
1 parent 3435511 commit 0d6574e

1 file changed

Lines changed: 13 additions & 27 deletions

File tree

src/nvme/linux.c

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ static DEFINE_CLEANUP_FUNC(
619619
#define _cleanup_evp_pkey_ctx_ __cleanup__(cleanup_evp_pkey_ctx)
620620

621621
/*
622-
* hkdf_info_printf()
622+
* hkdf_expand_labelf()
623623
*
624624
* Helper function to append variable length label and context to an HkdfLabel
625625
*
@@ -635,8 +635,8 @@ static DEFINE_CLEANUP_FUNC(
635635
* Returns the number of bytes appended to the HKDF info buffer, or -1 on an
636636
* error.
637637
*/
638-
__attribute__((format(printf, 2, 3)))
639-
static int hkdf_info_printf(EVP_PKEY_CTX *ctx, char *fmt, ...)
638+
__attribute__((format(printf, 3, 4)))
639+
static int hkdf_expand_label(EVP_PKEY_CTX *ctx, char *label, char *fmt, ...)
640640
{
641641
_cleanup_free_ char *str = NULL;
642642
va_list myargs;
@@ -651,11 +651,14 @@ static int hkdf_info_printf(EVP_PKEY_CTX *ctx, char *fmt, ...)
651651
if (ret > 255)
652652
return -1;
653653
len = ret;
654-
if (EVP_PKEY_CTX_add1_hkdf_info(ctx, (unsigned char *)&len, 1) <= 0)
654+
if (EVP_PKEY_CTX_add1_hkdf_info(ctx, (unsigned char *)&len, 2) <= 0)
655+
return -1;
656+
if (EVP_PKEY_CTX_add1_hkdf_info(ctx, (unsigned char *)label,
657+
strlen(label)) <= 0)
655658
return -1;
656659
if (EVP_PKEY_CTX_add1_hkdf_info(ctx, (unsigned char *)str, len) <= 0)
657660
return -1;
658-
return (ret + 1);
661+
return (ret + strlen(label) + 2);
659662
}
660663

661664
/*
@@ -725,20 +728,10 @@ static int derive_retained_key(int hmac, const char *hostnqn,
725728
errno = ENOKEY;
726729
return -1;
727730
}
728-
if (EVP_PKEY_CTX_add1_hkdf_info(ctx,
729-
(const unsigned char *)&length, 2) <= 0) {
730-
errno = ENOKEY;
731-
return -1;
732-
}
733-
if (hkdf_info_printf(ctx, "tls13 HostNQN") <= 0) {
734-
errno = ENOKEY;
735-
return -1;
736-
}
737-
if (hkdf_info_printf(ctx, "%s", hostnqn) <= 0) {
731+
if (hkdf_expand_label(ctx, "tls13 HostNQN", %s", hostnqn) <= 0) {
738732
errno = ENOKEY;
739733
return -1;
740734
}
741-
742735
if (EVP_PKEY_derive(ctx, retained, &key_len) <= 0) {
743736
errno = ENOKEY;
744737
return -1;
@@ -803,24 +796,17 @@ static int derive_tls_key(int version, unsigned char cipher,
803796
errno = ENOKEY;
804797
return -1;
805798
}
806-
if (EVP_PKEY_CTX_add1_hkdf_info(ctx,
807-
(const unsigned char *)&length, 2) <= 0) {
808-
errno = ENOKEY;
809-
return -1;
810-
}
811-
if (hkdf_info_printf(ctx, "tls13 nvme-tls-psk") <= 0) {
812-
errno = ENOKEY;
813-
return -1;
814-
}
815799
switch (version) {
816800
case 0:
817-
if (hkdf_info_printf(ctx, "%s", context) <= 0) {
801+
if (hkdf_expand_label(ctx, "tls13 nvme-tls-psk",
802+
"%s", context) <= 0) {
818803
errno = ENOKEY;
819804
return -1;
820805
}
821806
break;
822807
case 1:
823-
if (hkdf_info_printf(ctx, "%02d %s", cipher, context) <= 0) {
808+
if (hkdf_expand_label(ctx, "tls13 nvme-tls-psk"
809+
"%02d %s", cipher, context) <= 0) {
824810
errno = ENOKEY;
825811
return -1;
826812
}

0 commit comments

Comments
 (0)