drm/amdgpu: Restore HQD persistent state register
[platform/kernel/linux-starfive.git] / crypto / algif_rng.c
1 /*
2  * algif_rng: User-space interface for random number generators
3  *
4  * This file provides the user-space API for random number generators.
5  *
6  * Copyright (C) 2014, Stephan Mueller <smueller@chronox.de>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, and the entire permission notice in its entirety,
13  *    including the disclaimer of warranties.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of the author may not be used to endorse or promote
18  *    products derived from this software without specific prior
19  *    written permission.
20  *
21  * ALTERNATIVELY, this product may be distributed under the terms of
22  * the GNU General Public License, in which case the provisions of the GPL2
23  * are required INSTEAD OF the above restrictions.  (This clause is
24  * necessary due to a potential bad interaction between the GPL and
25  * the restrictions contained in a BSD-style copyright.)
26  *
27  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
28  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
30  * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
33  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
34  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  */
40
41 #include <linux/capability.h>
42 #include <linux/module.h>
43 #include <crypto/rng.h>
44 #include <linux/random.h>
45 #include <crypto/if_alg.h>
46 #include <linux/net.h>
47 #include <net/sock.h>
48
49 MODULE_LICENSE("GPL");
50 MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
51 MODULE_DESCRIPTION("User-space interface for random number generators");
52
53 struct rng_ctx {
54 #define MAXSIZE 128
55         unsigned int len;
56         struct crypto_rng *drng;
57         u8 *addtl;
58         size_t addtl_len;
59 };
60
61 struct rng_parent_ctx {
62         struct crypto_rng *drng;
63         u8 *entropy;
64 };
65
66 static void rng_reset_addtl(struct rng_ctx *ctx)
67 {
68         kfree_sensitive(ctx->addtl);
69         ctx->addtl = NULL;
70         ctx->addtl_len = 0;
71 }
72
73 static int _rng_recvmsg(struct crypto_rng *drng, struct msghdr *msg, size_t len,
74                         u8 *addtl, size_t addtl_len)
75 {
76         int err = 0;
77         int genlen = 0;
78         u8 result[MAXSIZE];
79
80         if (len == 0)
81                 return 0;
82         if (len > MAXSIZE)
83                 len = MAXSIZE;
84
85         /*
86          * although not strictly needed, this is a precaution against coding
87          * errors
88          */
89         memset(result, 0, len);
90
91         /*
92          * The enforcement of a proper seeding of an RNG is done within an
93          * RNG implementation. Some RNGs (DRBG, krng) do not need specific
94          * seeding as they automatically seed. The X9.31 DRNG will return
95          * an error if it was not seeded properly.
96          */
97         genlen = crypto_rng_generate(drng, addtl, addtl_len, result, len);
98         if (genlen < 0)
99                 return genlen;
100
101         err = memcpy_to_msg(msg, result, len);
102         memzero_explicit(result, len);
103
104         return err ? err : len;
105 }
106
107 static int rng_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
108                        int flags)
109 {
110         struct sock *sk = sock->sk;
111         struct alg_sock *ask = alg_sk(sk);
112         struct rng_ctx *ctx = ask->private;
113
114         return _rng_recvmsg(ctx->drng, msg, len, NULL, 0);
115 }
116
117 static int rng_test_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
118                             int flags)
119 {
120         struct sock *sk = sock->sk;
121         struct alg_sock *ask = alg_sk(sk);
122         struct rng_ctx *ctx = ask->private;
123         int ret;
124
125         lock_sock(sock->sk);
126         ret = _rng_recvmsg(ctx->drng, msg, len, ctx->addtl, ctx->addtl_len);
127         rng_reset_addtl(ctx);
128         release_sock(sock->sk);
129
130         return ret;
131 }
132
133 static int rng_test_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
134 {
135         int err;
136         struct alg_sock *ask = alg_sk(sock->sk);
137         struct rng_ctx *ctx = ask->private;
138
139         lock_sock(sock->sk);
140         if (len > MAXSIZE) {
141                 err = -EMSGSIZE;
142                 goto unlock;
143         }
144
145         rng_reset_addtl(ctx);
146         ctx->addtl = kmalloc(len, GFP_KERNEL);
147         if (!ctx->addtl) {
148                 err = -ENOMEM;
149                 goto unlock;
150         }
151
152         err = memcpy_from_msg(ctx->addtl, msg, len);
153         if (err) {
154                 rng_reset_addtl(ctx);
155                 goto unlock;
156         }
157         ctx->addtl_len = len;
158
159 unlock:
160         release_sock(sock->sk);
161         return err ? err : len;
162 }
163
164 static struct proto_ops algif_rng_ops = {
165         .family         =       PF_ALG,
166
167         .connect        =       sock_no_connect,
168         .socketpair     =       sock_no_socketpair,
169         .getname        =       sock_no_getname,
170         .ioctl          =       sock_no_ioctl,
171         .listen         =       sock_no_listen,
172         .shutdown       =       sock_no_shutdown,
173         .mmap           =       sock_no_mmap,
174         .bind           =       sock_no_bind,
175         .accept         =       sock_no_accept,
176         .sendmsg        =       sock_no_sendmsg,
177         .sendpage       =       sock_no_sendpage,
178
179         .release        =       af_alg_release,
180         .recvmsg        =       rng_recvmsg,
181 };
182
183 static struct proto_ops __maybe_unused algif_rng_test_ops = {
184         .family         =       PF_ALG,
185
186         .connect        =       sock_no_connect,
187         .socketpair     =       sock_no_socketpair,
188         .getname        =       sock_no_getname,
189         .ioctl          =       sock_no_ioctl,
190         .listen         =       sock_no_listen,
191         .shutdown       =       sock_no_shutdown,
192         .mmap           =       sock_no_mmap,
193         .bind           =       sock_no_bind,
194         .accept         =       sock_no_accept,
195         .sendpage       =       sock_no_sendpage,
196
197         .release        =       af_alg_release,
198         .recvmsg        =       rng_test_recvmsg,
199         .sendmsg        =       rng_test_sendmsg,
200 };
201
202 static void *rng_bind(const char *name, u32 type, u32 mask)
203 {
204         struct rng_parent_ctx *pctx;
205         struct crypto_rng *rng;
206
207         pctx = kzalloc(sizeof(*pctx), GFP_KERNEL);
208         if (!pctx)
209                 return ERR_PTR(-ENOMEM);
210
211         rng = crypto_alloc_rng(name, type, mask);
212         if (IS_ERR(rng)) {
213                 kfree(pctx);
214                 return ERR_CAST(rng);
215         }
216
217         pctx->drng = rng;
218         return pctx;
219 }
220
221 static void rng_release(void *private)
222 {
223         struct rng_parent_ctx *pctx = private;
224
225         if (unlikely(!pctx))
226                 return;
227         crypto_free_rng(pctx->drng);
228         kfree_sensitive(pctx->entropy);
229         kfree_sensitive(pctx);
230 }
231
232 static void rng_sock_destruct(struct sock *sk)
233 {
234         struct alg_sock *ask = alg_sk(sk);
235         struct rng_ctx *ctx = ask->private;
236
237         rng_reset_addtl(ctx);
238         sock_kfree_s(sk, ctx, ctx->len);
239         af_alg_release_parent(sk);
240 }
241
242 static int rng_accept_parent(void *private, struct sock *sk)
243 {
244         struct rng_ctx *ctx;
245         struct rng_parent_ctx *pctx = private;
246         struct alg_sock *ask = alg_sk(sk);
247         unsigned int len = sizeof(*ctx);
248
249         ctx = sock_kmalloc(sk, len, GFP_KERNEL);
250         if (!ctx)
251                 return -ENOMEM;
252
253         ctx->len = len;
254         ctx->addtl = NULL;
255         ctx->addtl_len = 0;
256
257         /*
258          * No seeding done at that point -- if multiple accepts are
259          * done on one RNG instance, each resulting FD points to the same
260          * state of the RNG.
261          */
262
263         ctx->drng = pctx->drng;
264         ask->private = ctx;
265         sk->sk_destruct = rng_sock_destruct;
266
267         /*
268          * Non NULL pctx->entropy means that CAVP test has been initiated on
269          * this socket, replace proto_ops algif_rng_ops with algif_rng_test_ops.
270          */
271         if (IS_ENABLED(CONFIG_CRYPTO_USER_API_RNG_CAVP) && pctx->entropy)
272                 sk->sk_socket->ops = &algif_rng_test_ops;
273
274         return 0;
275 }
276
277 static int rng_setkey(void *private, const u8 *seed, unsigned int seedlen)
278 {
279         struct rng_parent_ctx *pctx = private;
280         /*
281          * Check whether seedlen is of sufficient size is done in RNG
282          * implementations.
283          */
284         return crypto_rng_reset(pctx->drng, seed, seedlen);
285 }
286
287 static int __maybe_unused rng_setentropy(void *private, sockptr_t entropy,
288                                          unsigned int len)
289 {
290         struct rng_parent_ctx *pctx = private;
291         u8 *kentropy = NULL;
292
293         if (!capable(CAP_SYS_ADMIN))
294                 return -EACCES;
295
296         if (pctx->entropy)
297                 return -EINVAL;
298
299         if (len > MAXSIZE)
300                 return -EMSGSIZE;
301
302         if (len) {
303                 kentropy = memdup_sockptr(entropy, len);
304                 if (IS_ERR(kentropy))
305                         return PTR_ERR(kentropy);
306         }
307
308         crypto_rng_alg(pctx->drng)->set_ent(pctx->drng, kentropy, len);
309         /*
310          * Since rng doesn't perform any memory management for the entropy
311          * buffer, save kentropy pointer to pctx now to free it after use.
312          */
313         pctx->entropy = kentropy;
314         return 0;
315 }
316
317 static const struct af_alg_type algif_type_rng = {
318         .bind           =       rng_bind,
319         .release        =       rng_release,
320         .accept         =       rng_accept_parent,
321         .setkey         =       rng_setkey,
322 #ifdef CONFIG_CRYPTO_USER_API_RNG_CAVP
323         .setentropy     =       rng_setentropy,
324 #endif
325         .ops            =       &algif_rng_ops,
326         .name           =       "rng",
327         .owner          =       THIS_MODULE
328 };
329
330 static int __init rng_init(void)
331 {
332         return af_alg_register_type(&algif_type_rng);
333 }
334
335 static void __exit rng_exit(void)
336 {
337         int err = af_alg_unregister_type(&algif_type_rng);
338         BUG_ON(err);
339 }
340
341 module_init(rng_init);
342 module_exit(rng_exit);