]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/tpm2-util.c
tree-wide: use ASSERT_PTR more
[thirdparty/systemd.git] / src / shared / tpm2-util.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "alloc-util.h"
4 #include "cryptsetup-util.h"
5 #include "def.h"
6 #include "dirent-util.h"
7 #include "dlfcn-util.h"
8 #include "efi-api.h"
9 #include "extract-word.h"
10 #include "fd-util.h"
11 #include "fileio.h"
12 #include "format-table.h"
13 #include "fs-util.h"
14 #include "hexdecoct.h"
15 #include "memory-util.h"
16 #include "openssl-util.h"
17 #include "parse-util.h"
18 #include "random-util.h"
19 #include "sha256.h"
20 #include "stat-util.h"
21 #include "time-util.h"
22 #include "tpm2-util.h"
23 #include "virt.h"
24
25 #if HAVE_TPM2
26 static void *libtss2_esys_dl = NULL;
27 static void *libtss2_rc_dl = NULL;
28 static void *libtss2_mu_dl = NULL;
29
30 TSS2_RC (*sym_Esys_Create)(ESYS_CONTEXT *esysContext, ESYS_TR parentHandle, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPM2B_SENSITIVE_CREATE *inSensitive, const TPM2B_PUBLIC *inPublic, const TPM2B_DATA *outsideInfo, const TPML_PCR_SELECTION *creationPCR, TPM2B_PRIVATE **outPrivate, TPM2B_PUBLIC **outPublic, TPM2B_CREATION_DATA **creationData, TPM2B_DIGEST **creationHash, TPMT_TK_CREATION **creationTicket) = NULL;
31 TSS2_RC (*sym_Esys_CreatePrimary)(ESYS_CONTEXT *esysContext, ESYS_TR primaryHandle, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPM2B_SENSITIVE_CREATE *inSensitive, const TPM2B_PUBLIC *inPublic, const TPM2B_DATA *outsideInfo, const TPML_PCR_SELECTION *creationPCR, ESYS_TR *objectHandle, TPM2B_PUBLIC **outPublic, TPM2B_CREATION_DATA **creationData, TPM2B_DIGEST **creationHash, TPMT_TK_CREATION **creationTicket) = NULL;
32 void (*sym_Esys_Finalize)(ESYS_CONTEXT **context) = NULL;
33 TSS2_RC (*sym_Esys_FlushContext)(ESYS_CONTEXT *esysContext, ESYS_TR flushHandle) = NULL;
34 void (*sym_Esys_Free)(void *ptr) = NULL;
35 TSS2_RC (*sym_Esys_GetCapability)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, TPM2_CAP capability, UINT32 property, UINT32 propertyCount, TPMI_YES_NO *moreData, TPMS_CAPABILITY_DATA **capabilityData);
36 TSS2_RC (*sym_Esys_GetRandom)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, UINT16 bytesRequested, TPM2B_DIGEST **randomBytes) = NULL;
37 TSS2_RC (*sym_Esys_Initialize)(ESYS_CONTEXT **esys_context, TSS2_TCTI_CONTEXT *tcti, TSS2_ABI_VERSION *abiVersion) = NULL;
38 TSS2_RC (*sym_Esys_Load)(ESYS_CONTEXT *esysContext, ESYS_TR parentHandle, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPM2B_PRIVATE *inPrivate, const TPM2B_PUBLIC *inPublic, ESYS_TR *objectHandle) = NULL;
39 TSS2_RC (*sym_Esys_LoadExternal)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPM2B_SENSITIVE *inPrivate, const TPM2B_PUBLIC *inPublic, ESYS_TR hierarchy, ESYS_TR *objectHandle);
40 TSS2_RC (*sym_Esys_PCR_Read)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1,ESYS_TR shandle2, ESYS_TR shandle3, const TPML_PCR_SELECTION *pcrSelectionIn, UINT32 *pcrUpdateCounter, TPML_PCR_SELECTION **pcrSelectionOut, TPML_DIGEST **pcrValues);
41 TSS2_RC (*sym_Esys_PolicyAuthorize)(ESYS_CONTEXT *esysContext, ESYS_TR policySession, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPM2B_DIGEST *approvedPolicy, const TPM2B_NONCE *policyRef, const TPM2B_NAME *keySign, const TPMT_TK_VERIFIED *checkTicket);
42 TSS2_RC (*sym_Esys_PolicyAuthValue)(ESYS_CONTEXT *esysContext, ESYS_TR policySession, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3) = NULL;
43 TSS2_RC (*sym_Esys_PolicyGetDigest)(ESYS_CONTEXT *esysContext, ESYS_TR policySession, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, TPM2B_DIGEST **policyDigest) = NULL;
44 TSS2_RC (*sym_Esys_PolicyPCR)(ESYS_CONTEXT *esysContext, ESYS_TR policySession, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPM2B_DIGEST *pcrDigest, const TPML_PCR_SELECTION *pcrs) = NULL;
45 TSS2_RC (*sym_Esys_StartAuthSession)(ESYS_CONTEXT *esysContext, ESYS_TR tpmKey, ESYS_TR bind, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPM2B_NONCE *nonceCaller, TPM2_SE sessionType, const TPMT_SYM_DEF *symmetric, TPMI_ALG_HASH authHash, ESYS_TR *sessionHandle) = NULL;
46 TSS2_RC (*sym_Esys_Startup)(ESYS_CONTEXT *esysContext, TPM2_SU startupType) = NULL;
47 TSS2_RC (*sym_Esys_TRSess_SetAttributes)(ESYS_CONTEXT *esysContext, ESYS_TR session, TPMA_SESSION flags, TPMA_SESSION mask);
48 TSS2_RC (*sym_Esys_TR_GetName)(ESYS_CONTEXT *esysContext, ESYS_TR handle, TPM2B_NAME **name);
49 TSS2_RC (*sym_Esys_TR_SetAuth)(ESYS_CONTEXT *esysContext, ESYS_TR handle, TPM2B_AUTH const *authValue) = NULL;
50 TSS2_RC (*sym_Esys_Unseal)(ESYS_CONTEXT *esysContext, ESYS_TR itemHandle, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, TPM2B_SENSITIVE_DATA **outData) = NULL;
51 TSS2_RC (*sym_Esys_VerifySignature)(ESYS_CONTEXT *esysContext, ESYS_TR keyHandle, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPM2B_DIGEST *digest, const TPMT_SIGNATURE *signature, TPMT_TK_VERIFIED **validation);
52
53 const char* (*sym_Tss2_RC_Decode)(TSS2_RC rc) = NULL;
54
55 TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Marshal)(TPM2B_PRIVATE const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL;
56 TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PRIVATE *dest) = NULL;
57 TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Marshal)(TPM2B_PUBLIC const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL;
58 TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PUBLIC *dest) = NULL;
59
60 int dlopen_tpm2(void) {
61 int r;
62
63 r = dlopen_many_sym_or_warn(
64 &libtss2_esys_dl, "libtss2-esys.so.0", LOG_DEBUG,
65 DLSYM_ARG(Esys_Create),
66 DLSYM_ARG(Esys_CreatePrimary),
67 DLSYM_ARG(Esys_Finalize),
68 DLSYM_ARG(Esys_FlushContext),
69 DLSYM_ARG(Esys_Free),
70 DLSYM_ARG(Esys_GetCapability),
71 DLSYM_ARG(Esys_GetRandom),
72 DLSYM_ARG(Esys_Initialize),
73 DLSYM_ARG(Esys_Load),
74 DLSYM_ARG(Esys_LoadExternal),
75 DLSYM_ARG(Esys_PCR_Read),
76 DLSYM_ARG(Esys_PolicyAuthorize),
77 DLSYM_ARG(Esys_PolicyAuthValue),
78 DLSYM_ARG(Esys_PolicyGetDigest),
79 DLSYM_ARG(Esys_PolicyPCR),
80 DLSYM_ARG(Esys_StartAuthSession),
81 DLSYM_ARG(Esys_Startup),
82 DLSYM_ARG(Esys_TRSess_SetAttributes),
83 DLSYM_ARG(Esys_TR_GetName),
84 DLSYM_ARG(Esys_TR_SetAuth),
85 DLSYM_ARG(Esys_Unseal),
86 DLSYM_ARG(Esys_VerifySignature));
87 if (r < 0)
88 return r;
89
90 r = dlopen_many_sym_or_warn(
91 &libtss2_rc_dl, "libtss2-rc.so.0", LOG_DEBUG,
92 DLSYM_ARG(Tss2_RC_Decode));
93 if (r < 0)
94 return r;
95
96 return dlopen_many_sym_or_warn(
97 &libtss2_mu_dl, "libtss2-mu.so.0", LOG_DEBUG,
98 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Marshal),
99 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Unmarshal),
100 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Marshal),
101 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Unmarshal));
102 }
103
104 void tpm2_context_destroy(struct tpm2_context *c) {
105 assert(c);
106
107 if (c->esys_context)
108 sym_Esys_Finalize(&c->esys_context);
109
110 c->tcti_context = mfree(c->tcti_context);
111
112 if (c->tcti_dl) {
113 dlclose(c->tcti_dl);
114 c->tcti_dl = NULL;
115 }
116 }
117
118 static inline void Esys_Finalize_wrapper(ESYS_CONTEXT **c) {
119 /* A wrapper around Esys_Finalize() for use with _cleanup_(). Only reasons we need this wrapper is
120 * because the function itself warn logs if we'd pass a pointer to NULL, and we don't want that. */
121 if (*c)
122 sym_Esys_Finalize(c);
123 }
124
125 ESYS_TR tpm2_flush_context_verbose(ESYS_CONTEXT *c, ESYS_TR handle) {
126 TSS2_RC rc;
127
128 if (!c || handle == ESYS_TR_NONE)
129 return ESYS_TR_NONE;
130
131 rc = sym_Esys_FlushContext(c, handle);
132 if (rc != TSS2_RC_SUCCESS) /* We ignore failures here (besides debug logging), since this is called
133 * in error paths, where we cannot do anything about failures anymore. And
134 * when it is called in successful codepaths by this time we already did
135 * what we wanted to do, and got the results we wanted so there's no
136 * reason to make this fail more loudly than necessary. */
137 log_debug("Failed to get flush context of TPM, ignoring: %s", sym_Tss2_RC_Decode(rc));
138
139 return ESYS_TR_NONE;
140 }
141
142 int tpm2_context_init(const char *device, struct tpm2_context *ret) {
143 _cleanup_(Esys_Finalize_wrapper) ESYS_CONTEXT *c = NULL;
144 _cleanup_free_ TSS2_TCTI_CONTEXT *tcti = NULL;
145 _cleanup_(dlclosep) void *dl = NULL;
146 TSS2_RC rc;
147 int r;
148
149 r = dlopen_tpm2();
150 if (r < 0)
151 return log_error_errno(r, "TPM2 support not installed: %m");
152
153 if (!device)
154 device = secure_getenv("SYSTEMD_TPM2_DEVICE");
155
156 if (device) {
157 const char *param, *driver, *fn;
158 const TSS2_TCTI_INFO* info;
159 TSS2_TCTI_INFO_FUNC func;
160 size_t sz = 0;
161
162 param = strchr(device, ':');
163 if (param) {
164 driver = strndupa_safe(device, param - device);
165 param++;
166 } else {
167 driver = "device";
168 param = device;
169 }
170
171 fn = strjoina("libtss2-tcti-", driver, ".so.0");
172
173 dl = dlopen(fn, RTLD_NOW);
174 if (!dl)
175 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to load %s: %s", fn, dlerror());
176
177 func = dlsym(dl, TSS2_TCTI_INFO_SYMBOL);
178 if (!func)
179 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
180 "Failed to find TCTI info symbol " TSS2_TCTI_INFO_SYMBOL ": %s",
181 dlerror());
182
183 info = func();
184 if (!info)
185 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to get TCTI info data.");
186
187
188 log_debug("Loaded TCTI module '%s' (%s) [Version %" PRIu32 "]", info->name, info->description, info->version);
189
190 rc = info->init(NULL, &sz, NULL);
191 if (rc != TPM2_RC_SUCCESS)
192 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
193 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));
194
195 tcti = malloc0(sz);
196 if (!tcti)
197 return log_oom();
198
199 rc = info->init(tcti, &sz, param);
200 if (rc != TPM2_RC_SUCCESS)
201 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
202 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));
203 }
204
205 rc = sym_Esys_Initialize(&c, tcti, NULL);
206 if (rc != TSS2_RC_SUCCESS)
207 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
208 "Failed to initialize TPM context: %s", sym_Tss2_RC_Decode(rc));
209
210 rc = sym_Esys_Startup(c, TPM2_SU_CLEAR);
211 if (rc == TPM2_RC_INITIALIZE)
212 log_debug("TPM already started up.");
213 else if (rc == TSS2_RC_SUCCESS)
214 log_debug("TPM successfully started up.");
215 else
216 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
217 "Failed to start up TPM: %s", sym_Tss2_RC_Decode(rc));
218
219 *ret = (struct tpm2_context) {
220 .esys_context = TAKE_PTR(c),
221 .tcti_context = TAKE_PTR(tcti),
222 .tcti_dl = TAKE_PTR(dl),
223 };
224
225 return 0;
226 }
227
228 #define TPM2_CREDIT_RANDOM_FLAG_PATH "/run/systemd/tpm-rng-credited"
229
230 static int tpm2_credit_random(ESYS_CONTEXT *c) {
231 size_t rps, done = 0;
232 TSS2_RC rc;
233 usec_t t;
234 int r;
235
236 assert(c);
237
238 /* Pulls some entropy from the TPM and adds it into the kernel RNG pool. That way we can say that the
239 * key we will ultimately generate with the kernel random pool is at least as good as the TPM's RNG,
240 * but likely better. Note that we don't trust the TPM RNG very much, hence do not actually credit
241 * any entropy. */
242
243 if (access(TPM2_CREDIT_RANDOM_FLAG_PATH, F_OK) < 0) {
244 if (errno != ENOENT)
245 log_debug_errno(errno, "Failed to detect if '" TPM2_CREDIT_RANDOM_FLAG_PATH "' exists, ignoring: %m");
246 } else {
247 log_debug("Not adding TPM2 entropy to the kernel random pool again.");
248 return 0; /* Already done */
249 }
250
251 t = now(CLOCK_MONOTONIC);
252
253 for (rps = random_pool_size(); rps > 0;) {
254 _cleanup_(Esys_Freep) TPM2B_DIGEST *buffer = NULL;
255
256 rc = sym_Esys_GetRandom(
257 c,
258 ESYS_TR_NONE,
259 ESYS_TR_NONE,
260 ESYS_TR_NONE,
261 MIN(rps, 32U), /* 32 is supposedly a safe choice, given that AES 256bit keys are this long, and TPM2 baseline requires support for those. */
262 &buffer);
263 if (rc != TSS2_RC_SUCCESS)
264 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
265 "Failed to acquire entropy from TPM: %s", sym_Tss2_RC_Decode(rc));
266
267 if (buffer->size == 0)
268 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
269 "Zero-sized entropy returned from TPM.");
270
271 r = random_write_entropy(-1, buffer->buffer, buffer->size, /* credit= */ false);
272 if (r < 0)
273 return log_error_errno(r, "Failed wo write entropy to kernel: %m");
274
275 done += buffer->size;
276 rps = LESS_BY(rps, buffer->size);
277 }
278
279 log_debug("Added %zu bytes of TPM2 entropy to the kernel random pool in %s.", done, FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - t, 0));
280
281 r = touch(TPM2_CREDIT_RANDOM_FLAG_PATH);
282 if (r < 0)
283 log_debug_errno(r, "Failed to touch '" TPM2_CREDIT_RANDOM_FLAG_PATH "', ignoring: %m");
284
285 return 0;
286 }
287
288 static int tpm2_make_primary(
289 ESYS_CONTEXT *c,
290 ESYS_TR *ret_primary,
291 TPMI_ALG_PUBLIC alg,
292 TPMI_ALG_PUBLIC *ret_alg) {
293
294 static const TPM2B_SENSITIVE_CREATE primary_sensitive = {};
295 static const TPM2B_PUBLIC primary_template_ecc = {
296 .size = sizeof(TPMT_PUBLIC),
297 .publicArea = {
298 .type = TPM2_ALG_ECC,
299 .nameAlg = TPM2_ALG_SHA256,
300 .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH,
301 .parameters.eccDetail = {
302 .symmetric = {
303 .algorithm = TPM2_ALG_AES,
304 .keyBits.aes = 128,
305 .mode.aes = TPM2_ALG_CFB,
306 },
307 .scheme.scheme = TPM2_ALG_NULL,
308 .curveID = TPM2_ECC_NIST_P256,
309 .kdf.scheme = TPM2_ALG_NULL,
310 },
311 },
312 };
313 static const TPM2B_PUBLIC primary_template_rsa = {
314 .size = sizeof(TPMT_PUBLIC),
315 .publicArea = {
316 .type = TPM2_ALG_RSA,
317 .nameAlg = TPM2_ALG_SHA256,
318 .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH,
319 .parameters.rsaDetail = {
320 .symmetric = {
321 .algorithm = TPM2_ALG_AES,
322 .keyBits.aes = 128,
323 .mode.aes = TPM2_ALG_CFB,
324 },
325 .scheme.scheme = TPM2_ALG_NULL,
326 .keyBits = 2048,
327 },
328 },
329 };
330
331 static const TPML_PCR_SELECTION creation_pcr = {};
332 ESYS_TR primary = ESYS_TR_NONE;
333 TSS2_RC rc;
334 usec_t ts;
335
336 log_debug("Creating primary key on TPM.");
337
338 /* So apparently not all TPM2 devices support ECC. ECC is generally preferably, because it's so much
339 * faster, noticeably so (~10s vs. ~240ms on my system). Hence, unless explicitly configured let's
340 * try to use ECC first, and if that does not work, let's fall back to RSA. */
341
342 ts = now(CLOCK_MONOTONIC);
343
344 if (IN_SET(alg, 0, TPM2_ALG_ECC)) {
345 rc = sym_Esys_CreatePrimary(
346 c,
347 ESYS_TR_RH_OWNER,
348 ESYS_TR_PASSWORD,
349 ESYS_TR_NONE,
350 ESYS_TR_NONE,
351 &primary_sensitive,
352 &primary_template_ecc,
353 NULL,
354 &creation_pcr,
355 &primary,
356 NULL,
357 NULL,
358 NULL,
359 NULL);
360
361 if (rc != TSS2_RC_SUCCESS) {
362 if (alg != 0)
363 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
364 "Failed to generate ECC primary key in TPM: %s", sym_Tss2_RC_Decode(rc));
365
366 log_debug("Failed to generate ECC primary key in TPM, trying RSA: %s", sym_Tss2_RC_Decode(rc));
367 } else {
368 log_debug("Successfully created ECC primary key on TPM.");
369 alg = TPM2_ALG_ECC;
370 }
371 }
372
373 if (IN_SET(alg, 0, TPM2_ALG_RSA)) {
374 rc = sym_Esys_CreatePrimary(
375 c,
376 ESYS_TR_RH_OWNER,
377 ESYS_TR_PASSWORD,
378 ESYS_TR_NONE,
379 ESYS_TR_NONE,
380 &primary_sensitive,
381 &primary_template_rsa,
382 NULL,
383 &creation_pcr,
384 &primary,
385 NULL,
386 NULL,
387 NULL,
388 NULL);
389 if (rc != TSS2_RC_SUCCESS)
390 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
391 "Failed to generate RSA primary key in TPM: %s", sym_Tss2_RC_Decode(rc));
392 else if (alg == 0) {
393 log_notice("TPM2 chip apparently does not support ECC primary keys, falling back to RSA. "
394 "This likely means TPM2 operations will be relatively slow, please be patient.");
395 alg = TPM2_ALG_RSA;
396 }
397
398 log_debug("Successfully created RSA primary key on TPM.");
399 }
400
401 log_debug("Generating primary key on TPM2 took %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - ts, USEC_PER_MSEC));
402
403 *ret_primary = primary;
404 if (ret_alg)
405 *ret_alg = alg;
406
407 return 0;
408 }
409
410 void tpm2_pcr_mask_to_selection(uint32_t mask, uint16_t bank, TPML_PCR_SELECTION *ret) {
411 assert(ret);
412
413 /* We only do 24bit here, as that's what PC TPMs are supposed to support */
414 assert(mask <= 0xFFFFFFU);
415
416 *ret = (TPML_PCR_SELECTION) {
417 .count = 1,
418 .pcrSelections[0] = {
419 .hash = bank,
420 .sizeofSelect = 3,
421 .pcrSelect[0] = mask & 0xFF,
422 .pcrSelect[1] = (mask >> 8) & 0xFF,
423 .pcrSelect[2] = (mask >> 16) & 0xFF,
424 }
425 };
426 }
427
428 static unsigned find_nth_bit(uint32_t mask, unsigned n) {
429 uint32_t bit = 1;
430
431 assert(n < 32);
432
433 /* Returns the bit index of the nth set bit, e.g. mask=0b101001, n=3 → 5 */
434
435 for (unsigned i = 0; i < sizeof(mask)*8; i++) {
436
437 if (bit & mask) {
438 if (n == 0)
439 return i;
440
441 n--;
442 }
443
444 bit <<= 1;
445 }
446
447 return UINT_MAX;
448 }
449
450 static int tpm2_pcr_mask_good(
451 ESYS_CONTEXT *c,
452 TPMI_ALG_HASH bank,
453 uint32_t mask) {
454
455 _cleanup_(Esys_Freep) TPML_DIGEST *pcr_values = NULL;
456 TPML_PCR_SELECTION selection;
457 bool good = false;
458 TSS2_RC rc;
459
460 assert(c);
461
462 /* So we have the problem that some systems might have working TPM2 chips, but the firmware doesn't
463 * actually measure into them, or only into a suboptimal bank. If so, the PCRs should be all zero or
464 * all 0xFF. Detect that, so that we can warn and maybe pick a better bank. */
465
466 tpm2_pcr_mask_to_selection(mask, bank, &selection);
467
468 rc = sym_Esys_PCR_Read(
469 c,
470 ESYS_TR_NONE,
471 ESYS_TR_NONE,
472 ESYS_TR_NONE,
473 &selection,
474 NULL,
475 NULL,
476 &pcr_values);
477 if (rc != TSS2_RC_SUCCESS)
478 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
479 "Failed to read TPM2 PCRs: %s", sym_Tss2_RC_Decode(rc));
480
481 /* If at least one of the selected PCR values is something other than all 0x00 or all 0xFF we are happy. */
482 for (unsigned i = 0; i < pcr_values->count; i++) {
483 if (DEBUG_LOGGING) {
484 _cleanup_free_ char *h = NULL;
485 unsigned j;
486
487 h = hexmem(pcr_values->digests[i].buffer, pcr_values->digests[i].size);
488 j = find_nth_bit(mask, i);
489 assert(j != UINT_MAX);
490
491 log_debug("PCR %u value: %s", j, strna(h));
492 }
493
494 if (!memeqbyte(0x00, pcr_values->digests[i].buffer, pcr_values->digests[i].size) &&
495 !memeqbyte(0xFF, pcr_values->digests[i].buffer, pcr_values->digests[i].size))
496 good = true;
497 }
498
499 return good;
500 }
501
502 static int tpm2_get_best_pcr_bank(
503 ESYS_CONTEXT *c,
504 uint32_t pcr_mask,
505 TPMI_ALG_HASH *ret) {
506
507 _cleanup_(Esys_Freep) TPMS_CAPABILITY_DATA *pcap = NULL;
508 TPMI_ALG_HASH supported_hash = 0, hash_with_valid_pcr = 0;
509 TPMI_YES_NO more;
510 TSS2_RC rc;
511
512 assert(c);
513
514 rc = sym_Esys_GetCapability(
515 c,
516 ESYS_TR_NONE,
517 ESYS_TR_NONE,
518 ESYS_TR_NONE,
519 TPM2_CAP_PCRS,
520 0,
521 1,
522 &more,
523 &pcap);
524 if (rc != TSS2_RC_SUCCESS)
525 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
526 "Failed to determine TPM2 PCR bank capabilities: %s", sym_Tss2_RC_Decode(rc));
527
528 assert(pcap->capability == TPM2_CAP_PCRS);
529
530 for (size_t i = 0; i < pcap->data.assignedPCR.count; i++) {
531 bool valid = true;
532 int good;
533
534 /* For now we are only interested in the SHA1 and SHA256 banks */
535 if (!IN_SET(pcap->data.assignedPCR.pcrSelections[i].hash, TPM2_ALG_SHA256, TPM2_ALG_SHA1))
536 continue;
537
538 /* As per
539 * https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_PFP_r1p05_v23_pub.pdf a
540 * TPM2 on a Client PC must have at least 24 PCRs. If this TPM has less, just skip over
541 * it. */
542 if (pcap->data.assignedPCR.pcrSelections[i].sizeofSelect < TPM2_PCRS_MAX/8) {
543 log_debug("Skipping TPM2 PCR bank %s with fewer than 24 PCRs.",
544 strna(tpm2_pcr_bank_to_string(pcap->data.assignedPCR.pcrSelections[i].hash)));
545 continue;
546 }
547
548 assert_cc(TPM2_PCRS_MAX % 8 == 0);
549
550 /* It's not enough to check how many PCRs there are, we also need to check that the 24 are
551 * enabled for this bank. Otherwise this TPM doesn't qualify. */
552 for (size_t j = 0; j < TPM2_PCRS_MAX/8; j++)
553 if (pcap->data.assignedPCR.pcrSelections[i].pcrSelect[j] != 0xFF) {
554 valid = false;
555 break;
556 }
557
558 if (!valid) {
559 log_debug("TPM2 PCR bank %s has fewer than 24 PCR bits enabled, ignoring.",
560 strna(tpm2_pcr_bank_to_string(pcap->data.assignedPCR.pcrSelections[i].hash)));
561 continue;
562 }
563
564 good = tpm2_pcr_mask_good(c, pcap->data.assignedPCR.pcrSelections[i].hash, pcr_mask);
565 if (good < 0)
566 return good;
567
568 if (pcap->data.assignedPCR.pcrSelections[i].hash == TPM2_ALG_SHA256) {
569 supported_hash = TPM2_ALG_SHA256;
570 if (good) {
571 /* Great, SHA256 is supported and has initialized PCR values, we are done. */
572 hash_with_valid_pcr = TPM2_ALG_SHA256;
573 break;
574 }
575 } else {
576 assert(pcap->data.assignedPCR.pcrSelections[i].hash == TPM2_ALG_SHA1);
577
578 if (supported_hash == 0)
579 supported_hash = TPM2_ALG_SHA1;
580
581 if (good && hash_with_valid_pcr == 0)
582 hash_with_valid_pcr = TPM2_ALG_SHA1;
583 }
584 }
585
586 /* We preferably pick SHA256, but only if its PCRs are initialized or neither the SHA1 nor the SHA256
587 * PCRs are initialized. If SHA256 is not supported but SHA1 is and its PCRs are too, we prefer
588 * SHA1.
589 *
590 * We log at LOG_NOTICE level whenever we end up using the SHA1 bank or when the PCRs we bind to are
591 * not initialized. */
592
593 if (hash_with_valid_pcr == TPM2_ALG_SHA256) {
594 assert(supported_hash == TPM2_ALG_SHA256);
595 log_debug("TPM2 device supports SHA256 PCR bank and SHA256 PCRs are valid, yay!");
596 *ret = TPM2_ALG_SHA256;
597 } else if (hash_with_valid_pcr == TPM2_ALG_SHA1) {
598 if (supported_hash == TPM2_ALG_SHA256)
599 log_notice("TPM2 device supports both SHA1 and SHA256 PCR banks, but only SHA1 PCRs are valid, falling back to SHA1 bank. This reduces the security level substantially.");
600 else {
601 assert(supported_hash == TPM2_ALG_SHA1);
602 log_notice("TPM2 device lacks support for SHA256 PCR bank, but SHA1 bank is supported and SHA1 PCRs are valid, falling back to SHA1 bank. This reduces the security level substantially.");
603 }
604
605 *ret = TPM2_ALG_SHA1;
606 } else if (supported_hash == TPM2_ALG_SHA256) {
607 log_notice("TPM2 device supports SHA256 PCR bank but none of the selected PCRs are valid! Firmware apparently did not initialize any of the selected PCRs. Proceeding anyway with SHA256 bank. PCR policy effectively unenforced!");
608 *ret = TPM2_ALG_SHA256;
609 } else if (supported_hash == TPM2_ALG_SHA1) {
610 log_notice("TPM2 device lacks support for SHA256 bank, but SHA1 bank is supported, but none of the selected PCRs are valid! Firmware apparently did not initialize any of the selected PCRs. Proceeding anyway with SHA1 bank. PCR policy effectively unenforced!");
611 *ret = TPM2_ALG_SHA1;
612 } else
613 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
614 "TPM2 module supports neither SHA1 nor SHA256 PCR banks, cannot operate.");
615
616 return 0;
617 }
618
619 static void hash_pin(const char *pin, size_t len, TPM2B_AUTH *auth) {
620 struct sha256_ctx hash;
621
622 assert(auth);
623 assert(pin);
624 auth->size = SHA256_DIGEST_SIZE;
625
626 sha256_init_ctx(&hash);
627 sha256_process_bytes(pin, len, &hash);
628 sha256_finish_ctx(&hash, auth->buffer);
629
630 explicit_bzero_safe(&hash, sizeof(hash));
631 }
632
633 static int tpm2_make_encryption_session(
634 ESYS_CONTEXT *c,
635 ESYS_TR primary,
636 ESYS_TR bind_key,
637 const char *pin,
638 ESYS_TR *ret_session) {
639
640 static const TPMT_SYM_DEF symmetric = {
641 .algorithm = TPM2_ALG_AES,
642 .keyBits.aes = 128,
643 .mode.aes = TPM2_ALG_CFB,
644 };
645 const TPMA_SESSION sessionAttributes = TPMA_SESSION_DECRYPT | TPMA_SESSION_ENCRYPT |
646 TPMA_SESSION_CONTINUESESSION;
647 ESYS_TR session = ESYS_TR_NONE;
648 TSS2_RC rc;
649
650 assert(c);
651
652 /*
653 * if a pin is set for the seal object, use it to bind the session
654 * key to that object. This prevents active bus interposers from
655 * faking a TPM and seeing the unsealed value. An active interposer
656 * could fake a TPM, satisfying the encrypted session, and just
657 * forward everything to the *real* TPM.
658 */
659 if (pin) {
660 TPM2B_AUTH auth = {};
661
662 hash_pin(pin, strlen(pin), &auth);
663
664 rc = sym_Esys_TR_SetAuth(c, bind_key, &auth);
665 /* ESAPI knows about it, so clear it from our memory */
666 explicit_bzero_safe(&auth, sizeof(auth));
667 if (rc != TSS2_RC_SUCCESS)
668 return log_error_errno(
669 SYNTHETIC_ERRNO(ENOTRECOVERABLE),
670 "Failed to load PIN in TPM: %s",
671 sym_Tss2_RC_Decode(rc));
672 }
673
674 log_debug("Starting HMAC encryption session.");
675
676 /* Start a salted, unbound HMAC session with a well-known key (e.g. primary key) as tpmKey, which
677 * means that the random salt will be encrypted with the well-known key. That way, only the TPM can
678 * recover the salt, which is then used for key derivation. */
679 rc = sym_Esys_StartAuthSession(
680 c,
681 primary,
682 bind_key,
683 ESYS_TR_NONE,
684 ESYS_TR_NONE,
685 ESYS_TR_NONE,
686 NULL,
687 TPM2_SE_HMAC,
688 &symmetric,
689 TPM2_ALG_SHA256,
690 &session);
691 if (rc != TSS2_RC_SUCCESS)
692 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
693 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc));
694
695 /* Enable parameter encryption/decryption with AES in CFB mode. Together with HMAC digests (which are
696 * always used for sessions), this provides confidentiality, integrity and replay protection for
697 * operations that use this session. */
698 rc = sym_Esys_TRSess_SetAttributes(c, session, sessionAttributes, 0xff);
699 if (rc != TSS2_RC_SUCCESS)
700 return log_error_errno(
701 SYNTHETIC_ERRNO(ENOTRECOVERABLE),
702 "Failed to configure TPM session: %s",
703 sym_Tss2_RC_Decode(rc));
704
705 if (ret_session) {
706 *ret_session = session;
707 session = ESYS_TR_NONE;
708 }
709
710 session = tpm2_flush_context_verbose(c, session);
711 return 0;
712 }
713
714 static int openssl_pubkey_to_tpm2_pubkey(EVP_PKEY *input, TPM2B_PUBLIC *output) {
715 #if OPENSSL_VERSION_MAJOR >= 3
716 _cleanup_(BN_freep) BIGNUM *n = NULL, *e = NULL;
717 #else
718 const BIGNUM *n = NULL, *e = NULL;
719 const RSA *rsa = NULL;
720 #endif
721 int n_bytes, e_bytes;
722
723 assert(input);
724 assert(output);
725
726 /* Converts an OpenSSL public key to a structure that the TPM chip can process. */
727
728 if (EVP_PKEY_base_id(input) != EVP_PKEY_RSA)
729 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Provided public key is not an RSA key.");
730
731 #if OPENSSL_VERSION_MAJOR >= 3
732 if (!EVP_PKEY_get_bn_param(input, OSSL_PKEY_PARAM_RSA_N, &n))
733 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to get RSA modulus from public key.");
734 #else
735 rsa = EVP_PKEY_get0_RSA(input);
736 if (!rsa)
737 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to extract RSA key from public key.");
738
739 n = RSA_get0_n(rsa);
740 if (!n)
741 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to get RSA modulus from public key.");
742 #endif
743
744 n_bytes = BN_num_bytes(n);
745 assert_se(n_bytes > 0);
746 if ((size_t) n_bytes > sizeof_field(TPM2B_PUBLIC, publicArea.unique.rsa.buffer))
747 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "RSA modulus too large for TPM2 public key object.");
748
749 #if OPENSSL_VERSION_MAJOR >= 3
750 if (!EVP_PKEY_get_bn_param(input, OSSL_PKEY_PARAM_RSA_E, &e))
751 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to get RSA exponent from public key.");
752 #else
753 e = RSA_get0_e(rsa);
754 if (!e)
755 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to get RSA exponent from public key.");
756 #endif
757
758 e_bytes = BN_num_bytes(e);
759 assert_se(e_bytes > 0);
760 if ((size_t) e_bytes > sizeof_field(TPM2B_PUBLIC, publicArea.parameters.rsaDetail.exponent))
761 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "RSA exponent too large for TPM2 public key object.");
762
763 *output = (TPM2B_PUBLIC) {
764 .size = sizeof(TPMT_PUBLIC),
765 .publicArea = {
766 .type = TPM2_ALG_RSA,
767 .nameAlg = TPM2_ALG_SHA256,
768 .objectAttributes = TPMA_OBJECT_DECRYPT | TPMA_OBJECT_SIGN_ENCRYPT | TPMA_OBJECT_USERWITHAUTH,
769 .parameters.rsaDetail = {
770 .scheme = {
771 .scheme = TPM2_ALG_NULL,
772 .details.anySig.hashAlg = TPM2_ALG_NULL,
773 },
774 .symmetric = {
775 .algorithm = TPM2_ALG_NULL,
776 .mode.sym = TPM2_ALG_NULL,
777 },
778 .keyBits = n_bytes * 8,
779 /* .exponent will be filled in below. */
780 },
781 .unique = {
782 .rsa.size = n_bytes,
783 /* .rsa.buffer will be filled in below. */
784 },
785 },
786 };
787
788 if (BN_bn2bin(n, output->publicArea.unique.rsa.buffer) <= 0)
789 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to convert RSA modulus.");
790
791 if (BN_bn2bin(e, (unsigned char*) &output->publicArea.parameters.rsaDetail.exponent) <= 0)
792 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to convert RSA exponent.");
793
794 return 0;
795 }
796
797 static int find_signature(
798 JsonVariant *v,
799 uint16_t pcr_bank,
800 uint32_t pcr_mask,
801 EVP_PKEY *pk,
802 const void *policy,
803 size_t policy_size,
804 void *ret_signature,
805 size_t *ret_signature_size) {
806
807 _cleanup_free_ void *fp = NULL;
808 JsonVariant *b, *i;
809 size_t fp_size;
810 const char *k;
811 int r;
812
813 /* Searches for a signature blob in the specified JSON object. Search keys are PCR bank, PCR mask,
814 * public key, and policy digest. */
815
816 if (!json_variant_is_object(v))
817 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Signature is not a JSON object.");
818
819 k = tpm2_pcr_bank_to_string(pcr_bank);
820 if (!k)
821 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Don't know PCR bank %" PRIu16, pcr_bank);
822
823 /* First, find field by bank */
824 b = json_variant_by_key(v, k);
825 if (!b)
826 return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "Signature lacks data for PCR bank '%s'.", k);
827
828 if (!json_variant_is_array(b))
829 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Bank data is not a JSON array.");
830
831 /* Now iterate through all signatures known for this bank */
832 JSON_VARIANT_ARRAY_FOREACH(i, b) {
833 _cleanup_free_ void *fpj_data = NULL, *polj_data = NULL;
834 JsonVariant *maskj, *fpj, *sigj, *polj;
835 size_t fpj_size, polj_size;
836 uint32_t parsed_mask;
837
838 if (!json_variant_is_object(i))
839 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Bank data element is not a JSON object");
840
841 /* Check if the PCR mask matches our expectations */
842 maskj = json_variant_by_key(i, "pcrs");
843 if (!maskj)
844 continue;
845
846 r = tpm2_parse_pcr_json_array(maskj, &parsed_mask);
847 if (r < 0)
848 return log_error_errno(r, "Failed to parse JSON PCR mask");
849
850 if (parsed_mask != pcr_mask)
851 continue; /* Not for this PCR mask */
852
853 /* Then check if this is for the public key we operate with */
854 fpj = json_variant_by_key(i, "pkfp");
855 if (!fpj)
856 continue;
857
858 r = json_variant_unhex(fpj, &fpj_data, &fpj_size);
859 if (r < 0)
860 return log_error_errno(r, "Failed to decode fingerprint in JSON data: %m");
861
862 if (!fp) {
863 r = pubkey_fingerprint(pk, EVP_sha256(), &fp, &fp_size);
864 if (r < 0)
865 return log_error_errno(r, "Failed to calculate public key fingerprint: %m");
866 }
867
868 if (memcmp_nn(fp, fp_size, fpj_data, fpj_size) != 0)
869 continue; /* Not for this public key */
870
871 /* Finally, check if this is for the PCR policy we expect this to be */
872 polj = json_variant_by_key(i, "pol");
873 if (!polj)
874 continue;
875
876 r = json_variant_unhex(polj, &polj_data, &polj_size);
877 if (r < 0)
878 return log_error_errno(r, "Failed to decode policy hash JSON data: %m");
879
880 if (memcmp_nn(policy, policy_size, polj_data, polj_size) != 0)
881 continue;
882
883 /* This entry matches all our expectations, now return the signature included in it */
884 sigj = json_variant_by_key(i, "sig");
885 if (!sigj)
886 continue;
887
888 return json_variant_unbase64(sigj, ret_signature, ret_signature_size);
889 }
890
891 return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "Couldn't find signature for this PCR bank, PCR index and public key.");
892 }
893
894 static int tpm2_make_policy_session(
895 ESYS_CONTEXT *c,
896 ESYS_TR primary,
897 ESYS_TR parent_session,
898 TPM2_SE session_type,
899 uint32_t hash_pcr_mask,
900 uint16_t pcr_bank, /* If UINT16_MAX, pick best bank automatically, otherwise specify bank explicitly. */
901 const void *pubkey,
902 size_t pubkey_size,
903 uint32_t pubkey_pcr_mask,
904 JsonVariant *signature_json,
905 bool use_pin,
906 ESYS_TR *ret_session,
907 TPM2B_DIGEST **ret_policy_digest,
908 TPMI_ALG_HASH *ret_pcr_bank) {
909
910 static const TPMT_SYM_DEF symmetric = {
911 .algorithm = TPM2_ALG_AES,
912 .keyBits.aes = 128,
913 .mode.aes = TPM2_ALG_CFB,
914 };
915 _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
916 ESYS_TR session = ESYS_TR_NONE, pubkey_handle = ESYS_TR_NONE;
917 _cleanup_(EVP_PKEY_freep) EVP_PKEY *pk = NULL;
918 TSS2_RC rc;
919 int r;
920
921 assert(c);
922 assert(pubkey || pubkey_size == 0);
923 assert(pubkey_pcr_mask == 0 || pubkey_size > 0);
924
925 log_debug("Starting authentication session.");
926
927 /* So apparently some TPM implementations don't implement trial mode correctly. To avoid issues let's
928 * avoid it when it is easy to. At the moment we only really need trial mode for the signed PCR
929 * policies (since only then we need to shove PCR values into the policy that don't match current
930 * state anyway), hence if we have none of those we don't need to bother. Hence, let's patch in
931 * TPM2_SE_POLICY even if trial mode is requested unless a pubkey PCR mask is specified that is
932 * non-zero, i.e. signed PCR policy is requested.
933 *
934 * One day we should switch to calculating policy hashes client side when trial mode is requested, to
935 * avoid this mess. */
936 if (session_type == TPM2_SE_TRIAL && pubkey_pcr_mask == 0)
937 session_type = TPM2_SE_POLICY;
938
939 if ((hash_pcr_mask | pubkey_pcr_mask) != 0) {
940 /* We are told to configure a PCR policy of some form, let's determine/validate the PCR bank to use. */
941
942 if (pcr_bank != UINT16_MAX) {
943 r = tpm2_pcr_mask_good(c, pcr_bank, hash_pcr_mask|pubkey_pcr_mask);
944 if (r < 0)
945 return r;
946 if (r == 0)
947 log_warning("Selected TPM2 PCRs are not initialized on this system, most likely due to a firmware issue. PCR policy is effectively not enforced. Proceeding anyway.");
948 } else {
949 /* No bank configured, pick automatically. Some TPM2 devices only can do SHA1. If we
950 * detect that use that, but preferably use SHA256 */
951 r = tpm2_get_best_pcr_bank(c, hash_pcr_mask|pubkey_pcr_mask, &pcr_bank);
952 if (r < 0)
953 return r;
954 }
955 }
956
957 if (pubkey_size > 0) {
958 /* If a pubkey is specified, load it to validate it, even if the PCR mask for this is actually zero, and we are thus not going to use it. */
959 _cleanup_fclose_ FILE *f = fmemopen((void*) pubkey, pubkey_size, "r");
960 if (!f)
961 return log_oom();
962
963 pk = PEM_read_PUBKEY(f, NULL, NULL, NULL);
964 if (!pk)
965 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse PEM public key.");
966 }
967
968 rc = sym_Esys_StartAuthSession(
969 c,
970 primary,
971 ESYS_TR_NONE,
972 parent_session,
973 ESYS_TR_NONE,
974 ESYS_TR_NONE,
975 NULL,
976 session_type,
977 &symmetric,
978 TPM2_ALG_SHA256,
979 &session);
980 if (rc != TSS2_RC_SUCCESS)
981 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
982 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc));
983
984 if (pubkey_pcr_mask != 0) {
985 log_debug("Configuring public key based PCR policy.");
986
987 /* First: load public key into the TPM */
988 TPM2B_PUBLIC pubkey_tpm2;
989 r = openssl_pubkey_to_tpm2_pubkey(pk, &pubkey_tpm2);
990 if (r < 0)
991 goto finish;
992
993 rc = sym_Esys_LoadExternal(
994 c,
995 ESYS_TR_NONE,
996 ESYS_TR_NONE,
997 ESYS_TR_NONE,
998 NULL,
999 &pubkey_tpm2,
1000 TPM2_RH_OWNER,
1001 &pubkey_handle);
1002 if (rc != TSS2_RC_SUCCESS) {
1003 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1004 "Failed to load public key into TPM: %s", sym_Tss2_RC_Decode(rc));
1005 goto finish;
1006 }
1007
1008 /* Acquire the "name" of what we just loaded */
1009 _cleanup_(Esys_Freep) TPM2B_NAME *pubkey_name = NULL;
1010 rc = sym_Esys_TR_GetName(
1011 c,
1012 pubkey_handle,
1013 &pubkey_name);
1014 if (rc != TSS2_RC_SUCCESS) {
1015 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1016 "Failed to get name of public key from TPM: %s", sym_Tss2_RC_Decode(rc));
1017 goto finish;
1018 }
1019
1020 /* Put together the PCR policy we want to use */
1021 TPML_PCR_SELECTION pcr_selection;
1022 tpm2_pcr_mask_to_selection(pubkey_pcr_mask, pcr_bank, &pcr_selection);
1023 rc = sym_Esys_PolicyPCR(
1024 c,
1025 session,
1026 ESYS_TR_NONE,
1027 ESYS_TR_NONE,
1028 ESYS_TR_NONE,
1029 NULL,
1030 &pcr_selection);
1031 if (rc != TSS2_RC_SUCCESS) {
1032 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1033 "Failed to add PCR policy to TPM: %s", sym_Tss2_RC_Decode(rc));
1034 goto finish;
1035 }
1036
1037 /* Get the policy hash of the PCR policy */
1038 _cleanup_(Esys_Freep) TPM2B_DIGEST *approved_policy = NULL;
1039 rc = sym_Esys_PolicyGetDigest(
1040 c,
1041 session,
1042 ESYS_TR_NONE,
1043 ESYS_TR_NONE,
1044 ESYS_TR_NONE,
1045 &approved_policy);
1046 if (rc != TSS2_RC_SUCCESS) {
1047 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1048 "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc));
1049 goto finish;
1050 }
1051
1052 /* When we are unlocking and have a signature, let's pass it to the TPM */
1053 _cleanup_(Esys_Freep) TPMT_TK_VERIFIED *check_ticket_buffer = NULL;
1054 const TPMT_TK_VERIFIED *check_ticket;
1055 if (signature_json) {
1056 _cleanup_free_ void *signature_raw = NULL;
1057 size_t signature_size;
1058
1059 r = find_signature(
1060 signature_json,
1061 pcr_bank,
1062 pubkey_pcr_mask,
1063 pk,
1064 approved_policy->buffer,
1065 approved_policy->size,
1066 &signature_raw,
1067 &signature_size);
1068 if (r < 0)
1069 goto finish;
1070
1071 /* TPM2_VerifySignature() will only verify the RSA part of the RSA+SHA256 signature,
1072 * hence we need to do the SHA256 part outselves, first */
1073 TPM2B_DIGEST signature_hash = {
1074 .size = SHA256_DIGEST_SIZE,
1075 };
1076 assert(sizeof(signature_hash.buffer) >= SHA256_DIGEST_SIZE);
1077 sha256_direct(approved_policy->buffer, approved_policy->size, signature_hash.buffer);
1078
1079 TPMT_SIGNATURE policy_signature = {
1080 .sigAlg = TPM2_ALG_RSASSA,
1081 .signature.rsassa = {
1082 .hash = TPM2_ALG_SHA256,
1083 .sig.size = signature_size,
1084 },
1085 };
1086 if (signature_size > sizeof(policy_signature.signature.rsassa.sig.buffer)) {
1087 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Signature larger than buffer.");
1088 goto finish;
1089 }
1090 memcpy(policy_signature.signature.rsassa.sig.buffer, signature_raw, signature_size);
1091
1092 rc = sym_Esys_VerifySignature(
1093 c,
1094 pubkey_handle,
1095 ESYS_TR_NONE,
1096 ESYS_TR_NONE,
1097 ESYS_TR_NONE,
1098 &signature_hash,
1099 &policy_signature,
1100 &check_ticket_buffer);
1101 if (rc != TSS2_RC_SUCCESS) {
1102 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1103 "Failed to validate signature in TPM: %s", sym_Tss2_RC_Decode(rc));
1104 goto finish;
1105 }
1106
1107 check_ticket = check_ticket_buffer;
1108 } else {
1109 /* When enrolling, we pass a NULL ticket */
1110 static const TPMT_TK_VERIFIED check_ticket_null = {
1111 .tag = TPM2_ST_VERIFIED,
1112 .hierarchy = TPM2_RH_OWNER,
1113 };
1114
1115 check_ticket = &check_ticket_null;
1116 }
1117
1118 rc = sym_Esys_PolicyAuthorize(
1119 c,
1120 session,
1121 ESYS_TR_NONE,
1122 ESYS_TR_NONE,
1123 ESYS_TR_NONE,
1124 approved_policy,
1125 /* policyRef= */ &(const TPM2B_NONCE) {},
1126 pubkey_name,
1127 check_ticket);
1128 if (rc != TSS2_RC_SUCCESS) {
1129 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1130 "Failed to push Authorize policy into TPM: %s", sym_Tss2_RC_Decode(rc));
1131 goto finish;
1132 }
1133 }
1134
1135 if (hash_pcr_mask != 0) {
1136 log_debug("Configuring hash-based PCR policy.");
1137
1138 TPML_PCR_SELECTION pcr_selection;
1139 tpm2_pcr_mask_to_selection(hash_pcr_mask, pcr_bank, &pcr_selection);
1140 rc = sym_Esys_PolicyPCR(
1141 c,
1142 session,
1143 ESYS_TR_NONE,
1144 ESYS_TR_NONE,
1145 ESYS_TR_NONE,
1146 NULL,
1147 &pcr_selection);
1148 if (rc != TSS2_RC_SUCCESS) {
1149 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1150 "Failed to add PCR policy to TPM: %s", sym_Tss2_RC_Decode(rc));
1151 goto finish;
1152 }
1153 }
1154
1155 if (use_pin) {
1156 log_debug("Configuring PIN policy.");
1157
1158 rc = sym_Esys_PolicyAuthValue(
1159 c,
1160 session,
1161 ESYS_TR_NONE,
1162 ESYS_TR_NONE,
1163 ESYS_TR_NONE);
1164 if (rc != TSS2_RC_SUCCESS) {
1165 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1166 "Failed to add authValue policy to TPM: %s",
1167 sym_Tss2_RC_Decode(rc));
1168 goto finish;
1169 }
1170 }
1171
1172 if (DEBUG_LOGGING || ret_policy_digest) {
1173 log_debug("Acquiring policy digest.");
1174
1175 rc = sym_Esys_PolicyGetDigest(
1176 c,
1177 session,
1178 ESYS_TR_NONE,
1179 ESYS_TR_NONE,
1180 ESYS_TR_NONE,
1181 &policy_digest);
1182
1183 if (rc != TSS2_RC_SUCCESS) {
1184 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1185 "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc));
1186 goto finish;
1187 }
1188
1189 if (DEBUG_LOGGING) {
1190 _cleanup_free_ char *h = NULL;
1191
1192 h = hexmem(policy_digest->buffer, policy_digest->size);
1193 if (!h) {
1194 r = log_oom();
1195 goto finish;
1196 }
1197
1198 log_debug("Session policy digest: %s", h);
1199 }
1200 }
1201
1202 if (ret_session) {
1203 *ret_session = session;
1204 session = ESYS_TR_NONE;
1205 }
1206
1207 if (ret_policy_digest)
1208 *ret_policy_digest = TAKE_PTR(policy_digest);
1209
1210 if (ret_pcr_bank)
1211 *ret_pcr_bank = pcr_bank;
1212
1213 r = 0;
1214
1215 finish:
1216 session = tpm2_flush_context_verbose(c, session);
1217 pubkey_handle = tpm2_flush_context_verbose(c, pubkey_handle);
1218 return r;
1219 }
1220
1221 int tpm2_seal(const char *device,
1222 uint32_t hash_pcr_mask,
1223 const void *pubkey,
1224 const size_t pubkey_size,
1225 uint32_t pubkey_pcr_mask,
1226 const char *pin,
1227 void **ret_secret,
1228 size_t *ret_secret_size,
1229 void **ret_blob,
1230 size_t *ret_blob_size,
1231 void **ret_pcr_hash,
1232 size_t *ret_pcr_hash_size,
1233 uint16_t *ret_pcr_bank,
1234 uint16_t *ret_primary_alg) {
1235
1236 _cleanup_(tpm2_context_destroy) struct tpm2_context c = {};
1237 _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
1238 _cleanup_(Esys_Freep) TPM2B_PRIVATE *private = NULL;
1239 _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
1240 static const TPML_PCR_SELECTION creation_pcr = {};
1241 _cleanup_(erase_and_freep) void *secret = NULL;
1242 _cleanup_free_ void *blob = NULL, *hash = NULL;
1243 TPM2B_SENSITIVE_CREATE hmac_sensitive;
1244 ESYS_TR primary = ESYS_TR_NONE, session = ESYS_TR_NONE;
1245 TPMI_ALG_PUBLIC primary_alg;
1246 TPM2B_PUBLIC hmac_template;
1247 TPMI_ALG_HASH pcr_bank;
1248 size_t k, blob_size;
1249 usec_t start;
1250 TSS2_RC rc;
1251 int r;
1252
1253 assert(pubkey || pubkey_size == 0);
1254
1255 assert(ret_secret);
1256 assert(ret_secret_size);
1257 assert(ret_blob);
1258 assert(ret_blob_size);
1259 assert(ret_pcr_hash);
1260 assert(ret_pcr_hash_size);
1261 assert(ret_pcr_bank);
1262
1263 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask));
1264 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));
1265
1266 /* So here's what we do here: we connect to the TPM2 chip. It persistently contains a "seed" key that
1267 * is randomized when the TPM2 is first initialized or reset and remains stable across boots. We
1268 * generate a "primary" key pair derived from that (ECC if possible, RSA as fallback). Given the seed
1269 * remains fixed this will result in the same key pair whenever we specify the exact same parameters
1270 * for it. We then create a PCR-bound policy session, which calculates a hash on the current PCR
1271 * values of the indexes we specify. We then generate a randomized key on the host (which is the key
1272 * we actually enroll in the LUKS2 keyslots), which we upload into the TPM2, where it is encrypted
1273 * with the "primary" key, taking the PCR policy session into account. We then download the encrypted
1274 * key from the TPM2 ("sealing") and marshall it into binary form, which is ultimately placed in the
1275 * LUKS2 JSON header.
1276 *
1277 * The TPM2 "seed" key and "primary" keys never leave the TPM2 chip (and cannot be extracted at
1278 * all). The random key we enroll in LUKS2 we generate on the host using the Linux random device. It
1279 * is stored in the LUKS2 JSON only in encrypted form with the "primary" key of the TPM2 chip, thus
1280 * binding the unlocking to the TPM2 chip. */
1281
1282 start = now(CLOCK_MONOTONIC);
1283
1284 r = tpm2_context_init(device, &c);
1285 if (r < 0)
1286 return r;
1287
1288 r = tpm2_make_primary(c.esys_context, &primary, 0, &primary_alg);
1289 if (r < 0)
1290 return r;
1291
1292 /* we cannot use the bind key before its created */
1293 r = tpm2_make_encryption_session(c.esys_context, primary, ESYS_TR_NONE, NULL, &session);
1294 if (r < 0)
1295 goto finish;
1296
1297 r = tpm2_make_policy_session(
1298 c.esys_context,
1299 primary,
1300 session,
1301 TPM2_SE_TRIAL,
1302 hash_pcr_mask,
1303 /* pcr_bank= */ UINT16_MAX,
1304 pubkey, pubkey_size,
1305 pubkey_pcr_mask,
1306 /* signature_json= */ NULL,
1307 !!pin,
1308 /* ret_session= */ NULL,
1309 &policy_digest,
1310 &pcr_bank);
1311 if (r < 0)
1312 goto finish;
1313
1314 /* We use a keyed hash object (i.e. HMAC) to store the secret key we want to use for unlocking the
1315 * LUKS2 volume with. We don't ever use for HMAC/keyed hash operations however, we just use it
1316 * because it's a key type that is universally supported and suitable for symmetric binary blobs. */
1317 hmac_template = (TPM2B_PUBLIC) {
1318 .size = sizeof(TPMT_PUBLIC),
1319 .publicArea = {
1320 .type = TPM2_ALG_KEYEDHASH,
1321 .nameAlg = TPM2_ALG_SHA256,
1322 .objectAttributes = TPMA_OBJECT_FIXEDTPM | TPMA_OBJECT_FIXEDPARENT,
1323 .parameters.keyedHashDetail.scheme.scheme = TPM2_ALG_NULL,
1324 .unique.keyedHash.size = 32,
1325 .authPolicy = *policy_digest,
1326 },
1327 };
1328
1329 hmac_sensitive = (TPM2B_SENSITIVE_CREATE) {
1330 .size = sizeof(hmac_sensitive.sensitive),
1331 .sensitive.data.size = 32,
1332 };
1333 if (pin)
1334 hash_pin(pin, strlen(pin), &hmac_sensitive.sensitive.userAuth);
1335
1336 assert(sizeof(hmac_sensitive.sensitive.data.buffer) >= hmac_sensitive.sensitive.data.size);
1337
1338 (void) tpm2_credit_random(c.esys_context);
1339
1340 log_debug("Generating secret key data.");
1341
1342 r = crypto_random_bytes(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size);
1343 if (r < 0) {
1344 log_error_errno(r, "Failed to generate secret key: %m");
1345 goto finish;
1346 }
1347
1348 log_debug("Creating HMAC key.");
1349
1350 rc = sym_Esys_Create(
1351 c.esys_context,
1352 primary,
1353 session, /* use HMAC session to enable parameter encryption */
1354 ESYS_TR_NONE,
1355 ESYS_TR_NONE,
1356 &hmac_sensitive,
1357 &hmac_template,
1358 NULL,
1359 &creation_pcr,
1360 &private,
1361 &public,
1362 NULL,
1363 NULL,
1364 NULL);
1365 if (rc != TSS2_RC_SUCCESS) {
1366 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1367 "Failed to generate HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc));
1368 goto finish;
1369 }
1370
1371 secret = memdup(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size);
1372 explicit_bzero_safe(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size);
1373 if (!secret) {
1374 r = log_oom();
1375 goto finish;
1376 }
1377
1378 log_debug("Marshalling private and public part of HMAC key.");
1379
1380 k = ALIGN8(sizeof(*private)) + ALIGN8(sizeof(*public)); /* Some roughly sensible start value */
1381 for (;;) {
1382 _cleanup_free_ void *buf = NULL;
1383 size_t offset = 0;
1384
1385 buf = malloc(k);
1386 if (!buf) {
1387 r = log_oom();
1388 goto finish;
1389 }
1390
1391 rc = sym_Tss2_MU_TPM2B_PRIVATE_Marshal(private, buf, k, &offset);
1392 if (rc == TSS2_RC_SUCCESS) {
1393 rc = sym_Tss2_MU_TPM2B_PUBLIC_Marshal(public, buf, k, &offset);
1394 if (rc == TSS2_RC_SUCCESS) {
1395 blob = TAKE_PTR(buf);
1396 blob_size = offset;
1397 break;
1398 }
1399 }
1400 if (rc != TSS2_MU_RC_INSUFFICIENT_BUFFER) {
1401 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1402 "Failed to marshal private/public key: %s", sym_Tss2_RC_Decode(rc));
1403 goto finish;
1404 }
1405
1406 if (k > SIZE_MAX / 2) {
1407 r = log_oom();
1408 goto finish;
1409 }
1410
1411 k *= 2;
1412 }
1413
1414 hash = memdup(policy_digest->buffer, policy_digest->size);
1415 if (!hash)
1416 return log_oom();
1417
1418 if (DEBUG_LOGGING)
1419 log_debug("Completed TPM2 key sealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
1420
1421 *ret_secret = TAKE_PTR(secret);
1422 *ret_secret_size = hmac_sensitive.sensitive.data.size;
1423 *ret_blob = TAKE_PTR(blob);
1424 *ret_blob_size = blob_size;
1425 *ret_pcr_hash = TAKE_PTR(hash);
1426 *ret_pcr_hash_size = policy_digest->size;
1427 *ret_pcr_bank = pcr_bank;
1428 *ret_primary_alg = primary_alg;
1429
1430 r = 0;
1431
1432 finish:
1433 explicit_bzero_safe(&hmac_sensitive, sizeof(hmac_sensitive));
1434 primary = tpm2_flush_context_verbose(c.esys_context, primary);
1435 session = tpm2_flush_context_verbose(c.esys_context, session);
1436 return r;
1437 }
1438
1439 int tpm2_unseal(const char *device,
1440 uint32_t hash_pcr_mask,
1441 uint16_t pcr_bank,
1442 const void *pubkey,
1443 size_t pubkey_size,
1444 uint32_t pubkey_pcr_mask,
1445 JsonVariant *signature,
1446 const char *pin,
1447 uint16_t primary_alg,
1448 const void *blob,
1449 size_t blob_size,
1450 const void *known_policy_hash,
1451 size_t known_policy_hash_size,
1452 void **ret_secret,
1453 size_t *ret_secret_size) {
1454
1455 _cleanup_(tpm2_context_destroy) struct tpm2_context c = {};
1456 ESYS_TR primary = ESYS_TR_NONE, session = ESYS_TR_NONE, hmac_session = ESYS_TR_NONE,
1457 hmac_key = ESYS_TR_NONE;
1458 _cleanup_(Esys_Freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
1459 _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
1460 _cleanup_(erase_and_freep) char *secret = NULL;
1461 TPM2B_PRIVATE private = {};
1462 TPM2B_PUBLIC public = {};
1463 size_t offset = 0;
1464 TSS2_RC rc;
1465 usec_t start;
1466 int r;
1467
1468 assert(blob);
1469 assert(blob_size > 0);
1470 assert(known_policy_hash_size == 0 || known_policy_hash);
1471 assert(pubkey_size == 0 || pubkey);
1472 assert(ret_secret);
1473 assert(ret_secret_size);
1474
1475 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask));
1476 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));
1477
1478 r = dlopen_tpm2();
1479 if (r < 0)
1480 return log_error_errno(r, "TPM2 support is not installed.");
1481
1482 /* So here's what we do here: We connect to the TPM2 chip. As we do when sealing we generate a
1483 * "primary" key on the TPM2 chip, with the same parameters as well as a PCR-bound policy
1484 * session. Given we pass the same parameters, this will result in the same "primary" key, and same
1485 * policy hash (the latter of course, only if the PCR values didn't change in between). We unmarshal
1486 * the encrypted key we stored in the LUKS2 JSON token header and upload it into the TPM2, where it
1487 * is decrypted if the seed and the PCR policy were right ("unsealing"). We then download the result,
1488 * and use it to unlock the LUKS2 volume. */
1489
1490 start = now(CLOCK_MONOTONIC);
1491
1492 log_debug("Unmarshalling private part of HMAC key.");
1493
1494 rc = sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal(blob, blob_size, &offset, &private);
1495 if (rc != TSS2_RC_SUCCESS)
1496 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1497 "Failed to unmarshal private key: %s", sym_Tss2_RC_Decode(rc));
1498
1499 log_debug("Unmarshalling public part of HMAC key.");
1500
1501 rc = sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal(blob, blob_size, &offset, &public);
1502 if (rc != TSS2_RC_SUCCESS)
1503 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1504 "Failed to unmarshal public key: %s", sym_Tss2_RC_Decode(rc));
1505
1506 r = tpm2_context_init(device, &c);
1507 if (r < 0)
1508 return r;
1509
1510 r = tpm2_make_primary(c.esys_context, &primary, primary_alg, NULL);
1511 if (r < 0)
1512 return r;
1513
1514 log_debug("Loading HMAC key into TPM.");
1515
1516 /*
1517 * Nothing sensitive on the bus, no need for encryption. Even if an attacker
1518 * gives you back a different key, the session initiation will fail if a pin
1519 * is provided. If an attacker gives back a bad key, we already lost since
1520 * primary key is not verified and they could attack there as well.
1521 */
1522 rc = sym_Esys_Load(
1523 c.esys_context,
1524 primary,
1525 ESYS_TR_PASSWORD,
1526 ESYS_TR_NONE,
1527 ESYS_TR_NONE,
1528 &private,
1529 &public,
1530 &hmac_key);
1531 if (rc != TSS2_RC_SUCCESS) {
1532 /* If we're in dictionary attack lockout mode, we should see a lockout error here, which we
1533 * need to translate for the caller. */
1534 if (rc == TPM2_RC_LOCKOUT)
1535 r = log_error_errno(
1536 SYNTHETIC_ERRNO(ENOLCK),
1537 "TPM2 device is in dictionary attack lockout mode.");
1538 else
1539 r = log_error_errno(
1540 SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1541 "Failed to load HMAC key in TPM: %s",
1542 sym_Tss2_RC_Decode(rc));
1543 goto finish;
1544 }
1545
1546 r = tpm2_make_encryption_session(c.esys_context, primary, hmac_key, pin, &hmac_session);
1547 if (r < 0)
1548 goto finish;
1549
1550 r = tpm2_make_policy_session(
1551 c.esys_context,
1552 primary,
1553 hmac_session,
1554 TPM2_SE_POLICY,
1555 hash_pcr_mask,
1556 pcr_bank,
1557 pubkey, pubkey_size,
1558 pubkey_pcr_mask,
1559 signature,
1560 !!pin,
1561 &session,
1562 &policy_digest,
1563 /* ret_pcr_bank= */ NULL);
1564 if (r < 0)
1565 goto finish;
1566
1567 /* If we know the policy hash to expect, and it doesn't match, we can shortcut things here, and not
1568 * wait until the TPM2 tells us to go away. */
1569 if (known_policy_hash_size > 0 &&
1570 memcmp_nn(policy_digest->buffer, policy_digest->size, known_policy_hash, known_policy_hash_size) != 0)
1571 return log_error_errno(SYNTHETIC_ERRNO(EPERM),
1572 "Current policy digest does not match stored policy digest, cancelling "
1573 "TPM2 authentication attempt.");
1574
1575 log_debug("Unsealing HMAC key.");
1576
1577 rc = sym_Esys_Unseal(
1578 c.esys_context,
1579 hmac_key,
1580 session,
1581 hmac_session, /* use HMAC session to enable parameter encryption */
1582 ESYS_TR_NONE,
1583 &unsealed);
1584 if (rc != TSS2_RC_SUCCESS) {
1585 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1586 "Failed to unseal HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc));
1587 goto finish;
1588 }
1589
1590 secret = memdup(unsealed->buffer, unsealed->size);
1591 explicit_bzero_safe(unsealed->buffer, unsealed->size);
1592 if (!secret) {
1593 r = log_oom();
1594 goto finish;
1595 }
1596
1597 if (DEBUG_LOGGING)
1598 log_debug("Completed TPM2 key unsealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
1599
1600 *ret_secret = TAKE_PTR(secret);
1601 *ret_secret_size = unsealed->size;
1602
1603 r = 0;
1604
1605 finish:
1606 primary = tpm2_flush_context_verbose(c.esys_context, primary);
1607 session = tpm2_flush_context_verbose(c.esys_context, session);
1608 hmac_key = tpm2_flush_context_verbose(c.esys_context, hmac_key);
1609 return r;
1610 }
1611
1612 #endif
1613
1614 int tpm2_list_devices(void) {
1615 #if HAVE_TPM2
1616 _cleanup_(table_unrefp) Table *t = NULL;
1617 _cleanup_(closedirp) DIR *d = NULL;
1618 int r;
1619
1620 r = dlopen_tpm2();
1621 if (r < 0)
1622 return log_error_errno(r, "TPM2 support is not installed.");
1623
1624 t = table_new("path", "device", "driver");
1625 if (!t)
1626 return log_oom();
1627
1628 d = opendir("/sys/class/tpmrm");
1629 if (!d) {
1630 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to open /sys/class/tpmrm: %m");
1631 if (errno != ENOENT)
1632 return -errno;
1633 } else {
1634 for (;;) {
1635 _cleanup_free_ char *device_path = NULL, *device = NULL, *driver_path = NULL, *driver = NULL, *node = NULL;
1636 struct dirent *de;
1637
1638 de = readdir_no_dot(d);
1639 if (!de)
1640 break;
1641
1642 device_path = path_join("/sys/class/tpmrm", de->d_name, "device");
1643 if (!device_path)
1644 return log_oom();
1645
1646 r = readlink_malloc(device_path, &device);
1647 if (r < 0)
1648 log_debug_errno(r, "Failed to read device symlink %s, ignoring: %m", device_path);
1649 else {
1650 driver_path = path_join(device_path, "driver");
1651 if (!driver_path)
1652 return log_oom();
1653
1654 r = readlink_malloc(driver_path, &driver);
1655 if (r < 0)
1656 log_debug_errno(r, "Failed to read driver symlink %s, ignoring: %m", driver_path);
1657 }
1658
1659 node = path_join("/dev", de->d_name);
1660 if (!node)
1661 return log_oom();
1662
1663 r = table_add_many(
1664 t,
1665 TABLE_PATH, node,
1666 TABLE_STRING, device ? last_path_component(device) : NULL,
1667 TABLE_STRING, driver ? last_path_component(driver) : NULL);
1668 if (r < 0)
1669 return table_log_add_error(r);
1670 }
1671 }
1672
1673 if (table_get_rows(t) <= 1) {
1674 log_info("No suitable TPM2 devices found.");
1675 return 0;
1676 }
1677
1678 r = table_print(t, stdout);
1679 if (r < 0)
1680 return log_error_errno(r, "Failed to show device table: %m");
1681
1682 return 0;
1683 #else
1684 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1685 "TPM2 not supported on this build.");
1686 #endif
1687 }
1688
1689 int tpm2_find_device_auto(
1690 int log_level, /* log level when no device is found */
1691 char **ret) {
1692 #if HAVE_TPM2
1693 _cleanup_(closedirp) DIR *d = NULL;
1694 int r;
1695
1696 r = dlopen_tpm2();
1697 if (r < 0)
1698 return log_error_errno(r, "TPM2 support is not installed.");
1699
1700 d = opendir("/sys/class/tpmrm");
1701 if (!d) {
1702 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
1703 "Failed to open /sys/class/tpmrm: %m");
1704 if (errno != ENOENT)
1705 return -errno;
1706 } else {
1707 _cleanup_free_ char *node = NULL;
1708
1709 for (;;) {
1710 struct dirent *de;
1711
1712 de = readdir_no_dot(d);
1713 if (!de)
1714 break;
1715
1716 if (node)
1717 return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ),
1718 "More than one TPM2 (tpmrm) device found.");
1719
1720 node = path_join("/dev", de->d_name);
1721 if (!node)
1722 return log_oom();
1723 }
1724
1725 if (node) {
1726 *ret = TAKE_PTR(node);
1727 return 0;
1728 }
1729 }
1730
1731 return log_full_errno(log_level, SYNTHETIC_ERRNO(ENODEV), "No TPM2 (tpmrm) device found.");
1732 #else
1733 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1734 "TPM2 not supported on this build.");
1735 #endif
1736 }
1737
1738 int tpm2_parse_pcrs(const char *s, uint32_t *ret) {
1739 const char *p = ASSERT_PTR(s);
1740 uint32_t mask = 0;
1741 int r;
1742
1743 if (isempty(s)) {
1744 *ret = 0;
1745 return 0;
1746 }
1747
1748 /* Parses a "," or "+" separated list of PCR indexes. We support "," since this is a list after all,
1749 * and most other tools expect comma separated PCR specifications. We also support "+" since in
1750 * /etc/crypttab the "," is already used to separate options, hence a different separator is nice to
1751 * avoid escaping. */
1752
1753 for (;;) {
1754 _cleanup_free_ char *pcr = NULL;
1755 unsigned n;
1756
1757 r = extract_first_word(&p, &pcr, ",+", EXTRACT_DONT_COALESCE_SEPARATORS);
1758 if (r == 0)
1759 break;
1760 if (r < 0)
1761 return log_error_errno(r, "Failed to parse PCR list: %s", s);
1762
1763 r = safe_atou(pcr, &n);
1764 if (r < 0)
1765 return log_error_errno(r, "Failed to parse PCR number: %s", pcr);
1766 if (n >= TPM2_PCRS_MAX)
1767 return log_error_errno(SYNTHETIC_ERRNO(ERANGE),
1768 "PCR number out of range (valid range 0…23): %u", n);
1769
1770 mask |= UINT32_C(1) << n;
1771 }
1772
1773 *ret = mask;
1774 return 0;
1775 }
1776
1777 int tpm2_make_pcr_json_array(uint32_t pcr_mask, JsonVariant **ret) {
1778 _cleanup_(json_variant_unrefp) JsonVariant *a = NULL;
1779 JsonVariant* pcr_array[TPM2_PCRS_MAX];
1780 unsigned n_pcrs = 0;
1781 int r;
1782
1783 for (size_t i = 0; i < ELEMENTSOF(pcr_array); i++) {
1784 if ((pcr_mask & (UINT32_C(1) << i)) == 0)
1785 continue;
1786
1787 r = json_variant_new_integer(pcr_array + n_pcrs, i);
1788 if (r < 0)
1789 goto finish;
1790
1791 n_pcrs++;
1792 }
1793
1794 r = json_variant_new_array(&a, pcr_array, n_pcrs);
1795 if (r < 0)
1796 goto finish;
1797
1798 if (ret)
1799 *ret = TAKE_PTR(a);
1800 r = 0;
1801
1802 finish:
1803 json_variant_unref_many(pcr_array, n_pcrs);
1804 return r;
1805 }
1806
1807 int tpm2_parse_pcr_json_array(JsonVariant *v, uint32_t *ret) {
1808 JsonVariant *e;
1809 uint32_t mask = 0;
1810
1811 if (!json_variant_is_array(v))
1812 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR array is not a JSON array.");
1813
1814 JSON_VARIANT_ARRAY_FOREACH(e, v) {
1815 uint64_t u;
1816
1817 if (!json_variant_is_unsigned(e))
1818 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR is not an unsigned integer.");
1819
1820 u = json_variant_unsigned(e);
1821 if (u >= TPM2_PCRS_MAX)
1822 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR number out of range: %" PRIu64, u);
1823
1824 mask |= UINT32_C(1) << u;
1825 }
1826
1827 if (ret)
1828 *ret = mask;
1829
1830 return 0;
1831 }
1832
1833 int tpm2_make_luks2_json(
1834 int keyslot,
1835 uint32_t hash_pcr_mask,
1836 uint16_t pcr_bank,
1837 const void *pubkey,
1838 size_t pubkey_size,
1839 uint32_t pubkey_pcr_mask,
1840 uint16_t primary_alg,
1841 const void *blob,
1842 size_t blob_size,
1843 const void *policy_hash,
1844 size_t policy_hash_size,
1845 TPM2Flags flags,
1846 JsonVariant **ret) {
1847
1848 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *hmj = NULL, *pkmj = NULL;
1849 _cleanup_free_ char *keyslot_as_string = NULL;
1850 int r;
1851
1852 assert(blob || blob_size == 0);
1853 assert(policy_hash || policy_hash_size == 0);
1854 assert(pubkey || pubkey_size == 0);
1855
1856 if (asprintf(&keyslot_as_string, "%i", keyslot) < 0)
1857 return -ENOMEM;
1858
1859 r = tpm2_make_pcr_json_array(hash_pcr_mask, &hmj);
1860 if (r < 0)
1861 return r;
1862
1863 if (pubkey_pcr_mask != 0) {
1864 r = tpm2_make_pcr_json_array(pubkey_pcr_mask, &pkmj);
1865 if (r < 0)
1866 return r;
1867 }
1868
1869 /* Note: We made the mistake of using "-" in the field names, which isn't particular compatible with
1870 * other programming languages. Let's not make things worse though, i.e. future additions to the JSON
1871 * object should use "_" rather than "-" in field names. */
1872
1873 r = json_build(&v,
1874 JSON_BUILD_OBJECT(
1875 JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-tpm2")),
1876 JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))),
1877 JSON_BUILD_PAIR("tpm2-blob", JSON_BUILD_BASE64(blob, blob_size)),
1878 JSON_BUILD_PAIR("tpm2-pcrs", JSON_BUILD_VARIANT(hmj)),
1879 JSON_BUILD_PAIR_CONDITION(!!tpm2_pcr_bank_to_string(pcr_bank), "tpm2-pcr-bank", JSON_BUILD_STRING(tpm2_pcr_bank_to_string(pcr_bank))),
1880 JSON_BUILD_PAIR_CONDITION(!!tpm2_primary_alg_to_string(primary_alg), "tpm2-primary-alg", JSON_BUILD_STRING(tpm2_primary_alg_to_string(primary_alg))),
1881 JSON_BUILD_PAIR("tpm2-policy-hash", JSON_BUILD_HEX(policy_hash, policy_hash_size)),
1882 JSON_BUILD_PAIR("tpm2-pin", JSON_BUILD_BOOLEAN(flags & TPM2_FLAGS_USE_PIN)),
1883 JSON_BUILD_PAIR_CONDITION(pubkey_pcr_mask != 0, "tpm2_pubkey_pcrs", JSON_BUILD_VARIANT(pkmj)),
1884 JSON_BUILD_PAIR_CONDITION(pubkey_pcr_mask != 0, "tpm2_pubkey", JSON_BUILD_BASE64(pubkey, pubkey_size))));
1885 if (r < 0)
1886 return r;
1887
1888 if (ret)
1889 *ret = TAKE_PTR(v);
1890
1891 return keyslot;
1892 }
1893
1894 int tpm2_parse_luks2_json(
1895 JsonVariant *v,
1896 int *ret_keyslot,
1897 uint32_t *ret_hash_pcr_mask,
1898 uint16_t *ret_pcr_bank,
1899 void **ret_pubkey,
1900 size_t *ret_pubkey_size,
1901 uint32_t *ret_pubkey_pcr_mask,
1902 uint16_t *ret_primary_alg,
1903 void **ret_blob,
1904 size_t *ret_blob_size,
1905 void **ret_policy_hash,
1906 size_t *ret_policy_hash_size,
1907 TPM2Flags *ret_flags) {
1908
1909 _cleanup_free_ void *blob = NULL, *policy_hash = NULL, *pubkey = NULL;
1910 size_t blob_size = 0, policy_hash_size = 0, pubkey_size = 0;
1911 uint32_t hash_pcr_mask = 0, pubkey_pcr_mask = 0;
1912 uint16_t primary_alg = TPM2_ALG_ECC; /* ECC was the only supported algorithm in systemd < 250, use that as implied default, for compatibility */
1913 uint16_t pcr_bank = UINT16_MAX; /* default: pick automatically */
1914 int r, keyslot = -1;
1915 TPM2Flags flags = 0;
1916 JsonVariant *w;
1917
1918 assert(v);
1919
1920 if (ret_keyslot) {
1921 keyslot = cryptsetup_get_keyslot_from_token(v);
1922 if (keyslot < 0) {
1923 /* Return a recognizable error when parsing this field, so that callers can handle parsing
1924 * errors of the keyslots field gracefully, since it's not 'owned' by us, but by the LUKS2
1925 * spec */
1926 log_debug_errno(keyslot, "Failed to extract keyslot index from TPM2 JSON data token, skipping: %m");
1927 return -EUCLEAN;
1928 }
1929 }
1930
1931 w = json_variant_by_key(v, "tpm2-pcrs");
1932 if (!w)
1933 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-pcrs' field.");
1934
1935 r = tpm2_parse_pcr_json_array(w, &hash_pcr_mask);
1936 if (r < 0)
1937 return log_debug_errno(r, "Failed to parse TPM2 PCR mask: %m");
1938
1939 /* The bank field is optional, since it was added in systemd 250 only. Before the bank was hardcoded
1940 * to SHA256. */
1941 w = json_variant_by_key(v, "tpm2-pcr-bank");
1942 if (w) {
1943 /* The PCR bank field is optional */
1944
1945 if (!json_variant_is_string(w))
1946 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR bank is not a string.");
1947
1948 r = tpm2_pcr_bank_from_string(json_variant_string(w));
1949 if (r < 0)
1950 return log_debug_errno(r, "TPM2 PCR bank invalid or not supported: %s", json_variant_string(w));
1951
1952 pcr_bank = r;
1953 }
1954
1955 /* The primary key algorithm field is optional, since it was also added in systemd 250 only. Before
1956 * the algorithm was hardcoded to ECC. */
1957 w = json_variant_by_key(v, "tpm2-primary-alg");
1958 if (w) {
1959 /* The primary key algorithm is optional */
1960
1961 if (!json_variant_is_string(w))
1962 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 primary key algorithm is not a string.");
1963
1964 r = tpm2_primary_alg_from_string(json_variant_string(w));
1965 if (r < 0)
1966 return log_debug_errno(r, "TPM2 primary key algorithm invalid or not supported: %s", json_variant_string(w));
1967
1968 primary_alg = r;
1969 }
1970
1971 w = json_variant_by_key(v, "tpm2-blob");
1972 if (!w)
1973 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-blob' field.");
1974
1975 r = json_variant_unbase64(w, &blob, &blob_size);
1976 if (r < 0)
1977 return log_debug_errno(r, "Invalid base64 data in 'tpm2-blob' field.");
1978
1979 w = json_variant_by_key(v, "tpm2-policy-hash");
1980 if (!w)
1981 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-policy-hash' field.");
1982
1983 r = json_variant_unhex(w, &policy_hash, &policy_hash_size);
1984 if (r < 0)
1985 return log_debug_errno(r, "Invalid base64 data in 'tpm2-policy-hash' field.");
1986
1987 w = json_variant_by_key(v, "tpm2-pin");
1988 if (w) {
1989 if (!json_variant_is_boolean(w))
1990 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PIN policy is not a boolean.");
1991
1992 SET_FLAG(flags, TPM2_FLAGS_USE_PIN, json_variant_boolean(w));
1993 }
1994
1995 w = json_variant_by_key(v, "tpm2_pubkey_pcrs");
1996 if (w) {
1997 r = tpm2_parse_pcr_json_array(w, &pubkey_pcr_mask);
1998 if (r < 0)
1999 return r;
2000 }
2001
2002 w = json_variant_by_key(v, "tpm2_pubkey");
2003 if (w) {
2004 r = json_variant_unbase64(w, &pubkey, &pubkey_size);
2005 if (r < 0)
2006 return log_debug_errno(r, "Failed to decode PCR public key.");
2007 } else if (pubkey_pcr_mask != 0)
2008 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Public key PCR mask set, but not public key included in JSON data, refusing.");
2009
2010 if (ret_keyslot)
2011 *ret_keyslot = keyslot;
2012 if (ret_hash_pcr_mask)
2013 *ret_hash_pcr_mask = hash_pcr_mask;
2014 if (ret_pcr_bank)
2015 *ret_pcr_bank = pcr_bank;
2016 if (ret_pubkey)
2017 *ret_pubkey = TAKE_PTR(pubkey);
2018 if (ret_pubkey_size)
2019 *ret_pubkey_size = pubkey_size;
2020 if (ret_pubkey_pcr_mask)
2021 *ret_pubkey_pcr_mask = pubkey_pcr_mask;
2022 if (ret_primary_alg)
2023 *ret_primary_alg = primary_alg;
2024 if (ret_blob)
2025 *ret_blob = TAKE_PTR(blob);
2026 if (ret_blob_size)
2027 *ret_blob_size = blob_size;
2028 if (ret_policy_hash)
2029 *ret_policy_hash = TAKE_PTR(policy_hash);
2030 if (ret_policy_hash_size)
2031 *ret_policy_hash_size = policy_hash_size;
2032 if (ret_flags)
2033 *ret_flags = flags;
2034
2035 return 0;
2036 }
2037
2038 const char *tpm2_pcr_bank_to_string(uint16_t bank) {
2039 if (bank == TPM2_ALG_SHA1)
2040 return "sha1";
2041 if (bank == TPM2_ALG_SHA256)
2042 return "sha256";
2043 if (bank == TPM2_ALG_SHA384)
2044 return "sha384";
2045 if (bank == TPM2_ALG_SHA512)
2046 return "sha512";
2047 return NULL;
2048 }
2049
2050 int tpm2_pcr_bank_from_string(const char *bank) {
2051 if (streq_ptr(bank, "sha1"))
2052 return TPM2_ALG_SHA1;
2053 if (streq_ptr(bank, "sha256"))
2054 return TPM2_ALG_SHA256;
2055 if (streq_ptr(bank, "sha384"))
2056 return TPM2_ALG_SHA384;
2057 if (streq_ptr(bank, "sha512"))
2058 return TPM2_ALG_SHA512;
2059 return -EINVAL;
2060 }
2061
2062 const char *tpm2_primary_alg_to_string(uint16_t alg) {
2063 if (alg == TPM2_ALG_ECC)
2064 return "ecc";
2065 if (alg == TPM2_ALG_RSA)
2066 return "rsa";
2067 return NULL;
2068 }
2069
2070 int tpm2_primary_alg_from_string(const char *alg) {
2071 if (streq_ptr(alg, "ecc"))
2072 return TPM2_ALG_ECC;
2073 if (streq_ptr(alg, "rsa"))
2074 return TPM2_ALG_RSA;
2075 return -EINVAL;
2076 }
2077
2078 Tpm2Support tpm2_support(void) {
2079 Tpm2Support support = TPM2_SUPPORT_NONE;
2080 int r;
2081
2082 if (detect_container() <= 0) {
2083 /* Check if there's a /dev/tpmrm* device via sysfs. If we run in a container we likely just
2084 * got the host sysfs mounted. Since devices are generally not virtualized for containers,
2085 * let's assume containers never have a TPM, at least for now. */
2086
2087 r = dir_is_empty("/sys/class/tpmrm", /* ignore_hidden_or_backup= */ false);
2088 if (r < 0) {
2089 if (r != -ENOENT)
2090 log_debug_errno(r, "Unable to test whether /sys/class/tpmrm/ exists and is populated, assuming it is not: %m");
2091 } else if (r == 0) /* populated! */
2092 support |= TPM2_SUPPORT_DRIVER;
2093 }
2094
2095 if (efi_has_tpm2())
2096 support |= TPM2_SUPPORT_FIRMWARE;
2097
2098 #if HAVE_TPM2
2099 support |= TPM2_SUPPORT_SYSTEM;
2100 #endif
2101
2102 return support;
2103 }
2104
2105 int tpm2_parse_pcr_argument(const char *arg, uint32_t *mask) {
2106 uint32_t m;
2107 int r;
2108
2109 assert(mask);
2110
2111 /* For use in getopt_long() command line parsers: merges masks specified on the command line */
2112
2113 if (isempty(arg)) {
2114 *mask = 0;
2115 return 0;
2116 }
2117
2118 r = tpm2_parse_pcrs(arg, &m);
2119 if (r < 0)
2120 return r;
2121
2122 if (*mask == UINT32_MAX)
2123 *mask = m;
2124 else
2125 *mask |= m;
2126
2127 return 0;
2128 }
2129
2130 int tpm2_load_pcr_signature(const char *path, JsonVariant **ret) {
2131 _cleanup_free_ char *discovered_path = NULL;
2132 _cleanup_fclose_ FILE *f = NULL;
2133 int r;
2134
2135 /* Tries to load a JSON PCR signature file. Takes an absolute path, a simple file name or NULL. In
2136 * the latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
2137
2138 if (!path)
2139 path = "tpm2-pcr-signature.json";
2140
2141 r = search_and_fopen(path, "re", NULL, (const char**) CONF_PATHS_STRV("systemd"), &f, &discovered_path);
2142 if (r < 0)
2143 return log_debug_errno(r, "Failed to find TPM PCR signature file '%s': %m", path);
2144
2145 r = json_parse_file(f, discovered_path, 0, ret, NULL, NULL);
2146 if (r < 0)
2147 return log_debug_errno(r, "Failed to parse TPM PCR signature JSON object '%s': %m", discovered_path);
2148
2149 return 0;
2150 }
2151
2152 int tpm2_load_pcr_public_key(const char *path, void **ret_pubkey, size_t *ret_pubkey_size) {
2153 _cleanup_free_ char *discovered_path = NULL;
2154 _cleanup_fclose_ FILE *f = NULL;
2155 int r;
2156
2157 /* Tries to load a PCR public key file. Takes an absolute path, a simple file name or NULL. In the
2158 * latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
2159
2160 if (!path)
2161 path = "tpm2-pcr-public-key.pem";
2162
2163 r = search_and_fopen(path, "re", NULL, (const char**) CONF_PATHS_STRV("systemd"), &f, &discovered_path);
2164 if (r < 0)
2165 return log_debug_errno(r, "Failed to find TPM PCR public key file '%s': %m", path);
2166
2167 r = read_full_stream(f, (char**) ret_pubkey, ret_pubkey_size);
2168 if (r < 0)
2169 return log_debug_errno(r, "Failed to load TPM PCR public key PEM file '%s': %m", discovered_path);
2170
2171 return 0;
2172 }
2173
2174 int pcr_mask_to_string(uint32_t mask, char **ret) {
2175 _cleanup_free_ char *buf = NULL;
2176 int r;
2177
2178 assert(ret);
2179
2180 for (unsigned i = 0; i < TPM2_PCRS_MAX; i++) {
2181 if (!(mask & (UINT32_C(1) << i)))
2182 continue;
2183
2184 r = strextendf_with_separator(&buf, "+", "%u", i);
2185 if (r < 0)
2186 return r;
2187 }
2188
2189 *ret = TAKE_PTR(buf);
2190 return 0;
2191 }