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