grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v21 25/33] util/grub-protect: Add new tool


From: Stefan Berger
Subject: Re: [PATCH v21 25/33] util/grub-protect: Add new tool
Date: Mon, 4 Nov 2024 13:11:08 -0500
User-agent: Mozilla Thunderbird



On 11/4/24 2:31 AM, Gary Lin wrote:
From: Hernan Gatta <hegatta@linux.microsoft.com>

To utilize the key protectors framework, there must be a way to protect
full-disk encryption keys in the first place. The grub-protect tool
includes support for the TPM2 key protector but other protectors that
require setup ahead of time can be supported in the future.

For the TPM2 key protector, the intended flow is for a user to have a
LUKS 1 or LUKS 2-protected fully-encrypted disk. The user then creates a
new LUKS key file, say by reading /dev/urandom into a file, and creates
a new LUKS key slot for this key. Then, the user invokes the grub-protect
tool to seal this key file to a set of PCRs using the system's TPM 2.0.
The resulting sealed key file is stored in an unencrypted partition such
as the EFI System Partition (ESP) so that GRUB may read it. The user also
has to ensure the cryptomount command is included in GRUB's boot script
and that it carries the requisite key protector (-P) parameter.

Sample usage:

$ dd if=/dev/urandom of=luks-key bs=1 count=32
$ sudo cryptsetup luksAddKey /dev/sdb1 luks-key --pbkdf=pbkdf2 --hash=sha512

To seal the key with TPM 2.0 Key File (recommended):

$ sudo grub-protect --action=add \
                     --protector=tpm2 \
                     --tpm2-pcrs=0,2,4,7,9 \
                     --tpm2key \
                     --tpm2-keyfile=luks-key \
                     --tpm2-outfile=/boot/efi/efi/grub/sealed.tpm

Or, to seal the key with the raw sealed key:

$ sudo grub-protect --action=add \
                     --protector=tpm2 \
                     --tpm2-pcrs=0,2,4,7,9 \
                     --tpm2-keyfile=luks-key \
                     --tpm2-outfile=/boot/efi/efi/grub/sealed.key

Then, in the boot script, for TPM 2.0 Key File:

tpm2_key_protector_init --tpm2key=(hd0,gpt1)/efi/grub/sealed.tpm
cryptomount -u <SDB1_UUID> -P tpm2

Or, for the raw sealed key:

tpm2_key_protector_init --keyfile=(hd0,gpt1)/efi/grub/sealed.key 
--pcrs=0,2,4,7,9
cryptomount -u <SDB1_UUID> -P tpm2

The benefit of using TPM 2.0 Key File is that the PCR set is already
written in the key file, so there is no need to specify PCRs when
invoking tpm2_key_protector_init.

Cc: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
Signed-off-by: Gary Lin <glin@suse.com>
---
  .gitignore                |    2 +
  Makefile.util.def         |   26 +
  configure.ac              |   30 +
  docs/man/grub-protect.h2m |    4 +
  util/grub-protect.c       | 1407 +++++++++++++++++++++++++++++++++++++
  5 files changed, 1469 insertions(+)
  create mode 100644 docs/man/grub-protect.h2m
  create mode 100644 util/grub-protect.c

diff --git a/.gitignore b/.gitignore
index 4c1f91db8..2105d87c8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -169,6 +169,8 @@ widthspec.bin
  /grub-ofpathname.exe
  /grub-probe
  /grub-probe.exe
+/grub-protect
+/grub-protect.exe
  /grub-reboot
  /grub-render-label
  /grub-render-label.exe
diff --git a/Makefile.util.def b/Makefile.util.def
index fb82f59a0..074c0aff7 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -208,6 +208,32 @@ program = {
    ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
  };
+program = {
+  name = grub-protect;
+  mansection = 1;
+
+  common = grub-core/kern/emu/argp_common.c;
+  common = grub-core/osdep/init.c;
+  common = grub-core/lib/tss2/buffer.c;
+  common = grub-core/lib/tss2/tss2_mu.c;
+  common = grub-core/lib/tss2/tpm2_cmd.c;
+  common = grub-core/commands/tpm2_key_protector/args.c;
+  common = grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c;
+  common = util/grub-protect.c;
+  common = util/probe.c;
+
+  cflags = '-I$(srcdir)/grub-core/lib/tss2 
-I$(srcdir)/grub-core/commands/tpm2_key_protector';
+
+  ldadd = libgrubmods.a;
+  ldadd = libgrubgcry.a;
+  ldadd = libgrubkern.a;
+  ldadd = grub-core/lib/gnulib/libgnu.a;
+  ldadd = '$(LIBTASN1)';
+  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) 
$(LIBGEOM)';
+
+  condition = COND_GRUB_PROTECT;
+};
+
  program = {
    name = grub-mkrelpath;
    mansection = 1;
diff --git a/configure.ac b/configure.ac
index 458b8382b..ad1e7bea5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,6 +76,7 @@ grub_TRANSFORM([grub-mkpasswd-pbkdf2])
  grub_TRANSFORM([grub-mkrelpath])
  grub_TRANSFORM([grub-mkrescue])
  grub_TRANSFORM([grub-probe])
+grub_TRANSFORM([grub-protect])
  grub_TRANSFORM([grub-reboot])
  grub_TRANSFORM([grub-script-check])
  grub_TRANSFORM([grub-set-default])
@@ -2068,6 +2069,29 @@ fi
  AC_SUBST([LIBZFS])
  AC_SUBST([LIBNVPAIR])
+AC_ARG_ENABLE([grub-protect],
+             [AS_HELP_STRING([--enable-grub-protect],
+                             [build and install the `grub-protect' utility 
(default=guessed)])])
+if test x"$enable_grub_protect" = xno ; then
+  grub_protect_excuse="explicitly disabled"
+fi
+
+LIBTASN1=
+if test x"$grub_protect_excuse" = x ; then
+  AC_CHECK_LIB([tasn1], [asn1_write_value], [LIBTASN1="-ltasn1"], 
[grub_protect_excuse="need libtasn1 library"])
+fi
+AC_SUBST([LIBTASN1])
+
+if test x"$enable_grub_protect" = xyes && test x"$grub_protect_excuse" != x ; 
then
+  AC_MSG_ERROR([grub-protect was explicitly requested but can't be compiled 
($grub_protect_excuse)])
+fi
+if test x"$grub_protect_excuse" = x ; then
+enable_grub_protect=yes
+else
+enable_grub_protect=no
+fi
+AC_SUBST([enable_grub_protect])
+
  LIBS=""
AC_SUBST([FONT_SOURCE])
@@ -2184,6 +2208,7 @@ AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test 
x$enable_grub_emu_sdl = xyes])
  AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes])
  AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes])
  AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes])
+AM_CONDITIONAL([COND_GRUB_PROTECT], [test x$enable_grub_protect = xyes])
  AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x])
  if test x$FONT_SOURCE != x ; then
     HAVE_FONT_SOURCE=1
@@ -2311,6 +2336,11 @@ echo grub-mount: Yes
  else
  echo grub-mount: No "($grub_mount_excuse)"
  fi
+if [ x"$grub_protect_excuse" = x ]; then
+echo grub-protect: Yes
+else
+echo grub-protect: No "($grub_protect_excuse)"
+fi
  if [ x"$starfield_excuse" = x ]; then
  echo starfield theme: Yes
  echo With DejaVuSans font from $DJVU_FONT_SOURCE
diff --git a/docs/man/grub-protect.h2m b/docs/man/grub-protect.h2m
new file mode 100644
index 000000000..ecf1c9eab
--- /dev/null
+++ b/docs/man/grub-protect.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-protect \- protect a disk key with a key protector
+[DESCRIPTION]
+grub-protect helps to protect a disk encryption key with a specified key 
protector.
diff --git a/util/grub-protect.c b/util/grub-protect.c
new file mode 100644
index 000000000..a120529ef
--- /dev/null
+++ b/util/grub-protect.c
@@ -0,0 +1,1407 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2022 Microsoft Corporation
+ *  Copyright (C) 2023 SUSE LLC
+ *  Copyright (C) 2024 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libtasn1.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <grub/emu/hostdisk.h>
+#include <grub/emu/misc.h>
+
+#include <grub/util/misc.h>
+
+#include <tss2_buffer.h>
+#include <tss2_mu.h>
+#include <tcg2.h>
+#include <tpm2_args.h>
+#include <tpm2.h>
+
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+#pragma GCC diagnostic ignored "-Wmissing-declarations"
+#include <argp.h>
+#pragma GCC diagnostic error "-Wmissing-prototypes"
+#pragma GCC diagnostic error "-Wmissing-declarations"
+
+#include "progname.h"
+
+/* Unprintable option keys for argp */
+typedef enum protect_opt
+{
+  /* General */
+  PROTECT_OPT_ACTION      = 'a',
+  PROTECT_OPT_PROTECTOR   = 'p',
+  /* TPM2 */
+  PROTECT_OPT_TPM2_DEVICE = 0x100,
+  PROTECT_OPT_TPM2_PCRS,
+  PROTECT_OPT_TPM2_ASYMMETRIC,
+  PROTECT_OPT_TPM2_BANK,
+  PROTECT_OPT_TPM2_SRK,
+  PROTECT_OPT_TPM2_KEYFILE,
+  PROTECT_OPT_TPM2_OUTFILE,
+  PROTECT_OPT_TPM2_EVICT,
+  PROTECT_OPT_TPM2_TPM2KEY
+} protect_opt_t;
+
+/* Option flags to keep track of specified arguments */
+typedef enum protect_arg
+{
+  /* General */
+  PROTECT_ARG_ACTION          = 1 << 0,
+  PROTECT_ARG_PROTECTOR       = 1 << 1,
+  /* TPM2 */
+  PROTECT_ARG_TPM2_DEVICE     = 1 << 2,
+  PROTECT_ARG_TPM2_PCRS       = 1 << 3,
+  PROTECT_ARG_TPM2_ASYMMETRIC = 1 << 4,
+  PROTECT_ARG_TPM2_BANK       = 1 << 5,
+  PROTECT_ARG_TPM2_SRK        = 1 << 6,
+  PROTECT_ARG_TPM2_KEYFILE    = 1 << 7,
+  PROTECT_ARG_TPM2_OUTFILE    = 1 << 8,
+  PROTECT_ARG_TPM2_EVICT      = 1 << 9,
+  PROTECT_ARG_TPM2_TPM2KEY    = 1 << 10
+} protect_arg_t;
+
+typedef enum protect_protector
+{
+  PROTECT_TYPE_ERROR,
+  PROTECT_TYPE_TPM2
+} protect_protector_t;
+
+typedef enum protect_action
+{
+  PROTECT_ACTION_ERROR,
+  PROTECT_ACTION_ADD,
+  PROTECT_ACTION_REMOVE
+} protect_action_t;
+
+typedef struct protect_args
+{
+  protect_arg_t args;
+  protect_action_t action;
+  protect_protector_t protector;
+
+  const char *tpm2_device;
+  grub_uint8_t tpm2_pcrs[TPM_MAX_PCRS];
+  grub_uint8_t tpm2_pcr_count;
+  grub_srk_type_t srk_type;
+  TPM_ALG_ID_t tpm2_bank;
+  TPM_HANDLE_t tpm2_srk;
+  const char *tpm2_keyfile;
+  const char *tpm2_outfile;
+  int tpm2_evict;
+  int tpm2_tpm2key;
+} protect_args_t;
+
+static struct argp_option protect_options[] =
+  {
+    /* Top-level options */
+   {
+      .name  = "action",
+      .key   = 'a',
+      .arg   = "add|remove",
+      .flags = 0,
+      .doc   =
+       N_("Add or remove a key protector to or from a key."),
+      .group = 0
+    },
+    {
+      .name  = "protector",
+      .key   = 'p',
+      .arg   = "tpm2",
+      .flags = 0,
+      .doc   =
+       N_("Set key protector to use (only tpm2 is currently supported)."),
+      .group = 0
+    },
+    /* TPM2 key protector options */
+    {
+      .name = "tpm2-device",
+      .key   = PROTECT_OPT_TPM2_DEVICE,
+      .arg   = "FILE",
+      .flags = 0,
+      .doc   =
+       N_("Set the path to the TPM2 device. (default: /dev/tpm0)"),
+      .group = 0
+    },
+    {
+      .name = "tpm2-pcrs",
+      .key   = PROTECT_OPT_TPM2_PCRS,
+      .arg   = "0[,1]...",
+      .flags = 0,
+      .doc   =
+       N_("Set a comma-separated list of PCRs used to authorize key release "
+          "e.g., '7,11'. Please be aware that PCR 0~7 are used by the "
+          "firmware and the measurement result may change after a "
+          "firmware update (for baremetal systems) or a package "
+          "(OVMF/SeaBIOS/SLOF) update in the VM host. This may lead to "
+          "the failure of key unsealing. (default: 7)"),
+      .group = 0
+    },
+    {
+      .name = "tpm2-bank",
+      .key  = PROTECT_OPT_TPM2_BANK,
+      .arg   = "ALG",
+      .flags = 0,
+      .doc   =
+       N_("Set the bank of PCRs used to authorize key release: "
+          "SHA1, SHA256, SHA384, or SHA512. (default: SHA256)"),
+      .group = 0
+    },
+    {
+      .name = "tpm2-keyfile",
+      .key   = PROTECT_OPT_TPM2_KEYFILE,
+      .arg   = "FILE",
+      .flags = 0,
+      .doc   =
+       N_("Set the path to a file that contains the cleartext key to 
protect."),
+      .group = 0
+    },
+    {
+      .name = "tpm2-outfile",
+      .key   = PROTECT_OPT_TPM2_OUTFILE,
+      .arg   = "FILE",
+      .flags = 0,
+      .doc   =
+       N_("Set the path to the file that will contain the key after sealing "
+          "(must be accessible to GRUB during boot)."),
+      .group = 0
+    },
+    {
+      .name = "tpm2-srk",
+      .key   = PROTECT_OPT_TPM2_SRK,
+      .arg   = "NUM",
+      .flags = 0,
+      .doc   =
+       N_("Set the SRK handle if the SRK is to be made persistent."),
+      .group = 0
+    },
+    {
+      .name = "tpm2-asymmetric",
+      .key   = PROTECT_OPT_TPM2_ASYMMETRIC,
+      .arg   = "TYPE",
+      .flags = 0,
+      .doc   =
+       N_("Set the type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)."
+          "(default: ECC)"),
+      .group = 0
+    },
+    {
+      .name = "tpm2-evict",
+      .key   = PROTECT_OPT_TPM2_EVICT,
+      .arg   = NULL,
+      .flags = 0,
+      .doc   =
+       N_("Evict a previously persisted SRK from the TPM, if any."),
+      .group = 0
+    },
+    {
+      .name = "tpm2key",
+      .key   = PROTECT_OPT_TPM2_TPM2KEY,
+      .arg   = NULL,
+      .flags = 0,
+      .doc   =
+       N_("Use TPM 2.0 Key File format."),
+      .group = 0
+    },
+    /* End of list */
+    { 0, 0, 0, 0, 0, 0 }
+  };
+
+static int protector_tpm2_fd = -1;
+
+static grub_err_t
+protect_read_file (const char *filepath, void **buffer, size_t *buffer_size)
+{
+  grub_err_t err;
+  FILE *f;
+  long len;
+  void *buf;
+
+  f = fopen (filepath, "rb");
+  if (f == NULL)
+    {
+      fprintf (stderr, N_("Could not open file: %s\n"), filepath);
+      return GRUB_ERR_FILE_NOT_FOUND;
+    }
+
+  if (fseek (f, 0, SEEK_END))
+    {
+      fprintf (stderr, N_("Could not seek file: %s\n"), filepath);
+      err = GRUB_ERR_FILE_READ_ERROR;
+      goto exit1;
+    }
+
+  len = ftell (f);
+  if (len <= 0)
+    {
+      fprintf (stderr, N_("Could not get file length: %s\n"), filepath);
+      err = GRUB_ERR_FILE_READ_ERROR;
+      goto exit1;
+    }
+
+  rewind (f);
+
+  buf = grub_malloc (len);
+  if (buf == NULL)
+    {
+      fprintf (stderr, N_("Could not allocate memory for file: %s\n"), 
filepath);
+      err = GRUB_ERR_OUT_OF_MEMORY;
+      goto exit1;
+    }
+
+  if (fread (buf, len, 1, f) != 1)
+    {
+      fprintf (stderr, N_("Could not read file: %s\n"), filepath);
+      err = GRUB_ERR_FILE_READ_ERROR;
+      goto exit2;
+    }
+
+  *buffer = buf;
+  *buffer_size = len;
+
+  buf = NULL;
+  err = GRUB_ERR_NONE;
+
+ exit2:
+  grub_free (buf);
+
+ exit1:
+  fclose (f);
+
+  return err;
+}
+
+static grub_err_t
+protect_write_file (const char *filepath, void *buffer, size_t buffer_size)
+{
+  grub_err_t err;
+  FILE *f;
+
+  f = fopen (filepath, "wb");
+  if (f == NULL)
+    return GRUB_ERR_FILE_NOT_FOUND;
+
+  if (fwrite (buffer, buffer_size, 1, f) != 1)
+  {
+    err = GRUB_ERR_WRITE_ERROR;
+    goto exit;
+  }
+
+  err = GRUB_ERR_NONE;
+
+ exit:
+  fclose (f);
+
+  return err;
+}
+
+grub_err_t
+grub_tcg2_get_max_output_size (grub_size_t *size)
+{
+  if (size == NULL)
+    return GRUB_ERR_BAD_ARGUMENT;
+
+  *size = GRUB_TPM2_BUFFER_CAPACITY;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_tcg2_submit_command (grub_size_t input_size, grub_uint8_t *input,
+                         grub_size_t output_size, grub_uint8_t *output)
+{
+  if (write (protector_tpm2_fd, input, input_size) != input_size)
+    {
+      fprintf (stderr, N_("Could not send TPM command.\n"));
+      return GRUB_ERR_BAD_DEVICE;
+    }
+
+  if (read (protector_tpm2_fd, output, output_size) < sizeof 
(TPM_RESPONSE_HEADER_t))
+    {
+      fprintf (stderr, N_("Could not get TPM response.\n"));
+      return GRUB_ERR_BAD_DEVICE;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+protect_tpm2_open_device (const char *dev_node)
+{
+  if (protector_tpm2_fd != -1)
+    return GRUB_ERR_NONE;
+
+  protector_tpm2_fd = open (dev_node, O_RDWR);
+  if (protector_tpm2_fd == -1)
+    {
+      fprintf (stderr, N_("Could not open TPM device (%s).\n"), strerror 
(errno));
+      return GRUB_ERR_FILE_NOT_FOUND;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+protect_tpm2_close_device (void)
+{
+  int err;
+
+  if (protector_tpm2_fd == -1)
+    return GRUB_ERR_NONE;
+
+  err = close (protector_tpm2_fd);
+  if (err != GRUB_ERR_NONE)
+  {
+    fprintf (stderr, N_("Could not close TPM device (%s).\n"), strerror 
(errno));
+    return GRUB_ERR_IO;
+  }
+
+  protector_tpm2_fd = -1;
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+protect_tpm2_get_policy_digest (protect_args_t *args, TPM2B_DIGEST_t *digest)
+{
+  TPM_RC_t rc;
+  TPML_PCR_SELECTION_t pcr_sel = {
+    .count = 1,
+    .pcrSelections = {
+      {
+       .hash = args->tpm2_bank,
+       .sizeOfSelect = 3,
+       .pcrSelect = {0}
+      },
+    }
+  };
+  TPML_PCR_SELECTION_t pcr_sel_out = {0};
+  TPML_DIGEST_t pcr_values = {0};
+  TPM2B_DIGEST_t pcr_digest = {0};
+  grub_size_t pcr_digest_len;
+  TPM2B_MAX_BUFFER_t pcr_concat = {0};
+  grub_size_t pcr_concat_len;
+  grub_uint8_t *pcr_cursor;
+  TPM2B_NONCE_t nonce = {0};
+  TPM2B_ENCRYPTED_SECRET_t salt = {0};
+  TPMT_SYM_DEF_t symmetric = {0};
+  TPMI_SH_AUTH_SESSION_t session = 0;
+  TPM2B_DIGEST_t policy_digest = {0};
+  grub_uint8_t i;
+  grub_err_t err;
+
+  /* PCR Read */
+  for (i = 0; i < args->tpm2_pcr_count; i++)
+    TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], 
args->tpm2_pcrs[i]);
+
+  rc = grub_tpm2_pcr_read (NULL, &pcr_sel, NULL, &pcr_sel_out, &pcr_values, 
NULL);
+  if (rc != TPM_RC_SUCCESS)
+    {
+      fprintf (stderr, "Failed to read PCRs (TPM2_PCR_Read: 0x%x).\n", rc);
+      return GRUB_ERR_BAD_DEVICE;
+    }
+
+  if ((pcr_sel_out.count != pcr_sel.count) ||
+       (pcr_sel.pcrSelections[0].sizeOfSelect !=
+       pcr_sel_out.pcrSelections[0].sizeOfSelect))
+    {
+      fprintf (stderr, N_("Could not read all the specified PCRs.\n"));
+      return GRUB_ERR_BAD_DEVICE;
+    }
+
+  /* Compute PCR Digest */
+  switch (args->tpm2_bank)
+    {
+    case TPM_ALG_SHA1:
+      pcr_digest_len = TPM_SHA1_DIGEST_SIZE;
+      break;
+    case TPM_ALG_SHA256:
+      pcr_digest_len = TPM_SHA256_DIGEST_SIZE;
+      break;
+    case TPM_ALG_SHA384:
+      pcr_digest_len = TPM_SHA384_DIGEST_SIZE;
+      break;
+    case TPM_ALG_SHA512:
+      pcr_digest_len = TPM_SHA512_DIGEST_SIZE;
+      break;
+    default:
+      return GRUB_ERR_BAD_ARGUMENT;
+    }
+
+  pcr_concat_len = pcr_digest_len * args->tpm2_pcr_count;
+  if (pcr_concat_len > TPM_MAX_DIGEST_BUFFER)
+    {
+      fprintf (stderr, N_("PCR concatenation buffer not enough.\n"));


not big enough

Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>




reply via email to

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