crypto: dh - allow for passing NULL to the ffdheXYZ(dh)s' ->set_secret()
authorNicolai Stange <nstange@suse.de>
Mon, 21 Feb 2022 12:10:57 +0000 (13:10 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Wed, 2 Mar 2022 22:47:51 +0000 (10:47 +1200)
Ephemeral key generation can be requested from any of the ffdheXYZ(dh)
variants' common ->set_secret() by passing it an (encoded) struct dh
with the key parameter being unset, i.e. with ->key_size == 0. As the
whole purpose of the ffdheXYZ(dh) templates is to fill in the group
parameters as appropriate, they expect ->p and ->g to be unset in any
input struct dh as well. This means that a user would have to encode an
all-zeroes struct dh instance via crypto_dh_encode_key() when requesting
ephemeral key generation from a ffdheXYZ(dh) instance, which is kind of
pointless.

Make dh_safe_prime_set_secret() to decode a struct dh from the supplied
buffer only if the latter is non-NULL and initialize it with all zeroes
otherwise.

That is, it is now possible to call

  crypto_kpp_set_secret(tfm, NULL, 0);

on any ffdheXYZ(dh) tfm for requesting ephemeral key generation.

Signed-off-by: Nicolai Stange <nstange@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/dh.c

index 869a047..d0d24f6 100644 (file)
@@ -444,17 +444,18 @@ static int dh_safe_prime_set_secret(struct crypto_kpp *tfm, const void *buffer,
        struct dh_safe_prime_instance_ctx *inst_ctx =
                dh_safe_prime_instance_ctx(tfm);
        struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
-       struct dh params;
+       struct dh params = {};
        void *buf = NULL, *key = NULL;
        unsigned int buf_size;
        int err;
 
-       err = __crypto_dh_decode_key(buffer, len, &params);
-       if (err)
-               return err;
-
-       if (params.p_size || params.g_size)
-               return -EINVAL;
+       if (buffer) {
+               err = __crypto_dh_decode_key(buffer, len, &params);
+               if (err)
+                       return err;
+               if (params.p_size || params.g_size)
+                       return -EINVAL;
+       }
 
        params.p = inst_ctx->safe_prime->p;
        params.p_size = inst_ctx->safe_prime->p_size;