From: Michael Chang <mchang@suse.com>
To: The development of GNU GRUB <grub-devel@gnu.org>
Cc: shkhisti@microsoft.com, jaskaran.khurana@microsoft.com,
christopher.co@microsoft.com, daniel.mihai@microsoft.com,
rharwood@redhat.com, jaredz@redhat.com,
development@efficientek.com, jejb@linux.ibm.com
Subject: Re: [PATCH v2 5/5] util/grub-protect: Add new tool
Date: Tue, 22 Mar 2022 13:54:29 +0800 [thread overview]
Message-ID: <20220322055429.GC10510@mazu> (raw)
In-Reply-To: <1643720577-22911-6-git-send-email-hegatta@linux.microsoft.com>
On Tue, Feb 01, 2022 at 05:02:57AM -0800, Hernan Gatta wrote:
[snip]
> +static grub_err_t
> +grub_protect_tpm2_get_policy_digest (struct grub_protect_args *args,
> + TPM2B_DIGEST *digest)
> +{
[snip]
> + for (i = 0; i < args->tpm2_pcr_count; i++)
> + {
> + if (pcr_values.digests[i].size != pcr_digest_len)
> + {
> + fprintf (stderr,
> + _("Bad PCR value size: expected %lu bytes but got %u bytes.\n"),
> + pcr_digest_len, pcr_values.digests[i].size);
Again please consider to use PRI[uxd]GRUB_.* for the conversion
specifier, otherwise i386-efi will not build.
Thanks,
Michael
> + goto exit2;
> + }
> +
> + grub_memcpy (pcr_cursor, pcr_values.digests[i].buffer, pcr_digest_len);
> + pcr_cursor += pcr_digest_len;
> + }
> +
> + grub_crypto_hash (hash_spec, pcr_digest, pcr_concat, pcr_concat_len);
> +
> + /* Start Trial Session */
> + nonce.size = TPM_SHA256_DIGEST_SIZE;
> + symmetric.algorithm = TPM_ALG_NULL;
> +
> + rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, 0, &nonce, &salt,
> + TPM_SE_TRIAL, &symmetric, TPM_ALG_SHA256,
> + &session, NULL, 0);
> + if (rc != TPM_RC_SUCCESS)
> + {
> + fprintf (stderr,
> + _("Failed to start trial policy session (TPM error: 0x%x).\n"),
> + rc);
> + err = GRUB_ERR_BAD_DEVICE;
> + goto exit2;
> + }
> +
> + /* PCR Policy */
> + memcpy (pcr_digest_in.buffer, pcr_digest, TPM_SHA256_DIGEST_SIZE);
> +
> + rc = TPM2_PolicyPCR (session, NULL, &pcr_digest_in, &pcr_sel, NULL);
> + if (rc != TPM_RC_SUCCESS)
> + {
> + fprintf (stderr, _("Failed to submit PCR policy (TPM error: 0x%x).\n"),
> + rc);
> + err = GRUB_ERR_BAD_DEVICE;
> + goto exit3;
> + }
> +
> + /* Retrieve Policy Digest */
> + rc = TPM2_PolicyGetDigest (session, NULL, &policy_digest, NULL);
> + if (rc != TPM_RC_SUCCESS)
> + {
> + fprintf (stderr, _("Failed to get policy digest (TPM error: 0x%x).\n"),
> + rc);
> + err = GRUB_ERR_BAD_DEVICE;
> + goto exit3;
> + }
> +
> + /* Epilogue */
> + *digest = policy_digest;
> + err = GRUB_ERR_NONE;
> +
> +exit3:
> + TPM2_FlushContext (session);
> +
> +exit2:
> + grub_free (pcr_concat);
> +
> +exit1:
> + grub_free (pcr_digest);
> +
> + return err;
> +}
> +
> +static grub_err_t
> +grub_protect_tpm2_get_srk (struct grub_protect_args *args, TPM_HANDLE *srk)
> +{
> + TPM_RC rc;
> + TPM2B_PUBLIC public;
> + TPMS_AUTH_COMMAND authCommand = { 0 };
> + TPM2B_SENSITIVE_CREATE inSensitive = { 0 };
> + TPM2B_PUBLIC inPublic = { 0 };
> + TPM2B_DATA outsideInfo = { 0 };
> + TPML_PCR_SELECTION creationPcr = { 0 };
> + TPM2B_PUBLIC outPublic = { 0 };
> + TPM2B_CREATION_DATA creationData = { 0 };
> + TPM2B_DIGEST creationHash = { 0 };
> + TPMT_TK_CREATION creationTicket = { 0 };
> + TPM2B_NAME srkName = { 0 };
> + TPM_HANDLE srkHandle;
> +
> + /* Find SRK */
> + rc = TPM2_ReadPublic (args->tpm2_srk, NULL, &public);
> + if (rc == TPM_RC_SUCCESS)
> + {
> + if (args->tpm2_persist)
> + fprintf (stderr,
> + _("Warning: --tpm2-persist was specified but the SRK already "
> + "exists on the TPM. Continuing anyway...\n"));
> +
> + *srk = TPM2_SRK_HANDLE;
> + return GRUB_ERR_NONE;
> + }
> +
> + /* The handle exists but its public area could not be read. */
> + if ((rc & ~TPM_RC_N_MASK) != TPM_RC_HANDLE)
> + {
> + fprintf (stderr,
> + _("The SRK exists on the TPM but its public area cannot be read "
> + "(TPM error: 0x%x).\n"), rc);
> + return GRUB_ERR_BAD_DEVICE;
> + }
> +
> + /* Create SRK */
> + authCommand.sessionHandle = TPM_RS_PW;
> + inPublic.publicArea.type = args->tpm2_asymmetric;
> + inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
> + inPublic.publicArea.objectAttributes.restricted = 1;
> + inPublic.publicArea.objectAttributes.userWithAuth = 1;
> + inPublic.publicArea.objectAttributes.decrypt = 1;
> + inPublic.publicArea.objectAttributes.fixedTPM = 1;
> + inPublic.publicArea.objectAttributes.fixedParent = 1;
> + inPublic.publicArea.objectAttributes.sensitiveDataOrigin = 1;
> + inPublic.publicArea.objectAttributes.noDA = 1;
> +
> + switch (args->tpm2_asymmetric)
> + {
> + case TPM_ALG_RSA:
> + inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES;
> + inPublic.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128;
> + inPublic.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CFB;
> + inPublic.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
> + inPublic.publicArea.parameters.rsaDetail.keyBits = 2048;
> + inPublic.publicArea.parameters.rsaDetail.exponent = 0;
> + break;
> +
> + case TPM_ALG_ECC:
> + inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES;
> + inPublic.publicArea.parameters.eccDetail.symmetric.keyBits.aes = 128;
> + inPublic.publicArea.parameters.eccDetail.symmetric.mode.aes = TPM_ALG_CFB;
> + inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_NULL;
> + inPublic.publicArea.parameters.eccDetail.curveID = TPM_ECC_NIST_P256;
> + inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL;
> + break;
> +
> + default:
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + rc = TPM2_CreatePrimary (TPM_RH_OWNER, &authCommand, &inSensitive, &inPublic,
> + &outsideInfo, &creationPcr, &srkHandle, &outPublic,
> + &creationData, &creationHash, &creationTicket,
> + &srkName, NULL);
> + if (rc != TPM_RC_SUCCESS)
> + {
> + fprintf (stderr, _("Failed to create SRK (TPM error: 0x%x).\n"), rc);
> + return GRUB_ERR_BAD_DEVICE;
> + }
> +
> + /* Persist SRK */
> + if (args->tpm2_persist)
> + {
> + rc = TPM2_EvictControl (TPM_RH_OWNER, srkHandle, args->tpm2_srk,
> + &authCommand, NULL);
> + if (rc == TPM_RC_SUCCESS)
> + {
> + TPM2_FlushContext (srkHandle);
> + srkHandle = args->tpm2_srk;
> + }
> + else
> + fprintf (stderr,
> + _("Warning: Failed to persist SRK (TPM error: 0x%x\n). "
> + "Continuing anyway...\n"), rc);
> + }
> +
> + /* Epilogue */
> + *srk = srkHandle;
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_protect_tpm2_seal (TPM2B_DIGEST *policyDigest, TPM_HANDLE srk,
> + grub_uint8_t *clearText, grub_size_t clearTextLength,
> + TPM2_SEALED_KEY *sealed_key)
> +{
> + TPM_RC rc;
> + TPMS_AUTH_COMMAND authCommand = { 0 };
> + TPM2B_SENSITIVE_CREATE inSensitive = { 0 };
> + TPM2B_PUBLIC inPublic = { 0 };
> + TPM2B_DATA outsideInfo = { 0 };
> + TPML_PCR_SELECTION pcr_sel = { 0 };
> + TPM2B_PRIVATE outPrivate = { 0 };
> + TPM2B_PUBLIC outPublic = { 0 };
> +
> + /* Seal Data */
> + authCommand.sessionHandle = TPM_RS_PW;
> +
> + inSensitive.sensitive.data.size = clearTextLength;
> + memcpy(inSensitive.sensitive.data.buffer, clearText, clearTextLength);
> +
> + inPublic.publicArea.type = TPM_ALG_KEYEDHASH;
> + inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
> + inPublic.publicArea.parameters.keyedHashDetail.scheme.scheme = TPM_ALG_NULL;
> + inPublic.publicArea.authPolicy = *policyDigest;
> +
> + rc = TPM2_Create (srk, &authCommand, &inSensitive, &inPublic, &outsideInfo,
> + &pcr_sel, &outPrivate, &outPublic, NULL, NULL, NULL, NULL);
> + if (rc != TPM_RC_SUCCESS)
> + {
> + fprintf (stderr, _("Failed to seal key (TPM error: 0x%x).\n"), rc);
> + return GRUB_ERR_BAD_DEVICE;
> + }
> +
> + /* Epilogue */
> + sealed_key->public = outPublic;
> + sealed_key->private = outPrivate;
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_protect_tpm2_export_sealed_key (const char *filepath,
> + TPM2_SEALED_KEY *sealed_key)
> +{
> + grub_err_t err;
> + struct grub_tpm2_buffer buf;
> +
> + grub_tpm2_buffer_init (&buf);
> + grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&buf, &sealed_key->public);
> + grub_tpm2_mu_TPM2B_Marshal (&buf, sealed_key->private.size,
> + sealed_key->private.buffer);
> + if (buf.error)
> + return GRUB_ERR_BAD_ARGUMENT;
> +
> + err = grub_protect_write_file (filepath, buf.data, buf.size);
> + if (err)
> + fprintf (stderr, _("Could not write sealed key file (Error: %u).\n"),
> + errno);
> +
> + return err;
> +}
> +
> +static grub_err_t
> +grub_protect_tpm2_add (struct grub_protect_args *args)
> +{
> + grub_err_t err;
> + grub_uint8_t *key;
> + grub_size_t key_size;
> + TPM_HANDLE srk;
> + TPM2B_DIGEST policy_digest;
> + TPM2_SEALED_KEY sealed_key;
> + char *grub_drive = NULL;
> +
> + grub_protect_get_grub_drive_for_file (args->tpm2_outfile, &grub_drive);
> +
> + err = grub_protect_tpm2_open_device (args->tpm2_device);
> + if (err)
> + return err;
> +
> + err = grub_protect_read_file (args->tpm2_keyfile, (void **)&key, &key_size);
> + if (err)
> + goto exit1;
> +
> + if (key_size > TPM_MAX_SYM_DATA)
> + {
> + fprintf (stderr,
> + _("Input key is too long, maximum allowed size is %u bytes.\n"),
> + TPM_MAX_SYM_DATA);
> + return GRUB_ERR_OUT_OF_RANGE;
> + }
> +
> + err = grub_protect_tpm2_get_srk (args, &srk);
> + if (err)
> + goto exit2;
> +
> + err = grub_protect_tpm2_get_policy_digest (args, &policy_digest);
> + if (err)
> + goto exit3;
> +
> + err = grub_protect_tpm2_seal (&policy_digest, srk, key, key_size,
> + &sealed_key);
> + if (err)
> + goto exit3;
> +
> + err = grub_protect_tpm2_export_sealed_key (args->tpm2_outfile, &sealed_key);
> + if (err)
> + goto exit3;
> +
> + if (grub_drive)
> + {
> + printf (_("GRUB drive for the sealed key file: %s\n"), grub_drive);
> + grub_free (grub_drive);
> + }
> + else
> + {
> + fprintf (stderr,
> + _("Warning: Could not determine GRUB drive for sealed key "
> + "file.\n"));
> + err = GRUB_ERR_NONE;
> + }
> +
> +exit3:
> + TPM2_FlushContext (srk);
> +
> +exit2:
> + grub_free (key);
> +
> +exit1:
> + grub_protect_tpm2_close_device ();
> +
> + return err;
> +}
> +
> +static grub_err_t
> +grub_protect_tpm2_remove (struct grub_protect_args *args)
> +{
> + TPM_RC rc;
> + TPM2B_PUBLIC public;
> + TPMS_AUTH_COMMAND authCommand = { 0 };
> + grub_err_t err;
> +
> + if (!args->tpm2_evict)
> + {
> + printf (_("--tpm2-evict not specified, nothing to do.\n"));
> + return GRUB_ERR_NONE;
> + }
> +
> + err = grub_protect_tpm2_open_device (args->tpm2_device);
> + if (err)
> + return err;
> +
> + /* Find SRK */
> + rc = TPM2_ReadPublic (args->tpm2_srk, NULL, &public);
> + if (rc != TPM_RC_SUCCESS)
> + {
> + fprintf (stderr, _("SRK with handle 0x%x not found.\n"), args->tpm2_srk);
> + err = GRUB_ERR_BAD_ARGUMENT;
> + goto exit1;
> + }
> +
> + /* Evict SRK */
> + authCommand.sessionHandle = TPM_RS_PW;
> +
> + rc = TPM2_EvictControl (TPM_RH_OWNER, args->tpm2_srk, args->tpm2_srk,
> + &authCommand, NULL);
> + if (rc != TPM_RC_SUCCESS)
> + {
> + fprintf (stderr,
> + _("Failed to evict SRK with handle 0x%x (TPM Error: 0x%x).\n"),
> + args->tpm2_srk, rc);
> + err = GRUB_ERR_BAD_DEVICE;
> + goto exit2;
> + }
> +
> + err = GRUB_ERR_NONE;
> +
> +exit2:
> + TPM2_FlushContext (args->tpm2_srk);
> +
> +exit1:
> + grub_protect_tpm2_close_device ();
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_protect_tpm2_run (struct grub_protect_args *args)
> +{
> + switch (args->action)
> + {
> + case GRUB_PROTECT_ACTION_ADD:
> + return grub_protect_tpm2_add (args);
> +
> + case GRUB_PROTECT_ACTION_REMOVE:
> + return grub_protect_tpm2_remove (args);
> +
> + default:
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +}
> +
> +static grub_err_t
> +grub_protect_tpm2_args_verify (struct grub_protect_args *args)
> +{
> + switch (args->action)
> + {
> + case GRUB_PROTECT_ACTION_ADD:
> + if (args->args & GRUB_PROTECT_ARG_TPM2_EVICT)
> + {
> + fprintf (stderr,
> + _("--tpm2-evict is invalid when --action is 'add'.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + if (!args->tpm2_keyfile)
> + {
> + fprintf (stderr, _("--tpm2-keyfile must be specified.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + if (!args->tpm2_outfile)
> + {
> + fprintf (stderr, _("--tpm2-outfile must be specified.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + if (!args->tpm2_device)
> + args->tpm2_device = "/dev/tpm0";
> +
> + if (!args->tpm2_pcr_count)
> + {
> + args->tpm2_pcrs[0] = 7;
> + args->tpm2_pcr_count = 1;
> + }
> +
> + if (!args->tpm2_srk)
> + args->tpm2_srk = TPM2_SRK_HANDLE;
> +
> + if (!args->tpm2_asymmetric)
> + args->tpm2_asymmetric = TPM_ALG_RSA;
> +
> + if (!args->tpm2_bank)
> + args->tpm2_bank = TPM_ALG_SHA256;
> +
> + break;
> +
> + case GRUB_PROTECT_ACTION_REMOVE:
> + if (args->args & GRUB_PROTECT_ARG_TPM2_ASYMMETRIC)
> + {
> + fprintf (stderr,
> + _("--tpm2-asymmetric is invalid when --action is 'remove'.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + if (args->args & GRUB_PROTECT_ARG_TPM2_BANK)
> + {
> + fprintf (stderr,
> + _("--tpm2-bank is invalid when --action is 'remove'.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + if (args->args & GRUB_PROTECT_ARG_TPM2_KEYFILE)
> + {
> + fprintf (stderr,
> + _("--tpm2-keyfile is invalid when --action is 'remove'.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + if (args->args & GRUB_PROTECT_ARG_TPM2_OUTFILE)
> + {
> + fprintf (stderr,
> + _("--tpm2-outfile is invalid when --action is 'remove'.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + if (args->args & GRUB_PROTECT_ARG_TPM2_PCRS)
> + {
> + fprintf (stderr,
> + _("--tpm2-pcrs is invalid when --action is 'remove'.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + if (args->args & GRUB_PROTECT_ARG_TPM2_PERSIST)
> + {
> + fprintf (stderr,
> + _("--tpm2-persist is invalid when --action is 'remove'.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + if (!args->tpm2_device)
> + args->tpm2_device = "/dev/tpm0";
> +
> + if (!args->tpm2_srk)
> + args->tpm2_srk = TPM2_SRK_HANDLE;
> +
> + break;
> +
> + default:
> + fprintf (stderr,
> + _("The TPM2 key protector only supports the following actions: "
> + "add, remove.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +static error_t
> +grub_protect_argp_parser (int key, char *arg, struct argp_state *state)
> +{
> + grub_err_t err;
> + struct grub_protect_args *args = state->input;
> +
> + switch (key)
> + {
> + case GRUB_PROTECT_OPT_ACTION:
> + if (args->args & GRUB_PROTECT_ARG_ACTION)
> + {
> + fprintf (stderr, _("--action|-a can only be specified once.\n"));
> + return EINVAL;
> + }
> +
> + if (grub_strcmp (arg, "add") == 0)
> + args->action = GRUB_PROTECT_ACTION_ADD;
> + else if (grub_strcmp (arg, "remove") == 0)
> + args->action = GRUB_PROTECT_ACTION_REMOVE;
> + else
> + {
> + fprintf (stderr, _("'%s' is not a valid action.\n"), arg);
> + return EINVAL;
> + }
> +
> + args->args |= GRUB_PROTECT_ARG_ACTION;
> + break;
> +
> + case GRUB_PROTECT_OPT_PROTECTOR:
> + if (args->args & GRUB_PROTECT_ARG_PROTECTOR)
> + {
> + fprintf (stderr, _("--protector|-p can only be specified once.\n"));
> + return EINVAL;
> + }
> +
> + if (grub_strcmp (arg, "tpm2") == 0)
> + args->protector = GRUB_PROTECT_TYPE_TPM2;
> + else
> + {
> + fprintf (stderr, _("'%s' is not a valid protector.\n"), arg);
> + return EINVAL;
> + }
> +
> + args->args |= GRUB_PROTECT_ARG_PROTECTOR;
> + break;
> +
> + case GRUB_PROTECT_OPT_TPM2_DEVICE:
> + if (args->args & GRUB_PROTECT_ARG_TPM2_DEVICE)
> + {
> + fprintf (stderr, _("--tpm2-device can only be specified once.\n"));
> + return EINVAL;
> + }
> +
> + args->tpm2_device = xstrdup(arg);
> + args->args |= GRUB_PROTECT_ARG_TPM2_DEVICE;
> + break;
> +
> + case GRUB_PROTECT_OPT_TPM2_PCRS:
> + if (args->args & GRUB_PROTECT_ARG_TPM2_PCRS)
> + {
> + fprintf (stderr, _("--tpm2-pcrs can only be specified once.\n"));
> + return EINVAL;
> + }
> +
> + err = grub_tpm2_protector_parse_pcrs (arg, args->tpm2_pcrs,
> + &args->tpm2_pcr_count);
> + if (err)
> + {
> + if (grub_errno)
> + grub_print_error ();
> + return EINVAL;
> + }
> +
> + args->args |= GRUB_PROTECT_ARG_TPM2_PCRS;
> + break;
> +
> + case GRUB_PROTECT_OPT_TPM2_SRK:
> + if (args->args & GRUB_PROTECT_ARG_TPM2_SRK)
> + {
> + fprintf (stderr, _("--tpm2-srk can only be specified once.\n"));
> + return EINVAL;
> + }
> +
> + err = grub_tpm2_protector_parse_tpm_handle (arg, &args->tpm2_srk);
> + if (err)
> + {
> + if (grub_errno)
> + grub_print_error ();
> + return EINVAL;
> + }
> +
> + args->args |= GRUB_PROTECT_ARG_TPM2_SRK;
> + break;
> +
> + case GRUB_PROTECT_OPT_TPM2_ASYMMETRIC:
> + if (args->args & GRUB_PROTECT_ARG_TPM2_ASYMMETRIC)
> + {
> + fprintf (stderr, _("--tpm2-asymmetric can only be specified once.\n"));
> + return EINVAL;
> + }
> +
> + err = grub_tpm2_protector_parse_asymmetric (arg, &args->tpm2_asymmetric);
> + if (err)
> + {
> + if (grub_errno)
> + grub_print_error ();
> + return EINVAL;
> + }
> +
> + args->args |= GRUB_PROTECT_ARG_TPM2_ASYMMETRIC;
> + break;
> +
> + case GRUB_PROTECT_OPT_TPM2_BANK:
> + if (args->args & GRUB_PROTECT_ARG_TPM2_BANK)
> + {
> + fprintf (stderr, _("--tpm2-bank can only be specified once.\n"));
> + return EINVAL;
> + }
> +
> + err = grub_tpm2_protector_parse_bank (arg, &args->tpm2_bank);
> + if (err)
> + {
> + if (grub_errno)
> + grub_print_error ();
> + return EINVAL;
> + }
> +
> + args->args |= GRUB_PROTECT_ARG_TPM2_BANK;
> + break;
> +
> + case GRUB_PROTECT_OPT_TPM2_KEYFILE:
> + if (args->args & GRUB_PROTECT_ARG_TPM2_KEYFILE)
> + {
> + fprintf (stderr, _("--tpm2-keyfile can only be specified once.\n"));
> + return EINVAL;
> + }
> +
> + args->tpm2_keyfile = xstrdup(arg);
> + args->args |= GRUB_PROTECT_ARG_TPM2_KEYFILE;
> + break;
> +
> + case GRUB_PROTECT_OPT_TPM2_OUTFILE:
> + if (args->args & GRUB_PROTECT_ARG_TPM2_OUTFILE)
> + {
> + fprintf (stderr, _("--tpm2-outfile can only be specified once.\n"));
> + return EINVAL;
> + }
> +
> + args->tpm2_outfile = xstrdup(arg);
> + args->args |= GRUB_PROTECT_ARG_TPM2_OUTFILE;
> + break;
> +
> + case GRUB_PROTECT_OPT_TPM2_PERSIST:
> + if (args->args & GRUB_PROTECT_ARG_TPM2_PERSIST)
> + {
> + fprintf (stderr, _("--tpm2-persist can only be specified once.\n"));
> + return EINVAL;
> + }
> +
> + args->tpm2_persist = 1;
> + args->args |= GRUB_PROTECT_ARG_TPM2_PERSIST;
> + break;
> +
> + case GRUB_PROTECT_OPT_TPM2_EVICT:
> + if (args->args & GRUB_PROTECT_ARG_TPM2_EVICT)
> + {
> + fprintf (stderr, _("--tpm2-evict can only be specified once.\n"));
> + return EINVAL;
> + }
> +
> + args->tpm2_evict = 1;
> + args->args |= GRUB_PROTECT_ARG_TPM2_EVICT;
> + break;
> +
> + default:
> + return ARGP_ERR_UNKNOWN;
> + }
> +
> + return 0;
> +}
> +
> +static grub_err_t
> +grub_protect_args_verify (struct grub_protect_args *args)
> +{
> + if (args->action == GRUB_PROTECT_ACTION_ERROR)
> + {
> + fprintf (stderr, "--action is mandatory.\n");
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + /* At the moment, the only configurable key protector is the TPM2 one, so it
> + * is the only key protector supported by this tool. */
> + if (args->protector != GRUB_PROTECT_TYPE_TPM2)
> + {
> + fprintf (stderr,
> + _("--protector is mandatory and only 'tpm2' is currently "
> + "supported.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + switch (args->protector)
> + {
> + case GRUB_PROTECT_TYPE_TPM2:
> + return grub_protect_tpm2_args_verify (args);
> + default:
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_protect_dispatch (struct grub_protect_args *args)
> +{
> + switch (args->protector)
> + {
> + case GRUB_PROTECT_TYPE_TPM2:
> + return grub_protect_tpm2_run (args);
> + default:
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +}
> +
> +static void
> +grub_protect_init (int *argc, char **argv[])
> +{
> + grub_util_host_init (argc, argv);
> +
> + grub_util_biosdisk_init (NULL);
> +
> + grub_init_all ();
> + grub_gcry_init_all ();
> +
> + grub_lvm_fini ();
> + grub_mdraid09_fini ();
> + grub_mdraid1x_fini ();
> + grub_diskfilter_fini ();
> + grub_diskfilter_init ();
> + grub_mdraid09_init ();
> + grub_mdraid1x_init ();
> + grub_lvm_init ();
> +}
> +
> +static void
> +grub_protect_fini (void)
> +{
> + grub_gcry_fini_all ();
> + grub_fini_all ();
> + grub_util_biosdisk_fini ();
> +}
> +
> +static struct argp grub_protect_argp =
> +{
> + .options = grub_protect_options,
> + .parser = grub_protect_argp_parser,
> + .args_doc = NULL,
> + .doc =
> + N_("Protect a cleartext key using a GRUB key protector that can retrieve "
> + "the key during boot to unlock fully-encrypted disks automatically."),
> + .children = NULL,
> + .help_filter = NULL,
> + .argp_domain = NULL
> +};
> +
> +int
> +main (int argc, char *argv[])
> +{
> + grub_err_t err;
> + struct grub_protect_args args = { 0 };
> +
> + if (argp_parse (&grub_protect_argp, argc, argv, 0, 0, &args) != 0)
> + {
> + fprintf (stderr, _("Could not parse arguments.\n"));
> + return GRUB_ERR_BAD_ARGUMENT;
> + }
> +
> + grub_protect_init (&argc, &argv);
> +
> + err = grub_protect_args_verify (&args);
> + if (err)
> + goto exit;
> +
> + err = grub_protect_dispatch (&args);
> + if (err)
> + goto exit;
> +
> +exit:
> + grub_protect_fini ();
> +
> + return err;
> +}
> --
> 1.8.3.1
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
next prev parent reply other threads:[~2022-03-22 5:54 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-01 13:02 [PATCH v2 0/5] Automatic TPM Disk Unlock Hernan Gatta
2022-02-01 13:02 ` [PATCH v2 1/5] protectors: Add key protectors framework Hernan Gatta
2022-02-01 13:02 ` [PATCH v2 2/5] tpm2: Add TPM Software Stack (TSS) Hernan Gatta
2022-02-01 13:02 ` [PATCH v2 3/5] protectors: Add TPM2 Key Protector Hernan Gatta
2022-03-22 3:47 ` Michael Chang
2022-03-22 5:46 ` Michael Chang
2022-02-01 13:02 ` [PATCH v2 4/5] cryptodisk: Support key protectors Hernan Gatta
2022-02-01 13:02 ` [PATCH v2 5/5] util/grub-protect: Add new tool Hernan Gatta
2022-03-22 5:54 ` Michael Chang [this message]
2022-02-01 21:40 ` [PATCH v2 0/5] Automatic TPM Disk Unlock Didier Spaier
2022-09-23 4:16 ` Max Vohra
2023-02-06 5:53 ` Gary Lin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220322055429.GC10510@mazu \
--to=mchang@suse.com \
--cc=christopher.co@microsoft.com \
--cc=daniel.mihai@microsoft.com \
--cc=development@efficientek.com \
--cc=grub-devel@gnu.org \
--cc=jaredz@redhat.com \
--cc=jaskaran.khurana@microsoft.com \
--cc=jejb@linux.ibm.com \
--cc=rharwood@redhat.com \
--cc=shkhisti@microsoft.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.