# Linux Entropy Recording and Validation

The test provided here is split into two aspects: the recording of the raw
entropy data and the validation of the data. Both aspects are implemented
with the code in the respective directories.

The idea is that you give the recording directory to the customer
so that he obtains the data. Once you receive the data, you process it
with the code in the validation directory.

## Getting Started

When standard testing shall be performed, the collection of raw entropy is
performed with the script `invoke_testing.sh`.

This test tool uses the Jitter RNG source code from the `src/` directory. If you
need to test a different code tree, please pull the respective code.

The results are stored in `../results-measurements` which then needs to be
processed with the `validation-runtime` and `validation-restart` logic.

For analyzing different aspects of the Jitter RNG, different flavors of the
test script are provided as follows which all obtain the raw unconditioned
noise data to be analyzed with the tool set given in `validation-runtime`:

* `invoke_testing.sh`: This test tool invokes the default behavior of the
  Jitter RNG. Its analysis tool is `validation-runtime/processdata.sh`
  
* `invoke_testing_fips.sh`: This test tool initializes the Jitter RNG with
  `JENT_FIPS` to obtain the FIPS 140 behavior. Its analysis tool is
  `validation-runtime/processdata.sh`
  
* `invoke_testing_ntg1.sh`: This test tool initializes the Jitter RNG with
  `JENT_NTG1` to obtain the BSI NTG.1 behavior. Its analysis tool is `validation-runtime/processdata_ntg1.sh`
  to obtain the entropy rate for each data stream. See [NTG.1 Recording] for
  details.
  
* `invoke_testing_memloop.sh`: This test tool initializes the Jitter RNG with
  `JENT_NTG1` to obtain the BSI NTG.1 behavior. Its analysis tool is
  `validation-runtime/processdata_memloop.sh`. See [NTG.1 Raw Noise Sources] for
  details.
  
* `invoke_testing_hashloop.sh`: This test tool initializes the Jitter RNG with
  `JENT_NTG1` to obtain the BSI NTG.1 behavior. Its analysis tool is
  `validation-runtime/processdata_hashloop.sh`. See [NTG.1 Raw Noise Sources] for
  details.

## Recording of Raw Entropy Data

If the `invoke_testing.sh` is not helpful for performing the test, the following
explanation outlines the specific test steps to be invoked manually.

For recoding the raw entropic data, the user has to compile the code.
To do that, he has to copy the following files into the recording directory
prior compilation. These files are taken from his Jitter RNG implementation
that he uses:

	* jitterentropy-base.c

	* jitterentropy.h

	* jitterentropy-base-user.h

Depending on the version of the Jitter RNG, the following commands have to
be invoked for compiling the test tool:

	* Jitter RNG 3.x: make -f Makefile.hashtime

The test is now invoked with the following command:

	* Jitter RNG 3.x:

		./jitterentropy-hashtime > /dev/shm/jent-raw.data

In addition, the collection of output data from the Jitter RNG must be
compiled with the following command:

	make -f Makefile.rng

To generate output data from the Jitter RNG for validation, invoke:

	./jitterentropy-rng 2> /dev/shm/jent.rngout

The program is compiled to collect a sample of 10000000 events each (see 
the ROUNDS parameter in Makefile).

## NTG.1 Recording

The NTG.1 raw data recording is provided with the shell script
`invoke_testing_ntg1.sh`. This script generates the following sets of data with
1,000,000 samples each:

* raw data of the "common" runtime operation and behavior (this data applies
to the random data generated by the Jitter RNG intended for reseeding a
deterministic RNG),

* raw data of the "hash loop" operation (this is the first of the two noise
sources used to generate the first 256 bit output block intended to initialize
a deterministic RNG), and

* raw data for the "memory access loop" operation (this is the second noise
source used to generate the first 256 bit output block intended to initialize
a deterministic RNG).

The generated data is intended to be processed with the
`validation-runtime/processdata_ntg1.sh` tool which delivers the staticial
data individually for the aforementioned data.

## NTG.1 Raw Noise Sources

BSI is interested in answering the following question: For NTG.1, two separate
noise sources must be used. The Jitter RNG offers the memory access and the
hash loop as raw noise sources. The question is how much entropy is delivered by
each of the noise source individually.

This question is relatively easy to answer for the hash loop, as the measurement
of the Keccak execution timing hardly requires any memory access (and thus
hardly has any interference with the memory access noise source), because
on bigger CPUs like Intel, the Keccak state fits into registers and thus the
"hash loop" measurement outlined in [NTG.1 Recording] measures this operation.
This is due to the fact that the "hash loop" measurement exclusively times
the Keccak operation. Nonetheless, if the hash loop provides insufficient
data, the analysis script `invoke_testing_hashloop.sh` can be invoked. The
data is analyzed with `validation-runtime/processdata_hashloop.sh`.

However, for the memory access, only the access to L2 or higher caches or the
main RAM are considered relevant, because the L1 at least to some degree used by
the hash loop operation and the remainder of the Jitter RNG logic as well
(e.g. the initial fetches). To achieve that testing of mainly the L2 cache, the
script `invoke_testing_memloop.sh` invokes the memory access loop with the
"deterministic" access pattern. This ensures the following:

* the decision on which byte in the memory array to access is determined with
  one ADD operation (as opposed to several instructions with the "quasi-random"
  access pattern). This ensures that access to the L1 instruction cache is very
  limited.
  
* apart from the calculation of the next byte to be accessed, only the byte
  itself is read, modified with an ADD and AND operation and written back again.
  This implies that again, the use of the L1 instruction cache is very
  limited and therefore only the memory access is truly measured. When the
  memory block is larger than the L1 cache, the memory access operation will
  require at least L2 acesses. 
  
With this testing approach, the L1 cache impact is reduced to become irrelevant
for the timing variations when selecting a memory block size that is larger than
the L1 data cache size. This approach now allows to almost exclusively
measure the timing variations derived from L2 or higher caches, or RAM itself.
  
The script `invoke_testing_memloop.sh` performs the testing with all commonly
supported memory sizes. Along with the analysis script 
`validation-runtime/processdata_memloop.sh` the entropy rate for each memory
block size is calculated. When now the memory sizes that are larger than the
tested CPU's L1 data cache are considered, the entropy rate that almost entirelyis derived from L2 is visible.
