grub-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]