summaryrefslogtreecommitdiffstats
path: root/src/havegetest.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/havegetest.h')
-rw-r--r--src/havegetest.h225
1 files changed, 225 insertions, 0 deletions
diff --git a/src/havegetest.h b/src/havegetest.h
new file mode 100644
index 0000000..8e9ac28
--- /dev/null
+++ b/src/havegetest.h
@@ -0,0 +1,225 @@
+/**
+ ** Simple entropy harvester based upon the havege RNG
+ **
+ ** Copyright 2018-2021 Jirka Hladky hladky DOT jiri AT gmail DOT com
+ ** Copyright 2012-2014 Gary Wuertz gary@issiweb.com
+ ** Copyright 2012 BenEleventh Consulting manolson@beneleventh.com
+ **
+ ** This program is free software: you can redistribute it and/or modify
+ ** it under the terms of the GNU General Public License as published by
+ ** the Free Software Foundation, either version 3 of the License, or
+ ** (at your option) any later version.
+ **
+ ** This program is distributed in the hope that it will be useful,
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ** GNU General Public License for more details.
+ **
+ ** You should have received a copy of the GNU General Public License
+ ** along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef HAVEGETEST_H
+#define HAVEGETEST_H
+/**
+ * The haveged test suite is built from the 8 tests specified in AIS-31
+ * organized into test procedure A and test procedure B and structured
+ * as state machines capable of processing segmented input streams.
+ */
+#include "havegecollect.h"
+/**
+ * All individual tests and the test procedures use the following
+ * simple state machine to manage input.
+ */
+typedef enum {
+ TEST_INIT, /* initialize test (internal) */
+ TEST_INPUT, /* test input needed */
+ TEST_EVAL, /* evaluating results (internal) */
+ TEST_DONE, /* test complete */
+ TEST_RETRY, /* retry the test */
+ TEST_IGNORE, /* ignore failure and continue */
+ TEST_FAIL /* Test has failed */
+ } TEST_STATE;
+/**
+ * AIS-31 procedure A uses the FIPS140-1 as test1 thru test4. A disjointedness test is
+ * used as test0 and a autocorrelation test is used as test5. test0 is executed only
+ * once, the other tests are repeated in sequence 257 times.
+ */
+#define AIS_A_REPS 257 /* reps for test1 through test 5 */
+/**
+ * Constants for the fips tests. Note AIS-31 v1 uses the unamended FIPS test limits
+ */
+#define FIPS_USED 20000
+#ifndef USE_AMENDED_FIPS
+#define FIPS_MAX_RUN 34
+#define FIPS_ONES_LOW 9654
+#define FIPS_ONES_HIGH 10346
+#define FIPS_POKER_LOW 1562822 /* 1.03 */
+#define FIPS_POKER_HIGH 1580438 /* 57.4 */
+#define FIPS_RUNS_LOW 2267,1079,502,223,90,90
+#define FIPS_RUNS_HIGH 2733,1421,748,402,223,223
+#else
+#define FIPS_MAX_RUN 25
+#define FIPS_ONES_LOW 9725
+#define FIPS_ONES_HIGH 10275
+#define FIPS_POKER_LOW 1576928 /* 2.16 */
+#define FIPS_POKER_HIGH 1576928 /* 46.17 */
+#define FIPS_RUNS_LOW 2315,1114,525,240,103,103
+#define FIPS_RUNS_HIGH 2685,1386,723,384,209,209
+#endif
+/**
+ * test 0 consumes 64k * 48 bits
+ */
+#define TEST0_LENGTH 65536
+#define TEST0_USED (TEST0_LENGTH * 48)
+#define TEST5_LENGTH 5000
+/**
+ * Fixed size input for procedure A
+ */
+#define AIS_A_SIZE (TEST0_USED+(2500*257))
+/**
+ * AIS-31 procedure A results
+ */
+typedef struct {
+ H_UINT testResult; /* id 8 bits, pass/fail 8bits */
+ H_UINT finalValue; /* end result */
+} resultA;
+/**
+ * AIS-31 procedure A context. Options are defined in haveged.h
+ * This puppy weighs in at ~3 MB.
+ */
+typedef struct {
+ H_UINT8 *data; /* input for test */
+ H_UINT range; /* number of bits of input */
+ H_UINT procState; /* procedure state */
+ H_UINT procRetry; /* retry indication */
+ H_UINT testId; /* test selector 0-5 */
+ H_UINT testRun; /* test index 1 - 1285 */
+ H_UINT testState; /* FSM state of current test */
+ H_UINT bridge; /* index for data bridge */
+ H_UINT bytesUsed; /* number of bytes used */
+ H_UINT options; /* duty cycle for test5 */
+ H_UINT8 aux[TEST0_USED]; /* extra work space */
+ resultA results[1286]; /* test results */
+ } procA;
+/**
+ * AIS-31 procedure B is a set of multinomial distribution tests
+ * and an entropy estimate (Coron' test). The distribution tests,
+ * test6 and test7, require at least AIS_LENGTH sequences of 1, 2
+ * 4, and 8 bits.
+ */
+/*
+ * Bit range of AIS-31 procedure B distribution tests
+ */
+#define AIS_LENGTH 100000
+/**
+ * AIS-31 test8 constants (Coron's test)
+ */
+#define Q 2560
+#define K 256000
+#define LN2 0.69314718055994530941
+/**
+ * AIS-31 procedure B results
+ */
+typedef struct {
+ H_UINT testResult; /* id 8 bits, pass/fail 8bits */
+ double finalValue; /* final value */
+ } resultB;
+/**
+ * AIS-31 procedure B context, a svelt 1.25 KB
+ */
+typedef struct {
+ H_UINT *noise; /* input for test */
+ H_UINT range; /* number of bits of input */
+ H_UINT procState; /* procedure state */
+ H_UINT procRetry; /* retry indication */
+ H_UINT testId; /* test selector 6-8 */
+ H_UINT testNbr; /* current test number */
+ H_UINT testState; /* FSM state of current test */
+ H_UINT seq; /* aisSeq() sequence needed */
+ H_UINT bitsUsed; /* bits used by procedure */
+ H_UINT bridge; /* data bridge test6,7 */
+ H_UINT counter[8]; /* sequence lengths */
+ H_UINT einsen[8]; /* sequence counts (ones) */
+ H_UINT full; /* sequence flags */
+ H_UINT lastpos[256]; /* counters for test 8 */
+ H_UINT options; /* RFU */
+ resultB results[9]; /* test results */
+ } procB;
+/**
+ * Testing options
+ */
+#define A_CYCLE 0x000001ff /* test5 duty cycle */
+#define A_WARN 0x00000200 /* Only warn of A fails */
+#define A_RUN 0x00000400 /* Run procedure A */
+#define A_OPTIONS 0x000003ff
+#define B_WARN 0x00001000 /* Only warn of B fails */
+#define B_RUN 0x00002000 /* Run proceure B */
+#define B_OPTIONS 0x00001000
+#define X_OPTIONS 0x000f0000 /* isolated test index */
+#define X_RUN 0x00100000 /* diagnostic isolated test */
+/**
+ * A test procedure run consists of an indicator and options
+ */
+typedef struct {
+ H_UINT action; /* action code A_RUN, B_RUN */
+ H_UINT options; /* WARN and other options */
+ } procInst;
+
+/**
+ * Services provided
+ */
+typedef int (*ptrDiscard)(H_COLLECT *rdr);
+typedef void (*ptrReport)(H_COLLECT * h_ctxt, H_UINT action, H_UINT prod, H_UINT state, H_UINT ct);
+typedef int (*ptrRun)(H_COLLECT *rdr, H_UINT prod);
+
+/**
+ * A test procedure is associated with a collection buffer. Some
+ * resources are shared by all collection buffers. This includes
+ * roll-your-own vtable used to avoid polluting the RNG name space
+ * This structure ends up in hptr->testData
+ */
+typedef struct {
+ ptrDiscard discard; /* release test resources */
+ ptrRun run; /* run test suite */
+ ptrReport report; /* report test results */
+ H_UINT options; /* verbosity, etc. */
+ H_UINT testsUsed; /* tests used */
+ procInst totTests[2]; /* tot tests to run */
+ procInst runTests[2]; /* production tests to run */
+ H_UINT procReps; /* Number of A repetitions */
+ H_UINT fips_low[6]; /* low runs thresholds */
+ H_UINT fips_high[6]; /* high runs thresholds */
+ char totText[8]; /* tot test text rep */
+ char prodText[8]; /* production test text rep */
+ H_UINT meters[H_OLT_PROD_B_P+1]; /* test counters */
+ double lastCoron; /* last test8 result */
+ double *G; /* test8 lookup table */
+} procShared;
+/**
+ * How to get test context and shared data from H_COLLECT
+ */
+#define TESTS_CONTEXT(c) (onlineTests *)(c->havege_tests)
+#define TESTS_SHARED(c) (procShared *)(((H_PTR)(c->havege_app))->testData)
+/**
+ * Online testing context - one per collector. Note szTotal is for diagnostic
+ * use only, no effort is made to account for overflow.
+ */
+typedef struct {
+ H_UINT result; /* nz if failed */
+ H_UINT totIdx; /* tot test idx */
+ H_UINT runIdx; /* run test idx */
+ H_UINT szCarry; /* bits carried in next proc */
+ H_UINT szTotal; /* total bits processed */
+ procA *pA; /* procedure A instance */
+ procB *pB; /* procedure B instance */
+} onlineTests;
+/**
+ * Default options are to run the tot tests.
+ */
+#define DEFAULT_TEST_OPTIONS "ta8b"
+/**
+ * Public interface
+ */
+int havege_test(procShared *tps, H_PARAMS *params);
+
+#endif