1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include "efi-api.h"
4 #include "extract-word.h"
5 #include "parse-util.h"
6 #include "stat-util.h"
7 #include "tpm2-util.h"
8 #include "virt.h"
9 
10 #if HAVE_TPM2
11 #include "alloc-util.h"
12 #include "dirent-util.h"
13 #include "dlfcn-util.h"
14 #include "fd-util.h"
15 #include "format-table.h"
16 #include "fs-util.h"
17 #include "hexdecoct.h"
18 #include "memory-util.h"
19 #include "random-util.h"
20 #include "sha256.h"
21 #include "time-util.h"
22 
23 static void *libtss2_esys_dl = NULL;
24 static void *libtss2_rc_dl = NULL;
25 static void *libtss2_mu_dl = NULL;
26 
27 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;
28 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;
29 void (*sym_Esys_Finalize)(ESYS_CONTEXT **context) = NULL;
30 TSS2_RC (*sym_Esys_FlushContext)(ESYS_CONTEXT *esysContext, ESYS_TR flushHandle) = NULL;
31 void (*sym_Esys_Free)(void *ptr) = NULL;
32 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);
33 TSS2_RC (*sym_Esys_GetRandom)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, UINT16 bytesRequested, TPM2B_DIGEST **randomBytes) = NULL;
34 TSS2_RC (*sym_Esys_Initialize)(ESYS_CONTEXT **esys_context,  TSS2_TCTI_CONTEXT *tcti, TSS2_ABI_VERSION *abiVersion) = NULL;
35 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;
36 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);
37 TSS2_RC (*sym_Esys_PolicyAuthValue)(ESYS_CONTEXT *esysContext, ESYS_TR policySession, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3) = NULL;
38 TSS2_RC (*sym_Esys_PolicyGetDigest)(ESYS_CONTEXT *esysContext, ESYS_TR policySession, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, TPM2B_DIGEST **policyDigest) = NULL;
39 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;
40 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;
41 TSS2_RC (*sym_Esys_Startup)(ESYS_CONTEXT *esysContext, TPM2_SU startupType) = NULL;
42 TSS2_RC (*sym_Esys_TRSess_SetAttributes)(ESYS_CONTEXT *esysContext, ESYS_TR session, TPMA_SESSION flags, TPMA_SESSION mask);
43 TSS2_RC (*sym_Esys_TR_SetAuth)(ESYS_CONTEXT *esysContext, ESYS_TR handle, TPM2B_AUTH const *authValue) = NULL;
44 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;
45 
46 const char* (*sym_Tss2_RC_Decode)(TSS2_RC rc) = NULL;
47 
48 TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Marshal)(TPM2B_PRIVATE const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL;
49 TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PRIVATE  *dest) = NULL;
50 TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Marshal)(TPM2B_PUBLIC const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL;
51 TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PUBLIC *dest) = NULL;
52 
dlopen_tpm2(void)53 int dlopen_tpm2(void) {
54         int r;
55 
56         r = dlopen_many_sym_or_warn(
57                         &libtss2_esys_dl, "libtss2-esys.so.0", LOG_DEBUG,
58                         DLSYM_ARG(Esys_Create),
59                         DLSYM_ARG(Esys_CreatePrimary),
60                         DLSYM_ARG(Esys_Finalize),
61                         DLSYM_ARG(Esys_FlushContext),
62                         DLSYM_ARG(Esys_Free),
63                         DLSYM_ARG(Esys_GetCapability),
64                         DLSYM_ARG(Esys_GetRandom),
65                         DLSYM_ARG(Esys_Initialize),
66                         DLSYM_ARG(Esys_Load),
67                         DLSYM_ARG(Esys_PCR_Read),
68                         DLSYM_ARG(Esys_PolicyAuthValue),
69                         DLSYM_ARG(Esys_PolicyGetDigest),
70                         DLSYM_ARG(Esys_PolicyPCR),
71                         DLSYM_ARG(Esys_StartAuthSession),
72                         DLSYM_ARG(Esys_Startup),
73                         DLSYM_ARG(Esys_TRSess_SetAttributes),
74                         DLSYM_ARG(Esys_TR_SetAuth),
75                         DLSYM_ARG(Esys_Unseal));
76         if (r < 0)
77                 return r;
78 
79         r = dlopen_many_sym_or_warn(
80                         &libtss2_rc_dl, "libtss2-rc.so.0", LOG_DEBUG,
81                         DLSYM_ARG(Tss2_RC_Decode));
82         if (r < 0)
83                 return r;
84 
85         return dlopen_many_sym_or_warn(
86                         &libtss2_mu_dl, "libtss2-mu.so.0", LOG_DEBUG,
87                         DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Marshal),
88                         DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Unmarshal),
89                         DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Marshal),
90                         DLSYM_ARG(Tss2_MU_TPM2B_PUBLIC_Unmarshal));
91 }
92 
93 struct tpm2_context {
94         ESYS_CONTEXT *esys_context;
95         void *tcti_dl;
96         TSS2_TCTI_CONTEXT *tcti_context;
97 };
98 
tpm2_context_destroy(struct tpm2_context * c)99 static void tpm2_context_destroy(struct tpm2_context *c) {
100         assert(c);
101 
102         if (c->esys_context)
103                 sym_Esys_Finalize(&c->esys_context);
104 
105         c->tcti_context = mfree(c->tcti_context);
106 
107         if (c->tcti_dl) {
108                 dlclose(c->tcti_dl);
109                 c->tcti_dl = NULL;
110         }
111 }
112 
Esys_Finalize_wrapper(ESYS_CONTEXT ** c)113 static inline void Esys_Finalize_wrapper(ESYS_CONTEXT **c) {
114         /* A wrapper around Esys_Finalize() for use with _cleanup_(). Only reasons we need this wrapper is
115          * because the function itself warn logs if we'd pass a pointer to NULL, and we don't want that. */
116         if (*c)
117                 sym_Esys_Finalize(c);
118 }
119 
Esys_Freep(void * p)120 static inline void Esys_Freep(void *p) {
121         if (*(void**) p)
122                 sym_Esys_Free(*(void**) p);
123 }
124 
flush_context_verbose(ESYS_CONTEXT * c,ESYS_TR handle)125 static ESYS_TR flush_context_verbose(ESYS_CONTEXT *c, ESYS_TR handle) {
126         TSS2_RC rc;
127 
128         if (!c || handle == ESYS_TR_NONE)
129                 return ESYS_TR_NONE;
130 
131         rc = sym_Esys_FlushContext(c, handle);
132         if (rc != TSS2_RC_SUCCESS) /* We ignore failures here (besides debug logging), since this is called
133                                     * in error paths, where we cannot do anything about failures anymore. And
134                                     * when it is called in successful codepaths by this time we already did
135                                     * what we wanted to do, and got the results we wanted so there's no
136                                     * reason to make this fail more loudly than necessary. */
137                 log_debug("Failed to get flush context of TPM, ignoring: %s", sym_Tss2_RC_Decode(rc));
138 
139         return ESYS_TR_NONE;
140 }
141 
tpm2_init(const char * device,struct tpm2_context * ret)142 static int tpm2_init(const char *device, struct tpm2_context *ret) {
143         _cleanup_(Esys_Finalize_wrapper) ESYS_CONTEXT *c = NULL;
144         _cleanup_free_ TSS2_TCTI_CONTEXT *tcti = NULL;
145         _cleanup_(dlclosep) void *dl = NULL;
146         TSS2_RC rc;
147         int r;
148 
149         r = dlopen_tpm2();
150         if (r < 0)
151                 return log_error_errno(r, "TPM2 support not installed: %m");
152 
153         if (!device)
154                 device = secure_getenv("SYSTEMD_TPM2_DEVICE");
155 
156         if (device) {
157                 const char *param, *driver, *fn;
158                 const TSS2_TCTI_INFO* info;
159                 TSS2_TCTI_INFO_FUNC func;
160                 size_t sz = 0;
161 
162                 param = strchr(device, ':');
163                 if (param) {
164                         driver = strndupa_safe(device, param - device);
165                         param++;
166                 } else {
167                         driver = "device";
168                         param = device;
169                 }
170 
171                 fn = strjoina("libtss2-tcti-", driver, ".so.0");
172 
173                 dl = dlopen(fn, RTLD_NOW);
174                 if (!dl)
175                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to load %s: %s", fn, dlerror());
176 
177                 func = dlsym(dl, TSS2_TCTI_INFO_SYMBOL);
178                 if (!func)
179                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
180                                                "Failed to find TCTI info symbol " TSS2_TCTI_INFO_SYMBOL ": %s",
181                                                dlerror());
182 
183                 info = func();
184                 if (!info)
185                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to get TCTI info data.");
186 
187 
188                 log_debug("Loaded TCTI module '%s' (%s) [Version %" PRIu32 "]", info->name, info->description, info->version);
189 
190                 rc = info->init(NULL, &sz, NULL);
191                 if (rc != TPM2_RC_SUCCESS)
192                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
193                                                "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));
194 
195                 tcti = malloc0(sz);
196                 if (!tcti)
197                         return log_oom();
198 
199                 rc = info->init(tcti, &sz, param);
200                 if (rc != TPM2_RC_SUCCESS)
201                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
202                                                "Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));
203         }
204 
205         rc = sym_Esys_Initialize(&c, tcti, NULL);
206         if (rc != TSS2_RC_SUCCESS)
207                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
208                                        "Failed to initialize TPM context: %s", sym_Tss2_RC_Decode(rc));
209 
210         rc = sym_Esys_Startup(c, TPM2_SU_CLEAR);
211         if (rc == TPM2_RC_INITIALIZE)
212                 log_debug("TPM already started up.");
213         else if (rc == TSS2_RC_SUCCESS)
214                 log_debug("TPM successfully started up.");
215         else
216                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
217                                        "Failed to start up TPM: %s", sym_Tss2_RC_Decode(rc));
218 
219         *ret = (struct tpm2_context) {
220                 .esys_context = TAKE_PTR(c),
221                 .tcti_context = TAKE_PTR(tcti),
222                 .tcti_dl = TAKE_PTR(dl),
223         };
224 
225         return 0;
226 }
227 
tpm2_credit_random(ESYS_CONTEXT * c)228 static int tpm2_credit_random(ESYS_CONTEXT *c) {
229         size_t rps, done = 0;
230         TSS2_RC rc;
231         int r;
232 
233         assert(c);
234 
235         /* Pulls some entropy from the TPM and adds it into the kernel RNG pool. That way we can say that the
236          * key we will ultimately generate with the kernel random pool is at least as good as the TPM's RNG,
237          * but likely better. Note that we don't trust the TPM RNG very much, hence do not actually credit
238          * any entropy. */
239 
240         for (rps = random_pool_size(); rps > 0;) {
241                 _cleanup_(Esys_Freep) TPM2B_DIGEST *buffer = NULL;
242 
243                 rc = sym_Esys_GetRandom(
244                                 c,
245                                 ESYS_TR_NONE,
246                                 ESYS_TR_NONE,
247                                 ESYS_TR_NONE,
248                                 MIN(rps, 32U), /* 32 is supposedly a safe choice, given that AES 256bit keys are this long, and TPM2 baseline requires support for those. */
249                                 &buffer);
250                 if (rc != TSS2_RC_SUCCESS)
251                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
252                                                "Failed to acquire entropy from TPM: %s", sym_Tss2_RC_Decode(rc));
253 
254                 if (buffer->size == 0)
255                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
256                                                "Zero-sized entropy returned from TPM.");
257 
258                 r = random_write_entropy(-1, buffer->buffer, buffer->size, false);
259                 if (r < 0)
260                         return log_error_errno(r, "Failed wo write entropy to kernel: %m");
261 
262                 done += buffer->size;
263                 rps = LESS_BY(rps, buffer->size);
264         }
265 
266         log_debug("Added %zu bytes of entropy to the kernel random pool.", done);
267         return 0;
268 }
269 
tpm2_make_primary(ESYS_CONTEXT * c,ESYS_TR * ret_primary,TPMI_ALG_PUBLIC alg,TPMI_ALG_PUBLIC * ret_alg)270 static int tpm2_make_primary(
271                 ESYS_CONTEXT *c,
272                 ESYS_TR *ret_primary,
273                 TPMI_ALG_PUBLIC alg,
274                 TPMI_ALG_PUBLIC *ret_alg) {
275 
276         static const TPM2B_SENSITIVE_CREATE primary_sensitive = {};
277         static const TPM2B_PUBLIC primary_template_ecc = {
278                 .size = sizeof(TPMT_PUBLIC),
279                 .publicArea = {
280                         .type = TPM2_ALG_ECC,
281                         .nameAlg = TPM2_ALG_SHA256,
282                         .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH,
283                         .parameters = {
284                                 .eccDetail = {
285                                         .symmetric = {
286                                                 .algorithm = TPM2_ALG_AES,
287                                                 .keyBits.aes = 128,
288                                                 .mode.aes = TPM2_ALG_CFB,
289                                         },
290                                         .scheme.scheme = TPM2_ALG_NULL,
291                                         .curveID = TPM2_ECC_NIST_P256,
292                                         .kdf.scheme = TPM2_ALG_NULL,
293                                 },
294                         },
295                 },
296         };
297         static const TPM2B_PUBLIC primary_template_rsa = {
298                 .size = sizeof(TPMT_PUBLIC),
299                 .publicArea = {
300                         .type = TPM2_ALG_RSA,
301                         .nameAlg = TPM2_ALG_SHA256,
302                         .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH,
303                         .parameters = {
304                                 .rsaDetail = {
305                                         .symmetric = {
306                                                 .algorithm = TPM2_ALG_AES,
307                                                 .keyBits.aes = 128,
308                                                 .mode.aes = TPM2_ALG_CFB,
309                                         },
310                                         .scheme.scheme = TPM2_ALG_NULL,
311                                         .keyBits = 2048,
312                                 },
313                         },
314                 },
315         };
316 
317         static const TPML_PCR_SELECTION creation_pcr = {};
318         ESYS_TR primary = ESYS_TR_NONE;
319         TSS2_RC rc;
320         usec_t ts;
321 
322         log_debug("Creating primary key on TPM.");
323 
324         /* So apparently not all TPM2 devices support ECC. ECC is generally preferably, because it's so much
325          * faster, noticeably so (~10s vs. ~240ms on my system). Hence, unless explicitly configured let's
326          * try to use ECC first, and if that does not work, let's fall back to RSA. */
327 
328         ts = now(CLOCK_MONOTONIC);
329 
330         if (IN_SET(alg, 0, TPM2_ALG_ECC)) {
331                 rc = sym_Esys_CreatePrimary(
332                                 c,
333                                 ESYS_TR_RH_OWNER,
334                                 ESYS_TR_PASSWORD,
335                                 ESYS_TR_NONE,
336                                 ESYS_TR_NONE,
337                                 &primary_sensitive,
338                                 &primary_template_ecc,
339                                 NULL,
340                                 &creation_pcr,
341                                 &primary,
342                                 NULL,
343                                 NULL,
344                                 NULL,
345                                 NULL);
346 
347                 if (rc != TSS2_RC_SUCCESS) {
348                         if (alg != 0)
349                                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
350                                                        "Failed to generate ECC primary key in TPM: %s", sym_Tss2_RC_Decode(rc));
351 
352                         log_debug("Failed to generate ECC primary key in TPM, trying RSA: %s", sym_Tss2_RC_Decode(rc));
353                 } else {
354                         log_debug("Successfully created ECC primary key on TPM.");
355                         alg = TPM2_ALG_ECC;
356                 }
357         }
358 
359         if (IN_SET(alg, 0, TPM2_ALG_RSA)) {
360                 rc = sym_Esys_CreatePrimary(
361                                 c,
362                                 ESYS_TR_RH_OWNER,
363                                 ESYS_TR_PASSWORD,
364                                 ESYS_TR_NONE,
365                                 ESYS_TR_NONE,
366                                 &primary_sensitive,
367                                 &primary_template_rsa,
368                                 NULL,
369                                 &creation_pcr,
370                                 &primary,
371                                 NULL,
372                                 NULL,
373                                 NULL,
374                                 NULL);
375                 if (rc != TSS2_RC_SUCCESS)
376                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
377                                                "Failed to generate RSA primary key in TPM: %s", sym_Tss2_RC_Decode(rc));
378                 else if (alg == 0) {
379                         log_notice("TPM2 chip apparently does not support ECC primary keys, falling back to RSA. "
380                                    "This likely means TPM2 operations will be relatively slow, please be patient.");
381                         alg = TPM2_ALG_RSA;
382                 }
383 
384                 log_debug("Successfully created RSA primary key on TPM.");
385         }
386 
387         log_debug("Generating primary key on TPM2 took %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - ts, USEC_PER_MSEC));
388 
389         *ret_primary = primary;
390         if (ret_alg)
391                 *ret_alg = alg;
392 
393         return 0;
394 }
395 
tpm2_pcr_mask_to_selecion(uint32_t mask,uint16_t bank,TPML_PCR_SELECTION * ret)396 static void tpm2_pcr_mask_to_selecion(uint32_t mask, uint16_t bank, TPML_PCR_SELECTION *ret) {
397         assert(ret);
398 
399         /* We only do 24bit here, as that's what PC TPMs are supposed to support */
400         assert(mask <= 0xFFFFFFU);
401 
402         *ret = (TPML_PCR_SELECTION) {
403                 .count = 1,
404                 .pcrSelections[0].hash = bank,
405                 .pcrSelections[0].sizeofSelect = 3,
406                 .pcrSelections[0].pcrSelect[0] = mask & 0xFF,
407                 .pcrSelections[0].pcrSelect[1] = (mask >> 8) & 0xFF,
408                 .pcrSelections[0].pcrSelect[2] = (mask >> 16) & 0xFF,
409         };
410 }
411 
find_nth_bit(uint32_t mask,unsigned n)412 static unsigned find_nth_bit(uint32_t mask, unsigned n) {
413         uint32_t bit = 1;
414 
415         assert(n < 32);
416 
417         /* Returns the bit index of the nth set bit, e.g. mask=0b101001, n=3 → 5 */
418 
419         for (unsigned i = 0; i < sizeof(mask)*8; i++) {
420 
421                 if (bit & mask) {
422                         if (n == 0)
423                                 return i;
424 
425                         n--;
426                 }
427 
428                 bit <<= 1;
429         }
430 
431         return UINT_MAX;
432 }
433 
tpm2_pcr_mask_good(ESYS_CONTEXT * c,TPMI_ALG_HASH bank,uint32_t mask)434 static int tpm2_pcr_mask_good(
435                 ESYS_CONTEXT *c,
436                 TPMI_ALG_HASH bank,
437                 uint32_t mask) {
438 
439         _cleanup_(Esys_Freep) TPML_DIGEST *pcr_values = NULL;
440         TPML_PCR_SELECTION selection;
441         bool good = false;
442         TSS2_RC rc;
443 
444         assert(c);
445 
446         /* So we have the problem that some systems might have working TPM2 chips, but the firmware doesn't
447          * actually measure into them, or only into a suboptimal bank. If so, the PCRs should be all zero or
448          * all 0xFF. Detect that, so that we can warn and maybe pick a better bank. */
449 
450         tpm2_pcr_mask_to_selecion(mask, bank, &selection);
451 
452         rc = sym_Esys_PCR_Read(
453                         c,
454                         ESYS_TR_NONE,
455                         ESYS_TR_NONE,
456                         ESYS_TR_NONE,
457                         &selection,
458                         NULL,
459                         NULL,
460                         &pcr_values);
461         if (rc != TSS2_RC_SUCCESS)
462                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
463                                        "Failed to read TPM2 PCRs: %s", sym_Tss2_RC_Decode(rc));
464 
465         /* If at least one of the selected PCR values is something other than all 0x00 or all 0xFF we are happy. */
466         for (unsigned i = 0; i < pcr_values->count; i++) {
467                 if (DEBUG_LOGGING) {
468                         _cleanup_free_ char *h = NULL;
469                         unsigned j;
470 
471                         h = hexmem(pcr_values->digests[i].buffer, pcr_values->digests[i].size);
472                         j = find_nth_bit(mask, i);
473                         assert(j != UINT_MAX);
474 
475                         log_debug("PCR %u value: %s", j, strna(h));
476                 }
477 
478                 if (!memeqbyte(0x00, pcr_values->digests[i].buffer, pcr_values->digests[i].size) &&
479                     !memeqbyte(0xFF, pcr_values->digests[i].buffer, pcr_values->digests[i].size))
480                         good = true;
481         }
482 
483         return good;
484 }
485 
tpm2_get_best_pcr_bank(ESYS_CONTEXT * c,uint32_t pcr_mask,TPMI_ALG_HASH * ret)486 static int tpm2_get_best_pcr_bank(
487                 ESYS_CONTEXT *c,
488                 uint32_t pcr_mask,
489                 TPMI_ALG_HASH *ret) {
490 
491         _cleanup_(Esys_Freep) TPMS_CAPABILITY_DATA *pcap = NULL;
492         TPMI_ALG_HASH supported_hash = 0, hash_with_valid_pcr = 0;
493         TPMI_YES_NO more;
494         TSS2_RC rc;
495 
496         assert(c);
497 
498         rc = sym_Esys_GetCapability(
499                         c,
500                         ESYS_TR_NONE,
501                         ESYS_TR_NONE,
502                         ESYS_TR_NONE,
503                         TPM2_CAP_PCRS,
504                         0,
505                         1,
506                         &more,
507                         &pcap);
508         if (rc != TSS2_RC_SUCCESS)
509                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
510                                        "Failed to determine TPM2 PCR bank capabilities: %s", sym_Tss2_RC_Decode(rc));
511 
512         assert(pcap->capability == TPM2_CAP_PCRS);
513 
514         for (size_t i = 0; i < pcap->data.assignedPCR.count; i++) {
515                 bool valid = true;
516                 int good;
517 
518                 /* For now we are only interested in the SHA1 and SHA256 banks */
519                 if (!IN_SET(pcap->data.assignedPCR.pcrSelections[i].hash, TPM2_ALG_SHA256, TPM2_ALG_SHA1))
520                         continue;
521 
522                 /* As per
523                  * https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_PFP_r1p05_v23_pub.pdf a
524                  * TPM2 on a Client PC must have at least 24 PCRs. If this TPM has less, just skip over
525                  * it. */
526                 if (pcap->data.assignedPCR.pcrSelections[i].sizeofSelect < TPM2_PCRS_MAX/8) {
527                         log_debug("Skipping TPM2 PCR bank %s with fewer than 24 PCRs.",
528                                   strna(tpm2_pcr_bank_to_string(pcap->data.assignedPCR.pcrSelections[i].hash)));
529                         continue;
530                 }
531 
532                 assert_cc(TPM2_PCRS_MAX % 8 == 0);
533 
534                 /* It's not enough to check how many PCRs there are, we also need to check that the 24 are
535                  * enabled for this bank. Otherwise this TPM doesn't qualify. */
536                 for (size_t j = 0; j < TPM2_PCRS_MAX/8; j++)
537                         if (pcap->data.assignedPCR.pcrSelections[i].pcrSelect[j] != 0xFF) {
538                                 valid = false;
539                                 break;
540                         }
541 
542                 if (!valid) {
543                         log_debug("TPM2 PCR bank %s has fewer than 24 PCR bits enabled, ignoring.",
544                                   strna(tpm2_pcr_bank_to_string(pcap->data.assignedPCR.pcrSelections[i].hash)));
545                         continue;
546                 }
547 
548                 good = tpm2_pcr_mask_good(c, pcap->data.assignedPCR.pcrSelections[i].hash, pcr_mask);
549                 if (good < 0)
550                         return good;
551 
552                 if (pcap->data.assignedPCR.pcrSelections[i].hash == TPM2_ALG_SHA256) {
553                         supported_hash = TPM2_ALG_SHA256;
554                         if (good) {
555                                 /* Great, SHA256 is supported and has initialized PCR values, we are done. */
556                                 hash_with_valid_pcr = TPM2_ALG_SHA256;
557                                 break;
558                         }
559                 } else {
560                         assert(pcap->data.assignedPCR.pcrSelections[i].hash == TPM2_ALG_SHA1);
561 
562                         if (supported_hash == 0)
563                                 supported_hash = TPM2_ALG_SHA1;
564 
565                         if (good && hash_with_valid_pcr == 0)
566                                 hash_with_valid_pcr = TPM2_ALG_SHA1;
567                 }
568         }
569 
570         /* We preferably pick SHA256, but only if its PCRs are initialized or neither the SHA1 nor the SHA256
571          * PCRs are initialized. If SHA256 is not supported but SHA1 is and its PCRs are too, we prefer
572          * SHA1.
573          *
574          * We log at LOG_NOTICE level whenever we end up using the SHA1 bank or when the PCRs we bind to are
575          * not initialized. */
576 
577         if (hash_with_valid_pcr == TPM2_ALG_SHA256) {
578                 assert(supported_hash == TPM2_ALG_SHA256);
579                 log_debug("TPM2 device supports SHA256 PCR bank and SHA256 PCRs are valid, yay!");
580                 *ret = TPM2_ALG_SHA256;
581         } else if (hash_with_valid_pcr == TPM2_ALG_SHA1) {
582                 if (supported_hash == TPM2_ALG_SHA256)
583                         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.");
584                 else {
585                         assert(supported_hash == TPM2_ALG_SHA1);
586                         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.");
587                 }
588 
589                 *ret = TPM2_ALG_SHA1;
590         } else if (supported_hash == TPM2_ALG_SHA256) {
591                 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!");
592                 *ret = TPM2_ALG_SHA256;
593         } else if (supported_hash == TPM2_ALG_SHA1) {
594                 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!");
595                 *ret = TPM2_ALG_SHA1;
596         } else
597                 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
598                                        "TPM2 module supports neither SHA1 nor SHA256 PCR banks, cannot operate.");
599 
600         return 0;
601 }
602 
tpm2_make_encryption_session(ESYS_CONTEXT * c,ESYS_TR tpmKey,ESYS_TR * ret_session)603 static int tpm2_make_encryption_session(
604                 ESYS_CONTEXT *c,
605                 ESYS_TR tpmKey,
606                 ESYS_TR *ret_session) {
607 
608         static const TPMT_SYM_DEF symmetric = {
609                 .algorithm = TPM2_ALG_AES,
610                 .keyBits = {
611                         .aes = 128,
612                 },
613                 .mode = {
614                         .aes = TPM2_ALG_CFB,
615                 },
616         };
617         const TPMA_SESSION sessionAttributes = TPMA_SESSION_DECRYPT | TPMA_SESSION_ENCRYPT |
618                         TPMA_SESSION_CONTINUESESSION;
619         ESYS_TR session = ESYS_TR_NONE;
620         TSS2_RC rc;
621 
622         assert(c);
623 
624         log_debug("Starting HMAC encryption session.");
625 
626         /* Start a salted, unbound HMAC session with a well-known key (e.g. primary key) as tpmKey, which
627          * means that the random salt will be encrypted with the well-known key. That way, only the TPM can
628          * recover the salt, which is then used for key derivation. */
629         rc = sym_Esys_StartAuthSession(
630                         c,
631                         tpmKey,
632                         ESYS_TR_NONE,
633                         ESYS_TR_NONE,
634                         ESYS_TR_NONE,
635                         ESYS_TR_NONE,
636                         NULL,
637                         TPM2_SE_HMAC,
638                         &symmetric,
639                         TPM2_ALG_SHA256,
640                         &session);
641         if (rc != TSS2_RC_SUCCESS)
642                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
643                                        "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc));
644 
645         /* Enable parameter encryption/decryption with AES in CFB mode. Together with HMAC digests (which are
646          * always used for sessions), this provides confidentiality, integrity and replay protection for
647          * operations that use this session. */
648         rc = sym_Esys_TRSess_SetAttributes(c, session, sessionAttributes, 0xff);
649         if (rc != TSS2_RC_SUCCESS)
650                 return log_error_errno(
651                                 SYNTHETIC_ERRNO(ENOTRECOVERABLE),
652                                 "Failed to configure TPM session: %s",
653                                 sym_Tss2_RC_Decode(rc));
654 
655         if (ret_session) {
656                 *ret_session = session;
657                 session = ESYS_TR_NONE;
658         }
659 
660         session = flush_context_verbose(c, session);
661         return 0;
662 }
663 
tpm2_make_pcr_session(ESYS_CONTEXT * c,ESYS_TR tpmKey,ESYS_TR parent_session,uint32_t pcr_mask,uint16_t pcr_bank,bool use_pin,ESYS_TR * ret_session,TPM2B_DIGEST ** ret_policy_digest,TPMI_ALG_HASH * ret_pcr_bank)664 static int tpm2_make_pcr_session(
665                 ESYS_CONTEXT *c,
666                 ESYS_TR tpmKey,
667                 ESYS_TR parent_session,
668                 uint32_t pcr_mask,
669                 uint16_t pcr_bank, /* If UINT16_MAX, pick best bank automatically, otherwise specify bank explicitly. */
670                 bool use_pin,
671                 ESYS_TR *ret_session,
672                 TPM2B_DIGEST **ret_policy_digest,
673                 TPMI_ALG_HASH *ret_pcr_bank) {
674 
675         static const TPMT_SYM_DEF symmetric = {
676                 .algorithm = TPM2_ALG_AES,
677                 .keyBits = {
678                         .aes = 128
679                 },
680                 .mode = {
681                         .aes = TPM2_ALG_CFB,
682                 }
683         };
684         _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
685         TPML_PCR_SELECTION pcr_selection;
686         ESYS_TR session = ESYS_TR_NONE;
687         TSS2_RC rc;
688         int r;
689 
690         assert(c);
691 
692         log_debug("Starting authentication session.");
693 
694         if (pcr_bank != UINT16_MAX) {
695                 r = tpm2_pcr_mask_good(c, pcr_bank, pcr_mask);
696                 if (r < 0)
697                         return r;
698                 if (r == 0)
699                         log_notice("Selected TPM2 PCRs are not initialized on this system, most likely due to a firmware issue. PCR policy is effectively not enforced. Proceeding anyway.");
700 
701                 tpm2_pcr_mask_to_selecion(pcr_mask, pcr_bank, &pcr_selection);
702         } else {
703                 TPMI_ALG_HASH h;
704 
705                 /* No bank configured, pick automatically. Some TPM2 devices only can do SHA1. If we detect
706                  * that use that, but preferably use SHA256 */
707                 r = tpm2_get_best_pcr_bank(c, pcr_mask, &h);
708                 if (r < 0)
709                         return r;
710 
711                 tpm2_pcr_mask_to_selecion(pcr_mask, h, &pcr_selection);
712         }
713 
714         rc = sym_Esys_StartAuthSession(
715                         c,
716                         tpmKey,
717                         ESYS_TR_NONE,
718                         parent_session,
719                         ESYS_TR_NONE,
720                         ESYS_TR_NONE,
721                         NULL,
722                         TPM2_SE_POLICY,
723                         &symmetric,
724                         TPM2_ALG_SHA256,
725                         &session);
726         if (rc != TSS2_RC_SUCCESS)
727                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
728                                        "Failed to open session in TPM: %s", sym_Tss2_RC_Decode(rc));
729 
730         log_debug("Configuring PCR policy.");
731 
732         rc = sym_Esys_PolicyPCR(
733                         c,
734                         session,
735                         ESYS_TR_NONE,
736                         ESYS_TR_NONE,
737                         ESYS_TR_NONE,
738                         NULL,
739                         &pcr_selection);
740         if (rc != TSS2_RC_SUCCESS) {
741                 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
742                                     "Failed to add PCR policy to TPM: %s", sym_Tss2_RC_Decode(rc));
743                 goto finish;
744         }
745 
746         if (use_pin) {
747                 rc = sym_Esys_PolicyAuthValue(
748                                 c,
749                                 session,
750                                 ESYS_TR_NONE,
751                                 ESYS_TR_NONE,
752                                 ESYS_TR_NONE);
753                 if (rc != TSS2_RC_SUCCESS) {
754                         r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
755                                             "Failed to add authValue policy to TPM: %s",
756                                             sym_Tss2_RC_Decode(rc));
757                         goto finish;
758                 }
759         }
760 
761         if (DEBUG_LOGGING || ret_policy_digest) {
762                 log_debug("Acquiring policy digest.");
763 
764                 rc = sym_Esys_PolicyGetDigest(
765                                 c,
766                                 session,
767                                 ESYS_TR_NONE,
768                                 ESYS_TR_NONE,
769                                 ESYS_TR_NONE,
770                                 &policy_digest);
771 
772                 if (rc != TSS2_RC_SUCCESS) {
773                         r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
774                                             "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc));
775                         goto finish;
776                 }
777 
778                 if (DEBUG_LOGGING) {
779                         _cleanup_free_ char *h = NULL;
780 
781                         h = hexmem(policy_digest->buffer, policy_digest->size);
782                         if (!h) {
783                                 r = log_oom();
784                                 goto finish;
785                         }
786 
787                         log_debug("Session policy digest: %s", h);
788                 }
789         }
790 
791         if (ret_session) {
792                 *ret_session = session;
793                 session = ESYS_TR_NONE;
794         }
795 
796         if (ret_policy_digest)
797                 *ret_policy_digest = TAKE_PTR(policy_digest);
798 
799         if (ret_pcr_bank)
800                 *ret_pcr_bank = pcr_selection.pcrSelections[0].hash;
801 
802         r = 0;
803 
804 finish:
805         session = flush_context_verbose(c, session);
806         return r;
807 }
808 
hash_pin(const char * pin,size_t len,uint8_t ret_digest[static SHA256_DIGEST_SIZE])809 static void hash_pin(const char *pin, size_t len, uint8_t ret_digest[static SHA256_DIGEST_SIZE]) {
810         struct sha256_ctx hash;
811 
812         assert(pin);
813 
814         sha256_init_ctx(&hash);
815         sha256_process_bytes(pin, len, &hash);
816         sha256_finish_ctx(&hash, ret_digest);
817 
818         explicit_bzero_safe(&hash, sizeof(hash));
819 }
820 
tpm2_seal(const char * device,uint32_t pcr_mask,const char * pin,void ** ret_secret,size_t * ret_secret_size,void ** ret_blob,size_t * ret_blob_size,void ** ret_pcr_hash,size_t * ret_pcr_hash_size,uint16_t * ret_pcr_bank,uint16_t * ret_primary_alg)821 int tpm2_seal(
822                 const char *device,
823                 uint32_t pcr_mask,
824                 const char *pin,
825                 void **ret_secret,
826                 size_t *ret_secret_size,
827                 void **ret_blob,
828                 size_t *ret_blob_size,
829                 void **ret_pcr_hash,
830                 size_t *ret_pcr_hash_size,
831                 uint16_t *ret_pcr_bank,
832                 uint16_t *ret_primary_alg) {
833 
834         _cleanup_(tpm2_context_destroy) struct tpm2_context c = {};
835         _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
836         _cleanup_(Esys_Freep) TPM2B_PRIVATE *private = NULL;
837         _cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
838         static const TPML_PCR_SELECTION creation_pcr = {};
839         _cleanup_(erase_and_freep) void *secret = NULL;
840         _cleanup_free_ void *blob = NULL, *hash = NULL;
841         TPM2B_SENSITIVE_CREATE hmac_sensitive;
842         ESYS_TR primary = ESYS_TR_NONE, session = ESYS_TR_NONE;
843         TPMI_ALG_PUBLIC primary_alg;
844         TPM2B_PUBLIC hmac_template;
845         TPMI_ALG_HASH pcr_bank;
846         size_t k, blob_size;
847         usec_t start;
848         TSS2_RC rc;
849         int r;
850 
851         assert(ret_secret);
852         assert(ret_secret_size);
853         assert(ret_blob);
854         assert(ret_blob_size);
855         assert(ret_pcr_hash);
856         assert(ret_pcr_hash_size);
857         assert(ret_pcr_bank);
858 
859         assert(pcr_mask < (UINT32_C(1) << TPM2_PCRS_MAX)); /* Support 24 PCR banks */
860 
861         /* So here's what we do here: we connect to the TPM2 chip. It persistently contains a "seed" key that
862          * is randomized when the TPM2 is first initialized or reset and remains stable across boots. We
863          * generate a "primary" key pair derived from that (ECC if possible, RSA as fallback). Given the seed
864          * remains fixed this will result in the same key pair whenever we specify the exact same parameters
865          * for it. We then create a PCR-bound policy session, which calculates a hash on the current PCR
866          * values of the indexes we specify. We then generate a randomized key on the host (which is the key
867          * we actually enroll in the LUKS2 keyslots), which we upload into the TPM2, where it is encrypted
868          * with the "primary" key, taking the PCR policy session into account. We then download the encrypted
869          * key from the TPM2 ("sealing") and marshall it into binary form, which is ultimately placed in the
870          * LUKS2 JSON header.
871          *
872          * The TPM2 "seed" key and "primary" keys never leave the TPM2 chip (and cannot be extracted at
873          * all). The random key we enroll in LUKS2 we generate on the host using the Linux random device. It
874          * is stored in the LUKS2 JSON only in encrypted form with the "primary" key of the TPM2 chip, thus
875          * binding the unlocking to the TPM2 chip. */
876 
877         start = now(CLOCK_MONOTONIC);
878 
879         r = tpm2_init(device, &c);
880         if (r < 0)
881                 return r;
882 
883         r = tpm2_make_primary(c.esys_context, &primary, 0, &primary_alg);
884         if (r < 0)
885                 return r;
886 
887         r = tpm2_make_encryption_session(c.esys_context, primary, &session);
888         if (r < 0)
889                 goto finish;
890 
891         r = tpm2_make_pcr_session(c.esys_context, primary, session, pcr_mask, UINT16_MAX, !!pin, NULL,
892                                   &policy_digest, &pcr_bank);
893         if (r < 0)
894                 goto finish;
895 
896         /* We use a keyed hash object (i.e. HMAC) to store the secret key we want to use for unlocking the
897          * LUKS2 volume with. We don't ever use for HMAC/keyed hash operations however, we just use it
898          * because it's a key type that is universally supported and suitable for symmetric binary blobs. */
899         hmac_template = (TPM2B_PUBLIC) {
900                 .size = sizeof(TPMT_PUBLIC),
901                 .publicArea = {
902                         .type = TPM2_ALG_KEYEDHASH,
903                         .nameAlg = TPM2_ALG_SHA256,
904                         .objectAttributes = TPMA_OBJECT_FIXEDTPM | TPMA_OBJECT_FIXEDPARENT,
905                         .parameters = {
906                                 .keyedHashDetail = {
907                                         .scheme.scheme = TPM2_ALG_NULL,
908                                 },
909                         },
910                         .unique = {
911                                 .keyedHash = {
912                                         .size = 32,
913                                 },
914                         },
915                         .authPolicy = *policy_digest,
916                 },
917         };
918 
919         hmac_sensitive = (TPM2B_SENSITIVE_CREATE) {
920                 .size = sizeof(hmac_sensitive.sensitive),
921                 .sensitive.data.size = 32,
922         };
923         if (pin) {
924                 hash_pin(pin, strlen(pin), hmac_sensitive.sensitive.userAuth.buffer);
925                 hmac_sensitive.sensitive.userAuth.size = SHA256_DIGEST_SIZE;
926         }
927         assert(sizeof(hmac_sensitive.sensitive.data.buffer) >= hmac_sensitive.sensitive.data.size);
928 
929         (void) tpm2_credit_random(c.esys_context);
930 
931         log_debug("Generating secret key data.");
932 
933         r = genuine_random_bytes(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size, RANDOM_BLOCK);
934         if (r < 0) {
935                 log_error_errno(r, "Failed to generate secret key: %m");
936                 goto finish;
937         }
938 
939         log_debug("Creating HMAC key.");
940 
941         rc = sym_Esys_Create(
942                         c.esys_context,
943                         primary,
944                         session, /* use HMAC session to enable parameter encryption */
945                         ESYS_TR_NONE,
946                         ESYS_TR_NONE,
947                         &hmac_sensitive,
948                         &hmac_template,
949                         NULL,
950                         &creation_pcr,
951                         &private,
952                         &public,
953                         NULL,
954                         NULL,
955                         NULL);
956         if (rc != TSS2_RC_SUCCESS) {
957                 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
958                                     "Failed to generate HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc));
959                 goto finish;
960         }
961 
962         secret = memdup(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size);
963         explicit_bzero_safe(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size);
964         if (!secret) {
965                 r = log_oom();
966                 goto finish;
967         }
968 
969         log_debug("Marshalling private and public part of HMAC key.");
970 
971         k = ALIGN8(sizeof(*private)) + ALIGN8(sizeof(*public)); /* Some roughly sensible start value */
972         for (;;) {
973                 _cleanup_free_ void *buf = NULL;
974                 size_t offset = 0;
975 
976                 buf = malloc(k);
977                 if (!buf) {
978                         r = log_oom();
979                         goto finish;
980                 }
981 
982                 rc = sym_Tss2_MU_TPM2B_PRIVATE_Marshal(private, buf, k, &offset);
983                 if (rc == TSS2_RC_SUCCESS) {
984                         rc = sym_Tss2_MU_TPM2B_PUBLIC_Marshal(public, buf, k, &offset);
985                         if (rc == TSS2_RC_SUCCESS) {
986                                 blob = TAKE_PTR(buf);
987                                 blob_size = offset;
988                                 break;
989                         }
990                 }
991                 if (rc != TSS2_MU_RC_INSUFFICIENT_BUFFER) {
992                         r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
993                                             "Failed to marshal private/public key: %s", sym_Tss2_RC_Decode(rc));
994                         goto finish;
995                 }
996 
997                 if (k > SIZE_MAX / 2) {
998                         r = log_oom();
999                         goto finish;
1000                 }
1001 
1002                 k *= 2;
1003         }
1004 
1005         hash = memdup(policy_digest->buffer, policy_digest->size);
1006         if (!hash)
1007                 return log_oom();
1008 
1009         if (DEBUG_LOGGING)
1010                 log_debug("Completed TPM2 key sealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
1011 
1012         *ret_secret = TAKE_PTR(secret);
1013         *ret_secret_size = hmac_sensitive.sensitive.data.size;
1014         *ret_blob = TAKE_PTR(blob);
1015         *ret_blob_size = blob_size;
1016         *ret_pcr_hash = TAKE_PTR(hash);
1017         *ret_pcr_hash_size = policy_digest->size;
1018         *ret_pcr_bank = pcr_bank;
1019         *ret_primary_alg = primary_alg;
1020 
1021         r = 0;
1022 
1023 finish:
1024         explicit_bzero_safe(&hmac_sensitive, sizeof(hmac_sensitive));
1025         primary = flush_context_verbose(c.esys_context, primary);
1026         session = flush_context_verbose(c.esys_context, session);
1027         return r;
1028 }
1029 
tpm2_unseal(const char * device,uint32_t pcr_mask,uint16_t pcr_bank,uint16_t primary_alg,const void * blob,size_t blob_size,const void * known_policy_hash,size_t known_policy_hash_size,const char * pin,void ** ret_secret,size_t * ret_secret_size)1030 int tpm2_unseal(
1031                 const char *device,
1032                 uint32_t pcr_mask,
1033                 uint16_t pcr_bank,
1034                 uint16_t primary_alg,
1035                 const void *blob,
1036                 size_t blob_size,
1037                 const void *known_policy_hash,
1038                 size_t known_policy_hash_size,
1039                 const char *pin,
1040                 void **ret_secret,
1041                 size_t *ret_secret_size) {
1042 
1043         _cleanup_(tpm2_context_destroy) struct tpm2_context c = {};
1044         ESYS_TR primary = ESYS_TR_NONE, session = ESYS_TR_NONE, hmac_session = ESYS_TR_NONE,
1045                 hmac_key = ESYS_TR_NONE;
1046         _cleanup_(Esys_Freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
1047         _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
1048         _cleanup_(erase_and_freep) char *secret = NULL;
1049         TPM2B_PRIVATE private = {};
1050         TPM2B_PUBLIC public = {};
1051         size_t offset = 0;
1052         TSS2_RC rc;
1053         usec_t start;
1054         int r;
1055 
1056         assert(blob);
1057         assert(blob_size > 0);
1058         assert(known_policy_hash_size == 0 || known_policy_hash);
1059         assert(ret_secret);
1060         assert(ret_secret_size);
1061 
1062         assert(pcr_mask < (UINT32_C(1) << TPM2_PCRS_MAX)); /* Support 24 PCR banks */
1063 
1064         r = dlopen_tpm2();
1065         if (r < 0)
1066                 return log_error_errno(r, "TPM2 support is not installed.");
1067 
1068         /* So here's what we do here: We connect to the TPM2 chip. As we do when sealing we generate a
1069          * "primary" key on the TPM2 chip, with the same parameters as well as a PCR-bound policy
1070          * session. Given we pass the same parameters, this will result in the same "primary" key, and same
1071          * policy hash (the latter of course, only if the PCR values didn't change in between). We unmarshal
1072          * the encrypted key we stored in the LUKS2 JSON token header and upload it into the TPM2, where it
1073          * is decrypted if the seed and the PCR policy were right ("unsealing"). We then download the result,
1074          * and use it to unlock the LUKS2 volume. */
1075 
1076         start = now(CLOCK_MONOTONIC);
1077 
1078         log_debug("Unmarshalling private part of HMAC key.");
1079 
1080         rc = sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal(blob, blob_size, &offset, &private);
1081         if (rc != TSS2_RC_SUCCESS)
1082                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1083                                        "Failed to unmarshal private key: %s", sym_Tss2_RC_Decode(rc));
1084 
1085         log_debug("Unmarshalling public part of HMAC key.");
1086 
1087         rc = sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal(blob, blob_size, &offset, &public);
1088         if (rc != TSS2_RC_SUCCESS)
1089                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1090                                        "Failed to unmarshal public key: %s", sym_Tss2_RC_Decode(rc));
1091 
1092         r = tpm2_init(device, &c);
1093         if (r < 0)
1094                 return r;
1095 
1096         r = tpm2_make_primary(c.esys_context, &primary, primary_alg, NULL);
1097         if (r < 0)
1098                 return r;
1099 
1100         r = tpm2_make_encryption_session(c.esys_context, primary, &hmac_session);
1101         if (r < 0)
1102                 goto finish;
1103 
1104         r = tpm2_make_pcr_session(c.esys_context, primary, hmac_session, pcr_mask, pcr_bank, !!pin, &session,
1105                                   &policy_digest, NULL);
1106         if (r < 0)
1107                 goto finish;
1108 
1109         /* If we know the policy hash to expect, and it doesn't match, we can shortcut things here, and not
1110          * wait until the TPM2 tells us to go away. */
1111         if (known_policy_hash_size > 0 &&
1112             memcmp_nn(policy_digest->buffer, policy_digest->size, known_policy_hash, known_policy_hash_size) != 0)
1113                 return log_error_errno(SYNTHETIC_ERRNO(EPERM),
1114                                        "Current policy digest does not match stored policy digest, cancelling TPM2 authentication attempt.");
1115 
1116         log_debug("Loading HMAC key into TPM.");
1117 
1118         rc = sym_Esys_Load(
1119                         c.esys_context,
1120                         primary,
1121                         hmac_session, /* use HMAC session to enable parameter encryption */
1122                         ESYS_TR_NONE,
1123                         ESYS_TR_NONE,
1124                         &private,
1125                         &public,
1126                         &hmac_key);
1127         if (rc != TSS2_RC_SUCCESS) {
1128                 /* If we're in dictionary attack lockout mode, we should see a lockout error here, which we
1129                  * need to translate for the caller. */
1130                 if (rc == TPM2_RC_LOCKOUT)
1131                         r = log_error_errno(
1132                                         SYNTHETIC_ERRNO(ENOLCK),
1133                                         "TPM2 device is in dictionary attack lockout mode.");
1134                 else
1135                         r = log_error_errno(
1136                                         SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1137                                         "Failed to load HMAC key in TPM: %s",
1138                                         sym_Tss2_RC_Decode(rc));
1139                 goto finish;
1140         }
1141 
1142         if (pin) {
1143                 TPM2B_AUTH auth = {
1144                         .size = SHA256_DIGEST_SIZE
1145                 };
1146 
1147                 hash_pin(pin, strlen(pin), auth.buffer);
1148 
1149                 rc = sym_Esys_TR_SetAuth(c.esys_context, hmac_key, &auth);
1150                 explicit_bzero_safe(&auth, sizeof(auth));
1151                 if (rc != TSS2_RC_SUCCESS) {
1152                         r = log_error_errno(
1153                                         SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1154                                         "Failed to load PIN in TPM: %s",
1155                                         sym_Tss2_RC_Decode(rc));
1156                         goto finish;
1157                 }
1158         }
1159 
1160         log_debug("Unsealing HMAC key.");
1161 
1162         rc = sym_Esys_Unseal(
1163                         c.esys_context,
1164                         hmac_key,
1165                         session,
1166                         hmac_session, /* use HMAC session to enable parameter encryption */
1167                         ESYS_TR_NONE,
1168                         &unsealed);
1169         if (rc != TSS2_RC_SUCCESS) {
1170                 r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
1171                                     "Failed to unseal HMAC key in TPM: %s", sym_Tss2_RC_Decode(rc));
1172                 goto finish;
1173         }
1174 
1175         secret = memdup(unsealed->buffer, unsealed->size);
1176         explicit_bzero_safe(unsealed->buffer, unsealed->size);
1177         if (!secret) {
1178                 r = log_oom();
1179                 goto finish;
1180         }
1181 
1182         if (DEBUG_LOGGING)
1183                 log_debug("Completed TPM2 key unsealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
1184 
1185         *ret_secret = TAKE_PTR(secret);
1186         *ret_secret_size = unsealed->size;
1187 
1188         r = 0;
1189 
1190 finish:
1191         primary = flush_context_verbose(c.esys_context, primary);
1192         session = flush_context_verbose(c.esys_context, session);
1193         hmac_key = flush_context_verbose(c.esys_context, hmac_key);
1194         return r;
1195 }
1196 
1197 #endif
1198 
tpm2_list_devices(void)1199 int tpm2_list_devices(void) {
1200 #if HAVE_TPM2
1201         _cleanup_(table_unrefp) Table *t = NULL;
1202         _cleanup_(closedirp) DIR *d = NULL;
1203         int r;
1204 
1205         r = dlopen_tpm2();
1206         if (r < 0)
1207                 return log_error_errno(r, "TPM2 support is not installed.");
1208 
1209         t = table_new("path", "device", "driver");
1210         if (!t)
1211                 return log_oom();
1212 
1213         d = opendir("/sys/class/tpmrm");
1214         if (!d) {
1215                 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to open /sys/class/tpmrm: %m");
1216                 if (errno != ENOENT)
1217                         return -errno;
1218         } else {
1219                 for (;;) {
1220                         _cleanup_free_ char *device_path = NULL, *device = NULL, *driver_path = NULL, *driver = NULL, *node = NULL;
1221                         struct dirent *de;
1222 
1223                         de = readdir_no_dot(d);
1224                         if (!de)
1225                                 break;
1226 
1227                         device_path = path_join("/sys/class/tpmrm", de->d_name, "device");
1228                         if (!device_path)
1229                                 return log_oom();
1230 
1231                         r = readlink_malloc(device_path, &device);
1232                         if (r < 0)
1233                                 log_debug_errno(r, "Failed to read device symlink %s, ignoring: %m", device_path);
1234                         else {
1235                                 driver_path = path_join(device_path, "driver");
1236                                 if (!driver_path)
1237                                         return log_oom();
1238 
1239                                 r = readlink_malloc(driver_path, &driver);
1240                                 if (r < 0)
1241                                         log_debug_errno(r, "Failed to read driver symlink %s, ignoring: %m", driver_path);
1242                         }
1243 
1244                         node = path_join("/dev", de->d_name);
1245                         if (!node)
1246                                 return log_oom();
1247 
1248                         r = table_add_many(
1249                                         t,
1250                                         TABLE_PATH, node,
1251                                         TABLE_STRING, device ? last_path_component(device) : NULL,
1252                                         TABLE_STRING, driver ? last_path_component(driver) : NULL);
1253                         if (r < 0)
1254                                 return table_log_add_error(r);
1255                 }
1256         }
1257 
1258         if (table_get_rows(t) <= 1) {
1259                 log_info("No suitable TPM2 devices found.");
1260                 return 0;
1261         }
1262 
1263         r = table_print(t, stdout);
1264         if (r < 0)
1265                 return log_error_errno(r, "Failed to show device table: %m");
1266 
1267         return 0;
1268 #else
1269         return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1270                                "TPM2 not supported on this build.");
1271 #endif
1272 }
1273 
tpm2_find_device_auto(int log_level,char ** ret)1274 int tpm2_find_device_auto(
1275                 int log_level, /* log level when no device is found */
1276                 char **ret) {
1277 #if HAVE_TPM2
1278         _cleanup_(closedirp) DIR *d = NULL;
1279         int r;
1280 
1281         r = dlopen_tpm2();
1282         if (r < 0)
1283                 return log_error_errno(r, "TPM2 support is not installed.");
1284 
1285         d = opendir("/sys/class/tpmrm");
1286         if (!d) {
1287                 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
1288                                "Failed to open /sys/class/tpmrm: %m");
1289                 if (errno != ENOENT)
1290                         return -errno;
1291         } else {
1292                 _cleanup_free_ char *node = NULL;
1293 
1294                 for (;;) {
1295                         struct dirent *de;
1296 
1297                         de = readdir_no_dot(d);
1298                         if (!de)
1299                                 break;
1300 
1301                         if (node)
1302                                 return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ),
1303                                                        "More than one TPM2 (tpmrm) device found.");
1304 
1305                         node = path_join("/dev", de->d_name);
1306                         if (!node)
1307                                 return log_oom();
1308                 }
1309 
1310                 if (node) {
1311                         *ret = TAKE_PTR(node);
1312                         return 0;
1313                 }
1314         }
1315 
1316         return log_full_errno(log_level, SYNTHETIC_ERRNO(ENODEV), "No TPM2 (tpmrm) device found.");
1317 #else
1318         return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1319                                "TPM2 not supported on this build.");
1320 #endif
1321 }
1322 
tpm2_parse_pcrs(const char * s,uint32_t * ret)1323 int tpm2_parse_pcrs(const char *s, uint32_t *ret) {
1324         const char *p = s;
1325         uint32_t mask = 0;
1326         int r;
1327 
1328         assert(s);
1329 
1330         if (isempty(s)) {
1331                 *ret = 0;
1332                 return 0;
1333         }
1334 
1335         /* Parses a "," or "+" separated list of PCR indexes. We support "," since this is a list after all,
1336          * and most other tools expect comma separated PCR specifications. We also support "+" since in
1337          * /etc/crypttab the "," is already used to separate options, hence a different separator is nice to
1338          * avoid escaping. */
1339 
1340         for (;;) {
1341                 _cleanup_free_ char *pcr = NULL;
1342                 unsigned n;
1343 
1344                 r = extract_first_word(&p, &pcr, ",+", EXTRACT_DONT_COALESCE_SEPARATORS);
1345                 if (r == 0)
1346                         break;
1347                 if (r < 0)
1348                         return log_error_errno(r, "Failed to parse PCR list: %s", s);
1349 
1350                 r = safe_atou(pcr, &n);
1351                 if (r < 0)
1352                         return log_error_errno(r, "Failed to parse PCR number: %s", pcr);
1353                 if (n >= TPM2_PCRS_MAX)
1354                         return log_error_errno(SYNTHETIC_ERRNO(ERANGE),
1355                                                "PCR number out of range (valid range 0…23): %u", n);
1356 
1357                 mask |= UINT32_C(1) << n;
1358         }
1359 
1360         *ret = mask;
1361         return 0;
1362 }
1363 
tpm2_make_luks2_json(int keyslot,uint32_t pcr_mask,uint16_t pcr_bank,uint16_t primary_alg,const void * blob,size_t blob_size,const void * policy_hash,size_t policy_hash_size,TPM2Flags flags,JsonVariant ** ret)1364 int tpm2_make_luks2_json(
1365                 int keyslot,
1366                 uint32_t pcr_mask,
1367                 uint16_t pcr_bank,
1368                 uint16_t primary_alg,
1369                 const void *blob,
1370                 size_t blob_size,
1371                 const void *policy_hash,
1372                 size_t policy_hash_size,
1373                 TPM2Flags flags,
1374                 JsonVariant **ret) {
1375 
1376         _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *a = NULL;
1377         _cleanup_free_ char *keyslot_as_string = NULL;
1378         JsonVariant* pcr_array[TPM2_PCRS_MAX];
1379         unsigned n_pcrs = 0;
1380         int r;
1381 
1382         assert(blob || blob_size == 0);
1383         assert(policy_hash || policy_hash_size == 0);
1384 
1385         if (asprintf(&keyslot_as_string, "%i", keyslot) < 0)
1386                 return -ENOMEM;
1387 
1388         for (unsigned i = 0; i < ELEMENTSOF(pcr_array); i++) {
1389                 if ((pcr_mask & (UINT32_C(1) << i)) == 0)
1390                         continue;
1391 
1392                 r = json_variant_new_integer(pcr_array + n_pcrs, i);
1393                 if (r < 0) {
1394                         json_variant_unref_many(pcr_array, n_pcrs);
1395                         return -ENOMEM;
1396                 }
1397 
1398                 n_pcrs++;
1399         }
1400 
1401         r = json_variant_new_array(&a, pcr_array, n_pcrs);
1402         json_variant_unref_many(pcr_array, n_pcrs);
1403         if (r < 0)
1404                 return -ENOMEM;
1405 
1406         r = json_build(&v,
1407                        JSON_BUILD_OBJECT(
1408                                        JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-tpm2")),
1409                                        JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))),
1410                                        JSON_BUILD_PAIR("tpm2-blob", JSON_BUILD_BASE64(blob, blob_size)),
1411                                        JSON_BUILD_PAIR("tpm2-pcrs", JSON_BUILD_VARIANT(a)),
1412                                        JSON_BUILD_PAIR_CONDITION(!!tpm2_pcr_bank_to_string(pcr_bank), "tpm2-pcr-bank", JSON_BUILD_STRING(tpm2_pcr_bank_to_string(pcr_bank))),
1413                                        JSON_BUILD_PAIR_CONDITION(!!tpm2_primary_alg_to_string(primary_alg), "tpm2-primary-alg", JSON_BUILD_STRING(tpm2_primary_alg_to_string(primary_alg))),
1414                                        JSON_BUILD_PAIR("tpm2-policy-hash", JSON_BUILD_HEX(policy_hash, policy_hash_size)),
1415                                        JSON_BUILD_PAIR("tpm2-pin", JSON_BUILD_BOOLEAN(flags & TPM2_FLAGS_USE_PIN)))
1416                         );
1417         if (r < 0)
1418                 return r;
1419 
1420         if (ret)
1421                 *ret = TAKE_PTR(v);
1422 
1423         return keyslot;
1424 }
1425 
tpm2_pcr_bank_to_string(uint16_t bank)1426 const char *tpm2_pcr_bank_to_string(uint16_t bank) {
1427         /* For now, let's officially only support these two. We can extend this later on, should the need
1428          * arise. */
1429         if (bank == TPM2_ALG_SHA256)
1430                 return "sha256";
1431         if (bank == TPM2_ALG_SHA1)
1432                 return "sha1";
1433         return NULL;
1434 }
1435 
tpm2_pcr_bank_from_string(const char * bank)1436 int tpm2_pcr_bank_from_string(const char *bank) {
1437         if (streq_ptr(bank, "sha256"))
1438                 return TPM2_ALG_SHA256;
1439         if (streq_ptr(bank, "sha1"))
1440                 return TPM2_ALG_SHA1;
1441         return -EINVAL;
1442 }
1443 
tpm2_primary_alg_to_string(uint16_t alg)1444 const char *tpm2_primary_alg_to_string(uint16_t alg) {
1445         if (alg == TPM2_ALG_ECC)
1446                 return "ecc";
1447         if (alg == TPM2_ALG_RSA)
1448                 return "rsa";
1449         return NULL;
1450 }
1451 
tpm2_primary_alg_from_string(const char * alg)1452 int tpm2_primary_alg_from_string(const char *alg) {
1453         if (streq_ptr(alg, "ecc"))
1454                 return TPM2_ALG_ECC;
1455         if (streq_ptr(alg, "rsa"))
1456                 return TPM2_ALG_RSA;
1457         return -EINVAL;
1458 }
1459 
tpm2_support(void)1460 Tpm2Support tpm2_support(void) {
1461         Tpm2Support support = TPM2_SUPPORT_NONE;
1462         int r;
1463 
1464         if (detect_container() <= 0) {
1465                 /* Check if there's a /dev/tpmrm* device via sysfs. If we run in a container we likely just
1466                  * got the host sysfs mounted. Since devices are generally not virtualized for containers,
1467                  * let's assume containers never have a TPM, at least for now. */
1468 
1469                 r = dir_is_empty("/sys/class/tpmrm", /* ignore_hidden_or_backup= */ false);
1470                 if (r < 0) {
1471                         if (r != -ENOENT)
1472                                 log_debug_errno(r, "Unable to test whether /sys/class/tpmrm/ exists and is populated, assuming it is not: %m");
1473                 } else if (r == 0) /* populated! */
1474                         support |= TPM2_SUPPORT_DRIVER;
1475         }
1476 
1477         if (efi_has_tpm2())
1478                 support |= TPM2_SUPPORT_FIRMWARE;
1479 
1480 #if HAVE_TPM2
1481         support |= TPM2_SUPPORT_SYSTEM;
1482 #endif
1483 
1484         return support;
1485 }
1486