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