tpm2-setup: add new early boot tool for initializing the SRK
This adds an explicit service for initializing the TPM2 SRK. This is implicitly also done by systemd-cryptsetup, hence strictly speaking redundant, but doing this early has the benefit that we can parallelize this in a nicer way. This also write a copy of the SRK public key in PEM format to /run/ + /var/lib/, thus pinning the disk image to the TPM. Making the SRK public key is also useful for allowing easy offline encryption for a specific TPM. Sooner or later we should probably grow what this service does, the above is just the first step. For example, the service should probably offer the ability to reset the TPM (clear the owner hierarchy?) on a factory reset, if such a policy is needed. And we might want to install some default AK (?). Fixes: #27986 Also see: #22637
This commit is contained in:
@@ -741,7 +741,7 @@ int generator_write_cryptsetup_unit_section(
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"DefaultDependencies=no\n"
|
||||
"After=cryptsetup-pre.target systemd-udevd-kernel.socket\n"
|
||||
"After=cryptsetup-pre.target systemd-udevd-kernel.socket systemd-tpm2-setup-early.service\n"
|
||||
"Before=blockdev@dev-mapper-%%i.target\n"
|
||||
"Wants=blockdev@dev-mapper-%%i.target\n"
|
||||
"IgnoreOnIsolate=true\n");
|
||||
|
||||
@@ -148,7 +148,7 @@ int dlopen_tpm2(void) {
|
||||
DLSYM_ARG(Tss2_MU_TPMT_PUBLIC_Marshal));
|
||||
}
|
||||
|
||||
static void Esys_Freep(void *p) {
|
||||
void Esys_Freep(void *p) {
|
||||
if (*(void**) p)
|
||||
sym_Esys_Free(*(void**) p);
|
||||
}
|
||||
@@ -1175,7 +1175,7 @@ static int tpm2_get_srk(
|
||||
}
|
||||
|
||||
/* Get the SRK, creating one if needed. Returns 0 on success, or < 0 on error. */
|
||||
static int tpm2_get_or_create_srk(
|
||||
int tpm2_get_or_create_srk(
|
||||
Tpm2Context *c,
|
||||
const Tpm2Handle *session,
|
||||
TPM2B_PUBLIC **ret_public,
|
||||
@@ -1189,7 +1189,7 @@ static int tpm2_get_or_create_srk(
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 1)
|
||||
return 0;
|
||||
return 0; /* 0 → SRK already set up */
|
||||
|
||||
/* No SRK, create and persist one */
|
||||
TPM2B_PUBLIC template = { .size = sizeof(TPMT_PUBLIC), };
|
||||
@@ -1223,7 +1223,7 @@ static int tpm2_get_or_create_srk(
|
||||
/* This should never happen. */
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "SRK we just persisted couldn't be found.");
|
||||
|
||||
return 0;
|
||||
return 1; /* > 0 → SRK newly set up */
|
||||
}
|
||||
|
||||
/* Utility functions for TPMS_PCR_SELECTION. */
|
||||
|
||||
@@ -67,6 +67,8 @@ typedef struct {
|
||||
#define _tpm2_handle(c, h) { .tpm2_context = (c), .esys_handle = (h), }
|
||||
static const Tpm2Handle TPM2_HANDLE_NONE = _tpm2_handle(NULL, ESYS_TR_NONE);
|
||||
|
||||
void Esys_Freep(void *p);
|
||||
|
||||
int tpm2_handle_new(Tpm2Context *context, Tpm2Handle **ret_handle);
|
||||
Tpm2Handle *tpm2_handle_free(Tpm2Handle *handle);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Tpm2Handle*, tpm2_handle_free);
|
||||
@@ -188,6 +190,8 @@ int tpm2_calculate_sealing_policy(const Tpm2PCRValue *pcr_values, size_t n_pcr_v
|
||||
int tpm2_marshal_blob(const TPM2B_PUBLIC *public, const TPM2B_PRIVATE *private, void **ret_blob, size_t *ret_blob_size);
|
||||
int tpm2_unmarshal_blob(const void *blob, size_t blob_size, TPM2B_PUBLIC *ret_public, TPM2B_PRIVATE *ret_private);
|
||||
|
||||
int tpm2_get_or_create_srk(Tpm2Context *c, const Tpm2Handle *session, TPM2B_PUBLIC **ret_public, TPM2B_NAME **ret_name, TPM2B_NAME **ret_qname, Tpm2Handle **ret_handle);
|
||||
|
||||
int tpm2_seal(Tpm2Context *c, const TPM2B_DIGEST *policy, const char *pin, void **ret_secret, size_t *ret_secret_size, void **ret_blob, size_t *ret_blob_size, uint16_t *ret_primary_alg, void **ret_srk_buf, size_t *ret_srk_buf_size);
|
||||
int tpm2_unseal(const char *device, uint32_t hash_pcr_mask, uint16_t pcr_bank, const void *pubkey, size_t pubkey_size, uint32_t pubkey_pcr_mask, JsonVariant *signature, const char *pin, uint16_t primary_alg, const void *blob, size_t blob_size, const void *policy_hash, size_t policy_hash_size, const void *srk_buf, size_t srk_buf_size, void **ret_secret, size_t *ret_secret_size);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user