[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 5/5] util/grub-protect: Add new tool
From: |
Michael Chang |
Subject: |
Re: [PATCH v2 5/5] util/grub-protect: Add new tool |
Date: |
Tue, 22 Mar 2022 13:54:29 +0800 |
User-agent: |
Mutt/1.10.1 (2018-07-13) |
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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [PATCH v2 5/5] util/grub-protect: Add new tool,
Michael Chang <=