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 <smuel...@chronox.de>
> ---
>  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
> 
> 
> 

Reply via email to