xref: /spdk/test/unit/lib/nvmf/auth.c/auth_ut.c (revision fdd8cea261be5993a90a3de125823bd0807ee09a)
17b0bd881SKonrad Sztyber /* SPDX-License-Identifier: BSD-3-Clause
27b0bd881SKonrad Sztyber  * Copyright (c) 2024 Intel Corporation. All rights reserved.
37b0bd881SKonrad Sztyber  */
47b0bd881SKonrad Sztyber #include "spdk/stdinc.h"
57b0bd881SKonrad Sztyber 
67b0bd881SKonrad Sztyber #include "spdk_internal/cunit.h"
77b0bd881SKonrad Sztyber #include "spdk_internal/mock.h"
87b0bd881SKonrad Sztyber 
97b0bd881SKonrad Sztyber #include "common/lib/ut_multithread.c"
108e817b0cSKonrad Sztyber #include "unit/lib/json_mock.c"
117b0bd881SKonrad Sztyber #include "nvmf/auth.c"
127b0bd881SKonrad Sztyber 
137b0bd881SKonrad Sztyber DEFINE_STUB(spdk_nvme_dhchap_get_digest_name, const char *, (int d), NULL);
147b0bd881SKonrad Sztyber DEFINE_STUB(spdk_nvme_dhchap_get_dhgroup_name, const char *, (int d), NULL);
152c8f9257SKonrad Sztyber DEFINE_STUB(spdk_nvme_dhchap_get_digest_length, uint8_t, (int d), 0);
16f0bf11dbSKonrad Sztyber DEFINE_STUB_V(spdk_keyring_put_key, (struct spdk_key *k));
17f0bf11dbSKonrad Sztyber DEFINE_STUB(nvmf_subsystem_get_dhchap_key, struct spdk_key *,
18e622de2cSKonrad Sztyber 	    (struct spdk_nvmf_subsystem *s, const char *h, enum nvmf_auth_key_type t), NULL);
195b83ef1cSKonrad Sztyber DEFINE_STUB(spdk_nvme_dhchap_generate_dhkey, struct spdk_nvme_dhchap_dhkey *,
205b83ef1cSKonrad Sztyber 	    (enum spdk_nvmf_dhchap_dhgroup dhgroup), NULL);
215b83ef1cSKonrad Sztyber DEFINE_STUB_V(spdk_nvme_dhchap_dhkey_free, (struct spdk_nvme_dhchap_dhkey **key));
225b83ef1cSKonrad Sztyber DEFINE_STUB(spdk_nvme_dhchap_dhkey_derive_secret, int,
235b83ef1cSKonrad Sztyber 	    (struct spdk_nvme_dhchap_dhkey *key, const void *peer, size_t peerlen, void *secret,
245b83ef1cSKonrad Sztyber 	     size_t *seclen), 0);
252c8f9257SKonrad Sztyber DECLARE_WRAPPER(RAND_bytes, int, (unsigned char *buf, int num));
262c8f9257SKonrad Sztyber 
272c8f9257SKonrad Sztyber static uint8_t g_rand_val;
28985ef53aSKonrad Sztyber DEFINE_WRAPPER_MOCK(RAND_bytes, int) = 1;
292c8f9257SKonrad Sztyber 
302c8f9257SKonrad Sztyber int
312c8f9257SKonrad Sztyber __wrap_RAND_bytes(unsigned char *buf, int num)
322c8f9257SKonrad Sztyber {
332c8f9257SKonrad Sztyber 	memset(buf, g_rand_val, num);
342c8f9257SKonrad Sztyber 	return MOCK_GET(RAND_bytes);
352c8f9257SKonrad Sztyber }
36c54a29d8SKonrad Sztyber 
37eb267841SKonrad Sztyber void
38eb267841SKonrad Sztyber nvmf_qpair_set_state(struct spdk_nvmf_qpair *qpair, enum spdk_nvmf_qpair_state state)
39eb267841SKonrad Sztyber {
40eb267841SKonrad Sztyber 	qpair->state = state;
41eb267841SKonrad Sztyber }
42eb267841SKonrad Sztyber 
43c54a29d8SKonrad Sztyber int
44c54a29d8SKonrad Sztyber spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair)
45c54a29d8SKonrad Sztyber {
46eb267841SKonrad Sztyber 	nvmf_qpair_set_state(qpair, SPDK_NVMF_QPAIR_ERROR);
47c54a29d8SKonrad Sztyber 	return 0;
48c54a29d8SKonrad Sztyber }
497b0bd881SKonrad Sztyber 
507b0bd881SKonrad Sztyber static bool g_req_completed;
517b0bd881SKonrad Sztyber 
527b0bd881SKonrad Sztyber int
537b0bd881SKonrad Sztyber spdk_nvmf_request_complete(struct spdk_nvmf_request *req)
547b0bd881SKonrad Sztyber {
557b0bd881SKonrad Sztyber 	g_req_completed = true;
567b0bd881SKonrad Sztyber 	return 0;
577b0bd881SKonrad Sztyber }
587b0bd881SKonrad Sztyber 
59f0bf11dbSKonrad Sztyber static uint8_t g_rval;
60f0bf11dbSKonrad Sztyber DEFINE_RETURN_MOCK(spdk_nvme_dhchap_calculate, int);
61f0bf11dbSKonrad Sztyber 
62f0bf11dbSKonrad Sztyber int
63f0bf11dbSKonrad Sztyber spdk_nvme_dhchap_calculate(struct spdk_key *key, enum spdk_nvmf_dhchap_hash hash,
64f0bf11dbSKonrad Sztyber 			   const char *type, uint32_t seq, uint16_t tid, uint8_t scc,
65f0bf11dbSKonrad Sztyber 			   const char *nqn1, const char *nqn2, const void *dhkey, size_t dhlen,
66f0bf11dbSKonrad Sztyber 			   const void *cval, void *rval)
67f0bf11dbSKonrad Sztyber {
68f0bf11dbSKonrad Sztyber 	memset(rval, g_rval, spdk_nvme_dhchap_get_digest_length(hash));
69f0bf11dbSKonrad Sztyber 	return MOCK_GET(spdk_nvme_dhchap_calculate);
70f0bf11dbSKonrad Sztyber }
71f0bf11dbSKonrad Sztyber 
725b83ef1cSKonrad Sztyber static uint8_t g_dhv;
735b83ef1cSKonrad Sztyber static size_t g_dhvlen;
745b83ef1cSKonrad Sztyber DEFINE_RETURN_MOCK(spdk_nvme_dhchap_dhkey_get_pubkey, int);
755b83ef1cSKonrad Sztyber 
765b83ef1cSKonrad Sztyber int
775b83ef1cSKonrad Sztyber spdk_nvme_dhchap_dhkey_get_pubkey(struct spdk_nvme_dhchap_dhkey *dhkey, void *pub, size_t *len)
785b83ef1cSKonrad Sztyber {
795b83ef1cSKonrad Sztyber 	int rc;
805b83ef1cSKonrad Sztyber 
815b83ef1cSKonrad Sztyber 	rc = MOCK_GET(spdk_nvme_dhchap_dhkey_get_pubkey);
825b83ef1cSKonrad Sztyber 	if (rc != 0) {
835b83ef1cSKonrad Sztyber 		return rc;
845b83ef1cSKonrad Sztyber 	}
855b83ef1cSKonrad Sztyber 
865b83ef1cSKonrad Sztyber 	SPDK_CU_ASSERT_FATAL(*len >= g_dhvlen);
875b83ef1cSKonrad Sztyber 	memset(pub, g_dhv, g_dhvlen);
885b83ef1cSKonrad Sztyber 	*len = g_dhvlen;
895b83ef1cSKonrad Sztyber 
905b83ef1cSKonrad Sztyber 	return rc;
915b83ef1cSKonrad Sztyber }
925b83ef1cSKonrad Sztyber 
937b0bd881SKonrad Sztyber static void
947b0bd881SKonrad Sztyber ut_clear_resp(struct spdk_nvmf_request *req)
957b0bd881SKonrad Sztyber {
967b0bd881SKonrad Sztyber 	memset(&req->rsp->nvme_cpl, 0, sizeof(req->rsp->nvme_cpl));
977b0bd881SKonrad Sztyber }
987b0bd881SKonrad Sztyber 
997b0bd881SKonrad Sztyber #define ut_prep_cmd(_req, _cmd, _buf, _len, _lfield)		\
1007b0bd881SKonrad Sztyber 	do {							\
1017b0bd881SKonrad Sztyber 		(_req)->cmd = (void *)_cmd;			\
1027b0bd881SKonrad Sztyber 		(_req)->iov[0].iov_base = _buf;			\
1037b0bd881SKonrad Sztyber 		(_req)->iov[0].iov_len = _len;			\
1047b0bd881SKonrad Sztyber 		(_req)->iovcnt = 1;				\
1057b0bd881SKonrad Sztyber 		(_req)->length = _len;				\
1067b0bd881SKonrad Sztyber 		(_cmd)->secp = SPDK_NVMF_AUTH_SECP_NVME;	\
1077b0bd881SKonrad Sztyber 		(_cmd)->spsp0 = 1;				\
1087b0bd881SKonrad Sztyber 		(_cmd)->spsp1 = 1;				\
1097b0bd881SKonrad Sztyber 		(_cmd)->_lfield = _len;				\
1107b0bd881SKonrad Sztyber 	} while (0)
1117b0bd881SKonrad Sztyber 
1127b0bd881SKonrad Sztyber #define ut_prep_send_cmd(req, cmd, buf, len) ut_prep_cmd(req, cmd, buf, len, tl)
1137b0bd881SKonrad Sztyber #define ut_prep_recv_cmd(req, cmd, buf, len) ut_prep_cmd(req, cmd, buf, len, al)
1147b0bd881SKonrad Sztyber 
1157b0bd881SKonrad Sztyber static void
1167b0bd881SKonrad Sztyber test_auth_send_recv_error(void)
1177b0bd881SKonrad Sztyber {
1187b0bd881SKonrad Sztyber 	union nvmf_c2h_msg rsp = {};
1197b0bd881SKonrad Sztyber 	struct spdk_nvmf_subsystem subsys = {};
1207b0bd881SKonrad Sztyber 	struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
1217b0bd881SKonrad Sztyber 	struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr };
1227b0bd881SKonrad Sztyber 	struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
1237b0bd881SKonrad Sztyber 	struct spdk_nvme_cpl *cpl = &rsp.nvme_cpl;
1247b0bd881SKonrad Sztyber 	struct spdk_nvmf_fabric_auth_send_cmd send_cmd = {};
1257b0bd881SKonrad Sztyber 	struct spdk_nvmf_fabric_auth_recv_cmd recv_cmd = {};
126b2dcccf3SKonrad Sztyber 	struct spdk_nvmf_qpair_auth *auth;
1277b0bd881SKonrad Sztyber 	int rc;
1287b0bd881SKonrad Sztyber 
1297b0bd881SKonrad Sztyber 	rc = nvmf_qpair_auth_init(&qpair);
1307b0bd881SKonrad Sztyber 	SPDK_CU_ASSERT_FATAL(rc == 0);
1317b0bd881SKonrad Sztyber 	ut_prep_send_cmd(&req, &send_cmd, NULL, 255);
1327b0bd881SKonrad Sztyber 	ut_prep_recv_cmd(&req, &recv_cmd, NULL, 255);
133b2dcccf3SKonrad Sztyber 	auth = qpair.auth;
1347b0bd881SKonrad Sztyber 
1357b0bd881SKonrad Sztyber 	/* Bad secp (send) */
1367b0bd881SKonrad Sztyber 	g_req_completed = false;
1377b0bd881SKonrad Sztyber 	req.cmd = (void *)&send_cmd;
1387b0bd881SKonrad Sztyber 	ut_clear_resp(&req);
1397b0bd881SKonrad Sztyber 	send_cmd.secp = SPDK_NVMF_AUTH_SECP_NVME + 1;
1407b0bd881SKonrad Sztyber 
1417b0bd881SKonrad Sztyber 	nvmf_auth_send_exec(&req);
1427b0bd881SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1437b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
1447b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
1457b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.dnr, 1);
1467b0bd881SKonrad Sztyber 	send_cmd.secp = SPDK_NVMF_AUTH_SECP_NVME;
1477b0bd881SKonrad Sztyber 
1487b0bd881SKonrad Sztyber 	/* Bad secp (recv) */
1497b0bd881SKonrad Sztyber 	g_req_completed = false;
1507b0bd881SKonrad Sztyber 	req.cmd = (void *)&recv_cmd;
1517b0bd881SKonrad Sztyber 	ut_clear_resp(&req);
1527b0bd881SKonrad Sztyber 	recv_cmd.secp = SPDK_NVMF_AUTH_SECP_NVME + 1;
1537b0bd881SKonrad Sztyber 
1547b0bd881SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
1557b0bd881SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1567b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
1577b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
1587b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.dnr, 1);
1597b0bd881SKonrad Sztyber 	recv_cmd.secp = SPDK_NVMF_AUTH_SECP_NVME;
1607b0bd881SKonrad Sztyber 
1617b0bd881SKonrad Sztyber 	/* Bad spsp0 (send) */
1627b0bd881SKonrad Sztyber 	g_req_completed = false;
1637b0bd881SKonrad Sztyber 	req.cmd = (void *)&send_cmd;
1647b0bd881SKonrad Sztyber 	ut_clear_resp(&req);
1657b0bd881SKonrad Sztyber 	send_cmd.spsp0 = 2;
1667b0bd881SKonrad Sztyber 
1677b0bd881SKonrad Sztyber 	nvmf_auth_send_exec(&req);
1687b0bd881SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1697b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
1707b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
1717b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.dnr, 1);
1727b0bd881SKonrad Sztyber 	send_cmd.spsp0 = 1;
1737b0bd881SKonrad Sztyber 
1747b0bd881SKonrad Sztyber 	/* Bad spsp0 (recv) */
1757b0bd881SKonrad Sztyber 	g_req_completed = false;
1767b0bd881SKonrad Sztyber 	req.cmd = (void *)&recv_cmd;
1777b0bd881SKonrad Sztyber 	ut_clear_resp(&req);
1787b0bd881SKonrad Sztyber 	recv_cmd.spsp0 = 2;
1797b0bd881SKonrad Sztyber 
1807b0bd881SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
1817b0bd881SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1827b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
1837b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
1847b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.dnr, 1);
1857b0bd881SKonrad Sztyber 	recv_cmd.spsp0 = 1;
1867b0bd881SKonrad Sztyber 
1877b0bd881SKonrad Sztyber 	/* Bad spsp1 (send) */
1887b0bd881SKonrad Sztyber 	g_req_completed = false;
1897b0bd881SKonrad Sztyber 	req.cmd = (void *)&send_cmd;
1907b0bd881SKonrad Sztyber 	ut_clear_resp(&req);
1917b0bd881SKonrad Sztyber 	send_cmd.spsp1 = 2;
1927b0bd881SKonrad Sztyber 
1937b0bd881SKonrad Sztyber 	nvmf_auth_send_exec(&req);
1947b0bd881SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1957b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
1967b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
1977b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.dnr, 1);
1987b0bd881SKonrad Sztyber 	send_cmd.spsp1 = 1;
1997b0bd881SKonrad Sztyber 
2007b0bd881SKonrad Sztyber 	/* Bad spsp1 (recv) */
2017b0bd881SKonrad Sztyber 	g_req_completed = false;
2027b0bd881SKonrad Sztyber 	req.cmd = (void *)&recv_cmd;
2037b0bd881SKonrad Sztyber 	ut_clear_resp(&req);
2047b0bd881SKonrad Sztyber 	recv_cmd.spsp1 = 2;
2057b0bd881SKonrad Sztyber 
2067b0bd881SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
2077b0bd881SKonrad Sztyber 	CU_ASSERT(g_req_completed);
2087b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
2097b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
2107b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.dnr, 1);
2117b0bd881SKonrad Sztyber 	recv_cmd.spsp1 = 1;
2127b0bd881SKonrad Sztyber 
2137b0bd881SKonrad Sztyber 	/* Bad length (send) */
2147b0bd881SKonrad Sztyber 	g_req_completed = false;
2157b0bd881SKonrad Sztyber 	req.cmd = (void *)&send_cmd;
2167b0bd881SKonrad Sztyber 	ut_clear_resp(&req);
2177b0bd881SKonrad Sztyber 	send_cmd.tl = req.length + 1;
2187b0bd881SKonrad Sztyber 
2197b0bd881SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
2207b0bd881SKonrad Sztyber 	CU_ASSERT(g_req_completed);
2217b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
2227b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
2237b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.dnr, 1);
2247b0bd881SKonrad Sztyber 	send_cmd.tl = req.length;
2257b0bd881SKonrad Sztyber 
2267b0bd881SKonrad Sztyber 	/* Bad length (recv) */
2277b0bd881SKonrad Sztyber 	g_req_completed = false;
2287b0bd881SKonrad Sztyber 	req.cmd = (void *)&recv_cmd;
2297b0bd881SKonrad Sztyber 	ut_clear_resp(&req);
2307b0bd881SKonrad Sztyber 	recv_cmd.al = req.length - 1;
2317b0bd881SKonrad Sztyber 
2327b0bd881SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
2337b0bd881SKonrad Sztyber 	CU_ASSERT(g_req_completed);
2347b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
2357b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
2367b0bd881SKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.dnr, 1);
2377b0bd881SKonrad Sztyber 	recv_cmd.al = req.length;
2387b0bd881SKonrad Sztyber 
239b2dcccf3SKonrad Sztyber 	/* Bad length (smaller than common header) */
240b2dcccf3SKonrad Sztyber 	g_req_completed = false;
241b2dcccf3SKonrad Sztyber 	req.cmd = (union nvmf_h2c_msg *)&send_cmd;
242b2dcccf3SKonrad Sztyber 	ut_clear_resp(&req);
243b2dcccf3SKonrad Sztyber 	send_cmd.tl = req.length = sizeof(struct nvmf_auth_common_header) - 1;
244b2dcccf3SKonrad Sztyber 
245b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
246b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
247b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
248b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
249b2dcccf3SKonrad Sztyber 	send_cmd.tl = req.length = 255;
250b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
251b2dcccf3SKonrad Sztyber 	auth->fail_reason = 0;
252b2dcccf3SKonrad Sztyber 
253b2dcccf3SKonrad Sztyber 	nvmf_qpair_auth_destroy(&qpair);
254b2dcccf3SKonrad Sztyber }
255b2dcccf3SKonrad Sztyber 
256b2dcccf3SKonrad Sztyber static void
257b2dcccf3SKonrad Sztyber test_auth_negotiate(void)
258b2dcccf3SKonrad Sztyber {
259b2dcccf3SKonrad Sztyber 	union nvmf_c2h_msg rsp = {};
260b2dcccf3SKonrad Sztyber 	struct spdk_nvmf_subsystem subsys = {};
26100a557f2SKonrad Sztyber 	struct spdk_nvmf_tgt tgt = { .dhchap_digests = UINT32_MAX, .dhchap_dhgroups = UINT32_MAX };
26200a557f2SKonrad Sztyber 	struct spdk_nvmf_poll_group group = { .tgt = &tgt };
263b2dcccf3SKonrad Sztyber 	struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
26400a557f2SKonrad Sztyber 	struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr, .group = &group };
265b2dcccf3SKonrad Sztyber 	struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
266b2dcccf3SKonrad Sztyber 	struct spdk_nvmf_fabric_auth_send_cmd cmd = {};
267b2dcccf3SKonrad Sztyber 	struct spdk_nvmf_qpair_auth *auth;
268b2dcccf3SKonrad Sztyber 	struct spdk_nvmf_auth_negotiate *msg;
269b2dcccf3SKonrad Sztyber 	struct spdk_nvmf_auth_descriptor *desc;
270b2dcccf3SKonrad Sztyber 	uint8_t msgbuf[4096];
271b2dcccf3SKonrad Sztyber 	int rc;
272b2dcccf3SKonrad Sztyber 
273b2dcccf3SKonrad Sztyber 	msg = (void *)msgbuf;
274b2dcccf3SKonrad Sztyber 	rc = nvmf_qpair_auth_init(&qpair);
275b2dcccf3SKonrad Sztyber 	SPDK_CU_ASSERT_FATAL(rc == 0);
276b2dcccf3SKonrad Sztyber 	ut_prep_send_cmd(&req, &cmd, msgbuf, sizeof(*msg) + sizeof(*desc));
277b2dcccf3SKonrad Sztyber 	auth = qpair.auth;
278b2dcccf3SKonrad Sztyber 
279b2dcccf3SKonrad Sztyber 	/* Successful negotiation */
280b2dcccf3SKonrad Sztyber 	g_req_completed = false;
281b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
282b2dcccf3SKonrad Sztyber 	msg->auth_type = SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE;
283b2dcccf3SKonrad Sztyber 	msg->auth_id = SPDK_NVMF_AUTH_ID_NEGOTIATE;
284b2dcccf3SKonrad Sztyber 	msg->sc_c = SPDK_NVMF_AUTH_SCC_DISABLED;
285b2dcccf3SKonrad Sztyber 	msg->napd = 1;
286b2dcccf3SKonrad Sztyber 	desc = &msg->descriptors[0];
287b2dcccf3SKonrad Sztyber 	desc->auth_id = SPDK_NVMF_AUTH_TYPE_DHCHAP;
288b2dcccf3SKonrad Sztyber 	desc->halen = 3;
289b2dcccf3SKonrad Sztyber 	desc->hash_id_list[0] = SPDK_NVMF_DHCHAP_HASH_SHA256;
290b2dcccf3SKonrad Sztyber 	desc->hash_id_list[1] = SPDK_NVMF_DHCHAP_HASH_SHA384;
291b2dcccf3SKonrad Sztyber 	desc->hash_id_list[2] = SPDK_NVMF_DHCHAP_HASH_SHA512;
292b2dcccf3SKonrad Sztyber 	desc->dhlen = 6;
293b2dcccf3SKonrad Sztyber 	desc->dhg_id_list[0] = SPDK_NVMF_DHCHAP_DHGROUP_NULL;
294b2dcccf3SKonrad Sztyber 	desc->dhg_id_list[1] = SPDK_NVMF_DHCHAP_DHGROUP_2048;
295b2dcccf3SKonrad Sztyber 	desc->dhg_id_list[2] = SPDK_NVMF_DHCHAP_DHGROUP_3072;
296b2dcccf3SKonrad Sztyber 	desc->dhg_id_list[3] = SPDK_NVMF_DHCHAP_DHGROUP_4096;
297b2dcccf3SKonrad Sztyber 	desc->dhg_id_list[4] = SPDK_NVMF_DHCHAP_DHGROUP_6144;
298b2dcccf3SKonrad Sztyber 	desc->dhg_id_list[5] = SPDK_NVMF_DHCHAP_DHGROUP_8192;
299b2dcccf3SKonrad Sztyber 
300b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
301b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
302b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, SPDK_NVMF_DHCHAP_HASH_SHA512);
3035b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->dhgroup, SPDK_NVMF_DHCHAP_DHGROUP_8192);
304b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_CHALLENGE);
305b2dcccf3SKonrad Sztyber 
306b2dcccf3SKonrad Sztyber 	/* Invalid auth state */
307b2dcccf3SKonrad Sztyber 	g_req_completed = false;
308b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_ERROR;
309b2dcccf3SKonrad Sztyber 	auth->digest = -1;
310b2dcccf3SKonrad Sztyber 
311b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
312b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
313b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
314b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
315b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
316b2dcccf3SKonrad Sztyber 
317b2dcccf3SKonrad Sztyber 	/* scc mismatch */
318b2dcccf3SKonrad Sztyber 	g_req_completed = false;
319b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
320b2dcccf3SKonrad Sztyber 	msg->sc_c = SPDK_NVMF_AUTH_SCC_TLS;
321b2dcccf3SKonrad Sztyber 
322b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
323b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
324b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
325b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
326b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_SCC_MISMATCH);
327b2dcccf3SKonrad Sztyber 	msg->sc_c = SPDK_NVMF_AUTH_SCC_DISABLED;
328b2dcccf3SKonrad Sztyber 
329b2dcccf3SKonrad Sztyber 	/* Missing DH-HMAC-CHAP protocol (napd=0) */
330b2dcccf3SKonrad Sztyber 	g_req_completed = false;
331b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
332b2dcccf3SKonrad Sztyber 	req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg);
333b2dcccf3SKonrad Sztyber 	msg->napd = 0;
334b2dcccf3SKonrad Sztyber 
335b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
336b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
337b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
338b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
339b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_PROTOCOL_UNUSABLE);
340b2dcccf3SKonrad Sztyber 	req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg) + sizeof(*desc);
341b2dcccf3SKonrad Sztyber 	msg->napd = 1;
342b2dcccf3SKonrad Sztyber 
343b2dcccf3SKonrad Sztyber 	/* Missing DH-HMAC-CHAP protocol */
344b2dcccf3SKonrad Sztyber 	g_req_completed = false;
345b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
346b2dcccf3SKonrad Sztyber 	desc->auth_id = SPDK_NVMF_AUTH_TYPE_DHCHAP + 1;
347b2dcccf3SKonrad Sztyber 
348b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
349b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
350b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
351b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
352b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_PROTOCOL_UNUSABLE);
353b2dcccf3SKonrad Sztyber 	desc->auth_id = SPDK_NVMF_AUTH_TYPE_DHCHAP;
354b2dcccf3SKonrad Sztyber 
355b2dcccf3SKonrad Sztyber 	/* No valid digests (halen=0) */
356b2dcccf3SKonrad Sztyber 	g_req_completed = false;
357b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
358b2dcccf3SKonrad Sztyber 	desc->halen = 0;
359b2dcccf3SKonrad Sztyber 
360b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
361b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
362b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
363b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
364b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_HASH_UNUSABLE);
365b2dcccf3SKonrad Sztyber 
366b2dcccf3SKonrad Sztyber 	/* No valid digests */
367b2dcccf3SKonrad Sztyber 	g_req_completed = false;
368b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
369b2dcccf3SKonrad Sztyber 	desc->hash_id_list[0] = SPDK_NVMF_DHCHAP_HASH_SHA512 + 1;
370b2dcccf3SKonrad Sztyber 	desc->hash_id_list[1] = SPDK_NVMF_DHCHAP_HASH_SHA512 + 2;
371b2dcccf3SKonrad Sztyber 	desc->hash_id_list[2] = SPDK_NVMF_DHCHAP_HASH_SHA512 + 3;
372b2dcccf3SKonrad Sztyber 	desc->halen = 3;
373b2dcccf3SKonrad Sztyber 
374b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
375b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
376b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
377b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
378b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_HASH_UNUSABLE);
379b2dcccf3SKonrad Sztyber 	desc->hash_id_list[0] = SPDK_NVMF_DHCHAP_HASH_SHA256;
380b2dcccf3SKonrad Sztyber 	desc->hash_id_list[1] = SPDK_NVMF_DHCHAP_HASH_SHA384;
381b2dcccf3SKonrad Sztyber 	desc->hash_id_list[2] = SPDK_NVMF_DHCHAP_HASH_SHA512;
382b2dcccf3SKonrad Sztyber 
383b2dcccf3SKonrad Sztyber 	/* No valid dhgroups (dhlen=0) */
384b2dcccf3SKonrad Sztyber 	g_req_completed = false;
385b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
386b2dcccf3SKonrad Sztyber 	desc->dhlen = 0;
387b2dcccf3SKonrad Sztyber 
388b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
389b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
390b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
391b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
392b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_DHGROUP_UNUSABLE);
393b2dcccf3SKonrad Sztyber 
394b2dcccf3SKonrad Sztyber 	/* No valid dhgroups */
395b2dcccf3SKonrad Sztyber 	g_req_completed = false;
396b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
397b2dcccf3SKonrad Sztyber 	desc->dhlen = 2;
398b2dcccf3SKonrad Sztyber 	desc->dhg_id_list[0] = SPDK_NVMF_DHCHAP_DHGROUP_8192 + 1;
399b2dcccf3SKonrad Sztyber 	desc->dhg_id_list[1] = SPDK_NVMF_DHCHAP_DHGROUP_8192 + 2;
400b2dcccf3SKonrad Sztyber 
401b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
402b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
403b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
404b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
405b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_DHGROUP_UNUSABLE);
406b2dcccf3SKonrad Sztyber 	desc->dhg_id_list[0] = SPDK_NVMF_DHCHAP_DHGROUP_NULL;
407b2dcccf3SKonrad Sztyber 	desc->dhg_id_list[1] = SPDK_NVMF_DHCHAP_DHGROUP_2048;
408b2dcccf3SKonrad Sztyber 	desc->dhlen = 6;
409b2dcccf3SKonrad Sztyber 
410b2dcccf3SKonrad Sztyber 	/* Bad halen value */
411b2dcccf3SKonrad Sztyber 	g_req_completed = false;
412b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
413b2dcccf3SKonrad Sztyber 	desc->halen = 255;
414b2dcccf3SKonrad Sztyber 
415b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
416b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
417b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
418b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
419b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
420b2dcccf3SKonrad Sztyber 	desc->halen = 3;
421b2dcccf3SKonrad Sztyber 
422b2dcccf3SKonrad Sztyber 	/* Bad dhlen value */
423b2dcccf3SKonrad Sztyber 	g_req_completed = false;
424b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
425b2dcccf3SKonrad Sztyber 	desc->dhlen = 255;
426b2dcccf3SKonrad Sztyber 
427b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
428b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
429b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
430b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
431b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
432b2dcccf3SKonrad Sztyber 	desc->dhlen = 6;
433b2dcccf3SKonrad Sztyber 
434b2dcccf3SKonrad Sztyber 	/* Invalid request length (too small) */
435b2dcccf3SKonrad Sztyber 	g_req_completed = false;
436b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
437b2dcccf3SKonrad Sztyber 	req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg) - 1;
438b2dcccf3SKonrad Sztyber 
439b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
440b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
441b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
442b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
443b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
444b2dcccf3SKonrad Sztyber 
445b2dcccf3SKonrad Sztyber 	/* Invalid request length (too small) */
446b2dcccf3SKonrad Sztyber 	g_req_completed = false;
447b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
448b2dcccf3SKonrad Sztyber 	req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg);
449b2dcccf3SKonrad Sztyber 
450b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
451b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
452b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
453b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
454b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
455b2dcccf3SKonrad Sztyber 
456b2dcccf3SKonrad Sztyber 	/* Invalid request length (too small) */
457b2dcccf3SKonrad Sztyber 	g_req_completed = false;
458b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
459b2dcccf3SKonrad Sztyber 	req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg) + sizeof(*desc) - 1;
460b2dcccf3SKonrad Sztyber 
461b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
462b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
463b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
464b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
465b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
466b2dcccf3SKonrad Sztyber 
467b2dcccf3SKonrad Sztyber 	/* Invalid request length (too large) */
468b2dcccf3SKonrad Sztyber 	g_req_completed = false;
469b2dcccf3SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
470b2dcccf3SKonrad Sztyber 	req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg) + sizeof(*desc) + 1;
471b2dcccf3SKonrad Sztyber 
472b2dcccf3SKonrad Sztyber 	nvmf_auth_send_exec(&req);
473b2dcccf3SKonrad Sztyber 	CU_ASSERT(g_req_completed);
474b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
475b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
476b2dcccf3SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
477b2dcccf3SKonrad Sztyber 	req.length = cmd.tl = req.iov[0].iov_len = sizeof(*msg) + sizeof(*desc);
478b2dcccf3SKonrad Sztyber 
47900a557f2SKonrad Sztyber 	/* No common digests */
48000a557f2SKonrad Sztyber 	g_req_completed = false;
48100a557f2SKonrad Sztyber 	auth->digest = -1;
48200a557f2SKonrad Sztyber 	auth->dhgroup = -1;
48300a557f2SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
48400a557f2SKonrad Sztyber 	desc->halen = 1;
48500a557f2SKonrad Sztyber 	tgt.dhchap_digests = SPDK_BIT(SPDK_NVMF_DHCHAP_HASH_SHA384) |
48600a557f2SKonrad Sztyber 			     SPDK_BIT(SPDK_NVMF_DHCHAP_HASH_SHA512);
48700a557f2SKonrad Sztyber 
48800a557f2SKonrad Sztyber 	nvmf_auth_send_exec(&req);
48900a557f2SKonrad Sztyber 	CU_ASSERT(g_req_completed);
49000a557f2SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, -1);
49100a557f2SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
49200a557f2SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_HASH_UNUSABLE);
49300a557f2SKonrad Sztyber 	tgt.dhchap_digests = UINT32_MAX;
49400a557f2SKonrad Sztyber 	desc->halen = 3;
49500a557f2SKonrad Sztyber 
49600a557f2SKonrad Sztyber 	/* No common dhgroups */
49700a557f2SKonrad Sztyber 	g_req_completed = false;
49800a557f2SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
49900a557f2SKonrad Sztyber 	desc->dhlen = 1;
50000a557f2SKonrad Sztyber 	tgt.dhchap_dhgroups = SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_2048) |
50100a557f2SKonrad Sztyber 			      SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_3072) |
50200a557f2SKonrad Sztyber 			      SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_4096) |
50300a557f2SKonrad Sztyber 			      SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_6144) |
50400a557f2SKonrad Sztyber 			      SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_8192);
50500a557f2SKonrad Sztyber 
50600a557f2SKonrad Sztyber 	nvmf_auth_send_exec(&req);
50700a557f2SKonrad Sztyber 	CU_ASSERT(g_req_completed);
50800a557f2SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->dhgroup, -1);
50900a557f2SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
51000a557f2SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_DHGROUP_UNUSABLE);
51100a557f2SKonrad Sztyber 	tgt.dhchap_dhgroups = UINT32_MAX;
51200a557f2SKonrad Sztyber 	desc->dhlen = 6;
51300a557f2SKonrad Sztyber 
5147b0bd881SKonrad Sztyber 	nvmf_qpair_auth_destroy(&qpair);
5157b0bd881SKonrad Sztyber }
5167b0bd881SKonrad Sztyber 
517c54a29d8SKonrad Sztyber static void
518c54a29d8SKonrad Sztyber test_auth_timeout(void)
519c54a29d8SKonrad Sztyber {
520c54a29d8SKonrad Sztyber 	union nvmf_c2h_msg rsp = {};
521c54a29d8SKonrad Sztyber 	struct spdk_nvmf_subsystem subsys = {};
52200a557f2SKonrad Sztyber 	struct spdk_nvmf_tgt tgt = { .dhchap_digests = UINT32_MAX, .dhchap_dhgroups = UINT32_MAX };
52300a557f2SKonrad Sztyber 	struct spdk_nvmf_poll_group group = { .tgt = &tgt };
524c54a29d8SKonrad Sztyber 	struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
52500a557f2SKonrad Sztyber 	struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr, .group = &group };
526c54a29d8SKonrad Sztyber 	struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
527c54a29d8SKonrad Sztyber 	struct spdk_nvmf_fabric_auth_send_cmd cmd = {};
528c54a29d8SKonrad Sztyber 	struct spdk_nvmf_qpair_auth *auth;
529c54a29d8SKonrad Sztyber 	struct spdk_nvmf_auth_negotiate *msg;
530c54a29d8SKonrad Sztyber 	struct spdk_nvmf_auth_descriptor *desc;
531c54a29d8SKonrad Sztyber 	uint8_t msgbuf[4096];
532c54a29d8SKonrad Sztyber 	int rc;
533c54a29d8SKonrad Sztyber 
534c54a29d8SKonrad Sztyber 	msg = (void *)msgbuf;
535c54a29d8SKonrad Sztyber 	ut_prep_send_cmd(&req, &cmd, msgbuf, sizeof(*msg) + sizeof(*desc));
536c54a29d8SKonrad Sztyber 	MOCK_SET(spdk_get_ticks_hz, 1000 * 1000);
537c54a29d8SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
538c54a29d8SKonrad Sztyber 
539c54a29d8SKonrad Sztyber 	/* Check that a timeout is correctly detected and qpair is disconnected */
540c54a29d8SKonrad Sztyber 	rc = nvmf_qpair_auth_init(&qpair);
541c54a29d8SKonrad Sztyber 	SPDK_CU_ASSERT_FATAL(rc == 0);
542c54a29d8SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, NVMF_AUTH_DEFAULT_KATO_US - 1);
543c54a29d8SKonrad Sztyber 	poll_threads();
544c54a29d8SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_AUTHENTICATING);
545c54a29d8SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, NVMF_AUTH_DEFAULT_KATO_US);
546c54a29d8SKonrad Sztyber 	poll_threads();
547c54a29d8SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
548c54a29d8SKonrad Sztyber 	nvmf_qpair_auth_destroy(&qpair);
549c54a29d8SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
550c54a29d8SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, 0);
551c54a29d8SKonrad Sztyber 
552c54a29d8SKonrad Sztyber 	/* Check a case where a non-zero kato is set in controller features */
553c54a29d8SKonrad Sztyber 	ctrlr.feat.keep_alive_timer.bits.kato = 10 * 1000;
554c54a29d8SKonrad Sztyber 	rc = nvmf_qpair_auth_init(&qpair);
555c54a29d8SKonrad Sztyber 	SPDK_CU_ASSERT_FATAL(rc == 0);
556c54a29d8SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, 10 * 1000 * 1000 - 1);
557c54a29d8SKonrad Sztyber 	poll_threads();
558c54a29d8SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_AUTHENTICATING);
559c54a29d8SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, 10 * 1000 * 1000);
560c54a29d8SKonrad Sztyber 	poll_threads();
561c54a29d8SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
562c54a29d8SKonrad Sztyber 	nvmf_qpair_auth_destroy(&qpair);
563c54a29d8SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
564c54a29d8SKonrad Sztyber 	ctrlr.feat.keep_alive_timer.bits.kato = 0;
565c54a29d8SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, 0);
566c54a29d8SKonrad Sztyber 
567c54a29d8SKonrad Sztyber 	/* Check that reception of a command rearms the timeout poller */
568c54a29d8SKonrad Sztyber 	rc = nvmf_qpair_auth_init(&qpair);
569c54a29d8SKonrad Sztyber 	SPDK_CU_ASSERT_FATAL(rc == 0);
570c54a29d8SKonrad Sztyber 	auth = qpair.auth;
571c54a29d8SKonrad Sztyber 
572c54a29d8SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, NVMF_AUTH_DEFAULT_KATO_US / 2);
573c54a29d8SKonrad Sztyber 	g_req_completed = false;
574c54a29d8SKonrad Sztyber 	msg->auth_type = SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE;
575c54a29d8SKonrad Sztyber 	msg->auth_id = SPDK_NVMF_AUTH_ID_NEGOTIATE;
576c54a29d8SKonrad Sztyber 	msg->sc_c = SPDK_NVMF_AUTH_SCC_DISABLED;
577c54a29d8SKonrad Sztyber 	msg->napd = 1;
578c54a29d8SKonrad Sztyber 	desc = &msg->descriptors[0];
579c54a29d8SKonrad Sztyber 	desc->auth_id = SPDK_NVMF_AUTH_TYPE_DHCHAP;
580c54a29d8SKonrad Sztyber 	desc->halen = 1;
581c54a29d8SKonrad Sztyber 	desc->hash_id_list[0] = SPDK_NVMF_DHCHAP_HASH_SHA256;
582c54a29d8SKonrad Sztyber 	desc->dhlen = 1;
583c54a29d8SKonrad Sztyber 	desc->dhg_id_list[0] = SPDK_NVMF_DHCHAP_DHGROUP_NULL;
584c54a29d8SKonrad Sztyber 
585c54a29d8SKonrad Sztyber 	nvmf_auth_send_exec(&req);
586c54a29d8SKonrad Sztyber 	CU_ASSERT(g_req_completed);
587c54a29d8SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->digest, SPDK_NVMF_DHCHAP_HASH_SHA256);
588c54a29d8SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_CHALLENGE);
589c54a29d8SKonrad Sztyber 
590c54a29d8SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, NVMF_AUTH_DEFAULT_KATO_US);
591c54a29d8SKonrad Sztyber 	poll_threads();
592c54a29d8SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_AUTHENTICATING);
593c54a29d8SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_CHALLENGE);
594c54a29d8SKonrad Sztyber 
595c54a29d8SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, NVMF_AUTH_DEFAULT_KATO_US + NVMF_AUTH_DEFAULT_KATO_US / 2);
596c54a29d8SKonrad Sztyber 	poll_threads();
597c54a29d8SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
598c54a29d8SKonrad Sztyber 	nvmf_qpair_auth_destroy(&qpair);
599c54a29d8SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, 0);
600*fdd8cea2SKonrad Sztyber 
601*fdd8cea2SKonrad Sztyber 	/* Check that a timeout during reauthentication doesn't disconnect the qpair, but only
602*fdd8cea2SKonrad Sztyber 	 * resets the state of the authentication */
603*fdd8cea2SKonrad Sztyber 	rc = nvmf_qpair_auth_init(&qpair);
604*fdd8cea2SKonrad Sztyber 	SPDK_CU_ASSERT_FATAL(rc == 0);
605*fdd8cea2SKonrad Sztyber 	auth = qpair.auth;
606*fdd8cea2SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
607*fdd8cea2SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_ENABLED;
608*fdd8cea2SKonrad Sztyber 
609*fdd8cea2SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, NVMF_AUTH_DEFAULT_KATO_US);
610*fdd8cea2SKonrad Sztyber 	poll_threads();
611*fdd8cea2SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ENABLED);
612*fdd8cea2SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_COMPLETED);
613*fdd8cea2SKonrad Sztyber 	nvmf_qpair_auth_destroy(&qpair);
614*fdd8cea2SKonrad Sztyber 	MOCK_SET(spdk_get_ticks, 0);
615c54a29d8SKonrad Sztyber }
616c54a29d8SKonrad Sztyber 
61767ab645cSKonrad Sztyber static void
61867ab645cSKonrad Sztyber test_auth_failure1(void)
61967ab645cSKonrad Sztyber {
62067ab645cSKonrad Sztyber 	union nvmf_c2h_msg rsp = {};
62167ab645cSKonrad Sztyber 	struct spdk_nvmf_subsystem subsys = {};
62267ab645cSKonrad Sztyber 	struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
62367ab645cSKonrad Sztyber 	struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr };
62467ab645cSKonrad Sztyber 	struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
62567ab645cSKonrad Sztyber 	struct spdk_nvmf_fabric_auth_recv_cmd cmd = {
62667ab645cSKonrad Sztyber 		.fctype = SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV
62767ab645cSKonrad Sztyber 	};
62867ab645cSKonrad Sztyber 	struct spdk_nvme_cpl *cpl = &rsp.nvme_cpl;
62967ab645cSKonrad Sztyber 	struct spdk_nvmf_qpair_auth *auth;
63067ab645cSKonrad Sztyber 	struct spdk_nvmf_auth_failure *msg;
63167ab645cSKonrad Sztyber 	uint8_t msgbuf[sizeof(*msg)];
63267ab645cSKonrad Sztyber 	int rc;
63367ab645cSKonrad Sztyber 
63467ab645cSKonrad Sztyber 	msg = (void *)msgbuf;
63567ab645cSKonrad Sztyber 	rc = nvmf_qpair_auth_init(&qpair);
63667ab645cSKonrad Sztyber 	SPDK_CU_ASSERT_FATAL(rc == 0);
63767ab645cSKonrad Sztyber 	auth = qpair.auth;
63867ab645cSKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
63967ab645cSKonrad Sztyber 
64067ab645cSKonrad Sztyber 	/* Check failure1 message fields */
64167ab645cSKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
64267ab645cSKonrad Sztyber 	g_req_completed = false;
64367ab645cSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_FAILURE1;
64467ab645cSKonrad Sztyber 	auth->fail_reason = SPDK_NVMF_AUTH_FAILED;
64567ab645cSKonrad Sztyber 	auth->tid = 8;
64667ab645cSKonrad Sztyber 
64767ab645cSKonrad Sztyber 	nvmf_auth_recv_exec(&req);
64867ab645cSKonrad Sztyber 	CU_ASSERT(g_req_completed);
64967ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sct, 0);
65067ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sc, 0);
65167ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_ERROR);
65267ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
65367ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
65467ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
65567ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->t_id, 8);
65667ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->rc, SPDK_NVMF_AUTH_FAILURE);
65767ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->rce, SPDK_NVMF_AUTH_FAILED);
65867ab645cSKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
65967ab645cSKonrad Sztyber 
66067ab645cSKonrad Sztyber 	/* Do a receive while expecting an auth send command */
66167ab645cSKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
66267ab645cSKonrad Sztyber 	g_req_completed = false;
66367ab645cSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_NEGOTIATE;
66467ab645cSKonrad Sztyber 	auth->fail_reason = 0;
66567ab645cSKonrad Sztyber 
66667ab645cSKonrad Sztyber 	nvmf_auth_recv_exec(&req);
66767ab645cSKonrad Sztyber 	CU_ASSERT(g_req_completed);
66867ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sct, 0);
66967ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sc, 0);
67067ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_ERROR);
67167ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
67267ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
67367ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
67467ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->t_id, 8);
67567ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->rc, SPDK_NVMF_AUTH_FAILURE);
67667ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->rce, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
67767ab645cSKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
67867ab645cSKonrad Sztyber 
67967ab645cSKonrad Sztyber 	/* Do a receive but specify a buffer that's too small */
68067ab645cSKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
68167ab645cSKonrad Sztyber 	g_req_completed = false;
68267ab645cSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_FAILURE1;
68367ab645cSKonrad Sztyber 	auth->fail_reason = SPDK_NVMF_AUTH_FAILED;
68467ab645cSKonrad Sztyber 	req.iov[0].iov_len = cmd.al = req.length = sizeof(*msg) - 1;
68567ab645cSKonrad Sztyber 
68667ab645cSKonrad Sztyber 	nvmf_auth_recv_exec(&req);
68767ab645cSKonrad Sztyber 	CU_ASSERT(g_req_completed);
68867ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sct, SPDK_NVME_SCT_GENERIC);
68967ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.sc, SPDK_NVME_SC_INVALID_FIELD);
69067ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(cpl->status.dnr, 1);
69167ab645cSKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
69267ab645cSKonrad Sztyber 	req.iov[0].iov_len = cmd.al = req.length = sizeof(*msg);
69367ab645cSKonrad Sztyber 
69467ab645cSKonrad Sztyber 	nvmf_qpair_auth_destroy(&qpair);
69567ab645cSKonrad Sztyber }
69667ab645cSKonrad Sztyber 
6972c8f9257SKonrad Sztyber static void
6982c8f9257SKonrad Sztyber test_auth_challenge(void)
6992c8f9257SKonrad Sztyber {
7002c8f9257SKonrad Sztyber 	union nvmf_c2h_msg rsp = {};
7012c8f9257SKonrad Sztyber 	struct spdk_nvmf_subsystem subsys = { .mutex = PTHREAD_MUTEX_INITIALIZER };
7022c8f9257SKonrad Sztyber 	struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
7032c8f9257SKonrad Sztyber 	struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr };
7042c8f9257SKonrad Sztyber 	struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
7052c8f9257SKonrad Sztyber 	struct spdk_nvmf_fabric_auth_recv_cmd cmd = {
7062c8f9257SKonrad Sztyber 		.fctype = SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV
7072c8f9257SKonrad Sztyber 	};
7082c8f9257SKonrad Sztyber 	struct spdk_nvmf_qpair_auth *auth;
7092c8f9257SKonrad Sztyber 	struct spdk_nvmf_dhchap_challenge *msg;
7102c8f9257SKonrad Sztyber 	struct spdk_nvmf_auth_failure *fail;
7115b83ef1cSKonrad Sztyber 	uint8_t msgbuf[4096], cval[4096], dhv[4096];
7122c8f9257SKonrad Sztyber 	int rc;
7132c8f9257SKonrad Sztyber 
7142c8f9257SKonrad Sztyber 	msg = (void *)msgbuf;
7152c8f9257SKonrad Sztyber 	fail = (void *)msgbuf;
7162c8f9257SKonrad Sztyber 	rc = nvmf_qpair_auth_init(&qpair);
7172c8f9257SKonrad Sztyber 	SPDK_CU_ASSERT_FATAL(rc == 0);
7182c8f9257SKonrad Sztyber 	auth = qpair.auth;
7192c8f9257SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
7202c8f9257SKonrad Sztyber 
7212c8f9257SKonrad Sztyber 	/* Successfully receive a challenge message */
7222c8f9257SKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
7232c8f9257SKonrad Sztyber 	g_req_completed = false;
7242c8f9257SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
7255b83ef1cSKonrad Sztyber 	auth->dhgroup = SPDK_NVMF_DHCHAP_DHGROUP_NULL;
7262c8f9257SKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
7272c8f9257SKonrad Sztyber 	g_rand_val = 0xa5;
7282c8f9257SKonrad Sztyber 	memset(cval, g_rand_val, sizeof(cval));
7292c8f9257SKonrad Sztyber 	auth->digest = SPDK_NVMF_DHCHAP_HASH_SHA384;
7302c8f9257SKonrad Sztyber 	auth->tid = 8;
7312c8f9257SKonrad Sztyber 
7322c8f9257SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
7332c8f9257SKonrad Sztyber 	CU_ASSERT(g_req_completed);
7342c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_REPLY);
7352c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_DHCHAP);
7362c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_DHCHAP_CHALLENGE);
7372c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->t_id, 8);
7382c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->hl, 48);
7392c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->hash_id, SPDK_NVMF_DHCHAP_HASH_SHA384);
7402c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->dhg_id, SPDK_NVMF_DHCHAP_DHGROUP_NULL);
7412c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->dhvlen, 0);
7422c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(memcmp(msg->cval, cval, 48), 0);
7432c8f9257SKonrad Sztyber 	CU_ASSERT(msg->seqnum != 0);
7442c8f9257SKonrad Sztyber 
7455b83ef1cSKonrad Sztyber 	/* Successfully receive a challenge message w/ a non-NULL dhgroup */
7465b83ef1cSKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
7475b83ef1cSKonrad Sztyber 	g_req_completed = false;
7485b83ef1cSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
7495b83ef1cSKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
7505b83ef1cSKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_generate_dhkey, (struct spdk_nvme_dhchap_dhkey *)0xdeadbeef);
7515b83ef1cSKonrad Sztyber 	g_rand_val = 0xa5;
7525b83ef1cSKonrad Sztyber 	g_dhv = 0xfe;
7535b83ef1cSKonrad Sztyber 	g_dhvlen = 256;
7545b83ef1cSKonrad Sztyber 	memset(cval, g_rand_val, sizeof(cval));
7555b83ef1cSKonrad Sztyber 	memset(dhv, g_dhv, sizeof(dhv));
7565b83ef1cSKonrad Sztyber 	auth->digest = SPDK_NVMF_DHCHAP_HASH_SHA384;
7575b83ef1cSKonrad Sztyber 	auth->dhgroup = SPDK_NVMF_DHCHAP_DHGROUP_2048;
7585b83ef1cSKonrad Sztyber 	auth->tid = 8;
7595b83ef1cSKonrad Sztyber 
7605b83ef1cSKonrad Sztyber 	nvmf_auth_recv_exec(&req);
7615b83ef1cSKonrad Sztyber 	CU_ASSERT(g_req_completed);
7625b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_REPLY);
7635b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_DHCHAP);
7645b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_DHCHAP_CHALLENGE);
7655b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->t_id, 8);
7665b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->hl, 48);
7675b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->hash_id, SPDK_NVMF_DHCHAP_HASH_SHA384);
7685b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->dhg_id, SPDK_NVMF_DHCHAP_DHGROUP_2048);
7695b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(msg->dhvlen, g_dhvlen);
7705b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(memcmp(msg->cval, cval, 48), 0);
7715b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(memcmp(&msg->cval[48], dhv, g_dhvlen), 0);
7725b83ef1cSKonrad Sztyber 	CU_ASSERT(msg->seqnum != 0);
7735b83ef1cSKonrad Sztyber 
7742c8f9257SKonrad Sztyber 	/* Check RAND_bytes failure */
7752c8f9257SKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
7762c8f9257SKonrad Sztyber 	g_req_completed = false;
7772c8f9257SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
7782c8f9257SKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
7792c8f9257SKonrad Sztyber 	auth->digest = SPDK_NVMF_DHCHAP_HASH_SHA384;
7802c8f9257SKonrad Sztyber 	auth->tid = 8;
7812c8f9257SKonrad Sztyber 	MOCK_SET(RAND_bytes, -1);
7822c8f9257SKonrad Sztyber 
7832c8f9257SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
7842c8f9257SKonrad Sztyber 	CU_ASSERT(g_req_completed);
7852c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
7862c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
7872c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
7882c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->t_id, 8);
7892c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
7902c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_FAILED);
7912c8f9257SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
7922c8f9257SKonrad Sztyber 	MOCK_SET(RAND_bytes, 1);
7932c8f9257SKonrad Sztyber 
7945b83ef1cSKonrad Sztyber 	/* Check spdk_nvme_dhchap_generate_dhkey failure */
7955b83ef1cSKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
7965b83ef1cSKonrad Sztyber 	g_req_completed = false;
7975b83ef1cSKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_generate_dhkey, NULL);
7985b83ef1cSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
7995b83ef1cSKonrad Sztyber 	auth->tid = 8;
8005b83ef1cSKonrad Sztyber 
8015b83ef1cSKonrad Sztyber 	nvmf_auth_recv_exec(&req);
8025b83ef1cSKonrad Sztyber 	CU_ASSERT(g_req_completed);
8035b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
8045b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
8055b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
8065b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(fail->t_id, 8);
8075b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
8085b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_FAILED);
8095b83ef1cSKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
8105b83ef1cSKonrad Sztyber 
8115b83ef1cSKonrad Sztyber 	/* Check spdk_nvme_dhchap_dhkey_get_pubkey failure */
8125b83ef1cSKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
8135b83ef1cSKonrad Sztyber 	g_req_completed = false;
8145b83ef1cSKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_generate_dhkey, (struct spdk_nvme_dhchap_dhkey *)0xdeadbeef);
8155b83ef1cSKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_dhkey_get_pubkey, -EIO);
8165b83ef1cSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
8175b83ef1cSKonrad Sztyber 	auth->tid = 8;
8185b83ef1cSKonrad Sztyber 
8195b83ef1cSKonrad Sztyber 	nvmf_auth_recv_exec(&req);
8205b83ef1cSKonrad Sztyber 	CU_ASSERT(g_req_completed);
8215b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
8225b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
8235b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
8245b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(fail->t_id, 8);
8255b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
8265b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_FAILED);
8275b83ef1cSKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
8285b83ef1cSKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_dhkey_get_pubkey, 0);
8295b83ef1cSKonrad Sztyber 
8302c8f9257SKonrad Sztyber 	/* Check insufficient buffer size */
8312c8f9257SKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(msgbuf));
8322c8f9257SKonrad Sztyber 	g_req_completed = false;
8332c8f9257SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
8342c8f9257SKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
8352c8f9257SKonrad Sztyber 	auth->tid = 8;
8362c8f9257SKonrad Sztyber 	cmd.al = req.length = req.iov[0].iov_len = sizeof(msg) + 47;
8372c8f9257SKonrad Sztyber 
8382c8f9257SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
8392c8f9257SKonrad Sztyber 	CU_ASSERT(g_req_completed);
8402c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
8412c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
8422c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
8432c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->t_id, 8);
8442c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
8452c8f9257SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
8462c8f9257SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
8472c8f9257SKonrad Sztyber 	MOCK_CLEAR(spdk_nvme_dhchap_get_digest_length);
8482c8f9257SKonrad Sztyber 
8492c8f9257SKonrad Sztyber 	nvmf_qpair_auth_destroy(&qpair);
8502c8f9257SKonrad Sztyber }
8512c8f9257SKonrad Sztyber 
852f0bf11dbSKonrad Sztyber static void
853f0bf11dbSKonrad Sztyber test_auth_reply(void)
854f0bf11dbSKonrad Sztyber {
855f0bf11dbSKonrad Sztyber 	union nvmf_c2h_msg rsp = {};
856f0bf11dbSKonrad Sztyber 	struct spdk_nvmf_subsystem subsys = {};
857f0bf11dbSKonrad Sztyber 	struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
858f0bf11dbSKonrad Sztyber 	struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr };
859f0bf11dbSKonrad Sztyber 	struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
860f0bf11dbSKonrad Sztyber 	struct spdk_nvmf_fabric_auth_send_cmd cmd = {};
861f0bf11dbSKonrad Sztyber 	struct spdk_nvmf_qpair_auth *auth;
862f0bf11dbSKonrad Sztyber 	struct spdk_nvmf_dhchap_reply *msg;
863f0bf11dbSKonrad Sztyber 	uint8_t hl = 48, msgbuf[4096];
864f0bf11dbSKonrad Sztyber 	int rc;
865f0bf11dbSKonrad Sztyber 
866f0bf11dbSKonrad Sztyber 	msg = (void *)msgbuf;
867f0bf11dbSKonrad Sztyber 	rc = nvmf_qpair_auth_init(&qpair);
868f0bf11dbSKonrad Sztyber 	SPDK_CU_ASSERT_FATAL(rc == 0);
869f0bf11dbSKonrad Sztyber 	ut_prep_send_cmd(&req, &cmd, msgbuf, sizeof(*msg) + 2 * hl);
870f0bf11dbSKonrad Sztyber 	auth = qpair.auth;
871f0bf11dbSKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
872f0bf11dbSKonrad Sztyber 	auth->tid = 8;
873f0bf11dbSKonrad Sztyber 
874f0bf11dbSKonrad Sztyber 	/* Execute a reply containing a correct response */
875f0bf11dbSKonrad Sztyber 	g_req_completed = false;
876f0bf11dbSKonrad Sztyber 	MOCK_SET(nvmf_subsystem_get_dhchap_key, (struct spdk_key *)0xdeadbeef);
877f0bf11dbSKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_get_digest_length, hl);
878f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
879f0bf11dbSKonrad Sztyber 	msg->auth_type = SPDK_NVMF_AUTH_TYPE_DHCHAP;
880f0bf11dbSKonrad Sztyber 	msg->auth_id = SPDK_NVMF_AUTH_ID_DHCHAP_REPLY;
881f0bf11dbSKonrad Sztyber 	msg->t_id = auth->tid;
882f0bf11dbSKonrad Sztyber 	msg->hl = hl;
883f0bf11dbSKonrad Sztyber 	msg->cvalid = 0;
884f0bf11dbSKonrad Sztyber 	msg->dhvlen = 0;
885f0bf11dbSKonrad Sztyber 	msg->seqnum = 0;
886f0bf11dbSKonrad Sztyber 	memset(msg->rval, 0xa5, hl);
887f0bf11dbSKonrad Sztyber 	g_rval = 0xa5;
888f0bf11dbSKonrad Sztyber 
889f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
890f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
891f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_SUCCESS1);
892f0bf11dbSKonrad Sztyber 
893f0bf11dbSKonrad Sztyber 	/* Execute a reply while not in the REPLY state */
894f0bf11dbSKonrad Sztyber 	g_req_completed = false;
895f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_CHALLENGE;
896f0bf11dbSKonrad Sztyber 
897f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
898f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
899f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
900f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
901f0bf11dbSKonrad Sztyber 
902f0bf11dbSKonrad Sztyber 	/* Bad message length (smaller than a base reply message) */
903f0bf11dbSKonrad Sztyber 	g_req_completed = false;
904f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
905f0bf11dbSKonrad Sztyber 	cmd.tl = req.iov[0].iov_len = req.length = sizeof(*msg) - 1;
906f0bf11dbSKonrad Sztyber 
907f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
908f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
909f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
910f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
911f0bf11dbSKonrad Sztyber 
912f0bf11dbSKonrad Sztyber 	/* Hash length mismatch */
913f0bf11dbSKonrad Sztyber 	g_req_completed = false;
914f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
915f0bf11dbSKonrad Sztyber 	msg->hl = 32;
916f0bf11dbSKonrad Sztyber 
917f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
918f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
919f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
920f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
921f0bf11dbSKonrad Sztyber 	msg->hl = hl;
922f0bf11dbSKonrad Sztyber 
923f0bf11dbSKonrad Sztyber 	/* Bad message length (smaller than size of msg + 2 * hl) */
924f0bf11dbSKonrad Sztyber 	g_req_completed = false;
925f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
926f0bf11dbSKonrad Sztyber 	cmd.tl = req.iov[0].iov_len = req.length = sizeof(*msg) + 2 * hl - 1;
927f0bf11dbSKonrad Sztyber 
928f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
929f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
930f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
931f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
932f0bf11dbSKonrad Sztyber 	cmd.tl = req.iov[0].iov_len = req.length = sizeof(*msg) + hl;
933f0bf11dbSKonrad Sztyber 
934f0bf11dbSKonrad Sztyber 	/* Bad message length (larger than size of msg + 2 * hl) */
935f0bf11dbSKonrad Sztyber 	g_req_completed = false;
936f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
937f0bf11dbSKonrad Sztyber 	cmd.tl = req.iov[0].iov_len = req.length = sizeof(*msg) + 2 * hl + 1;
938f0bf11dbSKonrad Sztyber 
939f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
940f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
941f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
942f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
943f0bf11dbSKonrad Sztyber 	cmd.tl = req.iov[0].iov_len = req.length = sizeof(*msg) + 2 * hl;
944f0bf11dbSKonrad Sztyber 
945f0bf11dbSKonrad Sztyber 	/* Transaction ID mismatch */
946f0bf11dbSKonrad Sztyber 	g_req_completed = false;
947f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
948f0bf11dbSKonrad Sztyber 	msg->t_id = auth->tid + 1;
949f0bf11dbSKonrad Sztyber 
950f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
951f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
952f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
953f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
954f0bf11dbSKonrad Sztyber 	msg->t_id = auth->tid;
955f0bf11dbSKonrad Sztyber 
956f0bf11dbSKonrad Sztyber 	/* Bad cvalid value */
957f0bf11dbSKonrad Sztyber 	g_req_completed = false;
958f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
959f0bf11dbSKonrad Sztyber 	msg->cvalid = 1;
960f0bf11dbSKonrad Sztyber 
961f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
962f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
963f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
964f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
965f0bf11dbSKonrad Sztyber 	msg->cvalid = 0;
966f0bf11dbSKonrad Sztyber 
967f0bf11dbSKonrad Sztyber 	/* Bad dhvlen (non-zero) */
968f0bf11dbSKonrad Sztyber 	g_req_completed = false;
969f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
970f0bf11dbSKonrad Sztyber 	msg->dhvlen = 1;
971f0bf11dbSKonrad Sztyber 
972f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
973f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
974f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
975f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
976f0bf11dbSKonrad Sztyber 	msg->dhvlen = 0;
977f0bf11dbSKonrad Sztyber 
978f0bf11dbSKonrad Sztyber 	/* Failure to get the key */
979f0bf11dbSKonrad Sztyber 	g_req_completed = false;
980f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
981f0bf11dbSKonrad Sztyber 	MOCK_SET(nvmf_subsystem_get_dhchap_key, NULL);
982f0bf11dbSKonrad Sztyber 
983f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
984f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
985f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
986f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
987f0bf11dbSKonrad Sztyber 	MOCK_SET(nvmf_subsystem_get_dhchap_key, (struct spdk_key *)0xdeadbeef);
988f0bf11dbSKonrad Sztyber 
989f0bf11dbSKonrad Sztyber 	/* Calculation failure */
990f0bf11dbSKonrad Sztyber 	g_req_completed = false;
991f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
992f0bf11dbSKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_calculate, -EPERM);
993f0bf11dbSKonrad Sztyber 
994f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
995f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
996f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
997f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
998f0bf11dbSKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_calculate, 0);
999f0bf11dbSKonrad Sztyber 
1000f0bf11dbSKonrad Sztyber 	/* Response mismatch */
1001f0bf11dbSKonrad Sztyber 	g_req_completed = false;
1002f0bf11dbSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
1003f0bf11dbSKonrad Sztyber 	g_rval = 0x5a;
1004f0bf11dbSKonrad Sztyber 
1005f0bf11dbSKonrad Sztyber 	nvmf_auth_send_exec(&req);
1006f0bf11dbSKonrad Sztyber 	CU_ASSERT(g_req_completed);
1007f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
1008f0bf11dbSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
1009f0bf11dbSKonrad Sztyber 	g_rval = 0xa5;
1010f0bf11dbSKonrad Sztyber 
10115b83ef1cSKonrad Sztyber 	/* DH secret derivation failure */
10125b83ef1cSKonrad Sztyber 	g_req_completed = false;
10135b83ef1cSKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
10145b83ef1cSKonrad Sztyber 	auth->dhgroup = SPDK_NVMF_DHCHAP_DHGROUP_2048;
10155b83ef1cSKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_dhkey_derive_secret, -EIO);
10165b83ef1cSKonrad Sztyber 
10175b83ef1cSKonrad Sztyber 	nvmf_auth_send_exec(&req);
10185b83ef1cSKonrad Sztyber 	CU_ASSERT(g_req_completed);
10195b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
10205b83ef1cSKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
10215b83ef1cSKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_dhkey_derive_secret, 0);
10225b83ef1cSKonrad Sztyber 
1023f83615b5SKonrad Sztyber 	/* Bad cvalid value */
1024f83615b5SKonrad Sztyber 	g_req_completed = false;
1025f83615b5SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
1026f83615b5SKonrad Sztyber 	msg->cvalid = 2;
1027f83615b5SKonrad Sztyber 
1028f83615b5SKonrad Sztyber 	nvmf_auth_send_exec(&req);
1029f83615b5SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1030f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
1031f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
1032f83615b5SKonrad Sztyber 
1033f83615b5SKonrad Sztyber 	/* Bad cvalid/seqnum combination */
1034f83615b5SKonrad Sztyber 	g_req_completed = false;
1035f83615b5SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
1036f83615b5SKonrad Sztyber 	msg->cvalid = 1;
1037f83615b5SKonrad Sztyber 	msg->seqnum = 0;
1038f83615b5SKonrad Sztyber 
1039f83615b5SKonrad Sztyber 	nvmf_auth_send_exec(&req);
1040f83615b5SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1041f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
1042f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
1043f83615b5SKonrad Sztyber 
1044f83615b5SKonrad Sztyber 	/* Missing controller key */
1045f83615b5SKonrad Sztyber 	g_req_completed = false;
1046f83615b5SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
1047f83615b5SKonrad Sztyber 	msg->cvalid = 1;
1048f83615b5SKonrad Sztyber 	msg->seqnum = 1;
1049f83615b5SKonrad Sztyber 	MOCK_ENQUEUE(nvmf_subsystem_get_dhchap_key, (struct spdk_key *)0xdeadbeef);
1050f83615b5SKonrad Sztyber 	MOCK_ENQUEUE(nvmf_subsystem_get_dhchap_key, NULL);
1051f83615b5SKonrad Sztyber 
1052f83615b5SKonrad Sztyber 	nvmf_auth_send_exec(&req);
1053f83615b5SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1054f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
1055f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
1056f83615b5SKonrad Sztyber 
105734edd9f1SKamil Godzwon 	/* Controller challenge calculation failure */
1058f83615b5SKonrad Sztyber 	g_req_completed = false;
1059f83615b5SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_REPLY;
1060f83615b5SKonrad Sztyber 	msg->cvalid = 1;
1061f83615b5SKonrad Sztyber 	msg->seqnum = 1;
1062f83615b5SKonrad Sztyber 	MOCK_ENQUEUE(spdk_nvme_dhchap_calculate, 0);
1063f83615b5SKonrad Sztyber 	MOCK_ENQUEUE(spdk_nvme_dhchap_calculate, -EIO);
1064f83615b5SKonrad Sztyber 
1065f83615b5SKonrad Sztyber 	nvmf_auth_send_exec(&req);
1066f83615b5SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1067f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_FAILURE1);
1068f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->fail_reason, SPDK_NVMF_AUTH_FAILED);
1069f83615b5SKonrad Sztyber 
1070f0bf11dbSKonrad Sztyber 	nvmf_qpair_auth_destroy(&qpair);
1071f0bf11dbSKonrad Sztyber }
1072f0bf11dbSKonrad Sztyber 
1073eb267841SKonrad Sztyber static void
1074eb267841SKonrad Sztyber test_auth_success1(void)
1075eb267841SKonrad Sztyber {
1076eb267841SKonrad Sztyber 	union nvmf_c2h_msg rsp = {};
1077eb267841SKonrad Sztyber 	struct spdk_nvmf_subsystem subsys = {};
1078eb267841SKonrad Sztyber 	struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsys };
1079eb267841SKonrad Sztyber 	struct spdk_nvmf_qpair qpair = { .ctrlr = &ctrlr };
1080eb267841SKonrad Sztyber 	struct spdk_nvmf_request req = { .qpair = &qpair, .rsp = &rsp };
1081eb267841SKonrad Sztyber 	struct spdk_nvmf_fabric_auth_recv_cmd cmd = {
1082eb267841SKonrad Sztyber 		.fctype = SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV
1083eb267841SKonrad Sztyber 	};
1084eb267841SKonrad Sztyber 	struct spdk_nvmf_qpair_auth *auth;
1085eb267841SKonrad Sztyber 	struct spdk_nvmf_dhchap_success1 *msg;
1086eb267841SKonrad Sztyber 	struct spdk_nvmf_auth_failure *fail;
1087f83615b5SKonrad Sztyber 	uint8_t msgbuf[sizeof(*msg) + 48];
1088eb267841SKonrad Sztyber 	int rc;
1089eb267841SKonrad Sztyber 
1090eb267841SKonrad Sztyber 	msg = (void *)msgbuf;
1091eb267841SKonrad Sztyber 	fail = (void *)msgbuf;
1092eb267841SKonrad Sztyber 	rc = nvmf_qpair_auth_init(&qpair);
1093eb267841SKonrad Sztyber 	SPDK_CU_ASSERT_FATAL(rc == 0);
1094eb267841SKonrad Sztyber 	auth = qpair.auth;
1095eb267841SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
1096eb267841SKonrad Sztyber 	auth->tid = 8;
1097eb267841SKonrad Sztyber 
1098eb267841SKonrad Sztyber 	/* Successfully receive a success message */
1099eb267841SKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
1100eb267841SKonrad Sztyber 	g_req_completed = false;
1101eb267841SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_SUCCESS1;
1102eb267841SKonrad Sztyber 
1103eb267841SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
1104eb267841SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1105eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_COMPLETED);
1106eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ENABLED);
1107eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_DHCHAP);
1108eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_DHCHAP_SUCCESS1);
1109eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->t_id, 8);
1110eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->hl, 48);
1111eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->rvalid, 0);
1112eb267841SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
1113eb267841SKonrad Sztyber 
1114f83615b5SKonrad Sztyber 	/* Successfully receive a success message w/ bidirectional authentication */
1115f83615b5SKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg) + 48);
1116f83615b5SKonrad Sztyber 	g_req_completed = false;
1117f83615b5SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_SUCCESS1;
1118f83615b5SKonrad Sztyber 	auth->cvalid = true;
1119f83615b5SKonrad Sztyber 	memset(auth->cval, 0xa5, 48);
1120f83615b5SKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
1121f83615b5SKonrad Sztyber 
1122f83615b5SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
1123f83615b5SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1124f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_SUCCESS2);
1125f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_type, SPDK_NVMF_AUTH_TYPE_DHCHAP);
1126f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->auth_id, SPDK_NVMF_AUTH_ID_DHCHAP_SUCCESS1);
1127f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->t_id, 8);
1128f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->hl, 48);
1129f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(msg->rvalid, 1);
1130f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(memcmp(msg->rval, auth->cval, 48), 0);
1131f83615b5SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
1132f83615b5SKonrad Sztyber 	auth->cvalid = false;
1133f83615b5SKonrad Sztyber 
1134eb267841SKonrad Sztyber 	/* Bad message length (smaller than success1 message) */
1135eb267841SKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
1136eb267841SKonrad Sztyber 	g_req_completed = false;
1137eb267841SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_SUCCESS1;
1138eb267841SKonrad Sztyber 	cmd.al = req.iov[0].iov_len = req.length = sizeof(*msg) - 1;
1139eb267841SKonrad Sztyber 
1140eb267841SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
1141eb267841SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1142eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_ERROR);
1143eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
1144eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
1145eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
1146eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->t_id, 8);
1147eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
1148eb267841SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
1149eb267841SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
1150f83615b5SKonrad Sztyber 
1151f83615b5SKonrad Sztyber 	/* Bad message length (smaller than msg + hl) */
1152f83615b5SKonrad Sztyber 	ut_prep_recv_cmd(&req, &cmd, msgbuf, sizeof(*msg));
1153f83615b5SKonrad Sztyber 	g_req_completed = false;
1154f83615b5SKonrad Sztyber 	auth->state = NVMF_QPAIR_AUTH_SUCCESS1;
1155f83615b5SKonrad Sztyber 	auth->cvalid = true;
1156f83615b5SKonrad Sztyber 	MOCK_SET(spdk_nvme_dhchap_get_digest_length, 48);
1157f83615b5SKonrad Sztyber 	cmd.al = req.iov[0].iov_len = req.length = sizeof(*msg) + 47;
1158f83615b5SKonrad Sztyber 
1159f83615b5SKonrad Sztyber 	nvmf_auth_recv_exec(&req);
1160f83615b5SKonrad Sztyber 	CU_ASSERT(g_req_completed);
1161f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(auth->state, NVMF_QPAIR_AUTH_ERROR);
1162f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(qpair.state, SPDK_NVMF_QPAIR_ERROR);
1163f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_type, SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE);
1164f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->auth_id, SPDK_NVMF_AUTH_ID_FAILURE1);
1165f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->t_id, 8);
1166f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rc, SPDK_NVMF_AUTH_FAILURE);
1167f83615b5SKonrad Sztyber 	CU_ASSERT_EQUAL(fail->rce, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
1168f83615b5SKonrad Sztyber 	qpair.state = SPDK_NVMF_QPAIR_AUTHENTICATING;
1169f83615b5SKonrad Sztyber 	auth->cvalid = false;
1170eb267841SKonrad Sztyber 	cmd.al = req.iov[0].iov_len = req.length = sizeof(*msg);
1171eb267841SKonrad Sztyber 
1172eb267841SKonrad Sztyber 	nvmf_qpair_auth_destroy(&qpair);
1173eb267841SKonrad Sztyber }
1174eb267841SKonrad Sztyber 
11757b0bd881SKonrad Sztyber int
11767b0bd881SKonrad Sztyber main(int argc, char **argv)
11777b0bd881SKonrad Sztyber {
11787b0bd881SKonrad Sztyber 	CU_pSuite suite = NULL;
11797b0bd881SKonrad Sztyber 	unsigned int num_failures;
11807b0bd881SKonrad Sztyber 
11817b0bd881SKonrad Sztyber 	CU_initialize_registry();
11827b0bd881SKonrad Sztyber 	suite = CU_add_suite("nvmf_auth", NULL, NULL);
11837b0bd881SKonrad Sztyber 	CU_ADD_TEST(suite, test_auth_send_recv_error);
1184b2dcccf3SKonrad Sztyber 	CU_ADD_TEST(suite, test_auth_negotiate);
1185c54a29d8SKonrad Sztyber 	CU_ADD_TEST(suite, test_auth_timeout);
118667ab645cSKonrad Sztyber 	CU_ADD_TEST(suite, test_auth_failure1);
11872c8f9257SKonrad Sztyber 	CU_ADD_TEST(suite, test_auth_challenge);
1188f0bf11dbSKonrad Sztyber 	CU_ADD_TEST(suite, test_auth_reply);
1189eb267841SKonrad Sztyber 	CU_ADD_TEST(suite, test_auth_success1);
11907b0bd881SKonrad Sztyber 
11917b0bd881SKonrad Sztyber 	allocate_threads(1);
11927b0bd881SKonrad Sztyber 	set_thread(0);
11937b0bd881SKonrad Sztyber 
11947b0bd881SKonrad Sztyber 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
11957b0bd881SKonrad Sztyber 	CU_cleanup_registry();
11967b0bd881SKonrad Sztyber 
11977b0bd881SKonrad Sztyber 	free_threads();
11987b0bd881SKonrad Sztyber 
11997b0bd881SKonrad Sztyber 	return num_failures;
12007b0bd881SKonrad Sztyber }
1201