15afdfd22SStephan Mueller /* 25afdfd22SStephan Mueller * algif_rng: User-space interface for random number generators 35afdfd22SStephan Mueller * 45afdfd22SStephan Mueller * This file provides the user-space API for random number generators. 55afdfd22SStephan Mueller * 65afdfd22SStephan Mueller * Copyright (C) 2014, Stephan Mueller <smueller@chronox.de> 75afdfd22SStephan Mueller * 85afdfd22SStephan Mueller * Redistribution and use in source and binary forms, with or without 95afdfd22SStephan Mueller * modification, are permitted provided that the following conditions 105afdfd22SStephan Mueller * are met: 115afdfd22SStephan Mueller * 1. Redistributions of source code must retain the above copyright 125afdfd22SStephan Mueller * notice, and the entire permission notice in its entirety, 135afdfd22SStephan Mueller * including the disclaimer of warranties. 145afdfd22SStephan Mueller * 2. Redistributions in binary form must reproduce the above copyright 155afdfd22SStephan Mueller * notice, this list of conditions and the following disclaimer in the 165afdfd22SStephan Mueller * documentation and/or other materials provided with the distribution. 175afdfd22SStephan Mueller * 3. The name of the author may not be used to endorse or promote 185afdfd22SStephan Mueller * products derived from this software without specific prior 195afdfd22SStephan Mueller * written permission. 205afdfd22SStephan Mueller * 215afdfd22SStephan Mueller * ALTERNATIVELY, this product may be distributed under the terms of 225afdfd22SStephan Mueller * the GNU General Public License, in which case the provisions of the GPL2 235afdfd22SStephan Mueller * are required INSTEAD OF the above restrictions. (This clause is 245afdfd22SStephan Mueller * necessary due to a potential bad interaction between the GPL and 255afdfd22SStephan Mueller * the restrictions contained in a BSD-style copyright.) 265afdfd22SStephan Mueller * 275afdfd22SStephan Mueller * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 285afdfd22SStephan Mueller * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 295afdfd22SStephan Mueller * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 305afdfd22SStephan Mueller * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 315afdfd22SStephan Mueller * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 325afdfd22SStephan Mueller * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 335afdfd22SStephan Mueller * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 345afdfd22SStephan Mueller * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 355afdfd22SStephan Mueller * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 365afdfd22SStephan Mueller * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 375afdfd22SStephan Mueller * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 385afdfd22SStephan Mueller * DAMAGE. 395afdfd22SStephan Mueller */ 405afdfd22SStephan Mueller 41*77ebdabeSElena Petrova #include <linux/capability.h> 425afdfd22SStephan Mueller #include <linux/module.h> 435afdfd22SStephan Mueller #include <crypto/rng.h> 445afdfd22SStephan Mueller #include <linux/random.h> 455afdfd22SStephan Mueller #include <crypto/if_alg.h> 465afdfd22SStephan Mueller #include <linux/net.h> 475afdfd22SStephan Mueller #include <net/sock.h> 485afdfd22SStephan Mueller 495afdfd22SStephan Mueller MODULE_LICENSE("GPL"); 505afdfd22SStephan Mueller MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>"); 515afdfd22SStephan Mueller MODULE_DESCRIPTION("User-space interface for random number generators"); 525afdfd22SStephan Mueller 535afdfd22SStephan Mueller struct rng_ctx { 545afdfd22SStephan Mueller #define MAXSIZE 128 555afdfd22SStephan Mueller unsigned int len; 565afdfd22SStephan Mueller struct crypto_rng *drng; 57*77ebdabeSElena Petrova u8 *addtl; 58*77ebdabeSElena Petrova size_t addtl_len; 595afdfd22SStephan Mueller }; 605afdfd22SStephan Mueller 61*77ebdabeSElena Petrova struct rng_parent_ctx { 62*77ebdabeSElena Petrova struct crypto_rng *drng; 63*77ebdabeSElena Petrova u8 *entropy; 64*77ebdabeSElena Petrova }; 65*77ebdabeSElena Petrova 66*77ebdabeSElena Petrova static void rng_reset_addtl(struct rng_ctx *ctx) 675afdfd22SStephan Mueller { 68*77ebdabeSElena Petrova kfree_sensitive(ctx->addtl); 69*77ebdabeSElena Petrova ctx->addtl = NULL; 70*77ebdabeSElena Petrova ctx->addtl_len = 0; 71*77ebdabeSElena Petrova } 72*77ebdabeSElena Petrova 73*77ebdabeSElena Petrova static int _rng_recvmsg(struct crypto_rng *drng, struct msghdr *msg, size_t len, 74*77ebdabeSElena Petrova u8 *addtl, size_t addtl_len) 75*77ebdabeSElena Petrova { 76*77ebdabeSElena Petrova int err = 0; 775afdfd22SStephan Mueller int genlen = 0; 785afdfd22SStephan Mueller u8 result[MAXSIZE]; 795afdfd22SStephan Mueller 805afdfd22SStephan Mueller if (len == 0) 815afdfd22SStephan Mueller return 0; 825afdfd22SStephan Mueller if (len > MAXSIZE) 835afdfd22SStephan Mueller len = MAXSIZE; 845afdfd22SStephan Mueller 855afdfd22SStephan Mueller /* 865afdfd22SStephan Mueller * although not strictly needed, this is a precaution against coding 875afdfd22SStephan Mueller * errors 885afdfd22SStephan Mueller */ 895afdfd22SStephan Mueller memset(result, 0, len); 905afdfd22SStephan Mueller 915afdfd22SStephan Mueller /* 925afdfd22SStephan Mueller * The enforcement of a proper seeding of an RNG is done within an 935afdfd22SStephan Mueller * RNG implementation. Some RNGs (DRBG, krng) do not need specific 945afdfd22SStephan Mueller * seeding as they automatically seed. The X9.31 DRNG will return 955afdfd22SStephan Mueller * an error if it was not seeded properly. 965afdfd22SStephan Mueller */ 97*77ebdabeSElena Petrova genlen = crypto_rng_generate(drng, addtl, addtl_len, result, len); 985afdfd22SStephan Mueller if (genlen < 0) 995afdfd22SStephan Mueller return genlen; 1005afdfd22SStephan Mueller 1015afdfd22SStephan Mueller err = memcpy_to_msg(msg, result, len); 1022ef4d5c4SStephan Mueller memzero_explicit(result, len); 1035afdfd22SStephan Mueller 1045afdfd22SStephan Mueller return err ? err : len; 1055afdfd22SStephan Mueller } 1065afdfd22SStephan Mueller 107*77ebdabeSElena Petrova static int rng_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, 108*77ebdabeSElena Petrova int flags) 109*77ebdabeSElena Petrova { 110*77ebdabeSElena Petrova struct sock *sk = sock->sk; 111*77ebdabeSElena Petrova struct alg_sock *ask = alg_sk(sk); 112*77ebdabeSElena Petrova struct rng_ctx *ctx = ask->private; 113*77ebdabeSElena Petrova 114*77ebdabeSElena Petrova return _rng_recvmsg(ctx->drng, msg, len, NULL, 0); 115*77ebdabeSElena Petrova } 116*77ebdabeSElena Petrova 117*77ebdabeSElena Petrova static int rng_test_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, 118*77ebdabeSElena Petrova int flags) 119*77ebdabeSElena Petrova { 120*77ebdabeSElena Petrova struct sock *sk = sock->sk; 121*77ebdabeSElena Petrova struct alg_sock *ask = alg_sk(sk); 122*77ebdabeSElena Petrova struct rng_ctx *ctx = ask->private; 123*77ebdabeSElena Petrova int ret; 124*77ebdabeSElena Petrova 125*77ebdabeSElena Petrova lock_sock(sock->sk); 126*77ebdabeSElena Petrova ret = _rng_recvmsg(ctx->drng, msg, len, ctx->addtl, ctx->addtl_len); 127*77ebdabeSElena Petrova rng_reset_addtl(ctx); 128*77ebdabeSElena Petrova release_sock(sock->sk); 129*77ebdabeSElena Petrova 130*77ebdabeSElena Petrova return ret; 131*77ebdabeSElena Petrova } 132*77ebdabeSElena Petrova 133*77ebdabeSElena Petrova static int rng_test_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) 134*77ebdabeSElena Petrova { 135*77ebdabeSElena Petrova int err; 136*77ebdabeSElena Petrova struct alg_sock *ask = alg_sk(sock->sk); 137*77ebdabeSElena Petrova struct rng_ctx *ctx = ask->private; 138*77ebdabeSElena Petrova 139*77ebdabeSElena Petrova lock_sock(sock->sk); 140*77ebdabeSElena Petrova if (len > MAXSIZE) { 141*77ebdabeSElena Petrova err = -EMSGSIZE; 142*77ebdabeSElena Petrova goto unlock; 143*77ebdabeSElena Petrova } 144*77ebdabeSElena Petrova 145*77ebdabeSElena Petrova rng_reset_addtl(ctx); 146*77ebdabeSElena Petrova ctx->addtl = kmalloc(len, GFP_KERNEL); 147*77ebdabeSElena Petrova if (!ctx->addtl) { 148*77ebdabeSElena Petrova err = -ENOMEM; 149*77ebdabeSElena Petrova goto unlock; 150*77ebdabeSElena Petrova } 151*77ebdabeSElena Petrova 152*77ebdabeSElena Petrova err = memcpy_from_msg(ctx->addtl, msg, len); 153*77ebdabeSElena Petrova if (err) { 154*77ebdabeSElena Petrova rng_reset_addtl(ctx); 155*77ebdabeSElena Petrova goto unlock; 156*77ebdabeSElena Petrova } 157*77ebdabeSElena Petrova ctx->addtl_len = len; 158*77ebdabeSElena Petrova 159*77ebdabeSElena Petrova unlock: 160*77ebdabeSElena Petrova release_sock(sock->sk); 161*77ebdabeSElena Petrova return err ? err : len; 162*77ebdabeSElena Petrova } 163*77ebdabeSElena Petrova 1645afdfd22SStephan Mueller static struct proto_ops algif_rng_ops = { 1655afdfd22SStephan Mueller .family = PF_ALG, 1665afdfd22SStephan Mueller 1675afdfd22SStephan Mueller .connect = sock_no_connect, 1685afdfd22SStephan Mueller .socketpair = sock_no_socketpair, 1695afdfd22SStephan Mueller .getname = sock_no_getname, 1705afdfd22SStephan Mueller .ioctl = sock_no_ioctl, 1715afdfd22SStephan Mueller .listen = sock_no_listen, 1725afdfd22SStephan Mueller .shutdown = sock_no_shutdown, 1735afdfd22SStephan Mueller .mmap = sock_no_mmap, 1745afdfd22SStephan Mueller .bind = sock_no_bind, 1755afdfd22SStephan Mueller .accept = sock_no_accept, 1765afdfd22SStephan Mueller .sendmsg = sock_no_sendmsg, 1775afdfd22SStephan Mueller .sendpage = sock_no_sendpage, 1785afdfd22SStephan Mueller 1795afdfd22SStephan Mueller .release = af_alg_release, 1805afdfd22SStephan Mueller .recvmsg = rng_recvmsg, 1815afdfd22SStephan Mueller }; 1825afdfd22SStephan Mueller 183*77ebdabeSElena Petrova static struct proto_ops __maybe_unused algif_rng_test_ops = { 184*77ebdabeSElena Petrova .family = PF_ALG, 185*77ebdabeSElena Petrova 186*77ebdabeSElena Petrova .connect = sock_no_connect, 187*77ebdabeSElena Petrova .socketpair = sock_no_socketpair, 188*77ebdabeSElena Petrova .getname = sock_no_getname, 189*77ebdabeSElena Petrova .ioctl = sock_no_ioctl, 190*77ebdabeSElena Petrova .listen = sock_no_listen, 191*77ebdabeSElena Petrova .shutdown = sock_no_shutdown, 192*77ebdabeSElena Petrova .mmap = sock_no_mmap, 193*77ebdabeSElena Petrova .bind = sock_no_bind, 194*77ebdabeSElena Petrova .accept = sock_no_accept, 195*77ebdabeSElena Petrova .sendpage = sock_no_sendpage, 196*77ebdabeSElena Petrova 197*77ebdabeSElena Petrova .release = af_alg_release, 198*77ebdabeSElena Petrova .recvmsg = rng_test_recvmsg, 199*77ebdabeSElena Petrova .sendmsg = rng_test_sendmsg, 200*77ebdabeSElena Petrova }; 201*77ebdabeSElena Petrova 2025afdfd22SStephan Mueller static void *rng_bind(const char *name, u32 type, u32 mask) 2035afdfd22SStephan Mueller { 204*77ebdabeSElena Petrova struct rng_parent_ctx *pctx; 205*77ebdabeSElena Petrova struct crypto_rng *rng; 206*77ebdabeSElena Petrova 207*77ebdabeSElena Petrova pctx = kzalloc(sizeof(*pctx), GFP_KERNEL); 208*77ebdabeSElena Petrova if (!pctx) 209*77ebdabeSElena Petrova return ERR_PTR(-ENOMEM); 210*77ebdabeSElena Petrova 211*77ebdabeSElena Petrova rng = crypto_alloc_rng(name, type, mask); 212*77ebdabeSElena Petrova if (IS_ERR(rng)) { 213*77ebdabeSElena Petrova kfree(pctx); 214*77ebdabeSElena Petrova return ERR_CAST(rng); 215*77ebdabeSElena Petrova } 216*77ebdabeSElena Petrova 217*77ebdabeSElena Petrova pctx->drng = rng; 218*77ebdabeSElena Petrova return pctx; 2195afdfd22SStephan Mueller } 2205afdfd22SStephan Mueller 2215afdfd22SStephan Mueller static void rng_release(void *private) 2225afdfd22SStephan Mueller { 223*77ebdabeSElena Petrova struct rng_parent_ctx *pctx = private; 224*77ebdabeSElena Petrova 225*77ebdabeSElena Petrova if (unlikely(!pctx)) 226*77ebdabeSElena Petrova return; 227*77ebdabeSElena Petrova crypto_free_rng(pctx->drng); 228*77ebdabeSElena Petrova kfree_sensitive(pctx->entropy); 229*77ebdabeSElena Petrova kfree_sensitive(pctx); 2305afdfd22SStephan Mueller } 2315afdfd22SStephan Mueller 2325afdfd22SStephan Mueller static void rng_sock_destruct(struct sock *sk) 2335afdfd22SStephan Mueller { 2345afdfd22SStephan Mueller struct alg_sock *ask = alg_sk(sk); 2355afdfd22SStephan Mueller struct rng_ctx *ctx = ask->private; 2365afdfd22SStephan Mueller 237*77ebdabeSElena Petrova rng_reset_addtl(ctx); 2385afdfd22SStephan Mueller sock_kfree_s(sk, ctx, ctx->len); 2395afdfd22SStephan Mueller af_alg_release_parent(sk); 2405afdfd22SStephan Mueller } 2415afdfd22SStephan Mueller 2425afdfd22SStephan Mueller static int rng_accept_parent(void *private, struct sock *sk) 2435afdfd22SStephan Mueller { 2445afdfd22SStephan Mueller struct rng_ctx *ctx; 245*77ebdabeSElena Petrova struct rng_parent_ctx *pctx = private; 2465afdfd22SStephan Mueller struct alg_sock *ask = alg_sk(sk); 2475afdfd22SStephan Mueller unsigned int len = sizeof(*ctx); 2485afdfd22SStephan Mueller 2495afdfd22SStephan Mueller ctx = sock_kmalloc(sk, len, GFP_KERNEL); 2505afdfd22SStephan Mueller if (!ctx) 2515afdfd22SStephan Mueller return -ENOMEM; 2525afdfd22SStephan Mueller 2535afdfd22SStephan Mueller ctx->len = len; 254*77ebdabeSElena Petrova ctx->addtl = NULL; 255*77ebdabeSElena Petrova ctx->addtl_len = 0; 2565afdfd22SStephan Mueller 2575afdfd22SStephan Mueller /* 2585afdfd22SStephan Mueller * No seeding done at that point -- if multiple accepts are 2595afdfd22SStephan Mueller * done on one RNG instance, each resulting FD points to the same 2605afdfd22SStephan Mueller * state of the RNG. 2615afdfd22SStephan Mueller */ 2625afdfd22SStephan Mueller 263*77ebdabeSElena Petrova ctx->drng = pctx->drng; 2645afdfd22SStephan Mueller ask->private = ctx; 2655afdfd22SStephan Mueller sk->sk_destruct = rng_sock_destruct; 2665afdfd22SStephan Mueller 267*77ebdabeSElena Petrova /* 268*77ebdabeSElena Petrova * Non NULL pctx->entropy means that CAVP test has been initiated on 269*77ebdabeSElena Petrova * this socket, replace proto_ops algif_rng_ops with algif_rng_test_ops. 270*77ebdabeSElena Petrova */ 271*77ebdabeSElena Petrova if (IS_ENABLED(CONFIG_CRYPTO_USER_API_RNG_CAVP) && pctx->entropy) 272*77ebdabeSElena Petrova sk->sk_socket->ops = &algif_rng_test_ops; 273*77ebdabeSElena Petrova 2745afdfd22SStephan Mueller return 0; 2755afdfd22SStephan Mueller } 2765afdfd22SStephan Mueller 2775afdfd22SStephan Mueller static int rng_setkey(void *private, const u8 *seed, unsigned int seedlen) 2785afdfd22SStephan Mueller { 279*77ebdabeSElena Petrova struct rng_parent_ctx *pctx = private; 2805afdfd22SStephan Mueller /* 2815afdfd22SStephan Mueller * Check whether seedlen is of sufficient size is done in RNG 2825afdfd22SStephan Mueller * implementations. 2835afdfd22SStephan Mueller */ 284*77ebdabeSElena Petrova return crypto_rng_reset(pctx->drng, seed, seedlen); 285*77ebdabeSElena Petrova } 286*77ebdabeSElena Petrova 287*77ebdabeSElena Petrova static int __maybe_unused rng_setentropy(void *private, sockptr_t entropy, 288*77ebdabeSElena Petrova unsigned int len) 289*77ebdabeSElena Petrova { 290*77ebdabeSElena Petrova struct rng_parent_ctx *pctx = private; 291*77ebdabeSElena Petrova u8 *kentropy = NULL; 292*77ebdabeSElena Petrova 293*77ebdabeSElena Petrova if (!capable(CAP_SYS_ADMIN)) 294*77ebdabeSElena Petrova return -EACCES; 295*77ebdabeSElena Petrova 296*77ebdabeSElena Petrova if (pctx->entropy) 297*77ebdabeSElena Petrova return -EINVAL; 298*77ebdabeSElena Petrova 299*77ebdabeSElena Petrova if (len > MAXSIZE) 300*77ebdabeSElena Petrova return -EMSGSIZE; 301*77ebdabeSElena Petrova 302*77ebdabeSElena Petrova if (len) { 303*77ebdabeSElena Petrova kentropy = memdup_sockptr(entropy, len); 304*77ebdabeSElena Petrova if (IS_ERR(kentropy)) 305*77ebdabeSElena Petrova return PTR_ERR(kentropy); 306*77ebdabeSElena Petrova } 307*77ebdabeSElena Petrova 308*77ebdabeSElena Petrova crypto_rng_alg(pctx->drng)->set_ent(pctx->drng, kentropy, len); 309*77ebdabeSElena Petrova /* 310*77ebdabeSElena Petrova * Since rng doesn't perform any memory management for the entropy 311*77ebdabeSElena Petrova * buffer, save kentropy pointer to pctx now to free it after use. 312*77ebdabeSElena Petrova */ 313*77ebdabeSElena Petrova pctx->entropy = kentropy; 314*77ebdabeSElena Petrova return 0; 3155afdfd22SStephan Mueller } 3165afdfd22SStephan Mueller 3175afdfd22SStephan Mueller static const struct af_alg_type algif_type_rng = { 3185afdfd22SStephan Mueller .bind = rng_bind, 3195afdfd22SStephan Mueller .release = rng_release, 3205afdfd22SStephan Mueller .accept = rng_accept_parent, 3215afdfd22SStephan Mueller .setkey = rng_setkey, 322*77ebdabeSElena Petrova #ifdef CONFIG_CRYPTO_USER_API_RNG_CAVP 323*77ebdabeSElena Petrova .setentropy = rng_setentropy, 324*77ebdabeSElena Petrova #endif 3255afdfd22SStephan Mueller .ops = &algif_rng_ops, 3265afdfd22SStephan Mueller .name = "rng", 3275afdfd22SStephan Mueller .owner = THIS_MODULE 3285afdfd22SStephan Mueller }; 3295afdfd22SStephan Mueller 3305afdfd22SStephan Mueller static int __init rng_init(void) 3315afdfd22SStephan Mueller { 3325afdfd22SStephan Mueller return af_alg_register_type(&algif_type_rng); 3335afdfd22SStephan Mueller } 3345afdfd22SStephan Mueller 335598de369SWei Yongjun static void __exit rng_exit(void) 3365afdfd22SStephan Mueller { 3375afdfd22SStephan Mueller int err = af_alg_unregister_type(&algif_type_rng); 3385afdfd22SStephan Mueller BUG_ON(err); 3395afdfd22SStephan Mueller } 3405afdfd22SStephan Mueller 3415afdfd22SStephan Mueller module_init(rng_init); 3425afdfd22SStephan Mueller module_exit(rng_exit); 343