Stephan,
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 <[email protected]>
> ---
> 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 */
Btw, 5.6.2.3.3 is partial validation, 5.6.2.3.2 is full validation
routine.
Thanks,
> +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
>
>
>