1212#include "nvme.h"
1313#include "fabrics.h"
1414#include <linux/nvme-auth.h>
15+ #include <linux/nvme-keyring.h>
1516
1617#define CHAP_BUF_SIZE 4096
1718static struct kmem_cache * nvme_chap_buf_cache ;
@@ -131,7 +132,13 @@ static int nvme_auth_set_dhchap_negotiate_data(struct nvme_ctrl *ctrl,
131132 data -> auth_type = NVME_AUTH_COMMON_MESSAGES ;
132133 data -> auth_id = NVME_AUTH_DHCHAP_MESSAGE_NEGOTIATE ;
133134 data -> t_id = cpu_to_le16 (chap -> transaction );
134- data -> sc_c = 0 ; /* No secure channel concatenation */
135+ if (ctrl -> opts -> concat && chap -> qid == 0 ) {
136+ if (ctrl -> opts -> tls_key )
137+ data -> sc_c = NVME_AUTH_SECP_REPLACETLSPSK ;
138+ else
139+ data -> sc_c = NVME_AUTH_SECP_NEWTLSPSK ;
140+ } else
141+ data -> sc_c = NVME_AUTH_SECP_NOSC ;
135142 data -> napd = 1 ;
136143 data -> auth_protocol [0 ].dhchap .authid = NVME_AUTH_DHCHAP_AUTH_ID ;
137144 data -> auth_protocol [0 ].dhchap .halen = 3 ;
@@ -311,8 +318,9 @@ static int nvme_auth_set_dhchap_reply_data(struct nvme_ctrl *ctrl,
311318 data -> hl = chap -> hash_len ;
312319 data -> dhvlen = cpu_to_le16 (chap -> host_key_len );
313320 memcpy (data -> rval , chap -> response , chap -> hash_len );
314- if (ctrl -> ctrl_key ) {
321+ if (ctrl -> ctrl_key )
315322 chap -> bi_directional = true;
323+ if (ctrl -> ctrl_key || ctrl -> opts -> concat ) {
316324 get_random_bytes (chap -> c2 , chap -> hash_len );
317325 data -> cvalid = 1 ;
318326 memcpy (data -> rval + chap -> hash_len , chap -> c2 ,
@@ -322,7 +330,10 @@ static int nvme_auth_set_dhchap_reply_data(struct nvme_ctrl *ctrl,
322330 } else {
323331 memset (chap -> c2 , 0 , chap -> hash_len );
324332 }
325- chap -> s2 = nvme_auth_get_seqnum ();
333+ if (ctrl -> opts -> concat )
334+ chap -> s2 = 0 ;
335+ else
336+ chap -> s2 = nvme_auth_get_seqnum ();
326337 data -> seqnum = cpu_to_le32 (chap -> s2 );
327338 if (chap -> host_key_len ) {
328339 dev_dbg (ctrl -> device , "%s: qid %d host public key %*ph\n" ,
@@ -677,6 +688,92 @@ static void nvme_auth_free_dhchap(struct nvme_dhchap_queue_context *chap)
677688 crypto_free_kpp (chap -> dh_tfm );
678689}
679690
691+ void nvme_auth_revoke_tls_key (struct nvme_ctrl * ctrl )
692+ {
693+ dev_dbg (ctrl -> device , "Wipe generated TLS PSK %08x\n" ,
694+ key_serial (ctrl -> opts -> tls_key ));
695+ key_revoke (ctrl -> opts -> tls_key );
696+ key_put (ctrl -> opts -> tls_key );
697+ ctrl -> opts -> tls_key = NULL ;
698+ }
699+ EXPORT_SYMBOL_GPL (nvme_auth_revoke_tls_key );
700+
701+ static int nvme_auth_secure_concat (struct nvme_ctrl * ctrl ,
702+ struct nvme_dhchap_queue_context * chap )
703+ {
704+ u8 * psk , * digest , * tls_psk ;
705+ struct key * tls_key ;
706+ size_t psk_len ;
707+ int ret = 0 ;
708+
709+ if (!chap -> sess_key ) {
710+ dev_warn (ctrl -> device ,
711+ "%s: qid %d no session key negotiated\n" ,
712+ __func__ , chap -> qid );
713+ return - ENOKEY ;
714+ }
715+
716+ if (chap -> qid ) {
717+ dev_warn (ctrl -> device ,
718+ "qid %d: secure concatenation not supported on I/O queues\n" ,
719+ chap -> qid );
720+ return - EINVAL ;
721+ }
722+ ret = nvme_auth_generate_psk (chap -> hash_id , chap -> sess_key ,
723+ chap -> sess_key_len ,
724+ chap -> c1 , chap -> c2 ,
725+ chap -> hash_len , & psk , & psk_len );
726+ if (ret ) {
727+ dev_warn (ctrl -> device ,
728+ "%s: qid %d failed to generate PSK, error %d\n" ,
729+ __func__ , chap -> qid , ret );
730+ return ret ;
731+ }
732+ dev_dbg (ctrl -> device ,
733+ "%s: generated psk %*ph\n" , __func__ , (int )psk_len , psk );
734+
735+ ret = nvme_auth_generate_digest (chap -> hash_id , psk , psk_len ,
736+ ctrl -> opts -> subsysnqn ,
737+ ctrl -> opts -> host -> nqn , & digest );
738+ if (ret ) {
739+ dev_warn (ctrl -> device ,
740+ "%s: qid %d failed to generate digest, error %d\n" ,
741+ __func__ , chap -> qid , ret );
742+ goto out_free_psk ;
743+ };
744+ dev_dbg (ctrl -> device , "%s: generated digest %s\n" ,
745+ __func__ , digest );
746+ ret = nvme_auth_derive_tls_psk (chap -> hash_id , psk , psk_len ,
747+ digest , & tls_psk );
748+ if (ret ) {
749+ dev_warn (ctrl -> device ,
750+ "%s: qid %d failed to derive TLS psk, error %d\n" ,
751+ __func__ , chap -> qid , ret );
752+ goto out_free_digest ;
753+ };
754+
755+ tls_key = nvme_tls_psk_refresh (ctrl -> opts -> keyring ,
756+ ctrl -> opts -> host -> nqn ,
757+ ctrl -> opts -> subsysnqn , chap -> hash_id ,
758+ tls_psk , psk_len , digest );
759+ if (IS_ERR (tls_key )) {
760+ ret = PTR_ERR (tls_key );
761+ dev_warn (ctrl -> device ,
762+ "%s: qid %d failed to insert generated key, error %d\n" ,
763+ __func__ , chap -> qid , ret );
764+ tls_key = NULL ;
765+ }
766+ kfree_sensitive (tls_psk );
767+ if (ctrl -> opts -> tls_key )
768+ nvme_auth_revoke_tls_key (ctrl );
769+ ctrl -> opts -> tls_key = tls_key ;
770+ out_free_digest :
771+ kfree_sensitive (digest );
772+ out_free_psk :
773+ kfree_sensitive (psk );
774+ return ret ;
775+ }
776+
680777static void nvme_queue_auth_work (struct work_struct * work )
681778{
682779 struct nvme_dhchap_queue_context * chap =
@@ -833,6 +930,13 @@ static void nvme_queue_auth_work(struct work_struct *work)
833930 }
834931 if (!ret ) {
835932 chap -> error = 0 ;
933+ if (ctrl -> opts -> concat &&
934+ (ret = nvme_auth_secure_concat (ctrl , chap ))) {
935+ dev_warn (ctrl -> device ,
936+ "%s: qid %d failed to enable secure concatenation\n" ,
937+ __func__ , chap -> qid );
938+ chap -> error = ret ;
939+ }
836940 return ;
837941 }
838942
@@ -912,6 +1016,11 @@ static void nvme_ctrl_auth_work(struct work_struct *work)
9121016 "qid 0: authentication failed\n" );
9131017 return ;
9141018 }
1019+ /*
1020+ * Only run authentication on the admin queue for secure concatenation.
1021+ */
1022+ if (ctrl -> opts -> concat )
1023+ return ;
9151024
9161025 for (q = 1 ; q < ctrl -> queue_count ; q ++ ) {
9171026 ret = nvme_auth_negotiate (ctrl , q );
0 commit comments