0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #include <linux/kernel.h>
0041 #include <linux/module.h>
0042 #include <linux/slab.h>
0043 #include <linux/time.h>
0044 #include <crypto/internal/rng.h>
0045
0046 #include "jitterentropy.h"
0047
0048
0049
0050
0051
0052 void *jent_zalloc(unsigned int len)
0053 {
0054 return kzalloc(len, GFP_KERNEL);
0055 }
0056
0057 void jent_zfree(void *ptr)
0058 {
0059 kfree_sensitive(ptr);
0060 }
0061
0062 void jent_panic(char *s)
0063 {
0064 panic("%s", s);
0065 }
0066
0067 void jent_memcpy(void *dest, const void *src, unsigned int n)
0068 {
0069 memcpy(dest, src, n);
0070 }
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 void jent_get_nstime(__u64 *out)
0082 {
0083 __u64 tmp = 0;
0084
0085 tmp = random_get_entropy();
0086
0087
0088
0089
0090
0091
0092 if (tmp == 0)
0093 tmp = ktime_get_ns();
0094
0095 *out = tmp;
0096 }
0097
0098
0099
0100
0101
0102 struct jitterentropy {
0103 spinlock_t jent_lock;
0104 struct rand_data *entropy_collector;
0105 unsigned int reset_cnt;
0106 };
0107
0108 static int jent_kcapi_init(struct crypto_tfm *tfm)
0109 {
0110 struct jitterentropy *rng = crypto_tfm_ctx(tfm);
0111 int ret = 0;
0112
0113 rng->entropy_collector = jent_entropy_collector_alloc(1, 0);
0114 if (!rng->entropy_collector)
0115 ret = -ENOMEM;
0116
0117 spin_lock_init(&rng->jent_lock);
0118 return ret;
0119 }
0120
0121 static void jent_kcapi_cleanup(struct crypto_tfm *tfm)
0122 {
0123 struct jitterentropy *rng = crypto_tfm_ctx(tfm);
0124
0125 spin_lock(&rng->jent_lock);
0126 if (rng->entropy_collector)
0127 jent_entropy_collector_free(rng->entropy_collector);
0128 rng->entropy_collector = NULL;
0129 spin_unlock(&rng->jent_lock);
0130 }
0131
0132 static int jent_kcapi_random(struct crypto_rng *tfm,
0133 const u8 *src, unsigned int slen,
0134 u8 *rdata, unsigned int dlen)
0135 {
0136 struct jitterentropy *rng = crypto_rng_ctx(tfm);
0137 int ret = 0;
0138
0139 spin_lock(&rng->jent_lock);
0140
0141
0142 if (rng->reset_cnt > (1<<10)) {
0143 ret = -EFAULT;
0144 goto out;
0145 }
0146
0147 ret = jent_read_entropy(rng->entropy_collector, rdata, dlen);
0148
0149
0150 if (ret < -1) {
0151 pr_warn_ratelimited("Reset Jitter RNG due to health test failure: %s failure\n",
0152 (ret == -2) ? "Repetition Count Test" :
0153 "Adaptive Proportion Test");
0154
0155 rng->reset_cnt++;
0156
0157 ret = -EAGAIN;
0158 } else {
0159 rng->reset_cnt = 0;
0160
0161
0162 if (ret == -1)
0163 ret = -EINVAL;
0164 }
0165
0166 out:
0167 spin_unlock(&rng->jent_lock);
0168
0169 return ret;
0170 }
0171
0172 static int jent_kcapi_reset(struct crypto_rng *tfm,
0173 const u8 *seed, unsigned int slen)
0174 {
0175 return 0;
0176 }
0177
0178 static struct rng_alg jent_alg = {
0179 .generate = jent_kcapi_random,
0180 .seed = jent_kcapi_reset,
0181 .seedsize = 0,
0182 .base = {
0183 .cra_name = "jitterentropy_rng",
0184 .cra_driver_name = "jitterentropy_rng",
0185 .cra_priority = 100,
0186 .cra_ctxsize = sizeof(struct jitterentropy),
0187 .cra_module = THIS_MODULE,
0188 .cra_init = jent_kcapi_init,
0189 .cra_exit = jent_kcapi_cleanup,
0190
0191 }
0192 };
0193
0194 static int __init jent_mod_init(void)
0195 {
0196 int ret = 0;
0197
0198 ret = jent_entropy_init();
0199 if (ret) {
0200 pr_info("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
0201 return -EFAULT;
0202 }
0203 return crypto_register_rng(&jent_alg);
0204 }
0205
0206 static void __exit jent_mod_exit(void)
0207 {
0208 crypto_unregister_rng(&jent_alg);
0209 }
0210
0211 module_init(jent_mod_init);
0212 module_exit(jent_mod_exit);
0213
0214 MODULE_LICENSE("Dual BSD/GPL");
0215 MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
0216 MODULE_DESCRIPTION("Non-physical True Random Number Generator based on CPU Jitter");
0217 MODULE_ALIAS_CRYPTO("jitterentropy_rng");