]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/tpm2-util.c
tpm2: cache TPM's supported ECC curves
[thirdparty/systemd.git] / src / shared / tpm2-util.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <sys/file.h>
4
5 #include "alloc-util.h"
6 #include "constants.h"
7 #include "cryptsetup-util.h"
8 #include "dirent-util.h"
9 #include "dlfcn-util.h"
10 #include "efi-api.h"
11 #include "extract-word.h"
12 #include "fd-util.h"
13 #include "fileio.h"
14 #include "format-table.h"
15 #include "fs-util.h"
16 #include "hexdecoct.h"
17 #include "hmac.h"
18 #include "initrd-util.h"
19 #include "io-util.h"
20 #include "lock-util.h"
21 #include "log.h"
22 #include "logarithm.h"
23 #include "memory-util.h"
24 #include "mkdir.h"
25 #include "nulstr-util.h"
26 #include "parse-util.h"
27 #include "random-util.h"
28 #include "sha256.h"
29 #include "sort-util.h"
30 #include "stat-util.h"
31 #include "string-table.h"
32 #include "sync-util.h"
33 #include "time-util.h"
34 #include "tpm2-util.h"
35 #include "virt.h"
36
37 #if HAVE_TPM2
38 static void *libtss2_esys_dl = NULL;
39 static void *libtss2_rc_dl = NULL;
40 static void *libtss2_mu_dl = NULL;
41
42 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;
43 static TSS2_RC (*sym_Esys_CreateLoaded)(ESYS_CONTEXT *esysContext, ESYS_TR parentHandle, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPM2B_SENSITIVE_CREATE *inSensitive, const TPM2B_TEMPLATE *inPublic, ESYS_TR *objectHandle, TPM2B_PRIVATE **outPrivate, TPM2B_PUBLIC **outPublic) = NULL;
44 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;
45 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;
46 static void (*sym_Esys_Finalize)(ESYS_CONTEXT **context) = NULL;
47 static TSS2_RC (*sym_Esys_FlushContext)(ESYS_CONTEXT *esysContext, ESYS_TR flushHandle) = NULL;
48 static void (*sym_Esys_Free)(void *ptr) = NULL;
49 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;
50 static TSS2_RC (*sym_Esys_GetRandom)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, UINT16 bytesRequested, TPM2B_DIGEST **randomBytes) = NULL;
51 static TSS2_RC (*sym_Esys_Initialize)(ESYS_CONTEXT **esys_context, TSS2_TCTI_CONTEXT *tcti, TSS2_ABI_VERSION *abiVersion) = NULL;
52 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;
53 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;
54 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;
55 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;
56 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;
57 static TSS2_RC (*sym_Esys_PolicyAuthValue)(ESYS_CONTEXT *esysContext, ESYS_TR policySession, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3) = NULL;
58 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;
59 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;
60 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;
61 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;
62 static TSS2_RC (*sym_Esys_Startup)(ESYS_CONTEXT *esysContext, TPM2_SU startupType) = NULL;
63 static TSS2_RC (*sym_Esys_TestParms)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPMT_PUBLIC_PARMS *parameters) = NULL;
64 static TSS2_RC (*sym_Esys_TR_Close)(ESYS_CONTEXT *esys_context, ESYS_TR *rsrc_handle) = NULL;
65 static TSS2_RC (*sym_Esys_TR_Deserialize)(ESYS_CONTEXT *esys_context, uint8_t const *buffer, size_t buffer_size, ESYS_TR *esys_handle) = NULL;
66 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;
67 static TSS2_RC (*sym_Esys_TR_GetName)(ESYS_CONTEXT *esysContext, ESYS_TR handle, TPM2B_NAME **name) = NULL;
68 static TSS2_RC (*sym_Esys_TR_GetTpmHandle)(ESYS_CONTEXT *esys_context, ESYS_TR esys_handle, TPM2_HANDLE *tpm_handle) = NULL;
69 static TSS2_RC (*sym_Esys_TR_Serialize)(ESYS_CONTEXT *esys_context, ESYS_TR object, uint8_t **buffer, size_t *buffer_size) = NULL;
70 static TSS2_RC (*sym_Esys_TR_SetAuth)(ESYS_CONTEXT *esysContext, ESYS_TR handle, TPM2B_AUTH const *authValue) = NULL;
71 static TSS2_RC (*sym_Esys_TRSess_GetAttributes)(ESYS_CONTEXT *esysContext, ESYS_TR session, TPMA_SESSION *flags) = NULL;
72 static TSS2_RC (*sym_Esys_TRSess_SetAttributes)(ESYS_CONTEXT *esysContext, ESYS_TR session, TPMA_SESSION flags, TPMA_SESSION mask) = NULL;
73 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;
74 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;
75
76 static TSS2_RC (*sym_Tss2_MU_TPM2_CC_Marshal)(TPM2_CC src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL;
77 static TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Marshal)(TPM2B_PRIVATE const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL;
78 static TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PRIVATE *dest) = NULL;
79 static TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Marshal)(TPM2B_PUBLIC const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL;
80 static TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PUBLIC *dest) = NULL;
81 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;
82 static TSS2_RC (*sym_Tss2_MU_TPMT_HA_Marshal)(TPMT_HA const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL;
83 static TSS2_RC (*sym_Tss2_MU_TPMT_PUBLIC_Marshal)(TPMT_PUBLIC const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL;
84
85 static const char* (*sym_Tss2_RC_Decode)(TSS2_RC rc) = NULL;
86
87 int dlopen_tpm2(void) {
88 int r;
89
90 r = dlopen_many_sym_or_warn(
91 &libtss2_esys_dl, "libtss2-esys.so.0", LOG_DEBUG,
92 DLSYM_ARG(Esys_Create),
93 DLSYM_ARG(Esys_CreateLoaded),
94 DLSYM_ARG(Esys_CreatePrimary),
95 DLSYM_ARG(Esys_EvictControl),
96 DLSYM_ARG(Esys_Finalize),
97 DLSYM_ARG(Esys_FlushContext),
98 DLSYM_ARG(Esys_Free),
99 DLSYM_ARG(Esys_GetCapability),
100 DLSYM_ARG(Esys_GetRandom),
101 DLSYM_ARG(Esys_Initialize),
102 DLSYM_ARG(Esys_Load),
103 DLSYM_ARG(Esys_LoadExternal),
104 DLSYM_ARG(Esys_PCR_Extend),
105 DLSYM_ARG(Esys_PCR_Read),
106 DLSYM_ARG(Esys_PolicyAuthorize),
107 DLSYM_ARG(Esys_PolicyAuthValue),
108 DLSYM_ARG(Esys_PolicyGetDigest),
109 DLSYM_ARG(Esys_PolicyPCR),
110 DLSYM_ARG(Esys_ReadPublic),
111 DLSYM_ARG(Esys_StartAuthSession),
112 DLSYM_ARG(Esys_Startup),
113 DLSYM_ARG(Esys_TestParms),
114 DLSYM_ARG(Esys_TR_Close),
115 DLSYM_ARG(Esys_TR_Deserialize),
116 DLSYM_ARG(Esys_TR_FromTPMPublic),
117 DLSYM_ARG(Esys_TR_GetName),
118 DLSYM_ARG(Esys_TR_Serialize),
119 DLSYM_ARG(Esys_TR_SetAuth),
120 DLSYM_ARG(Esys_TRSess_GetAttributes),
121 DLSYM_ARG(Esys_TRSess_SetAttributes),
122 DLSYM_ARG(Esys_Unseal),
123 DLSYM_ARG(Esys_VerifySignature));
124 if (r < 0)
125 return r;
126
127 /* Esys_TR_GetTpmHandle was added to tpm2-tss in version 2.4.0. Once we can set a minimum tpm2-tss
128 * version of 2.4.0 this sym can be moved up to the normal list above. */
129 r = dlsym_many_or_warn(libtss2_esys_dl, LOG_DEBUG, DLSYM_ARG_FORCE(Esys_TR_GetTpmHandle));
130 if (r < 0)
131 log_debug("libtss2-esys too old, does not include Esys_TR_GetTpmHandle.");
132
133 r = dlopen_many_sym_or_warn(
134 &libtss2_rc_dl, "libtss2-rc.so.0", LOG_DEBUG,
135 DLSYM_ARG(Tss2_RC_Decode));
136 if (r < 0)
137 return r;
138
139 return dlopen_many_sym_or_warn(
140 &libtss2_mu_dl, "libtss2-mu.so.0", LOG_DEBUG,
141 DLSYM_ARG(Tss2_MU_TPM2_CC_Marshal),
142 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Marshal),
143 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Unmarshal),
144 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Marshal),
145 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Unmarshal),
146 DLSYM_ARG(Tss2_MU_TPML_PCR_SELECTION_Marshal),
147 DLSYM_ARG(Tss2_MU_TPMT_HA_Marshal),
148 DLSYM_ARG(Tss2_MU_TPMT_PUBLIC_Marshal));
149 }
150
151 void Esys_Freep(void *p) {
152 if (*(void**) p)
153 sym_Esys_Free(*(void**) p);
154 }
155
156 /* Get a specific TPM capability (or capabilities).
157 *
158 * Returns 0 if there are no more capability properties of the requested type, or 1 if there are more, or < 0
159 * on any error. Both 0 and 1 indicate this completed successfully, but do not indicate how many capability
160 * properties were provided in 'ret_capability_data'. To find the number of provided properties, check the
161 * specific type's 'count' field (e.g. for TPM2_CAP_ALGS, check ret_capability_data->algorithms.count).
162 *
163 * This calls TPM2_GetCapability() and does not alter the provided data, so it is important to understand how
164 * that TPM function works. It is recommended to check the TCG TPM specification Part 3 ("Commands") section
165 * on TPM2_GetCapability() for full details, but a short summary is: if this returns 0, all available
166 * properties have been provided in ret_capability_data, or no properties were available. If this returns 1,
167 * there are between 1 and "count" properties provided in ret_capability_data, and there are more available.
168 * Note that this may provide less than "count" properties even if the TPM has more available. Also, each
169 * capability category may have more specific requirements than described here; see the spec for exact
170 * details. */
171 static int tpm2_get_capability(
172 Tpm2Context *c,
173 TPM2_CAP capability,
174 uint32_t property,
175 uint32_t count,
176 TPMU_CAPABILITIES *ret_capability_data) {
177
178 _cleanup_(Esys_Freep) TPMS_CAPABILITY_DATA *capabilities = NULL;
179 TPMI_YES_NO more;
180 TSS2_RC rc;
181
182 assert(c);
183
184 log_debug("Getting TPM2 capability 0x%04" PRIx32 " property 0x%04" PRIx32 " count %" PRIu32 ".",
185 capability, property, count);
186
187 rc = sym_Esys_GetCapability(
188 c->esys_context,
189 ESYS_TR_NONE,
190 ESYS_TR_NONE,
191 ESYS_TR_NONE,
192 capability,
193 property,
194 count,
195 &more,
196 &capabilities);
197 if (rc != TSS2_RC_SUCCESS)
198 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
199 "Failed to get TPM2 capability 0x%04" PRIx32 " property 0x%04" PRIx32 ": %s",
200 capability, property, sym_Tss2_RC_Decode(rc));
201
202 if (capabilities->capability != capability)
203 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
204 "TPM provided wrong capability: 0x%04" PRIx32 " instead of 0x%04" PRIx32 ".",
205 capabilities->capability, capability);
206
207 if (ret_capability_data)
208 *ret_capability_data = capabilities->data;
209
210 return more == TPM2_YES;
211 }
212
213 #define TPMA_CC_TO_TPM2_CC(cca) (((cca) & TPMA_CC_COMMANDINDEX_MASK) >> TPMA_CC_COMMANDINDEX_SHIFT)
214
215 static int tpm2_cache_capabilities(Tpm2Context *c) {
216 TPMU_CAPABILITIES capability;
217 int r;
218
219 assert(c);
220
221 /* Cache the algorithms. The spec indicates supported algorithms can only be modified during runtime
222 * by the SetAlgorithmSet() command. Unfortunately, the spec doesn't require a TPM reinitialization
223 * after changing the algorithm set (unless the PCR algorithms are changed). However, the spec also
224 * indicates the TPM behavior after SetAlgorithmSet() is "vendor-dependent", giving the example of
225 * flushing sessions and objects, erasing policies, etc. So, if the algorithm set is programmatically
226 * changed while we are performing some operation, it's reasonable to assume it will break us even if
227 * we don't cache the algorithms, thus they should be "safe" to cache. */
228 TPM2_ALG_ID current_alg = TPM2_ALG_FIRST;
229 for (;;) {
230 r = tpm2_get_capability(
231 c,
232 TPM2_CAP_ALGS,
233 (uint32_t) current_alg, /* The spec states to cast TPM2_ALG_ID to uint32_t. */
234 TPM2_MAX_CAP_ALGS,
235 &capability);
236 if (r < 0)
237 return r;
238
239 TPML_ALG_PROPERTY algorithms = capability.algorithms;
240
241 /* We should never get 0; the TPM must support some algorithms, and it must not set 'more' if
242 * there are no more. */
243 assert(algorithms.count > 0);
244
245 if (!GREEDY_REALLOC_APPEND(
246 c->capability_algorithms,
247 c->n_capability_algorithms,
248 algorithms.algProperties,
249 algorithms.count))
250 return log_oom_debug();
251
252 if (r == 0)
253 break;
254
255 /* Set current_alg to alg id after last alg id the TPM provided */
256 current_alg = algorithms.algProperties[algorithms.count - 1].alg + 1;
257 }
258
259 /* Cache the command capabilities. The spec isn't actually clear if commands can be added/removed
260 * while running, but that would be crazy, so let's hope it is not possible. */
261 TPM2_CC current_cc = TPM2_CC_FIRST;
262 for (;;) {
263 r = tpm2_get_capability(
264 c,
265 TPM2_CAP_COMMANDS,
266 current_cc,
267 TPM2_MAX_CAP_CC,
268 &capability);
269 if (r < 0)
270 return r;
271
272 TPML_CCA commands = capability.command;
273
274 /* We should never get 0; the TPM must support some commands, and it must not set 'more' if
275 * there are no more. */
276 assert(commands.count > 0);
277
278 if (!GREEDY_REALLOC_APPEND(
279 c->capability_commands,
280 c->n_capability_commands,
281 commands.commandAttributes,
282 commands.count))
283 return log_oom_debug();
284
285 if (r == 0)
286 break;
287
288 /* Set current_cc to index after last cc the TPM provided */
289 current_cc = TPMA_CC_TO_TPM2_CC(commands.commandAttributes[commands.count - 1]) + 1;
290 }
291
292 /* Cache the ECC curves. The spec isn't actually clear if ECC curves can be added/removed
293 * while running, but that would be crazy, so let's hope it is not possible. */
294 TPM2_ECC_CURVE current_ecc_curve = TPM2_ECC_NONE;
295 for (;;) {
296 r = tpm2_get_capability(
297 c,
298 TPM2_CAP_ECC_CURVES,
299 current_ecc_curve,
300 TPM2_MAX_ECC_CURVES,
301 &capability);
302 if (r < 0)
303 return r;
304
305 TPML_ECC_CURVE ecc_curves = capability.eccCurves;
306
307 /* ECC support isn't required */
308 if (ecc_curves.count == 0)
309 break;
310
311 if (!GREEDY_REALLOC_APPEND(
312 c->capability_ecc_curves,
313 c->n_capability_ecc_curves,
314 ecc_curves.eccCurves,
315 ecc_curves.count))
316 return log_oom_debug();
317
318 if (r == 0)
319 break;
320
321 /* Set current_ecc_curve to index after last ecc curve the TPM provided */
322 current_ecc_curve = ecc_curves.eccCurves[ecc_curves.count - 1] + 1;
323 }
324
325 /* Cache the PCR capabilities, which are safe to cache, as the only way they can change is
326 * TPM2_PCR_Allocate(), which changes the allocation after the next _TPM_Init(). If the TPM is
327 * reinitialized while we are using it, all our context and sessions will be invalid, so we can
328 * safely assume the TPM PCR allocation will not change while we are using it. */
329 r = tpm2_get_capability(
330 c,
331 TPM2_CAP_PCRS,
332 /* property= */ 0,
333 /* count= */ 1,
334 &capability);
335 if (r < 0)
336 return r;
337 if (r == 1)
338 /* This should never happen. Part 3 ("Commands") of the TCG TPM2 spec in the section for
339 * TPM2_GetCapability states: "TPM_CAP_PCRS – Returns the current allocation of PCR in a
340 * TPML_PCR_SELECTION. The property parameter shall be zero. The TPM will always respond to
341 * this command with the full PCR allocation and moreData will be NO." */
342 log_debug("TPM bug: reported multiple PCR sets; using only first set.");
343 c->capability_pcrs = capability.assignedPCR;
344
345 return 0;
346 }
347
348 /* Get the TPMA_ALGORITHM for a TPM2_ALG_ID. Returns true if the TPM supports the algorithm and the
349 * TPMA_ALGORITHM is provided, otherwise false. */
350 static bool tpm2_get_capability_alg(Tpm2Context *c, TPM2_ALG_ID alg, TPMA_ALGORITHM *ret) {
351 assert(c);
352
353 FOREACH_ARRAY(alg_prop, c->capability_algorithms, c->n_capability_algorithms)
354 if (alg_prop->alg == alg) {
355 if (ret)
356 *ret = alg_prop->algProperties;
357 return true;
358 }
359
360 log_debug("TPM does not support alg 0x%02" PRIx16 ".", alg);
361 if (ret)
362 *ret = 0;
363
364 return false;
365 }
366
367 bool tpm2_supports_alg(Tpm2Context *c, TPM2_ALG_ID alg) {
368 return tpm2_get_capability_alg(c, alg, NULL);
369 }
370
371 /* Get the TPMA_CC for a TPM2_CC. Returns true if the TPM supports the command and the TPMA_CC is provided,
372 * otherwise false. */
373 static bool tpm2_get_capability_command(Tpm2Context *c, TPM2_CC command, TPMA_CC *ret) {
374 assert(c);
375
376 FOREACH_ARRAY(cca, c->capability_commands, c->n_capability_commands)
377 if (TPMA_CC_TO_TPM2_CC(*cca) == command) {
378 if (ret)
379 *ret = *cca;
380 return true;
381 }
382
383 log_debug("TPM does not support command 0x%04" PRIx32 ".", command);
384 if (ret)
385 *ret = 0;
386
387 return false;
388 }
389
390 bool tpm2_supports_command(Tpm2Context *c, TPM2_CC command) {
391 return tpm2_get_capability_command(c, command, NULL);
392 }
393
394 /* Returns true if the TPM supports the ECC curve, otherwise false. */
395 bool tpm2_supports_ecc_curve(Tpm2Context *c, TPM2_ECC_CURVE ecc_curve) {
396 assert(c);
397
398 FOREACH_ARRAY(curve, c->capability_ecc_curves, c->n_capability_ecc_curves)
399 if (*curve == ecc_curve)
400 return true;
401
402 log_debug("TPM does not support ECC curve 0x%" PRIx16 ".", ecc_curve);
403 return false;
404 }
405
406 /* Query the TPM for populated handles.
407 *
408 * This provides an array of handle indexes populated in the TPM, starting at the requested handle. The array will
409 * contain only populated handle addresses (which might not include the requested handle). The number of
410 * handles will be no more than the 'max' number requested. This will not search past the end of the handle
411 * range (i.e. handle & 0xff000000).
412 *
413 * Returns 0 if all populated handles in the range (starting at the requested handle) were provided (or no
414 * handles were in the range), or 1 if there are more populated handles in the range, or < 0 on any error. */
415 static int tpm2_get_capability_handles(
416 Tpm2Context *c,
417 TPM2_HANDLE start,
418 size_t max,
419 TPM2_HANDLE **ret_handles,
420 size_t *ret_n_handles) {
421
422 _cleanup_free_ TPM2_HANDLE *handles = NULL;
423 size_t n_handles = 0;
424 TPM2_HANDLE current = start;
425 int r = 0;
426
427 assert(c);
428 assert(ret_handles);
429 assert(ret_n_handles);
430
431 max = MIN(max, UINT32_MAX);
432
433 while (max > 0) {
434 TPMU_CAPABILITIES capability;
435 r = tpm2_get_capability(c, TPM2_CAP_HANDLES, current, (uint32_t) max, &capability);
436 if (r < 0)
437 return r;
438
439 TPML_HANDLE handle_list = capability.handles;
440 if (handle_list.count == 0)
441 break;
442
443 assert(handle_list.count <= max);
444
445 if (n_handles > SIZE_MAX - handle_list.count)
446 return log_oom_debug();
447
448 if (!GREEDY_REALLOC_APPEND(handles, n_handles, handle_list.handle, handle_list.count))
449 return log_oom_debug();
450
451 max -= handle_list.count;
452
453 /* Update current to the handle index after the last handle in the list. */
454 current = handles[n_handles - 1] + 1;
455
456 if (r == 0)
457 /* No more handles in this range. */
458 break;
459 }
460
461 *ret_handles = TAKE_PTR(handles);
462 *ret_n_handles = n_handles;
463
464 return r;
465 }
466
467 #define TPM2_HANDLE_RANGE(h) ((TPM2_HANDLE)((h) & TPM2_HR_RANGE_MASK))
468 #define TPM2_HANDLE_TYPE(h) ((TPM2_HT)(TPM2_HANDLE_RANGE(h) >> TPM2_HR_SHIFT))
469
470 /* Returns 1 if the handle is populated in the TPM, 0 if not, and < 0 on any error. */
471 static int tpm2_get_capability_handle(Tpm2Context *c, TPM2_HANDLE handle) {
472 _cleanup_free_ TPM2_HANDLE *handles = NULL;
473 size_t n_handles = 0;
474 int r;
475
476 r = tpm2_get_capability_handles(c, handle, 1, &handles, &n_handles);
477 if (r < 0)
478 return r;
479
480 return n_handles == 0 ? false : handles[0] == handle;
481 }
482
483 /* Returns 1 if the TPM supports the parms, or 0 if the TPM does not support the parms. */
484 bool tpm2_test_parms(Tpm2Context *c, TPMI_ALG_PUBLIC alg, const TPMU_PUBLIC_PARMS *parms) {
485 TSS2_RC rc;
486
487 assert(c);
488 assert(parms);
489
490 TPMT_PUBLIC_PARMS parameters = {
491 .type = alg,
492 .parameters = *parms,
493 };
494
495 rc = sym_Esys_TestParms(c->esys_context, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, &parameters);
496 if (rc != TSS2_RC_SUCCESS)
497 /* The spec says if the parms are not supported the TPM returns "...the appropriate
498 * unmarshaling error if a parameter is not valid". Since the spec (currently) defines 15
499 * unmarshaling errors, instead of checking for them all here, let's just assume any error
500 * indicates unsupported parms, and log the specific error text. */
501 log_debug("TPM does not support tested parms: %s", sym_Tss2_RC_Decode(rc));
502
503 return rc == TSS2_RC_SUCCESS;
504 }
505
506 static bool tpm2_supports_tpmt_public(Tpm2Context *c, const TPMT_PUBLIC *public) {
507 assert(c);
508 assert(public);
509
510 return tpm2_test_parms(c, public->type, &public->parameters);
511 }
512
513 static bool tpm2_supports_tpmt_sym_def_object(Tpm2Context *c, const TPMT_SYM_DEF_OBJECT *parameters) {
514 assert(c);
515 assert(parameters);
516
517 TPMU_PUBLIC_PARMS parms = {
518 .symDetail.sym = *parameters,
519 };
520
521 return tpm2_test_parms(c, TPM2_ALG_SYMCIPHER, &parms);
522 }
523
524 static bool tpm2_supports_tpmt_sym_def(Tpm2Context *c, const TPMT_SYM_DEF *parameters) {
525 assert(c);
526 assert(parameters);
527
528 /* Unfortunately, TPMT_SYM_DEF and TPMT_SYM_DEF_OBEJECT are separately defined, even though they are
529 * functionally identical. */
530 TPMT_SYM_DEF_OBJECT object = {
531 .algorithm = parameters->algorithm,
532 .keyBits = parameters->keyBits,
533 .mode = parameters->mode,
534 };
535
536 return tpm2_supports_tpmt_sym_def_object(c, &object);
537 }
538
539 static Tpm2Context *tpm2_context_free(Tpm2Context *c) {
540 if (!c)
541 return NULL;
542
543 if (c->esys_context)
544 sym_Esys_Finalize(&c->esys_context);
545
546 c->tcti_context = mfree(c->tcti_context);
547 c->tcti_dl = safe_dlclose(c->tcti_dl);
548
549 c->capability_algorithms = mfree(c->capability_algorithms);
550 c->capability_commands = mfree(c->capability_commands);
551 c->capability_ecc_curves = mfree(c->capability_ecc_curves);
552
553 return mfree(c);
554 }
555
556 DEFINE_TRIVIAL_REF_UNREF_FUNC(Tpm2Context, tpm2_context, tpm2_context_free);
557
558 static const TPMT_SYM_DEF SESSION_TEMPLATE_SYM_AES_128_CFB = {
559 .algorithm = TPM2_ALG_AES,
560 .keyBits.aes = 128,
561 .mode.aes = TPM2_ALG_CFB, /* The spec requires sessions to use CFB. */
562 };
563
564 int tpm2_context_new(const char *device, Tpm2Context **ret_context) {
565 _cleanup_(tpm2_context_unrefp) Tpm2Context *context = NULL;
566 TSS2_RC rc;
567 int r;
568
569 assert(ret_context);
570
571 context = new(Tpm2Context, 1);
572 if (!context)
573 return log_oom_debug();
574
575 *context = (Tpm2Context) {
576 .n_ref = 1,
577 };
578
579 r = dlopen_tpm2();
580 if (r < 0)
581 return log_debug_errno(r, "TPM2 support not installed: %m");
582
583 if (!device) {
584 device = secure_getenv("SYSTEMD_TPM2_DEVICE");
585 if (device)
586 /* Setting the env var to an empty string forces tpm2-tss' own device picking
587 * logic to be used. */
588 device = empty_to_null(device);
589 else
590 /* If nothing was specified explicitly, we'll use a hardcoded default: the "device" tcti
591 * driver and the "/dev/tpmrm0" device. We do this since on some distributions the tpm2-abrmd
592 * might be used and we really don't want that, since it is a system service and that creates
593 * various ordering issues/deadlocks during early boot. */
594 device = "device:/dev/tpmrm0";
595 }
596
597 if (device) {
598 const char *param, *driver, *fn;
599 const TSS2_TCTI_INFO* info;
600 TSS2_TCTI_INFO_FUNC func;
601 size_t sz = 0;
602
603 param = strchr(device, ':');
604 if (param) {
605 /* Syntax #1: Pair of driver string and arbitrary parameter */
606 driver = strndupa_safe(device, param - device);
607 if (isempty(driver))
608 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name is empty, refusing.");
609
610 param++;
611 } else if (path_is_absolute(device) && path_is_valid(device)) {
612 /* Syntax #2: TPM device node */
613 driver = "device";
614 param = device;
615 } else
616 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid TPM2 driver string, refusing.");
617
618 log_debug("Using TPM2 TCTI driver '%s' with device '%s'.", driver, param);
619
620 fn = strjoina("libtss2-tcti-", driver, ".so.0");
621
622 /* Better safe than sorry, let's refuse strings that cannot possibly be valid driver early, before going to disk. */
623 if (!filename_is_valid(fn))
624 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name '%s' not valid, refusing.", driver);
625
626 context->tcti_dl = dlopen(fn, RTLD_NOW);
627 if (!context->tcti_dl)
628 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to load %s: %s", fn, dlerror());
629
630 func = dlsym(context->tcti_dl, TSS2_TCTI_INFO_SYMBOL);
631 if (!func)
632 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
633 "Failed to find TCTI info symbol " TSS2_TCTI_INFO_SYMBOL ": %s",
634 dlerror());
635
636 info = func();
637 if (!info)
638 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to get TCTI info data.");
639
640 log_debug("Loaded TCTI module '%s' (%s) [Version %" PRIu32 "]", info->name, info->description, info->version);
641
642 rc = info->init(NULL, &sz, NULL);
643 if (rc != TPM2_RC_SUCCESS)
644 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
645 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));
646
647 context->tcti_context = malloc0(sz);
648 if (!context->tcti_context)
649 return log_oom_debug();
650
651 rc = info->init(context->tcti_context, &sz, param);
652 if (rc != TPM2_RC_SUCCESS)
653 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
654 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));
655 }
656
657 rc = sym_Esys_Initialize(&context->esys_context, context->tcti_context, NULL);
658 if (rc != TSS2_RC_SUCCESS)
659 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
660 "Failed to initialize TPM context: %s", sym_Tss2_RC_Decode(rc));
661
662 rc = sym_Esys_Startup(context->esys_context, TPM2_SU_CLEAR);
663 if (rc == TPM2_RC_INITIALIZE)
664 log_debug("TPM already started up.");
665 else if (rc == TSS2_RC_SUCCESS)
666 log_debug("TPM successfully started up.");
667 else
668 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
669 "Failed to start up TPM: %s", sym_Tss2_RC_Decode(rc));
670
671 r = tpm2_cache_capabilities(context);
672 if (r < 0)
673 return log_debug_errno(r, "Failed to cache TPM capbilities: %m");
674
675 /* We require AES and CFB support for session encryption. */
676 if (!tpm2_supports_alg(context, TPM2_ALG_AES))
677 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM does not support AES.");
678
679 if (!tpm2_supports_alg(context, TPM2_ALG_CFB))
680 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM does not support CFB.");
681
682 if (!tpm2_supports_tpmt_sym_def(context, &SESSION_TEMPLATE_SYM_AES_128_CFB))
683 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM does not support AES-128-CFB.");
684
685 *ret_context = TAKE_PTR(context);
686
687 return 0;
688 }
689
690 static void tpm2_handle_cleanup(ESYS_CONTEXT *esys_context, ESYS_TR esys_handle, bool flush) {
691 TSS2_RC rc;
692
693 if (!esys_context || esys_handle == ESYS_TR_NONE)
694 return;
695
696 /* Closing the handle removes its reference from the esys_context, but leaves the corresponding
697 * handle in the actual TPM. Flushing the handle removes its reference from the esys_context as well
698 * as removing its corresponding handle from the actual TPM. */
699 if (flush)
700 rc = sym_Esys_FlushContext(esys_context, esys_handle);
701 else
702 rc = sym_Esys_TR_Close(esys_context, &esys_handle);
703 if (rc != TSS2_RC_SUCCESS) /* We ignore failures here (besides debug logging), since this is called
704 * in error paths, where we cannot do anything about failures anymore. And
705 * when it is called in successful codepaths by this time we already did
706 * what we wanted to do, and got the results we wanted so there's no
707 * reason to make this fail more loudly than necessary. */
708 log_debug("Failed to %s TPM handle, ignoring: %s", flush ? "flush" : "close", sym_Tss2_RC_Decode(rc));
709 }
710
711 Tpm2Handle *tpm2_handle_free(Tpm2Handle *handle) {
712 if (!handle)
713 return NULL;
714
715 _cleanup_(tpm2_context_unrefp) Tpm2Context *context = (Tpm2Context*)handle->tpm2_context;
716 if (context)
717 tpm2_handle_cleanup(context->esys_context, handle->esys_handle, handle->flush);
718
719 return mfree(handle);
720 }
721
722 int tpm2_handle_new(Tpm2Context *context, Tpm2Handle **ret_handle) {
723 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
724
725 assert(ret_handle);
726
727 handle = new(Tpm2Handle, 1);
728 if (!handle)
729 return log_oom_debug();
730
731 *handle = (Tpm2Handle) {
732 .tpm2_context = tpm2_context_ref(context),
733 .esys_handle = ESYS_TR_NONE,
734 .flush = true,
735 };
736
737 *ret_handle = TAKE_PTR(handle);
738
739 return 0;
740 }
741
742 /* Create a Tpm2Handle object that references a pre-existing handle in the TPM, at the handle index provided.
743 * This should be used only for persistent, transient, or NV handles; and the handle must already exist in
744 * the TPM at the specified handle index. The handle index should not be 0. Returns 1 if found, 0 if the
745 * index is empty, or < 0 on error. Also see tpm2_get_srk() below; the SRK is a commonly used persistent
746 * Tpm2Handle. */
747 int tpm2_index_to_handle(
748 Tpm2Context *c,
749 TPM2_HANDLE index,
750 const Tpm2Handle *session,
751 TPM2B_PUBLIC **ret_public,
752 TPM2B_NAME **ret_name,
753 TPM2B_NAME **ret_qname,
754 Tpm2Handle **ret_handle) {
755
756 TSS2_RC rc;
757 int r;
758
759 assert(c);
760
761 /* Let's restrict this, at least for now, to allow only some handle types. */
762 switch (TPM2_HANDLE_TYPE(index)) {
763 case TPM2_HT_PERSISTENT:
764 case TPM2_HT_NV_INDEX:
765 case TPM2_HT_TRANSIENT:
766 break;
767 case TPM2_HT_PCR:
768 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
769 "Invalid handle 0x%08" PRIx32 " (in PCR range).", index);
770 case TPM2_HT_HMAC_SESSION:
771 case TPM2_HT_POLICY_SESSION:
772 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
773 "Invalid handle 0x%08" PRIx32 " (in session range).", index);
774 case TPM2_HT_PERMANENT: /* Permanent handles are defined, e.g. ESYS_TR_RH_OWNER. */
775 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
776 "Invalid handle 0x%08" PRIx32 " (in permanent range).", index);
777 default:
778 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
779 "Invalid handle 0x%08" PRIx32 " (in unknown range).", index);
780 }
781
782 r = tpm2_get_capability_handle(c, index);
783 if (r < 0)
784 return r;
785 if (r == 0) {
786 log_debug("TPM handle 0x%08" PRIx32 " not populated.", index);
787 if (ret_public)
788 *ret_public = NULL;
789 if (ret_name)
790 *ret_name = NULL;
791 if (ret_qname)
792 *ret_qname = NULL;
793 if (ret_handle)
794 *ret_handle = NULL;
795 return 0;
796 }
797
798 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
799 r = tpm2_handle_new(c, &handle);
800 if (r < 0)
801 return r;
802
803 /* Since we didn't create this handle in the TPM (this is only creating an ESYS_TR handle for the
804 * pre-existing TPM handle), we shouldn't flush (or evict) it on cleanup. */
805 handle->flush = false;
806
807 rc = sym_Esys_TR_FromTPMPublic(
808 c->esys_context,
809 index,
810 session ? session->esys_handle : ESYS_TR_NONE,
811 ESYS_TR_NONE,
812 ESYS_TR_NONE,
813 &handle->esys_handle);
814 if (rc != TSS2_RC_SUCCESS)
815 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
816 "Failed to read public info: %s", sym_Tss2_RC_Decode(rc));
817
818 if (ret_public || ret_name || ret_qname) {
819 r = tpm2_read_public(c, session, handle, ret_public, ret_name, ret_qname);
820 if (r < 0)
821 return r;
822 }
823
824 if (ret_handle)
825 *ret_handle = TAKE_PTR(handle);
826
827 return 1;
828 }
829
830 /* Get the handle index for the provided Tpm2Handle. */
831 int tpm2_index_from_handle(Tpm2Context *c, const Tpm2Handle *handle, TPM2_HANDLE *ret_index) {
832 TSS2_RC rc;
833
834 assert(c);
835 assert(handle);
836 assert(ret_index);
837
838 /* Esys_TR_GetTpmHandle was added to tpm2-tss in version 2.4.0. Once we can set a minimum tpm2-tss
839 * version of 2.4.0 this check can be removed. */
840 if (!sym_Esys_TR_GetTpmHandle)
841 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
842 "libtss2-esys too old, does not include Esys_TR_GetTpmHandle.");
843
844 rc = sym_Esys_TR_GetTpmHandle(c->esys_context, handle->esys_handle, ret_index);
845 if (rc != TSS2_RC_SUCCESS)
846 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
847 "Failed to get handle index: %s", sym_Tss2_RC_Decode(rc));
848
849 return 0;
850 }
851
852 /* Copy an object in the TPM at a transient handle to a persistent handle.
853 *
854 * The provided transient handle must exist in the TPM in the transient range. The persistent handle may be 0
855 * or any handle in the persistent range. If 0, this will try each handle in the persistent range, in
856 * ascending order, until an available one is found. If non-zero, only the requested persistent handle will
857 * be used.
858 *
859 * Note that the persistent handle parameter is an handle index (i.e. number), while the transient handle is
860 * a Tpm2Handle object. The returned persistent handle will be a Tpm2Handle object that is located in the TPM
861 * at the requested persistent handle index (or the first available if none was requested).
862 *
863 * Returns 1 if the object was successfully persisted, or 0 if there is already a key at the requested
864 * handle, or < 0 on error. Theoretically, this would also return 0 if no specific persistent handle is
865 * requiested but all persistent handles are used, but it is extremely unlikely the TPM has enough internal
866 * memory to store the entire persistent range, in which case an error will be returned if the TPM is out of
867 * memory for persistent storage. The persistent handle is only provided when returning 1. */
868 static int tpm2_persist_handle(
869 Tpm2Context *c,
870 const Tpm2Handle *transient_handle,
871 const Tpm2Handle *session,
872 TPMI_DH_PERSISTENT persistent_handle_index,
873 Tpm2Handle **ret_persistent_handle) {
874
875 /* We don't use TPM2_PERSISTENT_FIRST and TPM2_PERSISTENT_LAST here due to:
876 * https://github.com/systemd/systemd/pull/27713#issuecomment-1591864753 */
877 TPMI_DH_PERSISTENT first = UINT32_C(0x81000000), last = UINT32_C(0x81ffffff);
878 TSS2_RC rc;
879 int r;
880
881 assert(c);
882 assert(transient_handle);
883
884 /* If persistent handle index specified, only try that. */
885 if (persistent_handle_index != 0) {
886 if (TPM2_HANDLE_TYPE(persistent_handle_index) != TPM2_HT_PERSISTENT)
887 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
888 "Handle not in persistent range: 0x%x", persistent_handle_index);
889
890 first = last = persistent_handle_index;
891 }
892
893 for (TPMI_DH_PERSISTENT requested = first; requested <= last; requested++) {
894 _cleanup_(tpm2_handle_freep) Tpm2Handle *persistent_handle = NULL;
895 r = tpm2_handle_new(c, &persistent_handle);
896 if (r < 0)
897 return r;
898
899 /* Since this is a persistent handle, don't flush it. */
900 persistent_handle->flush = false;
901
902 rc = sym_Esys_EvictControl(
903 c->esys_context,
904 ESYS_TR_RH_OWNER,
905 transient_handle->esys_handle,
906 session ? session->esys_handle : ESYS_TR_PASSWORD,
907 ESYS_TR_NONE,
908 ESYS_TR_NONE,
909 requested,
910 &persistent_handle->esys_handle);
911 if (rc == TSS2_RC_SUCCESS) {
912 if (ret_persistent_handle)
913 *ret_persistent_handle = TAKE_PTR(persistent_handle);
914
915 return 1;
916 }
917 if (rc != TPM2_RC_NV_DEFINED)
918 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
919 "Failed to persist handle: %s", sym_Tss2_RC_Decode(rc));
920 }
921
922 if (ret_persistent_handle)
923 *ret_persistent_handle = NULL;
924
925 return 0;
926 }
927
928 #define TPM2_CREDIT_RANDOM_FLAG_PATH "/run/systemd/tpm-rng-credited"
929
930 static int tpm2_credit_random(Tpm2Context *c) {
931 size_t rps, done = 0;
932 TSS2_RC rc;
933 usec_t t;
934 int r;
935
936 assert(c);
937
938 /* Pulls some entropy from the TPM and adds it into the kernel RNG pool. That way we can say that the
939 * key we will ultimately generate with the kernel random pool is at least as good as the TPM's RNG,
940 * but likely better. Note that we don't trust the TPM RNG very much, hence do not actually credit
941 * any entropy. */
942
943 if (access(TPM2_CREDIT_RANDOM_FLAG_PATH, F_OK) < 0) {
944 if (errno != ENOENT)
945 log_debug_errno(errno, "Failed to detect if '" TPM2_CREDIT_RANDOM_FLAG_PATH "' exists, ignoring: %m");
946 } else {
947 log_debug("Not adding TPM2 entropy to the kernel random pool again.");
948 return 0; /* Already done */
949 }
950
951 t = now(CLOCK_MONOTONIC);
952
953 for (rps = random_pool_size(); rps > 0;) {
954 _cleanup_(Esys_Freep) TPM2B_DIGEST *buffer = NULL;
955
956 rc = sym_Esys_GetRandom(
957 c->esys_context,
958 ESYS_TR_NONE,
959 ESYS_TR_NONE,
960 ESYS_TR_NONE,
961 MIN(rps, 32U), /* 32 is supposedly a safe choice, given that AES 256bit keys are this long, and TPM2 baseline requires support for those. */
962 &buffer);
963 if (rc != TSS2_RC_SUCCESS)
964 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
965 "Failed to acquire entropy from TPM: %s", sym_Tss2_RC_Decode(rc));
966
967 if (buffer->size == 0)
968 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
969 "Zero-sized entropy returned from TPM.");
970
971 r = random_write_entropy(-1, buffer->buffer, buffer->size, /* credit= */ false);
972 if (r < 0)
973 return log_debug_errno(r, "Failed wo write entropy to kernel: %m");
974
975 done += buffer->size;
976 rps = LESS_BY(rps, buffer->size);
977 }
978
979 log_debug("Added %zu bytes of TPM2 entropy to the kernel random pool in %s.", done, FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - t, 0));
980
981 r = touch(TPM2_CREDIT_RANDOM_FLAG_PATH);
982 if (r < 0)
983 log_debug_errno(r, "Failed to touch '" TPM2_CREDIT_RANDOM_FLAG_PATH "', ignoring: %m");
984
985 return 0;
986 }
987
988 int tpm2_read_public(
989 Tpm2Context *c,
990 const Tpm2Handle *session,
991 const Tpm2Handle *handle,
992 TPM2B_PUBLIC **ret_public,
993 TPM2B_NAME **ret_name,
994 TPM2B_NAME **ret_qname) {
995
996 TSS2_RC rc;
997
998 assert(c);
999 assert(handle);
1000
1001 rc = sym_Esys_ReadPublic(
1002 c->esys_context,
1003 handle->esys_handle,
1004 session ? session->esys_handle : ESYS_TR_NONE,
1005 ESYS_TR_NONE,
1006 ESYS_TR_NONE,
1007 ret_public,
1008 ret_name,
1009 ret_qname);
1010 if (rc != TSS2_RC_SUCCESS)
1011 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1012 "Failed to read public info: %s", sym_Tss2_RC_Decode(rc));
1013
1014 return 0;
1015 }
1016
1017 /* Get one of the legacy primary key templates.
1018 *
1019 * The legacy templates should only be used for older sealed data that did not use the SRK. Instead of a
1020 * persistent SRK, a transient key was created to seal the data and then flushed; and the exact same template
1021 * must be used to recreate the same transient key to unseal the data. The alg parameter must be TPM2_ALG_RSA
1022 * or TPM2_ALG_ECC. This does not check if the alg is actually supported on this TPM. */
1023 static int tpm2_get_legacy_template(TPMI_ALG_PUBLIC alg, TPMT_PUBLIC *ret_template) {
1024 /* Do not modify. */
1025 static const TPMT_PUBLIC legacy_ecc = {
1026 .type = TPM2_ALG_ECC,
1027 .nameAlg = TPM2_ALG_SHA256,
1028 .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH,
1029 .parameters.eccDetail = {
1030 .symmetric = {
1031 .algorithm = TPM2_ALG_AES,
1032 .keyBits.aes = 128,
1033 .mode.aes = TPM2_ALG_CFB,
1034 },
1035 .scheme.scheme = TPM2_ALG_NULL,
1036 .curveID = TPM2_ECC_NIST_P256,
1037 .kdf.scheme = TPM2_ALG_NULL,
1038 },
1039 };
1040
1041 /* Do not modify. */
1042 static const TPMT_PUBLIC legacy_rsa = {
1043 .type = TPM2_ALG_RSA,
1044 .nameAlg = TPM2_ALG_SHA256,
1045 .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH,
1046 .parameters.rsaDetail = {
1047 .symmetric = {
1048 .algorithm = TPM2_ALG_AES,
1049 .keyBits.aes = 128,
1050 .mode.aes = TPM2_ALG_CFB,
1051 },
1052 .scheme.scheme = TPM2_ALG_NULL,
1053 .keyBits = 2048,
1054 },
1055 };
1056
1057 assert(ret_template);
1058
1059 if (alg == TPM2_ALG_ECC)
1060 *ret_template = legacy_ecc;
1061 else if (alg == TPM2_ALG_RSA)
1062 *ret_template = legacy_rsa;
1063 else
1064 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1065 "Unsupported legacy SRK alg: 0x%x", alg);
1066
1067 return 0;
1068 }
1069
1070 /* Get a Storage Root Key (SRK) template.
1071 *
1072 * The SRK template values are recommended by the "TCG TPM v2.0 Provisioning Guidance" document in section
1073 * 7.5.1 "Storage Primary Key (SRK) Templates", referencing "TCG EK Credential Profile for TPM Family 2.0".
1074 * The EK Credential Profile version 2.0 provides only a single template each for RSA and ECC, while later EK
1075 * Credential Profile versions provide more templates, and keep the original templates as "L-1" (for RSA) and
1076 * "L-2" (for ECC).
1077 *
1078 * https://trustedcomputinggroup.org/resource/tcg-tpm-v2-0-provisioning-guidance
1079 * https://trustedcomputinggroup.org/resource/http-trustedcomputinggroup-org-wp-content-uploads-tcg-ek-credential-profile
1080 *
1081 * These templates are only needed to create a new persistent SRK (or a new transient key that is
1082 * SRK-compatible). Preferably, the TPM should contain a shared SRK located at the reserved shared SRK handle
1083 * (see TPM2_SRK_HANDLE and tpm2_get_srk() below).
1084 *
1085 * The alg must be TPM2_ALG_RSA or TPM2_ALG_ECC. Returns error if the requested template is not supported on
1086 * this TPM. Also see tpm2_get_best_srk_template() below. */
1087 static int tpm2_get_srk_template(Tpm2Context *c, TPMI_ALG_PUBLIC alg, TPMT_PUBLIC *ret_template) {
1088 /* The attributes are the same between ECC and RSA templates. This has the changes specified in the
1089 * Provisioning Guidance document, specifically:
1090 * TPMA_OBJECT_USERWITHAUTH is added.
1091 * TPMA_OBJECT_ADMINWITHPOLICY is removed.
1092 * TPMA_OBJECT_NODA is added. */
1093 TPMA_OBJECT srk_attributes =
1094 TPMA_OBJECT_DECRYPT |
1095 TPMA_OBJECT_FIXEDPARENT |
1096 TPMA_OBJECT_FIXEDTPM |
1097 TPMA_OBJECT_NODA |
1098 TPMA_OBJECT_RESTRICTED |
1099 TPMA_OBJECT_SENSITIVEDATAORIGIN |
1100 TPMA_OBJECT_USERWITHAUTH;
1101
1102 /* The symmetric configuration is the same between ECC and RSA templates. */
1103 TPMT_SYM_DEF_OBJECT srk_symmetric = {
1104 .algorithm = TPM2_ALG_AES,
1105 .keyBits.aes = 128,
1106 .mode.aes = TPM2_ALG_CFB,
1107 };
1108
1109 /* Both templates have an empty authPolicy as specified by the Provisioning Guidance document. */
1110
1111 /* From the EK Credential Profile template "L-2". */
1112 TPMT_PUBLIC srk_ecc = {
1113 .type = TPM2_ALG_ECC,
1114 .nameAlg = TPM2_ALG_SHA256,
1115 .objectAttributes = srk_attributes,
1116 .parameters.eccDetail = {
1117 .symmetric = srk_symmetric,
1118 .scheme.scheme = TPM2_ALG_NULL,
1119 .curveID = TPM2_ECC_NIST_P256,
1120 .kdf.scheme = TPM2_ALG_NULL,
1121 },
1122 };
1123
1124 /* From the EK Credential Profile template "L-1". */
1125 TPMT_PUBLIC srk_rsa = {
1126 .type = TPM2_ALG_RSA,
1127 .nameAlg = TPM2_ALG_SHA256,
1128 .objectAttributes = srk_attributes,
1129 .parameters.rsaDetail = {
1130 .symmetric = srk_symmetric,
1131 .scheme.scheme = TPM2_ALG_NULL,
1132 .keyBits = 2048,
1133 },
1134 };
1135
1136 assert(c);
1137 assert(ret_template);
1138
1139 if (alg == TPM2_ALG_ECC) {
1140 if (!tpm2_supports_alg(c, TPM2_ALG_ECC))
1141 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1142 "TPM does not support ECC.");
1143
1144 if (!tpm2_supports_ecc_curve(c, srk_ecc.parameters.eccDetail.curveID))
1145 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1146 "TPM does not support ECC-NIST-P256 curve.");
1147
1148 if (!tpm2_supports_tpmt_public(c, &srk_ecc))
1149 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1150 "TPM does not support SRK ECC template L-2.");
1151
1152 *ret_template = srk_ecc;
1153 return 0;
1154 }
1155
1156 if (alg == TPM2_ALG_RSA) {
1157 if (!tpm2_supports_alg(c, TPM2_ALG_RSA))
1158 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1159 "TPM does not support RSA.");
1160
1161 if (!tpm2_supports_tpmt_public(c, &srk_rsa))
1162 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1163 "TPM does not support SRK RSA template L-1.");
1164
1165 *ret_template = srk_rsa;
1166 return 0;
1167 }
1168
1169 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Unsupported SRK alg: 0x%x.", alg);
1170 }
1171
1172 /* Get the best supported SRK template. ECC is preferred, then RSA. */
1173 static int tpm2_get_best_srk_template(Tpm2Context *c, TPMT_PUBLIC *ret_template) {
1174 if (tpm2_get_srk_template(c, TPM2_ALG_ECC, ret_template) >= 0 ||
1175 tpm2_get_srk_template(c, TPM2_ALG_RSA, ret_template) >= 0)
1176 return 0;
1177
1178 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1179 "TPM does not support either SRK template L-1 (RSA) or L-2 (ECC).");
1180 }
1181
1182 /* The SRK handle is defined in the Provisioning Guidance document (see above) in the table "Reserved Handles
1183 * for TPM Provisioning Fundamental Elements". The SRK is useful because it is "shared", meaning it has no
1184 * authValue nor authPolicy set, and thus may be used by anyone on the system to generate derived keys or
1185 * seal secrets. This is useful if the TPM has an auth (password) set for the 'owner hierarchy', which would
1186 * prevent users from generating primary transient keys, unless they knew the owner hierarchy auth. See
1187 * the Provisioning Guidance document for more details. */
1188 #define TPM2_SRK_HANDLE UINT32_C(0x81000001)
1189
1190 /* Get the SRK. Returns 1 if SRK is found, 0 if there is no SRK, or < 0 on error. Also see
1191 * tpm2_get_or_create_srk() below. */
1192 static int tpm2_get_srk(
1193 Tpm2Context *c,
1194 const Tpm2Handle *session,
1195 TPM2B_PUBLIC **ret_public,
1196 TPM2B_NAME **ret_name,
1197 TPM2B_NAME **ret_qname,
1198 Tpm2Handle **ret_handle) {
1199
1200 return tpm2_index_to_handle(c, TPM2_SRK_HANDLE, session, ret_public, ret_name, ret_qname, ret_handle);
1201 }
1202
1203 /* Get the SRK, creating one if needed. Returns 1 if a new SRK was created and persisted, 0 if an SRK already
1204 * exists, or < 0 on error. */
1205 int tpm2_get_or_create_srk(
1206 Tpm2Context *c,
1207 const Tpm2Handle *session,
1208 TPM2B_PUBLIC **ret_public,
1209 TPM2B_NAME **ret_name,
1210 TPM2B_NAME **ret_qname,
1211 Tpm2Handle **ret_handle) {
1212
1213 int r;
1214
1215 r = tpm2_get_srk(c, session, ret_public, ret_name, ret_qname, ret_handle);
1216 if (r < 0)
1217 return r;
1218 if (r == 1)
1219 return 0; /* 0 → SRK already set up */
1220
1221 /* No SRK, create and persist one */
1222 TPM2B_PUBLIC template = { .size = sizeof(TPMT_PUBLIC), };
1223 r = tpm2_get_best_srk_template(c, &template.publicArea);
1224 if (r < 0)
1225 return log_debug_errno(r, "Could not get best SRK template: %m");
1226
1227 _cleanup_(tpm2_handle_freep) Tpm2Handle *transient_handle = NULL;
1228 r = tpm2_create_primary(
1229 c,
1230 session,
1231 &template,
1232 /* sensitive= */ NULL,
1233 /* ret_public= */ NULL,
1234 &transient_handle);
1235 if (r < 0)
1236 return r;
1237
1238 /* Try to persist the transient SRK we created. No locking needed; if multiple threads are trying to
1239 * persist SRKs concurrently, only one will succeed (r == 1) while the rest will fail (r == 0). In
1240 * either case, all threads will get the persistent SRK below. */
1241 r = tpm2_persist_handle(c, transient_handle, session, TPM2_SRK_HANDLE, /* ret_persistent_handle= */ NULL);
1242 if (r < 0)
1243 return r;
1244
1245 /* The SRK should exist now. */
1246 r = tpm2_get_srk(c, session, ret_public, ret_name, ret_qname, ret_handle);
1247 if (r < 0)
1248 return r;
1249 if (r == 0)
1250 /* This should never happen. */
1251 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "SRK we just persisted couldn't be found.");
1252
1253 return 1; /* > 0 → SRK newly set up */
1254 }
1255
1256 /* Utility functions for TPMS_PCR_SELECTION. */
1257
1258 /* Convert a TPMS_PCR_SELECTION object to a mask. */
1259 uint32_t tpm2_tpms_pcr_selection_to_mask(const TPMS_PCR_SELECTION *s) {
1260 assert(s);
1261 assert(s->sizeofSelect <= sizeof(s->pcrSelect));
1262
1263 uint32_t mask = 0;
1264 for (unsigned i = 0; i < s->sizeofSelect; i++)
1265 SET_FLAG(mask, (uint32_t)s->pcrSelect[i] << (i * 8), true);
1266 return mask;
1267 }
1268
1269 /* Convert a mask and hash alg to a TPMS_PCR_SELECTION object. */
1270 void tpm2_tpms_pcr_selection_from_mask(uint32_t mask, TPMI_ALG_HASH hash_alg, TPMS_PCR_SELECTION *ret) {
1271 assert(ret);
1272
1273 /* This is currently hardcoded at 24 PCRs, above. */
1274 if (!TPM2_PCR_MASK_VALID(mask))
1275 log_debug("PCR mask selections (%x) out of range, ignoring.",
1276 mask & ~((uint32_t)TPM2_PCRS_MASK));
1277
1278 *ret = (TPMS_PCR_SELECTION){
1279 .hash = hash_alg,
1280 .sizeofSelect = TPM2_PCRS_MAX / 8,
1281 .pcrSelect[0] = mask & 0xff,
1282 .pcrSelect[1] = (mask >> 8) & 0xff,
1283 .pcrSelect[2] = (mask >> 16) & 0xff,
1284 };
1285 }
1286
1287 /* Test if all bits in the mask are set in the TPMS_PCR_SELECTION. */
1288 bool tpm2_tpms_pcr_selection_has_mask(const TPMS_PCR_SELECTION *s, uint32_t mask) {
1289 assert(s);
1290
1291 return FLAGS_SET(tpm2_tpms_pcr_selection_to_mask(s), mask);
1292 }
1293
1294 static void tpm2_tpms_pcr_selection_update_mask(TPMS_PCR_SELECTION *s, uint32_t mask, bool b) {
1295 assert(s);
1296
1297 tpm2_tpms_pcr_selection_from_mask(UPDATE_FLAG(tpm2_tpms_pcr_selection_to_mask(s), mask, b), s->hash, s);
1298 }
1299
1300 /* Add all PCR selections in the mask. */
1301 void tpm2_tpms_pcr_selection_add_mask(TPMS_PCR_SELECTION *s, uint32_t mask) {
1302 tpm2_tpms_pcr_selection_update_mask(s, mask, 1);
1303 }
1304
1305 /* Remove all PCR selections in the mask. */
1306 void tpm2_tpms_pcr_selection_sub_mask(TPMS_PCR_SELECTION *s, uint32_t mask) {
1307 tpm2_tpms_pcr_selection_update_mask(s, mask, 0);
1308 }
1309
1310 /* Add all PCR selections in 'b' to 'a'. Both must have the same hash alg. */
1311 void tpm2_tpms_pcr_selection_add(TPMS_PCR_SELECTION *a, const TPMS_PCR_SELECTION *b) {
1312 assert(a);
1313 assert(b);
1314 assert(a->hash == b->hash);
1315
1316 tpm2_tpms_pcr_selection_add_mask(a, tpm2_tpms_pcr_selection_to_mask(b));
1317 }
1318
1319 /* Remove all PCR selections in 'b' from 'a'. Both must have the same hash alg. */
1320 void tpm2_tpms_pcr_selection_sub(TPMS_PCR_SELECTION *a, const TPMS_PCR_SELECTION *b) {
1321 assert(a);
1322 assert(b);
1323 assert(a->hash == b->hash);
1324
1325 tpm2_tpms_pcr_selection_sub_mask(a, tpm2_tpms_pcr_selection_to_mask(b));
1326 }
1327
1328 /* Move all PCR selections in 'b' to 'a'. Both must have the same hash alg. */
1329 void tpm2_tpms_pcr_selection_move(TPMS_PCR_SELECTION *a, TPMS_PCR_SELECTION *b) {
1330 if (a == b)
1331 return;
1332
1333 tpm2_tpms_pcr_selection_add(a, b);
1334 tpm2_tpms_pcr_selection_from_mask(0, b->hash, b);
1335 }
1336
1337 #define FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml) \
1338 _FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml, UNIQ_T(l, UNIQ))
1339 #define _FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml, l) \
1340 for (typeof(tpml) (l) = (tpml); (l); (l) = NULL) \
1341 FOREACH_ARRAY(tpms, (l)->pcrSelections, (l)->count)
1342
1343 #define FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms) \
1344 FOREACH_PCR_IN_MASK(pcr, tpm2_tpms_pcr_selection_to_mask(tpms))
1345
1346 #define FOREACH_PCR_IN_TPML_PCR_SELECTION(pcr, tpms, tpml) \
1347 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml) \
1348 FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms)
1349
1350 char *tpm2_tpms_pcr_selection_to_string(const TPMS_PCR_SELECTION *s) {
1351 assert(s);
1352
1353 const char *algstr = strna(tpm2_hash_alg_to_string(s->hash));
1354
1355 _cleanup_free_ char *mask = tpm2_pcr_mask_to_string(tpm2_tpms_pcr_selection_to_mask(s));
1356 if (!mask)
1357 return NULL;
1358
1359 return strjoin(algstr, "(", mask, ")");
1360 }
1361
1362 size_t tpm2_tpms_pcr_selection_weight(const TPMS_PCR_SELECTION *s) {
1363 assert(s);
1364
1365 return popcount(tpm2_tpms_pcr_selection_to_mask(s));
1366 }
1367
1368 /* Utility functions for TPML_PCR_SELECTION. */
1369
1370 /* Remove the (0-based) index entry from 'l', shift all following entries, and update the count. */
1371 static void tpm2_tpml_pcr_selection_remove_index(TPML_PCR_SELECTION *l, uint32_t index) {
1372 assert(l);
1373 assert(l->count <= ELEMENTSOF(l->pcrSelections));
1374 assert(index < l->count);
1375
1376 size_t s = l->count - (index + 1);
1377 memmove(&l->pcrSelections[index], &l->pcrSelections[index + 1], s * sizeof(l->pcrSelections[0]));
1378 l->count--;
1379 }
1380
1381 /* Get a TPMS_PCR_SELECTION from a TPML_PCR_SELECTION for the given hash alg. Returns NULL if there is no
1382 * entry for the hash alg. This guarantees the returned entry contains all the PCR selections for the given
1383 * hash alg, which may require modifying the TPML_PCR_SELECTION by removing duplicate entries. */
1384 static TPMS_PCR_SELECTION *tpm2_tpml_pcr_selection_get_tpms_pcr_selection(
1385 TPML_PCR_SELECTION *l,
1386 TPMI_ALG_HASH hash_alg) {
1387
1388 assert(l);
1389 assert(l->count <= ELEMENTSOF(l->pcrSelections));
1390
1391 TPMS_PCR_SELECTION *selection = NULL;
1392 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s, l)
1393 if (s->hash == hash_alg) {
1394 selection = s;
1395 break;
1396 }
1397
1398 if (!selection)
1399 return NULL;
1400
1401 /* Iterate backwards through the entries, removing any other entries for the hash alg. */
1402 for (uint32_t i = l->count - 1; i > 0; i--) {
1403 TPMS_PCR_SELECTION *s = &l->pcrSelections[i];
1404
1405 if (selection == s)
1406 break;
1407
1408 if (s->hash == hash_alg) {
1409 tpm2_tpms_pcr_selection_move(selection, s);
1410 tpm2_tpml_pcr_selection_remove_index(l, i);
1411 }
1412 }
1413
1414 return selection;
1415 }
1416
1417 /* Combine all duplicate (same hash alg) TPMS_PCR_SELECTION entries in 'l'. */
1418 static void tpm2_tpml_pcr_selection_cleanup(TPML_PCR_SELECTION *l) {
1419 /* Can't use FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION() because we might modify l->count */
1420 for (uint32_t i = 0; i < l->count; i++)
1421 /* This removes all duplicate TPMS_PCR_SELECTION entries for this hash. */
1422 (void) tpm2_tpml_pcr_selection_get_tpms_pcr_selection(l, l->pcrSelections[i].hash);
1423 }
1424
1425 /* Convert a TPML_PCR_SELECTION object to a mask. Returns empty mask (i.e. 0) if 'hash_alg' is not in the object. */
1426 uint32_t tpm2_tpml_pcr_selection_to_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash_alg) {
1427 assert(l);
1428
1429 /* Make a copy, as tpm2_tpml_pcr_selection_get_tpms_pcr_selection() will modify the object if there
1430 * are multiple entries with the requested hash alg. */
1431 TPML_PCR_SELECTION lcopy = *l;
1432
1433 TPMS_PCR_SELECTION *s;
1434 s = tpm2_tpml_pcr_selection_get_tpms_pcr_selection(&lcopy, hash_alg);
1435 if (!s)
1436 return 0;
1437
1438 return tpm2_tpms_pcr_selection_to_mask(s);
1439 }
1440
1441 /* Convert a mask and hash alg to a TPML_PCR_SELECTION object. */
1442 void tpm2_tpml_pcr_selection_from_mask(uint32_t mask, TPMI_ALG_HASH hash_alg, TPML_PCR_SELECTION *ret) {
1443 assert(ret);
1444
1445 TPMS_PCR_SELECTION s;
1446 tpm2_tpms_pcr_selection_from_mask(mask, hash_alg, &s);
1447
1448 *ret = (TPML_PCR_SELECTION){
1449 .count = 1,
1450 .pcrSelections[0] = s,
1451 };
1452 }
1453
1454 /* Add the PCR selections in 's' to the corresponding hash alg TPMS_PCR_SELECTION entry in 'l'. Adds a new
1455 * TPMS_PCR_SELECTION entry for the hash alg if needed. This may modify the TPML_PCR_SELECTION by combining
1456 * entries with the same hash alg. */
1457 void tpm2_tpml_pcr_selection_add_tpms_pcr_selection(TPML_PCR_SELECTION *l, const TPMS_PCR_SELECTION *s) {
1458 assert(l);
1459 assert(s);
1460
1461 if (tpm2_tpms_pcr_selection_is_empty(s))
1462 return;
1463
1464 TPMS_PCR_SELECTION *selection = tpm2_tpml_pcr_selection_get_tpms_pcr_selection(l, s->hash);
1465 if (selection) {
1466 tpm2_tpms_pcr_selection_add(selection, s);
1467 return;
1468 }
1469
1470 /* It's already broken if the count is higher than the array has size for. */
1471 assert(l->count <= ELEMENTSOF(l->pcrSelections));
1472
1473 /* If full, the cleanup should result in at least one available entry. */
1474 if (l->count == ELEMENTSOF(l->pcrSelections))
1475 tpm2_tpml_pcr_selection_cleanup(l);
1476
1477 assert(l->count < ELEMENTSOF(l->pcrSelections));
1478 l->pcrSelections[l->count++] = *s;
1479 }
1480
1481 /* Remove the PCR selections in 's' from the corresponding hash alg TPMS_PCR_SELECTION entry in 'l'. This
1482 * will combine all entries for 's->hash' in 'l'. */
1483 void tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(TPML_PCR_SELECTION *l, const TPMS_PCR_SELECTION *s) {
1484 assert(l);
1485 assert(s);
1486
1487 if (tpm2_tpms_pcr_selection_is_empty(s))
1488 return;
1489
1490 TPMS_PCR_SELECTION *selection = tpm2_tpml_pcr_selection_get_tpms_pcr_selection(l, s->hash);
1491 if (selection)
1492 tpm2_tpms_pcr_selection_sub(selection, s);
1493 }
1494
1495 /* Test if all bits in the mask for the hash are set in the TPML_PCR_SELECTION. */
1496 bool tpm2_tpml_pcr_selection_has_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask) {
1497 assert(l);
1498
1499 return FLAGS_SET(tpm2_tpml_pcr_selection_to_mask(l, hash), mask);
1500 }
1501
1502 /* Add the PCR selections in the mask, with the provided hash. */
1503 void tpm2_tpml_pcr_selection_add_mask(TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask) {
1504 TPMS_PCR_SELECTION tpms;
1505
1506 assert(l);
1507
1508 tpm2_tpms_pcr_selection_from_mask(mask, hash, &tpms);
1509 tpm2_tpml_pcr_selection_add_tpms_pcr_selection(l, &tpms);
1510 }
1511
1512 /* Remove the PCR selections in the mask, with the provided hash. */
1513 void tpm2_tpml_pcr_selection_sub_mask(TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask) {
1514 TPMS_PCR_SELECTION tpms;
1515
1516 assert(l);
1517
1518 tpm2_tpms_pcr_selection_from_mask(mask, hash, &tpms);
1519 tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(l, &tpms);
1520 }
1521
1522 /* Add all PCR selections in 'b' to 'a'. */
1523 void tpm2_tpml_pcr_selection_add(TPML_PCR_SELECTION *a, const TPML_PCR_SELECTION *b) {
1524 assert(a);
1525 assert(b);
1526
1527 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection_b, b)
1528 tpm2_tpml_pcr_selection_add_tpms_pcr_selection(a, selection_b);
1529 }
1530
1531 /* Remove all PCR selections in 'b' from 'a'. */
1532 void tpm2_tpml_pcr_selection_sub(TPML_PCR_SELECTION *a, const TPML_PCR_SELECTION *b) {
1533 assert(a);
1534 assert(b);
1535
1536 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection_b, b)
1537 tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(a, selection_b);
1538 }
1539
1540 char *tpm2_tpml_pcr_selection_to_string(const TPML_PCR_SELECTION *l) {
1541 assert(l);
1542
1543 _cleanup_free_ char *banks = NULL;
1544 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s, l) {
1545 if (tpm2_tpms_pcr_selection_is_empty(s))
1546 continue;
1547
1548 _cleanup_free_ char *str = tpm2_tpms_pcr_selection_to_string(s);
1549 if (!str || !strextend_with_separator(&banks, ",", str))
1550 return NULL;
1551 }
1552
1553 return strjoin("[", strempty(banks), "]");
1554 }
1555
1556 size_t tpm2_tpml_pcr_selection_weight(const TPML_PCR_SELECTION *l) {
1557 assert(l);
1558 assert(l->count <= ELEMENTSOF(l->pcrSelections));
1559
1560 size_t weight = 0;
1561 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s, l) {
1562 size_t w = tpm2_tpms_pcr_selection_weight(s);
1563 assert(weight <= SIZE_MAX - w);
1564 weight += w;
1565 }
1566
1567 return weight;
1568 }
1569
1570 bool tpm2_pcr_value_valid(const Tpm2PCRValue *pcr_value) {
1571 int r;
1572
1573 if (!pcr_value)
1574 return false;
1575
1576 if (!TPM2_PCR_INDEX_VALID(pcr_value->index)) {
1577 log_debug("PCR index %u invalid.", pcr_value->index);
1578 return false;
1579 }
1580
1581 /* If it contains a value, the value size must match the hash size. */
1582 if (pcr_value->value.size > 0) {
1583 r = tpm2_hash_alg_to_size(pcr_value->hash);
1584 if (r < 0)
1585 return false;
1586
1587 if (pcr_value->value.size != (size_t) r) {
1588 log_debug("PCR hash 0x%" PRIx16 " expected size %d does not match actual size %" PRIu16 ".",
1589 pcr_value->hash, r, pcr_value->value.size);
1590 return false;
1591 }
1592 }
1593
1594 return true;
1595 }
1596
1597 /* Verify all entries are valid, and consistent with each other. The requirements for consistency are:
1598 *
1599 * 1) all entries must be sorted in ascending order (e.g. using tpm2_sort_pcr_values())
1600 * 2) all entries must be unique, i.e. there cannot be 2 entries with the same hash and index
1601 *
1602 * Returns true if all entries are valid (or if no entries are provided), false otherwise.
1603 */
1604 bool tpm2_pcr_values_valid(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
1605 if (!pcr_values && n_pcr_values > 0)
1606 return false;
1607
1608 const Tpm2PCRValue *previous = NULL;
1609 FOREACH_ARRAY(current, pcr_values, n_pcr_values) {
1610 if (!tpm2_pcr_value_valid(current))
1611 return false;
1612
1613 if (!previous) {
1614 previous = current;
1615 continue;
1616 }
1617
1618 /* Hashes must be sorted in ascending order */
1619 if (current->hash < previous->hash) {
1620 log_debug("PCR values not in ascending order, hash %" PRIu16 " is after %" PRIu16 ".",
1621 current->hash, previous->hash);
1622 return false;
1623 }
1624
1625 if (current->hash == previous->hash) {
1626 /* Indexes (for the same hash) must be sorted in ascending order */
1627 if (current->index < previous->index) {
1628 log_debug("PCR values not in ascending order, hash %" PRIu16 " index %u is after %u.",
1629 current->hash, current->index, previous->index);
1630 return false;
1631 }
1632
1633 /* Indexes (for the same hash) must not be duplicates */
1634 if (current->index == previous->index) {
1635 log_debug("PCR values contain duplicates for hash %" PRIu16 " index %u.",
1636 current->hash, previous->index);
1637 return false;
1638 }
1639 }
1640 }
1641
1642 return true;
1643 }
1644
1645 /* Returns true if any of the provided PCR values has an actual hash value included, false otherwise. */
1646 bool tpm2_pcr_values_has_any_values(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
1647 assert(pcr_values || n_pcr_values == 0);
1648
1649 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
1650 if (v->value.size > 0)
1651 return true;
1652
1653 return false;
1654 }
1655
1656 /* Returns true if all of the provided PCR values has an actual hash value included, false otherwise. */
1657 bool tpm2_pcr_values_has_all_values(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
1658 assert(pcr_values || n_pcr_values == 0);
1659
1660 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
1661 if (v->value.size == 0)
1662 return false;
1663
1664 return true;
1665 }
1666
1667 static int cmp_pcr_values(const Tpm2PCRValue *a, const Tpm2PCRValue *b) {
1668 assert(a);
1669 assert(b);
1670
1671 return CMP(a->hash, b->hash) ?: CMP(a->index, b->index);
1672 }
1673
1674 /* Sort the array of Tpm2PCRValue entries in-place. This sorts first in ascending order of hash algorithm
1675 * (sorting simply by the TPM2 hash algorithm number), and then sorting by pcr index. */
1676 void tpm2_sort_pcr_values(Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
1677 typesafe_qsort(pcr_values, n_pcr_values, cmp_pcr_values);
1678 }
1679
1680 int tpm2_pcr_values_from_mask(uint32_t mask, TPMI_ALG_HASH hash, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values) {
1681 _cleanup_free_ Tpm2PCRValue *pcr_values = NULL;
1682 size_t n_pcr_values = 0;
1683
1684 assert(ret_pcr_values);
1685 assert(ret_n_pcr_values);
1686
1687 FOREACH_PCR_IN_MASK(index, mask)
1688 if (!GREEDY_REALLOC_APPEND(
1689 pcr_values,
1690 n_pcr_values,
1691 &TPM2_PCR_VALUE_MAKE(index, hash, {}),
1692 1))
1693 return log_oom_debug();
1694
1695 *ret_pcr_values = TAKE_PTR(pcr_values);
1696 *ret_n_pcr_values = n_pcr_values;
1697
1698 return 0;
1699 }
1700
1701 int tpm2_pcr_values_to_mask(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, TPMI_ALG_HASH hash, uint32_t *ret_mask) {
1702 uint32_t mask = 0;
1703
1704 assert(pcr_values || n_pcr_values == 0);
1705 assert(ret_mask);
1706
1707 if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values))
1708 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid PCR values.");
1709
1710 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
1711 if (v->hash == hash)
1712 SET_BIT(mask, v->index);
1713
1714 *ret_mask = mask;
1715
1716 return 0;
1717 }
1718
1719 int tpm2_tpml_pcr_selection_from_pcr_values(
1720 const Tpm2PCRValue *pcr_values,
1721 size_t n_pcr_values,
1722 TPML_PCR_SELECTION *ret_selection,
1723 TPM2B_DIGEST **ret_values,
1724 size_t *ret_n_values) {
1725
1726 TPML_PCR_SELECTION selection = {};
1727 _cleanup_free_ TPM2B_DIGEST *values = NULL;
1728 size_t n_values = 0;
1729
1730 assert(pcr_values || n_pcr_values == 0);
1731
1732 if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values))
1733 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "PCR values are not valid.");
1734
1735 FOREACH_ARRAY(v, pcr_values, n_pcr_values) {
1736 tpm2_tpml_pcr_selection_add_mask(&selection, v->hash, INDEX_TO_MASK(uint32_t, v->index));
1737
1738 if (!GREEDY_REALLOC_APPEND(values, n_values, &v->value, 1))
1739 return log_oom_debug();
1740 }
1741
1742 if (ret_selection)
1743 *ret_selection = selection;
1744 if (ret_values)
1745 *ret_values = TAKE_PTR(values);
1746 if (ret_n_values)
1747 *ret_n_values = n_values;
1748
1749 return 0;
1750 }
1751
1752 /* Count the number of different hash algorithms for all the entries. */
1753 int tpm2_pcr_values_hash_count(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, size_t *ret_count) {
1754 TPML_PCR_SELECTION selection;
1755 int r;
1756
1757 assert(pcr_values);
1758 assert(ret_count);
1759
1760 r = tpm2_tpml_pcr_selection_from_pcr_values(
1761 pcr_values,
1762 n_pcr_values,
1763 &selection,
1764 /* ret_values= */ NULL,
1765 /* ret_n_values= */ NULL);
1766 if (r < 0)
1767 return r;
1768
1769 *ret_count = selection.count;
1770
1771 return 0;
1772 }
1773
1774 /* Parse a string argument into a Tpm2PCRValue object.
1775 *
1776 * The format is <index>[:hash[=value]] where index is the index number (or name) of the PCR, e.g. 0 (or
1777 * platform-code), hash is the name of the hash algorithm (e.g. sha256) and value is the hex hash digest
1778 * value, optionally with a leading 0x. This does not check for validity of the fields. */
1779 int tpm2_pcr_value_from_string(const char *arg, Tpm2PCRValue *ret_pcr_value) {
1780 Tpm2PCRValue pcr_value = {};
1781 const char *p = arg;
1782 int r;
1783
1784 assert(arg);
1785 assert(ret_pcr_value);
1786
1787 _cleanup_free_ char *index = NULL;
1788 r = extract_first_word(&p, &index, ":", /* flags= */ 0);
1789 if (r < 1)
1790 return log_debug_errno(r, "Could not parse pcr value '%s': %m", p);
1791
1792 r = tpm2_pcr_index_from_string(index);
1793 if (r < 0)
1794 return log_debug_errno(r, "Invalid pcr index '%s': %m", index);
1795 pcr_value.index = (unsigned) r;
1796
1797 if (!isempty(p)) {
1798 _cleanup_free_ char *hash = NULL;
1799 r = extract_first_word(&p, &hash, "=", /* flags= */ 0);
1800 if (r < 1)
1801 return log_debug_errno(r, "Could not parse pcr hash algorithm '%s': %m", p);
1802
1803 r = tpm2_hash_alg_from_string(hash);
1804 if (r < 0)
1805 return log_debug_errno(r, "Invalid pcr hash algorithm '%s': %m", hash);
1806 pcr_value.hash = (TPMI_ALG_HASH) r;
1807
1808 if (!isempty(p)) {
1809 /* Remove leading 0x if present */
1810 p = startswith_no_case(p, "0x") ?: p;
1811
1812 _cleanup_free_ void *buf = NULL;
1813 size_t buf_size = 0;
1814 r = unhexmem(p, SIZE_MAX, &buf, &buf_size);
1815 if (r < 0)
1816 return log_debug_errno(r, "Invalid pcr hash value '%s': %m", p);
1817
1818 r = TPM2B_DIGEST_CHECK_SIZE(buf_size);
1819 if (r < 0)
1820 return log_debug_errno(r, "PCR hash value size %zu too large.", buf_size);
1821
1822 pcr_value.value = TPM2B_DIGEST_MAKE(buf, buf_size);
1823 }
1824 }
1825
1826 *ret_pcr_value = pcr_value;
1827
1828 return 0;
1829 }
1830
1831 /* Return a string for the PCR value. The format is described in tpm2_pcr_value_from_string(). Note that if
1832 * the hash algorithm is not recognized, neither hash name nor hash digest value is included in the
1833 * string. This does not check for validity. */
1834 char *tpm2_pcr_value_to_string(const Tpm2PCRValue *pcr_value) {
1835 _cleanup_free_ char *index = NULL, *value = NULL;
1836
1837 if (asprintf(&index, "%u", pcr_value->index) < 0)
1838 return NULL;
1839
1840 const char *hash = pcr_value->hash > 0 ? tpm2_hash_alg_to_string(pcr_value->hash) : NULL;
1841
1842 if (hash && pcr_value->value.size > 0) {
1843 value = hexmem(pcr_value->value.buffer, pcr_value->value.size);
1844 if (!value)
1845 return NULL;
1846 }
1847
1848 return strjoin(index, hash ? ":" : "", strempty(hash), value ? "=" : "", strempty(value));
1849 }
1850
1851 /* Parse a string argument into an array of Tpm2PCRValue objects.
1852 *
1853 * The format is zero or more entries separated by ',' or '+'. The format of each entry is described in
1854 * tpm2_pcr_value_from_string(). This does not check for validity of the entries. */
1855 int tpm2_pcr_values_from_string(const char *arg, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values) {
1856 const char *p = arg;
1857 int r;
1858
1859 assert(arg);
1860 assert(ret_pcr_values);
1861 assert(ret_n_pcr_values);
1862
1863 _cleanup_free_ Tpm2PCRValue *pcr_values = NULL;
1864 size_t n_pcr_values = 0;
1865
1866 for (;;) {
1867 _cleanup_free_ char *pcr_arg = NULL;
1868 r = extract_first_word(&p, &pcr_arg, ",+", /* flags= */ 0);
1869 if (r < 0)
1870 return log_debug_errno(r, "Could not parse pcr values '%s': %m", p);
1871 if (r == 0)
1872 break;
1873
1874 Tpm2PCRValue pcr_value;
1875 r = tpm2_pcr_value_from_string(pcr_arg, &pcr_value);
1876 if (r < 0)
1877 return r;
1878
1879 if (!GREEDY_REALLOC_APPEND(pcr_values, n_pcr_values, &pcr_value, 1))
1880 return log_oom_debug();
1881 }
1882
1883 *ret_pcr_values = TAKE_PTR(pcr_values);
1884 *ret_n_pcr_values = n_pcr_values;
1885
1886 return 0;
1887 }
1888
1889 /* Return a string representing the array of PCR values. The format is as described in
1890 * tpm2_pcr_values_from_string(). This does not check for validity. */
1891 char *tpm2_pcr_values_to_string(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
1892 _cleanup_free_ char *s = NULL;
1893
1894 FOREACH_ARRAY(v, pcr_values, n_pcr_values) {
1895 _cleanup_free_ char *pcrstr = tpm2_pcr_value_to_string(v);
1896 if (!pcrstr || !strextend_with_separator(&s, "+", pcrstr))
1897 return NULL;
1898 }
1899
1900 return s ? TAKE_PTR(s) : strdup("");
1901 }
1902
1903 void tpm2_log_debug_tpml_pcr_selection(const TPML_PCR_SELECTION *l, const char *msg) {
1904 if (!DEBUG_LOGGING || !l)
1905 return;
1906
1907 _cleanup_free_ char *s = tpm2_tpml_pcr_selection_to_string(l);
1908 log_debug("%s: %s", msg ?: "PCR selection", strna(s));
1909 }
1910
1911 void tpm2_log_debug_pcr_value(const Tpm2PCRValue *pcr_value, const char *msg) {
1912 if (!DEBUG_LOGGING || !pcr_value)
1913 return;
1914
1915 _cleanup_free_ char *s = tpm2_pcr_value_to_string(pcr_value);
1916 log_debug("%s: %s", msg ?: "PCR value", strna(s));
1917 }
1918
1919 void tpm2_log_debug_buffer(const void *buffer, size_t size, const char *msg) {
1920 if (!DEBUG_LOGGING || !buffer || size == 0)
1921 return;
1922
1923 _cleanup_free_ char *h = hexmem(buffer, size);
1924 log_debug("%s: %s", msg ?: "Buffer", strna(h));
1925 }
1926
1927 void tpm2_log_debug_digest(const TPM2B_DIGEST *digest, const char *msg) {
1928 if (digest)
1929 tpm2_log_debug_buffer(digest->buffer, digest->size, msg ?: "Digest");
1930 }
1931
1932 void tpm2_log_debug_name(const TPM2B_NAME *name, const char *msg) {
1933 if (name)
1934 tpm2_log_debug_buffer(name->name, name->size, msg ?: "Name");
1935 }
1936
1937 static int tpm2_get_policy_digest(
1938 Tpm2Context *c,
1939 const Tpm2Handle *session,
1940 TPM2B_DIGEST **ret_policy_digest) {
1941
1942 TSS2_RC rc;
1943
1944 if (!DEBUG_LOGGING && !ret_policy_digest)
1945 return 0;
1946
1947 assert(c);
1948 assert(session);
1949
1950 log_debug("Acquiring policy digest.");
1951
1952 _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
1953 rc = sym_Esys_PolicyGetDigest(
1954 c->esys_context,
1955 session->esys_handle,
1956 ESYS_TR_NONE,
1957 ESYS_TR_NONE,
1958 ESYS_TR_NONE,
1959 &policy_digest);
1960 if (rc != TSS2_RC_SUCCESS)
1961 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1962 "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc));
1963
1964 tpm2_log_debug_digest(policy_digest, "Session policy digest");
1965
1966 if (ret_policy_digest)
1967 *ret_policy_digest = TAKE_PTR(policy_digest);
1968
1969 return 0;
1970 }
1971
1972 int tpm2_create_primary(
1973 Tpm2Context *c,
1974 const Tpm2Handle *session,
1975 const TPM2B_PUBLIC *template,
1976 const TPM2B_SENSITIVE_CREATE *sensitive,
1977 TPM2B_PUBLIC **ret_public,
1978 Tpm2Handle **ret_handle) {
1979
1980 usec_t ts;
1981 TSS2_RC rc;
1982 int r;
1983
1984 assert(c);
1985 assert(template);
1986
1987 log_debug("Creating primary key on TPM.");
1988
1989 ts = now(CLOCK_MONOTONIC);
1990
1991 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
1992 r = tpm2_handle_new(c, &handle);
1993 if (r < 0)
1994 return r;
1995
1996 _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
1997 rc = sym_Esys_CreatePrimary(
1998 c->esys_context,
1999 ESYS_TR_RH_OWNER,
2000 session ? session->esys_handle : ESYS_TR_PASSWORD,
2001 ESYS_TR_NONE,
2002 ESYS_TR_NONE,
2003 sensitive ? sensitive : &(TPM2B_SENSITIVE_CREATE) {},
2004 template,
2005 /* outsideInfo= */ NULL,
2006 &(TPML_PCR_SELECTION) {},
2007 &handle->esys_handle,
2008 &public,
2009 /* creationData= */ NULL,
2010 /* creationHash= */ NULL,
2011 /* creationTicket= */ NULL);
2012 if (rc != TSS2_RC_SUCCESS)
2013 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2014 "Failed to generate primary key in TPM: %s",
2015 sym_Tss2_RC_Decode(rc));
2016
2017 log_debug("Successfully created primary key on TPM in %s.",
2018 FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - ts, USEC_PER_MSEC));
2019
2020 if (ret_public)
2021 *ret_public = TAKE_PTR(public);
2022 if (ret_handle)
2023 *ret_handle = TAKE_PTR(handle);
2024
2025 return 0;
2026 }
2027
2028 /* Create a TPM object. Do not use this to create primary keys, because some HW TPMs refuse to allow that;
2029 * instead use tpm2_create_primary(). */
2030 int tpm2_create(Tpm2Context *c,
2031 const Tpm2Handle *parent,
2032 const Tpm2Handle *session,
2033 const TPMT_PUBLIC *template,
2034 const TPMS_SENSITIVE_CREATE *sensitive,
2035 TPM2B_PUBLIC **ret_public,
2036 TPM2B_PRIVATE **ret_private) {
2037
2038 usec_t ts;
2039 TSS2_RC rc;
2040
2041 assert(c);
2042 assert(parent);
2043 assert(template);
2044
2045 log_debug("Creating object on TPM.");
2046
2047 ts = now(CLOCK_MONOTONIC);
2048
2049 TPM2B_PUBLIC tpm2b_public = {
2050 .size = sizeof(*template) - sizeof(template->unique),
2051 .publicArea = *template,
2052 };
2053
2054 /* Zero the unique area. */
2055 zero(tpm2b_public.publicArea.unique);
2056
2057 TPM2B_SENSITIVE_CREATE tpm2b_sensitive;
2058 if (sensitive)
2059 tpm2b_sensitive = (TPM2B_SENSITIVE_CREATE) {
2060 .size = sizeof(*sensitive),
2061 .sensitive = *sensitive,
2062 };
2063 else
2064 tpm2b_sensitive = (TPM2B_SENSITIVE_CREATE) {};
2065
2066 _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
2067 _cleanup_(Esys_Freep) TPM2B_PRIVATE *private = NULL;
2068 rc = sym_Esys_Create(
2069 c->esys_context,
2070 parent->esys_handle,
2071 session ? session->esys_handle : ESYS_TR_PASSWORD,
2072 ESYS_TR_NONE,
2073 ESYS_TR_NONE,
2074 &tpm2b_sensitive,
2075 &tpm2b_public,
2076 /* outsideInfo= */ NULL,
2077 &(TPML_PCR_SELECTION) {},
2078 &private,
2079 &public,
2080 /* creationData= */ NULL,
2081 /* creationHash= */ NULL,
2082 /* creationTicket= */ NULL);
2083 if (rc != TSS2_RC_SUCCESS)
2084 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2085 "Failed to generate object in TPM: %s",
2086 sym_Tss2_RC_Decode(rc));
2087
2088 log_debug("Successfully created object on TPM in %s.",
2089 FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - ts, USEC_PER_MSEC));
2090
2091 if (ret_public)
2092 *ret_public = TAKE_PTR(public);
2093 if (ret_private)
2094 *ret_private = TAKE_PTR(private);
2095
2096 return 0;
2097 }
2098
2099 static int tpm2_load(
2100 Tpm2Context *c,
2101 const Tpm2Handle *parent,
2102 const Tpm2Handle *session,
2103 const TPM2B_PUBLIC *public,
2104 const TPM2B_PRIVATE *private,
2105 Tpm2Handle **ret_handle) {
2106
2107 TSS2_RC rc;
2108 int r;
2109
2110 assert(c);
2111 assert(public);
2112 assert(private);
2113 assert(ret_handle);
2114
2115 log_debug("Loading object into TPM.");
2116
2117 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
2118 r = tpm2_handle_new(c, &handle);
2119 if (r < 0)
2120 return r;
2121
2122 rc = sym_Esys_Load(
2123 c->esys_context,
2124 parent ? parent->esys_handle : ESYS_TR_RH_OWNER,
2125 session ? session->esys_handle : ESYS_TR_PASSWORD,
2126 ESYS_TR_NONE,
2127 ESYS_TR_NONE,
2128 private,
2129 public,
2130 &handle->esys_handle);
2131 if (rc == TPM2_RC_LOCKOUT)
2132 return log_debug_errno(SYNTHETIC_ERRNO(ENOLCK),
2133 "TPM2 device is in dictionary attack lockout mode.");
2134 if (rc != TSS2_RC_SUCCESS)
2135 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2136 "Failed to load key into TPM: %s", sym_Tss2_RC_Decode(rc));
2137
2138 *ret_handle = TAKE_PTR(handle);
2139
2140 return 0;
2141 }
2142
2143 static int tpm2_load_external(
2144 Tpm2Context *c,
2145 const Tpm2Handle *session,
2146 const TPM2B_PUBLIC *public,
2147 const TPM2B_SENSITIVE *private,
2148 Tpm2Handle **ret_handle) {
2149
2150 TSS2_RC rc;
2151 int r;
2152
2153 assert(c);
2154 assert(ret_handle);
2155
2156 log_debug("Loading external key into TPM.");
2157
2158 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
2159 r = tpm2_handle_new(c, &handle);
2160 if (r < 0)
2161 return r;
2162
2163 rc = sym_Esys_LoadExternal(
2164 c->esys_context,
2165 session ? session->esys_handle : ESYS_TR_NONE,
2166 ESYS_TR_NONE,
2167 ESYS_TR_NONE,
2168 private,
2169 public,
2170 #if HAVE_TSS2_ESYS3
2171 /* tpm2-tss >= 3.0.0 requires a ESYS_TR_RH_* constant specifying the requested
2172 * hierarchy, older versions need TPM2_RH_* instead. */
2173 ESYS_TR_RH_OWNER,
2174 #else
2175 TPM2_RH_OWNER,
2176 #endif
2177 &handle->esys_handle);
2178 if (rc != TSS2_RC_SUCCESS)
2179 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2180 "Failed to load public key into TPM: %s", sym_Tss2_RC_Decode(rc));
2181
2182 *ret_handle = TAKE_PTR(handle);
2183
2184 return 0;
2185 }
2186
2187 /* This calls TPM2_CreateLoaded() directly, without checking if the TPM supports it. Callers should instead
2188 * use tpm2_create_loaded(). */
2189 static int _tpm2_create_loaded(
2190 Tpm2Context *c,
2191 const Tpm2Handle *parent,
2192 const Tpm2Handle *session,
2193 const TPMT_PUBLIC *template,
2194 const TPMS_SENSITIVE_CREATE *sensitive,
2195 TPM2B_PUBLIC **ret_public,
2196 TPM2B_PRIVATE **ret_private,
2197 Tpm2Handle **ret_handle) {
2198
2199 usec_t ts;
2200 TSS2_RC rc;
2201 int r;
2202
2203 assert(c);
2204 assert(parent);
2205 assert(template);
2206
2207 log_debug("Creating loaded object on TPM.");
2208
2209 ts = now(CLOCK_MONOTONIC);
2210
2211 /* Copy the input template and zero the unique area. */
2212 TPMT_PUBLIC template_copy = *template;
2213 zero(template_copy.unique);
2214
2215 TPM2B_TEMPLATE tpm2b_template;
2216 size_t size = 0;
2217 rc = sym_Tss2_MU_TPMT_PUBLIC_Marshal(
2218 &template_copy,
2219 tpm2b_template.buffer,
2220 sizeof(tpm2b_template.buffer),
2221 &size);
2222 if (rc != TSS2_RC_SUCCESS)
2223 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2224 "Failed to marshal public key template: %s", sym_Tss2_RC_Decode(rc));
2225 assert(size <= UINT16_MAX);
2226 tpm2b_template.size = size;
2227
2228 TPM2B_SENSITIVE_CREATE tpm2b_sensitive;
2229 if (sensitive)
2230 tpm2b_sensitive = (TPM2B_SENSITIVE_CREATE) {
2231 .size = sizeof(*sensitive),
2232 .sensitive = *sensitive,
2233 };
2234 else
2235 tpm2b_sensitive = (TPM2B_SENSITIVE_CREATE) {};
2236
2237 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
2238 r = tpm2_handle_new(c, &handle);
2239 if (r < 0)
2240 return r;
2241
2242 _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
2243 _cleanup_(Esys_Freep) TPM2B_PRIVATE *private = NULL;
2244 rc = sym_Esys_CreateLoaded(
2245 c->esys_context,
2246 parent->esys_handle,
2247 session ? session->esys_handle : ESYS_TR_PASSWORD,
2248 ESYS_TR_NONE,
2249 ESYS_TR_NONE,
2250 &tpm2b_sensitive,
2251 &tpm2b_template,
2252 &handle->esys_handle,
2253 &private,
2254 &public);
2255 if (rc != TSS2_RC_SUCCESS)
2256 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2257 "Failed to generate loaded object in TPM: %s",
2258 sym_Tss2_RC_Decode(rc));
2259
2260 log_debug("Successfully created loaded object on TPM in %s.",
2261 FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - ts, USEC_PER_MSEC));
2262
2263 if (ret_public)
2264 *ret_public = TAKE_PTR(public);
2265 if (ret_private)
2266 *ret_private = TAKE_PTR(private);
2267 if (ret_handle)
2268 *ret_handle = TAKE_PTR(handle);
2269
2270 return 0;
2271 }
2272
2273 /* This calls TPM2_CreateLoaded() if the TPM supports it, otherwise it calls TPM2_Create() and TPM2_Load()
2274 * separately. Do not use this to create primary keys, because some HW TPMs refuse to allow that; instead use
2275 * tpm2_create_primary(). */
2276 int tpm2_create_loaded(
2277 Tpm2Context *c,
2278 const Tpm2Handle *parent,
2279 const Tpm2Handle *session,
2280 const TPMT_PUBLIC *template,
2281 const TPMS_SENSITIVE_CREATE *sensitive,
2282 TPM2B_PUBLIC **ret_public,
2283 TPM2B_PRIVATE **ret_private,
2284 Tpm2Handle **ret_handle) {
2285
2286 int r;
2287
2288 if (tpm2_supports_command(c, TPM2_CC_CreateLoaded))
2289 return _tpm2_create_loaded(c, parent, session, template, sensitive, ret_public, ret_private, ret_handle);
2290
2291 /* Unfortunately, this TPM doesn't support CreateLoaded (added at spec revision 130) so we need to
2292 * create and load manually. */
2293 _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
2294 _cleanup_(Esys_Freep) TPM2B_PRIVATE *private = NULL;
2295 r = tpm2_create(c, parent, session, template, sensitive, &public, &private);
2296 if (r < 0)
2297 return r;
2298
2299 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
2300 r = tpm2_load(c, parent, session, public, private, &handle);
2301 if (r < 0)
2302 return r;
2303
2304 if (ret_public)
2305 *ret_public = TAKE_PTR(public);
2306 if (ret_private)
2307 *ret_private = TAKE_PTR(private);
2308 if (ret_handle)
2309 *ret_handle = TAKE_PTR(handle);
2310
2311 return 0;
2312 }
2313
2314 /* Read hash values from the specified PCR selection. Provides a Tpm2PCRValue array that contains all
2315 * requested PCR values, in the order provided by the TPM. Normally, the provided pcr values will match
2316 * exactly what is in the provided selection, but the TPM may ignore some selected PCRs (for example, if an
2317 * unimplemented PCR index is requested), in which case those PCRs will be absent from the provided pcr
2318 * values. */
2319 int tpm2_pcr_read(
2320 Tpm2Context *c,
2321 const TPML_PCR_SELECTION *pcr_selection,
2322 Tpm2PCRValue **ret_pcr_values,
2323 size_t *ret_n_pcr_values) {
2324
2325 _cleanup_free_ Tpm2PCRValue *pcr_values = NULL;
2326 size_t n_pcr_values = 0;
2327 TSS2_RC rc;
2328
2329 assert(c);
2330 assert(pcr_selection);
2331 assert(ret_pcr_values);
2332 assert(ret_n_pcr_values);
2333
2334 TPML_PCR_SELECTION remaining = *pcr_selection;
2335 while (!tpm2_tpml_pcr_selection_is_empty(&remaining)) {
2336 _cleanup_(Esys_Freep) TPML_PCR_SELECTION *current_read = NULL;
2337 _cleanup_(Esys_Freep) TPML_DIGEST *current_values = NULL;
2338
2339 tpm2_log_debug_tpml_pcr_selection(&remaining, "Reading PCR selection");
2340
2341 /* Unfortunately, PCR_Read will not return more than 8 values. */
2342 rc = sym_Esys_PCR_Read(
2343 c->esys_context,
2344 ESYS_TR_NONE,
2345 ESYS_TR_NONE,
2346 ESYS_TR_NONE,
2347 &remaining,
2348 NULL,
2349 &current_read,
2350 &current_values);
2351 if (rc != TSS2_RC_SUCCESS)
2352 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2353 "Failed to read TPM2 PCRs: %s", sym_Tss2_RC_Decode(rc));
2354
2355 tpm2_log_debug_tpml_pcr_selection(current_read, "Read PCR selection");
2356
2357 if (tpm2_tpml_pcr_selection_is_empty(current_read)) {
2358 log_debug("TPM2 refused to read possibly unimplemented PCRs, ignoring.");
2359 break;
2360 }
2361
2362 unsigned i = 0;
2363 FOREACH_PCR_IN_TPML_PCR_SELECTION(index, tpms, current_read) {
2364 assert(i < current_values->count);
2365 Tpm2PCRValue pcr_value = {
2366 .index = index,
2367 .hash = tpms->hash,
2368 .value = current_values->digests[i++],
2369 };
2370
2371 tpm2_log_debug_pcr_value(&pcr_value, /* msg= */ NULL);
2372
2373 if (!GREEDY_REALLOC_APPEND(pcr_values, n_pcr_values, &pcr_value, 1))
2374 return log_oom_debug();
2375 }
2376 assert(i == current_values->count);
2377
2378 tpm2_tpml_pcr_selection_sub(&remaining, current_read);
2379 }
2380
2381 tpm2_sort_pcr_values(pcr_values, n_pcr_values);
2382
2383 if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values))
2384 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PCR values read from TPM are not valid.");
2385
2386 *ret_pcr_values = TAKE_PTR(pcr_values);
2387 *ret_n_pcr_values = n_pcr_values;
2388
2389 return 0;
2390 }
2391
2392 /* Read the PCR value for each TPM2PCRValue entry in the array that does not have a value set. If all entries
2393 * have an unset hash (i.e. hash == 0), this first detects the "best" PCR bank to use; otherwise, all entries
2394 * must have a valid hash set. All entries must have a valid index. If this cannot read a PCR value for all
2395 * appropriate entries, this returns an error. This does not check the array for validity. */
2396 int tpm2_pcr_read_missing_values(Tpm2Context *c, Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
2397 TPMI_ALG_HASH pcr_bank = 0;
2398 int r;
2399
2400 assert(c);
2401 assert(pcr_values || n_pcr_values == 0);
2402
2403 if (n_pcr_values > 0) {
2404 size_t hash_count;
2405 r = tpm2_pcr_values_hash_count(pcr_values, n_pcr_values, &hash_count);
2406 if (r < 0)
2407 return log_debug_errno(r, "Could not get hash count from pcr values: %m");
2408
2409 if (hash_count == 1 && pcr_values[0].hash == 0) {
2410 uint32_t mask;
2411 r = tpm2_pcr_values_to_mask(pcr_values, n_pcr_values, 0, &mask);
2412 if (r < 0)
2413 return r;
2414
2415 r = tpm2_get_best_pcr_bank(c, mask, &pcr_bank);
2416 if (r < 0)
2417 return r;
2418 }
2419 }
2420
2421 FOREACH_ARRAY(v, pcr_values, n_pcr_values) {
2422 if (v->hash == 0)
2423 v->hash = pcr_bank;
2424
2425 if (v->value.size > 0)
2426 continue;
2427
2428 TPML_PCR_SELECTION selection;
2429 r = tpm2_tpml_pcr_selection_from_pcr_values(v, 1, &selection, NULL, NULL);
2430 if (r < 0)
2431 return r;
2432
2433 _cleanup_free_ Tpm2PCRValue *read_values = NULL;
2434 size_t n_read_values;
2435 r = tpm2_pcr_read(c, &selection, &read_values, &n_read_values);
2436 if (r < 0)
2437 return r;
2438
2439 if (n_read_values == 0)
2440 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2441 "Could not read PCR hash 0x%" PRIu16 " index %u",
2442 v->hash, v->index);
2443
2444 assert(n_read_values == 1);
2445 assert(read_values[0].hash == v->hash);
2446 assert(read_values[0].index == v->index);
2447
2448 v->value = read_values[0].value;
2449 }
2450
2451 return 0;
2452 }
2453
2454 static int tpm2_pcr_mask_good(
2455 Tpm2Context *c,
2456 TPMI_ALG_HASH bank,
2457 uint32_t mask) {
2458
2459 TPML_PCR_SELECTION selection;
2460 int r;
2461
2462 assert(c);
2463
2464 /* So we have the problem that some systems might have working TPM2 chips, but the firmware doesn't
2465 * actually measure into them, or only into a suboptimal bank. If so, the PCRs should be all zero or
2466 * all 0xFF. Detect that, so that we can warn and maybe pick a better bank. */
2467
2468 tpm2_tpml_pcr_selection_from_mask(mask, bank, &selection);
2469
2470 _cleanup_free_ Tpm2PCRValue *pcr_values = NULL;
2471 size_t n_pcr_values;
2472 r = tpm2_pcr_read(c, &selection, &pcr_values, &n_pcr_values);
2473 if (r < 0)
2474 return r;
2475
2476 /* If at least one of the selected PCR values is something other than all 0x00 or all 0xFF we are happy. */
2477 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
2478 if (!memeqbyte(0x00, v->value.buffer, v->value.size) &&
2479 !memeqbyte(0xFF, v->value.buffer, v->value.size))
2480 return true;
2481
2482 return false;
2483 }
2484
2485 static int tpm2_bank_has24(const TPMS_PCR_SELECTION *selection) {
2486
2487 assert(selection);
2488
2489 /* As per https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_PFP_r1p05_v23_pub.pdf a
2490 * TPM2 on a Client PC must have at least 24 PCRs. If this TPM has less, just skip over it. */
2491 if (selection->sizeofSelect < TPM2_PCRS_MAX/8) {
2492 log_debug("Skipping TPM2 PCR bank %s with fewer than 24 PCRs.",
2493 strna(tpm2_hash_alg_to_string(selection->hash)));
2494 return false;
2495 }
2496
2497 assert_cc(TPM2_PCRS_MAX % 8 == 0);
2498
2499 /* It's not enough to check how many PCRs there are, we also need to check that the 24 are
2500 * enabled for this bank. Otherwise this TPM doesn't qualify. */
2501 bool valid = true;
2502 for (size_t j = 0; j < TPM2_PCRS_MAX/8; j++)
2503 if (selection->pcrSelect[j] != 0xFF) {
2504 valid = false;
2505 break;
2506 }
2507
2508 if (!valid)
2509 log_debug("TPM2 PCR bank %s has fewer than 24 PCR bits enabled, ignoring.",
2510 strna(tpm2_hash_alg_to_string(selection->hash)));
2511
2512 return valid;
2513 }
2514
2515 int tpm2_get_best_pcr_bank(
2516 Tpm2Context *c,
2517 uint32_t pcr_mask,
2518 TPMI_ALG_HASH *ret) {
2519
2520 TPMI_ALG_HASH supported_hash = 0, hash_with_valid_pcr = 0;
2521 int r;
2522
2523 assert(c);
2524 assert(ret);
2525
2526 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection, &c->capability_pcrs) {
2527 TPMI_ALG_HASH hash = selection->hash;
2528 int good;
2529
2530 /* For now we are only interested in the SHA1 and SHA256 banks */
2531 if (!IN_SET(hash, TPM2_ALG_SHA256, TPM2_ALG_SHA1))
2532 continue;
2533
2534 r = tpm2_bank_has24(selection);
2535 if (r < 0)
2536 return r;
2537 if (!r)
2538 continue;
2539
2540 good = tpm2_pcr_mask_good(c, hash, pcr_mask);
2541 if (good < 0)
2542 return good;
2543
2544 if (hash == TPM2_ALG_SHA256) {
2545 supported_hash = TPM2_ALG_SHA256;
2546 if (good) {
2547 /* Great, SHA256 is supported and has initialized PCR values, we are done. */
2548 hash_with_valid_pcr = TPM2_ALG_SHA256;
2549 break;
2550 }
2551 } else {
2552 assert(hash == TPM2_ALG_SHA1);
2553
2554 if (supported_hash == 0)
2555 supported_hash = TPM2_ALG_SHA1;
2556
2557 if (good && hash_with_valid_pcr == 0)
2558 hash_with_valid_pcr = TPM2_ALG_SHA1;
2559 }
2560 }
2561
2562 /* We preferably pick SHA256, but only if its PCRs are initialized or neither the SHA1 nor the SHA256
2563 * PCRs are initialized. If SHA256 is not supported but SHA1 is and its PCRs are too, we prefer
2564 * SHA1.
2565 *
2566 * We log at LOG_NOTICE level whenever we end up using the SHA1 bank or when the PCRs we bind to are
2567 * not initialized. */
2568
2569 if (hash_with_valid_pcr == TPM2_ALG_SHA256) {
2570 assert(supported_hash == TPM2_ALG_SHA256);
2571 log_debug("TPM2 device supports SHA256 PCR bank and SHA256 PCRs are valid, yay!");
2572 *ret = TPM2_ALG_SHA256;
2573 } else if (hash_with_valid_pcr == TPM2_ALG_SHA1) {
2574 if (supported_hash == TPM2_ALG_SHA256)
2575 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.");
2576 else {
2577 assert(supported_hash == TPM2_ALG_SHA1);
2578 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.");
2579 }
2580
2581 *ret = TPM2_ALG_SHA1;
2582 } else if (supported_hash == TPM2_ALG_SHA256) {
2583 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!");
2584 *ret = TPM2_ALG_SHA256;
2585 } else if (supported_hash == TPM2_ALG_SHA1) {
2586 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!");
2587 *ret = TPM2_ALG_SHA1;
2588 } else
2589 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
2590 "TPM2 module supports neither SHA1 nor SHA256 PCR banks, cannot operate.");
2591
2592 return 0;
2593 }
2594
2595 int tpm2_get_good_pcr_banks(
2596 Tpm2Context *c,
2597 uint32_t pcr_mask,
2598 TPMI_ALG_HASH **ret) {
2599
2600 _cleanup_free_ TPMI_ALG_HASH *good_banks = NULL, *fallback_banks = NULL;
2601 size_t n_good_banks = 0, n_fallback_banks = 0;
2602 int r;
2603
2604 assert(c);
2605 assert(ret);
2606
2607 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection, &c->capability_pcrs) {
2608 TPMI_ALG_HASH hash = selection->hash;
2609
2610 /* Let's see if this bank is superficially OK, i.e. has at least 24 enabled registers */
2611 r = tpm2_bank_has24(selection);
2612 if (r < 0)
2613 return r;
2614 if (!r)
2615 continue;
2616
2617 /* Let's now see if this bank has any of the selected PCRs actually initialized */
2618 r = tpm2_pcr_mask_good(c, hash, pcr_mask);
2619 if (r < 0)
2620 return r;
2621
2622 if (n_good_banks + n_fallback_banks >= INT_MAX)
2623 return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "Too many good TPM2 banks?");
2624
2625 if (r) {
2626 if (!GREEDY_REALLOC(good_banks, n_good_banks+1))
2627 return log_oom_debug();
2628
2629 good_banks[n_good_banks++] = hash;
2630 } else {
2631 if (!GREEDY_REALLOC(fallback_banks, n_fallback_banks+1))
2632 return log_oom_debug();
2633
2634 fallback_banks[n_fallback_banks++] = hash;
2635 }
2636 }
2637
2638 /* Preferably, use the good banks (i.e. the ones the PCR values are actually initialized so
2639 * far). Otherwise use the fallback banks (i.e. which exist and are enabled, but so far not used. */
2640 if (n_good_banks > 0) {
2641 log_debug("Found %zu fully initialized TPM2 banks.", n_good_banks);
2642 *ret = TAKE_PTR(good_banks);
2643 return (int) n_good_banks;
2644 }
2645 if (n_fallback_banks > 0) {
2646 log_debug("Found %zu enabled but un-initialized TPM2 banks.", n_fallback_banks);
2647 *ret = TAKE_PTR(fallback_banks);
2648 return (int) n_fallback_banks;
2649 }
2650
2651 /* No suitable banks found. */
2652 *ret = NULL;
2653 return 0;
2654 }
2655
2656 int tpm2_get_good_pcr_banks_strv(
2657 Tpm2Context *c,
2658 uint32_t pcr_mask,
2659 char ***ret) {
2660
2661 #if HAVE_OPENSSL
2662 _cleanup_free_ TPMI_ALG_HASH *algs = NULL;
2663 _cleanup_strv_free_ char **l = NULL;
2664 int n_algs;
2665
2666 assert(c);
2667 assert(ret);
2668
2669 n_algs = tpm2_get_good_pcr_banks(c, pcr_mask, &algs);
2670 if (n_algs < 0)
2671 return n_algs;
2672
2673 FOREACH_ARRAY(a, algs, n_algs) {
2674 _cleanup_free_ char *n = NULL;
2675 const EVP_MD *implementation;
2676 const char *salg;
2677
2678 salg = tpm2_hash_alg_to_string(*a);
2679 if (!salg)
2680 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unknown PCR algorithm, can't measure.");
2681
2682 implementation = EVP_get_digestbyname(salg);
2683 if (!implementation)
2684 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unsupported PCR algorithm, can't measure.");
2685
2686 n = strdup(ASSERT_PTR(EVP_MD_name(implementation)));
2687 if (!n)
2688 return log_oom_debug();
2689
2690 ascii_strlower(n); /* OpenSSL uses uppercase digest names, we prefer them lower case. */
2691
2692 if (strv_consume(&l, TAKE_PTR(n)) < 0)
2693 return log_oom_debug();
2694 }
2695
2696 *ret = TAKE_PTR(l);
2697 return 0;
2698 #else /* HAVE_OPENSSL */
2699 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
2700 #endif
2701 }
2702
2703 /* Hash data into the digest.
2704 *
2705 * If 'extend' is true, the hashing operation starts with the existing digest hash (and the digest is
2706 * required to have a hash and its size must be correct). If 'extend' is false, the digest size is
2707 * initialized to the correct size for 'alg' and the hashing operation does not include any existing digest
2708 * hash. If 'extend' is false and no data is provided, the digest is initialized to a zero digest.
2709 *
2710 * On success, the digest hash will be updated with the hashing operation result and the digest size will be
2711 * correct for 'alg'.
2712 *
2713 * This currently only provides SHA256, so 'alg' must be TPM2_ALG_SHA256. */
2714 int tpm2_digest_many(
2715 TPMI_ALG_HASH alg,
2716 TPM2B_DIGEST *digest,
2717 const struct iovec data[],
2718 size_t n_data,
2719 bool extend) {
2720
2721 struct sha256_ctx ctx;
2722
2723 assert(digest);
2724 assert(data || n_data == 0);
2725
2726 if (alg != TPM2_ALG_SHA256)
2727 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
2728 "Hash algorithm not supported: 0x%x", alg);
2729
2730 if (extend && digest->size != SHA256_DIGEST_SIZE)
2731 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
2732 "Digest size 0x%x, require 0x%x",
2733 digest->size, (unsigned)SHA256_DIGEST_SIZE);
2734
2735 /* Since we're hardcoding SHA256 (for now), we can check this at compile time. */
2736 assert_cc(sizeof(digest->buffer) >= SHA256_DIGEST_SIZE);
2737
2738 CLEANUP_ERASE(ctx);
2739
2740 sha256_init_ctx(&ctx);
2741
2742 if (extend)
2743 sha256_process_bytes(digest->buffer, digest->size, &ctx);
2744 else {
2745 *digest = (TPM2B_DIGEST){ .size = SHA256_DIGEST_SIZE, };
2746 if (n_data == 0) /* If not extending and no data, return zero hash */
2747 return 0;
2748 }
2749
2750 FOREACH_ARRAY(d, data, n_data)
2751 sha256_process_bytes(d->iov_base, d->iov_len, &ctx);
2752
2753 sha256_finish_ctx(&ctx, digest->buffer);
2754
2755 return 0;
2756 }
2757
2758 /* Same as tpm2_digest_many() but data is contained in TPM2B_DIGEST[]. The digests may be any size digests. */
2759 int tpm2_digest_many_digests(
2760 TPMI_ALG_HASH alg,
2761 TPM2B_DIGEST *digest,
2762 const TPM2B_DIGEST data[],
2763 size_t n_data,
2764 bool extend) {
2765
2766 _cleanup_free_ struct iovec *iovecs = NULL;
2767
2768 assert(data || n_data == 0);
2769
2770 iovecs = new(struct iovec, n_data);
2771 if (!iovecs)
2772 return log_oom_debug();
2773
2774 for (size_t i = 0; i < n_data; i++)
2775 iovecs[i] = IOVEC_MAKE((void*) data[i].buffer, data[i].size);
2776
2777 return tpm2_digest_many(alg, digest, iovecs, n_data, extend);
2778 }
2779
2780 /* This hashes the provided pin into a digest value, but also verifies that the final byte is not 0, because
2781 * the TPM specification Part 1 ("Architecture") section Authorization Values (subsection "Authorization Size
2782 * Convention") states "Trailing octets of zero are to be removed from any string before it is used as an
2783 * authValue". Since the TPM doesn't know if the auth value is a "string" or just a hash digest, any hash
2784 * digest that randomly happens to end in 0 must have the final 0(s) trimmed.
2785 *
2786 * This is required at 2 points. First, when setting the authValue during creation of new sealed objects, in
2787 * tpm2_seal(). This only applies to newly created objects, of course. Second, when using a previously
2788 * created sealed object that has an authValue set, we use the sealed objects as the session bind key. This
2789 * requires calling SetAuth so tpm2-tss can correctly calculate the HMAC to use for the encryption session.
2790 *
2791 * TPM implementations will perform the trimming for any authValue for existing sealed objects, so the
2792 * tpm2-tss library must also perform the trimming before HMAC calculation, but it does not yet; this bug is
2793 * open to add the trimming: https://github.com/tpm2-software/tpm2-tss/issues/2664
2794 *
2795 * Until our minimum tpm2-tss version contains a fix for that bug, we must perform the trimming
2796 * ourselves. Note that since we are trimming, which is exactly what a TPM implementation would do, this will
2797 * work for both existing objects with a authValue ending in 0(s) as well as new sealed objects we create,
2798 * which we will trim the 0(s) from before sending to the TPM.
2799 */
2800 static void tpm2_trim_auth_value(TPM2B_AUTH *auth) {
2801 bool trimmed = false;
2802
2803 assert(auth);
2804
2805 while (auth->size > 0 && auth->buffer[auth->size - 1] == 0) {
2806 trimmed = true;
2807 auth->size--;
2808 }
2809
2810 if (trimmed)
2811 log_debug("authValue ends in 0, trimming as required by the TPM2 specification Part 1 section 'HMAC Computation' authValue Note 2.");
2812 }
2813
2814 static int tpm2_get_pin_auth(TPMI_ALG_HASH hash, const char *pin, TPM2B_AUTH *ret_auth) {
2815 TPM2B_AUTH auth = {};
2816 int r;
2817
2818 assert(pin);
2819 assert(ret_auth);
2820
2821 r = tpm2_digest_buffer(hash, &auth, pin, strlen(pin), /* extend= */ false);
2822 if (r < 0)
2823 return r;
2824
2825 tpm2_trim_auth_value(&auth);
2826
2827 *ret_auth = TAKE_STRUCT(auth);
2828
2829 return 0;
2830 }
2831
2832 static int tpm2_set_auth(Tpm2Context *c, const Tpm2Handle *handle, const char *pin) {
2833 TPM2B_AUTH auth = {};
2834 TSS2_RC rc;
2835 int r;
2836
2837 assert(c);
2838 assert(handle);
2839
2840 if (!pin)
2841 return 0;
2842
2843 CLEANUP_ERASE(auth);
2844
2845 r = tpm2_get_pin_auth(TPM2_ALG_SHA256, pin, &auth);
2846 if (r < 0)
2847 return r;
2848
2849 rc = sym_Esys_TR_SetAuth(c->esys_context, handle->esys_handle, &auth);
2850 if (rc != TSS2_RC_SUCCESS)
2851 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2852 "Failed to load PIN in TPM: %s", sym_Tss2_RC_Decode(rc));
2853
2854 return 0;
2855 }
2856
2857 static bool tpm2_is_encryption_session(Tpm2Context *c, const Tpm2Handle *session) {
2858 TPMA_SESSION flags = 0;
2859 TSS2_RC rc;
2860
2861 assert(c);
2862 assert(session);
2863
2864 rc = sym_Esys_TRSess_GetAttributes(c->esys_context, session->esys_handle, &flags);
2865 if (rc != TSS2_RC_SUCCESS)
2866 return false;
2867
2868 return (flags & TPMA_SESSION_DECRYPT) && (flags & TPMA_SESSION_ENCRYPT);
2869 }
2870
2871 static int tpm2_make_encryption_session(
2872 Tpm2Context *c,
2873 const Tpm2Handle *primary,
2874 const Tpm2Handle *bind_key,
2875 Tpm2Handle **ret_session) {
2876
2877 const TPMA_SESSION sessionAttributes = TPMA_SESSION_DECRYPT | TPMA_SESSION_ENCRYPT |
2878 TPMA_SESSION_CONTINUESESSION;
2879 TSS2_RC rc;
2880 int r;
2881
2882 assert(c);
2883 assert(primary);
2884 assert(ret_session);
2885
2886 log_debug("Starting HMAC encryption session.");
2887
2888 /* Start a salted, unbound HMAC session with a well-known key (e.g. primary key) as tpmKey, which
2889 * means that the random salt will be encrypted with the well-known key. That way, only the TPM can
2890 * recover the salt, which is then used for key derivation. */
2891 _cleanup_(tpm2_handle_freep) Tpm2Handle *session = NULL;
2892 r = tpm2_handle_new(c, &session);
2893 if (r < 0)
2894 return r;
2895
2896 rc = sym_Esys_StartAuthSession(
2897 c->esys_context,
2898 primary->esys_handle,
2899 bind_key ? bind_key->esys_handle : ESYS_TR_NONE,
2900 ESYS_TR_NONE,
2901 ESYS_TR_NONE,
2902 ESYS_TR_NONE,
2903 NULL,
2904 TPM2_SE_HMAC,
2905 &SESSION_TEMPLATE_SYM_AES_128_CFB,
2906 TPM2_ALG_SHA256,
2907 &session->esys_handle);
2908 if (rc != TSS2_RC_SUCCESS)
2909 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2910 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc));
2911
2912 /* Enable parameter encryption/decryption with AES in CFB mode. Together with HMAC digests (which are
2913 * always used for sessions), this provides confidentiality, integrity and replay protection for
2914 * operations that use this session. */
2915 rc = sym_Esys_TRSess_SetAttributes(c->esys_context, session->esys_handle, sessionAttributes, 0xff);
2916 if (rc != TSS2_RC_SUCCESS)
2917 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2918 "Failed to configure TPM session: %s", sym_Tss2_RC_Decode(rc));
2919
2920 *ret_session = TAKE_PTR(session);
2921
2922 return 0;
2923 }
2924
2925 static int tpm2_make_policy_session(
2926 Tpm2Context *c,
2927 const Tpm2Handle *primary,
2928 const Tpm2Handle *encryption_session,
2929 Tpm2Handle **ret_session) {
2930
2931 TSS2_RC rc;
2932 int r;
2933
2934 assert(c);
2935 assert(primary);
2936 assert(encryption_session);
2937 assert(ret_session);
2938
2939 if (!tpm2_is_encryption_session(c, encryption_session))
2940 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
2941 "Missing encryption session");
2942
2943 log_debug("Starting policy session.");
2944
2945 _cleanup_(tpm2_handle_freep) Tpm2Handle *session = NULL;
2946 r = tpm2_handle_new(c, &session);
2947 if (r < 0)
2948 return r;
2949
2950 rc = sym_Esys_StartAuthSession(
2951 c->esys_context,
2952 primary->esys_handle,
2953 ESYS_TR_NONE,
2954 encryption_session->esys_handle,
2955 ESYS_TR_NONE,
2956 ESYS_TR_NONE,
2957 NULL,
2958 TPM2_SE_POLICY,
2959 &SESSION_TEMPLATE_SYM_AES_128_CFB,
2960 TPM2_ALG_SHA256,
2961 &session->esys_handle);
2962 if (rc != TSS2_RC_SUCCESS)
2963 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2964 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc));
2965
2966 *ret_session = TAKE_PTR(session);
2967
2968 return 0;
2969 }
2970
2971 static int find_signature(
2972 JsonVariant *v,
2973 const TPML_PCR_SELECTION *pcr_selection,
2974 const void *fp,
2975 size_t fp_size,
2976 const void *policy,
2977 size_t policy_size,
2978 void *ret_signature,
2979 size_t *ret_signature_size) {
2980
2981 #if HAVE_OPENSSL
2982 JsonVariant *b, *i;
2983 const char *k;
2984 int r;
2985
2986 /* Searches for a signature blob in the specified JSON object. Search keys are PCR bank, PCR mask,
2987 * public key, and policy digest. */
2988
2989 if (!json_variant_is_object(v))
2990 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Signature is not a JSON object.");
2991
2992 uint16_t pcr_bank = pcr_selection->pcrSelections[0].hash;
2993 uint32_t pcr_mask = tpm2_tpml_pcr_selection_to_mask(pcr_selection, pcr_bank);
2994
2995 k = tpm2_hash_alg_to_string(pcr_bank);
2996 if (!k)
2997 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Don't know PCR bank %" PRIu16, pcr_bank);
2998
2999 /* First, find field by bank */
3000 b = json_variant_by_key(v, k);
3001 if (!b)
3002 return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Signature lacks data for PCR bank '%s'.", k);
3003
3004 if (!json_variant_is_array(b))
3005 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Bank data is not a JSON array.");
3006
3007 /* Now iterate through all signatures known for this bank */
3008 JSON_VARIANT_ARRAY_FOREACH(i, b) {
3009 _cleanup_free_ void *fpj_data = NULL, *polj_data = NULL;
3010 JsonVariant *maskj, *fpj, *sigj, *polj;
3011 size_t fpj_size, polj_size;
3012 uint32_t parsed_mask;
3013
3014 if (!json_variant_is_object(i))
3015 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Bank data element is not a JSON object");
3016
3017 /* Check if the PCR mask matches our expectations */
3018 maskj = json_variant_by_key(i, "pcrs");
3019 if (!maskj)
3020 continue;
3021
3022 r = tpm2_parse_pcr_json_array(maskj, &parsed_mask);
3023 if (r < 0)
3024 return log_debug_errno(r, "Failed to parse JSON PCR mask");
3025
3026 if (parsed_mask != pcr_mask)
3027 continue; /* Not for this PCR mask */
3028
3029 /* Then check if this is for the public key we operate with */
3030 fpj = json_variant_by_key(i, "pkfp");
3031 if (!fpj)
3032 continue;
3033
3034 r = json_variant_unhex(fpj, &fpj_data, &fpj_size);
3035 if (r < 0)
3036 return log_debug_errno(r, "Failed to decode fingerprint in JSON data: %m");
3037
3038 if (memcmp_nn(fp, fp_size, fpj_data, fpj_size) != 0)
3039 continue; /* Not for this public key */
3040
3041 /* Finally, check if this is for the PCR policy we expect this to be */
3042 polj = json_variant_by_key(i, "pol");
3043 if (!polj)
3044 continue;
3045
3046 r = json_variant_unhex(polj, &polj_data, &polj_size);
3047 if (r < 0)
3048 return log_debug_errno(r, "Failed to decode policy hash JSON data: %m");
3049
3050 if (memcmp_nn(policy, policy_size, polj_data, polj_size) != 0)
3051 continue;
3052
3053 /* This entry matches all our expectations, now return the signature included in it */
3054 sigj = json_variant_by_key(i, "sig");
3055 if (!sigj)
3056 continue;
3057
3058 return json_variant_unbase64(sigj, ret_signature, ret_signature_size);
3059 }
3060
3061 return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Couldn't find signature for this PCR bank, PCR index and public key.");
3062 #else /* HAVE_OPENSSL */
3063 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
3064 #endif
3065 }
3066
3067 /* Calculates the "name" of a public key.
3068 *
3069 * As specified in TPM2 spec "Part 1: Architecture", a key's "name" is its nameAlg value followed by a hash
3070 * of its TPM2 public area, all properly marshalled. This allows a key's "name" to be dependent not only on
3071 * the key fingerprint, but also on the TPM2-specific fields that associated with the key (i.e. all fields in
3072 * TPMT_PUBLIC). Note that this means an existing key may not change any of its TPMT_PUBLIC fields, since
3073 * that would also change the key name.
3074 *
3075 * Since we (currently) hardcode to always using SHA256 for hashing, this returns an error if the public key
3076 * nameAlg is not TPM2_ALG_SHA256. */
3077 int tpm2_calculate_name(const TPMT_PUBLIC *public, TPM2B_NAME *ret_name) {
3078 TSS2_RC rc;
3079 int r;
3080
3081 assert(public);
3082 assert(ret_name);
3083
3084 r = dlopen_tpm2();
3085 if (r < 0)
3086 return log_debug_errno(r, "TPM2 support not installed: %m");
3087
3088 if (public->nameAlg != TPM2_ALG_SHA256)
3089 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
3090 "Unsupported nameAlg: 0x%x",
3091 public->nameAlg);
3092
3093 _cleanup_free_ uint8_t *buf = NULL;
3094 size_t size = 0;
3095
3096 buf = (uint8_t*) new(TPMT_PUBLIC, 1);
3097 if (!buf)
3098 return log_oom_debug();
3099
3100 rc = sym_Tss2_MU_TPMT_PUBLIC_Marshal(public, buf, sizeof(TPMT_PUBLIC), &size);
3101 if (rc != TSS2_RC_SUCCESS)
3102 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3103 "Failed to marshal public key: %s", sym_Tss2_RC_Decode(rc));
3104
3105 TPM2B_DIGEST digest = {};
3106 r = tpm2_digest_buffer(TPM2_ALG_SHA256, &digest, buf, size, /* extend= */ false);
3107 if (r < 0)
3108 return r;
3109
3110 TPMT_HA ha = {
3111 .hashAlg = TPM2_ALG_SHA256,
3112 };
3113 assert(digest.size <= sizeof(ha.digest.sha256));
3114 memcpy_safe(ha.digest.sha256, digest.buffer, digest.size);
3115
3116 TPM2B_NAME name;
3117 size = 0;
3118 rc = sym_Tss2_MU_TPMT_HA_Marshal(&ha, name.name, sizeof(name.name), &size);
3119 if (rc != TSS2_RC_SUCCESS)
3120 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3121 "Failed to marshal key name: %s", sym_Tss2_RC_Decode(rc));
3122 name.size = size;
3123
3124 tpm2_log_debug_name(&name, "Calculated name");
3125
3126 *ret_name = name;
3127
3128 return 0;
3129 }
3130
3131 /* Get the "name" of a key from the TPM.
3132 *
3133 * The "name" of a key is explained above in tpm2_calculate_name().
3134 *
3135 * The handle must reference a key already present in the TPM. It may be either a public key only, or a
3136 * public/private keypair. */
3137 static int tpm2_get_name(
3138 Tpm2Context *c,
3139 const Tpm2Handle *handle,
3140 TPM2B_NAME **ret_name) {
3141
3142 _cleanup_(Esys_Freep) TPM2B_NAME *name = NULL;
3143 TSS2_RC rc;
3144
3145 assert(c);
3146 assert(handle);
3147 assert(ret_name);
3148
3149 rc = sym_Esys_TR_GetName(c->esys_context, handle->esys_handle, &name);
3150 if (rc != TSS2_RC_SUCCESS)
3151 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3152 "Failed to get name of public key from TPM: %s", sym_Tss2_RC_Decode(rc));
3153
3154 tpm2_log_debug_name(name, "Object name");
3155
3156 *ret_name = TAKE_PTR(name);
3157
3158 return 0;
3159 }
3160
3161 /* Extend 'digest' with the PolicyAuthValue calculated hash. */
3162 int tpm2_calculate_policy_auth_value(TPM2B_DIGEST *digest) {
3163 TPM2_CC command = TPM2_CC_PolicyAuthValue;
3164 TSS2_RC rc;
3165 int r;
3166
3167 assert(digest);
3168 assert(digest->size == SHA256_DIGEST_SIZE);
3169
3170 r = dlopen_tpm2();
3171 if (r < 0)
3172 return log_debug_errno(r, "TPM2 support not installed: %m");
3173
3174 uint8_t buf[sizeof(command)];
3175 size_t offset = 0;
3176
3177 rc = sym_Tss2_MU_TPM2_CC_Marshal(command, buf, sizeof(buf), &offset);
3178 if (rc != TSS2_RC_SUCCESS)
3179 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3180 "Failed to marshal PolicyAuthValue command: %s", sym_Tss2_RC_Decode(rc));
3181
3182 if (offset != sizeof(command))
3183 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3184 "Offset 0x%zx wrong after marshalling PolicyAuthValue command", offset);
3185
3186 r = tpm2_digest_buffer(TPM2_ALG_SHA256, digest, buf, offset, /* extend= */ true);
3187 if (r < 0)
3188 return r;
3189
3190 tpm2_log_debug_digest(digest, "PolicyAuthValue calculated digest");
3191
3192 return 0;
3193 }
3194
3195 static int tpm2_policy_auth_value(
3196 Tpm2Context *c,
3197 const Tpm2Handle *session,
3198 TPM2B_DIGEST **ret_policy_digest) {
3199
3200 TSS2_RC rc;
3201
3202 assert(c);
3203 assert(session);
3204
3205 log_debug("Adding authValue policy.");
3206
3207 rc = sym_Esys_PolicyAuthValue(
3208 c->esys_context,
3209 session->esys_handle,
3210 ESYS_TR_NONE,
3211 ESYS_TR_NONE,
3212 ESYS_TR_NONE);
3213 if (rc != TSS2_RC_SUCCESS)
3214 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3215 "Failed to add authValue policy to TPM: %s",
3216 sym_Tss2_RC_Decode(rc));
3217
3218 return tpm2_get_policy_digest(c, session, ret_policy_digest);
3219 }
3220
3221 /* Extend 'digest' with the PolicyPCR calculated hash. */
3222 int tpm2_calculate_policy_pcr(
3223 const Tpm2PCRValue *pcr_values,
3224 size_t n_pcr_values,
3225 TPM2B_DIGEST *digest) {
3226
3227 TPM2_CC command = TPM2_CC_PolicyPCR;
3228 TSS2_RC rc;
3229 int r;
3230
3231 assert(pcr_values || n_pcr_values == 0);
3232 assert(digest);
3233 assert(digest->size == SHA256_DIGEST_SIZE);
3234
3235 r = dlopen_tpm2();
3236 if (r < 0)
3237 return log_debug_errno(r, "TPM2 support not installed: %m");
3238
3239 TPML_PCR_SELECTION pcr_selection;
3240 _cleanup_free_ TPM2B_DIGEST *values = NULL;
3241 size_t n_values;
3242 r = tpm2_tpml_pcr_selection_from_pcr_values(pcr_values, n_pcr_values, &pcr_selection, &values, &n_values);
3243 if (r < 0)
3244 return log_debug_errno(r, "Could not convert PCR values to TPML_PCR_SELECTION: %m");
3245
3246 TPM2B_DIGEST hash = {};
3247 r = tpm2_digest_many_digests(TPM2_ALG_SHA256, &hash, values, n_values, /* extend= */ false);
3248 if (r < 0)
3249 return r;
3250
3251 _cleanup_free_ uint8_t *buf = NULL;
3252 size_t size = 0, maxsize = sizeof(command) + sizeof(pcr_selection);
3253
3254 buf = malloc(maxsize);
3255 if (!buf)
3256 return log_oom_debug();
3257
3258 rc = sym_Tss2_MU_TPM2_CC_Marshal(command, buf, maxsize, &size);
3259 if (rc != TSS2_RC_SUCCESS)
3260 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3261 "Failed to marshal PolicyPCR command: %s", sym_Tss2_RC_Decode(rc));
3262
3263 rc = sym_Tss2_MU_TPML_PCR_SELECTION_Marshal(&pcr_selection, buf, maxsize, &size);
3264 if (rc != TSS2_RC_SUCCESS)
3265 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3266 "Failed to marshal PCR selection: %s", sym_Tss2_RC_Decode(rc));
3267
3268 struct iovec data[] = {
3269 IOVEC_MAKE(buf, size),
3270 IOVEC_MAKE(hash.buffer, hash.size),
3271 };
3272 r = tpm2_digest_many(TPM2_ALG_SHA256, digest, data, ELEMENTSOF(data), /* extend= */ true);
3273 if (r < 0)
3274 return r;
3275
3276 tpm2_log_debug_digest(digest, "PolicyPCR calculated digest");
3277
3278 return 0;
3279 }
3280
3281 static int tpm2_policy_pcr(
3282 Tpm2Context *c,
3283 const Tpm2Handle *session,
3284 const TPML_PCR_SELECTION *pcr_selection,
3285 TPM2B_DIGEST **ret_policy_digest) {
3286
3287 TSS2_RC rc;
3288
3289 assert(c);
3290 assert(session);
3291 assert(pcr_selection);
3292
3293 log_debug("Adding PCR hash policy.");
3294
3295 rc = sym_Esys_PolicyPCR(
3296 c->esys_context,
3297 session->esys_handle,
3298 ESYS_TR_NONE,
3299 ESYS_TR_NONE,
3300 ESYS_TR_NONE,
3301 NULL,
3302 pcr_selection);
3303 if (rc != TSS2_RC_SUCCESS)
3304 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3305 "Failed to add PCR policy to TPM: %s", sym_Tss2_RC_Decode(rc));
3306
3307 return tpm2_get_policy_digest(c, session, ret_policy_digest);
3308 }
3309
3310 /* Extend 'digest' with the PolicyAuthorize calculated hash. */
3311 int tpm2_calculate_policy_authorize(
3312 const TPM2B_PUBLIC *public,
3313 const TPM2B_DIGEST *policy_ref,
3314 TPM2B_DIGEST *digest) {
3315
3316 TPM2_CC command = TPM2_CC_PolicyAuthorize;
3317 TSS2_RC rc;
3318 int r;
3319
3320 assert(public);
3321 assert(digest);
3322 assert(digest->size == SHA256_DIGEST_SIZE);
3323
3324 r = dlopen_tpm2();
3325 if (r < 0)
3326 return log_debug_errno(r, "TPM2 support not installed: %m");
3327
3328 uint8_t buf[sizeof(command)];
3329 size_t offset = 0;
3330
3331 rc = sym_Tss2_MU_TPM2_CC_Marshal(command, buf, sizeof(buf), &offset);
3332 if (rc != TSS2_RC_SUCCESS)
3333 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3334 "Failed to marshal PolicyAuthorize command: %s", sym_Tss2_RC_Decode(rc));
3335
3336 if (offset != sizeof(command))
3337 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3338 "Offset 0x%zx wrong after marshalling PolicyAuthorize command", offset);
3339
3340 TPM2B_NAME name = {};
3341 r = tpm2_calculate_name(&public->publicArea, &name);
3342 if (r < 0)
3343 return r;
3344
3345 /* PolicyAuthorize does not use the previous hash value; we must zero and then extend it. */
3346 zero(digest->buffer);
3347
3348 struct iovec data[] = {
3349 IOVEC_MAKE(buf, offset),
3350 IOVEC_MAKE(name.name, name.size),
3351 };
3352 r = tpm2_digest_many(TPM2_ALG_SHA256, digest, data, ELEMENTSOF(data), /* extend= */ true);
3353 if (r < 0)
3354 return r;
3355
3356 /* PolicyAuthorize requires hashing twice; this is either an extension or rehashing. */
3357 if (policy_ref)
3358 r = tpm2_digest_many_digests(TPM2_ALG_SHA256, digest, policy_ref, 1, /* extend= */ true);
3359 else
3360 r = tpm2_digest_rehash(TPM2_ALG_SHA256, digest);
3361 if (r < 0)
3362 return r;
3363
3364 tpm2_log_debug_digest(digest, "PolicyAuthorize calculated digest");
3365
3366 return 0;
3367 }
3368
3369 static int tpm2_policy_authorize(
3370 Tpm2Context *c,
3371 const Tpm2Handle *session,
3372 TPML_PCR_SELECTION *pcr_selection,
3373 const TPM2B_PUBLIC *public,
3374 const void *fp,
3375 size_t fp_size,
3376 JsonVariant *signature_json,
3377 TPM2B_DIGEST **ret_policy_digest) {
3378
3379 TSS2_RC rc;
3380 int r;
3381
3382 assert(c);
3383 assert(session);
3384 assert(pcr_selection);
3385 assert(public);
3386 assert(fp && fp_size > 0);
3387
3388 log_debug("Adding PCR signature policy.");
3389
3390 _cleanup_(tpm2_handle_freep) Tpm2Handle *pubkey_handle = NULL;
3391 r = tpm2_load_external(c, NULL, public, NULL, &pubkey_handle);
3392 if (r < 0)
3393 return r;
3394
3395 /* Acquire the "name" of what we just loaded */
3396 _cleanup_(Esys_Freep) TPM2B_NAME *pubkey_name = NULL;
3397 r = tpm2_get_name(c, pubkey_handle, &pubkey_name);
3398 if (r < 0)
3399 return r;
3400
3401 /* If we have a signature, proceed with verifying the PCR digest */
3402 const TPMT_TK_VERIFIED *check_ticket;
3403 _cleanup_(Esys_Freep) TPMT_TK_VERIFIED *check_ticket_buffer = NULL;
3404 _cleanup_(Esys_Freep) TPM2B_DIGEST *approved_policy = NULL;
3405 if (signature_json) {
3406 r = tpm2_policy_pcr(
3407 c,
3408 session,
3409 pcr_selection,
3410 &approved_policy);
3411 if (r < 0)
3412 return r;
3413
3414 _cleanup_free_ void *signature_raw = NULL;
3415 size_t signature_size;
3416
3417 r = find_signature(
3418 signature_json,
3419 pcr_selection,
3420 fp, fp_size,
3421 approved_policy->buffer,
3422 approved_policy->size,
3423 &signature_raw,
3424 &signature_size);
3425 if (r < 0)
3426 return r;
3427
3428 /* TPM2_VerifySignature() will only verify the RSA part of the RSA+SHA256 signature,
3429 * hence we need to do the SHA256 part ourselves, first */
3430 TPM2B_DIGEST signature_hash = *approved_policy;
3431 r = tpm2_digest_rehash(TPM2_ALG_SHA256, &signature_hash);
3432 if (r < 0)
3433 return r;
3434
3435 r = TPM2B_PUBLIC_KEY_RSA_CHECK_SIZE(signature_size);
3436 if (r < 0)
3437 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Signature larger than buffer.");
3438
3439 TPMT_SIGNATURE policy_signature = {
3440 .sigAlg = TPM2_ALG_RSASSA,
3441 .signature.rsassa = {
3442 .hash = TPM2_ALG_SHA256,
3443 .sig = TPM2B_PUBLIC_KEY_RSA_MAKE(signature_raw, signature_size),
3444 },
3445 };
3446
3447 rc = sym_Esys_VerifySignature(
3448 c->esys_context,
3449 pubkey_handle->esys_handle,
3450 ESYS_TR_NONE,
3451 ESYS_TR_NONE,
3452 ESYS_TR_NONE,
3453 &signature_hash,
3454 &policy_signature,
3455 &check_ticket_buffer);
3456 if (rc != TSS2_RC_SUCCESS)
3457 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3458 "Failed to validate signature in TPM: %s", sym_Tss2_RC_Decode(rc));
3459
3460 check_ticket = check_ticket_buffer;
3461 } else {
3462 /* When enrolling, we pass a NULL ticket */
3463 static const TPMT_TK_VERIFIED check_ticket_null = {
3464 .tag = TPM2_ST_VERIFIED,
3465 .hierarchy = TPM2_RH_OWNER,
3466 };
3467
3468 check_ticket = &check_ticket_null;
3469 }
3470
3471 rc = sym_Esys_PolicyAuthorize(
3472 c->esys_context,
3473 session->esys_handle,
3474 ESYS_TR_NONE,
3475 ESYS_TR_NONE,
3476 ESYS_TR_NONE,
3477 approved_policy,
3478 /* policyRef= */ &(const TPM2B_NONCE) {},
3479 pubkey_name,
3480 check_ticket);
3481 if (rc != TSS2_RC_SUCCESS)
3482 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3483 "Failed to push Authorize policy into TPM: %s", sym_Tss2_RC_Decode(rc));
3484
3485 return tpm2_get_policy_digest(c, session, ret_policy_digest);
3486 }
3487
3488 /* Extend 'digest' with the calculated policy hash. */
3489 int tpm2_calculate_sealing_policy(
3490 const Tpm2PCRValue *pcr_values,
3491 size_t n_pcr_values,
3492 const TPM2B_PUBLIC *public,
3493 bool use_pin,
3494 TPM2B_DIGEST *digest) {
3495
3496 int r;
3497
3498 assert(pcr_values || n_pcr_values == 0);
3499 assert(digest);
3500
3501 if (public) {
3502 r = tpm2_calculate_policy_authorize(public, NULL, digest);
3503 if (r < 0)
3504 return r;
3505 }
3506
3507 if (n_pcr_values > 0) {
3508 r = tpm2_calculate_policy_pcr(pcr_values, n_pcr_values, digest);
3509 if (r < 0)
3510 return r;
3511 }
3512
3513 if (use_pin) {
3514 r = tpm2_calculate_policy_auth_value(digest);
3515 if (r < 0)
3516 return r;
3517 }
3518
3519 return 0;
3520 }
3521
3522 static int tpm2_build_sealing_policy(
3523 Tpm2Context *c,
3524 const Tpm2Handle *session,
3525 uint32_t hash_pcr_mask,
3526 uint16_t pcr_bank,
3527 const TPM2B_PUBLIC *public,
3528 const void *fp,
3529 size_t fp_size,
3530 uint32_t pubkey_pcr_mask,
3531 JsonVariant *signature_json,
3532 bool use_pin,
3533 TPM2B_DIGEST **ret_policy_digest) {
3534
3535 int r;
3536
3537 assert(c);
3538 assert(session);
3539 assert(pubkey_pcr_mask == 0 || public);
3540
3541 log_debug("Building sealing policy.");
3542
3543 if ((hash_pcr_mask | pubkey_pcr_mask) != 0) {
3544 r = tpm2_pcr_mask_good(c, pcr_bank, hash_pcr_mask|pubkey_pcr_mask);
3545 if (r < 0)
3546 return r;
3547 if (r == 0)
3548 log_debug("Selected TPM2 PCRs are not initialized on this system.");
3549 }
3550
3551 if (pubkey_pcr_mask != 0) {
3552 TPML_PCR_SELECTION pcr_selection;
3553 tpm2_tpml_pcr_selection_from_mask(pubkey_pcr_mask, (TPMI_ALG_HASH)pcr_bank, &pcr_selection);
3554 r = tpm2_policy_authorize(c, session, &pcr_selection, public, fp, fp_size, signature_json, NULL);
3555 if (r < 0)
3556 return r;
3557 }
3558
3559 if (hash_pcr_mask != 0) {
3560 TPML_PCR_SELECTION pcr_selection;
3561 tpm2_tpml_pcr_selection_from_mask(hash_pcr_mask, (TPMI_ALG_HASH)pcr_bank, &pcr_selection);
3562 r = tpm2_policy_pcr(c, session, &pcr_selection, NULL);
3563 if (r < 0)
3564 return r;
3565 }
3566
3567 if (use_pin) {
3568 r = tpm2_policy_auth_value(c, session, NULL);
3569 if (r < 0)
3570 return r;
3571 }
3572
3573 r = tpm2_get_policy_digest(c, session, ret_policy_digest);
3574 if (r < 0)
3575 return r;
3576
3577 return 0;
3578 }
3579
3580 #if HAVE_OPENSSL
3581 static const struct {
3582 TPM2_ECC_CURVE tpm2_ecc_curve_id;
3583 int openssl_ecc_curve_id;
3584 } tpm2_openssl_ecc_curve_table[] = {
3585 { TPM2_ECC_NIST_P192, NID_X9_62_prime192v1, },
3586 { TPM2_ECC_NIST_P224, NID_secp224r1, },
3587 { TPM2_ECC_NIST_P256, NID_X9_62_prime256v1, },
3588 { TPM2_ECC_NIST_P384, NID_secp384r1, },
3589 { TPM2_ECC_NIST_P521, NID_secp521r1, },
3590 { TPM2_ECC_SM2_P256, NID_sm2, },
3591 };
3592
3593 static int tpm2_ecc_curve_from_openssl_curve_id(int openssl_ecc_curve_id, TPM2_ECC_CURVE *ret) {
3594 assert(ret);
3595
3596 FOREACH_ARRAY(t, tpm2_openssl_ecc_curve_table, ELEMENTSOF(tpm2_openssl_ecc_curve_table))
3597 if (t->openssl_ecc_curve_id == openssl_ecc_curve_id) {
3598 *ret = t->tpm2_ecc_curve_id;
3599 return 0;
3600 }
3601
3602 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
3603 "Openssl ECC curve id %d not supported.", openssl_ecc_curve_id);
3604 }
3605
3606 static int tpm2_ecc_curve_to_openssl_curve_id(TPM2_ECC_CURVE tpm2_ecc_curve_id, int *ret) {
3607 assert(ret);
3608
3609 FOREACH_ARRAY(t, tpm2_openssl_ecc_curve_table, ELEMENTSOF(tpm2_openssl_ecc_curve_table))
3610 if (t->tpm2_ecc_curve_id == tpm2_ecc_curve_id) {
3611 *ret = t->openssl_ecc_curve_id;
3612 return 0;
3613 }
3614
3615 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
3616 "TPM2 ECC curve %u not supported.", tpm2_ecc_curve_id);
3617 }
3618
3619 #define TPM2_RSA_DEFAULT_EXPONENT UINT32_C(0x10001)
3620
3621 int tpm2_tpm2b_public_to_openssl_pkey(const TPM2B_PUBLIC *public, EVP_PKEY **ret) {
3622 int r;
3623
3624 assert(public);
3625 assert(ret);
3626
3627 const TPMT_PUBLIC *p = &public->publicArea;
3628 switch (p->type) {
3629 case TPM2_ALG_ECC: {
3630 int curve_id;
3631 r = tpm2_ecc_curve_to_openssl_curve_id(p->parameters.eccDetail.curveID, &curve_id);
3632 if (r < 0)
3633 return r;
3634
3635 const TPMS_ECC_POINT *point = &p->unique.ecc;
3636 return ecc_pkey_from_curve_x_y(
3637 curve_id,
3638 point->x.buffer,
3639 point->x.size,
3640 point->y.buffer,
3641 point->y.size,
3642 ret);
3643 }
3644 case TPM2_ALG_RSA: {
3645 /* TPM specification Part 2 ("Structures") section for TPMS_RSA_PARAMS states "An exponent of
3646 * zero indicates that the exponent is the default of 2^16 + 1". */
3647 uint32_t exponent = htobe32(p->parameters.rsaDetail.exponent ?: TPM2_RSA_DEFAULT_EXPONENT);
3648 return rsa_pkey_from_n_e(
3649 p->unique.rsa.buffer,
3650 p->unique.rsa.size,
3651 &exponent,
3652 sizeof(exponent),
3653 ret);
3654 }
3655 default:
3656 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
3657 "TPM2 asymmetric algorithm 0x%" PRIx16 " not supported.", p->type);
3658 }
3659 }
3660
3661 int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) {
3662 int key_id, r;
3663
3664 assert(pkey);
3665 assert(ret);
3666
3667 TPMT_PUBLIC public = {
3668 .nameAlg = TPM2_ALG_SHA256,
3669 .objectAttributes = TPMA_OBJECT_DECRYPT | TPMA_OBJECT_SIGN_ENCRYPT | TPMA_OBJECT_USERWITHAUTH,
3670 .parameters.asymDetail = {
3671 .symmetric.algorithm = TPM2_ALG_NULL,
3672 .scheme.scheme = TPM2_ALG_NULL,
3673 },
3674 };
3675
3676 #if OPENSSL_VERSION_MAJOR >= 3
3677 key_id = EVP_PKEY_get_id(pkey);
3678 #else
3679 key_id = EVP_PKEY_id(pkey);
3680 #endif
3681
3682 switch (key_id) {
3683 case EVP_PKEY_EC: {
3684 public.type = TPM2_ALG_ECC;
3685
3686 int curve_id;
3687 _cleanup_free_ void *x = NULL, *y = NULL;
3688 size_t x_size, y_size;
3689 r = ecc_pkey_to_curve_x_y(pkey, &curve_id, &x, &x_size, &y, &y_size);
3690 if (r < 0)
3691 return log_debug_errno(r, "Could not get ECC key curve/x/y: %m");
3692
3693 TPM2_ECC_CURVE curve;
3694 r = tpm2_ecc_curve_from_openssl_curve_id(curve_id, &curve);
3695 if (r < 0)
3696 return r;
3697
3698 public.parameters.eccDetail.curveID = curve;
3699
3700 public.parameters.eccDetail.kdf.scheme = TPM2_ALG_NULL;
3701
3702 r = TPM2B_ECC_PARAMETER_CHECK_SIZE(x_size);
3703 if (r < 0)
3704 return log_debug_errno(r, "ECC key x size %zu too large.", x_size);
3705
3706 public.unique.ecc.x = TPM2B_ECC_PARAMETER_MAKE(x, x_size);
3707
3708 r = TPM2B_ECC_PARAMETER_CHECK_SIZE(y_size);
3709 if (r < 0)
3710 return log_debug_errno(r, "ECC key y size %zu too large.", y_size);
3711
3712 public.unique.ecc.y = TPM2B_ECC_PARAMETER_MAKE(y, y_size);
3713
3714 break;
3715 }
3716 case EVP_PKEY_RSA: {
3717 public.type = TPM2_ALG_RSA;
3718
3719 _cleanup_free_ void *n = NULL, *e = NULL;
3720 size_t n_size, e_size;
3721 r = rsa_pkey_to_n_e(pkey, &n, &n_size, &e, &e_size);
3722 if (r < 0)
3723 return log_debug_errno(r, "Could not get RSA key n/e: %m");
3724
3725 r = TPM2B_PUBLIC_KEY_RSA_CHECK_SIZE(n_size);
3726 if (r < 0)
3727 return log_debug_errno(r, "RSA key n size %zu too large.", n_size);
3728
3729 public.unique.rsa = TPM2B_PUBLIC_KEY_RSA_MAKE(n, n_size);
3730 public.parameters.rsaDetail.keyBits = n_size * 8;
3731
3732 if (sizeof(uint32_t) < e_size)
3733 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
3734 "RSA key e size %zu too large.", e_size);
3735
3736 uint32_t exponent = 0;
3737 memcpy(&exponent, e, e_size);
3738 exponent = be32toh(exponent) >> (32 - e_size * 8);
3739 if (exponent == TPM2_RSA_DEFAULT_EXPONENT)
3740 exponent = 0;
3741 public.parameters.rsaDetail.exponent = exponent;
3742
3743 break;
3744 }
3745 default:
3746 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
3747 "EVP_PKEY type %d not supported.", key_id);
3748 }
3749
3750 *ret = (TPM2B_PUBLIC) {
3751 .size = sizeof(public),
3752 .publicArea = public,
3753 };
3754
3755 return 0;
3756 }
3757 #endif
3758
3759 int tpm2_tpm2b_public_to_fingerprint(
3760 const TPM2B_PUBLIC *public,
3761 void **ret_fingerprint,
3762 size_t *ret_fingerprint_size) {
3763
3764 #if HAVE_OPENSSL
3765 int r;
3766
3767 assert(public);
3768 assert(ret_fingerprint);
3769 assert(ret_fingerprint_size);
3770
3771 _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
3772 r = tpm2_tpm2b_public_to_openssl_pkey(public, &pkey);
3773 if (r < 0)
3774 return r;
3775
3776 /* Hardcode fingerprint to SHA256 */
3777 return pubkey_fingerprint(pkey, EVP_sha256(), ret_fingerprint, ret_fingerprint_size);
3778 #else
3779 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
3780 #endif
3781 }
3782
3783 int tpm2_tpm2b_public_from_pem(const void *pem, size_t pem_size, TPM2B_PUBLIC *ret) {
3784 #if HAVE_OPENSSL
3785 int r;
3786
3787 assert(pem);
3788 assert(ret);
3789
3790 _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
3791 r = openssl_pkey_from_pem(pem, pem_size, &pkey);
3792 if (r < 0)
3793 return r;
3794
3795 return tpm2_tpm2b_public_from_openssl_pkey(pkey, ret);
3796 #else
3797 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
3798 #endif
3799 }
3800
3801 /* Marshal the public and private objects into a single nonstandard 'blob'. This is not a (publicly) standard
3802 * format, this is specific to how we currently store the sealed object. This 'blob' can be unmarshalled by
3803 * tpm2_unmarshal_blob(). */
3804 int tpm2_marshal_blob(
3805 const TPM2B_PUBLIC *public,
3806 const TPM2B_PRIVATE *private,
3807 void **ret_blob,
3808 size_t *ret_blob_size) {
3809
3810 TSS2_RC rc;
3811
3812 assert(public);
3813 assert(private);
3814 assert(ret_blob);
3815 assert(ret_blob_size);
3816
3817 size_t max_size = sizeof(*private) + sizeof(*public);
3818
3819 _cleanup_free_ void *blob = malloc(max_size);
3820 if (!blob)
3821 return log_oom_debug();
3822
3823 size_t blob_size = 0;
3824 rc = sym_Tss2_MU_TPM2B_PRIVATE_Marshal(private, blob, max_size, &blob_size);
3825 if (rc != TSS2_RC_SUCCESS)
3826 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3827 "Failed to marshal private key: %s", sym_Tss2_RC_Decode(rc));
3828
3829 rc = sym_Tss2_MU_TPM2B_PUBLIC_Marshal(public, blob, max_size, &blob_size);
3830 if (rc != TSS2_RC_SUCCESS)
3831 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3832 "Failed to marshal public key: %s", sym_Tss2_RC_Decode(rc));
3833
3834 *ret_blob = TAKE_PTR(blob);
3835 *ret_blob_size = blob_size;
3836
3837 return 0;
3838 }
3839
3840 /* Unmarshal the 'blob' into public and private objects. This is not a (publicly) standard format, this is
3841 * specific to how we currently store the sealed object. This expects the 'blob' to have been created by
3842 * tpm2_marshal_blob(). */
3843 int tpm2_unmarshal_blob(
3844 const void *blob,
3845 size_t blob_size,
3846 TPM2B_PUBLIC *ret_public,
3847 TPM2B_PRIVATE *ret_private) {
3848
3849 TSS2_RC rc;
3850
3851 assert(blob);
3852 assert(ret_public);
3853 assert(ret_private);
3854
3855 TPM2B_PRIVATE private = {};
3856 size_t offset = 0;
3857 rc = sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal(blob, blob_size, &offset, &private);
3858 if (rc != TSS2_RC_SUCCESS)
3859 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3860 "Failed to unmarshal private key: %s", sym_Tss2_RC_Decode(rc));
3861
3862 TPM2B_PUBLIC public = {};
3863 rc = sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal(blob, blob_size, &offset, &public);
3864 if (rc != TSS2_RC_SUCCESS)
3865 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3866 "Failed to unmarshal public key: %s", sym_Tss2_RC_Decode(rc));
3867
3868 *ret_public = public;
3869 *ret_private = private;
3870
3871 return 0;
3872 }
3873
3874 /* Serialize a handle. This produces a binary object that can be later deserialized (by the same TPM), even
3875 * across restarts of the TPM or reboots (assuming the handle is persistent). */
3876 static int tpm2_serialize(
3877 Tpm2Context *c,
3878 const Tpm2Handle *handle,
3879 void **ret_serialized,
3880 size_t *ret_serialized_size) {
3881
3882 TSS2_RC rc;
3883
3884 assert(c);
3885 assert(handle);
3886 assert(ret_serialized);
3887 assert(ret_serialized_size);
3888
3889 _cleanup_(Esys_Freep) unsigned char *serialized = NULL;
3890 size_t size = 0;
3891 rc = sym_Esys_TR_Serialize(c->esys_context, handle->esys_handle, &serialized, &size);
3892 if (rc != TSS2_RC_SUCCESS)
3893 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3894 "Failed to serialize: %s", sym_Tss2_RC_Decode(rc));
3895
3896 *ret_serialized = TAKE_PTR(serialized);
3897 *ret_serialized_size = size;
3898
3899 return 0;
3900 }
3901
3902 static int tpm2_deserialize(
3903 Tpm2Context *c,
3904 const void *serialized,
3905 size_t serialized_size,
3906 Tpm2Handle **ret_handle) {
3907
3908 TSS2_RC rc;
3909 int r;
3910
3911 assert(c);
3912 assert(serialized);
3913 assert(ret_handle);
3914
3915 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
3916 r = tpm2_handle_new(c, &handle);
3917 if (r < 0)
3918 return r;
3919
3920 /* Since this is an existing handle in the TPM we should not implicitly flush it. */
3921 handle->flush = false;
3922
3923 rc = sym_Esys_TR_Deserialize(c->esys_context, serialized, serialized_size, &handle->esys_handle);
3924 if (rc != TSS2_RC_SUCCESS)
3925 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3926 "Failed to deserialize: %s", sym_Tss2_RC_Decode(rc));
3927
3928 *ret_handle = TAKE_PTR(handle);
3929
3930 return 0;
3931 }
3932
3933 int tpm2_seal(Tpm2Context *c,
3934 const TPM2B_DIGEST *policy,
3935 const char *pin,
3936 void **ret_secret,
3937 size_t *ret_secret_size,
3938 void **ret_blob,
3939 size_t *ret_blob_size,
3940 uint16_t *ret_primary_alg,
3941 void **ret_srk_buf,
3942 size_t *ret_srk_buf_size) {
3943
3944 uint16_t primary_alg = 0;
3945 int r;
3946
3947 assert(ret_secret);
3948 assert(ret_secret_size);
3949 assert(ret_blob);
3950 assert(ret_blob_size);
3951
3952 /* So here's what we do here: we connect to the TPM2 chip. It persistently contains a "seed" key that
3953 * is randomized when the TPM2 is first initialized or reset and remains stable across boots. We
3954 * generate a "primary" key pair derived from that (ECC if possible, RSA as fallback). Given the seed
3955 * remains fixed this will result in the same key pair whenever we specify the exact same parameters
3956 * for it. We then create a PCR-bound policy session, which calculates a hash on the current PCR
3957 * values of the indexes we specify. We then generate a randomized key on the host (which is the key
3958 * we actually enroll in the LUKS2 keyslots), which we upload into the TPM2, where it is encrypted
3959 * with the "primary" key, taking the PCR policy session into account. We then download the encrypted
3960 * key from the TPM2 ("sealing") and marshall it into binary form, which is ultimately placed in the
3961 * LUKS2 JSON header.
3962 *
3963 * The TPM2 "seed" key and "primary" keys never leave the TPM2 chip (and cannot be extracted at
3964 * all). The random key we enroll in LUKS2 we generate on the host using the Linux random device. It
3965 * is stored in the LUKS2 JSON only in encrypted form with the "primary" key of the TPM2 chip, thus
3966 * binding the unlocking to the TPM2 chip. */
3967
3968 usec_t start = now(CLOCK_MONOTONIC);
3969
3970 /* We use a keyed hash object (i.e. HMAC) to store the secret key we want to use for unlocking the
3971 * LUKS2 volume with. We don't ever use for HMAC/keyed hash operations however, we just use it
3972 * because it's a key type that is universally supported and suitable for symmetric binary blobs. */
3973 TPMT_PUBLIC hmac_template = {
3974 .type = TPM2_ALG_KEYEDHASH,
3975 .nameAlg = TPM2_ALG_SHA256,
3976 .objectAttributes = TPMA_OBJECT_FIXEDTPM | TPMA_OBJECT_FIXEDPARENT,
3977 .parameters.keyedHashDetail.scheme.scheme = TPM2_ALG_NULL,
3978 .unique.keyedHash.size = SHA256_DIGEST_SIZE,
3979 .authPolicy = policy ? *policy : TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE),
3980 };
3981
3982 TPMS_SENSITIVE_CREATE hmac_sensitive = {
3983 .data.size = hmac_template.unique.keyedHash.size,
3984 };
3985
3986 CLEANUP_ERASE(hmac_sensitive);
3987
3988 if (pin) {
3989 r = tpm2_get_pin_auth(TPM2_ALG_SHA256, pin, &hmac_sensitive.userAuth);
3990 if (r < 0)
3991 return r;
3992 }
3993
3994 assert(sizeof(hmac_sensitive.data.buffer) >= hmac_sensitive.data.size);
3995
3996 (void) tpm2_credit_random(c);
3997
3998 log_debug("Generating secret key data.");
3999
4000 r = crypto_random_bytes(hmac_sensitive.data.buffer, hmac_sensitive.data.size);
4001 if (r < 0)
4002 return log_debug_errno(r, "Failed to generate secret key: %m");
4003
4004 _cleanup_(tpm2_handle_freep) Tpm2Handle *primary_handle = NULL;
4005 if (ret_srk_buf) {
4006 _cleanup_(Esys_Freep) TPM2B_PUBLIC *primary_public = NULL;
4007 r = tpm2_get_or_create_srk(
4008 c,
4009 /* session= */ NULL,
4010 &primary_public,
4011 /* ret_name= */ NULL,
4012 /* ret_qname= */ NULL,
4013 &primary_handle);
4014 if (r < 0)
4015 return r;
4016
4017 primary_alg = primary_public->publicArea.type;
4018 } else {
4019 /* TODO: force all callers to provide ret_srk_buf, so we can stop sealing with the legacy templates. */
4020 primary_alg = TPM2_ALG_ECC;
4021
4022 TPM2B_PUBLIC template = { .size = sizeof(TPMT_PUBLIC), };
4023 r = tpm2_get_legacy_template(primary_alg, &template.publicArea);
4024 if (r < 0)
4025 return log_debug_errno(r, "Could not get legacy ECC template: %m");
4026
4027 if (!tpm2_supports_tpmt_public(c, &template.publicArea)) {
4028 primary_alg = TPM2_ALG_RSA;
4029
4030 r = tpm2_get_legacy_template(primary_alg, &template.publicArea);
4031 if (r < 0)
4032 return log_debug_errno(r, "Could not get legacy RSA template: %m");
4033
4034 if (!tpm2_supports_tpmt_public(c, &template.publicArea))
4035 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
4036 "TPM does not support either ECC or RSA legacy template.");
4037 }
4038
4039 r = tpm2_create_primary(
4040 c,
4041 /* session= */ NULL,
4042 &template,
4043 /* sensitive= */ NULL,
4044 /* ret_public= */ NULL,
4045 &primary_handle);
4046 if (r < 0)
4047 return r;
4048 }
4049
4050 _cleanup_(tpm2_handle_freep) Tpm2Handle *encryption_session = NULL;
4051 r = tpm2_make_encryption_session(c, primary_handle, /* bind_key= */ NULL, &encryption_session);
4052 if (r < 0)
4053 return r;
4054
4055 _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
4056 _cleanup_(Esys_Freep) TPM2B_PRIVATE *private = NULL;
4057 r = tpm2_create(c, primary_handle, encryption_session, &hmac_template, &hmac_sensitive, &public, &private);
4058 if (r < 0)
4059 return r;
4060
4061 _cleanup_(erase_and_freep) void *secret = NULL;
4062 secret = memdup(hmac_sensitive.data.buffer, hmac_sensitive.data.size);
4063 if (!secret)
4064 return log_oom_debug();
4065
4066 log_debug("Marshalling private and public part of HMAC key.");
4067
4068 _cleanup_free_ void *blob = NULL;
4069 size_t blob_size;
4070 r = tpm2_marshal_blob(public, private, &blob, &blob_size);
4071 if (r < 0)
4072 return log_debug_errno(r, "Could not create sealed blob: %m");
4073
4074 if (DEBUG_LOGGING)
4075 log_debug("Completed TPM2 key sealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
4076
4077 _cleanup_free_ void *srk_buf = NULL;
4078 size_t srk_buf_size = 0;
4079 if (ret_srk_buf) {
4080 _cleanup_(Esys_Freep) void *tmp = NULL;
4081 r = tpm2_serialize(c, primary_handle, &tmp, &srk_buf_size);
4082 if (r < 0)
4083 return r;
4084
4085 /*
4086 * make a copy since we don't want the caller to understand that
4087 * ESYS allocated the pointer. It would make tracking what deallocator
4088 * to use for srk_buf in which context a PITA.
4089 */
4090 srk_buf = memdup(tmp, srk_buf_size);
4091 if (!srk_buf)
4092 return log_oom_debug();
4093
4094 *ret_srk_buf = TAKE_PTR(srk_buf);
4095 *ret_srk_buf_size = srk_buf_size;
4096 }
4097
4098 *ret_secret = TAKE_PTR(secret);
4099 *ret_secret_size = hmac_sensitive.data.size;
4100 *ret_blob = TAKE_PTR(blob);
4101 *ret_blob_size = blob_size;
4102
4103 if (ret_primary_alg)
4104 *ret_primary_alg = primary_alg;
4105
4106 return 0;
4107 }
4108
4109 #define RETRY_UNSEAL_MAX 30u
4110
4111 int tpm2_unseal(Tpm2Context *c,
4112 uint32_t hash_pcr_mask,
4113 uint16_t pcr_bank,
4114 const void *pubkey,
4115 size_t pubkey_size,
4116 uint32_t pubkey_pcr_mask,
4117 JsonVariant *signature,
4118 const char *pin,
4119 uint16_t primary_alg,
4120 const void *blob,
4121 size_t blob_size,
4122 const void *known_policy_hash,
4123 size_t known_policy_hash_size,
4124 const void *srk_buf,
4125 size_t srk_buf_size,
4126 void **ret_secret,
4127 size_t *ret_secret_size) {
4128
4129 TSS2_RC rc;
4130 int r;
4131
4132 assert(blob);
4133 assert(blob_size > 0);
4134 assert(known_policy_hash_size == 0 || known_policy_hash);
4135 assert(pubkey_size == 0 || pubkey);
4136 assert(ret_secret);
4137 assert(ret_secret_size);
4138
4139 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask));
4140 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));
4141
4142 /* So here's what we do here: We connect to the TPM2 chip. As we do when sealing we generate a
4143 * "primary" key on the TPM2 chip, with the same parameters as well as a PCR-bound policy session.
4144 * Given we pass the same parameters, this will result in the same "primary" key, and same policy
4145 * hash (the latter of course, only if the PCR values didn't change in between). We unmarshal the
4146 * encrypted key we stored in the LUKS2 JSON token header and upload it into the TPM2, where it is
4147 * decrypted if the seed and the PCR policy were right ("unsealing"). We then download the result,
4148 * and use it to unlock the LUKS2 volume. */
4149
4150 usec_t start = now(CLOCK_MONOTONIC);
4151
4152 TPM2B_PUBLIC public;
4153 TPM2B_PRIVATE private;
4154 r = tpm2_unmarshal_blob(blob, blob_size, &public, &private);
4155 if (r < 0)
4156 return log_debug_errno(r, "Could not extract parts from blob: %m");
4157
4158 /* Older code did not save the pcr_bank, and unsealing needed to detect the best pcr bank to use,
4159 * so we need to handle that legacy situation. */
4160 if (pcr_bank == UINT16_MAX) {
4161 r = tpm2_get_best_pcr_bank(c, hash_pcr_mask|pubkey_pcr_mask, &pcr_bank);
4162 if (r < 0)
4163 return r;
4164 }
4165
4166 _cleanup_(tpm2_handle_freep) Tpm2Handle *primary_handle = NULL;
4167 if (srk_buf) {
4168 r = tpm2_deserialize(c, srk_buf, srk_buf_size, &primary_handle);
4169 if (r < 0)
4170 return r;
4171 } else if (primary_alg != 0) {
4172 TPM2B_PUBLIC template = { .size = sizeof(TPMT_PUBLIC), };
4173 r = tpm2_get_legacy_template(primary_alg, &template.publicArea);
4174 if (r < 0)
4175 return log_debug_errno(r, "Could not get legacy template: %m");
4176
4177 r = tpm2_create_primary(
4178 c,
4179 /* session= */ NULL,
4180 &template,
4181 /* sensitive= */ NULL,
4182 /* ret_public= */ NULL,
4183 &primary_handle);
4184 if (r < 0)
4185 return r;
4186 } else
4187 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
4188 "No SRK or primary alg provided.");
4189
4190 log_debug("Loading HMAC key into TPM.");
4191
4192 /*
4193 * Nothing sensitive on the bus, no need for encryption. Even if an attacker
4194 * gives you back a different key, the session initiation will fail. In the
4195 * SRK model, the tpmKey is verified. In the non-srk model, with pin, the bindKey
4196 * provides protections.
4197 */
4198 _cleanup_(tpm2_handle_freep) Tpm2Handle *hmac_key = NULL;
4199 r = tpm2_load(c, primary_handle, NULL, &public, &private, &hmac_key);
4200 if (r < 0)
4201 return r;
4202
4203 TPM2B_PUBLIC pubkey_tpm2b;
4204 _cleanup_free_ void *fp = NULL;
4205 size_t fp_size = 0;
4206 if (pubkey) {
4207 r = tpm2_tpm2b_public_from_pem(pubkey, pubkey_size, &pubkey_tpm2b);
4208 if (r < 0)
4209 return log_debug_errno(r, "Could not create TPMT_PUBLIC: %m");
4210
4211 r = tpm2_tpm2b_public_to_fingerprint(&pubkey_tpm2b, &fp, &fp_size);
4212 if (r < 0)
4213 return log_debug_errno(r, "Could not get key fingerprint: %m");
4214 }
4215
4216 /*
4217 * if a pin is set for the seal object, use it to bind the session
4218 * key to that object. This prevents active bus interposers from
4219 * faking a TPM and seeing the unsealed value. An active interposer
4220 * could fake a TPM, satisfying the encrypted session, and just
4221 * forward everything to the *real* TPM.
4222 */
4223 r = tpm2_set_auth(c, hmac_key, pin);
4224 if (r < 0)
4225 return r;
4226
4227 _cleanup_(tpm2_handle_freep) Tpm2Handle *encryption_session = NULL;
4228 r = tpm2_make_encryption_session(c, primary_handle, hmac_key, &encryption_session);
4229 if (r < 0)
4230 return r;
4231
4232 _cleanup_(Esys_Freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
4233 for (unsigned i = RETRY_UNSEAL_MAX;; i--) {
4234 _cleanup_(tpm2_handle_freep) Tpm2Handle *policy_session = NULL;
4235 _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
4236 r = tpm2_make_policy_session(
4237 c,
4238 primary_handle,
4239 encryption_session,
4240 &policy_session);
4241 if (r < 0)
4242 return r;
4243
4244 r = tpm2_build_sealing_policy(
4245 c,
4246 policy_session,
4247 hash_pcr_mask,
4248 pcr_bank,
4249 pubkey ? &pubkey_tpm2b : NULL,
4250 fp, fp_size,
4251 pubkey_pcr_mask,
4252 signature,
4253 !!pin,
4254 &policy_digest);
4255 if (r < 0)
4256 return r;
4257
4258 /* If we know the policy hash to expect, and it doesn't match, we can shortcut things here, and not
4259 * wait until the TPM2 tells us to go away. */
4260 if (known_policy_hash_size > 0 &&
4261 memcmp_nn(policy_digest->buffer, policy_digest->size, known_policy_hash, known_policy_hash_size) != 0)
4262 return log_debug_errno(SYNTHETIC_ERRNO(EPERM),
4263 "Current policy digest does not match stored policy digest, cancelling "
4264 "TPM2 authentication attempt.");
4265
4266 log_debug("Unsealing HMAC key.");
4267
4268 rc = sym_Esys_Unseal(
4269 c->esys_context,
4270 hmac_key->esys_handle,
4271 policy_session->esys_handle,
4272 encryption_session->esys_handle, /* use HMAC session to enable parameter encryption */
4273 ESYS_TR_NONE,
4274 &unsealed);
4275 if (rc == TSS2_RC_SUCCESS)
4276 break;
4277 if (rc != TPM2_RC_PCR_CHANGED || i == 0)
4278 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4279 "Failed to unseal HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc));
4280 log_debug("A PCR value changed during the TPM2 policy session, restarting HMAC key unsealing (%u tries left).", i);
4281 }
4282
4283 _cleanup_(erase_and_freep) char *secret = NULL;
4284 secret = memdup(unsealed->buffer, unsealed->size);
4285 explicit_bzero_safe(unsealed->buffer, unsealed->size);
4286 if (!secret)
4287 return log_oom_debug();
4288
4289 if (DEBUG_LOGGING)
4290 log_debug("Completed TPM2 key unsealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
4291
4292 *ret_secret = TAKE_PTR(secret);
4293 *ret_secret_size = unsealed->size;
4294
4295 return 0;
4296 }
4297
4298 #endif
4299
4300 int tpm2_list_devices(void) {
4301 #if HAVE_TPM2
4302 _cleanup_(table_unrefp) Table *t = NULL;
4303 _cleanup_closedir_ DIR *d = NULL;
4304 int r;
4305
4306 r = dlopen_tpm2();
4307 if (r < 0)
4308 return log_error_errno(r, "TPM2 support is not installed.");
4309
4310 t = table_new("path", "device", "driver");
4311 if (!t)
4312 return log_oom();
4313
4314 d = opendir("/sys/class/tpmrm");
4315 if (!d) {
4316 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to open /sys/class/tpmrm: %m");
4317 if (errno != ENOENT)
4318 return -errno;
4319 } else {
4320 for (;;) {
4321 _cleanup_free_ char *device_path = NULL, *device = NULL, *driver_path = NULL, *driver = NULL, *node = NULL;
4322 struct dirent *de;
4323
4324 de = readdir_no_dot(d);
4325 if (!de)
4326 break;
4327
4328 device_path = path_join("/sys/class/tpmrm", de->d_name, "device");
4329 if (!device_path)
4330 return log_oom();
4331
4332 r = readlink_malloc(device_path, &device);
4333 if (r < 0)
4334 log_debug_errno(r, "Failed to read device symlink %s, ignoring: %m", device_path);
4335 else {
4336 driver_path = path_join(device_path, "driver");
4337 if (!driver_path)
4338 return log_oom();
4339
4340 r = readlink_malloc(driver_path, &driver);
4341 if (r < 0)
4342 log_debug_errno(r, "Failed to read driver symlink %s, ignoring: %m", driver_path);
4343 }
4344
4345 node = path_join("/dev", de->d_name);
4346 if (!node)
4347 return log_oom();
4348
4349 r = table_add_many(
4350 t,
4351 TABLE_PATH, node,
4352 TABLE_STRING, device ? last_path_component(device) : NULL,
4353 TABLE_STRING, driver ? last_path_component(driver) : NULL);
4354 if (r < 0)
4355 return table_log_add_error(r);
4356 }
4357 }
4358
4359 if (table_get_rows(t) <= 1) {
4360 log_info("No suitable TPM2 devices found.");
4361 return 0;
4362 }
4363
4364 r = table_print(t, stdout);
4365 if (r < 0)
4366 return log_error_errno(r, "Failed to show device table: %m");
4367
4368 return 0;
4369 #else
4370 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
4371 "TPM2 not supported on this build.");
4372 #endif
4373 }
4374
4375 int tpm2_find_device_auto(char **ret) {
4376 #if HAVE_TPM2
4377 _cleanup_closedir_ DIR *d = NULL;
4378 int r;
4379
4380 r = dlopen_tpm2();
4381 if (r < 0)
4382 return log_debug_errno(r, "TPM2 support is not installed.");
4383
4384 d = opendir("/sys/class/tpmrm");
4385 if (!d) {
4386 log_debug_errno(errno, "Failed to open /sys/class/tpmrm: %m");
4387 if (errno != ENOENT)
4388 return -errno;
4389 } else {
4390 _cleanup_free_ char *node = NULL;
4391
4392 for (;;) {
4393 struct dirent *de;
4394
4395 de = readdir_no_dot(d);
4396 if (!de)
4397 break;
4398
4399 if (node)
4400 return log_debug_errno(SYNTHETIC_ERRNO(ENOTUNIQ),
4401 "More than one TPM2 (tpmrm) device found.");
4402
4403 node = path_join("/dev", de->d_name);
4404 if (!node)
4405 return log_oom_debug();
4406 }
4407
4408 if (node) {
4409 *ret = TAKE_PTR(node);
4410 return 0;
4411 }
4412 }
4413
4414 return log_debug_errno(SYNTHETIC_ERRNO(ENODEV), "No TPM2 (tpmrm) device found.");
4415 #else
4416 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
4417 "TPM2 not supported on this build.");
4418 #endif
4419 }
4420
4421 #if HAVE_TPM2
4422 static const char* tpm2_userspace_event_type_table[_TPM2_USERSPACE_EVENT_TYPE_MAX] = {
4423 [TPM2_EVENT_PHASE] = "phase",
4424 [TPM2_EVENT_FILESYSTEM] = "filesystem",
4425 [TPM2_EVENT_VOLUME_KEY] = "volume-key",
4426 [TPM2_EVENT_MACHINE_ID] = "machine-id",
4427 };
4428
4429 DEFINE_STRING_TABLE_LOOKUP(tpm2_userspace_event_type, Tpm2UserspaceEventType);
4430
4431 const char *tpm2_userspace_log_path(void) {
4432 return secure_getenv("SYSTEMD_MEASURE_LOG_USERSPACE") ?: "/run/log/systemd/tpm2-measure.log";
4433 }
4434
4435 static int tpm2_userspace_log_open(void) {
4436 _cleanup_close_ int fd = -EBADF;
4437 struct stat st;
4438 const char *e;
4439 int r;
4440
4441 e = tpm2_userspace_log_path();
4442 (void) mkdir_parents(e, 0755);
4443
4444 /* We use access mode 0600 here (even though the measurements should not strictly be confidential),
4445 * because we use BSD file locking on it, and if anyone but root can access the file they can also
4446 * lock it, which we want to avoid. */
4447 fd = open(e, O_CREAT|O_WRONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
4448 if (fd < 0)
4449 return log_debug_errno(errno, "Failed to open TPM log file '%s' for writing, ignoring: %m", e);
4450
4451 if (flock(fd, LOCK_EX) < 0)
4452 return log_debug_errno(errno, "Failed to lock TPM log file '%s', ignoring: %m", e);
4453
4454 if (fstat(fd, &st) < 0)
4455 return log_debug_errno(errno, "Failed to fstat TPM log file '%s', ignoring: %m", e);
4456
4457 r = stat_verify_regular(&st);
4458 if (r < 0)
4459 return log_debug_errno(r, "TPM log file '%s' is not regular, ignoring: %m", e);
4460
4461 /* We set the sticky bit when we are about to append to the log file. We'll unset it afterwards
4462 * again. If we manage to take a lock on a file that has it set we know we didn't write it fully and
4463 * it is corrupted. Ideally we'd like to use user xattrs for this, but unfortunately tmpfs (which is
4464 * our assumed backend fs) doesn't know user xattrs. */
4465 if (st.st_mode & S_ISVTX)
4466 return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "TPM log file '%s' aborted, ignoring.", e);
4467
4468 if (fchmod(fd, 0600 | S_ISVTX) < 0)
4469 return log_debug_errno(errno, "Failed to chmod() TPM log file '%s', ignoring: %m", e);
4470
4471 return TAKE_FD(fd);
4472 }
4473
4474 static int tpm2_userspace_log(
4475 int fd,
4476 unsigned pcr_index,
4477 const TPML_DIGEST_VALUES *values,
4478 Tpm2UserspaceEventType event_type,
4479 const char *description) {
4480
4481 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *array = NULL;
4482 _cleanup_free_ char *f = NULL;
4483 sd_id128_t boot_id;
4484 int r;
4485
4486 assert(values);
4487 assert(values->count > 0);
4488
4489 /* We maintain a local PCR measurement log. This implements a subset of the TCG Canonical Event Log
4490 * Format – the JSON flavour –
4491 * (https://trustedcomputinggroup.org/resource/canonical-event-log-format/), but departs in certain
4492 * ways from it, specifically:
4493 *
4494 * - We don't write out a recnum. It's a bit too vaguely defined which means we'd have to read
4495 * through the whole logs (include firmware logs) before knowing what the next value is we should
4496 * use. Hence we simply don't write this out as append-time, and instead expect a consumer to add
4497 * it in when it uses the data.
4498 *
4499 * - We write this out in RFC 7464 application/json-seq rather than as a JSON array. Writing this as
4500 * JSON array would mean that for each appending we'd have to read the whole log file fully into
4501 * memory before writing it out again. We prefer a strictly append-only write pattern however. (RFC
4502 * 7464 is what jq --seq eats.) Conversion into a proper JSON array is trivial.
4503 *
4504 * It should be possible to convert this format in a relatively straight-forward way into the
4505 * official TCG Canonical Event Log Format on read, by simply adding in a few more fields that can be
4506 * determined from the full dataset.
4507 *
4508 * We set the 'content_type' field to "systemd" to make clear this data is generated by us, and
4509 * include various interesting fields in the 'content' subobject, including a CLOCK_BOOTTIME
4510 * timestamp which can be used to order this measurement against possibly other measurements
4511 * independently done by other subsystems on the system.
4512 */
4513
4514 if (fd < 0) /* Apparently tpm2_local_log_open() failed earlier, let's not complain again */
4515 return 0;
4516
4517 for (size_t i = 0; i < values->count; i++) {
4518 const EVP_MD *implementation;
4519 const char *a;
4520
4521 assert_se(a = tpm2_hash_alg_to_string(values->digests[i].hashAlg));
4522 assert_se(implementation = EVP_get_digestbyname(a));
4523
4524 r = json_variant_append_arrayb(
4525 &array, JSON_BUILD_OBJECT(
4526 JSON_BUILD_PAIR_STRING("hashAlg", a),
4527 JSON_BUILD_PAIR("digest", JSON_BUILD_HEX(&values->digests[i].digest, EVP_MD_size(implementation)))));
4528 if (r < 0)
4529 return log_debug_errno(r, "Failed to append digest object to JSON array: %m");
4530 }
4531
4532 assert(array);
4533
4534 r = sd_id128_get_boot(&boot_id);
4535 if (r < 0)
4536 return log_debug_errno(r, "Failed to acquire boot ID: %m");
4537
4538 r = json_build(&v, JSON_BUILD_OBJECT(
4539 JSON_BUILD_PAIR("pcr", JSON_BUILD_UNSIGNED(pcr_index)),
4540 JSON_BUILD_PAIR("digests", JSON_BUILD_VARIANT(array)),
4541 JSON_BUILD_PAIR("content_type", JSON_BUILD_STRING("systemd")),
4542 JSON_BUILD_PAIR("content", JSON_BUILD_OBJECT(
4543 JSON_BUILD_PAIR_CONDITION(description, "string", JSON_BUILD_STRING(description)),
4544 JSON_BUILD_PAIR("bootId", JSON_BUILD_ID128(boot_id)),
4545 JSON_BUILD_PAIR("timestamp", JSON_BUILD_UNSIGNED(now(CLOCK_BOOTTIME))),
4546 JSON_BUILD_PAIR_CONDITION(event_type >= 0, "eventType", JSON_BUILD_STRING(tpm2_userspace_event_type_to_string(event_type)))))));
4547 if (r < 0)
4548 return log_debug_errno(r, "Failed to build log record JSON: %m");
4549
4550 r = json_variant_format(v, JSON_FORMAT_SEQ, &f);
4551 if (r < 0)
4552 return log_debug_errno(r, "Failed to format JSON: %m");
4553
4554 if (lseek(fd, 0, SEEK_END) == (off_t) -1)
4555 return log_debug_errno(errno, "Failed to seek to end of JSON log: %m");
4556
4557 r = loop_write(fd, f, SIZE_MAX);
4558 if (r < 0)
4559 return log_debug_errno(r, "Failed to write JSON data to log: %m");
4560
4561 if (fsync(fd) < 0)
4562 return log_debug_errno(errno, "Failed to sync JSON data: %m");
4563
4564 /* Unset S_ISVTX again */
4565 if (fchmod(fd, 0600) < 0)
4566 return log_debug_errno(errno, "Failed to chmod() TPM log file, ignoring: %m");
4567
4568 r = fsync_full(fd);
4569 if (r < 0)
4570 return log_debug_errno(r, "Failed to sync JSON log: %m");
4571
4572 return 1;
4573 }
4574
4575 int tpm2_extend_bytes(
4576 Tpm2Context *c,
4577 char **banks,
4578 unsigned pcr_index,
4579 const void *data,
4580 size_t data_size,
4581 const void *secret,
4582 size_t secret_size,
4583 Tpm2UserspaceEventType event_type,
4584 const char *description) {
4585
4586 #if HAVE_OPENSSL
4587 _cleanup_close_ int log_fd = -EBADF;
4588 TPML_DIGEST_VALUES values = {};
4589 TSS2_RC rc;
4590
4591 assert(c);
4592 assert(data || data_size == 0);
4593 assert(secret || secret_size == 0);
4594
4595 if (data_size == SIZE_MAX)
4596 data_size = strlen(data);
4597 if (secret_size == SIZE_MAX)
4598 secret_size = strlen(secret);
4599
4600 if (pcr_index >= TPM2_PCRS_MAX)
4601 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Can't measure into unsupported PCR %u, refusing.", pcr_index);
4602
4603 if (strv_isempty(banks))
4604 return 0;
4605
4606 STRV_FOREACH(bank, banks) {
4607 const EVP_MD *implementation;
4608 int id;
4609
4610 assert_se(implementation = EVP_get_digestbyname(*bank));
4611
4612 if (values.count >= ELEMENTSOF(values.digests))
4613 return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "Too many banks selected.");
4614
4615 if ((size_t) EVP_MD_size(implementation) > sizeof(values.digests[values.count].digest))
4616 return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "Hash result too large for TPM2.");
4617
4618 id = tpm2_hash_alg_from_string(EVP_MD_name(implementation));
4619 if (id < 0)
4620 return log_debug_errno(id, "Can't map hash name to TPM2.");
4621
4622 values.digests[values.count].hashAlg = id;
4623
4624 /* So here's a twist: sometimes we want to measure secrets (e.g. root file system volume
4625 * key), but we'd rather not leak a literal hash of the secret to the TPM (given that the
4626 * wire is unprotected, and some other subsystem might use the simple, literal hash of the
4627 * secret for other purposes, maybe because it needs a shorter secret derived from it for
4628 * some unrelated purpose, who knows). Hence we instead measure an HMAC signature of a
4629 * private non-secret string instead. */
4630 if (secret_size > 0) {
4631 if (!HMAC(implementation, secret, secret_size, data, data_size, (unsigned char*) &values.digests[values.count].digest, NULL))
4632 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to calculate HMAC of data to measure.");
4633 } else if (EVP_Digest(data, data_size, (unsigned char*) &values.digests[values.count].digest, NULL, implementation, NULL) != 1)
4634 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash data to measure.");
4635
4636 values.count++;
4637 }
4638
4639 /* Open + lock the log file *before* we start measuring, so that noone else can come between our log
4640 * and our measurement and change either */
4641 log_fd = tpm2_userspace_log_open();
4642
4643 rc = sym_Esys_PCR_Extend(
4644 c->esys_context,
4645 ESYS_TR_PCR0 + pcr_index,
4646 ESYS_TR_PASSWORD,
4647 ESYS_TR_NONE,
4648 ESYS_TR_NONE,
4649 &values);
4650 if (rc != TSS2_RC_SUCCESS)
4651 return log_debug_errno(
4652 SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4653 "Failed to measure into PCR %u: %s",
4654 pcr_index,
4655 sym_Tss2_RC_Decode(rc));
4656
4657 /* Now, write what we just extended to the log, too. */
4658 (void) tpm2_userspace_log(log_fd, pcr_index, &values, event_type, description);
4659
4660 return 0;
4661 #else /* HAVE_OPENSSL */
4662 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
4663 #endif
4664 }
4665 #endif
4666
4667 char *tpm2_pcr_mask_to_string(uint32_t mask) {
4668 _cleanup_free_ char *s = NULL;
4669
4670 FOREACH_PCR_IN_MASK(n, mask)
4671 if (strextendf_with_separator(&s, "+", "%d", n) < 0)
4672 return NULL;
4673
4674 if (!s)
4675 return strdup("");
4676
4677 return TAKE_PTR(s);
4678 }
4679
4680 int tpm2_make_pcr_json_array(uint32_t pcr_mask, JsonVariant **ret) {
4681 _cleanup_(json_variant_unrefp) JsonVariant *a = NULL;
4682 int r;
4683
4684 assert(ret);
4685
4686 for (size_t i = 0; i < TPM2_PCRS_MAX; i++) {
4687 _cleanup_(json_variant_unrefp) JsonVariant *e = NULL;
4688
4689 if ((pcr_mask & (UINT32_C(1) << i)) == 0)
4690 continue;
4691
4692 r = json_variant_new_integer(&e, i);
4693 if (r < 0)
4694 return r;
4695
4696 r = json_variant_append_array(&a, e);
4697 if (r < 0)
4698 return r;
4699 }
4700
4701 if (!a)
4702 return json_variant_new_array(ret, NULL, 0);
4703
4704 *ret = TAKE_PTR(a);
4705 return 0;
4706 }
4707
4708 int tpm2_parse_pcr_json_array(JsonVariant *v, uint32_t *ret) {
4709 JsonVariant *e;
4710 uint32_t mask = 0;
4711
4712 if (!json_variant_is_array(v))
4713 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR array is not a JSON array.");
4714
4715 JSON_VARIANT_ARRAY_FOREACH(e, v) {
4716 uint64_t u;
4717
4718 if (!json_variant_is_unsigned(e))
4719 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR is not an unsigned integer.");
4720
4721 u = json_variant_unsigned(e);
4722 if (u >= TPM2_PCRS_MAX)
4723 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR number out of range: %" PRIu64, u);
4724
4725 mask |= UINT32_C(1) << u;
4726 }
4727
4728 if (ret)
4729 *ret = mask;
4730
4731 return 0;
4732 }
4733
4734 int tpm2_make_luks2_json(
4735 int keyslot,
4736 uint32_t hash_pcr_mask,
4737 uint16_t pcr_bank,
4738 const void *pubkey,
4739 size_t pubkey_size,
4740 uint32_t pubkey_pcr_mask,
4741 uint16_t primary_alg,
4742 const void *blob,
4743 size_t blob_size,
4744 const void *policy_hash,
4745 size_t policy_hash_size,
4746 const void *salt,
4747 size_t salt_size,
4748 const void *srk_buf,
4749 size_t srk_buf_size,
4750 TPM2Flags flags,
4751 JsonVariant **ret) {
4752
4753 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *hmj = NULL, *pkmj = NULL;
4754 _cleanup_free_ char *keyslot_as_string = NULL;
4755 int r;
4756
4757 assert(blob || blob_size == 0);
4758 assert(policy_hash || policy_hash_size == 0);
4759 assert(pubkey || pubkey_size == 0);
4760
4761 if (asprintf(&keyslot_as_string, "%i", keyslot) < 0)
4762 return -ENOMEM;
4763
4764 r = tpm2_make_pcr_json_array(hash_pcr_mask, &hmj);
4765 if (r < 0)
4766 return r;
4767
4768 if (pubkey_pcr_mask != 0) {
4769 r = tpm2_make_pcr_json_array(pubkey_pcr_mask, &pkmj);
4770 if (r < 0)
4771 return r;
4772 }
4773
4774 /* Note: We made the mistake of using "-" in the field names, which isn't particular compatible with
4775 * other programming languages. Let's not make things worse though, i.e. future additions to the JSON
4776 * object should use "_" rather than "-" in field names. */
4777
4778 r = json_build(&v,
4779 JSON_BUILD_OBJECT(
4780 JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-tpm2")),
4781 JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))),
4782 JSON_BUILD_PAIR("tpm2-blob", JSON_BUILD_BASE64(blob, blob_size)),
4783 JSON_BUILD_PAIR("tpm2-pcrs", JSON_BUILD_VARIANT(hmj)),
4784 JSON_BUILD_PAIR_CONDITION(!!tpm2_hash_alg_to_string(pcr_bank), "tpm2-pcr-bank", JSON_BUILD_STRING(tpm2_hash_alg_to_string(pcr_bank))),
4785 JSON_BUILD_PAIR_CONDITION(!!tpm2_asym_alg_to_string(primary_alg), "tpm2-primary-alg", JSON_BUILD_STRING(tpm2_asym_alg_to_string(primary_alg))),
4786 JSON_BUILD_PAIR("tpm2-policy-hash", JSON_BUILD_HEX(policy_hash, policy_hash_size)),
4787 JSON_BUILD_PAIR("tpm2-pin", JSON_BUILD_BOOLEAN(flags & TPM2_FLAGS_USE_PIN)),
4788 JSON_BUILD_PAIR_CONDITION(pubkey_pcr_mask != 0, "tpm2_pubkey_pcrs", JSON_BUILD_VARIANT(pkmj)),
4789 JSON_BUILD_PAIR_CONDITION(pubkey_pcr_mask != 0, "tpm2_pubkey", JSON_BUILD_BASE64(pubkey, pubkey_size)),
4790 JSON_BUILD_PAIR_CONDITION(salt, "tpm2_salt", JSON_BUILD_BASE64(salt, salt_size)),
4791 JSON_BUILD_PAIR_CONDITION(srk_buf, "tpm2_srk", JSON_BUILD_BASE64(srk_buf, srk_buf_size))));
4792 if (r < 0)
4793 return r;
4794
4795 if (ret)
4796 *ret = TAKE_PTR(v);
4797
4798 return keyslot;
4799 }
4800
4801 int tpm2_parse_luks2_json(
4802 JsonVariant *v,
4803 int *ret_keyslot,
4804 uint32_t *ret_hash_pcr_mask,
4805 uint16_t *ret_pcr_bank,
4806 void **ret_pubkey,
4807 size_t *ret_pubkey_size,
4808 uint32_t *ret_pubkey_pcr_mask,
4809 uint16_t *ret_primary_alg,
4810 void **ret_blob,
4811 size_t *ret_blob_size,
4812 void **ret_policy_hash,
4813 size_t *ret_policy_hash_size,
4814 void **ret_salt,
4815 size_t *ret_salt_size,
4816 void **ret_srk_buf,
4817 size_t *ret_srk_buf_size,
4818 TPM2Flags *ret_flags) {
4819
4820 _cleanup_free_ void *blob = NULL, *policy_hash = NULL, *pubkey = NULL, *salt = NULL, *srk_buf = NULL;
4821 size_t blob_size = 0, policy_hash_size = 0, pubkey_size = 0, salt_size = 0, srk_buf_size = 0;
4822 uint32_t hash_pcr_mask = 0, pubkey_pcr_mask = 0;
4823 uint16_t primary_alg = TPM2_ALG_ECC; /* ECC was the only supported algorithm in systemd < 250, use that as implied default, for compatibility */
4824 uint16_t pcr_bank = UINT16_MAX; /* default: pick automatically */
4825 int r, keyslot = -1;
4826 TPM2Flags flags = 0;
4827 JsonVariant *w;
4828
4829 assert(v);
4830
4831 if (ret_keyslot) {
4832 keyslot = cryptsetup_get_keyslot_from_token(v);
4833 if (keyslot < 0) {
4834 /* Return a recognizable error when parsing this field, so that callers can handle parsing
4835 * errors of the keyslots field gracefully, since it's not 'owned' by us, but by the LUKS2
4836 * spec */
4837 log_debug_errno(keyslot, "Failed to extract keyslot index from TPM2 JSON data token, skipping: %m");
4838 return -EUCLEAN;
4839 }
4840 }
4841
4842 w = json_variant_by_key(v, "tpm2-pcrs");
4843 if (!w)
4844 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-pcrs' field.");
4845
4846 r = tpm2_parse_pcr_json_array(w, &hash_pcr_mask);
4847 if (r < 0)
4848 return log_debug_errno(r, "Failed to parse TPM2 PCR mask: %m");
4849
4850 /* The bank field is optional, since it was added in systemd 250 only. Before the bank was hardcoded
4851 * to SHA256. */
4852 w = json_variant_by_key(v, "tpm2-pcr-bank");
4853 if (w) {
4854 /* The PCR bank field is optional */
4855
4856 if (!json_variant_is_string(w))
4857 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR bank is not a string.");
4858
4859 r = tpm2_hash_alg_from_string(json_variant_string(w));
4860 if (r < 0)
4861 return log_debug_errno(r, "TPM2 PCR bank invalid or not supported: %s", json_variant_string(w));
4862
4863 pcr_bank = r;
4864 }
4865
4866 /* The primary key algorithm field is optional, since it was also added in systemd 250 only. Before
4867 * the algorithm was hardcoded to ECC. */
4868 w = json_variant_by_key(v, "tpm2-primary-alg");
4869 if (w) {
4870 /* The primary key algorithm is optional */
4871
4872 if (!json_variant_is_string(w))
4873 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 primary key algorithm is not a string.");
4874
4875 r = tpm2_asym_alg_from_string(json_variant_string(w));
4876 if (r < 0)
4877 return log_debug_errno(r, "TPM2 asymmetric algorithm invalid or not supported: %s", json_variant_string(w));
4878
4879 primary_alg = r;
4880 }
4881
4882 w = json_variant_by_key(v, "tpm2-blob");
4883 if (!w)
4884 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-blob' field.");
4885
4886 r = json_variant_unbase64(w, &blob, &blob_size);
4887 if (r < 0)
4888 return log_debug_errno(r, "Invalid base64 data in 'tpm2-blob' field.");
4889
4890 w = json_variant_by_key(v, "tpm2-policy-hash");
4891 if (!w)
4892 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-policy-hash' field.");
4893
4894 r = json_variant_unhex(w, &policy_hash, &policy_hash_size);
4895 if (r < 0)
4896 return log_debug_errno(r, "Invalid base64 data in 'tpm2-policy-hash' field.");
4897
4898 w = json_variant_by_key(v, "tpm2-pin");
4899 if (w) {
4900 if (!json_variant_is_boolean(w))
4901 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PIN policy is not a boolean.");
4902
4903 SET_FLAG(flags, TPM2_FLAGS_USE_PIN, json_variant_boolean(w));
4904 }
4905
4906 w = json_variant_by_key(v, "tpm2_salt");
4907 if (w) {
4908 r = json_variant_unbase64(w, &salt, &salt_size);
4909 if (r < 0)
4910 return log_debug_errno(r, "Invalid base64 data in 'tpm2_salt' field.");
4911 }
4912
4913 w = json_variant_by_key(v, "tpm2_pubkey_pcrs");
4914 if (w) {
4915 r = tpm2_parse_pcr_json_array(w, &pubkey_pcr_mask);
4916 if (r < 0)
4917 return r;
4918 }
4919
4920 w = json_variant_by_key(v, "tpm2_pubkey");
4921 if (w) {
4922 r = json_variant_unbase64(w, &pubkey, &pubkey_size);
4923 if (r < 0)
4924 return log_debug_errno(r, "Failed to decode PCR public key.");
4925 } else if (pubkey_pcr_mask != 0)
4926 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Public key PCR mask set, but not public key included in JSON data, refusing.");
4927
4928 w = json_variant_by_key(v, "tpm2_srk");
4929 if (w) {
4930 r = json_variant_unbase64(w, &srk_buf, &srk_buf_size);
4931 if (r < 0)
4932 return log_debug_errno(r, "Invalid base64 data in 'tpm2_srk' field.");
4933 }
4934
4935 if (ret_keyslot)
4936 *ret_keyslot = keyslot;
4937 if (ret_hash_pcr_mask)
4938 *ret_hash_pcr_mask = hash_pcr_mask;
4939 if (ret_pcr_bank)
4940 *ret_pcr_bank = pcr_bank;
4941 if (ret_pubkey)
4942 *ret_pubkey = TAKE_PTR(pubkey);
4943 if (ret_pubkey_size)
4944 *ret_pubkey_size = pubkey_size;
4945 if (ret_pubkey_pcr_mask)
4946 *ret_pubkey_pcr_mask = pubkey_pcr_mask;
4947 if (ret_primary_alg)
4948 *ret_primary_alg = primary_alg;
4949 if (ret_blob)
4950 *ret_blob = TAKE_PTR(blob);
4951 if (ret_blob_size)
4952 *ret_blob_size = blob_size;
4953 if (ret_policy_hash)
4954 *ret_policy_hash = TAKE_PTR(policy_hash);
4955 if (ret_policy_hash_size)
4956 *ret_policy_hash_size = policy_hash_size;
4957 if (ret_salt)
4958 *ret_salt = TAKE_PTR(salt);
4959 if (ret_salt_size)
4960 *ret_salt_size = salt_size;
4961 if (ret_flags)
4962 *ret_flags = flags;
4963 if (ret_srk_buf)
4964 *ret_srk_buf = TAKE_PTR(srk_buf);
4965 if (ret_srk_buf_size)
4966 *ret_srk_buf_size = srk_buf_size;
4967
4968 return 0;
4969 }
4970
4971 int tpm2_hash_alg_to_size(uint16_t alg) {
4972 switch (alg) {
4973 case TPM2_ALG_SHA1:
4974 return 20;
4975 case TPM2_ALG_SHA256:
4976 return 32;
4977 case TPM2_ALG_SHA384:
4978 return 48;
4979 case TPM2_ALG_SHA512:
4980 return 64;
4981 default:
4982 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown hash algorithm id 0x%" PRIx16, alg);
4983 }
4984 }
4985
4986 const char *tpm2_hash_alg_to_string(uint16_t alg) {
4987 switch (alg) {
4988 case TPM2_ALG_SHA1:
4989 return "sha1";
4990 case TPM2_ALG_SHA256:
4991 return "sha256";
4992 case TPM2_ALG_SHA384:
4993 return "sha384";
4994 case TPM2_ALG_SHA512:
4995 return "sha512";
4996 default:
4997 log_debug("Unknown hash algorithm id 0x%" PRIx16, alg);
4998 return NULL;
4999 }
5000 }
5001
5002 int tpm2_hash_alg_from_string(const char *alg) {
5003 if (strcaseeq_ptr(alg, "sha1"))
5004 return TPM2_ALG_SHA1;
5005 if (strcaseeq_ptr(alg, "sha256"))
5006 return TPM2_ALG_SHA256;
5007 if (strcaseeq_ptr(alg, "sha384"))
5008 return TPM2_ALG_SHA384;
5009 if (strcaseeq_ptr(alg, "sha512"))
5010 return TPM2_ALG_SHA512;
5011 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown hash algorithm name '%s'", alg);
5012 }
5013
5014 const char *tpm2_asym_alg_to_string(uint16_t alg) {
5015 switch (alg) {
5016 case TPM2_ALG_ECC:
5017 return "ecc";
5018 case TPM2_ALG_RSA:
5019 return "rsa";
5020 default:
5021 log_debug("Unknown asymmetric algorithm id 0x%" PRIx16, alg);
5022 return NULL;
5023 }
5024 }
5025
5026 int tpm2_asym_alg_from_string(const char *alg) {
5027 if (strcaseeq_ptr(alg, "ecc"))
5028 return TPM2_ALG_ECC;
5029 if (strcaseeq_ptr(alg, "rsa"))
5030 return TPM2_ALG_RSA;
5031 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown asymmetric algorithm name '%s'", alg);
5032 }
5033
5034 Tpm2Support tpm2_support(void) {
5035 Tpm2Support support = TPM2_SUPPORT_NONE;
5036 int r;
5037
5038 if (detect_container() <= 0) {
5039 /* Check if there's a /dev/tpmrm* device via sysfs. If we run in a container we likely just
5040 * got the host sysfs mounted. Since devices are generally not virtualized for containers,
5041 * let's assume containers never have a TPM, at least for now. */
5042
5043 r = dir_is_empty("/sys/class/tpmrm", /* ignore_hidden_or_backup= */ false);
5044 if (r < 0) {
5045 if (r != -ENOENT)
5046 log_debug_errno(r, "Unable to test whether /sys/class/tpmrm/ exists and is populated, assuming it is not: %m");
5047 } else if (r == 0) /* populated! */
5048 support |= TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_DRIVER;
5049 else
5050 /* If the directory exists but is empty, we know the subsystem is enabled but no
5051 * driver has been loaded yet. */
5052 support |= TPM2_SUPPORT_SUBSYSTEM;
5053 }
5054
5055 if (efi_has_tpm2())
5056 support |= TPM2_SUPPORT_FIRMWARE;
5057
5058 #if HAVE_TPM2
5059 support |= TPM2_SUPPORT_SYSTEM;
5060
5061 r = dlopen_tpm2();
5062 if (r >= 0)
5063 support |= TPM2_SUPPORT_LIBRARIES;
5064 #endif
5065
5066 return support;
5067 }
5068
5069 #if HAVE_TPM2
5070 static void tpm2_pcr_values_apply_default_hash_alg(Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
5071 TPMI_ALG_HASH default_hash = 0;
5072 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
5073 if (v->hash != 0) {
5074 default_hash = v->hash;
5075 break;
5076 }
5077
5078 if (default_hash != 0)
5079 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
5080 if (v->hash == 0)
5081 v->hash = default_hash;
5082 }
5083 #endif
5084
5085 /* The following tpm2_parse_pcr_argument*() functions all log errors, to match the behavior of system-wide
5086 * parse_*_argument() functions. */
5087
5088 /* Parse the PCR selection/value arg(s) and return a corresponding array of Tpm2PCRValue objects.
5089 *
5090 * The format is the same as tpm2_pcr_values_from_string(). The first provided entry with a hash algorithm
5091 * set will be used as the 'default' hash algorithm. All entries with an unset hash algorithm will be updated
5092 * with the 'default' hash algorithm. The resulting array will be sorted and checked for validity.
5093 *
5094 * This will replace *ret_pcr_values with the new array of pcr values; to append to an existing array, use
5095 * tpm2_parse_pcr_argument_append(). */
5096 int tpm2_parse_pcr_argument(const char *arg, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values) {
5097 #if HAVE_TPM2
5098 int r;
5099
5100 assert(arg);
5101 assert(ret_pcr_values);
5102 assert(ret_n_pcr_values);
5103
5104 _cleanup_free_ Tpm2PCRValue *pcr_values = NULL;
5105 size_t n_pcr_values = 0;
5106 r = tpm2_pcr_values_from_string(arg, &pcr_values, &n_pcr_values);
5107 if (r < 0)
5108 return log_error_errno(r, "Could not parse PCR values from '%s': %m", arg);
5109
5110 tpm2_pcr_values_apply_default_hash_alg(pcr_values, n_pcr_values);
5111
5112 tpm2_sort_pcr_values(pcr_values, n_pcr_values);
5113
5114 if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values))
5115 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Parsed PCR values are not valid.");
5116
5117 *ret_pcr_values = TAKE_PTR(pcr_values);
5118 *ret_n_pcr_values = n_pcr_values;
5119
5120 return 0;
5121 #else
5122 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support is disabled.");
5123 #endif
5124 }
5125
5126 /* Same as tpm2_parse_pcr_argument(), but the pcr values array is appended to. If the provided pcr values
5127 * array is not NULL, it must point to an allocated pcr values array and the provided number of pcr values
5128 * must be correct.
5129 *
5130 * Note that 'arg' is parsed into a new array of pcr values independently of any previous pcr values,
5131 * including application of the default hash algorithm. Then the two arrays are combined, the default hash
5132 * algorithm check applied again (in case either the previous or current array had no default hash
5133 * algorithm), and then the resulting array is sorted and rechecked for validity. */
5134 int tpm2_parse_pcr_argument_append(const char *arg, Tpm2PCRValue **pcr_values, size_t *n_pcr_values) {
5135 #if HAVE_TPM2
5136 int r;
5137
5138 assert(arg);
5139 assert(pcr_values);
5140 assert(n_pcr_values);
5141
5142 _cleanup_free_ Tpm2PCRValue *more_pcr_values = NULL;
5143 size_t n_more_pcr_values;
5144 r = tpm2_parse_pcr_argument(arg, &more_pcr_values, &n_more_pcr_values);
5145 if (r < 0)
5146 return r;
5147
5148 /* If we got previous values, append them. */
5149 if (*pcr_values && !GREEDY_REALLOC_APPEND(more_pcr_values, n_more_pcr_values, *pcr_values, *n_pcr_values))
5150 return log_oom();
5151
5152 tpm2_pcr_values_apply_default_hash_alg(more_pcr_values, n_more_pcr_values);
5153
5154 tpm2_sort_pcr_values(more_pcr_values, n_more_pcr_values);
5155
5156 if (!tpm2_pcr_values_valid(more_pcr_values, n_more_pcr_values))
5157 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Parsed PCR values are not valid.");
5158
5159 SWAP_TWO(*pcr_values, more_pcr_values);
5160 *n_pcr_values = n_more_pcr_values;
5161
5162 return 0;
5163 #else
5164 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support is disabled.");
5165 #endif
5166 }
5167
5168 /* Same as tpm2_parse_pcr_argument() but converts the pcr values to a pcr mask. If more than one hash
5169 * algorithm is included in the pcr values array this results in error. This retains the previous behavior of
5170 * tpm2_parse_pcr_argument() of clearing the mask if 'arg' is empty, replacing the mask if it is set to
5171 * UINT32_MAX, and or-ing the mask otherwise. */
5172 int tpm2_parse_pcr_argument_to_mask(const char *arg, uint32_t *ret_mask) {
5173 #if HAVE_TPM2
5174 _cleanup_free_ Tpm2PCRValue *pcr_values = NULL;
5175 size_t n_pcr_values;
5176 int r;
5177
5178 assert(arg);
5179 assert(ret_mask);
5180
5181 r = tpm2_parse_pcr_argument(arg, &pcr_values, &n_pcr_values);
5182 if (r < 0)
5183 return r;
5184
5185 if (n_pcr_values == 0) {
5186 /* This retains the previous behavior of clearing the mask if the arg is empty */
5187 *ret_mask = 0;
5188 return 0;
5189 }
5190
5191 size_t hash_count;
5192 r = tpm2_pcr_values_hash_count(pcr_values, n_pcr_values, &hash_count);
5193 if (r < 0)
5194 return log_error_errno(r, "Could not get hash count from pcr values: %m");
5195
5196 if (hash_count > 1)
5197 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Multiple PCR hash banks selected.");
5198
5199 uint32_t new_mask;
5200 r = tpm2_pcr_values_to_mask(pcr_values, n_pcr_values, pcr_values[0].hash, &new_mask);
5201 if (r < 0)
5202 return log_error_errno(r, "Could not get pcr values mask: %m");
5203
5204 if (*ret_mask == UINT32_MAX)
5205 *ret_mask = new_mask;
5206 else
5207 *ret_mask |= new_mask;
5208
5209 return 0;
5210 #else
5211 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support is disabled.");
5212 #endif
5213 }
5214
5215 int tpm2_load_pcr_signature(const char *path, JsonVariant **ret) {
5216 _cleanup_strv_free_ char **search = NULL;
5217 _cleanup_free_ char *discovered_path = NULL;
5218 _cleanup_fclose_ FILE *f = NULL;
5219 int r;
5220
5221 /* Tries to load a JSON PCR signature file. Takes an absolute path, a simple file name or NULL. In
5222 * the latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
5223
5224 search = strv_split_nulstr(CONF_PATHS_NULSTR("systemd"));
5225 if (!search)
5226 return log_oom_debug();
5227
5228 if (!path) {
5229 /* If no path is specified, then look for "tpm2-pcr-signature.json" automatically. Also, in
5230 * this case include /.extra/ in the search path, but only in this case, and if we run in the
5231 * initrd. We don't want to be too eager here, after all /.extra/ is untrusted territory. */
5232
5233 path = "tpm2-pcr-signature.json";
5234
5235 if (in_initrd())
5236 if (strv_extend(&search, "/.extra") < 0)
5237 return log_oom_debug();
5238 }
5239
5240 r = search_and_fopen(path, "re", NULL, (const char**) search, &f, &discovered_path);
5241 if (r < 0)
5242 return log_debug_errno(r, "Failed to find TPM PCR signature file '%s': %m", path);
5243
5244 r = json_parse_file(f, discovered_path, 0, ret, NULL, NULL);
5245 if (r < 0)
5246 return log_debug_errno(r, "Failed to parse TPM PCR signature JSON object '%s': %m", discovered_path);
5247
5248 return 0;
5249 }
5250
5251 int tpm2_load_pcr_public_key(const char *path, void **ret_pubkey, size_t *ret_pubkey_size) {
5252 _cleanup_free_ char *discovered_path = NULL;
5253 _cleanup_fclose_ FILE *f = NULL;
5254 int r;
5255
5256 /* Tries to load a PCR public key file. Takes an absolute path, a simple file name or NULL. In the
5257 * latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
5258
5259 if (!path)
5260 path = "tpm2-pcr-public-key.pem";
5261
5262 r = search_and_fopen(path, "re", NULL, (const char**) CONF_PATHS_STRV("systemd"), &f, &discovered_path);
5263 if (r < 0)
5264 return log_debug_errno(r, "Failed to find TPM PCR public key file '%s': %m", path);
5265
5266 r = read_full_stream(f, (char**) ret_pubkey, ret_pubkey_size);
5267 if (r < 0)
5268 return log_debug_errno(r, "Failed to load TPM PCR public key PEM file '%s': %m", discovered_path);
5269
5270 return 0;
5271 }
5272
5273 #define PBKDF2_HMAC_SHA256_ITERATIONS 10000
5274
5275 /*
5276 * Implements PBKDF2 HMAC SHA256 for a derived keylen of 32
5277 * bytes and for PBKDF2_HMAC_SHA256_ITERATIONS count.
5278 * I found the wikipedia entry relevant and it contains links to
5279 * relevant RFCs:
5280 * - https://en.wikipedia.org/wiki/PBKDF2
5281 * - https://www.rfc-editor.org/rfc/rfc2898#section-5.2
5282 */
5283 int tpm2_util_pbkdf2_hmac_sha256(const void *pass,
5284 size_t passlen,
5285 const void *salt,
5286 size_t saltlen,
5287 uint8_t ret_key[static SHA256_DIGEST_SIZE]) {
5288
5289 uint8_t _cleanup_(erase_and_freep) *buffer = NULL;
5290 uint8_t u[SHA256_DIGEST_SIZE];
5291
5292 /* To keep this simple, since derived KeyLen (dkLen in docs)
5293 * Is the same as the hash output, we don't need multiple
5294 * blocks. Part of the algorithm is to add the block count
5295 * in, but this can be hardcoded to 1.
5296 */
5297 static const uint8_t block_cnt[] = { 0, 0, 0, 1 };
5298
5299 assert (salt);
5300 assert (saltlen > 0);
5301 assert (saltlen <= (SIZE_MAX - sizeof(block_cnt)));
5302 assert (passlen > 0);
5303
5304 /*
5305 * Build a buffer of salt + block_cnt and hmac_sha256 it we
5306 * do this as we don't have a context builder for HMAC_SHA256.
5307 */
5308 buffer = malloc(saltlen + sizeof(block_cnt));
5309 if (!buffer)
5310 return -ENOMEM;
5311
5312 memcpy(buffer, salt, saltlen);
5313 memcpy(&buffer[saltlen], block_cnt, sizeof(block_cnt));
5314
5315 hmac_sha256(pass, passlen, buffer, saltlen + sizeof(block_cnt), u);
5316
5317 /* dk needs to be an unmodified u as u gets modified in the loop */
5318 memcpy(ret_key, u, SHA256_DIGEST_SIZE);
5319 uint8_t *dk = ret_key;
5320
5321 for (size_t i = 1; i < PBKDF2_HMAC_SHA256_ITERATIONS; i++) {
5322 hmac_sha256(pass, passlen, u, sizeof(u), u);
5323
5324 for (size_t j=0; j < sizeof(u); j++)
5325 dk[j] ^= u[j];
5326 }
5327
5328 return 0;
5329 }
5330
5331 static const char* const tpm2_pcr_index_table[_TPM2_PCR_INDEX_MAX_DEFINED] = {
5332 [TPM2_PCR_PLATFORM_CODE] = "platform-code",
5333 [TPM2_PCR_PLATFORM_CONFIG] = "platform-config",
5334 [TPM2_PCR_EXTERNAL_CODE] = "external-code",
5335 [TPM2_PCR_EXTERNAL_CONFIG] = "external-config",
5336 [TPM2_PCR_BOOT_LOADER_CODE] = "boot-loader-code",
5337 [TPM2_PCR_BOOT_LOADER_CONFIG] = "boot-loader-config",
5338 [TPM2_PCR_HOST_PLATFORM] = "host-platform",
5339 [TPM2_PCR_SECURE_BOOT_POLICY] = "secure-boot-policy",
5340 [TPM2_PCR_KERNEL_INITRD] = "kernel-initrd",
5341 [TPM2_PCR_IMA] = "ima",
5342 [TPM2_PCR_KERNEL_BOOT] = "kernel-boot",
5343 [TPM2_PCR_KERNEL_CONFIG] = "kernel-config",
5344 [TPM2_PCR_SYSEXTS] = "sysexts",
5345 [TPM2_PCR_SHIM_POLICY] = "shim-policy",
5346 [TPM2_PCR_SYSTEM_IDENTITY] = "system-identity",
5347 [TPM2_PCR_DEBUG] = "debug",
5348 [TPM2_PCR_APPLICATION_SUPPORT] = "application-support",
5349 };
5350
5351 DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_FALLBACK(tpm2_pcr_index, int, TPM2_PCRS_MAX - 1);
5352 DEFINE_STRING_TABLE_LOOKUP_TO_STRING(tpm2_pcr_index, int);