]>
Commit | Line | Data |
---|---|---|
a3f9cd27 LP |
1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | ||
da92d39a | 3 | #include "hexdecoct.h" |
adcd3266 | 4 | #include "macro.h" |
a3f9cd27 | 5 | #include "tests.h" |
3aea672b LP |
6 | #include "tpm2-util.h" |
7 | #include "virt.h" | |
a3f9cd27 | 8 | |
2099cd62 LP |
9 | TEST(tpm2_pcr_index_from_string) { |
10 | assert_se(tpm2_pcr_index_from_string("platform-code") == 0); | |
11 | assert_se(tpm2_pcr_index_from_string("0") == 0); | |
12 | assert_se(tpm2_pcr_index_from_string("platform-config") == 1); | |
13 | assert_se(tpm2_pcr_index_from_string("1") == 1); | |
14 | assert_se(tpm2_pcr_index_from_string("external-code") == 2); | |
15 | assert_se(tpm2_pcr_index_from_string("2") == 2); | |
16 | assert_se(tpm2_pcr_index_from_string("external-config") == 3); | |
17 | assert_se(tpm2_pcr_index_from_string("3") == 3); | |
18 | assert_se(tpm2_pcr_index_from_string("boot-loader-code") == 4); | |
19 | assert_se(tpm2_pcr_index_from_string("4") == 4); | |
20 | assert_se(tpm2_pcr_index_from_string("boot-loader-config") == 5); | |
21 | assert_se(tpm2_pcr_index_from_string("5") == 5); | |
22 | assert_se(tpm2_pcr_index_from_string("secure-boot-policy") == 7); | |
23 | assert_se(tpm2_pcr_index_from_string("7") == 7); | |
24 | assert_se(tpm2_pcr_index_from_string("kernel-initrd") == 9); | |
25 | assert_se(tpm2_pcr_index_from_string("9") == 9); | |
26 | assert_se(tpm2_pcr_index_from_string("ima") == 10); | |
27 | assert_se(tpm2_pcr_index_from_string("10") == 10); | |
28 | assert_se(tpm2_pcr_index_from_string("kernel-boot") == 11); | |
29 | assert_se(tpm2_pcr_index_from_string("11") == 11); | |
30 | assert_se(tpm2_pcr_index_from_string("kernel-config") == 12); | |
31 | assert_se(tpm2_pcr_index_from_string("12") == 12); | |
32 | assert_se(tpm2_pcr_index_from_string("sysexts") == 13); | |
33 | assert_se(tpm2_pcr_index_from_string("13") == 13); | |
34 | assert_se(tpm2_pcr_index_from_string("shim-policy") == 14); | |
35 | assert_se(tpm2_pcr_index_from_string("14") == 14); | |
36 | assert_se(tpm2_pcr_index_from_string("system-identity") == 15); | |
37 | assert_se(tpm2_pcr_index_from_string("15") == 15); | |
38 | assert_se(tpm2_pcr_index_from_string("debug") == 16); | |
39 | assert_se(tpm2_pcr_index_from_string("16") == 16); | |
40 | assert_se(tpm2_pcr_index_from_string("application-support") == 23); | |
41 | assert_se(tpm2_pcr_index_from_string("23") == 23); | |
42 | assert_se(tpm2_pcr_index_from_string("hello") == -EINVAL); | |
43 | assert_se(tpm2_pcr_index_from_string("8") == 8); | |
44 | assert_se(tpm2_pcr_index_from_string("44") == -EINVAL); | |
45 | assert_se(tpm2_pcr_index_from_string("-5") == -EINVAL); | |
46 | assert_se(tpm2_pcr_index_from_string("24") == -EINVAL); | |
a3f9cd27 | 47 | } |
4f7452a8 | 48 | |
aae6eb96 WR |
49 | TEST(tpm2_util_pbkdf2_hmac_sha256) { |
50 | ||
51 | /* | |
52 | * The test vectors from RFC 6070 [1] are for dkLen of 20 as it's SHA1 | |
53 | * other RFCs I bumped into had various differing dkLen and iter counts, | |
54 | * so this was generated using Python's hmacmodule. | |
55 | * | |
56 | * 1. https://www.rfc-editor.org/rfc/rfc6070.html#page-2 | |
57 | */ | |
58 | static const struct { | |
59 | const uint8_t pass[256]; | |
60 | size_t passlen; | |
61 | const uint8_t salt[256]; | |
62 | size_t saltlen; | |
63 | uint8_t expected[SHA256_DIGEST_SIZE]; | |
64 | } test_vectors[] = { | |
65 | { .pass={'f', 'o', 'o', 'p', 'a', 's', 's'}, .passlen=7, .salt={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5'}, .saltlen=16, .expected={0xCB, 0xEA, 0x27, 0x23, 0x9A, 0x65, 0x99, 0xF6, 0x8C, 0x26, 0x54, 0x80, 0x5C, 0x63, 0x61, 0xD2, 0x91, 0x0A, 0x60, 0x3F, 0xC2, 0xF5, 0xF0, 0xAB, 0x55, 0x8B, 0x46, 0x07, 0x60, 0x93, 0xAB, 0xCB} }, | |
66 | { .pass={'f', 'o', 'o', 'p', 'a', 's', 's'}, .passlen=7, .salt={0x00, 'h', 'f', 's', 'd', 'j', 'h', 'f', 'd', 'j', 'h', 'j', 'd', 'f', 's'}, .saltlen=15, .expected={0x2B, 0xDF, 0x52, 0x29, 0x48, 0x3F, 0x98, 0x25, 0x01, 0x19, 0xB4, 0x42, 0xBC, 0xA7, 0x38, 0x5D, 0xCD, 0x08, 0xBD, 0xDC, 0x33, 0xBF, 0x32, 0x5E, 0x31, 0x87, 0x54, 0xFF, 0x2C, 0x23, 0x68, 0xFF} }, | |
67 | { .pass={'f', 'o', 'o', 'p', 'a', 's', 's'}, .passlen=7, .salt={'m', 'y', 's', 'a', 0x00, 'l', 't'}, .saltlen=7, .expected={0x7C, 0x24, 0xB4, 0x4D, 0x30, 0x11, 0x53, 0x24, 0x87, 0x56, 0x24, 0x10, 0xBA, 0x9F, 0xF2, 0x4E, 0xBB, 0xF5, 0x03, 0x56, 0x2B, 0xB1, 0xA1, 0x92, 0x8B, 0x5F, 0x32, 0x02, 0x23, 0x1F, 0x79, 0xE6} }, | |
68 | { .pass={'p', 'a', 's', 's', 'w', 'i', 't', 'h', 'n', 'u', 'l', 'l', 0x00, 'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}, .passlen=21, .salt={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5'}, .saltlen=16, .expected={0xE9, 0x53, 0xB7, 0x1D, 0xAB, 0xD1, 0xC1, 0xF3, 0xC4, 0x7F, 0x18, 0x96, 0xDD, 0xD7, 0x6B, 0xC6, 0x6A, 0xBD, 0xFB, 0x12, 0x7C, 0xF8, 0x68, 0xDC, 0x6E, 0xEF, 0x29, 0xCC, 0x1B, 0x30, 0x5B, 0x74} }, | |
69 | { .pass={'p', 'a', 's', 's', 'w', 'i', 't', 'h', 'n', 'u', 'l', 'l', 0x00, 'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}, .passlen=21, .salt={0x00, 'h', 'f', 's', 'd', 'j', 'h', 'f', 'd', 'j', 'h', 'j', 'd', 'f', 's'}, .saltlen=15, .expected={0x51, 0xA3, 0x82, 0xA5, 0x2F, 0x48, 0x84, 0xB3, 0x02, 0x0D, 0xC2, 0x42, 0x9A, 0x8F, 0x86, 0xCC, 0x66, 0xFD, 0x65, 0x87, 0x89, 0x07, 0x2B, 0x07, 0x82, 0x42, 0xD6, 0x6D, 0x43, 0xB8, 0xFD, 0xCF} }, | |
70 | { .pass={'p', 'a', 's', 's', 'w', 'i', 't', 'h', 'n', 'u', 'l', 'l', 0x00, 'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}, .passlen=21, .salt={'m', 'y', 's', 'a', 0x00, 'l', 't'}, .saltlen=7, .expected={0xEC, 0xFB, 0x5D, 0x5F, 0xF6, 0xA6, 0xE0, 0x79, 0x50, 0x64, 0x36, 0x64, 0xA3, 0x9A, 0x5C, 0xF3, 0x7A, 0x87, 0x0B, 0x64, 0x51, 0x59, 0x75, 0x64, 0x8B, 0x78, 0x2B, 0x62, 0x8F, 0x68, 0xD9, 0xCC} }, | |
71 | { .pass={0x00, 'p', 'a', 's', 's'}, .passlen=5, .salt={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5'}, .saltlen=16, .expected={0x8A, 0x9A, 0x47, 0x9A, 0x91, 0x22, 0x2F, 0x56, 0x29, 0x4F, 0x26, 0x00, 0xE7, 0xB3, 0xEB, 0x63, 0x6D, 0x51, 0xF2, 0x60, 0x17, 0x08, 0x20, 0x70, 0x82, 0x8F, 0xA3, 0xD7, 0xBE, 0x2B, 0xD5, 0x5D} }, | |
72 | { .pass={0x00, 'p', 'a', 's', 's'}, .passlen=5, .salt={0x00, 'h', 'f', 's', 'd', 'j', 'h', 'f', 'd', 'j', 'h', 'j', 'd', 'f', 's'}, .saltlen=15, .expected={0x72, 0x3A, 0xF5, 0xF7, 0xCD, 0x6C, 0x12, 0xDD, 0x53, 0x28, 0x46, 0x0C, 0x19, 0x0E, 0xF2, 0x91, 0xDE, 0xEA, 0xF9, 0x6F, 0x74, 0x32, 0x34, 0x3F, 0x84, 0xED, 0x8D, 0x2A, 0xDE, 0xC9, 0xC6, 0x34} }, | |
73 | { .pass={0x00, 'p', 'a', 's', 's'}, .passlen=5, .salt={'m', 'y', 's', 'a', 0x00, 'l', 't'}, .saltlen=7, .expected={0xE3, 0x07, 0x12, 0xBE, 0xEE, 0xF5, 0x5D, 0x18, 0x72, 0xF4, 0xCF, 0xF1, 0x20, 0x6B, 0xD6, 0x66, 0xCD, 0x7C, 0xE7, 0x4F, 0xC2, 0x16, 0x70, 0x5B, 0x9B, 0x2F, 0x7D, 0xE2, 0x3B, 0x42, 0x3A, 0x1B} }, | |
74 | }; | |
75 | ||
76 | uint8_t res[SHA256_DIGEST_SIZE]; | |
1d03d970 | 77 | for (size_t i = 0; i < sizeof(test_vectors)/sizeof(test_vectors[0]); i++) { |
aae6eb96 WR |
78 | |
79 | int rc = tpm2_util_pbkdf2_hmac_sha256( | |
80 | test_vectors[i].pass, | |
81 | test_vectors[i].passlen, | |
82 | test_vectors[i].salt, | |
83 | test_vectors[i].saltlen, | |
84 | res); | |
85 | assert_se(rc == 0); | |
86 | assert_se(memcmp(test_vectors[i].expected, res, SHA256_DIGEST_SIZE) == 0); | |
87 | } | |
88 | } | |
89 | ||
e067a49f DS |
90 | #if HAVE_TPM2 |
91 | ||
92 | #define POISON(type) \ | |
93 | ({ \ | |
94 | type _p; \ | |
95 | memset(&_p, 0xaa, sizeof(_p)); \ | |
96 | _p; \ | |
97 | }) | |
98 | #define POISON_TPML POISON(TPML_PCR_SELECTION) | |
99 | #define POISON_TPMS POISON(TPMS_PCR_SELECTION) | |
100 | #define POISON_U32 POISON(uint32_t) | |
101 | ||
102 | static void assert_tpms_pcr_selection_eq(TPMS_PCR_SELECTION *a, TPMS_PCR_SELECTION *b) { | |
103 | assert_se(a); | |
104 | assert_se(b); | |
105 | ||
106 | assert_se(a->hash == b->hash); | |
107 | assert_se(a->sizeofSelect == b->sizeofSelect); | |
108 | ||
109 | for (size_t i = 0; i < a->sizeofSelect; i++) | |
110 | assert_se(a->pcrSelect[i] == b->pcrSelect[i]); | |
111 | } | |
112 | ||
113 | static void assert_tpml_pcr_selection_eq(TPML_PCR_SELECTION *a, TPML_PCR_SELECTION *b) { | |
114 | assert_se(a); | |
115 | assert_se(b); | |
116 | ||
117 | assert_se(a->count == b->count); | |
118 | for (size_t i = 0; i < a->count; i++) | |
119 | assert_tpms_pcr_selection_eq(&a->pcrSelections[i], &b->pcrSelections[i]); | |
120 | } | |
121 | ||
122 | static void verify_tpms_pcr_selection(TPMS_PCR_SELECTION *s, uint32_t mask, TPMI_ALG_HASH hash) { | |
123 | assert_se(s->hash == hash); | |
124 | assert_se(s->sizeofSelect == 3); | |
125 | assert_se(s->pcrSelect[0] == (mask & 0xff)); | |
126 | assert_se(s->pcrSelect[1] == ((mask >> 8) & 0xff)); | |
127 | assert_se(s->pcrSelect[2] == ((mask >> 16) & 0xff)); | |
128 | assert_se(s->pcrSelect[3] == 0); | |
129 | ||
dbaae766 | 130 | assert_se(tpm2_tpms_pcr_selection_to_mask(s) == mask); |
e067a49f DS |
131 | } |
132 | ||
133 | static void verify_tpml_pcr_selection(TPML_PCR_SELECTION *l, TPMS_PCR_SELECTION s[], size_t count) { | |
134 | assert_se(l->count == count); | |
135 | for (size_t i = 0; i < count; i++) { | |
136 | assert_tpms_pcr_selection_eq(&s[i], &l->pcrSelections[i]); | |
137 | ||
e067a49f | 138 | TPMI_ALG_HASH hash = l->pcrSelections[i].hash; |
dbaae766 | 139 | verify_tpms_pcr_selection(&l->pcrSelections[i], tpm2_tpml_pcr_selection_to_mask(l, hash), hash); |
e067a49f DS |
140 | } |
141 | } | |
142 | ||
143 | static void _test_pcr_selection_mask_hash(uint32_t mask, TPMI_ALG_HASH hash) { | |
144 | TPMS_PCR_SELECTION s = POISON_TPMS; | |
145 | tpm2_tpms_pcr_selection_from_mask(mask, hash, &s); | |
146 | verify_tpms_pcr_selection(&s, mask, hash); | |
147 | ||
148 | TPML_PCR_SELECTION l = POISON_TPML; | |
149 | tpm2_tpml_pcr_selection_from_mask(mask, hash, &l); | |
150 | verify_tpml_pcr_selection(&l, &s, 1); | |
151 | verify_tpms_pcr_selection(&l.pcrSelections[0], mask, hash); | |
152 | ||
153 | uint32_t test_masks[] = { | |
154 | 0x0, 0x1, 0x100, 0x10000, 0xf0f0f0, 0xaaaaaa, 0xffffff, | |
155 | }; | |
156 | for (unsigned i = 0; i < ELEMENTSOF(test_masks); i++) { | |
157 | uint32_t test_mask = test_masks[i]; | |
158 | ||
159 | TPMS_PCR_SELECTION a = POISON_TPMS, b = POISON_TPMS, test_s = POISON_TPMS; | |
160 | tpm2_tpms_pcr_selection_from_mask(test_mask, hash, &test_s); | |
161 | ||
162 | a = s; | |
163 | b = test_s; | |
164 | tpm2_tpms_pcr_selection_add(&a, &b); | |
165 | verify_tpms_pcr_selection(&a, UPDATE_FLAG(mask, test_mask, true), hash); | |
166 | verify_tpms_pcr_selection(&b, test_mask, hash); | |
167 | ||
168 | a = s; | |
169 | b = test_s; | |
170 | tpm2_tpms_pcr_selection_sub(&a, &b); | |
171 | verify_tpms_pcr_selection(&a, UPDATE_FLAG(mask, test_mask, false), hash); | |
172 | verify_tpms_pcr_selection(&b, test_mask, hash); | |
173 | ||
174 | a = s; | |
175 | b = test_s; | |
176 | tpm2_tpms_pcr_selection_move(&a, &b); | |
177 | verify_tpms_pcr_selection(&a, UPDATE_FLAG(mask, test_mask, true), hash); | |
178 | verify_tpms_pcr_selection(&b, 0, hash); | |
179 | } | |
180 | } | |
181 | ||
182 | TEST(tpms_pcr_selection_mask_and_hash) { | |
183 | TPMI_ALG_HASH HASH_ALGS[] = { TPM2_ALG_SHA1, TPM2_ALG_SHA256, }; | |
184 | ||
185 | for (unsigned i = 0; i < ELEMENTSOF(HASH_ALGS); i++) | |
4916cc47 DS |
186 | for (uint32_t m2 = 0; m2 <= 0xffffff; m2 += 0x50000) |
187 | for (uint32_t m1 = 0; m1 <= 0xffff; m1 += 0x500) | |
188 | for (uint32_t m0 = 0; m0 <= 0xff; m0 += 0x5) | |
e067a49f DS |
189 | _test_pcr_selection_mask_hash(m0 | m1 | m2, HASH_ALGS[i]); |
190 | } | |
191 | ||
192 | static void _test_tpms_sw( | |
193 | TPMI_ALG_HASH hash, | |
194 | uint32_t mask, | |
195 | const char *expected_str, | |
196 | size_t expected_weight) { | |
197 | ||
198 | TPMS_PCR_SELECTION s = POISON_TPMS; | |
199 | tpm2_tpms_pcr_selection_from_mask(mask, hash, &s); | |
200 | ||
201 | _cleanup_free_ char *tpms_str = tpm2_tpms_pcr_selection_to_string(&s); | |
c79e88b3 | 202 | ASSERT_STREQ(tpms_str, expected_str); |
e067a49f DS |
203 | |
204 | assert_se(tpm2_tpms_pcr_selection_weight(&s) == expected_weight); | |
205 | assert_se(tpm2_tpms_pcr_selection_is_empty(&s) == (expected_weight == 0)); | |
206 | } | |
207 | ||
208 | TEST(tpms_pcr_selection_string_and_weight) { | |
209 | TPMI_ALG_HASH sha1 = TPM2_ALG_SHA1, sha256 = TPM2_ALG_SHA256; | |
210 | ||
211 | _test_tpms_sw(sha1, 0, "sha1()", 0); | |
212 | _test_tpms_sw(sha1, 1, "sha1(0)", 1); | |
213 | _test_tpms_sw(sha1, 0xf, "sha1(0+1+2+3)", 4); | |
214 | _test_tpms_sw(sha1, 0x00ff00, "sha1(8+9+10+11+12+13+14+15)", 8); | |
215 | _test_tpms_sw(sha1, 0xffffff, "sha1(0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23)", 24); | |
216 | _test_tpms_sw(sha256, 0, "sha256()", 0); | |
217 | _test_tpms_sw(sha256, 1, "sha256(0)", 1); | |
218 | _test_tpms_sw(sha256, 7, "sha256(0+1+2)", 3); | |
219 | _test_tpms_sw(sha256, 0xf00000, "sha256(20+21+22+23)", 4); | |
220 | _test_tpms_sw(sha256, 0xffffff, "sha256(0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23)", 24); | |
221 | } | |
222 | ||
223 | static void _tpml_pcr_selection_add_tpms(TPMS_PCR_SELECTION s[], size_t count, TPML_PCR_SELECTION *ret) { | |
224 | for (size_t i = 0; i < count; i++) | |
225 | tpm2_tpml_pcr_selection_add_tpms_pcr_selection(ret, &s[i]); | |
226 | } | |
227 | ||
228 | static void _tpml_pcr_selection_sub_tpms(TPMS_PCR_SELECTION s[], size_t count, TPML_PCR_SELECTION *ret) { | |
229 | for (size_t i = 0; i < count; i++) | |
230 | tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(ret, &s[i]); | |
231 | } | |
232 | ||
233 | static void _test_tpml_sw( | |
234 | TPMS_PCR_SELECTION s[], | |
235 | size_t count, | |
236 | size_t expected_count, | |
237 | const char *expected_str, | |
238 | size_t expected_weight) { | |
239 | ||
240 | TPML_PCR_SELECTION l = {}; | |
241 | _tpml_pcr_selection_add_tpms(s, count, &l); | |
242 | assert_se(l.count == expected_count); | |
243 | ||
244 | _cleanup_free_ char *tpml_str = tpm2_tpml_pcr_selection_to_string(&l); | |
c79e88b3 | 245 | ASSERT_STREQ(tpml_str, expected_str); |
e067a49f DS |
246 | |
247 | assert_se(tpm2_tpml_pcr_selection_weight(&l) == expected_weight); | |
248 | assert_se(tpm2_tpml_pcr_selection_is_empty(&l) == (expected_weight == 0)); | |
249 | } | |
250 | ||
251 | TEST(tpml_pcr_selection_string_and_weight) { | |
252 | size_t size = 0xaa; | |
253 | TPMI_ALG_HASH sha1 = TPM2_ALG_SHA1, | |
254 | sha256 = TPM2_ALG_SHA256, | |
255 | sha384 = TPM2_ALG_SHA384, | |
256 | sha512 = TPM2_ALG_SHA512; | |
257 | TPMS_PCR_SELECTION s[4] = { POISON_TPMS, POISON_TPMS, POISON_TPMS, POISON_TPMS, }; | |
258 | ||
259 | size = 0; | |
260 | tpm2_tpms_pcr_selection_from_mask(0x000002, sha1 , &s[size++]); | |
261 | tpm2_tpms_pcr_selection_from_mask(0x0080f0, sha384, &s[size++]); | |
262 | tpm2_tpms_pcr_selection_from_mask(0x010100, sha512, &s[size++]); | |
263 | tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256, &s[size++]); | |
264 | _test_tpml_sw(s, | |
265 | size, | |
266 | /* expected_count= */ 4, | |
267 | "[sha1(1),sha384(4+5+6+7+15),sha512(8+16),sha256(16+17+18+19+20+21+22+23)]", | |
268 | /* expected_weight= */ 16); | |
269 | ||
270 | size = 0; | |
271 | tpm2_tpms_pcr_selection_from_mask(0x0403aa, sha512, &s[size++]); | |
272 | tpm2_tpms_pcr_selection_from_mask(0x0080f0, sha256, &s[size++]); | |
273 | _test_tpml_sw(s, | |
274 | size, | |
275 | /* expected_count= */ 2, | |
276 | "[sha512(1+3+5+7+8+9+18),sha256(4+5+6+7+15)]", | |
277 | /* expected_weight= */ 12); | |
278 | ||
279 | size = 0; | |
280 | /* Empty hashes should be ignored */ | |
281 | tpm2_tpms_pcr_selection_from_mask(0x0300ce, sha384, &s[size++]); | |
282 | tpm2_tpms_pcr_selection_from_mask(0xffffff, sha512, &s[size++]); | |
283 | tpm2_tpms_pcr_selection_from_mask(0x000000, sha1 , &s[size++]); | |
284 | tpm2_tpms_pcr_selection_from_mask(0x330010, sha256, &s[size++]); | |
285 | _test_tpml_sw(s, | |
286 | size, | |
287 | /* expected_count= */ 3, | |
288 | "[sha384(1+2+3+6+7+16+17),sha512(0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23),sha256(4+16+17+20+21)]", | |
289 | /* expected_weight= */ 36); | |
290 | ||
291 | size = 0; | |
292 | /* Verify same-hash entries are properly combined. */ | |
293 | tpm2_tpms_pcr_selection_from_mask(0x000001, sha1 , &s[size++]); | |
294 | tpm2_tpms_pcr_selection_from_mask(0x000001, sha256, &s[size++]); | |
295 | tpm2_tpms_pcr_selection_from_mask(0x000010, sha1 , &s[size++]); | |
296 | tpm2_tpms_pcr_selection_from_mask(0x000010, sha256, &s[size++]); | |
297 | _test_tpml_sw(s, | |
298 | size, | |
299 | /* expected_count= */ 2, | |
300 | "[sha1(0+4),sha256(0+4)]", | |
301 | /* expected_weight= */ 4); | |
302 | } | |
303 | ||
304 | /* Test tpml add/sub by changing the tpms individually */ | |
305 | static void _test_tpml_addsub_tpms( | |
306 | TPML_PCR_SELECTION *start, | |
307 | TPMS_PCR_SELECTION add[], | |
308 | size_t add_count, | |
309 | TPMS_PCR_SELECTION expected1[], | |
310 | size_t expected1_count, | |
311 | TPMS_PCR_SELECTION sub[], | |
312 | size_t sub_count, | |
313 | TPMS_PCR_SELECTION expected2[], | |
314 | size_t expected2_count) { | |
315 | ||
316 | TPML_PCR_SELECTION l = *start; | |
317 | ||
318 | _tpml_pcr_selection_add_tpms(add, add_count, &l); | |
319 | verify_tpml_pcr_selection(&l, expected1, expected1_count); | |
320 | ||
321 | _tpml_pcr_selection_sub_tpms(sub, sub_count, &l); | |
322 | verify_tpml_pcr_selection(&l, expected2, expected2_count); | |
323 | } | |
324 | ||
325 | /* Test tpml add/sub by creating new tpmls */ | |
326 | static void _test_tpml_addsub_tpml( | |
327 | TPML_PCR_SELECTION *start, | |
328 | TPMS_PCR_SELECTION add[], | |
329 | size_t add_count, | |
330 | TPMS_PCR_SELECTION expected1[], | |
331 | size_t expected1_count, | |
332 | TPMS_PCR_SELECTION sub[], | |
333 | size_t sub_count, | |
334 | TPMS_PCR_SELECTION expected2[], | |
335 | size_t expected2_count) { | |
336 | ||
337 | TPML_PCR_SELECTION l = {}; | |
338 | tpm2_tpml_pcr_selection_add(&l, start); | |
339 | assert_tpml_pcr_selection_eq(&l, start); | |
340 | ||
341 | TPML_PCR_SELECTION addl = {}; | |
342 | _tpml_pcr_selection_add_tpms(add, add_count, &addl); | |
343 | tpm2_tpml_pcr_selection_add(&l, &addl); | |
344 | ||
345 | TPML_PCR_SELECTION e1 = {}; | |
346 | _tpml_pcr_selection_add_tpms(expected1, expected1_count, &e1); | |
347 | assert_tpml_pcr_selection_eq(&l, &e1); | |
348 | ||
349 | TPML_PCR_SELECTION subl = {}; | |
350 | _tpml_pcr_selection_add_tpms(sub, sub_count, &subl); | |
351 | tpm2_tpml_pcr_selection_sub(&l, &subl); | |
352 | ||
353 | TPML_PCR_SELECTION e2 = {}; | |
354 | _tpml_pcr_selection_add_tpms(expected2, expected2_count, &e2); | |
355 | assert_tpml_pcr_selection_eq(&l, &e2); | |
356 | } | |
357 | ||
358 | #define _test_tpml_addsub(...) \ | |
359 | ({ \ | |
360 | _test_tpml_addsub_tpms(__VA_ARGS__); \ | |
361 | _test_tpml_addsub_tpml(__VA_ARGS__); \ | |
362 | }) | |
363 | ||
364 | TEST(tpml_pcr_selection_add_sub) { | |
365 | size_t add_count = 0xaa, expected1_count = 0xaa, sub_count = 0xaa, expected2_count = 0xaa; | |
366 | TPMI_ALG_HASH sha1 = TPM2_ALG_SHA1, | |
367 | sha256 = TPM2_ALG_SHA256, | |
368 | sha384 = TPM2_ALG_SHA384, | |
369 | sha512 = TPM2_ALG_SHA512; | |
370 | TPML_PCR_SELECTION l = POISON_TPML; | |
371 | TPMS_PCR_SELECTION add[4] = { POISON_TPMS, POISON_TPMS, POISON_TPMS, POISON_TPMS, }, | |
372 | sub[4] = { POISON_TPMS, POISON_TPMS, POISON_TPMS, POISON_TPMS, }, | |
373 | expected1[4] = { POISON_TPMS, POISON_TPMS, POISON_TPMS, POISON_TPMS, }, | |
374 | expected2[4] = { POISON_TPMS, POISON_TPMS, POISON_TPMS, POISON_TPMS, }; | |
375 | ||
376 | l = (TPML_PCR_SELECTION){}; | |
377 | add_count = 0; | |
378 | expected1_count = 0; | |
379 | sub_count = 0; | |
380 | expected2_count = 0; | |
381 | tpm2_tpms_pcr_selection_from_mask(0x010101, sha256, &add[add_count++]); | |
382 | tpm2_tpms_pcr_selection_from_mask(0x101010, sha256, &add[add_count++]); | |
383 | tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &add[add_count++]); | |
384 | tpm2_tpms_pcr_selection_from_mask(0x111111, sha256, &expected1[expected1_count++]); | |
385 | tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &expected1[expected1_count++]); | |
386 | tpm2_tpms_pcr_selection_from_mask(0x000001, sha256, &sub[sub_count++]); | |
387 | tpm2_tpms_pcr_selection_from_mask(0xff0000, sha512, &sub[sub_count++]); | |
388 | tpm2_tpms_pcr_selection_from_mask(0x111110, sha256, &expected2[expected2_count++]); | |
389 | tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &expected2[expected2_count++]); | |
390 | _test_tpml_addsub(&l, | |
391 | add, add_count, | |
392 | expected1, expected1_count, | |
393 | sub, sub_count, | |
394 | expected2, expected2_count); | |
395 | ||
396 | l = (TPML_PCR_SELECTION){ | |
397 | .count = 1, | |
398 | .pcrSelections[0].hash = sha1, | |
399 | .pcrSelections[0].sizeofSelect = 3, | |
400 | .pcrSelections[0].pcrSelect[0] = 0xf0, | |
401 | }; | |
402 | add_count = 0; | |
403 | expected1_count = 0; | |
404 | sub_count = 0; | |
405 | expected2_count = 0; | |
406 | tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256, &add[add_count++]); | |
407 | tpm2_tpms_pcr_selection_from_mask(0xffff00, sha384, &add[add_count++]); | |
408 | tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &add[add_count++]); | |
409 | tpm2_tpms_pcr_selection_from_mask(0xf00000, sha1 , &add[add_count++]); | |
410 | tpm2_tpms_pcr_selection_from_mask(0xf000f0, sha1 , &expected1[expected1_count++]); | |
411 | tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256, &expected1[expected1_count++]); | |
412 | tpm2_tpms_pcr_selection_from_mask(0xffff00, sha384, &expected1[expected1_count++]); | |
413 | tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &expected1[expected1_count++]); | |
414 | tpm2_tpms_pcr_selection_from_mask(0x00ffff, sha256, &sub[sub_count++]); | |
415 | tpm2_tpms_pcr_selection_from_mask(0xf000f0, sha1 , &expected2[expected2_count++]); | |
416 | tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256, &expected2[expected2_count++]); | |
417 | tpm2_tpms_pcr_selection_from_mask(0xffff00, sha384, &expected2[expected2_count++]); | |
418 | tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &expected2[expected2_count++]); | |
419 | _test_tpml_addsub(&l, | |
420 | add, add_count, | |
421 | expected1, expected1_count, | |
422 | sub, sub_count, | |
423 | expected2, expected2_count); | |
424 | } | |
425 | ||
da92d39a DS |
426 | static bool digest_check(const TPM2B_DIGEST *digest, const char *expect) { |
427 | _cleanup_free_ char *h = NULL; | |
428 | ||
429 | assert_se(digest); | |
430 | assert_se(expect); | |
431 | ||
432 | h = hexmem(digest->buffer, digest->size); | |
433 | assert_se(h); | |
434 | ||
07c04061 | 435 | return strcaseeq(expect, h); |
da92d39a DS |
436 | } |
437 | ||
07c04061 | 438 | static void digest_init(TPM2B_DIGEST *digest, const char *hash) { |
da92d39a DS |
439 | assert_se(strlen(hash) <= sizeof(digest->buffer) * 2); |
440 | ||
0fdcfa78 | 441 | DEFINE_HEX_PTR(h, hash); |
07c04061 DS |
442 | |
443 | /* Make sure the length matches a known hash algorithm */ | |
0fdcfa78 | 444 | assert_se(IN_SET(h_len, TPM2_SHA1_DIGEST_SIZE, TPM2_SHA256_DIGEST_SIZE, TPM2_SHA384_DIGEST_SIZE, TPM2_SHA512_DIGEST_SIZE)); |
da92d39a | 445 | |
0fdcfa78 | 446 | *digest = TPM2B_DIGEST_MAKE(h, h_len); |
da92d39a DS |
447 | |
448 | assert_se(digest_check(digest, hash)); | |
449 | } | |
450 | ||
451 | TEST(digest_many) { | |
452 | TPM2B_DIGEST d, d0, d1, d2, d3, d4; | |
453 | ||
07c04061 DS |
454 | digest_init(&d0, "0000000000000000000000000000000000000000000000000000000000000000"); |
455 | digest_init(&d1, "17b7703d9d00776310ba032e88c1a8c2a9c630ebdd799db622f6631530789175"); | |
456 | digest_init(&d2, "12998c017066eb0d2a70b94e6ed3192985855ce390f321bbdb832022888bd251"); | |
457 | digest_init(&d3, "c3a65887fedd3fb4f5d0047e906dff830bcbd1293160909eb4b05f485e7387ad"); | |
458 | digest_init(&d4, "6491fb4bc08fc0b2ef47fc63db57e249917885e69d8c0d99667df83a59107a33"); | |
da92d39a DS |
459 | |
460 | /* tpm2_digest_init, tpm2_digest_rehash */ | |
461 | d = (TPM2B_DIGEST){ .size = 1, .buffer = { 2, }, }; | |
462 | assert_se(tpm2_digest_init(TPM2_ALG_SHA256, &d) == 0); | |
463 | assert_se(digest_check(&d, "0000000000000000000000000000000000000000000000000000000000000000")); | |
464 | assert_se(tpm2_digest_rehash(TPM2_ALG_SHA256, &d) == 0); | |
465 | assert_se(digest_check(&d, "66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925")); | |
466 | ||
467 | d = d1; | |
468 | assert_se(tpm2_digest_rehash(TPM2_ALG_SHA256, &d) == 0); | |
469 | assert_se(digest_check(&d, "ab55014b5ace12ba70c3acc887db571585a83539aad3633d252a710f268f405c")); | |
470 | assert_se(tpm2_digest_init(TPM2_ALG_SHA256, &d) == 0); | |
471 | assert_se(digest_check(&d, "0000000000000000000000000000000000000000000000000000000000000000")); | |
472 | ||
473 | /* tpm2_digest_many_digests */ | |
474 | assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, &d2, 1, false) == 0); | |
475 | assert_se(digest_check(&d, "56571a1be3fbeab18d215f549095915a004b5788ca0d535be668559129a76f25")); | |
476 | assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, &d2, 1, true) == 0); | |
477 | assert_se(digest_check(&d, "99dedaee8f4d8d10a8be184399fde8740d5e17ff783ee5c288a4486e4ce3a1fe")); | |
478 | ||
479 | const TPM2B_DIGEST da1[] = { d2, d3, }; | |
480 | assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da1, ELEMENTSOF(da1), false) == 0); | |
481 | assert_se(digest_check(&d, "525aa13ef9a61827778ec3acf16fbb23b65ae8770b8fb2684d3a33f9457dd6d8")); | |
482 | assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da1, ELEMENTSOF(da1), true) == 0); | |
483 | assert_se(digest_check(&d, "399ca2aa98963d1bd81a2b58a7e5cda24bba1be88fb4da9aa73d97706846566b")); | |
484 | ||
485 | const TPM2B_DIGEST da2[] = { d3, d2, d0 }; | |
486 | assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da2, ELEMENTSOF(da2), false) == 0); | |
487 | assert_se(digest_check(&d, "b26fd22db74d4cd896bff01c61aa498a575e4a553a7fb5a322a5fee36954313e")); | |
488 | assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da2, ELEMENTSOF(da2), true) == 0); | |
489 | assert_se(digest_check(&d, "091e79a5b09d4048df49a680f966f3ff67910afe185c3baf9704c9ca45bcf259")); | |
490 | ||
491 | const TPM2B_DIGEST da3[] = { d4, d4, d4, d4, d3, d4, d4, d4, d4, }; | |
492 | assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da3, ELEMENTSOF(da3), false) == 0); | |
493 | assert_se(digest_check(&d, "8eca947641b6002df79dfb571a7f78b7d0a61370a366f722386dfbe444d18830")); | |
494 | assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da3, ELEMENTSOF(da3), true) == 0); | |
495 | assert_se(digest_check(&d, "f9ba17bc0bbe8794e9bcbf112e4d59a11eb68fffbcd5516a746e4857829dff04")); | |
496 | ||
497 | /* tpm2_digest_buffer */ | |
498 | const uint8_t b1[] = { 1, 2, 3, 4, }; | |
499 | assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256, &d, b1, ELEMENTSOF(b1), false) == 0); | |
500 | assert_se(digest_check(&d, "9f64a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a")); | |
501 | assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256, &d, b1, ELEMENTSOF(b1), true) == 0); | |
502 | assert_se(digest_check(&d, "ff3bd307b287e9b29bb572f6ccfd19deb0106d0c4c3c5cfe8a1d03a396092ed4")); | |
503 | ||
504 | const void *b2 = d2.buffer; | |
505 | assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256, &d, b2, d2.size, false) == 0); | |
506 | assert_se(digest_check(&d, "56571a1be3fbeab18d215f549095915a004b5788ca0d535be668559129a76f25")); | |
507 | assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256, &d, b2, d2.size, true) == 0); | |
508 | assert_se(digest_check(&d, "99dedaee8f4d8d10a8be184399fde8740d5e17ff783ee5c288a4486e4ce3a1fe")); | |
509 | ||
510 | /* tpm2_digest_many */ | |
511 | const struct iovec iov1[] = { | |
512 | IOVEC_MAKE((void*) b1, ELEMENTSOF(b1)), | |
513 | IOVEC_MAKE(d2.buffer, d2.size), | |
514 | IOVEC_MAKE(d3.buffer, d3.size), | |
515 | }; | |
516 | assert_se(tpm2_digest_many(TPM2_ALG_SHA256, &d, iov1, ELEMENTSOF(iov1), false) == 0); | |
517 | assert_se(digest_check(&d, "cd7bde4a047af976b6f1b282309976229be59f96a78aa186de32a1aee488ab09")); | |
518 | assert_se(tpm2_digest_many(TPM2_ALG_SHA256, &d, iov1, ELEMENTSOF(iov1), true) == 0); | |
519 | assert_se(digest_check(&d, "02ecb0628264235111e0053e271092981c8b15d59cd46617836bee3149a4ecb0")); | |
520 | } | |
521 | ||
07c04061 DS |
522 | static void check_parse_pcr_argument( |
523 | const char *arg, | |
524 | const Tpm2PCRValue *prev_values, | |
525 | size_t n_prev_values, | |
526 | const Tpm2PCRValue *expected_values, | |
527 | size_t n_expected_values) { | |
528 | ||
529 | _cleanup_free_ Tpm2PCRValue *values = NULL; | |
530 | size_t n_values = 0; | |
531 | ||
532 | if (n_prev_values > 0) { | |
533 | assert_se(GREEDY_REALLOC_APPEND(values, n_values, prev_values, n_prev_values)); | |
534 | assert_se(tpm2_parse_pcr_argument_append(arg, &values, &n_values) == 0); | |
535 | } else | |
536 | assert_se(tpm2_parse_pcr_argument(arg, &values, &n_values) == 0); | |
537 | ||
538 | assert_se(n_values == n_expected_values); | |
539 | for (size_t i = 0; i < n_values; i++) { | |
540 | const Tpm2PCRValue *v = &values[i], *e = &expected_values[i]; | |
541 | //tpm2_log_debug_pcr_value(e, "Expected value"); | |
542 | //tpm2_log_debug_pcr_value(v, "Actual value"); | |
543 | ||
544 | assert_se(v->index == e->index); | |
545 | assert_se(v->hash == e->hash); | |
546 | assert_se(v->value.size == e->value.size); | |
547 | assert_se(memcmp(v->value.buffer, e->value.buffer, e->value.size) == 0); | |
548 | } | |
549 | ||
550 | size_t hash_count; | |
551 | assert_se(tpm2_pcr_values_hash_count(expected_values, n_expected_values, &hash_count) == 0); | |
552 | if (hash_count == 1) { | |
553 | uint32_t mask = UINT32_MAX, expected_mask = 0; | |
554 | ||
555 | if (n_prev_values > 0) | |
556 | assert_se(tpm2_pcr_values_to_mask(prev_values, n_prev_values, prev_values[0].hash, &mask) == 0); | |
557 | ||
558 | assert_se(tpm2_pcr_values_to_mask(expected_values, n_expected_values, expected_values[0].hash, &expected_mask) == 0); | |
559 | ||
560 | assert_se(tpm2_parse_pcr_argument_to_mask(arg, &mask) == 0); | |
561 | assert_se(mask == expected_mask); | |
562 | } | |
563 | ||
564 | size_t old_n_values = n_values; | |
565 | assert_se(tpm2_parse_pcr_argument_append("", &values, &n_values) == 0); | |
566 | assert_se(values); | |
567 | assert_se(n_values == old_n_values); | |
568 | } | |
569 | ||
570 | static void check_parse_pcr_argument_to_mask(const char *arg, int mask) { | |
571 | uint32_t m = 0; | |
572 | int r = tpm2_parse_pcr_argument_to_mask(arg, &m); | |
573 | ||
574 | if (mask < 0) | |
575 | assert_se(mask == r); | |
576 | else | |
577 | assert_se((uint32_t) mask == m); | |
578 | } | |
579 | ||
580 | TEST(parse_pcr_argument) { | |
581 | _cleanup_free_ Tpm2PCRValue *t0p = NULL; | |
582 | size_t n_t0p; | |
583 | assert_se(tpm2_parse_pcr_argument("", &t0p, &n_t0p) == 0); | |
584 | assert_se(n_t0p == 0); | |
585 | assert_se(tpm2_parse_pcr_argument_append("", &t0p, &n_t0p) == 0); | |
586 | assert_se(n_t0p == 0); | |
587 | uint32_t m0 = 0xf; | |
588 | assert_se(tpm2_parse_pcr_argument_to_mask("", &m0) == 0); | |
589 | assert_se(m0 == 0); | |
590 | assert_se(tpm2_parse_pcr_argument_to_mask("", &m0) == 0); | |
591 | assert_se(m0 == 0); | |
592 | ||
593 | Tpm2PCRValue t1[] = { | |
594 | TPM2_PCR_VALUE_MAKE(0, 0, {}), | |
595 | TPM2_PCR_VALUE_MAKE(4, 0, {}), | |
596 | TPM2_PCR_VALUE_MAKE(7, 0, {}), | |
597 | TPM2_PCR_VALUE_MAKE(11, 0, {}), | |
598 | }; | |
599 | check_parse_pcr_argument("0,4,7,11", NULL, 0, t1, ELEMENTSOF(t1)); | |
600 | check_parse_pcr_argument("11,4,7,0", NULL, 0, t1, ELEMENTSOF(t1)); | |
601 | check_parse_pcr_argument("7,4,0,11", NULL, 0, t1, ELEMENTSOF(t1)); | |
602 | check_parse_pcr_argument("11,7,4,0", NULL, 0, t1, ELEMENTSOF(t1)); | |
603 | check_parse_pcr_argument("0+4+7+11", NULL, 0, t1, ELEMENTSOF(t1)); | |
604 | check_parse_pcr_argument("0,4+7,11", NULL, 0, t1, ELEMENTSOF(t1)); | |
605 | ||
606 | Tpm2PCRValue t2[] = { | |
607 | TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA1, {}), | |
608 | TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA1, {}), | |
609 | TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA1, {}), | |
610 | TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA1, {}), | |
611 | }; | |
612 | check_parse_pcr_argument("0:sha1,4,7,11", NULL, 0, t2, ELEMENTSOF(t2)); | |
613 | check_parse_pcr_argument("11,4,7,0:sha1", NULL, 0, t2, ELEMENTSOF(t2)); | |
614 | check_parse_pcr_argument("7,4:sha1,0,11", NULL, 0, t2, ELEMENTSOF(t2)); | |
615 | check_parse_pcr_argument("0:sha1,4:sha1,7:sha1,11:sha1", NULL, 0, t2, ELEMENTSOF(t2)); | |
616 | check_parse_pcr_argument("0:sha1+4:sha1,11:sha1+7:sha1", NULL, 0, t2, ELEMENTSOF(t2)); | |
617 | ||
618 | Tpm2PCRValue t3[] = { | |
619 | TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA1, {}), | |
620 | TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA1, {}), | |
621 | TPM2_PCR_VALUE_MAKE(2, TPM2_ALG_SHA1, {}), | |
622 | TPM2_PCR_VALUE_MAKE(3, TPM2_ALG_SHA1, {}), | |
623 | TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA1, {}), | |
624 | TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA1, {}), | |
625 | TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA1, {}), | |
626 | TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA1, {}), | |
627 | }; | |
628 | check_parse_pcr_argument("1,2,3,12", t2, ELEMENTSOF(t2), t3, ELEMENTSOF(t3)); | |
629 | check_parse_pcr_argument("12,2,3,1", t2, ELEMENTSOF(t2), t3, ELEMENTSOF(t3)); | |
630 | check_parse_pcr_argument("1,2,3,12:sha1", t1, ELEMENTSOF(t1), t3, ELEMENTSOF(t3)); | |
631 | check_parse_pcr_argument("1,2,3,12:sha1", t2, ELEMENTSOF(t2), t3, ELEMENTSOF(t3)); | |
632 | check_parse_pcr_argument("1:sha1,2,3,12", t1, ELEMENTSOF(t1), t3, ELEMENTSOF(t3)); | |
633 | check_parse_pcr_argument("1:sha1,2,3,12", t2, ELEMENTSOF(t2), t3, ELEMENTSOF(t3)); | |
634 | check_parse_pcr_argument("1:sha1,2:sha1,3:sha1,12:sha1", t1, ELEMENTSOF(t1), t3, ELEMENTSOF(t3)); | |
635 | check_parse_pcr_argument("1:sha1,2:sha1,3:sha1,12:sha1", t2, ELEMENTSOF(t2), t3, ELEMENTSOF(t3)); | |
636 | ||
637 | TPM2B_DIGEST d4; | |
638 | digest_init(&d4, "FCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2"); | |
639 | Tpm2PCRValue t4[] = { | |
640 | TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA256, {}), | |
641 | TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA256, d4), | |
642 | TPM2_PCR_VALUE_MAKE(2, TPM2_ALG_SHA256, {}), | |
643 | TPM2_PCR_VALUE_MAKE(3, TPM2_ALG_SHA256, {}), | |
644 | TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA256, {}), | |
645 | TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA256, {}), | |
646 | TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA256, {}), | |
647 | TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA256, {}), | |
648 | }; | |
649 | check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2,3,12", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4)); | |
650 | check_parse_pcr_argument("12,2,3,1:sha256=FCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4)); | |
651 | check_parse_pcr_argument("12,2,3,1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4)); | |
652 | check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2,3,12:SHA256", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4)); | |
653 | check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2,3,12", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4)); | |
654 | check_parse_pcr_argument("1:sha256=FCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2:sha256,3:sha256,12:sha256", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4)); | |
655 | check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2:sha256,3:sha256,12:sha256", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4)); | |
656 | ||
657 | TPM2B_DIGEST d5; | |
658 | digest_init(&d5, "0F21EADB7F27377668E3C8069BE88D116491FBEE"); | |
659 | Tpm2PCRValue t5[] = { | |
660 | TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA1, d5), | |
661 | TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA256, {}), | |
662 | TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA256, d4), | |
663 | TPM2_PCR_VALUE_MAKE(2, TPM2_ALG_SHA256, {}), | |
664 | TPM2_PCR_VALUE_MAKE(3, TPM2_ALG_SHA256, {}), | |
665 | TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA256, {}), | |
666 | TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA256, {}), | |
667 | TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA256, {}), | |
668 | TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA256, {}), | |
669 | TPM2_PCR_VALUE_MAKE(5, TPM2_ALG_SHA384, {}), | |
670 | TPM2_PCR_VALUE_MAKE(6, TPM2_ALG_SHA512, {}), | |
671 | }; | |
672 | check_parse_pcr_argument("0,1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,1:sha1=0F21EADB7F27377668E3C8069BE88D116491FBEE,2,3,4,7,11,12,5:sha384,6:sha512", NULL, 0, t5, ELEMENTSOF(t5)); | |
673 | check_parse_pcr_argument("1:sha1=0F21EADB7F27377668E3C8069BE88D116491FBEE,6:sha512,5:sha384", t4, ELEMENTSOF(t4), t5, ELEMENTSOF(t5)); | |
674 | ||
675 | Tpm2PCRValue *v = NULL; | |
676 | size_t n_v = 0; | |
677 | assert_se(tpm2_parse_pcr_argument("1,100", &v, &n_v) < 0); | |
678 | assert_se(tpm2_parse_pcr_argument("1,2=123456abc", &v, &n_v) < 0); | |
679 | assert_se(tpm2_parse_pcr_argument("1,2:invalid", &v, &n_v) < 0); | |
680 | assert_se(tpm2_parse_pcr_argument("1:sha1=invalid", &v, &n_v) < 0); | |
5152b845 | 681 | ASSERT_NULL(v); |
07c04061 DS |
682 | assert_se(n_v == 0); |
683 | ||
684 | check_parse_pcr_argument_to_mask("", 0x0); | |
685 | check_parse_pcr_argument_to_mask("0", 0x1); | |
686 | check_parse_pcr_argument_to_mask("1", 0x2); | |
687 | check_parse_pcr_argument_to_mask("0,1", 0x3); | |
688 | check_parse_pcr_argument_to_mask("0+1", 0x3); | |
689 | check_parse_pcr_argument_to_mask("0-1", -EINVAL); | |
690 | check_parse_pcr_argument_to_mask("foo", -EINVAL); | |
691 | check_parse_pcr_argument_to_mask("0,1,2", 0x7); | |
692 | check_parse_pcr_argument_to_mask("0+1+2", 0x7); | |
693 | check_parse_pcr_argument_to_mask("0+1,2", 0x7); | |
694 | check_parse_pcr_argument_to_mask("0,1+2", 0x7); | |
695 | check_parse_pcr_argument_to_mask("0,2", 0x5); | |
696 | check_parse_pcr_argument_to_mask("0+2", 0x5); | |
697 | check_parse_pcr_argument_to_mask("7+application-support", 0x800080); | |
698 | check_parse_pcr_argument_to_mask("8+boot-loader-code", 0x110); | |
699 | check_parse_pcr_argument_to_mask("7,shim-policy,4", 0x4090); | |
700 | check_parse_pcr_argument_to_mask("sysexts,shim-policy+kernel-boot", 0x6800); | |
701 | check_parse_pcr_argument_to_mask("sysexts,shim+kernel-boot", -EINVAL); | |
702 | check_parse_pcr_argument_to_mask("sysexts+17+23", 0x822000); | |
703 | check_parse_pcr_argument_to_mask("6+boot-loader-code,44", -EINVAL); | |
704 | check_parse_pcr_argument_to_mask("debug+24", -EINVAL); | |
705 | } | |
706 | ||
adcd3266 DS |
707 | static const TPMT_PUBLIC test_rsa_template = { |
708 | .type = TPM2_ALG_RSA, | |
709 | .nameAlg = TPM2_ALG_SHA256, | |
710 | .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH, | |
711 | .parameters.rsaDetail = { | |
712 | .symmetric = { | |
713 | .algorithm = TPM2_ALG_AES, | |
714 | .keyBits.aes = 128, | |
715 | .mode.aes = TPM2_ALG_CFB, | |
dbae4b95 | 716 | }, |
adcd3266 DS |
717 | .scheme.scheme = TPM2_ALG_NULL, |
718 | .keyBits = 2048, | |
719 | }, | |
720 | }; | |
721 | ||
722 | static const TPMT_PUBLIC test_ecc_template = { | |
723 | .type = TPM2_ALG_ECC, | |
724 | .nameAlg = TPM2_ALG_SHA256, | |
725 | .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH, | |
726 | .parameters.eccDetail = { | |
727 | .symmetric = { | |
728 | .algorithm = TPM2_ALG_AES, | |
729 | .keyBits.aes = 128, | |
730 | .mode.aes = TPM2_ALG_CFB, | |
731 | }, | |
732 | .scheme.scheme = TPM2_ALG_NULL, | |
733 | .curveID = TPM2_ECC_NIST_P256, | |
734 | .kdf.scheme = TPM2_ALG_NULL, | |
735 | }, | |
736 | }; | |
737 | ||
738 | static const TPMT_PUBLIC *test_templates[] = { | |
739 | &test_rsa_template, | |
740 | &test_ecc_template, | |
741 | }; | |
742 | ||
743 | static void tpm2b_public_rsa_init(TPM2B_PUBLIC *public, const char *rsa_n) { | |
744 | TPMT_PUBLIC tpmt = test_rsa_template; | |
dbae4b95 | 745 | |
e3acb4d2 | 746 | DEFINE_HEX_PTR(key, rsa_n); |
0fdcfa78 | 747 | tpmt.unique.rsa = TPM2B_PUBLIC_KEY_RSA_MAKE(key, key_len); |
dbae4b95 | 748 | |
e3acb4d2 | 749 | public->size = sizeof(tpmt); |
dbae4b95 DS |
750 | public->publicArea = tpmt; |
751 | } | |
752 | ||
e3acb4d2 | 753 | static void tpm2b_public_ecc_init(TPM2B_PUBLIC *public, TPMI_ECC_CURVE curve, const char *x, const char *y) { |
adcd3266 DS |
754 | TPMT_PUBLIC tpmt = test_ecc_template; |
755 | tpmt.parameters.eccDetail.curveID = curve; | |
e3acb4d2 DS |
756 | |
757 | DEFINE_HEX_PTR(buf_x, x); | |
758 | tpmt.unique.ecc.x = TPM2B_ECC_PARAMETER_MAKE(buf_x, buf_x_len); | |
759 | ||
760 | DEFINE_HEX_PTR(buf_y, y); | |
761 | tpmt.unique.ecc.y = TPM2B_ECC_PARAMETER_MAKE(buf_y, buf_y_len); | |
762 | ||
763 | public->size = sizeof(tpmt); | |
764 | public->publicArea = tpmt; | |
765 | } | |
766 | ||
767 | #if HAVE_OPENSSL | |
768 | TEST(tpm2b_public_to_openssl_pkey) { | |
769 | DEFINE_HEX_PTR(msg, "edc64c6523778961fe9ba03ab7d624b27ca1dd5b01e7734cc6c891d50db04269"); | |
770 | TPM2B_PUBLIC public; | |
771 | ||
772 | /* RSA */ | |
773 | tpm2b_public_rsa_init(&public, "d71cff5bba2173f0434a389171048e7da8cf8409b892c62946481cc383089bc754324620967fea3d00a02a717cdda4bfe1525ad957d294b88434e0a3933e86fb40f234e4935fd2ba27eb1d21da87efa466b74eb4ad18d26059904643441cf402ee933d138a2151f40459c49d87fef59e2cb822768b2d8689a9b58f82bf9a37e70693f2b2d40dfa388d365c1b1f029a14c4fc8dadb68978ef377d20ff2ca24e7078464c705eab42f531557c9c6dc0df66b506d0c26ef604f8110c64867099267453c71871e7ed22505a09daf102afc34355209ca7680eccc0ed368d148f402fa58cbb6c9d52351f535f09e4e24ad805e149f130edaa2f5e7efed3a4d2d03adb85"); | |
774 | _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey_rsa = NULL; | |
775 | assert_se(tpm2_tpm2b_public_to_openssl_pkey(&public, &pkey_rsa) >= 0); | |
776 | ||
777 | _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx_rsa = EVP_PKEY_CTX_new((EVP_PKEY*) pkey_rsa, NULL); | |
778 | assert_se(ctx_rsa); | |
779 | assert_se(EVP_PKEY_verify_init(ctx_rsa) == 1); | |
780 | assert_se(EVP_PKEY_CTX_set_signature_md(ctx_rsa, EVP_sha256()) > 0); | |
781 | ||
782 | DEFINE_HEX_PTR(sig_rsa, "9f70a9e68911be3ec464cae91126328307bf355872127e042d6c61e0a80982872c151033bcf727abfae5fc9500c923120011e7ef4aa5fc690a59a034697b6022c141b4b209e2df6f4b282288cd9181073fbe7158ce113c79d87623423c1f3996ff931e59cc91db74f8e8656215b1436fc93ddec0f1f8fa8510826e674b250f047e6cba94c95ff98072a286baca94646b577974a1e00d56c21944e38960d8ee90511a2f938e5cf1ac7b7cc7ff8e3ac001d321254d3e4f988b90e9f6f873c26ecd0a12a626b3474833cdbb9e9f793238f6c97ee5b75a1a89bb7a7858d34ecfa6d34ac58d95085e6c4fbbebd47a4364be2725c2c6b3fa15d916f3c0b62a66fe76ae"); | |
783 | assert_se(EVP_PKEY_verify(ctx_rsa, sig_rsa, sig_rsa_len, (unsigned char*) msg, msg_len) == 1); | |
784 | ||
785 | /* ECC */ | |
786 | tpm2b_public_ecc_init(&public, TPM2_ECC_NIST_P256, "6fc0ecf3645c673ab7e86d1ec5b315afb950257c5f68ab23296160006711fac2", "8dd2ef7a2c9ecede91493ba98c8fb3f893aff325c6a1e0f752c657b2d6ca1413"); | |
787 | _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey_ecc = NULL; | |
788 | assert_se(tpm2_tpm2b_public_to_openssl_pkey(&public, &pkey_ecc) >= 0); | |
789 | ||
790 | _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx_ecc = EVP_PKEY_CTX_new((EVP_PKEY*) pkey_ecc, NULL); | |
791 | assert_se(ctx_ecc); | |
792 | assert_se(EVP_PKEY_verify_init(ctx_ecc) == 1); | |
793 | ||
794 | DEFINE_HEX_PTR(sig_ecc, "304602210092447ac0b5b32e90923f79bb4aba864b9c546a9900cf193a83243d35d189a2110221009a8b4df1dfa85e225eff9c606694d4d205a7a3968c9552f50bc2790209a90001"); | |
795 | assert_se(EVP_PKEY_verify(ctx_ecc, sig_ecc, sig_ecc_len, (unsigned char*) msg, msg_len) == 1); | |
796 | } | |
797 | ||
798 | static void get_tpm2b_public_from_pem(const void *pem, size_t pem_size, TPM2B_PUBLIC *ret) { | |
799 | _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL; | |
800 | TPM2B_PUBLIC p1 = {}, p2 = {}; | |
801 | ||
802 | assert(pem); | |
803 | assert(ret); | |
804 | ||
805 | assert_se(openssl_pkey_from_pem(pem, pem_size, &pkey) >= 0); | |
806 | assert_se(tpm2_tpm2b_public_from_openssl_pkey(pkey, &p1) >= 0); | |
807 | assert_se(tpm2_tpm2b_public_from_pem(pem, pem_size, &p2) >= 0); | |
808 | assert_se(memcmp_nn(&p1, sizeof(p1), &p2, sizeof(p2)) == 0); | |
809 | ||
810 | *ret = p1; | |
811 | } | |
812 | ||
813 | static void check_tpm2b_public_fingerprint(const TPM2B_PUBLIC *public, const char *hexfp) { | |
814 | DEFINE_HEX_PTR(expected, hexfp); | |
815 | _cleanup_free_ void *fp = NULL; | |
816 | size_t fp_size; | |
817 | ||
818 | assert_se(tpm2_tpm2b_public_to_fingerprint(public, &fp, &fp_size) >= 0); | |
819 | assert_se(memcmp_nn(fp, fp_size, expected, expected_len) == 0); | |
820 | } | |
821 | ||
e2e8d8f2 DS |
822 | static void check_tpm2b_public_name(const TPM2B_PUBLIC *public, const char *hexname) { |
823 | DEFINE_HEX_PTR(expected, hexname); | |
824 | TPM2B_NAME name = {}; | |
825 | ||
826 | assert_se(tpm2_calculate_pubkey_name(&public->publicArea, &name) >= 0); | |
827 | assert_se(memcmp_nn(name.name, name.size, expected, expected_len) == 0); | |
828 | } | |
829 | ||
830 | static void check_tpm2b_public_from_ecc_pem(const char *pem, const char *hexx, const char *hexy, const char *hexfp, const char *hexname) { | |
831 | TPM2B_PUBLIC public = {}; | |
e3acb4d2 DS |
832 | TPMT_PUBLIC *p = &public.publicArea; |
833 | ||
e2e8d8f2 DS |
834 | DEFINE_HEX_PTR(key, pem); |
835 | get_tpm2b_public_from_pem(key, key_len, &public); | |
e3acb4d2 DS |
836 | |
837 | assert_se(p->type == TPM2_ALG_ECC); | |
838 | assert_se(p->parameters.eccDetail.curveID == TPM2_ECC_NIST_P256); | |
839 | ||
e2e8d8f2 | 840 | DEFINE_HEX_PTR(expected_x, hexx); |
e3acb4d2 DS |
841 | assert_se(memcmp_nn(p->unique.ecc.x.buffer, p->unique.ecc.x.size, expected_x, expected_x_len) == 0); |
842 | ||
e2e8d8f2 | 843 | DEFINE_HEX_PTR(expected_y, hexy); |
e3acb4d2 DS |
844 | assert_se(memcmp_nn(p->unique.ecc.y.buffer, p->unique.ecc.y.size, expected_y, expected_y_len) == 0); |
845 | ||
e2e8d8f2 DS |
846 | check_tpm2b_public_fingerprint(&public, hexfp); |
847 | check_tpm2b_public_name(&public, hexname); | |
848 | } | |
e3acb4d2 | 849 | |
e2e8d8f2 DS |
850 | static void check_tpm2b_public_from_rsa_pem(const char *pem, const char *hexn, uint32_t exponent, const char *hexfp, const char *hexname) { |
851 | TPM2B_PUBLIC public = {}; | |
852 | TPMT_PUBLIC *p = &public.publicArea; | |
e3acb4d2 | 853 | |
e2e8d8f2 DS |
854 | DEFINE_HEX_PTR(key, pem); |
855 | get_tpm2b_public_from_pem(key, key_len, &public); | |
e3acb4d2 | 856 | |
e2e8d8f2 | 857 | assert_se(p->type == TPM2_ALG_RSA); |
e3acb4d2 | 858 | |
e2e8d8f2 DS |
859 | DEFINE_HEX_PTR(expected_n, hexn); |
860 | assert_se(memcmp_nn(p->unique.rsa.buffer, p->unique.rsa.size, expected_n, expected_n_len) == 0); | |
910caa24 | 861 | |
e2e8d8f2 | 862 | assert_se(p->parameters.rsaDetail.keyBits == expected_n_len * 8); |
910caa24 | 863 | |
e2e8d8f2 | 864 | assert_se(p->parameters.rsaDetail.exponent == exponent); |
910caa24 | 865 | |
e2e8d8f2 DS |
866 | check_tpm2b_public_fingerprint(&public, hexfp); |
867 | check_tpm2b_public_name(&public, hexname); | |
868 | } | |
910caa24 | 869 | |
e2e8d8f2 DS |
870 | TEST(tpm2b_public_from_openssl_pkey) { |
871 | /* standard ECC key */ | |
872 | check_tpm2b_public_from_ecc_pem("2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a30444151634451674145726a6e4575424c73496c3972687068777976584e50686a346a426e500a44586e794a304b395579724e6764365335413532542b6f5376746b436a365a726c34685847337741515558706f426c532b7448717452714c35513d3d0a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a", | |
873 | "ae39c4b812ec225f6b869870caf5cd3e18f88c19cf0d79f22742bd532acd81de", | |
874 | "92e40e764fea12bed9028fa66b9788571b7c004145e9a01952fad1eab51a8be5", | |
875 | "cd3373293b62a52b48c12100e80ea9bfd806266ce76893a5ec31cb128052d97c", | |
876 | "000b5c127e4dbaf8fb7bac641e8db25a84a48db876ca7ee3bd317ae1a4554ff72f17"); | |
877 | ||
878 | /* standard RSA key */ | |
879 | check_tpm2b_public_from_rsa_pem("2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d494942496a414e42676b71686b6947397730424151454641414f43415138414d49494243674b4341514541795639434950652f505852337a436f63787045300a6a575262546c3568585844436b472f584b79374b6d2f4439584942334b734f5a31436a5937375571372f674359363170697838697552756a73413464503165380a593445336c68556d374a332b6473766b626f4b64553243626d52494c2f6675627771694c4d587a41673342575278747234547545443533527a373634554650640a307a70304b68775231496230444c67772f344e67566f314146763378784b4d6478774d45683567676b73733038326332706c354a504e32587677426f744e6b4d0a5471526c745a4a35355244436170696e7153334577376675646c4e735851357746766c7432377a7637344b585165616d704c59433037584f6761304c676c536b0a79754774586b6a50542f735542544a705374615769674d5a6f714b7479563463515a58436b4a52684459614c47587673504233687a766d5671636e6b47654e540a65774944415141420a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a", | |
880 | "c95f4220f7bf3d7477cc2a1cc691348d645b4e5e615d70c2906fd72b2eca9bf0fd5c80772ac399d428d8efb52aeff80263ad698b1f22b91ba3b00e1d3f57bc638137961526ec9dfe76cbe46e829d53609b99120bfdfb9bc2a88b317cc0837056471b6be13b840f9dd1cfbeb85053ddd33a742a1c11d486f40cb830ff8360568d4016fdf1c4a31dc7030487982092cb34f36736a65e493cdd97bf0068b4d90c4ea465b59279e510c26a98a7a92dc4c3b7ee76536c5d0e7016f96ddbbcefef829741e6a6a4b602d3b5ce81ad0b8254a4cae1ad5e48cf4ffb140532694ad6968a0319a2a2adc95e1c4195c29094610d868b197bec3c1de1cef995a9c9e419e3537b", | |
881 | 0x10001, | |
882 | "d9186d13a7fd5b3644cee05448f49ad3574e82a2942ff93cf89598d36cca78a9", | |
883 | "000be1bd75c7976e7a30e9e82223b81a9eff0d42c30618e588db592ed5da94455e81"); | |
910caa24 | 884 | |
e2e8d8f2 DS |
885 | /* RSA key with non-default (i.e. not 0x10001) exponent */ |
886 | check_tpm2b_public_from_rsa_pem("2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d494942496a414e42676b71686b6947397730424151454641414f43415138414d49494243674b434151454179566c7551664b75565171596a5a71436a657a760a364e4a6f58654c736f702f72765375666330773769544d4f73566741557462515452505451725874397065537a4370524467634378656b6a544144577279304b0a6d59786a7a3634776c6a7030463959383068636a6b6b4b3759414d333054664c4648656c2b377574427370777142467a6e2b385a6659567353434b397354706f0a316c61376e5347514e7451576f36444a366c525a336a676d6d584f61544654416145304a432b7046584273564471736d46326438362f314e51714a755a5154520a575852636954704e58357649792f37766b6c5a6a685569526c78764e594f4e3070636476534a37364e74496e447a3048506f775a38705a454f4d2f4a454f59780a617a4c4a6a644936446b355279593578325a7949375074566a3057537242524f4d696f2b674c6556457a43343456336438315a38445138564e334c69625130330a70514944415141460a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a", | |
887 | "c9596e41f2ae550a988d9a828decefe8d2685de2eca29febbd2b9f734c3b89330eb1580052d6d04d13d342b5edf69792cc2a510e0702c5e9234c00d6af2d0a998c63cfae30963a7417d63cd217239242bb600337d137cb1477a5fbbbad06ca70a811739fef197d856c4822bdb13a68d656bb9d219036d416a3a0c9ea5459de382699739a4c54c0684d090bea455c1b150eab2617677cebfd4d42a26e6504d159745c893a4d5f9bc8cbfeef925663854891971bcd60e374a5c76f489efa36d2270f3d073e8c19f2964438cfc910e6316b32c98dd23a0e4e51c98e71d99c88ecfb558f4592ac144e322a3e80b7951330b8e15dddf3567c0d0f153772e26d0d37a5", | |
888 | 0x10005, | |
889 | "c8ca80a687d5972e1d961aaa2cfde2ff2e7a20d85e3ea0382804e70e013d65af", | |
890 | "000beb8974d36d8cf58fdc87460dda00319e10c94c1b9f222ac9ce29d1c4776246cc"); | |
e3acb4d2 DS |
891 | } |
892 | #endif | |
893 | ||
894 | static void check_name(const TPM2B_NAME *name, const char *expect) { | |
895 | assert_se(name->size == SHA256_DIGEST_SIZE + 2); | |
896 | ||
897 | DEFINE_HEX_PTR(e, expect); | |
898 | assert_se(name->size == e_len); | |
899 | assert_se(memcmp(name->name, e, e_len) == 0); | |
900 | } | |
901 | ||
b98c4f1d | 902 | TEST(calculate_pubkey_name) { |
dbae4b95 DS |
903 | TPM2B_PUBLIC public; |
904 | TPM2B_NAME name; | |
905 | ||
e3acb4d2 DS |
906 | /* RSA */ |
907 | tpm2b_public_rsa_init(&public, "9ec7341c52093ac40a1965a5df10432513c539adcf905e30577ab6ebc88ffe53cd08cef12ed9bec6125432f4fada3629b8b96d31b8f507aa35029188fe396da823fcb236027f7fbb01b0da3d87be7f999390449ced604bdf7e26c48657cc0671000f1147da195c3861c96642e54427cb7a11572e07567ec3fd6316978abc4bd92b27bb0a0e4958e599804eeb41d682b3b7fc1f960209f80a4fb8a1b64abfd96bf5d554e73cdd6ad1c8becb4fcf5e8f0c3e621d210e5e2f308f6520ad9a966779231b99f06c5989e5a23a9415c8808ab89ce81117632e2f8461cd4428bded40979236aeadafe8de3f51660a45e1dbc87694e6a36360201cca3ff9e7263e712727"); | |
b98c4f1d | 908 | assert_se(tpm2_calculate_pubkey_name(&public.publicArea, &name) >= 0); |
e3acb4d2 | 909 | check_name(&name, "000be78f74a470dd92e979ca067cdb2293a35f075e8560b436bd2ccea5da21486a07"); |
dbae4b95 | 910 | |
e3acb4d2 DS |
911 | /* ECC */ |
912 | tpm2b_public_ecc_init(&public, TPM2_ECC_NIST_P256, "238e02ee4fd5598add6b502429f1815418515e4b0d6551c8e816b38cb15451d1", "70c2d491769775ec43ccd5a571c429233e9d30cf0f486c2e01acd6cb32ba93b6"); | |
b98c4f1d | 913 | assert_se(tpm2_calculate_pubkey_name(&public.publicArea, &name) >= 0); |
e3acb4d2 | 914 | check_name(&name, "000b302787187ba19c82011c987bd2dcdbb652b3a543ccc5cb0b49c33d4caae604a6"); |
dbae4b95 DS |
915 | } |
916 | ||
8a716354 DS |
917 | TEST(calculate_policy_auth_value) { |
918 | TPM2B_DIGEST d; | |
919 | ||
07c04061 | 920 | digest_init(&d, "0000000000000000000000000000000000000000000000000000000000000000"); |
8a716354 DS |
921 | assert_se(tpm2_calculate_policy_auth_value(&d) == 0); |
922 | assert_se(digest_check(&d, "8fcd2169ab92694e0c633f1ab772842b8241bbc20288981fc7ac1eddc1fddb0e")); | |
923 | assert_se(tpm2_calculate_policy_auth_value(&d) == 0); | |
924 | assert_se(digest_check(&d, "759ebd5ed65100e0b4aa2d04b4b789c2672d92ecc9cdda4b5fa16a303132e008")); | |
925 | } | |
926 | ||
5c7852f7 DS |
927 | TEST(calculate_policy_authorize) { |
928 | TPM2B_PUBLIC public; | |
929 | TPM2B_DIGEST d; | |
930 | ||
e3acb4d2 DS |
931 | /* RSA */ |
932 | tpm2b_public_rsa_init(&public, "9ec7341c52093ac40a1965a5df10432513c539adcf905e30577ab6ebc88ffe53cd08cef12ed9bec6125432f4fada3629b8b96d31b8f507aa35029188fe396da823fcb236027f7fbb01b0da3d87be7f999390449ced604bdf7e26c48657cc0671000f1147da195c3861c96642e54427cb7a11572e07567ec3fd6316978abc4bd92b27bb0a0e4958e599804eeb41d682b3b7fc1f960209f80a4fb8a1b64abfd96bf5d554e73cdd6ad1c8becb4fcf5e8f0c3e621d210e5e2f308f6520ad9a966779231b99f06c5989e5a23a9415c8808ab89ce81117632e2f8461cd4428bded40979236aeadafe8de3f51660a45e1dbc87694e6a36360201cca3ff9e7263e712727"); | |
07c04061 | 933 | digest_init(&d, "0000000000000000000000000000000000000000000000000000000000000000"); |
5c7852f7 DS |
934 | assert_se(tpm2_calculate_policy_authorize(&public, NULL, &d) == 0); |
935 | assert_se(digest_check(&d, "95213a3784eaab04f427bc7e8851c2f1df0903be8e42428ec25dcefd907baff1")); | |
936 | assert_se(tpm2_calculate_policy_authorize(&public, NULL, &d) == 0); | |
937 | assert_se(digest_check(&d, "95213a3784eaab04f427bc7e8851c2f1df0903be8e42428ec25dcefd907baff1")); | |
e3acb4d2 DS |
938 | |
939 | /* ECC */ | |
940 | tpm2b_public_ecc_init(&public, TPM2_ECC_NIST_P256, "423a89da6f0998f510489ab9682706e762031ef8f9faef2a185eff67065a187e", "996f73291670cef9e303d6cd9fa19ddf2c9c1fb1e283324ca9acca07c405c8d0"); | |
941 | digest_init(&d, "0000000000000000000000000000000000000000000000000000000000000000"); | |
942 | assert_se(tpm2_calculate_policy_authorize(&public, NULL, &d) == 0); | |
943 | assert_se(digest_check(&d, "2a5b705e83f949c27ac4d2e79e54fb5fb0a60f0b37bbd54a0ee1022ba00d3628")); | |
944 | assert_se(tpm2_calculate_policy_authorize(&public, NULL, &d) == 0); | |
945 | assert_se(digest_check(&d, "2a5b705e83f949c27ac4d2e79e54fb5fb0a60f0b37bbd54a0ee1022ba00d3628")); | |
5c7852f7 DS |
946 | } |
947 | ||
dcbc4674 | 948 | TEST(calculate_policy_pcr) { |
6e8fb3ad DS |
949 | TPM2B_DIGEST d, dN[16]; |
950 | ||
07c04061 DS |
951 | digest_init(&dN[ 0], "2124793cbbe60c3a8637d3b84a5d054e87c351e1469a285acc04755e8b204dec"); |
952 | digest_init(&dN[ 1], "bf7592f18adcfdc549fc0b94939f5069a24697f9cff4a0dca29014767b97559d"); | |
953 | digest_init(&dN[ 2], "4b00cff9dee3a364979b2dc241b34568a8ad49fcf2713df259e47dff8875feed"); | |
954 | digest_init(&dN[ 3], "3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969"); | |
955 | digest_init(&dN[ 4], "368f85b3013041dfe203faaa364f00b07c5da7b1e5f1dbf2efb06fa6b9bd92de"); | |
956 | digest_init(&dN[ 5], "c97c40369691c8e4aa78fb3a52655cd193b780a838b8e23f5f476576919db5e5"); | |
957 | digest_init(&dN[ 6], "3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969"); | |
958 | digest_init(&dN[ 7], "aa1154c9e0a774854ccbed4c8ce7e9b906b3d700a1a8db1772d0341a62dbe51b"); | |
959 | digest_init(&dN[ 8], "cfde439a2c06af3479ca6bdc60429b90553d65300c5cfcc40004a08c6b5ad81a"); | |
960 | digest_init(&dN[ 9], "9c2bac22ef5ec84fcdb71c3ebf776cba1247e5da980e5ee08e45666a2edf0b8b"); | |
961 | digest_init(&dN[10], "9885873f4d7348199ad286f8f2476d4f866940950f6f9fb9f945ed352dbdcbd2"); | |
962 | digest_init(&dN[11], "42400ab950d21aa79d12cc4fdef67d1087a39ad64900619831c0974dbae54e44"); | |
963 | digest_init(&dN[12], "767d064382e56ca1ad3bdcc6bc596112e6c2008b593d3570d24c2bfa64c4628c"); | |
964 | digest_init(&dN[13], "30c16133175959408c9745d8dafadef5daf4b39cb2be04df0d60089bd46d3cc4"); | |
965 | digest_init(&dN[14], "e3991b7ddd47be7e92726a832d6874c5349b52b789fa0db8b558c69fea29574e"); | |
966 | digest_init(&dN[15], "852dae3ecb992bdeb13d6002fefeeffdd90feca8b378d56681ef2c885d0e5137"); | |
967 | ||
968 | digest_init(&d, "0000000000000000000000000000000000000000000000000000000000000000"); | |
6e8fb3ad DS |
969 | Tpm2PCRValue v1[] = { |
970 | TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA256, dN[4]), | |
971 | TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA256, dN[7]), | |
972 | TPM2_PCR_VALUE_MAKE(8, TPM2_ALG_SHA256, dN[8]), | |
973 | }; | |
974 | assert_se(tpm2_calculate_policy_pcr(v1, ELEMENTSOF(v1), &d) == 0); | |
dcbc4674 | 975 | assert_se(digest_check(&d, "76532a0e16f7e6bf6b02918c11f75d99d729fab0cc81d0df2c4284a2c4fe6e05")); |
6e8fb3ad | 976 | assert_se(tpm2_calculate_policy_pcr(v1, ELEMENTSOF(v1), &d) == 0); |
dcbc4674 DS |
977 | assert_se(digest_check(&d, "97e64bcabb64c1fa4b726528644926c8029f5b4458b0575c98c04fe225629a0b")); |
978 | ||
07c04061 | 979 | digest_init(&d, "0000000000000000000000000000000000000000000000000000000000000000"); |
6e8fb3ad DS |
980 | Tpm2PCRValue v2[] = { |
981 | TPM2_PCR_VALUE_MAKE( 0, TPM2_ALG_SHA256, dN[ 0]), | |
982 | TPM2_PCR_VALUE_MAKE( 1, TPM2_ALG_SHA256, dN[ 1]), | |
983 | TPM2_PCR_VALUE_MAKE( 2, TPM2_ALG_SHA256, dN[ 2]), | |
984 | TPM2_PCR_VALUE_MAKE( 3, TPM2_ALG_SHA256, dN[ 3]), | |
985 | TPM2_PCR_VALUE_MAKE( 4, TPM2_ALG_SHA256, dN[ 4]), | |
986 | TPM2_PCR_VALUE_MAKE( 5, TPM2_ALG_SHA256, dN[ 5]), | |
987 | TPM2_PCR_VALUE_MAKE( 6, TPM2_ALG_SHA256, dN[ 6]), | |
988 | TPM2_PCR_VALUE_MAKE( 7, TPM2_ALG_SHA256, dN[ 7]), | |
989 | TPM2_PCR_VALUE_MAKE( 8, TPM2_ALG_SHA256, dN[ 8]), | |
990 | TPM2_PCR_VALUE_MAKE( 9, TPM2_ALG_SHA256, dN[ 9]), | |
991 | TPM2_PCR_VALUE_MAKE(10, TPM2_ALG_SHA256, dN[10]), | |
992 | TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA256, dN[11]), | |
993 | TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA256, dN[12]), | |
994 | TPM2_PCR_VALUE_MAKE(13, TPM2_ALG_SHA256, dN[13]), | |
995 | TPM2_PCR_VALUE_MAKE(14, TPM2_ALG_SHA256, dN[14]), | |
996 | TPM2_PCR_VALUE_MAKE(15, TPM2_ALG_SHA256, dN[15]), | |
997 | }; | |
998 | assert_se(tpm2_calculate_policy_pcr(v2, ELEMENTSOF(v2), &d) == 0); | |
dcbc4674 | 999 | assert_se(digest_check(&d, "22be4f1674f792d6345cea9427701068f0e8d9f42755dcc0e927e545a68f9c13")); |
6e8fb3ad | 1000 | assert_se(tpm2_calculate_policy_pcr(v2, ELEMENTSOF(v2), &d) == 0); |
dcbc4674 DS |
1001 | assert_se(digest_check(&d, "7481fd1b116078eb3ac2456e4ad542c9b46b9b8eb891335771ca8e7c8f8e4415")); |
1002 | } | |
1003 | ||
2eea1b8f DS |
1004 | static void check_srk_rsa_template(TPMT_PUBLIC *template) { |
1005 | assert_se(template->type == TPM2_ALG_RSA); | |
1006 | assert_se(template->nameAlg == TPM2_ALG_SHA256); | |
1007 | assert_se(template->objectAttributes == 0x30472); | |
1008 | assert_se(template->parameters.rsaDetail.symmetric.algorithm == TPM2_ALG_AES); | |
1009 | assert_se(template->parameters.rsaDetail.symmetric.keyBits.sym == 128); | |
1010 | assert_se(template->parameters.rsaDetail.symmetric.mode.sym == TPM2_ALG_CFB); | |
1011 | assert_se(template->parameters.rsaDetail.scheme.scheme == TPM2_ALG_NULL); | |
1012 | assert_se(template->parameters.rsaDetail.keyBits == 2048); | |
1013 | } | |
1014 | ||
1015 | static void check_srk_ecc_template(TPMT_PUBLIC *template) { | |
1016 | assert_se(template->type == TPM2_ALG_ECC); | |
1017 | assert_se(template->nameAlg == TPM2_ALG_SHA256); | |
1018 | assert_se(template->objectAttributes == 0x30472); | |
1019 | assert_se(template->parameters.eccDetail.symmetric.algorithm == TPM2_ALG_AES); | |
1020 | assert_se(template->parameters.eccDetail.symmetric.keyBits.sym == 128); | |
1021 | assert_se(template->parameters.eccDetail.symmetric.mode.sym == TPM2_ALG_CFB); | |
1022 | assert_se(template->parameters.eccDetail.scheme.scheme == TPM2_ALG_NULL); | |
1023 | assert_se(template->parameters.eccDetail.kdf.scheme == TPM2_ALG_NULL); | |
1024 | assert_se(template->parameters.eccDetail.curveID == TPM2_ECC_NIST_P256); | |
1025 | } | |
1026 | ||
78893337 | 1027 | TEST(tpm2_get_srk_template) { |
2eea1b8f DS |
1028 | TPMT_PUBLIC template; |
1029 | ||
1030 | assert_se(tpm2_get_srk_template(TPM2_ALG_RSA, &template) >= 0); | |
1031 | check_srk_rsa_template(&template); | |
1032 | ||
1033 | assert_se(tpm2_get_srk_template(TPM2_ALG_ECC, &template) >= 0); | |
1034 | check_srk_ecc_template(&template); | |
1035 | } | |
1036 | ||
1037 | static void check_best_srk_template(Tpm2Context *c) { | |
47a7a4d4 LP |
1038 | TEST_LOG_FUNC(); |
1039 | ||
2eea1b8f DS |
1040 | TPMT_PUBLIC template; |
1041 | assert_se(tpm2_get_best_srk_template(c, &template) >= 0); | |
1042 | ||
1043 | assert_se(IN_SET(template.type, TPM2_ALG_ECC, TPM2_ALG_RSA)); | |
1044 | ||
1045 | if (template.type == TPM2_ALG_RSA) | |
1046 | check_srk_rsa_template(&template); | |
1047 | else | |
1048 | check_srk_ecc_template(&template); | |
78893337 DS |
1049 | } |
1050 | ||
adcd3266 DS |
1051 | static void check_test_parms(Tpm2Context *c) { |
1052 | assert(c); | |
a47060bb | 1053 | |
47a7a4d4 LP |
1054 | TEST_LOG_FUNC(); |
1055 | ||
a47060bb DS |
1056 | TPMU_PUBLIC_PARMS parms = { |
1057 | .symDetail.sym = { | |
1058 | .algorithm = TPM2_ALG_AES, | |
1059 | .keyBits.aes = 128, | |
1060 | .mode.aes = TPM2_ALG_CFB, | |
1061 | }, | |
1062 | }; | |
1063 | ||
1064 | /* Test with invalid parms */ | |
1065 | assert_se(!tpm2_test_parms(c, TPM2_ALG_CFB, &parms)); | |
1066 | ||
1067 | TPMU_PUBLIC_PARMS invalid_parms = parms; | |
1068 | invalid_parms.symDetail.sym.keyBits.aes = 1; | |
1069 | assert_se(!tpm2_test_parms(c, TPM2_ALG_SYMCIPHER, &invalid_parms)); | |
1070 | ||
1071 | /* Test with valid parms */ | |
1072 | assert_se(tpm2_test_parms(c, TPM2_ALG_SYMCIPHER, &parms)); | |
adcd3266 DS |
1073 | } |
1074 | ||
1075 | static void check_supports_alg(Tpm2Context *c) { | |
1076 | assert(c); | |
a47060bb | 1077 | |
47a7a4d4 LP |
1078 | TEST_LOG_FUNC(); |
1079 | ||
a47060bb | 1080 | /* Test invalid algs */ |
cbc92a31 DS |
1081 | assert_se(!tpm2_supports_alg(c, TPM2_ALG_ERROR)); |
1082 | assert_se(!tpm2_supports_alg(c, TPM2_ALG_LAST + 1)); | |
a47060bb DS |
1083 | |
1084 | /* Test valid algs */ | |
cbc92a31 DS |
1085 | assert_se(tpm2_supports_alg(c, TPM2_ALG_RSA)); |
1086 | assert_se(tpm2_supports_alg(c, TPM2_ALG_AES)); | |
1087 | assert_se(tpm2_supports_alg(c, TPM2_ALG_CFB)); | |
adcd3266 DS |
1088 | } |
1089 | ||
1090 | static void check_supports_command(Tpm2Context *c) { | |
1091 | assert(c); | |
adbf0c8c | 1092 | |
47a7a4d4 LP |
1093 | TEST_LOG_FUNC(); |
1094 | ||
171d5b69 DS |
1095 | /* Test invalid commands. TPM specification Part 2 ("Structures") section "TPM_CC (Command Codes)" |
1096 | * states bits 31:30 and 28:16 are reserved and must be 0. */ | |
1097 | assert_se(!tpm2_supports_command(c, UINT32_C(0x80000000))); | |
1098 | assert_se(!tpm2_supports_command(c, UINT32_C(0x40000000))); | |
1099 | assert_se(!tpm2_supports_command(c, UINT32_C(0x00100000))); | |
1100 | assert_se(!tpm2_supports_command(c, UINT32_C(0x80000144))); | |
1101 | assert_se(!tpm2_supports_command(c, UINT32_C(0x40000144))); | |
1102 | assert_se(!tpm2_supports_command(c, UINT32_C(0x00100144))); | |
1103 | ||
1104 | /* Test valid commands. We should be able to expect all TPMs support these. */ | |
1105 | assert_se(tpm2_supports_command(c, TPM2_CC_Startup)); | |
1106 | assert_se(tpm2_supports_command(c, TPM2_CC_StartAuthSession)); | |
adbf0c8c DS |
1107 | assert_se(tpm2_supports_command(c, TPM2_CC_Create)); |
1108 | assert_se(tpm2_supports_command(c, TPM2_CC_CreatePrimary)); | |
1109 | assert_se(tpm2_supports_command(c, TPM2_CC_Unseal)); | |
a47060bb DS |
1110 | } |
1111 | ||
2eea1b8f | 1112 | static void check_get_or_create_srk(Tpm2Context *c) { |
47a7a4d4 LP |
1113 | TEST_LOG_FUNC(); |
1114 | ||
2eea1b8f DS |
1115 | _cleanup_free_ TPM2B_PUBLIC *public = NULL; |
1116 | _cleanup_free_ TPM2B_NAME *name = NULL, *qname = NULL; | |
1117 | _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL; | |
1118 | assert_se(tpm2_get_or_create_srk(c, NULL, &public, &name, &qname, &handle) >= 0); | |
1119 | assert_se(public && name && qname && handle); | |
1120 | ||
1121 | _cleanup_free_ TPM2B_PUBLIC *public2 = NULL; | |
1122 | _cleanup_free_ TPM2B_NAME *name2 = NULL, *qname2 = NULL; | |
1123 | _cleanup_(tpm2_handle_freep) Tpm2Handle *handle2 = NULL; | |
1124 | assert_se(tpm2_get_srk(c, NULL, &public2, &name2, &qname2, &handle2) >= 0); | |
1125 | assert_se(public2 && name2 && qname2 && handle2); | |
1126 | ||
1127 | assert_se(memcmp_nn(public, sizeof(*public), public2, sizeof(*public2)) == 0); | |
1128 | assert_se(memcmp_nn(name->name, name->size, name2->name, name2->size) == 0); | |
1129 | assert_se(memcmp_nn(qname->name, qname->size, qname2->name, qname2->size) == 0); | |
1130 | } | |
1131 | ||
65883f6c DS |
1132 | #if HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3 |
1133 | static void calculate_seal_and_unseal( | |
1134 | Tpm2Context *c, | |
1135 | TPM2_HANDLE parent_index, | |
1136 | const TPM2B_PUBLIC *parent_public) { | |
1137 | ||
1138 | _cleanup_free_ char *secret_string = NULL; | |
1139 | assert_se(asprintf(&secret_string, "The classified documents are in room %x", parent_index) > 0); | |
1140 | size_t secret_size = strlen(secret_string) + 1; | |
1141 | ||
8d042bc4 | 1142 | _cleanup_(iovec_done) struct iovec blob = {}, serialized_parent = {}; |
65883f6c DS |
1143 | assert_se(tpm2_calculate_seal( |
1144 | parent_index, | |
1145 | parent_public, | |
1146 | /* attributes= */ NULL, | |
8d042bc4 | 1147 | &IOVEC_MAKE(secret_string, secret_size), |
65883f6c DS |
1148 | /* policy= */ NULL, |
1149 | /* pin= */ NULL, | |
8d042bc4 LP |
1150 | /* ret_secret= */ NULL, |
1151 | &blob, | |
1152 | &serialized_parent) >= 0); | |
65883f6c | 1153 | |
8d042bc4 | 1154 | _cleanup_(iovec_done) struct iovec unsealed_secret = {}; |
65883f6c DS |
1155 | assert_se(tpm2_unseal( |
1156 | c, | |
1157 | /* hash_pcr_mask= */ 0, | |
1158 | /* pcr_bank= */ 0, | |
8d042bc4 | 1159 | /* pubkey= */ NULL, |
65883f6c DS |
1160 | /* pubkey_pcr_mask= */ 0, |
1161 | /* signature= */ NULL, | |
1162 | /* pin= */ NULL, | |
1163 | /* pcrlock_policy= */ NULL, | |
1164 | /* primary_alg= */ 0, | |
8d042bc4 LP |
1165 | &blob, |
1166 | /* known_policy_hash= */ NULL, | |
1167 | &serialized_parent, | |
1168 | &unsealed_secret) >= 0); | |
65883f6c | 1169 | |
8d042bc4 | 1170 | assert_se(memcmp_nn(secret_string, secret_size, unsealed_secret.iov_base, unsealed_secret.iov_len) == 0); |
65883f6c | 1171 | |
8d042bc4 LP |
1172 | char unsealed_string[unsealed_secret.iov_len]; |
1173 | assert_se(snprintf(unsealed_string, unsealed_secret.iov_len, "%s", (char*) unsealed_secret.iov_base) == (int) unsealed_secret.iov_len - 1); | |
65883f6c DS |
1174 | log_debug("Unsealed secret is: %s", unsealed_string); |
1175 | } | |
1176 | ||
1177 | static int check_calculate_seal(Tpm2Context *c) { | |
1178 | assert(c); | |
1179 | int r; | |
1180 | ||
3aea672b LP |
1181 | if (detect_virtualization() == VIRTUALIZATION_NONE && !slow_tests_enabled()) { |
1182 | log_notice("Skipping slow calculate seal TPM2 tests. Physical system detected, and slow tests disabled."); | |
1183 | return 0; | |
1184 | } | |
1185 | ||
47a7a4d4 LP |
1186 | TEST_LOG_FUNC(); |
1187 | ||
65883f6c DS |
1188 | _cleanup_free_ TPM2B_PUBLIC *srk_public = NULL; |
1189 | assert_se(tpm2_get_srk(c, NULL, &srk_public, NULL, NULL, NULL) >= 0); | |
1190 | calculate_seal_and_unseal(c, TPM2_SRK_HANDLE, srk_public); | |
1191 | ||
1192 | TPMI_ALG_ASYM test_algs[] = { TPM2_ALG_RSA, TPM2_ALG_ECC, }; | |
1193 | for (unsigned i = 0; i < ELEMENTSOF(test_algs); i++) { | |
1194 | TPMI_ALG_ASYM alg = test_algs[i]; | |
1195 | ||
1196 | TPM2B_PUBLIC template = { .size = sizeof(TPMT_PUBLIC), }; | |
1197 | assert_se(tpm2_get_srk_template(alg, &template.publicArea) >= 0); | |
1198 | ||
1199 | _cleanup_free_ TPM2B_PUBLIC *public = NULL; | |
1200 | _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL; | |
1201 | assert_se(tpm2_create_primary(c, NULL, &template, NULL, &public, &handle) >= 0); | |
1202 | ||
1203 | /* Once our minimum libtss2-esys version is 2.4.0 or later, this can assume | |
1204 | * tpm2_index_from_handle() should always work. */ | |
1205 | TPM2_HANDLE index; | |
1206 | r = tpm2_index_from_handle(c, handle, &index); | |
1207 | if (r == -EOPNOTSUPP) | |
1208 | return log_tests_skipped("libtss2-esys version too old to support tpm2_index_from_handle()"); | |
1209 | assert_se(r >= 0); | |
1210 | ||
1211 | calculate_seal_and_unseal(c, index, public); | |
1212 | } | |
1213 | ||
1214 | return 0; | |
1215 | } | |
1216 | #endif /* HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3 */ | |
1217 | ||
adcd3266 DS |
1218 | static void check_seal_unseal_for_handle(Tpm2Context *c, TPM2_HANDLE handle) { |
1219 | TPM2B_DIGEST policy = TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE); | |
1220 | ||
1221 | assert(c); | |
1222 | ||
1223 | log_debug("Check seal/unseal for handle 0x%" PRIx32, handle); | |
1224 | ||
8d042bc4 | 1225 | _cleanup_(iovec_done) struct iovec secret = {}, blob = {}, srk = {}, unsealed_secret = {}; |
adcd3266 DS |
1226 | assert_se(tpm2_seal( |
1227 | c, | |
1228 | handle, | |
1229 | &policy, | |
1230 | /* pin= */ NULL, | |
8d042bc4 LP |
1231 | &secret, |
1232 | &blob, | |
adcd3266 | 1233 | /* ret_primary_alg= */ NULL, |
8d042bc4 | 1234 | &srk) >= 0); |
adcd3266 DS |
1235 | |
1236 | assert_se(tpm2_unseal( | |
1237 | c, | |
1238 | /* hash_pcr_mask= */ 0, | |
1239 | /* pcr_bank= */ 0, | |
8d042bc4 | 1240 | /* pubkey= */ NULL, |
adcd3266 DS |
1241 | /* pubkey_pcr_mask= */ 0, |
1242 | /* signature= */ NULL, | |
1243 | /* pin= */ NULL, | |
a4342701 | 1244 | /* pcrlock_policy= */ NULL, |
adcd3266 | 1245 | /* primary_alg= */ 0, |
8d042bc4 LP |
1246 | &blob, |
1247 | /* policy_hash= */ NULL, | |
1248 | &srk, | |
1249 | &unsealed_secret) >= 0); | |
adcd3266 | 1250 | |
8d042bc4 | 1251 | assert_se(iovec_memcmp(&secret, &unsealed_secret) == 0); |
adcd3266 DS |
1252 | } |
1253 | ||
1254 | static void check_seal_unseal(Tpm2Context *c) { | |
1255 | int r; | |
1256 | ||
1257 | assert(c); | |
1258 | ||
3aea672b LP |
1259 | if (detect_virtualization() == VIRTUALIZATION_NONE && !slow_tests_enabled()) { |
1260 | log_notice("Skipping slow seal/unseal TPM2 tests. Physical system detected, and slow tests disabled."); | |
1261 | return; | |
1262 | } | |
1263 | ||
47a7a4d4 LP |
1264 | TEST_LOG_FUNC(); |
1265 | ||
adcd3266 DS |
1266 | check_seal_unseal_for_handle(c, 0); |
1267 | check_seal_unseal_for_handle(c, TPM2_SRK_HANDLE); | |
1268 | ||
85471164 | 1269 | FOREACH_ELEMENT(template, test_templates) { |
adcd3266 DS |
1270 | TPM2B_PUBLIC public = { |
1271 | .publicArea = **template, | |
1272 | .size = sizeof(**template), | |
1273 | }; | |
1274 | _cleanup_(tpm2_handle_freep) Tpm2Handle *transient_handle = NULL; | |
1275 | assert_se(tpm2_create_primary( | |
1276 | c, | |
1277 | /* session= */ NULL, | |
1278 | &public, | |
1279 | /* sensitive= */ NULL, | |
1280 | /* ret_public= */ NULL, | |
1281 | &transient_handle) >= 0); | |
1282 | ||
1283 | TPMI_DH_PERSISTENT transient_handle_index; | |
1284 | r = tpm2_index_from_handle(c, transient_handle, &transient_handle_index); | |
1285 | if (r == -EOPNOTSUPP) { | |
1286 | /* libesys too old */ | |
1287 | log_tests_skipped("libesys too old for tpm2_index_from_handle"); | |
1288 | return; | |
1289 | } | |
1290 | assert_se(r >= 0); | |
1291 | ||
1292 | check_seal_unseal_for_handle(c, transient_handle_index); | |
1293 | } | |
1294 | } | |
1295 | ||
1296 | TEST_RET(tests_which_require_tpm) { | |
1297 | _cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL; | |
65883f6c | 1298 | int r = 0; |
adcd3266 DS |
1299 | |
1300 | if (tpm2_context_new(NULL, &c) < 0) | |
1301 | return log_tests_skipped("Could not find TPM"); | |
1302 | ||
1303 | check_test_parms(c); | |
1304 | check_supports_alg(c); | |
1305 | check_supports_command(c); | |
2eea1b8f DS |
1306 | check_best_srk_template(c); |
1307 | check_get_or_create_srk(c); | |
adcd3266 DS |
1308 | check_seal_unseal(c); |
1309 | ||
65883f6c DS |
1310 | #if HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3 /* calculating sealed object requires openssl >= 3 */ |
1311 | r = check_calculate_seal(c); | |
1312 | #endif | |
1313 | ||
1314 | return r; | |
adcd3266 DS |
1315 | } |
1316 | ||
e067a49f DS |
1317 | #endif /* HAVE_TPM2 */ |
1318 | ||
4f7452a8 | 1319 | DEFINE_TEST_MAIN(LOG_DEBUG); |