grub-devel
[Top][All Lists]
Advanced

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

Re: [PATCH v4 6/6] disk: Implement support for LUKS2


From: Daniel Kiper
Subject: Re: [PATCH v4 6/6] disk: Implement support for LUKS2
Date: Mon, 18 Nov 2019 15:33:28 +0100
User-agent: NeoMutt/20170113 (1.7.2)

On Mon, Nov 18, 2019 at 09:45:17AM +0100, Patrick Steinhardt wrote:
> With cryptsetup 2.0, a new version of LUKS was introduced that breaks
> compatibility with the previous version due to various reasons. GRUB
> currently lacks any support for LUKS2, making it impossible to decrypt
> disks encrypted with that version. This commit implements support for
> this new format.
>
> Note that LUKS1 and LUKS2 are quite different data formats. While they
> do share the same disk signature in the first few bytes, representation
> of encryption parameters is completely different between both versions.
> While the former version one relied on a single binary header, only,
> LUKS2 uses the binary header only in order to locate the actual metadata
> which is encoded in JSON. Furthermore, the new data format is a lot more
> complex to allow for more flexible setups, like e.g. having multiple
> encrypted segments and other features that weren't previously possible.
> Because of this, it was decided that it doesn't make sense to keep both
> LUKS1 and LUKS2 support in the same module and instead to implement it
> in two different modules "luks" and "luks2".
>
> The proposed support for LUKS2 is able to make use of the metadata to
> decrypt such disks. Note though that in the current version, only the
> PBKDF2 key derival function is supported. This can mostly attributed to
> the fact that the libgcrypt library currently has no support for either
> Argon2i or Argon2id, which are the remaining KDFs supported by LUKS2. It
> wouldn't have been much of a problem to bundle those algorithms with
> GRUB itself, but it was decided against that in order to keep down the
> number of patches required for initial LUKS2 support. Adding it in the
> future would be trivial, given that the code structure is already in
> place.
>
> Signed-off-by: Patrick Steinhardt <address@hidden>
> ---
>  Makefile.util.def           |   4 +-
>  docs/grub.texi              |   5 +-
>  grub-core/Makefile.core.def |   8 +
>  grub-core/disk/luks2.c      | 674 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 688 insertions(+), 3 deletions(-)
>  create mode 100644 grub-core/disk/luks2.c
>
> diff --git a/Makefile.util.def b/Makefile.util.def
> index 969d32f00..94336392b 100644
> --- a/Makefile.util.def
> +++ b/Makefile.util.def
> @@ -3,7 +3,7 @@ AutoGen definitions Makefile.tpl;
>  library = {
>    name = libgrubkern.a;
>    cflags = '$(CFLAGS_GNULIB)';
> -  cppflags = '$(CPPFLAGS_GNULIB)';
> +  cppflags = '$(CPPFLAGS_GNULIB) -I$(srcdir)/grub-core/lib/json';
>
>    common = util/misc.c;
>    common = grub-core/kern/command.c;
> @@ -36,7 +36,9 @@ library = {
>    common = grub-core/kern/misc.c;
>    common = grub-core/kern/partition.c;
>    common = grub-core/lib/crypto.c;
> +  common = grub-core/lib/json/json.c;
>    common = grub-core/disk/luks.c;
> +  common = grub-core/disk/luks2.c;
>    common = grub-core/disk/geli.c;
>    common = grub-core/disk/cryptodisk.c;
>    common = grub-core/disk/AFSplitter.c;
> diff --git a/docs/grub.texi b/docs/grub.texi
> index c25ab7a5f..ab3210458 100644
> --- a/docs/grub.texi
> +++ b/docs/grub.texi
> @@ -4211,8 +4211,9 @@ is requested interactively. Option @var{device} 
> configures specific grub device
>  with specified @var{uuid}; option @option{-a} configures all detected 
> encrypted
>  devices; option @option{-b} configures all geli containers that have boot 
> flag set.
>
> -GRUB suports devices encrypted using LUKS and geli. Note that necessary 
> modules (@var{luks} and @var{geli}) have to be loaded manually before this 
> command can
> -be used.
> +GRUB suports devices encrypted using LUKS, LUKS2 and geli. Note that 
> necessary
> +modules (@var{luks}, @var{luks2} and @var{geli}) have to be loaded manually
> +before this command can be used.
>  @end deffn
>
>
> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> index db346a9f4..a0507a1fa 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -1191,6 +1191,14 @@ module = {
>    common = disk/luks.c;
>  };
>
> +module = {
> +  name = luks2;
> +  common = disk/luks2.c;
> +  common = lib/gnulib/base64.c;
> +  cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
> +  cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/json';
> +};
> +
>  module = {
>    name = geli;
>    common = disk/geli.c;
> diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
> new file mode 100644
> index 000000000..37f42d811
> --- /dev/null
> +++ b/grub-core/disk/luks2.c
> @@ -0,0 +1,674 @@
> +/*
> + *  GRUB  --  GRand Unified Bootloader
> + *  Copyright (C) 2019  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 <grub/cryptodisk.h>
> +#include <grub/types.h>
> +#include <grub/misc.h>
> +#include <grub/mm.h>
> +#include <grub/dl.h>
> +#include <grub/err.h>
> +#include <grub/disk.h>
> +#include <grub/crypto.h>
> +#include <grub/partition.h>
> +#include <grub/i18n.h>
> +
> +#include <base64.h>
> +#include <json.h>
> +
> +GRUB_MOD_LICENSE ("GPLv3+");
> +
> +#define LUKS_MAGIC_1ST "LUKS\xBA\xBE"
> +#define LUKS_MAGIC_2ND "SKUL\xBA\xBE"

Please add empty line here.

> +#define MAX_PASSPHRASE 256
> +
> +enum grub_luks2_kdf_type
> +{
> +  LUKS2_KDF_TYPE_ARGON2I,
> +  LUKS2_KDF_TYPE_PBKDF2
> +};
> +typedef enum grub_luks2_kdf_type grub_luks2_kdf_type_t;

[...]

> +/* Determine whether to use primary or secondary header */
> +static grub_err_t
> +luks2_read_header (grub_disk_t disk, grub_luks2_header_t *outhdr)
> +{
> +  grub_luks2_header_t primary, secondary, *header = &primary;
> +  grub_err_t ret;
> +
> +  /* Read the primary LUKS header. */
> +  ret = grub_disk_read (disk, 0, 0, sizeof (primary), &primary);
> +  if (ret)
> +    return ret;
> +
> +  /* Look for LUKS magic sequence.  */
> +  if (grub_memcmp (primary.magic, LUKS_MAGIC_1ST, sizeof (primary.magic)) ||
> +      grub_be_to_cpu16 (primary.version) != 2)
> +    return GRUB_ERR_BAD_SIGNATURE;

I think that you should use GRUB_ERR_UNKNOWN_FS (GRUB_ERR_BAD_FS?)
instead of GRUB_ERR_BAD_SIGNATURE because the latter has different
meaning (grep for its usage and you know what I mean) here.

> +  /* Read the secondary header. */
> +  ret = grub_disk_read (disk, 0, grub_be_to_cpu64 (primary.hdr_size), sizeof 
> (secondary), &secondary);
> +  if (ret)
> +    return ret;
> +
> +  /* Look for LUKS magic sequence.  */
> +  if (grub_memcmp (secondary.magic, LUKS_MAGIC_2ND, sizeof 
> (secondary.magic)) ||
> +      grub_be_to_cpu16 (secondary.version) != 2)
> +    return GRUB_ERR_BAD_SIGNATURE;

Ditto...

> +  if (grub_be_to_cpu64 (primary.seqid) < grub_be_to_cpu64 (secondary.seqid))
> +      header = &secondary;
> +  grub_memcpy (outhdr, header, sizeof (*header));
> +
> +  return GRUB_ERR_NONE;
> +}

Daniel



reply via email to

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