Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2024 Intel Corporation. All rights reserved.
3 : : */
4 : : #include "spdk/stdinc.h"
5 : :
6 : : #include "spdk_internal/cunit.h"
7 : : #include "spdk_internal/mock.h"
8 : :
9 : : #include "common/lib/ut_multithread.c"
10 : : #include "unit/lib/json_mock.c"
11 : : #include "nvmf/auth.c"
12 : :
13 [ # # ]: 0 : DEFINE_STUB(spdk_nvme_dhchap_get_digest_name, const char *, (int d), NULL);
14 [ # # ]: 0 : DEFINE_STUB(spdk_nvme_dhchap_get_dhgroup_name, const char *, (int d), NULL);
15 [ # # ]: 0 : DEFINE_STUB(spdk_nvme_dhchap_get_digest_length, uint8_t, (int d), 0);
16 : 0 : DEFINE_STUB_V(spdk_keyring_put_key, (struct spdk_key *k));
17 [ # # ]: 0 : DEFINE_STUB(nvmf_subsystem_get_dhchap_key, struct spdk_key *,
18 : : (struct spdk_nvmf_subsystem *s, const char *h, enum nvmf_auth_key_type t), NULL);
19 [ # # ]: 0 : DEFINE_STUB(spdk_nvme_dhchap_generate_dhkey, struct spdk_nvme_dhchap_dhkey *,
20 : : (enum spdk_nvmf_dhchap_dhgroup dhgroup), NULL);
21 : 0 : DEFINE_STUB_V(spdk_nvme_dhchap_dhkey_free, (struct spdk_nvme_dhchap_dhkey **key));
22 [ # # ]: 0 : DEFINE_STUB(spdk_nvme_dhchap_dhkey_derive_secret, int,
23 : : (struct spdk_nvme_dhchap_dhkey *key, const void *peer, size_t peerlen, void *secret,
24 : : size_t *seclen), 0);
25 : : DECLARE_WRAPPER(RAND_bytes, int, (unsigned char *buf, int num));
26 : :
27 : : static uint8_t g_rand_val;
28 [ # # ]: 0 : DEFINE_WRAPPER_MOCK(RAND_bytes, int) = 1;
29 : :
30 : : int
31 : 0 : __wrap_RAND_bytes(unsigned char *buf, int num)
32 : : {
33 : 0 : memset(buf, g_rand_val, num);
34 [ # # ]: 0 : return MOCK_GET(RAND_bytes);
35 : : }
36 : :
37 : : void
38 : 0 : nvmf_qpair_set_state(struct spdk_nvmf_qpair *qpair, enum spdk_nvmf_qpair_state state)
39 : : {
40 : 0 : qpair->state = state;
41 : 0 : }
42 : :
43 : : int
44 : 0 : spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair)
45 : : {
46 : 0 : nvmf_qpair_set_state(qpair, SPDK_NVMF_QPAIR_ERROR);
47 : 0 : return 0;
48 : : }
49 : :
50 : : static bool g_req_completed;
51 : :
52 : : int
53 : 0 : spdk_nvmf_request_complete(struct spdk_nvmf_request *req)
54 : : {
55 : 0 : g_req_completed = true;
56 : 0 : return 0;
57 : : }
58 : :
59 : : static uint8_t g_rval;
60 [ # # ]: 0 : DEFINE_RETURN_MOCK(spdk_nvme_dhchap_calculate, int);
61 : :
62 : : int
63 : 0 : spdk_nvme_dhchap_calculate(struct spdk_key *key, enum spdk_nvmf_dhchap_hash hash,
64 : : const char *type, uint32_t seq, uint16_t tid, uint8_t scc,
65 : : const char *nqn1, const char *nqn2, const void *dhkey, size_t dhlen,
66 : : const void *cval, void *rval)
67 : : {
68 : 0 : memset(rval, g_rval, spdk_nvme_dhchap_get_digest_length(hash));
69 [ # # ]: 0 : return MOCK_GET(spdk_nvme_dhchap_calculate);
70 : : }
71 : :
72 : : static uint8_t g_dhv;
73 : : static size_t g_dhvlen;
74 [ # # ]: 0 : DEFINE_RETURN_MOCK(spdk_nvme_dhchap_dhkey_get_pubkey, int);
75 : :
76 : : int
77 : 0 : spdk_nvme_dhchap_dhkey_get_pubkey(struct spdk_nvme_dhchap_dhkey *dhkey, void *pub, size_t *len)
78 : : {
79 : : int rc;
80 : :
81 [ # # ]: 0 : rc = MOCK_GET(spdk_nvme_dhchap_dhkey_get_pubkey);
82 [ # # ]: 0 : if (rc != 0) {
83 : 0 : return rc;
84 : : }
85 : :
86 [ # # ]: 0 : SPDK_CU_ASSERT_FATAL(*len >= g_dhvlen);
87 : 0 : memset(pub, g_dhv, g_dhvlen);
88 : 0 : *len = g_dhvlen;
89 : :
90 : 0 : return rc;
91 : : }
92 : :
93 : : static void
94 : 0 : ut_clear_resp(struct spdk_nvmf_request *req)
95 : : {
96 : 0 : memset(&req->rsp->nvme_cpl, 0, sizeof(req->rsp->nvme_cpl));
97 : 0 : }
98 : :
99 : : #define ut_prep_cmd(_req, _cmd, _buf, _len, _lfield) \
100 : : do { \
101 : : (_req)->cmd = (void *)_cmd; \
102 : : (_req)->iov[0].iov_base = _buf; \
103 : : (_req)->iov[0].iov_len = _len; \
104 : : (_req)->iovcnt = 1; \
105 : : (_req)->length = _len; \
106 : : (_cmd)->secp = SPDK_NVMF_AUTH_SECP_NVME; \
107 : : (_cmd)->spsp0 = 1; \
108 : : (_cmd)->spsp1 = 1; \
109 : : (_cmd)->_lfield = _len; \
110 : : } while (0)
111 : :
112 : : #define ut_prep_send_cmd(req, cmd, buf, len) ut_prep_cmd(req, cmd, buf, len, tl)
113 : : #define ut_prep_recv_cmd(req, cmd, buf, len) ut_prep_cmd(req, cmd, buf, len, al)
114 : :
115 : : static void
116 : 0 : test_auth_send_recv_error(void)
117 : : {
118 : 0 : union nvmf_c2h_msg rsp = {};
119 : 0 : struct spdk_nvmf_subsystem subsys = {};
120 : 0 : struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
121 : 0 : struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr };
122 : 0 : struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
123 : 0 : struct spdk_nvme_cpl *cpl = &rsp.nvme_cpl;
124 : 0 : struct spdk_nvmf_fabric_auth_send_cmd send_cmd = {};
125 : 0 : struct spdk_nvmf_fabric_auth_recv_cmd recv_cmd = {};
126 : : struct spdk_nvmf_qpair_auth *auth;
127 : : int rc;
128 : :
129 : 0 : rc = nvmf_qpair_auth_init(&qpair);
130 [ # # ]: 0 : SPDK_CU_ASSERT_FATAL(rc == 0);
131 : 0 : ut_prep_send_cmd(&req, &send_cmd, NULL, 255);
132 : 0 : ut_prep_recv_cmd(&req, &recv_cmd, NULL, 255);
133 : 0 : auth = qpair.auth;
134 : :
135 : : /* Bad secp (send) */
136 : 0 : g_req_completed = false;
137 : 0 : req.cmd = (void *)&send_cmd;
138 : 0 : ut_clear_resp(&req);
139 : 0 : send_cmd.secp = SPDK_NVMF_AUTH_SECP_NVME + 1;
140 : :
141 : 0 : nvmf_auth_send_exec(&req);
142 : 0 : CU_ASSERT(g_req_completed);
143 : 0 : CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
144 : 0 : CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
145 : 0 : CU_ASSERT_EQUAL(cpl->status.dnr, 1);
146 : 0 : send_cmd.secp = SPDK_NVMF_AUTH_SECP_NVME;
147 : :
148 : : /* Bad secp (recv) */
149 : 0 : g_req_completed = false;
150 : 0 : req.cmd = (void *)&recv_cmd;
151 : 0 : ut_clear_resp(&req);
152 : 0 : recv_cmd.secp = SPDK_NVMF_AUTH_SECP_NVME + 1;
153 : :
154 : 0 : nvmf_auth_recv_exec(&req);
155 : 0 : CU_ASSERT(g_req_completed);
156 : 0 : CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
157 : 0 : CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
158 : 0 : CU_ASSERT_EQUAL(cpl->status.dnr, 1);
159 : 0 : recv_cmd.secp = SPDK_NVMF_AUTH_SECP_NVME;
160 : :
161 : : /* Bad spsp0 (send) */
162 : 0 : g_req_completed = false;
163 : 0 : req.cmd = (void *)&send_cmd;
164 : 0 : ut_clear_resp(&req);
165 : 0 : send_cmd.spsp0 = 2;
166 : :
167 : 0 : nvmf_auth_send_exec(&req);
168 : 0 : CU_ASSERT(g_req_completed);
169 : 0 : CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
170 : 0 : CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
171 : 0 : CU_ASSERT_EQUAL(cpl->status.dnr, 1);
172 : 0 : send_cmd.spsp0 = 1;
173 : :
174 : : /* Bad spsp0 (recv) */
175 : 0 : g_req_completed = false;
176 : 0 : req.cmd = (void *)&recv_cmd;
177 : 0 : ut_clear_resp(&req);
178 : 0 : recv_cmd.spsp0 = 2;
179 : :
180 : 0 : nvmf_auth_recv_exec(&req);
181 : 0 : CU_ASSERT(g_req_completed);
182 : 0 : CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
183 : 0 : CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
184 : 0 : CU_ASSERT_EQUAL(cpl->status.dnr, 1);
185 : 0 : recv_cmd.spsp0 = 1;
186 : :
187 : : /* Bad spsp1 (send) */
188 : 0 : g_req_completed = false;
189 : 0 : req.cmd = (void *)&send_cmd;
190 : 0 : ut_clear_resp(&req);
191 : 0 : send_cmd.spsp1 = 2;
192 : :
193 : 0 : nvmf_auth_send_exec(&req);
194 : 0 : CU_ASSERT(g_req_completed);
195 : 0 : CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
196 : 0 : CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
197 : 0 : CU_ASSERT_EQUAL(cpl->status.dnr, 1);
198 : 0 : send_cmd.spsp1 = 1;
199 : :
200 : : /* Bad spsp1 (recv) */
201 : 0 : g_req_completed = false;
202 : 0 : req.cmd = (void *)&recv_cmd;
203 : 0 : ut_clear_resp(&req);
204 : 0 : recv_cmd.spsp1 = 2;
205 : :
206 : 0 : nvmf_auth_recv_exec(&req);
207 : 0 : CU_ASSERT(g_req_completed);
208 : 0 : CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
209 : 0 : CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
210 : 0 : CU_ASSERT_EQUAL(cpl->status.dnr, 1);
211 : 0 : recv_cmd.spsp1 = 1;
212 : :
213 : : /* Bad length (send) */
214 : 0 : g_req_completed = false;
215 : 0 : req.cmd = (void *)&send_cmd;
216 : 0 : ut_clear_resp(&req);
217 : 0 : send_cmd.tl = req.length + 1;
218 : :
219 : 0 : nvmf_auth_recv_exec(&req);
220 : 0 : CU_ASSERT(g_req_completed);
221 : 0 : CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
222 : 0 : CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
223 : 0 : CU_ASSERT_EQUAL(cpl->status.dnr, 1);
224 : 0 : send_cmd.tl = req.length;
225 : :
226 : : /* Bad length (recv) */
227 : 0 : g_req_completed = false;
228 : 0 : req.cmd = (void *)&recv_cmd;
229 : 0 : ut_clear_resp(&req);
230 : 0 : recv_cmd.al = req.length - 1;
231 : :
232 : 0 : nvmf_auth_recv_exec(&req);
233 : 0 : CU_ASSERT(g_req_completed);
234 : 0 : CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
235 : 0 : CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
236 : 0 : CU_ASSERT_EQUAL(cpl->status.dnr, 1);
237 : 0 : recv_cmd.al = req.length;
238 : :
239 : : /* Bad length (smaller than common header) */
240 : 0 : g_req_completed = false;
241 : 0 : req.cmd = (union nvmf_h2c_msg *)&send_cmd;
242 : 0 : ut_clear_resp(&req);
243 : 0 : send_cmd.tl = req.length = sizeof(struct nvmf_auth_common_header) - 1;
244 : :
245 : 0 : nvmf_auth_send_exec(&req);
246 : 0 : CU_ASSERT(g_req_completed);
247 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
248 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
249 : 0 : send_cmd.tl = req.length = 255;
250 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
251 : 0 : auth->fail_reason = 0;
252 : :
253 : 0 : nvmf_qpair_auth_destroy(&qpair);
254 : 0 : }
255 : :
256 : : static void
257 : 0 : test_auth_negotiate(void)
258 : : {
259 : 0 : union nvmf_c2h_msg rsp = {};
260 : 0 : struct spdk_nvmf_subsystem subsys = {};
261 : 0 : struct spdk_nvmf_tgt tgt = { .dhchap_digests = UINT32_MAX, .dhchap_dhgroups = UINT32_MAX };
262 : 0 : struct spdk_nvmf_poll_group group = { .tgt = &tgt };
263 : 0 : struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
264 : 0 : struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr, .group = &group };
265 : 0 : struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
266 : 0 : struct spdk_nvmf_fabric_auth_send_cmd cmd = {};
267 : : struct spdk_nvmf_qpair_auth *auth;
268 : : struct spdk_nvmf_auth_negotiate *msg;
269 : : struct spdk_nvmf_auth_descriptor *desc;
270 : 0 : uint8_t msgbuf[4096];
271 : : int rc;
272 : :
273 : 0 : msg = (void *)msgbuf;
274 : 0 : rc = nvmf_qpair_auth_init(&qpair);
275 [ # # ]: 0 : SPDK_CU_ASSERT_FATAL(rc == 0);
276 : 0 : ut_prep_send_cmd(&req, &cmd, msgbuf, sizeof(*msg) + sizeof(*desc));
277 : 0 : auth = qpair.auth;
278 : :
279 : : /* Successful negotiation */
280 : 0 : g_req_completed = false;
281 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
282 : 0 : msg->auth_type = SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE;
283 : 0 : msg->auth_id = SPDK_NVMF_AUTH_ID_NEGOTIATE;
284 : 0 : msg->sc_c = SPDK_NVMF_AUTH_SCC_DISABLED;
285 : 0 : msg->napd = 1;
286 : 0 : desc = &msg->descriptors[0];
287 : 0 : desc->auth_id = SPDK_NVMF_AUTH_TYPE_DHCHAP;
288 : 0 : desc->halen = 3;
289 : 0 : desc->hash_id_list[0] = SPDK_NVMF_DHCHAP_HASH_SHA256;
290 : 0 : desc->hash_id_list[1] = SPDK_NVMF_DHCHAP_HASH_SHA384;
291 : 0 : desc->hash_id_list[2] = SPDK_NVMF_DHCHAP_HASH_SHA512;
292 : 0 : desc->dhlen = 6;
293 : 0 : desc->dhg_id_list[0] = SPDK_NVMF_DHCHAP_DHGROUP_NULL;
294 : 0 : desc->dhg_id_list[1] = SPDK_NVMF_DHCHAP_DHGROUP_2048;
295 : 0 : desc->dhg_id_list[2] = SPDK_NVMF_DHCHAP_DHGROUP_3072;
296 : 0 : desc->dhg_id_list[3] = SPDK_NVMF_DHCHAP_DHGROUP_4096;
297 : 0 : desc->dhg_id_list[4] = SPDK_NVMF_DHCHAP_DHGROUP_6144;
298 : 0 : desc->dhg_id_list[5] = SPDK_NVMF_DHCHAP_DHGROUP_8192;
299 : :
300 : 0 : nvmf_auth_send_exec(&req);
301 : 0 : CU_ASSERT(g_req_completed);
302 : 0 : CU_ASSERT_EQUAL(auth->digest, SPDK_NVMF_DHCHAP_HASH_SHA512);
303 : 0 : CU_ASSERT_EQUAL(auth->dhgroup, SPDK_NVMF_DHCHAP_DHGROUP_8192);
304 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_CHALLENGE);
305 : :
306 : : /* Invalid auth state */
307 : 0 : g_req_completed = false;
308 : 0 : auth->state = NVMF_QPAIR_AUTH_ERROR;
309 : 0 : auth->digest = -1;
310 : :
311 : 0 : nvmf_auth_send_exec(&req);
312 : 0 : CU_ASSERT(g_req_completed);
313 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
314 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
315 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
316 : :
317 : : /* scc mismatch */
318 : 0 : g_req_completed = false;
319 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
320 : 0 : msg->sc_c = SPDK_NVMF_AUTH_SCC_TLS;
321 : :
322 : 0 : nvmf_auth_send_exec(&req);
323 : 0 : CU_ASSERT(g_req_completed);
324 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
325 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
326 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_SCC_MISMATCH);
327 : 0 : msg->sc_c = SPDK_NVMF_AUTH_SCC_DISABLED;
328 : :
329 : : /* Missing DH-HMAC-CHAP protocol (napd=0) */
330 : 0 : g_req_completed = false;
331 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
332 : 0 : req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg);
333 : 0 : msg->napd = 0;
334 : :
335 : 0 : nvmf_auth_send_exec(&req);
336 : 0 : CU_ASSERT(g_req_completed);
337 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
338 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
339 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_PROTOCOL_UNUSABLE);
340 : 0 : req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg) + sizeof(*desc);
341 : 0 : msg->napd = 1;
342 : :
343 : : /* Missing DH-HMAC-CHAP protocol */
344 : 0 : g_req_completed = false;
345 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
346 : 0 : desc->auth_id = SPDK_NVMF_AUTH_TYPE_DHCHAP + 1;
347 : :
348 : 0 : nvmf_auth_send_exec(&req);
349 : 0 : CU_ASSERT(g_req_completed);
350 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
351 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
352 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_PROTOCOL_UNUSABLE);
353 : 0 : desc->auth_id = SPDK_NVMF_AUTH_TYPE_DHCHAP;
354 : :
355 : : /* No valid digests (halen=0) */
356 : 0 : g_req_completed = false;
357 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
358 : 0 : desc->halen = 0;
359 : :
360 : 0 : nvmf_auth_send_exec(&req);
361 : 0 : CU_ASSERT(g_req_completed);
362 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
363 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
364 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_HASH_UNUSABLE);
365 : :
366 : : /* No valid digests */
367 : 0 : g_req_completed = false;
368 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
369 : 0 : desc->hash_id_list[0] = SPDK_NVMF_DHCHAP_HASH_SHA512 + 1;
370 : 0 : desc->hash_id_list[1] = SPDK_NVMF_DHCHAP_HASH_SHA512 + 2;
371 : 0 : desc->hash_id_list[2] = SPDK_NVMF_DHCHAP_HASH_SHA512 + 3;
372 : 0 : desc->halen = 3;
373 : :
374 : 0 : nvmf_auth_send_exec(&req);
375 : 0 : CU_ASSERT(g_req_completed);
376 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
377 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
378 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_HASH_UNUSABLE);
379 : 0 : desc->hash_id_list[0] = SPDK_NVMF_DHCHAP_HASH_SHA256;
380 : 0 : desc->hash_id_list[1] = SPDK_NVMF_DHCHAP_HASH_SHA384;
381 : 0 : desc->hash_id_list[2] = SPDK_NVMF_DHCHAP_HASH_SHA512;
382 : :
383 : : /* No valid dhgroups (dhlen=0) */
384 : 0 : g_req_completed = false;
385 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
386 : 0 : desc->dhlen = 0;
387 : :
388 : 0 : nvmf_auth_send_exec(&req);
389 : 0 : CU_ASSERT(g_req_completed);
390 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
391 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
392 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_DHGROUP_UNUSABLE);
393 : :
394 : : /* No valid dhgroups */
395 : 0 : g_req_completed = false;
396 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
397 : 0 : desc->dhlen = 2;
398 : 0 : desc->dhg_id_list[0] = SPDK_NVMF_DHCHAP_DHGROUP_8192 + 1;
399 : 0 : desc->dhg_id_list[1] = SPDK_NVMF_DHCHAP_DHGROUP_8192 + 2;
400 : :
401 : 0 : nvmf_auth_send_exec(&req);
402 : 0 : CU_ASSERT(g_req_completed);
403 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
404 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
405 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_DHGROUP_UNUSABLE);
406 : 0 : desc->dhg_id_list[0] = SPDK_NVMF_DHCHAP_DHGROUP_NULL;
407 : 0 : desc->dhg_id_list[1] = SPDK_NVMF_DHCHAP_DHGROUP_2048;
408 : 0 : desc->dhlen = 6;
409 : :
410 : : /* Bad halen value */
411 : 0 : g_req_completed = false;
412 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
413 : 0 : desc->halen = 255;
414 : :
415 : 0 : nvmf_auth_send_exec(&req);
416 : 0 : CU_ASSERT(g_req_completed);
417 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
418 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
419 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
420 : 0 : desc->halen = 3;
421 : :
422 : : /* Bad dhlen value */
423 : 0 : g_req_completed = false;
424 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
425 : 0 : desc->dhlen = 255;
426 : :
427 : 0 : nvmf_auth_send_exec(&req);
428 : 0 : CU_ASSERT(g_req_completed);
429 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
430 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
431 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
432 : 0 : desc->dhlen = 6;
433 : :
434 : : /* Invalid request length (too small) */
435 : 0 : g_req_completed = false;
436 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
437 : 0 : req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg) - 1;
438 : :
439 : 0 : nvmf_auth_send_exec(&req);
440 : 0 : CU_ASSERT(g_req_completed);
441 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
442 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
443 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
444 : :
445 : : /* Invalid request length (too small) */
446 : 0 : g_req_completed = false;
447 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
448 : 0 : req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg);
449 : :
450 : 0 : nvmf_auth_send_exec(&req);
451 : 0 : CU_ASSERT(g_req_completed);
452 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
453 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
454 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
455 : :
456 : : /* Invalid request length (too small) */
457 : 0 : g_req_completed = false;
458 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
459 : 0 : req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg) + sizeof(*desc) - 1;
460 : :
461 : 0 : nvmf_auth_send_exec(&req);
462 : 0 : CU_ASSERT(g_req_completed);
463 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
464 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
465 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
466 : :
467 : : /* Invalid request length (too large) */
468 : 0 : g_req_completed = false;
469 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
470 : 0 : req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg) + sizeof(*desc) + 1;
471 : :
472 : 0 : nvmf_auth_send_exec(&req);
473 : 0 : CU_ASSERT(g_req_completed);
474 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
475 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
476 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
477 : 0 : req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg) + sizeof(*desc);
478 : :
479 : : /* No common digests */
480 : 0 : g_req_completed = false;
481 : 0 : auth->digest = -1;
482 : 0 : auth->dhgroup = -1;
483 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
484 : 0 : desc->halen = 1;
485 : 0 : tgt.dhchap_digests = SPDK_BIT(SPDK_NVMF_DHCHAP_HASH_SHA384) |
486 : : SPDK_BIT(SPDK_NVMF_DHCHAP_HASH_SHA512);
487 : :
488 : 0 : nvmf_auth_send_exec(&req);
489 : 0 : CU_ASSERT(g_req_completed);
490 : 0 : CU_ASSERT_EQUAL(auth->digest, -1);
491 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
492 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_HASH_UNUSABLE);
493 : 0 : tgt.dhchap_digests = UINT32_MAX;
494 : 0 : desc->halen = 3;
495 : :
496 : : /* No common dhgroups */
497 : 0 : g_req_completed = false;
498 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
499 : 0 : desc->dhlen = 1;
500 : 0 : tgt.dhchap_dhgroups = SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_2048) |
501 : : SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_3072) |
502 : : SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_4096) |
503 : : SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_6144) |
504 : : SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_8192);
505 : :
506 : 0 : nvmf_auth_send_exec(&req);
507 : 0 : CU_ASSERT(g_req_completed);
508 : 0 : CU_ASSERT_EQUAL(auth->dhgroup, -1);
509 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
510 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_DHGROUP_UNUSABLE);
511 : 0 : tgt.dhchap_dhgroups = UINT32_MAX;
512 : 0 : desc->dhlen = 6;
513 : :
514 : 0 : nvmf_qpair_auth_destroy(&qpair);
515 : 0 : }
516 : :
517 : : static void
518 : 0 : test_auth_timeout(void)
519 : : {
520 : 0 : union nvmf_c2h_msg rsp = {};
521 : 0 : struct spdk_nvmf_subsystem subsys = {};
522 : 0 : struct spdk_nvmf_tgt tgt = { .dhchap_digests = UINT32_MAX, .dhchap_dhgroups = UINT32_MAX };
523 : 0 : struct spdk_nvmf_poll_group group = { .tgt = &tgt };
524 : 0 : struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
525 : 0 : struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr, .group = &group };
526 : 0 : struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
527 : 0 : struct spdk_nvmf_fabric_auth_send_cmd cmd = {};
528 : : struct spdk_nvmf_qpair_auth *auth;
529 : : struct spdk_nvmf_auth_negotiate *msg;
530 : : struct spdk_nvmf_auth_descriptor *desc;
531 : 0 : uint8_t msgbuf[4096];
532 : : int rc;
533 : :
534 : 0 : msg = (void *)msgbuf;
535 : 0 : ut_prep_send_cmd(&req, &cmd, msgbuf, sizeof(*msg) + sizeof(*desc));
536 : 0 : MOCK_SET(spdk_get_ticks_hz, 1000 * 1000);
537 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
538 : :
539 : : /* Check that a timeout is correctly detected and qpair is disconnected */
540 : 0 : rc = nvmf_qpair_auth_init(&qpair);
541 [ # # ]: 0 : SPDK_CU_ASSERT_FATAL(rc == 0);
542 : 0 : MOCK_SET(spdk_get_ticks, NVMF_AUTH_DEFAULT_KATO_US - 1);
543 : 0 : poll_threads();
544 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_AUTHENTICATING);
545 : 0 : MOCK_SET(spdk_get_ticks, NVMF_AUTH_DEFAULT_KATO_US);
546 : 0 : poll_threads();
547 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
548 : 0 : nvmf_qpair_auth_destroy(&qpair);
549 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
550 : 0 : MOCK_SET(spdk_get_ticks, 0);
551 : :
552 : : /* Check a case where a non-zero kato is set in controller features */
553 : 0 : ctrlr.feat.keep_alive_timer.bits.kato = 10 * 1000;
554 : 0 : rc = nvmf_qpair_auth_init(&qpair);
555 [ # # ]: 0 : SPDK_CU_ASSERT_FATAL(rc == 0);
556 : 0 : MOCK_SET(spdk_get_ticks, 10 * 1000 * 1000 - 1);
557 : 0 : poll_threads();
558 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_AUTHENTICATING);
559 : 0 : MOCK_SET(spdk_get_ticks, 10 * 1000 * 1000);
560 : 0 : poll_threads();
561 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
562 : 0 : nvmf_qpair_auth_destroy(&qpair);
563 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
564 : 0 : ctrlr.feat.keep_alive_timer.bits.kato = 0;
565 : 0 : MOCK_SET(spdk_get_ticks, 0);
566 : :
567 : : /* Check that reception of a command rearms the timeout poller */
568 : 0 : rc = nvmf_qpair_auth_init(&qpair);
569 [ # # ]: 0 : SPDK_CU_ASSERT_FATAL(rc == 0);
570 : 0 : auth = qpair.auth;
571 : :
572 : 0 : MOCK_SET(spdk_get_ticks, NVMF_AUTH_DEFAULT_KATO_US / 2);
573 : 0 : g_req_completed = false;
574 : 0 : msg->auth_type = SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE;
575 : 0 : msg->auth_id = SPDK_NVMF_AUTH_ID_NEGOTIATE;
576 : 0 : msg->sc_c = SPDK_NVMF_AUTH_SCC_DISABLED;
577 : 0 : msg->napd = 1;
578 : 0 : desc = &msg->descriptors[0];
579 : 0 : desc->auth_id = SPDK_NVMF_AUTH_TYPE_DHCHAP;
580 : 0 : desc->halen = 1;
581 : 0 : desc->hash_id_list[0] = SPDK_NVMF_DHCHAP_HASH_SHA256;
582 : 0 : desc->dhlen = 1;
583 : 0 : desc->dhg_id_list[0] = SPDK_NVMF_DHCHAP_DHGROUP_NULL;
584 : :
585 : 0 : nvmf_auth_send_exec(&req);
586 : 0 : CU_ASSERT(g_req_completed);
587 : 0 : CU_ASSERT_EQUAL(auth->digest, SPDK_NVMF_DHCHAP_HASH_SHA256);
588 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_CHALLENGE);
589 : :
590 : 0 : MOCK_SET(spdk_get_ticks, NVMF_AUTH_DEFAULT_KATO_US);
591 : 0 : poll_threads();
592 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_AUTHENTICATING);
593 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_CHALLENGE);
594 : :
595 : 0 : MOCK_SET(spdk_get_ticks, NVMF_AUTH_DEFAULT_KATO_US + NVMF_AUTH_DEFAULT_KATO_US / 2);
596 : 0 : poll_threads();
597 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
598 : 0 : nvmf_qpair_auth_destroy(&qpair);
599 : 0 : MOCK_SET(spdk_get_ticks, 0);
600 : 0 : }
601 : :
602 : : static void
603 : 0 : test_auth_failure1(void)
604 : : {
605 : 0 : union nvmf_c2h_msg rsp = {};
606 : 0 : struct spdk_nvmf_subsystem subsys = {};
607 : 0 : struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
608 : 0 : struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr };
609 : 0 : struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
610 : 0 : struct spdk_nvmf_fabric_auth_recv_cmd cmd = {
611 : : .fctype = SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV
612 : : };
613 : 0 : struct spdk_nvme_cpl *cpl = &rsp.nvme_cpl;
614 : : struct spdk_nvmf_qpair_auth *auth;
615 : : struct spdk_nvmf_auth_failure *msg;
616 : 0 : uint8_t msgbuf[sizeof(*msg)];
617 : : int rc;
618 : :
619 : 0 : msg = (void *)msgbuf;
620 : 0 : rc = nvmf_qpair_auth_init(&qpair);
621 [ # # ]: 0 : SPDK_CU_ASSERT_FATAL(rc == 0);
622 : 0 : auth = qpair.auth;
623 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
624 : :
625 : : /* Check failure1 message fields */
626 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
627 : 0 : g_req_completed = false;
628 : 0 : auth->state = NVMF_QPAIR_AUTH_FAILURE1;
629 : 0 : auth->fail_reason = SPDK_NVMF_AUTH_FAILED;
630 : 0 : auth->tid = 8;
631 : :
632 : 0 : nvmf_auth_recv_exec(&req);
633 : 0 : CU_ASSERT(g_req_completed);
634 : 0 : CU_ASSERT_EQUAL(cpl->status.sct, 0);
635 : 0 : CU_ASSERT_EQUAL(cpl->status.sc, 0);
636 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_ERROR);
637 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
638 : 0 : CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
639 : 0 : CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
640 : 0 : CU_ASSERT_EQUAL(msg->t_id, 8);
641 : 0 : CU_ASSERT_EQUAL(msg->rc, SPDK_NVMF_AUTH_FAILURE);
642 : 0 : CU_ASSERT_EQUAL(msg->rce, SPDK_NVMF_AUTH_FAILED);
643 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
644 : :
645 : : /* Do a receive while expecting an auth send command */
646 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
647 : 0 : g_req_completed = false;
648 : 0 : auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
649 : 0 : auth->fail_reason = 0;
650 : :
651 : 0 : nvmf_auth_recv_exec(&req);
652 : 0 : CU_ASSERT(g_req_completed);
653 : 0 : CU_ASSERT_EQUAL(cpl->status.sct, 0);
654 : 0 : CU_ASSERT_EQUAL(cpl->status.sc, 0);
655 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_ERROR);
656 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
657 : 0 : CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
658 : 0 : CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
659 : 0 : CU_ASSERT_EQUAL(msg->t_id, 8);
660 : 0 : CU_ASSERT_EQUAL(msg->rc, SPDK_NVMF_AUTH_FAILURE);
661 : 0 : CU_ASSERT_EQUAL(msg->rce, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
662 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
663 : :
664 : : /* Do a receive but specify a buffer that's too small */
665 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
666 : 0 : g_req_completed = false;
667 : 0 : auth->state = NVMF_QPAIR_AUTH_FAILURE1;
668 : 0 : auth->fail_reason = SPDK_NVMF_AUTH_FAILED;
669 : 0 : req.iov[0].iov_len = cmd.al = req.length = sizeof(*msg) - 1;
670 : :
671 : 0 : nvmf_auth_recv_exec(&req);
672 : 0 : CU_ASSERT(g_req_completed);
673 : 0 : CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
674 : 0 : CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
675 : 0 : CU_ASSERT_EQUAL(cpl->status.dnr, 1);
676 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
677 : 0 : req.iov[0].iov_len = cmd.al = req.length = sizeof(*msg);
678 : :
679 : 0 : nvmf_qpair_auth_destroy(&qpair);
680 : 0 : }
681 : :
682 : : static void
683 : 0 : test_auth_challenge(void)
684 : : {
685 : 0 : union nvmf_c2h_msg rsp = {};
686 : 0 : struct spdk_nvmf_subsystem subsys = { .mutex = PTHREAD_MUTEX_INITIALIZER };
687 : 0 : struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
688 : 0 : struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr };
689 : 0 : struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
690 : 0 : struct spdk_nvmf_fabric_auth_recv_cmd cmd = {
691 : : .fctype = SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV
692 : : };
693 : : struct spdk_nvmf_qpair_auth *auth;
694 : : struct spdk_nvmf_dhchap_challenge *msg;
695 : : struct spdk_nvmf_auth_failure *fail;
696 : 0 : uint8_t msgbuf[4096], cval[4096], dhv[4096];
697 : : int rc;
698 : :
699 : 0 : msg = (void *)msgbuf;
700 : 0 : fail = (void *)msgbuf;
701 : 0 : rc = nvmf_qpair_auth_init(&qpair);
702 [ # # ]: 0 : SPDK_CU_ASSERT_FATAL(rc == 0);
703 : 0 : auth = qpair.auth;
704 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
705 : :
706 : : /* Successfully receive a challenge message */
707 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
708 : 0 : g_req_completed = false;
709 : 0 : auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
710 : 0 : auth->dhgroup = SPDK_NVMF_DHCHAP_DHGROUP_NULL;
711 : 0 : MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
712 : 0 : g_rand_val = 0xa5;
713 : 0 : memset(cval, g_rand_val, sizeof(cval));
714 : 0 : auth->digest = SPDK_NVMF_DHCHAP_HASH_SHA384;
715 : 0 : auth->tid = 8;
716 : :
717 : 0 : nvmf_auth_recv_exec(&req);
718 : 0 : CU_ASSERT(g_req_completed);
719 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_REPLY);
720 : 0 : CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_DHCHAP);
721 : 0 : CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_DHCHAP_CHALLENGE);
722 : 0 : CU_ASSERT_EQUAL(msg->t_id, 8);
723 : 0 : CU_ASSERT_EQUAL(msg->hl, 48);
724 : 0 : CU_ASSERT_EQUAL(msg->hash_id, SPDK_NVMF_DHCHAP_HASH_SHA384);
725 : 0 : CU_ASSERT_EQUAL(msg->dhg_id, SPDK_NVMF_DHCHAP_DHGROUP_NULL);
726 : 0 : CU_ASSERT_EQUAL(msg->dhvlen, 0);
727 : 0 : CU_ASSERT_EQUAL(memcmp(msg->cval, cval, 48), 0);
728 : 0 : CU_ASSERT(msg->seqnum != 0);
729 : :
730 : : /* Successfully receive a challenge message w/ a non-NULL dhgroup */
731 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
732 : 0 : g_req_completed = false;
733 : 0 : auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
734 : 0 : MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
735 : 0 : MOCK_SET(spdk_nvme_dhchap_generate_dhkey, (struct spdk_nvme_dhchap_dhkey *)0xdeadbeef);
736 : 0 : g_rand_val = 0xa5;
737 : 0 : g_dhv = 0xfe;
738 : 0 : g_dhvlen = 256;
739 : 0 : memset(cval, g_rand_val, sizeof(cval));
740 : 0 : memset(dhv, g_dhv, sizeof(dhv));
741 : 0 : auth->digest = SPDK_NVMF_DHCHAP_HASH_SHA384;
742 : 0 : auth->dhgroup = SPDK_NVMF_DHCHAP_DHGROUP_2048;
743 : 0 : auth->tid = 8;
744 : :
745 : 0 : nvmf_auth_recv_exec(&req);
746 : 0 : CU_ASSERT(g_req_completed);
747 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_REPLY);
748 : 0 : CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_DHCHAP);
749 : 0 : CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_DHCHAP_CHALLENGE);
750 : 0 : CU_ASSERT_EQUAL(msg->t_id, 8);
751 : 0 : CU_ASSERT_EQUAL(msg->hl, 48);
752 : 0 : CU_ASSERT_EQUAL(msg->hash_id, SPDK_NVMF_DHCHAP_HASH_SHA384);
753 : 0 : CU_ASSERT_EQUAL(msg->dhg_id, SPDK_NVMF_DHCHAP_DHGROUP_2048);
754 : 0 : CU_ASSERT_EQUAL(msg->dhvlen, g_dhvlen);
755 : 0 : CU_ASSERT_EQUAL(memcmp(msg->cval, cval, 48), 0);
756 : 0 : CU_ASSERT_EQUAL(memcmp(&msg->cval[48], dhv, g_dhvlen), 0);
757 : 0 : CU_ASSERT(msg->seqnum != 0);
758 : :
759 : : /* Check RAND_bytes failure */
760 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
761 : 0 : g_req_completed = false;
762 : 0 : auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
763 : 0 : MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
764 : 0 : auth->digest = SPDK_NVMF_DHCHAP_HASH_SHA384;
765 : 0 : auth->tid = 8;
766 : 0 : MOCK_SET(RAND_bytes, -1);
767 : :
768 : 0 : nvmf_auth_recv_exec(&req);
769 : 0 : CU_ASSERT(g_req_completed);
770 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
771 : 0 : CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
772 : 0 : CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
773 : 0 : CU_ASSERT_EQUAL(fail->t_id, 8);
774 : 0 : CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
775 : 0 : CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_FAILED);
776 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
777 : 0 : MOCK_SET(RAND_bytes, 1);
778 : :
779 : : /* Check spdk_nvme_dhchap_generate_dhkey failure */
780 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
781 : 0 : g_req_completed = false;
782 : 0 : MOCK_SET(spdk_nvme_dhchap_generate_dhkey, NULL);
783 : 0 : auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
784 : 0 : auth->tid = 8;
785 : :
786 : 0 : nvmf_auth_recv_exec(&req);
787 : 0 : CU_ASSERT(g_req_completed);
788 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
789 : 0 : CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
790 : 0 : CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
791 : 0 : CU_ASSERT_EQUAL(fail->t_id, 8);
792 : 0 : CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
793 : 0 : CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_FAILED);
794 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
795 : :
796 : : /* Check spdk_nvme_dhchap_dhkey_get_pubkey failure */
797 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
798 : 0 : g_req_completed = false;
799 : 0 : MOCK_SET(spdk_nvme_dhchap_generate_dhkey, (struct spdk_nvme_dhchap_dhkey *)0xdeadbeef);
800 : 0 : MOCK_SET(spdk_nvme_dhchap_dhkey_get_pubkey, -EIO);
801 : 0 : auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
802 : 0 : auth->tid = 8;
803 : :
804 : 0 : nvmf_auth_recv_exec(&req);
805 : 0 : CU_ASSERT(g_req_completed);
806 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
807 : 0 : CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
808 : 0 : CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
809 : 0 : CU_ASSERT_EQUAL(fail->t_id, 8);
810 : 0 : CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
811 : 0 : CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_FAILED);
812 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
813 : 0 : MOCK_SET(spdk_nvme_dhchap_dhkey_get_pubkey, 0);
814 : :
815 : : /* Check insufficient buffer size */
816 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
817 : 0 : g_req_completed = false;
818 : 0 : auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
819 : 0 : MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
820 : 0 : auth->tid = 8;
821 : 0 : cmd.al = req.length = req.iov[0].iov_len = sizeof(msg) + 47;
822 : :
823 : 0 : nvmf_auth_recv_exec(&req);
824 : 0 : CU_ASSERT(g_req_completed);
825 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
826 : 0 : CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
827 : 0 : CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
828 : 0 : CU_ASSERT_EQUAL(fail->t_id, 8);
829 : 0 : CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
830 : 0 : CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
831 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
832 [ # # # # ]: 0 : MOCK_CLEAR(spdk_nvme_dhchap_get_digest_length);
833 : :
834 : 0 : nvmf_qpair_auth_destroy(&qpair);
835 : 0 : }
836 : :
837 : : static void
838 : 0 : test_auth_reply(void)
839 : : {
840 : 0 : union nvmf_c2h_msg rsp = {};
841 : 0 : struct spdk_nvmf_subsystem subsys = {};
842 : 0 : struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
843 : 0 : struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr };
844 : 0 : struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
845 : 0 : struct spdk_nvmf_fabric_auth_send_cmd cmd = {};
846 : : struct spdk_nvmf_qpair_auth *auth;
847 : : struct spdk_nvmf_dhchap_reply *msg;
848 : 0 : uint8_t hl = 48, msgbuf[4096];
849 : : int rc;
850 : :
851 : 0 : msg = (void *)msgbuf;
852 : 0 : rc = nvmf_qpair_auth_init(&qpair);
853 [ # # ]: 0 : SPDK_CU_ASSERT_FATAL(rc == 0);
854 : 0 : ut_prep_send_cmd(&req, &cmd, msgbuf, sizeof(*msg) + 2 * hl);
855 : 0 : auth = qpair.auth;
856 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
857 : 0 : auth->tid = 8;
858 : :
859 : : /* Execute a reply containing a correct response */
860 : 0 : g_req_completed = false;
861 : 0 : MOCK_SET(nvmf_subsystem_get_dhchap_key, (struct spdk_key *)0xdeadbeef);
862 : 0 : MOCK_SET(spdk_nvme_dhchap_get_digest_length, hl);
863 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
864 : 0 : msg->auth_type = SPDK_NVMF_AUTH_TYPE_DHCHAP;
865 : 0 : msg->auth_id = SPDK_NVMF_AUTH_ID_DHCHAP_REPLY;
866 : 0 : msg->t_id = auth->tid;
867 : 0 : msg->hl = hl;
868 : 0 : msg->cvalid = 0;
869 : 0 : msg->dhvlen = 0;
870 : 0 : msg->seqnum = 0;
871 : 0 : memset(msg->rval, 0xa5, hl);
872 : 0 : g_rval = 0xa5;
873 : :
874 : 0 : nvmf_auth_send_exec(&req);
875 : 0 : CU_ASSERT(g_req_completed);
876 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_SUCCESS1);
877 : :
878 : : /* Execute a reply while not in the REPLY state */
879 : 0 : g_req_completed = false;
880 : 0 : auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
881 : :
882 : 0 : nvmf_auth_send_exec(&req);
883 : 0 : CU_ASSERT(g_req_completed);
884 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
885 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
886 : :
887 : : /* Bad message length (smaller than a base reply message) */
888 : 0 : g_req_completed = false;
889 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
890 : 0 : cmd.tl = req.iov[0].iov_len = req.length = sizeof(*msg) - 1;
891 : :
892 : 0 : nvmf_auth_send_exec(&req);
893 : 0 : CU_ASSERT(g_req_completed);
894 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
895 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
896 : :
897 : : /* Hash length mismatch */
898 : 0 : g_req_completed = false;
899 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
900 : 0 : msg->hl = 32;
901 : :
902 : 0 : nvmf_auth_send_exec(&req);
903 : 0 : CU_ASSERT(g_req_completed);
904 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
905 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
906 : 0 : msg->hl = hl;
907 : :
908 : : /* Bad message length (smaller than size of msg + 2 * hl) */
909 : 0 : g_req_completed = false;
910 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
911 : 0 : cmd.tl = req.iov[0].iov_len = req.length = sizeof(*msg) + 2 * hl - 1;
912 : :
913 : 0 : nvmf_auth_send_exec(&req);
914 : 0 : CU_ASSERT(g_req_completed);
915 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
916 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
917 : 0 : cmd.tl = req.iov[0].iov_len = req.length = sizeof(*msg) + hl;
918 : :
919 : : /* Bad message length (larger than size of msg + 2 * hl) */
920 : 0 : g_req_completed = false;
921 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
922 : 0 : cmd.tl = req.iov[0].iov_len = req.length = sizeof(*msg) + 2 * hl + 1;
923 : :
924 : 0 : nvmf_auth_send_exec(&req);
925 : 0 : CU_ASSERT(g_req_completed);
926 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
927 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
928 : 0 : cmd.tl = req.iov[0].iov_len = req.length = sizeof(*msg) + 2 * hl;
929 : :
930 : : /* Transaction ID mismatch */
931 : 0 : g_req_completed = false;
932 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
933 : 0 : msg->t_id = auth->tid + 1;
934 : :
935 : 0 : nvmf_auth_send_exec(&req);
936 : 0 : CU_ASSERT(g_req_completed);
937 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
938 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
939 : 0 : msg->t_id = auth->tid;
940 : :
941 : : /* Bad cvalid value */
942 : 0 : g_req_completed = false;
943 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
944 : 0 : msg->cvalid = 1;
945 : :
946 : 0 : nvmf_auth_send_exec(&req);
947 : 0 : CU_ASSERT(g_req_completed);
948 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
949 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
950 : 0 : msg->cvalid = 0;
951 : :
952 : : /* Bad dhvlen (non-zero) */
953 : 0 : g_req_completed = false;
954 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
955 : 0 : msg->dhvlen = 1;
956 : :
957 : 0 : nvmf_auth_send_exec(&req);
958 : 0 : CU_ASSERT(g_req_completed);
959 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
960 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
961 : 0 : msg->dhvlen = 0;
962 : :
963 : : /* Failure to get the key */
964 : 0 : g_req_completed = false;
965 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
966 : 0 : MOCK_SET(nvmf_subsystem_get_dhchap_key, NULL);
967 : :
968 : 0 : nvmf_auth_send_exec(&req);
969 : 0 : CU_ASSERT(g_req_completed);
970 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
971 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
972 : 0 : MOCK_SET(nvmf_subsystem_get_dhchap_key, (struct spdk_key *)0xdeadbeef);
973 : :
974 : : /* Calculation failure */
975 : 0 : g_req_completed = false;
976 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
977 : 0 : MOCK_SET(spdk_nvme_dhchap_calculate, -EPERM);
978 : :
979 : 0 : nvmf_auth_send_exec(&req);
980 : 0 : CU_ASSERT(g_req_completed);
981 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
982 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
983 : 0 : MOCK_SET(spdk_nvme_dhchap_calculate, 0);
984 : :
985 : : /* Response mismatch */
986 : 0 : g_req_completed = false;
987 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
988 : 0 : g_rval = 0x5a;
989 : :
990 : 0 : nvmf_auth_send_exec(&req);
991 : 0 : CU_ASSERT(g_req_completed);
992 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
993 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
994 : 0 : g_rval = 0xa5;
995 : :
996 : : /* DH secret derivation failure */
997 : 0 : g_req_completed = false;
998 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
999 : 0 : auth->dhgroup = SPDK_NVMF_DHCHAP_DHGROUP_2048;
1000 : 0 : MOCK_SET(spdk_nvme_dhchap_dhkey_derive_secret, -EIO);
1001 : :
1002 : 0 : nvmf_auth_send_exec(&req);
1003 : 0 : CU_ASSERT(g_req_completed);
1004 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
1005 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
1006 : 0 : MOCK_SET(spdk_nvme_dhchap_dhkey_derive_secret, 0);
1007 : :
1008 : : /* Bad cvalid value */
1009 : 0 : g_req_completed = false;
1010 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
1011 : 0 : msg->cvalid = 2;
1012 : :
1013 : 0 : nvmf_auth_send_exec(&req);
1014 : 0 : CU_ASSERT(g_req_completed);
1015 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
1016 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
1017 : :
1018 : : /* Bad cvalid/seqnum combination */
1019 : 0 : g_req_completed = false;
1020 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
1021 : 0 : msg->cvalid = 1;
1022 : 0 : msg->seqnum = 0;
1023 : :
1024 : 0 : nvmf_auth_send_exec(&req);
1025 : 0 : CU_ASSERT(g_req_completed);
1026 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
1027 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
1028 : :
1029 : : /* Missing controller key */
1030 : 0 : g_req_completed = false;
1031 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
1032 : 0 : msg->cvalid = 1;
1033 : 0 : msg->seqnum = 1;
1034 : 0 : MOCK_ENQUEUE(nvmf_subsystem_get_dhchap_key, (struct spdk_key *)0xdeadbeef);
1035 : 0 : MOCK_ENQUEUE(nvmf_subsystem_get_dhchap_key, NULL);
1036 : :
1037 : 0 : nvmf_auth_send_exec(&req);
1038 : 0 : CU_ASSERT(g_req_completed);
1039 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
1040 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
1041 : :
1042 : : /* Controller challange calcuation failure */
1043 : 0 : g_req_completed = false;
1044 : 0 : auth->state = NVMF_QPAIR_AUTH_REPLY;
1045 : 0 : msg->cvalid = 1;
1046 : 0 : msg->seqnum = 1;
1047 : 0 : MOCK_ENQUEUE(spdk_nvme_dhchap_calculate, 0);
1048 : 0 : MOCK_ENQUEUE(spdk_nvme_dhchap_calculate, -EIO);
1049 : :
1050 : 0 : nvmf_auth_send_exec(&req);
1051 : 0 : CU_ASSERT(g_req_completed);
1052 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
1053 : 0 : CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
1054 : :
1055 : 0 : nvmf_qpair_auth_destroy(&qpair);
1056 : 0 : }
1057 : :
1058 : : static void
1059 : 0 : test_auth_success1(void)
1060 : : {
1061 : 0 : union nvmf_c2h_msg rsp = {};
1062 : 0 : struct spdk_nvmf_subsystem subsys = {};
1063 : 0 : struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
1064 : 0 : struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr };
1065 : 0 : struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
1066 : 0 : struct spdk_nvmf_fabric_auth_recv_cmd cmd = {
1067 : : .fctype = SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV
1068 : : };
1069 : : struct spdk_nvmf_qpair_auth *auth;
1070 : : struct spdk_nvmf_dhchap_success1 *msg;
1071 : : struct spdk_nvmf_auth_failure *fail;
1072 : 0 : uint8_t msgbuf[sizeof(*msg) + 48];
1073 : : int rc;
1074 : :
1075 : 0 : msg = (void *)msgbuf;
1076 : 0 : fail = (void *)msgbuf;
1077 : 0 : rc = nvmf_qpair_auth_init(&qpair);
1078 [ # # ]: 0 : SPDK_CU_ASSERT_FATAL(rc == 0);
1079 : 0 : auth = qpair.auth;
1080 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
1081 : 0 : auth->tid = 8;
1082 : :
1083 : : /* Successfully receive a success message */
1084 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
1085 : 0 : g_req_completed = false;
1086 : 0 : auth->state = NVMF_QPAIR_AUTH_SUCCESS1;
1087 : :
1088 : 0 : nvmf_auth_recv_exec(&req);
1089 : 0 : CU_ASSERT(g_req_completed);
1090 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_COMPLETED);
1091 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ENABLED);
1092 : 0 : CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_DHCHAP);
1093 : 0 : CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_DHCHAP_SUCCESS1);
1094 : 0 : CU_ASSERT_EQUAL(msg->t_id, 8);
1095 : 0 : CU_ASSERT_EQUAL(msg->hl, 48);
1096 : 0 : CU_ASSERT_EQUAL(msg->rvalid, 0);
1097 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
1098 : :
1099 : : /* Successfully receive a success message w/ bidirectional authentication */
1100 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg) + 48);
1101 : 0 : g_req_completed = false;
1102 : 0 : auth->state = NVMF_QPAIR_AUTH_SUCCESS1;
1103 : 0 : auth->cvalid = true;
1104 : 0 : memset(auth->cval, 0xa5, 48);
1105 : 0 : MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
1106 : :
1107 : 0 : nvmf_auth_recv_exec(&req);
1108 : 0 : CU_ASSERT(g_req_completed);
1109 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_SUCCESS2);
1110 : 0 : CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_DHCHAP);
1111 : 0 : CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_DHCHAP_SUCCESS1);
1112 : 0 : CU_ASSERT_EQUAL(msg->t_id, 8);
1113 : 0 : CU_ASSERT_EQUAL(msg->hl, 48);
1114 : 0 : CU_ASSERT_EQUAL(msg->rvalid, 1);
1115 : 0 : CU_ASSERT_EQUAL(memcmp(msg->rval, auth->cval, 48), 0);
1116 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
1117 : 0 : auth->cvalid = false;
1118 : :
1119 : : /* Bad message length (smaller than success1 message) */
1120 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
1121 : 0 : g_req_completed = false;
1122 : 0 : auth->state = NVMF_QPAIR_AUTH_SUCCESS1;
1123 : 0 : cmd.al = req.iov[0].iov_len = req.length = sizeof(*msg) - 1;
1124 : :
1125 : 0 : nvmf_auth_recv_exec(&req);
1126 : 0 : CU_ASSERT(g_req_completed);
1127 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_ERROR);
1128 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
1129 : 0 : CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
1130 : 0 : CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
1131 : 0 : CU_ASSERT_EQUAL(fail->t_id, 8);
1132 : 0 : CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
1133 : 0 : CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
1134 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
1135 : :
1136 : : /* Bad message length (smaller than msg + hl) */
1137 : 0 : ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
1138 : 0 : g_req_completed = false;
1139 : 0 : auth->state = NVMF_QPAIR_AUTH_SUCCESS1;
1140 : 0 : auth->cvalid = true;
1141 : 0 : MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
1142 : 0 : cmd.al = req.iov[0].iov_len = req.length = sizeof(*msg) + 47;
1143 : :
1144 : 0 : nvmf_auth_recv_exec(&req);
1145 : 0 : CU_ASSERT(g_req_completed);
1146 : 0 : CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_ERROR);
1147 : 0 : CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
1148 : 0 : CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
1149 : 0 : CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
1150 : 0 : CU_ASSERT_EQUAL(fail->t_id, 8);
1151 : 0 : CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
1152 : 0 : CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
1153 : 0 : qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
1154 : 0 : auth->cvalid = false;
1155 : 0 : cmd.al = req.iov[0].iov_len = req.length = sizeof(*msg);
1156 : :
1157 : 0 : nvmf_qpair_auth_destroy(&qpair);
1158 : 0 : }
1159 : :
1160 : : int
1161 : 0 : main(int argc, char **argv)
1162 : : {
1163 : 0 : CU_pSuite suite = NULL;
1164 : : unsigned int num_failures;
1165 : :
1166 : 0 : CU_initialize_registry();
1167 : 0 : suite = CU_add_suite("nvmf_auth", NULL, NULL);
1168 : 0 : CU_ADD_TEST(suite, test_auth_send_recv_error);
1169 : 0 : CU_ADD_TEST(suite, test_auth_negotiate);
1170 : 0 : CU_ADD_TEST(suite, test_auth_timeout);
1171 : 0 : CU_ADD_TEST(suite, test_auth_failure1);
1172 : 0 : CU_ADD_TEST(suite, test_auth_challenge);
1173 : 0 : CU_ADD_TEST(suite, test_auth_reply);
1174 : 0 : CU_ADD_TEST(suite, test_auth_success1);
1175 : :
1176 : 0 : allocate_threads(1);
1177 : 0 : set_thread(0);
1178 : :
1179 : 0 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
1180 : 0 : CU_cleanup_registry();
1181 : :
1182 : 0 : free_threads();
1183 : :
1184 : 0 : return num_failures;
1185 : : }
|