1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2025 Oxide Computer Company
14 */
15
16 /*
17 * Basic tests for the SMBIOS Type 43 TPM
18 */
19
20 #include "smbios_test.h"
21
22 static const uint8_t smbios_tpm_vid[4] = { 't', 'r', 'a', 'p' };
23 static const char *smbios_tpm_desc = "Very Secure";
24 static const uint8_t smbios_tpm_major = 0x23;
25 static const uint8_t smbios_tpm_minor = 0x42;
26 static const uint32_t smbios_tpm_fwv1 = 0xff7777;
27 static const uint32_t smbios_tpm_fwv2 = 0x1234567;
28 static const uint64_t smbios_tpm_chars = 0xf0e1d2c3b4a59687;
29 static const uint32_t smbios_tpm_oem = 0xdeadbeef;
30
31 boolean_t
smbios_test_tpm_mktable_short(smbios_test_table_t * table)32 smbios_test_tpm_mktable_short(smbios_test_table_t *table)
33 {
34 smb_tpm_t tpm;
35
36 arc4random_buf(&tpm, sizeof (tpm));
37 tpm.smbtpm_hdr.smbh_type = SMB_TYPE_TPM;
38 tpm.smbtpm_hdr.smbh_len = sizeof (tpm) / 2;
39 (void) smbios_test_table_append(table, &tpm, sizeof (tpm) / 2);
40 smbios_test_table_append_eot(table);
41
42 return (B_TRUE);
43 }
44
45 boolean_t
smbios_test_tpm_mktable(smbios_test_table_t * table)46 smbios_test_tpm_mktable(smbios_test_table_t *table)
47 {
48 smb_tpm_t tpm;
49
50 bzero(&tpm, sizeof (tpm));
51 tpm.smbtpm_hdr.smbh_type = SMB_TYPE_TPM;
52 tpm.smbtpm_hdr.smbh_len = sizeof (tpm);
53 bcopy(smbios_tpm_vid, tpm.smbtpm_vid, sizeof (smbios_tpm_vid));
54 tpm.smbtpm_major = smbios_tpm_major;
55 tpm.smbtpm_minor = smbios_tpm_minor;
56 tpm.smbtpm_fwv1 = smbios_tpm_fwv1;
57 tpm.smbtpm_fwv2 = smbios_tpm_fwv2;
58 tpm.smbtpm_desc = 1;
59 tpm.smbtpm_chars = smbios_tpm_chars;
60 tpm.smbtpm_oem = smbios_tpm_oem;
61
62 (void) smbios_test_table_append(table, &tpm, sizeof (tpm));
63 smbios_test_table_append_string(table, smbios_tpm_desc);
64 smbios_test_table_str_fini(table);
65 smbios_test_table_append_eot(table);
66
67 return (B_TRUE);
68 }
69
70 boolean_t
smbios_test_tpm_verify_short(smbios_hdl_t * hdl)71 smbios_test_tpm_verify_short(smbios_hdl_t *hdl)
72 {
73 smbios_struct_t sp;
74 smbios_tpm_t tpm;
75
76 if (smbios_lookup_type(hdl, SMB_TYPE_TPM, &sp) == -1) {
77 warnx("failed to lookup SMBIOS tpm: %s",
78 smbios_errmsg(smbios_errno(hdl)));
79 return (B_FALSE);
80 }
81
82 if (smbios_info_tpm(hdl, sp.smbstr_id, &tpm) != -1) {
83 warnx("accidentally parsed invalid tpm as valid");
84 return (B_FALSE);
85 }
86
87 if (smbios_errno(hdl) != ESMB_SHORT) {
88 warnx("encountered wrong error for chassis, expected: "
89 "0x%x, found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
90 return (B_FALSE);
91 }
92
93 return (B_TRUE);
94 }
95
96 boolean_t
smbios_test_tpm_verify_badtype(smbios_hdl_t * hdl)97 smbios_test_tpm_verify_badtype(smbios_hdl_t *hdl)
98 {
99 smbios_struct_t sp;
100 smbios_tpm_t tpm;
101
102 if (smbios_lookup_type(hdl, SMB_TYPE_MEMDEVICE, &sp) == -1) {
103 warnx("failed to lookup SMBIOS memory device: %s",
104 smbios_errmsg(smbios_errno(hdl)));
105 return (B_FALSE);
106 }
107
108 if (smbios_info_tpm(hdl, sp.smbstr_id, &tpm) != -1) {
109 warnx("accidentally parsed invalid tpm information as "
110 "valid");
111 return (B_FALSE);
112 }
113
114 if (smbios_errno(hdl) != ESMB_TYPE) {
115 warnx("encountered wrong error for tpm, expected: "
116 "0x%x, found: 0x%x", ESMB_TYPE, smbios_errno(hdl));
117 return (B_FALSE);
118 }
119
120 return (B_TRUE);
121 }
122
123 boolean_t
smbios_test_tpm_verify(smbios_hdl_t * hdl)124 smbios_test_tpm_verify(smbios_hdl_t *hdl)
125 {
126 smbios_struct_t sp;
127 smbios_tpm_t tpm;
128 boolean_t ret = B_TRUE;
129
130 if (smbios_lookup_type(hdl, SMB_TYPE_TPM, &sp) == -1) {
131 warnx("failed to lookup SMBIOS tpm: %s",
132 smbios_errmsg(smbios_errno(hdl)));
133 return (B_FALSE);
134 }
135
136 if (smbios_info_tpm(hdl, sp.smbstr_id, &tpm) == -1) {
137 warnx("failed to get tpm: %s",
138 smbios_errmsg(smbios_errno(hdl)));
139 return (B_FALSE);
140 }
141
142 if (strcmp(tpm.smbtpm_desc, smbios_tpm_desc) != 0) {
143 warnx("tpm description mismatch: found %s, expected %s",
144 tpm.smbtpm_desc, smbios_tpm_desc);
145 ret = B_FALSE;
146 }
147
148 if (bcmp(tpm.smbtpm_vid, smbios_tpm_vid, sizeof (smbios_tpm_vid)) !=
149 0) {
150 warnx("tpm vendor mismatch: found \\x%2x \\x%2x \\x%2x \\x%2x",
151 tpm.smbtpm_vid[0], tpm.smbtpm_vid[1],
152 tpm.smbtpm_vid[2], tpm.smbtpm_vid[3]);
153 ret = B_FALSE;
154 }
155
156 if (tpm.smbtpm_major != smbios_tpm_major) {
157 warnx("tpm major version mismatch: found 0x%x, expected 0x%x",
158 tpm.smbtpm_major, smbios_tpm_major);
159 ret = B_FALSE;
160 }
161
162 if (tpm.smbtpm_minor != smbios_tpm_minor) {
163 warnx("tpm minor version mismatch: found 0x%x, expected 0x%x",
164 tpm.smbtpm_minor, smbios_tpm_minor);
165 ret = B_FALSE;
166 }
167
168 if (tpm.smbtpm_fwv1 != smbios_tpm_fwv1) {
169 warnx("tpm firmware version 1 mismatch: found 0x%x, "
170 "expected 0x%x", tpm.smbtpm_fwv1, smbios_tpm_fwv1);
171 ret = B_FALSE;
172 }
173
174 if (tpm.smbtpm_fwv2 != smbios_tpm_fwv2) {
175 warnx("tpm firmware version 2 mismatch: found 0x%x, "
176 "expected 0x%x", tpm.smbtpm_fwv2, smbios_tpm_fwv2);
177 ret = B_FALSE;
178 }
179
180 if (tpm.smbtpm_chars != smbios_tpm_chars) {
181 warnx("tpm characteristics mismatch: found 0x%" PRIx64
182 ", expected 0x%" PRIx64, tpm.smbtpm_chars,
183 smbios_tpm_chars);
184 ret = B_FALSE;
185 }
186
187 if (tpm.smbtpm_oem != smbios_tpm_oem) {
188 warnx("tpm OEM-defined mismatch: found 0x%x, expected 0x%x",
189 tpm.smbtpm_oem, smbios_tpm_oem);
190 ret = B_FALSE;
191 }
192
193 return (ret);
194 }
195