Just some bike-shedding: On Mon, Jul 13, 2020 at 05:48:57PM +0100, Elena Petrova wrote: > Extending the userspace RNG interface: > 1. adding ALG_SET_DRBG_ENTROPY setsockopt option for entropy input; > 2. using sendmsg syscall for specifying the additional data. > > Signed-off-by: Elena Petrova <lenaptr@xxxxxxxxxx> A cover letter shouldn't really be used for a single patch. Just put the details here in the commit message. > diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c > index 087c0ad09d38..c3d1667db367 100644 > --- a/crypto/algif_rng.c > +++ b/crypto/algif_rng.c > @@ -53,8 +53,24 @@ struct rng_ctx { > #define MAXSIZE 128 > unsigned int len; > struct crypto_rng *drng; > + u8 *addtl; > + size_t addtl_len; > }; > > +struct rng_parent_ctx { > + struct crypto_rng *drng; > + u8 *entropy; > +}; > + > +static void reset_addtl(struct rng_ctx *ctx) > +{ > + if (ctx->addtl) { > + kzfree(ctx->addtl); > + ctx->addtl = NULL; > + } > + ctx->addtl_len = 0; > +} It's recommended to prefix function names. So, reset_addtl => rng_reset_addtl. > +static int rng_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) > +{ > + int err; > + struct alg_sock *ask = alg_sk(sock->sk); > + struct rng_ctx *ctx = ask->private; > + > + reset_addtl(ctx); > + ctx->addtl = kzalloc(len, GFP_KERNEL); > + if (!ctx->addtl) > + return -ENOMEM; Shouldn't the length be limited here? Also, kmalloc would be sufficient since the memcpy_from_msg() immediately below initializes the memory. > + > + err = memcpy_from_msg(ctx->addtl, msg, len); > + if (err) { > + reset_addtl(ctx); > + return err; > + } > + ctx->addtl_len = len; > + > + return 0; > +} > static void *rng_bind(const char *name, u32 type, u32 mask) > { > - return crypto_alloc_rng(name, type, mask); > + struct rng_parent_ctx *pctx; > + void *err_ptr; > + > + pctx = kzalloc(sizeof(*pctx), GFP_KERNEL); > + if (!pctx) > + return ERR_PTR(-ENOMEM); > + > + pctx->drng = crypto_alloc_rng(name, type, mask); > + if (!IS_ERR(pctx->drng)) > + return pctx; > + > + err_ptr = pctx->drng; > + kfree(pctx); > + return err_ptr; > } The error handling here is weird. It would be more conventional to do something like: static void *rng_bind(const char *name, u32 type, u32 mask) { struct rng_parent_ctx *pctx; struct crypto_rng *rng; pctx = kzalloc(sizeof(*pctx), GFP_KERNEL); if (!pctx) return ERR_PTR(-ENOMEM); rng = crypto_alloc_rng(name, type, mask); if (IS_ERR(rng)) { kfree(pctx); return ERR_CAST(rng); } pctx->drng = rng; return pctx; } > > static void rng_release(void *private) > { > - crypto_free_rng(private); > + struct rng_parent_ctx *pctx = private; > + if (unlikely(!pctx)) > + return; There should be a blank line between declarations and statements. > + crypto_free_rng(pctx->drng); > + if (pctx->entropy) > + kzfree(pctx->entropy); No need to check for NULL before calling kzfree(). > +static int rng_setentropy(void *private, const u8 *entropy, unsigned int len) > +{ > + struct rng_parent_ctx *pctx = private; > + u8 *kentropy = NULL; > + > + if (pctx->entropy) > + return -EINVAL; > + > + if (entropy && len) { Best to check just 'len', so that users get an error as expected if they accidentally pass entry=NULL len=nonzero. > + kentropy = kzalloc(len, GFP_KERNEL); > + if (!kentropy) > + return -ENOMEM; > + if (copy_from_user(kentropy, entropy, len)) { > + kzfree(kentropy); > + return -EFAULT; > + } This can use memdup_user(). Also, should there be a length limit? > + } > + > + crypto_rng_alg(pctx->drng)->set_ent(pctx->drng, kentropy, len); > + pctx->entropy = kentropy; pctx->entropy could just be a bool 'has_entropy', right? The actual value doesn't need to be saved. - Eric