]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-tpm2.c
tpm2: add TPM2B_*_MAKE(), TPM2B_*_CHECK_SIZE() macros
[thirdparty/systemd.git] / src / test / test-tpm2.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "hexdecoct.h"
4 #include "tpm2-util.h"
5 #include "tests.h"
6
7 TEST(pcr_index_from_string) {
8 assert_se(pcr_index_from_string("platform-code") == 0);
9 assert_se(pcr_index_from_string("0") == 0);
10 assert_se(pcr_index_from_string("platform-config") == 1);
11 assert_se(pcr_index_from_string("1") == 1);
12 assert_se(pcr_index_from_string("external-code") == 2);
13 assert_se(pcr_index_from_string("2") == 2);
14 assert_se(pcr_index_from_string("external-config") == 3);
15 assert_se(pcr_index_from_string("3") == 3);
16 assert_se(pcr_index_from_string("boot-loader-code") == 4);
17 assert_se(pcr_index_from_string("4") == 4);
18 assert_se(pcr_index_from_string("boot-loader-config") == 5);
19 assert_se(pcr_index_from_string("5") == 5);
20 assert_se(pcr_index_from_string("secure-boot-policy") == 7);
21 assert_se(pcr_index_from_string("7") == 7);
22 assert_se(pcr_index_from_string("kernel-initrd") == 9);
23 assert_se(pcr_index_from_string("9") == 9);
24 assert_se(pcr_index_from_string("ima") == 10);
25 assert_se(pcr_index_from_string("10") == 10);
26 assert_se(pcr_index_from_string("kernel-boot") == 11);
27 assert_se(pcr_index_from_string("11") == 11);
28 assert_se(pcr_index_from_string("kernel-config") == 12);
29 assert_se(pcr_index_from_string("12") == 12);
30 assert_se(pcr_index_from_string("sysexts") == 13);
31 assert_se(pcr_index_from_string("13") == 13);
32 assert_se(pcr_index_from_string("shim-policy") == 14);
33 assert_se(pcr_index_from_string("14") == 14);
34 assert_se(pcr_index_from_string("system-identity") == 15);
35 assert_se(pcr_index_from_string("15") == 15);
36 assert_se(pcr_index_from_string("debug") == 16);
37 assert_se(pcr_index_from_string("16") == 16);
38 assert_se(pcr_index_from_string("application-support") == 23);
39 assert_se(pcr_index_from_string("23") == 23);
40 assert_se(pcr_index_from_string("hello") == -EINVAL);
41 assert_se(pcr_index_from_string("8") == 8);
42 assert_se(pcr_index_from_string("44") == -EINVAL);
43 assert_se(pcr_index_from_string("-5") == -EINVAL);
44 assert_se(pcr_index_from_string("24") == -EINVAL);
45 }
46
47 TEST(tpm2_util_pbkdf2_hmac_sha256) {
48
49 /*
50 * The test vectors from RFC 6070 [1] are for dkLen of 20 as it's SHA1
51 * other RFCs I bumped into had various differing dkLen and iter counts,
52 * so this was generated using Python's hmacmodule.
53 *
54 * 1. https://www.rfc-editor.org/rfc/rfc6070.html#page-2
55 */
56 static const struct {
57 const uint8_t pass[256];
58 size_t passlen;
59 const uint8_t salt[256];
60 size_t saltlen;
61 uint8_t expected[SHA256_DIGEST_SIZE];
62 } test_vectors[] = {
63 { .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} },
64 { .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} },
65 { .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} },
66 { .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} },
67 { .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} },
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={'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} },
69 { .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} },
70 { .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} },
71 { .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} },
72 };
73
74 uint8_t res[SHA256_DIGEST_SIZE];
75 for(size_t i = 0; i < sizeof(test_vectors)/sizeof(test_vectors[0]); i++) {
76
77 int rc = tpm2_util_pbkdf2_hmac_sha256(
78 test_vectors[i].pass,
79 test_vectors[i].passlen,
80 test_vectors[i].salt,
81 test_vectors[i].saltlen,
82 res);
83 assert_se(rc == 0);
84 assert_se(memcmp(test_vectors[i].expected, res, SHA256_DIGEST_SIZE) == 0);
85 }
86 }
87
88 #if HAVE_TPM2
89
90 #define POISON(type) \
91 ({ \
92 type _p; \
93 memset(&_p, 0xaa, sizeof(_p)); \
94 _p; \
95 })
96 #define POISON_TPML POISON(TPML_PCR_SELECTION)
97 #define POISON_TPMS POISON(TPMS_PCR_SELECTION)
98 #define POISON_U32 POISON(uint32_t)
99
100 static void assert_tpms_pcr_selection_eq(TPMS_PCR_SELECTION *a, TPMS_PCR_SELECTION *b) {
101 assert_se(a);
102 assert_se(b);
103
104 assert_se(a->hash == b->hash);
105 assert_se(a->sizeofSelect == b->sizeofSelect);
106
107 for (size_t i = 0; i < a->sizeofSelect; i++)
108 assert_se(a->pcrSelect[i] == b->pcrSelect[i]);
109 }
110
111 static void assert_tpml_pcr_selection_eq(TPML_PCR_SELECTION *a, TPML_PCR_SELECTION *b) {
112 assert_se(a);
113 assert_se(b);
114
115 assert_se(a->count == b->count);
116 for (size_t i = 0; i < a->count; i++)
117 assert_tpms_pcr_selection_eq(&a->pcrSelections[i], &b->pcrSelections[i]);
118 }
119
120 static void verify_tpms_pcr_selection(TPMS_PCR_SELECTION *s, uint32_t mask, TPMI_ALG_HASH hash) {
121 assert_se(s->hash == hash);
122 assert_se(s->sizeofSelect == 3);
123 assert_se(s->pcrSelect[0] == (mask & 0xff));
124 assert_se(s->pcrSelect[1] == ((mask >> 8) & 0xff));
125 assert_se(s->pcrSelect[2] == ((mask >> 16) & 0xff));
126 assert_se(s->pcrSelect[3] == 0);
127
128 assert_se(tpm2_tpms_pcr_selection_to_mask(s) == mask);
129 }
130
131 static void verify_tpml_pcr_selection(TPML_PCR_SELECTION *l, TPMS_PCR_SELECTION s[], size_t count) {
132 assert_se(l->count == count);
133 for (size_t i = 0; i < count; i++) {
134 assert_tpms_pcr_selection_eq(&s[i], &l->pcrSelections[i]);
135
136 TPMI_ALG_HASH hash = l->pcrSelections[i].hash;
137 verify_tpms_pcr_selection(&l->pcrSelections[i], tpm2_tpml_pcr_selection_to_mask(l, hash), hash);
138 }
139 }
140
141 static void _test_pcr_selection_mask_hash(uint32_t mask, TPMI_ALG_HASH hash) {
142 TPMS_PCR_SELECTION s = POISON_TPMS;
143 tpm2_tpms_pcr_selection_from_mask(mask, hash, &s);
144 verify_tpms_pcr_selection(&s, mask, hash);
145
146 TPML_PCR_SELECTION l = POISON_TPML;
147 tpm2_tpml_pcr_selection_from_mask(mask, hash, &l);
148 verify_tpml_pcr_selection(&l, &s, 1);
149 verify_tpms_pcr_selection(&l.pcrSelections[0], mask, hash);
150
151 uint32_t test_masks[] = {
152 0x0, 0x1, 0x100, 0x10000, 0xf0f0f0, 0xaaaaaa, 0xffffff,
153 };
154 for (unsigned i = 0; i < ELEMENTSOF(test_masks); i++) {
155 uint32_t test_mask = test_masks[i];
156
157 TPMS_PCR_SELECTION a = POISON_TPMS, b = POISON_TPMS, test_s = POISON_TPMS;
158 tpm2_tpms_pcr_selection_from_mask(test_mask, hash, &test_s);
159
160 a = s;
161 b = test_s;
162 tpm2_tpms_pcr_selection_add(&a, &b);
163 verify_tpms_pcr_selection(&a, UPDATE_FLAG(mask, test_mask, true), hash);
164 verify_tpms_pcr_selection(&b, test_mask, hash);
165
166 a = s;
167 b = test_s;
168 tpm2_tpms_pcr_selection_sub(&a, &b);
169 verify_tpms_pcr_selection(&a, UPDATE_FLAG(mask, test_mask, false), hash);
170 verify_tpms_pcr_selection(&b, test_mask, hash);
171
172 a = s;
173 b = test_s;
174 tpm2_tpms_pcr_selection_move(&a, &b);
175 verify_tpms_pcr_selection(&a, UPDATE_FLAG(mask, test_mask, true), hash);
176 verify_tpms_pcr_selection(&b, 0, hash);
177 }
178 }
179
180 TEST(tpms_pcr_selection_mask_and_hash) {
181 TPMI_ALG_HASH HASH_ALGS[] = { TPM2_ALG_SHA1, TPM2_ALG_SHA256, };
182
183 for (unsigned i = 0; i < ELEMENTSOF(HASH_ALGS); i++)
184 for (uint32_t m2 = 0; m2 <= 0xffffff; m2 += 0x50000)
185 for (uint32_t m1 = 0; m1 <= 0xffff; m1 += 0x500)
186 for (uint32_t m0 = 0; m0 <= 0xff; m0 += 0x5)
187 _test_pcr_selection_mask_hash(m0 | m1 | m2, HASH_ALGS[i]);
188 }
189
190 static void _test_tpms_sw(
191 TPMI_ALG_HASH hash,
192 uint32_t mask,
193 const char *expected_str,
194 size_t expected_weight) {
195
196 TPMS_PCR_SELECTION s = POISON_TPMS;
197 tpm2_tpms_pcr_selection_from_mask(mask, hash, &s);
198
199 _cleanup_free_ char *tpms_str = tpm2_tpms_pcr_selection_to_string(&s);
200 assert_se(streq(tpms_str, expected_str));
201
202 assert_se(tpm2_tpms_pcr_selection_weight(&s) == expected_weight);
203 assert_se(tpm2_tpms_pcr_selection_is_empty(&s) == (expected_weight == 0));
204 }
205
206 TEST(tpms_pcr_selection_string_and_weight) {
207 TPMI_ALG_HASH sha1 = TPM2_ALG_SHA1, sha256 = TPM2_ALG_SHA256;
208
209 _test_tpms_sw(sha1, 0, "sha1()", 0);
210 _test_tpms_sw(sha1, 1, "sha1(0)", 1);
211 _test_tpms_sw(sha1, 0xf, "sha1(0+1+2+3)", 4);
212 _test_tpms_sw(sha1, 0x00ff00, "sha1(8+9+10+11+12+13+14+15)", 8);
213 _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);
214 _test_tpms_sw(sha256, 0, "sha256()", 0);
215 _test_tpms_sw(sha256, 1, "sha256(0)", 1);
216 _test_tpms_sw(sha256, 7, "sha256(0+1+2)", 3);
217 _test_tpms_sw(sha256, 0xf00000, "sha256(20+21+22+23)", 4);
218 _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);
219 }
220
221 static void _tpml_pcr_selection_add_tpms(TPMS_PCR_SELECTION s[], size_t count, TPML_PCR_SELECTION *ret) {
222 for (size_t i = 0; i < count; i++)
223 tpm2_tpml_pcr_selection_add_tpms_pcr_selection(ret, &s[i]);
224 }
225
226 static void _tpml_pcr_selection_sub_tpms(TPMS_PCR_SELECTION s[], size_t count, TPML_PCR_SELECTION *ret) {
227 for (size_t i = 0; i < count; i++)
228 tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(ret, &s[i]);
229 }
230
231 static void _test_tpml_sw(
232 TPMS_PCR_SELECTION s[],
233 size_t count,
234 size_t expected_count,
235 const char *expected_str,
236 size_t expected_weight) {
237
238 TPML_PCR_SELECTION l = {};
239 _tpml_pcr_selection_add_tpms(s, count, &l);
240 assert_se(l.count == expected_count);
241
242 _cleanup_free_ char *tpml_str = tpm2_tpml_pcr_selection_to_string(&l);
243 assert_se(streq(tpml_str, expected_str));
244
245 assert_se(tpm2_tpml_pcr_selection_weight(&l) == expected_weight);
246 assert_se(tpm2_tpml_pcr_selection_is_empty(&l) == (expected_weight == 0));
247 }
248
249 TEST(tpml_pcr_selection_string_and_weight) {
250 size_t size = 0xaa;
251 TPMI_ALG_HASH sha1 = TPM2_ALG_SHA1,
252 sha256 = TPM2_ALG_SHA256,
253 sha384 = TPM2_ALG_SHA384,
254 sha512 = TPM2_ALG_SHA512;
255 TPMS_PCR_SELECTION s[4] = { POISON_TPMS, POISON_TPMS, POISON_TPMS, POISON_TPMS, };
256
257 size = 0;
258 tpm2_tpms_pcr_selection_from_mask(0x000002, sha1 , &s[size++]);
259 tpm2_tpms_pcr_selection_from_mask(0x0080f0, sha384, &s[size++]);
260 tpm2_tpms_pcr_selection_from_mask(0x010100, sha512, &s[size++]);
261 tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256, &s[size++]);
262 _test_tpml_sw(s,
263 size,
264 /* expected_count= */ 4,
265 "[sha1(1),sha384(4+5+6+7+15),sha512(8+16),sha256(16+17+18+19+20+21+22+23)]",
266 /* expected_weight= */ 16);
267
268 size = 0;
269 tpm2_tpms_pcr_selection_from_mask(0x0403aa, sha512, &s[size++]);
270 tpm2_tpms_pcr_selection_from_mask(0x0080f0, sha256, &s[size++]);
271 _test_tpml_sw(s,
272 size,
273 /* expected_count= */ 2,
274 "[sha512(1+3+5+7+8+9+18),sha256(4+5+6+7+15)]",
275 /* expected_weight= */ 12);
276
277 size = 0;
278 /* Empty hashes should be ignored */
279 tpm2_tpms_pcr_selection_from_mask(0x0300ce, sha384, &s[size++]);
280 tpm2_tpms_pcr_selection_from_mask(0xffffff, sha512, &s[size++]);
281 tpm2_tpms_pcr_selection_from_mask(0x000000, sha1 , &s[size++]);
282 tpm2_tpms_pcr_selection_from_mask(0x330010, sha256, &s[size++]);
283 _test_tpml_sw(s,
284 size,
285 /* expected_count= */ 3,
286 "[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)]",
287 /* expected_weight= */ 36);
288
289 size = 0;
290 /* Verify same-hash entries are properly combined. */
291 tpm2_tpms_pcr_selection_from_mask(0x000001, sha1 , &s[size++]);
292 tpm2_tpms_pcr_selection_from_mask(0x000001, sha256, &s[size++]);
293 tpm2_tpms_pcr_selection_from_mask(0x000010, sha1 , &s[size++]);
294 tpm2_tpms_pcr_selection_from_mask(0x000010, sha256, &s[size++]);
295 _test_tpml_sw(s,
296 size,
297 /* expected_count= */ 2,
298 "[sha1(0+4),sha256(0+4)]",
299 /* expected_weight= */ 4);
300 }
301
302 /* Test tpml add/sub by changing the tpms individually */
303 static void _test_tpml_addsub_tpms(
304 TPML_PCR_SELECTION *start,
305 TPMS_PCR_SELECTION add[],
306 size_t add_count,
307 TPMS_PCR_SELECTION expected1[],
308 size_t expected1_count,
309 TPMS_PCR_SELECTION sub[],
310 size_t sub_count,
311 TPMS_PCR_SELECTION expected2[],
312 size_t expected2_count) {
313
314 TPML_PCR_SELECTION l = *start;
315
316 _tpml_pcr_selection_add_tpms(add, add_count, &l);
317 verify_tpml_pcr_selection(&l, expected1, expected1_count);
318
319 _tpml_pcr_selection_sub_tpms(sub, sub_count, &l);
320 verify_tpml_pcr_selection(&l, expected2, expected2_count);
321 }
322
323 /* Test tpml add/sub by creating new tpmls */
324 static void _test_tpml_addsub_tpml(
325 TPML_PCR_SELECTION *start,
326 TPMS_PCR_SELECTION add[],
327 size_t add_count,
328 TPMS_PCR_SELECTION expected1[],
329 size_t expected1_count,
330 TPMS_PCR_SELECTION sub[],
331 size_t sub_count,
332 TPMS_PCR_SELECTION expected2[],
333 size_t expected2_count) {
334
335 TPML_PCR_SELECTION l = {};
336 tpm2_tpml_pcr_selection_add(&l, start);
337 assert_tpml_pcr_selection_eq(&l, start);
338
339 TPML_PCR_SELECTION addl = {};
340 _tpml_pcr_selection_add_tpms(add, add_count, &addl);
341 tpm2_tpml_pcr_selection_add(&l, &addl);
342
343 TPML_PCR_SELECTION e1 = {};
344 _tpml_pcr_selection_add_tpms(expected1, expected1_count, &e1);
345 assert_tpml_pcr_selection_eq(&l, &e1);
346
347 TPML_PCR_SELECTION subl = {};
348 _tpml_pcr_selection_add_tpms(sub, sub_count, &subl);
349 tpm2_tpml_pcr_selection_sub(&l, &subl);
350
351 TPML_PCR_SELECTION e2 = {};
352 _tpml_pcr_selection_add_tpms(expected2, expected2_count, &e2);
353 assert_tpml_pcr_selection_eq(&l, &e2);
354 }
355
356 #define _test_tpml_addsub(...) \
357 ({ \
358 _test_tpml_addsub_tpms(__VA_ARGS__); \
359 _test_tpml_addsub_tpml(__VA_ARGS__); \
360 })
361
362 TEST(tpml_pcr_selection_add_sub) {
363 size_t add_count = 0xaa, expected1_count = 0xaa, sub_count = 0xaa, expected2_count = 0xaa;
364 TPMI_ALG_HASH sha1 = TPM2_ALG_SHA1,
365 sha256 = TPM2_ALG_SHA256,
366 sha384 = TPM2_ALG_SHA384,
367 sha512 = TPM2_ALG_SHA512;
368 TPML_PCR_SELECTION l = POISON_TPML;
369 TPMS_PCR_SELECTION add[4] = { POISON_TPMS, POISON_TPMS, POISON_TPMS, POISON_TPMS, },
370 sub[4] = { POISON_TPMS, POISON_TPMS, POISON_TPMS, POISON_TPMS, },
371 expected1[4] = { POISON_TPMS, POISON_TPMS, POISON_TPMS, POISON_TPMS, },
372 expected2[4] = { POISON_TPMS, POISON_TPMS, POISON_TPMS, POISON_TPMS, };
373
374 l = (TPML_PCR_SELECTION){};
375 add_count = 0;
376 expected1_count = 0;
377 sub_count = 0;
378 expected2_count = 0;
379 tpm2_tpms_pcr_selection_from_mask(0x010101, sha256, &add[add_count++]);
380 tpm2_tpms_pcr_selection_from_mask(0x101010, sha256, &add[add_count++]);
381 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &add[add_count++]);
382 tpm2_tpms_pcr_selection_from_mask(0x111111, sha256, &expected1[expected1_count++]);
383 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &expected1[expected1_count++]);
384 tpm2_tpms_pcr_selection_from_mask(0x000001, sha256, &sub[sub_count++]);
385 tpm2_tpms_pcr_selection_from_mask(0xff0000, sha512, &sub[sub_count++]);
386 tpm2_tpms_pcr_selection_from_mask(0x111110, sha256, &expected2[expected2_count++]);
387 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &expected2[expected2_count++]);
388 _test_tpml_addsub(&l,
389 add, add_count,
390 expected1, expected1_count,
391 sub, sub_count,
392 expected2, expected2_count);
393
394 l = (TPML_PCR_SELECTION){
395 .count = 1,
396 .pcrSelections[0].hash = sha1,
397 .pcrSelections[0].sizeofSelect = 3,
398 .pcrSelections[0].pcrSelect[0] = 0xf0,
399 };
400 add_count = 0;
401 expected1_count = 0;
402 sub_count = 0;
403 expected2_count = 0;
404 tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256, &add[add_count++]);
405 tpm2_tpms_pcr_selection_from_mask(0xffff00, sha384, &add[add_count++]);
406 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &add[add_count++]);
407 tpm2_tpms_pcr_selection_from_mask(0xf00000, sha1 , &add[add_count++]);
408 tpm2_tpms_pcr_selection_from_mask(0xf000f0, sha1 , &expected1[expected1_count++]);
409 tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256, &expected1[expected1_count++]);
410 tpm2_tpms_pcr_selection_from_mask(0xffff00, sha384, &expected1[expected1_count++]);
411 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &expected1[expected1_count++]);
412 tpm2_tpms_pcr_selection_from_mask(0x00ffff, sha256, &sub[sub_count++]);
413 tpm2_tpms_pcr_selection_from_mask(0xf000f0, sha1 , &expected2[expected2_count++]);
414 tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256, &expected2[expected2_count++]);
415 tpm2_tpms_pcr_selection_from_mask(0xffff00, sha384, &expected2[expected2_count++]);
416 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512, &expected2[expected2_count++]);
417 _test_tpml_addsub(&l,
418 add, add_count,
419 expected1, expected1_count,
420 sub, sub_count,
421 expected2, expected2_count);
422 }
423
424 static bool digest_check(const TPM2B_DIGEST *digest, const char *expect) {
425 _cleanup_free_ char *h = NULL;
426
427 assert_se(digest);
428 assert_se(expect);
429
430 h = hexmem(digest->buffer, digest->size);
431 assert_se(h);
432
433 return strcaseeq(expect, h);
434 }
435
436 static void digest_init(TPM2B_DIGEST *digest, const char *hash) {
437 _cleanup_free_ void *h = NULL;
438 size_t s = 0;
439
440 assert_se(strlen(hash) <= sizeof(digest->buffer) * 2);
441
442 assert_se(unhexmem(hash, strlen(hash), &h, &s) == 0);
443
444 /* Make sure the length matches a known hash algorithm */
445 assert_se(IN_SET(s, TPM2_SHA1_DIGEST_SIZE, TPM2_SHA256_DIGEST_SIZE, TPM2_SHA384_DIGEST_SIZE, TPM2_SHA512_DIGEST_SIZE));
446
447 *digest = TPM2B_DIGEST_MAKE(h, s);
448
449 assert_se(digest_check(digest, hash));
450 }
451
452 TEST(digest_many) {
453 TPM2B_DIGEST d, d0, d1, d2, d3, d4;
454
455 digest_init(&d0, "0000000000000000000000000000000000000000000000000000000000000000");
456 digest_init(&d1, "17b7703d9d00776310ba032e88c1a8c2a9c630ebdd799db622f6631530789175");
457 digest_init(&d2, "12998c017066eb0d2a70b94e6ed3192985855ce390f321bbdb832022888bd251");
458 digest_init(&d3, "c3a65887fedd3fb4f5d0047e906dff830bcbd1293160909eb4b05f485e7387ad");
459 digest_init(&d4, "6491fb4bc08fc0b2ef47fc63db57e249917885e69d8c0d99667df83a59107a33");
460
461 /* tpm2_digest_init, tpm2_digest_rehash */
462 d = (TPM2B_DIGEST){ .size = 1, .buffer = { 2, }, };
463 assert_se(tpm2_digest_init(TPM2_ALG_SHA256, &d) == 0);
464 assert_se(digest_check(&d, "0000000000000000000000000000000000000000000000000000000000000000"));
465 assert_se(tpm2_digest_rehash(TPM2_ALG_SHA256, &d) == 0);
466 assert_se(digest_check(&d, "66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925"));
467
468 d = d1;
469 assert_se(tpm2_digest_rehash(TPM2_ALG_SHA256, &d) == 0);
470 assert_se(digest_check(&d, "ab55014b5ace12ba70c3acc887db571585a83539aad3633d252a710f268f405c"));
471 assert_se(tpm2_digest_init(TPM2_ALG_SHA256, &d) == 0);
472 assert_se(digest_check(&d, "0000000000000000000000000000000000000000000000000000000000000000"));
473
474 /* tpm2_digest_many_digests */
475 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, &d2, 1, false) == 0);
476 assert_se(digest_check(&d, "56571a1be3fbeab18d215f549095915a004b5788ca0d535be668559129a76f25"));
477 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, &d2, 1, true) == 0);
478 assert_se(digest_check(&d, "99dedaee8f4d8d10a8be184399fde8740d5e17ff783ee5c288a4486e4ce3a1fe"));
479
480 const TPM2B_DIGEST da1[] = { d2, d3, };
481 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da1, ELEMENTSOF(da1), false) == 0);
482 assert_se(digest_check(&d, "525aa13ef9a61827778ec3acf16fbb23b65ae8770b8fb2684d3a33f9457dd6d8"));
483 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da1, ELEMENTSOF(da1), true) == 0);
484 assert_se(digest_check(&d, "399ca2aa98963d1bd81a2b58a7e5cda24bba1be88fb4da9aa73d97706846566b"));
485
486 const TPM2B_DIGEST da2[] = { d3, d2, d0 };
487 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da2, ELEMENTSOF(da2), false) == 0);
488 assert_se(digest_check(&d, "b26fd22db74d4cd896bff01c61aa498a575e4a553a7fb5a322a5fee36954313e"));
489 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da2, ELEMENTSOF(da2), true) == 0);
490 assert_se(digest_check(&d, "091e79a5b09d4048df49a680f966f3ff67910afe185c3baf9704c9ca45bcf259"));
491
492 const TPM2B_DIGEST da3[] = { d4, d4, d4, d4, d3, d4, d4, d4, d4, };
493 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da3, ELEMENTSOF(da3), false) == 0);
494 assert_se(digest_check(&d, "8eca947641b6002df79dfb571a7f78b7d0a61370a366f722386dfbe444d18830"));
495 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256, &d, da3, ELEMENTSOF(da3), true) == 0);
496 assert_se(digest_check(&d, "f9ba17bc0bbe8794e9bcbf112e4d59a11eb68fffbcd5516a746e4857829dff04"));
497
498 /* tpm2_digest_buffer */
499 const uint8_t b1[] = { 1, 2, 3, 4, };
500 assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256, &d, b1, ELEMENTSOF(b1), false) == 0);
501 assert_se(digest_check(&d, "9f64a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a"));
502 assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256, &d, b1, ELEMENTSOF(b1), true) == 0);
503 assert_se(digest_check(&d, "ff3bd307b287e9b29bb572f6ccfd19deb0106d0c4c3c5cfe8a1d03a396092ed4"));
504
505 const void *b2 = d2.buffer;
506 assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256, &d, b2, d2.size, false) == 0);
507 assert_se(digest_check(&d, "56571a1be3fbeab18d215f549095915a004b5788ca0d535be668559129a76f25"));
508 assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256, &d, b2, d2.size, true) == 0);
509 assert_se(digest_check(&d, "99dedaee8f4d8d10a8be184399fde8740d5e17ff783ee5c288a4486e4ce3a1fe"));
510
511 /* tpm2_digest_many */
512 const struct iovec iov1[] = {
513 IOVEC_MAKE((void*) b1, ELEMENTSOF(b1)),
514 IOVEC_MAKE(d2.buffer, d2.size),
515 IOVEC_MAKE(d3.buffer, d3.size),
516 };
517 assert_se(tpm2_digest_many(TPM2_ALG_SHA256, &d, iov1, ELEMENTSOF(iov1), false) == 0);
518 assert_se(digest_check(&d, "cd7bde4a047af976b6f1b282309976229be59f96a78aa186de32a1aee488ab09"));
519 assert_se(tpm2_digest_many(TPM2_ALG_SHA256, &d, iov1, ELEMENTSOF(iov1), true) == 0);
520 assert_se(digest_check(&d, "02ecb0628264235111e0053e271092981c8b15d59cd46617836bee3149a4ecb0"));
521 }
522
523 static void check_parse_pcr_argument(
524 const char *arg,
525 const Tpm2PCRValue *prev_values,
526 size_t n_prev_values,
527 const Tpm2PCRValue *expected_values,
528 size_t n_expected_values) {
529
530 _cleanup_free_ Tpm2PCRValue *values = NULL;
531 size_t n_values = 0;
532
533 if (n_prev_values > 0) {
534 assert_se(GREEDY_REALLOC_APPEND(values, n_values, prev_values, n_prev_values));
535 assert_se(tpm2_parse_pcr_argument_append(arg, &values, &n_values) == 0);
536 } else
537 assert_se(tpm2_parse_pcr_argument(arg, &values, &n_values) == 0);
538
539 assert_se(n_values == n_expected_values);
540 for (size_t i = 0; i < n_values; i++) {
541 const Tpm2PCRValue *v = &values[i], *e = &expected_values[i];
542 //tpm2_log_debug_pcr_value(e, "Expected value");
543 //tpm2_log_debug_pcr_value(v, "Actual value");
544
545 assert_se(v->index == e->index);
546 assert_se(v->hash == e->hash);
547 assert_se(v->value.size == e->value.size);
548 assert_se(memcmp(v->value.buffer, e->value.buffer, e->value.size) == 0);
549 }
550
551 size_t hash_count;
552 assert_se(tpm2_pcr_values_hash_count(expected_values, n_expected_values, &hash_count) == 0);
553 if (hash_count == 1) {
554 uint32_t mask = UINT32_MAX, expected_mask = 0;
555
556 if (n_prev_values > 0)
557 assert_se(tpm2_pcr_values_to_mask(prev_values, n_prev_values, prev_values[0].hash, &mask) == 0);
558
559 assert_se(tpm2_pcr_values_to_mask(expected_values, n_expected_values, expected_values[0].hash, &expected_mask) == 0);
560
561 assert_se(tpm2_parse_pcr_argument_to_mask(arg, &mask) == 0);
562 assert_se(mask == expected_mask);
563 }
564
565 size_t old_n_values = n_values;
566 assert_se(tpm2_parse_pcr_argument_append("", &values, &n_values) == 0);
567 assert_se(values);
568 assert_se(n_values == old_n_values);
569 }
570
571 static void check_parse_pcr_argument_to_mask(const char *arg, int mask) {
572 uint32_t m = 0;
573 int r = tpm2_parse_pcr_argument_to_mask(arg, &m);
574
575 if (mask < 0)
576 assert_se(mask == r);
577 else
578 assert_se((uint32_t) mask == m);
579 }
580
581 TEST(parse_pcr_argument) {
582 _cleanup_free_ Tpm2PCRValue *t0p = NULL;
583 size_t n_t0p;
584 assert_se(tpm2_parse_pcr_argument("", &t0p, &n_t0p) == 0);
585 assert_se(n_t0p == 0);
586 assert_se(tpm2_parse_pcr_argument_append("", &t0p, &n_t0p) == 0);
587 assert_se(n_t0p == 0);
588 uint32_t m0 = 0xf;
589 assert_se(tpm2_parse_pcr_argument_to_mask("", &m0) == 0);
590 assert_se(m0 == 0);
591 assert_se(tpm2_parse_pcr_argument_to_mask("", &m0) == 0);
592 assert_se(m0 == 0);
593
594 Tpm2PCRValue t1[] = {
595 TPM2_PCR_VALUE_MAKE(0, 0, {}),
596 TPM2_PCR_VALUE_MAKE(4, 0, {}),
597 TPM2_PCR_VALUE_MAKE(7, 0, {}),
598 TPM2_PCR_VALUE_MAKE(11, 0, {}),
599 };
600 check_parse_pcr_argument("0,4,7,11", NULL, 0, t1, ELEMENTSOF(t1));
601 check_parse_pcr_argument("11,4,7,0", NULL, 0, t1, ELEMENTSOF(t1));
602 check_parse_pcr_argument("7,4,0,11", NULL, 0, t1, ELEMENTSOF(t1));
603 check_parse_pcr_argument("11,7,4,0", NULL, 0, t1, ELEMENTSOF(t1));
604 check_parse_pcr_argument("0+4+7+11", NULL, 0, t1, ELEMENTSOF(t1));
605 check_parse_pcr_argument("0,4+7,11", NULL, 0, t1, ELEMENTSOF(t1));
606
607 Tpm2PCRValue t2[] = {
608 TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA1, {}),
609 TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA1, {}),
610 TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA1, {}),
611 TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA1, {}),
612 };
613 check_parse_pcr_argument("0:sha1,4,7,11", NULL, 0, t2, ELEMENTSOF(t2));
614 check_parse_pcr_argument("11,4,7,0:sha1", NULL, 0, t2, ELEMENTSOF(t2));
615 check_parse_pcr_argument("7,4:sha1,0,11", NULL, 0, t2, ELEMENTSOF(t2));
616 check_parse_pcr_argument("0:sha1,4:sha1,7:sha1,11:sha1", NULL, 0, t2, ELEMENTSOF(t2));
617 check_parse_pcr_argument("0:sha1+4:sha1,11:sha1+7:sha1", NULL, 0, t2, ELEMENTSOF(t2));
618
619 Tpm2PCRValue t3[] = {
620 TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA1, {}),
621 TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA1, {}),
622 TPM2_PCR_VALUE_MAKE(2, TPM2_ALG_SHA1, {}),
623 TPM2_PCR_VALUE_MAKE(3, TPM2_ALG_SHA1, {}),
624 TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA1, {}),
625 TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA1, {}),
626 TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA1, {}),
627 TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA1, {}),
628 };
629 check_parse_pcr_argument("1,2,3,12", t2, ELEMENTSOF(t2), t3, ELEMENTSOF(t3));
630 check_parse_pcr_argument("12,2,3,1", t2, ELEMENTSOF(t2), t3, ELEMENTSOF(t3));
631 check_parse_pcr_argument("1,2,3,12:sha1", t1, ELEMENTSOF(t1), t3, ELEMENTSOF(t3));
632 check_parse_pcr_argument("1,2,3,12:sha1", t2, ELEMENTSOF(t2), t3, ELEMENTSOF(t3));
633 check_parse_pcr_argument("1:sha1,2,3,12", t1, ELEMENTSOF(t1), t3, ELEMENTSOF(t3));
634 check_parse_pcr_argument("1:sha1,2,3,12", t2, ELEMENTSOF(t2), t3, ELEMENTSOF(t3));
635 check_parse_pcr_argument("1:sha1,2:sha1,3:sha1,12:sha1", t1, ELEMENTSOF(t1), t3, ELEMENTSOF(t3));
636 check_parse_pcr_argument("1:sha1,2:sha1,3:sha1,12:sha1", t2, ELEMENTSOF(t2), t3, ELEMENTSOF(t3));
637
638 TPM2B_DIGEST d4;
639 digest_init(&d4, "FCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2");
640 Tpm2PCRValue t4[] = {
641 TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA256, {}),
642 TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA256, d4),
643 TPM2_PCR_VALUE_MAKE(2, TPM2_ALG_SHA256, {}),
644 TPM2_PCR_VALUE_MAKE(3, TPM2_ALG_SHA256, {}),
645 TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA256, {}),
646 TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA256, {}),
647 TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA256, {}),
648 TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA256, {}),
649 };
650 check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2,3,12", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4));
651 check_parse_pcr_argument("12,2,3,1:sha256=FCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4));
652 check_parse_pcr_argument("12,2,3,1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4));
653 check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2,3,12:SHA256", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4));
654 check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2,3,12", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4));
655 check_parse_pcr_argument("1:sha256=FCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2:sha256,3:sha256,12:sha256", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4));
656 check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2:sha256,3:sha256,12:sha256", t1, ELEMENTSOF(t1), t4, ELEMENTSOF(t4));
657
658 TPM2B_DIGEST d5;
659 digest_init(&d5, "0F21EADB7F27377668E3C8069BE88D116491FBEE");
660 Tpm2PCRValue t5[] = {
661 TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA1, d5),
662 TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA256, {}),
663 TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA256, d4),
664 TPM2_PCR_VALUE_MAKE(2, TPM2_ALG_SHA256, {}),
665 TPM2_PCR_VALUE_MAKE(3, TPM2_ALG_SHA256, {}),
666 TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA256, {}),
667 TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA256, {}),
668 TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA256, {}),
669 TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA256, {}),
670 TPM2_PCR_VALUE_MAKE(5, TPM2_ALG_SHA384, {}),
671 TPM2_PCR_VALUE_MAKE(6, TPM2_ALG_SHA512, {}),
672 };
673 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));
674 check_parse_pcr_argument("1:sha1=0F21EADB7F27377668E3C8069BE88D116491FBEE,6:sha512,5:sha384", t4, ELEMENTSOF(t4), t5, ELEMENTSOF(t5));
675
676 Tpm2PCRValue *v = NULL;
677 size_t n_v = 0;
678 assert_se(tpm2_parse_pcr_argument("1,100", &v, &n_v) < 0);
679 assert_se(tpm2_parse_pcr_argument("1,2=123456abc", &v, &n_v) < 0);
680 assert_se(tpm2_parse_pcr_argument("1,2:invalid", &v, &n_v) < 0);
681 assert_se(tpm2_parse_pcr_argument("1:sha1=invalid", &v, &n_v) < 0);
682 assert_se(v == NULL);
683 assert_se(n_v == 0);
684
685 check_parse_pcr_argument_to_mask("", 0x0);
686 check_parse_pcr_argument_to_mask("0", 0x1);
687 check_parse_pcr_argument_to_mask("1", 0x2);
688 check_parse_pcr_argument_to_mask("0,1", 0x3);
689 check_parse_pcr_argument_to_mask("0+1", 0x3);
690 check_parse_pcr_argument_to_mask("0-1", -EINVAL);
691 check_parse_pcr_argument_to_mask("foo", -EINVAL);
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,1+2", 0x7);
696 check_parse_pcr_argument_to_mask("0,2", 0x5);
697 check_parse_pcr_argument_to_mask("0+2", 0x5);
698 check_parse_pcr_argument_to_mask("7+application-support", 0x800080);
699 check_parse_pcr_argument_to_mask("8+boot-loader-code", 0x110);
700 check_parse_pcr_argument_to_mask("7,shim-policy,4", 0x4090);
701 check_parse_pcr_argument_to_mask("sysexts,shim-policy+kernel-boot", 0x6800);
702 check_parse_pcr_argument_to_mask("sysexts,shim+kernel-boot", -EINVAL);
703 check_parse_pcr_argument_to_mask("sysexts+17+23", 0x822000);
704 check_parse_pcr_argument_to_mask("6+boot-loader-code,44", -EINVAL);
705 check_parse_pcr_argument_to_mask("debug+24", -EINVAL);
706 }
707
708 static void tpm2b_public_init(TPM2B_PUBLIC *public) {
709 TPMT_PUBLIC tpmt = {
710 .type = TPM2_ALG_RSA,
711 .nameAlg = TPM2_ALG_SHA256,
712 .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH,
713 .parameters.rsaDetail = {
714 .symmetric = {
715 .algorithm = TPM2_ALG_AES,
716 .keyBits.aes = 128,
717 .mode.aes = TPM2_ALG_CFB,
718 },
719 .scheme.scheme = TPM2_ALG_NULL,
720 .keyBits = 2048,
721 },
722 };
723
724 const char *key = "9ec7341c52093ac40a1965a5df10432513c539adcf905e30577ab6ebc88ffe53cd08cef12ed9bec6125432f4fada3629b8b96d31b8f507aa35029188fe396da823fcb236027f7fbb01b0da3d87be7f999390449ced604bdf7e26c48657cc0671000f1147da195c3861c96642e54427cb7a11572e07567ec3fd6316978abc4bd92b27bb0a0e4958e599804eeb41d682b3b7fc1f960209f80a4fb8a1b64abfd96bf5d554e73cdd6ad1c8becb4fcf5e8f0c3e621d210e5e2f308f6520ad9a966779231b99f06c5989e5a23a9415c8808ab89ce81117632e2f8461cd4428bded40979236aeadafe8de3f51660a45e1dbc87694e6a36360201cca3ff9e7263e712727";
725 _cleanup_free_ void *mem = NULL;
726 size_t len = 0;
727 assert_se(unhexmem(key, strlen(key), &mem, &len) == 0);
728 tpmt.unique.rsa = TPM2B_PUBLIC_KEY_RSA_MAKE(mem, len);
729
730 public->publicArea = tpmt;
731 }
732
733 TEST(calculate_name) {
734 TPM2B_PUBLIC public;
735 TPM2B_NAME name;
736
737 tpm2b_public_init(&public);
738 assert_se(tpm2_calculate_name(&public.publicArea, &name) == 0);
739 assert_se(name.size == SHA256_DIGEST_SIZE + 2);
740
741 const char *expect = "000be78f74a470dd92e979ca067cdb2293a35f075e8560b436bd2ccea5da21486a07";
742 _cleanup_free_ char *h = hexmem(name.name, name.size);
743 assert_se(h);
744
745 assert_se(strlen(expect) == strlen(h));
746 assert_se(streq(expect, h));
747 }
748
749 TEST(calculate_policy_auth_value) {
750 TPM2B_DIGEST d;
751
752 digest_init(&d, "0000000000000000000000000000000000000000000000000000000000000000");
753 assert_se(tpm2_calculate_policy_auth_value(&d) == 0);
754 assert_se(digest_check(&d, "8fcd2169ab92694e0c633f1ab772842b8241bbc20288981fc7ac1eddc1fddb0e"));
755 assert_se(tpm2_calculate_policy_auth_value(&d) == 0);
756 assert_se(digest_check(&d, "759ebd5ed65100e0b4aa2d04b4b789c2672d92ecc9cdda4b5fa16a303132e008"));
757 }
758
759 TEST(calculate_policy_authorize) {
760 TPM2B_PUBLIC public;
761 TPM2B_DIGEST d;
762
763 tpm2b_public_init(&public);
764 digest_init(&d, "0000000000000000000000000000000000000000000000000000000000000000");
765 assert_se(tpm2_calculate_policy_authorize(&public, NULL, &d) == 0);
766 assert_se(digest_check(&d, "95213a3784eaab04f427bc7e8851c2f1df0903be8e42428ec25dcefd907baff1"));
767 assert_se(tpm2_calculate_policy_authorize(&public, NULL, &d) == 0);
768 assert_se(digest_check(&d, "95213a3784eaab04f427bc7e8851c2f1df0903be8e42428ec25dcefd907baff1"));
769 }
770
771 TEST(calculate_policy_pcr) {
772 TPM2B_DIGEST d, dN[16];
773
774 digest_init(&dN[ 0], "2124793cbbe60c3a8637d3b84a5d054e87c351e1469a285acc04755e8b204dec");
775 digest_init(&dN[ 1], "bf7592f18adcfdc549fc0b94939f5069a24697f9cff4a0dca29014767b97559d");
776 digest_init(&dN[ 2], "4b00cff9dee3a364979b2dc241b34568a8ad49fcf2713df259e47dff8875feed");
777 digest_init(&dN[ 3], "3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969");
778 digest_init(&dN[ 4], "368f85b3013041dfe203faaa364f00b07c5da7b1e5f1dbf2efb06fa6b9bd92de");
779 digest_init(&dN[ 5], "c97c40369691c8e4aa78fb3a52655cd193b780a838b8e23f5f476576919db5e5");
780 digest_init(&dN[ 6], "3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969");
781 digest_init(&dN[ 7], "aa1154c9e0a774854ccbed4c8ce7e9b906b3d700a1a8db1772d0341a62dbe51b");
782 digest_init(&dN[ 8], "cfde439a2c06af3479ca6bdc60429b90553d65300c5cfcc40004a08c6b5ad81a");
783 digest_init(&dN[ 9], "9c2bac22ef5ec84fcdb71c3ebf776cba1247e5da980e5ee08e45666a2edf0b8b");
784 digest_init(&dN[10], "9885873f4d7348199ad286f8f2476d4f866940950f6f9fb9f945ed352dbdcbd2");
785 digest_init(&dN[11], "42400ab950d21aa79d12cc4fdef67d1087a39ad64900619831c0974dbae54e44");
786 digest_init(&dN[12], "767d064382e56ca1ad3bdcc6bc596112e6c2008b593d3570d24c2bfa64c4628c");
787 digest_init(&dN[13], "30c16133175959408c9745d8dafadef5daf4b39cb2be04df0d60089bd46d3cc4");
788 digest_init(&dN[14], "e3991b7ddd47be7e92726a832d6874c5349b52b789fa0db8b558c69fea29574e");
789 digest_init(&dN[15], "852dae3ecb992bdeb13d6002fefeeffdd90feca8b378d56681ef2c885d0e5137");
790
791 digest_init(&d, "0000000000000000000000000000000000000000000000000000000000000000");
792 Tpm2PCRValue v1[] = {
793 TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA256, dN[4]),
794 TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA256, dN[7]),
795 TPM2_PCR_VALUE_MAKE(8, TPM2_ALG_SHA256, dN[8]),
796 };
797 assert_se(tpm2_calculate_policy_pcr(v1, ELEMENTSOF(v1), &d) == 0);
798 assert_se(digest_check(&d, "76532a0e16f7e6bf6b02918c11f75d99d729fab0cc81d0df2c4284a2c4fe6e05"));
799 assert_se(tpm2_calculate_policy_pcr(v1, ELEMENTSOF(v1), &d) == 0);
800 assert_se(digest_check(&d, "97e64bcabb64c1fa4b726528644926c8029f5b4458b0575c98c04fe225629a0b"));
801
802 digest_init(&d, "0000000000000000000000000000000000000000000000000000000000000000");
803 Tpm2PCRValue v2[] = {
804 TPM2_PCR_VALUE_MAKE( 0, TPM2_ALG_SHA256, dN[ 0]),
805 TPM2_PCR_VALUE_MAKE( 1, TPM2_ALG_SHA256, dN[ 1]),
806 TPM2_PCR_VALUE_MAKE( 2, TPM2_ALG_SHA256, dN[ 2]),
807 TPM2_PCR_VALUE_MAKE( 3, TPM2_ALG_SHA256, dN[ 3]),
808 TPM2_PCR_VALUE_MAKE( 4, TPM2_ALG_SHA256, dN[ 4]),
809 TPM2_PCR_VALUE_MAKE( 5, TPM2_ALG_SHA256, dN[ 5]),
810 TPM2_PCR_VALUE_MAKE( 6, TPM2_ALG_SHA256, dN[ 6]),
811 TPM2_PCR_VALUE_MAKE( 7, TPM2_ALG_SHA256, dN[ 7]),
812 TPM2_PCR_VALUE_MAKE( 8, TPM2_ALG_SHA256, dN[ 8]),
813 TPM2_PCR_VALUE_MAKE( 9, TPM2_ALG_SHA256, dN[ 9]),
814 TPM2_PCR_VALUE_MAKE(10, TPM2_ALG_SHA256, dN[10]),
815 TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA256, dN[11]),
816 TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA256, dN[12]),
817 TPM2_PCR_VALUE_MAKE(13, TPM2_ALG_SHA256, dN[13]),
818 TPM2_PCR_VALUE_MAKE(14, TPM2_ALG_SHA256, dN[14]),
819 TPM2_PCR_VALUE_MAKE(15, TPM2_ALG_SHA256, dN[15]),
820 };
821 assert_se(tpm2_calculate_policy_pcr(v2, ELEMENTSOF(v2), &d) == 0);
822 assert_se(digest_check(&d, "22be4f1674f792d6345cea9427701068f0e8d9f42755dcc0e927e545a68f9c13"));
823 assert_se(tpm2_calculate_policy_pcr(v2, ELEMENTSOF(v2), &d) == 0);
824 assert_se(digest_check(&d, "7481fd1b116078eb3ac2456e4ad542c9b46b9b8eb891335771ca8e7c8f8e4415"));
825 }
826
827 TEST(tpm_required_tests) {
828 int r;
829
830 _cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL;
831 r = tpm2_context_new(NULL, &c);
832 if (r < 0) {
833 log_tests_skipped("Could not find TPM");
834 return;
835 }
836
837 TPMU_PUBLIC_PARMS parms = {
838 .symDetail.sym = {
839 .algorithm = TPM2_ALG_AES,
840 .keyBits.aes = 128,
841 .mode.aes = TPM2_ALG_CFB,
842 },
843 };
844
845 /* Test with invalid parms */
846 assert_se(!tpm2_test_parms(c, TPM2_ALG_CFB, &parms));
847
848 TPMU_PUBLIC_PARMS invalid_parms = parms;
849 invalid_parms.symDetail.sym.keyBits.aes = 1;
850 assert_se(!tpm2_test_parms(c, TPM2_ALG_SYMCIPHER, &invalid_parms));
851
852 /* Test with valid parms */
853 assert_se(tpm2_test_parms(c, TPM2_ALG_SYMCIPHER, &parms));
854
855 /* Test invalid algs */
856 assert_se(!tpm2_supports_alg(c, TPM2_ALG_ERROR));
857 assert_se(!tpm2_supports_alg(c, TPM2_ALG_LAST + 1));
858
859 /* Test valid algs */
860 assert_se(tpm2_supports_alg(c, TPM2_ALG_RSA));
861 assert_se(tpm2_supports_alg(c, TPM2_ALG_AES));
862 assert_se(tpm2_supports_alg(c, TPM2_ALG_CFB));
863
864 /* Test invalid commands */
865 assert_se(!tpm2_supports_command(c, TPM2_CC_FIRST - 1));
866 assert_se(!tpm2_supports_command(c, TPM2_CC_LAST + 1));
867
868 /* Test valid commands */
869 assert_se(tpm2_supports_command(c, TPM2_CC_Create));
870 assert_se(tpm2_supports_command(c, TPM2_CC_CreatePrimary));
871 assert_se(tpm2_supports_command(c, TPM2_CC_Unseal));
872 }
873
874 #endif /* HAVE_TPM2 */
875
876 DEFINE_TEST_MAIN(LOG_DEBUG);