All of lore.kernel.org
 help / color / mirror / Atom feed
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3 4/6] lib: rsa: generate additional parameters for public key
Date: Wed, 20 Nov 2019 14:53:28 +0900	[thread overview]
Message-ID: <20191120055326.GA22427@linaro.org> (raw)
In-Reply-To: <CAPnjgZ12oTJ1r2LqQd-H4cEn7pShQ+fvmKFd-aZjY4Y4df6TLg@mail.gmail.com>

Simon,

On Tue, Nov 19, 2019 at 06:59:59PM -0800, Simon Glass wrote:
> Hi Takahiro,
> 
> On Tue, 12 Nov 2019 at 16:47, AKASHI Takahiro
> <takahiro.akashi@linaro.org> wrote:
> >
> > In the current implementation of FIT_SIGNATURE, five parameters for
> > a RSA public key are required while only two of them are essential.
> > (See rsa-mod-exp.h and uImage.FIT/signature.txt)
> > This is a result of considering relatively limited computer power
> > and resources on embedded systems, while such a assumption may not
> > be quite practical for other use cases.
> >
> > In this patch, added is a function, rsa_gen_key_prop(), which will
> > generate additional parameters for other uses, in particular
> > UEFI secure boot, on the fly.
> >
> > Note: the current code uses some "big number" routines from BearSSL
> > for the calculation.
> >
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > ---
> >  include/u-boot/rsa-mod-exp.h |  21 +
> >  lib/rsa/Kconfig              |   1 +
> >  lib/rsa/Makefile             |   1 +
> >  lib/rsa/rsa-keyprop.c        | 717 +++++++++++++++++++++++++++++++++++
> >  4 files changed, 740 insertions(+)
> >  create mode 100644 lib/rsa/rsa-keyprop.c
> >
> > diff --git a/include/u-boot/rsa-mod-exp.h b/include/u-boot/rsa-mod-exp.h
> > index 8a428c4b6a1a..374169b8304e 100644
> > --- a/include/u-boot/rsa-mod-exp.h
> > +++ b/include/u-boot/rsa-mod-exp.h
> > @@ -26,6 +26,27 @@ struct key_prop {
> >         uint32_t exp_len;       /* Exponent length in number of uint8_t */
> >  };
> >
> > +/**
> > + * rsa_gen_key_prop() - Generate key properties of RSA public key
> > + * @key:       Specifies key data in DER format
> > + * @keylen:    Length of @key
> > + *
> > + * This function takes a blob of encoded RSA public key data in DER
> > + * format, parse it and generate all the relevant properties
> > + * in key_prop structure.
> > + *
> > + * Return:     Pointer to struct key_prop on success, NULL on error
> > + */
> > +struct key_prop *rsa_gen_key_prop(const void *key, uint32_t keylen);
> > +
> > +/**
> > + * rsa_free_key_prop() - Free key properties
> > + * @prop:      Pointer to struct key_prop
> > + *
> > + * This function frees all the memories allocated by rsa_gen_key_prop().
> > + */
> > +void rsa_free_key_prop(struct key_prop *prop);
> > +
> >  /**
> >   * rsa_mod_exp_sw() - Perform RSA Modular Exponentiation in sw
> >   *
> > diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig
> > index 71e4c06bf883..d1d6f6cf64a3 100644
> > --- a/lib/rsa/Kconfig
> > +++ b/lib/rsa/Kconfig
> > @@ -33,6 +33,7 @@ config RSA_VERIFY
> >  config RSA_VERIFY_WITH_PKEY
> >         bool "Execute RSA verification without key parameters from FDT"
> >         depends on RSA
> > +       imply RSA_PUBLIC_KEY_PARSER
> >         help
> >           The standard RSA-signature verification code (FIT_SIGNATURE) uses
> >           pre-calculated key properties, that are stored in fdt blob, in
> > diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile
> > index c07305188e0c..14ed3cb4012b 100644
> > --- a/lib/rsa/Makefile
> > +++ b/lib/rsa/Makefile
> > @@ -6,4 +6,5 @@
> >  # Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> >
> >  obj-$(CONFIG_$(SPL_)RSA_VERIFY) += rsa-verify.o rsa-checksum.o
> > +obj-$(CONFIG_RSA_VERIFY_WITH_PKEY) += rsa-keyprop.o
> >  obj-$(CONFIG_RSA_SOFTWARE_EXP) += rsa-mod-exp.o
> > diff --git a/lib/rsa/rsa-keyprop.c b/lib/rsa/rsa-keyprop.c
> > new file mode 100644
> > index 000000000000..9458337cc608
> > --- /dev/null
> > +++ b/lib/rsa/rsa-keyprop.c
> > @@ -0,0 +1,717 @@
> > +// SPDX-License-Identifier: GPL-2.0+ and MIT
> > +/*
> > + * RSA library - generate parameters for a public key
> > + *
> > + * Copyright (c) 2019 Linaro Limited
> > + * Author: AKASHI Takahiro
> > + *
> > + * Big number routines in this file come from BearSSL:
> 
> Can we put these in their own file if we expect to update them? Really
> should be called by the original filename and go in lib/bearsll.

Honestly, I'd rather disagree with you because
* in the original code, each file has only a single function, then
  we will have to introduce bunch of small source files.
* it is quite unlikely for other components to re-use some of
  those functions in the future.
So splitting the file would practically make little use.

> [..]
> 
> > +/**
> > + * rsa_gen_key_prop() - Generate key properties of RSA public key
> > + * @key:       Specifies key data in DER format
> > + * @keylen:    Length of @key
> > + *
> > + * This function takes a blob of encoded RSA public key data in DER
> > + * format, parse it and generate all the relevant properties
> > + * in key_prop structure.
> > + *
> > + * Return:     Pointer to struct key_prop on success, NULL on error
> > + */
> > +struct key_prop *rsa_gen_key_prop(const void *key, uint32_t keylen)
> > +{
> > +       struct key_prop *prop;
> > +       struct rsa_key rsa_key;
> > +#define BR_MAX_RSA_SIZE 4096
> 
> const int?

Will change it to
        const int max_rsa_size = 4096;

> > +       uint32_t *n, *rr, *rrtmp;
> > +       int rlen, i, ret;
> > +
> > +       prop = calloc(sizeof(*prop), 1);
> > +       if (!prop)
> > +               return NULL;
> > +       n = calloc(sizeof(uint32_t), 1 + (BR_MAX_RSA_SIZE >> 5));
> > +       rr = calloc(sizeof(uint32_t), 1 + (BR_MAX_RSA_SIZE >> 5));
> > +       rrtmp = calloc(sizeof(uint32_t), 1 + (BR_MAX_RSA_SIZE >> 5));
> > +       if (!n || !rr || !rrtmp)
> > +               return NULL;
> 
> This can cause memory leak and will likely generate a coverity warning.

Okay, will fix it.

> > +
> > +       ret = rsa_parse_pub_key(&rsa_key, key, keylen);
> > +       if (ret)
> > +               goto err;
> > +
> > +       /* modulus */
> > +       /* removing leading 0's */
> > +       for (i = 0; i < rsa_key.n_sz && !rsa_key.n[i]; i++)
> > +               ;
> > +       prop->num_bits = (rsa_key.n_sz - i) * 8;
> > +       prop->modulus = malloc(rsa_key.n_sz - i);
> > +       if (!prop->modulus)
> > +               goto err;
> > +       memcpy((void *)prop->modulus, &rsa_key.n[i], rsa_key.n_sz - i);
> > +
> > +       /* exponent */
> > +       prop->public_exponent = calloc(1, sizeof(uint64_t));
> > +       if (!prop->public_exponent)
> > +               goto err;
> > +       memcpy((void *)prop->public_exponent + sizeof(uint64_t) - rsa_key.e_sz,
> > +              rsa_key.e, rsa_key.e_sz);
> > +       prop->exp_len = rsa_key.e_sz;
> > +
> > +       /* n0 inverse */
> > +       br_i32_decode(n, &rsa_key.n[i], rsa_key.n_sz - i);
> > +       prop->n0inv = br_i32_ninv32(n[1]);
> > +
> > +       /* R^2 mod n; R = 2^(num_bits) */
> > +       rlen = prop->num_bits * 2; /* #bits of R^2 = (2^num_bits)^2 */
> > +       rr[0] = 0;
> > +       *(uint8_t *)&rr[0] = (1 << (rlen % 8));
> > +       for (i = 1; i < (((rlen + 31) >> 5) + 1); i++)
> > +               rr[i] = 0;
> > +       br_i32_decode(rrtmp, rr, ((rlen + 7) >> 3) + 1);
> > +       br_i32_reduce(rr, rrtmp, n);
> > +
> > +       rlen = (prop->num_bits + 7) >> 3; /* #bytes of R^2 mod n */
> > +       prop->rr = malloc(rlen);
> > +       if (!prop->rr)
> > +               goto err;
> > +       br_i32_encode((void *)prop->rr, rlen, rr);
> > +
> > +       return prop;
> > +
> > +err:
> > +       free(n);
> > +       free(rr);
> > +       free(rrtmp);
> > +       rsa_free_key_prop(prop);
> > +       return NULL;
> 
> This should return -ENOMEM if we are out of memory. The caller cannot
> divine what went wrong.

Agree.

Thank you for your review,
-Takahiro Akashi


> > +}
> > --
> > 2.21.0
> >
> 
> Regards,
> Simon

  reply	other threads:[~2019-11-20  5:53 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-13  0:47 [U-Boot] [PATCH v3 0/6] rsa: extend rsa_verify() for UEFI secure boot AKASHI Takahiro
2019-11-13  0:47 ` [U-Boot] [PATCH v3 1/6] lib: rsa: decouple rsa from FIT image verification AKASHI Takahiro
2019-11-20  2:59   ` Simon Glass
2019-11-13  0:47 ` [U-Boot] [PATCH v3 2/6] rsa: add CONFIG_RSA_VERIFY_WITH_PKEY config AKASHI Takahiro
2019-11-20  2:59   ` Simon Glass
2019-11-13  0:47 ` [U-Boot] [PATCH v3 3/6] include: image.h: add key info to image_sign_info AKASHI Takahiro
2019-11-20  2:59   ` Simon Glass
2019-11-20  5:47     ` AKASHI Takahiro
2019-11-13  0:47 ` [U-Boot] [PATCH v3 4/6] lib: rsa: generate additional parameters for public key AKASHI Takahiro
2019-11-20  2:59   ` Simon Glass
2019-11-20  5:53     ` AKASHI Takahiro [this message]
2019-11-13  0:47 ` [U-Boot] [PATCH v3 5/6] lib: rsa: add rsa_verify_with_pkey() AKASHI Takahiro
2019-11-20  2:59   ` Simon Glass
2019-11-20  5:54     ` AKASHI Takahiro
2019-11-13  0:47 ` [U-Boot] [PATCH v3 6/6] test: add rsa_verify() unit test AKASHI Takahiro
2019-11-20  2:59   ` Simon Glass
2019-11-20  5:58     ` AKASHI Takahiro

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=20191120055326.GA22427@linaro.org \
    --to=takahiro.akashi@linaro.org \
    --cc=u-boot@lists.denx.de \
    /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.