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_Extend
)(ESYS_CONTEXT
*esysContext
, ESYS_TR pcrHandle
, ESYS_TR shandle1
, ESYS_TR shandle2
, ESYS_TR shandle3
, const TPML_DIGEST_VALUES
*digests
);
41 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
);
42 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
);
43 TSS2_RC (*sym_Esys_PolicyAuthValue
)(ESYS_CONTEXT
*esysContext
, ESYS_TR policySession
, ESYS_TR shandle1
, ESYS_TR shandle2
, ESYS_TR shandle3
) = NULL
;
44 TSS2_RC (*sym_Esys_PolicyGetDigest
)(ESYS_CONTEXT
*esysContext
, ESYS_TR policySession
, ESYS_TR shandle1
, ESYS_TR shandle2
, ESYS_TR shandle3
, TPM2B_DIGEST
**policyDigest
) = NULL
;
45 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
;
46 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
;
47 TSS2_RC (*sym_Esys_Startup
)(ESYS_CONTEXT
*esysContext
, TPM2_SU startupType
) = NULL
;
48 TSS2_RC (*sym_Esys_TRSess_SetAttributes
)(ESYS_CONTEXT
*esysContext
, ESYS_TR session
, TPMA_SESSION flags
, TPMA_SESSION mask
);
49 TSS2_RC (*sym_Esys_TR_GetName
)(ESYS_CONTEXT
*esysContext
, ESYS_TR handle
, TPM2B_NAME
**name
);
50 TSS2_RC (*sym_Esys_TR_SetAuth
)(ESYS_CONTEXT
*esysContext
, ESYS_TR handle
, TPM2B_AUTH
const *authValue
) = NULL
;
51 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
;
52 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
);
54 const char* (*sym_Tss2_RC_Decode
)(TSS2_RC rc
) = NULL
;
56 TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Marshal
)(TPM2B_PRIVATE
const *src
, uint8_t buffer
[], size_t buffer_size
, size_t *offset
) = NULL
;
57 TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal
)(uint8_t const buffer
[], size_t buffer_size
, size_t *offset
, TPM2B_PRIVATE
*dest
) = NULL
;
58 TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Marshal
)(TPM2B_PUBLIC
const *src
, uint8_t buffer
[], size_t buffer_size
, size_t *offset
) = NULL
;
59 TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal
)(uint8_t const buffer
[], size_t buffer_size
, size_t *offset
, TPM2B_PUBLIC
*dest
) = NULL
;
61 int dlopen_tpm2(void) {
64 r
= dlopen_many_sym_or_warn(
65 &libtss2_esys_dl
, "libtss2-esys.so.0", LOG_DEBUG
,
66 DLSYM_ARG(Esys_Create
),
67 DLSYM_ARG(Esys_CreatePrimary
),
68 DLSYM_ARG(Esys_Finalize
),
69 DLSYM_ARG(Esys_FlushContext
),
71 DLSYM_ARG(Esys_GetCapability
),
72 DLSYM_ARG(Esys_GetRandom
),
73 DLSYM_ARG(Esys_Initialize
),
75 DLSYM_ARG(Esys_LoadExternal
),
76 DLSYM_ARG(Esys_PCR_Extend
),
77 DLSYM_ARG(Esys_PCR_Read
),
78 DLSYM_ARG(Esys_PolicyAuthorize
),
79 DLSYM_ARG(Esys_PolicyAuthValue
),
80 DLSYM_ARG(Esys_PolicyGetDigest
),
81 DLSYM_ARG(Esys_PolicyPCR
),
82 DLSYM_ARG(Esys_StartAuthSession
),
83 DLSYM_ARG(Esys_Startup
),
84 DLSYM_ARG(Esys_TRSess_SetAttributes
),
85 DLSYM_ARG(Esys_TR_GetName
),
86 DLSYM_ARG(Esys_TR_SetAuth
),
87 DLSYM_ARG(Esys_Unseal
),
88 DLSYM_ARG(Esys_VerifySignature
));
92 r
= dlopen_many_sym_or_warn(
93 &libtss2_rc_dl
, "libtss2-rc.so.0", LOG_DEBUG
,
94 DLSYM_ARG(Tss2_RC_Decode
));
98 return dlopen_many_sym_or_warn(
99 &libtss2_mu_dl
, "libtss2-mu.so.0", LOG_DEBUG
,
100 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Marshal
),
101 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Unmarshal
),
102 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Marshal
),
103 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Unmarshal
));
106 void tpm2_context_destroy(struct tpm2_context
*c
) {
110 sym_Esys_Finalize(&c
->esys_context
);
112 c
->tcti_context
= mfree(c
->tcti_context
);
120 static inline void Esys_Finalize_wrapper(ESYS_CONTEXT
**c
) {
121 /* A wrapper around Esys_Finalize() for use with _cleanup_(). Only reasons we need this wrapper is
122 * because the function itself warn logs if we'd pass a pointer to NULL, and we don't want that. */
124 sym_Esys_Finalize(c
);
127 ESYS_TR
tpm2_flush_context_verbose(ESYS_CONTEXT
*c
, ESYS_TR handle
) {
130 if (!c
|| handle
== ESYS_TR_NONE
)
133 rc
= sym_Esys_FlushContext(c
, handle
);
134 if (rc
!= TSS2_RC_SUCCESS
) /* We ignore failures here (besides debug logging), since this is called
135 * in error paths, where we cannot do anything about failures anymore. And
136 * when it is called in successful codepaths by this time we already did
137 * what we wanted to do, and got the results we wanted so there's no
138 * reason to make this fail more loudly than necessary. */
139 log_debug("Failed to get flush context of TPM, ignoring: %s", sym_Tss2_RC_Decode(rc
));
144 int tpm2_context_init(const char *device
, struct tpm2_context
*ret
) {
145 _cleanup_(Esys_Finalize_wrapper
) ESYS_CONTEXT
*c
= NULL
;
146 _cleanup_free_ TSS2_TCTI_CONTEXT
*tcti
= NULL
;
147 _cleanup_(dlclosep
) void *dl
= NULL
;
153 return log_error_errno(r
, "TPM2 support not installed: %m");
156 device
= secure_getenv("SYSTEMD_TPM2_DEVICE");
159 const char *param
, *driver
, *fn
;
160 const TSS2_TCTI_INFO
* info
;
161 TSS2_TCTI_INFO_FUNC func
;
164 param
= strchr(device
, ':');
166 driver
= strndupa_safe(device
, param
- device
);
173 fn
= strjoina("libtss2-tcti-", driver
, ".so.0");
175 dl
= dlopen(fn
, RTLD_NOW
);
177 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "Failed to load %s: %s", fn
, dlerror());
179 func
= dlsym(dl
, TSS2_TCTI_INFO_SYMBOL
);
181 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
182 "Failed to find TCTI info symbol " TSS2_TCTI_INFO_SYMBOL
": %s",
187 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "Unable to get TCTI info data.");
190 log_debug("Loaded TCTI module '%s' (%s) [Version %" PRIu32
"]", info
->name
, info
->description
, info
->version
);
192 rc
= info
->init(NULL
, &sz
, NULL
);
193 if (rc
!= TPM2_RC_SUCCESS
)
194 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
195 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc
));
201 rc
= info
->init(tcti
, &sz
, param
);
202 if (rc
!= TPM2_RC_SUCCESS
)
203 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
204 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc
));
207 rc
= sym_Esys_Initialize(&c
, tcti
, NULL
);
208 if (rc
!= TSS2_RC_SUCCESS
)
209 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
210 "Failed to initialize TPM context: %s", sym_Tss2_RC_Decode(rc
));
212 rc
= sym_Esys_Startup(c
, TPM2_SU_CLEAR
);
213 if (rc
== TPM2_RC_INITIALIZE
)
214 log_debug("TPM already started up.");
215 else if (rc
== TSS2_RC_SUCCESS
)
216 log_debug("TPM successfully started up.");
218 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
219 "Failed to start up TPM: %s", sym_Tss2_RC_Decode(rc
));
221 *ret
= (struct tpm2_context
) {
222 .esys_context
= TAKE_PTR(c
),
223 .tcti_context
= TAKE_PTR(tcti
),
224 .tcti_dl
= TAKE_PTR(dl
),
230 #define TPM2_CREDIT_RANDOM_FLAG_PATH "/run/systemd/tpm-rng-credited"
232 static int tpm2_credit_random(ESYS_CONTEXT
*c
) {
233 size_t rps
, done
= 0;
240 /* Pulls some entropy from the TPM and adds it into the kernel RNG pool. That way we can say that the
241 * key we will ultimately generate with the kernel random pool is at least as good as the TPM's RNG,
242 * but likely better. Note that we don't trust the TPM RNG very much, hence do not actually credit
245 if (access(TPM2_CREDIT_RANDOM_FLAG_PATH
, F_OK
) < 0) {
247 log_debug_errno(errno
, "Failed to detect if '" TPM2_CREDIT_RANDOM_FLAG_PATH
"' exists, ignoring: %m");
249 log_debug("Not adding TPM2 entropy to the kernel random pool again.");
250 return 0; /* Already done */
253 t
= now(CLOCK_MONOTONIC
);
255 for (rps
= random_pool_size(); rps
> 0;) {
256 _cleanup_(Esys_Freep
) TPM2B_DIGEST
*buffer
= NULL
;
258 rc
= sym_Esys_GetRandom(
263 MIN(rps
, 32U), /* 32 is supposedly a safe choice, given that AES 256bit keys are this long, and TPM2 baseline requires support for those. */
265 if (rc
!= TSS2_RC_SUCCESS
)
266 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
267 "Failed to acquire entropy from TPM: %s", sym_Tss2_RC_Decode(rc
));
269 if (buffer
->size
== 0)
270 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
271 "Zero-sized entropy returned from TPM.");
273 r
= random_write_entropy(-1, buffer
->buffer
, buffer
->size
, /* credit= */ false);
275 return log_error_errno(r
, "Failed wo write entropy to kernel: %m");
277 done
+= buffer
->size
;
278 rps
= LESS_BY(rps
, buffer
->size
);
281 log_debug("Added %zu bytes of TPM2 entropy to the kernel random pool in %s.", done
, FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - t
, 0));
283 r
= touch(TPM2_CREDIT_RANDOM_FLAG_PATH
);
285 log_debug_errno(r
, "Failed to touch '" TPM2_CREDIT_RANDOM_FLAG_PATH
"', ignoring: %m");
290 static int tpm2_make_primary(
292 ESYS_TR
*ret_primary
,
294 TPMI_ALG_PUBLIC
*ret_alg
) {
296 static const TPM2B_SENSITIVE_CREATE primary_sensitive
= {};
297 static const TPM2B_PUBLIC primary_template_ecc
= {
298 .size
= sizeof(TPMT_PUBLIC
),
300 .type
= TPM2_ALG_ECC
,
301 .nameAlg
= TPM2_ALG_SHA256
,
302 .objectAttributes
= TPMA_OBJECT_RESTRICTED
|TPMA_OBJECT_DECRYPT
|TPMA_OBJECT_FIXEDTPM
|TPMA_OBJECT_FIXEDPARENT
|TPMA_OBJECT_SENSITIVEDATAORIGIN
|TPMA_OBJECT_USERWITHAUTH
,
303 .parameters
.eccDetail
= {
305 .algorithm
= TPM2_ALG_AES
,
307 .mode
.aes
= TPM2_ALG_CFB
,
309 .scheme
.scheme
= TPM2_ALG_NULL
,
310 .curveID
= TPM2_ECC_NIST_P256
,
311 .kdf
.scheme
= TPM2_ALG_NULL
,
315 static const TPM2B_PUBLIC primary_template_rsa
= {
316 .size
= sizeof(TPMT_PUBLIC
),
318 .type
= TPM2_ALG_RSA
,
319 .nameAlg
= TPM2_ALG_SHA256
,
320 .objectAttributes
= TPMA_OBJECT_RESTRICTED
|TPMA_OBJECT_DECRYPT
|TPMA_OBJECT_FIXEDTPM
|TPMA_OBJECT_FIXEDPARENT
|TPMA_OBJECT_SENSITIVEDATAORIGIN
|TPMA_OBJECT_USERWITHAUTH
,
321 .parameters
.rsaDetail
= {
323 .algorithm
= TPM2_ALG_AES
,
325 .mode
.aes
= TPM2_ALG_CFB
,
327 .scheme
.scheme
= TPM2_ALG_NULL
,
333 static const TPML_PCR_SELECTION creation_pcr
= {};
334 ESYS_TR primary
= ESYS_TR_NONE
;
338 log_debug("Creating primary key on TPM.");
340 /* So apparently not all TPM2 devices support ECC. ECC is generally preferably, because it's so much
341 * faster, noticeably so (~10s vs. ~240ms on my system). Hence, unless explicitly configured let's
342 * try to use ECC first, and if that does not work, let's fall back to RSA. */
344 ts
= now(CLOCK_MONOTONIC
);
346 if (IN_SET(alg
, 0, TPM2_ALG_ECC
)) {
347 rc
= sym_Esys_CreatePrimary(
354 &primary_template_ecc
,
363 if (rc
!= TSS2_RC_SUCCESS
) {
365 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
366 "Failed to generate ECC primary key in TPM: %s", sym_Tss2_RC_Decode(rc
));
368 log_debug("Failed to generate ECC primary key in TPM, trying RSA: %s", sym_Tss2_RC_Decode(rc
));
370 log_debug("Successfully created ECC primary key on TPM.");
375 if (IN_SET(alg
, 0, TPM2_ALG_RSA
)) {
376 rc
= sym_Esys_CreatePrimary(
383 &primary_template_rsa
,
391 if (rc
!= TSS2_RC_SUCCESS
)
392 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
393 "Failed to generate RSA primary key in TPM: %s", sym_Tss2_RC_Decode(rc
));
395 log_notice("TPM2 chip apparently does not support ECC primary keys, falling back to RSA. "
396 "This likely means TPM2 operations will be relatively slow, please be patient.");
400 log_debug("Successfully created RSA primary key on TPM.");
403 log_debug("Generating primary key on TPM2 took %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - ts
, USEC_PER_MSEC
));
405 *ret_primary
= primary
;
412 void tpm2_pcr_mask_to_selection(uint32_t mask
, uint16_t bank
, TPML_PCR_SELECTION
*ret
) {
415 /* We only do 24bit here, as that's what PC TPMs are supposed to support */
416 assert(mask
<= 0xFFFFFFU
);
418 *ret
= (TPML_PCR_SELECTION
) {
420 .pcrSelections
[0] = {
423 .pcrSelect
[0] = mask
& 0xFF,
424 .pcrSelect
[1] = (mask
>> 8) & 0xFF,
425 .pcrSelect
[2] = (mask
>> 16) & 0xFF,
430 static unsigned find_nth_bit(uint32_t mask
, unsigned n
) {
435 /* Returns the bit index of the nth set bit, e.g. mask=0b101001, n=3 → 5 */
437 for (unsigned i
= 0; i
< sizeof(mask
)*8; i
++) {
452 static int tpm2_pcr_mask_good(
457 _cleanup_(Esys_Freep
) TPML_DIGEST
*pcr_values
= NULL
;
458 TPML_PCR_SELECTION selection
;
464 /* So we have the problem that some systems might have working TPM2 chips, but the firmware doesn't
465 * actually measure into them, or only into a suboptimal bank. If so, the PCRs should be all zero or
466 * all 0xFF. Detect that, so that we can warn and maybe pick a better bank. */
468 tpm2_pcr_mask_to_selection(mask
, bank
, &selection
);
470 rc
= sym_Esys_PCR_Read(
479 if (rc
!= TSS2_RC_SUCCESS
)
480 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
481 "Failed to read TPM2 PCRs: %s", sym_Tss2_RC_Decode(rc
));
483 /* If at least one of the selected PCR values is something other than all 0x00 or all 0xFF we are happy. */
484 for (unsigned i
= 0; i
< pcr_values
->count
; i
++) {
486 _cleanup_free_
char *h
= NULL
;
489 h
= hexmem(pcr_values
->digests
[i
].buffer
, pcr_values
->digests
[i
].size
);
490 j
= find_nth_bit(mask
, i
);
491 assert(j
!= UINT_MAX
);
493 log_debug("PCR %u value: %s", j
, strna(h
));
496 if (!memeqbyte(0x00, pcr_values
->digests
[i
].buffer
, pcr_values
->digests
[i
].size
) &&
497 !memeqbyte(0xFF, pcr_values
->digests
[i
].buffer
, pcr_values
->digests
[i
].size
))
504 static int tpm2_bank_has24(const TPMS_PCR_SELECTION
*selection
) {
508 /* As per https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_PFP_r1p05_v23_pub.pdf a
509 * TPM2 on a Client PC must have at least 24 PCRs. If this TPM has less, just skip over it. */
510 if (selection
->sizeofSelect
< TPM2_PCRS_MAX
/8) {
511 log_debug("Skipping TPM2 PCR bank %s with fewer than 24 PCRs.",
512 strna(tpm2_pcr_bank_to_string(selection
->hash
)));
516 assert_cc(TPM2_PCRS_MAX
% 8 == 0);
518 /* It's not enough to check how many PCRs there are, we also need to check that the 24 are
519 * enabled for this bank. Otherwise this TPM doesn't qualify. */
521 for (size_t j
= 0; j
< TPM2_PCRS_MAX
/8; j
++)
522 if (selection
->pcrSelect
[j
] != 0xFF) {
528 log_debug("TPM2 PCR bank %s has fewer than 24 PCR bits enabled, ignoring.",
529 strna(tpm2_pcr_bank_to_string(selection
->hash
)));
534 static int tpm2_get_best_pcr_bank(
537 TPMI_ALG_HASH
*ret
) {
539 _cleanup_(Esys_Freep
) TPMS_CAPABILITY_DATA
*pcap
= NULL
;
540 TPMI_ALG_HASH supported_hash
= 0, hash_with_valid_pcr
= 0;
547 rc
= sym_Esys_GetCapability(
557 if (rc
!= TSS2_RC_SUCCESS
)
558 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
559 "Failed to determine TPM2 PCR bank capabilities: %s", sym_Tss2_RC_Decode(rc
));
561 assert(pcap
->capability
== TPM2_CAP_PCRS
);
563 for (size_t i
= 0; i
< pcap
->data
.assignedPCR
.count
; i
++) {
566 /* For now we are only interested in the SHA1 and SHA256 banks */
567 if (!IN_SET(pcap
->data
.assignedPCR
.pcrSelections
[i
].hash
, TPM2_ALG_SHA256
, TPM2_ALG_SHA1
))
570 r
= tpm2_bank_has24(pcap
->data
.assignedPCR
.pcrSelections
+ i
);
576 good
= tpm2_pcr_mask_good(c
, pcap
->data
.assignedPCR
.pcrSelections
[i
].hash
, pcr_mask
);
580 if (pcap
->data
.assignedPCR
.pcrSelections
[i
].hash
== TPM2_ALG_SHA256
) {
581 supported_hash
= TPM2_ALG_SHA256
;
583 /* Great, SHA256 is supported and has initialized PCR values, we are done. */
584 hash_with_valid_pcr
= TPM2_ALG_SHA256
;
588 assert(pcap
->data
.assignedPCR
.pcrSelections
[i
].hash
== TPM2_ALG_SHA1
);
590 if (supported_hash
== 0)
591 supported_hash
= TPM2_ALG_SHA1
;
593 if (good
&& hash_with_valid_pcr
== 0)
594 hash_with_valid_pcr
= TPM2_ALG_SHA1
;
598 /* We preferably pick SHA256, but only if its PCRs are initialized or neither the SHA1 nor the SHA256
599 * PCRs are initialized. If SHA256 is not supported but SHA1 is and its PCRs are too, we prefer
602 * We log at LOG_NOTICE level whenever we end up using the SHA1 bank or when the PCRs we bind to are
603 * not initialized. */
605 if (hash_with_valid_pcr
== TPM2_ALG_SHA256
) {
606 assert(supported_hash
== TPM2_ALG_SHA256
);
607 log_debug("TPM2 device supports SHA256 PCR bank and SHA256 PCRs are valid, yay!");
608 *ret
= TPM2_ALG_SHA256
;
609 } else if (hash_with_valid_pcr
== TPM2_ALG_SHA1
) {
610 if (supported_hash
== TPM2_ALG_SHA256
)
611 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.");
613 assert(supported_hash
== TPM2_ALG_SHA1
);
614 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.");
617 *ret
= TPM2_ALG_SHA1
;
618 } else if (supported_hash
== TPM2_ALG_SHA256
) {
619 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!");
620 *ret
= TPM2_ALG_SHA256
;
621 } else if (supported_hash
== TPM2_ALG_SHA1
) {
622 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!");
623 *ret
= TPM2_ALG_SHA1
;
625 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
626 "TPM2 module supports neither SHA1 nor SHA256 PCR banks, cannot operate.");
631 static void hash_pin(const char *pin
, size_t len
, TPM2B_AUTH
*auth
) {
632 struct sha256_ctx hash
;
636 auth
->size
= SHA256_DIGEST_SIZE
;
638 sha256_init_ctx(&hash
);
639 sha256_process_bytes(pin
, len
, &hash
);
640 sha256_finish_ctx(&hash
, auth
->buffer
);
642 explicit_bzero_safe(&hash
, sizeof(hash
));
645 static int tpm2_make_encryption_session(
650 ESYS_TR
*ret_session
) {
652 static const TPMT_SYM_DEF symmetric
= {
653 .algorithm
= TPM2_ALG_AES
,
655 .mode
.aes
= TPM2_ALG_CFB
,
657 const TPMA_SESSION sessionAttributes
= TPMA_SESSION_DECRYPT
| TPMA_SESSION_ENCRYPT
|
658 TPMA_SESSION_CONTINUESESSION
;
659 ESYS_TR session
= ESYS_TR_NONE
;
665 * if a pin is set for the seal object, use it to bind the session
666 * key to that object. This prevents active bus interposers from
667 * faking a TPM and seeing the unsealed value. An active interposer
668 * could fake a TPM, satisfying the encrypted session, and just
669 * forward everything to the *real* TPM.
672 TPM2B_AUTH auth
= {};
674 hash_pin(pin
, strlen(pin
), &auth
);
676 rc
= sym_Esys_TR_SetAuth(c
, bind_key
, &auth
);
677 /* ESAPI knows about it, so clear it from our memory */
678 explicit_bzero_safe(&auth
, sizeof(auth
));
679 if (rc
!= TSS2_RC_SUCCESS
)
680 return log_error_errno(
681 SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
682 "Failed to load PIN in TPM: %s",
683 sym_Tss2_RC_Decode(rc
));
686 log_debug("Starting HMAC encryption session.");
688 /* Start a salted, unbound HMAC session with a well-known key (e.g. primary key) as tpmKey, which
689 * means that the random salt will be encrypted with the well-known key. That way, only the TPM can
690 * recover the salt, which is then used for key derivation. */
691 rc
= sym_Esys_StartAuthSession(
703 if (rc
!= TSS2_RC_SUCCESS
)
704 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
705 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc
));
707 /* Enable parameter encryption/decryption with AES in CFB mode. Together with HMAC digests (which are
708 * always used for sessions), this provides confidentiality, integrity and replay protection for
709 * operations that use this session. */
710 rc
= sym_Esys_TRSess_SetAttributes(c
, session
, sessionAttributes
, 0xff);
711 if (rc
!= TSS2_RC_SUCCESS
)
712 return log_error_errno(
713 SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
714 "Failed to configure TPM session: %s",
715 sym_Tss2_RC_Decode(rc
));
718 *ret_session
= session
;
719 session
= ESYS_TR_NONE
;
722 session
= tpm2_flush_context_verbose(c
, session
);
726 static int openssl_pubkey_to_tpm2_pubkey(EVP_PKEY
*input
, TPM2B_PUBLIC
*output
) {
727 #if OPENSSL_VERSION_MAJOR >= 3
728 _cleanup_(BN_freep
) BIGNUM
*n
= NULL
, *e
= NULL
;
730 const BIGNUM
*n
= NULL
, *e
= NULL
;
731 const RSA
*rsa
= NULL
;
733 int n_bytes
, e_bytes
;
738 /* Converts an OpenSSL public key to a structure that the TPM chip can process. */
740 if (EVP_PKEY_base_id(input
) != EVP_PKEY_RSA
)
741 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Provided public key is not an RSA key.");
743 #if OPENSSL_VERSION_MAJOR >= 3
744 if (!EVP_PKEY_get_bn_param(input
, OSSL_PKEY_PARAM_RSA_N
, &n
))
745 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to get RSA modulus from public key.");
747 rsa
= EVP_PKEY_get0_RSA(input
);
749 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to extract RSA key from public key.");
753 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to get RSA modulus from public key.");
756 n_bytes
= BN_num_bytes(n
);
757 assert_se(n_bytes
> 0);
758 if ((size_t) n_bytes
> sizeof_field(TPM2B_PUBLIC
, publicArea
.unique
.rsa
.buffer
))
759 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "RSA modulus too large for TPM2 public key object.");
761 #if OPENSSL_VERSION_MAJOR >= 3
762 if (!EVP_PKEY_get_bn_param(input
, OSSL_PKEY_PARAM_RSA_E
, &e
))
763 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to get RSA exponent from public key.");
767 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to get RSA exponent from public key.");
770 e_bytes
= BN_num_bytes(e
);
771 assert_se(e_bytes
> 0);
772 if ((size_t) e_bytes
> sizeof_field(TPM2B_PUBLIC
, publicArea
.parameters
.rsaDetail
.exponent
))
773 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "RSA exponent too large for TPM2 public key object.");
775 *output
= (TPM2B_PUBLIC
) {
776 .size
= sizeof(TPMT_PUBLIC
),
778 .type
= TPM2_ALG_RSA
,
779 .nameAlg
= TPM2_ALG_SHA256
,
780 .objectAttributes
= TPMA_OBJECT_DECRYPT
| TPMA_OBJECT_SIGN_ENCRYPT
| TPMA_OBJECT_USERWITHAUTH
,
781 .parameters
.rsaDetail
= {
783 .scheme
= TPM2_ALG_NULL
,
784 .details
.anySig
.hashAlg
= TPM2_ALG_NULL
,
787 .algorithm
= TPM2_ALG_NULL
,
788 .mode
.sym
= TPM2_ALG_NULL
,
790 .keyBits
= n_bytes
* 8,
791 /* .exponent will be filled in below. */
795 /* .rsa.buffer will be filled in below. */
800 if (BN_bn2bin(n
, output
->publicArea
.unique
.rsa
.buffer
) <= 0)
801 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to convert RSA modulus.");
803 if (BN_bn2bin(e
, (unsigned char*) &output
->publicArea
.parameters
.rsaDetail
.exponent
) <= 0)
804 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to convert RSA exponent.");
809 static int find_signature(
817 size_t *ret_signature_size
) {
819 _cleanup_free_
void *fp
= NULL
;
825 /* Searches for a signature blob in the specified JSON object. Search keys are PCR bank, PCR mask,
826 * public key, and policy digest. */
828 if (!json_variant_is_object(v
))
829 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Signature is not a JSON object.");
831 k
= tpm2_pcr_bank_to_string(pcr_bank
);
833 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
), "Don't know PCR bank %" PRIu16
, pcr_bank
);
835 /* First, find field by bank */
836 b
= json_variant_by_key(v
, k
);
838 return log_error_errno(SYNTHETIC_ERRNO(ENXIO
), "Signature lacks data for PCR bank '%s'.", k
);
840 if (!json_variant_is_array(b
))
841 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Bank data is not a JSON array.");
843 /* Now iterate through all signatures known for this bank */
844 JSON_VARIANT_ARRAY_FOREACH(i
, b
) {
845 _cleanup_free_
void *fpj_data
= NULL
, *polj_data
= NULL
;
846 JsonVariant
*maskj
, *fpj
, *sigj
, *polj
;
847 size_t fpj_size
, polj_size
;
848 uint32_t parsed_mask
;
850 if (!json_variant_is_object(i
))
851 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Bank data element is not a JSON object");
853 /* Check if the PCR mask matches our expectations */
854 maskj
= json_variant_by_key(i
, "pcrs");
858 r
= tpm2_parse_pcr_json_array(maskj
, &parsed_mask
);
860 return log_error_errno(r
, "Failed to parse JSON PCR mask");
862 if (parsed_mask
!= pcr_mask
)
863 continue; /* Not for this PCR mask */
865 /* Then check if this is for the public key we operate with */
866 fpj
= json_variant_by_key(i
, "pkfp");
870 r
= json_variant_unhex(fpj
, &fpj_data
, &fpj_size
);
872 return log_error_errno(r
, "Failed to decode fingerprint in JSON data: %m");
875 r
= pubkey_fingerprint(pk
, EVP_sha256(), &fp
, &fp_size
);
877 return log_error_errno(r
, "Failed to calculate public key fingerprint: %m");
880 if (memcmp_nn(fp
, fp_size
, fpj_data
, fpj_size
) != 0)
881 continue; /* Not for this public key */
883 /* Finally, check if this is for the PCR policy we expect this to be */
884 polj
= json_variant_by_key(i
, "pol");
888 r
= json_variant_unhex(polj
, &polj_data
, &polj_size
);
890 return log_error_errno(r
, "Failed to decode policy hash JSON data: %m");
892 if (memcmp_nn(policy
, policy_size
, polj_data
, polj_size
) != 0)
895 /* This entry matches all our expectations, now return the signature included in it */
896 sigj
= json_variant_by_key(i
, "sig");
900 return json_variant_unbase64(sigj
, ret_signature
, ret_signature_size
);
903 return log_error_errno(SYNTHETIC_ERRNO(ENXIO
), "Couldn't find signature for this PCR bank, PCR index and public key.");
906 static int tpm2_make_policy_session(
909 ESYS_TR parent_session
,
910 TPM2_SE session_type
,
911 uint32_t hash_pcr_mask
,
912 uint16_t pcr_bank
, /* If UINT16_MAX, pick best bank automatically, otherwise specify bank explicitly. */
915 uint32_t pubkey_pcr_mask
,
916 JsonVariant
*signature_json
,
918 ESYS_TR
*ret_session
,
919 TPM2B_DIGEST
**ret_policy_digest
,
920 TPMI_ALG_HASH
*ret_pcr_bank
) {
922 static const TPMT_SYM_DEF symmetric
= {
923 .algorithm
= TPM2_ALG_AES
,
925 .mode
.aes
= TPM2_ALG_CFB
,
927 _cleanup_(Esys_Freep
) TPM2B_DIGEST
*policy_digest
= NULL
;
928 ESYS_TR session
= ESYS_TR_NONE
, pubkey_handle
= ESYS_TR_NONE
;
929 _cleanup_(EVP_PKEY_freep
) EVP_PKEY
*pk
= NULL
;
934 assert(pubkey
|| pubkey_size
== 0);
935 assert(pubkey_pcr_mask
== 0 || pubkey_size
> 0);
937 log_debug("Starting authentication session.");
939 /* So apparently some TPM implementations don't implement trial mode correctly. To avoid issues let's
940 * avoid it when it is easy to. At the moment we only really need trial mode for the signed PCR
941 * policies (since only then we need to shove PCR values into the policy that don't match current
942 * state anyway), hence if we have none of those we don't need to bother. Hence, let's patch in
943 * TPM2_SE_POLICY even if trial mode is requested unless a pubkey PCR mask is specified that is
944 * non-zero, i.e. signed PCR policy is requested.
946 * One day we should switch to calculating policy hashes client side when trial mode is requested, to
947 * avoid this mess. */
948 if (session_type
== TPM2_SE_TRIAL
&& pubkey_pcr_mask
== 0)
949 session_type
= TPM2_SE_POLICY
;
951 if ((hash_pcr_mask
| pubkey_pcr_mask
) != 0) {
952 /* We are told to configure a PCR policy of some form, let's determine/validate the PCR bank to use. */
954 if (pcr_bank
!= UINT16_MAX
) {
955 r
= tpm2_pcr_mask_good(c
, pcr_bank
, hash_pcr_mask
|pubkey_pcr_mask
);
959 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.");
961 /* No bank configured, pick automatically. Some TPM2 devices only can do SHA1. If we
962 * detect that use that, but preferably use SHA256 */
963 r
= tpm2_get_best_pcr_bank(c
, hash_pcr_mask
|pubkey_pcr_mask
, &pcr_bank
);
969 if (pubkey_size
> 0) {
970 /* 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. */
971 _cleanup_fclose_
FILE *f
= fmemopen((void*) pubkey
, pubkey_size
, "r");
975 pk
= PEM_read_PUBKEY(f
, NULL
, NULL
, NULL
);
977 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to parse PEM public key.");
980 rc
= sym_Esys_StartAuthSession(
992 if (rc
!= TSS2_RC_SUCCESS
)
993 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
994 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc
));
996 if (pubkey_pcr_mask
!= 0) {
997 log_debug("Configuring public key based PCR policy.");
999 /* First: load public key into the TPM */
1000 TPM2B_PUBLIC pubkey_tpm2
;
1001 r
= openssl_pubkey_to_tpm2_pubkey(pk
, &pubkey_tpm2
);
1005 rc
= sym_Esys_LoadExternal(
1014 if (rc
!= TSS2_RC_SUCCESS
) {
1015 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1016 "Failed to load public key into TPM: %s", sym_Tss2_RC_Decode(rc
));
1020 /* Acquire the "name" of what we just loaded */
1021 _cleanup_(Esys_Freep
) TPM2B_NAME
*pubkey_name
= NULL
;
1022 rc
= sym_Esys_TR_GetName(
1026 if (rc
!= TSS2_RC_SUCCESS
) {
1027 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1028 "Failed to get name of public key from TPM: %s", sym_Tss2_RC_Decode(rc
));
1032 /* Put together the PCR policy we want to use */
1033 TPML_PCR_SELECTION pcr_selection
;
1034 tpm2_pcr_mask_to_selection(pubkey_pcr_mask
, pcr_bank
, &pcr_selection
);
1035 rc
= sym_Esys_PolicyPCR(
1043 if (rc
!= TSS2_RC_SUCCESS
) {
1044 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1045 "Failed to add PCR policy to TPM: %s", sym_Tss2_RC_Decode(rc
));
1049 /* Get the policy hash of the PCR policy */
1050 _cleanup_(Esys_Freep
) TPM2B_DIGEST
*approved_policy
= NULL
;
1051 rc
= sym_Esys_PolicyGetDigest(
1058 if (rc
!= TSS2_RC_SUCCESS
) {
1059 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1060 "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc
));
1064 /* When we are unlocking and have a signature, let's pass it to the TPM */
1065 _cleanup_(Esys_Freep
) TPMT_TK_VERIFIED
*check_ticket_buffer
= NULL
;
1066 const TPMT_TK_VERIFIED
*check_ticket
;
1067 if (signature_json
) {
1068 _cleanup_free_
void *signature_raw
= NULL
;
1069 size_t signature_size
;
1076 approved_policy
->buffer
,
1077 approved_policy
->size
,
1083 /* TPM2_VerifySignature() will only verify the RSA part of the RSA+SHA256 signature,
1084 * hence we need to do the SHA256 part ourselves, first */
1085 TPM2B_DIGEST signature_hash
= {
1086 .size
= SHA256_DIGEST_SIZE
,
1088 assert(sizeof(signature_hash
.buffer
) >= SHA256_DIGEST_SIZE
);
1089 sha256_direct(approved_policy
->buffer
, approved_policy
->size
, signature_hash
.buffer
);
1091 TPMT_SIGNATURE policy_signature
= {
1092 .sigAlg
= TPM2_ALG_RSASSA
,
1093 .signature
.rsassa
= {
1094 .hash
= TPM2_ALG_SHA256
,
1095 .sig
.size
= signature_size
,
1098 if (signature_size
> sizeof(policy_signature
.signature
.rsassa
.sig
.buffer
)) {
1099 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "Signature larger than buffer.");
1102 memcpy(policy_signature
.signature
.rsassa
.sig
.buffer
, signature_raw
, signature_size
);
1104 rc
= sym_Esys_VerifySignature(
1112 &check_ticket_buffer
);
1113 if (rc
!= TSS2_RC_SUCCESS
) {
1114 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1115 "Failed to validate signature in TPM: %s", sym_Tss2_RC_Decode(rc
));
1119 check_ticket
= check_ticket_buffer
;
1121 /* When enrolling, we pass a NULL ticket */
1122 static const TPMT_TK_VERIFIED check_ticket_null
= {
1123 .tag
= TPM2_ST_VERIFIED
,
1124 .hierarchy
= TPM2_RH_OWNER
,
1127 check_ticket
= &check_ticket_null
;
1130 rc
= sym_Esys_PolicyAuthorize(
1137 /* policyRef= */ &(const TPM2B_NONCE
) {},
1140 if (rc
!= TSS2_RC_SUCCESS
) {
1141 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1142 "Failed to push Authorize policy into TPM: %s", sym_Tss2_RC_Decode(rc
));
1147 if (hash_pcr_mask
!= 0) {
1148 log_debug("Configuring hash-based PCR policy.");
1150 TPML_PCR_SELECTION pcr_selection
;
1151 tpm2_pcr_mask_to_selection(hash_pcr_mask
, pcr_bank
, &pcr_selection
);
1152 rc
= sym_Esys_PolicyPCR(
1160 if (rc
!= TSS2_RC_SUCCESS
) {
1161 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1162 "Failed to add PCR policy to TPM: %s", sym_Tss2_RC_Decode(rc
));
1168 log_debug("Configuring PIN policy.");
1170 rc
= sym_Esys_PolicyAuthValue(
1176 if (rc
!= TSS2_RC_SUCCESS
) {
1177 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1178 "Failed to add authValue policy to TPM: %s",
1179 sym_Tss2_RC_Decode(rc
));
1184 if (DEBUG_LOGGING
|| ret_policy_digest
) {
1185 log_debug("Acquiring policy digest.");
1187 rc
= sym_Esys_PolicyGetDigest(
1195 if (rc
!= TSS2_RC_SUCCESS
) {
1196 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1197 "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc
));
1201 if (DEBUG_LOGGING
) {
1202 _cleanup_free_
char *h
= NULL
;
1204 h
= hexmem(policy_digest
->buffer
, policy_digest
->size
);
1210 log_debug("Session policy digest: %s", h
);
1215 *ret_session
= session
;
1216 session
= ESYS_TR_NONE
;
1219 if (ret_policy_digest
)
1220 *ret_policy_digest
= TAKE_PTR(policy_digest
);
1223 *ret_pcr_bank
= pcr_bank
;
1228 session
= tpm2_flush_context_verbose(c
, session
);
1229 pubkey_handle
= tpm2_flush_context_verbose(c
, pubkey_handle
);
1233 int tpm2_seal(const char *device
,
1234 uint32_t hash_pcr_mask
,
1236 const size_t pubkey_size
,
1237 uint32_t pubkey_pcr_mask
,
1240 size_t *ret_secret_size
,
1242 size_t *ret_blob_size
,
1243 void **ret_pcr_hash
,
1244 size_t *ret_pcr_hash_size
,
1245 uint16_t *ret_pcr_bank
,
1246 uint16_t *ret_primary_alg
) {
1248 _cleanup_(tpm2_context_destroy
) struct tpm2_context c
= {};
1249 _cleanup_(Esys_Freep
) TPM2B_DIGEST
*policy_digest
= NULL
;
1250 _cleanup_(Esys_Freep
) TPM2B_PRIVATE
*private = NULL
;
1251 _cleanup_(Esys_Freep
) TPM2B_PUBLIC
*public = NULL
;
1252 static const TPML_PCR_SELECTION creation_pcr
= {};
1253 _cleanup_(erase_and_freep
) void *secret
= NULL
;
1254 _cleanup_free_
void *blob
= NULL
, *hash
= NULL
;
1255 TPM2B_SENSITIVE_CREATE hmac_sensitive
;
1256 ESYS_TR primary
= ESYS_TR_NONE
, session
= ESYS_TR_NONE
;
1257 TPMI_ALG_PUBLIC primary_alg
;
1258 TPM2B_PUBLIC hmac_template
;
1259 TPMI_ALG_HASH pcr_bank
;
1260 size_t k
, blob_size
;
1265 assert(pubkey
|| pubkey_size
== 0);
1268 assert(ret_secret_size
);
1270 assert(ret_blob_size
);
1271 assert(ret_pcr_hash
);
1272 assert(ret_pcr_hash_size
);
1273 assert(ret_pcr_bank
);
1275 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask
));
1276 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask
));
1278 /* So here's what we do here: we connect to the TPM2 chip. It persistently contains a "seed" key that
1279 * is randomized when the TPM2 is first initialized or reset and remains stable across boots. We
1280 * generate a "primary" key pair derived from that (ECC if possible, RSA as fallback). Given the seed
1281 * remains fixed this will result in the same key pair whenever we specify the exact same parameters
1282 * for it. We then create a PCR-bound policy session, which calculates a hash on the current PCR
1283 * values of the indexes we specify. We then generate a randomized key on the host (which is the key
1284 * we actually enroll in the LUKS2 keyslots), which we upload into the TPM2, where it is encrypted
1285 * with the "primary" key, taking the PCR policy session into account. We then download the encrypted
1286 * key from the TPM2 ("sealing") and marshall it into binary form, which is ultimately placed in the
1287 * LUKS2 JSON header.
1289 * The TPM2 "seed" key and "primary" keys never leave the TPM2 chip (and cannot be extracted at
1290 * all). The random key we enroll in LUKS2 we generate on the host using the Linux random device. It
1291 * is stored in the LUKS2 JSON only in encrypted form with the "primary" key of the TPM2 chip, thus
1292 * binding the unlocking to the TPM2 chip. */
1294 start
= now(CLOCK_MONOTONIC
);
1296 r
= tpm2_context_init(device
, &c
);
1300 r
= tpm2_make_primary(c
.esys_context
, &primary
, 0, &primary_alg
);
1304 /* we cannot use the bind key before its created */
1305 r
= tpm2_make_encryption_session(c
.esys_context
, primary
, ESYS_TR_NONE
, NULL
, &session
);
1309 r
= tpm2_make_policy_session(
1315 /* pcr_bank= */ UINT16_MAX
,
1316 pubkey
, pubkey_size
,
1318 /* signature_json= */ NULL
,
1320 /* ret_session= */ NULL
,
1326 /* We use a keyed hash object (i.e. HMAC) to store the secret key we want to use for unlocking the
1327 * LUKS2 volume with. We don't ever use for HMAC/keyed hash operations however, we just use it
1328 * because it's a key type that is universally supported and suitable for symmetric binary blobs. */
1329 hmac_template
= (TPM2B_PUBLIC
) {
1330 .size
= sizeof(TPMT_PUBLIC
),
1332 .type
= TPM2_ALG_KEYEDHASH
,
1333 .nameAlg
= TPM2_ALG_SHA256
,
1334 .objectAttributes
= TPMA_OBJECT_FIXEDTPM
| TPMA_OBJECT_FIXEDPARENT
,
1335 .parameters
.keyedHashDetail
.scheme
.scheme
= TPM2_ALG_NULL
,
1336 .unique
.keyedHash
.size
= 32,
1337 .authPolicy
= *policy_digest
,
1341 hmac_sensitive
= (TPM2B_SENSITIVE_CREATE
) {
1342 .size
= sizeof(hmac_sensitive
.sensitive
),
1343 .sensitive
.data
.size
= 32,
1346 hash_pin(pin
, strlen(pin
), &hmac_sensitive
.sensitive
.userAuth
);
1348 assert(sizeof(hmac_sensitive
.sensitive
.data
.buffer
) >= hmac_sensitive
.sensitive
.data
.size
);
1350 (void) tpm2_credit_random(c
.esys_context
);
1352 log_debug("Generating secret key data.");
1354 r
= crypto_random_bytes(hmac_sensitive
.sensitive
.data
.buffer
, hmac_sensitive
.sensitive
.data
.size
);
1356 log_error_errno(r
, "Failed to generate secret key: %m");
1360 log_debug("Creating HMAC key.");
1362 rc
= sym_Esys_Create(
1365 session
, /* use HMAC session to enable parameter encryption */
1377 if (rc
!= TSS2_RC_SUCCESS
) {
1378 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1379 "Failed to generate HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc
));
1383 secret
= memdup(hmac_sensitive
.sensitive
.data
.buffer
, hmac_sensitive
.sensitive
.data
.size
);
1384 explicit_bzero_safe(hmac_sensitive
.sensitive
.data
.buffer
, hmac_sensitive
.sensitive
.data
.size
);
1390 log_debug("Marshalling private and public part of HMAC key.");
1392 k
= ALIGN8(sizeof(*private)) + ALIGN8(sizeof(*public)); /* Some roughly sensible start value */
1394 _cleanup_free_
void *buf
= NULL
;
1403 rc
= sym_Tss2_MU_TPM2B_PRIVATE_Marshal(private, buf
, k
, &offset
);
1404 if (rc
== TSS2_RC_SUCCESS
) {
1405 rc
= sym_Tss2_MU_TPM2B_PUBLIC_Marshal(public, buf
, k
, &offset
);
1406 if (rc
== TSS2_RC_SUCCESS
) {
1407 blob
= TAKE_PTR(buf
);
1412 if (rc
!= TSS2_MU_RC_INSUFFICIENT_BUFFER
) {
1413 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1414 "Failed to marshal private/public key: %s", sym_Tss2_RC_Decode(rc
));
1418 if (k
> SIZE_MAX
/ 2) {
1426 hash
= memdup(policy_digest
->buffer
, policy_digest
->size
);
1431 log_debug("Completed TPM2 key sealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - start
, 1));
1433 *ret_secret
= TAKE_PTR(secret
);
1434 *ret_secret_size
= hmac_sensitive
.sensitive
.data
.size
;
1435 *ret_blob
= TAKE_PTR(blob
);
1436 *ret_blob_size
= blob_size
;
1437 *ret_pcr_hash
= TAKE_PTR(hash
);
1438 *ret_pcr_hash_size
= policy_digest
->size
;
1439 *ret_pcr_bank
= pcr_bank
;
1440 *ret_primary_alg
= primary_alg
;
1445 explicit_bzero_safe(&hmac_sensitive
, sizeof(hmac_sensitive
));
1446 primary
= tpm2_flush_context_verbose(c
.esys_context
, primary
);
1447 session
= tpm2_flush_context_verbose(c
.esys_context
, session
);
1451 int tpm2_unseal(const char *device
,
1452 uint32_t hash_pcr_mask
,
1456 uint32_t pubkey_pcr_mask
,
1457 JsonVariant
*signature
,
1459 uint16_t primary_alg
,
1462 const void *known_policy_hash
,
1463 size_t known_policy_hash_size
,
1465 size_t *ret_secret_size
) {
1467 _cleanup_(tpm2_context_destroy
) struct tpm2_context c
= {};
1468 ESYS_TR primary
= ESYS_TR_NONE
, session
= ESYS_TR_NONE
, hmac_session
= ESYS_TR_NONE
,
1469 hmac_key
= ESYS_TR_NONE
;
1470 _cleanup_(Esys_Freep
) TPM2B_SENSITIVE_DATA
* unsealed
= NULL
;
1471 _cleanup_(Esys_Freep
) TPM2B_DIGEST
*policy_digest
= NULL
;
1472 _cleanup_(erase_and_freep
) char *secret
= NULL
;
1473 TPM2B_PRIVATE
private = {};
1474 TPM2B_PUBLIC
public = {};
1481 assert(blob_size
> 0);
1482 assert(known_policy_hash_size
== 0 || known_policy_hash
);
1483 assert(pubkey_size
== 0 || pubkey
);
1485 assert(ret_secret_size
);
1487 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask
));
1488 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask
));
1492 return log_error_errno(r
, "TPM2 support is not installed.");
1494 /* So here's what we do here: We connect to the TPM2 chip. As we do when sealing we generate a
1495 * "primary" key on the TPM2 chip, with the same parameters as well as a PCR-bound policy
1496 * session. Given we pass the same parameters, this will result in the same "primary" key, and same
1497 * policy hash (the latter of course, only if the PCR values didn't change in between). We unmarshal
1498 * the encrypted key we stored in the LUKS2 JSON token header and upload it into the TPM2, where it
1499 * is decrypted if the seed and the PCR policy were right ("unsealing"). We then download the result,
1500 * and use it to unlock the LUKS2 volume. */
1502 start
= now(CLOCK_MONOTONIC
);
1504 log_debug("Unmarshalling private part of HMAC key.");
1506 rc
= sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal(blob
, blob_size
, &offset
, &private);
1507 if (rc
!= TSS2_RC_SUCCESS
)
1508 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1509 "Failed to unmarshal private key: %s", sym_Tss2_RC_Decode(rc
));
1511 log_debug("Unmarshalling public part of HMAC key.");
1513 rc
= sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal(blob
, blob_size
, &offset
, &public);
1514 if (rc
!= TSS2_RC_SUCCESS
)
1515 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1516 "Failed to unmarshal public key: %s", sym_Tss2_RC_Decode(rc
));
1518 r
= tpm2_context_init(device
, &c
);
1522 r
= tpm2_make_primary(c
.esys_context
, &primary
, primary_alg
, NULL
);
1526 log_debug("Loading HMAC key into TPM.");
1529 * Nothing sensitive on the bus, no need for encryption. Even if an attacker
1530 * gives you back a different key, the session initiation will fail if a pin
1531 * is provided. If an attacker gives back a bad key, we already lost since
1532 * primary key is not verified and they could attack there as well.
1543 if (rc
!= TSS2_RC_SUCCESS
) {
1544 /* If we're in dictionary attack lockout mode, we should see a lockout error here, which we
1545 * need to translate for the caller. */
1546 if (rc
== TPM2_RC_LOCKOUT
)
1547 r
= log_error_errno(
1548 SYNTHETIC_ERRNO(ENOLCK
),
1549 "TPM2 device is in dictionary attack lockout mode.");
1551 r
= log_error_errno(
1552 SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1553 "Failed to load HMAC key in TPM: %s",
1554 sym_Tss2_RC_Decode(rc
));
1558 r
= tpm2_make_encryption_session(c
.esys_context
, primary
, hmac_key
, pin
, &hmac_session
);
1562 r
= tpm2_make_policy_session(
1569 pubkey
, pubkey_size
,
1575 /* ret_pcr_bank= */ NULL
);
1579 /* If we know the policy hash to expect, and it doesn't match, we can shortcut things here, and not
1580 * wait until the TPM2 tells us to go away. */
1581 if (known_policy_hash_size
> 0 &&
1582 memcmp_nn(policy_digest
->buffer
, policy_digest
->size
, known_policy_hash
, known_policy_hash_size
) != 0)
1583 return log_error_errno(SYNTHETIC_ERRNO(EPERM
),
1584 "Current policy digest does not match stored policy digest, cancelling "
1585 "TPM2 authentication attempt.");
1587 log_debug("Unsealing HMAC key.");
1589 rc
= sym_Esys_Unseal(
1593 hmac_session
, /* use HMAC session to enable parameter encryption */
1596 if (rc
!= TSS2_RC_SUCCESS
) {
1597 r
= log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1598 "Failed to unseal HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc
));
1602 secret
= memdup(unsealed
->buffer
, unsealed
->size
);
1603 explicit_bzero_safe(unsealed
->buffer
, unsealed
->size
);
1610 log_debug("Completed TPM2 key unsealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - start
, 1));
1612 *ret_secret
= TAKE_PTR(secret
);
1613 *ret_secret_size
= unsealed
->size
;
1618 primary
= tpm2_flush_context_verbose(c
.esys_context
, primary
);
1619 session
= tpm2_flush_context_verbose(c
.esys_context
, session
);
1620 hmac_key
= tpm2_flush_context_verbose(c
.esys_context
, hmac_key
);
1626 int tpm2_list_devices(void) {
1628 _cleanup_(table_unrefp
) Table
*t
= NULL
;
1629 _cleanup_(closedirp
) DIR *d
= NULL
;
1634 return log_error_errno(r
, "TPM2 support is not installed.");
1636 t
= table_new("path", "device", "driver");
1640 d
= opendir("/sys/class/tpmrm");
1642 log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
, "Failed to open /sys/class/tpmrm: %m");
1643 if (errno
!= ENOENT
)
1647 _cleanup_free_
char *device_path
= NULL
, *device
= NULL
, *driver_path
= NULL
, *driver
= NULL
, *node
= NULL
;
1650 de
= readdir_no_dot(d
);
1654 device_path
= path_join("/sys/class/tpmrm", de
->d_name
, "device");
1658 r
= readlink_malloc(device_path
, &device
);
1660 log_debug_errno(r
, "Failed to read device symlink %s, ignoring: %m", device_path
);
1662 driver_path
= path_join(device_path
, "driver");
1666 r
= readlink_malloc(driver_path
, &driver
);
1668 log_debug_errno(r
, "Failed to read driver symlink %s, ignoring: %m", driver_path
);
1671 node
= path_join("/dev", de
->d_name
);
1678 TABLE_STRING
, device
? last_path_component(device
) : NULL
,
1679 TABLE_STRING
, driver
? last_path_component(driver
) : NULL
);
1681 return table_log_add_error(r
);
1685 if (table_get_rows(t
) <= 1) {
1686 log_info("No suitable TPM2 devices found.");
1690 r
= table_print(t
, stdout
);
1692 return log_error_errno(r
, "Failed to show device table: %m");
1696 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
1697 "TPM2 not supported on this build.");
1701 int tpm2_find_device_auto(
1702 int log_level
, /* log level when no device is found */
1705 _cleanup_(closedirp
) DIR *d
= NULL
;
1710 return log_error_errno(r
, "TPM2 support is not installed.");
1712 d
= opendir("/sys/class/tpmrm");
1714 log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
,
1715 "Failed to open /sys/class/tpmrm: %m");
1716 if (errno
!= ENOENT
)
1719 _cleanup_free_
char *node
= NULL
;
1724 de
= readdir_no_dot(d
);
1729 return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ
),
1730 "More than one TPM2 (tpmrm) device found.");
1732 node
= path_join("/dev", de
->d_name
);
1738 *ret
= TAKE_PTR(node
);
1743 return log_full_errno(log_level
, SYNTHETIC_ERRNO(ENODEV
), "No TPM2 (tpmrm) device found.");
1745 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
1746 "TPM2 not supported on this build.");
1750 int tpm2_parse_pcrs(const char *s
, uint32_t *ret
) {
1751 const char *p
= ASSERT_PTR(s
);
1760 /* Parses a "," or "+" separated list of PCR indexes. We support "," since this is a list after all,
1761 * and most other tools expect comma separated PCR specifications. We also support "+" since in
1762 * /etc/crypttab the "," is already used to separate options, hence a different separator is nice to
1763 * avoid escaping. */
1766 _cleanup_free_
char *pcr
= NULL
;
1769 r
= extract_first_word(&p
, &pcr
, ",+", EXTRACT_DONT_COALESCE_SEPARATORS
);
1773 return log_error_errno(r
, "Failed to parse PCR list: %s", s
);
1775 r
= safe_atou(pcr
, &n
);
1777 return log_error_errno(r
, "Failed to parse PCR number: %s", pcr
);
1778 if (n
>= TPM2_PCRS_MAX
)
1779 return log_error_errno(SYNTHETIC_ERRNO(ERANGE
),
1780 "PCR number out of range (valid range 0…23): %u", n
);
1782 mask
|= UINT32_C(1) << n
;
1789 int tpm2_make_pcr_json_array(uint32_t pcr_mask
, JsonVariant
**ret
) {
1790 _cleanup_(json_variant_unrefp
) JsonVariant
*a
= NULL
;
1791 JsonVariant
* pcr_array
[TPM2_PCRS_MAX
];
1792 unsigned n_pcrs
= 0;
1795 for (size_t i
= 0; i
< ELEMENTSOF(pcr_array
); i
++) {
1796 if ((pcr_mask
& (UINT32_C(1) << i
)) == 0)
1799 r
= json_variant_new_integer(pcr_array
+ n_pcrs
, i
);
1806 r
= json_variant_new_array(&a
, pcr_array
, n_pcrs
);
1815 json_variant_unref_many(pcr_array
, n_pcrs
);
1819 int tpm2_parse_pcr_json_array(JsonVariant
*v
, uint32_t *ret
) {
1823 if (!json_variant_is_array(v
))
1824 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PCR array is not a JSON array.");
1826 JSON_VARIANT_ARRAY_FOREACH(e
, v
) {
1829 if (!json_variant_is_unsigned(e
))
1830 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PCR is not an unsigned integer.");
1832 u
= json_variant_unsigned(e
);
1833 if (u
>= TPM2_PCRS_MAX
)
1834 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PCR number out of range: %" PRIu64
, u
);
1836 mask
|= UINT32_C(1) << u
;
1845 int tpm2_make_luks2_json(
1847 uint32_t hash_pcr_mask
,
1851 uint32_t pubkey_pcr_mask
,
1852 uint16_t primary_alg
,
1855 const void *policy_hash
,
1856 size_t policy_hash_size
,
1858 JsonVariant
**ret
) {
1860 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
, *hmj
= NULL
, *pkmj
= NULL
;
1861 _cleanup_free_
char *keyslot_as_string
= NULL
;
1864 assert(blob
|| blob_size
== 0);
1865 assert(policy_hash
|| policy_hash_size
== 0);
1866 assert(pubkey
|| pubkey_size
== 0);
1868 if (asprintf(&keyslot_as_string
, "%i", keyslot
) < 0)
1871 r
= tpm2_make_pcr_json_array(hash_pcr_mask
, &hmj
);
1875 if (pubkey_pcr_mask
!= 0) {
1876 r
= tpm2_make_pcr_json_array(pubkey_pcr_mask
, &pkmj
);
1881 /* Note: We made the mistake of using "-" in the field names, which isn't particular compatible with
1882 * other programming languages. Let's not make things worse though, i.e. future additions to the JSON
1883 * object should use "_" rather than "-" in field names. */
1887 JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-tpm2")),
1888 JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string
))),
1889 JSON_BUILD_PAIR("tpm2-blob", JSON_BUILD_BASE64(blob
, blob_size
)),
1890 JSON_BUILD_PAIR("tpm2-pcrs", JSON_BUILD_VARIANT(hmj
)),
1891 JSON_BUILD_PAIR_CONDITION(!!tpm2_pcr_bank_to_string(pcr_bank
), "tpm2-pcr-bank", JSON_BUILD_STRING(tpm2_pcr_bank_to_string(pcr_bank
))),
1892 JSON_BUILD_PAIR_CONDITION(!!tpm2_primary_alg_to_string(primary_alg
), "tpm2-primary-alg", JSON_BUILD_STRING(tpm2_primary_alg_to_string(primary_alg
))),
1893 JSON_BUILD_PAIR("tpm2-policy-hash", JSON_BUILD_HEX(policy_hash
, policy_hash_size
)),
1894 JSON_BUILD_PAIR("tpm2-pin", JSON_BUILD_BOOLEAN(flags
& TPM2_FLAGS_USE_PIN
)),
1895 JSON_BUILD_PAIR_CONDITION(pubkey_pcr_mask
!= 0, "tpm2_pubkey_pcrs", JSON_BUILD_VARIANT(pkmj
)),
1896 JSON_BUILD_PAIR_CONDITION(pubkey_pcr_mask
!= 0, "tpm2_pubkey", JSON_BUILD_BASE64(pubkey
, pubkey_size
))));
1906 int tpm2_parse_luks2_json(
1909 uint32_t *ret_hash_pcr_mask
,
1910 uint16_t *ret_pcr_bank
,
1912 size_t *ret_pubkey_size
,
1913 uint32_t *ret_pubkey_pcr_mask
,
1914 uint16_t *ret_primary_alg
,
1916 size_t *ret_blob_size
,
1917 void **ret_policy_hash
,
1918 size_t *ret_policy_hash_size
,
1919 TPM2Flags
*ret_flags
) {
1921 _cleanup_free_
void *blob
= NULL
, *policy_hash
= NULL
, *pubkey
= NULL
;
1922 size_t blob_size
= 0, policy_hash_size
= 0, pubkey_size
= 0;
1923 uint32_t hash_pcr_mask
= 0, pubkey_pcr_mask
= 0;
1924 uint16_t primary_alg
= TPM2_ALG_ECC
; /* ECC was the only supported algorithm in systemd < 250, use that as implied default, for compatibility */
1925 uint16_t pcr_bank
= UINT16_MAX
; /* default: pick automatically */
1926 int r
, keyslot
= -1;
1927 TPM2Flags flags
= 0;
1933 keyslot
= cryptsetup_get_keyslot_from_token(v
);
1935 /* Return a recognizable error when parsing this field, so that callers can handle parsing
1936 * errors of the keyslots field gracefully, since it's not 'owned' by us, but by the LUKS2
1938 log_debug_errno(keyslot
, "Failed to extract keyslot index from TPM2 JSON data token, skipping: %m");
1943 w
= json_variant_by_key(v
, "tpm2-pcrs");
1945 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 token data lacks 'tpm2-pcrs' field.");
1947 r
= tpm2_parse_pcr_json_array(w
, &hash_pcr_mask
);
1949 return log_debug_errno(r
, "Failed to parse TPM2 PCR mask: %m");
1951 /* The bank field is optional, since it was added in systemd 250 only. Before the bank was hardcoded
1953 w
= json_variant_by_key(v
, "tpm2-pcr-bank");
1955 /* The PCR bank field is optional */
1957 if (!json_variant_is_string(w
))
1958 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PCR bank is not a string.");
1960 r
= tpm2_pcr_bank_from_string(json_variant_string(w
));
1962 return log_debug_errno(r
, "TPM2 PCR bank invalid or not supported: %s", json_variant_string(w
));
1967 /* The primary key algorithm field is optional, since it was also added in systemd 250 only. Before
1968 * the algorithm was hardcoded to ECC. */
1969 w
= json_variant_by_key(v
, "tpm2-primary-alg");
1971 /* The primary key algorithm is optional */
1973 if (!json_variant_is_string(w
))
1974 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 primary key algorithm is not a string.");
1976 r
= tpm2_primary_alg_from_string(json_variant_string(w
));
1978 return log_debug_errno(r
, "TPM2 primary key algorithm invalid or not supported: %s", json_variant_string(w
));
1983 w
= json_variant_by_key(v
, "tpm2-blob");
1985 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 token data lacks 'tpm2-blob' field.");
1987 r
= json_variant_unbase64(w
, &blob
, &blob_size
);
1989 return log_debug_errno(r
, "Invalid base64 data in 'tpm2-blob' field.");
1991 w
= json_variant_by_key(v
, "tpm2-policy-hash");
1993 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 token data lacks 'tpm2-policy-hash' field.");
1995 r
= json_variant_unhex(w
, &policy_hash
, &policy_hash_size
);
1997 return log_debug_errno(r
, "Invalid base64 data in 'tpm2-policy-hash' field.");
1999 w
= json_variant_by_key(v
, "tpm2-pin");
2001 if (!json_variant_is_boolean(w
))
2002 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PIN policy is not a boolean.");
2004 SET_FLAG(flags
, TPM2_FLAGS_USE_PIN
, json_variant_boolean(w
));
2007 w
= json_variant_by_key(v
, "tpm2_pubkey_pcrs");
2009 r
= tpm2_parse_pcr_json_array(w
, &pubkey_pcr_mask
);
2014 w
= json_variant_by_key(v
, "tpm2_pubkey");
2016 r
= json_variant_unbase64(w
, &pubkey
, &pubkey_size
);
2018 return log_debug_errno(r
, "Failed to decode PCR public key.");
2019 } else if (pubkey_pcr_mask
!= 0)
2020 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "Public key PCR mask set, but not public key included in JSON data, refusing.");
2023 *ret_keyslot
= keyslot
;
2024 if (ret_hash_pcr_mask
)
2025 *ret_hash_pcr_mask
= hash_pcr_mask
;
2027 *ret_pcr_bank
= pcr_bank
;
2029 *ret_pubkey
= TAKE_PTR(pubkey
);
2030 if (ret_pubkey_size
)
2031 *ret_pubkey_size
= pubkey_size
;
2032 if (ret_pubkey_pcr_mask
)
2033 *ret_pubkey_pcr_mask
= pubkey_pcr_mask
;
2034 if (ret_primary_alg
)
2035 *ret_primary_alg
= primary_alg
;
2037 *ret_blob
= TAKE_PTR(blob
);
2039 *ret_blob_size
= blob_size
;
2040 if (ret_policy_hash
)
2041 *ret_policy_hash
= TAKE_PTR(policy_hash
);
2042 if (ret_policy_hash_size
)
2043 *ret_policy_hash_size
= policy_hash_size
;
2050 const char *tpm2_pcr_bank_to_string(uint16_t bank
) {
2051 if (bank
== TPM2_ALG_SHA1
)
2053 if (bank
== TPM2_ALG_SHA256
)
2055 if (bank
== TPM2_ALG_SHA384
)
2057 if (bank
== TPM2_ALG_SHA512
)
2062 int tpm2_pcr_bank_from_string(const char *bank
) {
2063 if (strcaseeq_ptr(bank
, "sha1"))
2064 return TPM2_ALG_SHA1
;
2065 if (strcaseeq_ptr(bank
, "sha256"))
2066 return TPM2_ALG_SHA256
;
2067 if (strcaseeq_ptr(bank
, "sha384"))
2068 return TPM2_ALG_SHA384
;
2069 if (strcaseeq_ptr(bank
, "sha512"))
2070 return TPM2_ALG_SHA512
;
2074 const char *tpm2_primary_alg_to_string(uint16_t alg
) {
2075 if (alg
== TPM2_ALG_ECC
)
2077 if (alg
== TPM2_ALG_RSA
)
2082 int tpm2_primary_alg_from_string(const char *alg
) {
2083 if (strcaseeq_ptr(alg
, "ecc"))
2084 return TPM2_ALG_ECC
;
2085 if (strcaseeq_ptr(alg
, "rsa"))
2086 return TPM2_ALG_RSA
;
2090 Tpm2Support
tpm2_support(void) {
2091 Tpm2Support support
= TPM2_SUPPORT_NONE
;
2094 if (detect_container() <= 0) {
2095 /* Check if there's a /dev/tpmrm* device via sysfs. If we run in a container we likely just
2096 * got the host sysfs mounted. Since devices are generally not virtualized for containers,
2097 * let's assume containers never have a TPM, at least for now. */
2099 r
= dir_is_empty("/sys/class/tpmrm", /* ignore_hidden_or_backup= */ false);
2102 log_debug_errno(r
, "Unable to test whether /sys/class/tpmrm/ exists and is populated, assuming it is not: %m");
2103 } else if (r
== 0) /* populated! */
2104 support
|= TPM2_SUPPORT_DRIVER
;
2108 support
|= TPM2_SUPPORT_FIRMWARE
;
2111 support
|= TPM2_SUPPORT_SYSTEM
;
2117 int tpm2_parse_pcr_argument(const char *arg
, uint32_t *mask
) {
2123 /* For use in getopt_long() command line parsers: merges masks specified on the command line */
2130 r
= tpm2_parse_pcrs(arg
, &m
);
2134 if (*mask
== UINT32_MAX
)
2142 int tpm2_load_pcr_signature(const char *path
, JsonVariant
**ret
) {
2143 _cleanup_free_
char *discovered_path
= NULL
;
2144 _cleanup_fclose_
FILE *f
= NULL
;
2147 /* Tries to load a JSON PCR signature file. Takes an absolute path, a simple file name or NULL. In
2148 * the latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
2151 path
= "tpm2-pcr-signature.json";
2153 r
= search_and_fopen(path
, "re", NULL
, (const char**) CONF_PATHS_STRV("systemd"), &f
, &discovered_path
);
2155 return log_debug_errno(r
, "Failed to find TPM PCR signature file '%s': %m", path
);
2157 r
= json_parse_file(f
, discovered_path
, 0, ret
, NULL
, NULL
);
2159 return log_debug_errno(r
, "Failed to parse TPM PCR signature JSON object '%s': %m", discovered_path
);
2164 int tpm2_load_pcr_public_key(const char *path
, void **ret_pubkey
, size_t *ret_pubkey_size
) {
2165 _cleanup_free_
char *discovered_path
= NULL
;
2166 _cleanup_fclose_
FILE *f
= NULL
;
2169 /* Tries to load a PCR public key file. Takes an absolute path, a simple file name or NULL. In the
2170 * latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
2173 path
= "tpm2-pcr-public-key.pem";
2175 r
= search_and_fopen(path
, "re", NULL
, (const char**) CONF_PATHS_STRV("systemd"), &f
, &discovered_path
);
2177 return log_debug_errno(r
, "Failed to find TPM PCR public key file '%s': %m", path
);
2179 r
= read_full_stream(f
, (char**) ret_pubkey
, ret_pubkey_size
);
2181 return log_debug_errno(r
, "Failed to load TPM PCR public key PEM file '%s': %m", discovered_path
);
2186 int pcr_mask_to_string(uint32_t mask
, char **ret
) {
2187 _cleanup_free_
char *buf
= NULL
;
2192 for (unsigned i
= 0; i
< TPM2_PCRS_MAX
; i
++) {
2193 if (!(mask
& (UINT32_C(1) << i
)))
2196 r
= strextendf_with_separator(&buf
, "+", "%u", i
);
2201 *ret
= TAKE_PTR(buf
);