Reviewed-by: Marcelo Henrique Cerri Tested-by: Marcelo Henrique Cerri On Sun, Jul 12, 2020 at 06:42:14PM +0200, Stephan Müller wrote: > After the generation of a local public key, SP800-56A rev 3 section > 5.6.2.1.3 mandates a validation of that key with a full validation > compliant to section 5.6.2.3.3. > > Only if the full validation passes, the key is allowed to be used. > > The patch adds the full key validation compliant to 5.6.2.3.3 and > performs the required check on the generated public key. > > Signed-off-by: Stephan Mueller > --- > crypto/ecc.c | 31 ++++++++++++++++++++++++++++++- > crypto/ecc.h | 14 ++++++++++++++ > 2 files changed, 44 insertions(+), 1 deletion(-) > > diff --git a/crypto/ecc.c b/crypto/ecc.c > index 52e2d49262f2..7308487e7c55 100644 > --- a/crypto/ecc.c > +++ b/crypto/ecc.c > @@ -1404,7 +1404,9 @@ int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits, > } > > ecc_point_mult(pk, &curve->g, priv, NULL, curve, ndigits); > - if (ecc_point_is_zero(pk)) { > + > + /* SP800-56A rev 3 5.6.2.1.3 key check */ > + if (ecc_is_pubkey_valid_full(curve, pk)) { > ret = -EAGAIN; > goto err_free_point; > } > @@ -1452,6 +1454,33 @@ int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve, > } > EXPORT_SYMBOL(ecc_is_pubkey_valid_partial); > > +/* SP800-56A section 5.6.2.3.3 full verification */ > +int ecc_is_pubkey_valid_full(const struct ecc_curve *curve, > + struct ecc_point *pk) > +{ > + struct ecc_point *nQ; > + > + /* Checks 1 through 3 */ > + int ret = ecc_is_pubkey_valid_partial(curve, pk); > + > + if (ret) > + return ret; > + > + /* Check 4: Verify that nQ is the zero point. */ > + nQ = ecc_alloc_point(pk->ndigits); > + if (!nQ) > + return -ENOMEM; > + > + ecc_point_mult(nQ, pk, curve->n, NULL, curve, pk->ndigits); > + if (!ecc_point_is_zero(nQ)) > + ret = -EINVAL; > + > + ecc_free_point(nQ); > + > + return ret; > +} > +EXPORT_SYMBOL(ecc_is_pubkey_valid_full); > + > int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, > const u64 *private_key, const u64 *public_key, > u64 *secret) > diff --git a/crypto/ecc.h b/crypto/ecc.h > index ab0eb70b9c09..d4e546b9ad79 100644 > --- a/crypto/ecc.h > +++ b/crypto/ecc.h > @@ -147,6 +147,20 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, > int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve, > struct ecc_point *pk); > > +/** > + * ecc_is_pubkey_valid_full() - Full public key validation > + * > + * @curve: elliptic curve domain parameters > + * @pk: public key as a point > + * > + * Valdiate public key according to SP800-56A section 5.6.2.3.3 ECC Full > + * Public-Key Validation Routine. > + * > + * Return: 0 if validation is successful, -EINVAL if validation is failed. > + */ > +int ecc_is_pubkey_valid_full(const struct ecc_curve *curve, > + struct ecc_point *pk); > + > /** > * vli_is_zero() - Determine is vli is zero > * > -- > 2.26.2 > > > > -- Regards, Marcelo