@@ -564,7 +564,7 @@ static int derive_psk_digest(const char *hostnqn, const char *subsysnqn,
564564 return -1 ;
565565}
566566
567- static int derive_tls_key (int version , int cipher , const char * digest , int digest_length_in_bytes ,
567+ static int derive_tls_key (int version , int cipher , const char * context ,
568568 unsigned char * retained ,
569569 unsigned char * psk , size_t key_len )
570570{
@@ -714,137 +714,6 @@ static int derive_retained_key(int hmac, const char *hostnqn,
714714 return key_len ;
715715}
716716
717- /*
718- *
719- * HKDF_Extract_Expand_Label(): This function performs the following operations
720- * PRK=HKDF-Extract(0, Secret) followed by
721- * HKDF-Expand-Label(PRK, Label, Ctx, HashLengh) to generate a new secret
722- *
723- * HKDF-Expand-Label: Reference: https://datatracker.ietf.org/doc/html/rfc8446#page-102
724- * HKDF-Extract & HKDF-Expand : Reference: https://www.rfc-editor.org/rfc/rfc5869.txt
725- *
726- * HKDF-Expand-Label(Secret, Label, Context, Length) =
727- * HKDF-Expand(Secret, HkdfLabel, Length)
728- *
729- * Where HkdfLabel is specified as:
730- *
731- * struct {
732- * uint16 length = Length;
733- * opaque label<7..255> = "tls13 " + Label;
734- * opaque context<0..255> = Context;
735- * } HkdfLabel;
736- *
737- * Derive-Secret(Secret, Label, Messages) =
738- * HKDF-Expand-Label(Secret, Label,
739- * Transcript-Hash(Messages), Hash.length)
740- *
741- *
742- * [cipher] : HMAC algorithm type [256/384]
743- * [Secret] : Input to HKDF-Extract(0, Secret)
744- * [label] : Label to be added to base label ("tls13 ") to produce the HkdfLabel:'opaque label'
745- * [label_length] : Length of the Label
746- * [context] : Context to produce to produce the HkdfLabel:'opaque context'
747- * [context_length] : Context length to produce to produce the HkdfLabel:'opaque context'
748- * [new_seret] : Pointer to the NewSecret generated by HKDF-Expand-Label(...)
749- * [derived_secret_length] : Length parameter for HKDF-Expand(Secret, HkdfLabel, Length)
750- *
751- */
752- int HKDF_Extract_Expand_Label (unsigned char cipher ,
753- const unsigned char * secret ,
754- const char * label , uint8_t label_length ,
755- const char * context , uint8_t context_length ,
756- unsigned char * derived_secret , uint8_t derived_secret_length )
757- {
758- _cleanup_evp_pkey_ctx_ EVP_PKEY_CTX * ctx = NULL ;
759- size_t key_len = derived_secret_length ;
760-
761- const EVP_MD * md ;
762- size_t hmac_len ;
763-
764- md = select_hmac (cipher , & hmac_len );
765- if (!md || !hmac_len || ((uint16_t )hmac_len != derived_secret_length )) {
766-
767-
768- errno = EINVAL ;
769- return -1 ;
770- }
771-
772- ctx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF , NULL );
773- if (!ctx ) {
774- errno = ENOMEM ;
775- return -1 ;
776- }
777-
778- if (EVP_PKEY_derive_init (ctx ) <= 0 ) {
779- errno = ENOMEM ;
780- return -1 ;
781- }
782- if (EVP_PKEY_CTX_set_hkdf_md (ctx , md ) <= 0 ) {
783- errno = ENOKEY ;
784- return -1 ;
785- }
786- if (EVP_PKEY_CTX_set1_hkdf_key (ctx , secret , key_len ) <= 0 ) {
787- errno = ENOKEY ;
788- return -1 ;
789- }
790- ////////////////////////////////////////////////////////////////////////////////////////
791- // HkdfLabel: Part 1/3
792- // uint16 length = Length;
793- // The 'Length' needs to be represented based on the network byte-order based on
794- // the TLS specification
795- ////////////////////////////////////////////////////////////////////////////////////////
796- uint16_t hkdf_expand_label_length = (((uint16_t )hmac_len & 0xFF ) << 8 ) | ((uint16_t )hmac_len >> 8 );
797- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
798- (const unsigned char * )& hkdf_expand_label_length , 2 ) <= 0 ) {
799- errno = ENOKEY ;
800- return -1 ;
801- }
802-
803- ////////////////////////////////////////////////////////////////////////////////////////
804- // HkdfLabel: Part 2/3
805- // opaque label<7..255> = "tls13 " + Label;
806- ////////////////////////////////////////////////////////////////////////////////////////
807- const char * tls_13_label = "tls13 " ;
808- uint8_t f_label_length = strlen (tls_13_label ) + label_length ;
809- // add label length: since label is opaque
810- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,(const unsigned char * )& f_label_length , 1 ) <= 0 ) {
811- errno = ENOKEY ;
812- return -1 ;
813- }
814-
815- if (EVP_PKEY_CTX_add1_hkdf_info (ctx , (const unsigned char * )"tls13 " , 6 ) <= 0 ) {
816- errno = ENOKEY ;
817- return -1 ;
818- }
819-
820- if (EVP_PKEY_CTX_add1_hkdf_info (ctx , (const unsigned char * )label , label_length ) <= 0 ) {
821- errno = ENOKEY ;
822- return -1 ;
823- }
824-
825- ////////////////////////////////////////////////////////////////////////////////////////
826- // HkdfLabel: Part 3/3
827- // opaque context<0..255> = Context
828- ////////////////////////////////////////////////////////////////////////////////////////
829- if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,(const unsigned char * )& context_length , 1 ) <= 0 ) {
830- errno = ENOKEY ;
831- return -1 ;
832- }
833-
834- if (EVP_PKEY_CTX_add1_hkdf_info (ctx , (const unsigned char * )context , context_length )<= 0 ) {
835- errno = ENOKEY ;
836- return -1 ;
837- }
838-
839- // Generate Key now
840- if (EVP_PKEY_derive (ctx , derived_secret , & key_len ) <= 0 ) {
841- errno = ENOKEY ;
842- return -1 ;
843- }
844-
845- return key_len ;
846- }
847-
848717/*
849718 * derive_tls_key()
850719 *
@@ -868,29 +737,77 @@ int HKDF_Extract_Expand_Label(unsigned char cipher,
868737 * and the value '0' is invalid here.
869738 */
870739static int derive_tls_key (int version , unsigned char cipher ,
871- const char * psk_digest , uint8_t psk_digest_buffer_length , unsigned char * retained ,
740+ const char * context , unsigned char * retained ,
872741 unsigned char * psk , size_t key_len )
873742{
874- // Reference: https://nvmexpress.org/wp-content/uploads/NVM-Express-TCP-Transport-Specification-Revision-1.1-2024.08.05-Ratified.pdf
875- //
876- // 1. PRK = HKDF-Extract(0, Input PSK); and
877- // 2. TLS PSK = HKDF-Expand-Label(PRK, “nvme-tls-psk”, Context, L),
878- //
879- // Context = “<hash> <PSK digest>” :
880- char context [64 + 3 ]; // Max hash size length (64) + 3
881- uint8_t context_length = psk_digest_buffer_length ;
882- if (version == 1 ) {
883- sprintf (& context [0 ], "%02d " , cipher );
884- memcpy (& context [3 ], psk_digest , psk_digest_buffer_length );
885- context_length += 3 ;
886- }
887- else
888- {
889- memcpy (& context [0 ], psk_digest , psk_digest_buffer_length );
890- }
891-
892- return HKDF_Extract_Expand_Label (cipher , & retained [0 ], "nvme-tls-psk" , strlen ("nvme-tls-psk" ),
893- context , context_length , psk , key_len );
743+ _cleanup_evp_pkey_ctx_ EVP_PKEY_CTX * ctx = NULL ;
744+ uint16_t length = key_len & 0xFFFF ;
745+ const EVP_MD * md ;
746+ size_t hmac_len ;
747+
748+ md = select_hmac (cipher , & hmac_len );
749+ if (!md || !hmac_len ) {
750+ errno = EINVAL ;
751+ return -1 ;
752+ }
753+
754+ ctx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF , NULL );
755+ if (!ctx ) {
756+ errno = ENOMEM ;
757+ return -1 ;
758+ }
759+
760+ if (EVP_PKEY_derive_init (ctx ) <= 0 ) {
761+ errno = ENOMEM ;
762+ return -1 ;
763+ }
764+ if (EVP_PKEY_CTX_set_hkdf_md (ctx , md ) <= 0 ) {
765+ errno = ENOKEY ;
766+ return -1 ;
767+ }
768+ if (EVP_PKEY_CTX_set1_hkdf_key (ctx , retained , key_len ) <= 0 ) {
769+ errno = ENOKEY ;
770+ return -1 ;
771+ }
772+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
773+ (const unsigned char * )& length , 2 ) <= 0 ) {
774+ errno = ENOKEY ;
775+ return -1 ;
776+ }
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 ) {
784+ errno = ENOKEY ;
785+ return -1 ;
786+ }
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 ) {
794+ errno = ENOKEY ;
795+ return -1 ;
796+ }
797+ }
798+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
799+ (const unsigned char * )context ,
800+ strlen (context )) <= 0 ) {
801+ errno = ENOKEY ;
802+ return -1 ;
803+ }
804+
805+ if (EVP_PKEY_derive (ctx , psk , & key_len ) <= 0 ) {
806+ errno = ENOKEY ;
807+ return -1 ;
808+ }
809+
810+ return key_len ;
894811}
895812
896813static DEFINE_CLEANUP_FUNC (
@@ -1156,7 +1073,7 @@ static int derive_nvme_keys(const char *hostnqn, const char *subsysnqn,
11561073 digest , identity );
11571074 if (ret < 0 )
11581075 return ret ;
1159- return derive_tls_key (version , cipher , context , strlen ( context ), retained ,
1076+ return derive_tls_key (version , cipher , context , retained ,
11601077 psk , key_len );
11611078}
11621079
0 commit comments