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 <p...@pks.im> > --- > 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 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel