All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: Daniel Kiper <dkiper@net-space.pl>
Cc: grub-devel@gnu.org, Glenn Washburn <development@efficientek.com>
Subject: Re: [PATCH v5 2/2] luks2: Fix decoding of digests and salts with escaped chars
Date: Tue, 12 Jul 2022 16:09:18 +0200	[thread overview]
Message-ID: <Ys2AjincN5qQqtnz@ncase> (raw)
In-Reply-To: <20220712133022.ybsq6w3foq5ynlhv@tomti.i.net-space.pl>

[-- Attachment #1: Type: text/plain, Size: 4402 bytes --]

On Tue, Jul 12, 2022 at 03:30:22PM +0200, Daniel Kiper wrote:
> On Mon, Jul 11, 2022 at 12:44:59PM +0200, Patrick Steinhardt wrote:
> > It was reported in the #grub IRC channel on Libera that decryption of
> > LUKS2 partitions fails with errors about invalid digests and/or salts.
> > In all of these cases, what failed was decoding the Base64
> > representation of these, where the encoded data contained invalid
> > characters.
> >
> > As it turns out, the root cause is that json-c, which is used by
> > cryptsetup to read and write the JSON header, will escape some
> > characters by prepending a backslash when writing JSON strings by
> > default. Most importantly, json-c also escapes the forward slash, which
> > is part of the Base64 alphabet. Because GRUB doesn't know to unescape
> > such characters, decoding this string will rightfully fail.
> >
> > Interestingly, this issue has until now only been reported by users of
> > Ubuntu 18.04. And a bit of digging in fact reveals that cryptsetup has
> > changed the logic in a054206d (Suppress useless slash escaping in json
> > lib, 2018-04-20), which has been released with cryptsetup v2.0.3. Ubuntu
> > 18.04 is still shipping with cryptsetup v2.0.2 though, which explains
> > why this is not a more frequent issue.
> >
> > Fix the issue by using our new `grub_json_unescape ()` helper function
> > that handles unescaping for us.
> >
> > Reported-by: Afdal
> 
> Any chance to add this guy email here?

He didn't want his mail address to be associated with his name here.

> > Signed-off-by: Patrick Steinhardt <ps@pks.im>
> > ---
> >  grub-core/disk/luks2.c | 28 ++++++++++++++++++++++++----
> >  1 file changed, 24 insertions(+), 4 deletions(-)
> >
> > diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
> > index bf741d70f..c24c6e98d 100644
> > --- a/grub-core/disk/luks2.c
> > +++ b/grub-core/disk/luks2.c
> > @@ -384,6 +384,24 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
> >    return cryptodisk;
> >  }
> >
> > +static grub_err_t
> > +luks2_base64_decode (const char *in, grub_size_t inlen, grub_uint8_t *decoded, idx_t *decodedlen)
> > +{
> > +  grub_size_t unescaped_len = 0;
> > +  char *unescaped = NULL;
> > +  bool successful;
> > +
> > +  if (grub_json_unescape (&unescaped, &unescaped_len, in, inlen) != GRUB_ERR_NONE)
> > +    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("could not unescape Base64 string"));
> > +
> > +  successful = base64_decode (unescaped, (grub_size_t) unescaped_len, (char *) decoded, decodedlen);
> 
> Now (grub_size_t) cast seems redundant because unescaped_len is defined
> as grub_size_t.
> 
> Otherwise patch LGTM. So, if you fix this you can add my RB.

Oops, right. Will fix.

Patrick

> > +  grub_free (unescaped);
> > +  if (!successful)
> > +    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("could not decode Base64 string"));
> > +
> > +  return GRUB_ERR_NONE;
> > +}
> > +
> >  static grub_err_t
> >  luks2_verify_key (grub_luks2_digest_t *d, grub_uint8_t *candidate_key,
> >  		  grub_size_t candidate_key_len)
> > @@ -395,9 +413,11 @@ luks2_verify_key (grub_luks2_digest_t *d, grub_uint8_t *candidate_key,
> >    gcry_err_code_t gcry_ret;
> >
> >    /* Decode both digest and salt */
> > -  if (!base64_decode (d->digest, grub_strlen (d->digest), (char *)digest, &digestlen))
> > +  if (luks2_base64_decode (d->digest, grub_strlen (d->digest),
> > +			   digest, &digestlen) != GRUB_ERR_NONE)
> >      return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest");
> > -  if (!base64_decode (d->salt, grub_strlen (d->salt), (char *)salt, &saltlen))
> > +  if (luks2_base64_decode (d->salt, grub_strlen (d->salt),
> > +			   salt, &saltlen) != GRUB_ERR_NONE)
> >      return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest salt");
> >
> >    /* Configure the hash used for the digest. */
> > @@ -435,8 +455,8 @@ luks2_decrypt_key (grub_uint8_t *out_key,
> >    gcry_err_code_t gcry_ret;
> >    grub_err_t ret;
> >
> > -  if (!base64_decode (k->kdf.salt, grub_strlen (k->kdf.salt),
> > -		     (char *)salt, &saltlen))
> > +  if (luks2_base64_decode (k->kdf.salt, grub_strlen (k->kdf.salt),
> > +			   salt, &saltlen) != GRUB_ERR_NONE)
> >      {
> >        ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid keyslot salt");
> >        goto err;
> 
> Daniel

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

      reply	other threads:[~2022-07-12 14:09 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-11 10:44 [PATCH v5 0/2] luks2: Fix decoding of digests and salts with escaped chars Patrick Steinhardt
2022-07-11 10:44 ` [PATCH v5 1/2] json: Add function to unescape JSON-encoded strings Patrick Steinhardt
2022-07-11 13:08   ` Nicholas Vinson
2022-07-12 13:39     ` Daniel Kiper
2022-08-15 15:44       ` Patrick Steinhardt
2022-07-11 10:44 ` [PATCH v5 2/2] luks2: Fix decoding of digests and salts with escaped chars Patrick Steinhardt
2022-07-12 13:30   ` Daniel Kiper
2022-07-12 14:09     ` Patrick Steinhardt [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Ys2AjincN5qQqtnz@ncase \
    --to=ps@pks.im \
    --cc=development@efficientek.com \
    --cc=dkiper@net-space.pl \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.