]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/tpm2-util.c
tpm2: rename struct tpm2_context to Tpm2Context
[thirdparty/systemd.git] / src / shared / tpm2-util.c
CommitLineData
5e521624
LP
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
5e521624 3#include "alloc-util.h"
28db6fbf 4#include "constants.h"
fdf6c27c 5#include "cryptsetup-util.h"
5e521624
LP
6#include "dirent-util.h"
7#include "dlfcn-util.h"
fdf6c27c
LP
8#include "efi-api.h"
9#include "extract-word.h"
5e521624 10#include "fd-util.h"
6a0779cb 11#include "fileio.h"
5e521624
LP
12#include "format-table.h"
13#include "fs-util.h"
14#include "hexdecoct.h"
aae6eb96 15#include "hmac.h"
5e521624 16#include "memory-util.h"
d9b5841d 17#include "openssl-util.h"
fdf6c27c 18#include "parse-util.h"
5e521624 19#include "random-util.h"
2f5a892a 20#include "sha256.h"
fdf6c27c 21#include "stat-util.h"
5e521624 22#include "time-util.h"
fdf6c27c
LP
23#include "tpm2-util.h"
24#include "virt.h"
5e521624 25
fdf6c27c 26#if HAVE_TPM2
5e521624
LP
27static void *libtss2_esys_dl = NULL;
28static void *libtss2_rc_dl = NULL;
29static void *libtss2_mu_dl = NULL;
30
31TSS2_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;
32TSS2_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;
33void (*sym_Esys_Finalize)(ESYS_CONTEXT **context) = NULL;
34TSS2_RC (*sym_Esys_FlushContext)(ESYS_CONTEXT *esysContext, ESYS_TR flushHandle) = NULL;
35void (*sym_Esys_Free)(void *ptr) = NULL;
07697bfe 36TSS2_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);
5e521624
LP
37TSS2_RC (*sym_Esys_GetRandom)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, UINT16 bytesRequested, TPM2B_DIGEST **randomBytes) = NULL;
38TSS2_RC (*sym_Esys_Initialize)(ESYS_CONTEXT **esys_context, TSS2_TCTI_CONTEXT *tcti, TSS2_ABI_VERSION *abiVersion) = NULL;
39TSS2_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;
0d756413 40TSS2_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);
1421943a 41TSS2_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);
321a9d9e 42TSS2_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);
0d756413 43TSS2_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);
2f5a892a 44TSS2_RC (*sym_Esys_PolicyAuthValue)(ESYS_CONTEXT *esysContext, ESYS_TR policySession, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3) = NULL;
5e521624
LP
45TSS2_RC (*sym_Esys_PolicyGetDigest)(ESYS_CONTEXT *esysContext, ESYS_TR policySession, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, TPM2B_DIGEST **policyDigest) = NULL;
46TSS2_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;
47TSS2_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;
48TSS2_RC (*sym_Esys_Startup)(ESYS_CONTEXT *esysContext, TPM2_SU startupType) = NULL;
da29de23 49TSS2_RC (*sym_Esys_TRSess_SetAttributes)(ESYS_CONTEXT *esysContext, ESYS_TR session, TPMA_SESSION flags, TPMA_SESSION mask);
0d756413 50TSS2_RC (*sym_Esys_TR_GetName)(ESYS_CONTEXT *esysContext, ESYS_TR handle, TPM2B_NAME **name);
2f5a892a 51TSS2_RC (*sym_Esys_TR_SetAuth)(ESYS_CONTEXT *esysContext, ESYS_TR handle, TPM2B_AUTH const *authValue) = NULL;
5e521624 52TSS2_RC (*sym_Esys_Unseal)(ESYS_CONTEXT *esysContext, ESYS_TR itemHandle, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, TPM2B_SENSITIVE_DATA **outData) = NULL;
0d756413 53TSS2_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);
5e521624
LP
54
55const char* (*sym_Tss2_RC_Decode)(TSS2_RC rc) = NULL;
56
57TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Marshal)(TPM2B_PRIVATE const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL;
58TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PRIVATE *dest) = NULL;
59TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Marshal)(TPM2B_PUBLIC const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL;
60TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PUBLIC *dest) = NULL;
61
62int dlopen_tpm2(void) {
d32f7a8e
ZJS
63 int r;
64
65 r = dlopen_many_sym_or_warn(
66 &libtss2_esys_dl, "libtss2-esys.so.0", LOG_DEBUG,
67 DLSYM_ARG(Esys_Create),
68 DLSYM_ARG(Esys_CreatePrimary),
69 DLSYM_ARG(Esys_Finalize),
70 DLSYM_ARG(Esys_FlushContext),
71 DLSYM_ARG(Esys_Free),
07697bfe 72 DLSYM_ARG(Esys_GetCapability),
d32f7a8e
ZJS
73 DLSYM_ARG(Esys_GetRandom),
74 DLSYM_ARG(Esys_Initialize),
75 DLSYM_ARG(Esys_Load),
0d756413 76 DLSYM_ARG(Esys_LoadExternal),
1421943a 77 DLSYM_ARG(Esys_PCR_Extend),
321a9d9e 78 DLSYM_ARG(Esys_PCR_Read),
0d756413 79 DLSYM_ARG(Esys_PolicyAuthorize),
2f5a892a 80 DLSYM_ARG(Esys_PolicyAuthValue),
d32f7a8e
ZJS
81 DLSYM_ARG(Esys_PolicyGetDigest),
82 DLSYM_ARG(Esys_PolicyPCR),
83 DLSYM_ARG(Esys_StartAuthSession),
84 DLSYM_ARG(Esys_Startup),
da29de23 85 DLSYM_ARG(Esys_TRSess_SetAttributes),
0d756413 86 DLSYM_ARG(Esys_TR_GetName),
2f5a892a 87 DLSYM_ARG(Esys_TR_SetAuth),
0d756413
LP
88 DLSYM_ARG(Esys_Unseal),
89 DLSYM_ARG(Esys_VerifySignature));
d32f7a8e
ZJS
90 if (r < 0)
91 return r;
92
93 r = dlopen_many_sym_or_warn(
94 &libtss2_rc_dl, "libtss2-rc.so.0", LOG_DEBUG,
95 DLSYM_ARG(Tss2_RC_Decode));
96 if (r < 0)
97 return r;
98
99 return dlopen_many_sym_or_warn(
100 &libtss2_mu_dl, "libtss2-mu.so.0", LOG_DEBUG,
101 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Marshal),
102 DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Unmarshal),
103 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Marshal),
104 DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Unmarshal));
5e521624
LP
105}
106
bd860983 107void tpm2_context_destroy(Tpm2Context *c) {
5e521624
LP
108 assert(c);
109
110 if (c->esys_context)
111 sym_Esys_Finalize(&c->esys_context);
112
113 c->tcti_context = mfree(c->tcti_context);
f2592ef0 114 c->tcti_dl = safe_dlclose(c->tcti_dl);
5e521624
LP
115}
116
117static inline void Esys_Finalize_wrapper(ESYS_CONTEXT **c) {
118 /* A wrapper around Esys_Finalize() for use with _cleanup_(). Only reasons we need this wrapper is
119 * because the function itself warn logs if we'd pass a pointer to NULL, and we don't want that. */
120 if (*c)
121 sym_Esys_Finalize(c);
122}
123
bad4c73c 124ESYS_TR tpm2_flush_context_verbose(ESYS_CONTEXT *c, ESYS_TR handle) {
5e521624
LP
125 TSS2_RC rc;
126
127 if (!c || handle == ESYS_TR_NONE)
128 return ESYS_TR_NONE;
129
130 rc = sym_Esys_FlushContext(c, handle);
131 if (rc != TSS2_RC_SUCCESS) /* We ignore failures here (besides debug logging), since this is called
132 * in error paths, where we cannot do anything about failures anymore. And
133 * when it is called in successful codepaths by this time we already did
134 * what we wanted to do, and got the results we wanted so there's no
135 * reason to make this fail more loudly than necessary. */
136 log_debug("Failed to get flush context of TPM, ignoring: %s", sym_Tss2_RC_Decode(rc));
137
138 return ESYS_TR_NONE;
139}
140
bd860983 141int tpm2_context_init(const char *device, Tpm2Context *ret) {
5e521624
LP
142 _cleanup_(Esys_Finalize_wrapper) ESYS_CONTEXT *c = NULL;
143 _cleanup_free_ TSS2_TCTI_CONTEXT *tcti = NULL;
144 _cleanup_(dlclosep) void *dl = NULL;
145 TSS2_RC rc;
146 int r;
147
148 r = dlopen_tpm2();
149 if (r < 0)
150 return log_error_errno(r, "TPM2 support not installed: %m");
151
34906680 152 if (!device) {
5e521624 153 device = secure_getenv("SYSTEMD_TPM2_DEVICE");
34906680
LP
154 if (device)
155 /* Setting the env var to an empty string forces tpm2-tss' own device picking
156 * logic to be used. */
157 device = empty_to_null(device);
158 else
159 /* If nothing was specified explicitly, we'll use a hardcoded default: the "device" tcti
160 * driver and the "/dev/tpmrm0" device. We do this since on some distributions the tpm2-abrmd
161 * might be used and we really don't want that, since it is a system service and that creates
162 * various ordering issues/deadlocks during early boot. */
163 device = "device:/dev/tpmrm0";
164 }
5e521624
LP
165
166 if (device) {
167 const char *param, *driver, *fn;
168 const TSS2_TCTI_INFO* info;
169 TSS2_TCTI_INFO_FUNC func;
170 size_t sz = 0;
171
172 param = strchr(device, ':');
173 if (param) {
50a08514 174 /* Syntax #1: Pair of driver string and arbitrary parameter */
2f82562b 175 driver = strndupa_safe(device, param - device);
50a08514
LP
176 if (isempty(driver))
177 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name is empty, refusing.");
178
5e521624 179 param++;
50a08514
LP
180 } else if (path_is_absolute(device) && path_is_valid(device)) {
181 /* Syntax #2: TPM device node */
5e521624
LP
182 driver = "device";
183 param = device;
50a08514
LP
184 } else
185 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid TPM2 driver string, refusing.");
186
187 log_debug("Using TPM2 TCTI driver '%s' with device '%s'.", driver, param);
5e521624
LP
188
189 fn = strjoina("libtss2-tcti-", driver, ".so.0");
190
50a08514
LP
191 /* Better safe than sorry, let's refuse strings that cannot possibly be valid driver early, before going to disk. */
192 if (!filename_is_valid(fn))
193 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name '%s' not valid, refusing.", driver);
194
5e521624
LP
195 dl = dlopen(fn, RTLD_NOW);
196 if (!dl)
197 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to load %s: %s", fn, dlerror());
198
199 func = dlsym(dl, TSS2_TCTI_INFO_SYMBOL);
200 if (!func)
201 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
202 "Failed to find TCTI info symbol " TSS2_TCTI_INFO_SYMBOL ": %s",
203 dlerror());
204
205 info = func();
206 if (!info)
207 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to get TCTI info data.");
208
209
210 log_debug("Loaded TCTI module '%s' (%s) [Version %" PRIu32 "]", info->name, info->description, info->version);
211
212 rc = info->init(NULL, &sz, NULL);
213 if (rc != TPM2_RC_SUCCESS)
214 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
215 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));
216
217 tcti = malloc0(sz);
218 if (!tcti)
219 return log_oom();
220
d2bf22fb 221 rc = info->init(tcti, &sz, param);
5e521624
LP
222 if (rc != TPM2_RC_SUCCESS)
223 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
224 "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));
225 }
226
227 rc = sym_Esys_Initialize(&c, tcti, NULL);
228 if (rc != TSS2_RC_SUCCESS)
229 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
230 "Failed to initialize TPM context: %s", sym_Tss2_RC_Decode(rc));
231
232 rc = sym_Esys_Startup(c, TPM2_SU_CLEAR);
233 if (rc == TPM2_RC_INITIALIZE)
234 log_debug("TPM already started up.");
235 else if (rc == TSS2_RC_SUCCESS)
236 log_debug("TPM successfully started up.");
237 else
238 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
239 "Failed to start up TPM: %s", sym_Tss2_RC_Decode(rc));
240
bd860983 241 *ret = (Tpm2Context) {
5e521624
LP
242 .esys_context = TAKE_PTR(c),
243 .tcti_context = TAKE_PTR(tcti),
244 .tcti_dl = TAKE_PTR(dl),
245 };
246
247 return 0;
248}
249
aba5dac3
LP
250#define TPM2_CREDIT_RANDOM_FLAG_PATH "/run/systemd/tpm-rng-credited"
251
5e521624
LP
252static int tpm2_credit_random(ESYS_CONTEXT *c) {
253 size_t rps, done = 0;
254 TSS2_RC rc;
aba5dac3 255 usec_t t;
5e521624
LP
256 int r;
257
258 assert(c);
259
260 /* Pulls some entropy from the TPM and adds it into the kernel RNG pool. That way we can say that the
261 * key we will ultimately generate with the kernel random pool is at least as good as the TPM's RNG,
262 * but likely better. Note that we don't trust the TPM RNG very much, hence do not actually credit
263 * any entropy. */
264
aba5dac3
LP
265 if (access(TPM2_CREDIT_RANDOM_FLAG_PATH, F_OK) < 0) {
266 if (errno != ENOENT)
267 log_debug_errno(errno, "Failed to detect if '" TPM2_CREDIT_RANDOM_FLAG_PATH "' exists, ignoring: %m");
268 } else {
269 log_debug("Not adding TPM2 entropy to the kernel random pool again.");
270 return 0; /* Already done */
271 }
272
273 t = now(CLOCK_MONOTONIC);
274
5e521624
LP
275 for (rps = random_pool_size(); rps > 0;) {
276 _cleanup_(Esys_Freep) TPM2B_DIGEST *buffer = NULL;
277
278 rc = sym_Esys_GetRandom(
279 c,
280 ESYS_TR_NONE,
281 ESYS_TR_NONE,
282 ESYS_TR_NONE,
283 MIN(rps, 32U), /* 32 is supposedly a safe choice, given that AES 256bit keys are this long, and TPM2 baseline requires support for those. */
284 &buffer);
285 if (rc != TSS2_RC_SUCCESS)
286 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
287 "Failed to acquire entropy from TPM: %s", sym_Tss2_RC_Decode(rc));
288
289 if (buffer->size == 0)
290 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
291 "Zero-sized entropy returned from TPM.");
292
aba5dac3 293 r = random_write_entropy(-1, buffer->buffer, buffer->size, /* credit= */ false);
5e521624
LP
294 if (r < 0)
295 return log_error_errno(r, "Failed wo write entropy to kernel: %m");
296
297 done += buffer->size;
298 rps = LESS_BY(rps, buffer->size);
299 }
300
aba5dac3
LP
301 log_debug("Added %zu bytes of TPM2 entropy to the kernel random pool in %s.", done, FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - t, 0));
302
303 r = touch(TPM2_CREDIT_RANDOM_FLAG_PATH);
304 if (r < 0)
305 log_debug_errno(r, "Failed to touch '" TPM2_CREDIT_RANDOM_FLAG_PATH "', ignoring: %m");
306
5e521624
LP
307 return 0;
308}
309
310static int tpm2_make_primary(
311 ESYS_CONTEXT *c,
2b92a672
LP
312 ESYS_TR *ret_primary,
313 TPMI_ALG_PUBLIC alg,
314 TPMI_ALG_PUBLIC *ret_alg) {
5e521624
LP
315
316 static const TPM2B_SENSITIVE_CREATE primary_sensitive = {};
2b92a672 317 static const TPM2B_PUBLIC primary_template_ecc = {
5e521624
LP
318 .size = sizeof(TPMT_PUBLIC),
319 .publicArea = {
320 .type = TPM2_ALG_ECC,
321 .nameAlg = TPM2_ALG_SHA256,
322 .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH,
55efb33e
LP
323 .parameters.eccDetail = {
324 .symmetric = {
325 .algorithm = TPM2_ALG_AES,
326 .keyBits.aes = 128,
327 .mode.aes = TPM2_ALG_CFB,
5e521624 328 },
55efb33e
LP
329 .scheme.scheme = TPM2_ALG_NULL,
330 .curveID = TPM2_ECC_NIST_P256,
331 .kdf.scheme = TPM2_ALG_NULL,
5e521624
LP
332 },
333 },
334 };
2b92a672
LP
335 static const TPM2B_PUBLIC primary_template_rsa = {
336 .size = sizeof(TPMT_PUBLIC),
337 .publicArea = {
338 .type = TPM2_ALG_RSA,
339 .nameAlg = TPM2_ALG_SHA256,
340 .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH,
55efb33e
LP
341 .parameters.rsaDetail = {
342 .symmetric = {
343 .algorithm = TPM2_ALG_AES,
344 .keyBits.aes = 128,
345 .mode.aes = TPM2_ALG_CFB,
2b92a672 346 },
55efb33e
LP
347 .scheme.scheme = TPM2_ALG_NULL,
348 .keyBits = 2048,
2b92a672
LP
349 },
350 },
351 };
352
5e521624
LP
353 static const TPML_PCR_SELECTION creation_pcr = {};
354 ESYS_TR primary = ESYS_TR_NONE;
355 TSS2_RC rc;
2b92a672 356 usec_t ts;
5e521624
LP
357
358 log_debug("Creating primary key on TPM.");
359
2b92a672
LP
360 /* So apparently not all TPM2 devices support ECC. ECC is generally preferably, because it's so much
361 * faster, noticeably so (~10s vs. ~240ms on my system). Hence, unless explicitly configured let's
362 * try to use ECC first, and if that does not work, let's fall back to RSA. */
5e521624 363
2b92a672
LP
364 ts = now(CLOCK_MONOTONIC);
365
366 if (IN_SET(alg, 0, TPM2_ALG_ECC)) {
367 rc = sym_Esys_CreatePrimary(
368 c,
369 ESYS_TR_RH_OWNER,
370 ESYS_TR_PASSWORD,
371 ESYS_TR_NONE,
372 ESYS_TR_NONE,
373 &primary_sensitive,
374 &primary_template_ecc,
375 NULL,
376 &creation_pcr,
377 &primary,
378 NULL,
379 NULL,
380 NULL,
381 NULL);
382
383 if (rc != TSS2_RC_SUCCESS) {
384 if (alg != 0)
385 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
386 "Failed to generate ECC primary key in TPM: %s", sym_Tss2_RC_Decode(rc));
387
388 log_debug("Failed to generate ECC primary key in TPM, trying RSA: %s", sym_Tss2_RC_Decode(rc));
389 } else {
390 log_debug("Successfully created ECC primary key on TPM.");
391 alg = TPM2_ALG_ECC;
392 }
393 }
394
395 if (IN_SET(alg, 0, TPM2_ALG_RSA)) {
396 rc = sym_Esys_CreatePrimary(
397 c,
398 ESYS_TR_RH_OWNER,
399 ESYS_TR_PASSWORD,
400 ESYS_TR_NONE,
401 ESYS_TR_NONE,
402 &primary_sensitive,
403 &primary_template_rsa,
404 NULL,
405 &creation_pcr,
406 &primary,
407 NULL,
408 NULL,
409 NULL,
410 NULL);
411 if (rc != TSS2_RC_SUCCESS)
412 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
413 "Failed to generate RSA primary key in TPM: %s", sym_Tss2_RC_Decode(rc));
414 else if (alg == 0) {
415 log_notice("TPM2 chip apparently does not support ECC primary keys, falling back to RSA. "
416 "This likely means TPM2 operations will be relatively slow, please be patient.");
417 alg = TPM2_ALG_RSA;
418 }
419
420 log_debug("Successfully created RSA primary key on TPM.");
421 }
5e521624 422
2b92a672 423 log_debug("Generating primary key on TPM2 took %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - ts, USEC_PER_MSEC));
5e521624
LP
424
425 *ret_primary = primary;
2b92a672
LP
426 if (ret_alg)
427 *ret_alg = alg;
428
5e521624
LP
429 return 0;
430}
431
bad4c73c 432void tpm2_pcr_mask_to_selection(uint32_t mask, uint16_t bank, TPML_PCR_SELECTION *ret) {
321a9d9e
LP
433 assert(ret);
434
435 /* We only do 24bit here, as that's what PC TPMs are supposed to support */
436 assert(mask <= 0xFFFFFFU);
437
438 *ret = (TPML_PCR_SELECTION) {
439 .count = 1,
4dde902e
LP
440 .pcrSelections[0] = {
441 .hash = bank,
442 .sizeofSelect = 3,
443 .pcrSelect[0] = mask & 0xFF,
444 .pcrSelect[1] = (mask >> 8) & 0xFF,
445 .pcrSelect[2] = (mask >> 16) & 0xFF,
446 }
321a9d9e
LP
447 };
448}
449
450static unsigned find_nth_bit(uint32_t mask, unsigned n) {
451 uint32_t bit = 1;
452
453 assert(n < 32);
454
455 /* Returns the bit index of the nth set bit, e.g. mask=0b101001, n=3 → 5 */
456
457 for (unsigned i = 0; i < sizeof(mask)*8; i++) {
458
459 if (bit & mask) {
460 if (n == 0)
461 return i;
462
463 n--;
464 }
465
466 bit <<= 1;
467 }
468
469 return UINT_MAX;
470}
471
472static int tpm2_pcr_mask_good(
473 ESYS_CONTEXT *c,
474 TPMI_ALG_HASH bank,
475 uint32_t mask) {
476
477 _cleanup_(Esys_Freep) TPML_DIGEST *pcr_values = NULL;
478 TPML_PCR_SELECTION selection;
479 bool good = false;
480 TSS2_RC rc;
481
482 assert(c);
483
484 /* So we have the problem that some systems might have working TPM2 chips, but the firmware doesn't
485 * actually measure into them, or only into a suboptimal bank. If so, the PCRs should be all zero or
486 * all 0xFF. Detect that, so that we can warn and maybe pick a better bank. */
487
685e3417 488 tpm2_pcr_mask_to_selection(mask, bank, &selection);
321a9d9e
LP
489
490 rc = sym_Esys_PCR_Read(
491 c,
492 ESYS_TR_NONE,
493 ESYS_TR_NONE,
494 ESYS_TR_NONE,
495 &selection,
496 NULL,
497 NULL,
498 &pcr_values);
499 if (rc != TSS2_RC_SUCCESS)
500 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
501 "Failed to read TPM2 PCRs: %s", sym_Tss2_RC_Decode(rc));
502
503 /* If at least one of the selected PCR values is something other than all 0x00 or all 0xFF we are happy. */
504 for (unsigned i = 0; i < pcr_values->count; i++) {
505 if (DEBUG_LOGGING) {
506 _cleanup_free_ char *h = NULL;
507 unsigned j;
508
509 h = hexmem(pcr_values->digests[i].buffer, pcr_values->digests[i].size);
510 j = find_nth_bit(mask, i);
511 assert(j != UINT_MAX);
512
513 log_debug("PCR %u value: %s", j, strna(h));
514 }
515
516 if (!memeqbyte(0x00, pcr_values->digests[i].buffer, pcr_values->digests[i].size) &&
517 !memeqbyte(0xFF, pcr_values->digests[i].buffer, pcr_values->digests[i].size))
518 good = true;
519 }
520
521 return good;
522}
523
59fafaee
LP
524static int tpm2_bank_has24(const TPMS_PCR_SELECTION *selection) {
525
526 assert(selection);
527
528 /* As per https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_PFP_r1p05_v23_pub.pdf a
529 * TPM2 on a Client PC must have at least 24 PCRs. If this TPM has less, just skip over it. */
530 if (selection->sizeofSelect < TPM2_PCRS_MAX/8) {
531 log_debug("Skipping TPM2 PCR bank %s with fewer than 24 PCRs.",
7bfe0a48 532 strna(tpm2_hash_alg_to_string(selection->hash)));
59fafaee
LP
533 return false;
534 }
535
536 assert_cc(TPM2_PCRS_MAX % 8 == 0);
537
538 /* It's not enough to check how many PCRs there are, we also need to check that the 24 are
539 * enabled for this bank. Otherwise this TPM doesn't qualify. */
540 bool valid = true;
541 for (size_t j = 0; j < TPM2_PCRS_MAX/8; j++)
542 if (selection->pcrSelect[j] != 0xFF) {
543 valid = false;
544 break;
545 }
546
547 if (!valid)
548 log_debug("TPM2 PCR bank %s has fewer than 24 PCR bits enabled, ignoring.",
7bfe0a48 549 strna(tpm2_hash_alg_to_string(selection->hash)));
59fafaee
LP
550
551 return valid;
552}
553
07697bfe
LP
554static int tpm2_get_best_pcr_bank(
555 ESYS_CONTEXT *c,
321a9d9e 556 uint32_t pcr_mask,
07697bfe
LP
557 TPMI_ALG_HASH *ret) {
558
559 _cleanup_(Esys_Freep) TPMS_CAPABILITY_DATA *pcap = NULL;
321a9d9e 560 TPMI_ALG_HASH supported_hash = 0, hash_with_valid_pcr = 0;
07697bfe
LP
561 TPMI_YES_NO more;
562 TSS2_RC rc;
59fafaee 563 int r;
07697bfe 564
321a9d9e
LP
565 assert(c);
566
07697bfe
LP
567 rc = sym_Esys_GetCapability(
568 c,
569 ESYS_TR_NONE,
570 ESYS_TR_NONE,
571 ESYS_TR_NONE,
572 TPM2_CAP_PCRS,
573 0,
574 1,
575 &more,
576 &pcap);
577 if (rc != TSS2_RC_SUCCESS)
578 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
579 "Failed to determine TPM2 PCR bank capabilities: %s", sym_Tss2_RC_Decode(rc));
580
581 assert(pcap->capability == TPM2_CAP_PCRS);
582
583 for (size_t i = 0; i < pcap->data.assignedPCR.count; i++) {
321a9d9e
LP
584 int good;
585
586 /* For now we are only interested in the SHA1 and SHA256 banks */
587 if (!IN_SET(pcap->data.assignedPCR.pcrSelections[i].hash, TPM2_ALG_SHA256, TPM2_ALG_SHA1))
588 continue;
07697bfe 589
59fafaee
LP
590 r = tpm2_bank_has24(pcap->data.assignedPCR.pcrSelections + i);
591 if (r < 0)
592 return r;
593 if (!r)
07697bfe 594 continue;
07697bfe 595
321a9d9e
LP
596 good = tpm2_pcr_mask_good(c, pcap->data.assignedPCR.pcrSelections[i].hash, pcr_mask);
597 if (good < 0)
598 return good;
599
07697bfe 600 if (pcap->data.assignedPCR.pcrSelections[i].hash == TPM2_ALG_SHA256) {
321a9d9e
LP
601 supported_hash = TPM2_ALG_SHA256;
602 if (good) {
603 /* Great, SHA256 is supported and has initialized PCR values, we are done. */
604 hash_with_valid_pcr = TPM2_ALG_SHA256;
605 break;
606 }
607 } else {
608 assert(pcap->data.assignedPCR.pcrSelections[i].hash == TPM2_ALG_SHA1);
609
610 if (supported_hash == 0)
611 supported_hash = TPM2_ALG_SHA1;
07697bfe 612
321a9d9e
LP
613 if (good && hash_with_valid_pcr == 0)
614 hash_with_valid_pcr = TPM2_ALG_SHA1;
615 }
07697bfe
LP
616 }
617
321a9d9e
LP
618 /* We preferably pick SHA256, but only if its PCRs are initialized or neither the SHA1 nor the SHA256
619 * PCRs are initialized. If SHA256 is not supported but SHA1 is and its PCRs are too, we prefer
620 * SHA1.
621 *
622 * We log at LOG_NOTICE level whenever we end up using the SHA1 bank or when the PCRs we bind to are
623 * not initialized. */
624
625 if (hash_with_valid_pcr == TPM2_ALG_SHA256) {
626 assert(supported_hash == TPM2_ALG_SHA256);
627 log_debug("TPM2 device supports SHA256 PCR bank and SHA256 PCRs are valid, yay!");
628 *ret = TPM2_ALG_SHA256;
629 } else if (hash_with_valid_pcr == TPM2_ALG_SHA1) {
630 if (supported_hash == TPM2_ALG_SHA256)
631 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.");
632 else {
633 assert(supported_hash == TPM2_ALG_SHA1);
634 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.");
635 }
636
637 *ret = TPM2_ALG_SHA1;
638 } else if (supported_hash == TPM2_ALG_SHA256) {
639 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!");
640 *ret = TPM2_ALG_SHA256;
641 } else if (supported_hash == TPM2_ALG_SHA1) {
642 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!");
643 *ret = TPM2_ALG_SHA1;
644 } else
07697bfe
LP
645 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
646 "TPM2 module supports neither SHA1 nor SHA256 PCR banks, cannot operate.");
647
07697bfe
LP
648 return 0;
649}
650
c5bf1f85
LP
651int tpm2_get_good_pcr_banks(
652 ESYS_CONTEXT *c,
653 uint32_t pcr_mask,
654 TPMI_ALG_HASH **ret) {
655
656 _cleanup_free_ TPMI_ALG_HASH *good_banks = NULL, *fallback_banks = NULL;
657 _cleanup_(Esys_Freep) TPMS_CAPABILITY_DATA *pcap = NULL;
658 size_t n_good_banks = 0, n_fallback_banks = 0;
659 TPMI_YES_NO more;
660 TSS2_RC rc;
661 int r;
662
663 assert(c);
664 assert(ret);
665
666 rc = sym_Esys_GetCapability(
667 c,
668 ESYS_TR_NONE,
669 ESYS_TR_NONE,
670 ESYS_TR_NONE,
671 TPM2_CAP_PCRS,
672 0,
673 1,
674 &more,
675 &pcap);
676 if (rc != TSS2_RC_SUCCESS)
677 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
678 "Failed to determine TPM2 PCR bank capabilities: %s", sym_Tss2_RC_Decode(rc));
679
680 assert(pcap->capability == TPM2_CAP_PCRS);
681
682 for (size_t i = 0; i < pcap->data.assignedPCR.count; i++) {
683
684 /* Let's see if this bank is superficially OK, i.e. has at least 24 enabled registers */
685 r = tpm2_bank_has24(pcap->data.assignedPCR.pcrSelections + i);
686 if (r < 0)
687 return r;
688 if (!r)
689 continue;
690
691 /* Let's now see if this bank has any of the selected PCRs actually initialized */
692 r = tpm2_pcr_mask_good(c, pcap->data.assignedPCR.pcrSelections[i].hash, pcr_mask);
693 if (r < 0)
694 return r;
695
696 if (n_good_banks + n_fallback_banks >= INT_MAX)
697 return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "Too many good TPM2 banks?");
698
699 if (r) {
700 if (!GREEDY_REALLOC(good_banks, n_good_banks+1))
701 return log_oom();
702
703 good_banks[n_good_banks++] = pcap->data.assignedPCR.pcrSelections[i].hash;
704 } else {
705 if (!GREEDY_REALLOC(fallback_banks, n_fallback_banks+1))
706 return log_oom();
707
708 fallback_banks[n_fallback_banks++] = pcap->data.assignedPCR.pcrSelections[i].hash;
709 }
710 }
711
712 /* Preferably, use the good banks (i.e. the ones the PCR values are actually initialized so
713 * far). Otherwise use the fallback banks (i.e. which exist and are enabled, but so far not used. */
714 if (n_good_banks > 0) {
715 log_debug("Found %zu fully initialized TPM2 banks.", n_good_banks);
716 *ret = TAKE_PTR(good_banks);
717 return (int) n_good_banks;
718 }
719 if (n_fallback_banks > 0) {
720 log_debug("Found %zu enabled but un-initialized TPM2 banks.", n_fallback_banks);
721 *ret = TAKE_PTR(fallback_banks);
722 return (int) n_fallback_banks;
723 }
724
725 /* No suitable banks found. */
726 *ret = NULL;
727 return 0;
728}
729
e4481cc5
LP
730int tpm2_get_good_pcr_banks_strv(
731 ESYS_CONTEXT *c,
732 uint32_t pcr_mask,
733 char ***ret) {
734
735 _cleanup_free_ TPMI_ALG_HASH *algs = NULL;
736 _cleanup_strv_free_ char **l = NULL;
737 int n_algs;
738
739 assert(c);
740 assert(ret);
741
742 n_algs = tpm2_get_good_pcr_banks(c, pcr_mask, &algs);
743 if (n_algs < 0)
744 return n_algs;
745
746 for (int i = 0; i < n_algs; i++) {
747 _cleanup_free_ char *n = NULL;
748 const EVP_MD *implementation;
749 const char *salg;
750
7bfe0a48 751 salg = tpm2_hash_alg_to_string(algs[i]);
e4481cc5
LP
752 if (!salg)
753 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unknown PCR algorithm, can't measure.");
754
755 implementation = EVP_get_digestbyname(salg);
756 if (!implementation)
757 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unsupported PCR algorithm, can't measure.");
758
759 n = strdup(ASSERT_PTR(EVP_MD_name(implementation)));
760 if (!n)
761 return log_oom();
762
763 ascii_strlower(n); /* OpenSSL uses uppercase digest names, we prefer them lower case. */
764
765 if (strv_consume(&l, TAKE_PTR(n)) < 0)
766 return log_oom();
767 }
768
769 *ret = TAKE_PTR(l);
770 return 0;
771}
772
0e15c14f
WR
773static void hash_pin(const char *pin, size_t len, TPM2B_AUTH *auth) {
774 struct sha256_ctx hash;
775
776 assert(auth);
777 assert(pin);
692597c8 778
0e15c14f
WR
779 auth->size = SHA256_DIGEST_SIZE;
780
692597c8
LP
781 CLEANUP_ERASE(hash);
782
0e15c14f
WR
783 sha256_init_ctx(&hash);
784 sha256_process_bytes(pin, len, &hash);
785 sha256_finish_ctx(&hash, auth->buffer);
0e15c14f
WR
786}
787
da29de23
GG
788static int tpm2_make_encryption_session(
789 ESYS_CONTEXT *c,
9420fea8 790 ESYS_TR primary,
0e15c14f
WR
791 ESYS_TR bind_key,
792 const char *pin,
da29de23
GG
793 ESYS_TR *ret_session) {
794
795 static const TPMT_SYM_DEF symmetric = {
796 .algorithm = TPM2_ALG_AES,
4dde902e
LP
797 .keyBits.aes = 128,
798 .mode.aes = TPM2_ALG_CFB,
da29de23
GG
799 };
800 const TPMA_SESSION sessionAttributes = TPMA_SESSION_DECRYPT | TPMA_SESSION_ENCRYPT |
801 TPMA_SESSION_CONTINUESESSION;
802 ESYS_TR session = ESYS_TR_NONE;
803 TSS2_RC rc;
804
805 assert(c);
806
0e15c14f
WR
807 /*
808 * if a pin is set for the seal object, use it to bind the session
809 * key to that object. This prevents active bus interposers from
810 * faking a TPM and seeing the unsealed value. An active interposer
811 * could fake a TPM, satisfying the encrypted session, and just
812 * forward everything to the *real* TPM.
813 */
814 if (pin) {
815 TPM2B_AUTH auth = {};
816
692597c8
LP
817 CLEANUP_ERASE(auth);
818
0e15c14f
WR
819 hash_pin(pin, strlen(pin), &auth);
820
821 rc = sym_Esys_TR_SetAuth(c, bind_key, &auth);
0e15c14f
WR
822 if (rc != TSS2_RC_SUCCESS)
823 return log_error_errno(
824 SYNTHETIC_ERRNO(ENOTRECOVERABLE),
825 "Failed to load PIN in TPM: %s",
826 sym_Tss2_RC_Decode(rc));
827 }
828
da29de23
GG
829 log_debug("Starting HMAC encryption session.");
830
831 /* Start a salted, unbound HMAC session with a well-known key (e.g. primary key) as tpmKey, which
832 * means that the random salt will be encrypted with the well-known key. That way, only the TPM can
833 * recover the salt, which is then used for key derivation. */
834 rc = sym_Esys_StartAuthSession(
835 c,
9420fea8 836 primary,
0e15c14f 837 bind_key,
da29de23
GG
838 ESYS_TR_NONE,
839 ESYS_TR_NONE,
840 ESYS_TR_NONE,
841 NULL,
842 TPM2_SE_HMAC,
843 &symmetric,
844 TPM2_ALG_SHA256,
845 &session);
846 if (rc != TSS2_RC_SUCCESS)
847 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
848 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc));
849
850 /* Enable parameter encryption/decryption with AES in CFB mode. Together with HMAC digests (which are
851 * always used for sessions), this provides confidentiality, integrity and replay protection for
852 * operations that use this session. */
853 rc = sym_Esys_TRSess_SetAttributes(c, session, sessionAttributes, 0xff);
854 if (rc != TSS2_RC_SUCCESS)
855 return log_error_errno(
856 SYNTHETIC_ERRNO(ENOTRECOVERABLE),
857 "Failed to configure TPM session: %s",
858 sym_Tss2_RC_Decode(rc));
859
860 if (ret_session) {
861 *ret_session = session;
862 session = ESYS_TR_NONE;
863 }
864
bad4c73c 865 session = tpm2_flush_context_verbose(c, session);
da29de23
GG
866 return 0;
867}
868
395c1d9a 869#if HAVE_OPENSSL
d9b5841d
LP
870static int openssl_pubkey_to_tpm2_pubkey(EVP_PKEY *input, TPM2B_PUBLIC *output) {
871#if OPENSSL_VERSION_MAJOR >= 3
872 _cleanup_(BN_freep) BIGNUM *n = NULL, *e = NULL;
873#else
874 const BIGNUM *n = NULL, *e = NULL;
875 const RSA *rsa = NULL;
876#endif
877 int n_bytes, e_bytes;
878
879 assert(input);
880 assert(output);
881
882 /* Converts an OpenSSL public key to a structure that the TPM chip can process. */
883
884 if (EVP_PKEY_base_id(input) != EVP_PKEY_RSA)
885 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Provided public key is not an RSA key.");
886
887#if OPENSSL_VERSION_MAJOR >= 3
888 if (!EVP_PKEY_get_bn_param(input, OSSL_PKEY_PARAM_RSA_N, &n))
889 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to get RSA modulus from public key.");
890#else
891 rsa = EVP_PKEY_get0_RSA(input);
892 if (!rsa)
893 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to extract RSA key from public key.");
894
895 n = RSA_get0_n(rsa);
896 if (!n)
897 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to get RSA modulus from public key.");
898#endif
899
900 n_bytes = BN_num_bytes(n);
901 assert_se(n_bytes > 0);
902 if ((size_t) n_bytes > sizeof_field(TPM2B_PUBLIC, publicArea.unique.rsa.buffer))
903 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "RSA modulus too large for TPM2 public key object.");
904
905#if OPENSSL_VERSION_MAJOR >= 3
906 if (!EVP_PKEY_get_bn_param(input, OSSL_PKEY_PARAM_RSA_E, &e))
907 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to get RSA exponent from public key.");
908#else
909 e = RSA_get0_e(rsa);
910 if (!e)
911 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to get RSA exponent from public key.");
912#endif
913
914 e_bytes = BN_num_bytes(e);
915 assert_se(e_bytes > 0);
916 if ((size_t) e_bytes > sizeof_field(TPM2B_PUBLIC, publicArea.parameters.rsaDetail.exponent))
917 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "RSA exponent too large for TPM2 public key object.");
918
919 *output = (TPM2B_PUBLIC) {
920 .size = sizeof(TPMT_PUBLIC),
921 .publicArea = {
922 .type = TPM2_ALG_RSA,
923 .nameAlg = TPM2_ALG_SHA256,
924 .objectAttributes = TPMA_OBJECT_DECRYPT | TPMA_OBJECT_SIGN_ENCRYPT | TPMA_OBJECT_USERWITHAUTH,
925 .parameters.rsaDetail = {
926 .scheme = {
927 .scheme = TPM2_ALG_NULL,
928 .details.anySig.hashAlg = TPM2_ALG_NULL,
929 },
930 .symmetric = {
931 .algorithm = TPM2_ALG_NULL,
932 .mode.sym = TPM2_ALG_NULL,
933 },
934 .keyBits = n_bytes * 8,
935 /* .exponent will be filled in below. */
936 },
937 .unique = {
938 .rsa.size = n_bytes,
939 /* .rsa.buffer will be filled in below. */
940 },
941 },
942 };
943
944 if (BN_bn2bin(n, output->publicArea.unique.rsa.buffer) <= 0)
945 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to convert RSA modulus.");
946
947 if (BN_bn2bin(e, (unsigned char*) &output->publicArea.parameters.rsaDetail.exponent) <= 0)
948 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to convert RSA exponent.");
949
950 return 0;
951}
952
953static int find_signature(
954 JsonVariant *v,
955 uint16_t pcr_bank,
956 uint32_t pcr_mask,
957 EVP_PKEY *pk,
958 const void *policy,
959 size_t policy_size,
960 void *ret_signature,
961 size_t *ret_signature_size) {
962
963 _cleanup_free_ void *fp = NULL;
964 JsonVariant *b, *i;
965 size_t fp_size;
966 const char *k;
967 int r;
968
969 /* Searches for a signature blob in the specified JSON object. Search keys are PCR bank, PCR mask,
970 * public key, and policy digest. */
971
972 if (!json_variant_is_object(v))
973 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Signature is not a JSON object.");
974
7bfe0a48 975 k = tpm2_hash_alg_to_string(pcr_bank);
d9b5841d
LP
976 if (!k)
977 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Don't know PCR bank %" PRIu16, pcr_bank);
978
979 /* First, find field by bank */
980 b = json_variant_by_key(v, k);
981 if (!b)
982 return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "Signature lacks data for PCR bank '%s'.", k);
983
984 if (!json_variant_is_array(b))
985 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Bank data is not a JSON array.");
986
987 /* Now iterate through all signatures known for this bank */
988 JSON_VARIANT_ARRAY_FOREACH(i, b) {
989 _cleanup_free_ void *fpj_data = NULL, *polj_data = NULL;
990 JsonVariant *maskj, *fpj, *sigj, *polj;
991 size_t fpj_size, polj_size;
992 uint32_t parsed_mask;
993
994 if (!json_variant_is_object(i))
995 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Bank data element is not a JSON object");
996
997 /* Check if the PCR mask matches our expectations */
998 maskj = json_variant_by_key(i, "pcrs");
999 if (!maskj)
1000 continue;
1001
1002 r = tpm2_parse_pcr_json_array(maskj, &parsed_mask);
1003 if (r < 0)
1004 return log_error_errno(r, "Failed to parse JSON PCR mask");
1005
1006 if (parsed_mask != pcr_mask)
1007 continue; /* Not for this PCR mask */
1008
1009 /* Then check if this is for the public key we operate with */
1010 fpj = json_variant_by_key(i, "pkfp");
1011 if (!fpj)
1012 continue;
1013
1014 r = json_variant_unhex(fpj, &fpj_data, &fpj_size);
1015 if (r < 0)
1016 return log_error_errno(r, "Failed to decode fingerprint in JSON data: %m");
1017
1018 if (!fp) {
1019 r = pubkey_fingerprint(pk, EVP_sha256(), &fp, &fp_size);
1020 if (r < 0)
1021 return log_error_errno(r, "Failed to calculate public key fingerprint: %m");
1022 }
1023
1024 if (memcmp_nn(fp, fp_size, fpj_data, fpj_size) != 0)
1025 continue; /* Not for this public key */
1026
1027 /* Finally, check if this is for the PCR policy we expect this to be */
1028 polj = json_variant_by_key(i, "pol");
1029 if (!polj)
1030 continue;
1031
1032 r = json_variant_unhex(polj, &polj_data, &polj_size);
1033 if (r < 0)
1034 return log_error_errno(r, "Failed to decode policy hash JSON data: %m");
1035
1036 if (memcmp_nn(policy, policy_size, polj_data, polj_size) != 0)
1037 continue;
1038
1039 /* This entry matches all our expectations, now return the signature included in it */
1040 sigj = json_variant_by_key(i, "sig");
1041 if (!sigj)
1042 continue;
1043
1044 return json_variant_unbase64(sigj, ret_signature, ret_signature_size);
1045 }
1046
1047 return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "Couldn't find signature for this PCR bank, PCR index and public key.");
1048}
395c1d9a 1049#endif
d9b5841d
LP
1050
1051static int tpm2_make_policy_session(
5e521624 1052 ESYS_CONTEXT *c,
9420fea8 1053 ESYS_TR primary,
da29de23 1054 ESYS_TR parent_session,
73096907 1055 TPM2_SE session_type,
d9b5841d 1056 uint32_t hash_pcr_mask,
07697bfe 1057 uint16_t pcr_bank, /* If UINT16_MAX, pick best bank automatically, otherwise specify bank explicitly. */
d9b5841d
LP
1058 const void *pubkey,
1059 size_t pubkey_size,
1060 uint32_t pubkey_pcr_mask,
1061 JsonVariant *signature_json,
2f5a892a 1062 bool use_pin,
5e521624 1063 ESYS_TR *ret_session,
07697bfe
LP
1064 TPM2B_DIGEST **ret_policy_digest,
1065 TPMI_ALG_HASH *ret_pcr_bank) {
5e521624
LP
1066
1067 static const TPMT_SYM_DEF symmetric = {
1068 .algorithm = TPM2_ALG_AES,
821d94c4
LP
1069 .keyBits.aes = 128,
1070 .mode.aes = TPM2_ALG_CFB,
5e521624 1071 };
5e521624 1072 _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
d9b5841d 1073 ESYS_TR session = ESYS_TR_NONE, pubkey_handle = ESYS_TR_NONE;
5e521624
LP
1074 TSS2_RC rc;
1075 int r;
1076
1077 assert(c);
d9b5841d
LP
1078 assert(pubkey || pubkey_size == 0);
1079 assert(pubkey_pcr_mask == 0 || pubkey_size > 0);
5e521624
LP
1080
1081 log_debug("Starting authentication session.");
1082
251d2ea2
LP
1083 /* So apparently some TPM implementations don't implement trial mode correctly. To avoid issues let's
1084 * avoid it when it is easy to. At the moment we only really need trial mode for the signed PCR
1085 * policies (since only then we need to shove PCR values into the policy that don't match current
1086 * state anyway), hence if we have none of those we don't need to bother. Hence, let's patch in
1087 * TPM2_SE_POLICY even if trial mode is requested unless a pubkey PCR mask is specified that is
1088 * non-zero, i.e. signed PCR policy is requested.
1089 *
1090 * One day we should switch to calculating policy hashes client side when trial mode is requested, to
1091 * avoid this mess. */
1092 if (session_type == TPM2_SE_TRIAL && pubkey_pcr_mask == 0)
1093 session_type = TPM2_SE_POLICY;
1094
d9b5841d
LP
1095 if ((hash_pcr_mask | pubkey_pcr_mask) != 0) {
1096 /* We are told to configure a PCR policy of some form, let's determine/validate the PCR bank to use. */
d38466ba 1097
d9b5841d
LP
1098 if (pcr_bank != UINT16_MAX) {
1099 r = tpm2_pcr_mask_good(c, pcr_bank, hash_pcr_mask|pubkey_pcr_mask);
1100 if (r < 0)
1101 return r;
1102 if (r == 0)
1103 log_warning("Selected TPM2 PCRs are not initialized on this system, most likely due to a firmware issue. PCR policy is effectively not enforced. Proceeding anyway.");
1104 } else {
1105 /* No bank configured, pick automatically. Some TPM2 devices only can do SHA1. If we
1106 * detect that use that, but preferably use SHA256 */
1107 r = tpm2_get_best_pcr_bank(c, hash_pcr_mask|pubkey_pcr_mask, &pcr_bank);
1108 if (r < 0)
1109 return r;
1110 }
1111 }
321a9d9e 1112
395c1d9a
YW
1113#if HAVE_OPENSSL
1114 _cleanup_(EVP_PKEY_freep) EVP_PKEY *pk = NULL;
d9b5841d 1115 if (pubkey_size > 0) {
dc176813
ZJS
1116 /* If a pubkey is specified, load it to validate it, even if the PCR mask for this is
1117 * actually zero, and we are thus not going to use it. */
d9b5841d
LP
1118 _cleanup_fclose_ FILE *f = fmemopen((void*) pubkey, pubkey_size, "r");
1119 if (!f)
1120 return log_oom();
321a9d9e 1121
d9b5841d
LP
1122 pk = PEM_read_PUBKEY(f, NULL, NULL, NULL);
1123 if (!pk)
1124 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse PEM public key.");
07697bfe 1125 }
395c1d9a 1126#endif
07697bfe 1127
5e521624
LP
1128 rc = sym_Esys_StartAuthSession(
1129 c,
9420fea8 1130 primary,
5e521624 1131 ESYS_TR_NONE,
da29de23 1132 parent_session,
5e521624
LP
1133 ESYS_TR_NONE,
1134 ESYS_TR_NONE,
1135 NULL,
73096907 1136 session_type,
5e521624
LP
1137 &symmetric,
1138 TPM2_ALG_SHA256,
1139 &session);
1140 if (rc != TSS2_RC_SUCCESS)
1141 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1142 "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc));
1143
d9b5841d 1144 if (pubkey_pcr_mask != 0) {
395c1d9a 1145#if HAVE_OPENSSL
d9b5841d 1146 log_debug("Configuring public key based PCR policy.");
5e521624 1147
d9b5841d
LP
1148 /* First: load public key into the TPM */
1149 TPM2B_PUBLIC pubkey_tpm2;
1150 r = openssl_pubkey_to_tpm2_pubkey(pk, &pubkey_tpm2);
1151 if (r < 0)
1152 goto finish;
1153
1154 rc = sym_Esys_LoadExternal(
1155 c,
1156 ESYS_TR_NONE,
1157 ESYS_TR_NONE,
1158 ESYS_TR_NONE,
1159 NULL,
1160 &pubkey_tpm2,
155c5129
VK
1161#if HAVE_TSS2_ESYS3
1162 /* tpm2-tss >= 3.0.0 requires a ESYS_TR_RH_* constant specifying the requested
1163 * hierarchy, older versions need TPM2_RH_* instead. */
1164 ESYS_TR_RH_OWNER,
1165#else
d9b5841d 1166 TPM2_RH_OWNER,
155c5129 1167#endif
d9b5841d
LP
1168 &pubkey_handle);
1169 if (rc != TSS2_RC_SUCCESS) {
1170 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1171 "Failed to load public key into TPM: %s", sym_Tss2_RC_Decode(rc));
1172 goto finish;
1173 }
1174
1175 /* Acquire the "name" of what we just loaded */
1176 _cleanup_(Esys_Freep) TPM2B_NAME *pubkey_name = NULL;
1177 rc = sym_Esys_TR_GetName(
1178 c,
1179 pubkey_handle,
1180 &pubkey_name);
1181 if (rc != TSS2_RC_SUCCESS) {
1182 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1183 "Failed to get name of public key from TPM: %s", sym_Tss2_RC_Decode(rc));
1184 goto finish;
1185 }
1186
1187 /* Put together the PCR policy we want to use */
1188 TPML_PCR_SELECTION pcr_selection;
1189 tpm2_pcr_mask_to_selection(pubkey_pcr_mask, pcr_bank, &pcr_selection);
1190 rc = sym_Esys_PolicyPCR(
1191 c,
1192 session,
1193 ESYS_TR_NONE,
1194 ESYS_TR_NONE,
1195 ESYS_TR_NONE,
1196 NULL,
1197 &pcr_selection);
1198 if (rc != TSS2_RC_SUCCESS) {
1199 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1200 "Failed to add PCR policy to TPM: %s", sym_Tss2_RC_Decode(rc));
1201 goto finish;
1202 }
1203
1204 /* Get the policy hash of the PCR policy */
1205 _cleanup_(Esys_Freep) TPM2B_DIGEST *approved_policy = NULL;
1206 rc = sym_Esys_PolicyGetDigest(
1207 c,
1208 session,
1209 ESYS_TR_NONE,
1210 ESYS_TR_NONE,
1211 ESYS_TR_NONE,
1212 &approved_policy);
1213 if (rc != TSS2_RC_SUCCESS) {
1214 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1215 "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc));
1216 goto finish;
1217 }
1218
1219 /* When we are unlocking and have a signature, let's pass it to the TPM */
1220 _cleanup_(Esys_Freep) TPMT_TK_VERIFIED *check_ticket_buffer = NULL;
1221 const TPMT_TK_VERIFIED *check_ticket;
1222 if (signature_json) {
1223 _cleanup_free_ void *signature_raw = NULL;
1224 size_t signature_size;
1225
1226 r = find_signature(
1227 signature_json,
1228 pcr_bank,
1229 pubkey_pcr_mask,
1230 pk,
1231 approved_policy->buffer,
1232 approved_policy->size,
1233 &signature_raw,
1234 &signature_size);
1235 if (r < 0)
1236 goto finish;
1237
1238 /* TPM2_VerifySignature() will only verify the RSA part of the RSA+SHA256 signature,
af3d3873 1239 * hence we need to do the SHA256 part ourselves, first */
d9b5841d
LP
1240 TPM2B_DIGEST signature_hash = {
1241 .size = SHA256_DIGEST_SIZE,
1242 };
1243 assert(sizeof(signature_hash.buffer) >= SHA256_DIGEST_SIZE);
1244 sha256_direct(approved_policy->buffer, approved_policy->size, signature_hash.buffer);
1245
1246 TPMT_SIGNATURE policy_signature = {
1247 .sigAlg = TPM2_ALG_RSASSA,
1248 .signature.rsassa = {
1249 .hash = TPM2_ALG_SHA256,
1250 .sig.size = signature_size,
1251 },
1252 };
1253 if (signature_size > sizeof(policy_signature.signature.rsassa.sig.buffer)) {
1254 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Signature larger than buffer.");
1255 goto finish;
1256 }
1257 memcpy(policy_signature.signature.rsassa.sig.buffer, signature_raw, signature_size);
1258
1259 rc = sym_Esys_VerifySignature(
1260 c,
1261 pubkey_handle,
1262 ESYS_TR_NONE,
1263 ESYS_TR_NONE,
1264 ESYS_TR_NONE,
1265 &signature_hash,
1266 &policy_signature,
1267 &check_ticket_buffer);
1268 if (rc != TSS2_RC_SUCCESS) {
1269 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1270 "Failed to validate signature in TPM: %s", sym_Tss2_RC_Decode(rc));
1271 goto finish;
1272 }
1273
1274 check_ticket = check_ticket_buffer;
1275 } else {
1276 /* When enrolling, we pass a NULL ticket */
1277 static const TPMT_TK_VERIFIED check_ticket_null = {
1278 .tag = TPM2_ST_VERIFIED,
1279 .hierarchy = TPM2_RH_OWNER,
1280 };
1281
1282 check_ticket = &check_ticket_null;
1283 }
1284
1285 rc = sym_Esys_PolicyAuthorize(
1286 c,
1287 session,
1288 ESYS_TR_NONE,
1289 ESYS_TR_NONE,
1290 ESYS_TR_NONE,
1291 approved_policy,
1292 /* policyRef= */ &(const TPM2B_NONCE) {},
1293 pubkey_name,
1294 check_ticket);
1295 if (rc != TSS2_RC_SUCCESS) {
1296 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1297 "Failed to push Authorize policy into TPM: %s", sym_Tss2_RC_Decode(rc));
1298 goto finish;
1299 }
395c1d9a
YW
1300#else
1301 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
1302#endif
d9b5841d
LP
1303 }
1304
1305 if (hash_pcr_mask != 0) {
1306 log_debug("Configuring hash-based PCR policy.");
1307
1308 TPML_PCR_SELECTION pcr_selection;
1309 tpm2_pcr_mask_to_selection(hash_pcr_mask, pcr_bank, &pcr_selection);
1310 rc = sym_Esys_PolicyPCR(
1311 c,
1312 session,
1313 ESYS_TR_NONE,
1314 ESYS_TR_NONE,
1315 ESYS_TR_NONE,
1316 NULL,
1317 &pcr_selection);
1318 if (rc != TSS2_RC_SUCCESS) {
1319 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1320 "Failed to add PCR policy to TPM: %s", sym_Tss2_RC_Decode(rc));
1321 goto finish;
1322 }
5e521624
LP
1323 }
1324
2f5a892a 1325 if (use_pin) {
d9b5841d
LP
1326 log_debug("Configuring PIN policy.");
1327
2f5a892a
GG
1328 rc = sym_Esys_PolicyAuthValue(
1329 c,
1330 session,
1331 ESYS_TR_NONE,
1332 ESYS_TR_NONE,
1333 ESYS_TR_NONE);
1334 if (rc != TSS2_RC_SUCCESS) {
1335 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1336 "Failed to add authValue policy to TPM: %s",
1337 sym_Tss2_RC_Decode(rc));
1338 goto finish;
1339 }
1340 }
1341
5e521624
LP
1342 if (DEBUG_LOGGING || ret_policy_digest) {
1343 log_debug("Acquiring policy digest.");
1344
1345 rc = sym_Esys_PolicyGetDigest(
1346 c,
1347 session,
1348 ESYS_TR_NONE,
1349 ESYS_TR_NONE,
1350 ESYS_TR_NONE,
1351 &policy_digest);
1352
1353 if (rc != TSS2_RC_SUCCESS) {
1354 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1355 "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc));
1356 goto finish;
1357 }
1358
1359 if (DEBUG_LOGGING) {
1360 _cleanup_free_ char *h = NULL;
1361
1362 h = hexmem(policy_digest->buffer, policy_digest->size);
1363 if (!h) {
1364 r = log_oom();
1365 goto finish;
1366 }
1367
1368 log_debug("Session policy digest: %s", h);
1369 }
1370 }
1371
1372 if (ret_session) {
1373 *ret_session = session;
1374 session = ESYS_TR_NONE;
1375 }
1376
1377 if (ret_policy_digest)
1378 *ret_policy_digest = TAKE_PTR(policy_digest);
1379
07697bfe 1380 if (ret_pcr_bank)
d9b5841d 1381 *ret_pcr_bank = pcr_bank;
07697bfe 1382
5e521624
LP
1383 r = 0;
1384
1385finish:
bad4c73c 1386 session = tpm2_flush_context_verbose(c, session);
d9b5841d 1387 pubkey_handle = tpm2_flush_context_verbose(c, pubkey_handle);
5e521624
LP
1388 return r;
1389}
1390
d9b5841d
LP
1391int tpm2_seal(const char *device,
1392 uint32_t hash_pcr_mask,
1393 const void *pubkey,
1394 const size_t pubkey_size,
1395 uint32_t pubkey_pcr_mask,
1396 const char *pin,
1397 void **ret_secret,
1398 size_t *ret_secret_size,
1399 void **ret_blob,
1400 size_t *ret_blob_size,
1401 void **ret_pcr_hash,
1402 size_t *ret_pcr_hash_size,
1403 uint16_t *ret_pcr_bank,
1404 uint16_t *ret_primary_alg) {
5e521624 1405
bd860983 1406 _cleanup_(tpm2_context_destroy) Tpm2Context c = {};
5e521624
LP
1407 _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
1408 _cleanup_(Esys_Freep) TPM2B_PRIVATE *private = NULL;
1409 _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
1410 static const TPML_PCR_SELECTION creation_pcr = {};
1411 _cleanup_(erase_and_freep) void *secret = NULL;
1412 _cleanup_free_ void *blob = NULL, *hash = NULL;
da29de23 1413 ESYS_TR primary = ESYS_TR_NONE, session = ESYS_TR_NONE;
692597c8 1414 TPM2B_SENSITIVE_CREATE hmac_sensitive;
2b92a672 1415 TPMI_ALG_PUBLIC primary_alg;
5e521624 1416 TPM2B_PUBLIC hmac_template;
07697bfe 1417 TPMI_ALG_HASH pcr_bank;
5e521624
LP
1418 size_t k, blob_size;
1419 usec_t start;
1420 TSS2_RC rc;
1421 int r;
1422
d9b5841d
LP
1423 assert(pubkey || pubkey_size == 0);
1424
5e521624
LP
1425 assert(ret_secret);
1426 assert(ret_secret_size);
1427 assert(ret_blob);
1428 assert(ret_blob_size);
1429 assert(ret_pcr_hash);
1430 assert(ret_pcr_hash_size);
07697bfe 1431 assert(ret_pcr_bank);
5e521624 1432
d9b5841d
LP
1433 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask));
1434 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));
5e521624
LP
1435
1436 /* So here's what we do here: we connect to the TPM2 chip. It persistently contains a "seed" key that
1437 * is randomized when the TPM2 is first initialized or reset and remains stable across boots. We
2b92a672
LP
1438 * generate a "primary" key pair derived from that (ECC if possible, RSA as fallback). Given the seed
1439 * remains fixed this will result in the same key pair whenever we specify the exact same parameters
1440 * for it. We then create a PCR-bound policy session, which calculates a hash on the current PCR
1441 * values of the indexes we specify. We then generate a randomized key on the host (which is the key
1442 * we actually enroll in the LUKS2 keyslots), which we upload into the TPM2, where it is encrypted
1443 * with the "primary" key, taking the PCR policy session into account. We then download the encrypted
1444 * key from the TPM2 ("sealing") and marshall it into binary form, which is ultimately placed in the
1445 * LUKS2 JSON header.
5e521624
LP
1446 *
1447 * The TPM2 "seed" key and "primary" keys never leave the TPM2 chip (and cannot be extracted at
1448 * all). The random key we enroll in LUKS2 we generate on the host using the Linux random device. It
1449 * is stored in the LUKS2 JSON only in encrypted form with the "primary" key of the TPM2 chip, thus
1450 * binding the unlocking to the TPM2 chip. */
1451
1452 start = now(CLOCK_MONOTONIC);
1453
692597c8
LP
1454 CLEANUP_ERASE(hmac_sensitive);
1455
bad4c73c 1456 r = tpm2_context_init(device, &c);
5e521624
LP
1457 if (r < 0)
1458 return r;
1459
2b92a672 1460 r = tpm2_make_primary(c.esys_context, &primary, 0, &primary_alg);
5e521624
LP
1461 if (r < 0)
1462 return r;
1463
0e15c14f
WR
1464 /* we cannot use the bind key before its created */
1465 r = tpm2_make_encryption_session(c.esys_context, primary, ESYS_TR_NONE, NULL, &session);
da29de23
GG
1466 if (r < 0)
1467 goto finish;
1468
d9b5841d 1469 r = tpm2_make_policy_session(
73096907
LP
1470 c.esys_context,
1471 primary,
1472 session,
1473 TPM2_SE_TRIAL,
d9b5841d 1474 hash_pcr_mask,
73096907 1475 /* pcr_bank= */ UINT16_MAX,
d9b5841d
LP
1476 pubkey, pubkey_size,
1477 pubkey_pcr_mask,
1478 /* signature_json= */ NULL,
73096907
LP
1479 !!pin,
1480 /* ret_session= */ NULL,
1481 &policy_digest,
1482 &pcr_bank);
5e521624
LP
1483 if (r < 0)
1484 goto finish;
1485
1486 /* We use a keyed hash object (i.e. HMAC) to store the secret key we want to use for unlocking the
1487 * LUKS2 volume with. We don't ever use for HMAC/keyed hash operations however, we just use it
1488 * because it's a key type that is universally supported and suitable for symmetric binary blobs. */
1489 hmac_template = (TPM2B_PUBLIC) {
1490 .size = sizeof(TPMT_PUBLIC),
1491 .publicArea = {
1492 .type = TPM2_ALG_KEYEDHASH,
1493 .nameAlg = TPM2_ALG_SHA256,
1494 .objectAttributes = TPMA_OBJECT_FIXEDTPM | TPMA_OBJECT_FIXEDPARENT,
821d94c4 1495 .parameters.keyedHashDetail.scheme.scheme = TPM2_ALG_NULL,
1200777b 1496 .unique.keyedHash.size = SHA256_DIGEST_SIZE,
5e521624
LP
1497 .authPolicy = *policy_digest,
1498 },
1499 };
1500
1501 hmac_sensitive = (TPM2B_SENSITIVE_CREATE) {
1502 .size = sizeof(hmac_sensitive.sensitive),
1503 .sensitive.data.size = 32,
1504 };
0e15c14f
WR
1505 if (pin)
1506 hash_pin(pin, strlen(pin), &hmac_sensitive.sensitive.userAuth);
1507
5e521624
LP
1508 assert(sizeof(hmac_sensitive.sensitive.data.buffer) >= hmac_sensitive.sensitive.data.size);
1509
1510 (void) tpm2_credit_random(c.esys_context);
1511
1512 log_debug("Generating secret key data.");
1513
87cb1ab6 1514 r = crypto_random_bytes(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size);
5e521624
LP
1515 if (r < 0) {
1516 log_error_errno(r, "Failed to generate secret key: %m");
1517 goto finish;
1518 }
1519
1520 log_debug("Creating HMAC key.");
1521
1522 rc = sym_Esys_Create(
1523 c.esys_context,
1524 primary,
da29de23 1525 session, /* use HMAC session to enable parameter encryption */
5e521624
LP
1526 ESYS_TR_NONE,
1527 ESYS_TR_NONE,
1528 &hmac_sensitive,
1529 &hmac_template,
1530 NULL,
1531 &creation_pcr,
1532 &private,
1533 &public,
1534 NULL,
1535 NULL,
1536 NULL);
1537 if (rc != TSS2_RC_SUCCESS) {
1538 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1539 "Failed to generate HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc));
1540 goto finish;
1541 }
1542
1543 secret = memdup(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size);
5e521624
LP
1544 if (!secret) {
1545 r = log_oom();
1546 goto finish;
1547 }
1548
1549 log_debug("Marshalling private and public part of HMAC key.");
1550
1551 k = ALIGN8(sizeof(*private)) + ALIGN8(sizeof(*public)); /* Some roughly sensible start value */
1552 for (;;) {
1553 _cleanup_free_ void *buf = NULL;
1554 size_t offset = 0;
1555
1556 buf = malloc(k);
1557 if (!buf) {
1558 r = log_oom();
1559 goto finish;
1560 }
1561
1562 rc = sym_Tss2_MU_TPM2B_PRIVATE_Marshal(private, buf, k, &offset);
1563 if (rc == TSS2_RC_SUCCESS) {
1564 rc = sym_Tss2_MU_TPM2B_PUBLIC_Marshal(public, buf, k, &offset);
1565 if (rc == TSS2_RC_SUCCESS) {
1566 blob = TAKE_PTR(buf);
1567 blob_size = offset;
1568 break;
1569 }
1570 }
1571 if (rc != TSS2_MU_RC_INSUFFICIENT_BUFFER) {
1572 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1573 "Failed to marshal private/public key: %s", sym_Tss2_RC_Decode(rc));
1574 goto finish;
1575 }
1576
1577 if (k > SIZE_MAX / 2) {
1578 r = log_oom();
1579 goto finish;
1580 }
1581
1582 k *= 2;
1583 }
1584
1585 hash = memdup(policy_digest->buffer, policy_digest->size);
1586 if (!hash)
1587 return log_oom();
1588
5291f26d
ZJS
1589 if (DEBUG_LOGGING)
1590 log_debug("Completed TPM2 key sealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
5e521624
LP
1591
1592 *ret_secret = TAKE_PTR(secret);
1593 *ret_secret_size = hmac_sensitive.sensitive.data.size;
1594 *ret_blob = TAKE_PTR(blob);
1595 *ret_blob_size = blob_size;
1596 *ret_pcr_hash = TAKE_PTR(hash);
1597 *ret_pcr_hash_size = policy_digest->size;
07697bfe 1598 *ret_pcr_bank = pcr_bank;
2b92a672 1599 *ret_primary_alg = primary_alg;
5e521624
LP
1600
1601 r = 0;
1602
1603finish:
bad4c73c
LP
1604 primary = tpm2_flush_context_verbose(c.esys_context, primary);
1605 session = tpm2_flush_context_verbose(c.esys_context, session);
5e521624
LP
1606 return r;
1607}
1608
0254e4d6
AAF
1609#define RETRY_UNSEAL_MAX 30u
1610
d9b5841d
LP
1611int tpm2_unseal(const char *device,
1612 uint32_t hash_pcr_mask,
07697bfe 1613 uint16_t pcr_bank,
d9b5841d
LP
1614 const void *pubkey,
1615 size_t pubkey_size,
1616 uint32_t pubkey_pcr_mask,
1617 JsonVariant *signature,
1618 const char *pin,
2b92a672 1619 uint16_t primary_alg,
5e521624
LP
1620 const void *blob,
1621 size_t blob_size,
1622 const void *known_policy_hash,
1623 size_t known_policy_hash_size,
1624 void **ret_secret,
1625 size_t *ret_secret_size) {
1626
bd860983 1627 _cleanup_(tpm2_context_destroy) Tpm2Context c = {};
da29de23
GG
1628 ESYS_TR primary = ESYS_TR_NONE, session = ESYS_TR_NONE, hmac_session = ESYS_TR_NONE,
1629 hmac_key = ESYS_TR_NONE;
5e521624
LP
1630 _cleanup_(Esys_Freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
1631 _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
1632 _cleanup_(erase_and_freep) char *secret = NULL;
1633 TPM2B_PRIVATE private = {};
1634 TPM2B_PUBLIC public = {};
1635 size_t offset = 0;
1636 TSS2_RC rc;
1637 usec_t start;
1638 int r;
1639
1640 assert(blob);
1641 assert(blob_size > 0);
1642 assert(known_policy_hash_size == 0 || known_policy_hash);
d9b5841d 1643 assert(pubkey_size == 0 || pubkey);
5e521624
LP
1644 assert(ret_secret);
1645 assert(ret_secret_size);
1646
d9b5841d
LP
1647 assert(TPM2_PCR_MASK_VALID(hash_pcr_mask));
1648 assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));
5e521624 1649
1b30720c
LP
1650 r = dlopen_tpm2();
1651 if (r < 0)
1652 return log_error_errno(r, "TPM2 support is not installed.");
1653
5e521624 1654 /* So here's what we do here: We connect to the TPM2 chip. As we do when sealing we generate a
dc176813
ZJS
1655 * "primary" key on the TPM2 chip, with the same parameters as well as a PCR-bound policy session.
1656 * Given we pass the same parameters, this will result in the same "primary" key, and same policy
1657 * hash (the latter of course, only if the PCR values didn't change in between). We unmarshal the
1658 * encrypted key we stored in the LUKS2 JSON token header and upload it into the TPM2, where it is
1659 * decrypted if the seed and the PCR policy were right ("unsealing"). We then download the result,
5e521624
LP
1660 * and use it to unlock the LUKS2 volume. */
1661
1662 start = now(CLOCK_MONOTONIC);
1663
1664 log_debug("Unmarshalling private part of HMAC key.");
1665
1666 rc = sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal(blob, blob_size, &offset, &private);
1667 if (rc != TSS2_RC_SUCCESS)
1668 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1669 "Failed to unmarshal private key: %s", sym_Tss2_RC_Decode(rc));
1670
1671 log_debug("Unmarshalling public part of HMAC key.");
1672
1673 rc = sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal(blob, blob_size, &offset, &public);
1674 if (rc != TSS2_RC_SUCCESS)
1675 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1676 "Failed to unmarshal public key: %s", sym_Tss2_RC_Decode(rc));
1677
bad4c73c 1678 r = tpm2_context_init(device, &c);
5e521624
LP
1679 if (r < 0)
1680 return r;
1681
da29de23
GG
1682 r = tpm2_make_primary(c.esys_context, &primary, primary_alg, NULL);
1683 if (r < 0)
1684 return r;
1685
5e521624
LP
1686 log_debug("Loading HMAC key into TPM.");
1687
0e15c14f
WR
1688 /*
1689 * Nothing sensitive on the bus, no need for encryption. Even if an attacker
1690 * gives you back a different key, the session initiation will fail if a pin
1691 * is provided. If an attacker gives back a bad key, we already lost since
1692 * primary key is not verified and they could attack there as well.
1693 */
5e521624
LP
1694 rc = sym_Esys_Load(
1695 c.esys_context,
1696 primary,
0e15c14f 1697 ESYS_TR_PASSWORD,
5e521624
LP
1698 ESYS_TR_NONE,
1699 ESYS_TR_NONE,
1700 &private,
1701 &public,
1702 &hmac_key);
1703 if (rc != TSS2_RC_SUCCESS) {
2f5a892a
GG
1704 /* If we're in dictionary attack lockout mode, we should see a lockout error here, which we
1705 * need to translate for the caller. */
1706 if (rc == TPM2_RC_LOCKOUT)
1707 r = log_error_errno(
1708 SYNTHETIC_ERRNO(ENOLCK),
1709 "TPM2 device is in dictionary attack lockout mode.");
1710 else
1711 r = log_error_errno(
1712 SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1713 "Failed to load HMAC key in TPM: %s",
1714 sym_Tss2_RC_Decode(rc));
5e521624
LP
1715 goto finish;
1716 }
1717
0e15c14f
WR
1718 r = tpm2_make_encryption_session(c.esys_context, primary, hmac_key, pin, &hmac_session);
1719 if (r < 0)
1720 goto finish;
2f5a892a 1721
0254e4d6
AAF
1722 for (unsigned i = RETRY_UNSEAL_MAX;; i--) {
1723 r = tpm2_make_policy_session(
1724 c.esys_context,
1725 primary,
1726 hmac_session,
1727 TPM2_SE_POLICY,
1728 hash_pcr_mask,
1729 pcr_bank,
1730 pubkey, pubkey_size,
1731 pubkey_pcr_mask,
1732 signature,
1733 !!pin,
1734 &session,
1735 &policy_digest,
1736 /* ret_pcr_bank= */ NULL);
1737 if (r < 0)
1738 goto finish;
2f5a892a 1739
0254e4d6
AAF
1740 /* If we know the policy hash to expect, and it doesn't match, we can shortcut things here, and not
1741 * wait until the TPM2 tells us to go away. */
1742 if (known_policy_hash_size > 0 &&
1743 memcmp_nn(policy_digest->buffer, policy_digest->size, known_policy_hash, known_policy_hash_size) != 0)
1744 return log_error_errno(SYNTHETIC_ERRNO(EPERM),
1745 "Current policy digest does not match stored policy digest, cancelling "
1746 "TPM2 authentication attempt.");
2f5a892a 1747
0254e4d6 1748 log_debug("Unsealing HMAC key.");
5e521624 1749
0254e4d6
AAF
1750 rc = sym_Esys_Unseal(
1751 c.esys_context,
1752 hmac_key,
1753 session,
1754 hmac_session, /* use HMAC session to enable parameter encryption */
1755 ESYS_TR_NONE,
1756 &unsealed);
1757 if (rc == TPM2_RC_PCR_CHANGED && i > 0) {
1758 log_debug("A PCR value changed during the TPM2 policy session, restarting HMAC key unsealing (%u tries left).", i);
1759 session = tpm2_flush_context_verbose(c.esys_context, session);
1760 continue;
1761 }
1762 if (rc != TSS2_RC_SUCCESS) {
1763 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1764 "Failed to unseal HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc));
1765 goto finish;
1766 }
1767
1768 break;
5e521624
LP
1769 }
1770
1771 secret = memdup(unsealed->buffer, unsealed->size);
1772 explicit_bzero_safe(unsealed->buffer, unsealed->size);
1773 if (!secret) {
1774 r = log_oom();
1775 goto finish;
1776 }
1777
5291f26d
ZJS
1778 if (DEBUG_LOGGING)
1779 log_debug("Completed TPM2 key unsealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
5e521624
LP
1780
1781 *ret_secret = TAKE_PTR(secret);
1782 *ret_secret_size = unsealed->size;
1783
1784 r = 0;
1785
1786finish:
bad4c73c
LP
1787 primary = tpm2_flush_context_verbose(c.esys_context, primary);
1788 session = tpm2_flush_context_verbose(c.esys_context, session);
1789 hmac_key = tpm2_flush_context_verbose(c.esys_context, hmac_key);
5e521624
LP
1790 return r;
1791}
1792
1793#endif
1794
1795int tpm2_list_devices(void) {
1796#if HAVE_TPM2
1797 _cleanup_(table_unrefp) Table *t = NULL;
1798 _cleanup_(closedirp) DIR *d = NULL;
1799 int r;
1800
1801 r = dlopen_tpm2();
1802 if (r < 0)
1803 return log_error_errno(r, "TPM2 support is not installed.");
1804
1805 t = table_new("path", "device", "driver");
1806 if (!t)
1807 return log_oom();
1808
1809 d = opendir("/sys/class/tpmrm");
1810 if (!d) {
1811 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to open /sys/class/tpmrm: %m");
1812 if (errno != ENOENT)
1813 return -errno;
1814 } else {
1815 for (;;) {
1816 _cleanup_free_ char *device_path = NULL, *device = NULL, *driver_path = NULL, *driver = NULL, *node = NULL;
1817 struct dirent *de;
1818
1819 de = readdir_no_dot(d);
1820 if (!de)
1821 break;
1822
1823 device_path = path_join("/sys/class/tpmrm", de->d_name, "device");
1824 if (!device_path)
1825 return log_oom();
1826
1827 r = readlink_malloc(device_path, &device);
1828 if (r < 0)
1829 log_debug_errno(r, "Failed to read device symlink %s, ignoring: %m", device_path);
1830 else {
1831 driver_path = path_join(device_path, "driver");
1832 if (!driver_path)
1833 return log_oom();
1834
1835 r = readlink_malloc(driver_path, &driver);
1836 if (r < 0)
1837 log_debug_errno(r, "Failed to read driver symlink %s, ignoring: %m", driver_path);
1838 }
1839
1840 node = path_join("/dev", de->d_name);
1841 if (!node)
1842 return log_oom();
1843
1844 r = table_add_many(
1845 t,
1846 TABLE_PATH, node,
1847 TABLE_STRING, device ? last_path_component(device) : NULL,
1848 TABLE_STRING, driver ? last_path_component(driver) : NULL);
1849 if (r < 0)
1850 return table_log_add_error(r);
1851 }
1852 }
1853
1854 if (table_get_rows(t) <= 1) {
1855 log_info("No suitable TPM2 devices found.");
1856 return 0;
1857 }
1858
1859 r = table_print(t, stdout);
1860 if (r < 0)
1861 return log_error_errno(r, "Failed to show device table: %m");
1862
1863 return 0;
1864#else
1865 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1866 "TPM2 not supported on this build.");
1867#endif
1868}
1869
1870int tpm2_find_device_auto(
1871 int log_level, /* log level when no device is found */
1872 char **ret) {
1873#if HAVE_TPM2
1874 _cleanup_(closedirp) DIR *d = NULL;
1875 int r;
1876
1877 r = dlopen_tpm2();
1878 if (r < 0)
1879 return log_error_errno(r, "TPM2 support is not installed.");
1880
1881 d = opendir("/sys/class/tpmrm");
1882 if (!d) {
1883 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
1884 "Failed to open /sys/class/tpmrm: %m");
1885 if (errno != ENOENT)
1886 return -errno;
1887 } else {
1888 _cleanup_free_ char *node = NULL;
1889
1890 for (;;) {
1891 struct dirent *de;
1892
1893 de = readdir_no_dot(d);
1894 if (!de)
1895 break;
1896
1897 if (node)
1898 return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ),
1899 "More than one TPM2 (tpmrm) device found.");
1900
1901 node = path_join("/dev", de->d_name);
1902 if (!node)
1903 return log_oom();
1904 }
1905
1906 if (node) {
1907 *ret = TAKE_PTR(node);
1908 return 0;
1909 }
1910 }
1911
1912 return log_full_errno(log_level, SYNTHETIC_ERRNO(ENODEV), "No TPM2 (tpmrm) device found.");
1913#else
1914 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1915 "TPM2 not supported on this build.");
1916#endif
1917}
1918
15c591d1
LP
1919#if HAVE_TPM2
1920int tpm2_extend_bytes(
1921 ESYS_CONTEXT *c,
1922 char **banks,
1923 unsigned pcr_index,
1924 const void *data,
9885c874
LP
1925 size_t data_size,
1926 const void *secret,
1927 size_t secret_size) {
15c591d1
LP
1928
1929#if HAVE_OPENSSL
1930 TPML_DIGEST_VALUES values = {};
1931 TSS2_RC rc;
1932
1933 assert(c);
9885c874
LP
1934 assert(data || data_size == 0);
1935 assert(secret || secret_size == 0);
1936
1937 if (data_size == SIZE_MAX)
1938 data_size = strlen(data);
1939 if (secret_size == SIZE_MAX)
1940 secret_size = strlen(secret);
15c591d1
LP
1941
1942 if (pcr_index >= TPM2_PCRS_MAX)
1943 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Can't measure into unsupported PCR %u, refusing.", pcr_index);
1944
1945 if (strv_isempty(banks))
1946 return 0;
1947
1948 STRV_FOREACH(bank, banks) {
1949 const EVP_MD *implementation;
1950 int id;
1951
1952 assert_se(implementation = EVP_get_digestbyname(*bank));
1953
1954 if (values.count >= ELEMENTSOF(values.digests))
1955 return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "Too many banks selected.");
1956
1957 if ((size_t) EVP_MD_size(implementation) > sizeof(values.digests[values.count].digest))
1958 return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "Hash result too large for TPM2.");
1959
7bfe0a48 1960 id = tpm2_hash_alg_from_string(EVP_MD_name(implementation));
15c591d1
LP
1961 if (id < 0)
1962 return log_error_errno(id, "Can't map hash name to TPM2.");
1963
1964 values.digests[values.count].hashAlg = id;
1965
9885c874
LP
1966 /* So here's a twist: sometimes we want to measure secrets (e.g. root file system volume
1967 * key), but we'd rather not leak a literal hash of the secret to the TPM (given that the
1968 * wire is unprotected, and some other subsystem might use the simple, literal hash of the
1969 * secret for other purposes, maybe because it needs a shorter secret derived from it for
1970 * some unrelated purpose, who knows). Hence we instead measure an HMAC signature of a
1971 * private non-secret string instead. */
1972 if (secret_size > 0) {
1973 if (!HMAC(implementation, secret, secret_size, data, data_size, (unsigned char*) &values.digests[values.count].digest, NULL))
1974 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to calculate HMAC of data to measure.");
1975 } else if (EVP_Digest(data, data_size, (unsigned char*) &values.digests[values.count].digest, NULL, implementation, NULL) != 1)
1976 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash data to measure.");
15c591d1
LP
1977
1978 values.count++;
1979 }
1980
1981 rc = sym_Esys_PCR_Extend(
1982 c,
1983 ESYS_TR_PCR0 + pcr_index,
1984 ESYS_TR_PASSWORD,
1985 ESYS_TR_NONE,
1986 ESYS_TR_NONE,
1987 &values);
1988 if (rc != TSS2_RC_SUCCESS)
1989 return log_error_errno(
1990 SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1991 "Failed to measure into PCR %u: %s",
1992 pcr_index,
1993 sym_Tss2_RC_Decode(rc));
1994
1995 return 0;
1996#else
1997 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1998 "OpenSSL not supported on this build.");
1999#endif
2000}
2001#endif
2002
5e521624 2003int tpm2_parse_pcrs(const char *s, uint32_t *ret) {
99534007 2004 const char *p = ASSERT_PTR(s);
5e521624
LP
2005 uint32_t mask = 0;
2006 int r;
2007
d57f6340
LP
2008 if (isempty(s)) {
2009 *ret = 0;
2010 return 0;
2011 }
2012
a1788a69
LP
2013 /* Parses a "," or "+" separated list of PCR indexes. We support "," since this is a list after all,
2014 * and most other tools expect comma separated PCR specifications. We also support "+" since in
2015 * /etc/crypttab the "," is already used to separate options, hence a different separator is nice to
2016 * avoid escaping. */
5e521624
LP
2017
2018 for (;;) {
2019 _cleanup_free_ char *pcr = NULL;
2020 unsigned n;
2021
a1788a69 2022 r = extract_first_word(&p, &pcr, ",+", EXTRACT_DONT_COALESCE_SEPARATORS);
5e521624
LP
2023 if (r == 0)
2024 break;
2025 if (r < 0)
2026 return log_error_errno(r, "Failed to parse PCR list: %s", s);
2027
2028 r = safe_atou(pcr, &n);
2029 if (r < 0)
2030 return log_error_errno(r, "Failed to parse PCR number: %s", pcr);
2031 if (n >= TPM2_PCRS_MAX)
2032 return log_error_errno(SYNTHETIC_ERRNO(ERANGE),
2033 "PCR number out of range (valid range 0…23): %u", n);
2034
2035 mask |= UINT32_C(1) << n;
2036 }
2037
2038 *ret = mask;
2039 return 0;
2040}
2041
4436081e
LP
2042int tpm2_make_pcr_json_array(uint32_t pcr_mask, JsonVariant **ret) {
2043 _cleanup_(json_variant_unrefp) JsonVariant *a = NULL;
2044 JsonVariant* pcr_array[TPM2_PCRS_MAX];
2045 unsigned n_pcrs = 0;
2046 int r;
2047
2048 for (size_t i = 0; i < ELEMENTSOF(pcr_array); i++) {
2049 if ((pcr_mask & (UINT32_C(1) << i)) == 0)
2050 continue;
2051
2052 r = json_variant_new_integer(pcr_array + n_pcrs, i);
2053 if (r < 0)
2054 goto finish;
2055
2056 n_pcrs++;
2057 }
2058
2059 r = json_variant_new_array(&a, pcr_array, n_pcrs);
2060 if (r < 0)
2061 goto finish;
2062
2063 if (ret)
2064 *ret = TAKE_PTR(a);
2065 r = 0;
2066
2067finish:
2068 json_variant_unref_many(pcr_array, n_pcrs);
2069 return r;
2070}
8de8ec88
LP
2071
2072int tpm2_parse_pcr_json_array(JsonVariant *v, uint32_t *ret) {
2073 JsonVariant *e;
2074 uint32_t mask = 0;
2075
2076 if (!json_variant_is_array(v))
2077 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR array is not a JSON array.");
2078
2079 JSON_VARIANT_ARRAY_FOREACH(e, v) {
2080 uint64_t u;
2081
2082 if (!json_variant_is_unsigned(e))
2083 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR is not an unsigned integer.");
2084
2085 u = json_variant_unsigned(e);
2086 if (u >= TPM2_PCRS_MAX)
2087 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR number out of range: %" PRIu64, u);
2088
2089 mask |= UINT32_C(1) << u;
2090 }
2091
2092 if (ret)
2093 *ret = mask;
2094
2095 return 0;
2096}
4436081e 2097
5e521624
LP
2098int tpm2_make_luks2_json(
2099 int keyslot,
f0f4fcae 2100 uint32_t hash_pcr_mask,
07697bfe 2101 uint16_t pcr_bank,
f0f4fcae
LP
2102 const void *pubkey,
2103 size_t pubkey_size,
2104 uint32_t pubkey_pcr_mask,
2b92a672 2105 uint16_t primary_alg,
5e521624
LP
2106 const void *blob,
2107 size_t blob_size,
2108 const void *policy_hash,
2109 size_t policy_hash_size,
aae6eb96
WR
2110 const void *salt,
2111 size_t salt_size,
6c7a1681 2112 TPM2Flags flags,
5e521624
LP
2113 JsonVariant **ret) {
2114
f0f4fcae 2115 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *hmj = NULL, *pkmj = NULL;
5e521624 2116 _cleanup_free_ char *keyslot_as_string = NULL;
5e521624
LP
2117 int r;
2118
2119 assert(blob || blob_size == 0);
2120 assert(policy_hash || policy_hash_size == 0);
f0f4fcae 2121 assert(pubkey || pubkey_size == 0);
5e521624
LP
2122
2123 if (asprintf(&keyslot_as_string, "%i", keyslot) < 0)
2124 return -ENOMEM;
2125
f0f4fcae 2126 r = tpm2_make_pcr_json_array(hash_pcr_mask, &hmj);
5e521624 2127 if (r < 0)
4436081e 2128 return r;
5e521624 2129
f0f4fcae
LP
2130 if (pubkey_pcr_mask != 0) {
2131 r = tpm2_make_pcr_json_array(pubkey_pcr_mask, &pkmj);
2132 if (r < 0)
2133 return r;
2134 }
2135
2136 /* Note: We made the mistake of using "-" in the field names, which isn't particular compatible with
2137 * other programming languages. Let's not make things worse though, i.e. future additions to the JSON
2138 * object should use "_" rather than "-" in field names. */
2139
5e521624
LP
2140 r = json_build(&v,
2141 JSON_BUILD_OBJECT(
0cdf6b14 2142 JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-tpm2")),
5e521624
LP
2143 JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))),
2144 JSON_BUILD_PAIR("tpm2-blob", JSON_BUILD_BASE64(blob, blob_size)),
f0f4fcae 2145 JSON_BUILD_PAIR("tpm2-pcrs", JSON_BUILD_VARIANT(hmj)),
7bfe0a48
DS
2146 JSON_BUILD_PAIR_CONDITION(!!tpm2_hash_alg_to_string(pcr_bank), "tpm2-pcr-bank", JSON_BUILD_STRING(tpm2_hash_alg_to_string(pcr_bank))),
2147 JSON_BUILD_PAIR_CONDITION(!!tpm2_asym_alg_to_string(primary_alg), "tpm2-primary-alg", JSON_BUILD_STRING(tpm2_asym_alg_to_string(primary_alg))),
6c7a1681 2148 JSON_BUILD_PAIR("tpm2-policy-hash", JSON_BUILD_HEX(policy_hash, policy_hash_size)),
f0f4fcae
LP
2149 JSON_BUILD_PAIR("tpm2-pin", JSON_BUILD_BOOLEAN(flags & TPM2_FLAGS_USE_PIN)),
2150 JSON_BUILD_PAIR_CONDITION(pubkey_pcr_mask != 0, "tpm2_pubkey_pcrs", JSON_BUILD_VARIANT(pkmj)),
aae6eb96
WR
2151 JSON_BUILD_PAIR_CONDITION(pubkey_pcr_mask != 0, "tpm2_pubkey", JSON_BUILD_BASE64(pubkey, pubkey_size)),
2152 JSON_BUILD_PAIR_CONDITION(salt, "tpm2_salt", JSON_BUILD_BASE64(salt, salt_size))));
5e521624
LP
2153 if (r < 0)
2154 return r;
2155
2156 if (ret)
2157 *ret = TAKE_PTR(v);
2158
2159 return keyslot;
2160}
07697bfe 2161
fdf6c27c
LP
2162int tpm2_parse_luks2_json(
2163 JsonVariant *v,
2164 int *ret_keyslot,
2165 uint32_t *ret_hash_pcr_mask,
2166 uint16_t *ret_pcr_bank,
2167 void **ret_pubkey,
2168 size_t *ret_pubkey_size,
2169 uint32_t *ret_pubkey_pcr_mask,
2170 uint16_t *ret_primary_alg,
2171 void **ret_blob,
2172 size_t *ret_blob_size,
2173 void **ret_policy_hash,
2174 size_t *ret_policy_hash_size,
aae6eb96
WR
2175 void **ret_salt,
2176 size_t *ret_salt_size,
fdf6c27c
LP
2177 TPM2Flags *ret_flags) {
2178
aae6eb96
WR
2179 _cleanup_free_ void *blob = NULL, *policy_hash = NULL, *pubkey = NULL, *salt = NULL;
2180 size_t blob_size = 0, policy_hash_size = 0, pubkey_size = 0, salt_size = 0;
fdf6c27c
LP
2181 uint32_t hash_pcr_mask = 0, pubkey_pcr_mask = 0;
2182 uint16_t primary_alg = TPM2_ALG_ECC; /* ECC was the only supported algorithm in systemd < 250, use that as implied default, for compatibility */
2183 uint16_t pcr_bank = UINT16_MAX; /* default: pick automatically */
2184 int r, keyslot = -1;
2185 TPM2Flags flags = 0;
2186 JsonVariant *w;
2187
2188 assert(v);
2189
2190 if (ret_keyslot) {
2191 keyslot = cryptsetup_get_keyslot_from_token(v);
2192 if (keyslot < 0) {
2193 /* Return a recognizable error when parsing this field, so that callers can handle parsing
2194 * errors of the keyslots field gracefully, since it's not 'owned' by us, but by the LUKS2
2195 * spec */
2196 log_debug_errno(keyslot, "Failed to extract keyslot index from TPM2 JSON data token, skipping: %m");
2197 return -EUCLEAN;
2198 }
2199 }
2200
2201 w = json_variant_by_key(v, "tpm2-pcrs");
2202 if (!w)
2203 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-pcrs' field.");
2204
2205 r = tpm2_parse_pcr_json_array(w, &hash_pcr_mask);
2206 if (r < 0)
2207 return log_debug_errno(r, "Failed to parse TPM2 PCR mask: %m");
2208
2209 /* The bank field is optional, since it was added in systemd 250 only. Before the bank was hardcoded
2210 * to SHA256. */
2211 w = json_variant_by_key(v, "tpm2-pcr-bank");
2212 if (w) {
2213 /* The PCR bank field is optional */
2214
2215 if (!json_variant_is_string(w))
2216 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PCR bank is not a string.");
2217
7bfe0a48 2218 r = tpm2_hash_alg_from_string(json_variant_string(w));
fdf6c27c
LP
2219 if (r < 0)
2220 return log_debug_errno(r, "TPM2 PCR bank invalid or not supported: %s", json_variant_string(w));
2221
2222 pcr_bank = r;
2223 }
2224
2225 /* The primary key algorithm field is optional, since it was also added in systemd 250 only. Before
2226 * the algorithm was hardcoded to ECC. */
2227 w = json_variant_by_key(v, "tpm2-primary-alg");
2228 if (w) {
2229 /* The primary key algorithm is optional */
2230
2231 if (!json_variant_is_string(w))
2232 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 primary key algorithm is not a string.");
2233
7bfe0a48 2234 r = tpm2_asym_alg_from_string(json_variant_string(w));
fdf6c27c 2235 if (r < 0)
7bfe0a48 2236 return log_debug_errno(r, "TPM2 asymmetric algorithm invalid or not supported: %s", json_variant_string(w));
fdf6c27c
LP
2237
2238 primary_alg = r;
2239 }
2240
2241 w = json_variant_by_key(v, "tpm2-blob");
2242 if (!w)
2243 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-blob' field.");
2244
2245 r = json_variant_unbase64(w, &blob, &blob_size);
2246 if (r < 0)
2247 return log_debug_errno(r, "Invalid base64 data in 'tpm2-blob' field.");
2248
2249 w = json_variant_by_key(v, "tpm2-policy-hash");
2250 if (!w)
2251 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 token data lacks 'tpm2-policy-hash' field.");
2252
2253 r = json_variant_unhex(w, &policy_hash, &policy_hash_size);
2254 if (r < 0)
2255 return log_debug_errno(r, "Invalid base64 data in 'tpm2-policy-hash' field.");
2256
2257 w = json_variant_by_key(v, "tpm2-pin");
2258 if (w) {
2259 if (!json_variant_is_boolean(w))
2260 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 PIN policy is not a boolean.");
2261
2262 SET_FLAG(flags, TPM2_FLAGS_USE_PIN, json_variant_boolean(w));
2263 }
2264
aae6eb96
WR
2265 w = json_variant_by_key(v, "tpm2_salt");
2266 if (w) {
2267 r = json_variant_unbase64(w, &salt, &salt_size);
2268 if (r < 0)
2269 return log_debug_errno(r, "Invalid base64 data in 'tpm2_salt' field.");
2270 }
2271
fdf6c27c
LP
2272 w = json_variant_by_key(v, "tpm2_pubkey_pcrs");
2273 if (w) {
2274 r = tpm2_parse_pcr_json_array(w, &pubkey_pcr_mask);
2275 if (r < 0)
2276 return r;
2277 }
2278
2279 w = json_variant_by_key(v, "tpm2_pubkey");
2280 if (w) {
2281 r = json_variant_unbase64(w, &pubkey, &pubkey_size);
2282 if (r < 0)
2283 return log_debug_errno(r, "Failed to decode PCR public key.");
2284 } else if (pubkey_pcr_mask != 0)
2285 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Public key PCR mask set, but not public key included in JSON data, refusing.");
2286
2287 if (ret_keyslot)
2288 *ret_keyslot = keyslot;
2289 if (ret_hash_pcr_mask)
2290 *ret_hash_pcr_mask = hash_pcr_mask;
2291 if (ret_pcr_bank)
2292 *ret_pcr_bank = pcr_bank;
2293 if (ret_pubkey)
2294 *ret_pubkey = TAKE_PTR(pubkey);
2295 if (ret_pubkey_size)
2296 *ret_pubkey_size = pubkey_size;
2297 if (ret_pubkey_pcr_mask)
2298 *ret_pubkey_pcr_mask = pubkey_pcr_mask;
2299 if (ret_primary_alg)
2300 *ret_primary_alg = primary_alg;
2301 if (ret_blob)
2302 *ret_blob = TAKE_PTR(blob);
2303 if (ret_blob_size)
2304 *ret_blob_size = blob_size;
2305 if (ret_policy_hash)
2306 *ret_policy_hash = TAKE_PTR(policy_hash);
2307 if (ret_policy_hash_size)
2308 *ret_policy_hash_size = policy_hash_size;
aae6eb96
WR
2309 if (ret_salt)
2310 *ret_salt = TAKE_PTR(salt);
2311 if (ret_salt_size)
2312 *ret_salt_size = salt_size;
fdf6c27c
LP
2313 if (ret_flags)
2314 *ret_flags = flags;
2315
2316 return 0;
2317}
2318
7bfe0a48
DS
2319const char *tpm2_hash_alg_to_string(uint16_t alg) {
2320 if (alg == TPM2_ALG_SHA1)
07697bfe 2321 return "sha1";
7bfe0a48 2322 if (alg == TPM2_ALG_SHA256)
98193c39 2323 return "sha256";
7bfe0a48 2324 if (alg == TPM2_ALG_SHA384)
98193c39 2325 return "sha384";
7bfe0a48 2326 if (alg == TPM2_ALG_SHA512)
98193c39 2327 return "sha512";
07697bfe
LP
2328 return NULL;
2329}
2330
7bfe0a48
DS
2331int tpm2_hash_alg_from_string(const char *alg) {
2332 if (strcaseeq_ptr(alg, "sha1"))
07697bfe 2333 return TPM2_ALG_SHA1;
7bfe0a48 2334 if (strcaseeq_ptr(alg, "sha256"))
98193c39 2335 return TPM2_ALG_SHA256;
7bfe0a48 2336 if (strcaseeq_ptr(alg, "sha384"))
98193c39 2337 return TPM2_ALG_SHA384;
7bfe0a48 2338 if (strcaseeq_ptr(alg, "sha512"))
98193c39 2339 return TPM2_ALG_SHA512;
07697bfe
LP
2340 return -EINVAL;
2341}
2b92a672 2342
7bfe0a48 2343const char *tpm2_asym_alg_to_string(uint16_t alg) {
2b92a672
LP
2344 if (alg == TPM2_ALG_ECC)
2345 return "ecc";
2346 if (alg == TPM2_ALG_RSA)
2347 return "rsa";
2348 return NULL;
2349}
2350
7bfe0a48 2351int tpm2_asym_alg_from_string(const char *alg) {
f92ebc86 2352 if (strcaseeq_ptr(alg, "ecc"))
2b92a672 2353 return TPM2_ALG_ECC;
f92ebc86 2354 if (strcaseeq_ptr(alg, "rsa"))
2b92a672
LP
2355 return TPM2_ALG_RSA;
2356 return -EINVAL;
2357}
ba578556
LP
2358
2359Tpm2Support tpm2_support(void) {
2360 Tpm2Support support = TPM2_SUPPORT_NONE;
2361 int r;
2362
44d5dd65
LP
2363 if (detect_container() <= 0) {
2364 /* Check if there's a /dev/tpmrm* device via sysfs. If we run in a container we likely just
2365 * got the host sysfs mounted. Since devices are generally not virtualized for containers,
2366 * let's assume containers never have a TPM, at least for now. */
2367
db55bbf2 2368 r = dir_is_empty("/sys/class/tpmrm", /* ignore_hidden_or_backup= */ false);
44d5dd65
LP
2369 if (r < 0) {
2370 if (r != -ENOENT)
2371 log_debug_errno(r, "Unable to test whether /sys/class/tpmrm/ exists and is populated, assuming it is not: %m");
2372 } else if (r == 0) /* populated! */
300bba79
DDM
2373 support |= TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_DRIVER;
2374 else
2375 /* If the directory exists but is empty, we know the subsystem is enabled but no
2376 * driver has been loaded yet. */
2377 support |= TPM2_SUPPORT_SUBSYSTEM;
44d5dd65 2378 }
ba578556
LP
2379
2380 if (efi_has_tpm2())
2381 support |= TPM2_SUPPORT_FIRMWARE;
2382
2383#if HAVE_TPM2
2384 support |= TPM2_SUPPORT_SYSTEM;
2385#endif
2386
2387 return support;
2388}
222a951f
LP
2389
2390int tpm2_parse_pcr_argument(const char *arg, uint32_t *mask) {
2391 uint32_t m;
2392 int r;
2393
2394 assert(mask);
2395
2396 /* For use in getopt_long() command line parsers: merges masks specified on the command line */
2397
2398 if (isempty(arg)) {
2399 *mask = 0;
2400 return 0;
2401 }
2402
2403 r = tpm2_parse_pcrs(arg, &m);
2404 if (r < 0)
2405 return r;
2406
2407 if (*mask == UINT32_MAX)
2408 *mask = m;
2409 else
2410 *mask |= m;
2411
2412 return 0;
2413}
6a0779cb
LP
2414
2415int tpm2_load_pcr_signature(const char *path, JsonVariant **ret) {
2416 _cleanup_free_ char *discovered_path = NULL;
2417 _cleanup_fclose_ FILE *f = NULL;
2418 int r;
2419
2420 /* Tries to load a JSON PCR signature file. Takes an absolute path, a simple file name or NULL. In
2421 * the latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
2422
2423 if (!path)
2424 path = "tpm2-pcr-signature.json";
2425
2426 r = search_and_fopen(path, "re", NULL, (const char**) CONF_PATHS_STRV("systemd"), &f, &discovered_path);
2427 if (r < 0)
2428 return log_debug_errno(r, "Failed to find TPM PCR signature file '%s': %m", path);
2429
2430 r = json_parse_file(f, discovered_path, 0, ret, NULL, NULL);
2431 if (r < 0)
2432 return log_debug_errno(r, "Failed to parse TPM PCR signature JSON object '%s': %m", discovered_path);
2433
2434 return 0;
2435}
2436
2437int tpm2_load_pcr_public_key(const char *path, void **ret_pubkey, size_t *ret_pubkey_size) {
2438 _cleanup_free_ char *discovered_path = NULL;
2439 _cleanup_fclose_ FILE *f = NULL;
2440 int r;
2441
2442 /* Tries to load a PCR public key file. Takes an absolute path, a simple file name or NULL. In the
2443 * latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */
2444
2445 if (!path)
2446 path = "tpm2-pcr-public-key.pem";
2447
2448 r = search_and_fopen(path, "re", NULL, (const char**) CONF_PATHS_STRV("systemd"), &f, &discovered_path);
2449 if (r < 0)
2450 return log_debug_errno(r, "Failed to find TPM PCR public key file '%s': %m", path);
2451
2452 r = read_full_stream(f, (char**) ret_pubkey, ret_pubkey_size);
2453 if (r < 0)
2454 return log_debug_errno(r, "Failed to load TPM PCR public key PEM file '%s': %m", discovered_path);
2455
2456 return 0;
2457}
4d5cc0d4
LP
2458
2459int pcr_mask_to_string(uint32_t mask, char **ret) {
2460 _cleanup_free_ char *buf = NULL;
2461 int r;
2462
2463 assert(ret);
2464
2465 for (unsigned i = 0; i < TPM2_PCRS_MAX; i++) {
2466 if (!(mask & (UINT32_C(1) << i)))
2467 continue;
2468
2469 r = strextendf_with_separator(&buf, "+", "%u", i);
2470 if (r < 0)
2471 return r;
2472 }
2473
2474 *ret = TAKE_PTR(buf);
2475 return 0;
2476}
aae6eb96
WR
2477
2478#define PBKDF2_HMAC_SHA256_ITERATIONS 10000
2479
2480/*
2481 * Implements PBKDF2 HMAC SHA256 for a derived keylen of 32
2482 * bytes and for PBKDF2_HMAC_SHA256_ITERATIONS count.
2483 * I found the wikipedia entry relevant and it contains links to
2484 * relevant RFCs:
2485 * - https://en.wikipedia.org/wiki/PBKDF2
2486 * - https://www.rfc-editor.org/rfc/rfc2898#section-5.2
2487 */
2488int tpm2_util_pbkdf2_hmac_sha256(const void *pass,
2489 size_t passlen,
2490 const void *salt,
2491 size_t saltlen,
2492 uint8_t ret_key[static SHA256_DIGEST_SIZE]) {
2493
2494 uint8_t _cleanup_(erase_and_freep) *buffer = NULL;
2495 uint8_t u[SHA256_DIGEST_SIZE];
2496
2497 /* To keep this simple, since derived KeyLen (dkLen in docs)
2498 * Is the same as the hash output, we don't need multiple
2499 * blocks. Part of the algorithm is to add the block count
2500 * in, but this can be hardcoded to 1.
2501 */
2502 static const uint8_t block_cnt[] = { 0, 0, 0, 1 };
2503
2504 assert (saltlen > 0);
2505 assert (saltlen <= (SIZE_MAX - sizeof(block_cnt)));
2506 assert (passlen > 0);
2507
2508 /*
2509 * Build a buffer of salt + block_cnt and hmac_sha256 it we
2510 * do this as we don't have a context builder for HMAC_SHA256.
2511 */
2512 buffer = malloc(saltlen + sizeof(block_cnt));
2513 if (!buffer)
2514 return -ENOMEM;
2515
2516 memcpy(buffer, salt, saltlen);
2517 memcpy(&buffer[saltlen], block_cnt, sizeof(block_cnt));
2518
2519 hmac_sha256(pass, passlen, buffer, saltlen + sizeof(block_cnt), u);
2520
2521 /* dk needs to be an unmodified u as u gets modified in the loop */
2522 memcpy(ret_key, u, SHA256_DIGEST_SIZE);
2523 uint8_t *dk = ret_key;
2524
2525 for (size_t i = 1; i < PBKDF2_HMAC_SHA256_ITERATIONS; i++) {
2526 hmac_sha256(pass, passlen, u, sizeof(u), u);
2527
2528 for (size_t j=0; j < sizeof(u); j++)
2529 dk[j] ^= u[j];
2530 }
2531
2532 return 0;
2533}