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