1*758e9fbaSOystein Eftevaag /* SPDX-License-Identifier: BSD-2-Clause */
2*758e9fbaSOystein Eftevaag
3*758e9fbaSOystein Eftevaag #include <stdarg.h>
4*758e9fbaSOystein Eftevaag #include <stdbool.h>
5*758e9fbaSOystein Eftevaag #include <stddef.h>
6*758e9fbaSOystein Eftevaag #include <stdio.h>
7*758e9fbaSOystein Eftevaag #include <stdlib.h>
8*758e9fbaSOystein Eftevaag #include <string.h>
9*758e9fbaSOystein Eftevaag
10*758e9fbaSOystein Eftevaag #include <setjmp.h>
11*758e9fbaSOystein Eftevaag #include <cmocka.h>
12*758e9fbaSOystein Eftevaag
13*758e9fbaSOystein Eftevaag #include "tss2_rc.h"
14*758e9fbaSOystein Eftevaag
15*758e9fbaSOystein Eftevaag #define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0]))
16*758e9fbaSOystein Eftevaag
17*758e9fbaSOystein Eftevaag #define TPM2_ERROR_TSS2_RC_LAYER_COUNT (TSS2_RC_LAYER_MASK >> TSS2_RC_LAYER_SHIFT)
18*758e9fbaSOystein Eftevaag
19*758e9fbaSOystein Eftevaag #define assert_string_prefix(str, prefix) \
20*758e9fbaSOystein Eftevaag assert_memory_equal(str, prefix, strlen(prefix))
21*758e9fbaSOystein Eftevaag
22*758e9fbaSOystein Eftevaag static void
test_layers(void ** state)23*758e9fbaSOystein Eftevaag test_layers(void **state)
24*758e9fbaSOystein Eftevaag {
25*758e9fbaSOystein Eftevaag (void) state;
26*758e9fbaSOystein Eftevaag
27*758e9fbaSOystein Eftevaag static const char *known_layers[TPM2_ERROR_TSS2_RC_LAYER_COUNT] = {
28*758e9fbaSOystein Eftevaag "tpm:",
29*758e9fbaSOystein Eftevaag NULL,
30*758e9fbaSOystein Eftevaag NULL,
31*758e9fbaSOystein Eftevaag NULL,
32*758e9fbaSOystein Eftevaag NULL,
33*758e9fbaSOystein Eftevaag NULL,
34*758e9fbaSOystein Eftevaag "fapi:",
35*758e9fbaSOystein Eftevaag "esapi:",
36*758e9fbaSOystein Eftevaag "sys:",
37*758e9fbaSOystein Eftevaag "mu:",
38*758e9fbaSOystein Eftevaag "tcti:",
39*758e9fbaSOystein Eftevaag "rmt",
40*758e9fbaSOystein Eftevaag "rm",
41*758e9fbaSOystein Eftevaag "drvr",
42*758e9fbaSOystein Eftevaag };
43*758e9fbaSOystein Eftevaag
44*758e9fbaSOystein Eftevaag UINT8 layer;
45*758e9fbaSOystein Eftevaag for (layer = 0; layer < TPM2_ERROR_TSS2_RC_LAYER_COUNT; layer++) {
46*758e9fbaSOystein Eftevaag TSS2_RC rc = TSS2_RC_LAYER(layer);
47*758e9fbaSOystein Eftevaag
48*758e9fbaSOystein Eftevaag const char *got = Tss2_RC_Decode(rc);
49*758e9fbaSOystein Eftevaag
50*758e9fbaSOystein Eftevaag char buf[256];
51*758e9fbaSOystein Eftevaag snprintf(buf, sizeof(buf), "%u:", layer);
52*758e9fbaSOystein Eftevaag
53*758e9fbaSOystein Eftevaag const char *expected = known_layers[layer] ? known_layers[layer] : buf;
54*758e9fbaSOystein Eftevaag assert_string_prefix(got, expected);
55*758e9fbaSOystein Eftevaag }
56*758e9fbaSOystein Eftevaag }
57*758e9fbaSOystein Eftevaag
58*758e9fbaSOystein Eftevaag static void
test_tpm_format_0_version2_0_error(void ** state)59*758e9fbaSOystein Eftevaag test_tpm_format_0_version2_0_error(void **state)
60*758e9fbaSOystein Eftevaag {
61*758e9fbaSOystein Eftevaag (void) state;
62*758e9fbaSOystein Eftevaag
63*758e9fbaSOystein Eftevaag const char *m = Tss2_RC_Decode(TPM2_RC_SEQUENCE);
64*758e9fbaSOystein Eftevaag assert_string_equal(m, "tpm:error(2.0): improper use of a sequence"
65*758e9fbaSOystein Eftevaag " handle");
66*758e9fbaSOystein Eftevaag }
67*758e9fbaSOystein Eftevaag
test_tpm_format_0_version2_0_warn(void ** state)68*758e9fbaSOystein Eftevaag static void test_tpm_format_0_version2_0_warn(void **state)
69*758e9fbaSOystein Eftevaag {
70*758e9fbaSOystein Eftevaag (void) state;
71*758e9fbaSOystein Eftevaag
72*758e9fbaSOystein Eftevaag const char *m = Tss2_RC_Decode(TPM2_RC_REFERENCE_H0);
73*758e9fbaSOystein Eftevaag assert_string_equal(m,
74*758e9fbaSOystein Eftevaag "tpm:warn(2.0): the 1st handle in the handle area references a"
75*758e9fbaSOystein Eftevaag " transient object or session that is not loaded");
76*758e9fbaSOystein Eftevaag }
77*758e9fbaSOystein Eftevaag
78*758e9fbaSOystein Eftevaag static void
test_tpm2_format_0_unknown(void ** state)79*758e9fbaSOystein Eftevaag test_tpm2_format_0_unknown(void **state)
80*758e9fbaSOystein Eftevaag {
81*758e9fbaSOystein Eftevaag (void) state;
82*758e9fbaSOystein Eftevaag
83*758e9fbaSOystein Eftevaag const char *m = Tss2_RC_Decode(TPM2_RC_NOT_USED + 0x80);
84*758e9fbaSOystein Eftevaag assert_string_equal(m, "tpm:parameter(1):unknown error num: 0x3F");
85*758e9fbaSOystein Eftevaag }
86*758e9fbaSOystein Eftevaag
87*758e9fbaSOystein Eftevaag static void
test_tpm_format_1_unk_handle(void ** state)88*758e9fbaSOystein Eftevaag test_tpm_format_1_unk_handle(void **state)
89*758e9fbaSOystein Eftevaag {
90*758e9fbaSOystein Eftevaag (void) state;
91*758e9fbaSOystein Eftevaag
92*758e9fbaSOystein Eftevaag const char *m = Tss2_RC_Decode(TPM2_RC_HASH);
93*758e9fbaSOystein Eftevaag assert_string_equal(m,
94*758e9fbaSOystein Eftevaag "tpm:handle(unk):hash algorithm not supported or not appropriate");
95*758e9fbaSOystein Eftevaag }
96*758e9fbaSOystein Eftevaag
97*758e9fbaSOystein Eftevaag static void
test_tpm_format_1_unk_parameter(void ** state)98*758e9fbaSOystein Eftevaag test_tpm_format_1_unk_parameter(void **state)
99*758e9fbaSOystein Eftevaag {
100*758e9fbaSOystein Eftevaag (void) state;
101*758e9fbaSOystein Eftevaag
102*758e9fbaSOystein Eftevaag const char *m = Tss2_RC_Decode(TPM2_RC_HASH + TPM2_RC_P);
103*758e9fbaSOystein Eftevaag assert_string_equal(m,
104*758e9fbaSOystein Eftevaag "tpm:parameter(unk):hash algorithm not supported or not appropriate");
105*758e9fbaSOystein Eftevaag }
106*758e9fbaSOystein Eftevaag
107*758e9fbaSOystein Eftevaag static void
test_tpm_format_1_unk_session(void ** state)108*758e9fbaSOystein Eftevaag test_tpm_format_1_unk_session(void **state)
109*758e9fbaSOystein Eftevaag {
110*758e9fbaSOystein Eftevaag (void) state;
111*758e9fbaSOystein Eftevaag
112*758e9fbaSOystein Eftevaag const char *m = Tss2_RC_Decode(TPM2_RC_HASH + TPM2_RC_S);
113*758e9fbaSOystein Eftevaag assert_string_equal(m,
114*758e9fbaSOystein Eftevaag "tpm:session(unk):hash algorithm not supported or not appropriate");
115*758e9fbaSOystein Eftevaag }
116*758e9fbaSOystein Eftevaag
117*758e9fbaSOystein Eftevaag static void
test_tpm_format_1_5_handle(void ** state)118*758e9fbaSOystein Eftevaag test_tpm_format_1_5_handle(void **state)
119*758e9fbaSOystein Eftevaag {
120*758e9fbaSOystein Eftevaag (void) state;
121*758e9fbaSOystein Eftevaag
122*758e9fbaSOystein Eftevaag const char *m = Tss2_RC_Decode(TPM2_RC_HASH + TPM2_RC_5);
123*758e9fbaSOystein Eftevaag assert_string_equal(m,
124*758e9fbaSOystein Eftevaag "tpm:handle(5):hash algorithm not supported or not appropriate");
125*758e9fbaSOystein Eftevaag }
126*758e9fbaSOystein Eftevaag
127*758e9fbaSOystein Eftevaag static void
test_tpm2_format_1_unknown(void ** state)128*758e9fbaSOystein Eftevaag test_tpm2_format_1_unknown(void **state)
129*758e9fbaSOystein Eftevaag {
130*758e9fbaSOystein Eftevaag (void) state;
131*758e9fbaSOystein Eftevaag
132*758e9fbaSOystein Eftevaag const char *m = Tss2_RC_Decode(TPM2_RC_NOT_USED + 0x80);
133*758e9fbaSOystein Eftevaag assert_string_equal(m, "tpm:parameter(1):unknown error num: 0x3F");
134*758e9fbaSOystein Eftevaag }
135*758e9fbaSOystein Eftevaag
136*758e9fbaSOystein Eftevaag static void
test_tpm2_format_1_success(void ** state)137*758e9fbaSOystein Eftevaag test_tpm2_format_1_success(void **state)
138*758e9fbaSOystein Eftevaag {
139*758e9fbaSOystein Eftevaag (void) state;
140*758e9fbaSOystein Eftevaag
141*758e9fbaSOystein Eftevaag const char *m = Tss2_RC_Decode(TPM2_RC_SUCCESS);
142*758e9fbaSOystein Eftevaag assert_string_equal(m, "tpm:success");
143*758e9fbaSOystein Eftevaag }
144*758e9fbaSOystein Eftevaag
145*758e9fbaSOystein Eftevaag static const char *
custom_err_handler(TSS2_RC rc)146*758e9fbaSOystein Eftevaag custom_err_handler(TSS2_RC rc)
147*758e9fbaSOystein Eftevaag {
148*758e9fbaSOystein Eftevaag
149*758e9fbaSOystein Eftevaag static const char *err_map[] = { "error 1", "error 2", "error 3" };
150*758e9fbaSOystein Eftevaag
151*758e9fbaSOystein Eftevaag if (rc - 1u >= ARRAY_LEN(err_map)) {
152*758e9fbaSOystein Eftevaag return NULL;
153*758e9fbaSOystein Eftevaag }
154*758e9fbaSOystein Eftevaag
155*758e9fbaSOystein Eftevaag return err_map[rc - 1];
156*758e9fbaSOystein Eftevaag }
157*758e9fbaSOystein Eftevaag
158*758e9fbaSOystein Eftevaag static void
test_custom_handler(void ** state)159*758e9fbaSOystein Eftevaag test_custom_handler(void **state)
160*758e9fbaSOystein Eftevaag {
161*758e9fbaSOystein Eftevaag (void) state;
162*758e9fbaSOystein Eftevaag
163*758e9fbaSOystein Eftevaag /*
164*758e9fbaSOystein Eftevaag * Test registering a custom handler
165*758e9fbaSOystein Eftevaag */
166*758e9fbaSOystein Eftevaag TSS2_RC_HANDLER old = Tss2_RC_SetHandler(1, "cstm", custom_err_handler);
167*758e9fbaSOystein Eftevaag assert_null(old);
168*758e9fbaSOystein Eftevaag
169*758e9fbaSOystein Eftevaag /*
170*758e9fbaSOystein Eftevaag * Test getting error strings
171*758e9fbaSOystein Eftevaag */
172*758e9fbaSOystein Eftevaag unsigned i;
173*758e9fbaSOystein Eftevaag for (i = 1; i < 4; i++) {
174*758e9fbaSOystein Eftevaag // Make a layer 1 error with an error number of i.
175*758e9fbaSOystein Eftevaag TSS2_RC rc = TSS2_RC_LAYER(1) | i;
176*758e9fbaSOystein Eftevaag char buf[256];
177*758e9fbaSOystein Eftevaag snprintf(buf, sizeof(buf), "cstm:error %u", i);
178*758e9fbaSOystein Eftevaag
179*758e9fbaSOystein Eftevaag const char *e = Tss2_RC_Decode(rc);
180*758e9fbaSOystein Eftevaag assert_string_equal(e, buf);
181*758e9fbaSOystein Eftevaag }
182*758e9fbaSOystein Eftevaag
183*758e9fbaSOystein Eftevaag TSS2_RC rc = TSS2_RC_LAYER(1) | 42;
184*758e9fbaSOystein Eftevaag
185*758e9fbaSOystein Eftevaag /*
186*758e9fbaSOystein Eftevaag * Test an unknown error
187*758e9fbaSOystein Eftevaag */
188*758e9fbaSOystein Eftevaag const char *e = Tss2_RC_Decode(rc);
189*758e9fbaSOystein Eftevaag assert_string_equal(e, "cstm:0x2A");
190*758e9fbaSOystein Eftevaag
191*758e9fbaSOystein Eftevaag /*
192*758e9fbaSOystein Eftevaag * Test clearing a handler
193*758e9fbaSOystein Eftevaag */
194*758e9fbaSOystein Eftevaag old = Tss2_RC_SetHandler(1, "cstm", NULL);
195*758e9fbaSOystein Eftevaag assert_ptr_equal(old, custom_err_handler);
196*758e9fbaSOystein Eftevaag
197*758e9fbaSOystein Eftevaag /*
198*758e9fbaSOystein Eftevaag * Test an unknown layer
199*758e9fbaSOystein Eftevaag */
200*758e9fbaSOystein Eftevaag e = Tss2_RC_Decode(rc);
201*758e9fbaSOystein Eftevaag assert_string_equal(e, "1:0x2A");
202*758e9fbaSOystein Eftevaag }
203*758e9fbaSOystein Eftevaag
204*758e9fbaSOystein Eftevaag static void
test_zero_length_name(void ** state)205*758e9fbaSOystein Eftevaag test_zero_length_name(void **state)
206*758e9fbaSOystein Eftevaag {
207*758e9fbaSOystein Eftevaag (void) state;
208*758e9fbaSOystein Eftevaag
209*758e9fbaSOystein Eftevaag TSS2_RC_HANDLER old = Tss2_RC_SetHandler(TSS2_TPM_RC_LAYER, "",
210*758e9fbaSOystein Eftevaag custom_err_handler);
211*758e9fbaSOystein Eftevaag assert_non_null(old);
212*758e9fbaSOystein Eftevaag
213*758e9fbaSOystein Eftevaag old = Tss2_RC_SetHandler(TSS2_TPM_RC_LAYER, "",
214*758e9fbaSOystein Eftevaag custom_err_handler);
215*758e9fbaSOystein Eftevaag assert_ptr_equal(old, custom_err_handler);
216*758e9fbaSOystein Eftevaag }
217*758e9fbaSOystein Eftevaag
218*758e9fbaSOystein Eftevaag static void
test_over_length_name(void ** state)219*758e9fbaSOystein Eftevaag test_over_length_name(void **state)
220*758e9fbaSOystein Eftevaag {
221*758e9fbaSOystein Eftevaag (void) state;
222*758e9fbaSOystein Eftevaag
223*758e9fbaSOystein Eftevaag TSS2_RC_HANDLER old = Tss2_RC_SetHandler(1, "way to long of name", custom_err_handler);
224*758e9fbaSOystein Eftevaag assert_null(old);
225*758e9fbaSOystein Eftevaag
226*758e9fbaSOystein Eftevaag old = Tss2_RC_SetHandler(1, "way to long of name", custom_err_handler);
227*758e9fbaSOystein Eftevaag assert_ptr_equal(old, custom_err_handler);
228*758e9fbaSOystein Eftevaag }
229*758e9fbaSOystein Eftevaag
230*758e9fbaSOystein Eftevaag static void
test_null_name(void ** state)231*758e9fbaSOystein Eftevaag test_null_name(void **state)
232*758e9fbaSOystein Eftevaag {
233*758e9fbaSOystein Eftevaag (void) state;
234*758e9fbaSOystein Eftevaag
235*758e9fbaSOystein Eftevaag TSS2_RC_HANDLER old = Tss2_RC_SetHandler(1,
236*758e9fbaSOystein Eftevaag NULL, custom_err_handler);
237*758e9fbaSOystein Eftevaag assert_ptr_equal(old, custom_err_handler);
238*758e9fbaSOystein Eftevaag
239*758e9fbaSOystein Eftevaag old = Tss2_RC_SetHandler(1,
240*758e9fbaSOystein Eftevaag NULL, custom_err_handler);
241*758e9fbaSOystein Eftevaag assert_ptr_equal(old, custom_err_handler);
242*758e9fbaSOystein Eftevaag }
243*758e9fbaSOystein Eftevaag
244*758e9fbaSOystein Eftevaag static void
test_sys(void ** state)245*758e9fbaSOystein Eftevaag test_sys(void **state)
246*758e9fbaSOystein Eftevaag {
247*758e9fbaSOystein Eftevaag (void) state;
248*758e9fbaSOystein Eftevaag
249*758e9fbaSOystein Eftevaag const char *e = Tss2_RC_Decode(TSS2_SYS_RC_ABI_MISMATCH);
250*758e9fbaSOystein Eftevaag assert_string_equal(e,
251*758e9fbaSOystein Eftevaag "sys:Passed in ABI version doesn't match called module's ABI version");
252*758e9fbaSOystein Eftevaag }
253*758e9fbaSOystein Eftevaag
254*758e9fbaSOystein Eftevaag static void
test_esys(void ** state)255*758e9fbaSOystein Eftevaag test_esys(void **state)
256*758e9fbaSOystein Eftevaag {
257*758e9fbaSOystein Eftevaag (void) state;
258*758e9fbaSOystein Eftevaag
259*758e9fbaSOystein Eftevaag const char *e = Tss2_RC_Decode(TSS2_ESYS_RC_BAD_VALUE);
260*758e9fbaSOystein Eftevaag assert_string_equal(e,
261*758e9fbaSOystein Eftevaag "esapi:A parameter has a bad value");
262*758e9fbaSOystein Eftevaag }
263*758e9fbaSOystein Eftevaag
264*758e9fbaSOystein Eftevaag static void
test_mu(void ** state)265*758e9fbaSOystein Eftevaag test_mu(void **state)
266*758e9fbaSOystein Eftevaag {
267*758e9fbaSOystein Eftevaag (void) state;
268*758e9fbaSOystein Eftevaag
269*758e9fbaSOystein Eftevaag const char *e = Tss2_RC_Decode(TSS2_MU_RC_BAD_REFERENCE);
270*758e9fbaSOystein Eftevaag assert_string_equal(e,
271*758e9fbaSOystein Eftevaag "mu:A pointer is NULL that isn't allowed to be NULL.");
272*758e9fbaSOystein Eftevaag
273*758e9fbaSOystein Eftevaag }
274*758e9fbaSOystein Eftevaag
275*758e9fbaSOystein Eftevaag static void
test_tcti(void ** state)276*758e9fbaSOystein Eftevaag test_tcti(void **state)
277*758e9fbaSOystein Eftevaag {
278*758e9fbaSOystein Eftevaag (void) state;
279*758e9fbaSOystein Eftevaag
280*758e9fbaSOystein Eftevaag const char *e = Tss2_RC_Decode(TSS2_TCTI_RC_NO_CONNECTION);
281*758e9fbaSOystein Eftevaag assert_string_equal(e, "tcti:Fails to connect to next lower layer");
282*758e9fbaSOystein Eftevaag }
283*758e9fbaSOystein Eftevaag
284*758e9fbaSOystein Eftevaag /* link required symbol, but tpm2_tool.c declares it AND main, which
285*758e9fbaSOystein Eftevaag * we have a main below for cmocka tests.
286*758e9fbaSOystein Eftevaag */
287*758e9fbaSOystein Eftevaag bool output_enabled = true;
288*758e9fbaSOystein Eftevaag
289*758e9fbaSOystein Eftevaag int
main(int argc,char * argv[])290*758e9fbaSOystein Eftevaag main(int argc, char* argv[])
291*758e9fbaSOystein Eftevaag {
292*758e9fbaSOystein Eftevaag (void) argc;
293*758e9fbaSOystein Eftevaag (void) argv;
294*758e9fbaSOystein Eftevaag
295*758e9fbaSOystein Eftevaag const struct CMUnitTest tests[] = {
296*758e9fbaSOystein Eftevaag /* Layer tests */
297*758e9fbaSOystein Eftevaag cmocka_unit_test(test_layers),
298*758e9fbaSOystein Eftevaag cmocka_unit_test(test_tpm_format_0_version2_0_error),
299*758e9fbaSOystein Eftevaag cmocka_unit_test(test_tpm_format_0_version2_0_warn),
300*758e9fbaSOystein Eftevaag cmocka_unit_test(test_tpm2_format_0_unknown),
301*758e9fbaSOystein Eftevaag cmocka_unit_test(test_tpm_format_1_unk_handle),
302*758e9fbaSOystein Eftevaag cmocka_unit_test(test_tpm_format_1_unk_parameter),
303*758e9fbaSOystein Eftevaag cmocka_unit_test(test_tpm_format_1_unk_session),
304*758e9fbaSOystein Eftevaag cmocka_unit_test(test_tpm_format_1_5_handle),
305*758e9fbaSOystein Eftevaag cmocka_unit_test(test_tpm2_format_1_unknown),
306*758e9fbaSOystein Eftevaag cmocka_unit_test(test_tpm2_format_1_success),
307*758e9fbaSOystein Eftevaag cmocka_unit_test(test_custom_handler),
308*758e9fbaSOystein Eftevaag cmocka_unit_test(test_zero_length_name),
309*758e9fbaSOystein Eftevaag cmocka_unit_test(test_over_length_name),
310*758e9fbaSOystein Eftevaag cmocka_unit_test(test_null_name),
311*758e9fbaSOystein Eftevaag cmocka_unit_test(test_sys),
312*758e9fbaSOystein Eftevaag cmocka_unit_test(test_esys),
313*758e9fbaSOystein Eftevaag cmocka_unit_test(test_mu),
314*758e9fbaSOystein Eftevaag cmocka_unit_test(test_tcti),
315*758e9fbaSOystein Eftevaag };
316*758e9fbaSOystein Eftevaag
317*758e9fbaSOystein Eftevaag return cmocka_run_group_tests(tests, NULL, NULL);
318*758e9fbaSOystein Eftevaag }
319