@@ -794,6 +794,74 @@ static int derive_retained_key(int hmac, const char *hostnqn,
794794 return key_len ;
795795}
796796
797+ static int derive_retained_key_compat (int hmac , const char * hostnqn ,
798+ unsigned char * configured ,
799+ unsigned char * retained ,
800+ size_t key_len )
801+ {
802+ _cleanup_evp_pkey_ctx_ EVP_PKEY_CTX * ctx = NULL ;
803+ uint16_t length = htons (key_len & 0xFFFF );
804+ const EVP_MD * md ;
805+ size_t hmac_len ;
806+
807+ if (hmac == NVME_HMAC_ALG_NONE ) {
808+ memcpy (retained , configured , key_len );
809+ return key_len ;
810+ }
811+
812+ md = select_hmac (hmac , & hmac_len );
813+ if (!md || !hmac_len ) {
814+ errno = EINVAL ;
815+ return -1 ;
816+ }
817+
818+ ctx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF , NULL );
819+ if (!ctx ) {
820+ errno = ENOMEM ;
821+ return -1 ;
822+ }
823+
824+ if (EVP_PKEY_derive_init (ctx ) <= 0 ) {
825+ errno = ENOMEM ;
826+ return -1 ;
827+ }
828+ if (EVP_PKEY_CTX_set_hkdf_md (ctx , md ) <= 0 ) {
829+ errno = ENOKEY ;
830+ return -1 ;
831+ }
832+ if (EVP_PKEY_CTX_set1_hkdf_key (ctx , configured , key_len ) <= 0 ) {
833+ errno = ENOKEY ;
834+ return -1 ;
835+ }
836+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
837+ (const unsigned char * )& length , 2 ) <= 0 ) {
838+ errno = ENOKEY ;
839+ return -1 ;
840+ }
841+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
842+ (const unsigned char * )"tls13 " , 6 ) <= 0 ) {
843+ errno = ENOKEY ;
844+ return -1 ;
845+ }
846+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
847+ (const unsigned char * )"HostNQN" , 7 ) <= 0 ) {
848+ errno = ENOKEY ;
849+ return -1 ;
850+ }
851+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
852+ (const unsigned char * )hostnqn , strlen (hostnqn )) <= 0 ) {
853+ errno = ENOKEY ;
854+ return -1 ;
855+ }
856+
857+ if (EVP_PKEY_derive (ctx , retained , & key_len ) <= 0 ) {
858+ errno = ENOKEY ;
859+ return -1 ;
860+ }
861+
862+ return key_len ;
863+ }
864+
797865/*
798866 * derive_tls_key()
799867 *
@@ -885,6 +953,80 @@ static int derive_tls_key(int version, unsigned char cipher,
885953 return key_len ;
886954}
887955
956+ static int derive_tls_key_compat (int version , unsigned char cipher ,
957+ const char * context , unsigned char * retained ,
958+ unsigned char * psk , size_t key_len )
959+ {
960+ _cleanup_evp_pkey_ctx_ EVP_PKEY_CTX * ctx = NULL ;
961+ uint16_t length = htons (key_len & 0xFFFF );
962+ const EVP_MD * md ;
963+ size_t hmac_len ;
964+
965+ md = select_hmac (cipher , & hmac_len );
966+ if (!md || !hmac_len ) {
967+ errno = EINVAL ;
968+ return -1 ;
969+ }
970+
971+ ctx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF , NULL );
972+ if (!ctx ) {
973+ errno = ENOMEM ;
974+ return -1 ;
975+ }
976+
977+ if (EVP_PKEY_derive_init (ctx ) <= 0 ) {
978+ errno = ENOMEM ;
979+ return -1 ;
980+ }
981+ if (EVP_PKEY_CTX_set_hkdf_md (ctx , md ) <= 0 ) {
982+ errno = ENOKEY ;
983+ return -1 ;
984+ }
985+ if (EVP_PKEY_CTX_set1_hkdf_key (ctx , retained , key_len ) <= 0 ) {
986+ errno = ENOKEY ;
987+ return -1 ;
988+ }
989+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
990+ (const unsigned char * )& length , 2 ) <= 0 ) {
991+ errno = ENOKEY ;
992+ return -1 ;
993+ }
994+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
995+ (const unsigned char * )"tls13 " , 6 ) <= 0 ) {
996+ errno = ENOKEY ;
997+ return -1 ;
998+ }
999+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
1000+ (const unsigned char * )"nvme-tls-psk" , 12 ) <= 0 ) {
1001+ errno = ENOKEY ;
1002+ return -1 ;
1003+ }
1004+ if (version == 1 ) {
1005+ char hash_str [5 ];
1006+
1007+ sprintf (hash_str , "%02d " , cipher );
1008+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
1009+ (const unsigned char * )hash_str ,
1010+ strlen (hash_str )) <= 0 ) {
1011+ errno = ENOKEY ;
1012+ return -1 ;
1013+ }
1014+ }
1015+ if (EVP_PKEY_CTX_add1_hkdf_info (ctx ,
1016+ (const unsigned char * )context ,
1017+ strlen (context )) <= 0 ) {
1018+ errno = ENOKEY ;
1019+ return -1 ;
1020+ }
1021+
1022+ if (EVP_PKEY_derive (ctx , psk , & key_len ) <= 0 ) {
1023+ errno = ENOKEY ;
1024+ return -1 ;
1025+ }
1026+
1027+ return key_len ;
1028+ }
1029+
8881030static DEFINE_CLEANUP_FUNC (
8891031 cleanup_ossl_lib_ctx , OSSL_LIB_CTX * , OSSL_LIB_CTX_free )
8901032#define _cleanup_ossl_lib_ctx_ __cleanup__(cleanup_ossl_lib_ctx)
@@ -1102,7 +1244,7 @@ static int gen_tls_identity(const char *hostnqn, const char *subsysnqn,
11021244static int derive_nvme_keys (const char * hostnqn , const char * subsysnqn ,
11031245 char * identity , int version ,
11041246 int hmac , unsigned char * configured ,
1105- unsigned char * psk , int key_len )
1247+ unsigned char * psk , int key_len , bool compat )
11061248{
11071249 _cleanup_free_ unsigned char * retained = NULL ;
11081250 _cleanup_free_ char * digest = NULL ;
@@ -1120,7 +1262,12 @@ static int derive_nvme_keys(const char *hostnqn, const char *subsysnqn,
11201262 errno = ENOMEM ;
11211263 return -1 ;
11221264 }
1123- ret = derive_retained_key (hmac , hostnqn , configured , retained , key_len );
1265+ if (compat )
1266+ ret = derive_retained_key_compat (hmac , hostnqn , configured ,
1267+ retained , key_len );
1268+ else
1269+ ret = derive_retained_key (hmac , hostnqn , configured ,
1270+ retained , key_len );
11241271 if (ret < 0 )
11251272 return ret ;
11261273
@@ -1148,6 +1295,9 @@ static int derive_nvme_keys(const char *hostnqn, const char *subsysnqn,
11481295 digest , identity );
11491296 if (ret < 0 )
11501297 return ret ;
1298+ if (compat )
1299+ return derive_tls_key_compat (version , cipher , context , retained ,
1300+ psk , psk_len );
11511301 return derive_tls_key (version , cipher , context , retained ,
11521302 psk , key_len );
11531303}
@@ -1197,7 +1347,7 @@ char *nvme_generate_tls_key_identity(const char *hostnqn, const char *subsysnqn,
11971347
11981348 memset (psk , 0 , key_len );
11991349 ret = derive_nvme_keys (hostnqn , subsysnqn , identity , version , hmac ,
1200- configured_key , psk , key_len );
1350+ configured_key , psk , key_len , false );
12011351out_free_identity :
12021352 if (ret < 0 ) {
12031353 free (identity );
@@ -1365,10 +1515,11 @@ int nvme_scan_tls_keys(const char *keyring, nvme_scan_tls_keys_cb_t cb,
13651515 return ret ;
13661516}
13671517
1368- static long __nvme_insert_tls_key_versioned (key_serial_t keyring_id , const char * key_type ,
1369- const char * hostnqn , const char * subsysnqn ,
1370- int version , int hmac ,
1371- unsigned char * configured_key , int key_len )
1518+ static long __nvme_insert_tls_key (key_serial_t keyring_id , const char * key_type ,
1519+ const char * hostnqn , const char * subsysnqn ,
1520+ int version , int hmac ,
1521+ unsigned char * configured_key , int key_len ,
1522+ bool compat )
13721523{
13731524 _cleanup_free_ unsigned char * psk = NULL ;
13741525 _cleanup_free_ char * identity = NULL ;
@@ -1394,7 +1545,7 @@ static long __nvme_insert_tls_key_versioned(key_serial_t keyring_id, const char
13941545 }
13951546 memset (psk , 0 , key_len );
13961547 ret = derive_nvme_keys (hostnqn , subsysnqn , identity , version , hmac ,
1397- configured_key , psk , key_len );
1548+ configured_key , psk , key_len , compat );
13981549 if (ret != key_len ) {
13991550 errno = ENOKEY ;
14001551 return 0 ;
@@ -1422,10 +1573,33 @@ long nvme_insert_tls_key_versioned(const char *keyring, const char *key_type,
14221573 ret = nvme_set_keyring (keyring_id );
14231574 if (ret < 0 )
14241575 return 0 ;
1425- return __nvme_insert_tls_key_versioned (keyring_id , key_type ,
1426- hostnqn , subsysnqn ,
1427- version , hmac ,
1428- configured_key , key_len );
1576+ return __nvme_insert_tls_key (keyring_id , key_type ,
1577+ hostnqn , subsysnqn ,
1578+ version , hmac ,
1579+ configured_key , key_len , false);
1580+ }
1581+
1582+ long nvme_insert_tls_key_compat (const char * keyring , const char * key_type ,
1583+ const char * hostnqn , const char * subsysnqn ,
1584+ int version , int hmac ,
1585+ unsigned char * configured_key , int key_len )
1586+ {
1587+ key_serial_t keyring_id ;
1588+ int ret ;
1589+
1590+ keyring_id = nvme_lookup_keyring (keyring );
1591+ if (keyring_id == 0 ) {
1592+ errno = ENOKEY ;
1593+ return 0 ;
1594+ }
1595+
1596+ ret = nvme_set_keyring (keyring_id );
1597+ if (ret < 0 )
1598+ return 0 ;
1599+ return __nvme_insert_tls_key (keyring_id , key_type ,
1600+ hostnqn , subsysnqn ,
1601+ version , hmac ,
1602+ configured_key , key_len , true);
14291603}
14301604
14311605long nvme_revoke_tls_key (const char * keyring , const char * key_type ,
@@ -1447,7 +1621,7 @@ long nvme_revoke_tls_key(const char *keyring, const char *key_type,
14471621 return keyctl_revoke (key );
14481622}
14491623
1450- static long __nvme_insert_tls_key (long keyring_id ,
1624+ static long __nvme_import_tls_key (long keyring_id ,
14511625 const char * hostnqn , const char * subsysnqn ,
14521626 const char * identity , const char * key )
14531627{
@@ -1468,10 +1642,10 @@ static long __nvme_insert_tls_key(long keyring_id,
14681642 * configured key. Derive a new key and load the newly
14691643 * created key into the keystore.
14701644 */
1471- return __nvme_insert_tls_key_versioned (keyring_id , "psk" ,
1472- hostnqn , subsysnqn ,
1473- version , hmac ,
1474- key_data , key_len );
1645+ return __nvme_insert_tls_key (keyring_id , "psk" ,
1646+ hostnqn , subsysnqn ,
1647+ version , hmac ,
1648+ key_data , key_len , false );
14751649 }
14761650
14771651 return nvme_update_key (keyring_id , "psk" , identity ,
@@ -1526,7 +1700,7 @@ int __nvme_import_keys_from_config(nvme_host_t h, nvme_ctrl_t c,
15261700 id = nvme_lookup_key ("psk" , identity );
15271701
15281702 if (!id )
1529- id = __nvme_insert_tls_key (kr_id , hostnqn ,
1703+ id = __nvme_import_tls_key (kr_id , hostnqn ,
15301704 subsysnqn , identity , key );
15311705
15321706 if (id <= 0 ) {
0 commit comments