On Mon, Oct 21, 2024 at 07:11:00PM -0400, Stefan Berger wrote:
>
>
> On 10/21/24 4:07 AM, Gary Lin wrote:
> > From: Hernan Gatta <[email protected]>
> >
> > 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
> >
>
> > +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)
>
> An error message should be either printed here or the caller should print
> out an error. Otherwise no error message appears at all.
>
Right, the user needs to know what goes wrong with file reading.
I'll add messages for every error in this function.
> > + return GRUB_ERR_FILE_NOT_FOUND;
> > +
> > + if (fseek (f, 0, SEEK_END))
> > + {
> > + err = GRUB_ERR_FILE_READ_ERROR;
> > + goto exit1;
> > + }
> > +
> > + len = ftell (f);
> > + if (len <= 0)
> > + {
> > + err = GRUB_ERR_FILE_READ_ERROR;
> > + goto exit1;
> > + }
> > +
> > + rewind (f);
> > +
> > + buf = grub_malloc (len);
> > + if (buf == NULL)
> > + {
> > + err = GRUB_ERR_OUT_OF_MEMORY;
> > + goto exit1;
> > + }
> > +
> > + if (fread (buf, len, 1, f) != 1)
> > + {
> > + err = GRUB_ERR_FILE_READ_ERROR;
> > + goto exit2;
> > + }
> > +
> > + *buffer = buf;
> > + *buffer_size = len;
> > +
> > + buf = NULL;
> > + err = GRUB_ERR_NONE;
> > +
> > + exit2:
> > + grub_free (buf);
> > +
> > + exit1:
>
> probably also print an error message here that something with the file went
> wrong.
>
> > + 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)
>
> Here the caller prints out err. Good.
>
> > + 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)
> > +{
> > + static const grub_size_t header_size = sizeof (grub_uint16_t) +
> > + (2 * sizeof(grub_uint32_t));
> > +
> > + if (write (protector_tpm2_fd, input, input_size) != input_size)
>
> Also here ...
>
> > + return GRUB_ERR_BAD_DEVICE;
> > +
> > + if (read (protector_tpm2_fd, output, output_size) < header_size)
>
> ... and here since the (single) caller does not print an error.
>
I'll add error messages for write()/read() here.
Thanks,
Gary Lin
> > + return GRUB_ERR_BAD_DEVICE;
> > +
> > + return GRUB_ERR_NONE;
> > +}
> > +
_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel