|
@@ -957,10 +957,23 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
|
|
|
{
|
|
|
ssize_t ret = 0, i;
|
|
|
__u8 tmp[EXTRACT_SIZE];
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
/* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
|
|
|
- if (fips_enabled && !r->last_data_init)
|
|
|
- nbytes += EXTRACT_SIZE;
|
|
|
+ if (fips_enabled) {
|
|
|
+ spin_lock_irqsave(&r->lock, flags);
|
|
|
+ if (!r->last_data_init) {
|
|
|
+ r->last_data_init = true;
|
|
|
+ spin_unlock_irqrestore(&r->lock, flags);
|
|
|
+ trace_extract_entropy(r->name, EXTRACT_SIZE,
|
|
|
+ r->entropy_count, _RET_IP_);
|
|
|
+ xfer_secondary_pool(r, EXTRACT_SIZE);
|
|
|
+ extract_buf(r, tmp);
|
|
|
+ spin_lock_irqsave(&r->lock, flags);
|
|
|
+ memcpy(r->last_data, tmp, EXTRACT_SIZE);
|
|
|
+ }
|
|
|
+ spin_unlock_irqrestore(&r->lock, flags);
|
|
|
+ }
|
|
|
|
|
|
trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_);
|
|
|
xfer_secondary_pool(r, nbytes);
|
|
@@ -970,19 +983,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
|
|
|
extract_buf(r, tmp);
|
|
|
|
|
|
if (fips_enabled) {
|
|
|
- unsigned long flags;
|
|
|
-
|
|
|
-
|
|
|
- /* prime last_data value if need be, per fips 140-2 */
|
|
|
- if (!r->last_data_init) {
|
|
|
- spin_lock_irqsave(&r->lock, flags);
|
|
|
- memcpy(r->last_data, tmp, EXTRACT_SIZE);
|
|
|
- r->last_data_init = true;
|
|
|
- nbytes -= EXTRACT_SIZE;
|
|
|
- spin_unlock_irqrestore(&r->lock, flags);
|
|
|
- extract_buf(r, tmp);
|
|
|
- }
|
|
|
-
|
|
|
spin_lock_irqsave(&r->lock, flags);
|
|
|
if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
|
|
|
panic("Hardware RNG duplicated output!\n");
|