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 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 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 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 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 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