algif_rng.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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. #include <linux/module.h>
  41. #include <crypto/rng.h>
  42. #include <linux/random.h>
  43. #include <crypto/if_alg.h>
  44. #include <linux/net.h>
  45. #include <net/sock.h>
  46. MODULE_LICENSE("GPL");
  47. MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
  48. MODULE_DESCRIPTION("User-space interface for random number generators");
  49. struct rng_ctx {
  50. #define MAXSIZE 128
  51. unsigned int len;
  52. struct crypto_rng *drng;
  53. };
  54. static int rng_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
  55. int flags)
  56. {
  57. struct sock *sk = sock->sk;
  58. struct alg_sock *ask = alg_sk(sk);
  59. struct rng_ctx *ctx = ask->private;
  60. int err = -EFAULT;
  61. int genlen = 0;
  62. u8 result[MAXSIZE];
  63. if (len == 0)
  64. return 0;
  65. if (len > MAXSIZE)
  66. len = MAXSIZE;
  67. /*
  68. * although not strictly needed, this is a precaution against coding
  69. * errors
  70. */
  71. memset(result, 0, len);
  72. /*
  73. * The enforcement of a proper seeding of an RNG is done within an
  74. * RNG implementation. Some RNGs (DRBG, krng) do not need specific
  75. * seeding as they automatically seed. The X9.31 DRNG will return
  76. * an error if it was not seeded properly.
  77. */
  78. genlen = crypto_rng_get_bytes(ctx->drng, result, len);
  79. if (genlen < 0)
  80. return genlen;
  81. err = memcpy_to_msg(msg, result, len);
  82. memzero_explicit(result, len);
  83. return err ? err : len;
  84. }
  85. static struct proto_ops algif_rng_ops = {
  86. .family = PF_ALG,
  87. .connect = sock_no_connect,
  88. .socketpair = sock_no_socketpair,
  89. .getname = sock_no_getname,
  90. .ioctl = sock_no_ioctl,
  91. .listen = sock_no_listen,
  92. .shutdown = sock_no_shutdown,
  93. .getsockopt = sock_no_getsockopt,
  94. .mmap = sock_no_mmap,
  95. .bind = sock_no_bind,
  96. .accept = sock_no_accept,
  97. .setsockopt = sock_no_setsockopt,
  98. .poll = sock_no_poll,
  99. .sendmsg = sock_no_sendmsg,
  100. .sendpage = sock_no_sendpage,
  101. .release = af_alg_release,
  102. .recvmsg = rng_recvmsg,
  103. };
  104. static void *rng_bind(const char *name, u32 type, u32 mask)
  105. {
  106. return crypto_alloc_rng(name, type, mask);
  107. }
  108. static void rng_release(void *private)
  109. {
  110. crypto_free_rng(private);
  111. }
  112. static void rng_sock_destruct(struct sock *sk)
  113. {
  114. struct alg_sock *ask = alg_sk(sk);
  115. struct rng_ctx *ctx = ask->private;
  116. sock_kfree_s(sk, ctx, ctx->len);
  117. af_alg_release_parent(sk);
  118. }
  119. static int rng_accept_parent(void *private, struct sock *sk)
  120. {
  121. struct rng_ctx *ctx;
  122. struct alg_sock *ask = alg_sk(sk);
  123. unsigned int len = sizeof(*ctx);
  124. ctx = sock_kmalloc(sk, len, GFP_KERNEL);
  125. if (!ctx)
  126. return -ENOMEM;
  127. ctx->len = len;
  128. /*
  129. * No seeding done at that point -- if multiple accepts are
  130. * done on one RNG instance, each resulting FD points to the same
  131. * state of the RNG.
  132. */
  133. ctx->drng = private;
  134. ask->private = ctx;
  135. sk->sk_destruct = rng_sock_destruct;
  136. return 0;
  137. }
  138. static int rng_setkey(void *private, const u8 *seed, unsigned int seedlen)
  139. {
  140. /*
  141. * Check whether seedlen is of sufficient size is done in RNG
  142. * implementations.
  143. */
  144. return crypto_rng_reset(private, seed, seedlen);
  145. }
  146. static const struct af_alg_type algif_type_rng = {
  147. .bind = rng_bind,
  148. .release = rng_release,
  149. .accept = rng_accept_parent,
  150. .setkey = rng_setkey,
  151. .ops = &algif_rng_ops,
  152. .name = "rng",
  153. .owner = THIS_MODULE
  154. };
  155. static int __init rng_init(void)
  156. {
  157. return af_alg_register_type(&algif_type_rng);
  158. }
  159. static void __exit rng_exit(void)
  160. {
  161. int err = af_alg_unregister_type(&algif_type_rng);
  162. BUG_ON(err);
  163. }
  164. module_init(rng_init);
  165. module_exit(rng_exit);