Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * algif_rng: User-space interface for random number generators
0003  *
0004  * This file provides the user-space API for random number generators.
0005  *
0006  * Copyright (C) 2014, Stephan Mueller <smueller@chronox.de>
0007  *
0008  * Redistribution and use in source and binary forms, with or without
0009  * modification, are permitted provided that the following conditions
0010  * are met:
0011  * 1. Redistributions of source code must retain the above copyright
0012  *    notice, and the entire permission notice in its entirety,
0013  *    including the disclaimer of warranties.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  * 3. The name of the author may not be used to endorse or promote
0018  *    products derived from this software without specific prior
0019  *    written permission.
0020  *
0021  * ALTERNATIVELY, this product may be distributed under the terms of
0022  * the GNU General Public License, in which case the provisions of the GPL2
0023  * are required INSTEAD OF the above restrictions.  (This clause is
0024  * necessary due to a potential bad interaction between the GPL and
0025  * the restrictions contained in a BSD-style copyright.)
0026  *
0027  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
0028  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0029  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
0030  * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
0031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
0033  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
0034  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0035  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0036  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
0037  * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
0038  * DAMAGE.
0039  */
0040 
0041 #include <linux/capability.h>
0042 #include <linux/module.h>
0043 #include <crypto/rng.h>
0044 #include <linux/random.h>
0045 #include <crypto/if_alg.h>
0046 #include <linux/net.h>
0047 #include <net/sock.h>
0048 
0049 MODULE_LICENSE("GPL");
0050 MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
0051 MODULE_DESCRIPTION("User-space interface for random number generators");
0052 
0053 struct rng_ctx {
0054 #define MAXSIZE 128
0055     unsigned int len;
0056     struct crypto_rng *drng;
0057     u8 *addtl;
0058     size_t addtl_len;
0059 };
0060 
0061 struct rng_parent_ctx {
0062     struct crypto_rng *drng;
0063     u8 *entropy;
0064 };
0065 
0066 static void rng_reset_addtl(struct rng_ctx *ctx)
0067 {
0068     kfree_sensitive(ctx->addtl);
0069     ctx->addtl = NULL;
0070     ctx->addtl_len = 0;
0071 }
0072 
0073 static int _rng_recvmsg(struct crypto_rng *drng, struct msghdr *msg, size_t len,
0074             u8 *addtl, size_t addtl_len)
0075 {
0076     int err = 0;
0077     int genlen = 0;
0078     u8 result[MAXSIZE];
0079 
0080     if (len == 0)
0081         return 0;
0082     if (len > MAXSIZE)
0083         len = MAXSIZE;
0084 
0085     /*
0086      * although not strictly needed, this is a precaution against coding
0087      * errors
0088      */
0089     memset(result, 0, len);
0090 
0091     /*
0092      * The enforcement of a proper seeding of an RNG is done within an
0093      * RNG implementation. Some RNGs (DRBG, krng) do not need specific
0094      * seeding as they automatically seed. The X9.31 DRNG will return
0095      * an error if it was not seeded properly.
0096      */
0097     genlen = crypto_rng_generate(drng, addtl, addtl_len, result, len);
0098     if (genlen < 0)
0099         return genlen;
0100 
0101     err = memcpy_to_msg(msg, result, len);
0102     memzero_explicit(result, len);
0103 
0104     return err ? err : len;
0105 }
0106 
0107 static int rng_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
0108                int flags)
0109 {
0110     struct sock *sk = sock->sk;
0111     struct alg_sock *ask = alg_sk(sk);
0112     struct rng_ctx *ctx = ask->private;
0113 
0114     return _rng_recvmsg(ctx->drng, msg, len, NULL, 0);
0115 }
0116 
0117 static int rng_test_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
0118                 int flags)
0119 {
0120     struct sock *sk = sock->sk;
0121     struct alg_sock *ask = alg_sk(sk);
0122     struct rng_ctx *ctx = ask->private;
0123     int ret;
0124 
0125     lock_sock(sock->sk);
0126     ret = _rng_recvmsg(ctx->drng, msg, len, ctx->addtl, ctx->addtl_len);
0127     rng_reset_addtl(ctx);
0128     release_sock(sock->sk);
0129 
0130     return ret;
0131 }
0132 
0133 static int rng_test_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
0134 {
0135     int err;
0136     struct alg_sock *ask = alg_sk(sock->sk);
0137     struct rng_ctx *ctx = ask->private;
0138 
0139     lock_sock(sock->sk);
0140     if (len > MAXSIZE) {
0141         err = -EMSGSIZE;
0142         goto unlock;
0143     }
0144 
0145     rng_reset_addtl(ctx);
0146     ctx->addtl = kmalloc(len, GFP_KERNEL);
0147     if (!ctx->addtl) {
0148         err = -ENOMEM;
0149         goto unlock;
0150     }
0151 
0152     err = memcpy_from_msg(ctx->addtl, msg, len);
0153     if (err) {
0154         rng_reset_addtl(ctx);
0155         goto unlock;
0156     }
0157     ctx->addtl_len = len;
0158 
0159 unlock:
0160     release_sock(sock->sk);
0161     return err ? err : len;
0162 }
0163 
0164 static struct proto_ops algif_rng_ops = {
0165     .family     =   PF_ALG,
0166 
0167     .connect    =   sock_no_connect,
0168     .socketpair =   sock_no_socketpair,
0169     .getname    =   sock_no_getname,
0170     .ioctl      =   sock_no_ioctl,
0171     .listen     =   sock_no_listen,
0172     .shutdown   =   sock_no_shutdown,
0173     .mmap       =   sock_no_mmap,
0174     .bind       =   sock_no_bind,
0175     .accept     =   sock_no_accept,
0176     .sendmsg    =   sock_no_sendmsg,
0177     .sendpage   =   sock_no_sendpage,
0178 
0179     .release    =   af_alg_release,
0180     .recvmsg    =   rng_recvmsg,
0181 };
0182 
0183 static struct proto_ops __maybe_unused algif_rng_test_ops = {
0184     .family     =   PF_ALG,
0185 
0186     .connect    =   sock_no_connect,
0187     .socketpair =   sock_no_socketpair,
0188     .getname    =   sock_no_getname,
0189     .ioctl      =   sock_no_ioctl,
0190     .listen     =   sock_no_listen,
0191     .shutdown   =   sock_no_shutdown,
0192     .mmap       =   sock_no_mmap,
0193     .bind       =   sock_no_bind,
0194     .accept     =   sock_no_accept,
0195     .sendpage   =   sock_no_sendpage,
0196 
0197     .release    =   af_alg_release,
0198     .recvmsg    =   rng_test_recvmsg,
0199     .sendmsg    =   rng_test_sendmsg,
0200 };
0201 
0202 static void *rng_bind(const char *name, u32 type, u32 mask)
0203 {
0204     struct rng_parent_ctx *pctx;
0205     struct crypto_rng *rng;
0206 
0207     pctx = kzalloc(sizeof(*pctx), GFP_KERNEL);
0208     if (!pctx)
0209         return ERR_PTR(-ENOMEM);
0210 
0211     rng = crypto_alloc_rng(name, type, mask);
0212     if (IS_ERR(rng)) {
0213         kfree(pctx);
0214         return ERR_CAST(rng);
0215     }
0216 
0217     pctx->drng = rng;
0218     return pctx;
0219 }
0220 
0221 static void rng_release(void *private)
0222 {
0223     struct rng_parent_ctx *pctx = private;
0224 
0225     if (unlikely(!pctx))
0226         return;
0227     crypto_free_rng(pctx->drng);
0228     kfree_sensitive(pctx->entropy);
0229     kfree_sensitive(pctx);
0230 }
0231 
0232 static void rng_sock_destruct(struct sock *sk)
0233 {
0234     struct alg_sock *ask = alg_sk(sk);
0235     struct rng_ctx *ctx = ask->private;
0236 
0237     rng_reset_addtl(ctx);
0238     sock_kfree_s(sk, ctx, ctx->len);
0239     af_alg_release_parent(sk);
0240 }
0241 
0242 static int rng_accept_parent(void *private, struct sock *sk)
0243 {
0244     struct rng_ctx *ctx;
0245     struct rng_parent_ctx *pctx = private;
0246     struct alg_sock *ask = alg_sk(sk);
0247     unsigned int len = sizeof(*ctx);
0248 
0249     ctx = sock_kmalloc(sk, len, GFP_KERNEL);
0250     if (!ctx)
0251         return -ENOMEM;
0252 
0253     ctx->len = len;
0254     ctx->addtl = NULL;
0255     ctx->addtl_len = 0;
0256 
0257     /*
0258      * No seeding done at that point -- if multiple accepts are
0259      * done on one RNG instance, each resulting FD points to the same
0260      * state of the RNG.
0261      */
0262 
0263     ctx->drng = pctx->drng;
0264     ask->private = ctx;
0265     sk->sk_destruct = rng_sock_destruct;
0266 
0267     /*
0268      * Non NULL pctx->entropy means that CAVP test has been initiated on
0269      * this socket, replace proto_ops algif_rng_ops with algif_rng_test_ops.
0270      */
0271     if (IS_ENABLED(CONFIG_CRYPTO_USER_API_RNG_CAVP) && pctx->entropy)
0272         sk->sk_socket->ops = &algif_rng_test_ops;
0273 
0274     return 0;
0275 }
0276 
0277 static int rng_setkey(void *private, const u8 *seed, unsigned int seedlen)
0278 {
0279     struct rng_parent_ctx *pctx = private;
0280     /*
0281      * Check whether seedlen is of sufficient size is done in RNG
0282      * implementations.
0283      */
0284     return crypto_rng_reset(pctx->drng, seed, seedlen);
0285 }
0286 
0287 static int __maybe_unused rng_setentropy(void *private, sockptr_t entropy,
0288                      unsigned int len)
0289 {
0290     struct rng_parent_ctx *pctx = private;
0291     u8 *kentropy = NULL;
0292 
0293     if (!capable(CAP_SYS_ADMIN))
0294         return -EACCES;
0295 
0296     if (pctx->entropy)
0297         return -EINVAL;
0298 
0299     if (len > MAXSIZE)
0300         return -EMSGSIZE;
0301 
0302     if (len) {
0303         kentropy = memdup_sockptr(entropy, len);
0304         if (IS_ERR(kentropy))
0305             return PTR_ERR(kentropy);
0306     }
0307 
0308     crypto_rng_alg(pctx->drng)->set_ent(pctx->drng, kentropy, len);
0309     /*
0310      * Since rng doesn't perform any memory management for the entropy
0311      * buffer, save kentropy pointer to pctx now to free it after use.
0312      */
0313     pctx->entropy = kentropy;
0314     return 0;
0315 }
0316 
0317 static const struct af_alg_type algif_type_rng = {
0318     .bind       =   rng_bind,
0319     .release    =   rng_release,
0320     .accept     =   rng_accept_parent,
0321     .setkey     =   rng_setkey,
0322 #ifdef CONFIG_CRYPTO_USER_API_RNG_CAVP
0323     .setentropy =   rng_setentropy,
0324 #endif
0325     .ops        =   &algif_rng_ops,
0326     .name       =   "rng",
0327     .owner      =   THIS_MODULE
0328 };
0329 
0330 static int __init rng_init(void)
0331 {
0332     return af_alg_register_type(&algif_type_rng);
0333 }
0334 
0335 static void __exit rng_exit(void)
0336 {
0337     int err = af_alg_unregister_type(&algif_type_rng);
0338     BUG_ON(err);
0339 }
0340 
0341 module_init(rng_init);
0342 module_exit(rng_exit);