]>
Commit | Line | Data |
---|---|---|
af69267c HS |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * efi_selftest_devicepath | |
4 | * | |
5 | * Copyright (c) 2020 Heinrich Schuchardt <[email protected]> | |
6 | * | |
7 | * Test the EFI_TCG2_PROTOCOL | |
8 | */ | |
9 | ||
10 | #include <efi_selftest.h> | |
11 | #include <efi_tcg2.h> | |
aa1b5049 MK |
12 | /* |
13 | * Include containing the miniapp.efi application. | |
14 | * Note that tcg2 selftest measures the PE/COFF image, | |
15 | * so we must have the pre-build efi application for | |
16 | * each architecture. | |
17 | */ | |
18 | #if defined(__arm__) | |
19 | #include "efi_miniapp_tcg2_arm.h" | |
20 | #elif defined(__aarch64__) | |
21 | #include "efi_miniapp_tcg2_arm64.h" | |
22 | #elif defined(__i386__) | |
23 | #include "efi_miniapp_tcg2_ia32.h" | |
24 | #elif defined(__x86_64__) | |
25 | #include "efi_miniapp_tcg2_x86_64.h" | |
26 | #elif defined(__riscv) && (__riscv_xlen == 32) | |
27 | #include "efi_miniapp_tcg2_riscv32.h" | |
28 | #elif defined(__riscv) && (__riscv_xlen == 64) | |
29 | #include "efi_miniapp_tcg2_riscv64.h" | |
30 | #endif | |
31 | ||
32 | #include <linux/unaligned/be_byteshift.h> | |
33 | #include <linux/unaligned/le_byteshift.h> | |
34 | #include <mapmem.h> | |
35 | #include <smbios.h> | |
36 | #include <tables_csum.h> | |
af69267c HS |
37 | |
38 | static struct efi_boot_services *boottime; | |
39 | static const efi_guid_t guid_tcg2 = EFI_TCG2_PROTOCOL_GUID; | |
40 | ||
aa1b5049 MK |
41 | /* Block size of compressed disk image */ |
42 | #define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8 | |
43 | ||
44 | static efi_handle_t image_handle; | |
45 | /* Decompressed file image */ | |
46 | static u8 *image; | |
47 | ||
48 | /* One 8 byte block of the compressed disk image */ | |
49 | struct line { | |
50 | size_t addr; | |
51 | char *line; | |
52 | }; | |
53 | ||
54 | /* Compressed file image */ | |
55 | struct compressed_file_image { | |
56 | size_t length; | |
57 | struct line lines[]; | |
58 | }; | |
59 | ||
60 | static struct compressed_file_image img = EFI_ST_DISK_IMG; | |
61 | ||
62 | static struct efi_tcg2_event *efi_tcg2_event; | |
63 | ||
64 | static struct efi_runtime_services *runtime; | |
65 | #define BOOT_NAME_1000 u"Boot1000" | |
66 | #define BOOT_NAME_1001 u"Boot1001" | |
67 | #define BOOT_NAME_1002 u"Boot1002" | |
68 | ||
69 | #define DEFAULT_ATTR (EFI_VARIABLE_NON_VOLATILE | \ | |
70 | EFI_VARIABLE_BOOTSERVICE_ACCESS | \ | |
71 | EFI_VARIABLE_RUNTIME_ACCESS) | |
72 | ||
73 | /* "efidebug boot add -b 1000 test1000 virtio 0:1 /EFI/debian/grubaa64.efi" */ | |
74 | static const u8 boot_1000[] = { | |
75 | 0x01, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, | |
76 | 0x74, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x04, 0x14, 0x00, 0xb9, 0x73, | |
77 | 0x1d, 0xe6, 0x84, 0xa3, 0xcc, 0x4a, 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, | |
78 | 0x62, 0x8b, 0x01, 0x04, 0x15, 0x00, 0x92, 0x37, 0x29, 0x63, 0xf5, 0xad, | |
79 | 0x25, 0x93, 0xb9, 0x9f, 0x4e, 0x0e, 0x45, 0x5c, 0x1b, 0x1e, 0x00, 0x04, | |
80 | 0x01, 0x2a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, | |
81 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, | |
82 | 0x5a, 0x47, 0xc2, 0x35, 0x27, 0x44, 0x47, 0x9f, 0x01, 0x67, 0xfe, 0xfa, | |
83 | 0x1d, 0x06, 0xae, 0x02, 0x02, 0x04, 0x04, 0x36, 0x00, 0x5c, 0x00, 0x45, | |
84 | 0x00, 0x46, 0x00, 0x49, 0x00, 0x5c, 0x00, 0x64, 0x00, 0x65, 0x00, 0x62, | |
85 | 0x00, 0x69, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x5c, 0x00, 0x67, 0x00, 0x72, | |
86 | 0x00, 0x75, 0x00, 0x62, 0x00, 0x61, 0x00, 0x61, 0x00, 0x36, 0x00, 0x34, | |
87 | 0x00, 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00, 0x00, 0x00, 0x7f, | |
88 | 0xff, 0x04, 0x00 }; | |
89 | ||
90 | /* "efidebug boot add -b 1001 test1001 virtio 0:1 /EFI/debian/grubaa64.efi" */ | |
91 | static const u8 boot_1001[] = { | |
92 | 0x01, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, | |
93 | 0x74, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x04, 0x14, 0x00, 0xb9, 0x73, | |
94 | 0x1d, 0xe6, 0x84, 0xa3, 0xcc, 0x4a, 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, | |
95 | 0x62, 0x8b, 0x01, 0x04, 0x15, 0x00, 0x92, 0x37, 0x29, 0x63, 0xf5, 0xad, | |
96 | 0x25, 0x93, 0xb9, 0x9f, 0x4e, 0x0e, 0x45, 0x5c, 0x1b, 0x1e, 0x00, 0x04, | |
97 | 0x01, 0x2a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, | |
98 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, | |
99 | 0x5a, 0x47, 0xc2, 0x35, 0x27, 0x44, 0x47, 0x9f, 0x01, 0x67, 0xfe, 0xfa, | |
100 | 0x1d, 0x06, 0xae, 0x02, 0x02, 0x04, 0x04, 0x36, 0x00, 0x5c, 0x00, 0x45, | |
101 | 0x00, 0x46, 0x00, 0x49, 0x00, 0x5c, 0x00, 0x64, 0x00, 0x65, 0x00, 0x62, | |
102 | 0x00, 0x69, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x5c, 0x00, 0x67, 0x00, 0x72, | |
103 | 0x00, 0x75, 0x00, 0x62, 0x00, 0x61, 0x00, 0x61, 0x00, 0x36, 0x00, 0x34, | |
104 | 0x00, 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00, 0x00, 0x00, 0x7f, | |
105 | 0xff, 0x04, 0x00 }; | |
106 | ||
107 | /* "efidebug boot add -b 1002 test1002 virtio 0:1 /EFI/debian/grubaa64.efi" */ | |
108 | static const u8 boot_1002[] = { | |
109 | 0x01, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, | |
110 | 0x74, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x04, 0x14, 0x00, 0xb9, 0x73, | |
111 | 0x1d, 0xe6, 0x84, 0xa3, 0xcc, 0x4a, 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, | |
112 | 0x62, 0x8b, 0x01, 0x04, 0x15, 0x00, 0x92, 0x37, 0x29, 0x63, 0xf5, 0xad, | |
113 | 0x25, 0x93, 0xb9, 0x9f, 0x4e, 0x0e, 0x45, 0x5c, 0x1b, 0x1e, 0x00, 0x04, | |
114 | 0x01, 0x2a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, | |
115 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, | |
116 | 0x5a, 0x47, 0xc2, 0x35, 0x27, 0x44, 0x47, 0x9f, 0x01, 0x67, 0xfe, 0xfa, | |
117 | 0x1d, 0x06, 0xae, 0x02, 0x02, 0x04, 0x04, 0x36, 0x00, 0x5c, 0x00, 0x45, | |
118 | 0x00, 0x46, 0x00, 0x49, 0x00, 0x5c, 0x00, 0x64, 0x00, 0x65, 0x00, 0x62, | |
119 | 0x00, 0x69, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x5c, 0x00, 0x67, 0x00, 0x72, | |
120 | 0x00, 0x75, 0x00, 0x62, 0x00, 0x61, 0x00, 0x61, 0x00, 0x36, 0x00, 0x34, | |
121 | 0x00, 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00, 0x00, 0x00, 0x7f, | |
122 | 0xff, 0x04, 0x00}; | |
123 | ||
124 | /* "efidebug boot order 1002 1000 1001" */ | |
125 | static u8 boot_order[] = {0x02, 0x10, 0x00, 0x10, 0x01, 0x10}; | |
126 | ||
127 | static void *orig_smbios_table; | |
128 | static u64 dmi_addr = U32_MAX; | |
2497f6a8 | 129 | #define SMBIOS3_ENTRY_HEADER_SIZE 0x18 |
aa1b5049 | 130 | /* smbios table for the measurement test */ |
2497f6a8 MK |
131 | static u8 smbios3_table_test[] = { |
132 | 0x5f, 0x53, 0x4d, 0x33, 0x5f, 0x00, 0x18, 0x03, 0x07, 0x00, 0x01, 0x00, | |
133 | 0x5c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
134 | 0x00, 0x18, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x03, 0x00, 0x80, 0x08, | |
135 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x15, 0x0a, 0xff, 0xff, | |
136 | 0x55, 0x2d, 0x42, 0x6f, 0x6f, 0x74, 0x00, 0x32, 0x30, 0x32, 0x31, 0x2e, | |
137 | 0x31, 0x30, 0x2d, 0x72, 0x63, 0x34, 0x2d, 0x30, 0x30, 0x30, 0x30, 0x35, | |
138 | 0x2d, 0x67, 0x37, 0x32, 0x37, 0x63, 0x33, 0x66, 0x33, 0x32, 0x35, 0x39, | |
139 | 0x2d, 0x64, 0x69, 0x72, 0x74, 0x79, 0x00, 0x31, 0x30, 0x2f, 0x30, 0x31, | |
140 | 0x2f, 0x32, 0x30, 0x32, 0x31, 0x00, 0x00, 0x01, 0x1b, 0x01, 0x00, 0x01, | |
141 | 0x02, 0x00, 0x03, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, | |
142 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x55, 0x6e, | |
143 | 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, | |
144 | 0x6e, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x31, 0x32, | |
145 | 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x02, 0x0e, 0x02, 0x00, | |
146 | 0x01, 0x02, 0x00, 0x04, 0x03, 0x01, 0x01, 0x01, 0x00, 0x0a, 0x55, 0x6e, | |
147 | 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, | |
148 | 0x6e, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x33, 0x33, | |
149 | 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, | |
150 | 0x36, 0x37, 0x38, 0x00, 0x00, 0x03, 0x15, 0x03, 0x00, 0x01, 0x03, 0x00, | |
151 | 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
152 | 0x00, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32, | |
153 | 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, | |
154 | 0x33, 0x33, 0x33, 0x00, 0x00, 0x04, 0x30, 0x04, 0x00, 0x00, 0x03, 0x02, | |
155 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, | |
156 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, | |
157 | 0xff, 0x02, 0x03, 0x04, 0x04, 0x04, 0x08, 0x00, 0x00, 0x02, 0x00, 0x08, | |
158 | 0x00, 0x08, 0x00, 0x01, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, | |
159 | 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33, | |
160 | 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x35, 0x35, 0x35, 0x35, 0x35, | |
161 | 0x35, 0x35, 0x35, 0x00, 0x00, 0x20, 0x0b, 0x05, 0x00, 0x00, 0x00, 0x00, | |
162 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x04, 0x06, 0x00, 0x00, 0x00 | |
aa1b5049 MK |
163 | }; |
164 | ||
165 | #define IDX_ARRAY_SZ 3 /* support 24 PCRs */ | |
166 | #define TPM2_CMD_BUF_SIZE 64 | |
167 | /* TPM command is big endian */ | |
168 | #define __MSB(x) ((x) >> 8) | |
169 | #define __LSB(x) ((x) & 0xFF) | |
170 | #define tpm_u16(x) __MSB(x), __LSB(x) | |
171 | #define tpm_u32(x) tpm_u16((x) >> 16), tpm_u16((x) & 0xFFFF) | |
172 | #define TPM2_PCR_READ_HEADER_SIZE 30 | |
173 | ||
174 | static u8 (*pcrs)[TPM2_SHA256_DIGEST_SIZE]; | |
175 | static u8 expected_pcrs[EFI_TCG2_MAX_PCR_INDEX + 1][TPM2_SHA256_DIGEST_SIZE] = { | |
176 | {0x91, 0x21, 0x37, 0xc7, 0x1a, 0x49, 0x19, 0xc8, | |
177 | 0xf1, 0xfb, 0xa9, 0x84, 0x5c, 0x65, 0xa9, 0xdd, | |
178 | 0x7b, 0xb9, 0xfe, 0xa1, 0xcd, 0x64, 0x49, 0xdd, | |
179 | 0xed, 0xe2, 0x65, 0x82, 0xc5, 0x3e, 0xf4, 0xc4}, | |
180 | ||
2497f6a8 MK |
181 | {0x75, 0xb5, 0x91, 0x54, 0x12, 0xa8, 0xa4, 0x25, |
182 | 0x73, 0x79, 0xa7, 0x47, 0xd9, 0x32, 0x54, 0x78, | |
183 | 0x9a, 0x80, 0x3f, 0xa8, 0x34, 0xfe, 0xd2, 0xae, | |
184 | 0x76, 0xd3, 0x16, 0x4a, 0xb2, 0x03, 0xac, 0xe6}, | |
aa1b5049 MK |
185 | |
186 | {0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, | |
187 | 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, | |
188 | 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, | |
189 | 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, | |
190 | ||
191 | {0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, | |
192 | 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, | |
193 | 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, | |
194 | 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, | |
195 | ||
196 | /* PCR[4] is different per architecture */ | |
197 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
198 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
199 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
200 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
201 | ||
202 | {0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, | |
203 | 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, | |
204 | 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, | |
205 | 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, | |
206 | ||
207 | /* PCR[6] is different per architecture */ | |
208 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
209 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
210 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
211 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
212 | ||
213 | {0x96, 0x74, 0xae, 0xcd, 0x3f, 0x40, 0xb4, 0xa9, | |
214 | 0x36, 0xae, 0x19, 0xc8, 0x84, 0x8a, 0xb9, 0x5a, | |
215 | 0x87, 0x99, 0xd8, 0x89, 0x7f, 0xfc, 0x40, 0x48, | |
216 | 0x05, 0x99, 0x65, 0x2e, 0x55, 0xd4, 0x93, 0x32}, | |
217 | ||
218 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
219 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
220 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
221 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
222 | ||
223 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
224 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
225 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
226 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
227 | ||
228 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
229 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
230 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
232 | ||
233 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
234 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
235 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
237 | ||
238 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
239 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
240 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
241 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
242 | ||
243 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
244 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
245 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
246 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
247 | ||
248 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
249 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
250 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
251 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
252 | ||
253 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
254 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
255 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
256 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
257 | ||
258 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
259 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
260 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
261 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
262 | ||
263 | {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
264 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
265 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
266 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, | |
267 | ||
268 | {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
269 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
270 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
271 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, | |
272 | ||
273 | {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
274 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
275 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
276 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, | |
277 | ||
278 | {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
279 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
280 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
281 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, | |
282 | ||
283 | {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
284 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
285 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
286 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, | |
287 | ||
288 | {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
289 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
290 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
291 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, | |
292 | ||
293 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
294 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
295 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
296 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} | |
297 | }; | |
298 | ||
299 | /* | |
300 | * PCR[4] and PCR[6] have the PE/COFF image measurement, | |
301 | * this PCRs have different value in each architecture. | |
302 | */ | |
303 | #if defined(__arm__) | |
304 | static u8 expected_pcrs_per_arch[][TPM2_SHA256_DIGEST_SIZE] = { | |
305 | /* PCR[4] */ | |
306 | {0xcd, 0xa2, 0x06, 0xad, 0x83, 0x9b, 0x8f, 0x92, | |
307 | 0x01, 0xf9, 0xc8, 0x3d, 0xc9, 0x54, 0x66, 0xb3, | |
308 | 0x97, 0x35, 0x88, 0xe1, 0xea, 0xd3, 0x1a, 0xd6, | |
309 | 0x56, 0xee, 0x43, 0x1c, 0xdb, 0x4b, 0xf9, 0x1f}, | |
310 | /* PCR[6] */ | |
311 | {0x9c, 0xb8, 0x9d, 0x4a, 0xf6, 0x63, 0x95, 0xb0, | |
312 | 0x95, 0xfe, 0x44, 0x30, 0x0f, 0x3a, 0x0b, 0x7c, | |
313 | 0xef, 0xc7, 0xb6, 0x6a, 0x59, 0xae, 0xcb, 0xf6, | |
314 | 0xbd, 0x2d, 0xb5, 0xb9, 0xb4, 0x95, 0x7d, 0xaf} | |
315 | }; | |
316 | #elif defined(__aarch64__) | |
317 | static u8 expected_pcrs_per_arch[][TPM2_SHA256_DIGEST_SIZE] = { | |
318 | /* PCR[4] */ | |
319 | {0x69, 0xdb, 0x01, 0x5e, 0x07, 0xed, 0x9c, 0xbb, | |
320 | 0x27, 0x65, 0xb1, 0xf0, 0x7b, 0x04, 0xbc, 0x31, | |
321 | 0xd1, 0xec, 0x00, 0xe4, 0xe1, 0x49, 0xdb, 0x1e, | |
322 | 0x8b, 0x2d, 0xa2, 0x26, 0xb5, 0x8d, 0x07, 0xe2}, | |
323 | /* PCR[6] */ | |
324 | {0x53, 0x1b, 0x27, 0xb2, 0x6f, 0x2d, 0xab, 0x9b, | |
325 | 0x6f, 0xbc, 0xd1, 0x8f, 0xc9, 0x14, 0x48, 0xe7, | |
326 | 0x6d, 0x1b, 0xfb, 0x1b, 0x53, 0xc5, 0x8e, 0xf4, | |
327 | 0x41, 0x50, 0x79, 0x24, 0x66, 0x57, 0x7b, 0xf8} | |
328 | }; | |
329 | #elif defined(__i386__) | |
330 | static u8 expected_pcrs_per_arch[][TPM2_SHA256_DIGEST_SIZE] = { | |
331 | /* PCR[4] */ | |
332 | {0xec, 0x5e, 0xdb, 0x68, 0x13, 0x48, 0x36, 0x0a, | |
333 | 0x3a, 0xbc, 0x7b, 0x7b, 0xbc, 0x74, 0x7a, 0xa5, | |
334 | 0x55, 0xea, 0xb9, 0x09, 0x6a, 0x6e, 0xc3, 0x21, | |
335 | 0x51, 0x46, 0x22, 0xd2, 0x9d, 0xc9, 0xd5, 0x6a}, | |
336 | /* PCR[6] */ | |
337 | {0x26, 0x14, 0xe7, 0xde, 0x91, 0xd1, 0xf3, 0xde, | |
338 | 0x7a, 0xc2, 0x78, 0xaf, 0x4b, 0x2e, 0x05, 0x9d, | |
339 | 0x35, 0x17, 0xee, 0xcc, 0x0e, 0x77, 0x8d, 0x3f, | |
340 | 0x7e, 0x20, 0x75, 0xfa, 0xbc, 0xbc, 0x24, 0x3e} | |
341 | }; | |
342 | #elif defined(__x86_64__) | |
343 | static u8 expected_pcrs_per_arch[][TPM2_SHA256_DIGEST_SIZE] = { | |
344 | /* PCR[4] */ | |
345 | {0x9a, 0x75, 0x99, 0x8b, 0x74, 0x45, 0xb6, 0x26, | |
346 | 0x50, 0xe0, 0xbb, 0xfa, 0x2a, 0xa6, 0x19, 0xec, | |
347 | 0x97, 0x12, 0x0c, 0xb5, 0xc8, 0x2a, 0xfe, 0xe5, | |
348 | 0x29, 0xc8, 0xd3, 0x98, 0xe9, 0xd1, 0x9d, 0xd5}, | |
349 | /* PCR[6] */ | |
350 | {0xa2, 0xa2, 0xd3, 0xa7, 0x84, 0xc2, 0x95, 0x2a, | |
351 | 0xab, 0x6f, 0xe7, 0xe8, 0x86, 0x9f, 0x99, 0xc6, | |
352 | 0x6a, 0x8c, 0xcc, 0x5c, 0xb8, 0x83, 0xfa, 0x86, | |
353 | 0x56, 0x5e, 0x91, 0x17, 0x0b, 0x5f, 0x54, 0xa8} | |
354 | }; | |
355 | #elif defined(__riscv) && (__riscv_xlen == 32) | |
356 | static u8 expected_pcrs_per_arch[][TPM2_SHA256_DIGEST_SIZE] = { | |
357 | /* PCR[4] */ | |
358 | {0x64, 0xe9, 0x25, 0xb3, 0xd8, 0x33, 0xb3, 0x1b, | |
359 | 0x74, 0x0c, 0x81, 0x45, 0xef, 0x61, 0xf1, 0x87, | |
360 | 0xef, 0x65, 0x67, 0x28, 0x1a, 0x54, 0x97, 0xb2, | |
361 | 0xd3, 0x62, 0x00, 0xe7, 0xb6, 0x7a, 0xd5, 0x8e}, | |
362 | /* PCR[6] */ | |
363 | {0x82, 0xab, 0xc5, 0x6a, 0xbf, 0x08, 0x43, 0x3f, | |
364 | 0x85, 0xbd, 0x8f, 0x8e, 0x23, 0x62, 0x48, 0x4a, | |
365 | 0x44, 0x53, 0xf0, 0xae, 0x8d, 0x4c, 0xda, 0x04, | |
366 | 0x89, 0x9c, 0x0b, 0x81, 0x3a, 0x53, 0xf3, 0xac} | |
367 | }; | |
368 | #elif defined(__riscv) && (__riscv_xlen == 64) | |
369 | static u8 expected_pcrs_per_arch[][TPM2_SHA256_DIGEST_SIZE] = { | |
370 | /* PCR[4] */ | |
371 | {0x9b, 0x5f, 0x10, 0x24, 0x28, 0x5d, 0x7d, 0x1f, | |
372 | 0x9f, 0xee, 0xe9, 0x90, 0xf1, 0x7a, 0x03, 0xb1, | |
373 | 0x68, 0x7b, 0x28, 0x45, 0x98, 0x5e, 0xf5, 0x5e, | |
374 | 0xc1, 0x22, 0x61, 0x8c, 0x2f, 0xb5, 0xbf, 0x80}, | |
375 | /* PCR[6] */ | |
376 | {0x6d, 0x16, 0x17, 0xf4, 0x9a, 0xa8, 0x49, 0xc2, | |
377 | 0xf4, 0x9c, 0x35, 0x30, 0x0c, 0xde, 0x65, 0xdb, | |
378 | 0xd3, 0x37, 0x9c, 0xe2, 0x9f, 0x14, 0x81, 0x74, | |
379 | 0xc3, 0x94, 0x8a, 0x9e, 0x26, 0xbf, 0xfb, 0xb2} | |
380 | }; | |
381 | #endif | |
382 | ||
383 | struct boot_variable { | |
384 | u16 name[16]; | |
385 | u8 *buf; | |
386 | efi_uintn_t size; | |
387 | u32 attr; | |
388 | const u8 *test_data; | |
389 | efi_uintn_t test_data_size; | |
390 | }; | |
391 | ||
392 | static struct boot_variable boot_variable_test[] = { | |
393 | {u"BootOrder", NULL, 0, DEFAULT_ATTR, boot_order, sizeof(boot_order)}, | |
394 | {BOOT_NAME_1000, NULL, 0, DEFAULT_ATTR, boot_1000, sizeof(boot_1000)}, | |
395 | {BOOT_NAME_1001, NULL, 0, DEFAULT_ATTR, boot_1001, sizeof(boot_1001)}, | |
396 | {BOOT_NAME_1002, NULL, 0, DEFAULT_ATTR, boot_1002, sizeof(boot_1002)}, | |
397 | }; | |
398 | ||
399 | /* | |
400 | * efi_status_t decompress() - Decompress the disk image. | |
401 | * | |
402 | * @image decompressed disk image | |
185f812c | 403 | * Return: status code |
aa1b5049 MK |
404 | */ |
405 | static efi_status_t decompress(u8 **image) | |
406 | { | |
407 | u8 *buf; | |
408 | size_t i; | |
409 | size_t addr; | |
410 | size_t len; | |
411 | efi_status_t ret; | |
412 | ||
413 | ret = boottime->allocate_pool(EFI_LOADER_DATA, img.length, | |
414 | (void **)&buf); | |
415 | if (ret != EFI_SUCCESS) { | |
416 | efi_st_error("Out of memory\n"); | |
417 | return ret; | |
418 | } | |
419 | boottime->set_mem(buf, img.length, 0); | |
420 | ||
421 | for (i = 0; ; ++i) { | |
422 | if (!img.lines[i].line) | |
423 | break; | |
424 | addr = img.lines[i].addr; | |
425 | len = COMPRESSED_DISK_IMAGE_BLOCK_SIZE; | |
426 | if (addr + len > img.length) | |
427 | len = img.length - addr; | |
428 | boottime->copy_mem(buf + addr, img.lines[i].line, len); | |
429 | } | |
430 | *image = buf; | |
431 | return ret; | |
432 | } | |
433 | ||
434 | /* | |
435 | * efi_status_t setup_boot_variable() - configure dummy boot variables | |
436 | * | |
437 | * Preexisting variable values are saved and will be restored by | |
438 | * calling restore_boot_variable(). | |
439 | * | |
185f812c | 440 | * Return: status code |
aa1b5049 MK |
441 | */ |
442 | static efi_status_t setup_boot_variable(void) | |
443 | { | |
444 | efi_status_t ret; | |
445 | u32 i; | |
446 | efi_uintn_t size; | |
447 | ||
448 | for (i = 0; i < ARRAY_SIZE(boot_variable_test); i++) { | |
449 | size = 0; | |
450 | ret = runtime->get_variable(boot_variable_test[i].name, | |
451 | &efi_global_variable_guid, | |
452 | &boot_variable_test[i].attr, | |
453 | &size, | |
454 | NULL); | |
455 | if (ret == EFI_BUFFER_TOO_SMALL) { | |
456 | /* Variable exists, save the current value */ | |
457 | boot_variable_test[i].size = size; | |
458 | ret = boottime->allocate_pool(EFI_LOADER_DATA, | |
459 | boot_variable_test[i].size, | |
460 | (void **)&boot_variable_test[i].buf); | |
461 | if (ret != EFI_SUCCESS) { | |
462 | efi_st_error("Failed to allocate buffer for boot variable\n"); | |
463 | return ret; | |
464 | } | |
465 | ret = runtime->get_variable(boot_variable_test[i].name, | |
466 | &efi_global_variable_guid, | |
467 | &boot_variable_test[i].attr, | |
468 | &boot_variable_test[i].size, | |
469 | boot_variable_test[i].buf); | |
470 | if (ret != EFI_SUCCESS) { | |
471 | efi_st_error("Failed to get current boot variable\n"); | |
472 | return ret; | |
473 | } | |
474 | } | |
475 | ||
476 | /* set boot variable for the measurement test */ | |
477 | ret = runtime->set_variable(boot_variable_test[i].name, | |
478 | &efi_global_variable_guid, | |
479 | boot_variable_test[i].attr, | |
480 | boot_variable_test[i].test_data_size, | |
481 | boot_variable_test[i].test_data); | |
482 | if (ret != EFI_SUCCESS) { | |
483 | efi_st_error("Failed to set test boot variable(%d)n", i); | |
484 | return ret; | |
485 | } | |
486 | } | |
487 | ||
488 | return 0; | |
489 | } | |
490 | ||
491 | /* | |
492 | * efi_status_t restore_boot_variable() - restore original values | |
493 | * | |
494 | * Restore the variable values saved in setup_boot_variable(). | |
495 | * | |
185f812c | 496 | * Return: status code |
aa1b5049 MK |
497 | */ |
498 | static efi_status_t restore_boot_variable(void) | |
499 | { | |
500 | int i; | |
501 | efi_status_t ret; | |
502 | ||
503 | for (i = 0; i < ARRAY_SIZE(boot_variable_test); i++) { | |
504 | if (boot_variable_test[i].buf) { | |
505 | ret = runtime->set_variable(boot_variable_test[i].name, | |
506 | &efi_global_variable_guid, | |
507 | boot_variable_test[i].attr, | |
508 | boot_variable_test[i].size, | |
509 | boot_variable_test[i].buf); | |
510 | if (ret != EFI_SUCCESS) { | |
511 | efi_st_error("Failed to restore boot variable\n"); | |
512 | return ret; | |
513 | } | |
514 | ret = boottime->free_pool(boot_variable_test[i].buf); | |
515 | if (ret != EFI_SUCCESS) { | |
516 | efi_st_error("Failed to free boot variable\n"); | |
517 | return ret; | |
518 | } | |
519 | } else { | |
520 | /* delete the variable used only for testing */ | |
521 | ret = runtime->set_variable(boot_variable_test[i].name, | |
522 | &efi_global_variable_guid, | |
523 | 0, 0, NULL); | |
524 | if (ret != EFI_SUCCESS) { | |
525 | efi_st_error("Failed to delete boot variable\n"); | |
526 | return ret; | |
527 | } | |
528 | } | |
529 | } | |
530 | ||
531 | return EFI_SUCCESS; | |
532 | } | |
533 | ||
534 | /** | |
535 | * void *find_smbios_table() - Find smbios table | |
536 | * | |
537 | * @systable system table | |
185f812c | 538 | * Return: status code |
aa1b5049 MK |
539 | */ |
540 | static void *find_smbios_table(const struct efi_system_table *systable) | |
541 | { | |
542 | u32 i; | |
543 | ||
544 | for (i = 0; i < systable->nr_tables; i++) { | |
2497f6a8 | 545 | if (!guidcmp(&smbios3_guid, &systable->tables[i].guid)) |
aa1b5049 MK |
546 | return systable->tables[i].table; |
547 | } | |
548 | ||
549 | return NULL; | |
550 | } | |
551 | ||
552 | /** | |
553 | * efi_status_t setup_smbios_table() - Prepare the dummy SMBIOS table | |
554 | * | |
555 | * @systable system table | |
185f812c | 556 | * Return: status code |
aa1b5049 MK |
557 | */ |
558 | static efi_status_t setup_smbios_table(const struct efi_system_table *systable) | |
559 | { | |
2497f6a8 | 560 | struct smbios3_entry *se; |
aa1b5049 MK |
561 | efi_status_t ret; |
562 | /* Map within the low 32 bits, to allow for 32bit SMBIOS tables */ | |
563 | void *dmi; | |
aa1b5049 | 564 | |
2497f6a8 | 565 | if (sizeof(smbios3_table_test) > EFI_PAGE_SIZE) |
aa1b5049 MK |
566 | return EFI_OUT_OF_RESOURCES; |
567 | ||
568 | orig_smbios_table = find_smbios_table(systable); | |
569 | ||
570 | /* Reserve 4kiB page for SMBIOS */ | |
571 | ret = boottime->allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, | |
572 | EFI_RUNTIME_SERVICES_DATA, 1, &dmi_addr); | |
573 | ||
574 | if (ret != EFI_SUCCESS) { | |
575 | /* Could not find space in lowmem, use highmem instead */ | |
576 | ret = boottime->allocate_pages(EFI_ALLOCATE_ANY_PAGES, | |
577 | EFI_RUNTIME_SERVICES_DATA, 1, | |
578 | &dmi_addr); | |
579 | ||
580 | if (ret != EFI_SUCCESS) | |
581 | return ret; | |
582 | } | |
583 | ||
584 | dmi = (void *)(uintptr_t)dmi_addr; | |
585 | se = dmi; | |
2497f6a8 | 586 | boottime->copy_mem(se, smbios3_table_test, sizeof(smbios3_table_test)); |
aa1b5049 MK |
587 | |
588 | /* update smbios table start address */ | |
2497f6a8 | 589 | se->struct_table_address = (uintptr_t)((u8 *)dmi + SMBIOS3_ENTRY_HEADER_SIZE); |
aa1b5049 | 590 | |
2497f6a8 | 591 | se->checksum = table_compute_checksum(se, sizeof(struct smbios3_entry)); |
aa1b5049 MK |
592 | |
593 | /* Install SMBIOS information as configuration table */ | |
2497f6a8 | 594 | ret = boottime->install_configuration_table(&smbios3_guid, dmi); |
aa1b5049 MK |
595 | if (ret != EFI_SUCCESS) { |
596 | efi_st_error("Cannot install SMBIOS table\n"); | |
597 | boottime->free_pages(dmi_addr, 1); | |
598 | } | |
599 | ||
600 | return ret; | |
601 | } | |
602 | ||
af69267c HS |
603 | /** |
604 | * efi_st_tcg2_setup() - setup test | |
605 | * | |
606 | * @handle: handle of the loaded image | |
607 | * @systable: system table | |
3dd719d4 | 608 | * Return: status code |
af69267c HS |
609 | */ |
610 | static int efi_st_tcg2_setup(const efi_handle_t img_handle, | |
611 | const struct efi_system_table *systable) | |
612 | { | |
aa1b5049 MK |
613 | efi_status_t ret; |
614 | struct uefi_image_load_event image_load_event; | |
615 | ||
616 | image_handle = img_handle; | |
af69267c | 617 | boottime = systable->boottime; |
aa1b5049 MK |
618 | runtime = systable->runtime; |
619 | ||
620 | /* Load the application image into memory */ | |
621 | decompress(&image); | |
622 | ||
623 | ret = boottime->allocate_pool(EFI_LOADER_DATA, | |
624 | sizeof(struct efi_tcg2_event) + | |
625 | sizeof(struct uefi_image_load_event), | |
626 | (void **)&efi_tcg2_event); | |
c900a42e HS |
627 | if (ret != EFI_SUCCESS) { |
628 | efi_st_error("Out of memory\n"); | |
aa1b5049 | 629 | return EFI_ST_FAILURE; |
c900a42e | 630 | } |
aa1b5049 MK |
631 | |
632 | efi_tcg2_event->size = sizeof(struct efi_tcg2_event) + | |
633 | sizeof(struct uefi_image_load_event); | |
634 | efi_tcg2_event->header.header_size = sizeof(struct efi_tcg2_event_header); | |
635 | efi_tcg2_event->header.header_version = 1; | |
636 | efi_tcg2_event->header.pcr_index = 6; | |
637 | efi_tcg2_event->header.event_type = EV_EFI_RUNTIME_SERVICES_DRIVER; | |
638 | image_load_event.image_location_in_memory = 0x12345678; | |
639 | image_load_event.image_length_in_memory = 0x300000; | |
640 | image_load_event.image_link_time_address = 0x87654321; | |
641 | image_load_event.length_of_device_path = 0; | |
642 | boottime->copy_mem(efi_tcg2_event->event, &image_load_event, | |
643 | sizeof(struct uefi_image_load_event)); | |
644 | ||
645 | ret = setup_boot_variable(); | |
646 | if (ret != EFI_SUCCESS) | |
647 | return EFI_ST_FAILURE; | |
648 | ||
649 | ret = setup_smbios_table(systable); | |
650 | if (ret != EFI_SUCCESS) | |
651 | return EFI_ST_FAILURE; | |
652 | ||
653 | ret = boottime->allocate_pool(EFI_LOADER_DATA, | |
654 | (EFI_TCG2_MAX_PCR_INDEX + 1) * | |
655 | TPM2_SHA256_DIGEST_SIZE, | |
656 | (void **)&pcrs); | |
c900a42e HS |
657 | if (ret != EFI_SUCCESS) { |
658 | efi_st_error("Out of memory\n"); | |
aa1b5049 | 659 | return EFI_ST_FAILURE; |
c900a42e | 660 | } |
aa1b5049 MK |
661 | |
662 | boottime->set_mem(pcrs, (EFI_TCG2_MAX_PCR_INDEX + 1) * TPM2_SHA256_DIGEST_SIZE, 0); | |
663 | ||
664 | /* setup expected PCRs per architecture */ | |
665 | boottime->copy_mem(&expected_pcrs[4], &expected_pcrs_per_arch[0], TPM2_SHA256_DIGEST_SIZE); | |
666 | boottime->copy_mem(&expected_pcrs[6], &expected_pcrs_per_arch[1], TPM2_SHA256_DIGEST_SIZE); | |
667 | ||
668 | return EFI_ST_SUCCESS; | |
669 | } | |
670 | ||
671 | /** | |
672 | * efi_status_t get_manufacturer_id() - Get manufacturer_id through submit_command API | |
673 | * | |
674 | * @tcg2 tcg2 protocol | |
675 | * @manufacturer_id pointer to the manufacturer_id | |
185f812c | 676 | * Return: status code |
aa1b5049 MK |
677 | */ |
678 | static efi_status_t get_manufacturer_id(struct efi_tcg2_protocol *tcg2, u32 *manufacturer_id) | |
679 | { | |
680 | efi_status_t ret; | |
681 | u8 cmd[TPM2_CMD_BUF_SIZE] = { | |
682 | tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ | |
683 | tpm_u32(22), /* Length */ | |
684 | tpm_u32(TPM2_CC_GET_CAPABILITY), /* Command code */ | |
685 | ||
686 | tpm_u32(TPM2_CAP_TPM_PROPERTIES), /* Capability */ | |
687 | tpm_u32(TPM2_PT_MANUFACTURER), /* Property */ | |
688 | tpm_u32(1), /* Property count */ | |
689 | }; | |
690 | u8 resp[TPM2_CMD_BUF_SIZE]; | |
691 | unsigned int value_off; | |
692 | ||
693 | ret = tcg2->submit_command(tcg2, 22, cmd, | |
694 | TPM2_CMD_BUF_SIZE, resp); | |
695 | if (ret != EFI_SUCCESS) | |
696 | return ret; | |
697 | ||
698 | /* | |
699 | * In the response buffer, the properties are located after the: | |
700 | * tag (u16), response size (u32), response code (u32), | |
701 | * YES/NO flag (u8), TPM_CAP (u32). | |
702 | * The value is located after count (u32), property (u32). | |
703 | */ | |
704 | value_off = sizeof(u16) + sizeof(u32) + sizeof(u32) + | |
705 | sizeof(u8) + sizeof(u32) + sizeof(u32) + sizeof(u32); | |
706 | *manufacturer_id = get_unaligned_be32(&resp[value_off]); | |
707 | ||
708 | return ret; | |
709 | } | |
710 | ||
711 | /** | |
712 | * efi_status_t get_manufacturer_id_buffer_small() - call submit_command with small resp buffer | |
713 | * | |
714 | * @tcg2 tcg2 protocol | |
715 | * @manufacturer_id pointer to the manufacturer_id | |
185f812c | 716 | * Return: status code |
aa1b5049 MK |
717 | */ |
718 | static efi_status_t get_manufacturer_id_buffer_small(struct efi_tcg2_protocol *tcg2) | |
719 | { | |
720 | efi_status_t ret; | |
721 | u8 cmd[TPM2_CMD_BUF_SIZE] = { | |
722 | tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ | |
723 | tpm_u32(22), /* Length */ | |
724 | tpm_u32(TPM2_CC_GET_CAPABILITY), /* Command code */ | |
725 | ||
726 | tpm_u32(TPM2_CAP_TPM_PROPERTIES), /* Capability */ | |
727 | tpm_u32(TPM2_PT_MANUFACTURER), /* Property */ | |
728 | tpm_u32(1), /* Property count */ | |
729 | }; | |
730 | u8 resp[1]; /* set smaller buffer than expected */ | |
731 | ||
732 | ret = tcg2->submit_command(tcg2, 22, cmd, 1, resp); | |
733 | ||
734 | return ret; | |
735 | } | |
736 | ||
737 | /** | |
738 | * efi_status_t read_pcr() - Read the PCR from the TPM device | |
739 | * | |
740 | * @tcg2 tcg2 protocol | |
741 | * @idx pcr index to read | |
185f812c | 742 | * Return: status code |
aa1b5049 MK |
743 | */ |
744 | static efi_status_t read_pcr(struct efi_tcg2_protocol *tcg2, u32 idx) | |
745 | { | |
746 | efi_status_t ret; | |
747 | u32 cmd_len = 17 + IDX_ARRAY_SZ; | |
748 | u8 cmd[TPM2_CMD_BUF_SIZE] = { | |
749 | tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ | |
750 | tpm_u32(cmd_len), /* Length */ | |
751 | tpm_u32(TPM2_CC_PCR_READ), /* Command code */ | |
752 | /* TPML_PCR_SELECTION */ | |
753 | tpm_u32(1), /* Number of selections */ | |
754 | tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */ | |
755 | IDX_ARRAY_SZ, /* Array size for selection */ | |
756 | /* bitmap(idx), Selected PCR bitmap */ | |
757 | }; | |
758 | u8 resp[TPM2_CMD_BUF_SIZE]; | |
759 | u32 pcr_sel_idx = idx / 8; | |
760 | u8 pcr_sel_bit = BIT(idx % 8); | |
761 | ||
762 | cmd[17 + pcr_sel_idx] = pcr_sel_bit; | |
763 | ret = tcg2->submit_command(tcg2, cmd_len, cmd, | |
764 | TPM2_CMD_BUF_SIZE, resp); | |
765 | if (ret != EFI_SUCCESS) { | |
766 | efi_st_error("tcg2->submit_command fail to read PCR\n"); | |
767 | return ret; | |
768 | } | |
769 | ||
770 | boottime->copy_mem(pcrs[idx], &resp[TPM2_PCR_READ_HEADER_SIZE], | |
771 | TPM2_SHA256_DIGEST_SIZE); | |
772 | ||
773 | return ret; | |
774 | } | |
775 | ||
776 | /** | |
777 | * int validate_pcrs() - Compare the expected and actual pcrs | |
778 | * | |
185f812c | 779 | * Return: status code |
aa1b5049 MK |
780 | */ |
781 | static int validate_pcrs(void) | |
782 | { | |
783 | u32 i; | |
784 | ||
785 | /* | |
786 | * - Skip PCR[0] validation. PCR[0] contains U-Boot version measurement | |
787 | * it contains the commit hash, so the measurement varies every build | |
788 | * with different commit hash. | |
789 | * - Skip PCR[7] validation. PCR[7] contains UEFI Secure Boot variables | |
790 | * measurement. These variables can not be updated through efi_selftest and | |
791 | * vary depending on the platform. | |
792 | * - Skip PCR[17..22] validation, they are not used in TCG PC Client | |
793 | * Platform Firmware Profile Specification | |
794 | */ | |
795 | for (i = 1; i < (EFI_TCG2_MAX_PCR_INDEX + 1); i++) { | |
796 | if (i == 7 || (i > 16 && i < 23)) | |
797 | continue; /* skip validation */ | |
798 | ||
799 | if (memcmp(pcrs[i], expected_pcrs[i], TPM2_SHA256_DIGEST_SIZE)) { | |
800 | efi_st_error("PCR[%d] is not the expected value\n", i); | |
801 | return EFI_ST_FAILURE; | |
802 | } | |
803 | } | |
af69267c HS |
804 | |
805 | return EFI_ST_SUCCESS; | |
806 | } | |
807 | ||
808 | /** | |
809 | * efi_st_tcg2_execute() - execute test | |
810 | * | |
aa1b5049 MK |
811 | * Call EFI_TCG2_PROTOCOL services and check the |
812 | * Measured Boot behavior. | |
af69267c HS |
813 | * |
814 | * Return: status code | |
815 | */ | |
816 | static int efi_st_tcg2_execute(void) | |
817 | { | |
818 | struct efi_tcg2_protocol *tcg2; | |
819 | struct efi_tcg2_boot_service_capability capability; | |
820 | efi_status_t ret; | |
aa1b5049 MK |
821 | u32 active_pcr_banks; |
822 | u64 eventlog, eventlog_last_entry; | |
823 | bool eventlog_truncated; | |
824 | efi_handle_t handle; | |
825 | efi_uintn_t exit_data_size = 0; | |
826 | u16 *exit_data = NULL; | |
827 | u32 i; | |
828 | u32 manufacturer_id; | |
af69267c HS |
829 | |
830 | ret = boottime->locate_protocol(&guid_tcg2, NULL, (void **)&tcg2); | |
831 | if (ret != EFI_SUCCESS) { | |
832 | efi_st_error("TCG2 protocol is not available.\n"); | |
833 | return EFI_ST_FAILURE; | |
834 | } | |
aa1b5049 MK |
835 | |
836 | /* EFI_TCG2_PROTOCOL.GetCapability test */ | |
af69267c HS |
837 | capability.size = sizeof(struct efi_tcg2_boot_service_capability) - 1; |
838 | ret = tcg2->get_capability(tcg2, &capability); | |
839 | if (ret != EFI_BUFFER_TOO_SMALL) { | |
840 | efi_st_error("tcg2->get_capability on small buffer failed\n"); | |
841 | return EFI_ST_FAILURE; | |
842 | } | |
843 | capability.size = sizeof(struct efi_tcg2_boot_service_capability); | |
844 | ret = tcg2->get_capability(tcg2, &capability); | |
845 | if (ret != EFI_SUCCESS) { | |
846 | efi_st_error("tcg2->get_capability failed\n"); | |
847 | return EFI_ST_FAILURE; | |
848 | } | |
849 | if (!capability.tpm_present_flag) { | |
850 | efi_st_error("TPM not present\n"); | |
851 | return EFI_ST_FAILURE; | |
852 | } | |
853 | efi_st_printf("TPM supports 0x%.8x event logs\n", | |
854 | capability.supported_event_logs); | |
aa1b5049 MK |
855 | |
856 | /* EFI_TCG2_PROTOCOL.GetActivePcrBanks test */ | |
857 | ret = tcg2->get_active_pcr_banks(tcg2, &active_pcr_banks); | |
858 | if (ret != EFI_SUCCESS) { | |
859 | efi_st_error("tcg2->get_active_pcr_banks failed\n"); | |
860 | return EFI_ST_FAILURE; | |
861 | } | |
862 | if (active_pcr_banks != capability.active_pcr_banks) { | |
863 | efi_st_error("tcg2->get_active_pcr_banks return wrong value\n"); | |
864 | return EFI_ST_FAILURE; | |
865 | } | |
866 | ||
867 | /* EFI_TCG2_PROTOCOL.HashLogExtendEvent test */ | |
868 | ret = tcg2->hash_log_extend_event(tcg2, EFI_TCG2_EXTEND_ONLY, | |
869 | (uintptr_t)image, | |
870 | img.length, efi_tcg2_event); | |
871 | if (ret != EFI_SUCCESS) { | |
872 | efi_st_error("tcg2->hash_log_extend_event(EXTEND_ONLY) failed\n"); | |
873 | return EFI_ST_FAILURE; | |
874 | } | |
875 | ||
876 | ret = tcg2->hash_log_extend_event(tcg2, PE_COFF_IMAGE, (uintptr_t)image, | |
877 | img.length, efi_tcg2_event); | |
878 | if (ret != EFI_SUCCESS) { | |
879 | efi_st_error("tcg2->hash_log_extend_event(PE_COFF_IMAGE) failed\n"); | |
880 | return EFI_ST_FAILURE; | |
881 | } | |
882 | ||
883 | /* EFI_TCG2_PROTOCOL.SubmitCommand test */ | |
884 | ret = get_manufacturer_id_buffer_small(tcg2); | |
885 | if (ret != EFI_OUT_OF_RESOURCES) { | |
886 | efi_st_error("get_manufacturer_id buffer too small failed\n"); | |
887 | return EFI_ST_FAILURE; | |
888 | } | |
889 | ||
890 | ret = get_manufacturer_id(tcg2, &manufacturer_id); | |
891 | if (ret != EFI_SUCCESS) { | |
892 | efi_st_error("get_manufacturer_id failed\n"); | |
893 | return EFI_ST_FAILURE; | |
894 | } | |
895 | if (capability.manufacturer_id != manufacturer_id) { | |
896 | efi_st_error("tcg2->submit_command test failed\n"); | |
897 | return EFI_ST_FAILURE; | |
898 | } | |
899 | ||
900 | /* tcg2_measure_pe_image test */ | |
901 | ret = boottime->load_image(false, image_handle, NULL, image, | |
902 | img.length, &handle); | |
903 | if (ret != EFI_SUCCESS) { | |
904 | efi_st_error("Failed to load image\n"); | |
905 | return EFI_ST_FAILURE; | |
906 | } | |
907 | ||
908 | /* measure ready_to_boot event(boot variables, smbios table, etc.) */ | |
909 | /* TODO: add GPT measurement test */ | |
910 | ret = boottime->start_image(handle, &exit_data_size, &exit_data); | |
911 | if (ret != EFI_UNSUPPORTED) { | |
912 | efi_st_error("Wrong return value from application\n"); | |
913 | return EFI_ST_FAILURE; | |
914 | } | |
915 | ret = boottime->free_pool(exit_data); | |
916 | if (ret != EFI_SUCCESS) { | |
917 | efi_st_error("Failed to free exit data\n"); | |
918 | return EFI_ST_FAILURE; | |
919 | } | |
920 | ||
921 | /* validate PCR read from the TPM device */ | |
922 | for (i = 0; i < (EFI_TCG2_MAX_PCR_INDEX + 1); i++) { | |
923 | ret = read_pcr(tcg2, i); | |
924 | if (ret != EFI_SUCCESS) { | |
925 | efi_st_error("read pcr error\n"); | |
926 | return EFI_ST_FAILURE; | |
927 | } | |
928 | } | |
929 | if (validate_pcrs()) { | |
930 | efi_st_error("PCR validation failed\n"); | |
931 | return EFI_ST_FAILURE; | |
932 | } | |
933 | ||
934 | /* EFI_TCG2_PROTOCOL.GetEventLog test */ | |
935 | ret = tcg2->get_eventlog(tcg2, TCG2_EVENT_LOG_FORMAT_TCG_2, &eventlog, | |
936 | &eventlog_last_entry, &eventlog_truncated); | |
937 | if (ret != EFI_SUCCESS) { | |
938 | efi_st_error("tcg2->get_eventlog failed\n"); | |
939 | return EFI_ST_FAILURE; | |
940 | } | |
941 | /* TODO: eventlog format check */ | |
942 | ||
af69267c HS |
943 | return EFI_ST_SUCCESS; |
944 | } | |
945 | ||
aa1b5049 MK |
946 | /* |
947 | * efi_st_tcg2_teardown() - Tear down unit test | |
948 | * | |
3dd719d4 | 949 | * Return: EFI_ST_SUCCESS for success |
aa1b5049 MK |
950 | */ |
951 | static int efi_st_tcg2_teardown(void) | |
952 | { | |
953 | efi_status_t r = EFI_ST_SUCCESS; | |
954 | ||
955 | if (image) { | |
956 | r = boottime->free_pool(image); | |
957 | if (r != EFI_SUCCESS) { | |
958 | efi_st_error("Failed to free image\n"); | |
959 | return EFI_ST_FAILURE; | |
960 | } | |
961 | } | |
962 | if (efi_tcg2_event) { | |
963 | r = boottime->free_pool(efi_tcg2_event); | |
964 | if (r != EFI_SUCCESS) { | |
965 | efi_st_error("Failed to free efi_tcg2_event\n"); | |
966 | return EFI_ST_FAILURE; | |
967 | } | |
968 | } | |
969 | if (pcrs) { | |
970 | r = boottime->free_pool(pcrs); | |
971 | if (r != EFI_SUCCESS) { | |
972 | efi_st_error("Failed to free pcr\n"); | |
973 | return EFI_ST_FAILURE; | |
974 | } | |
975 | } | |
976 | ||
977 | r = restore_boot_variable(); | |
978 | if (r != EFI_SUCCESS) { | |
979 | efi_st_error("Failed to restore boot variables\n"); | |
980 | return EFI_ST_FAILURE; | |
981 | } | |
982 | ||
983 | /* | |
984 | * Restore SMBIOS table | |
985 | * If orig_smbios_table is NULL, calling install_configuration_table() | |
986 | * removes dummy SMBIOS table form systab. | |
987 | */ | |
2497f6a8 | 988 | r = boottime->install_configuration_table(&smbios3_guid, orig_smbios_table); |
aa1b5049 MK |
989 | if (r != EFI_SUCCESS) { |
990 | efi_st_error("Failed to restore SMBOIS table\n"); | |
991 | return EFI_ST_FAILURE; | |
992 | } | |
993 | ||
994 | if (dmi_addr) { | |
995 | r = boottime->free_pages(dmi_addr, 1); | |
996 | if (r != EFI_SUCCESS) { | |
997 | efi_st_error("Failed to free dummy smbios table\n"); | |
998 | return EFI_ST_FAILURE; | |
999 | } | |
1000 | } | |
1001 | ||
1002 | return r; | |
1003 | } | |
1004 | ||
af69267c HS |
1005 | EFI_UNIT_TEST(tcg2) = { |
1006 | .name = "tcg2", | |
1007 | .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, | |
1008 | .execute = efi_st_tcg2_execute, | |
1009 | .setup = efi_st_tcg2_setup, | |
aa1b5049 MK |
1010 | .teardown = efi_st_tcg2_teardown, |
1011 | .on_request = true, | |
af69267c | 1012 | }; |