1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Cryptographic API. 4 * 5 * RNG operations. 6 * 7 * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com> 8 * Copyright (c) 2015 Herbert Xu <herbert@gondor.apana.org.au> 9 */ 10 11 #include <crypto/internal/rng.h> 12 #include <linux/atomic.h> 13 #include <linux/cryptouser.h> 14 #include <linux/err.h> 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/mutex.h> 18 #include <linux/random.h> 19 #include <linux/seq_file.h> 20 #include <linux/slab.h> 21 #include <linux/string.h> 22 #include <net/netlink.h> 23 24 #include "internal.h" 25 26 static DEFINE_MUTEX(crypto_default_rng_lock); 27 static struct crypto_rng *crypto_default_rng; 28 static int crypto_default_rng_refcnt; 29 30 int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen) 31 { 32 u8 *buf = NULL; 33 int err; 34 35 if (!seed && slen) { 36 buf = kmalloc(slen, GFP_KERNEL); 37 if (!buf) 38 return -ENOMEM; 39 40 err = get_random_bytes_wait(buf, slen); 41 if (err) 42 goto out; 43 seed = buf; 44 } 45 46 err = crypto_rng_alg(tfm)->seed(tfm, seed, slen); 47 out: 48 kfree_sensitive(buf); 49 return err; 50 } 51 EXPORT_SYMBOL_GPL(crypto_rng_reset); 52 53 static int crypto_rng_init_tfm(struct crypto_tfm *tfm) 54 { 55 return 0; 56 } 57 58 static unsigned int seedsize(struct crypto_alg *alg) 59 { 60 struct rng_alg *ralg = container_of(alg, struct rng_alg, base); 61 62 return ralg->seedsize; 63 } 64 65 static int __maybe_unused crypto_rng_report( 66 struct sk_buff *skb, struct crypto_alg *alg) 67 { 68 struct crypto_report_rng rrng = { 69 .type = "rng", 70 }; 71 72 rrng.seedsize = seedsize(alg); 73 74 return nla_put(skb, CRYPTOCFGA_REPORT_RNG, sizeof(rrng), &rrng); 75 } 76 77 static void __maybe_unused crypto_rng_show(struct seq_file *m, 78 struct crypto_alg *alg) 79 { 80 seq_printf(m, "type : rng\n"); 81 seq_printf(m, "seedsize : %u\n", seedsize(alg)); 82 } 83 84 static const struct crypto_type crypto_rng_type = { 85 .extsize = crypto_alg_extsize, 86 .init_tfm = crypto_rng_init_tfm, 87 #ifdef CONFIG_PROC_FS 88 .show = crypto_rng_show, 89 #endif 90 #if IS_ENABLED(CONFIG_CRYPTO_USER) 91 .report = crypto_rng_report, 92 #endif 93 .maskclear = ~CRYPTO_ALG_TYPE_MASK, 94 .maskset = CRYPTO_ALG_TYPE_MASK, 95 .type = CRYPTO_ALG_TYPE_RNG, 96 .tfmsize = offsetof(struct crypto_rng, base), 97 .algsize = offsetof(struct rng_alg, base), 98 }; 99 100 struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask) 101 { 102 return crypto_alloc_tfm(alg_name, &crypto_rng_type, type, mask); 103 } 104 EXPORT_SYMBOL_GPL(crypto_alloc_rng); 105 106 static int crypto_get_default_rng(void) 107 { 108 struct crypto_rng *rng; 109 int err; 110 111 mutex_lock(&crypto_default_rng_lock); 112 if (!crypto_default_rng) { 113 rng = crypto_alloc_rng("stdrng", 0, 0); 114 err = PTR_ERR(rng); 115 if (IS_ERR(rng)) 116 goto unlock; 117 118 err = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng)); 119 if (err) { 120 crypto_free_rng(rng); 121 goto unlock; 122 } 123 124 crypto_default_rng = rng; 125 } 126 127 crypto_default_rng_refcnt++; 128 err = 0; 129 130 unlock: 131 mutex_unlock(&crypto_default_rng_lock); 132 133 return err; 134 } 135 136 static void crypto_put_default_rng(void) 137 { 138 mutex_lock(&crypto_default_rng_lock); 139 crypto_default_rng_refcnt--; 140 mutex_unlock(&crypto_default_rng_lock); 141 } 142 143 int __crypto_stdrng_get_bytes(void *buf, unsigned int len) 144 { 145 int err; 146 147 err = crypto_get_default_rng(); 148 if (err) 149 return err; 150 151 err = crypto_rng_get_bytes(crypto_default_rng, buf, len); 152 crypto_put_default_rng(); 153 return err; 154 } 155 EXPORT_SYMBOL_GPL(__crypto_stdrng_get_bytes); 156 157 #if defined(CONFIG_CRYPTO_RNG) || defined(CONFIG_CRYPTO_RNG_MODULE) 158 int crypto_del_default_rng(void) 159 { 160 int err = -EBUSY; 161 162 mutex_lock(&crypto_default_rng_lock); 163 if (crypto_default_rng_refcnt) 164 goto out; 165 166 crypto_free_rng(crypto_default_rng); 167 crypto_default_rng = NULL; 168 169 err = 0; 170 171 out: 172 mutex_unlock(&crypto_default_rng_lock); 173 174 return err; 175 } 176 EXPORT_SYMBOL_GPL(crypto_del_default_rng); 177 #endif 178 179 static void rng_default_set_ent(struct crypto_rng *tfm, const u8 *data, 180 unsigned int len) 181 { 182 } 183 184 int crypto_register_rng(struct rng_alg *alg) 185 { 186 struct crypto_alg *base = &alg->base; 187 188 if (alg->seedsize > PAGE_SIZE / 8) 189 return -EINVAL; 190 191 base->cra_type = &crypto_rng_type; 192 base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; 193 base->cra_flags |= CRYPTO_ALG_TYPE_RNG; 194 195 if (!alg->set_ent) 196 alg->set_ent = rng_default_set_ent; 197 198 return crypto_register_alg(base); 199 } 200 EXPORT_SYMBOL_GPL(crypto_register_rng); 201 202 void crypto_unregister_rng(struct rng_alg *alg) 203 { 204 crypto_unregister_alg(&alg->base); 205 } 206 EXPORT_SYMBOL_GPL(crypto_unregister_rng); 207 208 int crypto_register_rngs(struct rng_alg *algs, int count) 209 { 210 int i, ret; 211 212 for (i = 0; i < count; i++) { 213 ret = crypto_register_rng(algs + i); 214 if (ret) { 215 crypto_unregister_rngs(algs, i); 216 return ret; 217 } 218 } 219 220 return 0; 221 } 222 EXPORT_SYMBOL_GPL(crypto_register_rngs); 223 224 void crypto_unregister_rngs(struct rng_alg *algs, int count) 225 { 226 int i; 227 228 for (i = count - 1; i >= 0; --i) 229 crypto_unregister_rng(algs + i); 230 } 231 EXPORT_SYMBOL_GPL(crypto_unregister_rngs); 232 233 MODULE_LICENSE("GPL"); 234 MODULE_DESCRIPTION("Random Number Generator"); 235