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