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