1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
8 TEST(tpm2_pcr_index_from_string
) {
9 assert_se(tpm2_pcr_index_from_string("platform-code") == 0);
10 assert_se(tpm2_pcr_index_from_string("0") == 0);
11 assert_se(tpm2_pcr_index_from_string("platform-config") == 1);
12 assert_se(tpm2_pcr_index_from_string("1") == 1);
13 assert_se(tpm2_pcr_index_from_string("external-code") == 2);
14 assert_se(tpm2_pcr_index_from_string("2") == 2);
15 assert_se(tpm2_pcr_index_from_string("external-config") == 3);
16 assert_se(tpm2_pcr_index_from_string("3") == 3);
17 assert_se(tpm2_pcr_index_from_string("boot-loader-code") == 4);
18 assert_se(tpm2_pcr_index_from_string("4") == 4);
19 assert_se(tpm2_pcr_index_from_string("boot-loader-config") == 5);
20 assert_se(tpm2_pcr_index_from_string("5") == 5);
21 assert_se(tpm2_pcr_index_from_string("secure-boot-policy") == 7);
22 assert_se(tpm2_pcr_index_from_string("7") == 7);
23 assert_se(tpm2_pcr_index_from_string("kernel-initrd") == 9);
24 assert_se(tpm2_pcr_index_from_string("9") == 9);
25 assert_se(tpm2_pcr_index_from_string("ima") == 10);
26 assert_se(tpm2_pcr_index_from_string("10") == 10);
27 assert_se(tpm2_pcr_index_from_string("kernel-boot") == 11);
28 assert_se(tpm2_pcr_index_from_string("11") == 11);
29 assert_se(tpm2_pcr_index_from_string("kernel-config") == 12);
30 assert_se(tpm2_pcr_index_from_string("12") == 12);
31 assert_se(tpm2_pcr_index_from_string("sysexts") == 13);
32 assert_se(tpm2_pcr_index_from_string("13") == 13);
33 assert_se(tpm2_pcr_index_from_string("shim-policy") == 14);
34 assert_se(tpm2_pcr_index_from_string("14") == 14);
35 assert_se(tpm2_pcr_index_from_string("system-identity") == 15);
36 assert_se(tpm2_pcr_index_from_string("15") == 15);
37 assert_se(tpm2_pcr_index_from_string("debug") == 16);
38 assert_se(tpm2_pcr_index_from_string("16") == 16);
39 assert_se(tpm2_pcr_index_from_string("application-support") == 23);
40 assert_se(tpm2_pcr_index_from_string("23") == 23);
41 assert_se(tpm2_pcr_index_from_string("hello") == -EINVAL
);
42 assert_se(tpm2_pcr_index_from_string("8") == 8);
43 assert_se(tpm2_pcr_index_from_string("44") == -EINVAL
);
44 assert_se(tpm2_pcr_index_from_string("-5") == -EINVAL
);
45 assert_se(tpm2_pcr_index_from_string("24") == -EINVAL
);
48 TEST(tpm2_util_pbkdf2_hmac_sha256
) {
51 * The test vectors from RFC 6070 [1] are for dkLen of 20 as it's SHA1
52 * other RFCs I bumped into had various differing dkLen and iter counts,
53 * so this was generated using Python's hmacmodule.
55 * 1. https://www.rfc-editor.org/rfc/rfc6070.html#page-2
58 const uint8_t pass
[256];
60 const uint8_t salt
[256];
62 uint8_t expected
[SHA256_DIGEST_SIZE
];
64 { .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} },
65 { .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} },
66 { .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} },
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
={'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} },
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
={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} },
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
={'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} },
70 { .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} },
71 { .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} },
72 { .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} },
75 uint8_t res
[SHA256_DIGEST_SIZE
];
76 for(size_t i
= 0; i
< sizeof(test_vectors
)/sizeof(test_vectors
[0]); i
++) {
78 int rc
= tpm2_util_pbkdf2_hmac_sha256(
80 test_vectors
[i
].passlen
,
82 test_vectors
[i
].saltlen
,
85 assert_se(memcmp(test_vectors
[i
].expected
, res
, SHA256_DIGEST_SIZE
) == 0);
91 #define POISON(type) \
94 memset(&_p, 0xaa, sizeof(_p)); \
97 #define POISON_TPML POISON(TPML_PCR_SELECTION)
98 #define POISON_TPMS POISON(TPMS_PCR_SELECTION)
99 #define POISON_U32 POISON(uint32_t)
101 static void assert_tpms_pcr_selection_eq(TPMS_PCR_SELECTION
*a
, TPMS_PCR_SELECTION
*b
) {
105 assert_se(a
->hash
== b
->hash
);
106 assert_se(a
->sizeofSelect
== b
->sizeofSelect
);
108 for (size_t i
= 0; i
< a
->sizeofSelect
; i
++)
109 assert_se(a
->pcrSelect
[i
] == b
->pcrSelect
[i
]);
112 static void assert_tpml_pcr_selection_eq(TPML_PCR_SELECTION
*a
, TPML_PCR_SELECTION
*b
) {
116 assert_se(a
->count
== b
->count
);
117 for (size_t i
= 0; i
< a
->count
; i
++)
118 assert_tpms_pcr_selection_eq(&a
->pcrSelections
[i
], &b
->pcrSelections
[i
]);
121 static void verify_tpms_pcr_selection(TPMS_PCR_SELECTION
*s
, uint32_t mask
, TPMI_ALG_HASH hash
) {
122 assert_se(s
->hash
== hash
);
123 assert_se(s
->sizeofSelect
== 3);
124 assert_se(s
->pcrSelect
[0] == (mask
& 0xff));
125 assert_se(s
->pcrSelect
[1] == ((mask
>> 8) & 0xff));
126 assert_se(s
->pcrSelect
[2] == ((mask
>> 16) & 0xff));
127 assert_se(s
->pcrSelect
[3] == 0);
129 assert_se(tpm2_tpms_pcr_selection_to_mask(s
) == mask
);
132 static void verify_tpml_pcr_selection(TPML_PCR_SELECTION
*l
, TPMS_PCR_SELECTION s
[], size_t count
) {
133 assert_se(l
->count
== count
);
134 for (size_t i
= 0; i
< count
; i
++) {
135 assert_tpms_pcr_selection_eq(&s
[i
], &l
->pcrSelections
[i
]);
137 TPMI_ALG_HASH hash
= l
->pcrSelections
[i
].hash
;
138 verify_tpms_pcr_selection(&l
->pcrSelections
[i
], tpm2_tpml_pcr_selection_to_mask(l
, hash
), hash
);
142 static void _test_pcr_selection_mask_hash(uint32_t mask
, TPMI_ALG_HASH hash
) {
143 TPMS_PCR_SELECTION s
= POISON_TPMS
;
144 tpm2_tpms_pcr_selection_from_mask(mask
, hash
, &s
);
145 verify_tpms_pcr_selection(&s
, mask
, hash
);
147 TPML_PCR_SELECTION l
= POISON_TPML
;
148 tpm2_tpml_pcr_selection_from_mask(mask
, hash
, &l
);
149 verify_tpml_pcr_selection(&l
, &s
, 1);
150 verify_tpms_pcr_selection(&l
.pcrSelections
[0], mask
, hash
);
152 uint32_t test_masks
[] = {
153 0x0, 0x1, 0x100, 0x10000, 0xf0f0f0, 0xaaaaaa, 0xffffff,
155 for (unsigned i
= 0; i
< ELEMENTSOF(test_masks
); i
++) {
156 uint32_t test_mask
= test_masks
[i
];
158 TPMS_PCR_SELECTION a
= POISON_TPMS
, b
= POISON_TPMS
, test_s
= POISON_TPMS
;
159 tpm2_tpms_pcr_selection_from_mask(test_mask
, hash
, &test_s
);
163 tpm2_tpms_pcr_selection_add(&a
, &b
);
164 verify_tpms_pcr_selection(&a
, UPDATE_FLAG(mask
, test_mask
, true), hash
);
165 verify_tpms_pcr_selection(&b
, test_mask
, hash
);
169 tpm2_tpms_pcr_selection_sub(&a
, &b
);
170 verify_tpms_pcr_selection(&a
, UPDATE_FLAG(mask
, test_mask
, false), hash
);
171 verify_tpms_pcr_selection(&b
, test_mask
, hash
);
175 tpm2_tpms_pcr_selection_move(&a
, &b
);
176 verify_tpms_pcr_selection(&a
, UPDATE_FLAG(mask
, test_mask
, true), hash
);
177 verify_tpms_pcr_selection(&b
, 0, hash
);
181 TEST(tpms_pcr_selection_mask_and_hash
) {
182 TPMI_ALG_HASH HASH_ALGS
[] = { TPM2_ALG_SHA1
, TPM2_ALG_SHA256
, };
184 for (unsigned i
= 0; i
< ELEMENTSOF(HASH_ALGS
); i
++)
185 for (uint32_t m2
= 0; m2
<= 0xffffff; m2
+= 0x50000)
186 for (uint32_t m1
= 0; m1
<= 0xffff; m1
+= 0x500)
187 for (uint32_t m0
= 0; m0
<= 0xff; m0
+= 0x5)
188 _test_pcr_selection_mask_hash(m0
| m1
| m2
, HASH_ALGS
[i
]);
191 static void _test_tpms_sw(
194 const char *expected_str
,
195 size_t expected_weight
) {
197 TPMS_PCR_SELECTION s
= POISON_TPMS
;
198 tpm2_tpms_pcr_selection_from_mask(mask
, hash
, &s
);
200 _cleanup_free_
char *tpms_str
= tpm2_tpms_pcr_selection_to_string(&s
);
201 assert_se(streq(tpms_str
, expected_str
));
203 assert_se(tpm2_tpms_pcr_selection_weight(&s
) == expected_weight
);
204 assert_se(tpm2_tpms_pcr_selection_is_empty(&s
) == (expected_weight
== 0));
207 TEST(tpms_pcr_selection_string_and_weight
) {
208 TPMI_ALG_HASH sha1
= TPM2_ALG_SHA1
, sha256
= TPM2_ALG_SHA256
;
210 _test_tpms_sw(sha1
, 0, "sha1()", 0);
211 _test_tpms_sw(sha1
, 1, "sha1(0)", 1);
212 _test_tpms_sw(sha1
, 0xf, "sha1(0+1+2+3)", 4);
213 _test_tpms_sw(sha1
, 0x00ff00, "sha1(8+9+10+11+12+13+14+15)", 8);
214 _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);
215 _test_tpms_sw(sha256
, 0, "sha256()", 0);
216 _test_tpms_sw(sha256
, 1, "sha256(0)", 1);
217 _test_tpms_sw(sha256
, 7, "sha256(0+1+2)", 3);
218 _test_tpms_sw(sha256
, 0xf00000, "sha256(20+21+22+23)", 4);
219 _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);
222 static void _tpml_pcr_selection_add_tpms(TPMS_PCR_SELECTION s
[], size_t count
, TPML_PCR_SELECTION
*ret
) {
223 for (size_t i
= 0; i
< count
; i
++)
224 tpm2_tpml_pcr_selection_add_tpms_pcr_selection(ret
, &s
[i
]);
227 static void _tpml_pcr_selection_sub_tpms(TPMS_PCR_SELECTION s
[], size_t count
, TPML_PCR_SELECTION
*ret
) {
228 for (size_t i
= 0; i
< count
; i
++)
229 tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(ret
, &s
[i
]);
232 static void _test_tpml_sw(
233 TPMS_PCR_SELECTION s
[],
235 size_t expected_count
,
236 const char *expected_str
,
237 size_t expected_weight
) {
239 TPML_PCR_SELECTION l
= {};
240 _tpml_pcr_selection_add_tpms(s
, count
, &l
);
241 assert_se(l
.count
== expected_count
);
243 _cleanup_free_
char *tpml_str
= tpm2_tpml_pcr_selection_to_string(&l
);
244 assert_se(streq(tpml_str
, expected_str
));
246 assert_se(tpm2_tpml_pcr_selection_weight(&l
) == expected_weight
);
247 assert_se(tpm2_tpml_pcr_selection_is_empty(&l
) == (expected_weight
== 0));
250 TEST(tpml_pcr_selection_string_and_weight
) {
252 TPMI_ALG_HASH sha1
= TPM2_ALG_SHA1
,
253 sha256
= TPM2_ALG_SHA256
,
254 sha384
= TPM2_ALG_SHA384
,
255 sha512
= TPM2_ALG_SHA512
;
256 TPMS_PCR_SELECTION s
[4] = { POISON_TPMS
, POISON_TPMS
, POISON_TPMS
, POISON_TPMS
, };
259 tpm2_tpms_pcr_selection_from_mask(0x000002, sha1
, &s
[size
++]);
260 tpm2_tpms_pcr_selection_from_mask(0x0080f0, sha384
, &s
[size
++]);
261 tpm2_tpms_pcr_selection_from_mask(0x010100, sha512
, &s
[size
++]);
262 tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256
, &s
[size
++]);
265 /* expected_count= */ 4,
266 "[sha1(1),sha384(4+5+6+7+15),sha512(8+16),sha256(16+17+18+19+20+21+22+23)]",
267 /* expected_weight= */ 16);
270 tpm2_tpms_pcr_selection_from_mask(0x0403aa, sha512
, &s
[size
++]);
271 tpm2_tpms_pcr_selection_from_mask(0x0080f0, sha256
, &s
[size
++]);
274 /* expected_count= */ 2,
275 "[sha512(1+3+5+7+8+9+18),sha256(4+5+6+7+15)]",
276 /* expected_weight= */ 12);
279 /* Empty hashes should be ignored */
280 tpm2_tpms_pcr_selection_from_mask(0x0300ce, sha384
, &s
[size
++]);
281 tpm2_tpms_pcr_selection_from_mask(0xffffff, sha512
, &s
[size
++]);
282 tpm2_tpms_pcr_selection_from_mask(0x000000, sha1
, &s
[size
++]);
283 tpm2_tpms_pcr_selection_from_mask(0x330010, sha256
, &s
[size
++]);
286 /* expected_count= */ 3,
287 "[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)]",
288 /* expected_weight= */ 36);
291 /* Verify same-hash entries are properly combined. */
292 tpm2_tpms_pcr_selection_from_mask(0x000001, sha1
, &s
[size
++]);
293 tpm2_tpms_pcr_selection_from_mask(0x000001, sha256
, &s
[size
++]);
294 tpm2_tpms_pcr_selection_from_mask(0x000010, sha1
, &s
[size
++]);
295 tpm2_tpms_pcr_selection_from_mask(0x000010, sha256
, &s
[size
++]);
298 /* expected_count= */ 2,
299 "[sha1(0+4),sha256(0+4)]",
300 /* expected_weight= */ 4);
303 /* Test tpml add/sub by changing the tpms individually */
304 static void _test_tpml_addsub_tpms(
305 TPML_PCR_SELECTION
*start
,
306 TPMS_PCR_SELECTION add
[],
308 TPMS_PCR_SELECTION expected1
[],
309 size_t expected1_count
,
310 TPMS_PCR_SELECTION sub
[],
312 TPMS_PCR_SELECTION expected2
[],
313 size_t expected2_count
) {
315 TPML_PCR_SELECTION l
= *start
;
317 _tpml_pcr_selection_add_tpms(add
, add_count
, &l
);
318 verify_tpml_pcr_selection(&l
, expected1
, expected1_count
);
320 _tpml_pcr_selection_sub_tpms(sub
, sub_count
, &l
);
321 verify_tpml_pcr_selection(&l
, expected2
, expected2_count
);
324 /* Test tpml add/sub by creating new tpmls */
325 static void _test_tpml_addsub_tpml(
326 TPML_PCR_SELECTION
*start
,
327 TPMS_PCR_SELECTION add
[],
329 TPMS_PCR_SELECTION expected1
[],
330 size_t expected1_count
,
331 TPMS_PCR_SELECTION sub
[],
333 TPMS_PCR_SELECTION expected2
[],
334 size_t expected2_count
) {
336 TPML_PCR_SELECTION l
= {};
337 tpm2_tpml_pcr_selection_add(&l
, start
);
338 assert_tpml_pcr_selection_eq(&l
, start
);
340 TPML_PCR_SELECTION addl
= {};
341 _tpml_pcr_selection_add_tpms(add
, add_count
, &addl
);
342 tpm2_tpml_pcr_selection_add(&l
, &addl
);
344 TPML_PCR_SELECTION e1
= {};
345 _tpml_pcr_selection_add_tpms(expected1
, expected1_count
, &e1
);
346 assert_tpml_pcr_selection_eq(&l
, &e1
);
348 TPML_PCR_SELECTION subl
= {};
349 _tpml_pcr_selection_add_tpms(sub
, sub_count
, &subl
);
350 tpm2_tpml_pcr_selection_sub(&l
, &subl
);
352 TPML_PCR_SELECTION e2
= {};
353 _tpml_pcr_selection_add_tpms(expected2
, expected2_count
, &e2
);
354 assert_tpml_pcr_selection_eq(&l
, &e2
);
357 #define _test_tpml_addsub(...) \
359 _test_tpml_addsub_tpms(__VA_ARGS__); \
360 _test_tpml_addsub_tpml(__VA_ARGS__); \
363 TEST(tpml_pcr_selection_add_sub
) {
364 size_t add_count
= 0xaa, expected1_count
= 0xaa, sub_count
= 0xaa, expected2_count
= 0xaa;
365 TPMI_ALG_HASH sha1
= TPM2_ALG_SHA1
,
366 sha256
= TPM2_ALG_SHA256
,
367 sha384
= TPM2_ALG_SHA384
,
368 sha512
= TPM2_ALG_SHA512
;
369 TPML_PCR_SELECTION l
= POISON_TPML
;
370 TPMS_PCR_SELECTION add
[4] = { POISON_TPMS
, POISON_TPMS
, POISON_TPMS
, POISON_TPMS
, },
371 sub
[4] = { POISON_TPMS
, POISON_TPMS
, POISON_TPMS
, POISON_TPMS
, },
372 expected1
[4] = { POISON_TPMS
, POISON_TPMS
, POISON_TPMS
, POISON_TPMS
, },
373 expected2
[4] = { POISON_TPMS
, POISON_TPMS
, POISON_TPMS
, POISON_TPMS
, };
375 l
= (TPML_PCR_SELECTION
){};
380 tpm2_tpms_pcr_selection_from_mask(0x010101, sha256
, &add
[add_count
++]);
381 tpm2_tpms_pcr_selection_from_mask(0x101010, sha256
, &add
[add_count
++]);
382 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512
, &add
[add_count
++]);
383 tpm2_tpms_pcr_selection_from_mask(0x111111, sha256
, &expected1
[expected1_count
++]);
384 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512
, &expected1
[expected1_count
++]);
385 tpm2_tpms_pcr_selection_from_mask(0x000001, sha256
, &sub
[sub_count
++]);
386 tpm2_tpms_pcr_selection_from_mask(0xff0000, sha512
, &sub
[sub_count
++]);
387 tpm2_tpms_pcr_selection_from_mask(0x111110, sha256
, &expected2
[expected2_count
++]);
388 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512
, &expected2
[expected2_count
++]);
389 _test_tpml_addsub(&l
,
391 expected1
, expected1_count
,
393 expected2
, expected2_count
);
395 l
= (TPML_PCR_SELECTION
){
397 .pcrSelections
[0].hash
= sha1
,
398 .pcrSelections
[0].sizeofSelect
= 3,
399 .pcrSelections
[0].pcrSelect
[0] = 0xf0,
405 tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256
, &add
[add_count
++]);
406 tpm2_tpms_pcr_selection_from_mask(0xffff00, sha384
, &add
[add_count
++]);
407 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512
, &add
[add_count
++]);
408 tpm2_tpms_pcr_selection_from_mask(0xf00000, sha1
, &add
[add_count
++]);
409 tpm2_tpms_pcr_selection_from_mask(0xf000f0, sha1
, &expected1
[expected1_count
++]);
410 tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256
, &expected1
[expected1_count
++]);
411 tpm2_tpms_pcr_selection_from_mask(0xffff00, sha384
, &expected1
[expected1_count
++]);
412 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512
, &expected1
[expected1_count
++]);
413 tpm2_tpms_pcr_selection_from_mask(0x00ffff, sha256
, &sub
[sub_count
++]);
414 tpm2_tpms_pcr_selection_from_mask(0xf000f0, sha1
, &expected2
[expected2_count
++]);
415 tpm2_tpms_pcr_selection_from_mask(0xff0000, sha256
, &expected2
[expected2_count
++]);
416 tpm2_tpms_pcr_selection_from_mask(0xffff00, sha384
, &expected2
[expected2_count
++]);
417 tpm2_tpms_pcr_selection_from_mask(0x0000ff, sha512
, &expected2
[expected2_count
++]);
418 _test_tpml_addsub(&l
,
420 expected1
, expected1_count
,
422 expected2
, expected2_count
);
425 static bool digest_check(const TPM2B_DIGEST
*digest
, const char *expect
) {
426 _cleanup_free_
char *h
= NULL
;
431 h
= hexmem(digest
->buffer
, digest
->size
);
434 return strcaseeq(expect
, h
);
437 static void digest_init(TPM2B_DIGEST
*digest
, const char *hash
) {
438 assert_se(strlen(hash
) <= sizeof(digest
->buffer
) * 2);
440 DEFINE_HEX_PTR(h
, hash
);
442 /* Make sure the length matches a known hash algorithm */
443 assert_se(IN_SET(h_len
, TPM2_SHA1_DIGEST_SIZE
, TPM2_SHA256_DIGEST_SIZE
, TPM2_SHA384_DIGEST_SIZE
, TPM2_SHA512_DIGEST_SIZE
));
445 *digest
= TPM2B_DIGEST_MAKE(h
, h_len
);
447 assert_se(digest_check(digest
, hash
));
451 TPM2B_DIGEST d
, d0
, d1
, d2
, d3
, d4
;
453 digest_init(&d0
, "0000000000000000000000000000000000000000000000000000000000000000");
454 digest_init(&d1
, "17b7703d9d00776310ba032e88c1a8c2a9c630ebdd799db622f6631530789175");
455 digest_init(&d2
, "12998c017066eb0d2a70b94e6ed3192985855ce390f321bbdb832022888bd251");
456 digest_init(&d3
, "c3a65887fedd3fb4f5d0047e906dff830bcbd1293160909eb4b05f485e7387ad");
457 digest_init(&d4
, "6491fb4bc08fc0b2ef47fc63db57e249917885e69d8c0d99667df83a59107a33");
459 /* tpm2_digest_init, tpm2_digest_rehash */
460 d
= (TPM2B_DIGEST
){ .size
= 1, .buffer
= { 2, }, };
461 assert_se(tpm2_digest_init(TPM2_ALG_SHA256
, &d
) == 0);
462 assert_se(digest_check(&d
, "0000000000000000000000000000000000000000000000000000000000000000"));
463 assert_se(tpm2_digest_rehash(TPM2_ALG_SHA256
, &d
) == 0);
464 assert_se(digest_check(&d
, "66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925"));
467 assert_se(tpm2_digest_rehash(TPM2_ALG_SHA256
, &d
) == 0);
468 assert_se(digest_check(&d
, "ab55014b5ace12ba70c3acc887db571585a83539aad3633d252a710f268f405c"));
469 assert_se(tpm2_digest_init(TPM2_ALG_SHA256
, &d
) == 0);
470 assert_se(digest_check(&d
, "0000000000000000000000000000000000000000000000000000000000000000"));
472 /* tpm2_digest_many_digests */
473 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256
, &d
, &d2
, 1, false) == 0);
474 assert_se(digest_check(&d
, "56571a1be3fbeab18d215f549095915a004b5788ca0d535be668559129a76f25"));
475 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256
, &d
, &d2
, 1, true) == 0);
476 assert_se(digest_check(&d
, "99dedaee8f4d8d10a8be184399fde8740d5e17ff783ee5c288a4486e4ce3a1fe"));
478 const TPM2B_DIGEST da1
[] = { d2
, d3
, };
479 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256
, &d
, da1
, ELEMENTSOF(da1
), false) == 0);
480 assert_se(digest_check(&d
, "525aa13ef9a61827778ec3acf16fbb23b65ae8770b8fb2684d3a33f9457dd6d8"));
481 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256
, &d
, da1
, ELEMENTSOF(da1
), true) == 0);
482 assert_se(digest_check(&d
, "399ca2aa98963d1bd81a2b58a7e5cda24bba1be88fb4da9aa73d97706846566b"));
484 const TPM2B_DIGEST da2
[] = { d3
, d2
, d0
};
485 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256
, &d
, da2
, ELEMENTSOF(da2
), false) == 0);
486 assert_se(digest_check(&d
, "b26fd22db74d4cd896bff01c61aa498a575e4a553a7fb5a322a5fee36954313e"));
487 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256
, &d
, da2
, ELEMENTSOF(da2
), true) == 0);
488 assert_se(digest_check(&d
, "091e79a5b09d4048df49a680f966f3ff67910afe185c3baf9704c9ca45bcf259"));
490 const TPM2B_DIGEST da3
[] = { d4
, d4
, d4
, d4
, d3
, d4
, d4
, d4
, d4
, };
491 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256
, &d
, da3
, ELEMENTSOF(da3
), false) == 0);
492 assert_se(digest_check(&d
, "8eca947641b6002df79dfb571a7f78b7d0a61370a366f722386dfbe444d18830"));
493 assert_se(tpm2_digest_many_digests(TPM2_ALG_SHA256
, &d
, da3
, ELEMENTSOF(da3
), true) == 0);
494 assert_se(digest_check(&d
, "f9ba17bc0bbe8794e9bcbf112e4d59a11eb68fffbcd5516a746e4857829dff04"));
496 /* tpm2_digest_buffer */
497 const uint8_t b1
[] = { 1, 2, 3, 4, };
498 assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256
, &d
, b1
, ELEMENTSOF(b1
), false) == 0);
499 assert_se(digest_check(&d
, "9f64a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a"));
500 assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256
, &d
, b1
, ELEMENTSOF(b1
), true) == 0);
501 assert_se(digest_check(&d
, "ff3bd307b287e9b29bb572f6ccfd19deb0106d0c4c3c5cfe8a1d03a396092ed4"));
503 const void *b2
= d2
.buffer
;
504 assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256
, &d
, b2
, d2
.size
, false) == 0);
505 assert_se(digest_check(&d
, "56571a1be3fbeab18d215f549095915a004b5788ca0d535be668559129a76f25"));
506 assert_se(tpm2_digest_buffer(TPM2_ALG_SHA256
, &d
, b2
, d2
.size
, true) == 0);
507 assert_se(digest_check(&d
, "99dedaee8f4d8d10a8be184399fde8740d5e17ff783ee5c288a4486e4ce3a1fe"));
509 /* tpm2_digest_many */
510 const struct iovec iov1
[] = {
511 IOVEC_MAKE((void*) b1
, ELEMENTSOF(b1
)),
512 IOVEC_MAKE(d2
.buffer
, d2
.size
),
513 IOVEC_MAKE(d3
.buffer
, d3
.size
),
515 assert_se(tpm2_digest_many(TPM2_ALG_SHA256
, &d
, iov1
, ELEMENTSOF(iov1
), false) == 0);
516 assert_se(digest_check(&d
, "cd7bde4a047af976b6f1b282309976229be59f96a78aa186de32a1aee488ab09"));
517 assert_se(tpm2_digest_many(TPM2_ALG_SHA256
, &d
, iov1
, ELEMENTSOF(iov1
), true) == 0);
518 assert_se(digest_check(&d
, "02ecb0628264235111e0053e271092981c8b15d59cd46617836bee3149a4ecb0"));
521 static void check_parse_pcr_argument(
523 const Tpm2PCRValue
*prev_values
,
524 size_t n_prev_values
,
525 const Tpm2PCRValue
*expected_values
,
526 size_t n_expected_values
) {
528 _cleanup_free_ Tpm2PCRValue
*values
= NULL
;
531 if (n_prev_values
> 0) {
532 assert_se(GREEDY_REALLOC_APPEND(values
, n_values
, prev_values
, n_prev_values
));
533 assert_se(tpm2_parse_pcr_argument_append(arg
, &values
, &n_values
) == 0);
535 assert_se(tpm2_parse_pcr_argument(arg
, &values
, &n_values
) == 0);
537 assert_se(n_values
== n_expected_values
);
538 for (size_t i
= 0; i
< n_values
; i
++) {
539 const Tpm2PCRValue
*v
= &values
[i
], *e
= &expected_values
[i
];
540 //tpm2_log_debug_pcr_value(e, "Expected value");
541 //tpm2_log_debug_pcr_value(v, "Actual value");
543 assert_se(v
->index
== e
->index
);
544 assert_se(v
->hash
== e
->hash
);
545 assert_se(v
->value
.size
== e
->value
.size
);
546 assert_se(memcmp(v
->value
.buffer
, e
->value
.buffer
, e
->value
.size
) == 0);
550 assert_se(tpm2_pcr_values_hash_count(expected_values
, n_expected_values
, &hash_count
) == 0);
551 if (hash_count
== 1) {
552 uint32_t mask
= UINT32_MAX
, expected_mask
= 0;
554 if (n_prev_values
> 0)
555 assert_se(tpm2_pcr_values_to_mask(prev_values
, n_prev_values
, prev_values
[0].hash
, &mask
) == 0);
557 assert_se(tpm2_pcr_values_to_mask(expected_values
, n_expected_values
, expected_values
[0].hash
, &expected_mask
) == 0);
559 assert_se(tpm2_parse_pcr_argument_to_mask(arg
, &mask
) == 0);
560 assert_se(mask
== expected_mask
);
563 size_t old_n_values
= n_values
;
564 assert_se(tpm2_parse_pcr_argument_append("", &values
, &n_values
) == 0);
566 assert_se(n_values
== old_n_values
);
569 static void check_parse_pcr_argument_to_mask(const char *arg
, int mask
) {
571 int r
= tpm2_parse_pcr_argument_to_mask(arg
, &m
);
574 assert_se(mask
== r
);
576 assert_se((uint32_t) mask
== m
);
579 TEST(parse_pcr_argument
) {
580 _cleanup_free_ Tpm2PCRValue
*t0p
= NULL
;
582 assert_se(tpm2_parse_pcr_argument("", &t0p
, &n_t0p
) == 0);
583 assert_se(n_t0p
== 0);
584 assert_se(tpm2_parse_pcr_argument_append("", &t0p
, &n_t0p
) == 0);
585 assert_se(n_t0p
== 0);
587 assert_se(tpm2_parse_pcr_argument_to_mask("", &m0
) == 0);
589 assert_se(tpm2_parse_pcr_argument_to_mask("", &m0
) == 0);
592 Tpm2PCRValue t1
[] = {
593 TPM2_PCR_VALUE_MAKE(0, 0, {}),
594 TPM2_PCR_VALUE_MAKE(4, 0, {}),
595 TPM2_PCR_VALUE_MAKE(7, 0, {}),
596 TPM2_PCR_VALUE_MAKE(11, 0, {}),
598 check_parse_pcr_argument("0,4,7,11", NULL
, 0, t1
, ELEMENTSOF(t1
));
599 check_parse_pcr_argument("11,4,7,0", NULL
, 0, t1
, ELEMENTSOF(t1
));
600 check_parse_pcr_argument("7,4,0,11", NULL
, 0, t1
, ELEMENTSOF(t1
));
601 check_parse_pcr_argument("11,7,4,0", NULL
, 0, t1
, ELEMENTSOF(t1
));
602 check_parse_pcr_argument("0+4+7+11", NULL
, 0, t1
, ELEMENTSOF(t1
));
603 check_parse_pcr_argument("0,4+7,11", NULL
, 0, t1
, ELEMENTSOF(t1
));
605 Tpm2PCRValue t2
[] = {
606 TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA1
, {}),
607 TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA1
, {}),
608 TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA1
, {}),
609 TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA1
, {}),
611 check_parse_pcr_argument("0:sha1,4,7,11", NULL
, 0, t2
, ELEMENTSOF(t2
));
612 check_parse_pcr_argument("11,4,7,0:sha1", NULL
, 0, t2
, ELEMENTSOF(t2
));
613 check_parse_pcr_argument("7,4:sha1,0,11", NULL
, 0, t2
, ELEMENTSOF(t2
));
614 check_parse_pcr_argument("0:sha1,4:sha1,7:sha1,11:sha1", NULL
, 0, t2
, ELEMENTSOF(t2
));
615 check_parse_pcr_argument("0:sha1+4:sha1,11:sha1+7:sha1", NULL
, 0, t2
, ELEMENTSOF(t2
));
617 Tpm2PCRValue t3
[] = {
618 TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA1
, {}),
619 TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA1
, {}),
620 TPM2_PCR_VALUE_MAKE(2, TPM2_ALG_SHA1
, {}),
621 TPM2_PCR_VALUE_MAKE(3, TPM2_ALG_SHA1
, {}),
622 TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA1
, {}),
623 TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA1
, {}),
624 TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA1
, {}),
625 TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA1
, {}),
627 check_parse_pcr_argument("1,2,3,12", t2
, ELEMENTSOF(t2
), t3
, ELEMENTSOF(t3
));
628 check_parse_pcr_argument("12,2,3,1", t2
, ELEMENTSOF(t2
), t3
, ELEMENTSOF(t3
));
629 check_parse_pcr_argument("1,2,3,12:sha1", t1
, ELEMENTSOF(t1
), t3
, ELEMENTSOF(t3
));
630 check_parse_pcr_argument("1,2,3,12:sha1", t2
, ELEMENTSOF(t2
), t3
, ELEMENTSOF(t3
));
631 check_parse_pcr_argument("1:sha1,2,3,12", t1
, ELEMENTSOF(t1
), t3
, ELEMENTSOF(t3
));
632 check_parse_pcr_argument("1:sha1,2,3,12", t2
, ELEMENTSOF(t2
), t3
, ELEMENTSOF(t3
));
633 check_parse_pcr_argument("1:sha1,2:sha1,3:sha1,12:sha1", t1
, ELEMENTSOF(t1
), t3
, ELEMENTSOF(t3
));
634 check_parse_pcr_argument("1:sha1,2:sha1,3:sha1,12:sha1", t2
, ELEMENTSOF(t2
), t3
, ELEMENTSOF(t3
));
637 digest_init(&d4
, "FCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2");
638 Tpm2PCRValue t4
[] = {
639 TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA256
, {}),
640 TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA256
, d4
),
641 TPM2_PCR_VALUE_MAKE(2, TPM2_ALG_SHA256
, {}),
642 TPM2_PCR_VALUE_MAKE(3, TPM2_ALG_SHA256
, {}),
643 TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA256
, {}),
644 TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA256
, {}),
645 TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA256
, {}),
646 TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA256
, {}),
648 check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2,3,12", t1
, ELEMENTSOF(t1
), t4
, ELEMENTSOF(t4
));
649 check_parse_pcr_argument("12,2,3,1:sha256=FCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2", t1
, ELEMENTSOF(t1
), t4
, ELEMENTSOF(t4
));
650 check_parse_pcr_argument("12,2,3,1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2", t1
, ELEMENTSOF(t1
), t4
, ELEMENTSOF(t4
));
651 check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2,3,12:SHA256", t1
, ELEMENTSOF(t1
), t4
, ELEMENTSOF(t4
));
652 check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2,3,12", t1
, ELEMENTSOF(t1
), t4
, ELEMENTSOF(t4
));
653 check_parse_pcr_argument("1:sha256=FCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2:sha256,3:sha256,12:sha256", t1
, ELEMENTSOF(t1
), t4
, ELEMENTSOF(t4
));
654 check_parse_pcr_argument("1:sha256=0xFCE7F1083082B16CFE2B085DD7858BB11A37C09B78E36C79E5A2FD529353C4E2,2:sha256,3:sha256,12:sha256", t1
, ELEMENTSOF(t1
), t4
, ELEMENTSOF(t4
));
657 digest_init(&d5
, "0F21EADB7F27377668E3C8069BE88D116491FBEE");
658 Tpm2PCRValue t5
[] = {
659 TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA1
, d5
),
660 TPM2_PCR_VALUE_MAKE(0, TPM2_ALG_SHA256
, {}),
661 TPM2_PCR_VALUE_MAKE(1, TPM2_ALG_SHA256
, d4
),
662 TPM2_PCR_VALUE_MAKE(2, TPM2_ALG_SHA256
, {}),
663 TPM2_PCR_VALUE_MAKE(3, TPM2_ALG_SHA256
, {}),
664 TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA256
, {}),
665 TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA256
, {}),
666 TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA256
, {}),
667 TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA256
, {}),
668 TPM2_PCR_VALUE_MAKE(5, TPM2_ALG_SHA384
, {}),
669 TPM2_PCR_VALUE_MAKE(6, TPM2_ALG_SHA512
, {}),
671 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
));
672 check_parse_pcr_argument("1:sha1=0F21EADB7F27377668E3C8069BE88D116491FBEE,6:sha512,5:sha384", t4
, ELEMENTSOF(t4
), t5
, ELEMENTSOF(t5
));
674 Tpm2PCRValue
*v
= NULL
;
676 assert_se(tpm2_parse_pcr_argument("1,100", &v
, &n_v
) < 0);
677 assert_se(tpm2_parse_pcr_argument("1,2=123456abc", &v
, &n_v
) < 0);
678 assert_se(tpm2_parse_pcr_argument("1,2:invalid", &v
, &n_v
) < 0);
679 assert_se(tpm2_parse_pcr_argument("1:sha1=invalid", &v
, &n_v
) < 0);
680 assert_se(v
== NULL
);
683 check_parse_pcr_argument_to_mask("", 0x0);
684 check_parse_pcr_argument_to_mask("0", 0x1);
685 check_parse_pcr_argument_to_mask("1", 0x2);
686 check_parse_pcr_argument_to_mask("0,1", 0x3);
687 check_parse_pcr_argument_to_mask("0+1", 0x3);
688 check_parse_pcr_argument_to_mask("0-1", -EINVAL
);
689 check_parse_pcr_argument_to_mask("foo", -EINVAL
);
690 check_parse_pcr_argument_to_mask("0,1,2", 0x7);
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,2", 0x5);
695 check_parse_pcr_argument_to_mask("0+2", 0x5);
696 check_parse_pcr_argument_to_mask("7+application-support", 0x800080);
697 check_parse_pcr_argument_to_mask("8+boot-loader-code", 0x110);
698 check_parse_pcr_argument_to_mask("7,shim-policy,4", 0x4090);
699 check_parse_pcr_argument_to_mask("sysexts,shim-policy+kernel-boot", 0x6800);
700 check_parse_pcr_argument_to_mask("sysexts,shim+kernel-boot", -EINVAL
);
701 check_parse_pcr_argument_to_mask("sysexts+17+23", 0x822000);
702 check_parse_pcr_argument_to_mask("6+boot-loader-code,44", -EINVAL
);
703 check_parse_pcr_argument_to_mask("debug+24", -EINVAL
);
706 static const TPMT_PUBLIC test_rsa_template
= {
707 .type
= TPM2_ALG_RSA
,
708 .nameAlg
= TPM2_ALG_SHA256
,
709 .objectAttributes
= TPMA_OBJECT_RESTRICTED
|TPMA_OBJECT_DECRYPT
|TPMA_OBJECT_FIXEDTPM
|TPMA_OBJECT_FIXEDPARENT
|TPMA_OBJECT_SENSITIVEDATAORIGIN
|TPMA_OBJECT_USERWITHAUTH
,
710 .parameters
.rsaDetail
= {
712 .algorithm
= TPM2_ALG_AES
,
714 .mode
.aes
= TPM2_ALG_CFB
,
716 .scheme
.scheme
= TPM2_ALG_NULL
,
721 static const TPMT_PUBLIC test_ecc_template
= {
722 .type
= TPM2_ALG_ECC
,
723 .nameAlg
= TPM2_ALG_SHA256
,
724 .objectAttributes
= TPMA_OBJECT_RESTRICTED
|TPMA_OBJECT_DECRYPT
|TPMA_OBJECT_FIXEDTPM
|TPMA_OBJECT_FIXEDPARENT
|TPMA_OBJECT_SENSITIVEDATAORIGIN
|TPMA_OBJECT_USERWITHAUTH
,
725 .parameters
.eccDetail
= {
727 .algorithm
= TPM2_ALG_AES
,
729 .mode
.aes
= TPM2_ALG_CFB
,
731 .scheme
.scheme
= TPM2_ALG_NULL
,
732 .curveID
= TPM2_ECC_NIST_P256
,
733 .kdf
.scheme
= TPM2_ALG_NULL
,
737 static const TPMT_PUBLIC
*test_templates
[] = {
742 static void tpm2b_public_rsa_init(TPM2B_PUBLIC
*public, const char *rsa_n
) {
743 TPMT_PUBLIC tpmt
= test_rsa_template
;
745 DEFINE_HEX_PTR(key
, rsa_n
);
746 tpmt
.unique
.rsa
= TPM2B_PUBLIC_KEY_RSA_MAKE(key
, key_len
);
748 public->size
= sizeof(tpmt
);
749 public->publicArea
= tpmt
;
752 static void tpm2b_public_ecc_init(TPM2B_PUBLIC
*public, TPMI_ECC_CURVE curve
, const char *x
, const char *y
) {
753 TPMT_PUBLIC tpmt
= test_ecc_template
;
754 tpmt
.parameters
.eccDetail
.curveID
= curve
;
756 DEFINE_HEX_PTR(buf_x
, x
);
757 tpmt
.unique
.ecc
.x
= TPM2B_ECC_PARAMETER_MAKE(buf_x
, buf_x_len
);
759 DEFINE_HEX_PTR(buf_y
, y
);
760 tpmt
.unique
.ecc
.y
= TPM2B_ECC_PARAMETER_MAKE(buf_y
, buf_y_len
);
762 public->size
= sizeof(tpmt
);
763 public->publicArea
= tpmt
;
767 TEST(tpm2b_public_to_openssl_pkey
) {
768 DEFINE_HEX_PTR(msg
, "edc64c6523778961fe9ba03ab7d624b27ca1dd5b01e7734cc6c891d50db04269");
772 tpm2b_public_rsa_init(&public, "d71cff5bba2173f0434a389171048e7da8cf8409b892c62946481cc383089bc754324620967fea3d00a02a717cdda4bfe1525ad957d294b88434e0a3933e86fb40f234e4935fd2ba27eb1d21da87efa466b74eb4ad18d26059904643441cf402ee933d138a2151f40459c49d87fef59e2cb822768b2d8689a9b58f82bf9a37e70693f2b2d40dfa388d365c1b1f029a14c4fc8dadb68978ef377d20ff2ca24e7078464c705eab42f531557c9c6dc0df66b506d0c26ef604f8110c64867099267453c71871e7ed22505a09daf102afc34355209ca7680eccc0ed368d148f402fa58cbb6c9d52351f535f09e4e24ad805e149f130edaa2f5e7efed3a4d2d03adb85");
773 _cleanup_(EVP_PKEY_freep
) EVP_PKEY
*pkey_rsa
= NULL
;
774 assert_se(tpm2_tpm2b_public_to_openssl_pkey(&public, &pkey_rsa
) >= 0);
776 _cleanup_(EVP_PKEY_CTX_freep
) EVP_PKEY_CTX
*ctx_rsa
= EVP_PKEY_CTX_new((EVP_PKEY
*) pkey_rsa
, NULL
);
778 assert_se(EVP_PKEY_verify_init(ctx_rsa
) == 1);
779 assert_se(EVP_PKEY_CTX_set_signature_md(ctx_rsa
, EVP_sha256()) > 0);
781 DEFINE_HEX_PTR(sig_rsa
, "9f70a9e68911be3ec464cae91126328307bf355872127e042d6c61e0a80982872c151033bcf727abfae5fc9500c923120011e7ef4aa5fc690a59a034697b6022c141b4b209e2df6f4b282288cd9181073fbe7158ce113c79d87623423c1f3996ff931e59cc91db74f8e8656215b1436fc93ddec0f1f8fa8510826e674b250f047e6cba94c95ff98072a286baca94646b577974a1e00d56c21944e38960d8ee90511a2f938e5cf1ac7b7cc7ff8e3ac001d321254d3e4f988b90e9f6f873c26ecd0a12a626b3474833cdbb9e9f793238f6c97ee5b75a1a89bb7a7858d34ecfa6d34ac58d95085e6c4fbbebd47a4364be2725c2c6b3fa15d916f3c0b62a66fe76ae");
782 assert_se(EVP_PKEY_verify(ctx_rsa
, sig_rsa
, sig_rsa_len
, (unsigned char*) msg
, msg_len
) == 1);
785 tpm2b_public_ecc_init(&public, TPM2_ECC_NIST_P256
, "6fc0ecf3645c673ab7e86d1ec5b315afb950257c5f68ab23296160006711fac2", "8dd2ef7a2c9ecede91493ba98c8fb3f893aff325c6a1e0f752c657b2d6ca1413");
786 _cleanup_(EVP_PKEY_freep
) EVP_PKEY
*pkey_ecc
= NULL
;
787 assert_se(tpm2_tpm2b_public_to_openssl_pkey(&public, &pkey_ecc
) >= 0);
789 _cleanup_(EVP_PKEY_CTX_freep
) EVP_PKEY_CTX
*ctx_ecc
= EVP_PKEY_CTX_new((EVP_PKEY
*) pkey_ecc
, NULL
);
791 assert_se(EVP_PKEY_verify_init(ctx_ecc
) == 1);
793 DEFINE_HEX_PTR(sig_ecc
, "304602210092447ac0b5b32e90923f79bb4aba864b9c546a9900cf193a83243d35d189a2110221009a8b4df1dfa85e225eff9c606694d4d205a7a3968c9552f50bc2790209a90001");
794 assert_se(EVP_PKEY_verify(ctx_ecc
, sig_ecc
, sig_ecc_len
, (unsigned char*) msg
, msg_len
) == 1);
797 static void get_tpm2b_public_from_pem(const void *pem
, size_t pem_size
, TPM2B_PUBLIC
*ret
) {
798 _cleanup_(EVP_PKEY_freep
) EVP_PKEY
*pkey
= NULL
;
799 TPM2B_PUBLIC p1
= {}, p2
= {};
804 assert_se(openssl_pkey_from_pem(pem
, pem_size
, &pkey
) >= 0);
805 assert_se(tpm2_tpm2b_public_from_openssl_pkey(pkey
, &p1
) >= 0);
806 assert_se(tpm2_tpm2b_public_from_pem(pem
, pem_size
, &p2
) >= 0);
807 assert_se(memcmp_nn(&p1
, sizeof(p1
), &p2
, sizeof(p2
)) == 0);
812 static void check_tpm2b_public_fingerprint(const TPM2B_PUBLIC
*public, const char *hexfp
) {
813 DEFINE_HEX_PTR(expected
, hexfp
);
814 _cleanup_free_
void *fp
= NULL
;
817 assert_se(tpm2_tpm2b_public_to_fingerprint(public, &fp
, &fp_size
) >= 0);
818 assert_se(memcmp_nn(fp
, fp_size
, expected
, expected_len
) == 0);
821 TEST(tpm2b_public_from_openssl_pkey
) {
823 TPMT_PUBLIC
*p
= &public.publicArea
;
825 DEFINE_HEX_PTR(key_ecc
, "2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a30444151634451674145726a6e4575424c73496c3972687068777976584e50686a346a426e500a44586e794a304b395579724e6764365335413532542b6f5376746b436a365a726c34685847337741515558706f426c532b7448717452714c35513d3d0a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a");
826 get_tpm2b_public_from_pem(key_ecc
, key_ecc_len
, &public);
828 assert_se(p
->type
== TPM2_ALG_ECC
);
829 assert_se(p
->parameters
.eccDetail
.curveID
== TPM2_ECC_NIST_P256
);
831 DEFINE_HEX_PTR(expected_x
, "ae39c4b812ec225f6b869870caf5cd3e18f88c19cf0d79f22742bd532acd81de");
832 assert_se(memcmp_nn(p
->unique
.ecc
.x
.buffer
, p
->unique
.ecc
.x
.size
, expected_x
, expected_x_len
) == 0);
834 DEFINE_HEX_PTR(expected_y
, "92e40e764fea12bed9028fa66b9788571b7c004145e9a01952fad1eab51a8be5");
835 assert_se(memcmp_nn(p
->unique
.ecc
.y
.buffer
, p
->unique
.ecc
.y
.size
, expected_y
, expected_y_len
) == 0);
837 check_tpm2b_public_fingerprint(&public, "cd3373293b62a52b48c12100e80ea9bfd806266ce76893a5ec31cb128052d97c");
839 DEFINE_HEX_PTR(key_rsa
, "2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d494942496a414e42676b71686b6947397730424151454641414f43415138414d49494243674b4341514541795639434950652f505852337a436f63787045300a6a575262546c3568585844436b472f584b79374b6d2f4439584942334b734f5a31436a5937375571372f674359363170697838697552756a73413464503165380a593445336c68556d374a332b6473766b626f4b64553243626d52494c2f6675627771694c4d587a41673342575278747234547545443533527a373634554650640a307a70304b68775231496230444c67772f344e67566f314146763378784b4d6478774d45683567676b73733038326332706c354a504e32587677426f744e6b4d0a5471526c745a4a35355244436170696e7153334577376675646c4e735851357746766c7432377a7637344b585165616d704c59433037584f6761304c676c536b0a79754774586b6a50542f735542544a705374615769674d5a6f714b7479563463515a58436b4a52684459614c47587673504233687a766d5671636e6b47654e540a65774944415141420a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a");
840 get_tpm2b_public_from_pem(key_rsa
, key_rsa_len
, &public);
842 DEFINE_HEX_PTR(expected_n
, "c95f4220f7bf3d7477cc2a1cc691348d645b4e5e615d70c2906fd72b2eca9bf0fd5c80772ac399d428d8efb52aeff80263ad698b1f22b91ba3b00e1d3f57bc638137961526ec9dfe76cbe46e829d53609b99120bfdfb9bc2a88b317cc0837056471b6be13b840f9dd1cfbeb85053ddd33a742a1c11d486f40cb830ff8360568d4016fdf1c4a31dc7030487982092cb34f36736a65e493cdd97bf0068b4d90c4ea465b59279e510c26a98a7a92dc4c3b7ee76536c5d0e7016f96ddbbcefef829741e6a6a4b602d3b5ce81ad0b8254a4cae1ad5e48cf4ffb140532694ad6968a0319a2a2adc95e1c4195c29094610d868b197bec3c1de1cef995a9c9e419e3537b");
843 assert_se(p
->unique
.rsa
.size
== expected_n_len
);
844 assert_se(memcmp(p
->unique
.rsa
.buffer
, expected_n
, expected_n_len
) == 0);
846 assert_se(p
->parameters
.rsaDetail
.keyBits
== expected_n_len
* 8);
848 assert_se(p
->parameters
.rsaDetail
.exponent
== 0);
850 check_tpm2b_public_fingerprint(&public, "d9186d13a7fd5b3644cee05448f49ad3574e82a2942ff93cf89598d36cca78a9");
854 static void check_name(const TPM2B_NAME
*name
, const char *expect
) {
855 assert_se(name
->size
== SHA256_DIGEST_SIZE
+ 2);
857 DEFINE_HEX_PTR(e
, expect
);
858 assert_se(name
->size
== e_len
);
859 assert_se(memcmp(name
->name
, e
, e_len
) == 0);
862 TEST(calculate_pubkey_name
) {
867 tpm2b_public_rsa_init(&public, "9ec7341c52093ac40a1965a5df10432513c539adcf905e30577ab6ebc88ffe53cd08cef12ed9bec6125432f4fada3629b8b96d31b8f507aa35029188fe396da823fcb236027f7fbb01b0da3d87be7f999390449ced604bdf7e26c48657cc0671000f1147da195c3861c96642e54427cb7a11572e07567ec3fd6316978abc4bd92b27bb0a0e4958e599804eeb41d682b3b7fc1f960209f80a4fb8a1b64abfd96bf5d554e73cdd6ad1c8becb4fcf5e8f0c3e621d210e5e2f308f6520ad9a966779231b99f06c5989e5a23a9415c8808ab89ce81117632e2f8461cd4428bded40979236aeadafe8de3f51660a45e1dbc87694e6a36360201cca3ff9e7263e712727");
868 assert_se(tpm2_calculate_pubkey_name(&public.publicArea
, &name
) >= 0);
869 check_name(&name
, "000be78f74a470dd92e979ca067cdb2293a35f075e8560b436bd2ccea5da21486a07");
872 tpm2b_public_ecc_init(&public, TPM2_ECC_NIST_P256
, "238e02ee4fd5598add6b502429f1815418515e4b0d6551c8e816b38cb15451d1", "70c2d491769775ec43ccd5a571c429233e9d30cf0f486c2e01acd6cb32ba93b6");
873 assert_se(tpm2_calculate_pubkey_name(&public.publicArea
, &name
) >= 0);
874 check_name(&name
, "000b302787187ba19c82011c987bd2dcdbb652b3a543ccc5cb0b49c33d4caae604a6");
877 TEST(calculate_policy_auth_value
) {
880 digest_init(&d
, "0000000000000000000000000000000000000000000000000000000000000000");
881 assert_se(tpm2_calculate_policy_auth_value(&d
) == 0);
882 assert_se(digest_check(&d
, "8fcd2169ab92694e0c633f1ab772842b8241bbc20288981fc7ac1eddc1fddb0e"));
883 assert_se(tpm2_calculate_policy_auth_value(&d
) == 0);
884 assert_se(digest_check(&d
, "759ebd5ed65100e0b4aa2d04b4b789c2672d92ecc9cdda4b5fa16a303132e008"));
887 TEST(calculate_policy_authorize
) {
892 tpm2b_public_rsa_init(&public, "9ec7341c52093ac40a1965a5df10432513c539adcf905e30577ab6ebc88ffe53cd08cef12ed9bec6125432f4fada3629b8b96d31b8f507aa35029188fe396da823fcb236027f7fbb01b0da3d87be7f999390449ced604bdf7e26c48657cc0671000f1147da195c3861c96642e54427cb7a11572e07567ec3fd6316978abc4bd92b27bb0a0e4958e599804eeb41d682b3b7fc1f960209f80a4fb8a1b64abfd96bf5d554e73cdd6ad1c8becb4fcf5e8f0c3e621d210e5e2f308f6520ad9a966779231b99f06c5989e5a23a9415c8808ab89ce81117632e2f8461cd4428bded40979236aeadafe8de3f51660a45e1dbc87694e6a36360201cca3ff9e7263e712727");
893 digest_init(&d
, "0000000000000000000000000000000000000000000000000000000000000000");
894 assert_se(tpm2_calculate_policy_authorize(&public, NULL
, &d
) == 0);
895 assert_se(digest_check(&d
, "95213a3784eaab04f427bc7e8851c2f1df0903be8e42428ec25dcefd907baff1"));
896 assert_se(tpm2_calculate_policy_authorize(&public, NULL
, &d
) == 0);
897 assert_se(digest_check(&d
, "95213a3784eaab04f427bc7e8851c2f1df0903be8e42428ec25dcefd907baff1"));
900 tpm2b_public_ecc_init(&public, TPM2_ECC_NIST_P256
, "423a89da6f0998f510489ab9682706e762031ef8f9faef2a185eff67065a187e", "996f73291670cef9e303d6cd9fa19ddf2c9c1fb1e283324ca9acca07c405c8d0");
901 digest_init(&d
, "0000000000000000000000000000000000000000000000000000000000000000");
902 assert_se(tpm2_calculate_policy_authorize(&public, NULL
, &d
) == 0);
903 assert_se(digest_check(&d
, "2a5b705e83f949c27ac4d2e79e54fb5fb0a60f0b37bbd54a0ee1022ba00d3628"));
904 assert_se(tpm2_calculate_policy_authorize(&public, NULL
, &d
) == 0);
905 assert_se(digest_check(&d
, "2a5b705e83f949c27ac4d2e79e54fb5fb0a60f0b37bbd54a0ee1022ba00d3628"));
908 TEST(calculate_policy_pcr
) {
909 TPM2B_DIGEST d
, dN
[16];
911 digest_init(&dN
[ 0], "2124793cbbe60c3a8637d3b84a5d054e87c351e1469a285acc04755e8b204dec");
912 digest_init(&dN
[ 1], "bf7592f18adcfdc549fc0b94939f5069a24697f9cff4a0dca29014767b97559d");
913 digest_init(&dN
[ 2], "4b00cff9dee3a364979b2dc241b34568a8ad49fcf2713df259e47dff8875feed");
914 digest_init(&dN
[ 3], "3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969");
915 digest_init(&dN
[ 4], "368f85b3013041dfe203faaa364f00b07c5da7b1e5f1dbf2efb06fa6b9bd92de");
916 digest_init(&dN
[ 5], "c97c40369691c8e4aa78fb3a52655cd193b780a838b8e23f5f476576919db5e5");
917 digest_init(&dN
[ 6], "3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969");
918 digest_init(&dN
[ 7], "aa1154c9e0a774854ccbed4c8ce7e9b906b3d700a1a8db1772d0341a62dbe51b");
919 digest_init(&dN
[ 8], "cfde439a2c06af3479ca6bdc60429b90553d65300c5cfcc40004a08c6b5ad81a");
920 digest_init(&dN
[ 9], "9c2bac22ef5ec84fcdb71c3ebf776cba1247e5da980e5ee08e45666a2edf0b8b");
921 digest_init(&dN
[10], "9885873f4d7348199ad286f8f2476d4f866940950f6f9fb9f945ed352dbdcbd2");
922 digest_init(&dN
[11], "42400ab950d21aa79d12cc4fdef67d1087a39ad64900619831c0974dbae54e44");
923 digest_init(&dN
[12], "767d064382e56ca1ad3bdcc6bc596112e6c2008b593d3570d24c2bfa64c4628c");
924 digest_init(&dN
[13], "30c16133175959408c9745d8dafadef5daf4b39cb2be04df0d60089bd46d3cc4");
925 digest_init(&dN
[14], "e3991b7ddd47be7e92726a832d6874c5349b52b789fa0db8b558c69fea29574e");
926 digest_init(&dN
[15], "852dae3ecb992bdeb13d6002fefeeffdd90feca8b378d56681ef2c885d0e5137");
928 digest_init(&d
, "0000000000000000000000000000000000000000000000000000000000000000");
929 Tpm2PCRValue v1
[] = {
930 TPM2_PCR_VALUE_MAKE(4, TPM2_ALG_SHA256
, dN
[4]),
931 TPM2_PCR_VALUE_MAKE(7, TPM2_ALG_SHA256
, dN
[7]),
932 TPM2_PCR_VALUE_MAKE(8, TPM2_ALG_SHA256
, dN
[8]),
934 assert_se(tpm2_calculate_policy_pcr(v1
, ELEMENTSOF(v1
), &d
) == 0);
935 assert_se(digest_check(&d
, "76532a0e16f7e6bf6b02918c11f75d99d729fab0cc81d0df2c4284a2c4fe6e05"));
936 assert_se(tpm2_calculate_policy_pcr(v1
, ELEMENTSOF(v1
), &d
) == 0);
937 assert_se(digest_check(&d
, "97e64bcabb64c1fa4b726528644926c8029f5b4458b0575c98c04fe225629a0b"));
939 digest_init(&d
, "0000000000000000000000000000000000000000000000000000000000000000");
940 Tpm2PCRValue v2
[] = {
941 TPM2_PCR_VALUE_MAKE( 0, TPM2_ALG_SHA256
, dN
[ 0]),
942 TPM2_PCR_VALUE_MAKE( 1, TPM2_ALG_SHA256
, dN
[ 1]),
943 TPM2_PCR_VALUE_MAKE( 2, TPM2_ALG_SHA256
, dN
[ 2]),
944 TPM2_PCR_VALUE_MAKE( 3, TPM2_ALG_SHA256
, dN
[ 3]),
945 TPM2_PCR_VALUE_MAKE( 4, TPM2_ALG_SHA256
, dN
[ 4]),
946 TPM2_PCR_VALUE_MAKE( 5, TPM2_ALG_SHA256
, dN
[ 5]),
947 TPM2_PCR_VALUE_MAKE( 6, TPM2_ALG_SHA256
, dN
[ 6]),
948 TPM2_PCR_VALUE_MAKE( 7, TPM2_ALG_SHA256
, dN
[ 7]),
949 TPM2_PCR_VALUE_MAKE( 8, TPM2_ALG_SHA256
, dN
[ 8]),
950 TPM2_PCR_VALUE_MAKE( 9, TPM2_ALG_SHA256
, dN
[ 9]),
951 TPM2_PCR_VALUE_MAKE(10, TPM2_ALG_SHA256
, dN
[10]),
952 TPM2_PCR_VALUE_MAKE(11, TPM2_ALG_SHA256
, dN
[11]),
953 TPM2_PCR_VALUE_MAKE(12, TPM2_ALG_SHA256
, dN
[12]),
954 TPM2_PCR_VALUE_MAKE(13, TPM2_ALG_SHA256
, dN
[13]),
955 TPM2_PCR_VALUE_MAKE(14, TPM2_ALG_SHA256
, dN
[14]),
956 TPM2_PCR_VALUE_MAKE(15, TPM2_ALG_SHA256
, dN
[15]),
958 assert_se(tpm2_calculate_policy_pcr(v2
, ELEMENTSOF(v2
), &d
) == 0);
959 assert_se(digest_check(&d
, "22be4f1674f792d6345cea9427701068f0e8d9f42755dcc0e927e545a68f9c13"));
960 assert_se(tpm2_calculate_policy_pcr(v2
, ELEMENTSOF(v2
), &d
) == 0);
961 assert_se(digest_check(&d
, "7481fd1b116078eb3ac2456e4ad542c9b46b9b8eb891335771ca8e7c8f8e4415"));
964 static void check_srk_rsa_template(TPMT_PUBLIC
*template) {
965 assert_se(template->type
== TPM2_ALG_RSA
);
966 assert_se(template->nameAlg
== TPM2_ALG_SHA256
);
967 assert_se(template->objectAttributes
== 0x30472);
968 assert_se(template->parameters
.rsaDetail
.symmetric
.algorithm
== TPM2_ALG_AES
);
969 assert_se(template->parameters
.rsaDetail
.symmetric
.keyBits
.sym
== 128);
970 assert_se(template->parameters
.rsaDetail
.symmetric
.mode
.sym
== TPM2_ALG_CFB
);
971 assert_se(template->parameters
.rsaDetail
.scheme
.scheme
== TPM2_ALG_NULL
);
972 assert_se(template->parameters
.rsaDetail
.keyBits
== 2048);
975 static void check_srk_ecc_template(TPMT_PUBLIC
*template) {
976 assert_se(template->type
== TPM2_ALG_ECC
);
977 assert_se(template->nameAlg
== TPM2_ALG_SHA256
);
978 assert_se(template->objectAttributes
== 0x30472);
979 assert_se(template->parameters
.eccDetail
.symmetric
.algorithm
== TPM2_ALG_AES
);
980 assert_se(template->parameters
.eccDetail
.symmetric
.keyBits
.sym
== 128);
981 assert_se(template->parameters
.eccDetail
.symmetric
.mode
.sym
== TPM2_ALG_CFB
);
982 assert_se(template->parameters
.eccDetail
.scheme
.scheme
== TPM2_ALG_NULL
);
983 assert_se(template->parameters
.eccDetail
.kdf
.scheme
== TPM2_ALG_NULL
);
984 assert_se(template->parameters
.eccDetail
.curveID
== TPM2_ECC_NIST_P256
);
987 TEST(tpm2_get_srk_template
) {
988 TPMT_PUBLIC
template;
990 assert_se(tpm2_get_srk_template(TPM2_ALG_RSA
, &template) >= 0);
991 check_srk_rsa_template(&template);
993 assert_se(tpm2_get_srk_template(TPM2_ALG_ECC
, &template) >= 0);
994 check_srk_ecc_template(&template);
997 static void check_best_srk_template(Tpm2Context
*c
) {
998 TPMT_PUBLIC
template;
999 assert_se(tpm2_get_best_srk_template(c
, &template) >= 0);
1001 assert_se(IN_SET(template.type
, TPM2_ALG_ECC
, TPM2_ALG_RSA
));
1003 if (template.type
== TPM2_ALG_RSA
)
1004 check_srk_rsa_template(&template);
1006 check_srk_ecc_template(&template);
1009 static void check_test_parms(Tpm2Context
*c
) {
1012 TPMU_PUBLIC_PARMS parms
= {
1014 .algorithm
= TPM2_ALG_AES
,
1016 .mode
.aes
= TPM2_ALG_CFB
,
1020 /* Test with invalid parms */
1021 assert_se(!tpm2_test_parms(c
, TPM2_ALG_CFB
, &parms
));
1023 TPMU_PUBLIC_PARMS invalid_parms
= parms
;
1024 invalid_parms
.symDetail
.sym
.keyBits
.aes
= 1;
1025 assert_se(!tpm2_test_parms(c
, TPM2_ALG_SYMCIPHER
, &invalid_parms
));
1027 /* Test with valid parms */
1028 assert_se(tpm2_test_parms(c
, TPM2_ALG_SYMCIPHER
, &parms
));
1031 static void check_supports_alg(Tpm2Context
*c
) {
1034 /* Test invalid algs */
1035 assert_se(!tpm2_supports_alg(c
, TPM2_ALG_ERROR
));
1036 assert_se(!tpm2_supports_alg(c
, TPM2_ALG_LAST
+ 1));
1038 /* Test valid algs */
1039 assert_se(tpm2_supports_alg(c
, TPM2_ALG_RSA
));
1040 assert_se(tpm2_supports_alg(c
, TPM2_ALG_AES
));
1041 assert_se(tpm2_supports_alg(c
, TPM2_ALG_CFB
));
1044 static void check_supports_command(Tpm2Context
*c
) {
1047 /* Test invalid commands. TPM specification Part 2 ("Structures") section "TPM_CC (Command Codes)"
1048 * states bits 31:30 and 28:16 are reserved and must be 0. */
1049 assert_se(!tpm2_supports_command(c
, UINT32_C(0x80000000)));
1050 assert_se(!tpm2_supports_command(c
, UINT32_C(0x40000000)));
1051 assert_se(!tpm2_supports_command(c
, UINT32_C(0x00100000)));
1052 assert_se(!tpm2_supports_command(c
, UINT32_C(0x80000144)));
1053 assert_se(!tpm2_supports_command(c
, UINT32_C(0x40000144)));
1054 assert_se(!tpm2_supports_command(c
, UINT32_C(0x00100144)));
1056 /* Test valid commands. We should be able to expect all TPMs support these. */
1057 assert_se(tpm2_supports_command(c
, TPM2_CC_Startup
));
1058 assert_se(tpm2_supports_command(c
, TPM2_CC_StartAuthSession
));
1059 assert_se(tpm2_supports_command(c
, TPM2_CC_Create
));
1060 assert_se(tpm2_supports_command(c
, TPM2_CC_CreatePrimary
));
1061 assert_se(tpm2_supports_command(c
, TPM2_CC_Unseal
));
1064 static void check_get_or_create_srk(Tpm2Context
*c
) {
1065 _cleanup_free_ TPM2B_PUBLIC
*public = NULL
;
1066 _cleanup_free_ TPM2B_NAME
*name
= NULL
, *qname
= NULL
;
1067 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*handle
= NULL
;
1068 assert_se(tpm2_get_or_create_srk(c
, NULL
, &public, &name
, &qname
, &handle
) >= 0);
1069 assert_se(public && name
&& qname
&& handle
);
1071 _cleanup_free_ TPM2B_PUBLIC
*public2
= NULL
;
1072 _cleanup_free_ TPM2B_NAME
*name2
= NULL
, *qname2
= NULL
;
1073 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*handle2
= NULL
;
1074 assert_se(tpm2_get_srk(c
, NULL
, &public2
, &name2
, &qname2
, &handle2
) >= 0);
1075 assert_se(public2
&& name2
&& qname2
&& handle2
);
1077 assert_se(memcmp_nn(public, sizeof(*public), public2
, sizeof(*public2
)) == 0);
1078 assert_se(memcmp_nn(name
->name
, name
->size
, name2
->name
, name2
->size
) == 0);
1079 assert_se(memcmp_nn(qname
->name
, qname
->size
, qname2
->name
, qname2
->size
) == 0);
1082 #if HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3
1083 static void calculate_seal_and_unseal(
1085 TPM2_HANDLE parent_index
,
1086 const TPM2B_PUBLIC
*parent_public
) {
1088 _cleanup_free_
char *secret_string
= NULL
;
1089 assert_se(asprintf(&secret_string
, "The classified documents are in room %x", parent_index
) > 0);
1090 size_t secret_size
= strlen(secret_string
) + 1;
1092 _cleanup_free_
void *blob
= NULL
;
1093 size_t blob_size
= 0;
1094 _cleanup_free_
void *serialized_parent
= NULL
;
1095 size_t serialized_parent_size
;
1096 assert_se(tpm2_calculate_seal(
1099 /* attributes= */ NULL
,
1100 secret_string
, secret_size
,
1103 /* ret_secret= */ NULL
, /* ret_secret_size= */ 0,
1105 &serialized_parent
, &serialized_parent_size
) >= 0);
1107 _cleanup_free_
void *unsealed_secret
= NULL
;
1108 size_t unsealed_secret_size
;
1109 assert_se(tpm2_unseal(
1111 /* hash_pcr_mask= */ 0,
1113 /* pubkey= */ NULL
, /* pubkey_size= */ 0,
1114 /* pubkey_pcr_mask= */ 0,
1115 /* signature= */ NULL
,
1117 /* pcrlock_policy= */ NULL
,
1118 /* primary_alg= */ 0,
1120 /* known_policy_hash= */ NULL
, /* known_policy_hash_size= */ 0,
1121 serialized_parent
, serialized_parent_size
,
1122 &unsealed_secret
, &unsealed_secret_size
) >= 0);
1124 assert_se(memcmp_nn(secret_string
, secret_size
, unsealed_secret
, unsealed_secret_size
) == 0);
1126 char unsealed_string
[unsealed_secret_size
];
1127 assert_se(snprintf(unsealed_string
, unsealed_secret_size
, "%s", (char*) unsealed_secret
) == (int) unsealed_secret_size
- 1);
1128 log_debug("Unsealed secret is: %s", unsealed_string
);
1131 static int check_calculate_seal(Tpm2Context
*c
) {
1135 _cleanup_free_ TPM2B_PUBLIC
*srk_public
= NULL
;
1136 assert_se(tpm2_get_srk(c
, NULL
, &srk_public
, NULL
, NULL
, NULL
) >= 0);
1137 calculate_seal_and_unseal(c
, TPM2_SRK_HANDLE
, srk_public
);
1139 TPMI_ALG_ASYM test_algs
[] = { TPM2_ALG_RSA
, TPM2_ALG_ECC
, };
1140 for (unsigned i
= 0; i
< ELEMENTSOF(test_algs
); i
++) {
1141 TPMI_ALG_ASYM alg
= test_algs
[i
];
1143 TPM2B_PUBLIC
template = { .size
= sizeof(TPMT_PUBLIC
), };
1144 assert_se(tpm2_get_srk_template(alg
, &template.publicArea
) >= 0);
1146 _cleanup_free_ TPM2B_PUBLIC
*public = NULL
;
1147 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*handle
= NULL
;
1148 assert_se(tpm2_create_primary(c
, NULL
, &template, NULL
, &public, &handle
) >= 0);
1150 /* Once our minimum libtss2-esys version is 2.4.0 or later, this can assume
1151 * tpm2_index_from_handle() should always work. */
1153 r
= tpm2_index_from_handle(c
, handle
, &index
);
1154 if (r
== -EOPNOTSUPP
)
1155 return log_tests_skipped("libtss2-esys version too old to support tpm2_index_from_handle()");
1158 calculate_seal_and_unseal(c
, index
, public);
1163 #endif /* HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3 */
1165 static void check_seal_unseal_for_handle(Tpm2Context
*c
, TPM2_HANDLE handle
) {
1166 TPM2B_DIGEST policy
= TPM2B_DIGEST_MAKE(NULL
, TPM2_SHA256_DIGEST_SIZE
);
1170 log_debug("Check seal/unseal for handle 0x%" PRIx32
, handle
);
1172 _cleanup_free_
void *secret
= NULL
, *blob
= NULL
, *srk
= NULL
, *unsealed_secret
= NULL
;
1173 size_t secret_size
, blob_size
, srk_size
, unsealed_secret_size
;
1174 assert_se(tpm2_seal(
1179 &secret
, &secret_size
,
1181 /* ret_primary_alg= */ NULL
,
1182 &srk
, &srk_size
) >= 0);
1184 assert_se(tpm2_unseal(
1186 /* hash_pcr_mask= */ 0,
1188 /* pubkey= */ NULL
, /* pubkey_size= */ 0,
1189 /* pubkey_pcr_mask= */ 0,
1190 /* signature= */ NULL
,
1192 /* pcrlock_policy= */ NULL
,
1193 /* primary_alg= */ 0,
1195 /* policy_hash= */ NULL
, /* policy_hash_size= */ 0,
1197 &unsealed_secret
, &unsealed_secret_size
) >= 0);
1199 assert_se(memcmp_nn(secret
, secret_size
, unsealed_secret
, unsealed_secret_size
) == 0);
1202 static void check_seal_unseal(Tpm2Context
*c
) {
1207 check_seal_unseal_for_handle(c
, 0);
1208 check_seal_unseal_for_handle(c
, TPM2_SRK_HANDLE
);
1210 FOREACH_ARRAY(template, test_templates
, ELEMENTSOF(test_templates
)) {
1211 TPM2B_PUBLIC
public = {
1212 .publicArea
= **template,
1213 .size
= sizeof(**template),
1215 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*transient_handle
= NULL
;
1216 assert_se(tpm2_create_primary(
1218 /* session= */ NULL
,
1220 /* sensitive= */ NULL
,
1221 /* ret_public= */ NULL
,
1222 &transient_handle
) >= 0);
1224 TPMI_DH_PERSISTENT transient_handle_index
;
1225 r
= tpm2_index_from_handle(c
, transient_handle
, &transient_handle_index
);
1226 if (r
== -EOPNOTSUPP
) {
1227 /* libesys too old */
1228 log_tests_skipped("libesys too old for tpm2_index_from_handle");
1233 check_seal_unseal_for_handle(c
, transient_handle_index
);
1237 TEST_RET(tests_which_require_tpm
) {
1238 _cleanup_(tpm2_context_unrefp
) Tpm2Context
*c
= NULL
;
1241 if (tpm2_context_new(NULL
, &c
) < 0)
1242 return log_tests_skipped("Could not find TPM");
1244 check_test_parms(c
);
1245 check_supports_alg(c
);
1246 check_supports_command(c
);
1247 check_best_srk_template(c
);
1248 check_get_or_create_srk(c
);
1249 check_seal_unseal(c
);
1251 #if HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3 /* calculating sealed object requires openssl >= 3 */
1252 r
= check_calculate_seal(c
);
1258 #endif /* HAVE_TPM2 */
1260 DEFINE_TEST_MAIN(LOG_DEBUG
);