1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "alloc-util.h"
4 #include "cryptsetup-util.h"
6 #include "dirent-util.h"
7 #include "dlfcn-util.h"
9 #include "extract-word.h"
12 #include "format-table.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"
20 #include "stat-util.h"
21 #include "time-util.h"
22 #include "tpm2-util.h"
26 static void *libtss2_esys_dl
= NULL
;
27 static void *libtss2_rc_dl
= NULL
;
28 static void *libtss2_mu_dl
= NULL
;
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
);
53 const char* (*sym_Tss2_RC_Decode
)(TSS2_RC rc
) = NULL
;
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
;
60 int dlopen_tpm2(void) {
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
),
70 DLSYM_ARG(Esys_GetCapability
),
71 DLSYM_ARG(Esys_GetRandom
),
72 DLSYM_ARG(Esys_Initialize
),
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
));
90 r
= dlopen_many_sym_or_warn(
91 &libtss2_rc_dl
, "libtss2-rc.so.0", LOG_DEBUG
,
92 DLSYM_ARG(Tss2_RC_Decode
));
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
));
104 void tpm2_context_destroy(struct tpm2_context
*c
) {
108 sym_Esys_Finalize(&c
->esys_context
);
110 c
->tcti_context
= mfree(c
->tcti_context
);
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. */
122 sym_Esys_Finalize(c
);
125 ESYS_TR
tpm2_flush_context_verbose(ESYS_CONTEXT
*c
, ESYS_TR handle
) {
128 if (!c
|| handle
== ESYS_TR_NONE
)
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
));
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
;
151 return log_error_errno(r
, "TPM2 support not installed: %m");
154 device
= secure_getenv("SYSTEMD_TPM2_DEVICE");
157 const char *param
, *driver
, *fn
;
158 const TSS2_TCTI_INFO
* info
;
159 TSS2_TCTI_INFO_FUNC func
;
162 param
= strchr(device
, ':');
164 driver
= strndupa_safe(device
, param
- device
);
171 fn
= strjoina("libtss2-tcti-", driver
, ".so.0");
173 dl
= dlopen(fn
, RTLD_NOW
);
175 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "Failed to load %s: %s", fn
, dlerror());
177 func
= dlsym(dl
, TSS2_TCTI_INFO_SYMBOL
);
179 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
180 "Failed to find TCTI info symbol " TSS2_TCTI_INFO_SYMBOL
": %s",
185 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "Unable to get TCTI info data.");
188 log_debug("Loaded TCTI module '%s' (%s) [Version %" PRIu32
"]", info
->name
, info
->description
, info
->version
);
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
));
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
));
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
));
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.");
216 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
217 "Failed to start up TPM: %s", sym_Tss2_RC_Decode(rc
));
219 *ret
= (struct tpm2_context
) {
220 .esys_context
= TAKE_PTR(c
),
221 .tcti_context
= TAKE_PTR(tcti
),
222 .tcti_dl
= TAKE_PTR(dl
),
228 #define TPM2_CREDIT_RANDOM_FLAG_PATH "/run/systemd/tpm-rng-credited"
230 static int tpm2_credit_random(ESYS_CONTEXT
*c
) {
231 size_t rps
, done
= 0;
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
243 if (access(TPM2_CREDIT_RANDOM_FLAG_PATH
, F_OK
) < 0) {
245 log_debug_errno(errno
, "Failed to detect if '" TPM2_CREDIT_RANDOM_FLAG_PATH
"' exists, ignoring: %m");
247 log_debug("Not adding TPM2 entropy to the kernel random pool again.");
248 return 0; /* Already done */
251 t
= now(CLOCK_MONOTONIC
);
253 for (rps
= random_pool_size(); rps
> 0;) {
254 _cleanup_(Esys_Freep
) TPM2B_DIGEST
*buffer
= NULL
;
256 rc
= sym_Esys_GetRandom(
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. */
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
));
267 if (buffer
->size
== 0)
268 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
269 "Zero-sized entropy returned from TPM.");
271 r
= random_write_entropy(-1, buffer
->buffer
, buffer
->size
, /* credit= */ false);
273 return log_error_errno(r
, "Failed wo write entropy to kernel: %m");
275 done
+= buffer
->size
;
276 rps
= LESS_BY(rps
, buffer
->size
);
279 log_debug("Added %zu bytes of TPM2 entropy to the kernel random pool in %s.", done
, FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - t
, 0));
281 r
= touch(TPM2_CREDIT_RANDOM_FLAG_PATH
);
283 log_debug_errno(r
, "Failed to touch '" TPM2_CREDIT_RANDOM_FLAG_PATH
"', ignoring: %m");
288 static int tpm2_make_primary(
290 ESYS_TR
*ret_primary
,
292 TPMI_ALG_PUBLIC
*ret_alg
) {
294 static const TPM2B_SENSITIVE_CREATE primary_sensitive
= {};
295 static const TPM2B_PUBLIC primary_template_ecc
= {
296 .size
= sizeof(TPMT_PUBLIC
),
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
= {
303 .algorithm
= TPM2_ALG_AES
,
305 .mode
.aes
= TPM2_ALG_CFB
,
307 .scheme
.scheme
= TPM2_ALG_NULL
,
308 .curveID
= TPM2_ECC_NIST_P256
,
309 .kdf
.scheme
= TPM2_ALG_NULL
,
313 static const TPM2B_PUBLIC primary_template_rsa
= {
314 .size
= sizeof(TPMT_PUBLIC
),
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
= {
321 .algorithm
= TPM2_ALG_AES
,
323 .mode
.aes
= TPM2_ALG_CFB
,
325 .scheme
.scheme
= TPM2_ALG_NULL
,
331 static const TPML_PCR_SELECTION creation_pcr
= {};
332 ESYS_TR primary
= ESYS_TR_NONE
;
336 log_debug("Creating primary key on TPM.");
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. */
342 ts
= now(CLOCK_MONOTONIC
);
344 if (IN_SET(alg
, 0, TPM2_ALG_ECC
)) {
345 rc
= sym_Esys_CreatePrimary(
352 &primary_template_ecc
,
361 if (rc
!= TSS2_RC_SUCCESS
) {
363 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
364 "Failed to generate ECC primary key in TPM: %s", sym_Tss2_RC_Decode(rc
));
366 log_debug("Failed to generate ECC primary key in TPM, trying RSA: %s", sym_Tss2_RC_Decode(rc
));
368 log_debug("Successfully created ECC primary key on TPM.");
373 if (IN_SET(alg
, 0, TPM2_ALG_RSA
)) {
374 rc
= sym_Esys_CreatePrimary(
381 &primary_template_rsa
,
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
));
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.");
398 log_debug("Successfully created RSA primary key on TPM.");
401 log_debug("Generating primary key on TPM2 took %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - ts
, USEC_PER_MSEC
));
403 *ret_primary
= primary
;
410 void tpm2_pcr_mask_to_selection(uint32_t mask
, uint16_t bank
, TPML_PCR_SELECTION
*ret
) {
413 /* We only do 24bit here, as that's what PC TPMs are supposed to support */
414 assert(mask
<= 0xFFFFFFU
);
416 *ret
= (TPML_PCR_SELECTION
) {
418 .pcrSelections
[0] = {
421 .pcrSelect
[0] = mask
& 0xFF,
422 .pcrSelect
[1] = (mask
>> 8) & 0xFF,
423 .pcrSelect
[2] = (mask
>> 16) & 0xFF,
428 static unsigned find_nth_bit(uint32_t mask
, unsigned n
) {
433 /* Returns the bit index of the nth set bit, e.g. mask=0b101001, n=3 → 5 */
435 for (unsigned i
= 0; i
< sizeof(mask
)*8; i
++) {
450 static int tpm2_pcr_mask_good(
455 _cleanup_(Esys_Freep
) TPML_DIGEST
*pcr_values
= NULL
;
456 TPML_PCR_SELECTION selection
;
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. */
466 tpm2_pcr_mask_to_selection(mask
, bank
, &selection
);
468 rc
= sym_Esys_PCR_Read(
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
));
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
++) {
484 _cleanup_free_
char *h
= NULL
;
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
);
491 log_debug("PCR %u value: %s", j
, strna(h
));
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
))
502 static int tpm2_get_best_pcr_bank(
505 TPMI_ALG_HASH
*ret
) {
507 _cleanup_(Esys_Freep
) TPMS_CAPABILITY_DATA
*pcap
= NULL
;
508 TPMI_ALG_HASH supported_hash
= 0, hash_with_valid_pcr
= 0;
514 rc
= sym_Esys_GetCapability(
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
));
528 assert(pcap
->capability
== TPM2_CAP_PCRS
);
530 for (size_t i
= 0; i
< pcap
->data
.assignedPCR
.count
; i
++) {
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
))
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
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
)));
548 assert_cc(TPM2_PCRS_MAX
% 8 == 0);
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) {
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
)));
564 good
= tpm2_pcr_mask_good(c
, pcap
->data
.assignedPCR
.pcrSelections
[i
].hash
, pcr_mask
);
568 if (pcap
->data
.assignedPCR
.pcrSelections
[i
].hash
== TPM2_ALG_SHA256
) {
569 supported_hash
= TPM2_ALG_SHA256
;
571 /* Great, SHA256 is supported and has initialized PCR values, we are done. */
572 hash_with_valid_pcr
= TPM2_ALG_SHA256
;
576 assert(pcap
->data
.assignedPCR
.pcrSelections
[i
].hash
== TPM2_ALG_SHA1
);
578 if (supported_hash
== 0)
579 supported_hash
= TPM2_ALG_SHA1
;
581 if (good
&& hash_with_valid_pcr
== 0)
582 hash_with_valid_pcr
= TPM2_ALG_SHA1
;
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
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. */
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.");
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.");
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
;
613 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
614 "TPM2 module supports neither SHA1 nor SHA256 PCR banks, cannot operate.");
619 static void hash_pin(const char *pin
, size_t len
, TPM2B_AUTH
*auth
) {
620 struct sha256_ctx hash
;
624 auth
->size
= SHA256_DIGEST_SIZE
;
626 sha256_init_ctx(&hash
);
627 sha256_process_bytes(pin
, len
, &hash
);
628 sha256_finish_ctx(&hash
, auth
->buffer
);
630 explicit_bzero_safe(&hash
, sizeof(hash
));
633 static int tpm2_make_encryption_session(
638 ESYS_TR
*ret_session
) {
640 static const TPMT_SYM_DEF symmetric
= {
641 .algorithm
= TPM2_ALG_AES
,
643 .mode
.aes
= TPM2_ALG_CFB
,
645 const TPMA_SESSION sessionAttributes
= TPMA_SESSION_DECRYPT
| TPMA_SESSION_ENCRYPT
|
646 TPMA_SESSION_CONTINUESESSION
;
647 ESYS_TR session
= ESYS_TR_NONE
;
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.
660 TPM2B_AUTH auth
= {};
662 hash_pin(pin
, strlen(pin
), &auth
);
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
));
674 log_debug("Starting HMAC encryption session.");
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(
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
));
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
));
706 *ret_session
= session
;
707 session
= ESYS_TR_NONE
;
710 session
= tpm2_flush_context_verbose(c
, session
);
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
;
718 const BIGNUM
*n
= NULL
, *e
= NULL
;
719 const RSA
*rsa
= NULL
;
721 int n_bytes
, e_bytes
;
726 /* Converts an OpenSSL public key to a structure that the TPM chip can process. */
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.");
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.");
735 rsa
= EVP_PKEY_get0_RSA(input
);
737 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to extract RSA key from public key.");
741 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to get RSA modulus from public key.");
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.");
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.");
755 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to get RSA exponent from public key.");
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.");
763 *output
= (TPM2B_PUBLIC
) {
764 .size
= sizeof(TPMT_PUBLIC
),
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
= {
771 .scheme
= TPM2_ALG_NULL
,
772 .details
.anySig
.hashAlg
= TPM2_ALG_NULL
,
775 .algorithm
= TPM2_ALG_NULL
,
776 .mode
.sym
= TPM2_ALG_NULL
,
778 .keyBits
= n_bytes
* 8,
779 /* .exponent will be filled in below. */
783 /* .rsa.buffer will be filled in below. */
788 if (BN_bn2bin(n
, output
->publicArea
.unique
.rsa
.buffer
) <= 0)
789 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to convert RSA modulus.");
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.");
797 static int find_signature(
805 size_t *ret_signature_size
) {
807 _cleanup_free_
void *fp
= NULL
;
813 /* Searches for a signature blob in the specified JSON object. Search keys are PCR bank, PCR mask,
814 * public key, and policy digest. */
816 if (!json_variant_is_object(v
))
817 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Signature is not a JSON object.");
819 k
= tpm2_pcr_bank_to_string(pcr_bank
);
821 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
), "Don't know PCR bank %" PRIu16
, pcr_bank
);
823 /* First, find field by bank */
824 b
= json_variant_by_key(v
, k
);
826 return log_error_errno(SYNTHETIC_ERRNO(ENXIO
), "Signature lacks data for PCR bank '%s'.", k
);
828 if (!json_variant_is_array(b
))
829 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Bank data is not a JSON array.");
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
;
838 if (!json_variant_is_object(i
))
839 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Bank data element is not a JSON object");
841 /* Check if the PCR mask matches our expectations */
842 maskj
= json_variant_by_key(i
, "pcrs");
846 r
= tpm2_parse_pcr_json_array(maskj
, &parsed_mask
);
848 return log_error_errno(r
, "Failed to parse JSON PCR mask");
850 if (parsed_mask
!= pcr_mask
)
851 continue; /* Not for this PCR mask */
853 /* Then check if this is for the public key we operate with */
854 fpj
= json_variant_by_key(i
, "pkfp");
858 r
= json_variant_unhex(fpj
, &fpj_data
, &fpj_size
);
860 return log_error_errno(r
, "Failed to decode fingerprint in JSON data: %m");
863 r
= pubkey_fingerprint(pk
, EVP_sha256(), &fp
, &fp_size
);
865 return log_error_errno(r
, "Failed to calculate public key fingerprint: %m");
868 if (memcmp_nn(fp
, fp_size
, fpj_data
, fpj_size
) != 0)
869 continue; /* Not for this public key */
871 /* Finally, check if this is for the PCR policy we expect this to be */
872 polj
= json_variant_by_key(i
, "pol");
876 r
= json_variant_unhex(polj
, &polj_data
, &polj_size
);
878 return log_error_errno(r
, "Failed to decode policy hash JSON data: %m");
880 if (memcmp_nn(policy
, policy_size
, polj_data
, polj_size
) != 0)
883 /* This entry matches all our expectations, now return the signature included in it */
884 sigj
= json_variant_by_key(i
, "sig");
888 return json_variant_unbase64(sigj
, ret_signature
, ret_signature_size
);
891 return log_error_errno(SYNTHETIC_ERRNO(ENXIO
), "Couldn't find signature for this PCR bank, PCR index and public key.");
894 static int tpm2_make_policy_session(
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. */
903 uint32_t pubkey_pcr_mask
,
904 JsonVariant
*signature_json
,
906 ESYS_TR
*ret_session
,
907 TPM2B_DIGEST
**ret_policy_digest
,
908 TPMI_ALG_HASH
*ret_pcr_bank
) {
910 static const TPMT_SYM_DEF symmetric
= {
911 .algorithm
= TPM2_ALG_AES
,
913 .mode
.aes
= TPM2_ALG_CFB
,
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
;
922 assert(pubkey
|| pubkey_size
== 0);
923 assert(pubkey_pcr_mask
== 0 || pubkey_size
> 0);
925 log_debug("Starting authentication session.");
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.
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
;
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. */
942 if (pcr_bank
!= UINT16_MAX
) {
943 r
= tpm2_pcr_mask_good(c
, pcr_bank
, hash_pcr_mask
|pubkey_pcr_mask
);
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.");
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
);
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");
963 pk
= PEM_read_PUBKEY(f
, NULL
, NULL
, NULL
);
965 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to parse PEM public key.");
968 rc
= sym_Esys_StartAuthSession(
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
));
984 if (pubkey_pcr_mask
!= 0) {
985 log_debug("Configuring public key based PCR policy.");
987 /* First: load public key into the TPM */
988 TPM2B_PUBLIC pubkey_tpm2
;
989 r
= openssl_pubkey_to_tpm2_pubkey(pk
, &pubkey_tpm2
);
993 rc
= sym_Esys_LoadExternal(
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
));
1008 /* Acquire the "name" of what we just loaded */
1009 _cleanup_(Esys_Freep
) TPM2B_NAME
*pubkey_name
= NULL
;
1010 rc
= sym_Esys_TR_GetName(
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
));
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(
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
));
1037 /* Get the policy hash of the PCR policy */
1038 _cleanup_(Esys_Freep
) TPM2B_DIGEST
*approved_policy
= NULL
;
1039 rc
= sym_Esys_PolicyGetDigest(
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
));
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
;
1064 approved_policy
->buffer
,
1065 approved_policy
->size
,
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
,
1076 assert(sizeof(signature_hash
.buffer
) >= SHA256_DIGEST_SIZE
);
1077 sha256_direct(approved_policy
->buffer
, approved_policy
->size
, signature_hash
.buffer
);
1079 TPMT_SIGNATURE policy_signature
= {
1080 .sigAlg
= TPM2_ALG_RSASSA
,
1081 .signature
.rsassa
= {
1082 .hash
= TPM2_ALG_SHA256
,
1083 .sig
.size
= signature_size
,
1086 if (signature_size
> sizeof(policy_signature
.signature
.rsassa
.sig
.buffer
)) {
1087 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "Signature larger than buffer.");
1090 memcpy(policy_signature
.signature
.rsassa
.sig
.buffer
, signature_raw
, signature_size
);
1092 rc
= sym_Esys_VerifySignature(
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
));
1107 check_ticket
= check_ticket_buffer
;
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
,
1115 check_ticket
= &check_ticket_null
;
1118 rc
= sym_Esys_PolicyAuthorize(
1125 /* policyRef= */ &(const TPM2B_NONCE
) {},
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
));
1135 if (hash_pcr_mask
!= 0) {
1136 log_debug("Configuring hash-based PCR policy.");
1138 TPML_PCR_SELECTION pcr_selection
;
1139 tpm2_pcr_mask_to_selection(hash_pcr_mask
, pcr_bank
, &pcr_selection
);
1140 rc
= sym_Esys_PolicyPCR(
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
));
1156 log_debug("Configuring PIN policy.");
1158 rc
= sym_Esys_PolicyAuthValue(
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
));
1172 if (DEBUG_LOGGING
|| ret_policy_digest
) {
1173 log_debug("Acquiring policy digest.");
1175 rc
= sym_Esys_PolicyGetDigest(
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
));
1189 if (DEBUG_LOGGING
) {
1190 _cleanup_free_
char *h
= NULL
;
1192 h
= hexmem(policy_digest
->buffer
, policy_digest
->size
);
1198 log_debug("Session policy digest: %s", h
);
1203 *ret_session
= session
;
1204 session
= ESYS_TR_NONE
;
1207 if (ret_policy_digest
)
1208 *ret_policy_digest
= TAKE_PTR(policy_digest
);
1211 *ret_pcr_bank
= pcr_bank
;
1216 session
= tpm2_flush_context_verbose(c
, session
);
1217 pubkey_handle
= tpm2_flush_context_verbose(c
, pubkey_handle
);
1221 int tpm2_seal(const char *device
,
1222 uint32_t hash_pcr_mask
,
1224 const size_t pubkey_size
,
1225 uint32_t pubkey_pcr_mask
,
1228 size_t *ret_secret_size
,
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
) {
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
;
1253 assert(pubkey
|| pubkey_size
== 0);
1256 assert(ret_secret_size
);
1258 assert(ret_blob_size
);
1259 assert(ret_pcr_hash
);
1260 assert(ret_pcr_hash_size
);
1261 assert(ret_pcr_bank
);
1263 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask
));
1264 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask
));
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.
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. */
1282 start
= now(CLOCK_MONOTONIC
);
1284 r
= tpm2_context_init(device
, &c
);
1288 r
= tpm2_make_primary(c
.esys_context
, &primary
, 0, &primary_alg
);
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
);
1297 r
= tpm2_make_policy_session(
1303 /* pcr_bank= */ UINT16_MAX
,
1304 pubkey
, pubkey_size
,
1306 /* signature_json= */ NULL
,
1308 /* ret_session= */ NULL
,
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
),
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
,
1329 hmac_sensitive
= (TPM2B_SENSITIVE_CREATE
) {
1330 .size
= sizeof(hmac_sensitive
.sensitive
),
1331 .sensitive
.data
.size
= 32,
1334 hash_pin(pin
, strlen(pin
), &hmac_sensitive
.sensitive
.userAuth
);
1336 assert(sizeof(hmac_sensitive
.sensitive
.data
.buffer
) >= hmac_sensitive
.sensitive
.data
.size
);
1338 (void) tpm2_credit_random(c
.esys_context
);
1340 log_debug("Generating secret key data.");
1342 r
= crypto_random_bytes(hmac_sensitive
.sensitive
.data
.buffer
, hmac_sensitive
.sensitive
.data
.size
);
1344 log_error_errno(r
, "Failed to generate secret key: %m");
1348 log_debug("Creating HMAC key.");
1350 rc
= sym_Esys_Create(
1353 session
, /* use HMAC session to enable parameter encryption */
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
));
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
);
1378 log_debug("Marshalling private and public part of HMAC key.");
1380 k
= ALIGN8(sizeof(*private)) + ALIGN8(sizeof(*public)); /* Some roughly sensible start value */
1382 _cleanup_free_
void *buf
= NULL
;
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
);
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
));
1406 if (k
> SIZE_MAX
/ 2) {
1414 hash
= memdup(policy_digest
->buffer
, policy_digest
->size
);
1419 log_debug("Completed TPM2 key sealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - start
, 1));
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
;
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
);
1439 int tpm2_unseal(const char *device
,
1440 uint32_t hash_pcr_mask
,
1444 uint32_t pubkey_pcr_mask
,
1445 JsonVariant
*signature
,
1447 uint16_t primary_alg
,
1450 const void *known_policy_hash
,
1451 size_t known_policy_hash_size
,
1453 size_t *ret_secret_size
) {
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 = {};
1469 assert(blob_size
> 0);
1470 assert(known_policy_hash_size
== 0 || known_policy_hash
);
1471 assert(pubkey_size
== 0 || pubkey
);
1473 assert(ret_secret_size
);
1475 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask
));
1476 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask
));
1480 return log_error_errno(r
, "TPM2 support is not installed.");
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. */
1490 start
= now(CLOCK_MONOTONIC
);
1492 log_debug("Unmarshalling private part of HMAC key.");
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
));
1499 log_debug("Unmarshalling public part of HMAC key.");
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
));
1506 r
= tpm2_context_init(device
, &c
);
1510 r
= tpm2_make_primary(c
.esys_context
, &primary
, primary_alg
, NULL
);
1514 log_debug("Loading HMAC key into TPM.");
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.
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.");
1539 r
= log_error_errno(
1540 SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1541 "Failed to load HMAC key in TPM: %s",
1542 sym_Tss2_RC_Decode(rc
));
1546 r
= tpm2_make_encryption_session(c
.esys_context
, primary
, hmac_key
, pin
, &hmac_session
);
1550 r
= tpm2_make_policy_session(
1557 pubkey
, pubkey_size
,
1563 /* ret_pcr_bank= */ NULL
);
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.");
1575 log_debug("Unsealing HMAC key.");
1577 rc
= sym_Esys_Unseal(
1581 hmac_session
, /* use HMAC session to enable parameter encryption */
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
));
1590 secret
= memdup(unsealed
->buffer
, unsealed
->size
);
1591 explicit_bzero_safe(unsealed
->buffer
, unsealed
->size
);
1598 log_debug("Completed TPM2 key unsealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - start
, 1));
1600 *ret_secret
= TAKE_PTR(secret
);
1601 *ret_secret_size
= unsealed
->size
;
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
);
1614 int tpm2_list_devices(void) {
1616 _cleanup_(table_unrefp
) Table
*t
= NULL
;
1617 _cleanup_(closedirp
) DIR *d
= NULL
;
1622 return log_error_errno(r
, "TPM2 support is not installed.");
1624 t
= table_new("path", "device", "driver");
1628 d
= opendir("/sys/class/tpmrm");
1630 log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
, "Failed to open /sys/class/tpmrm: %m");
1631 if (errno
!= ENOENT
)
1635 _cleanup_free_
char *device_path
= NULL
, *device
= NULL
, *driver_path
= NULL
, *driver
= NULL
, *node
= NULL
;
1638 de
= readdir_no_dot(d
);
1642 device_path
= path_join("/sys/class/tpmrm", de
->d_name
, "device");
1646 r
= readlink_malloc(device_path
, &device
);
1648 log_debug_errno(r
, "Failed to read device symlink %s, ignoring: %m", device_path
);
1650 driver_path
= path_join(device_path
, "driver");
1654 r
= readlink_malloc(driver_path
, &driver
);
1656 log_debug_errno(r
, "Failed to read driver symlink %s, ignoring: %m", driver_path
);
1659 node
= path_join("/dev", de
->d_name
);
1666 TABLE_STRING
, device
? last_path_component(device
) : NULL
,
1667 TABLE_STRING
, driver
? last_path_component(driver
) : NULL
);
1669 return table_log_add_error(r
);
1673 if (table_get_rows(t
) <= 1) {
1674 log_info("No suitable TPM2 devices found.");
1678 r
= table_print(t
, stdout
);
1680 return log_error_errno(r
, "Failed to show device table: %m");
1684 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
1685 "TPM2 not supported on this build.");
1689 int tpm2_find_device_auto(
1690 int log_level
, /* log level when no device is found */
1693 _cleanup_(closedirp
) DIR *d
= NULL
;
1698 return log_error_errno(r
, "TPM2 support is not installed.");
1700 d
= opendir("/sys/class/tpmrm");
1702 log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
,
1703 "Failed to open /sys/class/tpmrm: %m");
1704 if (errno
!= ENOENT
)
1707 _cleanup_free_
char *node
= NULL
;
1712 de
= readdir_no_dot(d
);
1717 return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ
),
1718 "More than one TPM2 (tpmrm) device found.");
1720 node
= path_join("/dev", de
->d_name
);
1726 *ret
= TAKE_PTR(node
);
1731 return log_full_errno(log_level
, SYNTHETIC_ERRNO(ENODEV
), "No TPM2 (tpmrm) device found.");
1733 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
1734 "TPM2 not supported on this build.");
1738 int tpm2_parse_pcrs(const char *s
, uint32_t *ret
) {
1739 const char *p
= ASSERT_PTR(s
);
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. */
1754 _cleanup_free_
char *pcr
= NULL
;
1757 r
= extract_first_word(&p
, &pcr
, ",+", EXTRACT_DONT_COALESCE_SEPARATORS
);
1761 return log_error_errno(r
, "Failed to parse PCR list: %s", s
);
1763 r
= safe_atou(pcr
, &n
);
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
);
1770 mask
|= UINT32_C(1) << n
;
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;
1783 for (size_t i
= 0; i
< ELEMENTSOF(pcr_array
); i
++) {
1784 if ((pcr_mask
& (UINT32_C(1) << i
)) == 0)
1787 r
= json_variant_new_integer(pcr_array
+ n_pcrs
, i
);
1794 r
= json_variant_new_array(&a
, pcr_array
, n_pcrs
);
1803 json_variant_unref_many(pcr_array
, n_pcrs
);
1807 int tpm2_parse_pcr_json_array(JsonVariant
*v
, uint32_t *ret
) {
1811 if (!json_variant_is_array(v
))
1812 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PCR array is not a JSON array.");
1814 JSON_VARIANT_ARRAY_FOREACH(e
, v
) {
1817 if (!json_variant_is_unsigned(e
))
1818 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PCR is not an unsigned integer.");
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
);
1824 mask
|= UINT32_C(1) << u
;
1833 int tpm2_make_luks2_json(
1835 uint32_t hash_pcr_mask
,
1839 uint32_t pubkey_pcr_mask
,
1840 uint16_t primary_alg
,
1843 const void *policy_hash
,
1844 size_t policy_hash_size
,
1846 JsonVariant
**ret
) {
1848 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
, *hmj
= NULL
, *pkmj
= NULL
;
1849 _cleanup_free_
char *keyslot_as_string
= NULL
;
1852 assert(blob
|| blob_size
== 0);
1853 assert(policy_hash
|| policy_hash_size
== 0);
1854 assert(pubkey
|| pubkey_size
== 0);
1856 if (asprintf(&keyslot_as_string
, "%i", keyslot
) < 0)
1859 r
= tpm2_make_pcr_json_array(hash_pcr_mask
, &hmj
);
1863 if (pubkey_pcr_mask
!= 0) {
1864 r
= tpm2_make_pcr_json_array(pubkey_pcr_mask
, &pkmj
);
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. */
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
))));
1894 int tpm2_parse_luks2_json(
1897 uint32_t *ret_hash_pcr_mask
,
1898 uint16_t *ret_pcr_bank
,
1900 size_t *ret_pubkey_size
,
1901 uint32_t *ret_pubkey_pcr_mask
,
1902 uint16_t *ret_primary_alg
,
1904 size_t *ret_blob_size
,
1905 void **ret_policy_hash
,
1906 size_t *ret_policy_hash_size
,
1907 TPM2Flags
*ret_flags
) {
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;
1921 keyslot
= cryptsetup_get_keyslot_from_token(v
);
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
1926 log_debug_errno(keyslot
, "Failed to extract keyslot index from TPM2 JSON data token, skipping: %m");
1931 w
= json_variant_by_key(v
, "tpm2-pcrs");
1933 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 token data lacks 'tpm2-pcrs' field.");
1935 r
= tpm2_parse_pcr_json_array(w
, &hash_pcr_mask
);
1937 return log_debug_errno(r
, "Failed to parse TPM2 PCR mask: %m");
1939 /* The bank field is optional, since it was added in systemd 250 only. Before the bank was hardcoded
1941 w
= json_variant_by_key(v
, "tpm2-pcr-bank");
1943 /* The PCR bank field is optional */
1945 if (!json_variant_is_string(w
))
1946 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PCR bank is not a string.");
1948 r
= tpm2_pcr_bank_from_string(json_variant_string(w
));
1950 return log_debug_errno(r
, "TPM2 PCR bank invalid or not supported: %s", json_variant_string(w
));
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");
1959 /* The primary key algorithm is optional */
1961 if (!json_variant_is_string(w
))
1962 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 primary key algorithm is not a string.");
1964 r
= tpm2_primary_alg_from_string(json_variant_string(w
));
1966 return log_debug_errno(r
, "TPM2 primary key algorithm invalid or not supported: %s", json_variant_string(w
));
1971 w
= json_variant_by_key(v
, "tpm2-blob");
1973 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 token data lacks 'tpm2-blob' field.");
1975 r
= json_variant_unbase64(w
, &blob
, &blob_size
);
1977 return log_debug_errno(r
, "Invalid base64 data in 'tpm2-blob' field.");
1979 w
= json_variant_by_key(v
, "tpm2-policy-hash");
1981 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 token data lacks 'tpm2-policy-hash' field.");
1983 r
= json_variant_unhex(w
, &policy_hash
, &policy_hash_size
);
1985 return log_debug_errno(r
, "Invalid base64 data in 'tpm2-policy-hash' field.");
1987 w
= json_variant_by_key(v
, "tpm2-pin");
1989 if (!json_variant_is_boolean(w
))
1990 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PIN policy is not a boolean.");
1992 SET_FLAG(flags
, TPM2_FLAGS_USE_PIN
, json_variant_boolean(w
));
1995 w
= json_variant_by_key(v
, "tpm2_pubkey_pcrs");
1997 r
= tpm2_parse_pcr_json_array(w
, &pubkey_pcr_mask
);
2002 w
= json_variant_by_key(v
, "tpm2_pubkey");
2004 r
= json_variant_unbase64(w
, &pubkey
, &pubkey_size
);
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.");
2011 *ret_keyslot
= keyslot
;
2012 if (ret_hash_pcr_mask
)
2013 *ret_hash_pcr_mask
= hash_pcr_mask
;
2015 *ret_pcr_bank
= pcr_bank
;
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
;
2025 *ret_blob
= TAKE_PTR(blob
);
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
;
2038 const char *tpm2_pcr_bank_to_string(uint16_t bank
) {
2039 if (bank
== TPM2_ALG_SHA1
)
2041 if (bank
== TPM2_ALG_SHA256
)
2043 if (bank
== TPM2_ALG_SHA384
)
2045 if (bank
== TPM2_ALG_SHA512
)
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
;
2062 const char *tpm2_primary_alg_to_string(uint16_t alg
) {
2063 if (alg
== TPM2_ALG_ECC
)
2065 if (alg
== TPM2_ALG_RSA
)
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
;
2078 Tpm2Support
tpm2_support(void) {
2079 Tpm2Support support
= TPM2_SUPPORT_NONE
;
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. */
2087 r
= dir_is_empty("/sys/class/tpmrm", /* ignore_hidden_or_backup= */ false);
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
;
2096 support
|= TPM2_SUPPORT_FIRMWARE
;
2099 support
|= TPM2_SUPPORT_SYSTEM
;
2105 int tpm2_parse_pcr_argument(const char *arg
, uint32_t *mask
) {
2111 /* For use in getopt_long() command line parsers: merges masks specified on the command line */
2118 r
= tpm2_parse_pcrs(arg
, &m
);
2122 if (*mask
== UINT32_MAX
)
2130 int tpm2_load_pcr_signature(const char *path
, JsonVariant
**ret
) {
2131 _cleanup_free_
char *discovered_path
= NULL
;
2132 _cleanup_fclose_
FILE *f
= NULL
;
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. */
2139 path
= "tpm2-pcr-signature.json";
2141 r
= search_and_fopen(path
, "re", NULL
, (const char**) CONF_PATHS_STRV("systemd"), &f
, &discovered_path
);
2143 return log_debug_errno(r
, "Failed to find TPM PCR signature file '%s': %m", path
);
2145 r
= json_parse_file(f
, discovered_path
, 0, ret
, NULL
, NULL
);
2147 return log_debug_errno(r
, "Failed to parse TPM PCR signature JSON object '%s': %m", discovered_path
);
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
;
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. */
2161 path
= "tpm2-pcr-public-key.pem";
2163 r
= search_and_fopen(path
, "re", NULL
, (const char**) CONF_PATHS_STRV("systemd"), &f
, &discovered_path
);
2165 return log_debug_errno(r
, "Failed to find TPM PCR public key file '%s': %m", path
);
2167 r
= read_full_stream(f
, (char**) ret_pubkey
, ret_pubkey_size
);
2169 return log_debug_errno(r
, "Failed to load TPM PCR public key PEM file '%s': %m", discovered_path
);
2174 int pcr_mask_to_string(uint32_t mask
, char **ret
) {
2175 _cleanup_free_
char *buf
= NULL
;
2180 for (unsigned i
= 0; i
< TPM2_PCRS_MAX
; i
++) {
2181 if (!(mask
& (UINT32_C(1) << i
)))
2184 r
= strextendf_with_separator(&buf
, "+", "%u", i
);
2189 *ret
= TAKE_PTR(buf
);