]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/tpm2-util.c
man/systemd-sysext: list ephemeral/ephemeral-import in the list of options
[thirdparty/systemd.git] / src / shared / tpm2-util.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <sys/file.h>
4 #include <unistd.h>
5
6 #include "alloc-util.h"
7 #include "ansi-color.h"
8 #include "bitfield.h"
9 #include "constants.h"
10 #include "creds-util.h"
11 #include "cryptsetup-util.h"
12 #include "dirent-util.h"
13 #include "dlfcn-util.h"
14 #include "efi-api.h"
15 #include "extract-word.h"
16 #include "fd-util.h"
17 #include "fileio.h"
18 #include "format-table.h"
19 #include "fs-util.h"
20 #include "hexdecoct.h"
21 #include "hmac.h"
22 #include "initrd-util.h"
23 #include "io-util.h"
24 #include "json-util.h"
25 #include "log.h"
26 #include "logarithm.h"
27 #include "memory-util.h"
28 #include "mkdir.h"
29 #include "ordered-set.h"
30 #include "random-util.h"
31 #include "recurse-dir.h"
32 #include "siphash24.h"
33 #include "sort-util.h"
34 #include "sparse-endian.h"
35 #include "stat-util.h"
36 #include "string-table.h"
37 #include "string-util.h"
38 #include "strv.h"
39 #include "sync-util.h"
40 #include "time-util.h"
41 #include "tpm2-pcr.h"
42 #include "tpm2-util.h"
43 #include "virt.h"
44
45 #if HAVE_OPENSSL
46 # include <openssl/hmac.h>
47 #endif
48
49 #if HAVE_TPM2
50 static void *libtss2_esys_dl = NULL;
51 static void *libtss2_rc_dl = NULL;
52 static void *libtss2_mu_dl = NULL;
53
54 static DLSYM_PROTOTYPE(Esys_Create) = NULL;
55 static DLSYM_PROTOTYPE(Esys_CreateLoaded) = NULL;
56 static DLSYM_PROTOTYPE(Esys_CreatePrimary) = NULL;
57 static DLSYM_PROTOTYPE(Esys_EvictControl) = NULL;
58 static DLSYM_PROTOTYPE(Esys_Finalize) = NULL;
59 static DLSYM_PROTOTYPE(Esys_FlushContext) = NULL;
60 static DLSYM_PROTOTYPE(Esys_Free) = NULL;
61 static DLSYM_PROTOTYPE(Esys_GetCapability) = NULL;
62 static DLSYM_PROTOTYPE(Esys_GetRandom) = NULL;
63 static DLSYM_PROTOTYPE(Esys_Import) = NULL;
64 static DLSYM_PROTOTYPE(Esys_Initialize) = NULL;
65 static DLSYM_PROTOTYPE(Esys_Load) = NULL;
66 static DLSYM_PROTOTYPE(Esys_LoadExternal) = NULL;
67 static DLSYM_PROTOTYPE(Esys_NV_DefineSpace) = NULL;
68 static DLSYM_PROTOTYPE(Esys_NV_UndefineSpace) = NULL;
69 static DLSYM_PROTOTYPE(Esys_NV_Write) = NULL;
70 static DLSYM_PROTOTYPE(Esys_PCR_Extend) = NULL;
71 static DLSYM_PROTOTYPE(Esys_PCR_Read) = NULL;
72 static DLSYM_PROTOTYPE(Esys_PolicyAuthValue) = NULL;
73 static DLSYM_PROTOTYPE(Esys_PolicyAuthorize) = NULL;
74 static DLSYM_PROTOTYPE(Esys_PolicyAuthorizeNV) = NULL;
75 static DLSYM_PROTOTYPE(Esys_PolicyGetDigest) = NULL;
76 static DLSYM_PROTOTYPE(Esys_PolicyOR) = NULL;
77 static DLSYM_PROTOTYPE(Esys_PolicyPCR) = NULL;
78 static DLSYM_PROTOTYPE(Esys_PolicySigned) = NULL;
79 static DLSYM_PROTOTYPE(Esys_ReadPublic) = NULL;
80 static DLSYM_PROTOTYPE(Esys_StartAuthSession) = NULL;
81 static DLSYM_PROTOTYPE(Esys_Startup) = NULL;
82 static DLSYM_PROTOTYPE(Esys_TestParms) = NULL;
83 static DLSYM_PROTOTYPE(Esys_TR_Close) = NULL;
84 static DLSYM_PROTOTYPE(Esys_TR_Deserialize) = NULL;
85 static DLSYM_PROTOTYPE(Esys_TR_FromTPMPublic) = NULL;
86 static DLSYM_PROTOTYPE(Esys_TR_GetName) = NULL;
87 static DLSYM_PROTOTYPE(Esys_TR_GetTpmHandle) = NULL;
88 static DLSYM_PROTOTYPE(Esys_TR_Serialize) = NULL;
89 static DLSYM_PROTOTYPE(Esys_TR_SetAuth) = NULL;
90 static DLSYM_PROTOTYPE(Esys_TRSess_GetAttributes) = NULL;
91 static DLSYM_PROTOTYPE(Esys_TRSess_GetNonceTPM) = NULL;
92 static DLSYM_PROTOTYPE(Esys_TRSess_SetAttributes) = NULL;
93 static DLSYM_PROTOTYPE(Esys_Unseal) = NULL;
94 static DLSYM_PROTOTYPE(Esys_VerifySignature) = NULL;
95
96 static DLSYM_PROTOTYPE(Tss2_MU_TPM2_CC_Marshal) = NULL;
97 static DLSYM_PROTOTYPE(Tss2_MU_TPM2_HANDLE_Marshal) = NULL;
98 static DLSYM_PROTOTYPE(Tss2_MU_TPM2B_DIGEST_Marshal) = NULL;
99 static DLSYM_PROTOTYPE(Tss2_MU_TPM2B_ENCRYPTED_SECRET_Marshal) = NULL;
100 static DLSYM_PROTOTYPE(Tss2_MU_TPM2B_ENCRYPTED_SECRET_Unmarshal) = NULL;
101 static DLSYM_PROTOTYPE(Tss2_MU_TPM2B_NAME_Marshal) = NULL;
102 static DLSYM_PROTOTYPE(Tss2_MU_TPM2B_PRIVATE_Marshal) = NULL;
103 static DLSYM_PROTOTYPE(Tss2_MU_TPM2B_PRIVATE_Unmarshal) = NULL;
104 static DLSYM_PROTOTYPE(Tss2_MU_TPM2B_PUBLIC_Marshal) = NULL;
105 static DLSYM_PROTOTYPE(Tss2_MU_TPM2B_PUBLIC_Unmarshal) = NULL;
106 static DLSYM_PROTOTYPE(Tss2_MU_TPM2B_SENSITIVE_Marshal) = NULL;
107 static DLSYM_PROTOTYPE(Tss2_MU_TPML_PCR_SELECTION_Marshal) = NULL;
108 static DLSYM_PROTOTYPE(Tss2_MU_TPMS_NV_PUBLIC_Marshal) = NULL;
109 static DLSYM_PROTOTYPE(Tss2_MU_TPM2B_NV_PUBLIC_Marshal) = NULL;
110 static DLSYM_PROTOTYPE(Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal) = NULL;
111 static DLSYM_PROTOTYPE(Tss2_MU_TPMS_ECC_POINT_Marshal) = NULL;
112 static DLSYM_PROTOTYPE(Tss2_MU_TPMT_HA_Marshal) = NULL;
113 static DLSYM_PROTOTYPE(Tss2_MU_TPMT_PUBLIC_Marshal) = NULL;
114 static DLSYM_PROTOTYPE(Tss2_MU_UINT32_Marshal) = NULL;
115
116 static DLSYM_PROTOTYPE(Tss2_RC_Decode) = NULL;
117
118 static int dlopen_tpm2_esys(void) {
119 int r;
120
121 ELF_NOTE_DLOPEN("tpm",
122 "Support for TPM",
123 ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
124 "libtss2-esys.so.0");
125
126 r = dlopen_many_sym_or_warn(
127 &libtss2_esys_dl, "libtss2-esys.so.0", LOG_DEBUG,
128 DLSYM_ARG(Esys_Create),
129 DLSYM_ARG(Esys_CreateLoaded),
130 DLSYM_ARG(Esys_CreatePrimary),
131 DLSYM_ARG(Esys_EvictControl),
132 DLSYM_ARG(Esys_Finalize),
133 DLSYM_ARG(Esys_FlushContext),
134 DLSYM_ARG(Esys_Free),
135 DLSYM_ARG(Esys_GetCapability),
136 DLSYM_ARG(Esys_GetRandom),
137 DLSYM_ARG(Esys_Import),
138 DLSYM_ARG(Esys_Initialize),
139 DLSYM_ARG(Esys_Load),
140 DLSYM_ARG(Esys_LoadExternal),
141 DLSYM_ARG(Esys_NV_DefineSpace),
142 DLSYM_ARG(Esys_NV_UndefineSpace),
143 DLSYM_ARG(Esys_NV_Write),
144 DLSYM_ARG(Esys_PCR_Extend),
145 DLSYM_ARG(Esys_PCR_Read),
146 DLSYM_ARG(Esys_PolicyAuthValue),
147 DLSYM_ARG(Esys_PolicyAuthorize),
148 DLSYM_ARG(Esys_PolicyAuthorizeNV),
149 DLSYM_ARG(Esys_PolicyGetDigest),
150 DLSYM_ARG(Esys_PolicyOR),
151 DLSYM_ARG(Esys_PolicyPCR),
152 DLSYM_ARG(Esys_PolicySigned),
153 DLSYM_ARG(Esys_ReadPublic),
154 DLSYM_ARG(Esys_StartAuthSession),
155 DLSYM_ARG(Esys_Startup),
156 DLSYM_ARG(Esys_TestParms),
157 DLSYM_ARG(Esys_TR_Close),
158 DLSYM_ARG(Esys_TR_Deserialize),
159 DLSYM_ARG(Esys_TR_FromTPMPublic),
160 DLSYM_ARG(Esys_TR_GetName),
161 DLSYM_ARG(Esys_TR_Serialize),
162 DLSYM_ARG(Esys_TR_SetAuth),
163 DLSYM_ARG(Esys_TRSess_GetAttributes),
164 DLSYM_ARG(Esys_TRSess_GetNonceTPM),
165 DLSYM_ARG(Esys_TRSess_SetAttributes),
166 DLSYM_ARG(Esys_Unseal),
167 DLSYM_ARG(Esys_VerifySignature));
168 if (r < 0)
169 return r;
170
171 /* Esys_TR_GetTpmHandle was added to tpm2-tss in version 2.4.0. Once we can set a minimum tpm2-tss
172 * version of 2.4.0 this sym can be moved up to the normal list above. */
173 r = dlsym_many_or_warn(libtss2_esys_dl, LOG_DEBUG, DLSYM_ARG_FORCE(Esys_TR_GetTpmHandle));
174 if (r < 0)
175 log_debug("libtss2-esys too old, does not include Esys_TR_GetTpmHandle.");
176
177 return 0;
178 }
179
180 static int dlopen_tpm2_rc(void) {
181 ELF_NOTE_DLOPEN("tpm",
182 "Support for TPM",
183 ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
184 "libtss2-rc.so.0");
185
186 return dlopen_many_sym_or_warn(
187 &libtss2_rc_dl, "libtss2-rc.so.0", LOG_DEBUG,
188 DLSYM_ARG(Tss2_RC_Decode));
189 }
190
191 static int dlopen_tpm2_mu(void) {
192 ELF_NOTE_DLOPEN("tpm",
193 "Support for TPM",
194 ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
195 "libtss2-mu.so.0");
196
197 return dlopen_many_sym_or_warn(
198 &libtss2_mu_dl, "libtss2-mu.so.0", LOG_DEBUG,
199 DLSYM_ARG(Tss2_MU_TPM2_CC_Marshal),
200 DLSYM_ARG(Tss2_MU_TPM2_HANDLE_Marshal),
201 DLSYM_ARG(Tss2_MU_TPM2B_DIGEST_Marshal),
202 DLSYM_ARG(Tss2_MU_TPM2B_ENCRYPTED_SECRET_Marshal),
203 DLSYM_ARG(Tss2_MU_TPM2B_ENCRYPTED_SECRET_Unmarshal),
204 DLSYM_ARG(Tss2_MU_TPM2B_NAME_Marshal),
205 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Marshal),
206 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Unmarshal),
207 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Marshal),
208 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Unmarshal),
209 DLSYM_ARG(Tss2_MU_TPM2B_SENSITIVE_Marshal),
210 DLSYM_ARG(Tss2_MU_TPML_PCR_SELECTION_Marshal),
211 DLSYM_ARG(Tss2_MU_TPMS_NV_PUBLIC_Marshal),
212 DLSYM_ARG(Tss2_MU_TPM2B_NV_PUBLIC_Marshal),
213 DLSYM_ARG(Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal),
214 DLSYM_ARG(Tss2_MU_TPMS_ECC_POINT_Marshal),
215 DLSYM_ARG(Tss2_MU_TPMT_HA_Marshal),
216 DLSYM_ARG(Tss2_MU_TPMT_PUBLIC_Marshal),
217 DLSYM_ARG(Tss2_MU_UINT32_Marshal));
218 }
219
220 int dlopen_tpm2(void) {
221 int r;
222
223 r = dlopen_tpm2_esys();
224 if (r < 0)
225 return r;
226
227 r = dlopen_tpm2_rc();
228 if (r < 0)
229 return r;
230
231 r = dlopen_tpm2_mu();
232 if (r < 0)
233 return r;
234
235 return 0;
236 }
237
238 void Esys_Freep(void *p) {
239 assert(p);
240
241 if (*(void**) p)
242 sym_Esys_Free(*(void**) p);
243 }
244
245 static void tpm2b_sensitive_data_erase_and_esys_freep(TPM2B_SENSITIVE_DATA **p) {
246 assert(p);
247
248 if (!*p)
249 return;
250
251 explicit_bzero_safe((*p)->buffer, (*p)->size);
252 sym_Esys_Free(*p);
253 }
254
255 /* Get a specific TPM capability (or capabilities).
256 *
257 * Returns 0 if there are no more capability properties of the requested type, or 1 if there are more, or < 0
258 * on any error. Both 0 and 1 indicate this completed successfully, but do not indicate how many capability
259 * properties were provided in 'ret_capability_data'. To find the number of provided properties, check the
260 * specific type's 'count' field (e.g. for TPM2_CAP_ALGS, check ret_capability_data->algorithms.count).
261 *
262 * This calls TPM2_GetCapability() and does not alter the provided data, so it is important to understand how
263 * that TPM function works. It is recommended to check the TCG TPM specification Part 3 ("Commands") section
264 * on TPM2_GetCapability() for full details, but a short summary is: if this returns 0, all available
265 * properties have been provided in ret_capability_data, or no properties were available. If this returns 1,
266 * there are between 1 and "count" properties provided in ret_capability_data, and there are more available.
267 * Note that this may provide less than "count" properties even if the TPM has more available. Also, each
268 * capability category may have more specific requirements than described here; see the spec for exact
269 * details. */
270 static int tpm2_get_capability(
271 Tpm2Context *c,
272 TPM2_CAP capability,
273 uint32_t property,
274 uint32_t count,
275 TPMU_CAPABILITIES *ret_capability_data) {
276
277 _cleanup_(Esys_Freep) TPMS_CAPABILITY_DATA *capabilities = NULL;
278 TPMI_YES_NO more;
279 TSS2_RC rc;
280
281 assert(c);
282
283 log_debug("Getting TPM2 capability 0x%04" PRIx32 " property 0x%04" PRIx32 " count %" PRIu32 ".",
284 capability, property, count);
285
286 rc = sym_Esys_GetCapability(
287 c->esys_context,
288 ESYS_TR_NONE,
289 ESYS_TR_NONE,
290 ESYS_TR_NONE,
291 capability,
292 property,
293 count,
294 &more,
295 &capabilities);
296 if (rc == TPM2_RC_VALUE)
297 return log_debug_errno(SYNTHETIC_ERRNO(ENXIO),
298 "Requested TPM2 capability 0x%04" PRIx32 " property 0x%04" PRIx32 " apparently doesn't exist: %s",
299 capability, property, sym_Tss2_RC_Decode(rc));
300 if (rc != TSS2_RC_SUCCESS)
301 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
302 "Failed to get TPM2 capability 0x%04" PRIx32 " property 0x%04" PRIx32 ": %s",
303 capability, property, sym_Tss2_RC_Decode(rc));
304 if (capabilities->capability != capability)
305 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
306 "TPM provided wrong capability: 0x%04" PRIx32 " instead of 0x%04" PRIx32 ".",
307 capabilities->capability, capability);
308
309 if (ret_capability_data)
310 *ret_capability_data = capabilities->data;
311
312 return more == TPM2_YES;
313 }
314
315 #define TPMA_CC_TO_TPM2_CC(cca) (((cca) & TPMA_CC_COMMANDINDEX_MASK) >> TPMA_CC_COMMANDINDEX_SHIFT)
316
317 static int tpm2_cache_capabilities(Tpm2Context *c) {
318 TPMU_CAPABILITIES capability;
319 int r;
320
321 assert(c);
322
323 /* Cache the algorithms. The spec indicates supported algorithms can only be modified during runtime
324 * by the SetAlgorithmSet() command. Unfortunately, the spec doesn't require a TPM reinitialization
325 * after changing the algorithm set (unless the PCR algorithms are changed). However, the spec also
326 * indicates the TPM behavior after SetAlgorithmSet() is "vendor-dependent", giving the example of
327 * flushing sessions and objects, erasing policies, etc. So, if the algorithm set is programmatically
328 * changed while we are performing some operation, it's reasonable to assume it will break us even if
329 * we don't cache the algorithms, thus they should be "safe" to cache. */
330 TPM2_ALG_ID current_alg = TPM2_ALG_FIRST;
331 for (;;) {
332 r = tpm2_get_capability(
333 c,
334 TPM2_CAP_ALGS,
335 (uint32_t) current_alg, /* The spec states to cast TPM2_ALG_ID to uint32_t. */
336 TPM2_MAX_CAP_ALGS,
337 &capability);
338 if (r < 0)
339 return r;
340
341 TPML_ALG_PROPERTY algorithms = capability.algorithms;
342
343 /* We should never get 0; the TPM must support some algorithms, and it must not set 'more' if
344 * there are no more. */
345 assert(algorithms.count > 0);
346
347 if (!GREEDY_REALLOC_APPEND(
348 c->capability_algorithms,
349 c->n_capability_algorithms,
350 algorithms.algProperties,
351 algorithms.count))
352 return log_oom_debug();
353
354 if (r == 0)
355 break;
356
357 /* Set current_alg to alg id after last alg id the TPM provided */
358 current_alg = algorithms.algProperties[algorithms.count - 1].alg + 1;
359 }
360
361 /* Cache the command capabilities. The spec isn't actually clear if commands can be added/removed
362 * while running, but that would be crazy, so let's hope it is not possible. */
363 TPM2_CC current_cc = TPM2_CC_FIRST;
364 for (;;) {
365 r = tpm2_get_capability(
366 c,
367 TPM2_CAP_COMMANDS,
368 current_cc,
369 TPM2_MAX_CAP_CC,
370 &capability);
371 if (r < 0)
372 return r;
373
374 TPML_CCA commands = capability.command;
375
376 /* We should never get 0; the TPM must support some commands, and it must not set 'more' if
377 * there are no more. */
378 assert(commands.count > 0);
379
380 if (!GREEDY_REALLOC_APPEND(
381 c->capability_commands,
382 c->n_capability_commands,
383 commands.commandAttributes,
384 commands.count))
385 return log_oom_debug();
386
387 if (r == 0)
388 break;
389
390 /* Set current_cc to index after last cc the TPM provided */
391 current_cc = TPMA_CC_TO_TPM2_CC(commands.commandAttributes[commands.count - 1]) + 1;
392 }
393
394 /* Cache the ECC curves. The spec isn't actually clear if ECC curves can be added/removed
395 * while running, but that would be crazy, so let's hope it is not possible. */
396 TPM2_ECC_CURVE current_ecc_curve = TPM2_ECC_NONE;
397 for (;;) {
398 r = tpm2_get_capability(
399 c,
400 TPM2_CAP_ECC_CURVES,
401 current_ecc_curve,
402 TPM2_MAX_ECC_CURVES,
403 &capability);
404 if (r == -ENXIO) /* If the TPM doesn't support ECC, it might return TPM2_RC_VALUE rather than capability.eccCurves == 0 */
405 break;
406 if (r < 0)
407 return r;
408
409 TPML_ECC_CURVE ecc_curves = capability.eccCurves;
410
411 /* ECC support isn't required */
412 if (ecc_curves.count == 0)
413 break;
414
415 if (!GREEDY_REALLOC_APPEND(
416 c->capability_ecc_curves,
417 c->n_capability_ecc_curves,
418 ecc_curves.eccCurves,
419 ecc_curves.count))
420 return log_oom_debug();
421
422 if (r == 0)
423 break;
424
425 /* Set current_ecc_curve to index after last ecc curve the TPM provided */
426 current_ecc_curve = ecc_curves.eccCurves[ecc_curves.count - 1] + 1;
427 }
428
429 /* Cache the PCR capabilities, which are safe to cache, as the only way they can change is
430 * TPM2_PCR_Allocate(), which changes the allocation after the next _TPM_Init(). If the TPM is
431 * reinitialized while we are using it, all our context and sessions will be invalid, so we can
432 * safely assume the TPM PCR allocation will not change while we are using it. */
433 r = tpm2_get_capability(
434 c,
435 TPM2_CAP_PCRS,
436 /* property= */ 0,
437 /* count= */ 1,
438 &capability);
439 if (r < 0)
440 return r;
441 if (r == 1)
442 /* This should never happen. Part 3 ("Commands") of the TCG TPM2 spec in the section for
443 * TPM2_GetCapability states: "TPM_CAP_PCRS – Returns the current allocation of PCR in a
444 * TPML_PCR_SELECTION. The property parameter shall be zero. The TPM will always respond to
445 * this command with the full PCR allocation and moreData will be NO." */
446 log_debug("TPM bug: reported multiple PCR sets; using only first set.");
447 c->capability_pcrs = capability.assignedPCR;
448
449 return 0;
450 }
451
452 /* Get the TPMA_ALGORITHM for a TPM2_ALG_ID. Returns true if the TPM supports the algorithm and the
453 * TPMA_ALGORITHM is provided, otherwise false. */
454 static bool tpm2_get_capability_alg(Tpm2Context *c, TPM2_ALG_ID alg, TPMA_ALGORITHM *ret) {
455 assert(c);
456
457 FOREACH_ARRAY(alg_prop, c->capability_algorithms, c->n_capability_algorithms)
458 if (alg_prop->alg == alg) {
459 if (ret)
460 *ret = alg_prop->algProperties;
461 return true;
462 }
463
464 log_debug("TPM does not support alg 0x%02" PRIx16 ".", alg);
465 if (ret)
466 *ret = 0;
467
468 return false;
469 }
470
471 bool tpm2_supports_alg(Tpm2Context *c, TPM2_ALG_ID alg) {
472 return tpm2_get_capability_alg(c, alg, NULL);
473 }
474
475 /* Get the TPMA_CC for a TPM2_CC. Returns true if the TPM supports the command and the TPMA_CC is provided,
476 * otherwise false. */
477 static bool tpm2_get_capability_command(Tpm2Context *c, TPM2_CC command, TPMA_CC *ret) {
478 assert(c);
479
480 FOREACH_ARRAY(cca, c->capability_commands, c->n_capability_commands)
481 if (TPMA_CC_TO_TPM2_CC(*cca) == command) {
482 if (ret)
483 *ret = *cca;
484 return true;
485 }
486
487 log_debug("TPM does not support command 0x%04" PRIx32 ".", command);
488 if (ret)
489 *ret = 0;
490
491 return false;
492 }
493
494 bool tpm2_supports_command(Tpm2Context *c, TPM2_CC command) {
495 return tpm2_get_capability_command(c, command, NULL);
496 }
497
498 /* Returns true if the TPM supports the ECC curve, otherwise false. */
499 bool tpm2_supports_ecc_curve(Tpm2Context *c, TPM2_ECC_CURVE ecc_curve) {
500 assert(c);
501
502 FOREACH_ARRAY(curve, c->capability_ecc_curves, c->n_capability_ecc_curves)
503 if (*curve == ecc_curve)
504 return true;
505
506 log_debug("TPM does not support ECC curve 0x%" PRIx16 ".", ecc_curve);
507 return false;
508 }
509
510 /* Query the TPM for populated handles.
511 *
512 * This provides an array of handle indexes populated in the TPM, starting at the requested handle. The array will
513 * contain only populated handle addresses (which might not include the requested handle). The number of
514 * handles will be no more than the 'max' number requested. This will not search past the end of the handle
515 * range (i.e. handle & 0xff000000).
516 *
517 * Returns 0 if all populated handles in the range (starting at the requested handle) were provided (or no
518 * handles were in the range), or 1 if there are more populated handles in the range, or < 0 on any error. */
519 static int tpm2_get_capability_handles(
520 Tpm2Context *c,
521 TPM2_HANDLE start,
522 size_t max,
523 TPM2_HANDLE **ret_handles,
524 size_t *ret_n_handles) {
525
526 _cleanup_free_ TPM2_HANDLE *handles = NULL;
527 size_t n_handles = 0;
528 TPM2_HANDLE current = start;
529 int r = 0;
530
531 assert(c);
532 assert(ret_handles);
533 assert(ret_n_handles);
534
535 max = MIN(max, UINT32_MAX);
536
537 while (max > 0) {
538 TPMU_CAPABILITIES capability;
539 r = tpm2_get_capability(c, TPM2_CAP_HANDLES, current, (uint32_t) max, &capability);
540 if (r < 0)
541 return r;
542
543 TPML_HANDLE handle_list = capability.handles;
544 if (handle_list.count == 0)
545 break;
546
547 assert(handle_list.count <= max);
548
549 if (n_handles > SIZE_MAX - handle_list.count)
550 return log_oom_debug();
551
552 if (!GREEDY_REALLOC_APPEND(handles, n_handles, handle_list.handle, handle_list.count))
553 return log_oom_debug();
554
555 max -= handle_list.count;
556
557 /* Update current to the handle index after the last handle in the list. */
558 current = handles[n_handles - 1] + 1;
559
560 if (r == 0)
561 /* No more handles in this range. */
562 break;
563 }
564
565 *ret_handles = TAKE_PTR(handles);
566 *ret_n_handles = n_handles;
567
568 return r;
569 }
570
571 #define TPM2_HANDLE_RANGE(h) ((TPM2_HANDLE)((h) & TPM2_HR_RANGE_MASK))
572 #define TPM2_HANDLE_TYPE(h) ((TPM2_HT)(TPM2_HANDLE_RANGE(h) >> TPM2_HR_SHIFT))
573
574 /* Returns 1 if the handle is populated in the TPM, 0 if not, and < 0 on any error. */
575 static int tpm2_get_capability_handle(Tpm2Context *c, TPM2_HANDLE handle) {
576 _cleanup_free_ TPM2_HANDLE *handles = NULL;
577 size_t n_handles = 0;
578 int r;
579
580 r = tpm2_get_capability_handles(c, handle, 1, &handles, &n_handles);
581 if (r < 0)
582 return r;
583
584 return n_handles == 0 ? false : handles[0] == handle;
585 }
586
587 /* Returns 1 if the TPM supports the parms, or 0 if the TPM does not support the parms. */
588 bool tpm2_test_parms(Tpm2Context *c, TPMI_ALG_PUBLIC alg, const TPMU_PUBLIC_PARMS *parms) {
589 TSS2_RC rc;
590
591 assert(c);
592 assert(parms);
593
594 TPMT_PUBLIC_PARMS parameters = {
595 .type = alg,
596 .parameters = *parms,
597 };
598
599 rc = sym_Esys_TestParms(c->esys_context, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, &parameters);
600 if (rc != TSS2_RC_SUCCESS)
601 /* The spec says if the parms are not supported the TPM returns "...the appropriate
602 * unmarshaling error if a parameter is not valid". Since the spec (currently) defines 15
603 * unmarshaling errors, instead of checking for them all here, let's just assume any error
604 * indicates unsupported parms, and log the specific error text. */
605 log_debug("TPM does not support tested parms: %s", sym_Tss2_RC_Decode(rc));
606
607 return rc == TSS2_RC_SUCCESS;
608 }
609
610 static bool tpm2_supports_tpmt_public(Tpm2Context *c, const TPMT_PUBLIC *public) {
611 assert(c);
612 assert(public);
613
614 return tpm2_test_parms(c, public->type, &public->parameters);
615 }
616
617 static bool tpm2_supports_tpmt_sym_def_object(Tpm2Context *c, const TPMT_SYM_DEF_OBJECT *parameters) {
618 assert(c);
619 assert(parameters);
620
621 TPMU_PUBLIC_PARMS parms = {
622 .symDetail.sym = *parameters,
623 };
624
625 return tpm2_test_parms(c, TPM2_ALG_SYMCIPHER, &parms);
626 }
627
628 static bool tpm2_supports_tpmt_sym_def(Tpm2Context *c, const TPMT_SYM_DEF *parameters) {
629 assert(c);
630 assert(parameters);
631
632 /* Unfortunately, TPMT_SYM_DEF and TPMT_SYM_DEF_OBEJECT are separately defined, even though they are
633 * functionally identical. */
634 TPMT_SYM_DEF_OBJECT object = {
635 .algorithm = parameters->algorithm,
636 .keyBits = parameters->keyBits,
637 .mode = parameters->mode,
638 };
639
640 return tpm2_supports_tpmt_sym_def_object(c, &object);
641 }
642
643 static Tpm2Context *tpm2_context_free(Tpm2Context *c) {
644 if (!c)
645 return NULL;
646
647 if (c->esys_context)
648 sym_Esys_Finalize(&c->esys_context);
649
650 c->tcti_context = mfree(c->tcti_context);
651 c->tcti_dl = safe_dlclose(c->tcti_dl);
652
653 c->capability_algorithms = mfree(c->capability_algorithms);
654 c->capability_commands = mfree(c->capability_commands);
655 c->capability_ecc_curves = mfree(c->capability_ecc_curves);
656
657 return mfree(c);
658 }
659
660 DEFINE_TRIVIAL_REF_UNREF_FUNC(Tpm2Context, tpm2_context, tpm2_context_free);
661
662 static const TPMT_SYM_DEF SESSION_TEMPLATE_SYM_AES_128_CFB = {
663 .algorithm = TPM2_ALG_AES,
664 .keyBits.aes = 128,
665 .mode.aes = TPM2_ALG_CFB, /* The spec requires sessions to use CFB. */
666 };
667
668 int tpm2_context_new(const char *device, Tpm2Context **ret_context) {
669 _cleanup_(tpm2_context_unrefp) Tpm2Context *context = NULL;
670 TSS2_RC rc;
671 int r;
672
673 assert(ret_context);
674
675 context = new(Tpm2Context, 1);
676 if (!context)
677 return log_oom_debug();
678
679 *context = (Tpm2Context) {
680 .n_ref = 1,
681 };
682
683 r = dlopen_tpm2();
684 if (r < 0)
685 return log_debug_errno(r, "TPM2 support not installed: %m");
686
687 if (!device) {
688 device = secure_getenv("SYSTEMD_TPM2_DEVICE");
689 if (device)
690 /* Setting the env var to an empty string forces tpm2-tss' own device picking
691 * logic to be used. */
692 device = empty_to_null(device);
693 else
694 /* If nothing was specified explicitly, we'll use a hardcoded default: the "device" tcti
695 * driver and the "/dev/tpmrm0" device. We do this since on some distributions the tpm2-abrmd
696 * might be used and we really don't want that, since it is a system service and that creates
697 * various ordering issues/deadlocks during early boot. */
698 device = "device:/dev/tpmrm0";
699 }
700
701 if (device) {
702 const char *param, *driver, *fn;
703 const TSS2_TCTI_INFO* info;
704 TSS2_TCTI_INFO_FUNC func;
705 size_t sz = 0;
706
707 param = strchr(device, ':');
708 if (param) {
709 /* Syntax #1: Pair of driver string and arbitrary parameter */
710 driver = strndupa_safe(device, param - device);
711 if (isempty(driver))
712 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name is empty, refusing.");
713
714 param++;
715 } else if (path_is_absolute(device) && path_is_valid(device)) {
716 /* Syntax #2: TPM device node */
717 driver = "device";
718 param = device;
719 } else
720 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid TPM2 driver string, refusing.");
721
722 log_debug("Using TPM2 TCTI driver '%s' with device '%s'.", driver, param);
723
724 fn = strjoina("libtss2-tcti-", driver, ".so.0");
725
726 /* Better safe than sorry, let's refuse strings that cannot possibly be valid driver early, before going to disk. */
727 if (!filename_is_valid(fn))
728 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name '%s' not valid, refusing.", driver);
729
730 context->tcti_dl = dlopen(fn, RTLD_NOW|RTLD_NODELETE);
731 if (!context->tcti_dl)
732 return log_debug_errno(SYNTHETIC_ERRNO(ENOPKG), "Failed to load %s: %s", fn, dlerror());
733
734 log_debug("Loaded '%s' via dlopen()", fn);
735
736 func = dlsym(context->tcti_dl, TSS2_TCTI_INFO_SYMBOL);
737 if (!func)
738 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
739 "Failed to find TCTI info symbol " TSS2_TCTI_INFO_SYMBOL ": %s",
740 dlerror());
741
742 info = func();
743 if (!info)
744 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to get TCTI info data.");
745
746 log_debug("Loaded TCTI module '%s' (%s) [Version %" PRIu32 "]", info->name, info->description, info->version);
747
748 rc = info->init(/* context= */ NULL, &sz, /* param= */ NULL);
749 if (rc != TPM2_RC_SUCCESS)
750 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
751 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));
752
753 context->tcti_context = malloc0(sz);
754 if (!context->tcti_context)
755 return log_oom_debug();
756
757 rc = info->init(context->tcti_context, &sz, param);
758 if (rc != TPM2_RC_SUCCESS)
759 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
760 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));
761 }
762
763 rc = sym_Esys_Initialize(&context->esys_context, context->tcti_context, NULL);
764 if (rc != TSS2_RC_SUCCESS)
765 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
766 "Failed to initialize TPM context: %s", sym_Tss2_RC_Decode(rc));
767
768 rc = sym_Esys_Startup(context->esys_context, TPM2_SU_CLEAR);
769 if (rc == TPM2_RC_INITIALIZE)
770 log_debug("TPM already started up.");
771 else if (rc == TSS2_RC_SUCCESS)
772 log_debug("TPM successfully started up.");
773 else
774 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
775 "Failed to start up TPM: %s", sym_Tss2_RC_Decode(rc));
776
777 r = tpm2_cache_capabilities(context);
778 if (r < 0)
779 return log_debug_errno(r, "Failed to cache TPM capabilities: %m");
780
781 /* We require AES and CFB support for session encryption. */
782 if (!tpm2_supports_alg(context, TPM2_ALG_AES))
783 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM does not support AES.");
784
785 if (!tpm2_supports_alg(context, TPM2_ALG_CFB))
786 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM does not support CFB.");
787
788 if (!tpm2_supports_tpmt_sym_def(context, &SESSION_TEMPLATE_SYM_AES_128_CFB))
789 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM does not support AES-128-CFB.");
790
791 *ret_context = TAKE_PTR(context);
792
793 return 0;
794 }
795
796 int tpm2_context_new_or_warn(const char *device, Tpm2Context **ret_context) {
797 int r;
798
799 assert(ret_context);
800
801 r = tpm2_context_new(device, ret_context);
802 if (r == -EOPNOTSUPP)
803 return log_error_errno(r, "TPM device not usable as it does not support the required functionality (AES-128-CFB missing?).");
804 if (r == -ENOPKG)
805 return log_error_errno(r, "TPM TCTI driver not available.");
806 if (r == -ENOENT)
807 return log_error_errno(r, "TPM device not found.");
808 if (r < 0)
809 return log_error_errno(r, "Failed to create TPM2 context: %m");
810
811 return 0;
812 }
813
814 static void tpm2_handle_cleanup(ESYS_CONTEXT *esys_context, ESYS_TR esys_handle, bool flush) {
815 TSS2_RC rc;
816
817 if (!esys_context || esys_handle == ESYS_TR_NONE)
818 return;
819
820 /* Closing the handle removes its reference from the esys_context, but leaves the corresponding
821 * handle in the actual TPM. Flushing the handle removes its reference from the esys_context as well
822 * as removing its corresponding handle from the actual TPM. */
823 if (flush)
824 rc = sym_Esys_FlushContext(esys_context, esys_handle);
825 else
826 /* We can't use Esys_TR_Close() because the tpm2-tss library does not use reference counting
827 * for handles, and a single Esys_TR_Close() will remove the handle (internal to the tpm2-tss
828 * library) that might be in use by other code that is using the same ESYS_CONTEXT. This
829 * directly affects us; for example the src/test/test-tpm2.c test function
830 * check_seal_unseal() will encounter this issue and will result in a failure when trying to
831 * cleanup (i.e. Esys_FlushContext) the transient primary key that the test function
832 * generates. However, not calling Esys_TR_Close() here should be ok, since any leaked handle
833 * references will be cleaned up when we free our ESYS_CONTEXT.
834 *
835 * An upstream bug is open here: https://github.com/tpm2-software/tpm2-tss/issues/2693 */
836 rc = TSS2_RC_SUCCESS; // FIXME: restore sym_Esys_TR_Close() use once tpm2-tss is fixed and adopted widely enough
837 if (rc != TSS2_RC_SUCCESS)
838 /* We ignore failures here (besides debug logging), since this is called in error paths,
839 * where we cannot do anything about failures anymore. And when it is called in successful
840 * codepaths by this time we already did what we wanted to do, and got the results we wanted
841 * so there's no reason to make this fail more loudly than necessary. */
842 log_debug("Failed to %s TPM handle, ignoring: %s", flush ? "flush" : "close", sym_Tss2_RC_Decode(rc));
843 }
844
845 Tpm2Handle *tpm2_handle_free(Tpm2Handle *handle) {
846 if (!handle)
847 return NULL;
848
849 _cleanup_(tpm2_context_unrefp) Tpm2Context *context = (Tpm2Context*)handle->tpm2_context;
850 if (context)
851 tpm2_handle_cleanup(context->esys_context, handle->esys_handle, handle->flush);
852
853 return mfree(handle);
854 }
855
856 int tpm2_handle_new(Tpm2Context *context, Tpm2Handle **ret_handle) {
857 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
858
859 assert(ret_handle);
860
861 handle = new(Tpm2Handle, 1);
862 if (!handle)
863 return log_oom_debug();
864
865 *handle = (Tpm2Handle) {
866 .tpm2_context = tpm2_context_ref(context),
867 .esys_handle = ESYS_TR_NONE,
868 .flush = true,
869 };
870
871 *ret_handle = TAKE_PTR(handle);
872
873 return 0;
874 }
875
876 static int tpm2_read_public(
877 Tpm2Context *c,
878 const Tpm2Handle *session,
879 const Tpm2Handle *handle,
880 TPM2B_PUBLIC **ret_public,
881 TPM2B_NAME **ret_name,
882 TPM2B_NAME **ret_qname) {
883
884 TSS2_RC rc;
885
886 assert(c);
887 assert(handle);
888
889 rc = sym_Esys_ReadPublic(
890 c->esys_context,
891 handle->esys_handle,
892 session ? session->esys_handle : ESYS_TR_NONE,
893 ESYS_TR_NONE,
894 ESYS_TR_NONE,
895 ret_public,
896 ret_name,
897 ret_qname);
898 if (rc != TSS2_RC_SUCCESS)
899 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
900 "Failed to read public info: %s", sym_Tss2_RC_Decode(rc));
901
902 return 0;
903 }
904
905 /* Create a Tpm2Handle object that references a pre-existing handle in the TPM, at the handle index provided.
906 * This should be used only for persistent, transient, or NV handles; and the handle must already exist in
907 * the TPM at the specified handle index. The handle index should not be 0. Returns 1 if found, 0 if the
908 * index is empty, or < 0 on error. Also see tpm2_get_srk() below; the SRK is a commonly used persistent
909 * Tpm2Handle. */
910 int tpm2_index_to_handle(
911 Tpm2Context *c,
912 TPM2_HANDLE index,
913 const Tpm2Handle *session,
914 TPM2B_PUBLIC **ret_public,
915 TPM2B_NAME **ret_name,
916 TPM2B_NAME **ret_qname,
917 Tpm2Handle **ret_handle) {
918
919 TSS2_RC rc;
920 int r;
921
922 assert(c);
923
924 /* Only allow persistent, transient, or NV index handle types. */
925 switch (TPM2_HANDLE_TYPE(index)) {
926 case TPM2_HT_PERSISTENT:
927 case TPM2_HT_NV_INDEX:
928 case TPM2_HT_TRANSIENT:
929 break;
930 case TPM2_HT_PCR:
931 /* PCR handles are referenced by their actual index number and do not need a Tpm2Handle */
932 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
933 "Invalid handle 0x%08" PRIx32 " (in PCR range).", index);
934 case TPM2_HT_HMAC_SESSION:
935 case TPM2_HT_POLICY_SESSION:
936 /* Session indexes are only used internally by tpm2-tss (or lower code) */
937 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
938 "Invalid handle 0x%08" PRIx32 " (in session range).", index);
939 case TPM2_HT_PERMANENT:
940 /* Permanent handles are defined, e.g. ESYS_TR_RH_OWNER. */
941 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
942 "Invalid handle 0x%08" PRIx32 " (in permanent range).", index);
943 default:
944 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
945 "Invalid handle 0x%08" PRIx32 " (in unknown range).", index);
946 }
947
948 /* For transient handles, the kernel tpm "resource manager" (i.e. /dev/tpmrm0) performs mapping
949 * which breaks GetCapability requests, so only check GetCapability if it's not a transient handle.
950 * https://bugzilla.kernel.org/show_bug.cgi?id=218009 */
951 if (TPM2_HANDLE_TYPE(index) != TPM2_HT_TRANSIENT) { // FIXME: once kernel bug is fixed, check transient handles too
952 r = tpm2_get_capability_handle(c, index);
953 if (r < 0)
954 return r;
955 if (r == 0) {
956 log_debug("TPM handle 0x%08" PRIx32 " not populated.", index);
957 if (ret_public)
958 *ret_public = NULL;
959 if (ret_name)
960 *ret_name = NULL;
961 if (ret_qname)
962 *ret_qname = NULL;
963 if (ret_handle)
964 *ret_handle = NULL;
965 return 0;
966 }
967 }
968
969 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
970 r = tpm2_handle_new(c, &handle);
971 if (r < 0)
972 return r;
973
974 /* Since we didn't create this handle in the TPM (this is only creating an ESYS_TR handle for the
975 * pre-existing TPM handle), we shouldn't flush (or evict) it on cleanup. */
976 handle->flush = false;
977
978 rc = sym_Esys_TR_FromTPMPublic(
979 c->esys_context,
980 index,
981 session ? session->esys_handle : ESYS_TR_NONE,
982 ESYS_TR_NONE,
983 ESYS_TR_NONE,
984 &handle->esys_handle);
985 if (rc != TSS2_RC_SUCCESS)
986 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
987 "Failed to read public info: %s", sym_Tss2_RC_Decode(rc));
988
989 if (ret_public || ret_name || ret_qname) {
990 r = tpm2_read_public(c, session, handle, ret_public, ret_name, ret_qname);
991 if (r < 0)
992 return r;
993 }
994
995 if (ret_handle)
996 *ret_handle = TAKE_PTR(handle);
997
998 return 1;
999 }
1000
1001 /* Get the handle index for the provided Tpm2Handle. */
1002 int tpm2_index_from_handle(Tpm2Context *c, const Tpm2Handle *handle, TPM2_HANDLE *ret_index) {
1003 TSS2_RC rc;
1004
1005 assert(c);
1006 assert(handle);
1007 assert(ret_index);
1008
1009 /* Esys_TR_GetTpmHandle was added to tpm2-tss in version 2.4.0. Once we can set a minimum tpm2-tss
1010 * version of 2.4.0 this check can be removed. */
1011 if (!sym_Esys_TR_GetTpmHandle)
1012 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1013 "libtss2-esys too old, does not include Esys_TR_GetTpmHandle.");
1014
1015 rc = sym_Esys_TR_GetTpmHandle(c->esys_context, handle->esys_handle, ret_index);
1016 if (rc != TSS2_RC_SUCCESS)
1017 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1018 "Failed to get handle index: %s", sym_Tss2_RC_Decode(rc));
1019
1020 return 0;
1021 }
1022
1023 /* Copy an object in the TPM at a transient handle to a persistent handle.
1024 *
1025 * The provided transient handle must exist in the TPM in the transient range. The persistent handle may be 0
1026 * or any handle in the persistent range. If 0, this will try each handle in the persistent range, in
1027 * ascending order, until an available one is found. If non-zero, only the requested persistent handle will
1028 * be used.
1029 *
1030 * Note that the persistent handle parameter is an handle index (i.e. number), while the transient handle is
1031 * a Tpm2Handle object. The returned persistent handle will be a Tpm2Handle object that is located in the TPM
1032 * at the requested persistent handle index (or the first available if none was requested).
1033 *
1034 * Returns 1 if the object was successfully persisted, or 0 if there is already a key at the requested
1035 * handle, or < 0 on error. Theoretically, this would also return 0 if no specific persistent handle is
1036 * requested but all persistent handles are used, but it is extremely unlikely the TPM has enough internal
1037 * memory to store the entire persistent range, in which case an error will be returned if the TPM is out of
1038 * memory for persistent storage. The persistent handle is only provided when returning 1. */
1039 static int tpm2_persist_handle(
1040 Tpm2Context *c,
1041 const Tpm2Handle *transient_handle,
1042 const Tpm2Handle *session,
1043 TPMI_DH_PERSISTENT persistent_handle_index,
1044 Tpm2Handle **ret_persistent_handle) {
1045
1046 /* We don't use TPM2_PERSISTENT_FIRST and TPM2_PERSISTENT_LAST here due to:
1047 * https://github.com/systemd/systemd/pull/27713#issuecomment-1591864753 */
1048 TPMI_DH_PERSISTENT first = UINT32_C(0x81000000), last = UINT32_C(0x81ffffff);
1049 TSS2_RC rc;
1050 int r;
1051
1052 assert(c);
1053 assert(transient_handle);
1054
1055 /* If persistent handle index specified, only try that. */
1056 if (persistent_handle_index != 0) {
1057 if (TPM2_HANDLE_TYPE(persistent_handle_index) != TPM2_HT_PERSISTENT)
1058 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
1059 "Handle not in persistent range: 0x%x", persistent_handle_index);
1060
1061 first = last = persistent_handle_index;
1062 }
1063
1064 for (TPMI_DH_PERSISTENT requested = first; requested <= last; requested++) {
1065 _cleanup_(tpm2_handle_freep) Tpm2Handle *persistent_handle = NULL;
1066 r = tpm2_handle_new(c, &persistent_handle);
1067 if (r < 0)
1068 return r;
1069
1070 /* Since this is a persistent handle, don't flush it. */
1071 persistent_handle->flush = false;
1072
1073 rc = sym_Esys_EvictControl(
1074 c->esys_context,
1075 ESYS_TR_RH_OWNER,
1076 transient_handle->esys_handle,
1077 session ? session->esys_handle : ESYS_TR_PASSWORD,
1078 ESYS_TR_NONE,
1079 ESYS_TR_NONE,
1080 requested,
1081 &persistent_handle->esys_handle);
1082 if (rc == TSS2_RC_SUCCESS) {
1083 if (ret_persistent_handle)
1084 *ret_persistent_handle = TAKE_PTR(persistent_handle);
1085
1086 return 1;
1087 }
1088 if (rc != TPM2_RC_NV_DEFINED)
1089 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1090 "Failed to persist handle: %s", sym_Tss2_RC_Decode(rc));
1091 }
1092
1093 if (ret_persistent_handle)
1094 *ret_persistent_handle = NULL;
1095
1096 return 0;
1097 }
1098
1099 #define TPM2_CREDIT_RANDOM_FLAG_PATH "/run/systemd/tpm-rng-credited"
1100
1101 static int tpm2_credit_random(Tpm2Context *c) {
1102 size_t rps, done = 0;
1103 TSS2_RC rc;
1104 usec_t t;
1105 int r;
1106
1107 assert(c);
1108
1109 /* Pulls some entropy from the TPM and adds it into the kernel RNG pool. That way we can say that the
1110 * key we will ultimately generate with the kernel random pool is at least as good as the TPM's RNG,
1111 * but likely better. Note that we don't trust the TPM RNG very much, hence do not actually credit
1112 * any entropy. */
1113
1114 if (access(TPM2_CREDIT_RANDOM_FLAG_PATH, F_OK) < 0) {
1115 if (errno != ENOENT)
1116 log_debug_errno(errno, "Failed to detect if '" TPM2_CREDIT_RANDOM_FLAG_PATH "' exists, ignoring: %m");
1117 } else {
1118 log_debug("Not adding TPM2 entropy to the kernel random pool again.");
1119 return 0; /* Already done */
1120 }
1121
1122 t = now(CLOCK_MONOTONIC);
1123
1124 for (rps = random_pool_size(); rps > 0;) {
1125 _cleanup_(Esys_Freep) TPM2B_DIGEST *buffer = NULL;
1126
1127 rc = sym_Esys_GetRandom(
1128 c->esys_context,
1129 ESYS_TR_NONE,
1130 ESYS_TR_NONE,
1131 ESYS_TR_NONE,
1132 MIN(rps, 32U), /* 32 is supposedly a safe choice, given that AES 256bit keys are this long, and TPM2 baseline requires support for those. */
1133 &buffer);
1134 if (rc != TSS2_RC_SUCCESS)
1135 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1136 "Failed to acquire entropy from TPM: %s", sym_Tss2_RC_Decode(rc));
1137
1138 if (buffer->size == 0)
1139 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1140 "Zero-sized entropy returned from TPM.");
1141
1142 r = random_write_entropy(-1, buffer->buffer, buffer->size, /* credit= */ false);
1143 if (r < 0)
1144 return log_debug_errno(r, "Failed wo write entropy to kernel: %m");
1145
1146 done += buffer->size;
1147 rps = LESS_BY(rps, buffer->size);
1148 }
1149
1150 log_debug("Added %zu bytes of TPM2 entropy to the kernel random pool in %s.", done, FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - t, 0));
1151
1152 r = touch(TPM2_CREDIT_RANDOM_FLAG_PATH);
1153 if (r < 0)
1154 log_debug_errno(r, "Failed to touch '" TPM2_CREDIT_RANDOM_FLAG_PATH "', ignoring: %m");
1155
1156 return 0;
1157 }
1158
1159 /* Get one of the legacy primary key templates.
1160 *
1161 * The legacy templates should only be used for older sealed data that did not use the SRK. Instead of a
1162 * persistent SRK, a transient key was created to seal the data and then flushed; and the exact same template
1163 * must be used to recreate the same transient key to unseal the data. The alg parameter must be TPM2_ALG_RSA
1164 * or TPM2_ALG_ECC. This does not check if the alg is actually supported on this TPM. */
1165 static int tpm2_get_legacy_template(TPMI_ALG_PUBLIC alg, TPMT_PUBLIC *ret_template) {
1166 /* Do not modify. */
1167 static const TPMT_PUBLIC legacy_ecc = {
1168 .type = TPM2_ALG_ECC,
1169 .nameAlg = TPM2_ALG_SHA256,
1170 .objectAttributes =
1171 TPMA_OBJECT_RESTRICTED|
1172 TPMA_OBJECT_DECRYPT|
1173 TPMA_OBJECT_FIXEDTPM|
1174 TPMA_OBJECT_FIXEDPARENT|
1175 TPMA_OBJECT_SENSITIVEDATAORIGIN|
1176 TPMA_OBJECT_USERWITHAUTH,
1177 .parameters.eccDetail = {
1178 .symmetric = {
1179 .algorithm = TPM2_ALG_AES,
1180 .keyBits.aes = 128,
1181 .mode.aes = TPM2_ALG_CFB,
1182 },
1183 .scheme.scheme = TPM2_ALG_NULL,
1184 .curveID = TPM2_ECC_NIST_P256,
1185 .kdf.scheme = TPM2_ALG_NULL,
1186 },
1187 };
1188
1189 /* Do not modify. */
1190 static const TPMT_PUBLIC legacy_rsa = {
1191 .type = TPM2_ALG_RSA,
1192 .nameAlg = TPM2_ALG_SHA256,
1193 .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH,
1194 .parameters.rsaDetail = {
1195 .symmetric = {
1196 .algorithm = TPM2_ALG_AES,
1197 .keyBits.aes = 128,
1198 .mode.aes = TPM2_ALG_CFB,
1199 },
1200 .scheme.scheme = TPM2_ALG_NULL,
1201 .keyBits = 2048,
1202 },
1203 };
1204
1205 assert(ret_template);
1206
1207 if (alg == TPM2_ALG_ECC)
1208 *ret_template = legacy_ecc;
1209 else if (alg == TPM2_ALG_RSA)
1210 *ret_template = legacy_rsa;
1211 else
1212 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1213 "Unsupported legacy SRK alg: 0x%x", alg);
1214
1215 return 0;
1216 }
1217
1218 /* Get a Storage Root Key (SRK) template.
1219 *
1220 * The SRK template values are recommended by the "TCG TPM v2.0 Provisioning Guidance" document in section
1221 * 7.5.1 "Storage Primary Key (SRK) Templates", referencing "TCG EK Credential Profile for TPM Family 2.0".
1222 * The EK Credential Profile version 2.0 provides only a single template each for RSA and ECC, while later EK
1223 * Credential Profile versions provide more templates, and keep the original templates as "L-1" (for RSA) and
1224 * "L-2" (for ECC).
1225 *
1226 * https://trustedcomputinggroup.org/resource/tcg-tpm-v2-0-provisioning-guidance
1227 * https://trustedcomputinggroup.org/resource/http-trustedcomputinggroup-org-wp-content-uploads-tcg-ek-credential-profile
1228 *
1229 * These templates are only needed to create a new persistent SRK (or a new transient key that is
1230 * SRK-compatible). Preferably, the TPM should contain a shared SRK located at the reserved shared SRK handle
1231 * (see TPM2_SRK_HANDLE in tpm2-util.h, and tpm2_get_srk() below).
1232 *
1233 * Returns 0 if the specified algorithm is ECC or RSA, otherwise -EOPNOTSUPP. */
1234 int tpm2_get_srk_template(TPMI_ALG_PUBLIC alg, TPMT_PUBLIC *ret_template) {
1235 /* The attributes are the same between ECC and RSA templates. This has the changes specified in the
1236 * Provisioning Guidance document, specifically:
1237 * TPMA_OBJECT_USERWITHAUTH is added.
1238 * TPMA_OBJECT_ADMINWITHPOLICY is removed.
1239 * TPMA_OBJECT_NODA is added. */
1240 TPMA_OBJECT srk_attributes =
1241 TPMA_OBJECT_DECRYPT |
1242 TPMA_OBJECT_FIXEDPARENT |
1243 TPMA_OBJECT_FIXEDTPM |
1244 TPMA_OBJECT_NODA |
1245 TPMA_OBJECT_RESTRICTED |
1246 TPMA_OBJECT_SENSITIVEDATAORIGIN |
1247 TPMA_OBJECT_USERWITHAUTH;
1248
1249 /* The symmetric configuration is the same between ECC and RSA templates. */
1250 TPMT_SYM_DEF_OBJECT srk_symmetric = {
1251 .algorithm = TPM2_ALG_AES,
1252 .keyBits.aes = 128,
1253 .mode.aes = TPM2_ALG_CFB,
1254 };
1255
1256 /* Both templates have an empty authPolicy as specified by the Provisioning Guidance document. */
1257
1258 /* From the EK Credential Profile template "L-2". */
1259 TPMT_PUBLIC srk_ecc = {
1260 .type = TPM2_ALG_ECC,
1261 .nameAlg = TPM2_ALG_SHA256,
1262 .objectAttributes = srk_attributes,
1263 .parameters.eccDetail = {
1264 .symmetric = srk_symmetric,
1265 .scheme.scheme = TPM2_ALG_NULL,
1266 .curveID = TPM2_ECC_NIST_P256,
1267 .kdf.scheme = TPM2_ALG_NULL,
1268 },
1269 };
1270
1271 /* From the EK Credential Profile template "L-1". */
1272 TPMT_PUBLIC srk_rsa = {
1273 .type = TPM2_ALG_RSA,
1274 .nameAlg = TPM2_ALG_SHA256,
1275 .objectAttributes = srk_attributes,
1276 .parameters.rsaDetail = {
1277 .symmetric = srk_symmetric,
1278 .scheme.scheme = TPM2_ALG_NULL,
1279 .keyBits = 2048,
1280 },
1281 };
1282
1283 assert(ret_template);
1284
1285 switch (alg) {
1286 case TPM2_ALG_ECC:
1287 *ret_template = srk_ecc;
1288 return 0;
1289 case TPM2_ALG_RSA:
1290 *ret_template = srk_rsa;
1291 return 0;
1292 }
1293
1294 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "No SRK for algorithm 0x%" PRIx16, alg);
1295 }
1296
1297 /* Get the best supported SRK template. ECC is preferred, then RSA. */
1298 int tpm2_get_best_srk_template(Tpm2Context *c, TPMT_PUBLIC *ret_template) {
1299 TPMT_PUBLIC template;
1300 int r;
1301
1302 assert(c);
1303 assert(ret_template);
1304
1305 r = tpm2_get_srk_template(TPM2_ALG_ECC, &template);
1306 if (r < 0)
1307 return r;
1308
1309 if (!tpm2_supports_alg(c, TPM2_ALG_ECC))
1310 log_debug("TPM does not support ECC.");
1311 else if (!tpm2_supports_ecc_curve(c, template.parameters.eccDetail.curveID))
1312 log_debug("TPM does not support ECC-NIST-P256 curve.");
1313 else if (!tpm2_supports_tpmt_public(c, &template))
1314 log_debug("TPM does not support SRK ECC template L-2.");
1315 else {
1316 *ret_template = template;
1317 return 0;
1318 }
1319
1320 r = tpm2_get_srk_template(TPM2_ALG_RSA, &template);
1321 if (r < 0)
1322 return r;
1323
1324 if (!tpm2_supports_alg(c, TPM2_ALG_RSA))
1325 log_debug("TPM does not support RSA.");
1326 else if (!tpm2_supports_tpmt_public(c, &template))
1327 log_debug("TPM does not support SRK RSA template L-1.");
1328 else {
1329 *ret_template = template;
1330 return 0;
1331 }
1332
1333 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1334 "TPM does not support either SRK template L-1 (RSA) or L-2 (ECC).");
1335 }
1336
1337 /* Get the SRK. Returns 1 if SRK is found, 0 if there is no SRK, or < 0 on error. Also see
1338 * tpm2_get_or_create_srk() below. */
1339 int tpm2_get_srk(
1340 Tpm2Context *c,
1341 const Tpm2Handle *session,
1342 TPM2B_PUBLIC **ret_public,
1343 TPM2B_NAME **ret_name,
1344 TPM2B_NAME **ret_qname,
1345 Tpm2Handle **ret_handle) {
1346
1347 return tpm2_index_to_handle(c, TPM2_SRK_HANDLE, session, ret_public, ret_name, ret_qname, ret_handle);
1348 }
1349
1350 /* Get the SRK, creating one if needed. Returns 1 if a new SRK was created and persisted, 0 if an SRK already
1351 * exists, or < 0 on error. */
1352 int tpm2_get_or_create_srk(
1353 Tpm2Context *c,
1354 const Tpm2Handle *session,
1355 TPM2B_PUBLIC **ret_public,
1356 TPM2B_NAME **ret_name,
1357 TPM2B_NAME **ret_qname,
1358 Tpm2Handle **ret_handle) {
1359
1360 int r;
1361
1362 r = tpm2_get_srk(c, session, ret_public, ret_name, ret_qname, ret_handle);
1363 if (r < 0)
1364 return r;
1365 if (r == 1)
1366 return 0; /* 0 → SRK already set up */
1367
1368 /* No SRK, create and persist one */
1369 TPM2B_PUBLIC template = {
1370 .size = sizeof(TPMT_PUBLIC),
1371 };
1372 r = tpm2_get_best_srk_template(c, &template.publicArea);
1373 if (r < 0)
1374 return log_debug_errno(r, "Could not get best SRK template: %m");
1375
1376 _cleanup_(tpm2_handle_freep) Tpm2Handle *transient_handle = NULL;
1377 r = tpm2_create_primary(
1378 c,
1379 session,
1380 &template,
1381 /* sensitive= */ NULL,
1382 /* ret_public= */ NULL,
1383 &transient_handle);
1384 if (r < 0)
1385 return r;
1386
1387 /* Try to persist the transient SRK we created. No locking needed; if multiple threads are trying to
1388 * persist SRKs concurrently, only one will succeed (r == 1) while the rest will fail (r == 0). In
1389 * either case, all threads will get the persistent SRK below. */
1390 r = tpm2_persist_handle(c, transient_handle, session, TPM2_SRK_HANDLE, /* ret_persistent_handle= */ NULL);
1391 if (r < 0)
1392 return r;
1393
1394 /* The SRK should exist now. */
1395 r = tpm2_get_srk(c, session, ret_public, ret_name, ret_qname, ret_handle);
1396 if (r < 0)
1397 return r;
1398 if (r == 0)
1399 /* This should never happen. */
1400 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "SRK we just persisted couldn't be found.");
1401
1402 return 1; /* > 0 → SRK newly set up */
1403 }
1404
1405 /* Utility functions for TPMS_PCR_SELECTION. */
1406
1407 /* Convert a TPMS_PCR_SELECTION object to a mask. */
1408 uint32_t tpm2_tpms_pcr_selection_to_mask(const TPMS_PCR_SELECTION *s) {
1409 assert(s);
1410 assert(s->sizeofSelect <= sizeof(s->pcrSelect));
1411
1412 uint32_t mask = 0;
1413 for (unsigned i = 0; i < s->sizeofSelect; i++)
1414 SET_FLAG(mask, (uint32_t)s->pcrSelect[i] << (i * 8), true);
1415 return mask;
1416 }
1417
1418 /* Convert a mask and hash alg to a TPMS_PCR_SELECTION object. */
1419 void tpm2_tpms_pcr_selection_from_mask(uint32_t mask, TPMI_ALG_HASH hash_alg, TPMS_PCR_SELECTION *ret) {
1420 assert(ret);
1421
1422 /* This is currently hardcoded at 24 PCRs, above. */
1423 if (!TPM2_PCR_MASK_VALID(mask))
1424 log_debug("PCR mask selections (%x) out of range, ignoring.",
1425 mask & ~((uint32_t)TPM2_PCRS_MASK));
1426
1427 *ret = (TPMS_PCR_SELECTION){
1428 .hash = hash_alg,
1429 .sizeofSelect = TPM2_PCRS_MAX / 8,
1430 .pcrSelect[0] = mask & 0xff,
1431 .pcrSelect[1] = (mask >> 8) & 0xff,
1432 .pcrSelect[2] = (mask >> 16) & 0xff,
1433 };
1434 }
1435
1436 /* Test if all bits in the mask are set in the TPMS_PCR_SELECTION. */
1437 bool tpm2_tpms_pcr_selection_has_mask(const TPMS_PCR_SELECTION *s, uint32_t mask) {
1438 assert(s);
1439
1440 return FLAGS_SET(tpm2_tpms_pcr_selection_to_mask(s), mask);
1441 }
1442
1443 static void tpm2_tpms_pcr_selection_update_mask(TPMS_PCR_SELECTION *s, uint32_t mask, bool b) {
1444 assert(s);
1445
1446 tpm2_tpms_pcr_selection_from_mask(UPDATE_FLAG(tpm2_tpms_pcr_selection_to_mask(s), mask, b), s->hash, s);
1447 }
1448
1449 /* Add all PCR selections in the mask. */
1450 void tpm2_tpms_pcr_selection_add_mask(TPMS_PCR_SELECTION *s, uint32_t mask) {
1451 tpm2_tpms_pcr_selection_update_mask(s, mask, 1);
1452 }
1453
1454 /* Remove all PCR selections in the mask. */
1455 void tpm2_tpms_pcr_selection_sub_mask(TPMS_PCR_SELECTION *s, uint32_t mask) {
1456 tpm2_tpms_pcr_selection_update_mask(s, mask, 0);
1457 }
1458
1459 /* Add all PCR selections in 'b' to 'a'. Both must have the same hash alg. */
1460 void tpm2_tpms_pcr_selection_add(TPMS_PCR_SELECTION *a, const TPMS_PCR_SELECTION *b) {
1461 assert(a);
1462 assert(b);
1463 assert(a->hash == b->hash);
1464
1465 tpm2_tpms_pcr_selection_add_mask(a, tpm2_tpms_pcr_selection_to_mask(b));
1466 }
1467
1468 /* Remove all PCR selections in 'b' from 'a'. Both must have the same hash alg. */
1469 void tpm2_tpms_pcr_selection_sub(TPMS_PCR_SELECTION *a, const TPMS_PCR_SELECTION *b) {
1470 assert(a);
1471 assert(b);
1472 assert(a->hash == b->hash);
1473
1474 tpm2_tpms_pcr_selection_sub_mask(a, tpm2_tpms_pcr_selection_to_mask(b));
1475 }
1476
1477 /* Move all PCR selections in 'b' to 'a'. Both must have the same hash alg. */
1478 void tpm2_tpms_pcr_selection_move(TPMS_PCR_SELECTION *a, TPMS_PCR_SELECTION *b) {
1479 if (a == b)
1480 return;
1481
1482 tpm2_tpms_pcr_selection_add(a, b);
1483 tpm2_tpms_pcr_selection_from_mask(0, b->hash, b);
1484 }
1485
1486 #define FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml) \
1487 _FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml, UNIQ_T(l, UNIQ))
1488 #define _FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml, l) \
1489 for (typeof(tpml) (l) = (tpml); (l); (l) = NULL) \
1490 FOREACH_ARRAY(tpms, (l)->pcrSelections, (l)->count)
1491
1492 #define FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms) \
1493 FOREACH_PCR_IN_MASK(pcr, tpm2_tpms_pcr_selection_to_mask(tpms))
1494
1495 #define FOREACH_PCR_IN_TPML_PCR_SELECTION(pcr, tpms, tpml) \
1496 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(tpms, tpml) \
1497 FOREACH_PCR_IN_TPMS_PCR_SELECTION(pcr, tpms)
1498
1499 char* tpm2_tpms_pcr_selection_to_string(const TPMS_PCR_SELECTION *s) {
1500 assert(s);
1501
1502 const char *algstr = strna(tpm2_hash_alg_to_string(s->hash));
1503
1504 _cleanup_free_ char *mask = tpm2_pcr_mask_to_string(tpm2_tpms_pcr_selection_to_mask(s));
1505 if (!mask)
1506 return NULL;
1507
1508 return strjoin(algstr, "(", mask, ")");
1509 }
1510
1511 size_t tpm2_tpms_pcr_selection_weight(const TPMS_PCR_SELECTION *s) {
1512 assert(s);
1513
1514 return popcount(tpm2_tpms_pcr_selection_to_mask(s));
1515 }
1516
1517 /* Utility functions for TPML_PCR_SELECTION. */
1518
1519 /* Remove the (0-based) index entry from 'l', shift all following entries, and update the count. */
1520 static void tpm2_tpml_pcr_selection_remove_index(TPML_PCR_SELECTION *l, uint32_t index) {
1521 assert(l);
1522 assert(l->count <= ELEMENTSOF(l->pcrSelections));
1523 assert(index < l->count);
1524
1525 size_t s = l->count - (index + 1);
1526 memmove(&l->pcrSelections[index], &l->pcrSelections[index + 1], s * sizeof(l->pcrSelections[0]));
1527 l->count--;
1528 }
1529
1530 /* Get a TPMS_PCR_SELECTION from a TPML_PCR_SELECTION for the given hash alg. Returns NULL if there is no
1531 * entry for the hash alg. This guarantees the returned entry contains all the PCR selections for the given
1532 * hash alg, which may require modifying the TPML_PCR_SELECTION by removing duplicate entries. */
1533 static TPMS_PCR_SELECTION *tpm2_tpml_pcr_selection_get_tpms_pcr_selection(
1534 TPML_PCR_SELECTION *l,
1535 TPMI_ALG_HASH hash_alg) {
1536
1537 assert(l);
1538 assert(l->count <= ELEMENTSOF(l->pcrSelections));
1539
1540 TPMS_PCR_SELECTION *selection = NULL;
1541 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s, l)
1542 if (s->hash == hash_alg) {
1543 selection = s;
1544 break;
1545 }
1546
1547 if (!selection)
1548 return NULL;
1549
1550 /* Iterate backwards through the entries, removing any other entries for the hash alg. */
1551 for (uint32_t i = l->count - 1; i > 0; i--) {
1552 TPMS_PCR_SELECTION *s = &l->pcrSelections[i];
1553
1554 if (selection == s)
1555 break;
1556
1557 if (s->hash == hash_alg) {
1558 tpm2_tpms_pcr_selection_move(selection, s);
1559 tpm2_tpml_pcr_selection_remove_index(l, i);
1560 }
1561 }
1562
1563 return selection;
1564 }
1565
1566 /* Combine all duplicate (same hash alg) TPMS_PCR_SELECTION entries in 'l'. */
1567 static void tpm2_tpml_pcr_selection_cleanup(TPML_PCR_SELECTION *l) {
1568 /* Can't use FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION() because we might modify l->count */
1569 for (uint32_t i = 0; i < l->count; i++)
1570 /* This removes all duplicate TPMS_PCR_SELECTION entries for this hash. */
1571 (void) tpm2_tpml_pcr_selection_get_tpms_pcr_selection(l, l->pcrSelections[i].hash);
1572 }
1573
1574 /* Convert a TPML_PCR_SELECTION object to a mask. Returns empty mask (i.e. 0) if 'hash_alg' is not in the object. */
1575 uint32_t tpm2_tpml_pcr_selection_to_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash_alg) {
1576 assert(l);
1577
1578 /* Make a copy, as tpm2_tpml_pcr_selection_get_tpms_pcr_selection() will modify the object if there
1579 * are multiple entries with the requested hash alg. */
1580 TPML_PCR_SELECTION lcopy = *l;
1581
1582 TPMS_PCR_SELECTION *s;
1583 s = tpm2_tpml_pcr_selection_get_tpms_pcr_selection(&lcopy, hash_alg);
1584 if (!s)
1585 return 0;
1586
1587 return tpm2_tpms_pcr_selection_to_mask(s);
1588 }
1589
1590 /* Convert a mask and hash alg to a TPML_PCR_SELECTION object. */
1591 void tpm2_tpml_pcr_selection_from_mask(uint32_t mask, TPMI_ALG_HASH hash_alg, TPML_PCR_SELECTION *ret) {
1592 assert(ret);
1593
1594 TPMS_PCR_SELECTION s;
1595 tpm2_tpms_pcr_selection_from_mask(mask, hash_alg, &s);
1596
1597 *ret = (TPML_PCR_SELECTION){
1598 .count = 1,
1599 .pcrSelections[0] = s,
1600 };
1601 }
1602
1603 /* Add the PCR selections in 's' to the corresponding hash alg TPMS_PCR_SELECTION entry in 'l'. Adds a new
1604 * TPMS_PCR_SELECTION entry for the hash alg if needed. This may modify the TPML_PCR_SELECTION by combining
1605 * entries with the same hash alg. */
1606 void tpm2_tpml_pcr_selection_add_tpms_pcr_selection(TPML_PCR_SELECTION *l, const TPMS_PCR_SELECTION *s) {
1607 assert(l);
1608 assert(s);
1609
1610 if (tpm2_tpms_pcr_selection_is_empty(s))
1611 return;
1612
1613 TPMS_PCR_SELECTION *selection = tpm2_tpml_pcr_selection_get_tpms_pcr_selection(l, s->hash);
1614 if (selection) {
1615 tpm2_tpms_pcr_selection_add(selection, s);
1616 return;
1617 }
1618
1619 /* It's already broken if the count is higher than the array has size for. */
1620 assert(l->count <= ELEMENTSOF(l->pcrSelections));
1621
1622 /* If full, the cleanup should result in at least one available entry. */
1623 if (l->count == ELEMENTSOF(l->pcrSelections))
1624 tpm2_tpml_pcr_selection_cleanup(l);
1625
1626 assert(l->count < ELEMENTSOF(l->pcrSelections));
1627 l->pcrSelections[l->count++] = *s;
1628 }
1629
1630 /* Remove the PCR selections in 's' from the corresponding hash alg TPMS_PCR_SELECTION entry in 'l'. This
1631 * will combine all entries for 's->hash' in 'l'. */
1632 void tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(TPML_PCR_SELECTION *l, const TPMS_PCR_SELECTION *s) {
1633 assert(l);
1634 assert(s);
1635
1636 if (tpm2_tpms_pcr_selection_is_empty(s))
1637 return;
1638
1639 TPMS_PCR_SELECTION *selection = tpm2_tpml_pcr_selection_get_tpms_pcr_selection(l, s->hash);
1640 if (selection)
1641 tpm2_tpms_pcr_selection_sub(selection, s);
1642 }
1643
1644 /* Test if all bits in the mask for the hash are set in the TPML_PCR_SELECTION. */
1645 bool tpm2_tpml_pcr_selection_has_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask) {
1646 assert(l);
1647
1648 return FLAGS_SET(tpm2_tpml_pcr_selection_to_mask(l, hash), mask);
1649 }
1650
1651 /* Add the PCR selections in the mask, with the provided hash. */
1652 void tpm2_tpml_pcr_selection_add_mask(TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask) {
1653 TPMS_PCR_SELECTION tpms;
1654
1655 assert(l);
1656
1657 tpm2_tpms_pcr_selection_from_mask(mask, hash, &tpms);
1658 tpm2_tpml_pcr_selection_add_tpms_pcr_selection(l, &tpms);
1659 }
1660
1661 /* Add all PCR selections in 'b' to 'a'. */
1662 void tpm2_tpml_pcr_selection_add(TPML_PCR_SELECTION *a, const TPML_PCR_SELECTION *b) {
1663 assert(a);
1664 assert(b);
1665
1666 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection_b, b)
1667 tpm2_tpml_pcr_selection_add_tpms_pcr_selection(a, selection_b);
1668 }
1669
1670 /* Remove all PCR selections in 'b' from 'a'. */
1671 void tpm2_tpml_pcr_selection_sub(TPML_PCR_SELECTION *a, const TPML_PCR_SELECTION *b) {
1672 assert(a);
1673 assert(b);
1674
1675 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection_b, b)
1676 tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(a, selection_b);
1677 }
1678
1679 char* tpm2_tpml_pcr_selection_to_string(const TPML_PCR_SELECTION *l) {
1680 assert(l);
1681
1682 _cleanup_free_ char *banks = NULL;
1683 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s, l) {
1684 if (tpm2_tpms_pcr_selection_is_empty(s))
1685 continue;
1686
1687 _cleanup_free_ char *str = tpm2_tpms_pcr_selection_to_string(s);
1688 if (!str || !strextend_with_separator(&banks, ",", str))
1689 return NULL;
1690 }
1691
1692 return strjoin("[", strempty(banks), "]");
1693 }
1694
1695 size_t tpm2_tpml_pcr_selection_weight(const TPML_PCR_SELECTION *l) {
1696 assert(l);
1697 assert(l->count <= ELEMENTSOF(l->pcrSelections));
1698
1699 size_t weight = 0;
1700 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(s, l) {
1701 size_t w = tpm2_tpms_pcr_selection_weight(s);
1702 assert(weight <= SIZE_MAX - w);
1703 weight += w;
1704 }
1705
1706 return weight;
1707 }
1708
1709 bool tpm2_pcr_value_valid(const Tpm2PCRValue *pcr_value) {
1710 int r;
1711
1712 if (!pcr_value)
1713 return false;
1714
1715 if (!TPM2_PCR_INDEX_VALID(pcr_value->index)) {
1716 log_debug("PCR index %u invalid.", pcr_value->index);
1717 return false;
1718 }
1719
1720 /* If it contains a value, the value size must match the hash size. */
1721 if (pcr_value->value.size > 0) {
1722 r = tpm2_hash_alg_to_size(pcr_value->hash);
1723 if (r < 0)
1724 return false;
1725
1726 if (pcr_value->value.size != (size_t) r) {
1727 log_debug("PCR hash 0x%" PRIx16 " expected size %d does not match actual size %" PRIu16 ".",
1728 pcr_value->hash, r, pcr_value->value.size);
1729 return false;
1730 }
1731 }
1732
1733 return true;
1734 }
1735
1736 /* Verify all entries are valid, and consistent with each other. The requirements for consistency are:
1737 *
1738 * 1) all entries must be sorted in ascending order (e.g. using tpm2_sort_pcr_values())
1739 * 2) all entries must be unique, i.e. there cannot be 2 entries with the same hash and index
1740 *
1741 * Returns true if all entries are valid (or if no entries are provided), false otherwise.
1742 */
1743 bool tpm2_pcr_values_valid(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
1744 if (!pcr_values && n_pcr_values > 0)
1745 return false;
1746
1747 const Tpm2PCRValue *previous = NULL;
1748 FOREACH_ARRAY(current, pcr_values, n_pcr_values) {
1749 if (!tpm2_pcr_value_valid(current))
1750 return false;
1751
1752 if (!previous) {
1753 previous = current;
1754 continue;
1755 }
1756
1757 /* Hashes must be sorted in ascending order */
1758 if (current->hash < previous->hash) {
1759 log_debug("PCR values not in ascending order, hash %" PRIu16 " is after %" PRIu16 ".",
1760 current->hash, previous->hash);
1761 return false;
1762 }
1763
1764 if (current->hash == previous->hash) {
1765 /* Indexes (for the same hash) must be sorted in ascending order */
1766 if (current->index < previous->index) {
1767 log_debug("PCR values not in ascending order, hash %" PRIu16 " index %u is after %u.",
1768 current->hash, current->index, previous->index);
1769 return false;
1770 }
1771
1772 /* Indexes (for the same hash) must not be duplicates */
1773 if (current->index == previous->index) {
1774 log_debug("PCR values contain duplicates for hash %" PRIu16 " index %u.",
1775 current->hash, previous->index);
1776 return false;
1777 }
1778 }
1779 }
1780
1781 return true;
1782 }
1783
1784 /* Returns true if any of the provided PCR values has an actual hash value included, false otherwise. */
1785 bool tpm2_pcr_values_has_any_values(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
1786 assert(pcr_values || n_pcr_values == 0);
1787
1788 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
1789 if (v->value.size > 0)
1790 return true;
1791
1792 return false;
1793 }
1794
1795 /* Returns true if all of the provided PCR values has an actual hash value included, false otherwise. */
1796 bool tpm2_pcr_values_has_all_values(const Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
1797 assert(pcr_values || n_pcr_values == 0);
1798
1799 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
1800 if (v->value.size == 0)
1801 return false;
1802
1803 return true;
1804 }
1805
1806 static int cmp_pcr_values(const Tpm2PCRValue *a, const Tpm2PCRValue *b) {
1807 assert(a);
1808 assert(b);
1809
1810 return CMP(a->hash, b->hash) ?: CMP(a->index, b->index);
1811 }
1812
1813 /* Sort the array of Tpm2PCRValue entries in-place. This sorts first in ascending order of hash algorithm
1814 * (sorting simply by the TPM2 hash algorithm number), and then sorting by pcr index. */
1815 void tpm2_sort_pcr_values(Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
1816 typesafe_qsort(pcr_values, n_pcr_values, cmp_pcr_values);
1817 }
1818
1819 int tpm2_pcr_values_to_mask(
1820 const Tpm2PCRValue *pcr_values,
1821 size_t n_pcr_values,
1822 TPMI_ALG_HASH hash,
1823 uint32_t *ret_mask) {
1824
1825 assert(pcr_values || n_pcr_values == 0);
1826 assert(ret_mask);
1827
1828 if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values))
1829 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid PCR values.");
1830
1831 uint32_t mask = 0;
1832 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
1833 if (hash == 0 || v->hash == hash)
1834 SET_BIT(mask, v->index);
1835
1836 *ret_mask = mask;
1837 return 0;
1838 }
1839
1840 int tpm2_tpml_pcr_selection_from_pcr_values(
1841 const Tpm2PCRValue *pcr_values,
1842 size_t n_pcr_values,
1843 TPML_PCR_SELECTION *ret_selection,
1844 TPM2B_DIGEST **ret_values,
1845 size_t *ret_n_values) {
1846
1847 TPML_PCR_SELECTION selection = {};
1848 _cleanup_free_ TPM2B_DIGEST *values = NULL;
1849 size_t n_values = 0;
1850
1851 assert(pcr_values || n_pcr_values == 0);
1852
1853 if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values))
1854 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "PCR values are not valid.");
1855
1856 FOREACH_ARRAY(v, pcr_values, n_pcr_values) {
1857 tpm2_tpml_pcr_selection_add_mask(&selection, v->hash, INDEX_TO_MASK(uint32_t, v->index));
1858
1859 if (!GREEDY_REALLOC_APPEND(values, n_values, &v->value, 1))
1860 return log_oom_debug();
1861 }
1862
1863 if (ret_selection)
1864 *ret_selection = selection;
1865 if (ret_values)
1866 *ret_values = TAKE_PTR(values);
1867 if (ret_n_values)
1868 *ret_n_values = n_values;
1869
1870 return 0;
1871 }
1872
1873 /* Count the number of different hash algorithms for all the entries. */
1874 int tpm2_pcr_values_hash_count(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, size_t *ret_count) {
1875 TPML_PCR_SELECTION selection;
1876 int r;
1877
1878 assert(pcr_values);
1879 assert(ret_count);
1880
1881 r = tpm2_tpml_pcr_selection_from_pcr_values(
1882 pcr_values,
1883 n_pcr_values,
1884 &selection,
1885 /* ret_values= */ NULL,
1886 /* ret_n_values= */ NULL);
1887 if (r < 0)
1888 return r;
1889
1890 *ret_count = selection.count;
1891
1892 return 0;
1893 }
1894
1895 /* Parse a string argument into a Tpm2PCRValue object.
1896 *
1897 * The format is <index>[:hash[=value]] where index is the index number (or name) of the PCR, e.g. 0 (or
1898 * platform-code), hash is the name of the hash algorithm (e.g. sha256) and value is the hex hash digest
1899 * value, optionally with a leading 0x. This does not check for validity of the fields. */
1900 int tpm2_pcr_value_from_string(const char *arg, Tpm2PCRValue *ret_pcr_value) {
1901 Tpm2PCRValue pcr_value = {};
1902 const char *p = arg;
1903 int r;
1904
1905 assert(arg);
1906 assert(ret_pcr_value);
1907
1908 _cleanup_free_ char *index = NULL;
1909 r = extract_first_word(&p, &index, ":", /* flags= */ 0);
1910 if (r < 1)
1911 return log_debug_errno(r, "Could not parse pcr value '%s': %m", p);
1912
1913 r = tpm2_pcr_index_from_string(index);
1914 if (r < 0)
1915 return log_debug_errno(r, "Invalid pcr index '%s': %m", index);
1916 pcr_value.index = (unsigned) r;
1917
1918 if (!isempty(p)) {
1919 _cleanup_free_ char *hash = NULL;
1920 r = extract_first_word(&p, &hash, "=", /* flags= */ 0);
1921 if (r < 1)
1922 return log_debug_errno(r, "Could not parse pcr hash algorithm '%s': %m", p);
1923
1924 r = tpm2_hash_alg_from_string(hash);
1925 if (r < 0)
1926 return log_debug_errno(r, "Invalid pcr hash algorithm '%s': %m", hash);
1927 pcr_value.hash = (TPMI_ALG_HASH) r;
1928
1929 if (!isempty(p)) {
1930 /* Remove leading 0x if present */
1931 p = startswith_no_case(p, "0x") ?: p;
1932
1933 _cleanup_free_ void *buf = NULL;
1934 size_t buf_size = 0;
1935 r = unhexmem(p, &buf, &buf_size);
1936 if (r < 0)
1937 return log_debug_errno(r, "Invalid pcr hash value '%s': %m", p);
1938
1939 r = TPM2B_DIGEST_CHECK_SIZE(buf_size);
1940 if (r < 0)
1941 return log_debug_errno(r, "PCR hash value size %zu too large.", buf_size);
1942
1943 pcr_value.value = TPM2B_DIGEST_MAKE(buf, buf_size);
1944 }
1945 }
1946
1947 *ret_pcr_value = pcr_value;
1948
1949 return 0;
1950 }
1951
1952 /* Return a string for the PCR value. The format is described in tpm2_pcr_value_from_string(). Note that if
1953 * the hash algorithm is not recognized, neither hash name nor hash digest value is included in the
1954 * string. This does not check for validity. */
1955 char* tpm2_pcr_value_to_string(const Tpm2PCRValue *pcr_value) {
1956 _cleanup_free_ char *index = NULL, *value = NULL;
1957
1958 if (asprintf(&index, "%u", pcr_value->index) < 0)
1959 return NULL;
1960
1961 const char *hash = pcr_value->hash > 0 ? tpm2_hash_alg_to_string(pcr_value->hash) : NULL;
1962
1963 if (hash && pcr_value->value.size > 0) {
1964 value = hexmem(pcr_value->value.buffer, pcr_value->value.size);
1965 if (!value)
1966 return NULL;
1967 }
1968
1969 return strjoin(index, hash ? ":" : "", strempty(hash), value ? "=" : "", strempty(value));
1970 }
1971
1972 /* Parse a string argument into an array of Tpm2PCRValue objects.
1973 *
1974 * The format is zero or more entries separated by ',' or '+'. The format of each entry is described in
1975 * tpm2_pcr_value_from_string(). This does not check for validity of the entries. */
1976 int tpm2_pcr_values_from_string(const char *arg, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values) {
1977 const char *p = arg;
1978 int r;
1979
1980 assert(arg);
1981 assert(ret_pcr_values);
1982 assert(ret_n_pcr_values);
1983
1984 _cleanup_free_ Tpm2PCRValue *pcr_values = NULL;
1985 size_t n_pcr_values = 0;
1986
1987 for (;;) {
1988 _cleanup_free_ char *pcr_arg = NULL;
1989 r = extract_first_word(&p, &pcr_arg, ",+", /* flags= */ 0);
1990 if (r < 0)
1991 return log_debug_errno(r, "Could not parse pcr values '%s': %m", p);
1992 if (r == 0)
1993 break;
1994
1995 Tpm2PCRValue pcr_value;
1996 r = tpm2_pcr_value_from_string(pcr_arg, &pcr_value);
1997 if (r < 0)
1998 return r;
1999
2000 if (!GREEDY_REALLOC_APPEND(pcr_values, n_pcr_values, &pcr_value, 1))
2001 return log_oom_debug();
2002 }
2003
2004 *ret_pcr_values = TAKE_PTR(pcr_values);
2005 *ret_n_pcr_values = n_pcr_values;
2006
2007 return 0;
2008 }
2009
2010 void tpm2_log_debug_tpml_pcr_selection(const TPML_PCR_SELECTION *l, const char *msg) {
2011 if (!DEBUG_LOGGING || !l)
2012 return;
2013
2014 _cleanup_free_ char *s = tpm2_tpml_pcr_selection_to_string(l);
2015 log_debug("%s: %s", msg ?: "PCR selection", strna(s));
2016 }
2017
2018 void tpm2_log_debug_pcr_value(const Tpm2PCRValue *pcr_value, const char *msg) {
2019 if (!DEBUG_LOGGING || !pcr_value)
2020 return;
2021
2022 _cleanup_free_ char *s = tpm2_pcr_value_to_string(pcr_value);
2023 log_debug("%s: %s", msg ?: "PCR value", strna(s));
2024 }
2025
2026 void tpm2_log_debug_buffer(const void *buffer, size_t size, const char *msg) {
2027 if (!DEBUG_LOGGING || !buffer || size == 0)
2028 return;
2029
2030 _cleanup_free_ char *h = hexmem(buffer, size);
2031 log_debug("%s: %s", msg ?: "Buffer", strna(h));
2032 }
2033
2034 void tpm2_log_debug_digest(const TPM2B_DIGEST *digest, const char *msg) {
2035 if (digest)
2036 tpm2_log_debug_buffer(digest->buffer, digest->size, msg ?: "Digest");
2037 }
2038
2039 void tpm2_log_debug_name(const TPM2B_NAME *name, const char *msg) {
2040 if (name)
2041 tpm2_log_debug_buffer(name->name, name->size, msg ?: "Name");
2042 }
2043
2044 static int tpm2_get_policy_digest(
2045 Tpm2Context *c,
2046 const Tpm2Handle *session,
2047 TPM2B_DIGEST **ret_policy_digest) {
2048
2049 TSS2_RC rc;
2050
2051 if (!DEBUG_LOGGING && !ret_policy_digest)
2052 return 0;
2053
2054 assert(c);
2055 assert(session);
2056
2057 log_debug("Acquiring policy digest.");
2058
2059 _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
2060 rc = sym_Esys_PolicyGetDigest(
2061 c->esys_context,
2062 session->esys_handle,
2063 ESYS_TR_NONE,
2064 ESYS_TR_NONE,
2065 ESYS_TR_NONE,
2066 &policy_digest);
2067 if (rc != TSS2_RC_SUCCESS)
2068 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2069 "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc));
2070
2071 tpm2_log_debug_digest(policy_digest, "Session policy digest");
2072
2073 if (ret_policy_digest)
2074 *ret_policy_digest = TAKE_PTR(policy_digest);
2075
2076 return 0;
2077 }
2078
2079 int tpm2_create_primary(
2080 Tpm2Context *c,
2081 const Tpm2Handle *session,
2082 const TPM2B_PUBLIC *template,
2083 const TPM2B_SENSITIVE_CREATE *sensitive,
2084 TPM2B_PUBLIC **ret_public,
2085 Tpm2Handle **ret_handle) {
2086
2087 usec_t ts;
2088 TSS2_RC rc;
2089 int r;
2090
2091 assert(c);
2092 assert(template);
2093
2094 log_debug("Creating primary key on TPM.");
2095
2096 ts = now(CLOCK_MONOTONIC);
2097
2098 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
2099 r = tpm2_handle_new(c, &handle);
2100 if (r < 0)
2101 return r;
2102
2103 _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
2104 rc = sym_Esys_CreatePrimary(
2105 c->esys_context,
2106 ESYS_TR_RH_OWNER,
2107 session ? session->esys_handle : ESYS_TR_PASSWORD,
2108 ESYS_TR_NONE,
2109 ESYS_TR_NONE,
2110 sensitive ?: &(TPM2B_SENSITIVE_CREATE) {},
2111 template,
2112 /* outsideInfo= */ NULL,
2113 &(TPML_PCR_SELECTION) {},
2114 &handle->esys_handle,
2115 &public,
2116 /* creationData= */ NULL,
2117 /* creationHash= */ NULL,
2118 /* creationTicket= */ NULL);
2119 if (rc == TPM2_RC_BAD_AUTH)
2120 return log_debug_errno(SYNTHETIC_ERRNO(EDEADLK), "Authorization failure while attempting to create primary key.");
2121 if (rc != TSS2_RC_SUCCESS)
2122 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2123 "Failed to generate primary key in TPM: %s",
2124 sym_Tss2_RC_Decode(rc));
2125
2126 log_debug("Successfully created primary key on TPM in %s.",
2127 FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - ts, USEC_PER_MSEC));
2128
2129 if (ret_public)
2130 *ret_public = TAKE_PTR(public);
2131 if (ret_handle)
2132 *ret_handle = TAKE_PTR(handle);
2133
2134 return 0;
2135 }
2136
2137 /* Create a TPM object. Do not use this to create primary keys, because some HW TPMs refuse to allow that;
2138 * instead use tpm2_create_primary(). */
2139 int tpm2_create(Tpm2Context *c,
2140 const Tpm2Handle *parent,
2141 const Tpm2Handle *session,
2142 const TPMT_PUBLIC *template,
2143 const TPMS_SENSITIVE_CREATE *sensitive,
2144 TPM2B_PUBLIC **ret_public,
2145 TPM2B_PRIVATE **ret_private) {
2146
2147 usec_t ts;
2148 TSS2_RC rc;
2149
2150 assert(c);
2151 assert(parent);
2152 assert(template);
2153
2154 log_debug("Creating object on TPM.");
2155
2156 ts = now(CLOCK_MONOTONIC);
2157
2158 TPM2B_PUBLIC tpm2b_public = {
2159 .size = sizeof(*template) - sizeof(template->unique),
2160 .publicArea = *template,
2161 };
2162
2163 /* Zero the unique area. */
2164 zero(tpm2b_public.publicArea.unique);
2165
2166 TPM2B_SENSITIVE_CREATE tpm2b_sensitive;
2167 if (sensitive)
2168 tpm2b_sensitive = (TPM2B_SENSITIVE_CREATE) {
2169 .size = sizeof(*sensitive),
2170 .sensitive = *sensitive,
2171 };
2172 else
2173 tpm2b_sensitive = (TPM2B_SENSITIVE_CREATE) {};
2174
2175 _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
2176 _cleanup_(Esys_Freep) TPM2B_PRIVATE *private = NULL;
2177 rc = sym_Esys_Create(
2178 c->esys_context,
2179 parent->esys_handle,
2180 session ? session->esys_handle : ESYS_TR_PASSWORD,
2181 ESYS_TR_NONE,
2182 ESYS_TR_NONE,
2183 &tpm2b_sensitive,
2184 &tpm2b_public,
2185 /* outsideInfo= */ NULL,
2186 &(TPML_PCR_SELECTION) {},
2187 &private,
2188 &public,
2189 /* creationData= */ NULL,
2190 /* creationHash= */ NULL,
2191 /* creationTicket= */ NULL);
2192 if (rc != TSS2_RC_SUCCESS)
2193 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2194 "Failed to generate object in TPM: %s",
2195 sym_Tss2_RC_Decode(rc));
2196
2197 log_debug("Successfully created object on TPM in %s.",
2198 FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - ts, USEC_PER_MSEC));
2199
2200 if (ret_public)
2201 *ret_public = TAKE_PTR(public);
2202 if (ret_private)
2203 *ret_private = TAKE_PTR(private);
2204
2205 return 0;
2206 }
2207
2208 int tpm2_load(
2209 Tpm2Context *c,
2210 const Tpm2Handle *parent,
2211 const Tpm2Handle *session,
2212 const TPM2B_PUBLIC *public,
2213 const TPM2B_PRIVATE *private,
2214 Tpm2Handle **ret_handle) {
2215
2216 TSS2_RC rc;
2217 int r;
2218
2219 assert(c);
2220 assert(public);
2221 assert(private);
2222 assert(ret_handle);
2223
2224 log_debug("Loading object into TPM.");
2225
2226 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
2227 r = tpm2_handle_new(c, &handle);
2228 if (r < 0)
2229 return r;
2230
2231 rc = sym_Esys_Load(
2232 c->esys_context,
2233 parent ? parent->esys_handle : ESYS_TR_RH_OWNER,
2234 session ? session->esys_handle : ESYS_TR_PASSWORD,
2235 ESYS_TR_NONE,
2236 ESYS_TR_NONE,
2237 private,
2238 public,
2239 &handle->esys_handle);
2240 if (rc == TPM2_RC_LOCKOUT)
2241 return log_debug_errno(SYNTHETIC_ERRNO(ENOLCK),
2242 "TPM2 device is in dictionary attack lockout mode.");
2243 if ((rc & ~(TPM2_RC_N_MASK|TPM2_RC_P)) == TPM2_RC_INTEGRITY) /* Return a recognizable error if this key does not belong to the local TPM */
2244 return log_debug_errno(SYNTHETIC_ERRNO(EREMOTE),
2245 "Key invalid or does not belong to current TPM.");
2246 if (rc != TSS2_RC_SUCCESS)
2247 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2248 "Failed to load key into TPM: %s", sym_Tss2_RC_Decode(rc));
2249
2250 *ret_handle = TAKE_PTR(handle);
2251
2252 return 0;
2253 }
2254
2255 static int tpm2_load_external(
2256 Tpm2Context *c,
2257 const Tpm2Handle *session,
2258 const TPM2B_PUBLIC *public,
2259 const TPM2B_SENSITIVE *private,
2260 Tpm2Handle **ret_handle) {
2261
2262 TSS2_RC rc;
2263 int r;
2264
2265 assert(c);
2266 assert(ret_handle);
2267
2268 log_debug("Loading external key into TPM.");
2269
2270 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
2271 r = tpm2_handle_new(c, &handle);
2272 if (r < 0)
2273 return r;
2274
2275 rc = sym_Esys_LoadExternal(
2276 c->esys_context,
2277 session ? session->esys_handle : ESYS_TR_NONE,
2278 ESYS_TR_NONE,
2279 ESYS_TR_NONE,
2280 private,
2281 public,
2282 #if HAVE_TSS2_ESYS3
2283 /* tpm2-tss >= 3.0.0 requires a ESYS_TR_RH_* constant specifying the requested
2284 * hierarchy, older versions need TPM2_RH_* instead. */
2285 private ? ESYS_TR_RH_NULL : ESYS_TR_RH_OWNER,
2286 #else
2287 private ? TPM2_RH_NULL : TPM2_RH_OWNER,
2288 #endif
2289 &handle->esys_handle);
2290 if (rc != TSS2_RC_SUCCESS)
2291 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2292 "Failed to load public key into TPM: %s", sym_Tss2_RC_Decode(rc));
2293
2294 *ret_handle = TAKE_PTR(handle);
2295
2296 return 0;
2297 }
2298
2299 static int tpm2_marshal_private(const TPM2B_PRIVATE *private, void **ret, size_t *ret_size) {
2300 size_t max_size = sizeof(*private), blob_size = 0;
2301 _cleanup_free_ void *blob = NULL;
2302 TSS2_RC rc;
2303
2304 assert(private);
2305 assert(ret);
2306 assert(ret_size);
2307
2308 blob = malloc0(max_size);
2309 if (!blob)
2310 return log_oom_debug();
2311
2312 rc = sym_Tss2_MU_TPM2B_PRIVATE_Marshal(private, blob, max_size, &blob_size);
2313 if (rc != TSS2_RC_SUCCESS)
2314 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2315 "Failed to marshal private key: %s", sym_Tss2_RC_Decode(rc));
2316
2317 *ret = TAKE_PTR(blob);
2318 *ret_size = blob_size;
2319 return 0;
2320 }
2321
2322 static int tpm2_unmarshal_private(const void *data, size_t size, TPM2B_PRIVATE *ret_private) {
2323 TPM2B_PRIVATE private = {};
2324 size_t offset = 0;
2325 TSS2_RC rc;
2326
2327 assert(data || size == 0);
2328 assert(ret_private);
2329
2330 rc = sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal(data, size, &offset, &private);
2331 if (rc != TSS2_RC_SUCCESS)
2332 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2333 "Failed to unmarshal private key: %s", sym_Tss2_RC_Decode(rc));
2334 if (offset != size)
2335 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2336 "Garbage at end of private key marshal data.");
2337
2338 *ret_private = private;
2339 return 0;
2340 }
2341
2342 int tpm2_marshal_public(const TPM2B_PUBLIC *public, void **ret, size_t *ret_size) {
2343 size_t max_size = sizeof(*public), blob_size = 0;
2344 _cleanup_free_ void *blob = NULL;
2345 TSS2_RC rc;
2346
2347 assert(public);
2348 assert(ret);
2349 assert(ret_size);
2350
2351 blob = malloc0(max_size);
2352 if (!blob)
2353 return log_oom_debug();
2354
2355 rc = sym_Tss2_MU_TPM2B_PUBLIC_Marshal(public, blob, max_size, &blob_size);
2356 if (rc != TSS2_RC_SUCCESS)
2357 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2358 "Failed to marshal public key: %s", sym_Tss2_RC_Decode(rc));
2359
2360 *ret = TAKE_PTR(blob);
2361 *ret_size = blob_size;
2362 return 0;
2363 }
2364
2365 static int tpm2_unmarshal_public(const void *data, size_t size, TPM2B_PUBLIC *ret_public) {
2366 TPM2B_PUBLIC public = {};
2367 size_t offset = 0;
2368 TSS2_RC rc;
2369
2370 assert(data || size == 0);
2371 assert(ret_public);
2372
2373 rc = sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal(data, size, &offset, &public);
2374 if (rc != TSS2_RC_SUCCESS)
2375 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2376 "Failed to unmarshal public key: %s", sym_Tss2_RC_Decode(rc));
2377 if (offset != size)
2378 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2379 "Garbage at end of public key marshal data.");
2380
2381 *ret_public = public;
2382 return 0;
2383 }
2384
2385 int tpm2_marshal_nv_public(const TPM2B_NV_PUBLIC *nv_public, void **ret, size_t *ret_size) {
2386 size_t max_size = sizeof(*nv_public), blob_size = 0;
2387 _cleanup_free_ void *blob = NULL;
2388 TSS2_RC rc;
2389
2390 assert(nv_public);
2391 assert(ret);
2392 assert(ret_size);
2393
2394 blob = malloc0(max_size);
2395 if (!blob)
2396 return log_oom_debug();
2397
2398 rc = sym_Tss2_MU_TPM2B_NV_PUBLIC_Marshal(nv_public, blob, max_size, &blob_size);
2399 if (rc != TSS2_RC_SUCCESS)
2400 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2401 "Failed to marshal NV public structure: %s", sym_Tss2_RC_Decode(rc));
2402
2403 *ret = TAKE_PTR(blob);
2404 *ret_size = blob_size;
2405 return 0;
2406 }
2407
2408 int tpm2_unmarshal_nv_public(const void *data, size_t size, TPM2B_NV_PUBLIC *ret_nv_public) {
2409 TPM2B_NV_PUBLIC nv_public = {};
2410 size_t offset = 0;
2411 TSS2_RC rc;
2412
2413 assert(data || size == 0);
2414 assert(ret_nv_public);
2415
2416 rc = sym_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal(data, size, &offset, &nv_public);
2417 if (rc != TSS2_RC_SUCCESS)
2418 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2419 "Failed to unmarshal NV public structure: %s", sym_Tss2_RC_Decode(rc));
2420 if (offset != size)
2421 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2422 "Garbage at end of NV public structure marshal data.");
2423
2424 *ret_nv_public = nv_public;
2425 return 0;
2426 }
2427
2428 static int tpm2_import(
2429 Tpm2Context *c,
2430 const Tpm2Handle *parent,
2431 const Tpm2Handle *session,
2432 const TPM2B_PUBLIC *public,
2433 const TPM2B_PRIVATE *private,
2434 const TPM2B_ENCRYPTED_SECRET *seed,
2435 const TPM2B_DATA *encryption_key,
2436 const TPMT_SYM_DEF_OBJECT *symmetric,
2437 TPM2B_PRIVATE **ret_private) {
2438
2439 TSS2_RC rc;
2440
2441 assert(c);
2442 assert(parent);
2443 assert(!!encryption_key == !!symmetric);
2444 assert(public);
2445 assert(private);
2446 assert(seed);
2447 assert(ret_private);
2448
2449 log_debug("Importing key into TPM.");
2450
2451 rc = sym_Esys_Import(
2452 c->esys_context,
2453 parent->esys_handle,
2454 session ? session->esys_handle : ESYS_TR_PASSWORD,
2455 ESYS_TR_NONE,
2456 ESYS_TR_NONE,
2457 encryption_key,
2458 public,
2459 private,
2460 seed,
2461 symmetric ?: &(TPMT_SYM_DEF_OBJECT){ .algorithm = TPM2_ALG_NULL, },
2462 ret_private);
2463 if (rc != TSS2_RC_SUCCESS)
2464 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2465 "Failed to import key into TPM: %s", sym_Tss2_RC_Decode(rc));
2466
2467 return 0;
2468 }
2469
2470 /* Read hash values from the specified PCR selection. Provides a Tpm2PCRValue array that contains all
2471 * requested PCR values, in the order provided by the TPM. Normally, the provided pcr values will match
2472 * exactly what is in the provided selection, but the TPM may ignore some selected PCRs (for example, if an
2473 * unimplemented PCR index is requested), in which case those PCRs will be absent from the provided pcr
2474 * values. */
2475 int tpm2_pcr_read(
2476 Tpm2Context *c,
2477 const TPML_PCR_SELECTION *pcr_selection,
2478 Tpm2PCRValue **ret_pcr_values,
2479 size_t *ret_n_pcr_values) {
2480
2481 _cleanup_free_ Tpm2PCRValue *pcr_values = NULL;
2482 size_t n_pcr_values = 0;
2483 TSS2_RC rc;
2484
2485 assert(c);
2486 assert(pcr_selection);
2487 assert(ret_pcr_values);
2488 assert(ret_n_pcr_values);
2489
2490 TPML_PCR_SELECTION remaining = *pcr_selection;
2491 while (!tpm2_tpml_pcr_selection_is_empty(&remaining)) {
2492 _cleanup_(Esys_Freep) TPML_PCR_SELECTION *current_read = NULL;
2493 _cleanup_(Esys_Freep) TPML_DIGEST *current_values = NULL;
2494
2495 tpm2_log_debug_tpml_pcr_selection(&remaining, "Reading PCR selection");
2496
2497 /* Unfortunately, PCR_Read will not return more than 8 values. */
2498 rc = sym_Esys_PCR_Read(
2499 c->esys_context,
2500 ESYS_TR_NONE,
2501 ESYS_TR_NONE,
2502 ESYS_TR_NONE,
2503 &remaining,
2504 NULL,
2505 &current_read,
2506 &current_values);
2507 if (rc != TSS2_RC_SUCCESS)
2508 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2509 "Failed to read TPM2 PCRs: %s", sym_Tss2_RC_Decode(rc));
2510
2511 tpm2_log_debug_tpml_pcr_selection(current_read, "Read PCR selection");
2512
2513 if (tpm2_tpml_pcr_selection_is_empty(current_read)) {
2514 log_debug("TPM2 refused to read possibly unimplemented PCRs, ignoring.");
2515 break;
2516 }
2517
2518 unsigned i = 0;
2519 FOREACH_PCR_IN_TPML_PCR_SELECTION(index, tpms, current_read) {
2520 assert(i < current_values->count);
2521 Tpm2PCRValue pcr_value = {
2522 .index = index,
2523 .hash = tpms->hash,
2524 .value = current_values->digests[i++],
2525 };
2526
2527 tpm2_log_debug_pcr_value(&pcr_value, /* msg= */ NULL);
2528
2529 if (!GREEDY_REALLOC_APPEND(pcr_values, n_pcr_values, &pcr_value, 1))
2530 return log_oom_debug();
2531 }
2532 assert(i == current_values->count);
2533
2534 tpm2_tpml_pcr_selection_sub(&remaining, current_read);
2535 }
2536
2537 tpm2_sort_pcr_values(pcr_values, n_pcr_values);
2538
2539 if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values))
2540 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PCR values read from TPM are not valid.");
2541
2542 *ret_pcr_values = TAKE_PTR(pcr_values);
2543 *ret_n_pcr_values = n_pcr_values;
2544
2545 return 0;
2546 }
2547
2548 /* Read the PCR value for each TPM2PCRValue entry in the array that does not have a value set. If all entries
2549 * have an unset hash (i.e. hash == 0), this first detects the "best" PCR bank to use; otherwise, all entries
2550 * must have a valid hash set. All entries must have a valid index. If this cannot read a PCR value for all
2551 * appropriate entries, this returns an error. This does not check the array for validity. */
2552 int tpm2_pcr_read_missing_values(Tpm2Context *c, Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
2553 TPMI_ALG_HASH pcr_bank = 0;
2554 int r;
2555
2556 assert(c);
2557 assert(pcr_values || n_pcr_values == 0);
2558
2559 if (n_pcr_values > 0) {
2560 size_t hash_count;
2561 r = tpm2_pcr_values_hash_count(pcr_values, n_pcr_values, &hash_count);
2562 if (r < 0)
2563 return log_debug_errno(r, "Could not get hash count from pcr values: %m");
2564
2565 if (hash_count == 1 && pcr_values[0].hash == 0) {
2566 uint32_t mask;
2567 r = tpm2_pcr_values_to_mask(pcr_values, n_pcr_values, 0, &mask);
2568 if (r < 0)
2569 return r;
2570
2571 r = tpm2_get_best_pcr_bank(c, mask, &pcr_bank);
2572 if (r < 0)
2573 return r;
2574 }
2575 }
2576
2577 FOREACH_ARRAY(v, pcr_values, n_pcr_values) {
2578 if (v->hash == 0)
2579 v->hash = pcr_bank;
2580
2581 if (v->value.size > 0)
2582 continue;
2583
2584 TPML_PCR_SELECTION selection;
2585 r = tpm2_tpml_pcr_selection_from_pcr_values(v, 1, &selection, NULL, NULL);
2586 if (r < 0)
2587 return r;
2588
2589 _cleanup_free_ Tpm2PCRValue *read_values = NULL;
2590 size_t n_read_values;
2591 r = tpm2_pcr_read(c, &selection, &read_values, &n_read_values);
2592 if (r < 0)
2593 return r;
2594
2595 if (n_read_values == 0)
2596 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
2597 "Could not read PCR hash 0x%" PRIu16 " index %u",
2598 v->hash, v->index);
2599
2600 assert(n_read_values == 1);
2601 assert(read_values[0].hash == v->hash);
2602 assert(read_values[0].index == v->index);
2603
2604 v->value = read_values[0].value;
2605 }
2606
2607 return 0;
2608 }
2609
2610 static int tpm2_pcr_mask_good(
2611 Tpm2Context *c,
2612 TPMI_ALG_HASH bank,
2613 uint32_t mask) {
2614
2615 TPML_PCR_SELECTION selection;
2616 int r;
2617
2618 assert(c);
2619
2620 /* So we have the problem that some systems might have working TPM2 chips, but the firmware doesn't
2621 * actually measure into them, or only into a suboptimal bank. If so, the PCRs should be all zero or
2622 * all 0xFF. Detect that, so that we can warn and maybe pick a better bank. */
2623
2624 tpm2_tpml_pcr_selection_from_mask(mask, bank, &selection);
2625
2626 _cleanup_free_ Tpm2PCRValue *pcr_values = NULL;
2627 size_t n_pcr_values;
2628 r = tpm2_pcr_read(c, &selection, &pcr_values, &n_pcr_values);
2629 if (r < 0)
2630 return r;
2631
2632 /* If at least one of the selected PCR values is something other than all 0x00 or all 0xFF we are happy. */
2633 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
2634 if (!memeqbyte(0x00, v->value.buffer, v->value.size) &&
2635 !memeqbyte(0xFF, v->value.buffer, v->value.size))
2636 return true;
2637
2638 return false;
2639 }
2640
2641 static int tpm2_bank_has24(const TPMS_PCR_SELECTION *selection) {
2642
2643 assert(selection);
2644
2645 /* As per https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_PFP_r1p05_v23_pub.pdf a
2646 * TPM2 on a Client PC must have at least 24 PCRs. If this TPM has less, just skip over it. */
2647 if (selection->sizeofSelect < TPM2_PCRS_MAX/8) {
2648 log_debug("Skipping TPM2 PCR bank %s with fewer than 24 PCRs.",
2649 strna(tpm2_hash_alg_to_string(selection->hash)));
2650 return false;
2651 }
2652
2653 assert_cc(TPM2_PCRS_MAX % 8 == 0);
2654
2655 /* It's not enough to check how many PCRs there are, we also need to check that the 24 are
2656 * enabled for this bank. Otherwise this TPM doesn't qualify. */
2657 bool valid = true;
2658 for (size_t j = 0; j < TPM2_PCRS_MAX/8; j++)
2659 if (selection->pcrSelect[j] != 0xFF) {
2660 valid = false;
2661 break;
2662 }
2663
2664 if (!valid)
2665 log_debug("TPM2 PCR bank %s has fewer than 24 PCR bits enabled, ignoring.",
2666 strna(tpm2_hash_alg_to_string(selection->hash)));
2667
2668 return valid;
2669 }
2670
2671 int tpm2_get_best_pcr_bank(
2672 Tpm2Context *c,
2673 uint32_t pcr_mask,
2674 TPMI_ALG_HASH *ret) {
2675
2676 TPMI_ALG_HASH supported_hash = 0, hash_with_valid_pcr = 0;
2677 int r;
2678
2679 assert(c);
2680 assert(ret);
2681
2682 if (pcr_mask == 0) {
2683 log_debug("Asked to pick best PCR bank but no PCRs selected we could derive this from. Defaulting to SHA256.");
2684 *ret = TPM2_ALG_SHA256; /* if no PCRs are selected this doesn't matter anyway... */
2685 return 0;
2686 }
2687
2688 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection, &c->capability_pcrs) {
2689 TPMI_ALG_HASH hash = selection->hash;
2690 int good;
2691
2692 /* For now we are only interested in the SHA1 and SHA256 banks */
2693 if (!IN_SET(hash, TPM2_ALG_SHA256, TPM2_ALG_SHA1))
2694 continue;
2695
2696 r = tpm2_bank_has24(selection);
2697 if (r < 0)
2698 return r;
2699 if (!r)
2700 continue;
2701
2702 good = tpm2_pcr_mask_good(c, hash, pcr_mask);
2703 if (good < 0)
2704 return good;
2705
2706 if (hash == TPM2_ALG_SHA256) {
2707 supported_hash = TPM2_ALG_SHA256;
2708 if (good) {
2709 /* Great, SHA256 is supported and has initialized PCR values, we are done. */
2710 hash_with_valid_pcr = TPM2_ALG_SHA256;
2711 break;
2712 }
2713 } else {
2714 assert(hash == TPM2_ALG_SHA1);
2715
2716 if (supported_hash == 0)
2717 supported_hash = TPM2_ALG_SHA1;
2718
2719 if (good && hash_with_valid_pcr == 0)
2720 hash_with_valid_pcr = TPM2_ALG_SHA1;
2721 }
2722 }
2723
2724 /* We preferably pick SHA256, but only if its PCRs are initialized or neither the SHA1 nor the SHA256
2725 * PCRs are initialized. If SHA256 is not supported but SHA1 is and its PCRs are too, we prefer
2726 * SHA1.
2727 *
2728 * We log at LOG_NOTICE level whenever we end up using the SHA1 bank or when the PCRs we bind to are
2729 * not initialized. */
2730
2731 if (hash_with_valid_pcr == TPM2_ALG_SHA256) {
2732 assert(supported_hash == TPM2_ALG_SHA256);
2733 log_debug("TPM2 device supports SHA256 PCR bank and SHA256 PCRs are valid, yay!");
2734 *ret = TPM2_ALG_SHA256;
2735 } else if (hash_with_valid_pcr == TPM2_ALG_SHA1) {
2736 if (supported_hash == TPM2_ALG_SHA256)
2737 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.");
2738 else {
2739 assert(supported_hash == TPM2_ALG_SHA1);
2740 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.");
2741 }
2742
2743 *ret = TPM2_ALG_SHA1;
2744 } else if (supported_hash == TPM2_ALG_SHA256) {
2745 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!");
2746 *ret = TPM2_ALG_SHA256;
2747 } else if (supported_hash == TPM2_ALG_SHA1) {
2748 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!");
2749 *ret = TPM2_ALG_SHA1;
2750 } else
2751 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
2752 "TPM2 module supports neither SHA1 nor SHA256 PCR banks, cannot operate.");
2753
2754 return 0;
2755 }
2756
2757 int tpm2_get_good_pcr_banks(
2758 Tpm2Context *c,
2759 uint32_t pcr_mask,
2760 TPMI_ALG_HASH **ret) {
2761
2762 _cleanup_free_ TPMI_ALG_HASH *good_banks = NULL, *fallback_banks = NULL;
2763 size_t n_good_banks = 0, n_fallback_banks = 0;
2764 int r;
2765
2766 assert(c);
2767 assert(ret);
2768
2769 FOREACH_TPMS_PCR_SELECTION_IN_TPML_PCR_SELECTION(selection, &c->capability_pcrs) {
2770 TPMI_ALG_HASH hash = selection->hash;
2771
2772 /* Let's see if this bank is superficially OK, i.e. has at least 24 enabled registers */
2773 r = tpm2_bank_has24(selection);
2774 if (r < 0)
2775 return r;
2776 if (!r)
2777 continue;
2778
2779 /* Let's now see if this bank has any of the selected PCRs actually initialized */
2780 r = tpm2_pcr_mask_good(c, hash, pcr_mask);
2781 if (r < 0)
2782 return r;
2783
2784 if (n_good_banks + n_fallback_banks >= INT_MAX)
2785 return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "Too many good TPM2 banks?");
2786
2787 if (r) {
2788 if (!GREEDY_REALLOC(good_banks, n_good_banks+1))
2789 return log_oom_debug();
2790
2791 good_banks[n_good_banks++] = hash;
2792 } else {
2793 if (!GREEDY_REALLOC(fallback_banks, n_fallback_banks+1))
2794 return log_oom_debug();
2795
2796 fallback_banks[n_fallback_banks++] = hash;
2797 }
2798 }
2799
2800 /* Preferably, use the good banks (i.e. the ones the PCR values are actually initialized so
2801 * far). Otherwise use the fallback banks (i.e. which exist and are enabled, but so far not used. */
2802 if (n_good_banks > 0) {
2803 log_debug("Found %zu fully initialized TPM2 banks.", n_good_banks);
2804 *ret = TAKE_PTR(good_banks);
2805 return (int) n_good_banks;
2806 }
2807 if (n_fallback_banks > 0) {
2808 log_debug("Found %zu enabled but un-initialized TPM2 banks.", n_fallback_banks);
2809 *ret = TAKE_PTR(fallback_banks);
2810 return (int) n_fallback_banks;
2811 }
2812
2813 /* No suitable banks found. */
2814 *ret = NULL;
2815 return 0;
2816 }
2817
2818 int tpm2_get_good_pcr_banks_strv(
2819 Tpm2Context *c,
2820 uint32_t pcr_mask,
2821 char ***ret) {
2822
2823 #if HAVE_OPENSSL
2824 _cleanup_free_ TPMI_ALG_HASH *algs = NULL;
2825 _cleanup_strv_free_ char **l = NULL;
2826 int n_algs;
2827
2828 assert(c);
2829 assert(ret);
2830
2831 n_algs = tpm2_get_good_pcr_banks(c, pcr_mask, &algs);
2832 if (n_algs < 0)
2833 return n_algs;
2834
2835 FOREACH_ARRAY(a, algs, n_algs) {
2836 _cleanup_free_ char *n = NULL;
2837 const EVP_MD *implementation;
2838 const char *salg;
2839
2840 salg = tpm2_hash_alg_to_string(*a);
2841 if (!salg)
2842 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unknown PCR algorithm, can't measure.");
2843
2844 implementation = EVP_get_digestbyname(salg);
2845 if (!implementation)
2846 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unsupported PCR algorithm, can't measure.");
2847
2848 n = strdup(ASSERT_PTR(EVP_MD_name(implementation)));
2849 if (!n)
2850 return log_oom_debug();
2851
2852 ascii_strlower(n); /* OpenSSL uses uppercase digest names, we prefer them lower case. */
2853
2854 if (strv_consume(&l, TAKE_PTR(n)) < 0)
2855 return log_oom_debug();
2856 }
2857
2858 *ret = TAKE_PTR(l);
2859 return 0;
2860 #else /* HAVE_OPENSSL */
2861 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
2862 #endif
2863 }
2864
2865 /* Hash data into the digest.
2866 *
2867 * If 'extend' is true, the hashing operation starts with the existing digest hash (and the digest is
2868 * required to have a hash and its size must be correct). If 'extend' is false, the digest size is
2869 * initialized to the correct size for 'alg' and the hashing operation does not include any existing digest
2870 * hash. If 'extend' is false and no data is provided, the digest is initialized to a zero digest.
2871 *
2872 * On success, the digest hash will be updated with the hashing operation result and the digest size will be
2873 * correct for 'alg'.
2874 *
2875 * This currently only provides SHA256, so 'alg' must be TPM2_ALG_SHA256. */
2876 int tpm2_digest_many(
2877 TPMI_ALG_HASH alg,
2878 TPM2B_DIGEST *digest,
2879 const struct iovec data[],
2880 size_t n_data,
2881 bool extend) {
2882
2883 struct sha256_ctx ctx;
2884
2885 assert(digest);
2886 assert(data || n_data == 0);
2887
2888 if (alg != TPM2_ALG_SHA256)
2889 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
2890 "Hash algorithm not supported: 0x%x", alg);
2891
2892 if (extend && digest->size != SHA256_DIGEST_SIZE)
2893 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
2894 "Digest size 0x%x, require 0x%x",
2895 digest->size, (unsigned)SHA256_DIGEST_SIZE);
2896
2897 /* Since we're hardcoding SHA256 (for now), we can check this at compile time. */
2898 assert_cc(sizeof(digest->buffer) >= SHA256_DIGEST_SIZE);
2899
2900 CLEANUP_ERASE(ctx);
2901
2902 sha256_init_ctx(&ctx);
2903
2904 if (extend)
2905 sha256_process_bytes(digest->buffer, digest->size, &ctx);
2906 else {
2907 *digest = (TPM2B_DIGEST) {
2908 .size = SHA256_DIGEST_SIZE,
2909 };
2910 if (n_data == 0) /* If not extending and no data, return zero hash */
2911 return 0;
2912 }
2913
2914 FOREACH_ARRAY(d, data, n_data)
2915 sha256_process_bytes(d->iov_base, d->iov_len, &ctx);
2916
2917 sha256_finish_ctx(&ctx, digest->buffer);
2918
2919 return 0;
2920 }
2921
2922 /* Same as tpm2_digest_many() but data is contained in TPM2B_DIGEST[]. The digests may be any size digests. */
2923 int tpm2_digest_many_digests(
2924 TPMI_ALG_HASH alg,
2925 TPM2B_DIGEST *digest,
2926 const TPM2B_DIGEST data[],
2927 size_t n_data,
2928 bool extend) {
2929
2930 _cleanup_free_ struct iovec *iovecs = NULL;
2931
2932 assert(data || n_data == 0);
2933
2934 iovecs = new(struct iovec, n_data);
2935 if (!iovecs)
2936 return log_oom_debug();
2937
2938 for (size_t i = 0; i < n_data; i++)
2939 iovecs[i] = IOVEC_MAKE((void*) data[i].buffer, data[i].size);
2940
2941 return tpm2_digest_many(alg, digest, iovecs, n_data, extend);
2942 }
2943
2944 /* This hashes the provided pin into a digest value, but also verifies that the final byte is not 0, because
2945 * the TPM specification Part 1 ("Architecture") section Authorization Values (subsection "Authorization Size
2946 * Convention") states "Trailing octets of zero are to be removed from any string before it is used as an
2947 * authValue". Since the TPM doesn't know if the auth value is a "string" or just a hash digest, any hash
2948 * digest that randomly happens to end in 0 must have the final 0(s) trimmed.
2949 *
2950 * This is required at 2 points. First, when setting the authValue during creation of new sealed objects, in
2951 * tpm2_seal(). This only applies to newly created objects, of course. Second, when using a previously
2952 * created sealed object that has an authValue set, we use the sealed objects as the session bind key. This
2953 * requires calling SetAuth so tpm2-tss can correctly calculate the HMAC to use for the encryption session.
2954 *
2955 * TPM implementations will perform the trimming for any authValue for existing sealed objects, so the
2956 * tpm2-tss library must also perform the trimming before HMAC calculation, but it does not yet; this bug is
2957 * open to add the trimming: https://github.com/tpm2-software/tpm2-tss/issues/2664
2958 *
2959 * Until our minimum tpm2-tss version contains a fix for that bug, we must perform the trimming
2960 * ourselves. Note that since we are trimming, which is exactly what a TPM implementation would do, this will
2961 * work for both existing objects with a authValue ending in 0(s) as well as new sealed objects we create,
2962 * which we will trim the 0(s) from before sending to the TPM.
2963 */
2964 static void tpm2_trim_auth_value(TPM2B_AUTH *auth) {
2965 bool trimmed = false;
2966
2967 assert(auth);
2968
2969 while (auth->size > 0 && auth->buffer[auth->size - 1] == 0) {
2970 trimmed = true;
2971 auth->size--;
2972 }
2973
2974 if (trimmed)
2975 log_debug("authValue ends in 0, trimming as required by the TPM2 specification Part 1 section 'HMAC Computation' authValue Note 2.");
2976 }
2977
2978 int tpm2_auth_value_from_pin(TPMI_ALG_HASH hash, const char *pin, TPM2B_AUTH *ret_auth) {
2979 TPM2B_AUTH auth = {};
2980 int r;
2981
2982 assert(pin);
2983 assert(ret_auth);
2984
2985 r = tpm2_digest_buffer(hash, &auth, pin, strlen(pin), /* extend= */ false);
2986 if (r < 0)
2987 return r;
2988
2989 tpm2_trim_auth_value(&auth);
2990
2991 *ret_auth = TAKE_STRUCT(auth);
2992
2993 return 0;
2994 }
2995
2996 int tpm2_set_auth_binary(Tpm2Context *c, const Tpm2Handle *handle, const TPM2B_AUTH *auth) {
2997 TSS2_RC rc;
2998
2999 assert(c);
3000 assert(handle);
3001
3002 if (!auth)
3003 return 0;
3004
3005 rc = sym_Esys_TR_SetAuth(c->esys_context, handle->esys_handle, auth);
3006 if (rc != TSS2_RC_SUCCESS)
3007 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3008 "Failed to load PIN in TPM: %s", sym_Tss2_RC_Decode(rc));
3009
3010 return 0;
3011 }
3012
3013 int tpm2_set_auth(Tpm2Context *c, const Tpm2Handle *handle, const char *pin) {
3014 TPM2B_AUTH auth = {};
3015 int r;
3016
3017 assert(c);
3018 assert(handle);
3019
3020 if (!pin)
3021 return 0;
3022
3023 CLEANUP_ERASE(auth);
3024
3025 r = tpm2_auth_value_from_pin(TPM2_ALG_SHA256, pin, &auth);
3026 if (r < 0)
3027 return r;
3028
3029 return tpm2_set_auth_binary(c, handle, &auth);
3030 }
3031
3032 static bool tpm2_is_encryption_session(Tpm2Context *c, const Tpm2Handle *session) {
3033 TPMA_SESSION flags = 0;
3034 TSS2_RC rc;
3035
3036 assert(c);
3037 assert(session);
3038
3039 rc = sym_Esys_TRSess_GetAttributes(c->esys_context, session->esys_handle, &flags);
3040 if (rc != TSS2_RC_SUCCESS)
3041 return false;
3042
3043 return (flags & TPMA_SESSION_DECRYPT) && (flags & TPMA_SESSION_ENCRYPT);
3044 }
3045
3046 int tpm2_make_encryption_session(
3047 Tpm2Context *c,
3048 const Tpm2Handle *primary,
3049 const Tpm2Handle *bind_key,
3050 Tpm2Handle **ret_session) {
3051
3052 const TPMA_SESSION sessionAttributes = TPMA_SESSION_DECRYPT | TPMA_SESSION_ENCRYPT |
3053 TPMA_SESSION_CONTINUESESSION;
3054 TSS2_RC rc;
3055 int r;
3056
3057 assert(c);
3058 assert(primary);
3059 assert(ret_session);
3060
3061 log_debug("Starting HMAC encryption session.");
3062
3063 /* Start a salted, unbound HMAC session with a well-known key (e.g. primary key) as tpmKey, which
3064 * means that the random salt will be encrypted with the well-known key. That way, only the TPM can
3065 * recover the salt, which is then used for key derivation. */
3066 _cleanup_(tpm2_handle_freep) Tpm2Handle *session = NULL;
3067 r = tpm2_handle_new(c, &session);
3068 if (r < 0)
3069 return r;
3070
3071 rc = sym_Esys_StartAuthSession(
3072 c->esys_context,
3073 primary->esys_handle,
3074 bind_key ? bind_key->esys_handle : ESYS_TR_NONE,
3075 ESYS_TR_NONE,
3076 ESYS_TR_NONE,
3077 ESYS_TR_NONE,
3078 NULL,
3079 TPM2_SE_HMAC,
3080 &SESSION_TEMPLATE_SYM_AES_128_CFB,
3081 TPM2_ALG_SHA256,
3082 &session->esys_handle);
3083 if (rc != TSS2_RC_SUCCESS)
3084 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3085 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc));
3086
3087 /* Enable parameter encryption/decryption with AES in CFB mode. Together with HMAC digests (which are
3088 * always used for sessions), this provides confidentiality, integrity and replay protection for
3089 * operations that use this session. */
3090 rc = sym_Esys_TRSess_SetAttributes(c->esys_context, session->esys_handle, sessionAttributes, 0xff);
3091 if (rc != TSS2_RC_SUCCESS)
3092 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3093 "Failed to configure TPM session: %s", sym_Tss2_RC_Decode(rc));
3094
3095 *ret_session = TAKE_PTR(session);
3096
3097 return 0;
3098 }
3099
3100 int tpm2_make_policy_session(
3101 Tpm2Context *c,
3102 const Tpm2Handle *primary,
3103 const Tpm2Handle *encryption_session,
3104 Tpm2Handle **ret_session) {
3105
3106 TSS2_RC rc;
3107 int r;
3108
3109 assert(c);
3110 assert(primary);
3111 assert(encryption_session);
3112 assert(ret_session);
3113
3114 if (!tpm2_is_encryption_session(c, encryption_session))
3115 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
3116 "Missing encryption session");
3117
3118 log_debug("Starting policy session.");
3119
3120 _cleanup_(tpm2_handle_freep) Tpm2Handle *session = NULL;
3121 r = tpm2_handle_new(c, &session);
3122 if (r < 0)
3123 return r;
3124
3125 rc = sym_Esys_StartAuthSession(
3126 c->esys_context,
3127 primary->esys_handle,
3128 ESYS_TR_NONE,
3129 encryption_session->esys_handle,
3130 ESYS_TR_NONE,
3131 ESYS_TR_NONE,
3132 NULL,
3133 TPM2_SE_POLICY,
3134 &SESSION_TEMPLATE_SYM_AES_128_CFB,
3135 TPM2_ALG_SHA256,
3136 &session->esys_handle);
3137 if ((rc & ~TPM2_RC_N_MASK) == TPM2_RC_AUTH_FAIL)
3138 return log_debug_errno(SYNTHETIC_ERRNO(EILSEQ),
3139 "Authorization failure from TPM: %s", sym_Tss2_RC_Decode(rc));
3140 if (rc == TPM2_RC_LOCKOUT)
3141 return log_debug_errno(SYNTHETIC_ERRNO(ENOLCK),
3142 "TPM2 device is in dictionary attack lockout mode.");
3143 if (rc != TSS2_RC_SUCCESS)
3144 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3145 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc));
3146
3147 *ret_session = TAKE_PTR(session);
3148
3149 return 0;
3150 }
3151
3152 static int find_signature(
3153 sd_json_variant *v,
3154 const TPML_PCR_SELECTION *pcr_selection,
3155 const void *fp,
3156 size_t fp_size,
3157 const void *policy,
3158 size_t policy_size,
3159 void *ret_signature,
3160 size_t *ret_signature_size) {
3161
3162 #if HAVE_OPENSSL
3163 sd_json_variant *b, *i;
3164 const char *k;
3165 int r;
3166
3167 /* Searches for a signature blob in the specified JSON object. Search keys are PCR bank, PCR mask,
3168 * public key, and policy digest. */
3169
3170 if (!sd_json_variant_is_object(v))
3171 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Signature is not a JSON object.");
3172
3173 uint16_t pcr_bank = pcr_selection->pcrSelections[0].hash;
3174 uint32_t pcr_mask = tpm2_tpml_pcr_selection_to_mask(pcr_selection, pcr_bank);
3175
3176 k = tpm2_hash_alg_to_string(pcr_bank);
3177 if (!k)
3178 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Don't know PCR bank %" PRIu16, pcr_bank);
3179
3180 /* First, find field by bank */
3181 b = sd_json_variant_by_key(v, k);
3182 if (!b)
3183 return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Signature lacks data for PCR bank '%s'.", k);
3184
3185 if (!sd_json_variant_is_array(b))
3186 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Bank data is not a JSON array.");
3187
3188 /* Now iterate through all signatures known for this bank */
3189 JSON_VARIANT_ARRAY_FOREACH(i, b) {
3190 _cleanup_free_ void *fpj_data = NULL, *polj_data = NULL;
3191 sd_json_variant *maskj, *fpj, *sigj, *polj;
3192 size_t fpj_size, polj_size;
3193 uint32_t parsed_mask;
3194
3195 if (!sd_json_variant_is_object(i))
3196 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Bank data element is not a JSON object");
3197
3198 /* Check if the PCR mask matches our expectations */
3199 maskj = sd_json_variant_by_key(i, "pcrs");
3200 if (!maskj)
3201 continue;
3202
3203 r = tpm2_parse_pcr_json_array(maskj, &parsed_mask);
3204 if (r < 0)
3205 return log_debug_errno(r, "Failed to parse JSON PCR mask");
3206
3207 if (parsed_mask != pcr_mask)
3208 continue; /* Not for this PCR mask */
3209
3210 /* Then check if this is for the public key we operate with */
3211 fpj = sd_json_variant_by_key(i, "pkfp");
3212 if (!fpj)
3213 continue;
3214
3215 r = sd_json_variant_unhex(fpj, &fpj_data, &fpj_size);
3216 if (r < 0)
3217 return log_debug_errno(r, "Failed to decode fingerprint in JSON data: %m");
3218
3219 if (memcmp_nn(fp, fp_size, fpj_data, fpj_size) != 0)
3220 continue; /* Not for this public key */
3221
3222 /* Finally, check if this is for the PCR policy we expect this to be */
3223 polj = sd_json_variant_by_key(i, "pol");
3224 if (!polj)
3225 continue;
3226
3227 r = sd_json_variant_unhex(polj, &polj_data, &polj_size);
3228 if (r < 0)
3229 return log_debug_errno(r, "Failed to decode policy hash JSON data: %m");
3230
3231 if (memcmp_nn(policy, policy_size, polj_data, polj_size) != 0)
3232 continue;
3233
3234 /* This entry matches all our expectations, now return the signature included in it */
3235 sigj = sd_json_variant_by_key(i, "sig");
3236 if (!sigj)
3237 continue;
3238
3239 return sd_json_variant_unbase64(sigj, ret_signature, ret_signature_size);
3240 }
3241
3242 return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Couldn't find signature for this PCR bank, PCR index and public key.");
3243 #else /* HAVE_OPENSSL */
3244 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
3245 #endif
3246 }
3247
3248 /* Calculates the "name" of a public key.
3249 *
3250 * As specified in TPM2 spec "Part 1: Architecture", a key's "name" is its nameAlg value followed by a hash
3251 * of its TPM2 public area, all properly marshalled. This allows a key's "name" to be dependent not only on
3252 * the key fingerprint, but also on the TPM2-specific fields that associated with the key (i.e. all fields in
3253 * TPMT_PUBLIC). Note that this means an existing key may not change any of its TPMT_PUBLIC fields, since
3254 * that would also change the key name.
3255 *
3256 * Since we (currently) hardcode to always using SHA256 for hashing, this returns an error if the public key
3257 * nameAlg is not TPM2_ALG_SHA256. */
3258 int tpm2_calculate_pubkey_name(const TPMT_PUBLIC *public, TPM2B_NAME *ret_name) {
3259 TSS2_RC rc;
3260 int r;
3261
3262 assert(public);
3263 assert(ret_name);
3264
3265 r = dlopen_tpm2();
3266 if (r < 0)
3267 return log_debug_errno(r, "TPM2 support not installed: %m");
3268
3269 if (public->nameAlg != TPM2_ALG_SHA256)
3270 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
3271 "Unsupported nameAlg: 0x%x",
3272 public->nameAlg);
3273
3274 _cleanup_free_ uint8_t *buf = NULL;
3275 size_t size = 0;
3276
3277 buf = (uint8_t*) new(TPMT_PUBLIC, 1);
3278 if (!buf)
3279 return log_oom_debug();
3280
3281 rc = sym_Tss2_MU_TPMT_PUBLIC_Marshal(public, buf, sizeof(TPMT_PUBLIC), &size);
3282 if (rc != TSS2_RC_SUCCESS)
3283 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3284 "Failed to marshal public key: %s", sym_Tss2_RC_Decode(rc));
3285
3286 TPM2B_DIGEST digest = {};
3287 r = tpm2_digest_buffer(TPM2_ALG_SHA256, &digest, buf, size, /* extend= */ false);
3288 if (r < 0)
3289 return r;
3290
3291 TPMT_HA ha = {
3292 .hashAlg = TPM2_ALG_SHA256,
3293 };
3294 assert(digest.size <= sizeof(ha.digest.sha256));
3295 memcpy_safe(ha.digest.sha256, digest.buffer, digest.size);
3296
3297 TPM2B_NAME name;
3298 size = 0;
3299 rc = sym_Tss2_MU_TPMT_HA_Marshal(&ha, name.name, sizeof(name.name), &size);
3300 if (rc != TSS2_RC_SUCCESS)
3301 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3302 "Failed to marshal key name: %s", sym_Tss2_RC_Decode(rc));
3303 name.size = size;
3304
3305 tpm2_log_debug_name(&name, "Calculated public key name");
3306
3307 *ret_name = name;
3308
3309 return 0;
3310 }
3311
3312 /* Get the "name" of a key from the TPM.
3313 *
3314 * The "name" of a key is explained above in tpm2_calculate_pubkey_name().
3315 *
3316 * The handle must reference a key already present in the TPM. It may be either a public key only, or a
3317 * public/private keypair. */
3318 int tpm2_get_name(
3319 Tpm2Context *c,
3320 const Tpm2Handle *handle,
3321 TPM2B_NAME **ret_name) {
3322
3323 _cleanup_(Esys_Freep) TPM2B_NAME *name = NULL;
3324 TSS2_RC rc;
3325
3326 assert(c);
3327 assert(handle);
3328 assert(ret_name);
3329
3330 rc = sym_Esys_TR_GetName(c->esys_context, handle->esys_handle, &name);
3331 if (rc != TSS2_RC_SUCCESS)
3332 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3333 "Failed to get name of public key from TPM: %s", sym_Tss2_RC_Decode(rc));
3334
3335 tpm2_log_debug_name(name, "Object name");
3336
3337 *ret_name = TAKE_PTR(name);
3338
3339 return 0;
3340 }
3341
3342 int tpm2_calculate_nv_index_name(const TPMS_NV_PUBLIC *nvpublic, TPM2B_NAME *ret_name) {
3343 TSS2_RC rc;
3344 int r;
3345
3346 assert(nvpublic);
3347 assert(ret_name);
3348
3349 r = dlopen_tpm2();
3350 if (r < 0)
3351 return log_debug_errno(r, "TPM2 support not installed: %m");
3352
3353 if (nvpublic->nameAlg != TPM2_ALG_SHA256)
3354 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
3355 "Unsupported nameAlg: 0x%x",
3356 nvpublic->nameAlg);
3357
3358 _cleanup_free_ uint8_t *buf = NULL;
3359 size_t size = 0;
3360
3361 buf = (uint8_t*) new(TPMS_NV_PUBLIC, 1);
3362 if (!buf)
3363 return log_oom_debug();
3364
3365 rc = sym_Tss2_MU_TPMS_NV_PUBLIC_Marshal(nvpublic, buf, sizeof(TPMS_NV_PUBLIC), &size);
3366 if (rc != TSS2_RC_SUCCESS)
3367 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3368 "Failed to marshal NV index: %s", sym_Tss2_RC_Decode(rc));
3369
3370 TPM2B_DIGEST digest = {};
3371 r = tpm2_digest_buffer(TPM2_ALG_SHA256, &digest, buf, size, /* extend= */ false);
3372 if (r < 0)
3373 return r;
3374
3375 TPMT_HA ha = {
3376 .hashAlg = TPM2_ALG_SHA256,
3377 };
3378 assert(digest.size <= sizeof(ha.digest.sha256));
3379 memcpy_safe(ha.digest.sha256, digest.buffer, digest.size);
3380
3381 TPM2B_NAME name;
3382 size = 0;
3383 rc = sym_Tss2_MU_TPMT_HA_Marshal(&ha, name.name, sizeof(name.name), &size);
3384 if (rc != TSS2_RC_SUCCESS)
3385 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3386 "Failed to marshal NV index name: %s", sym_Tss2_RC_Decode(rc));
3387 name.size = size;
3388
3389 tpm2_log_debug_name(&name, "Calculated NV index name");
3390
3391 *ret_name = name;
3392
3393 return 0;
3394 }
3395
3396 /* Extend 'digest' with the PolicyAuthValue calculated hash. */
3397 int tpm2_calculate_policy_auth_value(TPM2B_DIGEST *digest) {
3398 TPM2_CC command = TPM2_CC_PolicyAuthValue;
3399 TSS2_RC rc;
3400 int r;
3401
3402 assert(digest);
3403 assert(digest->size == SHA256_DIGEST_SIZE);
3404
3405 r = dlopen_tpm2();
3406 if (r < 0)
3407 return log_debug_errno(r, "TPM2 support not installed: %m");
3408
3409 uint8_t buf[sizeof(command)];
3410 size_t offset = 0;
3411
3412 rc = sym_Tss2_MU_TPM2_CC_Marshal(command, buf, sizeof(buf), &offset);
3413 if (rc != TSS2_RC_SUCCESS)
3414 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3415 "Failed to marshal PolicyAuthValue command: %s", sym_Tss2_RC_Decode(rc));
3416
3417 if (offset != sizeof(command))
3418 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3419 "Offset 0x%zx wrong after marshalling PolicyAuthValue command", offset);
3420
3421 r = tpm2_digest_buffer(TPM2_ALG_SHA256, digest, buf, offset, /* extend= */ true);
3422 if (r < 0)
3423 return r;
3424
3425 tpm2_log_debug_digest(digest, "PolicyAuthValue calculated digest");
3426
3427 return 0;
3428 }
3429
3430 int tpm2_policy_auth_value(
3431 Tpm2Context *c,
3432 const Tpm2Handle *session,
3433 TPM2B_DIGEST **ret_policy_digest) {
3434
3435 TSS2_RC rc;
3436
3437 assert(c);
3438 assert(session);
3439
3440 log_debug("Submitting AuthValue policy.");
3441
3442 rc = sym_Esys_PolicyAuthValue(
3443 c->esys_context,
3444 session->esys_handle,
3445 ESYS_TR_NONE,
3446 ESYS_TR_NONE,
3447 ESYS_TR_NONE);
3448 if (rc != TSS2_RC_SUCCESS)
3449 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3450 "Failed to add authValue policy to TPM: %s",
3451 sym_Tss2_RC_Decode(rc));
3452
3453 return tpm2_get_policy_digest(c, session, ret_policy_digest);
3454 }
3455
3456 /* Extend 'digest' with the PolicySigned calculated hash. */
3457 int tpm2_calculate_policy_signed(TPM2B_DIGEST *digest, const TPM2B_NAME *name) {
3458 TPM2_CC command = TPM2_CC_PolicySigned;
3459 TSS2_RC rc;
3460 int r;
3461
3462 assert(digest);
3463 assert(digest->size == SHA256_DIGEST_SIZE);
3464 assert(name);
3465
3466 r = dlopen_tpm2();
3467 if (r < 0)
3468 return log_debug_errno(r, "TPM2 support not installed: %m");
3469
3470 uint8_t buf[sizeof(command)];
3471 size_t offset = 0;
3472
3473 rc = sym_Tss2_MU_TPM2_CC_Marshal(command, buf, sizeof(buf), &offset);
3474 if (rc != TSS2_RC_SUCCESS)
3475 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3476 "Failed to marshal PolicySigned command: %s", sym_Tss2_RC_Decode(rc));
3477
3478 if (offset != sizeof(command))
3479 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3480 "Offset 0x%zx wrong after marshalling PolicySigned command", offset);
3481
3482 struct iovec data[] = {
3483 IOVEC_MAKE(buf, offset),
3484 IOVEC_MAKE(name->name, name->size),
3485 };
3486
3487 r = tpm2_digest_many(TPM2_ALG_SHA256, digest, data, ELEMENTSOF(data), /* extend= */ true);
3488 if (r < 0)
3489 return r;
3490
3491 const TPM2B_NONCE policyRef = {}; /* For now, we do not make use of the policyRef stuff */
3492
3493 r = tpm2_digest_buffer(TPM2_ALG_SHA256, digest, policyRef.buffer, policyRef.size, /* extend= */ true);
3494 if (r < 0)
3495 return r;
3496
3497 tpm2_log_debug_digest(digest, "PolicySigned calculated digest");
3498
3499 return 0;
3500 }
3501
3502 int tpm2_policy_signed_hmac_sha256(
3503 Tpm2Context *c,
3504 const Tpm2Handle *session,
3505 const Tpm2Handle *hmac_key_handle,
3506 const struct iovec *hmac_key,
3507 TPM2B_DIGEST **ret_policy_digest) {
3508
3509 #if HAVE_OPENSSL
3510 TSS2_RC rc;
3511 int r;
3512
3513 assert(c);
3514 assert(session);
3515 assert(hmac_key_handle);
3516 assert(iovec_is_set(hmac_key));
3517
3518 /* This sends a TPM2_PolicySigned command to the tpm. As signature key we use an HMAC-SHA256 key
3519 * specified in the hmac_key parameter. The secret key must be loaded into the TPM already and
3520 * referenced in hmac_key_handle. */
3521
3522 log_debug("Submitting PolicySigned policy for HMAC-SHA256.");
3523
3524 /* Acquire the nonce from the TPM that we shall sign */
3525 _cleanup_(Esys_Freep) TPM2B_NONCE *nonce = NULL;
3526 rc = sym_Esys_TRSess_GetNonceTPM(
3527 c->esys_context,
3528 session->esys_handle,
3529 &nonce);
3530 if (rc != TSS2_RC_SUCCESS)
3531 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3532 "Failed to determine NoneTPM of auth session: %s",
3533 sym_Tss2_RC_Decode(rc));
3534
3535 be32_t expiration = htobe64(0);
3536 const TPM2B_DIGEST cpHashA = {}; /* For now, we do not make use of the cpHashA stuff */
3537 const TPM2B_NONCE policyRef = {}; /* ditto, we do not bother with policyRef */
3538
3539 /* Put together the data to sign, as per TPM2 Spec Part 3, 23.3.1 */
3540 struct iovec data_to_sign[] = {
3541 IOVEC_MAKE(nonce->buffer, nonce->size),
3542 IOVEC_MAKE(&expiration, sizeof(expiration)),
3543 IOVEC_MAKE(cpHashA.buffer, cpHashA.size),
3544 IOVEC_MAKE(policyRef.buffer, policyRef.size),
3545 };
3546
3547 /* Now calculate the digest of the data we put together */
3548 TPM2B_DIGEST digest_to_sign;
3549 r = tpm2_digest_many(TPM2_ALG_SHA256, &digest_to_sign, data_to_sign, ELEMENTSOF(data_to_sign), /* extend= */ false);
3550 if (r < 0)
3551 return r;
3552
3553 unsigned char hmac_signature[SHA256_DIGEST_SIZE];
3554 unsigned hmac_signature_size = sizeof(hmac_signature);
3555
3556 /* And sign this with our key */
3557 if (!HMAC(EVP_sha256(),
3558 hmac_key->iov_base,
3559 hmac_key->iov_len,
3560 digest_to_sign.buffer,
3561 digest_to_sign.size,
3562 hmac_signature,
3563 &hmac_signature_size))
3564 return -ENOTRECOVERABLE;
3565
3566 /* Now bring the signature into a format that the TPM understands */
3567 TPMT_SIGNATURE sig = {
3568 .sigAlg = TPM2_ALG_HMAC,
3569 .signature.hmac.hashAlg = TPM2_ALG_SHA256,
3570 };
3571 assert(hmac_signature_size == sizeof(sig.signature.hmac.digest.sha256));
3572 memcpy(sig.signature.hmac.digest.sha256, hmac_signature, hmac_signature_size);
3573
3574 /* And submit the whole shebang to the TPM */
3575 rc = sym_Esys_PolicySigned(
3576 c->esys_context,
3577 hmac_key_handle->esys_handle,
3578 session->esys_handle,
3579 /* shandle1= */ ESYS_TR_NONE,
3580 /* shandle2= */ ESYS_TR_NONE,
3581 /* shandle3= */ ESYS_TR_NONE,
3582 nonce,
3583 &cpHashA,
3584 &policyRef,
3585 expiration,
3586 &sig,
3587 /* timeout= */ NULL,
3588 /* policyTicket= */ NULL);
3589 if (rc != TSS2_RC_SUCCESS)
3590 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3591 "Failed to add PolicySigned policy to TPM: %s",
3592 sym_Tss2_RC_Decode(rc));
3593
3594 return tpm2_get_policy_digest(c, session, ret_policy_digest);
3595 #else /* HAVE_OPENSSL */
3596 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
3597 #endif
3598 }
3599
3600 int tpm2_calculate_policy_authorize_nv(
3601 const TPM2B_NV_PUBLIC *public_info,
3602 TPM2B_DIGEST *digest) {
3603 TPM2_CC command = TPM2_CC_PolicyAuthorizeNV;
3604 TSS2_RC rc;
3605 int r;
3606
3607 assert(public_info);
3608 assert(digest);
3609 assert(digest->size == SHA256_DIGEST_SIZE);
3610
3611 r = dlopen_tpm2();
3612 if (r < 0)
3613 return log_debug_errno(r, "TPM2 support not installed: %m");
3614
3615 uint8_t buf[sizeof(command)];
3616 size_t offset = 0;
3617
3618 rc = sym_Tss2_MU_TPM2_CC_Marshal(command, buf, sizeof(buf), &offset);
3619 if (rc != TSS2_RC_SUCCESS)
3620 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3621 "Failed to marshal PolicyAuthorizeNV command: %s", sym_Tss2_RC_Decode(rc));
3622
3623 if (offset != sizeof(command))
3624 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3625 "Offset 0x%zx wrong after marshalling PolicyAuthorizeNV command", offset);
3626
3627 TPM2B_NV_PUBLIC public_info_copy = *public_info; /* Make a copy, since we must set TPMA_NV_WRITTEN for the calculation */
3628 public_info_copy.nvPublic.attributes |= TPMA_NV_WRITTEN;
3629
3630 TPM2B_NAME name = {};
3631 r = tpm2_calculate_nv_index_name(&public_info_copy.nvPublic, &name);
3632 if (r < 0)
3633 return r;
3634
3635 struct iovec data[] = {
3636 IOVEC_MAKE(buf, offset),
3637 IOVEC_MAKE(name.name, name.size),
3638 };
3639
3640 r = tpm2_digest_many(TPM2_ALG_SHA256, digest, data, ELEMENTSOF(data), /* extend= */ true);
3641 if (r < 0)
3642 return r;
3643
3644 tpm2_log_debug_digest(digest, "PolicyAuthorizeNV calculated digest");
3645
3646 return 0;
3647 }
3648
3649 int tpm2_policy_authorize_nv(
3650 Tpm2Context *c,
3651 const Tpm2Handle *session,
3652 const Tpm2Handle *nv_handle,
3653 TPM2B_DIGEST **ret_policy_digest) {
3654
3655 TSS2_RC rc;
3656
3657 assert(c);
3658 assert(session);
3659
3660 log_debug("Submitting AuthorizeNV policy.");
3661
3662 rc = sym_Esys_PolicyAuthorizeNV(
3663 c->esys_context,
3664 ESYS_TR_RH_OWNER,
3665 nv_handle->esys_handle,
3666 session->esys_handle,
3667 ESYS_TR_PASSWORD,
3668 ESYS_TR_NONE,
3669 ESYS_TR_NONE);
3670 if ((rc & ~(TPM2_RC_N_MASK|TPM2_RC_P)) == TPM2_RC_VALUE) /* Return a recognizable error if the policy
3671 * in the NV index does not match what we
3672 * just put together */
3673 return log_debug_errno(SYNTHETIC_ERRNO(EREMCHG),
3674 "Submitted policy does not match policy stored in PolicyAuthorizeNV.");
3675 if (rc != TSS2_RC_SUCCESS)
3676 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3677 "Failed to add AuthorizeNV policy to TPM: %s",
3678 sym_Tss2_RC_Decode(rc));
3679
3680 return tpm2_get_policy_digest(c, session, ret_policy_digest);
3681 }
3682
3683 int tpm2_policy_or(
3684 Tpm2Context *c,
3685 const Tpm2Handle *session,
3686 const TPM2B_DIGEST *branches, size_t n_branches,
3687 TPM2B_DIGEST **ret_policy_digest) {
3688
3689 TPML_DIGEST hash_list;
3690 TSS2_RC rc;
3691
3692 assert(c);
3693 assert(session);
3694
3695 if (n_branches > ELEMENTSOF(hash_list.digests))
3696 return -EOPNOTSUPP;
3697
3698 log_debug("Submitting OR policy.");
3699
3700 hash_list = (TPML_DIGEST) {
3701 .count = n_branches,
3702 };
3703
3704 memcpy(hash_list.digests, branches, n_branches * sizeof(TPM2B_DIGEST));
3705
3706 if (DEBUG_LOGGING)
3707 for (size_t i = 0; i < hash_list.count; i++) {
3708 _cleanup_free_ char *h = hexmem(hash_list.digests[i].buffer, hash_list.digests[i].size);
3709 log_debug("Submitting OR Branch #%zu: %s", i, h);
3710 }
3711
3712 rc = sym_Esys_PolicyOR(
3713 c->esys_context,
3714 session->esys_handle,
3715 ESYS_TR_NONE,
3716 ESYS_TR_NONE,
3717 ESYS_TR_NONE,
3718 &hash_list);
3719 if ((rc & ~(TPM2_RC_N_MASK|TPM2_RC_P)) == TPM2_RC_VALUE) /* Return a recognizable error if none of the OR branches matched */
3720 return log_debug_errno(SYNTHETIC_ERRNO(ENOANO),
3721 "None of the PolicyOR branches matched the current policy state.");
3722 if (rc != TSS2_RC_SUCCESS)
3723 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3724 "Failed to add OR policy to TPM: %s",
3725 sym_Tss2_RC_Decode(rc));
3726
3727 return tpm2_get_policy_digest(c, session, ret_policy_digest);
3728 }
3729
3730 /* Extend 'digest' with the PolicyOR calculated hash. */
3731 int tpm2_calculate_policy_or(const TPM2B_DIGEST *branches, size_t n_branches, TPM2B_DIGEST *digest) {
3732 TPM2_CC command = TPM2_CC_PolicyOR;
3733 TSS2_RC rc;
3734 int r;
3735
3736 assert(digest);
3737 assert(digest->size == SHA256_DIGEST_SIZE);
3738
3739 if (n_branches == 0)
3740 return -EINVAL;
3741 if (n_branches == 1)
3742 log_warning("PolicyOR with a single branch submitted, this is weird.");
3743 if (n_branches > 8)
3744 return -E2BIG;
3745
3746 r = dlopen_tpm2();
3747 if (r < 0)
3748 return log_error_errno(r, "TPM2 support not installed: %m");
3749
3750 uint8_t buf[sizeof(command)];
3751 size_t offset = 0;
3752
3753 rc = sym_Tss2_MU_TPM2_CC_Marshal(command, buf, sizeof(buf), &offset);
3754 if (rc != TSS2_RC_SUCCESS)
3755 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3756 "Failed to marshal PolicyOR command: %s", sym_Tss2_RC_Decode(rc));
3757
3758 if (offset != sizeof(command))
3759 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3760 "Offset 0x%zx wrong after marshalling PolicyOR command", offset);
3761 _cleanup_free_ struct iovec *data = new(struct iovec, 1 + n_branches);
3762 if (!data)
3763 return log_oom();
3764
3765 data[0] = IOVEC_MAKE(buf, offset);
3766 for (size_t i = 0; i < n_branches; i++) {
3767 data[1 + i] = IOVEC_MAKE((void*) branches[i].buffer, branches[i].size);
3768
3769 if (DEBUG_LOGGING) {
3770 _cleanup_free_ char *h = hexmem(branches[i].buffer, branches[i].size);
3771 log_debug("OR Branch #%zu: %s", i, h);
3772 }
3773 }
3774
3775 /* PolicyOR does not use the previous hash value; we must zero and then extend it. */
3776 zero(digest->buffer);
3777
3778 r = tpm2_digest_many(TPM2_ALG_SHA256, digest, data, 1 + n_branches, /* extend= */ true);
3779 if (r < 0)
3780 return r;
3781
3782 tpm2_log_debug_digest(digest, "PolicyOR calculated digest");
3783
3784 return 0;
3785 }
3786
3787 /* Extend 'digest' with the PolicyPCR calculated hash. */
3788 int tpm2_calculate_policy_pcr(
3789 const Tpm2PCRValue *pcr_values,
3790 size_t n_pcr_values,
3791 TPM2B_DIGEST *digest) {
3792
3793 TPM2_CC command = TPM2_CC_PolicyPCR;
3794 TSS2_RC rc;
3795 int r;
3796
3797 assert(pcr_values || n_pcr_values == 0);
3798 assert(digest);
3799 assert(digest->size == SHA256_DIGEST_SIZE);
3800
3801 r = dlopen_tpm2();
3802 if (r < 0)
3803 return log_debug_errno(r, "TPM2 support not installed: %m");
3804
3805 TPML_PCR_SELECTION pcr_selection;
3806 _cleanup_free_ TPM2B_DIGEST *values = NULL;
3807 size_t n_values;
3808 r = tpm2_tpml_pcr_selection_from_pcr_values(pcr_values, n_pcr_values, &pcr_selection, &values, &n_values);
3809 if (r < 0)
3810 return log_debug_errno(r, "Could not convert PCR values to TPML_PCR_SELECTION: %m");
3811
3812 TPM2B_DIGEST hash = {};
3813 r = tpm2_digest_many_digests(TPM2_ALG_SHA256, &hash, values, n_values, /* extend= */ false);
3814 if (r < 0)
3815 return r;
3816
3817 _cleanup_free_ uint8_t *buf = NULL;
3818 size_t size = 0, maxsize = sizeof(command) + sizeof(pcr_selection);
3819
3820 buf = malloc(maxsize);
3821 if (!buf)
3822 return log_oom_debug();
3823
3824 rc = sym_Tss2_MU_TPM2_CC_Marshal(command, buf, maxsize, &size);
3825 if (rc != TSS2_RC_SUCCESS)
3826 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3827 "Failed to marshal PolicyPCR command: %s", sym_Tss2_RC_Decode(rc));
3828
3829 rc = sym_Tss2_MU_TPML_PCR_SELECTION_Marshal(&pcr_selection, buf, maxsize, &size);
3830 if (rc != TSS2_RC_SUCCESS)
3831 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3832 "Failed to marshal PCR selection: %s", sym_Tss2_RC_Decode(rc));
3833
3834 struct iovec data[] = {
3835 IOVEC_MAKE(buf, size),
3836 IOVEC_MAKE(hash.buffer, hash.size),
3837 };
3838 r = tpm2_digest_many(TPM2_ALG_SHA256, digest, data, ELEMENTSOF(data), /* extend= */ true);
3839 if (r < 0)
3840 return r;
3841
3842 tpm2_log_debug_digest(digest, "PolicyPCR calculated digest");
3843
3844 return 0;
3845 }
3846
3847 int tpm2_policy_pcr(
3848 Tpm2Context *c,
3849 const Tpm2Handle *session,
3850 const TPML_PCR_SELECTION *pcr_selection,
3851 TPM2B_DIGEST **ret_policy_digest) {
3852
3853 TSS2_RC rc;
3854
3855 assert(c);
3856 assert(session);
3857 assert(pcr_selection);
3858
3859 log_debug("Submitting PCR hash policy.");
3860
3861 rc = sym_Esys_PolicyPCR(
3862 c->esys_context,
3863 session->esys_handle,
3864 ESYS_TR_NONE,
3865 ESYS_TR_NONE,
3866 ESYS_TR_NONE,
3867 NULL,
3868 pcr_selection);
3869 if (rc == TPM2_RC_PCR_CHANGED)
3870 return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN),
3871 "Failed to add PCR policy to TPM: %s", sym_Tss2_RC_Decode(rc));
3872 if (rc != TSS2_RC_SUCCESS)
3873 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3874 "Failed to add PCR policy to TPM: %s", sym_Tss2_RC_Decode(rc));
3875
3876 return tpm2_get_policy_digest(c, session, ret_policy_digest);
3877 }
3878
3879 /* Extend 'digest' with the PolicyAuthorize calculated hash. */
3880 int tpm2_calculate_policy_authorize(
3881 const TPM2B_PUBLIC *public,
3882 const TPM2B_DIGEST *policy_ref,
3883 TPM2B_DIGEST *digest) {
3884
3885 TPM2_CC command = TPM2_CC_PolicyAuthorize;
3886 TSS2_RC rc;
3887 int r;
3888
3889 assert(public);
3890 assert(digest);
3891 assert(digest->size == SHA256_DIGEST_SIZE);
3892
3893 r = dlopen_tpm2();
3894 if (r < 0)
3895 return log_debug_errno(r, "TPM2 support not installed: %m");
3896
3897 uint8_t buf[sizeof(command)];
3898 size_t offset = 0;
3899
3900 rc = sym_Tss2_MU_TPM2_CC_Marshal(command, buf, sizeof(buf), &offset);
3901 if (rc != TSS2_RC_SUCCESS)
3902 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3903 "Failed to marshal PolicyAuthorize command: %s", sym_Tss2_RC_Decode(rc));
3904
3905 if (offset != sizeof(command))
3906 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
3907 "Offset 0x%zx wrong after marshalling PolicyAuthorize command", offset);
3908
3909 TPM2B_NAME name = {};
3910 r = tpm2_calculate_pubkey_name(&public->publicArea, &name);
3911 if (r < 0)
3912 return r;
3913
3914 /* PolicyAuthorize does not use the previous hash value; we must zero and then extend it. */
3915 zero(digest->buffer);
3916
3917 struct iovec data[] = {
3918 IOVEC_MAKE(buf, offset),
3919 IOVEC_MAKE(name.name, name.size),
3920 };
3921 r = tpm2_digest_many(TPM2_ALG_SHA256, digest, data, ELEMENTSOF(data), /* extend= */ true);
3922 if (r < 0)
3923 return r;
3924
3925 /* PolicyAuthorize requires hashing twice; this is either an extension or rehashing. */
3926 if (policy_ref)
3927 r = tpm2_digest_many_digests(TPM2_ALG_SHA256, digest, policy_ref, 1, /* extend= */ true);
3928 else
3929 r = tpm2_digest_rehash(TPM2_ALG_SHA256, digest);
3930 if (r < 0)
3931 return r;
3932
3933 tpm2_log_debug_digest(digest, "PolicyAuthorize calculated digest");
3934
3935 return 0;
3936 }
3937
3938 static int tpm2_policy_authorize(
3939 Tpm2Context *c,
3940 const Tpm2Handle *session,
3941 TPML_PCR_SELECTION *pcr_selection,
3942 const TPM2B_PUBLIC *public,
3943 const void *fp,
3944 size_t fp_size,
3945 sd_json_variant *signature_json,
3946 TPM2B_DIGEST **ret_policy_digest) {
3947
3948 TSS2_RC rc;
3949 int r;
3950
3951 assert(c);
3952 assert(session);
3953 assert(pcr_selection);
3954 assert(public);
3955 assert(fp && fp_size > 0);
3956
3957 log_debug("Adding PCR signature policy.");
3958
3959 _cleanup_(tpm2_handle_freep) Tpm2Handle *pubkey_handle = NULL;
3960 r = tpm2_load_external(c, NULL, public, NULL, &pubkey_handle);
3961 if (r < 0)
3962 return r;
3963
3964 /* Acquire the "name" of what we just loaded */
3965 _cleanup_(Esys_Freep) TPM2B_NAME *pubkey_name = NULL;
3966 r = tpm2_get_name(c, pubkey_handle, &pubkey_name);
3967 if (r < 0)
3968 return r;
3969
3970 /* If we have a signature, proceed with verifying the PCR digest */
3971 const TPMT_TK_VERIFIED *check_ticket;
3972 _cleanup_(Esys_Freep) TPMT_TK_VERIFIED *check_ticket_buffer = NULL;
3973 _cleanup_(Esys_Freep) TPM2B_DIGEST *approved_policy = NULL;
3974 if (signature_json) {
3975 r = tpm2_policy_pcr(
3976 c,
3977 session,
3978 pcr_selection,
3979 &approved_policy);
3980 if (r < 0)
3981 return r;
3982
3983 _cleanup_free_ void *signature_raw = NULL;
3984 size_t signature_size;
3985
3986 r = find_signature(
3987 signature_json,
3988 pcr_selection,
3989 fp, fp_size,
3990 approved_policy->buffer,
3991 approved_policy->size,
3992 &signature_raw,
3993 &signature_size);
3994 if (r < 0)
3995 return r;
3996
3997 /* TPM2_VerifySignature() will only verify the RSA part of the RSA+SHA256 signature,
3998 * hence we need to do the SHA256 part ourselves, first */
3999 TPM2B_DIGEST signature_hash = *approved_policy;
4000 r = tpm2_digest_rehash(TPM2_ALG_SHA256, &signature_hash);
4001 if (r < 0)
4002 return r;
4003
4004 r = TPM2B_PUBLIC_KEY_RSA_CHECK_SIZE(signature_size);
4005 if (r < 0)
4006 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Signature larger than buffer.");
4007
4008 TPMT_SIGNATURE policy_signature = {
4009 .sigAlg = TPM2_ALG_RSASSA,
4010 .signature.rsassa = {
4011 .hash = TPM2_ALG_SHA256,
4012 .sig = TPM2B_PUBLIC_KEY_RSA_MAKE(signature_raw, signature_size),
4013 },
4014 };
4015
4016 rc = sym_Esys_VerifySignature(
4017 c->esys_context,
4018 pubkey_handle->esys_handle,
4019 ESYS_TR_NONE,
4020 ESYS_TR_NONE,
4021 ESYS_TR_NONE,
4022 &signature_hash,
4023 &policy_signature,
4024 &check_ticket_buffer);
4025 if (rc != TSS2_RC_SUCCESS)
4026 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4027 "Failed to validate signature in TPM: %s", sym_Tss2_RC_Decode(rc));
4028
4029 check_ticket = check_ticket_buffer;
4030 } else {
4031 /* When enrolling, we pass a NULL ticket */
4032 static const TPMT_TK_VERIFIED check_ticket_null = {
4033 .tag = TPM2_ST_VERIFIED,
4034 .hierarchy = TPM2_RH_OWNER,
4035 };
4036
4037 check_ticket = &check_ticket_null;
4038 }
4039
4040 rc = sym_Esys_PolicyAuthorize(
4041 c->esys_context,
4042 session->esys_handle,
4043 ESYS_TR_NONE,
4044 ESYS_TR_NONE,
4045 ESYS_TR_NONE,
4046 approved_policy,
4047 /* policyRef= */ &(const TPM2B_NONCE) {},
4048 pubkey_name,
4049 check_ticket);
4050 if (rc != TSS2_RC_SUCCESS)
4051 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4052 "Failed to push Authorize policy into TPM: %s", sym_Tss2_RC_Decode(rc));
4053
4054 return tpm2_get_policy_digest(c, session, ret_policy_digest);
4055 }
4056
4057 /* Extend 'digest' with the calculated policy hash. */
4058 int tpm2_calculate_sealing_policy(
4059 const Tpm2PCRValue *pcr_values,
4060 size_t n_pcr_values,
4061 const TPM2B_PUBLIC *public,
4062 bool use_pin,
4063 const Tpm2PCRLockPolicy *pcrlock_policy,
4064 TPM2B_DIGEST *digest) {
4065
4066 int r;
4067
4068 assert(pcr_values || n_pcr_values == 0);
4069 assert(digest);
4070
4071 /* The combination of signed PCR policies and pcrlock is not supported (because we cannot combine
4072 * PolicyAuthorize and PolicyAuthorizeNV in one policy). Callers need to use "sharding" of the
4073 * symmetric FDE unlock key to make policies like that work. */
4074 if (public && pcrlock_policy)
4075 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Policies that combined signed PCR and pcrlock are not supported.");
4076
4077 if (public) {
4078 r = tpm2_calculate_policy_authorize(public, NULL, digest);
4079 if (r < 0)
4080 return r;
4081 }
4082
4083 if (pcrlock_policy) {
4084 TPM2B_NV_PUBLIC nv_public;
4085
4086 r = tpm2_unmarshal_nv_public(
4087 pcrlock_policy->nv_public.iov_base,
4088 pcrlock_policy->nv_public.iov_len,
4089 &nv_public);
4090 if (r < 0)
4091 return r;
4092
4093 r = tpm2_calculate_policy_authorize_nv(&nv_public, digest);
4094 if (r < 0)
4095 return r;
4096 }
4097
4098 if (n_pcr_values > 0) {
4099 r = tpm2_calculate_policy_pcr(pcr_values, n_pcr_values, digest);
4100 if (r < 0)
4101 return r;
4102 }
4103
4104 if (use_pin) {
4105 r = tpm2_calculate_policy_auth_value(digest);
4106 if (r < 0)
4107 return r;
4108 }
4109
4110 return 0;
4111 }
4112
4113 static int tpm2_build_sealing_policy(
4114 Tpm2Context *c,
4115 const Tpm2Handle *session,
4116 uint32_t hash_pcr_mask,
4117 uint16_t pcr_bank,
4118 const TPM2B_PUBLIC *public,
4119 const void *fp,
4120 size_t fp_size,
4121 uint32_t pubkey_pcr_mask,
4122 sd_json_variant *signature_json,
4123 bool use_pin,
4124 const Tpm2PCRLockPolicy *pcrlock_policy,
4125 TPM2B_DIGEST **ret_policy_digest) {
4126
4127 int r;
4128
4129 assert(c);
4130 assert(session);
4131 assert(pubkey_pcr_mask == 0 || public);
4132
4133 log_debug("Building sealing policy.");
4134
4135 if ((hash_pcr_mask | pubkey_pcr_mask) != 0) {
4136 r = tpm2_pcr_mask_good(c, pcr_bank, hash_pcr_mask|pubkey_pcr_mask);
4137 if (r < 0)
4138 return r;
4139 if (r == 0)
4140 log_debug("Selected TPM2 PCRs are not initialized on this system.");
4141 }
4142
4143 if (pubkey_pcr_mask != 0 && pcrlock_policy)
4144 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Policies with both signed PCR and pcrlock are currently not supported.");
4145
4146 if (pubkey_pcr_mask != 0) {
4147 TPML_PCR_SELECTION pcr_selection;
4148 tpm2_tpml_pcr_selection_from_mask(pubkey_pcr_mask, (TPMI_ALG_HASH)pcr_bank, &pcr_selection);
4149 r = tpm2_policy_authorize(c, session, &pcr_selection, public, fp, fp_size, signature_json, NULL);
4150 if (r < 0)
4151 return r;
4152 }
4153
4154 if (pcrlock_policy) {
4155 _cleanup_(tpm2_handle_freep) Tpm2Handle *nv_handle = NULL;
4156
4157 r = tpm2_policy_super_pcr(
4158 c,
4159 session,
4160 &pcrlock_policy->prediction,
4161 pcrlock_policy->algorithm);
4162 if (r < 0)
4163 return r;
4164
4165 r = tpm2_deserialize(
4166 c,
4167 pcrlock_policy->nv_handle.iov_base,
4168 pcrlock_policy->nv_handle.iov_len,
4169 &nv_handle);
4170 if (r < 0)
4171 return r;
4172
4173 r = tpm2_policy_authorize_nv(
4174 c,
4175 session,
4176 nv_handle,
4177 NULL);
4178 if (r < 0)
4179 return r;
4180 }
4181
4182 if (hash_pcr_mask != 0) {
4183 TPML_PCR_SELECTION pcr_selection;
4184 tpm2_tpml_pcr_selection_from_mask(hash_pcr_mask, (TPMI_ALG_HASH)pcr_bank, &pcr_selection);
4185 r = tpm2_policy_pcr(c, session, &pcr_selection, NULL);
4186 if (r < 0)
4187 return r;
4188 }
4189
4190 if (use_pin) {
4191 r = tpm2_policy_auth_value(c, session, NULL);
4192 if (r < 0)
4193 return r;
4194 }
4195
4196 r = tpm2_get_policy_digest(c, session, ret_policy_digest);
4197 if (r < 0)
4198 return r;
4199
4200 return 0;
4201 }
4202
4203 #if HAVE_OPENSSL
4204 static const struct {
4205 TPM2_ECC_CURVE tpm2_ecc_curve_id;
4206 int openssl_ecc_curve_id;
4207 } tpm2_openssl_ecc_curve_table[] = {
4208 { TPM2_ECC_NIST_P192, NID_X9_62_prime192v1, },
4209 { TPM2_ECC_NIST_P224, NID_secp224r1, },
4210 { TPM2_ECC_NIST_P256, NID_X9_62_prime256v1, },
4211 { TPM2_ECC_NIST_P384, NID_secp384r1, },
4212 { TPM2_ECC_NIST_P521, NID_secp521r1, },
4213 { TPM2_ECC_SM2_P256, NID_sm2, },
4214 };
4215
4216 static int tpm2_ecc_curve_from_openssl_curve_id(int openssl_ecc_curve_id, TPM2_ECC_CURVE *ret) {
4217 assert(ret);
4218
4219 FOREACH_ELEMENT(t, tpm2_openssl_ecc_curve_table)
4220 if (t->openssl_ecc_curve_id == openssl_ecc_curve_id) {
4221 *ret = t->tpm2_ecc_curve_id;
4222 return 0;
4223 }
4224
4225 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
4226 "OpenSSL ECC curve id %d not supported.", openssl_ecc_curve_id);
4227 }
4228
4229 static int tpm2_ecc_curve_to_openssl_curve_id(TPM2_ECC_CURVE tpm2_ecc_curve_id, int *ret) {
4230 assert(ret);
4231
4232 FOREACH_ELEMENT(t, tpm2_openssl_ecc_curve_table)
4233 if (t->tpm2_ecc_curve_id == tpm2_ecc_curve_id) {
4234 *ret = t->openssl_ecc_curve_id;
4235 return 0;
4236 }
4237
4238 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
4239 "TPM2 ECC curve %u not supported.", tpm2_ecc_curve_id);
4240 }
4241
4242 #define TPM2_RSA_DEFAULT_EXPONENT UINT32_C(0x10001)
4243
4244 int tpm2_tpm2b_public_to_openssl_pkey(const TPM2B_PUBLIC *public, EVP_PKEY **ret) {
4245 int r;
4246
4247 assert(public);
4248 assert(ret);
4249
4250 const TPMT_PUBLIC *p = &public->publicArea;
4251 switch (p->type) {
4252 case TPM2_ALG_ECC: {
4253 int curve_id;
4254 r = tpm2_ecc_curve_to_openssl_curve_id(p->parameters.eccDetail.curveID, &curve_id);
4255 if (r < 0)
4256 return r;
4257
4258 const TPMS_ECC_POINT *point = &p->unique.ecc;
4259 return ecc_pkey_from_curve_x_y(
4260 curve_id,
4261 point->x.buffer,
4262 point->x.size,
4263 point->y.buffer,
4264 point->y.size,
4265 ret);
4266 }
4267 case TPM2_ALG_RSA: {
4268 /* TPM specification Part 2 ("Structures") section for TPMS_RSA_PARAMS states "An exponent of
4269 * zero indicates that the exponent is the default of 2^16 + 1". */
4270 uint32_t exponent = htobe32(p->parameters.rsaDetail.exponent ?: TPM2_RSA_DEFAULT_EXPONENT);
4271 return rsa_pkey_from_n_e(
4272 p->unique.rsa.buffer,
4273 p->unique.rsa.size,
4274 &exponent,
4275 sizeof(exponent),
4276 ret);
4277 }
4278 default:
4279 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
4280 "TPM2 asymmetric algorithm 0x%" PRIx16 " not supported.", p->type);
4281 }
4282 }
4283
4284 /* Be careful before changing anything in this function, as the TPM key "name" is calculated using the entire
4285 * TPMT_PUBLIC (after marshalling), and that "name" is used (for example) to calculate the policy hash for
4286 * the Authorize policy. So we must ensure this conversion of a PEM to TPM2B_PUBLIC does not change the
4287 * "name", because it would break unsealing of previously-sealed objects that used (for example)
4288 * tpm2_calculate_policy_authorize(). See bug #30546. */
4289 int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) {
4290 int key_id, r;
4291
4292 assert(pkey);
4293 assert(ret);
4294
4295 TPMT_PUBLIC public = {
4296 .nameAlg = TPM2_ALG_SHA256,
4297 .objectAttributes = TPMA_OBJECT_DECRYPT | TPMA_OBJECT_SIGN_ENCRYPT | TPMA_OBJECT_USERWITHAUTH,
4298 .parameters.asymDetail = {
4299 .symmetric.algorithm = TPM2_ALG_NULL,
4300 .scheme.scheme = TPM2_ALG_NULL,
4301 },
4302 };
4303
4304 #if OPENSSL_VERSION_MAJOR >= 3
4305 key_id = EVP_PKEY_get_id(pkey);
4306 #else
4307 key_id = EVP_PKEY_id(pkey);
4308 #endif
4309
4310 switch (key_id) {
4311 case EVP_PKEY_EC: {
4312 public.type = TPM2_ALG_ECC;
4313
4314 int curve_id;
4315 _cleanup_free_ void *x = NULL, *y = NULL;
4316 size_t x_size, y_size;
4317 r = ecc_pkey_to_curve_x_y(pkey, &curve_id, &x, &x_size, &y, &y_size);
4318 if (r < 0)
4319 return log_debug_errno(r, "Could not get ECC key curve/x/y: %m");
4320
4321 TPM2_ECC_CURVE curve;
4322 r = tpm2_ecc_curve_from_openssl_curve_id(curve_id, &curve);
4323 if (r < 0)
4324 return r;
4325
4326 public.parameters.eccDetail.curveID = curve;
4327
4328 public.parameters.eccDetail.kdf.scheme = TPM2_ALG_NULL;
4329
4330 r = TPM2B_ECC_PARAMETER_CHECK_SIZE(x_size);
4331 if (r < 0)
4332 return log_debug_errno(r, "ECC key x size %zu too large.", x_size);
4333
4334 public.unique.ecc.x = TPM2B_ECC_PARAMETER_MAKE(x, x_size);
4335
4336 r = TPM2B_ECC_PARAMETER_CHECK_SIZE(y_size);
4337 if (r < 0)
4338 return log_debug_errno(r, "ECC key y size %zu too large.", y_size);
4339
4340 public.unique.ecc.y = TPM2B_ECC_PARAMETER_MAKE(y, y_size);
4341
4342 break;
4343 }
4344 case EVP_PKEY_RSA: {
4345 public.type = TPM2_ALG_RSA;
4346
4347 _cleanup_free_ void *n = NULL, *e = NULL;
4348 size_t n_size, e_size;
4349 r = rsa_pkey_to_n_e(pkey, &n, &n_size, &e, &e_size);
4350 if (r < 0)
4351 return log_debug_errno(r, "Could not get RSA key n/e: %m");
4352
4353 r = TPM2B_PUBLIC_KEY_RSA_CHECK_SIZE(n_size);
4354 if (r < 0)
4355 return log_debug_errno(r, "RSA key n size %zu too large.", n_size);
4356
4357 public.unique.rsa = TPM2B_PUBLIC_KEY_RSA_MAKE(n, n_size);
4358 public.parameters.rsaDetail.keyBits = n_size * 8;
4359
4360 if (sizeof(uint32_t) < e_size)
4361 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
4362 "RSA key e size %zu too large.", e_size);
4363
4364 uint32_t exponent = 0;
4365 memcpy(&exponent, e, e_size);
4366 exponent = be32toh(exponent) >> (32 - e_size * 8);
4367
4368 /* TPM specification Part 2 ("Structures") section for TPMS_RSA_PARAMS states "An exponent of
4369 * zero indicates that the exponent is the default of 2^16 + 1". However, we have no reason
4370 * to special case it in our PEM->TPM2B_PUBLIC conversion, and doing so could break backwards
4371 * compatibility, so even if it is the "default" value of 0x10001, we do not set it to 0. */
4372 public.parameters.rsaDetail.exponent = exponent;
4373
4374 break;
4375 }
4376 default:
4377 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
4378 "EVP_PKEY type %d not supported.", key_id);
4379 }
4380
4381 *ret = (TPM2B_PUBLIC) {
4382 .size = sizeof(public),
4383 .publicArea = public,
4384 };
4385
4386 return 0;
4387 }
4388 #endif
4389
4390 int tpm2_tpm2b_public_to_fingerprint(
4391 const TPM2B_PUBLIC *public,
4392 void **ret_fingerprint,
4393 size_t *ret_fingerprint_size) {
4394
4395 #if HAVE_OPENSSL
4396 int r;
4397
4398 assert(public);
4399 assert(ret_fingerprint);
4400 assert(ret_fingerprint_size);
4401
4402 _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
4403 r = tpm2_tpm2b_public_to_openssl_pkey(public, &pkey);
4404 if (r < 0)
4405 return r;
4406
4407 /* Hardcode fingerprint to SHA256 */
4408 return pubkey_fingerprint(pkey, EVP_sha256(), ret_fingerprint, ret_fingerprint_size);
4409 #else
4410 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
4411 #endif
4412 }
4413
4414 int tpm2_tpm2b_public_from_pem(const void *pem, size_t pem_size, TPM2B_PUBLIC *ret) {
4415 #if HAVE_OPENSSL
4416 int r;
4417
4418 assert(pem);
4419 assert(ret);
4420
4421 _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
4422 r = openssl_pubkey_from_pem(pem, pem_size, &pkey);
4423 if (r < 0)
4424 return r;
4425
4426 return tpm2_tpm2b_public_from_openssl_pkey(pkey, ret);
4427 #else
4428 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
4429 #endif
4430 }
4431
4432 /* Marshal the public, private, and seed objects into a single nonstandard 'blob'. The public and private
4433 * objects are required, while the seed is optional. This is not a (publicly) standard format, this is
4434 * specific to how we currently store the sealed object. This 'blob' can be unmarshalled by
4435 * tpm2_unmarshal_blob(). */
4436 int tpm2_marshal_blob(
4437 const TPM2B_PUBLIC *public,
4438 const TPM2B_PRIVATE *private,
4439 const TPM2B_ENCRYPTED_SECRET *seed,
4440 void **ret_blob,
4441 size_t *ret_blob_size) {
4442
4443 TSS2_RC rc;
4444
4445 assert(public);
4446 assert(private);
4447 assert(ret_blob);
4448 assert(ret_blob_size);
4449
4450 size_t max_size = sizeof(*private) + sizeof(*public);
4451 if (seed)
4452 max_size += sizeof(*seed);
4453
4454 _cleanup_free_ void *blob = malloc(max_size);
4455 if (!blob)
4456 return log_oom_debug();
4457
4458 size_t blob_size = 0;
4459 rc = sym_Tss2_MU_TPM2B_PRIVATE_Marshal(private, blob, max_size, &blob_size);
4460 if (rc != TSS2_RC_SUCCESS)
4461 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4462 "Failed to marshal private key: %s", sym_Tss2_RC_Decode(rc));
4463
4464 rc = sym_Tss2_MU_TPM2B_PUBLIC_Marshal(public, blob, max_size, &blob_size);
4465 if (rc != TSS2_RC_SUCCESS)
4466 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4467 "Failed to marshal public key: %s", sym_Tss2_RC_Decode(rc));
4468
4469 if (seed) {
4470 rc = sym_Tss2_MU_TPM2B_ENCRYPTED_SECRET_Marshal(seed, blob, max_size, &blob_size);
4471 if (rc != TSS2_RC_SUCCESS)
4472 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4473 "Failed to marshal encrypted seed: %s", sym_Tss2_RC_Decode(rc));
4474 }
4475
4476 *ret_blob = TAKE_PTR(blob);
4477 *ret_blob_size = blob_size;
4478
4479 return 0;
4480 }
4481
4482 /* Unmarshal the 'blob' into public, private, and seed objects. The public and private objects are required
4483 * in the 'blob', while the seed is optional. This is not a (publicly) standard format, this is specific to
4484 * how we currently store the sealed object. This expects the 'blob' to have been created by
4485 * tpm2_marshal_blob(). */
4486 int tpm2_unmarshal_blob(
4487 const void *blob,
4488 size_t blob_size,
4489 TPM2B_PUBLIC *ret_public,
4490 TPM2B_PRIVATE *ret_private,
4491 TPM2B_ENCRYPTED_SECRET *ret_seed) {
4492
4493 TSS2_RC rc;
4494
4495 assert(blob);
4496 assert(ret_public);
4497 assert(ret_private);
4498 assert(ret_seed);
4499
4500 TPM2B_PRIVATE private = {};
4501 size_t offset = 0;
4502 rc = sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal(blob, blob_size, &offset, &private);
4503 if (rc != TSS2_RC_SUCCESS)
4504 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4505 "Failed to unmarshal private key: %s", sym_Tss2_RC_Decode(rc));
4506
4507 TPM2B_PUBLIC public = {};
4508 rc = sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal(blob, blob_size, &offset, &public);
4509 if (rc != TSS2_RC_SUCCESS)
4510 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4511 "Failed to unmarshal public key: %s", sym_Tss2_RC_Decode(rc));
4512
4513 TPM2B_ENCRYPTED_SECRET seed = {};
4514 if (blob_size > offset) {
4515 rc = sym_Tss2_MU_TPM2B_ENCRYPTED_SECRET_Unmarshal(blob, blob_size, &offset, &seed);
4516 if (rc != TSS2_RC_SUCCESS)
4517 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4518 "Failed to unmarshal encrypted seed: %s", sym_Tss2_RC_Decode(rc));
4519 }
4520
4521 *ret_public = public;
4522 *ret_private = private;
4523 *ret_seed = seed;
4524
4525 return 0;
4526 }
4527
4528 /* Calculate a serialized handle. Once the upstream tpm2-tss library provides an api to do this, we can
4529 * remove this function. The addition of this functionality in tpm2-tss may be tracked here:
4530 * https://github.com/tpm2-software/tpm2-tss/issues/2575 */
4531 int tpm2_calculate_serialize(
4532 TPM2_HANDLE handle,
4533 const TPM2B_NAME *name,
4534 const TPM2B_PUBLIC *public,
4535 void **ret_serialized,
4536 size_t *ret_serialized_size) {
4537
4538 TSS2_RC rc;
4539
4540 assert(name);
4541 assert(public);
4542 assert(ret_serialized);
4543 assert(ret_serialized_size);
4544
4545 size_t max_size = sizeof(TPM2_HANDLE) + sizeof(TPM2B_NAME) + sizeof(uint32_t) + sizeof(TPM2B_PUBLIC);
4546 _cleanup_free_ void *serialized = malloc(max_size);
4547 if (!serialized)
4548 return log_oom_debug();
4549
4550 size_t serialized_size = 0;
4551 rc = sym_Tss2_MU_TPM2_HANDLE_Marshal(handle, serialized, max_size, &serialized_size);
4552 if (rc != TSS2_RC_SUCCESS)
4553 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4554 "Failed to marshal tpm handle: %s", sym_Tss2_RC_Decode(rc));
4555
4556 rc = sym_Tss2_MU_TPM2B_NAME_Marshal(name, serialized, max_size, &serialized_size);
4557 if (rc != TSS2_RC_SUCCESS)
4558 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4559 "Failed to marshal name: %s", sym_Tss2_RC_Decode(rc));
4560
4561 /* This is defined (non-publicly) in the tpm2-tss source as IESYSC_KEY_RSRC, to a value of "1". */
4562 rc = sym_Tss2_MU_UINT32_Marshal(UINT32_C(1), serialized, max_size, &serialized_size);
4563 if (rc != TSS2_RC_SUCCESS)
4564 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4565 "Failed to marshal esys resource id: %s", sym_Tss2_RC_Decode(rc));
4566
4567 rc = sym_Tss2_MU_TPM2B_PUBLIC_Marshal(public, serialized, max_size, &serialized_size);
4568 if (rc != TSS2_RC_SUCCESS)
4569 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4570 "Failed to marshal public: %s", sym_Tss2_RC_Decode(rc));
4571
4572 *ret_serialized = TAKE_PTR(serialized);
4573 *ret_serialized_size = serialized_size;
4574
4575 return 0;
4576 }
4577
4578 /* Serialize a handle. This produces a binary object that can be later deserialized (by the same TPM), even
4579 * across restarts of the TPM or reboots (assuming the handle is persistent). */
4580 int tpm2_serialize(
4581 Tpm2Context *c,
4582 const Tpm2Handle *handle,
4583 void **ret_serialized,
4584 size_t *ret_serialized_size) {
4585
4586 TSS2_RC rc;
4587
4588 assert(c);
4589 assert(handle);
4590 assert(ret_serialized);
4591 assert(ret_serialized_size);
4592
4593 _cleanup_(Esys_Freep) unsigned char *serialized = NULL;
4594 size_t size = 0;
4595 rc = sym_Esys_TR_Serialize(c->esys_context, handle->esys_handle, &serialized, &size);
4596 if (rc != TSS2_RC_SUCCESS)
4597 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4598 "Failed to serialize: %s", sym_Tss2_RC_Decode(rc));
4599
4600 *ret_serialized = TAKE_PTR(serialized);
4601 *ret_serialized_size = size;
4602
4603 return 0;
4604 }
4605
4606 int tpm2_deserialize(
4607 Tpm2Context *c,
4608 const void *serialized,
4609 size_t serialized_size,
4610 Tpm2Handle **ret_handle) {
4611
4612 TSS2_RC rc;
4613 int r;
4614
4615 assert(c);
4616 assert(serialized);
4617 assert(ret_handle);
4618
4619 _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
4620 r = tpm2_handle_new(c, &handle);
4621 if (r < 0)
4622 return r;
4623
4624 /* Since this is an existing handle in the TPM we should not implicitly flush it. */
4625 handle->flush = false;
4626
4627 rc = sym_Esys_TR_Deserialize(c->esys_context, serialized, serialized_size, &handle->esys_handle);
4628 if (rc != TSS2_RC_SUCCESS)
4629 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4630 "Failed to deserialize: %s", sym_Tss2_RC_Decode(rc));
4631
4632 *ret_handle = TAKE_PTR(handle);
4633
4634 return 0;
4635 }
4636
4637 #if HAVE_OPENSSL
4638
4639 /* KDFa() as defined by the TPM spec. */
4640 static int tpm2_kdfa(
4641 TPMI_ALG_HASH hash_alg,
4642 const void *key,
4643 size_t key_len,
4644 const char *label,
4645 const void *context,
4646 size_t context_len,
4647 size_t bits,
4648 void **ret_key,
4649 size_t *ret_key_len) {
4650
4651 int r;
4652
4653 assert(key);
4654 assert(label);
4655 assert(context || context_len == 0);
4656 assert(bits > 0);
4657 assert(bits <= SIZE_MAX - 7);
4658 assert(ret_key);
4659 assert(ret_key_len);
4660
4661 log_debug("Calculating KDFa().");
4662
4663 size_t len = DIV_ROUND_UP(bits, 8);
4664
4665 const char *hash_alg_name = tpm2_hash_alg_to_string(hash_alg);
4666 if (!hash_alg_name)
4667 return -EOPNOTSUPP;
4668
4669 _cleanup_free_ void *buf = NULL;
4670 r = kdf_kb_hmac_derive(
4671 "COUNTER",
4672 hash_alg_name,
4673 key,
4674 key_len,
4675 label,
4676 strlen(label),
4677 context,
4678 context_len,
4679 /* seed= */ NULL,
4680 /* seed_size= */ 0,
4681 len,
4682 &buf);
4683 if (r < 0)
4684 return r;
4685
4686 /* If the number of bits results in a partial byte, the TPM spec requires we zero the unrequested
4687 * bits in the MSB (i.e. at index 0). From the spec Part 1 ("Architecture") section on Key
4688 * Derivation Function, specifically KDFa():
4689 *
4690 * "The implied return from this function is a sequence of octets with a length equal to (bits + 7) /
4691 * 8. If bits is not an even multiple of 8, then the returned value occupies the least significant
4692 * bits of the returned octet array, and the additional, high-order bits in the 0th octet are
4693 * CLEAR. The unused bits of the most significant octet (MSO) are masked off and not shifted." */
4694 size_t partial = bits % 8;
4695 if (partial > 0)
4696 ((uint8_t*) buf)[0] &= 0xffu >> (8 - partial);
4697
4698 *ret_key = TAKE_PTR(buf);
4699 *ret_key_len = len;
4700
4701 return 0;
4702 }
4703
4704 /* KDFe() as defined by the TPM spec. */
4705 static int tpm2_kdfe(
4706 TPMI_ALG_HASH hash_alg,
4707 const void *shared_secret,
4708 size_t shared_secret_len,
4709 const char *label,
4710 const void *context_u,
4711 size_t context_u_size,
4712 const void *context_v,
4713 size_t context_v_size,
4714 size_t bits,
4715 void **ret_key,
4716 size_t *ret_key_len) {
4717
4718 int r;
4719
4720 assert(shared_secret);
4721 assert(label);
4722 assert(context_u);
4723 assert(context_v);
4724 assert(bits > 0);
4725 assert(bits <= SIZE_MAX - 7);
4726 assert(ret_key);
4727 assert(ret_key_len);
4728
4729 log_debug("Calculating KDFe().");
4730
4731 size_t len = DIV_ROUND_UP(bits, 8);
4732
4733 const char *hash_alg_name = tpm2_hash_alg_to_string(hash_alg);
4734 if (!hash_alg_name)
4735 return -EOPNOTSUPP;
4736
4737 size_t info_len = strlen(label) + 1 + context_u_size + context_v_size;
4738 _cleanup_free_ void *info = malloc(info_len);
4739 if (!info)
4740 return log_oom_debug();
4741
4742 _unused_ void *end = mempcpy(mempcpy(stpcpy(info, label) + 1, context_u, context_u_size),
4743 context_v, context_v_size);
4744 /* assert we copied exactly the right amount that we allocated */
4745 assert(end > info && (uintptr_t) end - (uintptr_t) info == info_len);
4746
4747 _cleanup_free_ void *buf = NULL;
4748 r = kdf_ss_derive(
4749 hash_alg_name,
4750 shared_secret,
4751 shared_secret_len,
4752 /* salt= */ NULL,
4753 /* salt_size= */ 0,
4754 info,
4755 info_len,
4756 len,
4757 &buf);
4758 if (r < 0)
4759 return r;
4760
4761 *ret_key = TAKE_PTR(buf);
4762 *ret_key_len = len;
4763
4764 return 0;
4765 }
4766
4767 static int tpm2_calculate_seal_public(
4768 const TPM2B_PUBLIC *parent,
4769 const TPMA_OBJECT *attributes,
4770 const TPM2B_DIGEST *policy,
4771 const TPM2B_DIGEST *seed,
4772 const void *secret,
4773 size_t secret_size,
4774 TPM2B_PUBLIC *ret) {
4775
4776 int r;
4777
4778 assert(parent);
4779 assert(seed);
4780 assert(secret);
4781 assert(ret);
4782
4783 log_debug("Calculating public part of sealed object.");
4784
4785 struct iovec data[] = {
4786 IOVEC_MAKE((void*) seed->buffer, seed->size),
4787 IOVEC_MAKE((void*) secret, secret_size),
4788 };
4789 TPM2B_DIGEST unique;
4790 r = tpm2_digest_many(
4791 parent->publicArea.nameAlg,
4792 &unique,
4793 data,
4794 ELEMENTSOF(data),
4795 /* extend= */ false);
4796 if (r < 0)
4797 return r;
4798
4799 *ret = (TPM2B_PUBLIC) {
4800 .size = sizeof(TPMT_PUBLIC),
4801 .publicArea = {
4802 .type = TPM2_ALG_KEYEDHASH,
4803 .nameAlg = parent->publicArea.nameAlg,
4804 .objectAttributes = attributes ? *attributes : 0,
4805 .authPolicy = policy ? *policy : TPM2B_DIGEST_MAKE(NULL, unique.size),
4806 .parameters.keyedHashDetail.scheme.scheme = TPM2_ALG_NULL,
4807 .unique.keyedHash = unique,
4808 },
4809 };
4810
4811 return 0;
4812 }
4813
4814 static int tpm2_calculate_seal_private(
4815 const TPM2B_PUBLIC *parent,
4816 const TPM2B_NAME *name,
4817 const char *pin,
4818 const TPM2B_DIGEST *seed,
4819 const void *secret,
4820 size_t secret_size,
4821 TPM2B_PRIVATE *ret) {
4822
4823 TSS2_RC rc;
4824 int r;
4825
4826 assert(parent);
4827 assert(name);
4828 assert(seed);
4829 assert(secret);
4830 assert(ret);
4831
4832 log_debug("Calculating private part of sealed object.");
4833
4834 _cleanup_free_ void *storage_key = NULL;
4835 size_t storage_key_size;
4836 r = tpm2_kdfa(parent->publicArea.nameAlg,
4837 seed->buffer,
4838 seed->size,
4839 "STORAGE",
4840 name->name,
4841 name->size,
4842 (size_t) parent->publicArea.parameters.asymDetail.symmetric.keyBits.sym,
4843 &storage_key,
4844 &storage_key_size);
4845 if (r < 0)
4846 return log_debug_errno(r, "Could not calculate storage key KDFa: %m");
4847
4848 r = tpm2_hash_alg_to_size(parent->publicArea.nameAlg);
4849 if (r < 0)
4850 return -EOPNOTSUPP;
4851
4852 size_t bits = (size_t) r * 8;
4853
4854 _cleanup_free_ void *integrity_key = NULL;
4855 size_t integrity_key_size;
4856 r = tpm2_kdfa(parent->publicArea.nameAlg,
4857 seed->buffer,
4858 seed->size,
4859 "INTEGRITY",
4860 /* context= */ NULL,
4861 /* context_len= */ 0,
4862 bits,
4863 &integrity_key,
4864 &integrity_key_size);
4865 if (r < 0)
4866 return log_debug_errno(r, "Could not calculate integrity key KDFa: %m");
4867
4868 TPM2B_AUTH auth = {};
4869 if (pin) {
4870 r = tpm2_auth_value_from_pin(parent->publicArea.nameAlg, pin, &auth);
4871 if (r < 0)
4872 return r;
4873 }
4874
4875 TPM2B_SENSITIVE sensitive = {
4876 .size = sizeof(TPMT_SENSITIVE),
4877 .sensitiveArea = {
4878 .sensitiveType = TPM2_ALG_KEYEDHASH,
4879 .authValue = auth,
4880 .seedValue = *seed,
4881 .sensitive.bits = TPM2B_SENSITIVE_DATA_MAKE(secret, secret_size),
4882 },
4883 };
4884
4885 _cleanup_free_ void *marshalled_sensitive = malloc(sizeof(sensitive));
4886 if (!marshalled_sensitive)
4887 return log_oom_debug();
4888
4889 size_t marshalled_sensitive_size = 0;
4890 rc = sym_Tss2_MU_TPM2B_SENSITIVE_Marshal(
4891 &sensitive,
4892 marshalled_sensitive,
4893 sizeof(sensitive),
4894 &marshalled_sensitive_size);
4895 if (rc != TSS2_RC_SUCCESS)
4896 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4897 "Failed to marshal sensitive: %s", sym_Tss2_RC_Decode(rc));
4898
4899 const char *sym_alg = tpm2_sym_alg_to_string(parent->publicArea.parameters.asymDetail.symmetric.algorithm);
4900 if (!sym_alg)
4901 return -EOPNOTSUPP;
4902
4903 const char *sym_mode = tpm2_sym_mode_to_string(parent->publicArea.parameters.asymDetail.symmetric.mode.sym);
4904 if (!sym_mode)
4905 return -EOPNOTSUPP;
4906
4907 _cleanup_free_ void *encrypted_sensitive = NULL;
4908 size_t encrypted_sensitive_size;
4909 r = openssl_cipher(
4910 sym_alg,
4911 parent->publicArea.parameters.asymDetail.symmetric.keyBits.sym,
4912 sym_mode,
4913 storage_key, storage_key_size,
4914 /* iv= */ NULL, /* iv_size= */ 0,
4915 marshalled_sensitive, marshalled_sensitive_size,
4916 &encrypted_sensitive, &encrypted_sensitive_size);
4917 if (r < 0)
4918 return r;
4919
4920 const char *hash_alg_name = tpm2_hash_alg_to_string(parent->publicArea.nameAlg);
4921 if (!hash_alg_name)
4922 return -EOPNOTSUPP;
4923
4924 _cleanup_free_ void *hmac_buffer = NULL;
4925 size_t hmac_size = 0;
4926 struct iovec hmac_data[] = {
4927 IOVEC_MAKE((void*) encrypted_sensitive, encrypted_sensitive_size),
4928 IOVEC_MAKE((void*) name->name, name->size),
4929 };
4930 r = openssl_hmac_many(
4931 hash_alg_name,
4932 integrity_key,
4933 integrity_key_size,
4934 hmac_data,
4935 ELEMENTSOF(hmac_data),
4936 &hmac_buffer,
4937 &hmac_size);
4938 if (r < 0)
4939 return r;
4940
4941 TPM2B_DIGEST outer_hmac = TPM2B_DIGEST_MAKE(hmac_buffer, hmac_size);
4942
4943 TPM2B_PRIVATE private = {};
4944 size_t private_size = 0;
4945 rc = sym_Tss2_MU_TPM2B_DIGEST_Marshal(
4946 &outer_hmac,
4947 private.buffer,
4948 sizeof(private.buffer),
4949 &private_size);
4950 if (rc != TSS2_RC_SUCCESS)
4951 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
4952 "Failed to marshal digest: %s", sym_Tss2_RC_Decode(rc));
4953 private.size = private_size;
4954
4955 assert(sizeof(private.buffer) - private.size >= encrypted_sensitive_size);
4956 memcpy_safe(&private.buffer[private.size], encrypted_sensitive, encrypted_sensitive_size);
4957 private.size += encrypted_sensitive_size;
4958
4959 *ret = private;
4960
4961 return 0;
4962 }
4963
4964 static int tpm2_calculate_seal_rsa_seed(
4965 const TPM2B_PUBLIC *parent,
4966 void **ret_seed,
4967 size_t *ret_seed_size,
4968 void **ret_encrypted_seed,
4969 size_t *ret_encrypted_seed_size) {
4970
4971 int r;
4972
4973 assert(parent);
4974 assert(ret_seed);
4975 assert(ret_seed_size);
4976 assert(ret_encrypted_seed);
4977 assert(ret_encrypted_seed_size);
4978
4979 log_debug("Calculating encrypted seed for RSA sealed object.");
4980
4981 _cleanup_(EVP_PKEY_freep) EVP_PKEY *parent_pkey = NULL;
4982 r = tpm2_tpm2b_public_to_openssl_pkey(parent, &parent_pkey);
4983 if (r < 0)
4984 return log_debug_errno(r, "Could not convert TPM2B_PUBLIC to OpenSSL PKEY: %m");
4985
4986 r = tpm2_hash_alg_to_size(parent->publicArea.nameAlg);
4987 if (r < 0)
4988 return -EOPNOTSUPP;
4989
4990 size_t seed_size = (size_t) r;
4991
4992 _cleanup_free_ void *seed = malloc(seed_size);
4993 if (!seed)
4994 return log_oom_debug();
4995
4996 r = crypto_random_bytes(seed, seed_size);
4997 if (r < 0)
4998 return log_debug_errno(r, "Failed to generate random seed: %m");
4999
5000 const char *hash_alg_name = tpm2_hash_alg_to_string(parent->publicArea.nameAlg);
5001 if (!hash_alg_name)
5002 return -EOPNOTSUPP;
5003
5004 _cleanup_free_ void *encrypted_seed = NULL;
5005 size_t encrypted_seed_size;
5006 r = rsa_oaep_encrypt_bytes(
5007 parent_pkey,
5008 hash_alg_name,
5009 "DUPLICATE",
5010 seed,
5011 seed_size,
5012 &encrypted_seed,
5013 &encrypted_seed_size);
5014 if (r < 0)
5015 return log_debug_errno(r, "Could not RSA-OAEP encrypt random seed: %m");
5016
5017 *ret_seed = TAKE_PTR(seed);
5018 *ret_seed_size = seed_size;
5019 *ret_encrypted_seed = TAKE_PTR(encrypted_seed);
5020 *ret_encrypted_seed_size = encrypted_seed_size;
5021
5022 return 0;
5023 }
5024
5025 static int tpm2_calculate_seal_ecc_seed(
5026 const TPM2B_PUBLIC *parent,
5027 void **ret_seed,
5028 size_t *ret_seed_size,
5029 void **ret_encrypted_seed,
5030 size_t *ret_encrypted_seed_size) {
5031
5032 TSS2_RC rc;
5033 int r;
5034
5035 assert(parent);
5036 assert(ret_seed);
5037 assert(ret_seed_size);
5038 assert(ret_encrypted_seed);
5039 assert(ret_encrypted_seed_size);
5040
5041 log_debug("Calculating encrypted seed for ECC sealed object.");
5042
5043 _cleanup_(EVP_PKEY_freep) EVP_PKEY *parent_pkey = NULL;
5044 r = tpm2_tpm2b_public_to_openssl_pkey(parent, &parent_pkey);
5045 if (r < 0)
5046 return log_debug_errno(r, "Could not convert TPM2B_PUBLIC to OpenSSL PKEY: %m");
5047
5048 int curve_id;
5049 r = ecc_pkey_to_curve_x_y(
5050 parent_pkey,
5051 &curve_id,
5052 /* ret_x= */ NULL, /* ret_x_size= */ NULL,
5053 /* ret_y= */ NULL, /* ret_y_size= */ NULL);
5054 if (r < 0)
5055 return r;
5056
5057 _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
5058 r = ecc_pkey_new(curve_id, &pkey);
5059 if (r < 0)
5060 return r;
5061
5062 _cleanup_free_ void *shared_secret = NULL;
5063 size_t shared_secret_size;
5064 r = ecc_ecdh(pkey, parent_pkey, &shared_secret, &shared_secret_size);
5065 if (r < 0)
5066 return log_debug_errno(r, "Could not generate ECC shared secret: %m");
5067
5068 _cleanup_free_ void *x = NULL, *y = NULL;
5069 size_t x_size, y_size;
5070 r = ecc_pkey_to_curve_x_y(pkey, /* ret_curve_id= */ NULL, &x, &x_size, &y, &y_size);
5071 if (r < 0)
5072 return log_debug_errno(r, "Could not get ECC get x/y: %m");
5073
5074 r = TPM2B_ECC_PARAMETER_CHECK_SIZE(x_size);
5075 if (r < 0)
5076 return log_debug_errno(r, "ECC point x size %zu is too large: %m", x_size);
5077
5078 r = TPM2B_ECC_PARAMETER_CHECK_SIZE(y_size);
5079 if (r < 0)
5080 return log_debug_errno(r, "ECC point y size %zu is too large: %m", y_size);
5081
5082 TPMS_ECC_POINT point = {
5083 .x = TPM2B_ECC_PARAMETER_MAKE(x, x_size),
5084 .y = TPM2B_ECC_PARAMETER_MAKE(y, y_size),
5085 };
5086
5087 _cleanup_free_ void *encrypted_seed = malloc(sizeof(point));
5088 if (!encrypted_seed)
5089 return log_oom_debug();
5090
5091 size_t encrypted_seed_size = 0;
5092 rc = sym_Tss2_MU_TPMS_ECC_POINT_Marshal(&point, encrypted_seed, sizeof(point), &encrypted_seed_size);
5093 if (rc != TPM2_RC_SUCCESS)
5094 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
5095 "Failed to marshal ECC point: %s", sym_Tss2_RC_Decode(rc));
5096
5097 r = tpm2_hash_alg_to_size(parent->publicArea.nameAlg);
5098 if (r < 0)
5099 return -EOPNOTSUPP;
5100
5101 size_t bits = (size_t) r * 8;
5102
5103 _cleanup_free_ void *seed = NULL;
5104 size_t seed_size = 0; /* Explicit initialization to appease gcc */
5105 r = tpm2_kdfe(parent->publicArea.nameAlg,
5106 shared_secret,
5107 shared_secret_size,
5108 "DUPLICATE",
5109 x,
5110 x_size,
5111 parent->publicArea.unique.ecc.x.buffer,
5112 parent->publicArea.unique.ecc.x.size,
5113 bits,
5114 &seed,
5115 &seed_size);
5116 if (r < 0)
5117 return log_debug_errno(r, "Could not calculate KDFe: %m");
5118
5119 *ret_seed = TAKE_PTR(seed);
5120 *ret_seed_size = seed_size;
5121 *ret_encrypted_seed = TAKE_PTR(encrypted_seed);
5122 *ret_encrypted_seed_size = encrypted_seed_size;
5123
5124 return 0;
5125 }
5126
5127 static int tpm2_calculate_seal_seed(
5128 const TPM2B_PUBLIC *parent,
5129 TPM2B_DIGEST *ret_seed,
5130 TPM2B_ENCRYPTED_SECRET *ret_encrypted_seed) {
5131
5132 int r;
5133
5134 assert(parent);
5135 assert(ret_seed);
5136 assert(ret_encrypted_seed);
5137
5138 log_debug("Calculating encrypted seed for sealed object.");
5139
5140 _cleanup_free_ void *seed = NULL, *encrypted_seed = NULL;
5141 size_t seed_size = 0, encrypted_seed_size = 0; /* Explicit initialization to appease gcc */
5142 if (parent->publicArea.type == TPM2_ALG_RSA)
5143 r = tpm2_calculate_seal_rsa_seed(parent, &seed, &seed_size, &encrypted_seed, &encrypted_seed_size);
5144 else if (parent->publicArea.type == TPM2_ALG_ECC)
5145 r = tpm2_calculate_seal_ecc_seed(parent, &seed, &seed_size, &encrypted_seed, &encrypted_seed_size);
5146 else
5147 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
5148 "Unsupported parent key type 0x%" PRIx16, parent->publicArea.type);
5149 if (r < 0)
5150 return log_debug_errno(r, "Could not calculate encrypted seed: %m");
5151
5152 *ret_seed = TPM2B_DIGEST_MAKE(seed, seed_size);
5153 *ret_encrypted_seed = TPM2B_ENCRYPTED_SECRET_MAKE(encrypted_seed, encrypted_seed_size);
5154
5155 return 0;
5156 }
5157
5158 #endif /* HAVE_OPENSSL */
5159
5160 int tpm2_calculate_seal(
5161 TPM2_HANDLE parent_handle,
5162 const TPM2B_PUBLIC *parent_public,
5163 const TPMA_OBJECT *attributes,
5164 const struct iovec *secret,
5165 const TPM2B_DIGEST *policy,
5166 const char *pin,
5167 struct iovec *ret_secret,
5168 struct iovec *ret_blob,
5169 struct iovec *ret_serialized_parent) {
5170
5171 #if HAVE_OPENSSL
5172 int r;
5173
5174 assert(parent_public);
5175 assert(iovec_is_valid(secret));
5176 assert(secret || ret_secret);
5177 assert(!(secret && ret_secret)); /* Either provide a secret, or we create one, but not both */
5178 assert(ret_blob);
5179 assert(ret_serialized_parent);
5180
5181 log_debug("Calculating sealed object.");
5182
5183 /* Default to the SRK. */
5184 if (parent_handle == 0)
5185 parent_handle = TPM2_SRK_HANDLE;
5186
5187 switch (TPM2_HANDLE_TYPE(parent_handle)) {
5188 case TPM2_HT_PERSISTENT:
5189 case TPM2_HT_NV_INDEX:
5190 break;
5191 case TPM2_HT_TRANSIENT:
5192 log_warning("Handle is transient, sealed secret may not be recoverable.");
5193 break;
5194 default:
5195 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
5196 "Handle 0x%" PRIx32 " not persistent, transient, or NV.",
5197 parent_handle);
5198 }
5199
5200 _cleanup_(iovec_done_erase) struct iovec generated_secret = {};
5201 if (!secret) {
5202 /* No secret provided, generate a random secret. We use SHA256 digest length, though it can
5203 * be up to TPM2_MAX_SEALED_DATA. The secret length is not limited to the nameAlg hash
5204 * size. */
5205 r = crypto_random_bytes_allocate_iovec(TPM2_SHA256_DIGEST_SIZE, &generated_secret);
5206 if (r < 0)
5207 return log_debug_errno(r, "Failed to generate secret key: %m");
5208
5209 secret = &generated_secret;
5210 }
5211
5212 if (secret->iov_len > TPM2_MAX_SEALED_DATA)
5213 return log_debug_errno(SYNTHETIC_ERRNO(EOVERFLOW),
5214 "Secret size %zu too large, limit is %d bytes.",
5215 secret->iov_len, TPM2_MAX_SEALED_DATA);
5216
5217 TPM2B_DIGEST random_seed;
5218 TPM2B_ENCRYPTED_SECRET seed;
5219 r = tpm2_calculate_seal_seed(parent_public, &random_seed, &seed);
5220 if (r < 0)
5221 return r;
5222
5223 TPM2B_PUBLIC public;
5224 r = tpm2_calculate_seal_public(parent_public, attributes, policy, &random_seed, secret->iov_base, secret->iov_len, &public);
5225 if (r < 0)
5226 return r;
5227
5228 TPM2B_NAME name;
5229 r = tpm2_calculate_pubkey_name(&public.publicArea, &name);
5230 if (r < 0)
5231 return r;
5232
5233 TPM2B_PRIVATE private;
5234 r = tpm2_calculate_seal_private(parent_public, &name, pin, &random_seed, secret->iov_base, secret->iov_len, &private);
5235 if (r < 0)
5236 return r;
5237
5238 _cleanup_(iovec_done) struct iovec blob = {};
5239 r = tpm2_marshal_blob(&public, &private, &seed, &blob.iov_base, &blob.iov_len);
5240 if (r < 0)
5241 return log_debug_errno(r, "Could not create sealed blob: %m");
5242
5243 TPM2B_NAME parent_name;
5244 r = tpm2_calculate_pubkey_name(&parent_public->publicArea, &parent_name);
5245 if (r < 0)
5246 return r;
5247
5248 _cleanup_(iovec_done) struct iovec serialized_parent = {};
5249 r = tpm2_calculate_serialize(
5250 parent_handle,
5251 &parent_name,
5252 parent_public,
5253 &serialized_parent.iov_base,
5254 &serialized_parent.iov_len);
5255 if (r < 0)
5256 return r;
5257
5258 if (ret_secret)
5259 *ret_secret = TAKE_STRUCT(generated_secret);
5260 *ret_blob = TAKE_STRUCT(blob);
5261 *ret_serialized_parent = TAKE_STRUCT(serialized_parent);
5262
5263 return 0;
5264 #else /* HAVE_OPENSSL */
5265 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
5266 #endif
5267 }
5268
5269 int tpm2_seal(Tpm2Context *c,
5270 uint32_t seal_key_handle,
5271 const TPM2B_DIGEST policy[],
5272 size_t n_policy,
5273 const char *pin,
5274 struct iovec *ret_secret,
5275 struct iovec **ret_blobs,
5276 size_t *ret_n_blobs,
5277 uint16_t *ret_primary_alg,
5278 struct iovec *ret_srk) {
5279
5280 uint16_t primary_alg = 0;
5281 int r;
5282
5283 assert(ret_secret);
5284 assert(ret_blobs);
5285 assert(ret_n_blobs);
5286
5287 /* So here's what we do here: we connect to the TPM2 chip. It persistently contains a "seed" key that
5288 * is randomized when the TPM2 is first initialized or reset and remains stable across boots. We
5289 * generate a "primary" key pair derived from that (ECC if possible, RSA as fallback). Given the seed
5290 * remains fixed this will result in the same key pair whenever we specify the exact same parameters
5291 * for it. We then create a PCR-bound policy session, which calculates a hash on the current PCR
5292 * values of the indexes we specify. We then generate a randomized key on the host (which is the key
5293 * we actually enroll in the LUKS2 keyslots), which we upload into the TPM2, where it is encrypted
5294 * with the "primary" key, taking the PCR policy session into account. We then download the encrypted
5295 * key from the TPM2 ("sealing") and marshall it into binary form, which is ultimately placed in the
5296 * LUKS2 JSON header.
5297 *
5298 * The TPM2 "seed" key and "primary" keys never leave the TPM2 chip (and cannot be extracted at
5299 * all). The random key we enroll in LUKS2 we generate on the host using the Linux random device. It
5300 * is stored in the LUKS2 JSON only in encrypted form with the "primary" key of the TPM2 chip, thus
5301 * binding the unlocking to the TPM2 chip. */
5302
5303 usec_t start = now(CLOCK_MONOTONIC);
5304
5305 TPMA_OBJECT hmac_attributes =
5306 TPMA_OBJECT_FIXEDTPM |
5307 TPMA_OBJECT_FIXEDPARENT;
5308
5309 /* If protected by PIN, a user-selected low-entropy password, enable DA protection.
5310 Without a PIN, the key's left protected only by a PCR policy, which does not benefit
5311 from DA protection. */
5312 hmac_attributes |= pin ? 0 : TPMA_OBJECT_NODA;
5313
5314 /* We use a keyed hash object (i.e. HMAC) to store the secret key we want to use for unlocking the
5315 * LUKS2 volume with. We don't ever use for HMAC/keyed hash operations however, we just use it
5316 * because it's a key type that is universally supported and suitable for symmetric binary blobs. */
5317 TPMT_PUBLIC hmac_template = {
5318 .type = TPM2_ALG_KEYEDHASH,
5319 .nameAlg = TPM2_ALG_SHA256,
5320 .objectAttributes = hmac_attributes,
5321 .parameters.keyedHashDetail.scheme.scheme = TPM2_ALG_NULL,
5322 .unique.keyedHash.size = SHA256_DIGEST_SIZE,
5323 };
5324
5325 TPMS_SENSITIVE_CREATE hmac_sensitive = {
5326 .data.size = hmac_template.unique.keyedHash.size,
5327 };
5328
5329 CLEANUP_ERASE(hmac_sensitive);
5330
5331 if (pin) {
5332 r = tpm2_auth_value_from_pin(TPM2_ALG_SHA256, pin, &hmac_sensitive.userAuth);
5333 if (r < 0)
5334 return r;
5335 }
5336
5337 assert(sizeof(hmac_sensitive.data.buffer) >= hmac_sensitive.data.size);
5338
5339 (void) tpm2_credit_random(c);
5340
5341 _cleanup_(tpm2_handle_freep) Tpm2Handle *primary_handle = NULL;
5342 if (ret_srk) {
5343 _cleanup_(Esys_Freep) TPM2B_PUBLIC *primary_public = NULL;
5344
5345 if (IN_SET(seal_key_handle, 0, TPM2_SRK_HANDLE)) {
5346 r = tpm2_get_or_create_srk(
5347 c,
5348 /* session= */ NULL,
5349 &primary_public,
5350 /* ret_name= */ NULL,
5351 /* ret_qname= */ NULL,
5352 &primary_handle);
5353 if (r < 0)
5354 return r;
5355 } else if (IN_SET(TPM2_HANDLE_TYPE(seal_key_handle), TPM2_HT_TRANSIENT, TPM2_HT_PERSISTENT)) {
5356 r = tpm2_index_to_handle(
5357 c,
5358 seal_key_handle,
5359 /* session= */ NULL,
5360 &primary_public,
5361 /* ret_name= */ NULL,
5362 /* ret_qname= */ NULL,
5363 &primary_handle);
5364 if (r < 0)
5365 return r;
5366 if (r == 0)
5367 /* We do NOT automatically create anything other than the SRK */
5368 return log_debug_errno(SYNTHETIC_ERRNO(ENOENT),
5369 "No handle found at index 0x%" PRIx32, seal_key_handle);
5370 } else
5371 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
5372 "Seal key handle 0x%" PRIx32 " is neither transient nor persistent.",
5373 seal_key_handle);
5374
5375 primary_alg = primary_public->publicArea.type;
5376 } else {
5377 if (seal_key_handle != 0)
5378 log_debug("Using primary alg sealing, but seal key handle also provided; ignoring seal key handle.");
5379
5380 /* TODO: force all callers to provide ret_srk, so we can stop sealing with the legacy templates. */
5381 primary_alg = TPM2_ALG_ECC;
5382
5383 TPM2B_PUBLIC template = {
5384 .size = sizeof(TPMT_PUBLIC),
5385 };
5386 r = tpm2_get_legacy_template(primary_alg, &template.publicArea);
5387 if (r < 0)
5388 return log_debug_errno(r, "Could not get legacy ECC template: %m");
5389
5390 if (!tpm2_supports_tpmt_public(c, &template.publicArea)) {
5391 primary_alg = TPM2_ALG_RSA;
5392
5393 r = tpm2_get_legacy_template(primary_alg, &template.publicArea);
5394 if (r < 0)
5395 return log_debug_errno(r, "Could not get legacy RSA template: %m");
5396
5397 if (!tpm2_supports_tpmt_public(c, &template.publicArea))
5398 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
5399 "TPM does not support either ECC or RSA legacy template.");
5400 }
5401
5402 r = tpm2_create_primary(
5403 c,
5404 /* session= */ NULL,
5405 &template,
5406 /* sensitive= */ NULL,
5407 /* ret_public= */ NULL,
5408 &primary_handle);
5409 if (r < 0)
5410 return r;
5411 }
5412
5413 _cleanup_(tpm2_handle_freep) Tpm2Handle *encryption_session = NULL;
5414 r = tpm2_make_encryption_session(c, primary_handle, /* bind_key= */ NULL, &encryption_session);
5415 if (r < 0)
5416 return r;
5417
5418 log_debug("Generating secret key data.");
5419
5420 /* At least one shard, and if we have multiple policies, then we need one shard for each */
5421 size_t n_shards = MAX(n_policy, 1U);
5422
5423 /* Create a large secret which covers all shards we need */
5424 _cleanup_(iovec_done_erase) struct iovec secret = {};
5425 r = crypto_random_bytes_allocate_iovec(hmac_sensitive.data.size * n_shards, &secret);
5426 if (r < 0)
5427 return log_debug_errno(r, "Failed to generate secret key: %m");
5428
5429 struct iovec *blobs = new0(struct iovec, n_shards);
5430 size_t n_blobs = 0;
5431
5432 CLEANUP_ARRAY(blobs, n_blobs, iovec_array_free);
5433
5434 for (size_t shard = 0; shard < n_shards; shard++) {
5435
5436 /* Patch this shard's policy into the template */
5437 if (shard < n_policy)
5438 hmac_template.authPolicy = policy[shard];
5439 else
5440 hmac_template.authPolicy = TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE);
5441
5442 /* Copy in this shard's secret key */
5443 memcpy(hmac_sensitive.data.buffer,
5444 (const uint8_t*) secret.iov_base + (hmac_sensitive.data.size * shard),
5445 hmac_sensitive.data.size);
5446
5447 log_debug("Creating HMAC key on TPM for shard %zu.", shard);
5448
5449 _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
5450 _cleanup_(Esys_Freep) TPM2B_PRIVATE *private = NULL;
5451 r = tpm2_create(c, primary_handle, encryption_session, &hmac_template, &hmac_sensitive, &public, &private);
5452 if (r < 0)
5453 return r;
5454
5455 log_debug("Marshalling private and public part of HMAC key for shard %zu.", shard);
5456
5457 r = tpm2_marshal_blob(public, private, /* seed= */ NULL, &blobs[n_blobs].iov_base, &blobs[n_blobs].iov_len);
5458 if (r < 0)
5459 return log_debug_errno(r, "Could not create sealed blob: %m");
5460
5461 n_blobs++;
5462 }
5463
5464 if (DEBUG_LOGGING)
5465 log_debug("Completed TPM2 key sealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
5466
5467 if (ret_srk) {
5468 _cleanup_(iovec_done) struct iovec srk = {};
5469 _cleanup_(Esys_Freep) void *tmp = NULL;
5470 size_t tmp_size;
5471
5472 r = tpm2_serialize(c, primary_handle, &tmp, &tmp_size);
5473 if (r < 0)
5474 return r;
5475
5476 /*
5477 * make a copy since we don't want the caller to understand that
5478 * ESYS allocated the pointer. It would make tracking what deallocator
5479 * to use for srk in which context a PITA.
5480 */
5481 srk.iov_base = memdup(tmp, tmp_size);
5482 if (!srk.iov_base)
5483 return log_oom_debug();
5484 srk.iov_len = tmp_size;
5485
5486 *ret_srk = TAKE_STRUCT(srk);
5487 }
5488
5489 *ret_secret = TAKE_STRUCT(secret);
5490 *ret_blobs = TAKE_PTR(blobs);
5491 *ret_n_blobs = n_blobs;
5492
5493 if (ret_primary_alg)
5494 *ret_primary_alg = primary_alg;
5495
5496 return 0;
5497 }
5498
5499 #define RETRY_UNSEAL_MAX 30u
5500
5501 int tpm2_unseal(Tpm2Context *c,
5502 uint32_t hash_pcr_mask,
5503 uint16_t pcr_bank,
5504 const struct iovec *pubkey,
5505 uint32_t pubkey_pcr_mask,
5506 sd_json_variant *signature,
5507 const char *pin,
5508 const Tpm2PCRLockPolicy *pcrlock_policy,
5509 uint16_t primary_alg,
5510 const struct iovec blobs[],
5511 size_t n_blobs,
5512 const struct iovec known_policy_hash[],
5513 size_t n_known_policy_hash,
5514 const struct iovec *srk,
5515 struct iovec *ret_secret) {
5516
5517 /* Returns the following errors:
5518 *
5519 * -EREMOTE → blob is from a different TPM
5520 * -EDEADLK → couldn't create primary key because authorization failure
5521 * -ENOLCK → TPM is in dictionary lockout mode
5522 * -EREMCHG → submitted policy doesn't match NV index stored policy (in case of PolicyAuthorizeNV)
5523 * -ENOANO → none of the PolicyOR branches of a policy matched current state
5524 * -EUCLEAN → PCR state doesn't match expectations
5525 * -EPERM → stored policy does not match TPM state
5526 * -ENOTRECOVERABLE → all other kinds of TPM errors
5527 * -EILSEQ → bad PIN
5528 *
5529 * Of these all four of EREMCHG, ENOANO, EUCLEAN, EPERM can all mean that PCR state is not matching
5530 * expectations. */
5531
5532 TSS2_RC rc;
5533 int r;
5534
5535 assert(n_blobs > 0);
5536 assert(iovec_is_valid(pubkey));
5537 assert(ret_secret);
5538
5539 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask));
5540 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));
5541
5542 /* So here's what we do here: We connect to the TPM2 chip. As we do when sealing we generate a
5543 * "primary" key on the TPM2 chip, with the same parameters as well as a PCR-bound policy session.
5544 * Given we pass the same parameters, this will result in the same "primary" key, and same policy
5545 * hash (the latter of course, only if the PCR values didn't change in between). We unmarshal the
5546 * encrypted key we stored in the LUKS2 JSON token header and upload it into the TPM2, where it is
5547 * decrypted if the seed and the PCR policy were right ("unsealing"). We then download the result,
5548 * and use it to unlock the LUKS2 volume. */
5549
5550 usec_t start = now(CLOCK_MONOTONIC);
5551
5552 size_t n_shards = pcrlock_policy && iovec_is_set(pubkey) ? 2 : 1;
5553 if (n_blobs != n_shards)
5554 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Number of provided key blobs (%zu) does not match policy requirements (%zu).", n_blobs, n_shards);
5555 if (n_known_policy_hash > 0 && n_known_policy_hash != n_shards)
5556 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Number of provided known policy hashes (%zu) does not match policy requirements (%zu or 0).", n_known_policy_hash, n_shards);
5557
5558 /* Older code did not save the pcr_bank, and unsealing needed to detect the best pcr bank to use,
5559 * so we need to handle that legacy situation. */
5560 if (pcr_bank == UINT16_MAX) {
5561 r = tpm2_get_best_pcr_bank(c, hash_pcr_mask|pubkey_pcr_mask, &pcr_bank);
5562 if (r < 0)
5563 return r;
5564 }
5565
5566 _cleanup_(tpm2_handle_freep) Tpm2Handle *primary_handle = NULL;
5567 if (iovec_is_set(srk)) {
5568 r = tpm2_deserialize(c, srk->iov_base, srk->iov_len, &primary_handle);
5569 if (r < 0)
5570 return r;
5571 } else if (primary_alg != 0) {
5572 TPM2B_PUBLIC template = {
5573 .size = sizeof(TPMT_PUBLIC),
5574 };
5575 r = tpm2_get_legacy_template(primary_alg, &template.publicArea);
5576 if (r < 0)
5577 return log_debug_errno(r, "Could not get legacy template: %m");
5578
5579 r = tpm2_create_primary(
5580 c,
5581 /* session= */ NULL,
5582 &template,
5583 /* sensitive= */ NULL,
5584 /* ret_public= */ NULL,
5585 &primary_handle);
5586 if (r < 0)
5587 return r;
5588 } else
5589 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
5590 "No SRK or primary alg provided.");
5591
5592 TPM2B_PUBLIC pubkey_tpm2b;
5593 _cleanup_(iovec_done) struct iovec fp = {};
5594 if (iovec_is_set(pubkey)) {
5595 r = tpm2_tpm2b_public_from_pem(pubkey->iov_base, pubkey->iov_len, &pubkey_tpm2b);
5596 if (r < 0)
5597 return log_debug_errno(r, "Could not create TPMT_PUBLIC: %m");
5598
5599 r = tpm2_tpm2b_public_to_fingerprint(&pubkey_tpm2b, &fp.iov_base, &fp.iov_len);
5600 if (r < 0)
5601 return log_debug_errno(r, "Could not get key fingerprint: %m");
5602 }
5603
5604 _cleanup_(iovec_done_erase) struct iovec secret = {};
5605 for (unsigned i = RETRY_UNSEAL_MAX;; i--) {
5606 bool retry = false;
5607 iovec_done_erase(&secret); /* clear data from previous unseal attempt */
5608
5609 for (size_t shard = 0; shard < n_blobs; shard++) {
5610 TPM2B_PUBLIC public;
5611 TPM2B_PRIVATE private;
5612 TPM2B_ENCRYPTED_SECRET seed = {};
5613 r = tpm2_unmarshal_blob(blobs[shard].iov_base, blobs[shard].iov_len, &public, &private, &seed);
5614 if (r < 0)
5615 return log_debug_errno(r, "Could not extract parts from blob: %m");
5616
5617 if (seed.size > 0) {
5618 /* This is a calculated (or duplicated) sealed object, and must be imported. */
5619 _cleanup_free_ TPM2B_PRIVATE *imported_private = NULL;
5620 r = tpm2_import(c,
5621 primary_handle,
5622 /* session= */ NULL,
5623 &public,
5624 &private,
5625 &seed,
5626 /* encryption_key= */ NULL,
5627 /* symmetric= */ NULL,
5628 &imported_private);
5629 if (r < 0)
5630 return r;
5631
5632 private = *imported_private;
5633 }
5634
5635 log_debug("Loading HMAC key into TPM for shard %zu.", shard);
5636
5637 /* Nothing sensitive on the bus, no need for encryption. Even if an attacker gives
5638 * you back a different key, the session initiation will fail. In the SRK model, the
5639 * tpmKey is verified. In the non-srk model, with pin, the bindKey provides
5640 * protections. */
5641 _cleanup_(tpm2_handle_freep) Tpm2Handle *hmac_key = NULL;
5642 r = tpm2_load(c, primary_handle, NULL, &public, &private, &hmac_key);
5643 if (r < 0)
5644 return r;
5645
5646 /* If a PIN is set for the seal object, use it to bind the session key to that
5647 * object. This prevents active bus interposers from faking a TPM and seeing the
5648 * unsealed value. An active interposer could fake a TPM, satisfying the encrypted
5649 * session, and just forward everything to the *real* TPM. */
5650 r = tpm2_set_auth(c, hmac_key, pin);
5651 if (r < 0)
5652 return r;
5653
5654 _cleanup_(tpm2_handle_freep) Tpm2Handle *encryption_session = NULL;
5655 r = tpm2_make_encryption_session(c, primary_handle, hmac_key, &encryption_session);
5656 if (r < 0)
5657 return r;
5658
5659 _cleanup_(tpm2_handle_freep) Tpm2Handle *policy_session = NULL;
5660 _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
5661 r = tpm2_make_policy_session(
5662 c,
5663 primary_handle,
5664 encryption_session,
5665 &policy_session);
5666 if (r < 0)
5667 return r; /* Will return EILSEQ on auth failure (i.e. bad PIN) */
5668
5669 /* If both public PCR key and pcrlock policies are requested, then generate the
5670 * public PCR policy for the first shared, and the pcrlock policy for the 2nd */
5671 r = tpm2_build_sealing_policy(
5672 c,
5673 policy_session,
5674 hash_pcr_mask,
5675 pcr_bank,
5676 shard == 0 && iovec_is_set(pubkey) ? &pubkey_tpm2b : NULL,
5677 fp.iov_base, fp.iov_len,
5678 shard == 0 ? pubkey_pcr_mask : 0,
5679 signature,
5680 !!pin,
5681 (shard == 1 || !iovec_is_set(pubkey)) ? pcrlock_policy : NULL,
5682 &policy_digest);
5683 if (r == -EUCLEAN && i > 0) {
5684 log_debug("A PCR value changed during the TPM2 policy session, restarting HMAC key unsealing (%u tries left).", i);
5685 retry = true;
5686 break;
5687 }
5688 if (r < 0)
5689 return r;
5690
5691 /* If we know the policy hash to expect, and it doesn't match, we can shortcut things here, and not
5692 * wait until the TPM2 tells us to go away. */
5693 if (n_known_policy_hash > 0 && memcmp_nn(policy_digest->buffer,
5694 policy_digest->size,
5695 known_policy_hash[shard].iov_base,
5696 known_policy_hash[shard].iov_len) != 0) {
5697 #if HAVE_OPENSSL
5698 if (shard == 0 &&
5699 iovec_is_set(pubkey) &&
5700 pubkey_tpm2b.publicArea.type == TPM2_ALG_RSA &&
5701 pubkey_tpm2b.publicArea.parameters.rsaDetail.exponent == TPM2_RSA_DEFAULT_EXPONENT) {
5702 /* Due to bug #30546, if using RSA pubkey with the default exponent, we may
5703 * need to set the exponent to the TPM special-case value of 0 and retry. */
5704 log_debug("Policy hash mismatch, retrying with RSA pubkey exponent set to 0.");
5705 pubkey_tpm2b.publicArea.parameters.rsaDetail.exponent = 0;
5706 retry = true;
5707 break;
5708 }
5709 #endif
5710 return log_debug_errno(SYNTHETIC_ERRNO(EPERM),
5711 "Current policy digest does not match stored policy digest, cancelling "
5712 "TPM2 authentication attempt.");
5713 }
5714
5715 log_debug("Unsealing HMAC key for shard %zu.", shard);
5716
5717 _cleanup_(tpm2b_sensitive_data_erase_and_esys_freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
5718 rc = sym_Esys_Unseal(
5719 c->esys_context,
5720 hmac_key->esys_handle,
5721 policy_session->esys_handle,
5722 encryption_session->esys_handle, /* use HMAC session to enable parameter encryption */
5723 ESYS_TR_NONE,
5724 &unsealed);
5725 if (rc == TPM2_RC_PCR_CHANGED && i > 0) {
5726 log_debug("A PCR value changed during the TPM2 policy session, restarting HMAC key unsealing (%u tries left).", i);
5727 retry = true;
5728 break;
5729 }
5730 if (rc != TPM2_RC_SUCCESS)
5731 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
5732 "Failed to unseal HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc));
5733
5734 if (!iovec_append(&secret, &IOVEC_MAKE(unsealed->buffer, unsealed->size)))
5735 return log_oom_debug();
5736 }
5737
5738 if (!retry)
5739 break;
5740 }
5741
5742 if (DEBUG_LOGGING)
5743 log_debug("Completed TPM2 key unsealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
5744
5745 *ret_secret = TAKE_STRUCT(secret);
5746 return 0;
5747 }
5748
5749 static TPM2_HANDLE generate_random_nv_index(void) {
5750 return TPM2_NV_INDEX_UNASSIGNED_FIRST +
5751 (TPM2_HANDLE) random_u64_range(TPM2_NV_INDEX_UNASSIGNED_LAST - TPM2_NV_INDEX_UNASSIGNED_FIRST + 1);
5752 }
5753
5754 int tpm2_define_policy_nv_index(
5755 Tpm2Context *c,
5756 const Tpm2Handle *session,
5757 TPM2_HANDLE requested_nv_index,
5758 const TPM2B_DIGEST *write_policy,
5759 TPM2_HANDLE *ret_nv_index,
5760 Tpm2Handle **ret_nv_handle,
5761 TPM2B_NV_PUBLIC *ret_nv_public) {
5762
5763 _cleanup_(tpm2_handle_freep) Tpm2Handle *new_handle = NULL;
5764 TSS2_RC rc;
5765 int r;
5766
5767 assert(c);
5768
5769 /* Allocates an nvindex to store a policy for use in PolicyAuthorizeNV in. This is where pcrlock then
5770 * stores its predicted PCR policies in. If 'requested_nv_index' will try to allocate the specified
5771 * nvindex, otherwise will find a free one, and use that. */
5772
5773 r = tpm2_handle_new(c, &new_handle);
5774 if (r < 0)
5775 return r;
5776
5777 new_handle->flush = false; /* This is a persistent NV index, don't flush hence */
5778
5779 for (unsigned try = 0; try < 25U; try++) {
5780 TPM2_HANDLE nv_index;
5781
5782 if (requested_nv_index != 0)
5783 nv_index = requested_nv_index;
5784 else
5785 nv_index = generate_random_nv_index();
5786
5787 TPM2B_NV_PUBLIC public_info = {
5788 .size = sizeof_field(TPM2B_NV_PUBLIC, nvPublic),
5789 .nvPublic = {
5790 .nvIndex = nv_index,
5791 .nameAlg = TPM2_ALG_SHA256,
5792 .attributes = TPM2_NT_ORDINARY | TPMA_NV_WRITEALL | TPMA_NV_POLICYWRITE | TPMA_NV_OWNERREAD,
5793 .dataSize = offsetof(TPMT_HA, digest) + tpm2_hash_alg_to_size(TPM2_ALG_SHA256),
5794 },
5795 };
5796
5797 if (write_policy)
5798 public_info.nvPublic.authPolicy = *write_policy;
5799
5800 rc = sym_Esys_NV_DefineSpace(
5801 c->esys_context,
5802 /* authHandle= */ ESYS_TR_RH_OWNER,
5803 /* shandle1= */ session ? session->esys_handle : ESYS_TR_PASSWORD,
5804 /* shandle2= */ ESYS_TR_NONE,
5805 /* shandle3= */ ESYS_TR_NONE,
5806 /* auth= */ NULL,
5807 &public_info,
5808 &new_handle->esys_handle);
5809
5810 if (rc == TSS2_RC_SUCCESS) {
5811 log_debug("NV Index 0x%" PRIx32 " successfully allocated.", nv_index);
5812
5813 if (ret_nv_index)
5814 *ret_nv_index = nv_index;
5815
5816 if (ret_nv_handle)
5817 *ret_nv_handle = TAKE_PTR(new_handle);
5818
5819 if (ret_nv_public)
5820 *ret_nv_public = public_info;
5821
5822 return 0;
5823 }
5824 if (rc != TPM2_RC_NV_DEFINED)
5825 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
5826 "Failed to allocate NV index: %s", sym_Tss2_RC_Decode(rc));
5827
5828 if (requested_nv_index != 0) {
5829 assert(nv_index == requested_nv_index);
5830 return log_debug_errno(SYNTHETIC_ERRNO(EEXIST),
5831 "Requested NV index 0x%" PRIx32 " already taken.", requested_nv_index);
5832 }
5833
5834 log_debug("NV index 0x%" PRIu32 " already taken, trying another one (%u tries left)", nv_index, try);
5835 }
5836
5837 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
5838 "Too many attempts trying to allocate NV index: %s", sym_Tss2_RC_Decode(rc));
5839 }
5840
5841 int tpm2_write_policy_nv_index(
5842 Tpm2Context *c,
5843 const Tpm2Handle *policy_session,
5844 TPM2_HANDLE nv_index,
5845 const Tpm2Handle *nv_handle,
5846 const TPM2B_DIGEST *policy_digest) {
5847
5848 TSS2_RC rc;
5849
5850 assert(c);
5851 assert(policy_session);
5852 assert(nv_handle);
5853 assert(policy_digest);
5854
5855 if (policy_digest->size != tpm2_hash_alg_to_size(TPM2_ALG_SHA256))
5856 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Policy to store in NV index has wrong size.");
5857
5858 TPMT_HA ha = {
5859 .hashAlg = TPM2_ALG_SHA256,
5860 };
5861 assert(policy_digest->size <= sizeof_field(TPMT_HA, digest));
5862 memcpy_safe(&ha.digest, policy_digest->buffer, policy_digest->size);
5863
5864 TPM2B_MAX_NV_BUFFER buffer = {};
5865 size_t written = 0;
5866 rc = sym_Tss2_MU_TPMT_HA_Marshal(&ha, buffer.buffer, sizeof(buffer.buffer), &written);
5867 if (rc != TSS2_RC_SUCCESS)
5868 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
5869 "Failed to marshal policy digest.");
5870
5871 buffer.size = written;
5872
5873 rc = sym_Esys_NV_Write(
5874 c->esys_context,
5875 /* authHandle= */ nv_handle->esys_handle,
5876 /* nvIndex= */ nv_handle->esys_handle,
5877 /* shandle1= */ policy_session->esys_handle,
5878 /* shandle2= */ ESYS_TR_NONE,
5879 /* shandle3= */ ESYS_TR_NONE,
5880 &buffer,
5881 /* offset= */ 0);
5882 if (rc != TSS2_RC_SUCCESS)
5883 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
5884 "Failed to write NV index: %s", sym_Tss2_RC_Decode(rc));
5885
5886 if (DEBUG_LOGGING) {
5887 _cleanup_free_ char *h = NULL;
5888 h = hexmem(policy_digest->buffer, policy_digest->size);
5889 log_debug("Written policy digest %s to NV index 0x%x", strnull(h), nv_index);
5890 }
5891
5892 return 0;
5893 }
5894
5895 int tpm2_undefine_policy_nv_index(
5896 Tpm2Context *c,
5897 const Tpm2Handle *session,
5898 TPM2_HANDLE nv_index,
5899 const Tpm2Handle *nv_handle) {
5900
5901 TSS2_RC rc;
5902
5903 assert(c);
5904 assert(nv_handle);
5905
5906 rc = sym_Esys_NV_UndefineSpace(
5907 c->esys_context,
5908 /* authHandle= */ ESYS_TR_RH_OWNER,
5909 /* nvIndex= */ nv_handle->esys_handle,
5910 /* shandle1= */ session ? session->esys_handle : ESYS_TR_NONE,
5911 /* shandle2= */ ESYS_TR_NONE,
5912 /* shandle3= */ ESYS_TR_NONE);
5913 if (rc != TSS2_RC_SUCCESS)
5914 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
5915 "Failed to undefine NV index: %s", sym_Tss2_RC_Decode(rc));
5916
5917 log_debug("Undefined NV index 0x%x", nv_index);
5918 return 0;
5919 }
5920
5921 int tpm2_seal_data(
5922 Tpm2Context *c,
5923 const struct iovec *data,
5924 const Tpm2Handle *primary_handle,
5925 const Tpm2Handle *encryption_session,
5926 const TPM2B_DIGEST *policy,
5927 struct iovec *ret_public,
5928 struct iovec *ret_private) {
5929
5930 int r;
5931
5932 assert(c);
5933 assert(data);
5934 assert(primary_handle);
5935
5936 /* This is a generic version of tpm2_seal(), that doesn't imply any policy or any specific
5937 * combination of the two keypairs in their marshalling. tpm2_seal() is somewhat specific to the FDE
5938 * usecase. We probably should migrate tpm2_seal() to use tpm2_seal_data() eventually. */
5939
5940 if (data->iov_len >= sizeof_field(TPMS_SENSITIVE_CREATE, data.buffer))
5941 return -E2BIG;
5942
5943 TPMT_PUBLIC hmac_template = {
5944 .type = TPM2_ALG_KEYEDHASH,
5945 .nameAlg = TPM2_ALG_SHA256,
5946 .objectAttributes = TPMA_OBJECT_FIXEDTPM | TPMA_OBJECT_FIXEDPARENT,
5947 .parameters.keyedHashDetail.scheme.scheme = TPM2_ALG_NULL,
5948 .unique.keyedHash.size = data->iov_len,
5949 .authPolicy = policy ? *policy : TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE),
5950 };
5951
5952 TPMS_SENSITIVE_CREATE hmac_sensitive = {
5953 .data.size = hmac_template.unique.keyedHash.size,
5954 };
5955
5956 CLEANUP_ERASE(hmac_sensitive);
5957
5958 memcpy_safe(hmac_sensitive.data.buffer, data->iov_base, data->iov_len);
5959
5960 _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
5961 _cleanup_(Esys_Freep) TPM2B_PRIVATE *private = NULL;
5962 r = tpm2_create(c, primary_handle, encryption_session, &hmac_template, &hmac_sensitive, &public, &private);
5963 if (r < 0)
5964 return r;
5965
5966 _cleanup_(iovec_done) struct iovec public_blob = {}, private_blob = {};
5967
5968 r = tpm2_marshal_private(private, &private_blob.iov_base, &private_blob.iov_len);
5969 if (r < 0)
5970 return r;
5971
5972 r = tpm2_marshal_public(public, &public_blob.iov_base, &public_blob.iov_len);
5973 if (r < 0)
5974 return r;
5975
5976 if (ret_public)
5977 *ret_public = TAKE_STRUCT(public_blob);
5978 if (ret_private)
5979 *ret_private = TAKE_STRUCT(private_blob);
5980
5981 return 0;
5982 }
5983
5984 int tpm2_unseal_data(
5985 Tpm2Context *c,
5986 const struct iovec *public_blob,
5987 const struct iovec *private_blob,
5988 const Tpm2Handle *primary_handle,
5989 const Tpm2Handle *policy_session,
5990 const Tpm2Handle *encryption_session,
5991 struct iovec *ret_data) {
5992
5993 TSS2_RC rc;
5994 int r;
5995
5996 assert(c);
5997 assert(public_blob);
5998 assert(private_blob);
5999 assert(primary_handle);
6000
6001 TPM2B_PUBLIC public;
6002 r = tpm2_unmarshal_public(public_blob->iov_base, public_blob->iov_len, &public);
6003 if (r < 0)
6004 return r;
6005
6006 TPM2B_PRIVATE private;
6007 r = tpm2_unmarshal_private(private_blob->iov_base, private_blob->iov_len, &private);
6008 if (r < 0)
6009 return r;
6010
6011 _cleanup_(tpm2_handle_freep) Tpm2Handle *what = NULL;
6012 r = tpm2_load(c, primary_handle, NULL, &public, &private, &what);
6013 if (r < 0)
6014 return r;
6015
6016 _cleanup_(tpm2b_sensitive_data_erase_and_esys_freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
6017 rc = sym_Esys_Unseal(
6018 c->esys_context,
6019 what->esys_handle,
6020 policy_session ? policy_session->esys_handle : ESYS_TR_NONE,
6021 encryption_session ? encryption_session->esys_handle : ESYS_TR_NONE,
6022 ESYS_TR_NONE,
6023 &unsealed);
6024 if (rc == TPM2_RC_PCR_CHANGED)
6025 return log_debug_errno(SYNTHETIC_ERRNO(ESTALE),
6026 "PCR changed while unsealing.");
6027 if (rc != TSS2_RC_SUCCESS)
6028 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
6029 "Failed to unseal data: %s", sym_Tss2_RC_Decode(rc));
6030
6031 _cleanup_(iovec_done) struct iovec d = {
6032 .iov_base = memdup(unsealed->buffer, unsealed->size),
6033 .iov_len = unsealed->size,
6034 };
6035 if (!d.iov_base)
6036 return log_oom_debug();
6037
6038 *ret_data = TAKE_STRUCT(d);
6039 return 0;
6040 }
6041 #endif /* HAVE_TPM2 */
6042
6043 int tpm2_list_devices(bool legend, bool quiet) {
6044 #if HAVE_TPM2
6045 _cleanup_(table_unrefp) Table *t = NULL;
6046 _cleanup_closedir_ DIR *d = NULL;
6047 int r;
6048
6049 r = dlopen_tpm2();
6050 if (r < 0)
6051 return log_error_errno(r, "TPM2 support is not installed.");
6052
6053 t = table_new("path", "device", "driver");
6054 if (!t)
6055 return log_oom();
6056
6057 (void) table_set_header(t, legend);
6058
6059 d = opendir("/sys/class/tpmrm");
6060 if (!d) {
6061 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to open %s: %m", "/sys/class/tpmrm");
6062 if (errno != ENOENT)
6063 return -errno;
6064 } else {
6065 for (;;) {
6066 _cleanup_free_ char *device_path = NULL, *device = NULL, *driver_path = NULL, *driver = NULL, *node = NULL;
6067 struct dirent *de;
6068
6069 de = readdir_no_dot(d);
6070 if (!de)
6071 break;
6072
6073 device_path = path_join("/sys/class/tpmrm", de->d_name, "device");
6074 if (!device_path)
6075 return log_oom();
6076
6077 r = readlink_malloc(device_path, &device);
6078 if (r < 0)
6079 log_debug_errno(r, "Failed to read device symlink %s, ignoring: %m", device_path);
6080 else {
6081 driver_path = path_join(device_path, "driver");
6082 if (!driver_path)
6083 return log_oom();
6084
6085 r = readlink_malloc(driver_path, &driver);
6086 if (r < 0)
6087 log_debug_errno(r, "Failed to read driver symlink %s, ignoring: %m", driver_path);
6088 }
6089
6090 node = path_join("/dev", de->d_name);
6091 if (!node)
6092 return log_oom();
6093
6094 r = table_add_many(
6095 t,
6096 TABLE_PATH, node,
6097 TABLE_STRING, device ? last_path_component(device) : NULL,
6098 TABLE_STRING, driver ? last_path_component(driver) : NULL);
6099 if (r < 0)
6100 return table_log_add_error(r);
6101 }
6102 }
6103
6104 if (table_isempty(t) && !quiet) {
6105 log_info("No suitable TPM2 devices found.");
6106 return 0;
6107 }
6108
6109 r = table_print(t, stdout);
6110 if (r < 0)
6111 return log_error_errno(r, "Failed to show device table: %m");
6112
6113 return 0;
6114 #else
6115 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
6116 "TPM2 not supported on this build.");
6117 #endif
6118 }
6119
6120 int tpm2_find_device_auto(char **ret) {
6121 #if HAVE_TPM2
6122 _cleanup_closedir_ DIR *d = NULL;
6123 int r;
6124
6125 r = dlopen_tpm2();
6126 if (r < 0)
6127 return log_debug_errno(r, "TPM2 support is not installed.");
6128
6129 d = opendir("/sys/class/tpmrm");
6130 if (!d) {
6131 log_debug_errno(errno, "Failed to open %s: %m", "/sys/class/tpmrm");
6132 if (errno != ENOENT)
6133 return -errno;
6134 } else {
6135 _cleanup_free_ char *node = NULL;
6136
6137 for (;;) {
6138 struct dirent *de;
6139
6140 de = readdir_no_dot(d);
6141 if (!de)
6142 break;
6143
6144 if (node)
6145 return log_debug_errno(SYNTHETIC_ERRNO(ENOTUNIQ),
6146 "More than one TPM2 (tpmrm) device found.");
6147
6148 node = path_join("/dev", de->d_name);
6149 if (!node)
6150 return log_oom_debug();
6151 }
6152
6153 if (node) {
6154 *ret = TAKE_PTR(node);
6155 return 0;
6156 }
6157 }
6158
6159 return log_debug_errno(SYNTHETIC_ERRNO(ENODEV), "No TPM2 (tpmrm) device found.");
6160 #else
6161 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
6162 "TPM2 not supported on this build.");
6163 #endif
6164 }
6165
6166 #if HAVE_TPM2
6167 static const char* tpm2_userspace_event_type_table[_TPM2_USERSPACE_EVENT_TYPE_MAX] = {
6168 [TPM2_EVENT_PHASE] = "phase",
6169 [TPM2_EVENT_FILESYSTEM] = "filesystem",
6170 [TPM2_EVENT_VOLUME_KEY] = "volume-key",
6171 [TPM2_EVENT_MACHINE_ID] = "machine-id",
6172 };
6173
6174 DEFINE_STRING_TABLE_LOOKUP(tpm2_userspace_event_type, Tpm2UserspaceEventType);
6175
6176 const char* tpm2_userspace_log_path(void) {
6177 return secure_getenv("SYSTEMD_MEASURE_LOG_USERSPACE") ?: "/run/log/systemd/tpm2-measure.log";
6178 }
6179
6180 const char* tpm2_firmware_log_path(void) {
6181 return secure_getenv("SYSTEMD_MEASURE_LOG_FIRMWARE") ?: "/sys/kernel/security/tpm0/binary_bios_measurements";
6182 }
6183
6184 #if HAVE_OPENSSL
6185 static int tpm2_userspace_log_open(void) {
6186 _cleanup_close_ int fd = -EBADF;
6187 struct stat st;
6188 const char *e;
6189 int r;
6190
6191 e = tpm2_userspace_log_path();
6192 (void) mkdir_parents(e, 0755);
6193
6194 /* We use access mode 0600 here (even though the measurements should not strictly be confidential),
6195 * because we use BSD file locking on it, and if anyone but root can access the file they can also
6196 * lock it, which we want to avoid. */
6197 fd = open(e, O_CREAT|O_WRONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
6198 if (fd < 0)
6199 return log_debug_errno(errno, "Failed to open TPM log file '%s' for writing, ignoring: %m", e);
6200
6201 if (flock(fd, LOCK_EX) < 0)
6202 return log_debug_errno(errno, "Failed to lock TPM log file '%s', ignoring: %m", e);
6203
6204 if (fstat(fd, &st) < 0)
6205 return log_debug_errno(errno, "Failed to fstat TPM log file '%s', ignoring: %m", e);
6206
6207 r = stat_verify_regular(&st);
6208 if (r < 0)
6209 return log_debug_errno(r, "TPM log file '%s' is not regular, ignoring: %m", e);
6210
6211 /* We set the sticky bit when we are about to append to the log file. We'll unset it afterwards
6212 * again. If we manage to take a lock on a file that has it set we know we didn't write it fully and
6213 * it is corrupted. Ideally we'd like to use user xattrs for this, but unfortunately tmpfs (which is
6214 * our assumed backend fs) doesn't know user xattrs. */
6215 if (st.st_mode & S_ISVTX)
6216 return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "TPM log file '%s' aborted, ignoring.", e);
6217
6218 if (fchmod(fd, 0600 | S_ISVTX) < 0)
6219 return log_debug_errno(errno, "Failed to chmod() TPM log file '%s', ignoring: %m", e);
6220
6221 return TAKE_FD(fd);
6222 }
6223
6224 static int tpm2_userspace_log(
6225 int fd,
6226 unsigned pcr_index,
6227 const TPML_DIGEST_VALUES *values,
6228 Tpm2UserspaceEventType event_type,
6229 const char *description) {
6230
6231 _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL, *array = NULL;
6232 _cleanup_free_ char *f = NULL;
6233 sd_id128_t boot_id;
6234 int r;
6235
6236 assert(values);
6237 assert(values->count > 0);
6238
6239 /* We maintain a local PCR measurement log. This implements a subset of the TCG Canonical Event Log
6240 * Format – the JSON flavour –
6241 * (https://trustedcomputinggroup.org/resource/canonical-event-log-format/), but departs in certain
6242 * ways from it, specifically:
6243 *
6244 * - We don't write out a recnum. It's a bit too vaguely defined which means we'd have to read
6245 * through the whole logs (include firmware logs) before knowing what the next value is we should
6246 * use. Hence we simply don't write this out as append-time, and instead expect a consumer to add
6247 * it in when it uses the data.
6248 *
6249 * - We write this out in RFC 7464 application/json-seq rather than as a JSON array. Writing this as
6250 * JSON array would mean that for each appending we'd have to read the whole log file fully into
6251 * memory before writing it out again. We prefer a strictly append-only write pattern however. (RFC
6252 * 7464 is what jq --seq eats.) Conversion into a proper JSON array is trivial.
6253 *
6254 * It should be possible to convert this format in a relatively straight-forward way into the
6255 * official TCG Canonical Event Log Format on read, by simply adding in a few more fields that can be
6256 * determined from the full dataset.
6257 *
6258 * We set the 'content_type' field to "systemd" to make clear this data is generated by us, and
6259 * include various interesting fields in the 'content' subobject, including a CLOCK_BOOTTIME
6260 * timestamp which can be used to order this measurement against possibly other measurements
6261 * independently done by other subsystems on the system.
6262 */
6263
6264 if (fd < 0) /* Apparently tpm2_local_log_open() failed earlier, let's not complain again */
6265 return 0;
6266
6267 for (size_t i = 0; i < values->count; i++) {
6268 const EVP_MD *implementation;
6269 const char *a;
6270
6271 assert_se(a = tpm2_hash_alg_to_string(values->digests[i].hashAlg));
6272 assert_se(implementation = EVP_get_digestbyname(a));
6273
6274 r = sd_json_variant_append_arraybo(
6275 &array,
6276 SD_JSON_BUILD_PAIR_STRING("hashAlg", a),
6277 SD_JSON_BUILD_PAIR("digest", SD_JSON_BUILD_HEX(&values->digests[i].digest, EVP_MD_size(implementation))));
6278 if (r < 0)
6279 return log_debug_errno(r, "Failed to append digest object to JSON array: %m");
6280 }
6281
6282 assert(array);
6283
6284 r = sd_id128_get_boot(&boot_id);
6285 if (r < 0)
6286 return log_debug_errno(r, "Failed to acquire boot ID: %m");
6287
6288 r = sd_json_buildo(
6289 &v,
6290 SD_JSON_BUILD_PAIR("pcr", SD_JSON_BUILD_UNSIGNED(pcr_index)),
6291 SD_JSON_BUILD_PAIR("digests", SD_JSON_BUILD_VARIANT(array)),
6292 SD_JSON_BUILD_PAIR("content_type", SD_JSON_BUILD_STRING("systemd")),
6293 SD_JSON_BUILD_PAIR("content", SD_JSON_BUILD_OBJECT(
6294 SD_JSON_BUILD_PAIR_CONDITION(!!description, "string", SD_JSON_BUILD_STRING(description)),
6295 SD_JSON_BUILD_PAIR("bootId", SD_JSON_BUILD_ID128(boot_id)),
6296 SD_JSON_BUILD_PAIR("timestamp", SD_JSON_BUILD_UNSIGNED(now(CLOCK_BOOTTIME))),
6297 SD_JSON_BUILD_PAIR_CONDITION(event_type >= 0, "eventType", SD_JSON_BUILD_STRING(tpm2_userspace_event_type_to_string(event_type))))));
6298 if (r < 0)
6299 return log_debug_errno(r, "Failed to build log record JSON: %m");
6300
6301 r = sd_json_variant_format(v, SD_JSON_FORMAT_SEQ, &f);
6302 if (r < 0)
6303 return log_debug_errno(r, "Failed to format JSON: %m");
6304
6305 if (lseek(fd, 0, SEEK_END) < 0)
6306 return log_debug_errno(errno, "Failed to seek to end of JSON log: %m");
6307
6308 r = loop_write(fd, f, SIZE_MAX);
6309 if (r < 0)
6310 return log_debug_errno(r, "Failed to write JSON data to log: %m");
6311
6312 if (fsync(fd) < 0)
6313 return log_debug_errno(errno, "Failed to sync JSON data: %m");
6314
6315 /* Unset S_ISVTX again */
6316 if (fchmod(fd, 0600) < 0)
6317 return log_debug_errno(errno, "Failed to chmod() TPM log file, ignoring: %m");
6318
6319 r = fsync_full(fd);
6320 if (r < 0)
6321 return log_debug_errno(r, "Failed to sync JSON log: %m");
6322
6323 return 1;
6324 }
6325 #endif
6326
6327 int tpm2_extend_bytes(
6328 Tpm2Context *c,
6329 char **banks,
6330 unsigned pcr_index,
6331 const void *data,
6332 size_t data_size,
6333 const void *secret,
6334 size_t secret_size,
6335 Tpm2UserspaceEventType event_type,
6336 const char *description) {
6337
6338 #if HAVE_OPENSSL
6339 _cleanup_close_ int log_fd = -EBADF;
6340 TPML_DIGEST_VALUES values = {};
6341 TSS2_RC rc;
6342
6343 assert(c);
6344 assert(data || data_size == 0);
6345 assert(secret || secret_size == 0);
6346
6347 if (data_size == SIZE_MAX)
6348 data_size = strlen(data);
6349 if (secret_size == SIZE_MAX)
6350 secret_size = strlen(secret);
6351
6352 if (pcr_index >= TPM2_PCRS_MAX)
6353 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Can't measure into unsupported PCR %u, refusing.", pcr_index);
6354
6355 if (strv_isempty(banks))
6356 return 0;
6357
6358 STRV_FOREACH(bank, banks) {
6359 const EVP_MD *implementation;
6360 int id;
6361
6362 assert_se(implementation = EVP_get_digestbyname(*bank));
6363
6364 if (values.count >= ELEMENTSOF(values.digests))
6365 return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "Too many banks selected.");
6366
6367 if ((size_t) EVP_MD_size(implementation) > sizeof(values.digests[values.count].digest))
6368 return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "Hash result too large for TPM2.");
6369
6370 id = tpm2_hash_alg_from_string(EVP_MD_name(implementation));
6371 if (id < 0)
6372 return log_debug_errno(id, "Can't map hash name to TPM2.");
6373
6374 values.digests[values.count].hashAlg = id;
6375
6376 /* So here's a twist: sometimes we want to measure secrets (e.g. root file system volume
6377 * key), but we'd rather not leak a literal hash of the secret to the TPM (given that the
6378 * wire is unprotected, and some other subsystem might use the simple, literal hash of the
6379 * secret for other purposes, maybe because it needs a shorter secret derived from it for
6380 * some unrelated purpose, who knows). Hence we instead measure an HMAC signature of a
6381 * private non-secret string instead. */
6382 if (secret_size > 0) {
6383 if (!HMAC(implementation, secret, secret_size, data, data_size, (unsigned char*) &values.digests[values.count].digest, NULL))
6384 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to calculate HMAC of data to measure.");
6385 } else if (EVP_Digest(data, data_size, (unsigned char*) &values.digests[values.count].digest, NULL, implementation, NULL) != 1)
6386 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash data to measure.");
6387
6388 values.count++;
6389 }
6390
6391 /* Open + lock the log file *before* we start measuring, so that no one else can come between our log
6392 * and our measurement and change either */
6393 log_fd = tpm2_userspace_log_open();
6394
6395 rc = sym_Esys_PCR_Extend(
6396 c->esys_context,
6397 ESYS_TR_PCR0 + pcr_index,
6398 ESYS_TR_PASSWORD,
6399 ESYS_TR_NONE,
6400 ESYS_TR_NONE,
6401 &values);
6402 if (rc != TSS2_RC_SUCCESS)
6403 return log_debug_errno(
6404 SYNTHETIC_ERRNO(ENOTRECOVERABLE),
6405 "Failed to measure into PCR %u: %s",
6406 pcr_index,
6407 sym_Tss2_RC_Decode(rc));
6408
6409 /* Now, write what we just extended to the log, too. */
6410 (void) tpm2_userspace_log(log_fd, pcr_index, &values, event_type, description);
6411
6412 return 0;
6413 #else /* HAVE_OPENSSL */
6414 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
6415 #endif
6416 }
6417
6418 const uint16_t tpm2_hash_algorithms[] = {
6419 TPM2_ALG_SHA1,
6420 TPM2_ALG_SHA256,
6421 TPM2_ALG_SHA384,
6422 TPM2_ALG_SHA512,
6423 0,
6424 };
6425
6426 assert_cc(ELEMENTSOF(tpm2_hash_algorithms) == TPM2_N_HASH_ALGORITHMS + 1);
6427
6428 static size_t tpm2_hash_algorithm_index(uint16_t algorithm) {
6429 for (size_t i = 0; i < TPM2_N_HASH_ALGORITHMS; i++)
6430 if (tpm2_hash_algorithms[i] == algorithm)
6431 return i;
6432
6433 return SIZE_MAX;
6434 }
6435
6436 TPM2B_DIGEST *tpm2_pcr_prediction_result_get_hash(Tpm2PCRPredictionResult *result, uint16_t alg) {
6437 size_t alg_idx;
6438
6439 assert(result);
6440
6441 alg_idx = tpm2_hash_algorithm_index(alg);
6442 if (alg_idx == SIZE_MAX) /* Algorithm not known? */
6443 return NULL;
6444
6445 if (result->hash[alg_idx].size <= 0) /* No hash value for this algorithm? */
6446 return NULL;
6447
6448 return result->hash + alg_idx;
6449 }
6450
6451 void tpm2_pcr_prediction_done(Tpm2PCRPrediction *p) {
6452 assert(p);
6453
6454 for (uint32_t pcr = 0; pcr < TPM2_PCRS_MAX; pcr++)
6455 ordered_set_free(p->results[pcr]);
6456 }
6457
6458 static void tpm2_pcr_prediction_result_hash_func(const Tpm2PCRPredictionResult *banks, struct siphash *state) {
6459 assert(banks);
6460
6461 for (size_t i = 0; i < TPM2_N_HASH_ALGORITHMS; i++)
6462 siphash24_compress_safe(banks->hash[i].buffer, banks->hash[i].size, state);
6463 }
6464
6465 static int tpm2_pcr_prediction_result_compare_func(const Tpm2PCRPredictionResult *a, const Tpm2PCRPredictionResult *b) {
6466 int r;
6467
6468 assert(a);
6469 assert(b);
6470
6471 for (size_t i = 0; i < TPM2_N_HASH_ALGORITHMS; i++) {
6472 r = memcmp_nn(a->hash[i].buffer, a->hash[i].size,
6473 b->hash[i].buffer, b->hash[i].size);
6474 if (r != 0)
6475 return r;
6476 }
6477
6478 return 0;
6479 }
6480
6481 DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
6482 tpm2_pcr_prediction_result_hash_ops,
6483 Tpm2PCRPredictionResult,
6484 tpm2_pcr_prediction_result_hash_func,
6485 tpm2_pcr_prediction_result_compare_func,
6486 Tpm2PCRPredictionResult,
6487 free);
6488
6489 static Tpm2PCRPredictionResult *find_prediction_result_by_algorithm(OrderedSet *set, Tpm2PCRPredictionResult *result, size_t alg_idx) {
6490 Tpm2PCRPredictionResult *f;
6491
6492 assert(result);
6493 assert(alg_idx != SIZE_MAX);
6494
6495 f = ordered_set_get(set, result); /* Full match? */
6496 if (f)
6497 return f;
6498
6499 /* If this doesn't match full, then see if there an entry that at least matches by the relevant
6500 * algorithm (we are fine if predictions are "incomplete" in some algorithms) */
6501
6502 ORDERED_SET_FOREACH(f, set)
6503 if (memcmp_nn(result->hash[alg_idx].buffer, result->hash[alg_idx].size,
6504 f->hash[alg_idx].buffer, f->hash[alg_idx].size) == 0)
6505 return f;
6506
6507 return NULL;
6508 }
6509
6510 bool tpm2_pcr_prediction_equal(
6511 Tpm2PCRPrediction *a,
6512 Tpm2PCRPrediction *b,
6513 uint16_t algorithm) {
6514
6515 if (a == b)
6516 return true;
6517 if (!a || !b)
6518 return false;
6519
6520 if (a->pcrs != b->pcrs)
6521 return false;
6522
6523 size_t alg_idx = tpm2_hash_algorithm_index(algorithm);
6524 if (alg_idx == SIZE_MAX)
6525 return false;
6526
6527 for (uint32_t pcr = 0; pcr < TPM2_PCRS_MAX; pcr++) {
6528 Tpm2PCRPredictionResult *banks;
6529
6530 ORDERED_SET_FOREACH(banks, a->results[pcr])
6531 if (!find_prediction_result_by_algorithm(b->results[pcr], banks, alg_idx))
6532 return false;
6533
6534 ORDERED_SET_FOREACH(banks, b->results[pcr])
6535 if (!find_prediction_result_by_algorithm(a->results[pcr], banks, alg_idx))
6536 return false;
6537 }
6538
6539 return true;
6540 }
6541
6542 int tpm2_pcr_prediction_to_json(
6543 const Tpm2PCRPrediction *prediction,
6544 uint16_t algorithm,
6545 sd_json_variant **ret) {
6546
6547 _cleanup_(sd_json_variant_unrefp) sd_json_variant *aj = NULL;
6548 int r;
6549
6550 assert(prediction);
6551 assert(ret);
6552
6553 for (uint32_t pcr = 0; pcr < TPM2_PCRS_MAX; pcr++) {
6554 _cleanup_(sd_json_variant_unrefp) sd_json_variant *vj = NULL;
6555 Tpm2PCRPredictionResult *banks;
6556
6557 if (!BIT_SET(prediction->pcrs, pcr))
6558 continue;
6559
6560 ORDERED_SET_FOREACH(banks, prediction->results[pcr]) {
6561
6562 TPM2B_DIGEST *hash = tpm2_pcr_prediction_result_get_hash(banks, algorithm);
6563 if (!hash)
6564 continue;
6565
6566 r = sd_json_variant_append_arrayb(
6567 &vj,
6568 SD_JSON_BUILD_HEX(hash->buffer, hash->size));
6569 if (r < 0)
6570 return log_error_errno(r, "Failed to append hash variant to JSON array: %m");
6571 }
6572
6573 if (!vj)
6574 continue;
6575
6576 r = sd_json_variant_append_arraybo(
6577 &aj,
6578 SD_JSON_BUILD_PAIR_INTEGER("pcr", pcr),
6579 SD_JSON_BUILD_PAIR_VARIANT("values", vj));
6580 if (r < 0)
6581 return log_error_errno(r, "Failed to append PCR variants to JSON array: %m");
6582 }
6583
6584 if (!aj) {
6585 r = sd_json_variant_new_array(&aj, NULL, 0);
6586 if (r < 0)
6587 return r;
6588 }
6589
6590 *ret = TAKE_PTR(aj);
6591 return 0;
6592 }
6593
6594 int tpm2_pcr_prediction_from_json(
6595 Tpm2PCRPrediction *prediction,
6596 uint16_t algorithm,
6597 sd_json_variant *aj) {
6598
6599 int r;
6600
6601 assert(prediction);
6602
6603 size_t alg_index = tpm2_hash_algorithm_index(algorithm);
6604 assert(alg_index < TPM2_N_HASH_ALGORITHMS);
6605
6606 if (!sd_json_variant_is_array(aj))
6607 return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "PCR variant array is not an array.");
6608
6609 sd_json_variant *pcr;
6610 JSON_VARIANT_ARRAY_FOREACH(pcr, aj) {
6611 sd_json_variant *nr, *values;
6612
6613 nr = sd_json_variant_by_key(pcr, "pcr");
6614 if (!nr)
6615 return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "PCR array entry lacks PCR index field");
6616
6617 if (!sd_json_variant_is_unsigned(nr) ||
6618 sd_json_variant_unsigned(nr) >= TPM2_PCRS_MAX)
6619 return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "PCR array entry PCR index is not an integer in the range 0…23");
6620
6621 values = sd_json_variant_by_key(pcr, "values");
6622 if (!values)
6623 return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "PCR array entry lacks values field");
6624
6625 if (!sd_json_variant_is_array(values))
6626 return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "PCR array entry values field is not an array");
6627
6628 prediction->pcrs |= UINT32_C(1) << sd_json_variant_unsigned(nr);
6629
6630 sd_json_variant *v;
6631 JSON_VARIANT_ARRAY_FOREACH(v, values) {
6632 _cleanup_free_ void *buffer = NULL;
6633 size_t size;
6634
6635 r = sd_json_variant_unhex(v, &buffer, &size);
6636 if (r < 0)
6637 return log_error_errno(r, "Failed to decode PCR policy array hash value");
6638
6639 if (size <= 0)
6640 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "PCR policy array hash value is zero.");
6641
6642 if (size > sizeof_field(TPM2B_DIGEST, buffer))
6643 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "PCR policy array hash value is too large.");
6644
6645 _cleanup_free_ Tpm2PCRPredictionResult *banks = new0(Tpm2PCRPredictionResult, 1);
6646 if (!banks)
6647 return log_oom();
6648
6649 memcpy(banks->hash[alg_index].buffer, buffer, size);
6650 banks->hash[alg_index].size = size;
6651
6652 r = ordered_set_ensure_put(prediction->results + sd_json_variant_unsigned(nr), &tpm2_pcr_prediction_result_hash_ops, banks);
6653 if (r == -EEXIST) /* Let's allow duplicates */
6654 continue;
6655 if (r < 0)
6656 return log_error_errno(r, "Failed to insert result into set: %m");
6657
6658 TAKE_PTR(banks);
6659 }
6660 }
6661
6662 return 0;
6663 }
6664
6665 int tpm2_calculate_policy_super_pcr(
6666 Tpm2PCRPrediction *prediction,
6667 uint16_t algorithm,
6668 TPM2B_DIGEST *pcr_policy) {
6669
6670 int r;
6671
6672 assert_se(prediction);
6673 assert_se(pcr_policy);
6674
6675 /* Start with a zero policy if not specified otherwise. */
6676 TPM2B_DIGEST super_pcr_policy_digest = *pcr_policy;
6677
6678 /* First we look for all PCRs that have exactly one allowed hash value, and generate a single PolicyPCR policy from them */
6679 _cleanup_free_ Tpm2PCRValue *single_values = NULL;
6680 size_t n_single_values = 0;
6681 BIT_FOREACH(pcr, prediction->pcrs) {
6682 if (ordered_set_size(prediction->results[pcr]) != 1)
6683 continue;
6684
6685 log_debug("Including PCR %i in single value PolicyPCR expression", pcr);
6686
6687 Tpm2PCRPredictionResult *banks = ASSERT_PTR(ordered_set_first(prediction->results[pcr]));
6688
6689 TPM2B_DIGEST *hash = tpm2_pcr_prediction_result_get_hash(banks, algorithm);
6690 if (!hash)
6691 continue;
6692
6693 if (!GREEDY_REALLOC(single_values, n_single_values + 1))
6694 return -ENOMEM;
6695
6696 single_values[n_single_values++] = TPM2_PCR_VALUE_MAKE(pcr, algorithm, *hash);
6697 }
6698
6699 if (n_single_values > 0) {
6700 /* Evolve policy based on the expected PCR value for what we found. */
6701 r = tpm2_calculate_policy_pcr(
6702 single_values,
6703 n_single_values,
6704 &super_pcr_policy_digest);
6705 if (r < 0)
6706 return r;
6707 }
6708
6709 /* Now deal with the PCRs for which we have variants, i.e. more than one allowed values */
6710 for (uint32_t pcr = 0; pcr < TPM2_PCRS_MAX; pcr++) {
6711 _cleanup_free_ TPM2B_DIGEST *pcr_policy_digest_variants = NULL;
6712 size_t n_pcr_policy_digest_variants = 0;
6713 Tpm2PCRPredictionResult *banks;
6714
6715 if (!BIT_SET(prediction->pcrs, pcr))
6716 continue;
6717
6718 if (ordered_set_size(prediction->results[pcr]) <= 1) /* We only care for PCRs with 2 or more variants in this loop */
6719 continue;
6720
6721 if (ordered_set_size(prediction->results[pcr]) > 8)
6722 return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "PCR policies with more than 8 alternatives per PCR are currently not supported.");
6723
6724 ORDERED_SET_FOREACH(banks, prediction->results[pcr]) {
6725 /* Start from the super PCR policy from the previous PCR we looked at so far. */
6726 TPM2B_DIGEST pcr_policy_digest = super_pcr_policy_digest;
6727
6728 TPM2B_DIGEST *hash = tpm2_pcr_prediction_result_get_hash(banks, algorithm);
6729 if (!hash)
6730 continue;
6731
6732 /* Evolve it based on the expected PCR value for this PCR */
6733 r = tpm2_calculate_policy_pcr(
6734 &TPM2_PCR_VALUE_MAKE(
6735 pcr,
6736 algorithm,
6737 *hash),
6738 /* n_pcr_values= */ 1,
6739 &pcr_policy_digest);
6740 if (r < 0)
6741 return r;
6742
6743 /* Store away this new variant */
6744 if (!GREEDY_REALLOC(pcr_policy_digest_variants, n_pcr_policy_digest_variants + 1))
6745 return log_oom();
6746
6747 pcr_policy_digest_variants[n_pcr_policy_digest_variants++] = pcr_policy_digest;
6748
6749 log_debug("Calculated PCR policy variant %zu for PCR %" PRIu32, n_pcr_policy_digest_variants, pcr);
6750 }
6751
6752 assert_se(n_pcr_policy_digest_variants >= 2);
6753 assert_se(n_pcr_policy_digest_variants <= 8);
6754
6755 /* Now combine all our variant into one OR policy */
6756 r = tpm2_calculate_policy_or(
6757 pcr_policy_digest_variants,
6758 n_pcr_policy_digest_variants,
6759 &super_pcr_policy_digest);
6760 if (r < 0)
6761 return r;
6762
6763 log_debug("Combined %zu variants in OR policy.", n_pcr_policy_digest_variants);
6764 }
6765
6766 *pcr_policy = super_pcr_policy_digest;
6767 return 0;
6768 }
6769
6770 int tpm2_policy_super_pcr(
6771 Tpm2Context *c,
6772 const Tpm2Handle *session,
6773 const Tpm2PCRPrediction *prediction,
6774 uint16_t algorithm) {
6775
6776 int r;
6777
6778 assert_se(c);
6779 assert_se(session);
6780 assert_se(prediction);
6781
6782 TPM2B_DIGEST previous_policy_digest = TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE);
6783
6784 uint32_t single_value_pcrs = 0;
6785
6786 /* Look for all PCRs that have only a singled allowed hash value, and synthesize a single PolicyPCR policy item for them */
6787 for (uint32_t pcr = 0; pcr < TPM2_PCRS_MAX; pcr++) {
6788 if (!BIT_SET(prediction->pcrs, pcr))
6789 continue;
6790
6791 if (ordered_set_size(prediction->results[pcr]) != 1)
6792 continue;
6793
6794 log_debug("Including PCR %" PRIu32 " in single value PolicyPCR expression", pcr);
6795
6796 single_value_pcrs |= UINT32_C(1) << pcr;
6797 }
6798
6799 if (single_value_pcrs != 0) {
6800 TPML_PCR_SELECTION pcr_selection;
6801 tpm2_tpml_pcr_selection_from_mask(single_value_pcrs, algorithm, &pcr_selection);
6802
6803 _cleanup_free_ TPM2B_DIGEST *current_policy_digest = NULL;
6804 r = tpm2_policy_pcr(
6805 c,
6806 session,
6807 &pcr_selection,
6808 &current_policy_digest);
6809 if (r == -EUCLEAN) {
6810 _cleanup_free_ char *j = NULL;
6811
6812 for (uint32_t pcr = 0; pcr < TPM2_PCRS_MAX; pcr++)
6813 if (single_value_pcrs & (UINT32_C(1) << pcr))
6814 (void) strextendf_with_separator(&j, ", ", "%" PRIu32, pcr);
6815
6816 return log_error_errno(r, "Combined value for PCR(s) %s encoded in policy does not match the current TPM state. Either the system has been tempered with or the provided policy is incorrect.", strna(j));
6817 }
6818 if (r < 0)
6819 return log_error_errno(r, "Failed to submit PCR policy to TPM: %m");
6820
6821 previous_policy_digest = *current_policy_digest;
6822 }
6823
6824 for (uint32_t pcr = 0; pcr < TPM2_PCRS_MAX; pcr++) {
6825 size_t n_branches;
6826
6827 if (!BIT_SET(prediction->pcrs, pcr))
6828 continue;
6829
6830 n_branches = ordered_set_size(prediction->results[pcr]);
6831 if (n_branches < 1 || n_branches > 8)
6832 return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Number of variants per PCR not in range 1…8");
6833
6834 if (n_branches == 1) /* Single choice PCRs are already covered by the loop above */
6835 continue;
6836
6837 log_debug("Submitting PCR/OR policy for PCR %" PRIu32, pcr);
6838
6839 TPML_PCR_SELECTION pcr_selection;
6840 tpm2_tpml_pcr_selection_from_mask(UINT32_C(1) << pcr, algorithm, &pcr_selection);
6841
6842 _cleanup_free_ TPM2B_DIGEST *current_policy_digest = NULL;
6843 r = tpm2_policy_pcr(
6844 c,
6845 session,
6846 &pcr_selection,
6847 &current_policy_digest);
6848 if (r == -EUCLEAN)
6849 return log_error_errno(r, "Value for PCR %" PRIu32 " encoded in policy does not match the current TPM state. Either the system has been tempered with or the provided policy is incorrect.", pcr);
6850 if (r < 0)
6851 return log_error_errno(r, "Failed to submit PCR policy to TPM: %m");
6852
6853 _cleanup_free_ TPM2B_DIGEST *branches = NULL;
6854 branches = new0(TPM2B_DIGEST, n_branches);
6855 if (!branches)
6856 return log_oom();
6857
6858 Tpm2PCRPredictionResult *banks;
6859 size_t i = 0;
6860 ORDERED_SET_FOREACH(banks, prediction->results[pcr]) {
6861 TPM2B_DIGEST pcr_policy_digest = previous_policy_digest;
6862
6863 TPM2B_DIGEST *hash = tpm2_pcr_prediction_result_get_hash(banks, algorithm);
6864 if (!hash)
6865 continue;
6866
6867 /* Evolve it based on the expected PCR value for this PCR */
6868 r = tpm2_calculate_policy_pcr(
6869 &TPM2_PCR_VALUE_MAKE(
6870 pcr,
6871 algorithm,
6872 *hash),
6873 /* n_pcr_values= */ 1,
6874 &pcr_policy_digest);
6875 if (r < 0)
6876 return log_error_errno(r, "Failed to calculate PolicyPCR: %m");
6877
6878 branches[i++] = pcr_policy_digest;
6879 }
6880
6881 assert_se(i == n_branches);
6882
6883 current_policy_digest = mfree(current_policy_digest);
6884 r = tpm2_policy_or(
6885 c,
6886 session,
6887 branches,
6888 n_branches,
6889 &current_policy_digest);
6890 if (r == -ENOANO)
6891 return log_error_errno(r, "None of the alternative values for PCR %" PRIu32 " encoded in policy match the current TPM state. Either the system has been tempered with or the provided policy is incorrect.", pcr);
6892 if (r < 0)
6893 return log_error_errno(r, "Failed to submit OR policy to TPM: %m");
6894
6895 previous_policy_digest = *current_policy_digest;
6896 }
6897
6898 return 0;
6899 }
6900
6901 void tpm2_pcrlock_policy_done(Tpm2PCRLockPolicy *data) {
6902 assert(data);
6903
6904 data->prediction_json = sd_json_variant_unref(data->prediction_json);
6905 tpm2_pcr_prediction_done(&data->prediction);
6906 iovec_done(&data->nv_handle);
6907 iovec_done(&data->nv_public);
6908 iovec_done(&data->srk_handle);
6909 iovec_done(&data->pin_public);
6910 iovec_done(&data->pin_private);
6911 }
6912
6913 static int json_dispatch_tpm2_algorithm(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
6914 uint16_t *algorithm = ASSERT_PTR(userdata);
6915 int r;
6916
6917 r = tpm2_hash_alg_from_string(sd_json_variant_string(variant));
6918 if (r < 0 || tpm2_hash_algorithm_index(r) == SIZE_MAX)
6919 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid hash algorithm: %s", sd_json_variant_string(variant));
6920
6921 *algorithm = r;
6922 return 0;
6923 }
6924
6925 int tpm2_pcrlock_search_file(const char *path, FILE **ret_file, char **ret_path) {
6926 static const char search[] =
6927 "/run/systemd\0"
6928 "/var/lib/systemd\0";
6929
6930 int r;
6931
6932 if (!path)
6933 path = "pcrlock.json";
6934
6935 r = search_and_fopen_nulstr(path, ret_file ? "re" : NULL, NULL, search, ret_file, ret_path);
6936 if (r < 0)
6937 return log_debug_errno(r, "Failed to find TPM2 pcrlock policy file '%s': %m", path);
6938
6939 return 0;
6940 }
6941
6942 int tpm2_pcrlock_policy_from_json(
6943 sd_json_variant *v,
6944 Tpm2PCRLockPolicy *ret_policy) {
6945
6946 /* We use a type check of _JSON_VARIANT_TYPE_INVALID for the integer fields to allow
6947 * json_dispatch_uint32() to parse strings as integers to work around the integer type weakness of
6948 * JSON's design. */
6949 static const sd_json_dispatch_field policy_dispatch[] = {
6950 { "pcrBank", SD_JSON_VARIANT_STRING, json_dispatch_tpm2_algorithm, offsetof(Tpm2PCRLockPolicy, algorithm), SD_JSON_MANDATORY },
6951 { "pcrValues", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_variant, offsetof(Tpm2PCRLockPolicy, prediction_json), SD_JSON_MANDATORY },
6952 { "nvIndex", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint32, offsetof(Tpm2PCRLockPolicy, nv_index), SD_JSON_MANDATORY },
6953 { "nvHandle", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, offsetof(Tpm2PCRLockPolicy, nv_handle), SD_JSON_MANDATORY },
6954 { "nvPublic", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, offsetof(Tpm2PCRLockPolicy, nv_public), SD_JSON_MANDATORY },
6955 { "srkHandle", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, offsetof(Tpm2PCRLockPolicy, srk_handle), SD_JSON_MANDATORY },
6956 { "pinPublic", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, offsetof(Tpm2PCRLockPolicy, pin_public), SD_JSON_MANDATORY },
6957 { "pinPrivate", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, offsetof(Tpm2PCRLockPolicy, pin_private), SD_JSON_MANDATORY },
6958 {}
6959 };
6960
6961 _cleanup_(tpm2_pcrlock_policy_done) Tpm2PCRLockPolicy policy = {};
6962 int r;
6963
6964 assert(v);
6965 assert(ret_policy);
6966
6967 r = sd_json_dispatch(v, policy_dispatch, SD_JSON_LOG, &policy);
6968 if (r < 0)
6969 return r;
6970
6971 r = tpm2_pcr_prediction_from_json(&policy.prediction, policy.algorithm, policy.prediction_json);
6972 if (r < 0)
6973 return r;
6974
6975 *ret_policy = TAKE_STRUCT(policy);
6976 return 1;
6977 }
6978
6979 int tpm2_pcrlock_policy_load(
6980 const char *path,
6981 Tpm2PCRLockPolicy *ret_policy) {
6982
6983 _cleanup_free_ char *discovered_path = NULL;
6984 _cleanup_fclose_ FILE *f = NULL;
6985 int r;
6986
6987 r = tpm2_pcrlock_search_file(path, &f, &discovered_path);
6988 if (r == -ENOENT) {
6989 *ret_policy = (Tpm2PCRLockPolicy) {};
6990 return 0;
6991 }
6992 if (r < 0)
6993 return log_error_errno(r, "Failed to load TPM2 pcrlock policy file: %m");
6994
6995 _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
6996 r = sd_json_parse_file(
6997 f,
6998 discovered_path,
6999 /* flags = */ 0,
7000 &v,
7001 /* reterr_line= */ NULL,
7002 /* ret_column= */ NULL);
7003 if (r < 0)
7004 return log_error_errno(r, "Failed to parse existing pcrlock policy file '%s': %m", discovered_path);
7005
7006 return tpm2_pcrlock_policy_from_json(v, ret_policy);
7007 }
7008
7009 static int pcrlock_policy_load_credential(
7010 const char *name,
7011 const struct iovec *data,
7012 Tpm2PCRLockPolicy *ret) {
7013
7014 _cleanup_free_ char *c = NULL;
7015 int r;
7016
7017 assert(name);
7018
7019 c = strdup(name);
7020 if (!c)
7021 return log_oom();
7022
7023 ascii_strlower(c); /* Lowercase, to match what we did at encryption time */
7024
7025 _cleanup_(iovec_done) struct iovec decoded = {};
7026 r = decrypt_credential_and_warn(
7027 c,
7028 now(CLOCK_REALTIME),
7029 /* tpm2_device= */ NULL,
7030 /* tpm2_signature_path= */ NULL,
7031 UID_INVALID,
7032 data,
7033 CREDENTIAL_ALLOW_NULL,
7034 &decoded);
7035 if (r < 0)
7036 return r;
7037
7038 if (memchr(decoded.iov_base, 0, decoded.iov_len))
7039 return log_error_errno(r, "Credential '%s' contains embedded NUL byte, refusing.", name);
7040
7041 _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
7042 r = sd_json_parse(decoded.iov_base,
7043 /* flags= */ 0,
7044 &v,
7045 /* reterr_line= */ NULL,
7046 /* ret_column= */ NULL);
7047 if (r < 0)
7048 return log_error_errno(r, "Failed to parse pcrlock policy: %m");
7049
7050 r = tpm2_pcrlock_policy_from_json(v, ret);
7051 if (r < 0)
7052 return r;
7053
7054 return 0;
7055 }
7056
7057 int tpm2_pcrlock_policy_from_credentials(
7058 const struct iovec *srk,
7059 const struct iovec *nv,
7060 Tpm2PCRLockPolicy *ret) {
7061
7062 _cleanup_close_ int dfd = -EBADF;
7063 int r;
7064
7065 /* During boot we'll not have access to the pcrlock.json file in /var/. In order to support
7066 * pcrlock-bound root file systems we'll store a copy of the JSON data, wrapped in an (plaintext)
7067 * credential in the ESP or XBOOTLDR partition. There might be multiple of those however (because of
7068 * multi-boot), hence we use the SRK and NV data from the LUKS2 header as search key, and parse all
7069 * such JSON policies until we find a matching one. */
7070
7071 const char *cp = secure_getenv("SYSTEMD_ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY") ?: ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY;
7072
7073 dfd = open(cp, O_CLOEXEC|O_DIRECTORY);
7074 if (dfd < 0) {
7075 if (errno == ENOENT) {
7076 log_debug("No encrypted system credentials passed.");
7077 return 0;
7078 }
7079
7080 return log_error_errno(errno, "Failed to open system credentials directory.");
7081 }
7082
7083 _cleanup_free_ DirectoryEntries *de = NULL;
7084 r = readdir_all(dfd, RECURSE_DIR_IGNORE_DOT, &de);
7085 if (r < 0)
7086 return log_error_errno(r, "Failed to enumerate system credentials: %m");
7087
7088 FOREACH_ARRAY(i, de->entries, de->n_entries) {
7089 _cleanup_(iovec_done) struct iovec data = {};
7090 struct dirent *d = *i;
7091
7092 if (!startswith_no_case(d->d_name, "pcrlock.")) /* VFAT is case-insensitive, hence don't be too strict here */
7093 continue;
7094
7095 r = read_full_file_full(
7096 dfd, d->d_name,
7097 /* offset= */ UINT64_MAX,
7098 /* size= */ CREDENTIAL_ENCRYPTED_SIZE_MAX,
7099 READ_FULL_FILE_UNBASE64|READ_FULL_FILE_FAIL_WHEN_LARGER,
7100 /* bind_name= */ NULL,
7101 (char**) &data.iov_base,
7102 &data.iov_len);
7103 if (r == -ENOENT)
7104 continue;
7105 if (r < 0) {
7106 log_warning_errno(r, "Failed to read credentials file %s/%s, skipping: %m", ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY, d->d_name);
7107 continue;
7108 }
7109
7110 _cleanup_(tpm2_pcrlock_policy_done) Tpm2PCRLockPolicy loaded_policy = {};
7111 r = pcrlock_policy_load_credential(
7112 d->d_name,
7113 &data,
7114 &loaded_policy);
7115 if (r < 0) {
7116 log_warning_errno(r, "Loading of pcrlock policy from credential '%s/%s' failed, skipping.", ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY, d->d_name);
7117 continue;
7118 }
7119
7120 if ((!srk || iovec_memcmp(srk, &loaded_policy.srk_handle) == 0) &&
7121 (!nv || iovec_memcmp(nv, &loaded_policy.nv_handle) == 0)) {
7122 *ret = TAKE_STRUCT(loaded_policy);
7123 return 1;
7124 }
7125 }
7126
7127 log_info("No pcrlock policy found among system credentials.");
7128 *ret = (Tpm2PCRLockPolicy) {};
7129 return 0;
7130 }
7131
7132 int tpm2_load_public_key_file(const char *path, TPM2B_PUBLIC *ret) {
7133 _cleanup_free_ char *device_key_buffer = NULL;
7134 TPM2B_PUBLIC device_key_public = {};
7135 size_t device_key_buffer_size;
7136 TSS2_RC rc;
7137 int r;
7138
7139 assert(path);
7140 assert(ret);
7141
7142 r = dlopen_tpm2();
7143 if (r < 0)
7144 return log_debug_errno(r, "TPM2 support not installed: %m");
7145
7146 r = read_full_file(path, &device_key_buffer, &device_key_buffer_size);
7147 if (r < 0)
7148 return log_error_errno(r, "Failed to read device key from file '%s': %m", path);
7149
7150 size_t offset = 0;
7151 rc = sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal(
7152 (uint8_t*) device_key_buffer,
7153 device_key_buffer_size,
7154 &offset,
7155 &device_key_public);
7156 if (rc != TSS2_RC_SUCCESS)
7157 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
7158 "Could not unmarshal public key from file.");
7159
7160 assert(offset <= device_key_buffer_size);
7161 if (offset != device_key_buffer_size)
7162 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
7163 "Found %zu bytes of trailing garbage in public key file.",
7164 device_key_buffer_size - offset);
7165
7166 *ret = device_key_public;
7167 return 0;
7168 }
7169
7170 int tpm2_hmac_key_from_pin(Tpm2Context *c, const Tpm2Handle *session, const TPM2B_AUTH *pin, Tpm2Handle **ret) {
7171 int r;
7172
7173 assert(c);
7174 assert(pin);
7175 assert(ret);
7176
7177 log_debug("Converting PIN into TPM2 HMAC-SHA256 object.");
7178
7179 /* Load the PIN (which we have stored in the "auth" TPM2B_AUTH) into the TPM as an HMAC key so that
7180 * we can use it in a TPM2_PolicySigned() to write to the nvindex. For that we'll prep a pair of
7181 * TPM2B_PUBLIC and TPM2B_SENSITIVE that defines an HMAC-SHA256 keyed hash function, and initialize
7182 * it based on the provided PIN data. */
7183
7184 TPM2B_PUBLIC auth_hmac_public = {
7185 .publicArea = {
7186 .type = TPM2_ALG_KEYEDHASH,
7187 .nameAlg = TPM2_ALG_SHA256,
7188 .objectAttributes = TPMA_OBJECT_SIGN_ENCRYPT,
7189 .parameters.keyedHashDetail.scheme = {
7190 .scheme = TPM2_ALG_HMAC,
7191 .details.hmac.hashAlg = TPM2_ALG_SHA256,
7192 },
7193 .unique.keyedHash.size = SHA256_DIGEST_SIZE,
7194 },
7195 };
7196
7197 TPM2B_SENSITIVE auth_hmac_private = {
7198 .sensitiveArea = {
7199 .sensitiveType = TPM2_ALG_KEYEDHASH,
7200 .sensitive.bits.size = pin->size,
7201 .seedValue.size = SHA256_DIGEST_SIZE,
7202 },
7203 };
7204
7205 /* Copy in the key data */
7206 memcpy_safe(auth_hmac_private.sensitiveArea.sensitive.bits.buffer, pin->buffer, pin->size);
7207
7208 /* NB: We initialize the seed of the TPMT_SENSITIVE structure to all zeroes, since we want a stable
7209 * "name" of the PIN object */
7210
7211 /* Now calculate the "unique" field for the public area, based on the sensitive data, according to
7212 * the algorithm in the TPM2 spec, part 1, Section 27.5.3.2 */
7213 struct iovec sensitive_data[] = {
7214 IOVEC_MAKE(auth_hmac_private.sensitiveArea.seedValue.buffer, auth_hmac_private.sensitiveArea.seedValue.size),
7215 IOVEC_MAKE(auth_hmac_private.sensitiveArea.sensitive.bits.buffer, auth_hmac_private.sensitiveArea.sensitive.bits.size),
7216 };
7217 r = tpm2_digest_many(
7218 auth_hmac_public.publicArea.nameAlg,
7219 &auth_hmac_public.publicArea.unique.keyedHash,
7220 sensitive_data,
7221 ELEMENTSOF(sensitive_data),
7222 /* extend= */ false);
7223 if (r < 0)
7224 return r;
7225
7226 /* And now load the public/private parts into the TPM and get a handle back */
7227 r = tpm2_load_external(
7228 c,
7229 session,
7230 &auth_hmac_public,
7231 &auth_hmac_private,
7232 ret);
7233 if (r < 0)
7234 return log_error_errno(r, "Failed to load PIN into TPM2: %m");
7235
7236 return 0;
7237 }
7238 #endif
7239
7240 char* tpm2_pcr_mask_to_string(uint32_t mask) {
7241 _cleanup_free_ char *s = NULL;
7242
7243 FOREACH_PCR_IN_MASK(n, mask)
7244 if (strextendf_with_separator(&s, "+", "%d", n) < 0)
7245 return NULL;
7246
7247 if (!s)
7248 return strdup("");
7249
7250 return TAKE_PTR(s);
7251 }
7252
7253 int tpm2_make_pcr_json_array(uint32_t pcr_mask, sd_json_variant **ret) {
7254 _cleanup_(sd_json_variant_unrefp) sd_json_variant *a = NULL;
7255 int r;
7256
7257 assert(ret);
7258
7259 for (size_t i = 0; i < TPM2_PCRS_MAX; i++) {
7260 _cleanup_(sd_json_variant_unrefp) sd_json_variant *e = NULL;
7261
7262 if ((pcr_mask & (UINT32_C(1) << i)) == 0)
7263 continue;
7264
7265 r = sd_json_variant_new_integer(&e, i);
7266 if (r < 0)
7267 return r;
7268
7269 r = sd_json_variant_append_array(&a, e);
7270 if (r < 0)
7271 return r;
7272 }
7273
7274 if (!a)
7275 return sd_json_variant_new_array(ret, NULL, 0);
7276
7277 *ret = TAKE_PTR(a);
7278 return 0;
7279 }
7280
7281 int tpm2_parse_pcr_json_array(sd_json_variant *v, uint32_t *ret) {
7282 sd_json_variant *e;
7283 uint32_t mask = 0;
7284
7285 if (!sd_json_variant_is_array(v))
7286 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR array is not a JSON array.");
7287
7288 JSON_VARIANT_ARRAY_FOREACH(e, v) {
7289 uint64_t u;
7290
7291 if (!sd_json_variant_is_unsigned(e))
7292 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR is not an unsigned integer.");
7293
7294 u = sd_json_variant_unsigned(e);
7295 if (u >= TPM2_PCRS_MAX)
7296 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR number out of range: %" PRIu64, u);
7297
7298 mask |= UINT32_C(1) << u;
7299 }
7300
7301 if (ret)
7302 *ret = mask;
7303
7304 return 0;
7305 }
7306
7307 static int tpm2_make_shard_array(
7308 const struct iovec data[],
7309 size_t n_data,
7310 int (*encode_iovec)(sd_json_variant **, const void*, size_t n), /* pass sd_json_variant_new_base64() or sd_json_variant_new_hex() */
7311 sd_json_variant **ret) {
7312
7313 int r;
7314
7315 /* Turns a series of struct iovec into either an array of base64/hex strings, or a single string
7316 * thereof. Used for generated "tpm2-blob" or "tpm2-policy-hash" fields. */
7317
7318 assert(data);
7319 assert(n_data > 0);
7320 assert(encode_iovec);
7321 assert(ret);
7322
7323 /* Only one item? Then create only one encoded string, for compatibility with older versions which
7324 * didn't support the "sharding" scheme */
7325 if (n_data == 1)
7326 return encode_iovec(ret, data[0].iov_base, data[0].iov_len);
7327
7328 /* Multiple items? Then generate an array of encoded strings */
7329 _cleanup_(sd_json_variant_unrefp) sd_json_variant *j = NULL;
7330
7331 FOREACH_ARRAY(d, data, n_data) {
7332 _cleanup_(sd_json_variant_unrefp) sd_json_variant *item = NULL;
7333
7334 r = encode_iovec(&item, d->iov_base, d->iov_len);
7335 if (r < 0)
7336 return r;
7337
7338 r = sd_json_variant_append_array(&j, item);
7339 if (r < 0)
7340 return r;
7341 }
7342
7343 *ret = TAKE_PTR(j);
7344 return 0;
7345 }
7346
7347 int tpm2_make_luks2_json(
7348 int keyslot,
7349 uint32_t hash_pcr_mask,
7350 uint16_t pcr_bank,
7351 const struct iovec *pubkey,
7352 uint32_t pubkey_pcr_mask,
7353 uint16_t primary_alg,
7354 const struct iovec blobs[],
7355 size_t n_blobs,
7356 const struct iovec policy_hash[],
7357 size_t n_policy_hash,
7358 const struct iovec *salt,
7359 const struct iovec *srk,
7360 const struct iovec *pcrlock_nv,
7361 TPM2Flags flags,
7362 sd_json_variant **ret) {
7363
7364 _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL, *hmj = NULL, *pkmj = NULL;
7365 _cleanup_free_ char *keyslot_as_string = NULL;
7366 int r;
7367
7368 assert(iovec_is_valid(pubkey));
7369 assert(n_blobs >= 1);
7370 assert(n_policy_hash >= 1);
7371
7372 if (asprintf(&keyslot_as_string, "%i", keyslot) < 0)
7373 return -ENOMEM;
7374
7375 r = tpm2_make_pcr_json_array(hash_pcr_mask, &hmj);
7376 if (r < 0)
7377 return r;
7378
7379 if (pubkey_pcr_mask != 0) {
7380 r = tpm2_make_pcr_json_array(pubkey_pcr_mask, &pkmj);
7381 if (r < 0)
7382 return r;
7383 }
7384
7385 _cleanup_(sd_json_variant_unrefp) sd_json_variant *phj = NULL;
7386 r = tpm2_make_shard_array(policy_hash, n_policy_hash, sd_json_variant_new_hex, &phj);
7387 if (r < 0)
7388 return r;
7389
7390 _cleanup_(sd_json_variant_unrefp) sd_json_variant *bj = NULL;
7391 r = tpm2_make_shard_array(blobs, n_blobs, sd_json_variant_new_base64, &bj);
7392 if (r < 0)
7393 return r;
7394
7395 /* Note: We made the mistake of using "-" in the field names, which isn't particular compatible with
7396 * other programming languages. Let's not make things worse though, i.e. future additions to the JSON
7397 * object should use "_" rather than "-" in field names. */
7398
7399 r = sd_json_buildo(
7400 &v,
7401 SD_JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-tpm2")),
7402 SD_JSON_BUILD_PAIR("keyslots", SD_JSON_BUILD_ARRAY(SD_JSON_BUILD_STRING(keyslot_as_string))),
7403 SD_JSON_BUILD_PAIR("tpm2-blob", SD_JSON_BUILD_VARIANT(bj)),
7404 SD_JSON_BUILD_PAIR("tpm2-pcrs", SD_JSON_BUILD_VARIANT(hmj)),
7405 SD_JSON_BUILD_PAIR_CONDITION(pcr_bank != 0 && tpm2_hash_alg_to_string(pcr_bank), "tpm2-pcr-bank", SD_JSON_BUILD_STRING(tpm2_hash_alg_to_string(pcr_bank))),
7406 SD_JSON_BUILD_PAIR_CONDITION(primary_alg != 0 && tpm2_asym_alg_to_string(primary_alg), "tpm2-primary-alg", SD_JSON_BUILD_STRING(tpm2_asym_alg_to_string(primary_alg))),
7407 SD_JSON_BUILD_PAIR("tpm2-policy-hash", SD_JSON_BUILD_VARIANT(phj)),
7408 SD_JSON_BUILD_PAIR_CONDITION(FLAGS_SET(flags, TPM2_FLAGS_USE_PIN), "tpm2-pin", SD_JSON_BUILD_BOOLEAN(true)),
7409 SD_JSON_BUILD_PAIR_CONDITION(FLAGS_SET(flags, TPM2_FLAGS_USE_PCRLOCK), "tpm2_pcrlock", SD_JSON_BUILD_BOOLEAN(true)),
7410 SD_JSON_BUILD_PAIR_CONDITION(pubkey_pcr_mask != 0, "tpm2_pubkey_pcrs", SD_JSON_BUILD_VARIANT(pkmj)),
7411 SD_JSON_BUILD_PAIR_CONDITION(iovec_is_set(pubkey), "tpm2_pubkey", JSON_BUILD_IOVEC_BASE64(pubkey)),
7412 SD_JSON_BUILD_PAIR_CONDITION(iovec_is_set(salt), "tpm2_salt", JSON_BUILD_IOVEC_BASE64(salt)),
7413 SD_JSON_BUILD_PAIR_CONDITION(iovec_is_set(srk), "tpm2_srk", JSON_BUILD_IOVEC_BASE64(srk)),
7414 SD_JSON_BUILD_PAIR_CONDITION(iovec_is_set(pcrlock_nv), "tpm2_pcrlock_nv", JSON_BUILD_IOVEC_BASE64(pcrlock_nv)));
7415 if (r < 0)
7416 return r;
7417
7418 if (ret)
7419 *ret = TAKE_PTR(v);
7420
7421 return keyslot;
7422 }
7423
7424 static int tpm2_parse_shard_array(
7425 sd_json_variant *v,
7426 const char *name,
7427 int (*decode_iovec)(sd_json_variant*, struct iovec *ret), /* pass json_variant_unbase64_iovec() or json_variant_unhex_iovec() */
7428 struct iovec **ret_data,
7429 size_t *ret_n_data) {
7430
7431 int r;
7432
7433 assert(v);
7434 assert(name);
7435 assert(decode_iovec);
7436 assert(ret_data);
7437 assert(ret_n_data);
7438
7439 /* Parses the "tpm2-blob" or "tpm2-policy-hash" fields of our LUKS JSON serialization. This can
7440 * either be an array of base64/hex strings, or a single such string. The former to allow for sharded
7441 * keys. The latter mostly for compatibility with older versions where we didn't support sharded
7442 * keys. */
7443
7444 struct iovec *data = NULL;
7445 size_t n_data = 0;
7446 CLEANUP_ARRAY(data, n_data, iovec_array_free);
7447
7448 if (sd_json_variant_is_array(v)) {
7449 if (sd_json_variant_elements(v) == 0)
7450 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data contains empty '%s' array.", name);
7451
7452 data = new0(struct iovec, sd_json_variant_elements(v));
7453 if (!data)
7454 return log_oom_debug();
7455
7456 sd_json_variant *i;
7457 JSON_VARIANT_ARRAY_FOREACH(i, v) {
7458 r = decode_iovec(i, data + n_data);
7459 if (r < 0)
7460 return log_debug_errno(r, "Invalid data in '%s' field.", name);
7461
7462 n_data++;
7463 }
7464 } else {
7465 data = new0(struct iovec, 1);
7466 if (!data)
7467 return log_oom_debug();
7468
7469 r = decode_iovec(v, data + 0);
7470 if (r < 0)
7471 return log_debug_errno(r, "Invalid data in '%s' field.", name);
7472
7473 n_data = 1;
7474 }
7475
7476 *ret_data = TAKE_PTR(data);
7477 *ret_n_data = n_data;
7478 return 0;
7479 }
7480
7481 int tpm2_parse_luks2_json(
7482 sd_json_variant *v,
7483 int *ret_keyslot,
7484 uint32_t *ret_hash_pcr_mask,
7485 uint16_t *ret_pcr_bank,
7486 struct iovec *ret_pubkey,
7487 uint32_t *ret_pubkey_pcr_mask,
7488 uint16_t *ret_primary_alg,
7489 struct iovec **ret_blobs,
7490 size_t *ret_n_blobs,
7491 struct iovec **ret_policy_hash,
7492 size_t *ret_n_policy_hash,
7493 struct iovec *ret_salt,
7494 struct iovec *ret_srk,
7495 struct iovec *ret_pcrlock_nv,
7496 TPM2Flags *ret_flags) {
7497
7498 _cleanup_(iovec_done) struct iovec pubkey = {}, salt = {}, srk = {}, pcrlock_nv = {};
7499 uint32_t hash_pcr_mask = 0, pubkey_pcr_mask = 0;
7500 uint16_t primary_alg = TPM2_ALG_ECC; /* ECC was the only supported algorithm in systemd < 250, use that as implied default, for compatibility */
7501 uint16_t pcr_bank = UINT16_MAX; /* default: pick automatically */
7502 int r, keyslot = -1;
7503 TPM2Flags flags = 0;
7504 sd_json_variant *w;
7505
7506 assert(v);
7507
7508 if (ret_keyslot) {
7509 keyslot = cryptsetup_get_keyslot_from_token(v);
7510 if (keyslot < 0) {
7511 /* Return a recognizable error when parsing this field, so that callers can handle parsing
7512 * errors of the keyslots field gracefully, since it's not 'owned' by us, but by the LUKS2
7513 * spec */
7514 log_debug_errno(keyslot, "Failed to extract keyslot index from TPM2 JSON data token, skipping: %m");
7515 return -EUCLEAN;
7516 }
7517 }
7518
7519 w = sd_json_variant_by_key(v, "tpm2-pcrs");
7520 if (!w)
7521 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-pcrs' field.");
7522
7523 r = tpm2_parse_pcr_json_array(w, &hash_pcr_mask);
7524 if (r < 0)
7525 return log_debug_errno(r, "Failed to parse TPM2 PCR mask: %m");
7526
7527 /* The bank field is optional, since it was added in systemd 250 only. Before the bank was hardcoded
7528 * to SHA256. */
7529 w = sd_json_variant_by_key(v, "tpm2-pcr-bank");
7530 if (w) {
7531 /* The PCR bank field is optional */
7532
7533 if (!sd_json_variant_is_string(w))
7534 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR bank is not a string.");
7535
7536 r = tpm2_hash_alg_from_string(sd_json_variant_string(w));
7537 if (r < 0)
7538 return log_debug_errno(r, "TPM2 PCR bank invalid or not supported: %s", sd_json_variant_string(w));
7539
7540 pcr_bank = r;
7541 }
7542
7543 /* The primary key algorithm field is optional, since it was also added in systemd 250 only. Before
7544 * the algorithm was hardcoded to ECC. */
7545 w = sd_json_variant_by_key(v, "tpm2-primary-alg");
7546 if (w) {
7547 /* The primary key algorithm is optional */
7548
7549 if (!sd_json_variant_is_string(w))
7550 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 primary key algorithm is not a string.");
7551
7552 r = tpm2_asym_alg_from_string(sd_json_variant_string(w));
7553 if (r < 0)
7554 return log_debug_errno(r, "TPM2 asymmetric algorithm invalid or not supported: %s", sd_json_variant_string(w));
7555
7556 primary_alg = r;
7557 }
7558
7559 w = sd_json_variant_by_key(v, "tpm2-blob");
7560 if (!w)
7561 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-blob' field.");
7562
7563 struct iovec *blobs = NULL;
7564 size_t n_blobs = 0;
7565 CLEANUP_ARRAY(blobs, n_blobs, iovec_array_free);
7566
7567 r = tpm2_parse_shard_array(w, "tpm2-blob", json_variant_unbase64_iovec, &blobs, &n_blobs);
7568 if (r < 0)
7569 return r;
7570
7571 w = sd_json_variant_by_key(v, "tpm2-policy-hash");
7572 if (!w)
7573 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-policy-hash' field.");
7574
7575 struct iovec *policy_hash = NULL;
7576 size_t n_policy_hash = 0;
7577 CLEANUP_ARRAY(policy_hash, n_policy_hash, iovec_array_free);
7578
7579 r = tpm2_parse_shard_array(w, "tpm2-policy-hash", json_variant_unhex_iovec, &policy_hash, &n_policy_hash);
7580 if (r < 0)
7581 return r;
7582
7583 w = sd_json_variant_by_key(v, "tpm2-pin");
7584 if (w) {
7585 if (!sd_json_variant_is_boolean(w))
7586 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PIN policy is not a boolean.");
7587
7588 SET_FLAG(flags, TPM2_FLAGS_USE_PIN, sd_json_variant_boolean(w));
7589 }
7590
7591 w = sd_json_variant_by_key(v, "tpm2_pcrlock");
7592 if (w) {
7593 if (!sd_json_variant_is_boolean(w))
7594 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 pclock policy is not a boolean.");
7595
7596 SET_FLAG(flags, TPM2_FLAGS_USE_PCRLOCK, sd_json_variant_boolean(w));
7597 }
7598
7599 w = sd_json_variant_by_key(v, "tpm2_salt");
7600 if (w) {
7601 r = json_variant_unbase64_iovec(w, &salt);
7602 if (r < 0)
7603 return log_debug_errno(r, "Invalid base64 data in 'tpm2_salt' field.");
7604 }
7605
7606 w = sd_json_variant_by_key(v, "tpm2_pubkey_pcrs");
7607 if (w) {
7608 r = tpm2_parse_pcr_json_array(w, &pubkey_pcr_mask);
7609 if (r < 0)
7610 return r;
7611 }
7612
7613 w = sd_json_variant_by_key(v, "tpm2_pubkey");
7614 if (w) {
7615 r = json_variant_unbase64_iovec(w, &pubkey);
7616 if (r < 0)
7617 return log_debug_errno(r, "Failed to decode PCR public key.");
7618 } else if (pubkey_pcr_mask != 0)
7619 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Public key PCR mask set, but not public key included in JSON data, refusing.");
7620
7621 w = sd_json_variant_by_key(v, "tpm2_srk");
7622 if (w) {
7623 r = json_variant_unbase64_iovec(w, &srk);
7624 if (r < 0)
7625 return log_debug_errno(r, "Invalid base64 data in 'tpm2_srk' field.");
7626 }
7627
7628 w = sd_json_variant_by_key(v, "tpm2_pcrlock_nv");
7629 if (w) {
7630 r = json_variant_unbase64_iovec(w, &pcrlock_nv);
7631 if (r < 0)
7632 return log_debug_errno(r, "Invalid base64 data in 'tpm2_pcrlock_nv' field.");
7633 }
7634
7635 if (ret_keyslot)
7636 *ret_keyslot = keyslot;
7637 if (ret_hash_pcr_mask)
7638 *ret_hash_pcr_mask = hash_pcr_mask;
7639 if (ret_pcr_bank)
7640 *ret_pcr_bank = pcr_bank;
7641 if (ret_pubkey)
7642 *ret_pubkey = TAKE_STRUCT(pubkey);
7643 if (ret_pubkey_pcr_mask)
7644 *ret_pubkey_pcr_mask = pubkey_pcr_mask;
7645 if (ret_primary_alg)
7646 *ret_primary_alg = primary_alg;
7647 if (ret_blobs)
7648 *ret_blobs = TAKE_PTR(blobs);
7649 if (ret_n_blobs)
7650 *ret_n_blobs = n_blobs;
7651 if (ret_policy_hash)
7652 *ret_policy_hash = TAKE_PTR(policy_hash);
7653 if (ret_n_policy_hash)
7654 *ret_n_policy_hash = n_policy_hash;
7655 if (ret_salt)
7656 *ret_salt = TAKE_STRUCT(salt);
7657 if (ret_srk)
7658 *ret_srk = TAKE_STRUCT(srk);
7659 if (ret_pcrlock_nv)
7660 *ret_pcrlock_nv = TAKE_STRUCT(pcrlock_nv);
7661 if (ret_flags)
7662 *ret_flags = flags;
7663 return 0;
7664 }
7665
7666 int tpm2_hash_alg_to_size(uint16_t alg) {
7667 switch (alg) {
7668 case TPM2_ALG_SHA1:
7669 return 20;
7670 case TPM2_ALG_SHA256:
7671 return 32;
7672 case TPM2_ALG_SHA384:
7673 return 48;
7674 case TPM2_ALG_SHA512:
7675 return 64;
7676 default:
7677 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown hash algorithm id 0x%" PRIx16, alg);
7678 }
7679 }
7680
7681 const char* tpm2_hash_alg_to_string(uint16_t alg) {
7682 switch (alg) {
7683 case TPM2_ALG_SHA1:
7684 return "sha1";
7685 case TPM2_ALG_SHA256:
7686 return "sha256";
7687 case TPM2_ALG_SHA384:
7688 return "sha384";
7689 case TPM2_ALG_SHA512:
7690 return "sha512";
7691 default:
7692 log_debug("Unknown hash algorithm id 0x%" PRIx16, alg);
7693 return NULL;
7694 }
7695 }
7696
7697 int tpm2_hash_alg_from_string(const char *alg) {
7698 if (strcaseeq_ptr(alg, "sha1"))
7699 return TPM2_ALG_SHA1;
7700 if (strcaseeq_ptr(alg, "sha256"))
7701 return TPM2_ALG_SHA256;
7702 if (strcaseeq_ptr(alg, "sha384"))
7703 return TPM2_ALG_SHA384;
7704 if (strcaseeq_ptr(alg, "sha512"))
7705 return TPM2_ALG_SHA512;
7706 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown hash algorithm name '%s'", alg);
7707 }
7708
7709 const char* tpm2_asym_alg_to_string(uint16_t alg) {
7710 switch (alg) {
7711 case TPM2_ALG_ECC:
7712 return "ecc";
7713 case TPM2_ALG_RSA:
7714 return "rsa";
7715 default:
7716 log_debug("Unknown asymmetric algorithm id 0x%" PRIx16, alg);
7717 return NULL;
7718 }
7719 }
7720
7721 int tpm2_asym_alg_from_string(const char *alg) {
7722 if (strcaseeq_ptr(alg, "ecc"))
7723 return TPM2_ALG_ECC;
7724 if (strcaseeq_ptr(alg, "rsa"))
7725 return TPM2_ALG_RSA;
7726 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown asymmetric algorithm name '%s'", alg);
7727 }
7728
7729 const char* tpm2_sym_alg_to_string(uint16_t alg) {
7730 switch (alg) {
7731 #if HAVE_TPM2
7732 case TPM2_ALG_AES:
7733 return "aes";
7734 #endif
7735 default:
7736 log_debug("Unknown symmetric algorithm id 0x%" PRIx16, alg);
7737 return NULL;
7738 }
7739 }
7740
7741 const char* tpm2_sym_mode_to_string(uint16_t mode) {
7742 switch (mode) {
7743 #if HAVE_TPM2
7744 case TPM2_ALG_CTR:
7745 return "ctr";
7746 case TPM2_ALG_OFB:
7747 return "ofb";
7748 case TPM2_ALG_CBC:
7749 return "cbc";
7750 case TPM2_ALG_CFB:
7751 return "cfb";
7752 case TPM2_ALG_ECB:
7753 return "ecb";
7754 #endif
7755 default:
7756 log_debug("Unknown symmetric mode id 0x%" PRIx16, mode);
7757 return NULL;
7758 }
7759 }
7760
7761 int tpm2_sym_mode_from_string(const char *mode) {
7762 #if HAVE_TPM2
7763 if (strcaseeq_ptr(mode, "ctr"))
7764 return TPM2_ALG_CTR;
7765 if (strcaseeq_ptr(mode, "ofb"))
7766 return TPM2_ALG_OFB;
7767 if (strcaseeq_ptr(mode, "cbc"))
7768 return TPM2_ALG_CBC;
7769 if (strcaseeq_ptr(mode, "cfb"))
7770 return TPM2_ALG_CFB;
7771 if (strcaseeq_ptr(mode, "ecb"))
7772 return TPM2_ALG_ECB;
7773 #endif
7774 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown symmetric mode name '%s'", mode);
7775 }
7776
7777 Tpm2Support tpm2_support_full(Tpm2Support mask) {
7778 Tpm2Support support = TPM2_SUPPORT_NONE;
7779 int r;
7780
7781 if (((mask & (TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_DRIVER)) != 0) && detect_container() <= 0) {
7782 /* Check if there's a /dev/tpmrm* device via sysfs. If we run in a container we likely just
7783 * got the host sysfs mounted. Since devices are generally not virtualized for containers,
7784 * let's assume containers never have a TPM, at least for now. */
7785
7786 r = dir_is_empty("/sys/class/tpmrm", /* ignore_hidden_or_backup= */ false);
7787 if (r < 0) {
7788 if (r != -ENOENT)
7789 log_debug_errno(r, "Unable to test whether /sys/class/tpmrm/ exists and is populated, assuming it is not: %m");
7790 } else if (r == 0) /* populated! */
7791 support |= TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_DRIVER;
7792 else
7793 /* If the directory exists but is empty, we know the subsystem is enabled but no
7794 * driver has been loaded yet. */
7795 support |= TPM2_SUPPORT_SUBSYSTEM;
7796 }
7797
7798 if (FLAGS_SET(mask, TPM2_SUPPORT_FIRMWARE) && efi_has_tpm2())
7799 support |= TPM2_SUPPORT_FIRMWARE;
7800
7801 #if HAVE_TPM2
7802 support |= TPM2_SUPPORT_SYSTEM;
7803
7804 if ((mask & (TPM2_SUPPORT_LIBRARIES|TPM2_SUPPORT_LIBTSS2_ALL)) != 0) {
7805 r = dlopen_tpm2_esys();
7806 if (r >= 0)
7807 support |= TPM2_SUPPORT_LIBTSS2_ESYS;
7808
7809 r = dlopen_tpm2_rc();
7810 if (r >= 0)
7811 support |= TPM2_SUPPORT_LIBTSS2_RC;
7812
7813 r = dlopen_tpm2_mu();
7814 if (r >= 0)
7815 support |= TPM2_SUPPORT_LIBTSS2_MU;
7816
7817 if (FLAGS_SET(support, TPM2_SUPPORT_LIBTSS2_ALL))
7818 support |= TPM2_SUPPORT_LIBRARIES;
7819 }
7820 #endif
7821
7822 return support & mask;
7823 }
7824
7825 static void print_field(const char *prefix, const char *s, bool supported) {
7826 printf("%s%s%s%s%s\n", strempty(prefix), supported ? ansi_green() : ansi_red(), plus_minus(supported), s, ansi_normal());
7827 }
7828
7829 int verb_has_tpm2_generic(bool quiet) {
7830 Tpm2Support s;
7831
7832 s = tpm2_support();
7833
7834 if (!quiet) {
7835 if (s == TPM2_SUPPORT_FULL)
7836 printf("%syes%s\n", ansi_green(), ansi_normal());
7837 else if (s == TPM2_SUPPORT_NONE)
7838 printf("%sno%s\n", ansi_red(), ansi_normal());
7839 else
7840 printf("%spartial%s\n", ansi_yellow(), ansi_normal());
7841
7842 print_field(NULL, "firmware", FLAGS_SET(s, TPM2_SUPPORT_FIRMWARE));
7843 print_field(NULL, "driver", FLAGS_SET(s, TPM2_SUPPORT_DRIVER));
7844 print_field(NULL, "system", FLAGS_SET(s, TPM2_SUPPORT_SYSTEM));
7845 print_field(NULL, "subsystem", FLAGS_SET(s, TPM2_SUPPORT_SUBSYSTEM));
7846 print_field(NULL, "libraries", FLAGS_SET(s, TPM2_SUPPORT_LIBRARIES));
7847 print_field(" ", "libtss2-esys.so.0", FLAGS_SET(s, TPM2_SUPPORT_LIBTSS2_ESYS));
7848 print_field(" ", "libtss2-rc.so.0", FLAGS_SET(s, TPM2_SUPPORT_LIBTSS2_RC));
7849 print_field(" ", "libtss2-mu.so.0", FLAGS_SET(s, TPM2_SUPPORT_LIBTSS2_MU));
7850 }
7851
7852 assert_cc(TPM2_SUPPORT_API <= 255); /* make sure this is safe to use as process exit status */
7853
7854 /* Return inverted bit flags. So that TPM2_SUPPORT_FULL becomes EXIT_SUCCESS and the other values
7855 * become some reasonable values 1…7. i.e. the flags we return here tell what is missing rather than
7856 * what is there, acknowledging the fact that for process exit statuses it is customary to return
7857 * zero (EXIT_FAILURE) when all is good, instead of all being bad. */
7858 return ~s & TPM2_SUPPORT_API;
7859 }
7860
7861 #if HAVE_TPM2
7862 static void tpm2_pcr_values_apply_default_hash_alg(Tpm2PCRValue *pcr_values, size_t n_pcr_values) {
7863 TPMI_ALG_HASH default_hash = 0;
7864 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
7865 if (v->hash != 0) {
7866 default_hash = v->hash;
7867 break;
7868 }
7869
7870 if (default_hash != 0)
7871 FOREACH_ARRAY(v, pcr_values, n_pcr_values)
7872 if (v->hash == 0)
7873 v->hash = default_hash;
7874 }
7875 #endif
7876
7877 /* The following tpm2_parse_pcr_argument*() functions all log errors, to match the behavior of system-wide
7878 * parse_*_argument() functions. */
7879
7880 /* Parse the PCR selection/value arg(s) and return a corresponding array of Tpm2PCRValue objects.
7881 *
7882 * The format is the same as tpm2_pcr_values_from_string(). The first provided entry with a hash algorithm
7883 * set will be used as the 'default' hash algorithm. All entries with an unset hash algorithm will be updated
7884 * with the 'default' hash algorithm. The resulting array will be sorted and checked for validity.
7885 *
7886 * This will replace *ret_pcr_values with the new array of pcr values; to append to an existing array, use
7887 * tpm2_parse_pcr_argument_append(). */
7888 int tpm2_parse_pcr_argument(const char *arg, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values) {
7889 #if HAVE_TPM2
7890 int r;
7891
7892 assert(arg);
7893 assert(ret_pcr_values);
7894 assert(ret_n_pcr_values);
7895
7896 _cleanup_free_ Tpm2PCRValue *pcr_values = NULL;
7897 size_t n_pcr_values = 0;
7898 r = tpm2_pcr_values_from_string(arg, &pcr_values, &n_pcr_values);
7899 if (r < 0)
7900 return log_error_errno(r, "Could not parse PCR values from '%s': %m", arg);
7901
7902 tpm2_pcr_values_apply_default_hash_alg(pcr_values, n_pcr_values);
7903
7904 tpm2_sort_pcr_values(pcr_values, n_pcr_values);
7905
7906 if (!tpm2_pcr_values_valid(pcr_values, n_pcr_values))
7907 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Parsed PCR values are not valid.");
7908
7909 *ret_pcr_values = TAKE_PTR(pcr_values);
7910 *ret_n_pcr_values = n_pcr_values;
7911
7912 return 0;
7913 #else
7914 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support is disabled.");
7915 #endif
7916 }
7917
7918 /* Same as tpm2_parse_pcr_argument(), but the pcr values array is appended to. If the provided pcr values
7919 * array is not NULL, it must point to an allocated pcr values array and the provided number of pcr values
7920 * must be correct.
7921 *
7922 * Note that 'arg' is parsed into a new array of pcr values independently of any previous pcr values,
7923 * including application of the default hash algorithm. Then the two arrays are combined, the default hash
7924 * algorithm check applied again (in case either the previous or current array had no default hash
7925 * algorithm), and then the resulting array is sorted and rechecked for validity. */
7926 int tpm2_parse_pcr_argument_append(const char *arg, Tpm2PCRValue **pcr_values, size_t *n_pcr_values) {
7927 #if HAVE_TPM2
7928 int r;
7929
7930 assert(arg);
7931 assert(pcr_values);
7932 assert(n_pcr_values);
7933
7934 _cleanup_free_ Tpm2PCRValue *more_pcr_values = NULL;
7935 size_t n_more_pcr_values;
7936 r = tpm2_parse_pcr_argument(arg, &more_pcr_values, &n_more_pcr_values);
7937 if (r < 0)
7938 return r;
7939
7940 /* If we got previous values, append them. */
7941 if (*pcr_values && !GREEDY_REALLOC_APPEND(more_pcr_values, n_more_pcr_values, *pcr_values, *n_pcr_values))
7942 return log_oom();
7943
7944 tpm2_pcr_values_apply_default_hash_alg(more_pcr_values, n_more_pcr_values);
7945
7946 tpm2_sort_pcr_values(more_pcr_values, n_more_pcr_values);
7947
7948 if (!tpm2_pcr_values_valid(more_pcr_values, n_more_pcr_values))
7949 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Parsed PCR values are not valid.");
7950
7951 SWAP_TWO(*pcr_values, more_pcr_values);
7952 *n_pcr_values = n_more_pcr_values;
7953
7954 return 0;
7955 #else
7956 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support is disabled.");
7957 #endif
7958 }
7959
7960 int tpm2_parse_pcr_argument_to_mask(const char *arg, uint32_t *mask) {
7961 #if HAVE_TPM2
7962 int r;
7963
7964 /* Same as tpm2_parse_pcr_argument() but converts the pcr values to a pcr mask. If a hash algorithm or
7965 * hash value is specified an error is generated (after all we only return the mask here, nothing
7966 * else). This retains the previous behavior of tpm2_parse_pcr_argument() of clearing the mask if
7967 * 'arg' is empty, replacing the mask if it is set to UINT32_MAX, and or-ing the mask otherwise. */
7968
7969 assert(arg);
7970 assert(mask);
7971
7972 _cleanup_free_ Tpm2PCRValue *pcr_values = NULL;
7973 size_t n_pcr_values;
7974 r = tpm2_parse_pcr_argument(arg, &pcr_values, &n_pcr_values);
7975 if (r < 0)
7976 return r;
7977
7978 if (n_pcr_values == 0) {
7979 /* This retains the previous behavior of clearing the mask if the arg is empty */
7980 *mask = 0;
7981 return 0;
7982 }
7983
7984 FOREACH_ARRAY(v, pcr_values, n_pcr_values) {
7985 if (v->hash != 0)
7986 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
7987 "Not expecting hash algorithm specification in PCR mask value, refusing: %s", arg);
7988 if (v->value.size != 0)
7989 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
7990 "Not expecting hash value specification in PCR mask value, refusing: %s", arg);
7991 }
7992
7993 uint32_t new_mask;
7994 r = tpm2_pcr_values_to_mask(pcr_values, n_pcr_values, /* hash= */ 0, &new_mask);
7995 if (r < 0)
7996 return log_error_errno(r, "Could not get pcr values mask: %m");
7997
7998 if (*mask == UINT32_MAX)
7999 *mask = new_mask;
8000 else
8001 *mask |= new_mask;
8002
8003 return 0;
8004 #else
8005 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support is disabled.");
8006 #endif
8007 }
8008
8009 int tpm2_load_pcr_signature(const char *path, sd_json_variant **ret) {
8010 _cleanup_strv_free_ char **search = NULL;
8011 _cleanup_free_ char *discovered_path = NULL;
8012 _cleanup_fclose_ FILE *f = NULL;
8013 int r;
8014
8015 /* Tries to load a JSON PCR signature file. Takes an absolute path, a simple file name or NULL. In
8016 * the latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
8017
8018 search = strv_new(CONF_PATHS("systemd"));
8019 if (!search)
8020 return log_oom_debug();
8021
8022 if (!path) {
8023 /* If no path is specified, then look for "tpm2-pcr-signature.json" automatically. Also, in
8024 * this case include /.extra/ in the search path, but only in this case, and if we run in the
8025 * initrd. We don't want to be too eager here, after all /.extra/ is untrusted territory. */
8026
8027 path = "tpm2-pcr-signature.json";
8028
8029 if (in_initrd())
8030 if (strv_extend(&search, "/.extra") < 0)
8031 return log_oom_debug();
8032 }
8033
8034 r = search_and_fopen(path, "re", NULL, (const char**) search, &f, &discovered_path);
8035 if (r < 0)
8036 return log_debug_errno(r, "Failed to find TPM PCR signature file '%s': %m", path);
8037
8038 r = sd_json_parse_file(f, discovered_path, 0, ret, NULL, NULL);
8039 if (r < 0)
8040 return log_debug_errno(r, "Failed to parse TPM PCR signature JSON object '%s': %m", discovered_path);
8041
8042 return 0;
8043 }
8044
8045 int tpm2_load_pcr_public_key(const char *path, void **ret_pubkey, size_t *ret_pubkey_size) {
8046 _cleanup_free_ char *discovered_path = NULL;
8047 _cleanup_fclose_ FILE *f = NULL;
8048 int r;
8049
8050 /* Tries to load a PCR public key file. Takes an absolute path, a simple file name or NULL. In the
8051 * latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
8052
8053 if (!path)
8054 path = "tpm2-pcr-public-key.pem";
8055
8056 r = search_and_fopen(path, "re", NULL, (const char**) CONF_PATHS_STRV("systemd"), &f, &discovered_path);
8057 if (r < 0)
8058 return log_debug_errno(r, "Failed to find TPM PCR public key file '%s': %m", path);
8059
8060 r = read_full_stream(f, (char**) ret_pubkey, ret_pubkey_size);
8061 if (r < 0)
8062 return log_debug_errno(r, "Failed to load TPM PCR public key PEM file '%s': %m", discovered_path);
8063
8064 return 0;
8065 }
8066
8067 #define PBKDF2_HMAC_SHA256_ITERATIONS 10000
8068
8069 /*
8070 * Implements PBKDF2 HMAC SHA256 for a derived keylen of 32
8071 * bytes and for PBKDF2_HMAC_SHA256_ITERATIONS count.
8072 * I found the wikipedia entry relevant and it contains links to
8073 * relevant RFCs:
8074 * - https://en.wikipedia.org/wiki/PBKDF2
8075 * - https://www.rfc-editor.org/rfc/rfc2898#section-5.2
8076 */
8077 int tpm2_util_pbkdf2_hmac_sha256(const void *pass,
8078 size_t passlen,
8079 const void *salt,
8080 size_t saltlen,
8081 uint8_t ret_key[static SHA256_DIGEST_SIZE]) {
8082
8083 _cleanup_(erase_and_freep) uint8_t *buffer = NULL;
8084 uint8_t u[SHA256_DIGEST_SIZE];
8085
8086 /* To keep this simple, since derived KeyLen (dkLen in docs)
8087 * Is the same as the hash output, we don't need multiple
8088 * blocks. Part of the algorithm is to add the block count
8089 * in, but this can be hardcoded to 1.
8090 */
8091 static const uint8_t block_cnt[] = { 0, 0, 0, 1 };
8092
8093 assert(salt);
8094 assert(saltlen > 0);
8095 assert(saltlen <= (SIZE_MAX - sizeof(block_cnt)));
8096 assert(passlen > 0);
8097
8098 /*
8099 * Build a buffer of salt + block_cnt and hmac_sha256 it we
8100 * do this as we don't have a context builder for HMAC_SHA256.
8101 */
8102 buffer = malloc(saltlen + sizeof(block_cnt));
8103 if (!buffer)
8104 return -ENOMEM;
8105
8106 memcpy(buffer, salt, saltlen);
8107 memcpy(&buffer[saltlen], block_cnt, sizeof(block_cnt));
8108
8109 hmac_sha256(pass, passlen, buffer, saltlen + sizeof(block_cnt), u);
8110
8111 /* dk needs to be an unmodified u as u gets modified in the loop */
8112 memcpy(ret_key, u, SHA256_DIGEST_SIZE);
8113 uint8_t *dk = ret_key;
8114
8115 for (size_t i = 1; i < PBKDF2_HMAC_SHA256_ITERATIONS; i++) {
8116 hmac_sha256(pass, passlen, u, sizeof(u), u);
8117
8118 for (size_t j=0; j < sizeof(u); j++)
8119 dk[j] ^= u[j];
8120 }
8121
8122 return 0;
8123 }
8124
8125 static const char* const tpm2_pcr_index_table[_TPM2_PCR_INDEX_MAX_DEFINED] = {
8126 [TPM2_PCR_PLATFORM_CODE] = "platform-code",
8127 [TPM2_PCR_PLATFORM_CONFIG] = "platform-config",
8128 [TPM2_PCR_EXTERNAL_CODE] = "external-code",
8129 [TPM2_PCR_EXTERNAL_CONFIG] = "external-config",
8130 [TPM2_PCR_BOOT_LOADER_CODE] = "boot-loader-code",
8131 [TPM2_PCR_BOOT_LOADER_CONFIG] = "boot-loader-config",
8132 [TPM2_PCR_HOST_PLATFORM] = "host-platform",
8133 [TPM2_PCR_SECURE_BOOT_POLICY] = "secure-boot-policy",
8134 [TPM2_PCR_KERNEL_INITRD] = "kernel-initrd",
8135 [TPM2_PCR_IMA] = "ima",
8136 [TPM2_PCR_KERNEL_BOOT] = "kernel-boot",
8137 [TPM2_PCR_KERNEL_CONFIG] = "kernel-config",
8138 [TPM2_PCR_SYSEXTS] = "sysexts",
8139 [TPM2_PCR_SHIM_POLICY] = "shim-policy",
8140 [TPM2_PCR_SYSTEM_IDENTITY] = "system-identity",
8141 [TPM2_PCR_DEBUG] = "debug",
8142 [TPM2_PCR_APPLICATION_SUPPORT] = "application-support",
8143 };
8144
8145 DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_FALLBACK(tpm2_pcr_index, int, TPM2_PCRS_MAX - 1);
8146 DEFINE_STRING_TABLE_LOOKUP_TO_STRING(tpm2_pcr_index, int);