On Fri, Mar 14, 2025 at 02:58:48PM +0100, Yann Diorcet wrote: > For the moment only the system-tpm2 token type is supported. > Hi Yann,
Could you consider creating a cover letter for this patch set? A cover letter is useful for the reviewer to have the overview of the patches before diving into the code. And, the cover letter with '--range-diff' is very helpful to check the difference between revisions. Besides the cover letter, I'd suggest to write more commit messages for each patch. The detailed commit messages benefit not only the reviewer but also other developers who want to read the code. Thanks, Gary Lin > Signed-off-by: Yann Diorcet <diorcet.y...@gmail.com> > --- > grub-core/disk/luks2.c | 152 ++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 149 insertions(+), 3 deletions(-) > > diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c > index 8036d76ff..abe751d64 100644 > --- a/grub-core/disk/luks2.c > +++ b/grub-core/disk/luks2.c > @@ -36,6 +36,9 @@ GRUB_MOD_LICENSE ("GPLv3+"); > #define LUKS_MAGIC_1ST "LUKS\xBA\xBE" > #define LUKS_MAGIC_2ND "SKUL\xBA\xBE" > > +/* From tss2_types.h */ > +#define TPM_MAX_PCRS 24 > + > enum grub_luks2_kdf_type > { > LUKS2_KDF_TYPE_ARGON2I, > @@ -125,6 +128,51 @@ struct grub_luks2_digest > }; > typedef struct grub_luks2_digest grub_luks2_digest_t; > > + > +enum grub_luks2_token_type > +{ > + LUKS2_TOKEN_TYPE_NONE, > + LUKS2_TOKEN_TYPE_SYSTEMD_TPM2 > +}; > + > +typedef enum grub_luks2_token_type grub_luks2_token_type_t; > + > +enum grub_luks2_token_systemd_tpm2_algo_type > +{ > + LUKS2_TOKEN_SYSTEMD_TPM2_ALGO_TYPE_ECC, > + LUKS2_TOKEN_SYSTEMD_TPM2_ALGO_TYPE_RSA > +}; > + > +typedef enum grub_luks2_token_systemd_tpm2_algo_type > grub_luks2_token_systemd_tpm2_algo_type_t; > + > +enum grub_luks2_token_systemd_tpm2_pcr_bank_type > +{ > + LUKS2_TOKEN_SYSTEMD_TPM2_PCR_BANK_TYPE_SHA256, > + LUKS2_TOKEN_SYSTEMD_TPM2_PCR_BANK_TYPE_SHA1 > +}; > + > +typedef enum grub_luks2_token_systemd_tpm2_pcr_bank_type > grub_luks2_token_systemd_tpm2_pcr_bank_type_t; > + > +struct grub_luks2_token > +{ > + grub_uint64_t idx; > + grub_luks2_token_type_t type; > + grub_uint64_t keyslots; > + union > + { > + struct > + { > + grub_uint32_t pcr_mask; > + grub_luks2_token_systemd_tpm2_pcr_bank_type_t pcr_bank; > + grub_luks2_token_systemd_tpm2_algo_type_t primary_alg; > + const char *base64_blob; > + const char *hex_policy_hash; > + const char *base64_srk; > + } systemd_tpm2; > + } u; > +}; > +typedef struct grub_luks2_token grub_luks2_token_t; > + > gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, > grub_uint8_t * dst, grub_size_t blocksize, > grub_size_t blocknumbers); > @@ -258,11 +306,88 @@ luks2_parse_digest (grub_luks2_digest_t *out, const > grub_json_t *digest) > return GRUB_ERR_NONE; > } > > +static grub_err_t > +luks2_parse_token (grub_luks2_token_t *out, const grub_json_t *token) > +{ > + grub_json_t keyslots, pcrs, o; > + grub_size_t i, size; > + grub_uint64_t bit; > + const char *type; > + const char *pcr_bank; > + const char *alg; > + > + if (grub_json_getstring (&type, token, "type")) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest type"); > + else if (grub_strcmp (type, "systemd-tpm2")) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported digest type %s", > type); > + out->type = LUKS2_TOKEN_TYPE_SYSTEMD_TPM2; > + > + if (grub_json_getvalue (&keyslots, token, "keyslots") || > + grub_json_getvalue (&pcrs, token, "tpm2-pcrs") || > + grub_json_getstring (&pcr_bank, token, "tpm2-pcr-bank") || > + grub_json_getstring (&out->u.systemd_tpm2.base64_blob, token, > "tpm2-blob") || > + grub_json_getstring (&out->u.systemd_tpm2.hex_policy_hash, token, > "tpm2-policy-hash")) > + { > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing token parameters"); > + } > + > + if (grub_json_getsize (&size, &pcrs)) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "token references no pcrs"); > + > + out->u.systemd_tpm2.pcr_mask = 0; > + for (i = 0; i < size; i++) > + { > + if (grub_json_getchild (&o, &pcrs, i) || > + grub_json_getuint64 (&bit, &o, NULL) || bit >= TPM_MAX_PCRS) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid pcr"); > + out->u.systemd_tpm2.pcr_mask |= (1 << bit); > + } > + > + if (grub_strcmp (pcr_bank, "sha256") == 0) > + out->u.systemd_tpm2.pcr_bank = > LUKS2_TOKEN_SYSTEMD_TPM2_PCR_BANK_TYPE_SHA256; > + else if (grub_strcmp (pcr_bank, "sha1") == 0) > + out->u.systemd_tpm2.pcr_bank = > LUKS2_TOKEN_SYSTEMD_TPM2_PCR_BANK_TYPE_SHA1; > + else > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported pcr-bank type > %s", pcr_bank); > + > + // Default is hardcoded ECC > + if (grub_json_getstring (&alg, token, "tpm2-primary-alg") == GRUB_ERR_NONE) > + { > + if (grub_strcmp (alg, "ecc") == 0) > + out->u.systemd_tpm2.primary_alg = > LUKS2_TOKEN_SYSTEMD_TPM2_ALGO_TYPE_ECC; > + else if (grub_strcmp (alg, "rsa") == 0) > + out->u.systemd_tpm2.primary_alg = > LUKS2_TOKEN_SYSTEMD_TPM2_ALGO_TYPE_RSA; > + else > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported algo type > %s", alg); > + } > + else > + out->u.systemd_tpm2.primary_alg = LUKS2_TOKEN_SYSTEMD_TPM2_ALGO_TYPE_ECC; > + > + if (grub_json_getsize (&size, &keyslots)) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "token references no > keyslots"); > + out->keyslots = 0; > + for (i = 0; i < size; i++) > + { > + if (grub_json_getchild (&o, &keyslots, i) || > + grub_json_getuint64 (&bit, &o, NULL)) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid keyslot"); > + out->keyslots |= (1 << bit); > + } > + > + /* Optional SRK */ > + if (grub_json_getstring (&out->u.systemd_tpm2.base64_srk, token, > "tpm2_srk")) > + { > + out->u.systemd_tpm2.base64_srk = NULL; > + } > + > + return GRUB_ERR_NONE; > +} > + > static grub_err_t > luks2_get_keyslot (grub_luks2_keyslot_t *k, grub_luks2_digest_t *d, > grub_luks2_segment_t *s, > - const grub_json_t *root, grub_size_t keyslot_json_idx) > + grub_luks2_token_t *t, const grub_json_t *root, > grub_size_t keyslot_json_idx) > { > - grub_json_t keyslots, keyslot, digests, digest, segments, segment; > + grub_json_t keyslots, keyslot, digests, digest, segments, segment, tokens, > token; > grub_size_t json_idx, size; > > /* Get nth keyslot */ > @@ -309,6 +434,27 @@ luks2_get_keyslot (grub_luks2_keyslot_t *k, > grub_luks2_digest_t *d, grub_luks2_s > if (json_idx == size) > return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for digest \"%" > PRIuGRUB_UINT64_T "\"", d->idx); > > + if (t == NULL) > + return GRUB_ERR_NONE; > + > + /* Get token that matches the keyslot. */ > + if (grub_json_getvalue (&tokens, root, "tokens") || > + grub_json_getsize (&size, &tokens)) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not get tokens"); > + for (json_idx = 0; json_idx < size; json_idx++) > + { > + if (grub_json_getchild (&token, &tokens, json_idx) || > + grub_json_getuint64 (&t->idx, &token, NULL) || > + grub_json_getchild (&token, &token, 0) || > + luks2_parse_token (t, &token)) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse token index > %" PRIuGRUB_SIZE, json_idx); > + > + if ((t->keyslots & (1 << k->idx))) > + break; > + } > + if (json_idx == size) > + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No token for keyslot \"%" > PRIuGRUB_UINT64_T "\"", k->idx); > + > return GRUB_ERR_NONE; > } > > @@ -626,7 +772,7 @@ luks2_recover_key (grub_disk_t source, > typeof (source->total_sectors) max_crypt_sectors = 0; > > grub_errno = GRUB_ERR_NONE; > - ret = luks2_get_keyslot (&keyslot, &digest, &segment, json, json_idx); > + ret = luks2_get_keyslot (&keyslot, &digest, &segment, NULL, json, > json_idx); > if (ret) > { > /* > -- > 2.39.5 > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel