Re: [PATCH v11 13/20] util/grub-protect: Add new tool

2024-04-15 Thread Gary Lin via Grub-devel
On Mon, Apr 15, 2024 at 05:40:53PM +0800, Gary Lin wrote:
> On Fri, Apr 12, 2024 at 04:52:02PM -0400, Stefan Berger wrote:
> > 
> > 
> > On 4/12/24 04:39, Gary Lin via Grub-devel wrote:
> > > From: Hernan Gatta 
> > > 
> > > 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/boot/grub2/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/boot/grub2/sealed.key
> > > 
> > > Then, in the boot script, for TPM 2.0 Key File:
> > > 
> > > tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm
> > > cryptomount -u  -P tpm2
> > > 
> > > Or, for the raw sealed key:
> > > 
> > > tpm2_key_protector_init --keyfile=(hd0,gpt1)/boot/grub2/sealed.key 
> > > --pcrs=0,2,4,7,9
> > > cryptomount -u  -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.
> > > 
> > > Signed-off-by: Hernan Gatta 
> > > Signed-off-by: Gary Lin 
> > > ---
> > >   .gitignore  |2 +
> > >   Makefile.util.def   |   22 +
> > >   configure.ac|   30 +
> > >   util/grub-protect.c | 1396 +++
> > >   4 files changed, 1450 insertions(+)
> > >   create mode 100644 util/grub-protect.c
> > > 
[...]
> > > +  /* Create SRK */
> > > +  authCommand.sessionHandle = TPM_RS_PW;
> > > +  inPublic.publicArea.type = args->srk_type.type;
> > > +  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->srk_type.type)
> > > +{
> > > +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 = 
> > > args->srk_type.detail.rsa_bits;
> > 
> > Same comment here about pairing RSA3072 with AES-256 and SHA-512 maybe
> > (since SHA 384 isn't supported here).
> > 
> It's sad that we don't have native SHA384 support due to the outdated
> libgcrypt :(
> 
I revised the code and found We actually don't need libgcrypt here. When
writing the patches to support authorized policy, TPM2_Hash() was introduced,
and we can replace grub_crypto_hash() with TPM2_Hash() to enable SHA-384
digest calculation.

Gary Lin

> > Rest LGTM.
> > 
> Thanks for reviewing the patch!
> 
> Gary Lin
> 

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v11 13/20] util/grub-protect: Add new tool

2024-04-15 Thread Gary Lin via Grub-devel
On Fri, Apr 12, 2024 at 04:52:02PM -0400, Stefan Berger wrote:
> 
> 
> On 4/12/24 04:39, Gary Lin via Grub-devel wrote:
> > From: Hernan Gatta 
> > 
> > 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/boot/grub2/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/boot/grub2/sealed.key
> > 
> > Then, in the boot script, for TPM 2.0 Key File:
> > 
> > tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm
> > cryptomount -u  -P tpm2
> > 
> > Or, for the raw sealed key:
> > 
> > tpm2_key_protector_init --keyfile=(hd0,gpt1)/boot/grub2/sealed.key 
> > --pcrs=0,2,4,7,9
> > cryptomount -u  -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.
> > 
> > Signed-off-by: Hernan Gatta 
> > Signed-off-by: Gary Lin 
> > ---
> >   .gitignore  |2 +
> >   Makefile.util.def   |   22 +
> >   configure.ac|   30 +
> >   util/grub-protect.c | 1396 +++
> >   4 files changed, 1450 insertions(+)
> >   create mode 100644 util/grub-protect.c
> > 
> > diff --git a/.gitignore b/.gitignore
> > index 4d0dfb700..d7b7c22d6 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 19ad5a96f..a0a3e2cd5 100644
> > --- a/Makefile.util.def
> > +++ b/Makefile.util.def
> > @@ -207,6 +207,28 @@ program = {
> > ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
> >   };
> > +program = {
> > +  name = grub-protect;
> > +
> > +  common = grub-core/osdep/init.c;
> > +  common = grub-core/tpm2/args.c;
> > +  common = grub-core/tpm2/buffer.c;
> > +  common = grub-core/tpm2/mu.c;
> > +  common = grub-core/tpm2/tpm2.c;
> > +  common = grub-core/tpm2/tpm2key_asn1_tab.c;
> > +  common = util/grub-protect.c;
> > +  common = util/probe.c;
> > +
> > +  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 84a202c6e..3a07ab570 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])
> > @@ -2057,6 +2058,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="exp

Re: [PATCH v11 13/20] util/grub-protect: Add new tool

2024-04-12 Thread Stefan Berger



On 4/12/24 04:39, Gary Lin via Grub-devel wrote:

From: Hernan Gatta 

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/boot/grub2/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/boot/grub2/sealed.key

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

tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm
cryptomount -u  -P tpm2

Or, for the raw sealed key:

tpm2_key_protector_init --keyfile=(hd0,gpt1)/boot/grub2/sealed.key 
--pcrs=0,2,4,7,9
cryptomount -u  -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.

Signed-off-by: Hernan Gatta 
Signed-off-by: Gary Lin 
---
  .gitignore  |2 +
  Makefile.util.def   |   22 +
  configure.ac|   30 +
  util/grub-protect.c | 1396 +++
  4 files changed, 1450 insertions(+)
  create mode 100644 util/grub-protect.c

diff --git a/.gitignore b/.gitignore
index 4d0dfb700..d7b7c22d6 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 19ad5a96f..a0a3e2cd5 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -207,6 +207,28 @@ program = {
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
  };
  
+program = {

+  name = grub-protect;
+
+  common = grub-core/osdep/init.c;
+  common = grub-core/tpm2/args.c;
+  common = grub-core/tpm2/buffer.c;
+  common = grub-core/tpm2/mu.c;
+  common = grub-core/tpm2/tpm2.c;
+  common = grub-core/tpm2/tpm2key_asn1_tab.c;
+  common = util/grub-protect.c;
+  common = util/probe.c;
+
+  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 84a202c6e..3a07ab570 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])
@@ -2057,6 +2058,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_S

[PATCH v11 13/20] util/grub-protect: Add new tool

2024-04-12 Thread Gary Lin via Grub-devel
From: Hernan Gatta 

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/boot/grub2/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/boot/grub2/sealed.key

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

tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm
cryptomount -u  -P tpm2

Or, for the raw sealed key:

tpm2_key_protector_init --keyfile=(hd0,gpt1)/boot/grub2/sealed.key 
--pcrs=0,2,4,7,9
cryptomount -u  -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.

Signed-off-by: Hernan Gatta 
Signed-off-by: Gary Lin 
---
 .gitignore  |2 +
 Makefile.util.def   |   22 +
 configure.ac|   30 +
 util/grub-protect.c | 1396 +++
 4 files changed, 1450 insertions(+)
 create mode 100644 util/grub-protect.c

diff --git a/.gitignore b/.gitignore
index 4d0dfb700..d7b7c22d6 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 19ad5a96f..a0a3e2cd5 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -207,6 +207,28 @@ program = {
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 };
 
+program = {
+  name = grub-protect;
+
+  common = grub-core/osdep/init.c;
+  common = grub-core/tpm2/args.c;
+  common = grub-core/tpm2/buffer.c;
+  common = grub-core/tpm2/mu.c;
+  common = grub-core/tpm2/tpm2.c;
+  common = grub-core/tpm2/tpm2key_asn1_tab.c;
+  common = util/grub-protect.c;
+  common = util/probe.c;
+
+  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 84a202c6e..3a07ab570 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])
@@ -2057,6 +2058,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])
@@ -2173,6 +2197,7 @@ AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test 
x$enabl