1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (C) 2021 Intel Corporation.
3 * All rights reserved.
4 */
5
6 #include "spdk/stdinc.h"
7 #include "spdk_internal/cunit.h"
8 #include "nvme/nvme_opal.c"
9 #include "common/lib/test_env.c"
10
11 SPDK_LOG_REGISTER_COMPONENT(nvme)
12
13 DEFINE_STUB(spdk_nvme_ctrlr_cmd_security_receive, int,
14 (struct spdk_nvme_ctrlr *ctrlr, uint8_t secp, uint16_t spsp,
15 uint8_t nssf, void *payload, uint32_t payload_size,
16 spdk_nvme_cmd_cb cb_fn, void *cb_arg), 1);
17
18 DEFINE_STUB(spdk_nvme_ctrlr_security_receive, int,
19 (struct spdk_nvme_ctrlr *ctrlr, uint8_t secp,
20 uint16_t spsp, uint8_t nssf, void *payload, size_t size), 0);
21
22 DEFINE_STUB(spdk_nvme_ctrlr_process_admin_completions, int,
23 (struct spdk_nvme_ctrlr *ctrlr), 0);
24
25 DEFINE_STUB(spdk_nvme_ctrlr_cmd_security_send, int,
26 (struct spdk_nvme_ctrlr *ctrlr, uint8_t secp,
27 uint16_t spsp, uint8_t nssf, void *payload,
28 uint32_t payload_size, spdk_nvme_cmd_cb cb_fn, void *cb_arg), 0);
29
30 static int g_ut_recv_status = 0;
31 static void *g_ut_sess_ctx;
32
33 static void
ut_opal_sess_cb(struct opal_session * sess,int status,void * ctx)34 ut_opal_sess_cb(struct opal_session *sess, int status, void *ctx)
35 {
36 g_ut_recv_status = status;
37 g_ut_sess_ctx = ctx;
38 }
39
40 static void
reset_ut_global_variables(void)41 reset_ut_global_variables(void)
42 {
43 g_ut_recv_status = 0;
44 g_ut_sess_ctx = NULL;
45 }
46
47 static void
test_opal_nvme_security_recv_send_done(void)48 test_opal_nvme_security_recv_send_done(void)
49 {
50 struct spdk_nvme_cpl cpl = {};
51 struct spdk_opal_compacket header = {};
52 struct spdk_opal_dev dev = {};
53 struct opal_session sess = {};
54
55 sess.sess_cb = ut_opal_sess_cb;
56 sess.cb_arg = (void *)0xDEADBEEF;
57 sess.dev = &dev;
58 memcpy(sess.resp, &header, sizeof(header));
59
60 /* Case 1: receive/send IO error */
61 reset_ut_global_variables();
62 cpl.status.sct = SPDK_NVME_SCT_MEDIA_ERROR;
63
64 opal_nvme_security_recv_done(&sess, &cpl);
65 CU_ASSERT(g_ut_recv_status == -EIO);
66 CU_ASSERT(g_ut_sess_ctx == (void *)0xDEADBEEF);
67
68 reset_ut_global_variables();
69 opal_nvme_security_send_done(&sess, &cpl);
70 CU_ASSERT(g_ut_recv_status == -EIO);
71 CU_ASSERT(g_ut_sess_ctx == (void *)0xDEADBEEF);
72
73 /* Case 2: receive with opal header no outstanding data */
74 reset_ut_global_variables();
75 memset(&header, 0, sizeof(header));
76 cpl.status.sct = SPDK_NVME_SCT_GENERIC;
77
78 opal_nvme_security_recv_done(&sess, &cpl);
79 CU_ASSERT(g_ut_recv_status == 0);
80 CU_ASSERT(g_ut_sess_ctx == (void *)0xDEADBEEF);
81
82 /* Case 3: receive with opal header outstanding data and send done success */
83 reset_ut_global_variables();
84 header.outstanding_data = 0xff;
85 memcpy(sess.resp, &header, sizeof(header));
86 cpl.status.sct = SPDK_NVME_SCT_GENERIC;
87
88 opal_nvme_security_recv_done(&sess, &cpl);
89 CU_ASSERT(g_ut_recv_status == 1);
90 CU_ASSERT(g_ut_sess_ctx == (void *)0xDEADBEEF);
91
92 reset_ut_global_variables();
93 opal_nvme_security_send_done(&sess, &cpl);
94 CU_ASSERT(g_ut_recv_status == 1);
95 CU_ASSERT(g_ut_sess_ctx == (void *)0xDEADBEEF);
96 }
97
98 static void
test_opal_add_short_atom_header(void)99 test_opal_add_short_atom_header(void)
100 {
101 struct opal_session sess = {};
102 int err = 0;
103
104 /* short atom header */
105 memset(&sess, 0, sizeof(sess));
106 sess.cmd_pos = 0;
107
108 opal_add_token_bytestring(&err, &sess, spdk_opal_uid[UID_SMUID],
109 OPAL_UID_LENGTH);
110 CU_ASSERT(sess.cmd[0] & SPDK_SHORT_ATOM_ID);
111 CU_ASSERT(sess.cmd[0] & SPDK_SHORT_ATOM_BYTESTRING_FLAG);
112 CU_ASSERT((sess.cmd[0] & SPDK_SHORT_ATOM_SIGN_FLAG) == 0);
113 CU_ASSERT(sess.cmd_pos == OPAL_UID_LENGTH + 1);
114 CU_ASSERT(!memcmp(&sess.cmd[1], spdk_opal_uid, OPAL_UID_LENGTH + 1));
115
116 /* medium atom header */
117 memset(&sess, 0, sizeof(sess));
118 sess.cmd_pos = 0;
119
120 opal_add_token_bytestring(&err, &sess, spdk_opal_uid[UID_SMUID],
121 0x10);
122 CU_ASSERT(sess.cmd[0] & SPDK_SHORT_ATOM_ID);
123 CU_ASSERT(sess.cmd[0] & SPDK_MEDIUM_ATOM_BYTESTRING_FLAG);
124 CU_ASSERT((sess.cmd[0] & SPDK_MEDIUM_ATOM_SIGN_FLAG) == 0);
125 CU_ASSERT(sess.cmd_pos == 0x12);
126 CU_ASSERT(!memcmp(&sess.cmd[2], spdk_opal_uid, 0x10));
127
128 /* Invalid length */
129 memset(&sess, 0, sizeof(sess));
130 err = 0;
131
132 opal_add_token_bytestring(&err, &sess, spdk_opal_uid[UID_SMUID],
133 0x1000);
134 CU_ASSERT(err == -ERANGE);
135 CU_ASSERT(sess.cmd_pos == 0);
136 }
137
138 int
main(int argc,char ** argv)139 main(int argc, char **argv)
140 {
141 CU_pSuite suite = NULL;
142 unsigned int num_failures;
143
144 CU_initialize_registry();
145
146 suite = CU_add_suite("nvme_opal", NULL, NULL);
147 CU_ADD_TEST(suite, test_opal_nvme_security_recv_send_done);
148 CU_ADD_TEST(suite, test_opal_add_short_atom_header);
149
150 num_failures = spdk_ut_run_tests(argc, argv, NULL);
151 CU_cleanup_registry();
152 return num_failures;
153 }
154