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 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel