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