@@ -665,6 +665,46 @@ static DEFINE_CLEANUP_FUNC(
665665 cleanup_evp_pkey_ctx , EVP_PKEY_CTX * , EVP_PKEY_CTX_free )
666666#define _cleanup_evp_pkey_ctx_ __cleanup__(cleanup_evp_pkey_ctx)
667667
668+ /*
669+ * hkdf_info_printf()
670+ *
671+ * Helper function to append variable length label and context to an HkdfLabel
672+ *
673+ * RFC 8446 (TLS 1.3) Section 7.1 defines the HKDF-Expand-Label function as a
674+ * specialization of the HKDF-Expand function (RFC 5869), where the info
675+ * parameter is structured as an HkdfLabel.
676+ *
677+ * An HkdfLabel structure includes two variable length vectors (label and
678+ * context) which must be preceded by their content length as per RFC 8446
679+ * Section 3.4 (and not NUL terminated as per Section 7.1). Additionally,
680+ * HkdfLabel.label must begin with "tls13 "
681+ *
682+ * Returns the number of bytes appended to the HKDF info buffer, or -1 on an
683+ * error.
684+ */
685+ __attribute__((format (printf , 2 , 3 )))
686+ static int hkdf_info_printf (EVP_PKEY_CTX * ctx , char * fmt , ...)
687+ {
688+ _cleanup_free_ char * str ;
689+ uint8_t len ;
690+ int ret ;
691+
692+ va_list myargs ;
693+ va_start (myargs , fmt );
694+ ret = vasprintf (& str , fmt , myargs );
695+ va_end (myargs );
696+ if (ret < 0 )
697+ return ret ;
698+ if (ret > 255 )
699+ return -1 ;
700+ len = ret ;
701+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx , (unsigned char * )& len , 1 ) <= 0 )
702+ return -1 ;
703+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx , (unsigned char * )str , len ) <= 0 )
704+ return -1 ;
705+ return (ret + 1 );
706+ }
707+
668708/*
669709 * derive_retained_key()
670710 *
@@ -699,7 +739,7 @@ static int derive_retained_key(int hmac, const char *hostnqn,
699739 size_t key_len )
700740{
701741 _cleanup_evp_pkey_ctx_ EVP_PKEY_CTX * ctx = NULL ;
702- uint16_t length = key_len & 0xFFFF ;
742+ uint16_t length = htons ( key_len & 0xFFFF ) ;
703743 const EVP_MD * md ;
704744 size_t hmac_len ;
705745
@@ -737,18 +777,11 @@ static int derive_retained_key(int hmac, const char *hostnqn,
737777 errno = ENOKEY ;
738778 return -1 ;
739779 }
740- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
741- (const unsigned char * )"tls13 " , 6 ) <= 0 ) {
742- errno = ENOKEY ;
743- return -1 ;
744- }
745- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
746- (const unsigned char * )"HostNQN" , 7 ) <= 0 ) {
780+ if (hkdf_info_printf (ctx , "tls13 HostNQN" ) <= 0 ) {
747781 errno = ENOKEY ;
748782 return -1 ;
749783 }
750- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
751- (const unsigned char * )hostnqn , strlen (hostnqn )) <= 0 ) {
784+ if (hkdf_info_printf (ctx , "%s" , hostnqn ) <= 0 ) {
752785 errno = ENOKEY ;
753786 return -1 ;
754787 }
@@ -783,12 +816,13 @@ static int derive_retained_key(int hmac, const char *hostnqn,
783816 *
784817 * and the value '0' is invalid here.
785818 */
819+
786820static int derive_tls_key (int version , unsigned char cipher ,
787821 const char * context , unsigned char * retained ,
788822 unsigned char * psk , size_t key_len )
789823{
790824 _cleanup_evp_pkey_ctx_ EVP_PKEY_CTX * ctx = NULL ;
791- uint16_t length = key_len & 0xFFFF ;
825+ uint16_t length = htons ( key_len & 0xFFFF ) ;
792826 const EVP_MD * md ;
793827 size_t hmac_len ;
794828
@@ -821,30 +855,24 @@ static int derive_tls_key(int version, unsigned char cipher,
821855 errno = ENOKEY ;
822856 return -1 ;
823857 }
824- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
825- (const unsigned char * )"tls13 " , 6 ) <= 0 ) {
826- errno = ENOKEY ;
827- return -1 ;
828- }
829- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
830- (const unsigned char * )"nvme-tls-psk" , 12 ) <= 0 ) {
858+ if (hkdf_info_printf (ctx , "tls13 nvme-tls-psk" ) <= 0 ) {
831859 errno = ENOKEY ;
832860 return -1 ;
833861 }
834- if (version == 1 ) {
835- char hash_str [5 ];
836-
837- sprintf (hash_str , "%02d " , cipher );
838- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
839- (const unsigned char * )hash_str ,
840- strlen (hash_str )) <= 0 ) {
862+ switch (version ) {
863+ case 0 :
864+ if (hkdf_info_printf (ctx , "%s" , context ) <= 0 ) {
841865 errno = ENOKEY ;
842866 return -1 ;
843867 }
844- }
845- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
846- (const unsigned char * )context ,
847- strlen (context )) <= 0 ) {
868+ break ;
869+ case 1 :
870+ if (hkdf_info_printf (ctx , "%02d %s" , cipher , context ) <= 0 ) {
871+ errno = ENOKEY ;
872+ return -1 ;
873+ }
874+ break ;
875+ default :
848876 errno = ENOKEY ;
849877 return -1 ;
850878 }
0 commit comments