1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "alloc-util.h"
5 #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"
16 #include "initrd-util.h"
17 #include "lock-util.h"
19 #include "logarithm.h"
20 #include "memory-util.h"
21 #include "nulstr-util.h"
22 #include "openssl-util.h"
23 #include "parse-util.h"
24 #include "random-util.h"
26 #include "stat-util.h"
27 #include "string-table.h"
28 #include "time-util.h"
29 #include "tpm2-util.h"
33 static void *libtss2_esys_dl
= NULL
;
34 static void *libtss2_rc_dl
= NULL
;
35 static void *libtss2_mu_dl
= NULL
;
37 static 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
;
38 static 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
;
39 static TSS2_RC (*sym_Esys_EvictControl
)(ESYS_CONTEXT
*esysContext
, ESYS_TR auth
, ESYS_TR objectHandle
, ESYS_TR shandle1
, ESYS_TR shandle2
, ESYS_TR shandle3
, TPMI_DH_PERSISTENT persistentHandle
, ESYS_TR
*newObjectHandle
) = NULL
;
40 static void (*sym_Esys_Finalize
)(ESYS_CONTEXT
**context
) = NULL
;
41 static TSS2_RC (*sym_Esys_FlushContext
)(ESYS_CONTEXT
*esysContext
, ESYS_TR flushHandle
) = NULL
;
42 static void (*sym_Esys_Free
)(void *ptr
) = NULL
;
43 static 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
) = NULL
;
44 static TSS2_RC (*sym_Esys_GetRandom
)(ESYS_CONTEXT
*esysContext
, ESYS_TR shandle1
, ESYS_TR shandle2
, ESYS_TR shandle3
, UINT16 bytesRequested
, TPM2B_DIGEST
**randomBytes
) = NULL
;
45 static TSS2_RC (*sym_Esys_Initialize
)(ESYS_CONTEXT
**esys_context
, TSS2_TCTI_CONTEXT
*tcti
, TSS2_ABI_VERSION
*abiVersion
) = NULL
;
46 static 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
;
47 static 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
) = NULL
;
48 static 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
) = NULL
;
49 static 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
) = NULL
;
50 static 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
) = NULL
;
51 static TSS2_RC (*sym_Esys_PolicyAuthValue
)(ESYS_CONTEXT
*esysContext
, ESYS_TR policySession
, ESYS_TR shandle1
, ESYS_TR shandle2
, ESYS_TR shandle3
) = NULL
;
52 static TSS2_RC (*sym_Esys_PolicyGetDigest
)(ESYS_CONTEXT
*esysContext
, ESYS_TR policySession
, ESYS_TR shandle1
, ESYS_TR shandle2
, ESYS_TR shandle3
, TPM2B_DIGEST
**policyDigest
) = NULL
;
53 static 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
;
54 static TSS2_RC (*sym_Esys_ReadPublic
)(ESYS_CONTEXT
*esysContext
, ESYS_TR objectHandle
, ESYS_TR shandle1
, ESYS_TR shandle2
, ESYS_TR shandle3
, TPM2B_PUBLIC
**outPublic
, TPM2B_NAME
**name
, TPM2B_NAME
**qualifiedName
) = NULL
;
55 static 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
;
56 static TSS2_RC (*sym_Esys_Startup
)(ESYS_CONTEXT
*esysContext
, TPM2_SU startupType
) = NULL
;
57 static TSS2_RC (*sym_Esys_TestParms
)(ESYS_CONTEXT
*esysContext
, ESYS_TR shandle1
, ESYS_TR shandle2
, ESYS_TR shandle3
, const TPMT_PUBLIC_PARMS
*parameters
) = NULL
;
58 static TSS2_RC (*sym_Esys_TR_Close
)(ESYS_CONTEXT
*esys_context
, ESYS_TR
*rsrc_handle
) = NULL
;
59 static TSS2_RC (*sym_Esys_TR_Deserialize
)(ESYS_CONTEXT
*esys_context
, uint8_t const *buffer
, size_t buffer_size
, ESYS_TR
*esys_handle
) = NULL
;
60 static TSS2_RC (*sym_Esys_TR_FromTPMPublic
)(ESYS_CONTEXT
*esysContext
, TPM2_HANDLE tpm_handle
, ESYS_TR optionalSession1
, ESYS_TR optionalSession2
, ESYS_TR optionalSession3
, ESYS_TR
*object
) = NULL
;
61 static TSS2_RC (*sym_Esys_TR_GetName
)(ESYS_CONTEXT
*esysContext
, ESYS_TR handle
, TPM2B_NAME
**name
) = NULL
;
62 static TSS2_RC (*sym_Esys_TR_Serialize
)(ESYS_CONTEXT
*esys_context
, ESYS_TR object
, uint8_t **buffer
, size_t *buffer_size
) = NULL
;
63 static TSS2_RC (*sym_Esys_TR_SetAuth
)(ESYS_CONTEXT
*esysContext
, ESYS_TR handle
, TPM2B_AUTH
const *authValue
) = NULL
;
64 static TSS2_RC (*sym_Esys_TRSess_GetAttributes
)(ESYS_CONTEXT
*esysContext
, ESYS_TR session
, TPMA_SESSION
*flags
) = NULL
;
65 static TSS2_RC (*sym_Esys_TRSess_SetAttributes
)(ESYS_CONTEXT
*esysContext
, ESYS_TR session
, TPMA_SESSION flags
, TPMA_SESSION mask
) = NULL
;
66 static 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
;
67 static 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
) = NULL
;
69 static TSS2_RC (*sym_Tss2_MU_TPM2_CC_Marshal
)(TPM2_CC src
, uint8_t buffer
[], size_t buffer_size
, size_t *offset
) = NULL
;
70 static TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Marshal
)(TPM2B_PRIVATE
const *src
, uint8_t buffer
[], size_t buffer_size
, size_t *offset
) = NULL
;
71 static TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal
)(uint8_t const buffer
[], size_t buffer_size
, size_t *offset
, TPM2B_PRIVATE
*dest
) = NULL
;
72 static TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Marshal
)(TPM2B_PUBLIC
const *src
, uint8_t buffer
[], size_t buffer_size
, size_t *offset
) = NULL
;
73 static TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal
)(uint8_t const buffer
[], size_t buffer_size
, size_t *offset
, TPM2B_PUBLIC
*dest
) = NULL
;
74 static TSS2_RC (*sym_Tss2_MU_TPML_PCR_SELECTION_Marshal
)(TPML_PCR_SELECTION
const *src
, uint8_t buffer
[], size_t buffer_size
, size_t *offset
) = NULL
;
75 static TSS2_RC (*sym_Tss2_MU_TPMT_HA_Marshal
)(TPMT_HA
const *src
, uint8_t buffer
[], size_t buffer_size
, size_t *offset
) = NULL
;
76 static TSS2_RC (*sym_Tss2_MU_TPMT_PUBLIC_Marshal
)(TPMT_PUBLIC
const *src
, uint8_t buffer
[], size_t buffer_size
, size_t *offset
) = NULL
;
78 static const char* (*sym_Tss2_RC_Decode
)(TSS2_RC rc
) = NULL
;
80 int dlopen_tpm2(void) {
83 r
= dlopen_many_sym_or_warn(
84 &libtss2_esys_dl
, "libtss2-esys.so.0", LOG_DEBUG
,
85 DLSYM_ARG(Esys_Create
),
86 DLSYM_ARG(Esys_CreatePrimary
),
87 DLSYM_ARG(Esys_EvictControl
),
88 DLSYM_ARG(Esys_Finalize
),
89 DLSYM_ARG(Esys_FlushContext
),
91 DLSYM_ARG(Esys_GetCapability
),
92 DLSYM_ARG(Esys_GetRandom
),
93 DLSYM_ARG(Esys_Initialize
),
95 DLSYM_ARG(Esys_LoadExternal
),
96 DLSYM_ARG(Esys_PCR_Extend
),
97 DLSYM_ARG(Esys_PCR_Read
),
98 DLSYM_ARG(Esys_PolicyAuthorize
),
99 DLSYM_ARG(Esys_PolicyAuthValue
),
100 DLSYM_ARG(Esys_PolicyGetDigest
),
101 DLSYM_ARG(Esys_PolicyPCR
),
102 DLSYM_ARG(Esys_ReadPublic
),
103 DLSYM_ARG(Esys_StartAuthSession
),
104 DLSYM_ARG(Esys_Startup
),
105 DLSYM_ARG(Esys_TestParms
),
106 DLSYM_ARG(Esys_TR_Close
),
107 DLSYM_ARG(Esys_TR_Deserialize
),
108 DLSYM_ARG(Esys_TR_FromTPMPublic
),
109 DLSYM_ARG(Esys_TR_GetName
),
110 DLSYM_ARG(Esys_TR_Serialize
),
111 DLSYM_ARG(Esys_TR_SetAuth
),
112 DLSYM_ARG(Esys_TRSess_GetAttributes
),
113 DLSYM_ARG(Esys_TRSess_SetAttributes
),
114 DLSYM_ARG(Esys_Unseal
),
115 DLSYM_ARG(Esys_VerifySignature
));
119 r
= dlopen_many_sym_or_warn(
120 &libtss2_rc_dl
, "libtss2-rc.so.0", LOG_DEBUG
,
121 DLSYM_ARG(Tss2_RC_Decode
));
125 return dlopen_many_sym_or_warn(
126 &libtss2_mu_dl
, "libtss2-mu.so.0", LOG_DEBUG
,
127 DLSYM_ARG(Tss2_MU_TPM2_CC_Marshal
),
128 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Marshal
),
129 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Unmarshal
),
130 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Marshal
),
131 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Unmarshal
),
132 DLSYM_ARG(Tss2_MU_TPML_PCR_SELECTION_Marshal
),
133 DLSYM_ARG(Tss2_MU_TPMT_HA_Marshal
),
134 DLSYM_ARG(Tss2_MU_TPMT_PUBLIC_Marshal
));
137 static inline void Esys_Freep(void *p
) {
139 sym_Esys_Free(*(void**) p
);
142 /* Get a specific TPM capability (or capabilities).
144 * Returns 0 if there are no more capability properties of the requested type, or 1 if there are more, or < 0
145 * on any error. Both 0 and 1 indicate this completed successfully, but do not indicate how many capability
146 * properties were provided in 'ret_capability_data'. To find the number of provided properties, check the
147 * specific type's 'count' field (e.g. for TPM2_CAP_ALGS, check ret_capability_data->algorithms.count).
149 * This calls TPM2_GetCapability() and does not alter the provided data, so it is important to understand how
150 * that TPM function works. It is recommended to check the TCG TPM specification Part 3 ("Commands") section
151 * on TPM2_GetCapability() for full details, but a short summary is: if this returns 0, all available
152 * properties have been provided in ret_capability_data, or no properties were available. If this returns 1,
153 * there are between 1 and "count" properties provided in ret_capability_data, and there are more available.
154 * Note that this may provide less than "count" properties even if the TPM has more available. Also, each
155 * capability category may have more specific requirements than described here; see the spec for exact
157 static int tpm2_get_capability(
162 TPMU_CAPABILITIES
*ret_capability_data
) {
164 _cleanup_(Esys_Freep
) TPMS_CAPABILITY_DATA
*capabilities
= NULL
;
170 log_debug("Getting TPM2 capability 0x%04" PRIx32
" property 0x%04" PRIx32
" count %" PRIu32
".",
171 capability
, property
, count
);
173 rc
= sym_Esys_GetCapability(
183 if (rc
!= TSS2_RC_SUCCESS
)
184 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
185 "Failed to get TPM2 capability 0x%04" PRIx32
" property 0x%04" PRIx32
": %s",
186 capability
, property
, sym_Tss2_RC_Decode(rc
));
188 if (capabilities
->capability
!= capability
)
189 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
190 "TPM provided wrong capability: 0x%04" PRIx32
" instead of 0x%04" PRIx32
".",
191 capabilities
->capability
, capability
);
193 if (ret_capability_data
)
194 *ret_capability_data
= capabilities
->data
;
196 return more
== TPM2_YES
;
199 static int tpm2_cache_capabilities(Tpm2Context
*c
) {
200 TPMU_CAPABILITIES capability
;
205 /* Cache the PCR capabilities, which are safe to cache, as the only way they can change is
206 * TPM2_PCR_Allocate(), which changes the allocation after the next _TPM_Init(). If the TPM is
207 * reinitialized while we are using it, all our context and sessions will be invalid, so we can
208 * safely assume the TPM PCR allocation will not change while we are using it. */
209 r
= tpm2_get_capability(
218 /* This should never happen. Part 3 ("Commands") of the TCG TPM2 spec in the section for
219 * TPM2_GetCapability states: "TPM_CAP_PCRS – Returns the current allocation of PCR in a
220 * TPML_PCR_SELECTION. The property parameter shall be zero. The TPM will always respond to
221 * this command with the full PCR allocation and moreData will be NO." */
222 log_warning("TPM bug: reported multiple PCR sets; using only first set.");
223 c
->capability_pcrs
= capability
.assignedPCR
;
228 #define tpm2_capability_pcrs(c) ((c)->capability_pcrs)
230 /* Get the TPMA_ALGORITHM for a TPM2_ALG_ID.
232 * Returns 1 if the TPM supports the algorithm and the TPMA_ALGORITHM is provided, or 0 if the TPM does not
233 * support the algorithm, or < 0 for any errors. */
234 static int tpm2_get_capability_alg(Tpm2Context
*c
, TPM2_ALG_ID alg
, TPMA_ALGORITHM
*ret
) {
235 TPMU_CAPABILITIES capability
;
240 /* The spec explicitly states the TPM2_ALG_ID should be cast to uint32_t. */
241 r
= tpm2_get_capability(c
, TPM2_CAP_ALGS
, (uint32_t) alg
, 1, &capability
);
245 TPML_ALG_PROPERTY algorithms
= capability
.algorithms
;
246 if (algorithms
.count
== 0 || algorithms
.algProperties
[0].alg
!= alg
) {
247 log_debug("TPM does not support alg 0x%02" PRIx16
".", alg
);
252 *ret
= algorithms
.algProperties
[0].algProperties
;
257 /* Returns 1 if the TPM supports the alg, 0 if the TPM does not support the alg, or < 0 for any error. */
258 int tpm2_supports_alg(Tpm2Context
*c
, TPM2_ALG_ID alg
) {
259 return tpm2_get_capability_alg(c
, alg
, NULL
);
262 /* Returns 1 if the TPM supports the ECC curve, 0 if not, or < 0 for any error. */
263 static int tpm2_supports_ecc_curve(Tpm2Context
*c
, TPM2_ECC_CURVE curve
) {
264 TPMU_CAPABILITIES capability
;
267 /* The spec explicitly states the TPM2_ECC_CURVE should be cast to uint32_t. */
268 r
= tpm2_get_capability(c
, TPM2_CAP_ECC_CURVES
, (uint32_t) curve
, 1, &capability
);
272 TPML_ECC_CURVE eccCurves
= capability
.eccCurves
;
273 if (eccCurves
.count
== 0 || eccCurves
.eccCurves
[0] != curve
) {
274 log_debug("TPM does not support ECC curve 0x%02" PRIx16
".", curve
);
281 /* Query the TPM for populated handles.
283 * This provides an array of handle indexes populated in the TPM, starting at the requested handle. The array will
284 * contain only populated handle addresses (which might not include the requested handle). The number of
285 * handles will be no more than the 'max' number requested. This will not search past the end of the handle
286 * range (i.e. handle & 0xff000000).
288 * Returns 0 if all populated handles in the range (starting at the requested handle) were provided (or no
289 * handles were in the range), or 1 if there are more populated handles in the range, or < 0 on any error. */
290 static int tpm2_get_capability_handles(
294 TPM2_HANDLE
**ret_handles
,
295 size_t *ret_n_handles
) {
297 _cleanup_free_ TPM2_HANDLE
*handles
= NULL
;
298 size_t n_handles
= 0;
299 TPM2_HANDLE current
= start
;
304 assert(ret_n_handles
);
307 TPMU_CAPABILITIES capability
;
308 r
= tpm2_get_capability(c
, TPM2_CAP_HANDLES
, current
, (uint32_t) max
, &capability
);
312 TPML_HANDLE handle_list
= capability
.handles
;
313 if (handle_list
.count
== 0)
316 assert(handle_list
.count
<= max
);
318 if (n_handles
> SIZE_MAX
- handle_list
.count
)
321 if (!GREEDY_REALLOC(handles
, n_handles
+ handle_list
.count
))
324 memcpy_safe(&handles
[n_handles
], handle_list
.handle
, sizeof(handles
[0]) * handle_list
.count
);
326 max
-= handle_list
.count
;
327 n_handles
+= handle_list
.count
;
329 /* Update current to the handle index after the last handle in the list. */
330 current
= handles
[n_handles
- 1] + 1;
333 /* No more handles in this range. */
337 *ret_handles
= TAKE_PTR(handles
);
338 *ret_n_handles
= n_handles
;
343 #define TPM2_HANDLE_RANGE(h) ((TPM2_HANDLE)((h) & TPM2_HR_RANGE_MASK))
344 #define TPM2_HANDLE_TYPE(h) ((TPM2_HT)(TPM2_HANDLE_RANGE(h) >> TPM2_HR_SHIFT))
346 /* Returns 1 if the handle is populated in the TPM, 0 if not, and < 0 on any error. */
347 static int tpm2_get_capability_handle(Tpm2Context
*c
, TPM2_HANDLE handle
) {
348 _cleanup_free_ TPM2_HANDLE
*handles
= NULL
;
349 size_t n_handles
= 0;
352 r
= tpm2_get_capability_handles(c
, handle
, 1, &handles
, &n_handles
);
356 return n_handles
== 0 ? false : handles
[0] == handle
;
359 /* Returns 1 if the TPM supports the parms, or 0 if the TPM does not support the parms. */
360 bool tpm2_test_parms(Tpm2Context
*c
, TPMI_ALG_PUBLIC alg
, const TPMU_PUBLIC_PARMS
*parms
) {
366 TPMT_PUBLIC_PARMS parameters
= {
368 .parameters
= *parms
,
371 rc
= sym_Esys_TestParms(c
->esys_context
, ESYS_TR_NONE
, ESYS_TR_NONE
, ESYS_TR_NONE
, ¶meters
);
372 if (rc
!= TSS2_RC_SUCCESS
)
373 /* The spec says if the parms are not supported the TPM returns "...the appropriate
374 * unmarshaling error if a parameter is not valid". Since the spec (currently) defines 15
375 * unmarshaling errors, instead of checking for them all here, let's just assume any error
376 * indicates unsupported parms, and log the specific error text. */
377 log_debug("TPM does not support tested parms: %s", sym_Tss2_RC_Decode(rc
));
379 return rc
== TSS2_RC_SUCCESS
;
382 static inline bool tpm2_supports_tpmt_public(Tpm2Context
*c
, const TPMT_PUBLIC
*public) {
386 return tpm2_test_parms(c
, public->type
, &public->parameters
);
389 static inline bool tpm2_supports_tpmt_sym_def_object(Tpm2Context
*c
, const TPMT_SYM_DEF_OBJECT
*parameters
) {
393 TPMU_PUBLIC_PARMS parms
= {
394 .symDetail
.sym
= *parameters
,
397 return tpm2_test_parms(c
, TPM2_ALG_SYMCIPHER
, &parms
);
400 static inline bool tpm2_supports_tpmt_sym_def(Tpm2Context
*c
, const TPMT_SYM_DEF
*parameters
) {
404 /* Unfortunately, TPMT_SYM_DEF and TPMT_SYM_DEF_OBEJECT are separately defined, even though they are
405 * functionally identical. */
406 TPMT_SYM_DEF_OBJECT object
= {
407 .algorithm
= parameters
->algorithm
,
408 .keyBits
= parameters
->keyBits
,
409 .mode
= parameters
->mode
,
412 return tpm2_supports_tpmt_sym_def_object(c
, &object
);
415 static Tpm2Context
*tpm2_context_free(Tpm2Context
*c
) {
420 sym_Esys_Finalize(&c
->esys_context
);
422 c
->tcti_context
= mfree(c
->tcti_context
);
423 c
->tcti_dl
= safe_dlclose(c
->tcti_dl
);
428 DEFINE_TRIVIAL_REF_UNREF_FUNC(Tpm2Context
, tpm2_context
, tpm2_context_free
);
430 static const TPMT_SYM_DEF SESSION_TEMPLATE_SYM_AES_128_CFB
= {
431 .algorithm
= TPM2_ALG_AES
,
433 .mode
.aes
= TPM2_ALG_CFB
, /* The spec requires sessions to use CFB. */
436 int tpm2_context_new(const char *device
, Tpm2Context
**ret_context
) {
437 _cleanup_(tpm2_context_unrefp
) Tpm2Context
*context
= NULL
;
443 context
= new(Tpm2Context
, 1);
447 *context
= (Tpm2Context
) {
453 return log_error_errno(r
, "TPM2 support not installed: %m");
456 device
= secure_getenv("SYSTEMD_TPM2_DEVICE");
458 /* Setting the env var to an empty string forces tpm2-tss' own device picking
459 * logic to be used. */
460 device
= empty_to_null(device
);
462 /* If nothing was specified explicitly, we'll use a hardcoded default: the "device" tcti
463 * driver and the "/dev/tpmrm0" device. We do this since on some distributions the tpm2-abrmd
464 * might be used and we really don't want that, since it is a system service and that creates
465 * various ordering issues/deadlocks during early boot. */
466 device
= "device:/dev/tpmrm0";
470 const char *param
, *driver
, *fn
;
471 const TSS2_TCTI_INFO
* info
;
472 TSS2_TCTI_INFO_FUNC func
;
475 param
= strchr(device
, ':');
477 /* Syntax #1: Pair of driver string and arbitrary parameter */
478 driver
= strndupa_safe(device
, param
- device
);
480 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 driver name is empty, refusing.");
483 } else if (path_is_absolute(device
) && path_is_valid(device
)) {
484 /* Syntax #2: TPM device node */
488 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Invalid TPM2 driver string, refusing.");
490 log_debug("Using TPM2 TCTI driver '%s' with device '%s'.", driver
, param
);
492 fn
= strjoina("libtss2-tcti-", driver
, ".so.0");
494 /* Better safe than sorry, let's refuse strings that cannot possibly be valid driver early, before going to disk. */
495 if (!filename_is_valid(fn
))
496 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 driver name '%s' not valid, refusing.", driver
);
498 context
->tcti_dl
= dlopen(fn
, RTLD_NOW
);
499 if (!context
->tcti_dl
)
500 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "Failed to load %s: %s", fn
, dlerror());
502 func
= dlsym(context
->tcti_dl
, TSS2_TCTI_INFO_SYMBOL
);
504 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
505 "Failed to find TCTI info symbol " TSS2_TCTI_INFO_SYMBOL
": %s",
510 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "Unable to get TCTI info data.");
512 log_debug("Loaded TCTI module '%s' (%s) [Version %" PRIu32
"]", info
->name
, info
->description
, info
->version
);
514 rc
= info
->init(NULL
, &sz
, NULL
);
515 if (rc
!= TPM2_RC_SUCCESS
)
516 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
517 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc
));
519 context
->tcti_context
= malloc0(sz
);
520 if (!context
->tcti_context
)
523 rc
= info
->init(context
->tcti_context
, &sz
, param
);
524 if (rc
!= TPM2_RC_SUCCESS
)
525 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
526 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc
));
529 rc
= sym_Esys_Initialize(&context
->esys_context
, context
->tcti_context
, NULL
);
530 if (rc
!= TSS2_RC_SUCCESS
)
531 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
532 "Failed to initialize TPM context: %s", sym_Tss2_RC_Decode(rc
));
534 rc
= sym_Esys_Startup(context
->esys_context
, TPM2_SU_CLEAR
);
535 if (rc
== TPM2_RC_INITIALIZE
)
536 log_debug("TPM already started up.");
537 else if (rc
== TSS2_RC_SUCCESS
)
538 log_debug("TPM successfully started up.");
540 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
541 "Failed to start up TPM: %s", sym_Tss2_RC_Decode(rc
));
543 r
= tpm2_cache_capabilities(context
);
547 /* We require AES and CFB support for session encryption. */
548 r
= tpm2_supports_alg(context
, TPM2_ALG_AES
);
552 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "TPM does not support AES.");
554 r
= tpm2_supports_alg(context
, TPM2_ALG_CFB
);
558 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "TPM does not support CFB.");
560 if (!tpm2_supports_tpmt_sym_def(context
, &SESSION_TEMPLATE_SYM_AES_128_CFB
))
561 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "TPM does not support AES-128-CFB.");
563 *ret_context
= TAKE_PTR(context
);
568 static void tpm2_handle_cleanup(ESYS_CONTEXT
*esys_context
, ESYS_TR esys_handle
, bool flush
) {
571 if (!esys_context
|| esys_handle
== ESYS_TR_NONE
)
574 /* Closing the handle removes its reference from the esys_context, but leaves the corresponding
575 * handle in the actual TPM. Flushing the handle removes its reference from the esys_context as well
576 * as removing its corresponding handle from the actual TPM. */
578 rc
= sym_Esys_FlushContext(esys_context
, esys_handle
);
580 rc
= sym_Esys_TR_Close(esys_context
, &esys_handle
);
581 if (rc
!= TSS2_RC_SUCCESS
) /* We ignore failures here (besides debug logging), since this is called
582 * in error paths, where we cannot do anything about failures anymore. And
583 * when it is called in successful codepaths by this time we already did
584 * what we wanted to do, and got the results we wanted so there's no
585 * reason to make this fail more loudly than necessary. */
586 log_debug("Failed to %s TPM handle, ignoring: %s", flush
? "flush" : "close", sym_Tss2_RC_Decode(rc
));
589 Tpm2Handle
*tpm2_handle_free(Tpm2Handle
*handle
) {
593 _cleanup_(tpm2_context_unrefp
) Tpm2Context
*context
= (Tpm2Context
*)handle
->tpm2_context
;
595 tpm2_handle_cleanup(context
->esys_context
, handle
->esys_handle
, handle
->flush
);
597 return mfree(handle
);
600 int tpm2_handle_new(Tpm2Context
*context
, Tpm2Handle
**ret_handle
) {
601 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*handle
= NULL
;
605 handle
= new(Tpm2Handle
, 1);
609 *handle
= (Tpm2Handle
) {
610 .tpm2_context
= tpm2_context_ref(context
),
611 .esys_handle
= ESYS_TR_NONE
,
615 *ret_handle
= TAKE_PTR(handle
);
620 /* Create a Tpm2Handle object that references a pre-existing handle in the TPM, at the TPM2_HANDLE address
621 * provided. This should be used only for persistent, transient, or NV handles. Returns 1 on success, 0 if
622 * the requested handle is not present in the TPM, or < 0 on error. */
623 static int tpm2_esys_handle_from_tpm_handle(
625 const Tpm2Handle
*session
,
626 TPM2_HANDLE tpm_handle
,
627 Tpm2Handle
**ret_handle
) {
633 assert(tpm_handle
> 0);
636 /* Let's restrict this, at least for now, to allow only some handle types. */
637 switch (TPM2_HANDLE_TYPE(tpm_handle
)) {
638 case TPM2_HT_PERSISTENT
:
639 case TPM2_HT_NV_INDEX
:
640 case TPM2_HT_TRANSIENT
:
643 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
644 "Refusing to create ESYS handle for PCR handle 0x%08" PRIx32
".",
646 case TPM2_HT_HMAC_SESSION
:
647 case TPM2_HT_POLICY_SESSION
:
648 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
649 "Refusing to create ESYS handle for session handle 0x%08" PRIx32
".",
651 case TPM2_HT_PERMANENT
: /* Permanent handles are defined, e.g. ESYS_TR_RH_OWNER. */
652 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
653 "Refusing to create ESYS handle for permanent handle 0x%08" PRIx32
".",
656 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
657 "Refusing to create ESYS handle for unknown handle 0x%08" PRIx32
".",
661 r
= tpm2_get_capability_handle(c
, tpm_handle
);
665 log_debug("TPM handle 0x%08" PRIx32
" not populated.", tpm_handle
);
670 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*handle
= NULL
;
671 r
= tpm2_handle_new(c
, &handle
);
675 /* Since we didn't create this handle in the TPM (this is only creating an ESYS_TR handle for the
676 * pre-existing TPM handle), we shouldn't flush (or evict) it on cleanup. */
677 handle
->flush
= false;
679 rc
= sym_Esys_TR_FromTPMPublic(
682 session
? session
->esys_handle
: ESYS_TR_NONE
,
685 &handle
->esys_handle
);
686 if (rc
!= TSS2_RC_SUCCESS
)
687 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
688 "Failed to read public info: %s", sym_Tss2_RC_Decode(rc
));
690 *ret_handle
= TAKE_PTR(handle
);
695 #define TPM2_CREDIT_RANDOM_FLAG_PATH "/run/systemd/tpm-rng-credited"
697 static int tpm2_credit_random(Tpm2Context
*c
) {
698 size_t rps
, done
= 0;
705 /* Pulls some entropy from the TPM and adds it into the kernel RNG pool. That way we can say that the
706 * key we will ultimately generate with the kernel random pool is at least as good as the TPM's RNG,
707 * but likely better. Note that we don't trust the TPM RNG very much, hence do not actually credit
710 if (access(TPM2_CREDIT_RANDOM_FLAG_PATH
, F_OK
) < 0) {
712 log_debug_errno(errno
, "Failed to detect if '" TPM2_CREDIT_RANDOM_FLAG_PATH
"' exists, ignoring: %m");
714 log_debug("Not adding TPM2 entropy to the kernel random pool again.");
715 return 0; /* Already done */
718 t
= now(CLOCK_MONOTONIC
);
720 for (rps
= random_pool_size(); rps
> 0;) {
721 _cleanup_(Esys_Freep
) TPM2B_DIGEST
*buffer
= NULL
;
723 rc
= sym_Esys_GetRandom(
728 MIN(rps
, 32U), /* 32 is supposedly a safe choice, given that AES 256bit keys are this long, and TPM2 baseline requires support for those. */
730 if (rc
!= TSS2_RC_SUCCESS
)
731 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
732 "Failed to acquire entropy from TPM: %s", sym_Tss2_RC_Decode(rc
));
734 if (buffer
->size
== 0)
735 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
736 "Zero-sized entropy returned from TPM.");
738 r
= random_write_entropy(-1, buffer
->buffer
, buffer
->size
, /* credit= */ false);
740 return log_error_errno(r
, "Failed wo write entropy to kernel: %m");
742 done
+= buffer
->size
;
743 rps
= LESS_BY(rps
, buffer
->size
);
746 log_debug("Added %zu bytes of TPM2 entropy to the kernel random pool in %s.", done
, FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - t
, 0));
748 r
= touch(TPM2_CREDIT_RANDOM_FLAG_PATH
);
750 log_debug_errno(r
, "Failed to touch '" TPM2_CREDIT_RANDOM_FLAG_PATH
"', ignoring: %m");
755 static int tpm2_read_public(
757 const Tpm2Handle
*session
,
758 const Tpm2Handle
*handle
,
759 TPM2B_PUBLIC
**ret_public
,
760 TPM2B_NAME
**ret_name
,
761 TPM2B_NAME
**ret_qname
) {
768 rc
= sym_Esys_ReadPublic(
771 session
? session
->esys_handle
: ESYS_TR_NONE
,
777 if (rc
!= TSS2_RC_SUCCESS
)
778 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
779 "Failed to read public info: %s", sym_Tss2_RC_Decode(rc
));
784 /* Get one of the legacy primary key templates.
786 * The legacy templates should only be used for older sealed data that did not use the SRK. Instead of a
787 * persistent SRK, a transient key was created to seal the data and then flushed; and the exact same template
788 * must be used to recreate the same transient key to unseal the data. The alg parameter must be TPM2_ALG_RSA
789 * or TPM2_ALG_ECC. This does not check if the alg is actually supported on this TPM. */
790 static int tpm2_get_legacy_template(TPMI_ALG_PUBLIC alg
, TPMT_PUBLIC
*ret_template
) {
792 static const TPMT_PUBLIC legacy_ecc
= {
793 .type
= TPM2_ALG_ECC
,
794 .nameAlg
= TPM2_ALG_SHA256
,
795 .objectAttributes
= TPMA_OBJECT_RESTRICTED
|TPMA_OBJECT_DECRYPT
|TPMA_OBJECT_FIXEDTPM
|TPMA_OBJECT_FIXEDPARENT
|TPMA_OBJECT_SENSITIVEDATAORIGIN
|TPMA_OBJECT_USERWITHAUTH
,
796 .parameters
.eccDetail
= {
798 .algorithm
= TPM2_ALG_AES
,
800 .mode
.aes
= TPM2_ALG_CFB
,
802 .scheme
.scheme
= TPM2_ALG_NULL
,
803 .curveID
= TPM2_ECC_NIST_P256
,
804 .kdf
.scheme
= TPM2_ALG_NULL
,
809 static const TPMT_PUBLIC legacy_rsa
= {
810 .type
= TPM2_ALG_RSA
,
811 .nameAlg
= TPM2_ALG_SHA256
,
812 .objectAttributes
= TPMA_OBJECT_RESTRICTED
|TPMA_OBJECT_DECRYPT
|TPMA_OBJECT_FIXEDTPM
|TPMA_OBJECT_FIXEDPARENT
|TPMA_OBJECT_SENSITIVEDATAORIGIN
|TPMA_OBJECT_USERWITHAUTH
,
813 .parameters
.rsaDetail
= {
815 .algorithm
= TPM2_ALG_AES
,
817 .mode
.aes
= TPM2_ALG_CFB
,
819 .scheme
.scheme
= TPM2_ALG_NULL
,
824 assert(ret_template
);
826 if (alg
== TPM2_ALG_ECC
)
827 *ret_template
= legacy_ecc
;
828 else if (alg
== TPM2_ALG_RSA
)
829 *ret_template
= legacy_rsa
;
831 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
832 "Unsupported legacy SRK alg: 0x%x", alg
);
837 /* Get a Storage Root Key (SRK) template.
839 * The SRK template values are recommended by the "TCG TPM v2.0 Provisioning Guidance" document in section
840 * 7.5.1 "Storage Primary Key (SRK) Templates", referencing "TCG EK Credential Profile for TPM Family 2.0".
841 * The EK Credential Profile version 2.0 provides only a single template each for RSA and ECC, while later EK
842 * Credential Profile versions provide more templates, and keep the original templates as "L-1" (for RSA) and
845 * https://trustedcomputinggroup.org/resource/tcg-tpm-v2-0-provisioning-guidance
846 * https://trustedcomputinggroup.org/resource/http-trustedcomputinggroup-org-wp-content-uploads-tcg-ek-credential-profile
848 * These templates are only needed to create a new persistent SRK (or a new transient key that is
849 * SRK-compatible). Preferably, the TPM should contain a shared SRK located at the reserved shared SRK handle
850 * (see TPM2_SRK_HANDLE and tpm2_get_srk() below).
852 * The alg must be TPM2_ALG_RSA or TPM2_ALG_ECC. Returns error if the requested template is not supported on
854 static int tpm2_get_srk_template(Tpm2Context
*c
, TPMI_ALG_PUBLIC alg
, TPMT_PUBLIC
*ret_template
) {
855 /* The attributes are the same between ECC and RSA templates. This has the changes specified in the
856 * Provisioning Guidance document, specifically:
857 * TPMA_OBJECT_USERWITHAUTH is added.
858 * TPMA_OBJECT_ADMINWITHPOLICY is removed.
859 * TPMA_OBJECT_NODA is added. */
860 TPMA_OBJECT srk_attributes
=
861 TPMA_OBJECT_DECRYPT
|
862 TPMA_OBJECT_FIXEDPARENT
|
863 TPMA_OBJECT_FIXEDTPM
|
865 TPMA_OBJECT_RESTRICTED
|
866 TPMA_OBJECT_SENSITIVEDATAORIGIN
|
867 TPMA_OBJECT_USERWITHAUTH
;
869 /* The symmetric configuration is the same between ECC and RSA templates. */
870 TPMT_SYM_DEF_OBJECT srk_symmetric
= {
871 .algorithm
= TPM2_ALG_AES
,
873 .mode
.aes
= TPM2_ALG_CFB
,
876 /* Both templates have an empty authPolicy as specified by the Provisioning Guidance document. */
878 /* From the EK Credential Profile template "L-2". */
879 TPMT_PUBLIC srk_ecc
= {
880 .type
= TPM2_ALG_ECC
,
881 .nameAlg
= TPM2_ALG_SHA256
,
882 .objectAttributes
= srk_attributes
,
883 .parameters
.eccDetail
= {
884 .symmetric
= srk_symmetric
,
885 .scheme
.scheme
= TPM2_ALG_NULL
,
886 .curveID
= TPM2_ECC_NIST_P256
,
887 .kdf
.scheme
= TPM2_ALG_NULL
,
891 /* From the EK Credential Profile template "L-1". */
892 TPMT_PUBLIC srk_rsa
= {
893 .type
= TPM2_ALG_RSA
,
894 .nameAlg
= TPM2_ALG_SHA256
,
895 .objectAttributes
= srk_attributes
,
896 .parameters
.rsaDetail
= {
897 .symmetric
= srk_symmetric
,
898 .scheme
.scheme
= TPM2_ALG_NULL
,
904 assert(ret_template
);
906 if (alg
== TPM2_ALG_ECC
) {
907 if (!tpm2_supports_alg(c
, TPM2_ALG_ECC
))
908 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
909 "TPM does not support ECC.");
911 if (!tpm2_supports_ecc_curve(c
, srk_ecc
.parameters
.eccDetail
.curveID
))
912 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
913 "TPM does not support ECC-NIST-P256 curve.");
915 if (!tpm2_supports_tpmt_public(c
, &srk_ecc
))
916 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
917 "TPM does not support SRK ECC template L-2.");
919 *ret_template
= srk_ecc
;
923 if (alg
== TPM2_ALG_RSA
) {
924 if (!tpm2_supports_alg(c
, TPM2_ALG_RSA
))
925 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
926 "TPM does not support RSA.");
928 if (!tpm2_supports_tpmt_public(c
, &srk_rsa
))
929 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
930 "TPM does not support SRK RSA template L-1.");
932 *ret_template
= srk_rsa
;
936 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
), "Unsupported SRK alg: 0x%x.", alg
);
939 /* The SRK handle is defined in the Provisioning Guidance document (see above) in the table "Reserved Handles
940 * for TPM Provisioning Fundamental Elements". The SRK is useful because it is "shared", meaning it has no
941 * authValue nor authPolicy set, and thus may be used by anyone on the system to generate derived keys or
942 * seal secrets. This is useful if the TPM has an auth (password) set for the 'owner hierarchy', which would
943 * prevent users from generating primary transient keys, unless they knew the owner hierarchy auth. See
944 * the Provisioning Guidance document for more details. */
945 #define TPM2_SRK_HANDLE UINT32_C(0x81000001)
948 * Retrieves the SRK handle if present. Returns 0 if SRK not present, 1 if present
951 static int tpm2_get_srk(
953 const Tpm2Handle
*session
,
954 TPM2B_PUBLIC
**ret_public
,
955 TPM2B_NAME
**ret_name
,
956 TPM2B_NAME
**ret_qname
,
957 Tpm2Handle
**ret_handle
) {
963 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*handle
= NULL
;
964 r
= tpm2_esys_handle_from_tpm_handle(c
, session
, TPM2_SRK_HANDLE
, &handle
);
967 if (r
== 0) { /* SRK not found */
979 if (ret_public
|| ret_name
|| ret_qname
) {
980 r
= tpm2_read_public(c
, session
, handle
, ret_public
, ret_name
, ret_qname
);
986 *ret_handle
= TAKE_PTR(handle
);
991 static int tpm2_make_primary(
995 TPMI_ALG_PUBLIC
*ret_alg
,
996 Tpm2Handle
**ret_primary
) {
998 static const TPM2B_SENSITIVE_CREATE primary_sensitive
= {};
999 static const TPML_PCR_SELECTION creation_pcr
= {};
1000 TPM2B_PUBLIC primary_template
= { .size
= sizeof(TPMT_PUBLIC
), };
1001 _cleanup_(release_lock_file
) LockFile srk_lock
= LOCK_FILE_INIT
;
1006 log_debug("Creating %s on TPM.", use_srk_model
? "SRK" : "Transient Primary Key");
1008 /* So apparently not all TPM2 devices support ECC. ECC is generally preferably, because it's so much
1009 * faster, noticeably so (~10s vs. ~240ms on my system). Hence, unless explicitly configured let's
1010 * try to use ECC first, and if that does not work, let's fall back to RSA. */
1012 ts
= now(CLOCK_MONOTONIC
);
1014 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*primary
= NULL
;
1016 /* we only need the SRK lock when making the SRK since its not atomic, transient
1017 * primary creations don't even matter if they stomp on each other, the TPM will
1018 * keep kicking back the same key.
1020 if (use_srk_model
) {
1021 r
= make_lock_file("/run/systemd/tpm2-srk-init", LOCK_EX
, &srk_lock
);
1023 return log_error_errno(r
, "Failed to take TPM SRK lock: %m");
1026 /* Find existing SRK and use it if present */
1027 if (use_srk_model
) {
1028 _cleanup_(Esys_Freep
) TPM2B_PUBLIC
*primary_public
= NULL
;
1029 r
= tpm2_get_srk(c
, NULL
, &primary_public
, NULL
, NULL
, &primary
);
1031 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1032 "Failed to establish if SRK is present");
1034 log_debug("Discovered existing SRK");
1036 TPMI_ALG_PUBLIC got_alg
= primary_public
->publicArea
.type
;
1037 if (alg
!= 0 && alg
!= got_alg
)
1038 log_warning("Caller asked for specific algorithm %u, but existing SRK is %u, ignoring",
1044 *ret_primary
= TAKE_PTR(primary
);
1047 log_debug("Did not find SRK, generating...");
1050 r
= tpm2_handle_new(c
, &primary
);
1054 if (IN_SET(alg
, 0, TPM2_ALG_ECC
)) {
1056 r
= tpm2_get_srk_template(c
, TPM2_ALG_ECC
, &primary_template
.publicArea
);
1058 r
= tpm2_get_legacy_template(TPM2_ALG_ECC
, &primary_template
.publicArea
);
1062 rc
= sym_Esys_CreatePrimary(
1072 &primary
->esys_handle
,
1078 if (rc
!= TSS2_RC_SUCCESS
) {
1080 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1081 "Failed to generate ECC primary key in TPM: %s", sym_Tss2_RC_Decode(rc
));
1083 log_debug("Failed to generate ECC primary key in TPM, trying RSA: %s", sym_Tss2_RC_Decode(rc
));
1085 log_debug("Successfully created ECC primary key on TPM.");
1090 if (IN_SET(alg
, 0, TPM2_ALG_RSA
)) {
1092 r
= tpm2_get_srk_template(c
, TPM2_ALG_RSA
, &primary_template
.publicArea
);
1094 r
= tpm2_get_legacy_template(TPM2_ALG_RSA
, &primary_template
.publicArea
);
1098 rc
= sym_Esys_CreatePrimary(
1108 &primary
->esys_handle
,
1113 if (rc
!= TSS2_RC_SUCCESS
)
1114 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1115 "Failed to generate RSA primary key in TPM: %s", sym_Tss2_RC_Decode(rc
));
1116 else if (alg
== 0) {
1117 log_notice("TPM2 chip apparently does not support ECC primary keys, falling back to RSA. "
1118 "This likely means TPM2 operations will be relatively slow, please be patient.");
1122 log_debug("Successfully created RSA primary key on TPM.");
1125 log_debug("Generating %s on the TPM2 took %s.", use_srk_model
? "SRK" : "Transient Primary Key",
1126 FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - ts
, USEC_PER_MSEC
));
1128 if (use_srk_model
) {
1129 rc
= sym_Esys_EvictControl(c
->esys_context
, ESYS_TR_RH_OWNER
, primary
->esys_handle
,
1130 ESYS_TR_PASSWORD
, ESYS_TR_NONE
, ESYS_TR_NONE
, TPM2_SRK_HANDLE
, &primary
->esys_handle
);
1131 if (rc
!= TSS2_RC_SUCCESS
)
1132 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1133 "Failed to persist SRK within TPM: %s", sym_Tss2_RC_Decode(rc
));
1134 primary
->flush
= false;
1138 *ret_primary
= TAKE_PTR(primary
);
1145 /* Utility functions for TPMS_PCR_SELECTION. */
1147 /* Convert a TPMS_PCR_SELECTION object to a mask. */
1148 void tpm2_tpms_pcr_selection_to_mask(const TPMS_PCR_SELECTION
*s
, uint32_t *ret
) {
1150 assert(s
->sizeofSelect
<= sizeof(s
->pcrSelect
));
1154 for (unsigned i
= 0; i
< s
->sizeofSelect
; i
++)
1155 SET_FLAG(mask
, (uint32_t)s
->pcrSelect
[i
] << (i
* 8), true);
1159 /* Convert a mask and hash alg to a TPMS_PCR_SELECTION object. */
1160 void tpm2_tpms_pcr_selection_from_mask(uint32_t mask
, TPMI_ALG_HASH hash_alg
, TPMS_PCR_SELECTION
*ret
) {
1163 /* This is currently hardcoded at 24 PCRs, above. */
1164 if (!TPM2_PCR_MASK_VALID(mask
))
1165 log_warning("PCR mask selections (%x) out of range, ignoring.",
1166 mask
& ~((uint32_t)TPM2_PCRS_MASK
));
1168 *ret
= (TPMS_PCR_SELECTION
){
1170 .sizeofSelect
= TPM2_PCRS_MAX
/ 8,
1171 .pcrSelect
[0] = mask
& 0xff,
1172 .pcrSelect
[1] = (mask
>> 8) & 0xff,
1173 .pcrSelect
[2] = (mask
>> 16) & 0xff,
1177 /* Add all PCR selections in 'b' to 'a'. Both must have the same hash alg. */
1178 void tpm2_tpms_pcr_selection_add(TPMS_PCR_SELECTION
*a
, const TPMS_PCR_SELECTION
*b
) {
1181 assert(a
->hash
== b
->hash
);
1183 uint32_t maska
, maskb
;
1184 tpm2_tpms_pcr_selection_to_mask(a
, &maska
);
1185 tpm2_tpms_pcr_selection_to_mask(b
, &maskb
);
1186 tpm2_tpms_pcr_selection_from_mask(maska
| maskb
, a
->hash
, a
);
1189 /* Remove all PCR selections in 'b' from 'a'. Both must have the same hash alg. */
1190 void tpm2_tpms_pcr_selection_sub(TPMS_PCR_SELECTION
*a
, const TPMS_PCR_SELECTION
*b
) {
1193 assert(a
->hash
== b
->hash
);
1195 uint32_t maska
, maskb
;
1196 tpm2_tpms_pcr_selection_to_mask(a
, &maska
);
1197 tpm2_tpms_pcr_selection_to_mask(b
, &maskb
);
1198 tpm2_tpms_pcr_selection_from_mask(maska
& ~maskb
, a
->hash
, a
);
1201 /* Move all PCR selections in 'b' to 'a'. Both must have the same hash alg. */
1202 void tpm2_tpms_pcr_selection_move(TPMS_PCR_SELECTION
*a
, TPMS_PCR_SELECTION
*b
) {
1206 tpm2_tpms_pcr_selection_add(a
, b
);
1207 tpm2_tpms_pcr_selection_from_mask(0, b
->hash
, b
);
1210 #define FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms) \
1211 _FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms, UNIQ)
1212 #define _FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms, uniq) \
1213 FOREACH_PCR_IN_MASK(pcr, \
1214 ({ uint32_t UNIQ_T(_mask, uniq); \
1215 tpm2_tpms_pcr_selection_to_mask(tpms, &UNIQ_T(_mask, uniq)); \
1216 UNIQ_T(_mask, uniq); \
1219 #define FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml) \
1220 UNIQ_FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml, UNIQ)
1221 #define UNIQ_FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml, uniq) \
1222 for (TPML_PCR_SELECTION *UNIQ_T(_tpml, uniq) = (TPML_PCR_SELECTION*)(tpml); \
1223 UNIQ_T(_tpml, uniq); UNIQ_T(_tpml, uniq) = NULL) \
1224 _FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, UNIQ_T(_tpml, uniq))
1225 #define _FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml) \
1226 for (TPMS_PCR_SELECTION *tpms = tpml->pcrSelections; \
1227 (uint32_t)(tpms - tpml->pcrSelections) < tpml->count; \
1230 #define FOREACH_PCR_IN_TPML_PCR_SELECTION(pcr, tpms, tpml) \
1231 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml) \
1232 FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms)
1234 char *tpm2_tpms_pcr_selection_to_string(const TPMS_PCR_SELECTION
*s
) {
1237 const char *algstr
= strna(tpm2_hash_alg_to_string(s
->hash
));
1240 tpm2_tpms_pcr_selection_to_mask(s
, &mask
);
1241 _cleanup_free_
char *maskstr
= tpm2_pcr_mask_to_string(mask
);
1245 return strjoin(algstr
, "(", maskstr
, ")");
1248 size_t tpm2_tpms_pcr_selection_weight(const TPMS_PCR_SELECTION
*s
) {
1252 tpm2_tpms_pcr_selection_to_mask(s
, &mask
);
1253 return popcount(mask
);
1256 /* Utility functions for TPML_PCR_SELECTION. */
1258 /* Remove the (0-based) index entry from 'l', shift all following entries, and update the count. */
1259 static void tpm2_tpml_pcr_selection_remove_index(TPML_PCR_SELECTION
*l
, uint32_t index
) {
1261 assert(l
->count
<= sizeof(l
->pcrSelections
));
1262 assert(index
< l
->count
);
1264 size_t s
= l
->count
- (index
+ 1);
1265 memmove(&l
->pcrSelections
[index
], &l
->pcrSelections
[index
+ 1], s
* sizeof(l
->pcrSelections
[0]));
1269 /* Get a TPMS_PCR_SELECTION from a TPML_PCR_SELECTION for the given hash alg. Returns NULL if there is no
1270 * entry for the hash alg. This guarantees the returned entry contains all the PCR selections for the given
1271 * hash alg, which may require modifying the TPML_PCR_SELECTION by removing duplicate entries. */
1272 static TPMS_PCR_SELECTION
*tpm2_tpml_pcr_selection_get_tpms_pcr_selection(
1273 TPML_PCR_SELECTION
*l
,
1274 TPMI_ALG_HASH hash_alg
) {
1278 TPMS_PCR_SELECTION
*selection
= NULL
;
1279 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s
, l
)
1280 if (s
->hash
== hash_alg
) {
1288 /* Iterate backwards through the entries, removing any other entries for the hash alg. */
1289 for (uint32_t i
= l
->count
- 1; i
> 0; i
--) {
1290 TPMS_PCR_SELECTION
*s
= &l
->pcrSelections
[i
];
1295 if (s
->hash
== hash_alg
) {
1296 tpm2_tpms_pcr_selection_move(selection
, s
);
1297 tpm2_tpml_pcr_selection_remove_index(l
, i
);
1304 /* Convert a TPML_PCR_SELECTION object to a mask. Returns -ENOENT if 'hash_alg' is not in the object. */
1305 int tpm2_tpml_pcr_selection_to_mask(const TPML_PCR_SELECTION
*l
, TPMI_ALG_HASH hash_alg
, uint32_t *ret
) {
1309 /* Make a copy, as tpm2_tpml_pcr_selection_get_tpms_pcr_selection() will modify the object if there
1310 * are multiple entries with the requested hash alg. */
1311 TPML_PCR_SELECTION lcopy
= *l
;
1313 TPMS_PCR_SELECTION
*s
;
1314 s
= tpm2_tpml_pcr_selection_get_tpms_pcr_selection(&lcopy
, hash_alg
);
1316 return SYNTHETIC_ERRNO(ENOENT
);
1318 tpm2_tpms_pcr_selection_to_mask(s
, ret
);
1322 /* Convert a mask and hash alg to a TPML_PCR_SELECTION object. */
1323 void tpm2_tpml_pcr_selection_from_mask(uint32_t mask
, TPMI_ALG_HASH hash_alg
, TPML_PCR_SELECTION
*ret
) {
1326 TPMS_PCR_SELECTION s
;
1327 tpm2_tpms_pcr_selection_from_mask(mask
, hash_alg
, &s
);
1329 *ret
= (TPML_PCR_SELECTION
){
1331 .pcrSelections
[0] = s
,
1335 /* Combine all duplicate (same hash alg) TPMS_PCR_SELECTION entries in 'l'. */
1336 static void tpm2_tpml_pcr_selection_cleanup(TPML_PCR_SELECTION
*l
) {
1337 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s
, l
)
1338 /* This removes all duplicates for s->hash. */
1339 (void) tpm2_tpml_pcr_selection_get_tpms_pcr_selection(l
, s
->hash
);
1342 /* Add the PCR selections in 's' to the corresponding hash alg TPMS_PCR_SELECTION entry in 'l'. Adds a new
1343 * TPMS_PCR_SELECTION entry for the hash alg if needed. This may modify the TPML_PCR_SELECTION by combining
1344 * entries with the same hash alg. */
1345 void tpm2_tpml_pcr_selection_add_tpms_pcr_selection(TPML_PCR_SELECTION
*l
, const TPMS_PCR_SELECTION
*s
) {
1349 if (tpm2_tpms_pcr_selection_is_empty(s
))
1352 TPMS_PCR_SELECTION
*selection
= tpm2_tpml_pcr_selection_get_tpms_pcr_selection(l
, s
->hash
);
1354 tpm2_tpms_pcr_selection_add(selection
, s
);
1358 /* It's already broken if the count is higher than the array has size for. */
1359 assert(!(l
->count
> sizeof(l
->pcrSelections
)));
1361 /* If full, the cleanup should result in at least one available entry. */
1362 if (l
->count
== sizeof(l
->pcrSelections
))
1363 tpm2_tpml_pcr_selection_cleanup(l
);
1365 assert(l
->count
< sizeof(l
->pcrSelections
));
1366 l
->pcrSelections
[l
->count
++] = *s
;
1369 /* Remove the PCR selections in 's' from the corresponding hash alg TPMS_PCR_SELECTION entry in 'l'. This
1370 * will combine all entries for 's->hash' in 'l'. */
1371 void tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(TPML_PCR_SELECTION
*l
, const TPMS_PCR_SELECTION
*s
) {
1375 if (tpm2_tpms_pcr_selection_is_empty(s
))
1378 TPMS_PCR_SELECTION
*selection
= tpm2_tpml_pcr_selection_get_tpms_pcr_selection(l
, s
->hash
);
1380 tpm2_tpms_pcr_selection_sub(selection
, s
);
1383 /* Add all PCR selections in 'b' to 'a'. */
1384 void tpm2_tpml_pcr_selection_add(TPML_PCR_SELECTION
*a
, const TPML_PCR_SELECTION
*b
) {
1388 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection_b
, (TPML_PCR_SELECTION
*) b
)
1389 tpm2_tpml_pcr_selection_add_tpms_pcr_selection(a
, selection_b
);
1392 /* Remove all PCR selections in 'b' from 'a'. */
1393 void tpm2_tpml_pcr_selection_sub(TPML_PCR_SELECTION
*a
, const TPML_PCR_SELECTION
*b
) {
1397 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection_b
, (TPML_PCR_SELECTION
*) b
)
1398 tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(a
, selection_b
);
1401 char *tpm2_tpml_pcr_selection_to_string(const TPML_PCR_SELECTION
*l
) {
1404 _cleanup_free_
char *banks
= NULL
;
1405 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s
, (TPML_PCR_SELECTION
*) l
) {
1406 if (tpm2_tpms_pcr_selection_is_empty(s
))
1409 _cleanup_free_
char *str
= tpm2_tpms_pcr_selection_to_string(s
);
1410 if (!str
|| !strextend_with_separator(&banks
, ",", str
))
1414 return strjoin("[", strempty(banks
), "]");
1417 size_t tpm2_tpml_pcr_selection_weight(const TPML_PCR_SELECTION
*l
) {
1419 assert(l
->count
<= sizeof(l
->pcrSelections
));
1422 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s
, l
) {
1423 size_t w
= tpm2_tpms_pcr_selection_weight(s
);
1424 assert(weight
<= SIZE_MAX
- w
);
1431 static void tpm2_log_debug_tpml_pcr_selection(const TPML_PCR_SELECTION
*l
, const char *msg
) {
1432 if (!DEBUG_LOGGING
|| !l
)
1435 _cleanup_free_
char *s
= tpm2_tpml_pcr_selection_to_string(l
);
1436 log_debug("%s: %s", msg
?: "PCR selection", strna(s
));
1439 static void tpm2_log_debug_buffer(const void *buffer
, size_t size
, const char *msg
) {
1440 if (!DEBUG_LOGGING
|| !buffer
|| size
== 0)
1443 _cleanup_free_
char *h
= hexmem(buffer
, size
);
1444 log_debug("%s: %s", msg
?: "Buffer", strna(h
));
1447 static void tpm2_log_debug_digest(const TPM2B_DIGEST
*digest
, const char *msg
) {
1449 tpm2_log_debug_buffer(digest
->buffer
, digest
->size
, msg
?: "Digest");
1452 static void tpm2_log_debug_name(const TPM2B_NAME
*name
, const char *msg
) {
1454 tpm2_log_debug_buffer(name
->name
, name
->size
, msg
?: "Name");
1457 static int tpm2_get_policy_digest(
1459 const Tpm2Handle
*session
,
1460 TPM2B_DIGEST
**ret_policy_digest
) {
1464 if (!DEBUG_LOGGING
&& !ret_policy_digest
)
1470 log_debug("Acquiring policy digest.");
1472 _cleanup_(Esys_Freep
) TPM2B_DIGEST
*policy_digest
= NULL
;
1473 rc
= sym_Esys_PolicyGetDigest(
1475 session
->esys_handle
,
1480 if (rc
!= TSS2_RC_SUCCESS
)
1481 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1482 "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc
));
1484 tpm2_log_debug_digest(policy_digest
, "Session policy digest");
1486 if (ret_policy_digest
)
1487 *ret_policy_digest
= TAKE_PTR(policy_digest
);
1492 static int tpm2_pcr_read(
1494 const TPML_PCR_SELECTION
*pcr_selection
,
1495 TPML_PCR_SELECTION
*ret_pcr_selection
,
1496 TPM2B_DIGEST
**ret_pcr_values
,
1497 size_t *ret_n_pcr_values
) {
1499 _cleanup_free_ TPM2B_DIGEST
*pcr_values
= NULL
;
1500 TPML_PCR_SELECTION remaining
, total_read
= {};
1501 size_t n_pcr_values
= 0;
1505 assert(pcr_selection
);
1507 remaining
= *pcr_selection
;
1508 while (!tpm2_tpml_pcr_selection_is_empty(&remaining
)) {
1509 _cleanup_(Esys_Freep
) TPML_PCR_SELECTION
*current_read
= NULL
;
1510 _cleanup_(Esys_Freep
) TPML_DIGEST
*current_values
= NULL
;
1512 tpm2_log_debug_tpml_pcr_selection(&remaining
, "Reading PCR selection");
1514 /* Unfortunately, PCR_Read will not return more than 8 values. */
1515 rc
= sym_Esys_PCR_Read(
1524 if (rc
!= TSS2_RC_SUCCESS
)
1525 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1526 "Failed to read TPM2 PCRs: %s", sym_Tss2_RC_Decode(rc
));
1528 if (tpm2_tpml_pcr_selection_is_empty(current_read
)) {
1529 log_warning("TPM2 refused to read possibly unimplemented PCRs, ignoring.");
1533 tpm2_tpml_pcr_selection_sub(&remaining
, current_read
);
1534 tpm2_tpml_pcr_selection_add(&total_read
, current_read
);
1536 if (!GREEDY_REALLOC(pcr_values
, n_pcr_values
+ current_values
->count
))
1539 memcpy_safe(&pcr_values
[n_pcr_values
], current_values
->digests
,
1540 current_values
->count
* sizeof(TPM2B_DIGEST
));
1541 n_pcr_values
+= current_values
->count
;
1543 if (DEBUG_LOGGING
) {
1545 FOREACH_PCR_IN_TPML_PCR_SELECTION(pcr
, s
, current_read
) {
1546 assert(i
< current_values
->count
);
1548 TPM2B_DIGEST
*d
= ¤t_values
->digests
[i
];
1551 TPML_PCR_SELECTION l
;
1552 tpm2_tpml_pcr_selection_from_mask(INDEX_TO_MASK(uint32_t, pcr
), s
->hash
, &l
);
1554 _cleanup_free_
char *desc
= tpm2_tpml_pcr_selection_to_string(&l
);
1555 tpm2_log_debug_digest(d
, strna(desc
));
1560 if (ret_pcr_selection
)
1561 *ret_pcr_selection
= total_read
;
1563 *ret_pcr_values
= TAKE_PTR(pcr_values
);
1564 if (ret_n_pcr_values
)
1565 *ret_n_pcr_values
= n_pcr_values
;
1570 static int tpm2_pcr_mask_good(
1575 _cleanup_free_ TPM2B_DIGEST
*pcr_values
= NULL
;
1576 TPML_PCR_SELECTION selection
;
1577 size_t n_pcr_values
= 0;
1582 /* So we have the problem that some systems might have working TPM2 chips, but the firmware doesn't
1583 * actually measure into them, or only into a suboptimal bank. If so, the PCRs should be all zero or
1584 * all 0xFF. Detect that, so that we can warn and maybe pick a better bank. */
1586 tpm2_tpml_pcr_selection_from_mask(mask
, bank
, &selection
);
1588 r
= tpm2_pcr_read(c
, &selection
, &selection
, &pcr_values
, &n_pcr_values
);
1592 /* If at least one of the selected PCR values is something other than all 0x00 or all 0xFF we are happy. */
1594 FOREACH_PCR_IN_TPML_PCR_SELECTION(pcr
, s
, &selection
) {
1595 assert(i
< n_pcr_values
);
1597 if (!memeqbyte(0x00, pcr_values
[i
].buffer
, pcr_values
[i
].size
) &&
1598 !memeqbyte(0xFF, pcr_values
[i
].buffer
, pcr_values
[i
].size
))
1607 static int tpm2_bank_has24(const TPMS_PCR_SELECTION
*selection
) {
1611 /* As per https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_PFP_r1p05_v23_pub.pdf a
1612 * TPM2 on a Client PC must have at least 24 PCRs. If this TPM has less, just skip over it. */
1613 if (selection
->sizeofSelect
< TPM2_PCRS_MAX
/8) {
1614 log_debug("Skipping TPM2 PCR bank %s with fewer than 24 PCRs.",
1615 strna(tpm2_hash_alg_to_string(selection
->hash
)));
1619 assert_cc(TPM2_PCRS_MAX
% 8 == 0);
1621 /* It's not enough to check how many PCRs there are, we also need to check that the 24 are
1622 * enabled for this bank. Otherwise this TPM doesn't qualify. */
1624 for (size_t j
= 0; j
< TPM2_PCRS_MAX
/8; j
++)
1625 if (selection
->pcrSelect
[j
] != 0xFF) {
1631 log_debug("TPM2 PCR bank %s has fewer than 24 PCR bits enabled, ignoring.",
1632 strna(tpm2_hash_alg_to_string(selection
->hash
)));
1637 static int tpm2_get_best_pcr_bank(
1640 TPMI_ALG_HASH
*ret
) {
1642 TPML_PCR_SELECTION pcrs
;
1643 TPMI_ALG_HASH supported_hash
= 0, hash_with_valid_pcr
= 0;
1649 pcrs
= tpm2_capability_pcrs(c
);
1650 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection
, &pcrs
) {
1651 TPMI_ALG_HASH hash
= selection
->hash
;
1654 /* For now we are only interested in the SHA1 and SHA256 banks */
1655 if (!IN_SET(hash
, TPM2_ALG_SHA256
, TPM2_ALG_SHA1
))
1658 r
= tpm2_bank_has24(selection
);
1664 good
= tpm2_pcr_mask_good(c
, hash
, pcr_mask
);
1668 if (hash
== TPM2_ALG_SHA256
) {
1669 supported_hash
= TPM2_ALG_SHA256
;
1671 /* Great, SHA256 is supported and has initialized PCR values, we are done. */
1672 hash_with_valid_pcr
= TPM2_ALG_SHA256
;
1676 assert(hash
== TPM2_ALG_SHA1
);
1678 if (supported_hash
== 0)
1679 supported_hash
= TPM2_ALG_SHA1
;
1681 if (good
&& hash_with_valid_pcr
== 0)
1682 hash_with_valid_pcr
= TPM2_ALG_SHA1
;
1686 /* We preferably pick SHA256, but only if its PCRs are initialized or neither the SHA1 nor the SHA256
1687 * PCRs are initialized. If SHA256 is not supported but SHA1 is and its PCRs are too, we prefer
1690 * We log at LOG_NOTICE level whenever we end up using the SHA1 bank or when the PCRs we bind to are
1691 * not initialized. */
1693 if (hash_with_valid_pcr
== TPM2_ALG_SHA256
) {
1694 assert(supported_hash
== TPM2_ALG_SHA256
);
1695 log_debug("TPM2 device supports SHA256 PCR bank and SHA256 PCRs are valid, yay!");
1696 *ret
= TPM2_ALG_SHA256
;
1697 } else if (hash_with_valid_pcr
== TPM2_ALG_SHA1
) {
1698 if (supported_hash
== TPM2_ALG_SHA256
)
1699 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.");
1701 assert(supported_hash
== TPM2_ALG_SHA1
);
1702 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.");
1705 *ret
= TPM2_ALG_SHA1
;
1706 } else if (supported_hash
== TPM2_ALG_SHA256
) {
1707 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!");
1708 *ret
= TPM2_ALG_SHA256
;
1709 } else if (supported_hash
== TPM2_ALG_SHA1
) {
1710 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!");
1711 *ret
= TPM2_ALG_SHA1
;
1713 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
1714 "TPM2 module supports neither SHA1 nor SHA256 PCR banks, cannot operate.");
1719 int tpm2_get_good_pcr_banks(
1722 TPMI_ALG_HASH
**ret
) {
1724 _cleanup_free_ TPMI_ALG_HASH
*good_banks
= NULL
, *fallback_banks
= NULL
;
1725 TPML_PCR_SELECTION pcrs
;
1726 size_t n_good_banks
= 0, n_fallback_banks
= 0;
1732 pcrs
= tpm2_capability_pcrs(c
);
1733 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection
, &pcrs
) {
1734 TPMI_ALG_HASH hash
= selection
->hash
;
1736 /* Let's see if this bank is superficially OK, i.e. has at least 24 enabled registers */
1737 r
= tpm2_bank_has24(selection
);
1743 /* Let's now see if this bank has any of the selected PCRs actually initialized */
1744 r
= tpm2_pcr_mask_good(c
, hash
, pcr_mask
);
1748 if (n_good_banks
+ n_fallback_banks
>= INT_MAX
)
1749 return log_error_errno(SYNTHETIC_ERRNO(E2BIG
), "Too many good TPM2 banks?");
1752 if (!GREEDY_REALLOC(good_banks
, n_good_banks
+1))
1755 good_banks
[n_good_banks
++] = hash
;
1757 if (!GREEDY_REALLOC(fallback_banks
, n_fallback_banks
+1))
1760 fallback_banks
[n_fallback_banks
++] = hash
;
1764 /* Preferably, use the good banks (i.e. the ones the PCR values are actually initialized so
1765 * far). Otherwise use the fallback banks (i.e. which exist and are enabled, but so far not used. */
1766 if (n_good_banks
> 0) {
1767 log_debug("Found %zu fully initialized TPM2 banks.", n_good_banks
);
1768 *ret
= TAKE_PTR(good_banks
);
1769 return (int) n_good_banks
;
1771 if (n_fallback_banks
> 0) {
1772 log_debug("Found %zu enabled but un-initialized TPM2 banks.", n_fallback_banks
);
1773 *ret
= TAKE_PTR(fallback_banks
);
1774 return (int) n_fallback_banks
;
1777 /* No suitable banks found. */
1782 int tpm2_get_good_pcr_banks_strv(
1788 _cleanup_free_ TPMI_ALG_HASH
*algs
= NULL
;
1789 _cleanup_strv_free_
char **l
= NULL
;
1795 n_algs
= tpm2_get_good_pcr_banks(c
, pcr_mask
, &algs
);
1799 for (int i
= 0; i
< n_algs
; i
++) {
1800 _cleanup_free_
char *n
= NULL
;
1801 const EVP_MD
*implementation
;
1804 salg
= tpm2_hash_alg_to_string(algs
[i
]);
1806 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "TPM2 operates with unknown PCR algorithm, can't measure.");
1808 implementation
= EVP_get_digestbyname(salg
);
1809 if (!implementation
)
1810 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "TPM2 operates with unsupported PCR algorithm, can't measure.");
1812 n
= strdup(ASSERT_PTR(EVP_MD_name(implementation
)));
1816 ascii_strlower(n
); /* OpenSSL uses uppercase digest names, we prefer them lower case. */
1818 if (strv_consume(&l
, TAKE_PTR(n
)) < 0)
1824 #else /* HAVE_OPENSSL */
1825 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
), "OpenSSL support is disabled.");
1829 /* Hash data into the digest.
1831 * If 'extend' is true, the hashing operation starts with the existing digest hash (and the digest is
1832 * required to have a hash and its size must be correct). If 'extend' is false, the digest size is
1833 * initialized to the correct size for 'alg' and the hashing operation does not include any existing digest
1834 * hash. If 'extend' is false and no data is provided, the digest is initialized to a zero digest.
1836 * On success, the digest hash will be updated with the hashing operation result and the digest size will be
1837 * correct for 'alg'.
1839 * This currently only provides SHA256, so 'alg' must be TPM2_ALG_SHA256. */
1840 int tpm2_digest_many(
1842 TPM2B_DIGEST
*digest
,
1843 const struct iovec data
[],
1847 struct sha256_ctx ctx
;
1850 assert(data
|| n_data
== 0);
1852 if (alg
!= TPM2_ALG_SHA256
)
1853 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
1854 "Hash algorithm not supported: 0x%x", alg
);
1856 if (extend
&& digest
->size
!= SHA256_DIGEST_SIZE
)
1857 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
1858 "Digest size 0x%x, require 0x%x",
1859 digest
->size
, (unsigned)SHA256_DIGEST_SIZE
);
1861 /* Since we're hardcoding SHA256 (for now), we can check this at compile time. */
1862 assert_cc(sizeof(digest
->buffer
) >= SHA256_DIGEST_SIZE
);
1866 sha256_init_ctx(&ctx
);
1869 sha256_process_bytes(digest
->buffer
, digest
->size
, &ctx
);
1871 *digest
= (TPM2B_DIGEST
){ .size
= SHA256_DIGEST_SIZE
, };
1872 if (n_data
== 0) /* If not extending and no data, return zero hash */
1876 for (size_t i
= 0; i
< n_data
; i
++)
1877 sha256_process_bytes(data
[i
].iov_base
, data
[i
].iov_len
, &ctx
);
1879 sha256_finish_ctx(&ctx
, digest
->buffer
);
1884 /* Same as tpm2_digest_many() but data is contained in TPM2B_DIGEST[]. The digests may be any size digests. */
1885 int tpm2_digest_many_digests(
1887 TPM2B_DIGEST
*digest
,
1888 const TPM2B_DIGEST data
[],
1892 _cleanup_free_
struct iovec
*iovecs
= NULL
;
1894 assert(data
|| n_data
== 0);
1896 iovecs
= new(struct iovec
, n_data
);
1900 for (size_t i
= 0; i
< n_data
; i
++)
1901 iovecs
[i
] = IOVEC_MAKE((void*) data
[i
].buffer
, data
[i
].size
);
1903 return tpm2_digest_many(alg
, digest
, iovecs
, n_data
, extend
);
1906 static int tpm2_set_auth(Tpm2Context
*c
, const Tpm2Handle
*handle
, const char *pin
) {
1907 TPM2B_AUTH auth
= {};
1917 CLEANUP_ERASE(auth
);
1919 r
= tpm2_digest_buffer(TPM2_ALG_SHA256
, &auth
, pin
, strlen(pin
), /* extend= */ false);
1923 rc
= sym_Esys_TR_SetAuth(c
->esys_context
, handle
->esys_handle
, &auth
);
1924 if (rc
!= TSS2_RC_SUCCESS
)
1925 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1926 "Failed to load PIN in TPM: %s", sym_Tss2_RC_Decode(rc
));
1931 static bool tpm2_is_encryption_session(Tpm2Context
*c
, const Tpm2Handle
*session
) {
1932 TPMA_SESSION flags
= 0;
1938 rc
= sym_Esys_TRSess_GetAttributes(c
->esys_context
, session
->esys_handle
, &flags
);
1939 if (rc
!= TSS2_RC_SUCCESS
)
1942 return (flags
& TPMA_SESSION_DECRYPT
) && (flags
& TPMA_SESSION_ENCRYPT
);
1945 static int tpm2_make_encryption_session(
1947 const Tpm2Handle
*primary
,
1948 const Tpm2Handle
*bind_key
,
1949 Tpm2Handle
**ret_session
) {
1951 const TPMA_SESSION sessionAttributes
= TPMA_SESSION_DECRYPT
| TPMA_SESSION_ENCRYPT
|
1952 TPMA_SESSION_CONTINUESESSION
;
1957 assert(ret_session
);
1959 log_debug("Starting HMAC encryption session.");
1961 /* Start a salted, unbound HMAC session with a well-known key (e.g. primary key) as tpmKey, which
1962 * means that the random salt will be encrypted with the well-known key. That way, only the TPM can
1963 * recover the salt, which is then used for key derivation. */
1964 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*session
= NULL
;
1965 r
= tpm2_handle_new(c
, &session
);
1969 rc
= sym_Esys_StartAuthSession(
1971 primary
->esys_handle
,
1972 bind_key
->esys_handle
,
1978 &SESSION_TEMPLATE_SYM_AES_128_CFB
,
1980 &session
->esys_handle
);
1981 if (rc
!= TSS2_RC_SUCCESS
)
1982 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1983 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc
));
1985 /* Enable parameter encryption/decryption with AES in CFB mode. Together with HMAC digests (which are
1986 * always used for sessions), this provides confidentiality, integrity and replay protection for
1987 * operations that use this session. */
1988 rc
= sym_Esys_TRSess_SetAttributes(c
->esys_context
, session
->esys_handle
, sessionAttributes
, 0xff);
1989 if (rc
!= TSS2_RC_SUCCESS
)
1990 return log_error_errno(
1991 SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
1992 "Failed to configure TPM session: %s",
1993 sym_Tss2_RC_Decode(rc
));
1995 *ret_session
= TAKE_PTR(session
);
2000 static int tpm2_make_policy_session(
2002 const Tpm2Handle
*primary
,
2003 const Tpm2Handle
*encryption_session
,
2005 Tpm2Handle
**ret_session
) {
2007 TPM2_SE session_type
= trial
? TPM2_SE_TRIAL
: TPM2_SE_POLICY
;
2013 assert(encryption_session
);
2014 assert(ret_session
);
2016 if (!tpm2_is_encryption_session(c
, encryption_session
))
2017 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
2018 "Missing encryption session");
2020 log_debug("Starting policy session.");
2022 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*session
= NULL
;
2023 r
= tpm2_handle_new(c
, &session
);
2027 rc
= sym_Esys_StartAuthSession(
2029 primary
->esys_handle
,
2031 encryption_session
->esys_handle
,
2036 &SESSION_TEMPLATE_SYM_AES_128_CFB
,
2038 &session
->esys_handle
);
2039 if (rc
!= TSS2_RC_SUCCESS
)
2040 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2041 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc
));
2043 *ret_session
= TAKE_PTR(session
);
2048 static int openssl_pubkey_to_tpm2_pubkey(
2051 TPM2B_PUBLIC
*output
,
2053 size_t *ret_fp_size
) {
2056 #if OPENSSL_VERSION_MAJOR >= 3
2057 _cleanup_(BN_freep
) BIGNUM
*n
= NULL
, *e
= NULL
;
2059 const BIGNUM
*n
= NULL
, *e
= NULL
;
2060 const RSA
*rsa
= NULL
;
2062 int r
, n_bytes
, e_bytes
;
2065 assert(pubkey_size
> 0);
2068 /* Converts an OpenSSL public key to a structure that the TPM chip can process. */
2070 _cleanup_fclose_
FILE *f
= NULL
;
2071 f
= fmemopen((void*) pubkey
, pubkey_size
, "r");
2075 _cleanup_(EVP_PKEY_freep
) EVP_PKEY
*input
= NULL
;
2076 input
= PEM_read_PUBKEY(f
, NULL
, NULL
, NULL
);
2078 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to parse PEM public key.");
2080 if (EVP_PKEY_base_id(input
) != EVP_PKEY_RSA
)
2081 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Provided public key is not an RSA key.");
2083 #if OPENSSL_VERSION_MAJOR >= 3
2084 if (!EVP_PKEY_get_bn_param(input
, OSSL_PKEY_PARAM_RSA_N
, &n
))
2085 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to get RSA modulus from public key.");
2087 rsa
= EVP_PKEY_get0_RSA(input
);
2089 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to extract RSA key from public key.");
2091 n
= RSA_get0_n(rsa
);
2093 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to get RSA modulus from public key.");
2096 n_bytes
= BN_num_bytes(n
);
2097 assert_se(n_bytes
> 0);
2098 if ((size_t) n_bytes
> sizeof_field(TPM2B_PUBLIC
, publicArea
.unique
.rsa
.buffer
))
2099 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "RSA modulus too large for TPM2 public key object.");
2101 #if OPENSSL_VERSION_MAJOR >= 3
2102 if (!EVP_PKEY_get_bn_param(input
, OSSL_PKEY_PARAM_RSA_E
, &e
))
2103 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to get RSA exponent from public key.");
2105 e
= RSA_get0_e(rsa
);
2107 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to get RSA exponent from public key.");
2110 e_bytes
= BN_num_bytes(e
);
2111 assert_se(e_bytes
> 0);
2112 if ((size_t) e_bytes
> sizeof_field(TPM2B_PUBLIC
, publicArea
.parameters
.rsaDetail
.exponent
))
2113 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "RSA exponent too large for TPM2 public key object.");
2115 *output
= (TPM2B_PUBLIC
) {
2116 .size
= sizeof(TPMT_PUBLIC
),
2118 .type
= TPM2_ALG_RSA
,
2119 .nameAlg
= TPM2_ALG_SHA256
,
2120 .objectAttributes
= TPMA_OBJECT_DECRYPT
| TPMA_OBJECT_SIGN_ENCRYPT
| TPMA_OBJECT_USERWITHAUTH
,
2121 .parameters
.rsaDetail
= {
2123 .scheme
= TPM2_ALG_NULL
,
2124 .details
.anySig
.hashAlg
= TPM2_ALG_NULL
,
2127 .algorithm
= TPM2_ALG_NULL
,
2128 .mode
.sym
= TPM2_ALG_NULL
,
2130 .keyBits
= n_bytes
* 8,
2131 /* .exponent will be filled in below. */
2134 .rsa
.size
= n_bytes
,
2135 /* .rsa.buffer will be filled in below. */
2140 if (BN_bn2bin(n
, output
->publicArea
.unique
.rsa
.buffer
) <= 0)
2141 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to convert RSA modulus.");
2143 if (BN_bn2bin(e
, (unsigned char*) &output
->publicArea
.parameters
.rsaDetail
.exponent
) <= 0)
2144 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Failed to convert RSA exponent.");
2147 _cleanup_free_
void *fp
= NULL
;
2150 assert(ret_fp_size
);
2152 r
= pubkey_fingerprint(input
, EVP_sha256(), &fp
, &fp_size
);
2154 return log_error_errno(r
, "Failed to calculate public key fingerprint: %m");
2156 *ret_fp
= TAKE_PTR(fp
);
2157 *ret_fp_size
= fp_size
;
2161 #else /* HAVE_OPENSSL */
2162 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
), "OpenSSL support is disabled.");
2166 static int find_signature(
2168 const TPML_PCR_SELECTION
*pcr_selection
,
2173 void *ret_signature
,
2174 size_t *ret_signature_size
) {
2181 /* Searches for a signature blob in the specified JSON object. Search keys are PCR bank, PCR mask,
2182 * public key, and policy digest. */
2184 if (!json_variant_is_object(v
))
2185 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Signature is not a JSON object.");
2187 uint16_t pcr_bank
= pcr_selection
->pcrSelections
[0].hash
;
2189 r
= tpm2_tpml_pcr_selection_to_mask(pcr_selection
, pcr_bank
, &pcr_mask
);
2193 k
= tpm2_hash_alg_to_string(pcr_bank
);
2195 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
), "Don't know PCR bank %" PRIu16
, pcr_bank
);
2197 /* First, find field by bank */
2198 b
= json_variant_by_key(v
, k
);
2200 return log_error_errno(SYNTHETIC_ERRNO(ENXIO
), "Signature lacks data for PCR bank '%s'.", k
);
2202 if (!json_variant_is_array(b
))
2203 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Bank data is not a JSON array.");
2205 /* Now iterate through all signatures known for this bank */
2206 JSON_VARIANT_ARRAY_FOREACH(i
, b
) {
2207 _cleanup_free_
void *fpj_data
= NULL
, *polj_data
= NULL
;
2208 JsonVariant
*maskj
, *fpj
, *sigj
, *polj
;
2209 size_t fpj_size
, polj_size
;
2210 uint32_t parsed_mask
;
2212 if (!json_variant_is_object(i
))
2213 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Bank data element is not a JSON object");
2215 /* Check if the PCR mask matches our expectations */
2216 maskj
= json_variant_by_key(i
, "pcrs");
2220 r
= tpm2_parse_pcr_json_array(maskj
, &parsed_mask
);
2222 return log_error_errno(r
, "Failed to parse JSON PCR mask");
2224 if (parsed_mask
!= pcr_mask
)
2225 continue; /* Not for this PCR mask */
2227 /* Then check if this is for the public key we operate with */
2228 fpj
= json_variant_by_key(i
, "pkfp");
2232 r
= json_variant_unhex(fpj
, &fpj_data
, &fpj_size
);
2234 return log_error_errno(r
, "Failed to decode fingerprint in JSON data: %m");
2236 if (memcmp_nn(fp
, fp_size
, fpj_data
, fpj_size
) != 0)
2237 continue; /* Not for this public key */
2239 /* Finally, check if this is for the PCR policy we expect this to be */
2240 polj
= json_variant_by_key(i
, "pol");
2244 r
= json_variant_unhex(polj
, &polj_data
, &polj_size
);
2246 return log_error_errno(r
, "Failed to decode policy hash JSON data: %m");
2248 if (memcmp_nn(policy
, policy_size
, polj_data
, polj_size
) != 0)
2251 /* This entry matches all our expectations, now return the signature included in it */
2252 sigj
= json_variant_by_key(i
, "sig");
2256 return json_variant_unbase64(sigj
, ret_signature
, ret_signature_size
);
2259 return log_error_errno(SYNTHETIC_ERRNO(ENXIO
), "Couldn't find signature for this PCR bank, PCR index and public key.");
2260 #else /* HAVE_OPENSSL */
2261 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
), "OpenSSL support is disabled.");
2265 /* Calculates the "name" of a public key.
2267 * As specified in TPM2 spec "Part 1: Architecture", a key's "name" is its nameAlg value followed by a hash
2268 * of its TPM2 public area, all properly marshalled. This allows a key's "name" to be dependent not only on
2269 * the key fingerprint, but also on the TPM2-specific fields that associated with the key (i.e. all fields in
2270 * TPMT_PUBLIC). Note that this means an existing key may not change any of its TPMT_PUBLIC fields, since
2271 * that would also change the key name.
2273 * Since we (currently) hardcode to always using SHA256 for hashing, this returns an error if the public key
2274 * nameAlg is not TPM2_ALG_SHA256. */
2275 int tpm2_calculate_name(const TPMT_PUBLIC
*public, TPM2B_NAME
*ret_name
) {
2284 return log_error_errno(r
, "TPM2 support not installed: %m");
2286 if (public->nameAlg
!= TPM2_ALG_SHA256
)
2287 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
2288 "Unsupported nameAlg: 0x%x",
2291 _cleanup_free_
uint8_t *buf
= NULL
;
2294 buf
= (uint8_t*) new(TPMT_PUBLIC
, 1);
2298 rc
= sym_Tss2_MU_TPMT_PUBLIC_Marshal(public, buf
, sizeof(TPMT_PUBLIC
), &size
);
2299 if (rc
!= TSS2_RC_SUCCESS
)
2300 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2301 "Failed to marshal public key: %s", sym_Tss2_RC_Decode(rc
));
2303 TPM2B_DIGEST digest
= {};
2304 r
= tpm2_digest_buffer(TPM2_ALG_SHA256
, &digest
, buf
, size
, /* extend= */ false);
2309 .hashAlg
= TPM2_ALG_SHA256
,
2311 assert(digest
.size
<= sizeof(ha
.digest
.sha256
));
2312 memcpy_safe(ha
.digest
.sha256
, digest
.buffer
, digest
.size
);
2316 rc
= sym_Tss2_MU_TPMT_HA_Marshal(&ha
, name
.name
, sizeof(name
.name
), &size
);
2317 if (rc
!= TSS2_RC_SUCCESS
)
2318 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2319 "Failed to marshal key name: %s", sym_Tss2_RC_Decode(rc
));
2322 tpm2_log_debug_name(&name
, "Calculated name");
2329 /* Get the "name" of a key from the TPM.
2331 * The "name" of a key is explained above in tpm2_calculate_name().
2333 * The handle must reference a key already present in the TPM. It may be either a public key only, or a
2334 * public/private keypair. */
2335 static int tpm2_get_name(
2337 const Tpm2Handle
*handle
,
2338 TPM2B_NAME
**ret_name
) {
2340 _cleanup_(Esys_Freep
) TPM2B_NAME
*name
= NULL
;
2347 rc
= sym_Esys_TR_GetName(c
->esys_context
, handle
->esys_handle
, &name
);
2348 if (rc
!= TSS2_RC_SUCCESS
)
2349 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2350 "Failed to get name of public key from TPM: %s", sym_Tss2_RC_Decode(rc
));
2352 tpm2_log_debug_name(name
, "Object name");
2354 *ret_name
= TAKE_PTR(name
);
2359 /* Extend 'digest' with the PolicyAuthValue calculated hash. */
2360 int tpm2_calculate_policy_auth_value(TPM2B_DIGEST
*digest
) {
2361 TPM2_CC command
= TPM2_CC_PolicyAuthValue
;
2366 assert(digest
->size
== SHA256_DIGEST_SIZE
);
2370 return log_error_errno(r
, "TPM2 support not installed: %m");
2372 uint8_t buf
[sizeof(command
)];
2375 rc
= sym_Tss2_MU_TPM2_CC_Marshal(command
, buf
, sizeof(buf
), &offset
);
2376 if (rc
!= TSS2_RC_SUCCESS
)
2377 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2378 "Failed to marshal PolicyAuthValue command: %s", sym_Tss2_RC_Decode(rc
));
2380 if (offset
!= sizeof(command
))
2381 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2382 "Offset 0x%zx wrong after marshalling PolicyAuthValue command", offset
);
2384 r
= tpm2_digest_buffer(TPM2_ALG_SHA256
, digest
, buf
, offset
, /* extend= */ true);
2388 tpm2_log_debug_digest(digest
, "PolicyAuthValue calculated digest");
2393 static int tpm2_policy_auth_value(
2395 const Tpm2Handle
*session
,
2396 TPM2B_DIGEST
**ret_policy_digest
) {
2403 log_debug("Adding authValue policy.");
2405 rc
= sym_Esys_PolicyAuthValue(
2407 session
->esys_handle
,
2411 if (rc
!= TSS2_RC_SUCCESS
)
2412 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2413 "Failed to add authValue policy to TPM: %s",
2414 sym_Tss2_RC_Decode(rc
));
2416 return tpm2_get_policy_digest(c
, session
, ret_policy_digest
);
2419 /* Extend 'digest' with the PolicyPCR calculated hash. */
2420 int tpm2_calculate_policy_pcr(
2421 const TPML_PCR_SELECTION
*pcr_selection
,
2422 const TPM2B_DIGEST pcr_values
[],
2423 size_t n_pcr_values
,
2424 TPM2B_DIGEST
*digest
) {
2426 TPM2_CC command
= TPM2_CC_PolicyPCR
;
2430 assert(pcr_selection
);
2431 assert(pcr_values
|| n_pcr_values
== 0);
2433 assert(digest
->size
== SHA256_DIGEST_SIZE
);
2437 return log_error_errno(r
, "TPM2 support not installed: %m");
2439 TPM2B_DIGEST hash
= {};
2440 r
= tpm2_digest_many_digests(TPM2_ALG_SHA256
, &hash
, pcr_values
, n_pcr_values
, /* extend= */ false);
2444 _cleanup_free_
uint8_t *buf
= NULL
;
2445 size_t size
= 0, maxsize
= sizeof(command
) + sizeof(*pcr_selection
);
2447 buf
= malloc(maxsize
);
2451 rc
= sym_Tss2_MU_TPM2_CC_Marshal(command
, buf
, maxsize
, &size
);
2452 if (rc
!= TSS2_RC_SUCCESS
)
2453 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2454 "Failed to marshal PolicyPCR command: %s", sym_Tss2_RC_Decode(rc
));
2456 rc
= sym_Tss2_MU_TPML_PCR_SELECTION_Marshal(pcr_selection
, buf
, maxsize
, &size
);
2457 if (rc
!= TSS2_RC_SUCCESS
)
2458 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2459 "Failed to marshal PCR selection: %s", sym_Tss2_RC_Decode(rc
));
2461 struct iovec data
[] = {
2462 IOVEC_MAKE(buf
, size
),
2463 IOVEC_MAKE(hash
.buffer
, hash
.size
),
2465 r
= tpm2_digest_many(TPM2_ALG_SHA256
, digest
, data
, ELEMENTSOF(data
), /* extend= */ true);
2469 tpm2_log_debug_digest(digest
, "PolicyPCR calculated digest");
2474 static int tpm2_policy_pcr(
2476 const Tpm2Handle
*session
,
2477 const TPML_PCR_SELECTION
*pcr_selection
,
2478 TPM2B_DIGEST
**ret_policy_digest
) {
2484 assert(pcr_selection
);
2486 log_debug("Adding PCR hash policy.");
2488 rc
= sym_Esys_PolicyPCR(
2490 session
->esys_handle
,
2496 if (rc
!= TSS2_RC_SUCCESS
)
2497 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2498 "Failed to add PCR policy to TPM: %s", sym_Tss2_RC_Decode(rc
));
2500 return tpm2_get_policy_digest(c
, session
, ret_policy_digest
);
2503 /* Extend 'digest' with the PolicyAuthorize calculated hash. */
2504 int tpm2_calculate_policy_authorize(
2505 const TPM2B_PUBLIC
*public,
2506 const TPM2B_DIGEST
*policy_ref
,
2507 TPM2B_DIGEST
*digest
) {
2509 TPM2_CC command
= TPM2_CC_PolicyAuthorize
;
2515 assert(digest
->size
== SHA256_DIGEST_SIZE
);
2519 return log_error_errno(r
, "TPM2 support not installed: %m");
2521 uint8_t buf
[sizeof(command
)];
2524 rc
= sym_Tss2_MU_TPM2_CC_Marshal(command
, buf
, sizeof(buf
), &offset
);
2525 if (rc
!= TSS2_RC_SUCCESS
)
2526 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2527 "Failed to marshal PolicyAuthorize command: %s", sym_Tss2_RC_Decode(rc
));
2529 if (offset
!= sizeof(command
))
2530 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2531 "Offset 0x%zx wrong after marshalling PolicyAuthorize command", offset
);
2533 TPM2B_NAME name
= {};
2534 r
= tpm2_calculate_name(&public->publicArea
, &name
);
2538 /* PolicyAuthorize does not use the previous hash value; we must zero and then extend it. */
2539 zero(digest
->buffer
);
2541 struct iovec data
[] = {
2542 IOVEC_MAKE(buf
, offset
),
2543 IOVEC_MAKE(name
.name
, name
.size
),
2545 r
= tpm2_digest_many(TPM2_ALG_SHA256
, digest
, data
, ELEMENTSOF(data
), /* extend= */ true);
2549 /* PolicyAuthorize requires hashing twice; this is either an extension or rehashing. */
2551 r
= tpm2_digest_many_digests(TPM2_ALG_SHA256
, digest
, policy_ref
, 1, /* extend= */ true);
2553 r
= tpm2_digest_rehash(TPM2_ALG_SHA256
, digest
);
2557 tpm2_log_debug_digest(digest
, "PolicyAuthorize calculated digest");
2562 static int tpm2_policy_authorize(
2564 const Tpm2Handle
*session
,
2565 TPML_PCR_SELECTION
*pcr_selection
,
2566 const TPM2B_PUBLIC
*public,
2569 JsonVariant
*signature_json
,
2570 TPM2B_DIGEST
**ret_policy_digest
) {
2577 assert(pcr_selection
);
2579 assert(fp
&& fp_size
> 0);
2581 log_debug("Adding PCR signature policy.");
2583 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*pubkey_handle
= NULL
;
2584 r
= tpm2_handle_new(c
, &pubkey_handle
);
2588 /* Load the key into the TPM */
2589 rc
= sym_Esys_LoadExternal(
2597 /* tpm2-tss >= 3.0.0 requires a ESYS_TR_RH_* constant specifying the requested
2598 * hierarchy, older versions need TPM2_RH_* instead. */
2603 &pubkey_handle
->esys_handle
);
2604 if (rc
!= TSS2_RC_SUCCESS
)
2605 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2606 "Failed to load public key into TPM: %s", sym_Tss2_RC_Decode(rc
));
2608 /* Acquire the "name" of what we just loaded */
2609 _cleanup_(Esys_Freep
) TPM2B_NAME
*pubkey_name
= NULL
;
2610 r
= tpm2_get_name(c
, pubkey_handle
, &pubkey_name
);
2614 /* If we have a signature, proceed with verifying the PCR digest */
2615 const TPMT_TK_VERIFIED
*check_ticket
;
2616 _cleanup_(Esys_Freep
) TPMT_TK_VERIFIED
*check_ticket_buffer
= NULL
;
2617 _cleanup_(Esys_Freep
) TPM2B_DIGEST
*approved_policy
= NULL
;
2618 if (signature_json
) {
2619 r
= tpm2_policy_pcr(
2627 _cleanup_free_
void *signature_raw
= NULL
;
2628 size_t signature_size
;
2634 approved_policy
->buffer
,
2635 approved_policy
->size
,
2641 /* TPM2_VerifySignature() will only verify the RSA part of the RSA+SHA256 signature,
2642 * hence we need to do the SHA256 part ourselves, first */
2643 TPM2B_DIGEST signature_hash
= *approved_policy
;
2644 r
= tpm2_digest_rehash(TPM2_ALG_SHA256
, &signature_hash
);
2648 TPMT_SIGNATURE policy_signature
= {
2649 .sigAlg
= TPM2_ALG_RSASSA
,
2650 .signature
.rsassa
= {
2651 .hash
= TPM2_ALG_SHA256
,
2652 .sig
.size
= signature_size
,
2655 if (signature_size
> sizeof(policy_signature
.signature
.rsassa
.sig
.buffer
))
2656 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "Signature larger than buffer.");
2657 memcpy(policy_signature
.signature
.rsassa
.sig
.buffer
, signature_raw
, signature_size
);
2659 rc
= sym_Esys_VerifySignature(
2661 pubkey_handle
->esys_handle
,
2667 &check_ticket_buffer
);
2668 if (rc
!= TSS2_RC_SUCCESS
)
2669 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2670 "Failed to validate signature in TPM: %s", sym_Tss2_RC_Decode(rc
));
2672 check_ticket
= check_ticket_buffer
;
2674 /* When enrolling, we pass a NULL ticket */
2675 static const TPMT_TK_VERIFIED check_ticket_null
= {
2676 .tag
= TPM2_ST_VERIFIED
,
2677 .hierarchy
= TPM2_RH_OWNER
,
2680 check_ticket
= &check_ticket_null
;
2683 rc
= sym_Esys_PolicyAuthorize(
2685 session
->esys_handle
,
2690 /* policyRef= */ &(const TPM2B_NONCE
) {},
2693 if (rc
!= TSS2_RC_SUCCESS
)
2694 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2695 "Failed to push Authorize policy into TPM: %s", sym_Tss2_RC_Decode(rc
));
2697 return tpm2_get_policy_digest(c
, session
, ret_policy_digest
);
2700 /* Extend 'digest' with the calculated policy hash. */
2701 static int tpm2_calculate_sealing_policy(
2702 const TPML_PCR_SELECTION
*hash_pcr_selection
,
2703 const TPM2B_DIGEST
*hash_pcr_values
,
2704 size_t n_hash_pcr_values
,
2705 const TPM2B_PUBLIC
*public,
2707 TPM2B_DIGEST
*digest
) {
2714 r
= tpm2_calculate_policy_authorize(public, NULL
, digest
);
2719 if (hash_pcr_selection
&& !tpm2_tpml_pcr_selection_is_empty(hash_pcr_selection
)) {
2720 r
= tpm2_calculate_policy_pcr(hash_pcr_selection
, hash_pcr_values
, n_hash_pcr_values
, digest
);
2726 r
= tpm2_calculate_policy_auth_value(digest
);
2734 static int tpm2_build_sealing_policy(
2736 const Tpm2Handle
*session
,
2737 uint32_t hash_pcr_mask
,
2739 const TPM2B_PUBLIC
*public,
2742 uint32_t pubkey_pcr_mask
,
2743 JsonVariant
*signature_json
,
2745 TPM2B_DIGEST
**ret_policy_digest
) {
2751 assert(pubkey_pcr_mask
== 0 || public);
2753 log_debug("Building sealing policy.");
2755 if ((hash_pcr_mask
| pubkey_pcr_mask
) != 0) {
2756 r
= tpm2_pcr_mask_good(c
, pcr_bank
, hash_pcr_mask
|pubkey_pcr_mask
);
2760 log_warning("Selected TPM2 PCRs are not initialized on this system.");
2763 if (pubkey_pcr_mask
!= 0) {
2764 TPML_PCR_SELECTION pcr_selection
;
2765 tpm2_tpml_pcr_selection_from_mask(pubkey_pcr_mask
, (TPMI_ALG_HASH
)pcr_bank
, &pcr_selection
);
2766 r
= tpm2_policy_authorize(c
, session
, &pcr_selection
, public, fp
, fp_size
, signature_json
, NULL
);
2771 if (hash_pcr_mask
!= 0) {
2772 TPML_PCR_SELECTION pcr_selection
;
2773 tpm2_tpml_pcr_selection_from_mask(hash_pcr_mask
, (TPMI_ALG_HASH
)pcr_bank
, &pcr_selection
);
2774 r
= tpm2_policy_pcr(c
, session
, &pcr_selection
, NULL
);
2780 r
= tpm2_policy_auth_value(c
, session
, NULL
);
2785 r
= tpm2_get_policy_digest(c
, session
, ret_policy_digest
);
2792 int tpm2_seal(const char *device
,
2793 uint32_t hash_pcr_mask
,
2795 const size_t pubkey_size
,
2796 uint32_t pubkey_pcr_mask
,
2799 size_t *ret_secret_size
,
2801 size_t *ret_blob_size
,
2802 void **ret_pcr_hash
,
2803 size_t *ret_pcr_hash_size
,
2804 uint16_t *ret_pcr_bank
,
2805 uint16_t *ret_primary_alg
,
2807 size_t *ret_srk_buf_size
) {
2809 _cleanup_(Esys_Freep
) TPM2B_PRIVATE
*private = NULL
;
2810 _cleanup_(Esys_Freep
) TPM2B_PUBLIC
*public = NULL
;
2811 _cleanup_(Esys_Freep
) uint8_t *srk_buf
= NULL
;
2812 static const TPML_PCR_SELECTION creation_pcr
= {};
2813 _cleanup_(erase_and_freep
) void *secret
= NULL
;
2814 _cleanup_free_
void *hash
= NULL
;
2815 TPM2B_SENSITIVE_CREATE hmac_sensitive
;
2816 TPM2B_PUBLIC hmac_template
;
2819 size_t srk_buf_size
;
2822 assert(pubkey
|| pubkey_size
== 0);
2825 assert(ret_secret_size
);
2827 assert(ret_blob_size
);
2828 assert(ret_pcr_hash
);
2829 assert(ret_pcr_hash_size
);
2830 assert(ret_pcr_bank
);
2832 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask
));
2833 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask
));
2835 /* So here's what we do here: we connect to the TPM2 chip. It persistently contains a "seed" key that
2836 * is randomized when the TPM2 is first initialized or reset and remains stable across boots. We
2837 * generate a "primary" key pair derived from that (ECC if possible, RSA as fallback). Given the seed
2838 * remains fixed this will result in the same key pair whenever we specify the exact same parameters
2839 * for it. We then create a PCR-bound policy session, which calculates a hash on the current PCR
2840 * values of the indexes we specify. We then generate a randomized key on the host (which is the key
2841 * we actually enroll in the LUKS2 keyslots), which we upload into the TPM2, where it is encrypted
2842 * with the "primary" key, taking the PCR policy session into account. We then download the encrypted
2843 * key from the TPM2 ("sealing") and marshall it into binary form, which is ultimately placed in the
2844 * LUKS2 JSON header.
2846 * The TPM2 "seed" key and "primary" keys never leave the TPM2 chip (and cannot be extracted at
2847 * all). The random key we enroll in LUKS2 we generate on the host using the Linux random device. It
2848 * is stored in the LUKS2 JSON only in encrypted form with the "primary" key of the TPM2 chip, thus
2849 * binding the unlocking to the TPM2 chip. */
2851 start
= now(CLOCK_MONOTONIC
);
2853 CLEANUP_ERASE(hmac_sensitive
);
2855 _cleanup_(tpm2_context_unrefp
) Tpm2Context
*c
= NULL
;
2856 r
= tpm2_context_new(device
, &c
);
2860 TPMI_ALG_HASH pcr_bank
= 0;
2861 if (hash_pcr_mask
| pubkey_pcr_mask
) {
2862 /* Some TPM2 devices only can do SHA1. Prefer SHA256 but allow SHA1. */
2863 r
= tpm2_get_best_pcr_bank(c
, hash_pcr_mask
|pubkey_pcr_mask
, &pcr_bank
);
2868 TPML_PCR_SELECTION hash_pcr_selection
= {};
2869 _cleanup_free_ TPM2B_DIGEST
*hash_pcr_values
= NULL
;
2870 size_t n_hash_pcr_values
= 0;
2871 if (hash_pcr_mask
) {
2872 /* For now, we just read the current values from the system; we need to be able to specify
2873 * expected values, eventually. */
2874 tpm2_tpml_pcr_selection_from_mask(hash_pcr_mask
, pcr_bank
, &hash_pcr_selection
);
2875 r
= tpm2_pcr_read(c
, &hash_pcr_selection
, &hash_pcr_selection
, &hash_pcr_values
, &n_hash_pcr_values
);
2880 TPM2B_PUBLIC pubkey_tpm2
, *authorize_key
= NULL
;
2882 r
= openssl_pubkey_to_tpm2_pubkey(pubkey
, pubkey_size
, &pubkey_tpm2
, NULL
, NULL
);
2885 authorize_key
= &pubkey_tpm2
;
2888 TPM2B_DIGEST policy_digest
;
2889 r
= tpm2_digest_init(TPM2_ALG_SHA256
, &policy_digest
);
2893 r
= tpm2_calculate_sealing_policy(
2894 &hash_pcr_selection
,
2903 /* We use a keyed hash object (i.e. HMAC) to store the secret key we want to use for unlocking the
2904 * LUKS2 volume with. We don't ever use for HMAC/keyed hash operations however, we just use it
2905 * because it's a key type that is universally supported and suitable for symmetric binary blobs. */
2906 hmac_template
= (TPM2B_PUBLIC
) {
2907 .size
= sizeof(TPMT_PUBLIC
),
2909 .type
= TPM2_ALG_KEYEDHASH
,
2910 .nameAlg
= TPM2_ALG_SHA256
,
2911 .objectAttributes
= TPMA_OBJECT_FIXEDTPM
| TPMA_OBJECT_FIXEDPARENT
,
2912 .parameters
.keyedHashDetail
.scheme
.scheme
= TPM2_ALG_NULL
,
2913 .unique
.keyedHash
.size
= SHA256_DIGEST_SIZE
,
2914 .authPolicy
= policy_digest
,
2918 hmac_sensitive
= (TPM2B_SENSITIVE_CREATE
) {
2919 .size
= sizeof(hmac_sensitive
.sensitive
),
2920 .sensitive
.data
.size
= 32,
2923 r
= tpm2_digest_buffer(TPM2_ALG_SHA256
, &hmac_sensitive
.sensitive
.userAuth
, pin
, strlen(pin
), /* extend= */ false);
2928 assert(sizeof(hmac_sensitive
.sensitive
.data
.buffer
) >= hmac_sensitive
.sensitive
.data
.size
);
2930 (void) tpm2_credit_random(c
);
2932 log_debug("Generating secret key data.");
2934 r
= crypto_random_bytes(hmac_sensitive
.sensitive
.data
.buffer
, hmac_sensitive
.sensitive
.data
.size
);
2936 return log_error_errno(r
, "Failed to generate secret key: %m");
2938 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*primary_handle
= NULL
;
2939 TPMI_ALG_PUBLIC primary_alg
;
2940 r
= tpm2_make_primary(c
, /* alg = */0, !!ret_srk_buf
, &primary_alg
, &primary_handle
);
2944 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*encryption_session
= NULL
;
2945 r
= tpm2_make_encryption_session(c
, primary_handle
, &TPM2_HANDLE_NONE
, &encryption_session
);
2949 log_debug("Creating HMAC key.");
2951 rc
= sym_Esys_Create(
2953 primary_handle
->esys_handle
,
2954 encryption_session
->esys_handle
, /* use HMAC session to enable parameter encryption */
2966 if (rc
!= TSS2_RC_SUCCESS
)
2967 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2968 "Failed to generate HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc
));
2970 secret
= memdup(hmac_sensitive
.sensitive
.data
.buffer
, hmac_sensitive
.sensitive
.data
.size
);
2974 log_debug("Marshalling private and public part of HMAC key.");
2976 _cleanup_free_
void *blob
= NULL
;
2977 size_t max_size
= sizeof(*private) + sizeof(*public), blob_size
= 0;
2979 blob
= malloc0(max_size
);
2983 rc
= sym_Tss2_MU_TPM2B_PRIVATE_Marshal(private, blob
, max_size
, &blob_size
);
2984 if (rc
!= TSS2_RC_SUCCESS
)
2985 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2986 "Failed to marshal private key: %s", sym_Tss2_RC_Decode(rc
));
2988 rc
= sym_Tss2_MU_TPM2B_PUBLIC_Marshal(public, blob
, max_size
, &blob_size
);
2989 if (rc
!= TSS2_RC_SUCCESS
)
2990 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
2991 "Failed to marshal public key: %s", sym_Tss2_RC_Decode(rc
));
2993 hash
= memdup(policy_digest
.buffer
, policy_digest
.size
);
2997 /* serialize the key for storage in the LUKS header. A deserialized ESYS_TR provides both
2998 * the raw TPM handle as well as the object name. The object name is used to verify that
2999 * the key we use later is the key we expect to establish the session with.
3002 log_debug("Serializing SRK ESYS_TR reference");
3003 rc
= sym_Esys_TR_Serialize(c
->esys_context
, primary_handle
->esys_handle
, &srk_buf
, &srk_buf_size
);
3004 if (rc
!= TSS2_RC_SUCCESS
)
3005 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
3006 "Failed to serialize primary key: %s", sym_Tss2_RC_Decode(rc
));
3010 log_debug("Completed TPM2 key sealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - start
, 1));
3014 * make a copy since we don't want the caller to understand that
3015 * ESYS allocated the pointer. It would make tracking what deallocator
3016 * to use for srk_buf in which context a PITA.
3018 void *tmp
= memdup(srk_buf
, srk_buf_size
);
3022 *ret_srk_buf
= TAKE_PTR(tmp
);
3023 *ret_srk_buf_size
= srk_buf_size
;
3026 *ret_secret
= TAKE_PTR(secret
);
3027 *ret_secret_size
= hmac_sensitive
.sensitive
.data
.size
;
3028 *ret_blob
= TAKE_PTR(blob
);
3029 *ret_blob_size
= blob_size
;
3030 *ret_pcr_hash
= TAKE_PTR(hash
);
3031 *ret_pcr_hash_size
= policy_digest
.size
;
3032 *ret_pcr_bank
= pcr_bank
;
3033 *ret_primary_alg
= primary_alg
;
3038 #define RETRY_UNSEAL_MAX 30u
3040 int tpm2_unseal(const char *device
,
3041 uint32_t hash_pcr_mask
,
3045 uint32_t pubkey_pcr_mask
,
3046 JsonVariant
*signature
,
3048 uint16_t primary_alg
,
3051 const void *known_policy_hash
,
3052 size_t known_policy_hash_size
,
3053 const void *srk_buf
,
3054 size_t srk_buf_size
,
3056 size_t *ret_secret_size
) {
3058 _cleanup_(Esys_Freep
) TPM2B_SENSITIVE_DATA
* unsealed
= NULL
;
3059 _cleanup_(erase_and_freep
) char *secret
= NULL
;
3060 TPM2B_PRIVATE
private = {};
3061 TPM2B_PUBLIC
public = {};
3068 assert(blob_size
> 0);
3069 assert(known_policy_hash_size
== 0 || known_policy_hash
);
3070 assert(pubkey_size
== 0 || pubkey
);
3072 assert(ret_secret_size
);
3074 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask
));
3075 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask
));
3079 return log_error_errno(r
, "TPM2 support is not installed.");
3081 /* So here's what we do here: We connect to the TPM2 chip. As we do when sealing we generate a
3082 * "primary" key on the TPM2 chip, with the same parameters as well as a PCR-bound policy session.
3083 * Given we pass the same parameters, this will result in the same "primary" key, and same policy
3084 * hash (the latter of course, only if the PCR values didn't change in between). We unmarshal the
3085 * encrypted key we stored in the LUKS2 JSON token header and upload it into the TPM2, where it is
3086 * decrypted if the seed and the PCR policy were right ("unsealing"). We then download the result,
3087 * and use it to unlock the LUKS2 volume. */
3089 start
= now(CLOCK_MONOTONIC
);
3091 log_debug("Unmarshalling private part of HMAC key.");
3093 rc
= sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal(blob
, blob_size
, &offset
, &private);
3094 if (rc
!= TSS2_RC_SUCCESS
)
3095 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
3096 "Failed to unmarshal private key: %s", sym_Tss2_RC_Decode(rc
));
3098 log_debug("Unmarshalling public part of HMAC key.");
3100 rc
= sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal(blob
, blob_size
, &offset
, &public);
3101 if (rc
!= TSS2_RC_SUCCESS
)
3102 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
3103 "Failed to unmarshal public key: %s", sym_Tss2_RC_Decode(rc
));
3105 _cleanup_(tpm2_context_unrefp
) Tpm2Context
*c
= NULL
;
3106 r
= tpm2_context_new(device
, &c
);
3110 /* If their is a primary key we trust, like an SRK, use it */
3111 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*primary
= NULL
;
3114 r
= tpm2_handle_new(c
, &primary
);
3118 primary
->flush
= false;
3120 log_debug("Found existing SRK key to use, deserializing ESYS_TR");
3121 rc
= sym_Esys_TR_Deserialize(
3125 &primary
->esys_handle
);
3126 if (rc
!= TSS2_RC_SUCCESS
)
3127 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
3128 "Failed to deserialize primary key: %s", sym_Tss2_RC_Decode(rc
));
3129 /* old callers without an SRK still need to create a key */
3131 r
= tpm2_make_primary(c
, primary_alg
, false, NULL
, &primary
);
3136 log_debug("Loading HMAC key into TPM.");
3139 * Nothing sensitive on the bus, no need for encryption. Even if an attacker
3140 * gives you back a different key, the session initiation will fail. In the
3141 * SRK model, the tpmKey is verified. In the non-srk model, with pin, the bindKey
3142 * provides protections.
3144 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*hmac_key
= NULL
;
3145 r
= tpm2_handle_new(c
, &hmac_key
);
3151 primary
->esys_handle
,
3157 &hmac_key
->esys_handle
);
3158 if (rc
!= TSS2_RC_SUCCESS
) {
3159 /* If we're in dictionary attack lockout mode, we should see a lockout error here, which we
3160 * need to translate for the caller. */
3161 if (rc
== TPM2_RC_LOCKOUT
)
3162 return log_error_errno(
3163 SYNTHETIC_ERRNO(ENOLCK
),
3164 "TPM2 device is in dictionary attack lockout mode.");
3166 return log_error_errno(
3167 SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
3168 "Failed to load HMAC key in TPM: %s",
3169 sym_Tss2_RC_Decode(rc
));
3172 TPM2B_PUBLIC pubkey_tpm2
, *authorize_key
= NULL
;
3173 _cleanup_free_
void *fp
= NULL
;
3176 r
= openssl_pubkey_to_tpm2_pubkey(pubkey
, pubkey_size
, &pubkey_tpm2
, &fp
, &fp_size
);
3179 authorize_key
= &pubkey_tpm2
;
3183 * if a pin is set for the seal object, use it to bind the session
3184 * key to that object. This prevents active bus interposers from
3185 * faking a TPM and seeing the unsealed value. An active interposer
3186 * could fake a TPM, satisfying the encrypted session, and just
3187 * forward everything to the *real* TPM.
3189 r
= tpm2_set_auth(c
, hmac_key
, pin
);
3193 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*encryption_session
= NULL
;
3194 r
= tpm2_make_encryption_session(c
, primary
, hmac_key
, &encryption_session
);
3198 for (unsigned i
= RETRY_UNSEAL_MAX
;; i
--) {
3199 _cleanup_(tpm2_handle_freep
) Tpm2Handle
*policy_session
= NULL
;
3200 _cleanup_(Esys_Freep
) TPM2B_DIGEST
*policy_digest
= NULL
;
3201 r
= tpm2_make_policy_session(
3210 r
= tpm2_build_sealing_policy(
3224 /* If we know the policy hash to expect, and it doesn't match, we can shortcut things here, and not
3225 * wait until the TPM2 tells us to go away. */
3226 if (known_policy_hash_size
> 0 &&
3227 memcmp_nn(policy_digest
->buffer
, policy_digest
->size
, known_policy_hash
, known_policy_hash_size
) != 0)
3228 return log_error_errno(SYNTHETIC_ERRNO(EPERM
),
3229 "Current policy digest does not match stored policy digest, cancelling "
3230 "TPM2 authentication attempt.");
3232 log_debug("Unsealing HMAC key.");
3234 rc
= sym_Esys_Unseal(
3236 hmac_key
->esys_handle
,
3237 policy_session
->esys_handle
,
3238 encryption_session
->esys_handle
, /* use HMAC session to enable parameter encryption */
3241 if (rc
== TSS2_RC_SUCCESS
)
3243 if (rc
!= TPM2_RC_PCR_CHANGED
|| i
== 0)
3244 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
3245 "Failed to unseal HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc
));
3246 log_debug("A PCR value changed during the TPM2 policy session, restarting HMAC key unsealing (%u tries left).", i
);
3249 secret
= memdup(unsealed
->buffer
, unsealed
->size
);
3250 explicit_bzero_safe(unsealed
->buffer
, unsealed
->size
);
3255 log_debug("Completed TPM2 key unsealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC
) - start
, 1));
3257 *ret_secret
= TAKE_PTR(secret
);
3258 *ret_secret_size
= unsealed
->size
;
3265 int tpm2_list_devices(void) {
3267 _cleanup_(table_unrefp
) Table
*t
= NULL
;
3268 _cleanup_closedir_
DIR *d
= NULL
;
3273 return log_error_errno(r
, "TPM2 support is not installed.");
3275 t
= table_new("path", "device", "driver");
3279 d
= opendir("/sys/class/tpmrm");
3281 log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
, "Failed to open /sys/class/tpmrm: %m");
3282 if (errno
!= ENOENT
)
3286 _cleanup_free_
char *device_path
= NULL
, *device
= NULL
, *driver_path
= NULL
, *driver
= NULL
, *node
= NULL
;
3289 de
= readdir_no_dot(d
);
3293 device_path
= path_join("/sys/class/tpmrm", de
->d_name
, "device");
3297 r
= readlink_malloc(device_path
, &device
);
3299 log_debug_errno(r
, "Failed to read device symlink %s, ignoring: %m", device_path
);
3301 driver_path
= path_join(device_path
, "driver");
3305 r
= readlink_malloc(driver_path
, &driver
);
3307 log_debug_errno(r
, "Failed to read driver symlink %s, ignoring: %m", driver_path
);
3310 node
= path_join("/dev", de
->d_name
);
3317 TABLE_STRING
, device
? last_path_component(device
) : NULL
,
3318 TABLE_STRING
, driver
? last_path_component(driver
) : NULL
);
3320 return table_log_add_error(r
);
3324 if (table_get_rows(t
) <= 1) {
3325 log_info("No suitable TPM2 devices found.");
3329 r
= table_print(t
, stdout
);
3331 return log_error_errno(r
, "Failed to show device table: %m");
3335 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
3336 "TPM2 not supported on this build.");
3340 int tpm2_find_device_auto(
3341 int log_level
, /* log level when no device is found */
3344 _cleanup_closedir_
DIR *d
= NULL
;
3349 return log_error_errno(r
, "TPM2 support is not installed.");
3351 d
= opendir("/sys/class/tpmrm");
3353 log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
,
3354 "Failed to open /sys/class/tpmrm: %m");
3355 if (errno
!= ENOENT
)
3358 _cleanup_free_
char *node
= NULL
;
3363 de
= readdir_no_dot(d
);
3368 return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ
),
3369 "More than one TPM2 (tpmrm) device found.");
3371 node
= path_join("/dev", de
->d_name
);
3377 *ret
= TAKE_PTR(node
);
3382 return log_full_errno(log_level
, SYNTHETIC_ERRNO(ENODEV
), "No TPM2 (tpmrm) device found.");
3384 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
3385 "TPM2 not supported on this build.");
3390 int tpm2_extend_bytes(
3397 size_t secret_size
) {
3400 TPML_DIGEST_VALUES values
= {};
3404 assert(data
|| data_size
== 0);
3405 assert(secret
|| secret_size
== 0);
3407 if (data_size
== SIZE_MAX
)
3408 data_size
= strlen(data
);
3409 if (secret_size
== SIZE_MAX
)
3410 secret_size
= strlen(secret
);
3412 if (pcr_index
>= TPM2_PCRS_MAX
)
3413 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
), "Can't measure into unsupported PCR %u, refusing.", pcr_index
);
3415 if (strv_isempty(banks
))
3418 STRV_FOREACH(bank
, banks
) {
3419 const EVP_MD
*implementation
;
3422 assert_se(implementation
= EVP_get_digestbyname(*bank
));
3424 if (values
.count
>= ELEMENTSOF(values
.digests
))
3425 return log_error_errno(SYNTHETIC_ERRNO(E2BIG
), "Too many banks selected.");
3427 if ((size_t) EVP_MD_size(implementation
) > sizeof(values
.digests
[values
.count
].digest
))
3428 return log_error_errno(SYNTHETIC_ERRNO(E2BIG
), "Hash result too large for TPM2.");
3430 id
= tpm2_hash_alg_from_string(EVP_MD_name(implementation
));
3432 return log_error_errno(id
, "Can't map hash name to TPM2.");
3434 values
.digests
[values
.count
].hashAlg
= id
;
3436 /* So here's a twist: sometimes we want to measure secrets (e.g. root file system volume
3437 * key), but we'd rather not leak a literal hash of the secret to the TPM (given that the
3438 * wire is unprotected, and some other subsystem might use the simple, literal hash of the
3439 * secret for other purposes, maybe because it needs a shorter secret derived from it for
3440 * some unrelated purpose, who knows). Hence we instead measure an HMAC signature of a
3441 * private non-secret string instead. */
3442 if (secret_size
> 0) {
3443 if (!HMAC(implementation
, secret
, secret_size
, data
, data_size
, (unsigned char*) &values
.digests
[values
.count
].digest
, NULL
))
3444 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "Failed to calculate HMAC of data to measure.");
3445 } else if (EVP_Digest(data
, data_size
, (unsigned char*) &values
.digests
[values
.count
].digest
, NULL
, implementation
, NULL
) != 1)
3446 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE
), "Failed to hash data to measure.");
3451 rc
= sym_Esys_PCR_Extend(
3453 ESYS_TR_PCR0
+ pcr_index
,
3458 if (rc
!= TSS2_RC_SUCCESS
)
3459 return log_error_errno(
3460 SYNTHETIC_ERRNO(ENOTRECOVERABLE
),
3461 "Failed to measure into PCR %u: %s",
3463 sym_Tss2_RC_Decode(rc
));
3466 #else /* HAVE_OPENSSL */
3467 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
), "OpenSSL support is disabled.");
3472 char *tpm2_pcr_mask_to_string(uint32_t mask
) {
3473 _cleanup_free_
char *s
= NULL
;
3475 FOREACH_PCR_IN_MASK(n
, mask
)
3476 if (strextendf_with_separator(&s
, "+", "%d", n
) < 0)
3485 int tpm2_pcr_mask_from_string(const char *arg
, uint32_t *ret_mask
) {
3497 /* Parses a "," or "+" separated list of PCR indexes. We support "," since this is a list after all,
3498 * and most other tools expect comma separated PCR specifications. We also support "+" since in
3499 * /etc/crypttab the "," is already used to separate options, hence a different separator is nice to
3500 * avoid escaping. */
3502 const char *p
= arg
;
3504 _cleanup_free_
char *pcr
= NULL
;
3507 r
= extract_first_word(&p
, &pcr
, ",+", EXTRACT_DONT_COALESCE_SEPARATORS
);
3511 return log_error_errno(r
, "Failed to parse PCR list: %s", arg
);
3513 r
= pcr_index_from_string(pcr
);
3515 return log_error_errno(r
, "Failed to parse specified PCR or specified PCR is out of range: %s", pcr
);
3524 int tpm2_make_pcr_json_array(uint32_t pcr_mask
, JsonVariant
**ret
) {
3525 _cleanup_(json_variant_unrefp
) JsonVariant
*a
= NULL
;
3526 JsonVariant
* pcr_array
[TPM2_PCRS_MAX
];
3527 unsigned n_pcrs
= 0;
3530 for (size_t i
= 0; i
< ELEMENTSOF(pcr_array
); i
++) {
3531 if ((pcr_mask
& (UINT32_C(1) << i
)) == 0)
3534 r
= json_variant_new_integer(pcr_array
+ n_pcrs
, i
);
3541 r
= json_variant_new_array(&a
, pcr_array
, n_pcrs
);
3550 json_variant_unref_many(pcr_array
, n_pcrs
);
3554 int tpm2_parse_pcr_json_array(JsonVariant
*v
, uint32_t *ret
) {
3558 if (!json_variant_is_array(v
))
3559 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PCR array is not a JSON array.");
3561 JSON_VARIANT_ARRAY_FOREACH(e
, v
) {
3564 if (!json_variant_is_unsigned(e
))
3565 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PCR is not an unsigned integer.");
3567 u
= json_variant_unsigned(e
);
3568 if (u
>= TPM2_PCRS_MAX
)
3569 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PCR number out of range: %" PRIu64
, u
);
3571 mask
|= UINT32_C(1) << u
;
3580 int tpm2_make_luks2_json(
3582 uint32_t hash_pcr_mask
,
3586 uint32_t pubkey_pcr_mask
,
3587 uint16_t primary_alg
,
3590 const void *policy_hash
,
3591 size_t policy_hash_size
,
3594 const void *srk_buf
,
3595 size_t srk_buf_size
,
3597 JsonVariant
**ret
) {
3599 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
, *hmj
= NULL
, *pkmj
= NULL
;
3600 _cleanup_free_
char *keyslot_as_string
= NULL
;
3603 assert(blob
|| blob_size
== 0);
3604 assert(policy_hash
|| policy_hash_size
== 0);
3605 assert(pubkey
|| pubkey_size
== 0);
3607 if (asprintf(&keyslot_as_string
, "%i", keyslot
) < 0)
3610 r
= tpm2_make_pcr_json_array(hash_pcr_mask
, &hmj
);
3614 if (pubkey_pcr_mask
!= 0) {
3615 r
= tpm2_make_pcr_json_array(pubkey_pcr_mask
, &pkmj
);
3620 /* Note: We made the mistake of using "-" in the field names, which isn't particular compatible with
3621 * other programming languages. Let's not make things worse though, i.e. future additions to the JSON
3622 * object should use "_" rather than "-" in field names. */
3626 JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-tpm2")),
3627 JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string
))),
3628 JSON_BUILD_PAIR("tpm2-blob", JSON_BUILD_BASE64(blob
, blob_size
)),
3629 JSON_BUILD_PAIR("tpm2-pcrs", JSON_BUILD_VARIANT(hmj
)),
3630 JSON_BUILD_PAIR_CONDITION(!!tpm2_hash_alg_to_string(pcr_bank
), "tpm2-pcr-bank", JSON_BUILD_STRING(tpm2_hash_alg_to_string(pcr_bank
))),
3631 JSON_BUILD_PAIR_CONDITION(!!tpm2_asym_alg_to_string(primary_alg
), "tpm2-primary-alg", JSON_BUILD_STRING(tpm2_asym_alg_to_string(primary_alg
))),
3632 JSON_BUILD_PAIR("tpm2-policy-hash", JSON_BUILD_HEX(policy_hash
, policy_hash_size
)),
3633 JSON_BUILD_PAIR("tpm2-pin", JSON_BUILD_BOOLEAN(flags
& TPM2_FLAGS_USE_PIN
)),
3634 JSON_BUILD_PAIR_CONDITION(pubkey_pcr_mask
!= 0, "tpm2_pubkey_pcrs", JSON_BUILD_VARIANT(pkmj
)),
3635 JSON_BUILD_PAIR_CONDITION(pubkey_pcr_mask
!= 0, "tpm2_pubkey", JSON_BUILD_BASE64(pubkey
, pubkey_size
)),
3636 JSON_BUILD_PAIR_CONDITION(salt
, "tpm2_salt", JSON_BUILD_BASE64(salt
, salt_size
)),
3637 JSON_BUILD_PAIR_CONDITION(srk_buf
, "tpm2_srk", JSON_BUILD_BASE64(srk_buf
, srk_buf_size
))));
3647 int tpm2_parse_luks2_json(
3650 uint32_t *ret_hash_pcr_mask
,
3651 uint16_t *ret_pcr_bank
,
3653 size_t *ret_pubkey_size
,
3654 uint32_t *ret_pubkey_pcr_mask
,
3655 uint16_t *ret_primary_alg
,
3657 size_t *ret_blob_size
,
3658 void **ret_policy_hash
,
3659 size_t *ret_policy_hash_size
,
3661 size_t *ret_salt_size
,
3663 size_t *ret_srk_buf_size
,
3664 TPM2Flags
*ret_flags
) {
3666 _cleanup_free_
void *blob
= NULL
, *policy_hash
= NULL
, *pubkey
= NULL
, *salt
= NULL
, *srk_buf
= NULL
;
3667 size_t blob_size
= 0, policy_hash_size
= 0, pubkey_size
= 0, salt_size
= 0, srk_buf_size
= 0;
3668 uint32_t hash_pcr_mask
= 0, pubkey_pcr_mask
= 0;
3669 uint16_t primary_alg
= TPM2_ALG_ECC
; /* ECC was the only supported algorithm in systemd < 250, use that as implied default, for compatibility */
3670 uint16_t pcr_bank
= UINT16_MAX
; /* default: pick automatically */
3671 int r
, keyslot
= -1;
3672 TPM2Flags flags
= 0;
3678 keyslot
= cryptsetup_get_keyslot_from_token(v
);
3680 /* Return a recognizable error when parsing this field, so that callers can handle parsing
3681 * errors of the keyslots field gracefully, since it's not 'owned' by us, but by the LUKS2
3683 log_debug_errno(keyslot
, "Failed to extract keyslot index from TPM2 JSON data token, skipping: %m");
3688 w
= json_variant_by_key(v
, "tpm2-pcrs");
3690 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 token data lacks 'tpm2-pcrs' field.");
3692 r
= tpm2_parse_pcr_json_array(w
, &hash_pcr_mask
);
3694 return log_debug_errno(r
, "Failed to parse TPM2 PCR mask: %m");
3696 /* The bank field is optional, since it was added in systemd 250 only. Before the bank was hardcoded
3698 w
= json_variant_by_key(v
, "tpm2-pcr-bank");
3700 /* The PCR bank field is optional */
3702 if (!json_variant_is_string(w
))
3703 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PCR bank is not a string.");
3705 r
= tpm2_hash_alg_from_string(json_variant_string(w
));
3707 return log_debug_errno(r
, "TPM2 PCR bank invalid or not supported: %s", json_variant_string(w
));
3712 /* The primary key algorithm field is optional, since it was also added in systemd 250 only. Before
3713 * the algorithm was hardcoded to ECC. */
3714 w
= json_variant_by_key(v
, "tpm2-primary-alg");
3716 /* The primary key algorithm is optional */
3718 if (!json_variant_is_string(w
))
3719 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 primary key algorithm is not a string.");
3721 r
= tpm2_asym_alg_from_string(json_variant_string(w
));
3723 return log_debug_errno(r
, "TPM2 asymmetric algorithm invalid or not supported: %s", json_variant_string(w
));
3728 w
= json_variant_by_key(v
, "tpm2-blob");
3730 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 token data lacks 'tpm2-blob' field.");
3732 r
= json_variant_unbase64(w
, &blob
, &blob_size
);
3734 return log_debug_errno(r
, "Invalid base64 data in 'tpm2-blob' field.");
3736 w
= json_variant_by_key(v
, "tpm2-policy-hash");
3738 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 token data lacks 'tpm2-policy-hash' field.");
3740 r
= json_variant_unhex(w
, &policy_hash
, &policy_hash_size
);
3742 return log_debug_errno(r
, "Invalid base64 data in 'tpm2-policy-hash' field.");
3744 w
= json_variant_by_key(v
, "tpm2-pin");
3746 if (!json_variant_is_boolean(w
))
3747 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "TPM2 PIN policy is not a boolean.");
3749 SET_FLAG(flags
, TPM2_FLAGS_USE_PIN
, json_variant_boolean(w
));
3752 w
= json_variant_by_key(v
, "tpm2_salt");
3754 r
= json_variant_unbase64(w
, &salt
, &salt_size
);
3756 return log_debug_errno(r
, "Invalid base64 data in 'tpm2_salt' field.");
3759 w
= json_variant_by_key(v
, "tpm2_pubkey_pcrs");
3761 r
= tpm2_parse_pcr_json_array(w
, &pubkey_pcr_mask
);
3766 w
= json_variant_by_key(v
, "tpm2_pubkey");
3768 r
= json_variant_unbase64(w
, &pubkey
, &pubkey_size
);
3770 return log_debug_errno(r
, "Failed to decode PCR public key.");
3771 } else if (pubkey_pcr_mask
!= 0)
3772 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "Public key PCR mask set, but not public key included in JSON data, refusing.");
3774 w
= json_variant_by_key(v
, "tpm2_srk");
3776 r
= json_variant_unbase64(w
, &srk_buf
, &srk_buf_size
);
3778 return log_debug_errno(r
, "Invalid base64 data in 'tpm2_srk' field.");
3782 *ret_keyslot
= keyslot
;
3783 if (ret_hash_pcr_mask
)
3784 *ret_hash_pcr_mask
= hash_pcr_mask
;
3786 *ret_pcr_bank
= pcr_bank
;
3788 *ret_pubkey
= TAKE_PTR(pubkey
);
3789 if (ret_pubkey_size
)
3790 *ret_pubkey_size
= pubkey_size
;
3791 if (ret_pubkey_pcr_mask
)
3792 *ret_pubkey_pcr_mask
= pubkey_pcr_mask
;
3793 if (ret_primary_alg
)
3794 *ret_primary_alg
= primary_alg
;
3796 *ret_blob
= TAKE_PTR(blob
);
3798 *ret_blob_size
= blob_size
;
3799 if (ret_policy_hash
)
3800 *ret_policy_hash
= TAKE_PTR(policy_hash
);
3801 if (ret_policy_hash_size
)
3802 *ret_policy_hash_size
= policy_hash_size
;
3804 *ret_salt
= TAKE_PTR(salt
);
3806 *ret_salt_size
= salt_size
;
3810 *ret_srk_buf
= TAKE_PTR(srk_buf
);
3811 if (ret_srk_buf_size
)
3812 *ret_srk_buf_size
= srk_buf_size
;
3817 const char *tpm2_hash_alg_to_string(uint16_t alg
) {
3818 if (alg
== TPM2_ALG_SHA1
)
3820 if (alg
== TPM2_ALG_SHA256
)
3822 if (alg
== TPM2_ALG_SHA384
)
3824 if (alg
== TPM2_ALG_SHA512
)
3829 int tpm2_hash_alg_from_string(const char *alg
) {
3830 if (strcaseeq_ptr(alg
, "sha1"))
3831 return TPM2_ALG_SHA1
;
3832 if (strcaseeq_ptr(alg
, "sha256"))
3833 return TPM2_ALG_SHA256
;
3834 if (strcaseeq_ptr(alg
, "sha384"))
3835 return TPM2_ALG_SHA384
;
3836 if (strcaseeq_ptr(alg
, "sha512"))
3837 return TPM2_ALG_SHA512
;
3841 const char *tpm2_asym_alg_to_string(uint16_t alg
) {
3842 if (alg
== TPM2_ALG_ECC
)
3844 if (alg
== TPM2_ALG_RSA
)
3849 int tpm2_asym_alg_from_string(const char *alg
) {
3850 if (strcaseeq_ptr(alg
, "ecc"))
3851 return TPM2_ALG_ECC
;
3852 if (strcaseeq_ptr(alg
, "rsa"))
3853 return TPM2_ALG_RSA
;
3857 Tpm2Support
tpm2_support(void) {
3858 Tpm2Support support
= TPM2_SUPPORT_NONE
;
3861 if (detect_container() <= 0) {
3862 /* Check if there's a /dev/tpmrm* device via sysfs. If we run in a container we likely just
3863 * got the host sysfs mounted. Since devices are generally not virtualized for containers,
3864 * let's assume containers never have a TPM, at least for now. */
3866 r
= dir_is_empty("/sys/class/tpmrm", /* ignore_hidden_or_backup= */ false);
3869 log_debug_errno(r
, "Unable to test whether /sys/class/tpmrm/ exists and is populated, assuming it is not: %m");
3870 } else if (r
== 0) /* populated! */
3871 support
|= TPM2_SUPPORT_SUBSYSTEM
|TPM2_SUPPORT_DRIVER
;
3873 /* If the directory exists but is empty, we know the subsystem is enabled but no
3874 * driver has been loaded yet. */
3875 support
|= TPM2_SUPPORT_SUBSYSTEM
;
3879 support
|= TPM2_SUPPORT_FIRMWARE
;
3882 support
|= TPM2_SUPPORT_SYSTEM
;
3888 int tpm2_parse_pcr_argument(const char *arg
, uint32_t *mask
) {
3894 /* For use in getopt_long() command line parsers: merges masks specified on the command line */
3901 r
= tpm2_pcr_mask_from_string(arg
, &m
);
3905 if (*mask
== UINT32_MAX
)
3913 int tpm2_load_pcr_signature(const char *path
, JsonVariant
**ret
) {
3914 _cleanup_strv_free_
char **search
= NULL
;
3915 _cleanup_free_
char *discovered_path
= NULL
;
3916 _cleanup_fclose_
FILE *f
= NULL
;
3919 /* Tries to load a JSON PCR signature file. Takes an absolute path, a simple file name or NULL. In
3920 * the latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
3922 search
= strv_split_nulstr(CONF_PATHS_NULSTR("systemd"));
3927 /* If no path is specified, then look for "tpm2-pcr-signature.json" automatically. Also, in
3928 * this case include /.extra/ in the search path, but only in this case, and if we run in the
3929 * initrd. We don't want to be too eager here, after all /.extra/ is untrusted territory. */
3931 path
= "tpm2-pcr-signature.json";
3934 if (strv_extend(&search
, "/.extra") < 0)
3938 r
= search_and_fopen(path
, "re", NULL
, (const char**) search
, &f
, &discovered_path
);
3940 return log_debug_errno(r
, "Failed to find TPM PCR signature file '%s': %m", path
);
3942 r
= json_parse_file(f
, discovered_path
, 0, ret
, NULL
, NULL
);
3944 return log_debug_errno(r
, "Failed to parse TPM PCR signature JSON object '%s': %m", discovered_path
);
3949 int tpm2_load_pcr_public_key(const char *path
, void **ret_pubkey
, size_t *ret_pubkey_size
) {
3950 _cleanup_free_
char *discovered_path
= NULL
;
3951 _cleanup_fclose_
FILE *f
= NULL
;
3954 /* Tries to load a PCR public key file. Takes an absolute path, a simple file name or NULL. In the
3955 * latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
3958 path
= "tpm2-pcr-public-key.pem";
3960 r
= search_and_fopen(path
, "re", NULL
, (const char**) CONF_PATHS_STRV("systemd"), &f
, &discovered_path
);
3962 return log_debug_errno(r
, "Failed to find TPM PCR public key file '%s': %m", path
);
3964 r
= read_full_stream(f
, (char**) ret_pubkey
, ret_pubkey_size
);
3966 return log_debug_errno(r
, "Failed to load TPM PCR public key PEM file '%s': %m", discovered_path
);
3971 #define PBKDF2_HMAC_SHA256_ITERATIONS 10000
3974 * Implements PBKDF2 HMAC SHA256 for a derived keylen of 32
3975 * bytes and for PBKDF2_HMAC_SHA256_ITERATIONS count.
3976 * I found the wikipedia entry relevant and it contains links to
3978 * - https://en.wikipedia.org/wiki/PBKDF2
3979 * - https://www.rfc-editor.org/rfc/rfc2898#section-5.2
3981 int tpm2_util_pbkdf2_hmac_sha256(const void *pass
,
3985 uint8_t ret_key
[static SHA256_DIGEST_SIZE
]) {
3987 uint8_t _cleanup_(erase_and_freep
) *buffer
= NULL
;
3988 uint8_t u
[SHA256_DIGEST_SIZE
];
3990 /* To keep this simple, since derived KeyLen (dkLen in docs)
3991 * Is the same as the hash output, we don't need multiple
3992 * blocks. Part of the algorithm is to add the block count
3993 * in, but this can be hardcoded to 1.
3995 static const uint8_t block_cnt
[] = { 0, 0, 0, 1 };
3998 assert (saltlen
> 0);
3999 assert (saltlen
<= (SIZE_MAX
- sizeof(block_cnt
)));
4000 assert (passlen
> 0);
4003 * Build a buffer of salt + block_cnt and hmac_sha256 it we
4004 * do this as we don't have a context builder for HMAC_SHA256.
4006 buffer
= malloc(saltlen
+ sizeof(block_cnt
));
4010 memcpy(buffer
, salt
, saltlen
);
4011 memcpy(&buffer
[saltlen
], block_cnt
, sizeof(block_cnt
));
4013 hmac_sha256(pass
, passlen
, buffer
, saltlen
+ sizeof(block_cnt
), u
);
4015 /* dk needs to be an unmodified u as u gets modified in the loop */
4016 memcpy(ret_key
, u
, SHA256_DIGEST_SIZE
);
4017 uint8_t *dk
= ret_key
;
4019 for (size_t i
= 1; i
< PBKDF2_HMAC_SHA256_ITERATIONS
; i
++) {
4020 hmac_sha256(pass
, passlen
, u
, sizeof(u
), u
);
4022 for (size_t j
=0; j
< sizeof(u
); j
++)
4029 static const char* const pcr_index_table
[_PCR_INDEX_MAX_DEFINED
] = {
4030 [PCR_PLATFORM_CODE
] = "platform-code",
4031 [PCR_PLATFORM_CONFIG
] = "platform-config",
4032 [PCR_EXTERNAL_CODE
] = "external-code",
4033 [PCR_EXTERNAL_CONFIG
] = "external-config",
4034 [PCR_BOOT_LOADER_CODE
] = "boot-loader-code",
4035 [PCR_BOOT_LOADER_CONFIG
] = "boot-loader-config",
4036 [PCR_SECURE_BOOT_POLICY
] = "secure-boot-policy",
4037 [PCR_KERNEL_INITRD
] = "kernel-initrd",
4039 [PCR_KERNEL_BOOT
] = "kernel-boot",
4040 [PCR_KERNEL_CONFIG
] = "kernel-config",
4041 [PCR_SYSEXTS
] = "sysexts",
4042 [PCR_SHIM_POLICY
] = "shim-policy",
4043 [PCR_SYSTEM_IDENTITY
] = "system-identity",
4044 [PCR_DEBUG
] = "debug",
4045 [PCR_APPLICATION_SUPPORT
] = "application-support",
4048 DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_FALLBACK(pcr_index
, int, TPM2_PCRS_MAX
- 1);
4049 DEFINE_STRING_TABLE_LOOKUP_TO_STRING(pcr_index
, int);