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