rng.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Cryptographic API.
  3. *
  4. * RNG operations.
  5. *
  6. * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the Free
  10. * Software Foundation; either version 2 of the License, or (at your option)
  11. * any later version.
  12. *
  13. */
  14. #include <asm/atomic.h>
  15. #include <crypto/internal/rng.h>
  16. #include <linux/err.h>
  17. #include <linux/module.h>
  18. #include <linux/mutex.h>
  19. #include <linux/random.h>
  20. #include <linux/seq_file.h>
  21. #include <linux/slab.h>
  22. #include <linux/string.h>
  23. static DEFINE_MUTEX(crypto_default_rng_lock);
  24. struct crypto_rng *crypto_default_rng;
  25. EXPORT_SYMBOL_GPL(crypto_default_rng);
  26. static int crypto_default_rng_refcnt;
  27. static int rngapi_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
  28. {
  29. u8 *buf = NULL;
  30. int err;
  31. if (!seed && slen) {
  32. buf = kmalloc(slen, GFP_KERNEL);
  33. if (!buf)
  34. return -ENOMEM;
  35. get_random_bytes(buf, slen);
  36. seed = buf;
  37. }
  38. err = crypto_rng_alg(tfm)->rng_reset(tfm, seed, slen);
  39. kfree(buf);
  40. return err;
  41. }
  42. static int crypto_init_rng_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
  43. {
  44. struct rng_alg *alg = &tfm->__crt_alg->cra_rng;
  45. struct rng_tfm *ops = &tfm->crt_rng;
  46. ops->rng_gen_random = alg->rng_make_random;
  47. ops->rng_reset = rngapi_reset;
  48. return 0;
  49. }
  50. static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
  51. __attribute__ ((unused));
  52. static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
  53. {
  54. seq_printf(m, "type : rng\n");
  55. seq_printf(m, "seedsize : %u\n", alg->cra_rng.seedsize);
  56. }
  57. static unsigned int crypto_rng_ctxsize(struct crypto_alg *alg, u32 type,
  58. u32 mask)
  59. {
  60. return alg->cra_ctxsize;
  61. }
  62. const struct crypto_type crypto_rng_type = {
  63. .ctxsize = crypto_rng_ctxsize,
  64. .init = crypto_init_rng_ops,
  65. #ifdef CONFIG_PROC_FS
  66. .show = crypto_rng_show,
  67. #endif
  68. };
  69. EXPORT_SYMBOL_GPL(crypto_rng_type);
  70. int crypto_get_default_rng(void)
  71. {
  72. struct crypto_rng *rng;
  73. int err;
  74. mutex_lock(&crypto_default_rng_lock);
  75. if (!crypto_default_rng) {
  76. rng = crypto_alloc_rng("stdrng", 0, 0);
  77. err = PTR_ERR(rng);
  78. if (IS_ERR(rng))
  79. goto unlock;
  80. err = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
  81. if (err) {
  82. crypto_free_rng(rng);
  83. goto unlock;
  84. }
  85. crypto_default_rng = rng;
  86. }
  87. crypto_default_rng_refcnt++;
  88. err = 0;
  89. unlock:
  90. mutex_unlock(&crypto_default_rng_lock);
  91. return err;
  92. }
  93. EXPORT_SYMBOL_GPL(crypto_get_default_rng);
  94. void crypto_put_default_rng(void)
  95. {
  96. mutex_lock(&crypto_default_rng_lock);
  97. if (!--crypto_default_rng_refcnt) {
  98. crypto_free_rng(crypto_default_rng);
  99. crypto_default_rng = NULL;
  100. }
  101. mutex_unlock(&crypto_default_rng_lock);
  102. }
  103. EXPORT_SYMBOL_GPL(crypto_put_default_rng);
  104. MODULE_LICENSE("GPL");
  105. MODULE_DESCRIPTION("Random Number Generator");