@@ -43,8 +43,26 @@ static u8 nvmet_auth_negotiate(struct nvmet_req *req, void *d)
4343 data -> auth_protocol [0 ].dhchap .halen ,
4444 data -> auth_protocol [0 ].dhchap .dhlen );
4545 req -> sq -> dhchap_tid = le16_to_cpu (data -> t_id );
46- if (data -> sc_c )
47- return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH ;
46+ if (data -> sc_c != NVME_AUTH_SECP_NOSC ) {
47+ if (!IS_ENABLED (CONFIG_NVME_TARGET_TCP_TLS ))
48+ return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH ;
49+ /* Secure concatenation can only be enabled on the admin queue */
50+ if (req -> sq -> qid )
51+ return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH ;
52+ switch (data -> sc_c ) {
53+ case NVME_AUTH_SECP_NEWTLSPSK :
54+ if (nvmet_queue_tls_keyid (req -> sq ))
55+ return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH ;
56+ break ;
57+ case NVME_AUTH_SECP_REPLACETLSPSK :
58+ if (!nvmet_queue_tls_keyid (req -> sq ))
59+ return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH ;
60+ break ;
61+ default :
62+ return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH ;
63+ }
64+ ctrl -> concat = true;
65+ }
4866
4967 if (data -> napd != 1 )
5068 return NVME_AUTH_DHCHAP_FAILURE_HASH_UNUSABLE ;
@@ -103,6 +121,12 @@ static u8 nvmet_auth_negotiate(struct nvmet_req *req, void *d)
103121 nvme_auth_dhgroup_name (fallback_dhgid ));
104122 ctrl -> dh_gid = fallback_dhgid ;
105123 }
124+ if (ctrl -> dh_gid == NVME_AUTH_DHGROUP_NULL && ctrl -> concat ) {
125+ pr_debug ("%s: ctrl %d qid %d: NULL DH group invalid "
126+ "for secure channel concatenation\n" , __func__ ,
127+ ctrl -> cntlid , req -> sq -> qid );
128+ return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH ;
129+ }
106130 pr_debug ("%s: ctrl %d qid %d: selected DH group %s (%d)\n" ,
107131 __func__ , ctrl -> cntlid , req -> sq -> qid ,
108132 nvme_auth_dhgroup_name (ctrl -> dh_gid ), ctrl -> dh_gid );
@@ -148,12 +172,22 @@ static u8 nvmet_auth_reply(struct nvmet_req *req, void *d)
148172 if (memcmp (data -> rval , response , data -> hl )) {
149173 pr_info ("ctrl %d qid %d host response mismatch\n" ,
150174 ctrl -> cntlid , req -> sq -> qid );
175+ pr_debug ("ctrl %d qid %d rval %*ph\n" ,
176+ ctrl -> cntlid , req -> sq -> qid , data -> hl , data -> rval );
177+ pr_debug ("ctrl %d qid %d response %*ph\n" ,
178+ ctrl -> cntlid , req -> sq -> qid , data -> hl , response );
151179 kfree (response );
152180 return NVME_AUTH_DHCHAP_FAILURE_FAILED ;
153181 }
154182 kfree (response );
155183 pr_debug ("%s: ctrl %d qid %d host authenticated\n" ,
156184 __func__ , ctrl -> cntlid , req -> sq -> qid );
185+ if (!data -> cvalid && ctrl -> concat ) {
186+ pr_debug ("%s: ctrl %d qid %d invalid challenge\n" ,
187+ __func__ , ctrl -> cntlid , req -> sq -> qid );
188+ return NVME_AUTH_DHCHAP_FAILURE_FAILED ;
189+ }
190+ req -> sq -> dhchap_s2 = le32_to_cpu (data -> seqnum );
157191 if (data -> cvalid ) {
158192 req -> sq -> dhchap_c2 = kmemdup (data -> rval + data -> hl , data -> hl ,
159193 GFP_KERNEL );
@@ -163,11 +197,23 @@ static u8 nvmet_auth_reply(struct nvmet_req *req, void *d)
163197 pr_debug ("%s: ctrl %d qid %d challenge %*ph\n" ,
164198 __func__ , ctrl -> cntlid , req -> sq -> qid , data -> hl ,
165199 req -> sq -> dhchap_c2 );
166- } else {
200+ }
201+ /*
202+ * NVMe Base Spec 2.2 section 8.3.4.5.4: DH-HMAC-CHAP_Reply message
203+ * Sequence Number (SEQNUM): [ .. ]
204+ * The value 0h is used to indicate that bidirectional authentication
205+ * is not performed, but a challenge value C2 is carried in order to
206+ * generate a pre-shared key (PSK) for subsequent establishment of a
207+ * secure channel.
208+ */
209+ if (req -> sq -> dhchap_s2 == 0 ) {
210+ if (ctrl -> concat )
211+ nvmet_auth_insert_psk (req -> sq );
167212 req -> sq -> authenticated = true;
213+ kfree (req -> sq -> dhchap_c2 );
168214 req -> sq -> dhchap_c2 = NULL ;
169- }
170- req -> sq -> dhchap_s2 = le32_to_cpu ( data -> seqnum ) ;
215+ } else if (! data -> cvalid )
216+ req -> sq -> authenticated = true ;
171217
172218 return 0 ;
173219}
@@ -303,6 +349,8 @@ void nvmet_execute_auth_send(struct nvmet_req *req)
303349 }
304350 goto done_kfree ;
305351 case NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2 :
352+ if (ctrl -> concat )
353+ nvmet_auth_insert_psk (req -> sq );
306354 req -> sq -> authenticated = true;
307355 pr_debug ("%s: ctrl %d qid %d ctrl authenticated\n" ,
308356 __func__ , ctrl -> cntlid , req -> sq -> qid );
0 commit comments