@@ -686,45 +686,8 @@ static DEFINE_CLEANUP_FUNC(
686686 cleanup_evp_pkey_ctx , EVP_PKEY_CTX * , EVP_PKEY_CTX_free )
687687#define _cleanup_evp_pkey_ctx_ __cleanup__(cleanup_evp_pkey_ctx)
688688
689- /*
690- * hkdf_info_printf()
691- *
692- * Helper function to append variable length label and context to an HkdfLabel
693- *
694- * RFC 8446 (TLS 1.3) Section 7.1 defines the HKDF-Expand-Label function as a
695- * specialization of the HKDF-Expand function (RFC 5869), where the info
696- * parameter is structured as an HkdfLabel.
697- *
698- * An HkdfLabel structure includes two variable length vectors (label and
699- * context) which must be preceded by their content length as per RFC 8446
700- * Section 3.4 (and not NUL terminated as per Section 7.1). Additionally,
701- * HkdfLabel.label must begin with "tls13 "
702- *
703- * Returns the number of bytes appended to the HKDF info buffer, or -1 on an
704- * error.
705- */
706- __attribute__((format (printf , 2 , 3 )))
707- static int hkdf_info_printf (EVP_PKEY_CTX * ctx , char * fmt , ...)
708- {
709- _cleanup_free_ char * str ;
710- uint8_t len ;
711- int ret ;
712- va_list myargs ;
713-
714- va_start (myargs , fmt );
715- ret = vasprintf (& str , fmt , myargs );
716- va_end (myargs );
717- if (ret < 0 )
718- return ret ;
719- if (ret > 255 )
720- return -1 ;
721- len = ret ;
722- if (EVP_PKEY_CTX_add1_hkdf_info (ctx , (unsigned char * )& len , 1 ) <= 0 )
723- return -1 ;
724- if (EVP_PKEY_CTX_add1_hkdf_info (ctx , (unsigned char * )str , len ) <= 0 )
725- return -1 ;
726- return (ret + 1 );
727- }
689+ /* NVMe is using the TLS 1.3 HkdfLabel structure */
690+ #define HKDF_INFO_MAX_LEN 514
728691
729692/*
730693 * derive_retained_key()
@@ -760,9 +723,18 @@ static int derive_retained_key(int hmac, const char *hostnqn,
760723 size_t key_len )
761724{
762725 _cleanup_evp_pkey_ctx_ EVP_PKEY_CTX * ctx = NULL ;
763- uint16_t length = htons ( key_len & 0xFFFF ) ;
726+ _cleanup_free_ uint8_t * hkdf_info = NULL ;
764727 const EVP_MD * md ;
765728 size_t hmac_len ;
729+ char * pos ;
730+ int ret ;
731+
732+ /* +1 byte so that the snprintf terminating null can not overflow */
733+ hkdf_info = malloc (HKDF_INFO_MAX_LEN + 1 );
734+ if (!hkdf_info ) {
735+ errno = ENOMEM ;
736+ return -1 ;
737+ }
766738
767739 if (hmac == NVME_HMAC_ALG_NONE ) {
768740 memcpy (retained , configured , key_len );
@@ -793,16 +765,26 @@ static int derive_retained_key(int hmac, const char *hostnqn,
793765 errno = ENOKEY ;
794766 return -1 ;
795767 }
796- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
797- (const unsigned char * )& length , 2 ) <= 0 ) {
768+
769+ pos = (char * )hkdf_info ;
770+ * (uint16_t * )pos = htons (key_len & 0xFFFF );
771+ pos += sizeof (uint16_t );
772+
773+ ret = snprintf (pos , 257 , "%ctls13 HostNQN" , 13 );
774+ if (ret <= 0 || ret > 256 ) {
798775 errno = ENOKEY ;
799776 return -1 ;
800777 }
801- if (hkdf_info_printf (ctx , "tls13 HostNQN" ) <= 0 ) {
778+ pos += ret ;
779+
780+ ret = snprintf (pos , 257 , "%c%s" , (int ) strlen (hostnqn ), hostnqn );
781+ if (ret <= 0 || ret > 256 ) {
802782 errno = ENOKEY ;
803783 return -1 ;
804784 }
805- if (hkdf_info_printf (ctx , "%s" , hostnqn ) <= 0 ) {
785+ pos += ret ;
786+
787+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx , hkdf_info , (pos - (char * )hkdf_info )) <= 0 ) {
806788 errno = ENOKEY ;
807789 return -1 ;
808790 }
@@ -911,9 +893,18 @@ static int derive_tls_key(int version, unsigned char cipher,
911893 unsigned char * psk , size_t key_len )
912894{
913895 _cleanup_evp_pkey_ctx_ EVP_PKEY_CTX * ctx = NULL ;
914- uint16_t length = htons ( key_len & 0xFFFF ) ;
896+ _cleanup_free_ uint8_t * hkdf_info = NULL ;
915897 const EVP_MD * md ;
916898 size_t hmac_len ;
899+ char * pos ;
900+ int ret ;
901+
902+ /* +1 byte so that the snprintf terminating null can not overflow */
903+ hkdf_info = malloc (HKDF_INFO_MAX_LEN + 1 );
904+ if (!hkdf_info ) {
905+ errno = ENOMEM ;
906+ return -1 ;
907+ }
917908
918909 md = select_hmac (cipher , & hmac_len );
919910 if (!md || !hmac_len ) {
@@ -939,33 +930,44 @@ static int derive_tls_key(int version, unsigned char cipher,
939930 errno = ENOKEY ;
940931 return -1 ;
941932 }
942- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
943- (const unsigned char * )& length , 2 ) <= 0 ) {
944- errno = ENOKEY ;
945- return -1 ;
946- }
947- if (hkdf_info_printf (ctx , "tls13 nvme-tls-psk" ) <= 0 ) {
933+
934+ pos = (char * )hkdf_info ;
935+ * (uint16_t * )pos = htons (key_len & 0xFFFF );
936+ pos += sizeof (uint16_t );
937+
938+ ret = snprintf (pos , 257 , "%ctls13 nvme-tls-psk" , 18 );
939+ if (ret <= 0 || ret > 256 ) {
948940 errno = ENOKEY ;
949941 return -1 ;
950942 }
943+ pos += ret ;
944+
951945 switch (version ) {
952946 case 0 :
953- if (hkdf_info_printf (ctx , "%s" , context ) <= 0 ) {
947+ ret = snprintf (pos , 257 , "%c%s" , (int ) strlen (context ), context );
948+ if (ret <= 0 || ret > 256 ) {
954949 errno = ENOKEY ;
955950 return -1 ;
956951 }
952+ pos += ret ;
957953 break ;
958954 case 1 :
959- if (hkdf_info_printf (ctx , "%02d %s" , cipher , context ) <= 0 ) {
955+ ret = snprintf (pos , 257 , "%c%02d %s" , (int ) strlen (context ) + 3 , cipher , context );
956+ if (ret <= 0 || ret > 256 ) {
960957 errno = ENOKEY ;
961958 return -1 ;
962959 }
960+ pos += ret ;
963961 break ;
964962 default :
965963 errno = ENOKEY ;
966964 return -1 ;
967965 }
968966
967+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx , hkdf_info , (pos - (char * )hkdf_info )) <= 0 ) {
968+ errno = ENOKEY ;
969+ return -1 ;
970+ }
969971 if (EVP_PKEY_derive (ctx , psk , & key_len ) <= 0 ) {
970972 errno = ENOKEY ;
971973 return -1 ;
0 commit comments