| .. | .. |
|---|
| 37 | 37 | * DAMAGE. |
|---|
| 38 | 38 | */ |
|---|
| 39 | 39 | |
|---|
| 40 | +#include <linux/kernel.h> |
|---|
| 40 | 41 | #include <linux/module.h> |
|---|
| 41 | 42 | #include <linux/slab.h> |
|---|
| 42 | 43 | #include <linux/fips.h> |
|---|
| 43 | 44 | #include <linux/time.h> |
|---|
| 44 | | -#include <linux/crypto.h> |
|---|
| 45 | 45 | #include <crypto/internal/rng.h> |
|---|
| 46 | 46 | |
|---|
| 47 | | -struct rand_data; |
|---|
| 48 | | -int jent_read_entropy(struct rand_data *ec, unsigned char *data, |
|---|
| 49 | | - unsigned int len); |
|---|
| 50 | | -int jent_entropy_init(void); |
|---|
| 51 | | -struct rand_data *jent_entropy_collector_alloc(unsigned int osr, |
|---|
| 52 | | - unsigned int flags); |
|---|
| 53 | | -void jent_entropy_collector_free(struct rand_data *entropy_collector); |
|---|
| 47 | +#include "jitterentropy.h" |
|---|
| 54 | 48 | |
|---|
| 55 | 49 | /*************************************************************************** |
|---|
| 56 | 50 | * Helper function |
|---|
| 57 | 51 | ***************************************************************************/ |
|---|
| 58 | | - |
|---|
| 59 | | -__u64 jent_rol64(__u64 word, unsigned int shift) |
|---|
| 60 | | -{ |
|---|
| 61 | | - return rol64(word, shift); |
|---|
| 62 | | -} |
|---|
| 63 | 52 | |
|---|
| 64 | 53 | void *jent_zalloc(unsigned int len) |
|---|
| 65 | 54 | { |
|---|
| .. | .. |
|---|
| 68 | 57 | |
|---|
| 69 | 58 | void jent_zfree(void *ptr) |
|---|
| 70 | 59 | { |
|---|
| 71 | | - kzfree(ptr); |
|---|
| 60 | + kfree_sensitive(ptr); |
|---|
| 72 | 61 | } |
|---|
| 73 | 62 | |
|---|
| 74 | 63 | int jent_fips_enabled(void) |
|---|
| .. | .. |
|---|
| 119 | 108 | struct jitterentropy { |
|---|
| 120 | 109 | spinlock_t jent_lock; |
|---|
| 121 | 110 | struct rand_data *entropy_collector; |
|---|
| 111 | + unsigned int reset_cnt; |
|---|
| 122 | 112 | }; |
|---|
| 123 | 113 | |
|---|
| 124 | 114 | static int jent_kcapi_init(struct crypto_tfm *tfm) |
|---|
| .. | .. |
|---|
| 153 | 143 | int ret = 0; |
|---|
| 154 | 144 | |
|---|
| 155 | 145 | spin_lock(&rng->jent_lock); |
|---|
| 146 | + |
|---|
| 147 | + /* Return a permanent error in case we had too many resets in a row. */ |
|---|
| 148 | + if (rng->reset_cnt > (1<<10)) { |
|---|
| 149 | + ret = -EFAULT; |
|---|
| 150 | + goto out; |
|---|
| 151 | + } |
|---|
| 152 | + |
|---|
| 156 | 153 | ret = jent_read_entropy(rng->entropy_collector, rdata, dlen); |
|---|
| 154 | + |
|---|
| 155 | + /* Reset RNG in case of health failures */ |
|---|
| 156 | + if (ret < -1) { |
|---|
| 157 | + pr_warn_ratelimited("Reset Jitter RNG due to health test failure: %s failure\n", |
|---|
| 158 | + (ret == -2) ? "Repetition Count Test" : |
|---|
| 159 | + "Adaptive Proportion Test"); |
|---|
| 160 | + |
|---|
| 161 | + rng->reset_cnt++; |
|---|
| 162 | + |
|---|
| 163 | + ret = -EAGAIN; |
|---|
| 164 | + } else { |
|---|
| 165 | + rng->reset_cnt = 0; |
|---|
| 166 | + |
|---|
| 167 | + /* Convert the Jitter RNG error into a usable error code */ |
|---|
| 168 | + if (ret == -1) |
|---|
| 169 | + ret = -EINVAL; |
|---|
| 170 | + } |
|---|
| 171 | + |
|---|
| 172 | +out: |
|---|
| 157 | 173 | spin_unlock(&rng->jent_lock); |
|---|
| 158 | 174 | |
|---|
| 159 | 175 | return ret; |
|---|