0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/atomic.h>
0012 #include <crypto/internal/rng.h>
0013 #include <linux/err.h>
0014 #include <linux/module.h>
0015 #include <linux/mutex.h>
0016 #include <linux/random.h>
0017 #include <linux/seq_file.h>
0018 #include <linux/slab.h>
0019 #include <linux/string.h>
0020 #include <linux/cryptouser.h>
0021 #include <linux/compiler.h>
0022 #include <net/netlink.h>
0023
0024 #include "internal.h"
0025
0026 static DEFINE_MUTEX(crypto_default_rng_lock);
0027 struct crypto_rng *crypto_default_rng;
0028 EXPORT_SYMBOL_GPL(crypto_default_rng);
0029 static int crypto_default_rng_refcnt;
0030
0031 int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen)
0032 {
0033 struct crypto_alg *alg = tfm->base.__crt_alg;
0034 u8 *buf = NULL;
0035 int err;
0036
0037 if (!seed && slen) {
0038 buf = kmalloc(slen, GFP_KERNEL);
0039 if (!buf)
0040 return -ENOMEM;
0041
0042 err = get_random_bytes_wait(buf, slen);
0043 if (err)
0044 goto out;
0045 seed = buf;
0046 }
0047
0048 crypto_stats_get(alg);
0049 err = crypto_rng_alg(tfm)->seed(tfm, seed, slen);
0050 crypto_stats_rng_seed(alg, err);
0051 out:
0052 kfree_sensitive(buf);
0053 return err;
0054 }
0055 EXPORT_SYMBOL_GPL(crypto_rng_reset);
0056
0057 static int crypto_rng_init_tfm(struct crypto_tfm *tfm)
0058 {
0059 return 0;
0060 }
0061
0062 static unsigned int seedsize(struct crypto_alg *alg)
0063 {
0064 struct rng_alg *ralg = container_of(alg, struct rng_alg, base);
0065
0066 return ralg->seedsize;
0067 }
0068
0069 #ifdef CONFIG_NET
0070 static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
0071 {
0072 struct crypto_report_rng rrng;
0073
0074 memset(&rrng, 0, sizeof(rrng));
0075
0076 strscpy(rrng.type, "rng", sizeof(rrng.type));
0077
0078 rrng.seedsize = seedsize(alg);
0079
0080 return nla_put(skb, CRYPTOCFGA_REPORT_RNG, sizeof(rrng), &rrng);
0081 }
0082 #else
0083 static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
0084 {
0085 return -ENOSYS;
0086 }
0087 #endif
0088
0089 static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
0090 __maybe_unused;
0091 static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
0092 {
0093 seq_printf(m, "type : rng\n");
0094 seq_printf(m, "seedsize : %u\n", seedsize(alg));
0095 }
0096
0097 static const struct crypto_type crypto_rng_type = {
0098 .extsize = crypto_alg_extsize,
0099 .init_tfm = crypto_rng_init_tfm,
0100 #ifdef CONFIG_PROC_FS
0101 .show = crypto_rng_show,
0102 #endif
0103 .report = crypto_rng_report,
0104 .maskclear = ~CRYPTO_ALG_TYPE_MASK,
0105 .maskset = CRYPTO_ALG_TYPE_MASK,
0106 .type = CRYPTO_ALG_TYPE_RNG,
0107 .tfmsize = offsetof(struct crypto_rng, base),
0108 };
0109
0110 struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask)
0111 {
0112 return crypto_alloc_tfm(alg_name, &crypto_rng_type, type, mask);
0113 }
0114 EXPORT_SYMBOL_GPL(crypto_alloc_rng);
0115
0116 int crypto_get_default_rng(void)
0117 {
0118 struct crypto_rng *rng;
0119 int err;
0120
0121 mutex_lock(&crypto_default_rng_lock);
0122 if (!crypto_default_rng) {
0123 rng = crypto_alloc_rng("stdrng", 0, 0);
0124 err = PTR_ERR(rng);
0125 if (IS_ERR(rng))
0126 goto unlock;
0127
0128 err = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
0129 if (err) {
0130 crypto_free_rng(rng);
0131 goto unlock;
0132 }
0133
0134 crypto_default_rng = rng;
0135 }
0136
0137 crypto_default_rng_refcnt++;
0138 err = 0;
0139
0140 unlock:
0141 mutex_unlock(&crypto_default_rng_lock);
0142
0143 return err;
0144 }
0145 EXPORT_SYMBOL_GPL(crypto_get_default_rng);
0146
0147 void crypto_put_default_rng(void)
0148 {
0149 mutex_lock(&crypto_default_rng_lock);
0150 crypto_default_rng_refcnt--;
0151 mutex_unlock(&crypto_default_rng_lock);
0152 }
0153 EXPORT_SYMBOL_GPL(crypto_put_default_rng);
0154
0155 #if defined(CONFIG_CRYPTO_RNG) || defined(CONFIG_CRYPTO_RNG_MODULE)
0156 int crypto_del_default_rng(void)
0157 {
0158 int err = -EBUSY;
0159
0160 mutex_lock(&crypto_default_rng_lock);
0161 if (crypto_default_rng_refcnt)
0162 goto out;
0163
0164 crypto_free_rng(crypto_default_rng);
0165 crypto_default_rng = NULL;
0166
0167 err = 0;
0168
0169 out:
0170 mutex_unlock(&crypto_default_rng_lock);
0171
0172 return err;
0173 }
0174 EXPORT_SYMBOL_GPL(crypto_del_default_rng);
0175 #endif
0176
0177 int crypto_register_rng(struct rng_alg *alg)
0178 {
0179 struct crypto_alg *base = &alg->base;
0180
0181 if (alg->seedsize > PAGE_SIZE / 8)
0182 return -EINVAL;
0183
0184 base->cra_type = &crypto_rng_type;
0185 base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
0186 base->cra_flags |= CRYPTO_ALG_TYPE_RNG;
0187
0188 return crypto_register_alg(base);
0189 }
0190 EXPORT_SYMBOL_GPL(crypto_register_rng);
0191
0192 void crypto_unregister_rng(struct rng_alg *alg)
0193 {
0194 crypto_unregister_alg(&alg->base);
0195 }
0196 EXPORT_SYMBOL_GPL(crypto_unregister_rng);
0197
0198 int crypto_register_rngs(struct rng_alg *algs, int count)
0199 {
0200 int i, ret;
0201
0202 for (i = 0; i < count; i++) {
0203 ret = crypto_register_rng(algs + i);
0204 if (ret)
0205 goto err;
0206 }
0207
0208 return 0;
0209
0210 err:
0211 for (--i; i >= 0; --i)
0212 crypto_unregister_rng(algs + i);
0213
0214 return ret;
0215 }
0216 EXPORT_SYMBOL_GPL(crypto_register_rngs);
0217
0218 void crypto_unregister_rngs(struct rng_alg *algs, int count)
0219 {
0220 int i;
0221
0222 for (i = count - 1; i >= 0; --i)
0223 crypto_unregister_rng(algs + i);
0224 }
0225 EXPORT_SYMBOL_GPL(crypto_unregister_rngs);
0226
0227 MODULE_LICENSE("GPL");
0228 MODULE_DESCRIPTION("Random Number Generator");