File: random_source.cpp

package info (click to toggle)
entropybroker 2.9-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,600 kB
  • sloc: cpp: 14,386; sh: 934; makefile: 188; java: 148; perl: 12
file content (98 lines) | stat: -rw-r--r-- 2,110 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <unistd.h>
#include <vector>
#include <string>

#include "error.h"
#include "log.h"
#include "utils.h"
#include "kernel_prng_io.h"
#include "kernel_prng_rw.h"
#include "random_source.h"

random_source::random_source(const random_source_t rs_in) : rs(rs_in), notified_errors(false)
{
	rng = new CryptoPP::AutoSeededRandomPool();
}

random_source::random_source(const random_source_t rs_in, const std::string & state_file_in) : rs(rs_in), state_file(state_file_in), notified_errors(false)
{
	retrieve_state(state_file_in);

	rng = new CryptoPP::AutoSeededRandomPool();
}

random_source::~random_source()
{
	if (state_file.length() > 0)
		dump_state(state_file);

	delete rng;
}

void random_source::get(unsigned char *const p, const size_t n)
{
	if (rs == RS_CRYPTOPP)
	{
		// this construction is implemented this as crypto++ 5.6.1 does not handle
		// EAGAIN errors correctly when reading from /dev/urandom
		int attempt = 0;

		for(;;)
		{
			try
			{
				rng -> GenerateBlock(p, n);

				break;
			}
			catch(CryptoPP::OS_RNG_Err ore)
			{
				if (!notified_errors)
				{
					notified_errors = true;

					dolog(LOG_WARNING, "crypto++ threw an error in the OS RNG: %s", ore.what());
				}

				if (++attempt > 16)
					error_exit("crypto++ CryptoPP::AutoSeededRandomPool() failed %d times, aborting", attempt);

				delete rng;
				rng = new CryptoPP::AutoSeededRandomPool();
			}
		}
	}
	else if (rs == RS_DEV_URANDOM)
	{
		if (kernel_rng_read_non_blocking(p, n) == -1)
			error_exit("kernel_rng_read_non_blocking failed");
	}
	else if (rs == RS_DEV_RANDOM)
	{
		if (kernel_rng_read_blocking(p, n) == -1)
			error_exit("kernel_rng_read_non_blocking failed");
	}
	else
	{
		error_exit("Unknown random source %s", rs);
	}
}

bool random_source::check_empty() const
{
	// FIXME /dev/[u]random, check if kernel_rng_get_entropy_count() < write_threshold

	return false;
}

void random_source::seed(const unsigned char *const in, const size_t n, const double byte_count)
{
}

void random_source::dump_state(const std::string & file)
{
}

void random_source::retrieve_state(const std::string & file)
{
}