[U-Boot] [RFC 2/3] lib: rsa: generate additional parameters for public key

Heinrich Schuchardt xypron.glpk at gmx.de
Thu Oct 3 13:37:14 UTC 2019


On 10/3/19 10:58 AM, AKASHI Takahiro wrote:
> Ilias,
>
> On Thu, Oct 03, 2019 at 10:34:33AM +0300, Ilias Apalodimas wrote:
>> On Fri, Sep 06, 2019 at 04:08:07PM +0900, AKASHI Takahiro 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 at linaro.org>
>>> ---
>>>   include/u-boot/rsa-mod-exp.h |   3 +
>>>   lib/rsa/Makefile             |   2 +-
>>>   lib/rsa/rsa-keyprop.c        | 631 +++++++++++++++++++++++++++++++++++
>>>   3 files changed, 635 insertions(+), 1 deletion(-)
>>>   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..ca189292d869 100644
>>> --- a/include/u-boot/rsa-mod-exp.h
>>> +++ b/include/u-boot/rsa-mod-exp.h
>>> @@ -26,6 +26,9 @@ struct key_prop {
>>>   	uint32_t exp_len;	/* Exponent length in number of uint8_t */
>>>   };
>>>
>>> +struct key_prop *rsa_gen_key_prop(const void *key, uint32_t keylen);
>>> +void rsa_free_key_prop(struct key_prop *prop);
>>> +
>>>   /**
>>>    * rsa_mod_exp_sw() - Perform RSA Modular Exponentiation in sw
>>>    *
>>> --- /dev/null
>>> +++ b/lib/rsa/rsa-keyprop.c
>>> @@ -0,0 +1,631 @@
>>> +
>>
>> [...]
>>
>>> +/* stripped version of src/inner.h */
>>> +
>>> +static inline unsigned
>>> +br_dec16be(const void *src)
>>> +{
>>> +#if 0 /* BR_BE_UNALIGNED */
>>> +	return ((const br_union_u16 *)src)->u;
>>> +#else
>>> +	const unsigned char *buf;
>>> +
>>> +	buf = src;
>>> +	return ((unsigned)buf[0] << 8) | (unsigned)buf[1];
>>> +#endif
>>> +}
>>> +
>>> +static inline uint32_t
>>> +br_dec32be(const void *src)
>>> +{
>>> +#if 0 /* BR_BE_UNALIGNED */
>>> +	return ((const br_union_u32 *)src)->u;
>>> +#else
>>> +	const unsigned char *buf;
>>> +
>>> +	buf = src;
>>> +	return ((uint32_t)buf[0] << 24)
>>> +		| ((uint32_t)buf[1] << 16)
>>> +		| ((uint32_t)buf[2] << 8)
>>> +		| (uint32_t)buf[3];
>>> +#endif
>>> +}
>>> +
>>> +static inline void
>>> +br_enc32be(void *dst, uint32_t x)
>>> +{
>>> +#if 0 /* BR_BE_UNALIGNED */
>>> +	((br_union_u32 *)dst)->u = x;
>>> +#else
>>> +	unsigned char *buf;
>>> +
>>> +	buf = dst;
>>> +	buf[0] = (unsigned char)(x >> 24);
>>> +	buf[1] = (unsigned char)(x >> 16);
>>> +	buf[2] = (unsigned char)(x >> 8);
>>> +	buf[3] = (unsigned char)x;
>>> +#endif
>>> +}
>>> +
>>
>> There's no U-Boot API for the above?
>
> Do you mean dec32be() and enc32be()?
> Yes, there are similar functions but I intentionally don't
> use them as I want to keep the difference between BearSSL's
> original code and imported one in this file to a minimum.
>
> Anyhow, this code won't work for big-endian. We should manage it.

htonl() does the conversion both for big- and little-endian for properly
aligned fields.

Tom is always unhappy when we unnecessarily enlarge the U-Boot binary.

Best regards

Heinrich

>
>>> +static inline uint32_t
>>> +NOT(uint32_t ctl)
>>> +{
>>> +	return ctl ^ 1;
>>> +}
>>
>> Ditto
>>
>>> +
>>> +static inline uint32_t
>>> +MUX(uint32_t ctl, uint32_t x, uint32_t y)
>>> +{
>>> +	return y ^ (-ctl & (x ^ y));
>>> +}
>>> +
>>> +static inline uint32_t
>>> +EQ(uint32_t x, uint32_t y)
>>> +{
>>> +	uint32_t q;
>>> +
>>> +	q = x ^ y;
>>> +	return NOT((q | -q) >> 31);
>>> +}
>>> +
>>> +static inline uint32_t
>>> +NEQ(uint32_t x, uint32_t y)
>>> +{
>>> +	uint32_t q;
>>> +
>>> +	q = x ^ y;
>>> +	return (q | -q) >> 31;
>>> +}
>>> +
>>> +static inline uint32_t
>>> +GT(uint32_t x, uint32_t y)
>>> +{
>>> +	/*
>>> +	 * If both x < 2^31 and x < 2^31, then y-x will have its high
>>
>> second one should be y^31
>
> Do you mean that the second "x < 2^31" be "y < 2^31"?
> You're right.
>
> Thanks,
> -Takahiro Akashi
>
>>
>>> +	 * bit set if x > y, cleared otherwise.
>>> +	 *
>>> +}
>>> +
>>> +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
>>> +	uint32_t *n, *rr, *rrtmp;
>>> +	int rlen, i, ret;
>>> +	prop->n0inv = br_i32_ninv32(n[1]);
>>> --
>>> 2.21.0
>>>
>>> _______________________________________________
>>> U-Boot mailing list
>>> U-Boot at lists.denx.de
>>> https://lists.denx.de/listinfo/u-boot
>>
>>
>> Regards
>> /Ilias
>



More information about the U-Boot mailing list