@@ -618,6 +618,46 @@ static DEFINE_CLEANUP_FUNC(
618618 cleanup_evp_pkey_ctx , EVP_PKEY_CTX * , EVP_PKEY_CTX_free )
619619#define _cleanup_evp_pkey_ctx_ __cleanup__(cleanup_evp_pkey_ctx)
620620
621+ /*
622+ * hkdf_info_printf()
623+ *
624+ * Helper function to append variable length label and context to an HkdfLabel
625+ *
626+ * RFC 8446 (TLS 1.3) Section 7.1 defines the HKDF-Expand-Label function as a
627+ * specialization of the HKDF-Expand function (RFC 5869), where the info
628+ * parameter is structured as an HkdfLabel.
629+ *
630+ * An HkdfLabel structure includes two variable length vectors (label and
631+ * context) which must be preceded by their content length as per RFC 8446
632+ * Section 3.4 (and not NUL terminated as per Section 7.1). Additionally,
633+ * HkdfLabel.label must begin with "tls13 "
634+ *
635+ * Returns the number of bytes appended to the HKDF info buffer, or -1 on an
636+ * error.
637+ */
638+ __attribute__((format (printf , 2 , 3 )))
639+ static int hkdf_info_printf (EVP_PKEY_CTX * ctx , char * fmt , ...)
640+ {
641+ _cleanup_free_ char * str = NULL ;
642+ va_list myargs ;
643+ uint8_t len ;
644+ int ret ;
645+
646+ va_start (myargs , fmt );
647+ ret = vasprintf (& str , fmt , myargs );
648+ va_end (myargs );
649+ if (ret < 0 )
650+ return ret ;
651+ if (ret > 255 )
652+ return -1 ;
653+ len = ret ;
654+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx , (unsigned char * )& len , 1 ) <= 0 )
655+ return -1 ;
656+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx , (unsigned char * )str , len ) <= 0 )
657+ return -1 ;
658+ return (ret + 1 );
659+ }
660+
621661/*
622662 * derive_retained_key()
623663 *
@@ -652,7 +692,7 @@ static int derive_retained_key(int hmac, const char *hostnqn,
652692 size_t key_len )
653693{
654694 _cleanup_evp_pkey_ctx_ EVP_PKEY_CTX * ctx = NULL ;
655- uint16_t length = key_len & 0xFFFF ;
695+ uint16_t length = htons ( key_len & 0xFFFF ) ;
656696 const EVP_MD * md ;
657697 size_t hmac_len ;
658698
@@ -690,18 +730,11 @@ static int derive_retained_key(int hmac, const char *hostnqn,
690730 errno = ENOKEY ;
691731 return -1 ;
692732 }
693- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
694- (const unsigned char * )"tls13 " , 6 ) <= 0 ) {
733+ if (hkdf_info_printf (ctx , "tls13 HostNQN" ) <= 0 ) {
695734 errno = ENOKEY ;
696735 return -1 ;
697736 }
698- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
699- (const unsigned char * )"HostNQN" , 7 ) <= 0 ) {
700- errno = ENOKEY ;
701- return -1 ;
702- }
703- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
704- (const unsigned char * )hostnqn , strlen (hostnqn )) <= 0 ) {
737+ if (hkdf_info_printf (ctx , "%s" , hostnqn ) <= 0 ) {
705738 errno = ENOKEY ;
706739 return -1 ;
707740 }
@@ -736,12 +769,13 @@ static int derive_retained_key(int hmac, const char *hostnqn,
736769 *
737770 * and the value '0' is invalid here.
738771 */
772+
739773static int derive_tls_key (int version , unsigned char cipher ,
740774 const char * context , unsigned char * retained ,
741775 unsigned char * psk , size_t key_len )
742776{
743777 _cleanup_evp_pkey_ctx_ EVP_PKEY_CTX * ctx = NULL ;
744- uint16_t length = key_len & 0xFFFF ;
778+ uint16_t length = htons ( key_len & 0xFFFF ) ;
745779 const EVP_MD * md ;
746780 size_t hmac_len ;
747781
@@ -774,30 +808,24 @@ static int derive_tls_key(int version, unsigned char cipher,
774808 errno = ENOKEY ;
775809 return -1 ;
776810 }
777- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
778- (const unsigned char * )"tls13 " , 6 ) <= 0 ) {
779- errno = ENOKEY ;
780- return -1 ;
781- }
782- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
783- (const unsigned char * )"nvme-tls-psk" , 12 ) <= 0 ) {
811+ if (hkdf_info_printf (ctx , "tls13 nvme-tls-psk" ) <= 0 ) {
784812 errno = ENOKEY ;
785813 return -1 ;
786814 }
787- if (version == 1 ) {
788- char hash_str [5 ];
789-
790- sprintf (hash_str , "%02d " , cipher );
791- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
792- (const unsigned char * )hash_str ,
793- strlen (hash_str )) <= 0 ) {
815+ switch (version ) {
816+ case 0 :
817+ if (hkdf_info_printf (ctx , "%s" , context ) <= 0 ) {
794818 errno = ENOKEY ;
795819 return -1 ;
796820 }
797- }
798- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
799- (const unsigned char * )context ,
800- strlen (context )) <= 0 ) {
821+ break ;
822+ case 1 :
823+ if (hkdf_info_printf (ctx , "%02d %s" , cipher , context ) <= 0 ) {
824+ errno = ENOKEY ;
825+ return -1 ;
826+ }
827+ break ;
828+ default :
801829 errno = ENOKEY ;
802830 return -1 ;
803831 }
0 commit comments