RE: [PATCH BlueZ v2 1/1] shared/ecc: Allow pre-composed Private Keys

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

 



Hi Marcel,

> -----Original Message-----
> From: Marcel Holtmann [mailto:marcel@xxxxxxxxxxxx]
> Sent: Monday, April 30, 2018 1:46 AM
> To: Gix, Brian <brian.gix@xxxxxxxxx>
> Cc: Luiz Augusto von Dentz <luiz.dentz@xxxxxxxxx>; linux-
> bluetooth@xxxxxxxxxxxxxxx
> Subject: Re: [PATCH BlueZ v2 1/1] shared/ecc: Allow pre-composed Private
> Keys
> 
> Hi Brian,
> 
> > Add function ecc_make_public_key() which takes a const private_key and
> > generates a validated public_key to complete the pair.
> >
> > Non-ephemeral key sets are required to support Bluetooth Mesh.
> > ---
> > src/shared/ecc.c | 42 +++++++++++++++++++++++++++++-------------
> > src/shared/ecc.h | 17 ++++++++++++++---
> > 2 files changed, 43 insertions(+), 16 deletions(-)
> >
> > diff --git a/src/shared/ecc.c b/src/shared/ecc.c index
> > eb2cc005d..47f229ca9 100644
> > --- a/src/shared/ecc.c
> > +++ b/src/shared/ecc.c
> > @@ -856,33 +856,49 @@ static void ecc_native2bytes(const uint64_t
> native[NUM_ECC_DIGITS],
> > 	}
> > }
> >
> > -bool ecc_make_key(uint8_t public_key[64], uint8_t private_key[32])
> > +bool ecc_make_public_key(const uint8_t private_key[32], uint8_t
> > +public_key[64])
> > {
> > 	struct ecc_point pk;
> > 	uint64_t priv[NUM_ECC_DIGITS];
> > -	unsigned tries = 0;
> >
> > -	do {
> > -		if (!get_random_number(priv) || (tries++ >= MAX_TRIES))
> > -			return false;
> > +	ecc_bytes2native(private_key, priv);
> >
> > -		if (vli_is_zero(priv))
> > -			continue;
> > +	if (vli_is_zero(priv))
> > +		return false;
> >
> > -		/* Make sure the private key is in the range [1, n-1]. */
> > -		if (vli_cmp(curve_n, priv) != 1)
> > -			continue;
> > +	/* Make sure the private key is in the range [1, n-1]. */
> > +	if (vli_cmp(curve_n, priv) != 1)
> > +		return false;
> > +
> > +	ecc_point_mult(&pk, &curve_g, priv, NULL, vli_num_bits(priv));
> >
> > -		ecc_point_mult(&pk, &curve_g, priv, NULL,
> vli_num_bits(priv));
> > -	} while (ecc_point_is_zero(&pk));
> > +	if (ecc_point_is_zero(&pk))
> > +		return false;
> >
> > -	ecc_native2bytes(priv, private_key);
> > 	ecc_native2bytes(pk.x, public_key);
> > 	ecc_native2bytes(pk.y, &public_key[32]);
> >
> > 	return true;
> > }
> >
> > +bool ecc_make_key(uint8_t public_key[64], uint8_t private_key[32]) {
> > +	uint64_t priv[NUM_ECC_DIGITS];
> > +	unsigned tries = 0;
> > +	bool result = false;
> > +
> > +	for (tries = 0; !result && tries < MAX_TRIES; tries++) {
> > +		if (!get_random_number(priv))
> > +			continue;
> > +
> > +		ecc_native2bytes(priv, private_key);
> > +
> > +		result = ecc_make_public_key(private_key, public_key);
> > +	}
> 
> this is actually a functional change. On result == false, the private_key return
> value is now populated. Also the !result in the for-loop check is rather
> complicated. That is hard to follow code. In addition setting tries = 0 on
> declaration is pointless. Just blindly trying to swap a do-while with a for-loop
> is not going to work.
> 
> I would have preferred you didn’t touch ecc_make_key at all and just create
> a new ecc_make_public_key. I think you tried to over-optimize here.

It is a "Functional change on Fail" which I disregarded as trivial (I do not believe
any implementations would use a return private_key on fail) but I do take your point.

Luiz has already applied the patch, but I can re-edit it to restore the original ecc_make_key()
to its original state (making the rest of the comments moot), and add ecc_make_public_key()
as a stand-alone function with no cross dependencies with ecc_make_key(). Thoughts?

> 
> > +
> > +	return result;
> > +}
> > +
> > bool ecc_valid_public_key(const uint8_t public_key[64]) {
> > 	struct ecc_point pk;
> > diff --git a/src/shared/ecc.h b/src/shared/ecc.h index
> > f89f2b0c3..a88e735c7 100644
> > --- a/src/shared/ecc.h
> > +++ b/src/shared/ecc.h
> > @@ -27,14 +27,25 @@
> > #include <stdbool.h>
> > #include <stdint.h>
> >
> > +/* Create a public key from a private key.
> > + *
> > + * Outputs:
> > + *	private_key - Const private key
> 
> This so wrong.
> 
> It is Inputs: private_key and the word “Const” has nothing to do here.

You are correct, that private_key here should be in listed as an Input. 

However const absolutely applies in this case (the input case) since it must
not be changed (it is non-ephemeral).


> 
> > + *	public_key  - Will be filled in with the public key.
> > + *
> > + * Returns true if the public key was generated successfully, false
> > + * if an error occurred. The keys are with the LSB first.
> > + */
> > +bool ecc_make_public_key(const uint8_t private_key[32], uint8_t
> > +public_key[64]);
> > +
> > /* Create a public/private key pair.
> >  *
> >  * Outputs:
> >  *	public_key  - Will be filled in with the public key.
> > - *	private_Key - Will be filled in with the private key.
> > + *	private_key - Will be filled in with the private key.
> >  *
> >  * Returns true if the key pair was generated successfully, false
> > - * if an error occurred. They keys are with the LSB first.
> > + * if an error occurred. The keys are with the LSB first.
> >  */
> > bool ecc_make_key(uint8_t public_key[64], uint8_t private_key[32]);
> >
> > @@ -54,7 +65,7 @@ bool ecc_valid_public_key(const uint8_t
> > public_key[64]);
> >  *
> >  * Inputs:
> >  *	public_key  - The public key of the remote party.
> > - *	private_Key - Your private key.
> > + *	private_key - Your private key.
> >  *
> >  * Outputs:
> >  *	secret - Will be filled in with the shared secret value.
> 
> Regards
> 
> Marcel

��.n��������+%������w��{.n�����{����^n�r������&��z�ޗ�zf���h���~����������_��+v���)ߣ�

[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux