diff --git a/src/swtpm_setup/swtpm.c b/src/swtpm_setup/swtpm.c index 55a5a67d..4c6231fb 100644 --- a/src/swtpm_setup/swtpm.c +++ b/src/swtpm_setup/swtpm.c @@ -1198,15 +1198,22 @@ static int swtpm_tpm2_createprimary_spk_rsa(struct swtpm *self, unsigned int rsa } /* Create either an ECC or RSA storage primary key (deprecated) */ -static int swtpm_tpm2_create_spk(struct swtpm *self, gboolean isecc, unsigned int rsa_keysize) +static int swtpm_tpm2_create_spk(struct swtpm *self, enum keyalgo keyalgo, + unsigned int rsa_keysize) { int ret; uint32_t curr_handle; - if (isecc) + switch (keyalgo) { + case KEYALGO_ECC: ret = swtpm_tpm2_createprimary_spk_ecc_nist_p384(self, &curr_handle); - else + break; + case KEYALGO_RSA: ret = swtpm_tpm2_createprimary_spk_rsa(self, rsa_keysize, &curr_handle); + break; + default: + ret = 1; + } if (ret != 0) return 1; @@ -1285,7 +1292,7 @@ static int swtpm_tpm2_createprimary_ek_ecc_nist_p384(struct swtpm *self, gboolea } /* Create an ECC or RSA EK */ -static int swtpm_tpm2_create_ek(struct swtpm *self, gboolean isecc, unsigned int rsa_keysize, +static int swtpm_tpm2_create_ek(struct swtpm *self, enum keyalgo keyalgo, unsigned int rsa_keysize, gboolean allowsigning, gboolean decryption, gboolean lock_nvram, gchar **ekparam, const gchar **key_description) { @@ -1295,11 +1302,17 @@ static int swtpm_tpm2_create_ek(struct swtpm *self, gboolean isecc, unsigned int unsigned char ektemplate[512]; size_t ektemplate_len = sizeof(ektemplate); - if (isecc) { + switch (keyalgo) { + case KEYALGO_ECC: tpm2_ek_handle = TPM2_EK_ECC_SECP384R1_HANDLE; keytype = "ECC"; nvindex = TPM2_NV_INDEX_ECC_SECP384R1_HI_EKTEMPLATE; - } else { + + ret = swtpm_tpm2_createprimary_ek_ecc_nist_p384(self, allowsigning, decryption, &curr_handle, + ektemplate, &ektemplate_len, ekparam, + key_description); + break; + case KEYALGO_RSA: if (rsa_keysize == 2048) { tpm2_ek_handle = TPM2_EK_RSA_HANDLE; keytype = "RSA 2048"; @@ -1316,14 +1329,12 @@ static int swtpm_tpm2_create_ek(struct swtpm *self, gboolean isecc, unsigned int logerr(self->logfile, "Internal error: Unsupported RSA keysize %u.\n", rsa_keysize); return 1; } - } - if (isecc) - ret = swtpm_tpm2_createprimary_ek_ecc_nist_p384(self, allowsigning, decryption, &curr_handle, - ektemplate, &ektemplate_len, ekparam, - key_description); - else ret = swtpm_tpm2_createprimary_ek_rsa(self, rsa_keysize, allowsigning, decryption, &curr_handle, ektemplate, &ektemplate_len, ekparam, key_description); + break; + default: + ret = 1; + } if (ret == 0) ret = swtpm_tpm2_evictcontrol(self, curr_handle, tpm2_ek_handle); @@ -1505,7 +1516,7 @@ static int swtpm_tpm2_write_cert_nvram(struct swtpm *self, uint32_t nvindex, } /* Write the platform certificate into an NVRAM area */ -static int swtpm_tpm2_write_ek_cert_nvram(struct swtpm *self, gboolean isecc, +static int swtpm_tpm2_write_ek_cert_nvram(struct swtpm *self, enum keyalgo keyalgo, unsigned int rsa_keysize, gboolean lock_nvram, const unsigned char *data, size_t data_len) { @@ -1519,7 +1530,8 @@ static int swtpm_tpm2_write_ek_cert_nvram(struct swtpm *self, gboolean isecc, TPMA_NV_NO_DA | TPMA_NV_WRITEDEFINE; - if (!isecc) { + switch (keyalgo) { + case KEYALGO_RSA: if (rsa_keysize == 2048) nvindex = TPM2_NV_INDEX_RSA2048_EKCERT; else if (rsa_keysize == 3072) @@ -1527,9 +1539,11 @@ static int swtpm_tpm2_write_ek_cert_nvram(struct swtpm *self, gboolean isecc, else if (rsa_keysize == 4096) nvindex = TPM2_NV_INDEX_RSA4096_HI_EKCERT; keytype = g_strdup_printf("RSA %d ", rsa_keysize); - } else { + break; + case KEYALGO_ECC: nvindex = TPM2_NV_INDEX_ECC_SECP384R1_HI_EKCERT; keytype = g_strdup("ECC "); + break; } return swtpm_tpm2_write_cert_nvram(self, nvindex, nvindexattrs, data, data_len, diff --git a/src/swtpm_setup/swtpm.h b/src/swtpm_setup/swtpm.h index ed8d3d4a..a5009a06 100644 --- a/src/swtpm_setup/swtpm.h +++ b/src/swtpm_setup/swtpm.h @@ -42,17 +42,22 @@ struct swtpm12_ops { int (*nv_lock)(struct swtpm *self); }; +enum keyalgo { + KEYALGO_RSA = 1, + KEYALGO_ECC = 2, +}; + /* TPM 2 specific ops */ struct swtpm2_ops { int (*shutdown)(struct swtpm *); - int (*create_spk)(struct swtpm *self, gboolean isecc, unsigned int rsa_keysize); - int (*create_ek)(struct swtpm *self, gboolean isecc, unsigned int rsa_keysize, + int (*create_spk)(struct swtpm *self,enum keyalgo keyalgo, unsigned int rsa_keysize); + int (*create_ek)(struct swtpm *self, enum keyalgo keyalgo, unsigned int rsa_keysize, gboolean allowsigning, gboolean decryption, gboolean lock_nvram, gchar **ekparam, const gchar **key_description); int (*get_all_pcr_banks)(struct swtpm *self, gchar ***all_pcr_banks); int (*set_active_pcr_banks)(struct swtpm *self, gchar **pcr_banks_l, gchar **all_pcr_banks, gchar ***active); - int (*write_ek_cert_nvram)(struct swtpm *self, gboolean isecc, unsigned int rsa_keysize, + int (*write_ek_cert_nvram)(struct swtpm *self, enum keyalgo keyalgo, unsigned int rsa_keysize, gboolean lock_nvram, const unsigned char *data, size_t data_len); int (*write_platform_cert_nvram)(struct swtpm *self, gboolean lock_nvram, const unsigned char *data, size_t data_len); diff --git a/src/swtpm_setup/swtpm_setup.c b/src/swtpm_setup/swtpm_setup.c index dfe6871a..8848501e 100644 --- a/src/swtpm_setup/swtpm_setup.c +++ b/src/swtpm_setup/swtpm_setup.c @@ -372,6 +372,7 @@ static int read_certificate_file(const gchar *certsdir, const gchar *filename, */ static int tpm2_persist_certificate(unsigned long flags, const gchar *certsdir, const struct flag_to_certfile *ftc, + enum keyalgo keyalgo, unsigned int rsa_keysize, struct swtpm2 *swtpm2, const gchar *user_certsdir, const gchar *key_type, const gchar *key_description) @@ -388,7 +389,7 @@ static int tpm2_persist_certificate(unsigned long flags, const gchar *certsdir, if (ftc->flag == SETUP_EK_CERT_F) { ret = swtpm2->ops->write_ek_cert_nvram(&swtpm2->swtpm, - !!(flags & SETUP_TPM2_ECC_F), rsa_keysize, + keyalgo, rsa_keysize, !!(flags & SETUP_LOCK_NVRAM_F), (const unsigned char*)filecontent, filecontent_len); } else { @@ -412,6 +413,7 @@ error_unlink: /* Create EK and certificate for a TPM 2 */ static int tpm2_create_ek_and_cert(unsigned long flags, const gchar *config_file, const gchar *certsdir, const gchar *vmid, + enum keyalgo keyalgo, unsigned int rsa_keysize, struct swtpm2 *swtpm2, const gchar *user_certsdir) { @@ -423,7 +425,7 @@ static int tpm2_create_ek_and_cert(unsigned long flags, const gchar *config_file int ret; if (flags & SETUP_CREATE_EK_F) { - ret = swtpm2->ops->create_ek(&swtpm2->swtpm, !!(flags & SETUP_TPM2_ECC_F), rsa_keysize, + ret = swtpm2->ops->create_ek(&swtpm2->swtpm, keyalgo, rsa_keysize, !!(flags & SETUP_ALLOW_SIGNING_F), !!(flags & SETUP_DECRYPTION_F), !!(flags & SETUP_LOCK_NVRAM_F), @@ -445,8 +447,8 @@ static int tpm2_create_ek_and_cert(unsigned long flags, const gchar *config_file key_type = flags_to_certfiles[idx].flag & SETUP_EK_CERT_F ? "ek" : ""; ret = tpm2_persist_certificate(flags, certsdir, &flags_to_certfiles[idx], - rsa_keysize, swtpm2, user_certsdir, - key_type, key_description); + keyalgo, rsa_keysize, swtpm2, + user_certsdir, key_type, key_description); if (ret) return 1; } @@ -459,22 +461,22 @@ static int tpm2_create_ek_and_cert(unsigned long flags, const gchar *config_file /* Create endorsement keys and certificates for a TPM 2 */ static int tpm2_create_eks_and_certs(unsigned long flags, const gchar *config_file, const gchar *certsdir, const gchar *vmid, + enum keyalgo ek1keyalgo, enum keyalgo ek2keyalgo, unsigned int rsa_keysize, struct swtpm2 *swtpm2, const gchar *user_certsdir) { int ret; - /* 1st key will be RSA */ - flags = flags & ~SETUP_TPM2_ECC_F; - ret = tpm2_create_ek_and_cert(flags, config_file, certsdir, vmid, rsa_keysize, swtpm2, - user_certsdir); + /* 1st key will be an RSA key */ + ret = tpm2_create_ek_and_cert(flags, config_file, certsdir, vmid, ek1keyalgo, + rsa_keysize, swtpm2, user_certsdir); if (ret != 0) return 1; - /* 2nd key will be an ECC; no more platform cert */ - flags = (flags & ~SETUP_PLATFORM_CERT_F) | SETUP_TPM2_ECC_F; - return tpm2_create_ek_and_cert(flags, config_file, certsdir, vmid, rsa_keysize, swtpm2, - user_certsdir); + /* 2nd key will be an ECC key; no more platform cert */ + flags &= ~SETUP_PLATFORM_CERT_F; + return tpm2_create_ek_and_cert(flags, config_file, certsdir, vmid, ek2keyalgo, + rsa_keysize, swtpm2, user_certsdir); } /* Get the default PCR banks from the config file and if nothing can @@ -606,11 +608,13 @@ malformatted: static int init_tpm2(unsigned long flags, gchar **swtpm_prg_l, const gchar *config_file, const gchar *tpm2_state_path, const gchar *vmid, const gchar *pcr_banks, const gchar *swtpm_keyopt, int *fds_to_pass, size_t n_fds_to_pass, + enum keyalgo ek1keyalgo, enum keyalgo ek2keyalgo, unsigned int rsa_keysize, const gchar *certsdir, const gchar *user_certsdir, const gchar *json_profile, int json_profile_fd, const gchar *profile_remove_disabled_param) { struct swtpm2 *swtpm2; + enum keyalgo keyalgo; struct swtpm *swtpm; int ret; @@ -633,13 +637,14 @@ static int init_tpm2(unsigned long flags, gchar **swtpm_prg_l, const gchar *conf goto error; if ((flags & SETUP_CREATE_SPK_F)) { - ret = swtpm2->ops->create_spk(swtpm, !!(flags & SETUP_TPM2_ECC_F), rsa_keysize); + keyalgo = flags & SETUP_TPM2_ECC_F ? KEYALGO_ECC : KEYALGO_RSA; + ret = swtpm2->ops->create_spk(swtpm, keyalgo, rsa_keysize); if (ret != 0) goto destroy; } - ret = tpm2_create_eks_and_certs(flags, config_file, certsdir, vmid, rsa_keysize, swtpm2, - user_certsdir); + ret = tpm2_create_eks_and_certs(flags, config_file, certsdir, vmid, ek1keyalgo, + ek2keyalgo, rsa_keysize, swtpm2, user_certsdir); if (ret != 0) goto destroy; } @@ -1448,6 +1453,8 @@ int main(int argc, char *argv[]) struct tm *tm; int ret = 1; g_autoptr(GError) error = NULL; + enum keyalgo ek1keyalgo = KEYALGO_RSA; + enum keyalgo ek2keyalgo = KEYALGO_ECC; setvbuf(stdout, 0, _IONBF, 0); @@ -1993,8 +2000,8 @@ int main(int argc, char *argv[]) swtpm_keyopt, fds_to_pass, n_fds_to_pass, certsdir, user_certsdir); } else { ret = init_tpm2(flags, swtpm_prg_l, config_file, tpm_state_path, vmid, pcr_banks, - swtpm_keyopt, fds_to_pass, n_fds_to_pass, rsa_keysize, certsdir, - user_certsdir, json_profile, json_profile_fd, + swtpm_keyopt, fds_to_pass, n_fds_to_pass, ek1keyalgo, ek2keyalgo, + rsa_keysize, certsdir, user_certsdir, json_profile, json_profile_fd, profile_remove_disabled_param); }