From 7ba2b75192fda0bd26c086c9263f7ee390532c77 Mon Sep 17 00:00:00 2001 From: Torben Hansen <50673096+torben-hansen@users.noreply.github.com> Date: Mon, 24 Feb 2025 17:31:26 -0800 Subject: [PATCH] Jitter Entropy 3.6.1 CI test --- crypto/fipsmodule/aes/mode_wrappers.c | 5 +- crypto/fipsmodule/rand/cpu_jitter_test.cc | 4 +- .../rand/entropy/tree_drbg_jitter_entropy.c | 2 +- third_party/jitterentropy/CMakeLists.txt | 13 +- third_party/jitterentropy/META.yml | 5 + third_party/jitterentropy/import.sh | 65 ++++ .../jitterentropy-library/CHANGES.md | 132 +++++++ .../{ => jitterentropy-library}/LICENSE | 2 +- .../{ => jitterentropy-library}/LICENSE.bsd | 0 .../{ => jitterentropy-library}/LICENSE.gplv2 | 0 .../jitterentropy-library/README.md | 69 ++++ .../arch/android/Android.mk | 34 ++ .../arch/android/AndroidManifest.xml | 19 + .../jitterentropy-library/arch/android/README | 14 + .../arch/jitterentropy-base-power.h | 147 ++++++++ .../arch/jitterentropy-base-s390.h | 140 +++++++ .../arch/jitterentropy-base-windows.h | 152 ++++++++ .../arch/jitterentropy-base-x86.h | 159 ++++++++ .../jitterentropy-library/doc/README | 1 + .../jitterentropy-library/doc/jitterentropy.3 | 342 ++++++++++++++++++ .../jitterentropy-base-user.h | 121 ++++++- .../jitterentropy.h | 97 +++-- .../src}/jitterentropy-base.c | 110 ++++-- .../src}/jitterentropy-base.h | 2 +- .../src}/jitterentropy-gcd.c | 6 +- .../src}/jitterentropy-gcd.h | 4 +- .../src}/jitterentropy-health.c | 74 ++-- .../src}/jitterentropy-health.h | 8 +- .../src/jitterentropy-internal.h | 88 +++++ .../src}/jitterentropy-noise.c | 125 ++++--- .../src}/jitterentropy-noise.h | 4 +- .../src}/jitterentropy-sha3.c | 83 ++--- .../src}/jitterentropy-sha3.h | 34 +- .../src}/jitterentropy-timer.c | 7 +- .../src}/jitterentropy-timer.h | 4 +- .../jitterentropy-library/tests/README.md | 10 + .../tests/gcd/CMakeLists.txt | 3 + .../jitterentropy-library/tests/gcd/Makefile | 194 ++++++++++ .../jitterentropy-library/tests/gcd/gcd.c | 66 ++++ .../tests/raw-entropy/README.md | 228 ++++++++++++ .../recording_restart_kernelspace/README.md | 22 ++ .../boottime_test_record.service | 13 + .../boottime_test_record.sh | 110 ++++++ .../recording_restart_kernelspace/install.sh | 20 + .../recording_runtime_kernelspace/LICENSE | 33 ++ .../recording_runtime_kernelspace/LICENSE.bsd | 26 ++ .../LICENSE.gplv2 | 340 +++++++++++++++++ .../recording_runtime_kernelspace/README.md | 23 ++ .../attic/Makefile.foldtime | 31 ++ .../attic/Makefile.lfsrtime | 31 ++ .../attic/README.md | 68 ++++ .../attic/invoke_testing.sh | 78 ++++ .../attic/jitterentropy-foldtime.c | 203 +++++++++++ .../attic/jitterentropy-lfsrtime.c | 232 ++++++++++++ .../getrawentropy.c | 139 +++++++ .../recording_userspace/CMakeLists.txt | 21 ++ .../raw-entropy/recording_userspace/LICENSE | 33 ++ .../recording_userspace/LICENSE.bsd | 26 ++ .../recording_userspace/LICENSE.gplv2 | 340 +++++++++++++++++ .../recording_userspace/Makefile.foldtime | 33 ++ .../recording_userspace/Makefile.hashtime | 58 +++ .../recording_userspace/Makefile.lfsrtime | 40 ++ .../recording_userspace/Makefile.osr | 49 +++ .../recording_userspace/Makefile.rng | 51 +++ .../raw-entropy/recording_userspace/README.md | 95 +++++ .../recording_userspace/analyze_options.sh | 38 ++ .../recording_userspace/invoke_testing.sh | 86 +++++ .../recording_userspace/jitterentropy | 1 + .../jitterentropy-foldtime.c | 69 ++++ .../jitterentropy-hashtime.c | 309 ++++++++++++++++ .../jitterentropy-lfsrtime.c | 133 +++++++ .../recording_userspace/jitterentropy-osr.c | 338 +++++++++++++++++ .../recording_userspace/jitterentropy-rng.c | 166 +++++++++ .../validation-restart-kernel/Makefile | 31 ++ .../validation-restart-kernel/README.md | 67 ++++ .../validation-restart-kernel/extractlsb.c | 231 ++++++++++++ .../validation-restart-kernel/processdata.sh | 149 ++++++++ .../raw-entropy/validation-restart/Makefile | 31 ++ .../raw-entropy/validation-restart/README.md | 68 ++++ .../validation-restart/analyze_options.sh | 118 ++++++ .../validation-restart/extractlsb.c | 241 ++++++++++++ .../validation-restart/processdata.sh | 170 +++++++++ .../validation-runtime-kernel/Makefile | 31 ++ .../validation-runtime-kernel/README.md | 239 ++++++++++++ .../validation-runtime-kernel/extractlsb.c | 231 ++++++++++++ .../validation-runtime-kernel/processdata.sh | 144 ++++++++ .../raw-entropy/validation-runtime/Makefile | 31 ++ .../raw-entropy/validation-runtime/README.md | 248 +++++++++++++ .../validation-runtime/analyze_options.sh | 116 ++++++ .../draw_graph_analyze_options.r | 41 +++ .../validation-runtime/extractlsb.c | 238 ++++++++++++ .../validation-runtime/processdata.sh | 180 +++++++++ tool/bssl_bm.h | 2 +- 93 files changed, 8216 insertions(+), 219 deletions(-) create mode 100644 third_party/jitterentropy/META.yml create mode 100755 third_party/jitterentropy/import.sh create mode 100644 third_party/jitterentropy/jitterentropy-library/CHANGES.md rename third_party/jitterentropy/{ => jitterentropy-library}/LICENSE (96%) rename third_party/jitterentropy/{ => jitterentropy-library}/LICENSE.bsd (100%) rename third_party/jitterentropy/{ => jitterentropy-library}/LICENSE.gplv2 (100%) create mode 100644 third_party/jitterentropy/jitterentropy-library/README.md create mode 100644 third_party/jitterentropy/jitterentropy-library/arch/android/Android.mk create mode 100644 third_party/jitterentropy/jitterentropy-library/arch/android/AndroidManifest.xml create mode 100644 third_party/jitterentropy/jitterentropy-library/arch/android/README create mode 100644 third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-power.h create mode 100644 third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-s390.h create mode 100644 third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-windows.h create mode 100644 third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-x86.h create mode 100644 third_party/jitterentropy/jitterentropy-library/doc/README create mode 100644 third_party/jitterentropy/jitterentropy-library/doc/jitterentropy.3 rename third_party/jitterentropy/{ => jitterentropy-library}/jitterentropy-base-user.h (74%) rename third_party/jitterentropy/{ => jitterentropy-library}/jitterentropy.h (82%) rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-base.c (89%) rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-base.h (94%) rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-gcd.c (96%) rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-gcd.h (92%) rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-health.c (86%) rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-health.h (87%) create mode 100644 third_party/jitterentropy/jitterentropy-library/src/jitterentropy-internal.h rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-noise.c (77%) rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-noise.h (92%) rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-sha3.c (84%) rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-sha3.h (58%) rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-timer.c (96%) rename third_party/jitterentropy/{ => jitterentropy-library/src}/jitterentropy-timer.h (96%) create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/README.md create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/gcd/CMakeLists.txt create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/gcd/Makefile create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/gcd/gcd.c create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/README.md create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/README.md create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/boottime_test_record.service create mode 100755 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/boottime_test_record.sh create mode 100755 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/install.sh create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE.bsd create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE.gplv2 create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/README.md create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/Makefile.foldtime create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/Makefile.lfsrtime create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/README.md create mode 100755 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/invoke_testing.sh create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/jitterentropy-foldtime.c create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/jitterentropy-lfsrtime.c create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/getrawentropy.c create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/CMakeLists.txt create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE.bsd create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE.gplv2 create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.foldtime create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.hashtime create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.lfsrtime create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.osr create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.rng create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/README.md create mode 100755 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/analyze_options.sh create mode 100755 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/invoke_testing.sh create mode 160000 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-foldtime.c create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-hashtime.c create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-lfsrtime.c create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-osr.c create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-rng.c create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/Makefile create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/README.md create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/extractlsb.c create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/processdata.sh create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/Makefile create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/README.md create mode 100755 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/analyze_options.sh create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/extractlsb.c create mode 100755 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/processdata.sh create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/Makefile create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/README.md create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/extractlsb.c create mode 100755 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/processdata.sh create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/Makefile create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/README.md create mode 100755 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/analyze_options.sh create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/draw_graph_analyze_options.r create mode 100644 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/extractlsb.c create mode 100755 third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/processdata.sh diff --git a/crypto/fipsmodule/aes/mode_wrappers.c b/crypto/fipsmodule/aes/mode_wrappers.c index ced71adac6..9c34fcebec 100644 --- a/crypto/fipsmodule/aes/mode_wrappers.c +++ b/crypto/fipsmodule/aes/mode_wrappers.c @@ -147,10 +147,11 @@ int aes_hw_xts_cipher(const uint8_t *in, uint8_t *out, size_t length, // this is the easy way out for now. if (length < 16) return 0; + fprintf(stderr, "avx512_xts_available() = %i\n", avx512_xts_available()); if (enc) { #if defined(AES_XTS_X86_64_AVX512) - if (avx512_xts_available()) { - aes_hw_xts_encrypt_avx512(in, out, length, key1, key2, iv); + if (avx512_xts_available()) { +aes_hw_xts_encrypt_avx512(in, out, length, key1, key2, iv); return 1; } #endif diff --git a/crypto/fipsmodule/rand/cpu_jitter_test.cc b/crypto/fipsmodule/rand/cpu_jitter_test.cc index 9aff8a4f3c..a1873b0e60 100644 --- a/crypto/fipsmodule/rand/cpu_jitter_test.cc +++ b/crypto/fipsmodule/rand/cpu_jitter_test.cc @@ -4,7 +4,7 @@ #include #include "../../test/test_util.h" -#include "../../../third_party/jitterentropy/jitterentropy.h" +#include "../../../third_party/jitterentropy/jitterentropy-library/jitterentropy.h" // Struct for Jitter entropy collector instance with constructor/desctructor. struct JitterEC { @@ -60,6 +60,6 @@ TEST(CPUJitterEntropyTest, Basic) { (char*) data1, data_len), data_len); // Verify that the Jitter library version is v3.4.0. - unsigned int jitter_version = 3040000; + unsigned int jitter_version = 3060100; EXPECT_EQ(jitter_version, jent_version()); } diff --git a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c index 574e783e82..e19e8317ae 100644 --- a/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c +++ b/crypto/fipsmodule/rand/entropy/tree_drbg_jitter_entropy.c @@ -11,7 +11,7 @@ #include "../../../internal.h" #include "../../../ube/internal.h" -#include "../../../../third_party/jitterentropy/jitterentropy.h" +#include "../../../../third_party/jitterentropy/jitterentropy-library/jitterentropy.h" // Randomness generation implements thread-local "frontend" DRBGs that serve // requests for randomness from consumers through exported functions such as diff --git a/third_party/jitterentropy/CMakeLists.txt b/third_party/jitterentropy/CMakeLists.txt index 3b107addcf..2b314e8915 100644 --- a/third_party/jitterentropy/CMakeLists.txt +++ b/third_party/jitterentropy/CMakeLists.txt @@ -7,12 +7,12 @@ # the same as the source code. set(JITTER_SOURCES - ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-base.c - ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-gcd.c - ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-health.c - ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-noise.c - ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-sha3.c - ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-timer.c) + ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-base.c + ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-gcd.c + ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-health.c + ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-noise.c + ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-sha3.c + ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-timer.c) include_directories(${PROJECT_SOURCE_DIR}/include) @@ -37,4 +37,5 @@ endif() set_source_files_properties(${JITTER_SOURCES} PROPERTIES COMPILE_FLAGS "${JITTER_COMPILE_FLAGS}") add_library(jitterentropy OBJECT ${JITTER_SOURCES}) add_dependencies(jitterentropy boringssl_prefix_symbols) +target_include_directories(jitterentropy BEFORE PRIVATE ${PROJECT_SOURCE_DIR}/third_party/jitterentropy/jitterentropy-library) target_include_directories(jitterentropy BEFORE PRIVATE ${PROJECT_BINARY_DIR}/symbol_prefix_include) diff --git a/third_party/jitterentropy/META.yml b/third_party/jitterentropy/META.yml new file mode 100644 index 0000000000..e832638796 --- /dev/null +++ b/third_party/jitterentropy/META.yml @@ -0,0 +1,5 @@ +name: jitterentropy-library +source: smuellerDD/jitterentropy-library.git +commit: 16c9e5c93e614f0df25f1cb30d0730102e6f4e41 +target: v3.6.1 +imported-at: 2025-02-24T16:50:05-0800 diff --git a/third_party/jitterentropy/import.sh b/third_party/jitterentropy/import.sh new file mode 100755 index 0000000000..d0373dfcb8 --- /dev/null +++ b/third_party/jitterentropy/import.sh @@ -0,0 +1,65 @@ +#!/bin/bash -xu + +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 OR ISC + +# +# https://github.com/smuellerDD/jitterentropy-library -> AWS-LC importer script +# +# This script imports a version of Jitter Entropy source into AWS-LC. +# +# Usage: +# +# ``` +# rm -rf ./jitterentropy-library +# ./import.sh +# ``` +# +# This imports Jitter Entroopy from https://github.com/smuellerDD/jitterentropy-library +# and leaves import meta data in META.yml. +# +# If you want to import a specific branch/tag or from a specific repository +# either GITHUB_TARGET or GITHUB_REPOSITORY as below: +# +# ``` +# GITHUB_REPOSITORY=/ GITHUB_TARGET= ./import.sh +# ``` + +GITHUB_SERVER_URL="https://github.com/" +GITHUB_REPOSITORY=${GITHUB_REPOSITORY:=smuellerDD/jitterentropy-library.git} +GITHUB_TARGET=${GITHUB_TARGET:=master} + +SRC="jitterentropy-library" +TMP="TEMP_CAN_DELETE" + +# Check if source directory already exists +if [ -d "${SRC}" ]; then + echo "Source directory or symlink ${SRC} does already exist -- please remove it before re-running the importer" + exit 1 +fi + +mkdir ${TMP} + +echo "Fetching repository ..." +git clone ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} ${TMP} --branch ${GITHUB_TARGET} --single-branch >/dev/null +GITHUB_COMMIT=$(cd ${TMP} >/dev/null; git rev-parse HEAD) + +echo "Copy source code ..." +mkdir ${SRC} +cp -r ${TMP}/* ${SRC} + +echo "Remove temporary artifacts ..." +rm -rf ${TMP} + +# Remove upstream repo build scripts from being invoked. +rm "${SRC}/CMakeLists.txt" +rm "${SRC}/Makefile" + +echo "Generating META.yml file ..." +cat < META.yml +name: ${SRC} +source: ${GITHUB_REPOSITORY} +commit: ${GITHUB_COMMIT} +target: ${GITHUB_TARGET} +imported-at: $(date "+%Y-%m-%dT%H:%M:%S%z") +EOF diff --git a/third_party/jitterentropy/jitterentropy-library/CHANGES.md b/third_party/jitterentropy/jitterentropy-library/CHANGES.md new file mode 100644 index 0000000000..d59bb7d7f8 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/CHANGES.md @@ -0,0 +1,132 @@ +3.6.1 + * Add more test code + * Add support for SunPRO compiler + * Fix compilation on OpenBSD by replacing sed with tr + * internal timer: Add support for Apple + * Various small fixes to compilation to imporve portability + +3.6.0 + * Remove bi-modal behavior of conditioning function + * Make jent_read_entropy_safe safer by retrying the health test + * Move the version information to make them available at compile time + +3.5.0 + * add distinction between intermittent and permanent health failure + + * add compile time option to allow configuring a mask to reduce the size of + the time stamp used for the APT + +3.4.1 + * add FIPS 140 hints to man page + * simplify the test tool to search for optimal configurations + * fix: jent_loop_shuffle: re-add setting the time that was lost with 3.4.0 + * enhancement: add ARM64 assembler code to read high-res timer + +3.4.0 + * enhancement: add API call jent_set_fips_failure_callback as requested by Daniel Ojalvo + * fix: Change the SHA-3 integration: The entropy pool is now a SHA-3 state. +It is filled with the time delta containing entropy and auxiliary data that does not contain entropy using a SHA update operation. The auxiliary data is calculated by a SHA-3 hashing of some varying state data. The time delta that contains entropy is measured about the SHA-3 hasing of the auxiliary data. This satisfies FIPS 140-3 IG D.K resolutions 4, 6, and 8. + * enhancement: add CMake support by Andrew Hopkins + +3.3.1 + * fix: bug fix in initialization logic by Vladis Dronov + * fix: use __asm__ instead of asm to suit the C11 standard + +3.3.0 + * add jent_get_cachesize if _SC_LEVEL1_DCACHE_SIZE is not defined + * limit the memory buffer size allocated and allow caller to provide + the means to provide a limit, too + * fix: update man page + * update README explaining how to handle entropy shortfall to make it consistent with the current code base + +3.2.0 + * fix: add API call jent_read_entropy_safe to header file + * enhancement: add jent_entropy_init_ex API call + * enhancement: call jent_entropy_init_ex automatically when jent_entropy_collector_alloc_internal detects that no self test has yet been performed + * test: provide jitterentropy-rng test tool allowing all options exported by the library to be invoked + * fix: re-add check of time_backwards in power-on test + * fix: silence static code analysis tool + * test: add test for GCD + * enhancement: add GCD selftest + * fix: simplify memory management for SHA-3 + * enhancement: add random memory access (JENT_RANDOM_MEMACCESS) + +3.1.0 + * Add link call to pthreads library as suggested by Mikhail Novosyolov + * Add ENTROPY_SAFETY_FACTOR to apply consideration of asymptotically reaching + full entropy following SP800-90C suggested by Joshua Hill + * Add test for finiding more entropy by changing the memory buffer size + used for the memory access loop + * Increase the memory buffer size to 512 kBytes per default based on + measurements on systems with low entropy. + * Add jent_ncpu() detecting the number of existing CPUs. Only when more than + one CPU is in the system, the internal timer thread is started. + * add GCD testing and analysis suggested by Joshua Hill + * add fixes to APT suggested by Joshua Hill + * add lag predictor health test suggested by Joshua Hill + * add jent_read_entropy_safe API call + * break up jitterentropy-base.c into various smaller code files + +3.0.2 + * Small fixes suggested by Joshua Hill + * Update the invocation of SHA-3 invocation: each loop iteration defined by the loop shuffle is a self-contained SHA-3 operation. Therefore, the conditioning information is always *one* SHA-3 operation with different time duration. + * add JENT_CONF_DISABLE_LOOP_SHUFFLE config option allowing disabling of the shuffle operation + * Use -O0 + +3.0.1 + * on older GCC versions use -fstack-protector as suggested by Warszawski, + Diego + * prevent creating the internal timer thread if a high-res hardware timer is + found as reported by Lonnie Abelbeck + +3.0.0 + * use RDTSC on x86 directly instead of clock_gettime + * use SHA-3 instead of LFSR + * add internal high-resolution timer support + +2.2.0 + * SP800-90B compliance: Add RCT runtime health test + * SP800-90B compliance: Add Chi-Squared runtime health test as a replacement + for the adaptive proportion test + * SP800-90B compliance: Increase initial entropy test to 1024 rounds + * SP800-90B compliance: Invoke runtime health tests during initialization + * remove FIPS 140-2 continuous self test (RCT covers the requirement as per + FIPS 140-2 IG 9.8) + * SP800-90B compliance: Do not mix stuck time deltas into entropy pool + +2.1.2: + * Add static library compilation thanks to Neil Horman + * Initialize variable ec to satisfy valgrind as suggested by Steve Grubb + * Add cross-compilation support suggested by Lonnie Abelbeck + +2.1.1: + * Fix implementation of mathematical properties. + +2.1.0: + * Convert all __[u|s][32|64] into [uint|int][32|64]_t + * Remove all code protected by #if defined(__KERNEL__) && !defined(MODULE) + * Add JENT_PRIVATE_COMPILE: Enable flag during compile when + compiling a private copy of the Jitter RNG + * Remove unused statistical test code + * Add FIPS 140-2 continuous self test code + * threshold for init-time stuck test configurable with JENT_STUCK_INIT_THRES + during compile time + +2.0.1: + * Invcation of stuck test during initalization + +2.0.0: + * Replace the XOR folding of a time delta with an LFSR -- the use of an + LFSR is mathematically more sound for the argument to maintain entropy + +1.2.0: + * Use constant time operation of jent_stir_pool to prevent leaking + timing information about RNG. + * Make it compile on 32 bit archtectures + +1.1.0: + * start new numbering schema + * update processing of bit that is deemed holding no entropy by heuristic: + XOR it into pool without LSFR and bit rotation (reported and suggested + by Kevin Fowler ) + diff --git a/third_party/jitterentropy/LICENSE b/third_party/jitterentropy/jitterentropy-library/LICENSE similarity index 96% rename from third_party/jitterentropy/LICENSE rename to third_party/jitterentropy/jitterentropy-library/LICENSE index cc9d1f1848..dd266c1fc6 100644 --- a/third_party/jitterentropy/LICENSE +++ b/third_party/jitterentropy/jitterentropy-library/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2017 - 2022, Stephan Mueller +Copyright (C) 2017 - 2024, Stephan Mueller Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/third_party/jitterentropy/LICENSE.bsd b/third_party/jitterentropy/jitterentropy-library/LICENSE.bsd similarity index 100% rename from third_party/jitterentropy/LICENSE.bsd rename to third_party/jitterentropy/jitterentropy-library/LICENSE.bsd diff --git a/third_party/jitterentropy/LICENSE.gplv2 b/third_party/jitterentropy/jitterentropy-library/LICENSE.gplv2 similarity index 100% rename from third_party/jitterentropy/LICENSE.gplv2 rename to third_party/jitterentropy/jitterentropy-library/LICENSE.gplv2 diff --git a/third_party/jitterentropy/jitterentropy-library/README.md b/third_party/jitterentropy/jitterentropy-library/README.md new file mode 100644 index 0000000000..73a1961f8b --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/README.md @@ -0,0 +1,69 @@ +Hardware RNG based on CPU timing jitter +======================================= + +The Jitter RNG provides a noise source using the CPU execution timing jitter. +It does not depend on any system resource other than a high-resolution time +stamp. It is a small-scale, yet fast entropy source that is viable in almost +all environments and on a lot of CPU architectures. + +The implementation of the Jitter RNG is independent of any operating system. +As such, it could even run on baremetal without any operating system. + +The design of the RNG is given in the documentation found in at +http://www.chronox.de/jent . This documentation also covers the full +assessment of the SP800-90B compliance as well as all required test code. + +API +--- + +The API is documented in the man page jitterentropy.3. + +To use the Jitter RNG, the header file jitterentropy.h must be included. + +Build Instructions +================== + +To generate the shared library `make` followed by `make install`. + +Android +------- + +To compile the code on Android, use the following Makefile: + +arch/android/Android.mk -- NDK make file template that can be used to directly + compile the CPU Jitter RNG code into Android binaries + +Direct CPU instructions +----------------------- + +If the function in jent_get_nstime is not available, you can replace the +jitterentropy-base-user.h with examples from the arch/ directory. + +Testing +======= + +There are numerous tests around the Jitter RNG. Yet, they are too big to be +loaded into the official repository. Email me, if you want them. + +Version Numbers +=============== +The version numbers for this library have the following schema: +MAJOR.MINOR.PATCHLEVEL + +Changes in the major number implies API and ABI incompatible changes, or +functional changes that require consumer to be updated (as long as this +number is zero, the API is not considered stable and can change without a +bump of the major version). + +Changes in the minor version are API compatible, but the ABI may change. +Functional enhancements only are added. Thus, a consumer can be left +unchanged if enhancements are not considered. The consumer only needs to +be recompiled. + +Patchlevel changes are API / ABI compatible. No functional changes, no +enhancements are made. This release is a bug fixe release only. The +consumer can be left unchanged and does not need to be recompiled. + +Author +====== +Stephan Mueller diff --git a/third_party/jitterentropy/jitterentropy-library/arch/android/Android.mk b/third_party/jitterentropy/jitterentropy-library/arch/android/Android.mk new file mode 100644 index 0000000000..0f2f9b83b7 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/arch/android/Android.mk @@ -0,0 +1,34 @@ +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := jitterentropy +LOCAL_CFLAGS := -O0 -DCRYPTO_CPU_JITTERENTROPY_STAT +LOCAL_SRC_FILES := jitterentropy-base.c jitterentropy-stat.c jitterentropy-foldtime.c + +# compile into a shared library that can be pulled into an APK +LOCAL_STATIC_LIBRARIES := android_native_app_glue +include $(BUILD_SHARED_LIBRARY) +$(call import-module,android/native_app_glue) + +# compilation of a standalone-binary that must be manually moved to +# Android /data partition for execution. +#include $(BUILD_EXECUTABLE) + +# compilation of the CPU Jitter RNG app +#LOCAL_SRC_FILES := jitterentropy-base.c jitterentropy-main-user.c + diff --git a/third_party/jitterentropy/jitterentropy-library/arch/android/AndroidManifest.xml b/third_party/jitterentropy/jitterentropy-library/arch/android/AndroidManifest.xml new file mode 100644 index 0000000000..53ef746148 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/arch/android/AndroidManifest.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/third_party/jitterentropy/jitterentropy-library/arch/android/README b/third_party/jitterentropy/jitterentropy-library/arch/android/README new file mode 100644 index 0000000000..75c327635c --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/arch/android/README @@ -0,0 +1,14 @@ +See comments in Android.mk + +When compiling an APK, follow roughly these steps + +1. create dir /jitterentropy +2. copy AndroidManifest.xml to /jitterentropy +3. copy code and Android.mk to /jitterentropy/jni +4. cd /jitterentropy +5. open eclipse and import project +6. on console android update project -p . -s +7. ../ndk-build +8. in eclipse: open manifest and compile + +am start -n de.chronox.jitterentropy/android.app.NativeActivity diff --git a/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-power.h b/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-power.h new file mode 100644 index 0000000000..2cb35ad2e1 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-power.h @@ -0,0 +1,147 @@ +/* + * Non-physical true random number generator based on timing jitter. + * + * Copyright Stephan Mueller , 2013 - 2024 + * + * License + * ======= + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU General Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _JITTERENTROPY_BASE_POWER_H +#define _JITTERENTROPY_BASE_POWER_H + +#include +#include +#include +#include + +/* taken from http://www.ecrypt.eu.org/ebats/cpucycles.html */ + +static inline void jent_get_nstime(uint64_t *out) +{ + unsigned long high; + unsigned long low; + unsigned long newhigh; + uint64_t result; + __asm__ __volatile__( + "Lcpucycles:mftbu %0;mftb %1;mftbu %2;cmpw %0,%2;bne Lcpucycles" + : "=r" (high), "=r" (low), "=r" (newhigh) + ); + result = high; + result <<= 32; + result |= low; + *out = result; +} + +static inline void *jent_zalloc(size_t len) +{ + void *tmp = NULL; + /* we have no secure memory allocation! Hence + * we do not sed CRYPTO_CPU_JITTERENTROPY_SECURE_MEMORY */ + tmp = malloc(len); + if(NULL != tmp) + memset(tmp, 0, len); + return tmp; +} + +static inline void jent_zfree(void *ptr, unsigned int len) +{ + memset(ptr, 0, len); + free(ptr); +} + +static inline int jent_fips_enabled(void) +{ + return 0; +} + +static inline long jent_ncpu(void) +{ + /* + * TODO: return number of available CPUs - + * this code disables timer thread as only one CPU is "detected". + */ + return 1; +} + +static inline void jent_yield(void) +{ + sched_yield(); +} + +static inline uint32_t jent_cache_size_roundup(void) +{ +#ifdef __linux__ + long l1 = sysconf(_SC_LEVEL1_DCACHE_SIZE); + long l2 = sysconf(_SC_LEVEL2_CACHE_SIZE); + long l3 = sysconf(_SC_LEVEL3_CACHE_SIZE); + uint32_t cache_size = 0; + + /* Cache size reported by system */ + if (l1 > 0) + cache_size += (uint32_t)l1; + if (l2 > 0) + cache_size += (uint32_t)l2; + if (l3 > 0) + cache_size += (uint32_t)l3; + + /* Force the output_size to be of the form (bounding_power_of_2 - 1). */ + cache_size |= (cache_size >> 1); + cache_size |= (cache_size >> 2); + cache_size |= (cache_size >> 4); + cache_size |= (cache_size >> 8); + cache_size |= (cache_size >> 16); + + if (cache_size == 0) + return 0; + + /* Make the output_size the smallest power of 2 strictly greater than cache_size. */ + cache_size++; + + return cache_size; +#else + return 0; +#endif +} + +/* --- helpers needed in user space -- */ + +static inline uint64_t rol64(uint64_t x, int n) +{ + return ( (x << (n&(64-1))) | (x >> ((64-n)&(64-1))) ); +} + +#endif /* _JITTERENTROPY_BASE_POWER_H */ + diff --git a/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-s390.h b/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-s390.h new file mode 100644 index 0000000000..479441a4c1 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-s390.h @@ -0,0 +1,140 @@ +/* + * Non-physical true random number generator based on timing jitter. + * + * Copyright Stephan Mueller , 2013 - 2024 + * + * License + * ======= + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU General Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _JITTERENTROPY_BASE_S390_H +#define _JITTERENTROPY_BASE_S390_H + +#include +#include +#include +#include + +static inline void jent_get_nstime(uint64_t *out) +{ + uint64_t clk; + /* this is MVS code! enable with -S in the compiler */ + /*__asm__ volatile("stck %0" : "=m" (clk) : : "cc"); */ + /* this is gcc */ + __asm__ __volatile__("stcke %0" : "=Q" (clk) : : "cc"); + *out = (uint64_t)(clk); +} + +static inline void *jent_zalloc(size_t len) +{ + void *tmp = NULL; + /* we have no secure memory allocation! Hence + * we do not sed CRYPTO_CPU_JITTERENTROPY_SECURE_MEMORY */ + tmp = malloc(len); + if(NULL != tmp) + memset(tmp, 0, len); + return tmp; +} + +static inline void jent_zfree(void *ptr, unsigned int len) +{ + memset(ptr, 0, len); + free(ptr); +} + +static inline int jent_fips_enabled(void) +{ + return 0; +} + +static inline long jent_ncpu(void) +{ + /* + * TODO: return number of available CPUs - + * this code disables timer thread as only one CPU is "detected". + */ + return 1; +} + +static inline void jent_yield(void) +{ + sched_yield(); +} + +static inline uint32_t jent_cache_size_roundup(void) +{ +#ifdef __linux__ + long l1 = sysconf(_SC_LEVEL1_DCACHE_SIZE); + long l2 = sysconf(_SC_LEVEL2_CACHE_SIZE); + long l3 = sysconf(_SC_LEVEL3_CACHE_SIZE); + uint32_t cache_size = 0; + + /* Cache size reported by system */ + if (l1 > 0) + cache_size += (uint32_t)l1; + if (l2 > 0) + cache_size += (uint32_t)l2; + if (l3 > 0) + cache_size += (uint32_t)l3; + + /* Force the output_size to be of the form (bounding_power_of_2 - 1). */ + cache_size |= (cache_size >> 1); + cache_size |= (cache_size >> 2); + cache_size |= (cache_size >> 4); + cache_size |= (cache_size >> 8); + cache_size |= (cache_size >> 16); + + if (cache_size == 0) + return 0; + + /* Make the output_size the smallest power of 2 strictly greater than cache_size. */ + cache_size++; + + return cache_size; +#else + return 0; +#endif +} + +/* --- helpers needed in user space -- */ + +static inline uint64_t rol64(uint64_t x, int n) +{ + return ( (x << (n&(64-1))) | (x >> ((64-n)&(64-1))) ); +} + + +#endif /* _JITTERENTROPY_BASE_S390_H */ + diff --git a/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-windows.h b/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-windows.h new file mode 100644 index 0000000000..f9523247fd --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-windows.h @@ -0,0 +1,152 @@ +/* + * Non-physical true random number generator based on timing jitter. + * + * Copyright Stephan Mueller , 2013 - 2024 + * + * License + * ======= + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU General Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + e USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _JITTERENTROPY_BASE_X86_H +#define _JITTERENTROPY_BASE_X86_H + +#include + +#if defined(_MSC_VER) +typedef int64_t ssize_t; +#include +#endif + +#include +#include +#include + +#if defined(AWSLC) +#include +#endif + +#if defined(_M_ARM) || defined(_M_ARM64) +#include +#include +#endif + +static inline void jent_get_nstime(uint64_t *out) +{ +#if defined(_M_ARM) || defined(_M_ARM64) + + /* Generic code. */ + LARGE_INTEGER ticks; + QueryPerformanceCounter(&ticks); + *out = ticks.QuadPart; + +#else + + /* x86, x86_64 intrinsic */ + *out = __rdtsc(); + +#endif +} + +static inline void *jent_zalloc(size_t len) +{ + void *tmp = NULL; + /* we have no secure memory allocation! Hence + * we do not sed CRYPTO_CPU_JITTERENTROPY_SECURE_MEMORY */ +#if defined(AWSLC) + tmp = OPENSSL_malloc(len); +#else + tmp = malloc(len); +#endif + if(NULL != tmp) + memset(tmp, 0, len); + return tmp; +} + +static inline void jent_zfree(void *ptr, unsigned int len) +{ +#if defined(AWSLC) + (void) len; + OPENSSL_free(ptr); +#else + memset(ptr, 0, len); + free(ptr); +#endif +} + +static inline int jent_fips_enabled(void) +{ +#if defined(AWSLC) + return FIPS_mode(); +#else + return 0; +#endif +} + +static inline void jent_memset_secure(void *s, size_t n) +{ +#if defined(AWSLC) + OPENSSL_cleanse(s, n); +#else + SecureZeroMemory(s, n); +#endif +} + +static inline long jent_ncpu(void) +{ + /* + * TODO: return number of available CPUs - + * this code disables timer thread as only one CPU is "detected". + */ + return 1; +} + +static inline void jent_yield(void) { } + +static inline uint32_t jent_cache_size_roundup(void) +{ + return 0; +} + +/* --- helpers needed in user space -- */ + +/* note: these helper functions are shamelessly stolen from the kernel :-) */ + +static inline uint64_t rol64(uint64_t word, unsigned int shift) +{ + return (word << shift) | (word >> (64 - shift)); +} + +#endif /* _JITTERENTROPY_BASE_X86_H */ + diff --git a/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-x86.h b/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-x86.h new file mode 100644 index 0000000000..e3b8f0bf8d --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/arch/jitterentropy-base-x86.h @@ -0,0 +1,159 @@ +/* + * Non-physical true random number generator based on timing jitter. + * + * Copyright Stephan Mueller , 2013 - 2024 + * + * License + * ======= + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU General Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _JITTERENTROPY_BASE_X86_H +#define _JITTERENTROPY_BASE_X86_H + +#include +#include +#include +#include + +/* Timer-less entropy source */ +#include + +typedef uint64_t __u64; + +/* taken from Linux kernel */ +#ifdef __x86_64__ +#define DECLARE_ARGS(val, low, high) unsigned long low, high +#define EAX_EDX_VAL(val, low, high) ((low) | (high) << 32) +#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) +#else +#define DECLARE_ARGS(val, low, high) unsigned long long val +#define EAX_EDX_VAL(val, low, high) (val) +#define EAX_EDX_RET(val, low, high) "=A" (val) +#endif + +static inline void jent_get_nstime(uint64_t *out) +{ + DECLARE_ARGS(val, low, high); + __asm__ __volatile__("rdtsc" : EAX_EDX_RET(val, low, high)); + *out = EAX_EDX_VAL(val, low, high); +} + +static inline void *jent_zalloc(size_t len) +{ + void *tmp = NULL; + /* we have no secure memory allocation! Hence + * we do not sed CRYPTO_CPU_JITTERENTROPY_SECURE_MEMORY */ + tmp = malloc(len); + if(NULL != tmp) + memset(tmp, 0, len); + return tmp; +} + +static inline void jent_zfree(void *ptr, unsigned int len) +{ + memset(ptr, 0, len); + free(ptr); +} + +static inline int jent_fips_enabled(void) +{ + return 0; +} + +static inline void jent_memset_secure(void *s, size_t n) +{ + memset(s, 0, n); + __asm__ __volatile__("" : : "r" (s) : "memory"); +} + +static inline long jent_ncpu(void) +{ + /* + * TODO: return number of available CPUs - + * this code disables timer thread as only one CPU is "detected". + */ + return 1; +} + +static inline void jent_yield(void) +{ + sched_yield(); +} + +static inline uint32_t jent_cache_size_roundup(void) +{ +#ifdef __linux__ + long l1 = sysconf(_SC_LEVEL1_DCACHE_SIZE); + long l2 = sysconf(_SC_LEVEL2_CACHE_SIZE); + long l3 = sysconf(_SC_LEVEL3_CACHE_SIZE); + uint32_t cache_size = 0; + + /* Cache size reported by system */ + if (l1 > 0) + cache_size += (uint32_t)l1; + if (l2 > 0) + cache_size += (uint32_t)l2; + if (l3 > 0) + cache_size += (uint32_t)l3; + + /* Force the output_size to be of the form (bounding_power_of_2 - 1). */ + cache_size |= (cache_size >> 1); + cache_size |= (cache_size >> 2); + cache_size |= (cache_size >> 4); + cache_size |= (cache_size >> 8); + cache_size |= (cache_size >> 16); + + if (cache_size == 0) + return 0; + + /* Make the output_size the smallest power of 2 strictly greater than cache_size. */ + cache_size++; + + return cache_size; +#else + return 0; +#endif +} + +/* --- helpers needed in user space -- */ + +static inline uint64_t rol64(uint64_t x, int n) +{ + return ( (x << (n&(64-1))) | (x >> ((64-n)&(64-1))) ); +} + + +#endif /* _JITTERENTROPY_BASE_X86_H */ + diff --git a/third_party/jitterentropy/jitterentropy-library/doc/README b/third_party/jitterentropy/jitterentropy-library/doc/README new file mode 100644 index 0000000000..0fbcf69ce3 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/doc/README @@ -0,0 +1 @@ +For design documentation, see http://www.chronox.de diff --git a/third_party/jitterentropy/jitterentropy-library/doc/jitterentropy.3 b/third_party/jitterentropy/jitterentropy-library/doc/jitterentropy.3 new file mode 100644 index 0000000000..5c71201053 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/doc/jitterentropy.3 @@ -0,0 +1,342 @@ +.\" Copyright (c) 2013 - 2024 by Stephan Mueller (smueller@chronox.de) +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of this +.\" manual under the conditions for verbatim copying, provided that the +.\" entire resulting derived work is distributed under the terms of a +.\" permission notice identical to this one. +.\" +.\" Formatted or processed versions of this manual, if unaccompanied by +.\" the source, must acknowledge the copyright and authors of this work. +.\" License. +.TH JITTERENTROPY 3 2021-03-08 +.SH NAME +jitterentropy \- CPU Jitter Random Number Generator +.SH SYNOPSIS +.nf +.B #include +.sp +.BI "int jent_entropy_switch_notime_impl(struct jent_notime_thread *" new_thread ); +.sp +.BI "int jent_set_fips_failure_callback(jent_fips_failure_cb " cb "); +.sp +.BI "int jent_entropy_init(" void "); +.sp +.BI "int jent_entropy_init_ex(unsigned int " osr ", unsigned int " flags ); +.sp +.BI "struct rand_data *jent_entropy_collector_alloc(unsigned int " osr ", +.BI " unsigned int " flags ); +.sp +.BI "void jent_entropy_collector_free(struct rand_data *" entropy_collector ); +.sp +.BI "ssize_t jent_read_entropy(struct rand_data *" entropy_collector ", +.BI " char *" data ", size_t " len ); +.sp +.BI "ssize_t jent_read_entropy_safe(struct rand_data **" entropy_collector ", +.BI " char *" data ", size_t " len ); +.sp +.BI "#define JENT_MAJVERSION x" +.sp +.BI "#define JENT_MINVERSION y" +.sp +.BI "#define JENT_PATCHLEVEL z" +.sp +.BI "#define JENT_VERSION (...)" +.sp +.BI "unsigned int jent_version(" void "); +.fi +.SH DESCRIPTION +The +.I jitterentropy +library provides a source of good entropy by collecting CPU +executing time jitter. The entropy in the CPU execution time +jitter is magnified by the CPU Jitter Random Number Generator. +The CPU Jitter Random Number Generator uses the CPU execution +timing jitter to generate a bit stream which complies with +different statistical measurements that determine the bit +stream is random. +.LP +The CPU Jitter Random Number Generator delivers entropy which +follows information theoretical requirements. Based on these +studies and the implementation, the caller can assume that +one bit of data extracted from the CPU Jitter Random Number +Generator holds one bit of entropy. +.LP +The CPU Jitter Random Number Generator provides a decentralized +source of entropy where the caller does not need to rely +on a centrally maintained source of entropy like +.IR /dev/random +or +.IR /dev/urandom . +.LP +.BR jent_entropy_switch_notime_impl () +allows the caller to set a thread handler that is used by the +Jitter RNG if it operates in the timer-less mode. See +.IR jitterentropy.h +for a documentation of +.IR new_thread . +This function must be called before +.BR jent_entropy_init () +as after this call, the change of the thread handler is denied. +.LP +.BR jent_set_fips_failure_callback () +allows the caller to set a callback that is invoked by the +Jitter RNG when a health test failure is detected. The callback +specified with the parameter +.BR cb +to the API function receives the Jitter RNG state with the parameter +.BR ec +and the FIPS health test failure with the parameter +.BR health_failure . +his function must be called before +.BR jent_entropy_init () +as after this call, the change of the callback is denied. +.LP +.BR jent_entropy_init () +initializes the CPU Jitter Random Number Generator. The function +performs statistical tests to verify that the underlying system +offers the properties needed for measuring and collecting entropy. +If the initialization is successful, which implies that the +statistical tests indicate the underlying system is appropriate, +the call returns with +.IR 0 . +A return code other than +.IR 0 +indicates a failure where the calling application +.B MUST NOT +use the CPU Jitter Random Number Generator. +.LP +.BR jent_entropy_init_ex () +behaves identically to +.BR jent_entropy_init () +except that it allows the caller to provide the +.IR osr +and +.IR flags +parameters which should be identical to the subsequent invocation of +.BR jent_entropy_collector_alloc (). +When specifying an oversampling rate +.IR osr +different than the default, the startup test honor this value and adjust +the self-test cut-off thresholds to the same values as used at runtime. +.LP +.BR jent_entropy_collector_alloc () +allocates a CPU Jitter entropy collector instance and returns the handle +to the caller. If the allocation fails, including memory +constraints, the call returns +.IR NULL . +The function requires two arguments, the oversampling rate +.IR osr +and a set of flags with +.IR flags . +The +.IR osr +value defines the amount of oversampling performed by the entropy +collector. Usually, a caller wants to provide the value 0 here to +apply the default oversampling. The call ensures that any value +lower than +.B JENT_MIN_OSR +is converted to +.B JENT_MIN_OSR +automatically. +.LP +The +.IR flags +value is either zero or one or more of the following flags. +.TP +.B JENT_DISABLE_MEMORY_ACCESS +If the system is constrained with memory, this flag +disables the allocation of that memory and therefore memory accesses. But +that also implies that the entropy collection process only relies on the +complexity of the CPU. Note, if somebody knows all details of that CPU +complexity, that person may potentially reduce the entropy delivered by the CPU +complexity. If that person can push the generated entropy below a threshold, +the CPU Jitter random number generator starts overestimating entropy from the +noise source. Thus, disabling memory accesses and relying only on the CPU +complexity should only be done if you really know what you are doing. +.TP +.B JENT_FORCE_INTERNAL_TIMER +This flag can be used to force the Jitter RNG to use the internal +high-resolution timer instead of using the hardware time stamp. Commonly, +the startup self test performed with +.BR jent_entropy_init () +uses the hardware timer with precedence if it is identified to be appropriate +for entropy collection. If the internal timer is not compiled, requesting +this flag returns an error. Even though a separate thread is spawned +to provide a high-resolution time stamp, this entire operation is completely +thread-safe as all relevant data is maintained as part of the +.IR entropy_collector +data structure. +.TP +.B JENT_DISABLE_INTERNAL_TIMER +This flag can be used to ensure that the internal timer is not used. +If this flag is used together with +.B JENT_FORCE_INTERNAL_TIMER +this is treated as an error and the allocation returns NULL. Also, +in case +.BR jent_entropy_init () +detects that the internal timer shall be used but the disable flag +is set, the allocation returns NULL. +.TP +.B JENT_FORCE_FIPS +Force full FIPS 140 and SP800-90B compliance irrespective of the +FIPS setting of the underlying operating system. +.TP +.B JENT_MAX_MEMSIZE_* +Define the maximum amount of memory that the Jitter RNG will use +for its operation supporting the collection of raw noise. Without +using one of these flags, the Jitter RNG uses a built-in limit. +The larger the amount of memory is the more entropy is collected. +Yet, the default value is safe on most CPUs. If you have memory +pressure but the entropy rate of your CPU is sufficient a lower +memory size may be used. Contrary when having sufficient memory +but insufficient entropy, larger memory sizes may be specified. +In any case, the Jitter RNG uses at most as much memory as the +sum of the CPU's data caches. +.LP +.BR jent_entropy_collector_free() +zeroizes and frees the given CPU Jitter entropy collector instance. +.LP +.BR jent_read_entropy () +generates a random bit stream and returns it to the caller. +.IR entropy_collector +is the CPU Jitter entropy collector instance which shall be used +to obtain random numbers. +.IR data +is the destination memory location where the random bit stream +is written to. The memory must have already been allocated by the +caller. +.IR len +is a length value provided by the caller indicating the number +of bytes the CPU Jitter Random Number Generator shall generate. +The caller can provide any value greater than 0. The caller +must ensure that +.IR data +is at least als big as +.IR len +indicates. The function returns the number of bytes generated +when the request is successfully completed. If the function returns +the error code +.IR -1 +then the caller handed in a non-initialized (i.e. NULL value) +for the entropy collector. The return code of +.IR -2 +indicates the SP800-90B repetition count online health test failed. +The error code of +.IR -3 +specifies that the SP800-90B adaptive proportion online health test +failed. +.IR -4 +marks that the internal timer generator cannot be initialized. +.IR -5 +specifies that the LAG predictor health test failed. +.IR -6 +indicates that the Repetitive Count Test (RCT) failed permanently. +.IR -7 +indicates that the Adaptive Proportion Test (APT) failed permanently. +.IR -8 +indicates that the LAG prediction test failed permanently. +.LP +When either online health test fails the Jitter RNG will not +have any data provided in +.IR data . +The entropy collector instance will remain in error state. To recover, +the entropy collector instance +.B MUST +be deallocated and a fresh instance must be allocated. It is +recommended that you increase the +.IR osr +value at least by one when newly allocating the Jitter RNG with +.BR jent_entropy_collector_alloc () +which implies that the health tests are less sensitive due to the +fact that the assumed entropy rate of the noise source is lower. +.LP +.BR jent_read_entropy_safe () +is a service function to and therefore operates identically to +.BR jent_read_entropy () +with the exception that it automatically re-allocates the entropy collector +if a health test failure is observed. Before reallocation, a +new power-on health test is performed. The allocation of the new entropy +collector automatically increases the OSR by one. This is done based +on the idea that a health test failure indicates that the assumed +entropy rate is too high. +.LP +Note the function returns with an health test error if the OSR is +getting too large. If an error is returned by this function, the Jitter +RNG is not safe to be used on the current system. +.LP +The function +.BR jent_read_entropy_safe () +has the same error codes as +.BR jent_read_entropy (). +.LP +.BR JENT_MAJVERSION +indicates API / ABI incompatible changes, functional changes that require +consumer to be updated. +.LP +.BR JENT_MINVERSION +indicates API compatible, ABI may change, functional enhancements only, +consumer can be left unchanged if enhancements are not considered. +.LP +.BR JENT_PATCHLEVEL +indicates API / ABI compatible, no functional changes, no enhancements, bug +fixes only. Also, the entropy collection is not changed in any way that +would necessitate a re-assessment. +.LP +.BR JENT_VERSION +the version number of the library as an integer value that is monotonically +increasing. The version numbers are multiples of 100. For example, version +1.2.3 is converted to 1020300 -- the last two digits are reserved for +future use. +.LP +.BR jent_version () +returns +.BR JENT_VERSION. +.PP +.SH FIPS 140-3 Considerations +In order for the Jitter RNG to execute compliant to FIPS 140-3 and by +extension also SP800-90B and SP800-90C compliant, the following +considerations must be applied: +.TP +.B Enable FIPS mode +The FIPS mode is enabled by using the +.IR JENT_FORCE_FIPS +flag during initialization of the Jitter RNG library. On Linux, the +the FIPS mode is transparently enabled if the entire operating system +was booted in FIPS mode, usually by using the "fips=1" Linux kernel +command line parameter. +.TP +.B Perform heursitic entropy analysis +The test tool set provided as part of the Jitter RNG library source +distribution contains the helper to obtain raw noise data at runtime +as well as at initialization time to calculate the SP800-90B entropy rate. +This rate must be above 0.333, the implied heuristic minimum by the Jitter +RNG library. +.TP +.B Resolve insufficient entropy +If insufficient entropy is found during the aforementioned SP800-90B +analysis, the test tool set provides a helper to analyze optimal +settings - see the test tool set for raw entropy for details. The resulting +configuration values are expected to be used with the +.IR flags +parameter of the calls +.BR jent_entropy_collector_alloc () +and +.BR jent_entropy_init_ex () . +It is recommended that the function +.BR jent_read_entropy_safe () +API call is used for generating random numbers. +.PP +.SH NOTES +In addition to use the generated random bit stream directly +for cryptographic operations, the output of +.BR jent_read_entropy () +can be used for seeding a deterministic random number generator. +.PP +.SH SEE ALSO +http://www.chronox.de provides the design description, +the entropy and statistical analyses as well as a number of +test cases. diff --git a/third_party/jitterentropy/jitterentropy-base-user.h b/third_party/jitterentropy/jitterentropy-library/jitterentropy-base-user.h similarity index 74% rename from third_party/jitterentropy/jitterentropy-base-user.h rename to third_party/jitterentropy/jitterentropy-library/jitterentropy-base-user.h index 8898463e67..08d6e28c23 100644 --- a/third_party/jitterentropy/jitterentropy-base-user.h +++ b/third_party/jitterentropy/jitterentropy-library/jitterentropy-base-user.h @@ -1,7 +1,7 @@ /* * Non-physical true random number generator based on timing jitter. * - * Copyright Stephan Mueller , 2013 - 2022 + * Copyright Stephan Mueller , 2013 - 2024 * * License * ======= @@ -49,15 +49,16 @@ * Compilation for OpenSSL #define OPENSSL */ +#include +#include + #include #include #include #include #include #include -#include -#include #include #include #include @@ -96,8 +97,9 @@ /* Support rdtsc read on 64-bit and 32-bit x86 architectures */ #ifdef __x86_64__ -# define DECLARE_ARGS(val, low, high) unsigned long low, high -# define EAX_EDX_VAL(val, low, high) (((uint64_t)low) | ((uint64_t)high) << 32) +/* specify 64 bit type since long is 32 bits in LLP64 x86_64 systems */ +# define DECLARE_ARGS(val, low, high) uint64_t low, high +# define EAX_EDX_VAL(val, low, high) ((low) | (high) << 32) # define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) #elif __i386__ # define DECLARE_ARGS(val, low, high) unsigned long val @@ -108,27 +110,120 @@ static inline void jent_get_nstime(uint64_t *out) { DECLARE_ARGS(val, low, high); - __asm__ __volatile__("rdtsc" : EAX_EDX_RET(val, low, high)); +#ifdef __sun__ + __asm("rdtsc" : EAX_EDX_RET(val, low, high)); +#else + __asm__ __volatile__("rdtsc" : EAX_EDX_RET(val, low, high)); +#endif *out = EAX_EDX_VAL(val, low, high); } #elif defined(__aarch64__) +#ifndef AARCH64_NSTIME_REGISTER +#define AARCH64_NSTIME_REGISTER "cntvct_el0" +#endif + static inline void jent_get_nstime(uint64_t *out) { uint64_t ctr_val; /* * Use the system counter for aarch64 (64 bit ARM). */ - __asm__ volatile("mrs %0, cntvct_el0" : "=r" (ctr_val)); + __asm__ __volatile__("mrs %0, " AARCH64_NSTIME_REGISTER : "=r" (ctr_val)); *out = ctr_val; } -#else /* (__x86_64__) || (__i386__) || (__aarch64__) */ +#elif defined(__s390x__) + +static inline void jent_get_nstime(uint64_t *out) +{ + /* + * This is MVS+STCK code! Enable it with -S in the compiler. + * + * uint64_t clk; + * __asm__ volatile("stck %0" : "=m" (clk) : : "cc"); + * *out = (uint64_t)(clk); + */ + + /* + * This is GCC+STCKE code. STCKE command and data format: + * z/Architecture - Principles of Operation + * http://publibz.boulder.ibm.com/epubs/pdf/dz9zr007.pdf + * + * The current value of bits 0-103 of the TOD clock is stored in bytes + * 1-13 of the sixteen-byte output: + * + * bits 0-7: zeros (reserved for future extention) + * bits 8-111: TOD Clock value + * bits 112-127: Programmable Field + * + * Output bit 59 (TOD-Clock bit 51) effectively increments every + * microsecond. Bits 60 to 111 of STCKE output are fractions of + * a miscrosecond: bit 59 is 1.0us, bit 60 is .5us, bit 61 is .25us, + * bit 62 is .125us, bit 63 is 62.5ns, etc. + * + * Some of these bits can be implemented, some not. 64 bits of + * the TOD clock are implemented usually nowadays, these are + * bits 8-71 of the output. + * + * The stepping value of TOD-clock bit position 63, if implemented, + * is 2^-12 microseconds, or approximately 244 picoseconds. This value + * is called a clock unit. + */ + + uint8_t clk[16]; + + __asm__ __volatile__("stcke %0" : "=Q" (clk) : : "cc"); + + /* s390x is big-endian, so just perfom a byte-by-byte copy */ + *out = *(uint64_t *)(clk + 1); +} + +#elif defined(__powerpc) +/* + * Uncomment this for newer PPC CPUs + * Newer PPC CPUs do not support mftbu/mftb + * these instructions were obsoleted and replaced by + * mfspr. special processor registers 268 and 269 are the + * ones we want. + */ + /* #define POWER_PC_USE_NEW_INSTRUCTIONS */ + +/* taken from http://www.ecrypt.eu.org/ebats/cpucycles.html */ + +static inline void jent_get_nstime(uint64_t *out) +{ + unsigned long high; + unsigned long low; + unsigned long newhigh; + uint64_t result; +#ifdef POWER_PC_USE_NEW_INSTRUCTIONS /* Newer PPC CPUs do not support mftbu/mftb */ + __asm__ __volatile__( + "Lcpucycles:mfspr %0, 269;mfspr %1, 268;mfspr %2, 269;cmpw %0,%2;bne Lcpucycles" + : "=r" (high), "=r" (low), "=r" (newhigh) + ); +#else + __asm__ __volatile__( + "Lcpucycles:mftbu %0;mftb %1;mftbu %2;cmpw %0,%2;bne Lcpucycles" + : "=r" (high), "=r" (low), "=r" (newhigh) + ); +#endif + result = high; + result <<= 32; + result |= low; + *out = result; +} + +#else /* (__x86_64__) || (__i386__) || (__aarch64__) || (__s390x__) || (__powerpc) */ static inline void jent_get_nstime(uint64_t *out) { -#ifdef _AIX + /* OSX does not have clock_gettime -- taken from + * http://developer.apple.com/library/mac/qa/qa1398/_index.html */ +# ifdef __MACH__ + *out = mach_absolute_time(); +# elif _AIX /* clock_gettime() on AIX returns a timer value that increments in * steps of 1000 */ @@ -139,7 +234,7 @@ static inline void jent_get_nstime(uint64_t *out) tmp = tmp << 32; tmp = tmp | aixtime.tb_low; *out = tmp; -# else /* __AIX */ +# else /* __MACH__ */ /* we could use CLOCK_MONOTONIC(_RAW), but with CLOCK_REALTIME * we get some nice extra entropy once in a while from the NTP actions * that we want to use as well... though, we do not rely on that @@ -152,7 +247,7 @@ static inline void jent_get_nstime(uint64_t *out) tmp = tmp + (uint64_t)time.tv_nsec; } *out = tmp; -# endif /* __AIX */ +# endif /* __MACH__ */ } #endif /* (__x86_64__) || (__i386__) || (__aarch64__) */ @@ -206,7 +301,7 @@ static inline int jent_fips_enabled(void) return FIPS_mode(); #elif defined(OPENSSL) #ifdef OPENSSL_FIPS - return FIPS_mode(); + return 1; #else return 0; #endif @@ -238,7 +333,7 @@ static inline void jent_memset_secure(void *s, size_t n) static inline long jent_ncpu(void) { -#ifdef _POSIX_SOURCE +#if defined(_POSIX_SOURCE) || defined(__APPLE__) long ncpu = sysconf(_SC_NPROCESSORS_ONLN); if (ncpu == -1) diff --git a/third_party/jitterentropy/jitterentropy.h b/third_party/jitterentropy/jitterentropy-library/jitterentropy.h similarity index 82% rename from third_party/jitterentropy/jitterentropy.h rename to third_party/jitterentropy/jitterentropy-library/jitterentropy.h index 8e9372c792..c029bae475 100644 --- a/third_party/jitterentropy/jitterentropy.h +++ b/third_party/jitterentropy/jitterentropy-library/jitterentropy.h @@ -1,7 +1,7 @@ /* * Non-physical true random number generator based on timing jitter. * - * Copyright Stephan Mueller , 2014 - 2022 + * Copyright Stephan Mueller , 2014 - 2024 * * License * ======= @@ -46,6 +46,30 @@ extern "C" { #endif +/* + * API / ABI incompatible changes, functional changes that require consumer to + * be updated (as long as this number is zero, the API is not considered stable + * and can change without a bump of the major version). + */ +#define JENT_MAJVERSION 3 + +/* + * API compatible, ABI may change, functional enhancements only, consumer can be + * left unchanged if enhancements are not considered. + */ +#define JENT_MINVERSION 6 + +/* + * API / ABI compatible, no functional changes, no enhancements, bug fixes only. + * Also, the entropy collection is not changed in any way that would necessitate + * a re-assessment. + */ +#define JENT_PATCHLEVEL 1 + +#define JENT_VERSION (JENT_MAJVERSION * 1000000 + \ + JENT_MINVERSION * 10000 + \ + JENT_PATCHLEVEL * 100) + /*************************************************************************** * Jitter RNG Configuration Section * @@ -94,6 +118,46 @@ extern "C" { */ #define JENT_RANDOM_MEMACCESS +/* + * Mask specifying the number of bits of the raw entropy data of the time delta + * value used for the APT. + * + * This value implies that for the APT, only the bits specified by + * JENT_APT_MASK are taken. This was suggested in a draft IG D.K resolution 22 + * provided by NIST, but further analysis + * (https://www.untruth.org/~josh/sp80090b/CMUF%20EWG%20Draft%20IG%20D.K%20Comments%20D10.pdf) + * suggests that this truncation / translation generally results in a health + * test with both a higher false positive rate (because multiple raw symbols + * map to the same symbol within the health test) and a lower statistical power + * when the APT cutoff is selected based on the apparent truncated entropy + * (i.e., truncation generally makes the test worse). NIST has since withdrawn + * this draft and stated that they will not propose truncation prior to + * health testing. + * Because the general tendency of such truncation to make the health test + * worse the default value is set such that no data is masked out and this + * should only be changed if a hardware-specific analysis suggests that some + * other mask setting is beneficial. + * The mask is applied to a time stamp where the GCD is already divided out, and thus no + * "non-moving" low-order bits are present. + */ +#define JENT_APT_MASK (UINT64_C(0xffffffffffffffff)) + +/* This parameter establishes the multiplicative factor that the desired + * memory region size should be larger than the observed cache size; the + * multiplicative factor is 2^JENT_CACHE_SHIFT_BITS. + * Set this to 0 if the desired memory region should be at least as large as + * the cache. If one wants most of the memory updates to result in a memory + * update, then this value should be at least 1. + * If the memory updates should dominantly result in a memory update, then + * the value should be set to at least 3. + * The actual size of the memory region is never larger than requested by + * the passed in JENT_MAX_MEMSIZE_* flag (if provided) or JENT_MEMORY_SIZE + * (if no JENT_MAX_MEMSIZE_* flag is provided). + */ +#ifndef JENT_CACHE_SHIFT_BITS +#define JENT_CACHE_SHIFT_BITS 0 +#endif + /*************************************************************************** * Jitter RNG State Definition Section ***************************************************************************/ @@ -104,8 +168,8 @@ extern "C" { #include "jitterentropy-base-user.h" #endif -#define SHA3_256_SIZE_DIGEST_BITS 256 -#define SHA3_256_SIZE_DIGEST (SHA3_256_SIZE_DIGEST_BITS >> 3) +#define JENT_SHA3_256_SIZE_DIGEST_BITS 256 +#define JENT_SHA3_256_SIZE_DIGEST (JENT_SHA3_256_SIZE_DIGEST_BITS >> 3) /* * The output 256 bits can receive more than 256 bits of min entropy, @@ -129,7 +193,7 @@ extern "C" { * The external caller provides these function pointers to handle the * management of the timer thread that is spawned by the Jitter RNG. * - * @var jent_notime_init This function is intended to initialze the threading + * @var jent_notime_init This function is intended to initialize the threading * support. All data that is required by the threading code must be * held in the data structure @param ctx. The Jitter RNG maintains the * data structure and uses it for every invocation of the following calls. @@ -175,7 +239,7 @@ struct rand_data * calculate the next random value. */ void *hash_state; /* SENSITIVE hash state entropy pool */ uint64_t prev_time; /* SENSITIVE Previous time stamp */ -#define DATA_SIZE_BITS (SHA3_256_SIZE_DIGEST_BITS) +#define DATA_SIZE_BITS (JENT_SHA3_256_SIZE_DIGEST_BITS) #ifndef JENT_HEALTH_LAG_PREDICTOR uint64_t last_delta; /* SENSITIVE stuck test */ @@ -222,8 +286,8 @@ struct rand_data int rct_count; /* Number of stuck values */ /* Adaptive Proportion Test for a significance level of 2^-30 */ - unsigned int apt_cutoff; /* Calculated using a corrected version - * of the SP800-90B sec 4.4.2 formula */ + unsigned int apt_cutoff; /* Intermittent health test failure */ + unsigned int apt_cutoff_permanent; /* Permanent health test failure */ #define JENT_APT_WINDOW_SIZE 512 /* Data window size */ unsigned int apt_observations; /* Number of collected observations in * current window. */ @@ -345,20 +409,6 @@ struct rand_data # define JENT_MIN_OSR 1 #endif -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -/* -- BEGIN Main interface functions -- */ - -#ifndef JENT_STUCK_INIT_THRES -/* - * Per default, not more than 90% of all measurements during initialization - * are allowed to be stuck. - * - * It is allowed to change this value as required for the intended environment. - */ -#define JENT_STUCK_INIT_THRES(x) ((x*9) / 10) -#endif - #ifdef JENT_PRIVATE_COMPILE # define JENT_PRIVATE_STATIC static #else /* JENT_PRIVATE_COMPILE */ @@ -453,6 +503,11 @@ static inline void jent_notime_fini(void *ctx) { (void)ctx; } #define JENT_RCT_FAILURE 1 /* Failure in RCT health test. */ #define JENT_APT_FAILURE 2 /* Failure in APT health test. */ #define JENT_LAG_FAILURE 4 /* Failure in Lag predictor health test. */ +#define JENT_PERMANENT_FAILURE_SHIFT 16 +#define JENT_PERMANENT_FAILURE(x) (x << JENT_PERMANENT_FAILURE_SHIFT) +#define JENT_RCT_FAILURE_PERMANENT JENT_PERMANENT_FAILURE(JENT_RCT_FAILURE) +#define JENT_APT_FAILURE_PERMANENT JENT_PERMANENT_FAILURE(JENT_APT_FAILURE) +#define JENT_LAG_FAILURE_PERMANENT JENT_PERMANENT_FAILURE(JENT_LAG_FAILURE) /* -- END error masks for health tests -- */ /* -- BEGIN statistical test functions only complied with CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT -- */ diff --git a/third_party/jitterentropy/jitterentropy-base.c b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-base.c similarity index 89% rename from third_party/jitterentropy/jitterentropy-base.c rename to third_party/jitterentropy/jitterentropy-library/src/jitterentropy-base.c index f2e79bd4ec..4790ee5b29 100644 --- a/third_party/jitterentropy/jitterentropy-base.c +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-base.c @@ -1,7 +1,7 @@ /* * Non-physical true random number generator based on timing jitter. * - * Copyright Stephan Mueller , 2014 - 2022 + * Copyright Stephan Mueller , 2014 - 2024 * * Design * ====== @@ -29,25 +29,14 @@ * DAMAGE. */ -#include "jitterentropy.h" - #include "jitterentropy-base.h" #include "jitterentropy-gcd.h" #include "jitterentropy-health.h" +#include "jitterentropy-internal.h" #include "jitterentropy-noise.h" #include "jitterentropy-timer.h" #include "jitterentropy-sha3.h" -#define MAJVERSION 3 /* API / ABI incompatible changes, functional changes that - * require consumer to be updated (as long as this number - * is zero, the API is not considered stable and can - * change without a bump of the major version) */ -#define MINVERSION 4 /* API compatible, ABI may change, functional - * enhancements only, consumer can be left unchanged if - * enhancements are not considered */ -#define PATCHLEVEL 0 /* API / ABI compatible, no functional changes, no - * enhancements, bug fixes only */ - /*************************************************************************** * Jitter RNG Static Definitions * @@ -82,13 +71,7 @@ JENT_PRIVATE_STATIC unsigned int jent_version(void) { - unsigned int version = 0; - - version = MAJVERSION * 1000000; - version += MINVERSION * 10000; - version += PATCHLEVEL * 100; - - return version; + return JENT_VERSION; } /*************************************************************************** @@ -162,9 +145,12 @@ static inline unsigned int jent_update_memsize(unsigned int flags) * The following error codes can occur: * -1 entropy_collector is NULL * -2 RCT failed - * -3 APT test failed + * -3 APT failed * -4 The timer cannot be initialized * -5 LAG failure + * -6 RCT permanent failure + * -7 APT permanent failure + * -8 LAG permanent failure */ JENT_PRIVATE_STATIC ssize_t jent_read_entropy(struct rand_data *ec, char *data, size_t len) @@ -186,7 +172,15 @@ ssize_t jent_read_entropy(struct rand_data *ec, char *data, size_t len) jent_random_data(ec); if ((health_test_result = jent_health_failure(ec))) { - if (health_test_result & JENT_RCT_FAILURE) + if (health_test_result & JENT_RCT_FAILURE_PERMANENT) + ret = -6; + else if (health_test_result & + JENT_APT_FAILURE_PERMANENT) + ret = -7; + else if (health_test_result & + JENT_LAG_FAILURE_PERMANENT) + ret = -8; + else if (health_test_result & JENT_RCT_FAILURE) ret = -2; else if (health_test_result & JENT_APT_FAILURE) ret = -3; @@ -276,7 +270,12 @@ ssize_t jent_read_entropy_safe(struct rand_data **ec, char *data, size_t len) return -1; while (len > 0) { - unsigned int osr, flags, max_mem_set; + unsigned int osr, flags, max_mem_set, apt_count, + apt_observations = 0, + lag_prediction_success_run, + lag_prediction_success_count; + int rct_count; + uint64_t current_delta; ret = jent_read_entropy(*ec, p, len); @@ -287,6 +286,19 @@ ssize_t jent_read_entropy_safe(struct rand_data **ec, char *data, size_t len) case -2: case -3: case -5: + apt_count = (*ec)->apt_count; + apt_observations = (*ec)->apt_observations; + current_delta = (*ec)->apt_base; + rct_count = (*ec)->rct_count; + lag_prediction_success_run = + (*ec)->lag_prediction_success_run; + lag_prediction_success_count = + (*ec)->lag_prediction_success_count; + + JE_FALLTHROUGH; + case -6: + case -7: + case -8: osr = (*ec)->osr + 1; flags = (*ec)->flags; max_mem_set = (*ec)->max_mem_set; @@ -308,10 +320,14 @@ ssize_t jent_read_entropy_safe(struct rand_data **ec, char *data, size_t len) * memory size */ jent_entropy_collector_free(*ec); + *ec = NULL; /* Perform new health test with updated OSR */ - if (jent_entropy_init_ex(osr, flags)) - return -1; + while (jent_entropy_init_ex(osr, flags)) { + osr++; + if (osr > 20) + return -1; + } *ec = _jent_entropy_collector_alloc(osr, flags); if (!*ec) @@ -320,6 +336,32 @@ ssize_t jent_read_entropy_safe(struct rand_data **ec, char *data, size_t len) /* Remember whether caller configured memory size */ (*ec)->max_mem_set = !!max_mem_set; + /* + * Set the health test state in case of intermittent + * failures. + */ + if (apt_observations) { + /* APT re-initialization */ + jent_apt_reinit(*ec, current_delta, apt_count, + apt_observations); + + /* RCT re-initialization */ + (*ec)->rct_count = rct_count; + + /* LAG re-initialization */ + (*ec)->lag_prediction_success_run = + lag_prediction_success_run; + (*ec)->lag_prediction_success_count = + lag_prediction_success_count; + } + + /* + * We are not returning the intermittent or permanent + * errors here. If a caller wants them, he should + * register a callback with + * jent_set_fips_failure_callback. + */ + break; default: @@ -358,7 +400,7 @@ ssize_t jent_read_entropy_safe(struct rand_data **ec, char *data, size_t len) */ static inline uint32_t jent_memsize(unsigned int flags) { - uint32_t memsize, max_memsize; + uint32_t cache_memsize=0, max_memsize=0, memsize=0; max_memsize = JENT_FLAGS_TO_MAX_MEMSIZE(flags); @@ -370,7 +412,11 @@ static inline uint32_t jent_memsize(unsigned int flags) } /* Allocate memory for adding variations based on memory access */ - memsize = jent_cache_size_roundup(); + cache_memsize = jent_cache_size_roundup(); + memsize = cache_memsize << JENT_CACHE_SHIFT_BITS; + /* If this value is left-shifted too much, it may be cleared. */ + /* If so, set the maximum possible power of two. */ + if (cache_memsize > memsize) memsize = 0x80000000; /* Limit the memory as defined by caller */ memsize = (memsize > max_memsize) ? max_memsize : memsize; @@ -440,11 +486,11 @@ static struct rand_data entropy_collector->memaccessloops = JENT_MEMORY_ACCESSLOOPS; } - if (sha3_alloc(&entropy_collector->hash_state)) + if (jent_sha3_alloc(&entropy_collector->hash_state)) goto err; /* Initialize the hash state */ - sha3_256_init(entropy_collector->hash_state); + jent_sha3_256_init(entropy_collector->hash_state); /* verify and set the oversampling rate */ if (osr < JENT_MIN_OSR) @@ -485,6 +531,8 @@ static struct rand_data err: if (entropy_collector->mem != NULL) jent_zfree(entropy_collector->mem, memsize); + if (entropy_collector->hash_state != NULL) + jent_sha3_dealloc(entropy_collector->hash_state); jent_zfree(entropy_collector, sizeof(struct rand_data)); return NULL; } @@ -526,7 +574,7 @@ JENT_PRIVATE_STATIC void jent_entropy_collector_free(struct rand_data *entropy_collector) { if (entropy_collector != NULL) { - sha3_dealloc(entropy_collector->hash_state); + jent_sha3_dealloc(entropy_collector->hash_state); jent_notime_disable(entropy_collector); if (entropy_collector->mem != NULL) { jent_zfree(entropy_collector->mem, @@ -682,7 +730,7 @@ static inline int jent_entropy_init_common_pre(void) jent_notime_block_switch(); jent_health_cb_block_switch(); - if (sha3_tester()) + if (jent_sha3_tester()) return EHASH; ret = jent_gcd_selftest(); diff --git a/third_party/jitterentropy/jitterentropy-base.h b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-base.h similarity index 94% rename from third_party/jitterentropy/jitterentropy-base.h rename to third_party/jitterentropy/jitterentropy-library/src/jitterentropy-base.h index 1451e77b7e..3eea8c7f19 100644 --- a/third_party/jitterentropy/jitterentropy-base.h +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 - 2022, Stephan Mueller + * Copyright (C) 2021 - 2024, Stephan Mueller * * License: see LICENSE file in root directory * diff --git a/third_party/jitterentropy/jitterentropy-gcd.c b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-gcd.c similarity index 96% rename from third_party/jitterentropy/jitterentropy-gcd.c rename to third_party/jitterentropy/jitterentropy-library/src/jitterentropy-gcd.c index 0b32712914..6a90c8cb03 100644 --- a/third_party/jitterentropy/jitterentropy-gcd.c +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-gcd.c @@ -1,7 +1,7 @@ /* Jitter RNG: GCD health test * - * Copyright (C) 2021 - 2022, Joshua E. Hill - * Copyright (C) 2021 - 2022, Stephan Mueller + * Copyright (C) 2021 - 2024, Joshua E. Hill + * Copyright (C) 2021 - 2024, Stephan Mueller * * License: see LICENSE file in root directory * @@ -19,8 +19,8 @@ * DAMAGE. */ -#include "jitterentropy.h" #include "jitterentropy-gcd.h" +#include "jitterentropy-internal.h" /* The common divisor for all timestamp deltas */ static uint64_t jent_common_timer_gcd = 0; diff --git a/third_party/jitterentropy/jitterentropy-gcd.h b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-gcd.h similarity index 92% rename from third_party/jitterentropy/jitterentropy-gcd.h rename to third_party/jitterentropy/jitterentropy-library/src/jitterentropy-gcd.h index 6eb1b7e954..64c9709ace 100644 --- a/third_party/jitterentropy/jitterentropy-gcd.h +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-gcd.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 - 2022, Stephan Mueller + * Copyright (C) 2021 - 2024, Stephan Mueller * * License: see LICENSE file in root directory * @@ -20,6 +20,8 @@ #ifndef JITTERENTROPY_GCD_H #define JITTERENTROPY_GCD_H +#include "jitterentropy-internal.h" + #ifdef __cplusplus extern "C" { diff --git a/third_party/jitterentropy/jitterentropy-health.c b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-health.c similarity index 86% rename from third_party/jitterentropy/jitterentropy-health.c rename to third_party/jitterentropy/jitterentropy-library/src/jitterentropy-health.c index bcc9d04f56..c4c37e72ce 100644 --- a/third_party/jitterentropy/jitterentropy-health.c +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-health.c @@ -1,7 +1,7 @@ /* Jitter RNG: Health Tests * - * Copyright (C) 2021 - 2022, Joshua E. Hill - * Copyright (C) 2021 - 2022, Stephan Mueller + * Copyright (C) 2021 - 2024, Joshua E. Hill + * Copyright (C) 2021 - 2024, Stephan Mueller * * License: see LICENSE file in root directory * @@ -86,6 +86,7 @@ void jent_lag_init(struct rand_data *ec, unsigned int osr) * Establish the lag global and local cutoffs based on the presumed * entropy rate of 1/osr. */ + /* TODO: add permanent health failure */ if (osr > ARRAY_SIZE(jent_lag_global_cutoff_lookup)) { ec->lag_global_cutoff = jent_lag_global_cutoff_lookup[ @@ -115,7 +116,7 @@ static void jent_lag_reset(struct rand_data *ec) /* Reset Lag counters */ ec->lag_prediction_success_count = 0; ec->lag_prediction_success_run = 0; - ec->lag_best_predictor = 0; //The first guess is basically arbitrary. + ec->lag_best_predictor = 0; /* The first guess is basically arbitrary. */ ec->lag_observations = 0; for (i = 0; i < JENT_LAG_HISTORY_SIZE; i++) { @@ -161,6 +162,7 @@ static void jent_lag_insert(struct rand_data *ec, uint64_t current_delta) ec->lag_prediction_success_count++; ec->lag_prediction_success_run++; + /* TODO: add permanent health failure */ if ((ec->lag_prediction_success_run >= ec->lag_local_cutoff) || (ec->lag_prediction_success_count >= ec->lag_global_cutoff)) ec->health_failure |= JENT_LAG_FAILURE; @@ -264,6 +266,10 @@ static inline uint64_t jent_delta3(struct rand_data *ec, uint64_t delta2) * necessarily have been observed, so there is no chance of observing 0 of these * symbols.) * + * For the alpha < 2^-53, R cannot be used as it uses a float data type without + * arbitrary precision. A SageMath script is used to calculate those cutoff + * values. + * * For any value above 14, this yields the maximal allowable value of 512 * (by FIPS 140-2 IG 7.19 Resolution # 16, we cannot choose a cutoff value that * renders the test unable to fail). @@ -271,6 +277,9 @@ static inline uint64_t jent_delta3(struct rand_data *ec, uint64_t delta2) static const unsigned int jent_apt_cutoff_lookup[15]= { 325, 422, 459, 477, 488, 494, 499, 502, 505, 507, 508, 509, 510, 511, 512 }; +static const unsigned int jent_apt_cutoff_permanent_lookup[15]= + { 355, 447, 479, 494, 502, 507, 510, 512, + 512, 512, 512, 512, 512, 512, 512 }; void jent_apt_init(struct rand_data *ec, unsigned int osr) { @@ -280,12 +289,32 @@ void jent_apt_init(struct rand_data *ec, unsigned int osr) */ if (osr >= ARRAY_SIZE(jent_apt_cutoff_lookup)) { ec->apt_cutoff = jent_apt_cutoff_lookup[ - ARRAY_SIZE(jent_apt_cutoff_lookup) - 1]; + ARRAY_SIZE(jent_apt_cutoff_lookup) - 1]; + ec->apt_cutoff_permanent = jent_apt_cutoff_permanent_lookup[ + ARRAY_SIZE(jent_apt_cutoff_permanent_lookup) - 1]; } else { ec->apt_cutoff = jent_apt_cutoff_lookup[osr - 1]; + ec->apt_cutoff_permanent = + jent_apt_cutoff_permanent_lookup[osr - 1]; } } +void jent_apt_reinit(struct rand_data *ec, + uint64_t current_delta, + unsigned int apt_count, + unsigned int apt_observations) +{ + ec->apt_base = current_delta; /* APT Step 1 */ + ec->apt_base_set = 1; /* APT Step 2 */ + + /* + * Reset APT counter + * Note that we've taken in the first symbol in the window. + */ + ec->apt_count = apt_count; + ec->apt_observations = apt_observations; +} + /** * Reset the APT counter * @@ -305,26 +334,21 @@ static void jent_apt_reset(struct rand_data *ec) */ static void jent_apt_insert(struct rand_data *ec, uint64_t current_delta) { + current_delta &= JENT_APT_MASK; + /* Initialize the base reference */ if (!ec->apt_base_set) { - ec->apt_base = current_delta; // APT Step 1 - ec->apt_base_set = 1; // APT Step 2 - - /* - * Reset APT counter - * Note that we've taken in the first symbol in the window. - */ - ec->apt_count = 1; // B = 1 - ec->apt_observations = 1; - + jent_apt_reinit(ec, current_delta, 1, 1); return; } if (current_delta == ec->apt_base) { - ec->apt_count++; // B = B + 1 + ec->apt_count++; /* B = B + 1 */ /* Note, ec->apt_count starts with one. */ - if (ec->apt_count >= ec->apt_cutoff) + if (ec->apt_count >= ec->apt_cutoff_permanent) + ec->health_failure |= JENT_APT_FAILURE_PERMANENT; + else if (ec->apt_count >= ec->apt_cutoff) ec->health_failure |= JENT_APT_FAILURE; } @@ -332,7 +356,7 @@ static void jent_apt_insert(struct rand_data *ec, uint64_t current_delta) /* Completed one window, the next symbol input will be new apt_base. */ if (ec->apt_observations >= JENT_APT_WINDOW_SIZE) - jent_apt_reset(ec); // APT Step 4 + jent_apt_reset(ec); /* APT Step 4 */ } /*************************************************************************** @@ -343,7 +367,8 @@ static void jent_apt_insert(struct rand_data *ec, uint64_t current_delta) * back-to-back values, the input to the RCT is the counting of the stuck * values during the generation of one Jitter RNG output block. * - * The RCT is applied with an alpha of 2^{-30} compliant to FIPS 140-2 IG 9.8. + * The RCT is applied with an alpha of 2^{-30} compliant to SP800-90B section + * 4.2 for the intermittent failure and 2^{-60} for permanent failures. * * During the counting operation, the Jitter RNG always calculates the RCT * cut-off value of C. If that value exceeds the allowed cut-off value, @@ -371,7 +396,7 @@ static void jent_rct_insert(struct rand_data *ec, int stuck) /* * The cutoff value is based on the following consideration: - * alpha = 2^-30 as recommended in FIPS 140-2 IG 9.8. + * alpha = 2^-30 or 2^-60 as recommended in SP800-90B. * In addition, we require an entropy value H of 1/osr as this * is the minimum entropy required to provide full entropy. * Note, we collect (DATA_SIZE_BITS + ENTROPY_SAFETY_FACTOR)*osr @@ -382,9 +407,13 @@ static void jent_rct_insert(struct rand_data *ec, int stuck) * Note, ec->rct_count (which equals to value B in the pseudo * code of SP800-90B section 4.4.1) starts with zero. Hence * we need to subtract one from the cutoff value as calculated - * following SP800-90B. Thus C = ceil(-log_2(alpha)/H) = 30*osr. + * following SP800-90B. Thus C = ceil(-log_2(alpha)/H) = 30*osr + * or 60*osr. */ - if ((unsigned int)ec->rct_count >= (30 * ec->osr)) { + if ((unsigned int)ec->rct_count >= (60 * ec->osr)) { + ec->rct_count = -1; + ec->health_failure |= JENT_RCT_FAILURE_PERMANENT; + } else if ((unsigned int)ec->rct_count >= (30 * ec->osr)) { ec->rct_count = -1; ec->health_failure |= JENT_RCT_FAILURE; } @@ -442,6 +471,9 @@ unsigned int jent_stuck(struct rand_data *ec, uint64_t current_delta) * 1 RCT failure * 2 APT failure * 4 Lag predictor test failure + * 1< + * Copyright (C) 2021 - 2024, Stephan Mueller * * License: see LICENSE file in root directory * @@ -20,7 +20,7 @@ #ifndef JITTERENTROPY_HEALTH_H #define JITTERENTROPY_HEALTH_H -#include "jitterentropy.h" +#include "jitterentropy-internal.h" #ifdef __cplusplus extern "C" @@ -46,6 +46,10 @@ static inline void jent_lag_init(struct rand_data *ec, unsigned int osr) #endif /* JENT_HEALTH_LAG_PREDICTOR */ void jent_apt_init(struct rand_data *ec, unsigned int osr); +void jent_apt_reinit(struct rand_data *ec, + uint64_t current_delta, + unsigned int apt_count, + unsigned int apt_observations); unsigned int jent_stuck(struct rand_data *ec, uint64_t current_delta); unsigned int jent_health_failure(struct rand_data *ec); diff --git a/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-internal.h b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-internal.h new file mode 100644 index 0000000000..e28cd22d19 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-internal.h @@ -0,0 +1,88 @@ +/* + * Non-physical true random number generator based on timing jitter. + * + * Copyright Stephan Mueller , 2014 - 2024 + * + * License + * ======= + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU General Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _JITTERENTROPY_INTERNAL_H +#define _JITTERENTROPY_INTERNAL_H + +#include "jitterentropy.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +/* -- BEGIN Main interface functions -- */ + +#ifndef JENT_STUCK_INIT_THRES +/* + * Per default, not more than 90% of all measurements during initialization + * are allowed to be stuck. + * + * It is allowed to change this value as required for the intended environment. + */ +#define JENT_STUCK_INIT_THRES(x) ((x*9) / 10) +#endif + +/* Portable switch fall-through to silence warnings. Only works for C. */ +#if defined(__GNUC__) && __GNUC__ >= 7 // gcc 7 +#define JE_FALLTHROUGH __attribute__ ((fallthrough)) +#elif defined(__clang__) +/* Separate logic to avoid errors when compiler doesn't understand __has_attribute */ +#if __has_attribute(fallthrough) && __clang_major__ >= 5 +/* + * Clang 3.5, at least, complains about "error: declaration does not declare + * anything", possibly because we put a semicolon after this macro in + * practice. Thus limit it to >= Clang 5, which does work. + */ +#define JE_FALLTHROUGH __attribute__ ((fallthrough)) +#else +#define JE_FALLTHROUGH +#endif +#else +#define JE_FALLTHROUGH +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _JITTERENTROPY_INTERNAL_H */ diff --git a/third_party/jitterentropy/jitterentropy-noise.c b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-noise.c similarity index 77% rename from third_party/jitterentropy/jitterentropy-noise.c rename to third_party/jitterentropy/jitterentropy-library/src/jitterentropy-noise.c index 5537f72bcb..3559a539f0 100644 --- a/third_party/jitterentropy/jitterentropy-noise.c +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-noise.c @@ -1,6 +1,6 @@ /* Jitter RNG: Noise Sources * - * Copyright (C) 2021 - 2022, Stephan Mueller + * Copyright (C) 2021 - 2024, Stephan Mueller * * License: see LICENSE file in root directory * @@ -33,34 +33,43 @@ * Update of the loop count used for the next round of * an entropy collection. * + * @ec [in] entropy collector struct * @bits [in] is the number of low bits of the timer to consider * @min [in] is the number of bits we shift the timer value to the right at * the end to make sure we have a guaranteed minimum value * * @return Newly calculated loop counter */ -static uint64_t jent_loop_shuffle(unsigned int bits, unsigned int min) +static uint64_t jent_loop_shuffle(struct rand_data *ec, + unsigned int bits, unsigned int min) { #ifdef JENT_CONF_DISABLE_LOOP_SHUFFLE + (void)ec; (void)bits; return (UINT64_C(1)< i; i++) { - shuffle ^= time & mask; - time = time >> bits; + for (i = 0; (((sizeof(time_now) << 3) + bits - 1) / bits) > i; i++) { + shuffle ^= time_now & mask; + time_now = time_now >> bits; } /* @@ -79,7 +88,7 @@ static uint64_t jent_loop_shuffle(unsigned int bits, unsigned int min) * This function injects the individual bits of the time value into the * entropy pool using a hash. * - * @ec [in] entropy collector struct -- may be NULL + * @ec [in] entropy collector struct * @time_delta [in] time delta to be injected * @loop_cnt [in] if a value not equal to 0 is set, use the given value as * number of loops to perform the hash operation @@ -92,20 +101,22 @@ static void jent_hash_time(struct rand_data *ec, uint64_t time_delta, uint64_t loop_cnt, unsigned int stuck) { HASH_CTX_ON_STACK(ctx); - uint8_t intermediary[SHA3_256_SIZE_DIGEST]; - uint64_t j = 0; + /* Size of intermediary ensures a Keccak operation during hash_update */ + uint8_t intermediary[JENT_SHA3_MAX_SIZE_BLOCK] = { 0 }; + uint64_t j = 0, output_value; #define MAX_HASH_LOOP 3 #define MIN_HASH_LOOP 0 /* Ensure that macros cannot overflow jent_loop_shuffle() */ BUILD_BUG_ON((MAX_HASH_LOOP + MIN_HASH_LOOP) > 63); uint64_t hash_loop_cnt = - jent_loop_shuffle(MAX_HASH_LOOP, MIN_HASH_LOOP); + jent_loop_shuffle(ec, MAX_HASH_LOOP, MIN_HASH_LOOP); - /* Use the memset to shut up valgrind */ - memset(intermediary, 0, sizeof(intermediary)); + /* Ensure that everything will fit into the intermediary buffer. */ + BUILD_BUG_ON(sizeof(intermediary) < (JENT_SHA3_256_SIZE_DIGEST + + sizeof(uint64_t))); - sha3_256_init(&ctx); + jent_sha3_256_init(&ctx); /* * testing purposes -- allow test app to set the counter, not @@ -128,40 +139,52 @@ static void jent_hash_time(struct rand_data *ec, uint64_t time_delta, * the sha3_final. */ for (j = 0; j < hash_loop_cnt; j++) { - sha3_update(&ctx, intermediary, sizeof(intermediary)); - sha3_update(&ctx, (uint8_t *)&ec->rct_count, - sizeof(ec->rct_count)); - sha3_update(&ctx, (uint8_t *)&ec->apt_cutoff, - sizeof(ec->apt_cutoff)); - sha3_update(&ctx, (uint8_t *)&ec->apt_observations, - sizeof(ec->apt_observations)); - sha3_update(&ctx, (uint8_t *)&ec->apt_count, - sizeof(ec->apt_count)); - sha3_update(&ctx,(uint8_t *) &ec->apt_base, - sizeof(ec->apt_base)); - sha3_update(&ctx, (uint8_t *)&j, sizeof(uint64_t)); - sha3_final(&ctx, intermediary); + jent_sha3_update(&ctx, intermediary, JENT_SHA3_256_SIZE_DIGEST); + jent_sha3_update(&ctx, (uint8_t *)&ec->rct_count, + sizeof(ec->rct_count)); + jent_sha3_update(&ctx, (uint8_t *)&ec->apt_cutoff, + sizeof(ec->apt_cutoff)); + jent_sha3_update(&ctx, (uint8_t *)&ec->apt_observations, + sizeof(ec->apt_observations)); + jent_sha3_update(&ctx, (uint8_t *)&ec->apt_count, + sizeof(ec->apt_count)); + jent_sha3_update(&ctx,(uint8_t *) &ec->apt_base, + sizeof(ec->apt_base)); + jent_sha3_update(&ctx, (uint8_t *)&j, sizeof(uint64_t)); + jent_sha3_final(&ctx, intermediary); } /* - * Inject the data from the previous loop into the pool. This data is - * not considered to contain any entropy, but it stirs the pool a bit. - */ - sha3_update(ec->hash_state, intermediary, sizeof(intermediary)); - - /* - * Insert the time stamp into the hash context representing the pool. + * Insert the time stamp into the intermediary buffer after the message + * digest of the intermediate data. * * If the time stamp is stuck, do not finally insert the value into the - * entropy pool. Although this operation should not do any harm even - * when the time stamp has no entropy, SP800-90B requires that any + * intermediary buffer. Although this operation should not do any harm + * even when the time stamp has no entropy, SP800-90B requires that any * conditioning operation to have an identical amount of input data * according to section 3.1.5. */ - if (!stuck) - sha3_update(ec->hash_state, (uint8_t *)&time_delta, sizeof(uint64_t)); + if (!stuck) { + /* Insert the time. */ + output_value = time_delta; + } else { + /* The time is considered stuck. Insert the fixed value 0. */ + output_value = 0; + } + + memcpy(intermediary + JENT_SHA3_256_SIZE_DIGEST, + (uint8_t *)&output_value, sizeof(uint64_t)); + + /* + * Inject the data from the intermediary buffer, including the hash we + * are using for timing, and (if the timer is not stuck) the time stamp. + * Only the time is considered to contain any entropy. The intermediary + * buffer is exactly SHA3-256-rate-size to always cause a Keccak + * operation. + */ + jent_sha3_update(ec->hash_state, intermediary, sizeof(intermediary)); - jent_memset_secure(&ctx, SHA_MAX_CTX_SIZE); + jent_memset_secure(&ctx, JENT_SHA_MAX_CTX_SIZE); jent_memset_secure(intermediary, sizeof(intermediary)); } @@ -193,7 +216,7 @@ static inline uint32_t xoshiro128starstar(uint32_t *s) static void jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) { - uint64_t i = 0, time_delta = 0; + uint64_t i = 0, time_now = 0; union { uint32_t u[4]; uint8_t b[sizeof(uint32_t) * 4]; @@ -203,7 +226,7 @@ static void jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) /* Ensure that macros cannot overflow jent_loop_shuffle() */ BUILD_BUG_ON((MAX_ACC_LOOP_BIT + MIN_ACC_LOOP_BIT) > 63); uint64_t acc_loop_cnt = - jent_loop_shuffle(MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT); + jent_loop_shuffle(ec, MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT); if (NULL == ec || NULL == ec->mem) return; @@ -221,8 +244,8 @@ static void jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) * timing, so we can now benefit from the Central Limit Theorem! */ for (i = 0; i < sizeof(prngState); i++) { - jent_get_nstime_internal(ec, &time_delta); - prngState.b[i] ^= (uint8_t)(time_delta & 0xff); + jent_get_nstime_internal(ec, &time_now); + prngState.b[i] ^= (uint8_t)(time_now & 0xff); } /* @@ -281,7 +304,7 @@ static void jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) /* Ensure that macros cannot overflow jent_loop_shuffle() */ BUILD_BUG_ON((MAX_ACC_LOOP_BIT + MIN_ACC_LOOP_BIT) > 63); uint64_t acc_loop_cnt = - jent_loop_shuffle(MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT); + jent_loop_shuffle(ec, MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT); if (NULL == ec || NULL == ec->mem) return; @@ -336,7 +359,7 @@ unsigned int jent_measure_jitter(struct rand_data *ec, uint64_t loop_cnt, uint64_t *ret_current_delta) { - uint64_t time_stamp = 0; + uint64_t time_now = 0; uint64_t current_delta = 0; unsigned int stuck; @@ -347,10 +370,10 @@ unsigned int jent_measure_jitter(struct rand_data *ec, * Get time stamp and calculate time delta to previous * invocation to measure the timing variations */ - jent_get_nstime_internal(ec, &time_stamp); - current_delta = jent_delta(ec->prev_time, time_stamp) / + jent_get_nstime_internal(ec, &time_now); + current_delta = jent_delta(ec->prev_time, time_now) / ec->jent_common_timer_gcd; - ec->prev_time = time_stamp; + ec->prev_time = time_now; /* Check whether we have a stuck measurement. */ stuck = jent_stuck(ec, current_delta); @@ -397,12 +420,12 @@ void jent_random_data(struct rand_data *ec) void jent_read_random_block(struct rand_data *ec, char *dst, size_t dst_len) { - uint8_t jent_block[SHA3_256_SIZE_DIGEST]; + uint8_t jent_block[JENT_SHA3_256_SIZE_DIGEST]; - BUILD_BUG_ON(SHA3_256_SIZE_DIGEST != (DATA_SIZE_BITS / 8)); + BUILD_BUG_ON(JENT_SHA3_256_SIZE_DIGEST != (DATA_SIZE_BITS / 8)); /* The final operation automatically re-initializes the ->hash_state */ - sha3_final(ec->hash_state, jent_block); + jent_sha3_final(ec->hash_state, jent_block); if (dst_len) memcpy(dst, jent_block, dst_len); @@ -410,6 +433,6 @@ void jent_read_random_block(struct rand_data *ec, char *dst, size_t dst_len) * Stir the new state with the data from the old state - the digest * of the old data is not considered to have entropy. */ - sha3_update(ec->hash_state, jent_block, sizeof(jent_block)); + jent_sha3_update(ec->hash_state, jent_block, sizeof(jent_block)); jent_memset_secure(jent_block, sizeof(jent_block)); } diff --git a/third_party/jitterentropy/jitterentropy-noise.h b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-noise.h similarity index 92% rename from third_party/jitterentropy/jitterentropy-noise.h rename to third_party/jitterentropy/jitterentropy-library/src/jitterentropy-noise.h index afe240ce31..3f31a585fc 100644 --- a/third_party/jitterentropy/jitterentropy-noise.h +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-noise.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 - 2022, Stephan Mueller + * Copyright (C) 2021 - 2024, Stephan Mueller * * License: see LICENSE file in root directory * @@ -20,7 +20,7 @@ #ifndef JITTERENTROPY_NOISE_H #define JITTERENTROPY_NOISE_H -#include "jitterentropy.h" +#include "jitterentropy-internal.h" #ifdef __cplusplus extern "C" diff --git a/third_party/jitterentropy/jitterentropy-sha3.c b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-sha3.c similarity index 84% rename from third_party/jitterentropy/jitterentropy-sha3.c rename to third_party/jitterentropy/jitterentropy-library/src/jitterentropy-sha3.c index 50a6cc4b70..53ab3b6327 100644 --- a/third_party/jitterentropy/jitterentropy-sha3.c +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-sha3.c @@ -1,6 +1,6 @@ /* Jitter RNG: SHA-3 Implementation * - * Copyright (C) 2021 - 2022, Stephan Mueller + * Copyright (C) 2021 - 2024, Stephan Mueller * * License: see LICENSE file in root directory * @@ -19,7 +19,7 @@ */ #include "jitterentropy-sha3.h" -#include "jitterentropy.h" +#include "jitterentropy-internal.h" /*************************************************************************** * Message Digest Implementation @@ -58,7 +58,7 @@ static inline void le64_to_ptr(uint8_t *p, const uint64_t value) /* state[x + y*5] */ #define A(x, y) (x + 5 * y) -static inline void keccakp_theta(uint64_t s[25]) +static inline void jent_keccakp_theta(uint64_t s[25]) { uint64_t C[5], D[5]; @@ -108,7 +108,7 @@ static inline void keccakp_theta(uint64_t s[25]) s[A(4, 4)] ^= D[4]; } -static inline void keccakp_rho(uint64_t s[25]) +static inline void jent_keccakp_rho(uint64_t s[25]) { /* Step 1 */ /* s[A(0, 0)] = s[A(0, 0)]; */ @@ -141,7 +141,7 @@ static inline void keccakp_rho(uint64_t s[25]) s[A(1, 1)] = rol64(s[A(1, 1)], RHO_ROL(23)); } -static inline void keccakp_pi(uint64_t s[25]) +static inline void jent_keccakp_pi(uint64_t s[25]) { uint64_t t = s[A(4, 4)]; @@ -173,7 +173,7 @@ static inline void keccakp_pi(uint64_t s[25]) s[A(4, 0)] = t; } -static inline void keccakp_chi(uint64_t s[25]) +static inline void jent_keccakp_chi(uint64_t s[25]) { uint64_t t0[5], t1[5]; @@ -220,7 +220,7 @@ static inline void keccakp_chi(uint64_t s[25]) s[A(4, 4)] ^= ~t0[4] & t1[4]; } -static const uint64_t keccakp_iota_vals[] = { +static const uint64_t jent_keccakp_iota_vals[] = { 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, @@ -231,27 +231,27 @@ static const uint64_t keccakp_iota_vals[] = { 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL }; -static inline void keccakp_iota(uint64_t s[25], unsigned int round) +static inline void jent_keccakp_iota(uint64_t s[25], unsigned int round) { - s[0] ^= keccakp_iota_vals[round]; + s[0] ^= jent_keccakp_iota_vals[round]; } -static inline void keccakp_1600(uint64_t s[25]) +static inline void jent_keccakp_1600(uint64_t s[25]) { unsigned int round; for (round = 0; round < 24; round++) { - keccakp_theta(s); - keccakp_rho(s); - keccakp_pi(s); - keccakp_chi(s); - keccakp_iota(s, round); + jent_keccakp_theta(s); + jent_keccakp_rho(s); + jent_keccakp_pi(s); + jent_keccakp_chi(s); + jent_keccakp_iota(s, round); } } /*********************************** SHA-3 ************************************/ -static inline void sha3_init(struct sha_ctx *ctx) +static inline void jent_sha3_init(struct jent_sha_ctx *ctx) { unsigned int i; @@ -260,15 +260,16 @@ static inline void sha3_init(struct sha_ctx *ctx) ctx->msg_len = 0; } -void sha3_256_init(struct sha_ctx *ctx) +void jent_sha3_256_init(struct jent_sha_ctx *ctx) { - sha3_init(ctx); - ctx->r = SHA3_256_SIZE_BLOCK; - ctx->rword = SHA3_256_SIZE_BLOCK / sizeof(uint64_t); - ctx->digestsize = SHA3_256_SIZE_DIGEST; + jent_sha3_init(ctx); + ctx->r = JENT_SHA3_256_SIZE_BLOCK; + ctx->rword = JENT_SHA3_256_SIZE_BLOCK / sizeof(uint64_t); + ctx->digestsize = JENT_SHA3_256_SIZE_DIGEST; } -static inline void sha3_fill_state(struct sha_ctx *ctx, const uint8_t *in) +static inline void jent_sha3_fill_state(struct jent_sha_ctx *ctx, + const uint8_t *in) { unsigned int i; @@ -278,7 +279,7 @@ static inline void sha3_fill_state(struct sha_ctx *ctx, const uint8_t *in) } } -void sha3_update(struct sha_ctx *ctx, const uint8_t *in, size_t inlen) +void jent_sha3_update(struct jent_sha_ctx *ctx, const uint8_t *in, size_t inlen) { size_t partial = ctx->msg_len % ctx->r; @@ -307,21 +308,21 @@ void sha3_update(struct sha_ctx *ctx, const uint8_t *in, size_t inlen) inlen -= todo; in += todo; - sha3_fill_state(ctx, ctx->partial); - keccakp_1600(ctx->state); + jent_sha3_fill_state(ctx, ctx->partial); + jent_keccakp_1600(ctx->state); } /* Perform a transformation of full block-size messages */ for (; inlen >= ctx->r; inlen -= ctx->r, in += ctx->r) { - sha3_fill_state(ctx, in); - keccakp_1600(ctx->state); + jent_sha3_fill_state(ctx, in); + jent_keccakp_1600(ctx->state); } /* If we have data left, copy it into the partial block buffer */ memcpy(ctx->partial, in, inlen); } -void sha3_final(struct sha_ctx *ctx, uint8_t *digest) +void jent_sha3_final(struct jent_sha_ctx *ctx, uint8_t *digest) { size_t partial = ctx->msg_len % ctx->r; unsigned int i; @@ -339,8 +340,8 @@ void sha3_final(struct sha_ctx *ctx, uint8_t *digest) ctx->partial[ctx->r - 1] |= 0x80; /* Final transformation */ - sha3_fill_state(ctx, ctx->partial); - keccakp_1600(ctx->state); + jent_sha3_fill_state(ctx, ctx->partial); + jent_keccakp_1600(ctx->state); /* * Sponge squeeze phase - the digest size is always smaller as the @@ -354,10 +355,10 @@ void sha3_final(struct sha_ctx *ctx, uint8_t *digest) le32_to_ptr(digest, (uint32_t)(ctx->state[i])); memset(ctx->partial, 0, ctx->r); - sha3_init(ctx); + jent_sha3_init(ctx); } -int sha3_tester(void) +int jent_sha3_tester(void) { HASH_CTX_ON_STACK(ctx); static const uint8_t msg_256[] = { 0x5E, 0x5E, 0xD6 }; @@ -367,14 +368,14 @@ int sha3_tester(void) 0x43, 0x86, 0x8C, 0xC4, 0x0E, 0xC5, 0x5E, 0x00, 0xBB, 0xBB, 0xBD, 0xF5, 0x91, 0x1E }; - uint8_t act[SHA3_256_SIZE_DIGEST] = { 0 }; + uint8_t act[JENT_SHA3_256_SIZE_DIGEST] = { 0 }; unsigned int i; - sha3_256_init(&ctx); - sha3_update(&ctx, msg_256, 3); - sha3_final(&ctx, act); + jent_sha3_256_init(&ctx); + jent_sha3_update(&ctx, msg_256, 3); + jent_sha3_final(&ctx, act); - for (i = 0; i < SHA3_256_SIZE_DIGEST; i++) { + for (i = 0; i < JENT_SHA3_256_SIZE_DIGEST; i++) { if (exp_256[i] != act[i]) return 1; } @@ -382,11 +383,11 @@ int sha3_tester(void) return 0; } -int sha3_alloc(void **hash_state) +int jent_sha3_alloc(void **hash_state) { struct sha_ctx *tmp; - tmp = jent_zalloc(SHA_MAX_CTX_SIZE); + tmp = jent_zalloc(JENT_SHA_MAX_CTX_SIZE); if (!tmp) return 1; @@ -395,9 +396,9 @@ int sha3_alloc(void **hash_state) return 0; } -void sha3_dealloc(void *hash_state) +void jent_sha3_dealloc(void *hash_state) { struct sha_ctx *ctx = (struct sha_ctx *)hash_state; - jent_zfree(ctx, SHA_MAX_CTX_SIZE); + jent_zfree(ctx, JENT_SHA_MAX_CTX_SIZE); } diff --git a/third_party/jitterentropy/jitterentropy-sha3.h b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-sha3.h similarity index 58% rename from third_party/jitterentropy/jitterentropy-sha3.h rename to third_party/jitterentropy/jitterentropy-library/src/jitterentropy-sha3.h index 565daffb96..c0a3770200 100644 --- a/third_party/jitterentropy/jitterentropy-sha3.h +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-sha3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 - 2022, Stephan Mueller + * Copyright (C) 2021 - 2024, Stephan Mueller * * License: see LICENSE file in root directory * @@ -20,36 +20,38 @@ #ifndef JITTERENTROPY_SHA3_H #define JITTERENTROPY_SHA3_H -#include "jitterentropy.h" +#include "jitterentropy-internal.h" #ifdef __cplusplus extern "C" { #endif -#define SHA3_SIZE_BLOCK(bits) ((1600 - 2 * bits) >> 3) -#define SHA3_256_SIZE_BLOCK SHA3_SIZE_BLOCK(SHA3_256_SIZE_DIGEST_BITS) -#define SHA3_MAX_SIZE_BLOCK SHA3_256_SIZE_BLOCK +#define JENT_SHA3_SIZE_BLOCK(bits) ((1600 - 2 * bits) >> 3) +#define JENT_SHA3_256_SIZE_BLOCK \ + JENT_SHA3_SIZE_BLOCK(JENT_SHA3_256_SIZE_DIGEST_BITS) +#define JENT_SHA3_MAX_SIZE_BLOCK JENT_SHA3_256_SIZE_BLOCK -struct sha_ctx { +struct jent_sha_ctx { uint64_t state[25]; size_t msg_len; unsigned int r; unsigned int rword; unsigned int digestsize; - uint8_t partial[SHA3_MAX_SIZE_BLOCK]; + uint8_t partial[JENT_SHA3_MAX_SIZE_BLOCK]; }; -#define SHA_MAX_CTX_SIZE (sizeof(struct sha_ctx)) +#define JENT_SHA_MAX_CTX_SIZE (sizeof(struct jent_sha_ctx)) #define HASH_CTX_ON_STACK(name) \ - struct sha_ctx name - -void sha3_256_init(struct sha_ctx *ctx); -void sha3_update(struct sha_ctx *ctx, const uint8_t *in, size_t inlen); -void sha3_final(struct sha_ctx *ctx, uint8_t *digest); -int sha3_alloc(void **hash_state); -void sha3_dealloc(void *hash_state); -int sha3_tester(void); + struct jent_sha_ctx name + +void jent_sha3_256_init(struct jent_sha_ctx *ctx); +void jent_sha3_update(struct jent_sha_ctx *ctx, const uint8_t *in, + size_t inlen); +void jent_sha3_final(struct jent_sha_ctx *ctx, uint8_t *digest); +int jent_sha3_alloc(void **hash_state); +void jent_sha3_dealloc(void *hash_state); +int jent_sha3_tester(void); #ifdef __cplusplus } diff --git a/third_party/jitterentropy/jitterentropy-timer.c b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-timer.c similarity index 96% rename from third_party/jitterentropy/jitterentropy-timer.c rename to third_party/jitterentropy/jitterentropy-library/src/jitterentropy-timer.c index d6fb0859e6..86a0489ff9 100644 --- a/third_party/jitterentropy/jitterentropy-timer.c +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-timer.c @@ -1,6 +1,6 @@ /* Jitter RNG: Internal timer implementation * - * Copyright (C) 2021 - 2022, Stephan Mueller + * Copyright (C) 2021 - 2024, Stephan Mueller * * License: see LICENSE file in root directory * @@ -26,6 +26,11 @@ * Thread handler ***************************************************************************/ +#ifdef USE_OLDER_GLIBC +__asm__(".symver pthread_join, pthread_join@GLIBC_2.2.5"); +__asm__(".symver pthread_create, pthread_create@GLIBC_2.2.5"); +#endif + JENT_PRIVATE_STATIC int jent_notime_init(void **ctx) { diff --git a/third_party/jitterentropy/jitterentropy-timer.h b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-timer.h similarity index 96% rename from third_party/jitterentropy/jitterentropy-timer.h rename to third_party/jitterentropy/jitterentropy-library/src/jitterentropy-timer.h index 6b6ae91754..947eeb07d9 100644 --- a/third_party/jitterentropy/jitterentropy-timer.h +++ b/third_party/jitterentropy/jitterentropy-library/src/jitterentropy-timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 - 2022, Stephan Mueller + * Copyright (C) 2021 - 2024, Stephan Mueller * * License: see LICENSE file in root directory * @@ -20,7 +20,7 @@ #ifndef JITTERENTROPY_TIMER_H #define JITTERENTROPY_TIMER_H -#include "jitterentropy.h" +#include "jitterentropy-internal.h" #ifdef __cplusplus extern "C" diff --git a/third_party/jitterentropy/jitterentropy-library/tests/README.md b/third_party/jitterentropy/jitterentropy-library/tests/README.md new file mode 100644 index 0000000000..7e722701ac --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/README.md @@ -0,0 +1,10 @@ +# Jitter RNG Tests + +The following Jitter RNG tests are available in the following +directories: + +* `raw-entropy`: Gathering of the raw unprocessed entropy data and restart test + entropy data required for the SP800-90B analysis + +# Author +Stephan Mueller diff --git a/third_party/jitterentropy/jitterentropy-library/tests/gcd/CMakeLists.txt b/third_party/jitterentropy/jitterentropy-library/tests/gcd/CMakeLists.txt new file mode 100644 index 0000000000..9a841922f6 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/gcd/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(gcd gcd.c) +target_include_directories(gcd PRIVATE ../../src) +target_link_libraries(gcd ${PROJECT_NAME}) diff --git a/third_party/jitterentropy/jitterentropy-library/tests/gcd/Makefile b/third_party/jitterentropy/jitterentropy-library/tests/gcd/Makefile new file mode 100644 index 0000000000..2ab8ab1e0e --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/gcd/Makefile @@ -0,0 +1,194 @@ +# +# Copyright (C) 2021 - 2024, Stephan Mueller +# + +CC ?= gcc +CFLAGS += -Wextra -Wall -pedantic -fPIC -O2 -std=gnu18 +#Hardening +CFLAGS += -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -fPIE -Wconversion -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum + +#Optimizations +CFLAGS += -flto +LDFLAGS += -flto + +UNAME_S := $(shell uname -s) +ifeq ($(UNAME_S),Linux) +LDFLAGS += -Wl,-z,relro,-z,now,--as-needed -pie +endif + +NAME := gcd + +DESTDIR := +ETCDIR := /etc +BINDIR := /bin +SBINDIR := /sbin +SHAREDIR := /usr/share/keyutils +MANDIR := /usr/share/man +MAN1 := $(MANDIR)/man1 +MAN3 := $(MANDIR)/man3 +MAN5 := $(MANDIR)/man5 +MAN7 := $(MANDIR)/man7 +MAN8 := $(MANDIR)/man8 +INCLUDEDIR := /usr/include +LN := ln +LNS := $(LN) -sf +STRIP ?= strip -s + +############################################################################### +# +# Define compilation options +# +############################################################################### +INCLUDE_DIRS := ../../ ../../src +LIBRARY_DIRS := +LIBRARIES := + +CFLAGS += $(foreach includedir,$(INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(LIBRARIES),-l$(library)) + +############################################################################### +# +# Get version name and cross check +# +############################################################################### +VERFILE := gcd.c + +APPMAJOR := $(shell grep '^\#define.*MAJVERSION' $(VERFILE) | awk '{print $$3}') +APPMINOR := $(shell grep '^\#define.*MINVERSION' $(VERFILE) | awk '{print $$3}') +APPPATCH := $(shell grep '^\#define.*PATCHLEVEL' $(VERFILE) | awk '{print $$3}') +APPVERSION := $(APPMAJOR).$(APPMINOR).$(APPPATCH) + +############################################################################### +# +# Guess at the appropriate lib directory and word size +# +############################################################################### +ifeq ($(UNAME_S),Linux) + +ifeq ($(origin LIBDIR),undefined) +LIBDIR := $(shell ldd /usr/bin/make | grep '\(/libc\.\)' | sed -e 's!.*\(/.*\)/libc[.].*!\1!') +endif +ifeq ($(origin USRLIBDIR),undefined) +USRLIBDIR := $(patsubst /lib/%,/usr/lib/%,$(LIBDIR)) +endif +BUILDFOR := $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')-bit + +ifeq ($(origin CFLAGS),undefined) +ifeq ($(BUILDFOR),32-bit) +CFLAGS += -m32 +LIBDIR := /lib +USRLIBDIR := /usr/lib +else +ifeq ($(BUILDFOR),64-bit) +CFLAGS += -m64 +LIBDIR := /lib64 +USRLIBDIR := /usr/lib64 +endif +endif +endif + +else +LIBDIR := /lib +USRLIBDIR := /usr/lib +endif + + +############################################################################### +# +# Define files to be compiled +# +############################################################################### +C_SRCS := $(wildcard *.c) ../../src/jitterentropy-gcd.c +C_OBJS := ${C_SRCS:.c=.o} +C_GCOV := ${C_SRCS:.c=.gcda} +C_GCOV += ${C_SRCS:.c=.gcno} +C_GCOV += ${C_SRCS:.c=.gcov} +OBJS := $(C_OBJS) + +analyze_srcs = $(filter %.c, $(sort $(C_SRCS))) +analyze_plists = $(analyze_srcs:%.c=%.plist) + +.PHONY: all scan install clean cppcheck distclean debug asanaddress asanthread leak gcov + +all: $(NAME) + +debug: CFLAGS += -g -DDEBUG +debug: DBG-$(NAME) + +asanaddress: CFLAGS += -g -DDEBUG -fsanitize=address -fno-omit-frame-pointer +asanaddress: LDFLAGS += -fsanitize=address +asanaddress: DBG-$(NAME) + +asanthread: CFLAGS += -g -DDEBUG -fsanitize=thread -fno-omit-frame-pointer +asanthread: LDFLAGS += -fsanitize=thread +asanthread: DBG-$(NAME) + +leak: CFLAGS += -g -DDEBUG -fsanitize=leak -fno-omit-frame-pointer +leak: LDFLAGS += -fsanitize=leak +leak: DBG-$(NAME) + +# Compile for the use of GCOV +# Usage after compilation: gcov .c +gcov: CFLAGS += -g -DDEBUG -fprofile-arcs -ftest-coverage +gcov: LDFLAGS += -fprofile-arcs +gcov: DBG-$(NAME) + +############################################################################### +# +# Build the library +# +############################################################################## + +$(NAME): $(OBJS) + $(CC) -o $(NAME) $(OBJS) $(LDFLAGS) + $(STRIP) $(NAME) + +DBG-$(NAME): $(OBJS) + $(CC) -g -DDEBUG -o $(NAME) $(OBJS) $(LDFLAGS) + +$(analyze_plists): %.plist: %.c + @echo " CCSA " $@ + clang --analyze $(CFLAGS) $< -o $@ + +scan: $(analyze_plists) + +cppcheck: + cppcheck --force -q --enable=performance --enable=warning --enable=portability *.h *.c ../lib/*.c ../lib/*.h + +asm: + $(foreach b, $(C_SRCS), $(CC) $(CFLAGS) -S -fverbose-asm -o ${b:.c=.s} $(b);) + +install: + install -m 0755 $(NAME) -D -t $(DESTDIR)$(BINDIR)/ + +############################################################################### +# +# Clean +# +############################################################################### + +clean: + @- $(RM) $(OBJS) + @- $(RM) $(NAME) + @- $(RM) $(C_GCOV) + @- $(RM) *.gcov + @- $(RM) $(analyze_plists) + +distclean: clean + +############################################################################### +# +# Show variables +# +############################################################################### +show_vars: + @echo APPVERSION=$(APPVERSION) + @echo DESTDIR=$(DESTDIR) + @echo BINDIR=$(BINDIR) + @echo LIBDIR=$(LIBDIR) + @echo USRLIBDIR=$(USRLIBDIR) + @echo BUILDFOR=$(BUILDFOR) + @echo NAME=$(NAME) + @echo LDFLAGS=$(LDFLAGS) + @echo CFLAGS=$(CFLAGS) diff --git a/third_party/jitterentropy/jitterentropy-library/tests/gcd/gcd.c b/third_party/jitterentropy/jitterentropy-library/tests/gcd/gcd.c new file mode 100644 index 0000000000..94c82d827a --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/gcd/gcd.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2021 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include +#include +#include + +#include "jitterentropy-gcd.h" + +#define MAJVERSION 0 /* API / ABI incompatible changes, + * functional changes that require consumer + * to be updated (as long as this number is + * zero, the API is not considered stable + * and can change without a bump of the + * major version). */ +#define MINVERSION 1 /* API compatible, ABI may change, + * functional enhancements only, consumer + * can be left unchanged if enhancements are + * not considered. */ +#define PATCHLEVEL 0 /* API / ABI compatible, no functional + * changes, no enhancements, bug fixes + * only. */ + +#define ELEM 1000 +#define EXP_GCD 50ULL +int main(int argc, char *argv[]) +{ + uint64_t *gcd = jent_gcd_init(ELEM); + uint64_t val; + unsigned int i; + + (void)argc; + (void)argv; + + for (i = 0; i < ELEM; i++) + jent_gcd_add_value(gcd, i * EXP_GCD, i); + + if (jent_gcd_analyze(gcd, ELEM)) + return 1; + + jent_gcd_fini(gcd, ELEM); + + if (jent_gcd_get(&val)) + return 2; + + if (val != EXP_GCD) + return 3; + + return 0; +} diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/README.md b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/README.md new file mode 100644 index 0000000000..db2b0c216f --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/README.md @@ -0,0 +1,228 @@ +# Jitter RNG SP800-90B Entropy Analysis Tool + +This archive contains the SP800-90B analysis tool to be used for the Jitter RNG. +The tool set consists of the following individual tools: + +- `recording_kernelspace`: This tool is used to gather the raw entropy of + the Linux kernel space Jitter RNG. + +- `recording_userspace`: This tools is used to gather the raw entropy of + the user space Jitter RNG implementation. + +- `validation-runtime`: This tool is used to calculate the minimum entropy + values compliant to SP800-90B section 3.1.3. + +- `validation-restart`: This tool is used to calculate the minimum entropy + values for the restart test compliant to SP800-90B section 3.1.4 + +See the README files in the different subdirectories. + +# Interpretation of Results + +## Runtime Tests + +The result of the data analysis performed with `validation-runtime` contains +in the file `jent-raw-noise-0001.minentropy_FF_8bits.var.txt` at the bottom data +like the following: + +``` +H_original: 2.387470 +H_bitstring: 0.337104 + +min(H_original, 8 X H_bitstring): 2.387470 +``` + +The last value gives you the entropy estimate per time delta. That means for one +time delta the given number of entropy in bits is collected on average. + +Per default, the Jitter RNG heuristic applies 1/3 bit of entropy per +time delta. This implies that the measurement must show that *at least* 1/3 bit +of entropy is present. In the example above, the measurement shows that +2.3 bits of entropy is present which implies that the available amount of +entropy is more than what the Jitter RNG heuristic applies. + +## Restart Tests + +The results of the restart tests obtained with `validation-restart` contains +in the file `jent-raw-noise-restart-consolidated.minentropy_FF_8bits.var.txt` +at the bottom data like the following: + +``` +H_r: 0.545707 +H_c: 1.363697 +H_I: 0.333000 + +Validation Test Passed... + +min(H_r, H_c, H_I): 0.333000 +``` + +The last value gives you the entropy estimate per time delta for the restart +tests. That means for one time delta the given number of entropy in bits +collected on average. + +Per default, the Jitter RNG heuristic applies 1/3 bit of entropy per +time delta. This implies that the measurement must show that 1/3 bit +of entropy is present. Unlike with the runtime tests, the restart tests +results compares the data against the Jitter RNG's H_I value of 1/3 bits. +Thus, the value must show 1/3 bits to show that sufficient entropy is +provided. In the example above, the measurement shows that +1/3 bits of entropy is present which implies that the available amount of +entropy is more than what the Jitter RNG heuristic applies. + +# Approach to Solve Insufficient Entropy + +The Jitter RNG does not need any specific configurations or settings. However, +in case your entropy assessment shows that insufficient entropy is +present (e.g. by showing that the measured entropy rate is less than 1/3), you +can perform a search whether different memory access values gives better +entropy. + +## Tool for Searching for More Entropy + +It is possible that the the default setting of the Jitter RNG does not deliver +sufficient entropy. It is possible to adjust the memory access part of the +Jitter RNG which may deliver more entropy. + +To support analysis of insufficient entropy, the following tools are provided. +The goal of those test tools is to detect the proper memory setting that is +appropriate for your environment. One memory setting consists of two values, +one for the number of memory blocks and one for the memory block size. + +- `recording_userspace/analyze_options.sh`: This tool generates a large number + of different test results for different settings for the memory access. Simply + execute the tool without any options. A large set of different test results + directories are created. + +- `validation-runtime/analyze_options.sh`: This tool analyzes all test results + directories created by the `recording_userspace/analyze_options.sh` for + the runtime data. It generates an overview file with all test results in + `results-runtime-multi`. Analyze it and extract the memory access settings + that gives you the intended entropy rate. + +- `validation-restart/analyze_options.sh`: This tool analyzes all test results + directories created by the `recording_userspace/analyze_options.sh` for + the restart data. It generates an overview file with all test results in + `results-restart-multi`. Analyze it and extract the memory access settings + that gives you the intended entropy rate. + +After you concluded the testing you have 2 memory settings that should be +appropriate for you. As you need exactly one memory setting, analyze again +the results to detect the memory setting that gives suitable entropy rates +for both, the runtime and restart tests. + +Once you found the suitable memory setting, compile the Jitter RNG library +with the following defines: + +`CFLAGS="-DJENT_MEMORY_BLOCKS= -DJENT_MEMORY_BLOCKSIZE="` + +### Example - JENT_RANDOM_MEMACCESS not defined + +For example, the test returns the following data (this list is truncated) + +``` +Number of blocks Blocksize min entropy +64 32 0.542445 +64 64 0.232963 +64 128 0.232486 +64 256 0.231005 +64 512 0.401778 +64 1024 0.326805 +64 2048 0.319931 +64 4096 0.225761 +64 8192 0.220877 +64 16384 0.330431 +128 32 0.069033 +128 64 0.068805 +128 128 0.221863 +... +``` + +You now conclude that the following line is good for you: + +``` +64 512 0.401778 +``` + +This now implies that your CFLAGS setting for compiling the Jitter RNG is + +`CFLAGS="-DJENT_MEMORY_BLOCKS=64 -DJENT_MEMORY_BLOCKSIZE=512"` + +Note, the Jitter RNG will allocate JENT_MEMORY_BLOCKS * JENT_MEMORY_BLOCKSIZE +bytes for its memory access operation. + +### Example - JENT_RANDOM_MEMACCESS defined + +For example, the test returns the following data + +``` +Number of bits min entropy +10 0.406505 +11 0.445082 +12 0.402972 +13 0.459021 +14 0.436911 +15 0.578995 +16 0.643272 +17 0.573532 +18 0.627915 +19 0.503923 +20 0.720609 +21 1.871527 +22 2.491569 +23 2.481533 +24 2.493987 +25 2.491303 +26 2.495017 +``` + +This stack tells you in the first column the actual amount of memory requested +to be allocated by the Jitter RNG for the memory access in powers of 2 (Note, +this amount is limited by the CPU's data cache size.). The second column is what +you can ignore for this test. + +You now conclude that the following line is good for you because the measurement +shows that about 1 bit of entropy per Jitter RNG time delta is received. This +is compared with the Jitter RNG internally applied entropy rate of 1/3 bits +of entropy per time delta which means that the Jitter RNG heuristics +underestimates the available entropy - which is the result you want. + +``` +21 1.871527 +``` + +This value means that the allocated memory is 2^21 = 2MBytes. + +You now have two options how to apply this value: either recompiling the +library and use this value as the default allocation or use it as +a flags field when allocating your Jitter RNG instance which does not +need to change the binary. + +When recompiling, you need to apply the value `21` with your +CFLAGS setting for compiling the Jitter RNG like this: + +`CFLAGS="-DJENT_MEMORY_BITS=21"` + +When using the value to allocate the Jitter RNG instance when you did not +recompile the library code you specify this value when invoking +`jent_entropy_init_ex` and `jent_entropy_collector_alloc` by adding the +following to your flags field: + +``` +unsigned int flags = 0; +... +flags |= JENT_MAX_MEMSIZE_2MB; + +ret = jent_entropy_init_ex(0, flags); +... +ret = jent_entropy_collector_alloc(0, flags); +... + +``` + +Note, the Jitter RNG will allocate 1 << JENT_MEMORY_BITS +bytes for its memory access operation, but at most what +jent_cache_size_roundup() returns. + +# Author +Stephan Mueller diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/README.md b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/README.md new file mode 100644 index 0000000000..73ad49f0e6 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/README.md @@ -0,0 +1,22 @@ +# Tests of Entropy during early boot + +This test collects the first 1,001 entropy event values generated during boot +of the Linux kernel. The collection of raw entropy after reboot is compliant +to SP800-90B section 3.1.4. + +The test infrastructure sets the Linux system up to reboot the system +some 1,000 times to collect these 1,001 event values. + +# Test procedure + +See boottime_test_record.sh. + +The result is a matrix where on each line the 1,001 successive time stamps +of the interrupts for one boot operation are recorded. + +The number of lines equals to the number of reboots. + +# Test analysis + +Copy the obtained output file into results and process the result by +invoking validation-restart-*/processdata.sh. diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/boottime_test_record.service b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/boottime_test_record.service new file mode 100644 index 0000000000..91a9c57e27 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/boottime_test_record.service @@ -0,0 +1,13 @@ +# Systemd configuration file +# +[Unit] +Description=Boot time test for Kernel Jitter RNG +DefaultDependencies=no +After=local-fs.target +Before=sysinit.target + +[Service] +ExecStart=/usr/local/sbin/boottime_test_record.sh + +[Install] +WantedBy=basic.target diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/boottime_test_record.sh b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/boottime_test_record.sh new file mode 100755 index 0000000000..957fe7f6cc --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/boottime_test_record.sh @@ -0,0 +1,110 @@ +#!/bin/bash +# +# Copyright (C) 2023 - 2024, Stephan Mueller +# +# Test for analyzing the boot time entropy by power cycling the test machine +# many times and record the first time stamps. +# +# Test execution: +# 1. Enable kernel option `CONFIG_CRYPTO_JITTERENTROPY_TESTINTERFACE`, +# enable configuration option `CONFIG_CRYPTO_USER_API_RNG`, +# compile, install and reboot the kernel, and ensure that the +# Linux kernel command line contains +# `jitterentropy_rng.boot_raw_hires_test=1` +# 2. Compile getrawentropy.c and install into /usr/local/sbin +# 3. Copy this file to /usr/local/sbin and make it executable and do not +# forget restorecon if applicable +# 4. Copy boottime_test_record.service to /etc/systemd/system/ +# 5. systemctl enable boottime_test_record +# 6. reboot and wait until reboot test completes +# 7. Pick up $OUTFILE and analyze +# +# If you want to restart the test, do: +# 1. Clean out $OUTFILE +# 2. start with step 4 from above +# +# Test interruption: +# Boot with kernel command line option of boottime_test_stop. After this +# interruption, the next reboot will continue collecting data for this +# test. The interruption does not affect the test data. +# +OUTFILE="/root/jent_raw_noise_restart" +STATE="/root/jent_state" +TESTS=1000 + +# Location of libkcapi helper tool +KCAPIRNG=/usr/bin/kcapi-rng + +DIR=$(dirname $OUTFILE) +if [ ! -d "$DIR" ] +then + mkdir -p $DIR +fi + +#testruns=$(ls $OUTFILE* | wc -l | cut -d" " -f1) +testruns=$(cat $STATE) +echo $((testruns+1)) > $STATE + +#add leading zeros +# If leading zeros are missing, execute: +# for i in jent_raw_noise_restart.?.data; do mv $i $(echo $i | cut -d. -f1).0000$(echo $i | cut -d. -f2).$(echo $i | cut -d. -f3) ; done +# for i in jent_raw_noise_restart.??.data; do mv $i $(echo $i | cut -d. -f1).000$(echo $i | cut -d. -f2).$(echo $i | cut -d. -f3) ; done +# for i in jent_raw_noise_restart.???.data; do mv $i $(echo $i | cut -d. -f1).00$(echo $i | cut -d. -f2).$(echo $i | cut -d. -f3) ; done +# for i in jent_raw_noise_restart.????.data; do mv $i $(echo $i | cut -d. -f1).0$(echo $i | cut -d. -f2).$(echo $i | cut -d. -f3) ; done +printf -v testruns "%05d" $testruns + +if [ ! -x "$KCAPIRNG" ] +then + echo "Test tool $KCAPIRNG not found" > $OUTFILE.$testruns.data + echo "Test tool $KCAPIRNG not found" + testruns=$TESTS +else + ( ( /usr/local/sbin/getrawentropy -f /sys/kernel/debug/jitterentropy_testing/jent_raw_hires -s 1001 > $OUTFILE.$testruns.data ) & ) + $KCAPIRNG -n "jitterentropy_rng" -b 2000 +fi + +testruns=$((testruns+1)) +if [ $testruns -ge $TESTS ]; then + systemctl stop boottime_test_record + systemctl disable boottime_test_record + + uname -a > /root/platform.txt && + cat /proc/cpuinfo >> /root/platform.txt && + echo "" >> /root/platform.txt && + cat /proc/cpuinfo >> /root/platform.txt && + echo "" >> /root/platform.txt && + echo "lspci" >> /root/platform.txt && + lspci -vvv >> /root/platform.txt + + exit 0 +fi + +if (cat /proc/cmdline | grep -q boottime_test_stop) ; then + exit 0 +fi + +# cannot kexec in VM (corruptions) +# Here's the snipped to run the VM: +# kvm -k de -vga vmware -usbdevice tablet -name bootloop -m 768 -smp 2 \ +# -net nic,model=e1000,macaddr=00:50:45:00:34:0F -net user,hostfwd=tcp:127.0.0.1:24-:22 +# -drive file=/vm-image-bootlooptests.img,format=raw,cache=writeback -boot c +# +mount -t proc proc /proc > /dev/null 2>&1 +if ! grep hypervisor /proc/cpuinfo > /dev/null 2>&1 ; then + if [ -f /boot/vmlinuz -a -f /boot/initrd ]; then + e=$( cat /proc/cmdline) + kexec -l /boot/vmlinuz --initrd=/boot/initrd --append="$e" + fi +fi + +# With kernel 4.9, the reboot may corrupt the file system. +# Hence, the following lines. +# Note, however, that it may be neccessary to enforce disc scan with outomatic repair on every reboot. + +sync ; sync +mount -o remount,ro / + +# kexec will only return upon error, like if not set up or fail of set up. +kexec -e + +reboot -f diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/install.sh b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/install.sh new file mode 100755 index 0000000000..746dd7c23a --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_restart_kernelspace/install.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Install the linux kernel and the service running the boottime test + +# Note: restorecon is needed for Fedora +if [ ! -x /usr/local/sbin/getrawentropy ]; +then + echo "getrawentropy must be installed in /usr/local/sbin" + exit 1 +fi + +cp boottime_test_record.sh /usr/local/sbin/ && +chmod u+x /usr/local/sbin/boottime_test_record.sh && +cp boottime_test_record.service /etc/systemd/system/ && +systemctl enable boottime_test_record && +restorecon -v -R / + +echo "To improve the reboot speed change the timeout in /etc/default/grub as follows" +echo "GRUB_TIMEOUT=1" +echo "Then run grub2-mkconfig to update the grub configuration file for the new setting to take effect." diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE new file mode 100644 index 0000000000..fcd1b3c527 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE @@ -0,0 +1,33 @@ +Copyright (C) 2016 - 2024, Stephan Mueller + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, and the entire permission notice in its entirety, + including the disclaimer of warranties. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +ALTERNATIVELY, this product may be distributed under the terms of +the GNU General Public License, in which case the provisions of the GPL2 +are required INSTEAD OF the above restrictions. (This clause is +necessary due to a potential bad interaction between the GPL and +the restrictions contained in a BSD-style copyright.) + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF +WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE.bsd b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE.bsd new file mode 100644 index 0000000000..8a70427190 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE.bsd @@ -0,0 +1,26 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE.gplv2 b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE.gplv2 new file mode 100644 index 0000000000..3912109b5c --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/LICENSE.gplv2 @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/README.md b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/README.md new file mode 100644 index 0000000000..97749c5697 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/README.md @@ -0,0 +1,23 @@ +# Obtain Raw Noise Data + +This tool offers the collection of raw entropy from the running Linux +kernel Jitter RNG, compliant to SP800-90B section 3.1.3 + +To obtain raw noise data from the Jitter RNG, follow these steps: + +1. Ensure patch providing kernel Jitter RNG test interface is applied, + select `CONFIG_CRYPTO_JITTERENTROPY_TESTINTERFACE`, compile, install and + reboot the kernel - if you want to stimulate the generation of entropy + with the command below, ensure the kernel option + `CONFIG_CRYPTO_USER_API_RNG` is set to `m` or `y`. + +2. Compile getrawentropy.c as documented in that file + +3. Execute as root to obtain the raw entropy data: + `getrawentropy -f /sys/kernel/debug/jitterentropy_testing/jent_raw_hires -s 1000001 > /dev/shm/jent_raw_noise.data` + +4. In parallel to step 3, stimulate the generation of entropy, e.g. by using + the following command with a tool from libkcapi using the following command + `kcapi-rng -n "jitterentropy_rng" -b 2000000 > /dev/null` + +5. Process the obtained data with validation-runtime-kernel/processdata.sh diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/Makefile.foldtime b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/Makefile.foldtime new file mode 100644 index 0000000000..573dddd91e --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/Makefile.foldtime @@ -0,0 +1,31 @@ +# Compile Noise Source as user space application + +CC ?= gcc +override CFLAGS +=-pedantic -Wall -Wextra -DROUNDS=100000000 -O0 -Wno-long-long + +program_NAME := jitterentropy-kernel-foldtime +#program_C_SRCS := $(wildcard *.c) +program_C_SRCS := jitterentropy-foldtime.c +program_C_OBJS := ${program_C_SRCS:.c=.o} +program_OBJS := $(program_C_OBJS) + +program_INCLUDE_DIRS := +program_LIBRARY_DIRS := +program_LIBRARIES := rt + +CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(program_NAME) + +$(program_NAME): $(program_OBJS) + $(CC) $(program_OBJS) -o $(program_NAME) $(LDFLAGS) + +clean: + @- $(RM) $(program_NAME) + @- $(RM) $(program_OBJS) + +distclean: clean diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/Makefile.lfsrtime b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/Makefile.lfsrtime new file mode 100644 index 0000000000..71ace101e6 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/Makefile.lfsrtime @@ -0,0 +1,31 @@ +# Compile Noise Source as user space application + +CC ?= gcc +override CFLAGS +=-pedantic -Wall -Wextra -DROUNDS=100000000 -O0 -Wno-long-long + +program_NAME := jitterentropy-kernel-lfsrtime +#program_C_SRCS := $(wildcard *.c) +program_C_SRCS := jitterentropy-lfsrtime.c +program_C_OBJS := ${program_C_SRCS:.c=.o} +program_OBJS := $(program_C_OBJS) + +program_INCLUDE_DIRS := +program_LIBRARY_DIRS := +program_LIBRARIES := rt + +CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(program_NAME) + +$(program_NAME): $(program_OBJS) + $(CC) $(program_OBJS) -o $(program_NAME) $(LDFLAGS) + +clean: + @- $(RM) $(program_NAME) + @- $(RM) $(program_OBJS) + +distclean: clean diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/README.md b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/README.md new file mode 100644 index 0000000000..f8f0731c7a --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/README.md @@ -0,0 +1,68 @@ +# Jitter RNG Kernel Space SP800-90B Data Collector + +This tool collects the raw data used for SP800-90B analysis. I.e. the collected +raw entropy data is obtained before any post processing. + +The collected data is simply the execution time of the functions +jent_memaccess and jent_lfsrtime which both are the heart of the Jitter RNG. +The reader should understand that additional functions in the Jitter RNG +contribute to the entropy. However, this collection tool disregards them +which implies that the analysis tool already applies a worst case analysis. + +## Test Implementations + +The following test implementations are available: + +- `Makefile.foldtime`: This tool is used for Linux kernels <= 5.1 + +- `Makefile.lfsrtime`: This tools is used for Linux kernel > 5.1 + +## Getting Started + +When standard testing shall be performed, the collection of raw entropy is +performed with the script `invoke_testing.sh`. + +Before executing the script, the following files from the used Jitter RNG +noise source shall be copied into this directory: + + * crypto/jitterentropy.c + +The results are stored in `../results-measurements` which then needs to be +processed with the `validation` and `validation-restart` logic. + +Please see the caveats for obtaining Jitter RNG output below. + +## Obtain Raw Entropy + +To use the data collection tool, follow these steps: + +1. Copy the file crypto/jitterentropy.c from the kernel code into this + directory. + +2. Compile the code with the available Makefile + +3. Execute the test and collect the output + + `./jitterentropy-kernel-lfsrtime > ../validation/jent-raw-noise.data` + +or + + `./jitterentropy-kernel-foldtime > ../validation/jent-raw-noise.data` + +4. Analyze the output with the code in the validation directory + +# Obtain Jitter RNG Output + +To generate Jitter RNG output, the Linux kernel AF_ALG interface can be used. +This implies that the kcapi-rng tool from [1] must be present. + +The following invocation provides the Jitter RNG output for further analysis: + + `kcapi-rng -n "jitterentropy_rng" -b ` + +Analyze the output with the code in the validation directory. + +[1] https://www.chronox.de/libkcapi.html + +# Author +Stephan Mueller diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/invoke_testing.sh b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/invoke_testing.sh new file mode 100755 index 0000000000..7c6952ca42 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/invoke_testing.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# Directory where to store the measurements +OUTDIR="../results-measurements" + +# Maximum number of entries to be extracted from the original file +NUM_EVENTS=1000000 + +# Number of restart tests +NUM_EVENTS_RESTART=1000 +NUM_RESTART=1000 + +NONIID_RESTART_DATA="jent-raw-noise-restart" +NONIID_DATA="jent-raw-noise" +IID_DATA="jent-conditioned.data" + +initialization() +{ + if [ ! -d $OUTDIR ] + then + mkdir $OUTDIR + if [ $? -ne 0 ] + then + echo "Creation of $OUTDIR failed" + exit 1 + fi + fi + + trap "make -s -f Makefile.lfsrtime clean; exit" 0 1 2 3 15 +} + +lfsroutput() +{ + echo "Obtaining $NUM_EVENTS blocks of output from Jitter RNG" + + local kcapi="/usr/bin/kcapi-rng" + + if [ ! -x "${kcapi}" ] + then + kcapi="/usr/local/bin/kcapi-rng" + fi + + if [ ! -x "${kcapi}" ] + then + echo "Application kcapi-rng does not exist - this is needed to obtain the LFSR output data on the current system" + return + fi + + local bytes=$(($NUM_EVENTS*8)) + ${kcapi} -n "jitterentropy_rng" -b $bytes > $OUTDIR/$IID_DATA +} + +raw_entropy_restart() +{ + echo "Obtaining $NUM_RESTART raw entropy measurement with $NUM_EVENTS_RESTART restarts from Jitter RNG" + + make -s -f Makefile.lfsrtime + + ./jitterentropy-kernel-lfsrtime $NUM_EVENTS_RESTART $NUM_RESTART $OUTDIR/$NONIID_RESTART_DATA + + make -s -f Makefile.lfsrtime clean +} + +raw_entropy() +{ + echo "Obtaining $NUM_EVENTS raw entropy measurement from Jitter RNG" + + make -s -f Makefile.lfsrtime + + ./jitterentropy-kernel-lfsrtime $NUM_EVENTS 1 $OUTDIR/$NONIID_DATA + + make -s -f Makefile.lfsrtime clean +} + +initialization +lfsroutput +raw_entropy +raw_entropy_restart diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/jitterentropy-foldtime.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/jitterentropy-foldtime.c new file mode 100644 index 0000000000..4e8479af63 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/jitterentropy-foldtime.c @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#ifdef __MACH__ +#include +#include +#include +#include +#include +#endif + +#undef NULL +typedef unsigned long long __u64; + +/*************************************************************************** + * Link code for user space + ***************************************************************************/ +__u64 jent_rol64(__u64 word, unsigned int shift) +{ + return (word << shift) | (word >> (64 - shift)); +} + +void *jent_zalloc(unsigned int len) +{ + return calloc(1, len); +} + +void jent_zfree(void *ptr) +{ + free(ptr); +} + +int jent_fips_enabled(void) +{ + return 1; +} + +void jent_panic(char *s) +{ + printf("%s", s); + exit(1); +} + +void jent_memcpy(void *dest, const void *src, unsigned int n) +{ + memcpy(dest, src, n); +} + +/* taken from Linux kernel */ +#ifdef X86_64 +#define DECLARE_ARGS(val, low, high) unsigned low, high +#define EAX_EDX_VAL(val, low, high) ((low) | ((__u64)(high) << 32)) +#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) +#else +#define DECLARE_ARGS(val, low, high) unsigned long long val +#define EAX_EDX_VAL(val, low, high) (val) +#define EAX_EDX_RET(val, low, high) "=A" (val) +#endif + +/* + * Obtain a high-resolution time stamp value. The time stamp is used to measure + * the execution time of a given code path and its variations. Hence, the time + * stamp must have a sufficiently high resolution. + * + * Note, if the function returns zero because a given architecture does not + * implement a high-resolution time stamp, the RNG code's runtime test + * will detect it and will not produce output. + */ +void jent_get_nstime(__u64 *out) +{ + /* OSX does not have clock_gettime -- taken from + * http://developer.apple.com/library/mac/qa/qa1398/_index.html */ +#ifdef __MACH__ + *out = mach_absolute_time(); + +#elif _AIX + /* clock_gettime() on AIX returns a timer value that increments in + * steps of 1000 + */ + uint64_t tmp = 0; + timebasestruct_t aixtime; + read_real_time(&aixtime, TIMEBASE_SZ); + tmp = aixtime.tb_high; + tmp = tmp << 32; + tmp = tmp | aixtime.tb_low; + *out = tmp; + +#elif (defined(__i386__) || defined(__x86_64__)) + DECLARE_ARGS(val, low, high); + asm volatile("rdtsc" : EAX_EDX_RET(val, low, high)); + *out = EAX_EDX_VAL(val, low, high); + +#else + /* we could use CLOCK_MONOTONIC(_RAW), but with CLOCK_REALTIME + * we get some nice extra entropy once in a while from the NTP actions + * that we want to use as well... though, we do not rely on that + * extra little entropy */ + uint64_t tmp = 0; + struct timespec time; + if (clock_gettime(CLOCK_REALTIME, &time) == 0) + { + tmp = time.tv_sec; + tmp = tmp << 32; + tmp = tmp | time.tv_nsec; + } + *out = tmp; +#endif +} + +/*************************************************************************** + * Include Jitter RNG code + ***************************************************************************/ + +#include "jitterentropy.c" + +/*************************************************************************** + * Statistical test logic not compiled for regular operation + ***************************************************************************/ +/* + * Statistical test: return the time duration for the folding operation. If min + * is set, perform the given number of LFSR ops. Otherwise, allow the + * loop count shuffling to define the number of LFSR ops. + */ +static +uint64_t jent_fold_var_stat(struct rand_data *ec, unsigned int min) +{ + __u64 time = 0; + __u64 time2 = 0; + __u64 data = 0; + + jent_get_nstime(&time); + jent_memaccess(ec, min); + jent_fold_time(ec, time, &data, min); + jent_get_nstime(&time2); + return ((time2 - time)); +} + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; +#ifdef ROUNDS + size_t size = 0; + struct rand_data *ec; + + ec = jent_entropy_collector_alloc(0, 0); + if(!ec) + return 1; + + while(size < ROUNDS) +#else + while(1) +#endif + { + uint64_t duration = 0; + uint64_t duration_min = 0; + /* When enabling the for loops, you effectively get a cache + * and TLB flush -- but tests show that flushing the cache + * does not change the results, considering that you want to + * remove the outliers from the dataset before processing it + * as you do not want to have measurements based interferred + * by interrupts, etc. + */ +/* int i = 0; + for(i=0; i<1000; i++) */ +/* mb(); */ + duration = jent_fold_var_stat(ec, 0); +/* mb(); */ +/* for(i=0; i<1000; i++) */ + duration_min = jent_fold_var_stat(ec, 1); +/* mb(); */ + printf("%lu %lu\n", duration, duration_min); +#ifdef ROUNDS + size++; +#endif + } + + return 0; +} + diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/jitterentropy-lfsrtime.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/jitterentropy-lfsrtime.c new file mode 100644 index 0000000000..06571f9f7a --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/attic/jitterentropy-lfsrtime.c @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __MACH__ +#include +#include +#include +#include +#include +#endif + +#undef NULL +typedef unsigned long long __u64; + +/*************************************************************************** + * Link code for user space + ***************************************************************************/ + +void *jent_zalloc(unsigned int len) +{ + return calloc(1, len); +} + +void jent_zfree(void *ptr) +{ + free(ptr); +} + +int jent_fips_enabled(void) +{ + /* Enable full SP800-90B health test handling */ + return 1; +} + +void jent_panic(char *s) +{ + printf("%s", s); + exit(1); +} + +void jent_memcpy(void *dest, const void *src, unsigned int n) +{ + memcpy(dest, src, n); +} + +/* taken from Linux kernel */ +#ifdef X86_64 +#define DECLARE_ARGS(val, low, high) unsigned low, high +#define EAX_EDX_VAL(val, low, high) ((low) | ((__u64)(high) << 32)) +#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) +#else +#define DECLARE_ARGS(val, low, high) unsigned long long val +#define EAX_EDX_VAL(val, low, high) (val) +#define EAX_EDX_RET(val, low, high) "=A" (val) +#endif + +/* + * Obtain a high-resolution time stamp value. The time stamp is used to measure + * the execution time of a given code path and its variations. Hence, the time + * stamp must have a sufficiently high resolution. + * + * Note, if the function returns zero because a given architecture does not + * implement a high-resolution time stamp, the RNG code's runtime test + * will detect it and will not produce output. + */ +void jent_get_nstime(__u64 *out) +{ + /* OSX does not have clock_gettime -- taken from + * http://developer.apple.com/library/mac/qa/qa1398/_index.html */ +#ifdef __MACH__ + *out = mach_absolute_time(); + +#elif _AIX + /* clock_gettime() on AIX returns a timer value that increments in + * steps of 1000 + */ + uint64_t tmp = 0; + timebasestruct_t aixtime; + read_real_time(&aixtime, TIMEBASE_SZ); + tmp = aixtime.tb_high; + tmp = tmp << 32; + tmp = tmp | aixtime.tb_low; + *out = tmp; + +#elif (defined(__i386__) || defined(__x86_64__)) + DECLARE_ARGS(val, low, high); + asm volatile("rdtsc" : EAX_EDX_RET(val, low, high)); + *out = EAX_EDX_VAL(val, low, high); + +#else + /* we could use CLOCK_MONOTONIC(_RAW), but with CLOCK_REALTIME + * we get some nice extra entropy once in a while from the NTP actions + * that we want to use as well... though, we do not rely on that + * extra little entropy */ + uint64_t tmp = 0; + struct timespec time; + if (clock_gettime(CLOCK_REALTIME, &time) == 0) + { + tmp = time.tv_sec; + tmp = tmp << 32; + tmp = tmp | time.tv_nsec; + } + *out = tmp; +#endif +} + +/*************************************************************************** + * Include Jitter RNG code + ***************************************************************************/ + +#include "jitterentropy.c" + +/*************************************************************************** + * Statistical test logic not compiled for regular operation + ***************************************************************************/ +/* + * Statistical test: return the time duration for the folding operation. If min + * is set, perform the given number of LFSR ops. Otherwise, allow the + * loop count shuffling to define the number of LFSR ops. + */ +static +uint64_t jent_lfsr_var_stat(struct rand_data *ec, unsigned int min) +{ + __u64 time = 0; + __u64 time2 = 0; + + jent_get_nstime(&time); + jent_memaccess(ec, min); + jent_lfsr_time(ec, time, min, 0); + jent_get_nstime(&time2); + return ((time2 - time)); +} + +static int jent_one_test(const char *pathname, unsigned long rounds) +{ + unsigned long size = 0; + struct rand_data *ec; + FILE *out = NULL; + int ret = 0; + + printf("Processing %s\n", pathname); + + out = fopen(pathname, "w"); + if (!out) { + ret = 1; + goto out; + } + + ec = jent_entropy_collector_alloc(0, 0); + if(!ec) { + ret = 1; + goto out; + } + + for (size = 0; size < rounds; size++) { + uint64_t duration = 0; + uint64_t duration_min = 0; + + duration = jent_lfsr_var_stat(ec, 0); + duration_min = jent_lfsr_var_stat(ec, 1); + fprintf(out, "%lu %lu\n", duration, duration_min); + } + +out: + if (out) + fclose(out); + + return ret; +} + +/* + * Invoke the application with + * argv[1]: number of raw entropy measurements to be obtained for one + * entropy collector instance. + * argv[2]: number of test repetitions with a new entropy estimator + * allocated for each round - this satisfies the restart tests + * defined in SP800-90B section 3.1.4.3 and FIPS IG 7.18. + * argv[3]: File name of the output data + */ +int main(int argc, char * argv[]) +{ + unsigned long i, rounds, repeats; + int ret; + char pathname[4096]; + + if (argc != 4) { + printf("%s \n", argv[0]); + return 1; + } + + rounds = strtoul(argv[1], NULL, 10); + if (rounds >= UINT_MAX) + return 1; + + repeats = strtoul(argv[2], NULL, 10); + if (repeats >= UINT_MAX) + return 1; + + for (i = 1; i <= repeats; i++) { + snprintf(pathname, sizeof(pathname), "%s-%.4lu.data", argv[3], + i); + ret = jent_one_test(pathname, rounds); + if (ret) + return ret; + } + + return 0; +} diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/getrawentropy.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/getrawentropy.c new file mode 100644 index 0000000000..4849b5b1a8 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_runtime_kernelspace/getrawentropy.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* + * Compile: + * gcc -Wall -pedantic -Wextra -o getrawentropy getrawentropy.c + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RAWENTROPY_SAMPLES 1000 +#define DEBUGFS_INTERFACE "/sys/kernel/debug/jitterentropy_testing/jent_raw_hires" + +struct opts { + size_t samples; + char *debugfs_file; +}; + +static int getrawentropy(struct opts *opts) +{ +#define BUFFER_SIZE (RAWENTROPY_SAMPLES * sizeof(uint32_t)) + uint32_t requested = opts->samples * sizeof(uint32_t); + uint8_t *buffer_p, buffer[BUFFER_SIZE]; + ssize_t ret; + int fd = -1; + + fd = open(opts->debugfs_file, O_RDONLY); + if (fd < 0) + return errno; + + while (requested) { + unsigned int i; + unsigned int gather = ((BUFFER_SIZE > requested) ? + requested : BUFFER_SIZE); + + buffer_p = buffer; + + ret = read(fd, buffer_p, gather); + if (ret < 0) { + ret = -errno; + goto out; + } + + for (i = 0; i < ret / (sizeof(uint32_t)); i++) { + uint32_t val; + + memcpy(&val, buffer_p, sizeof(uint32_t)); + printf("%u\n", val); + buffer_p += sizeof(uint32_t); + } + + requested -= ret; + } + + ret = 0; + +out: + if (fd >= 0) + close(fd); + + return (int)ret; +} + +int main(int argc, char *argv[]) +{ + struct opts opts; + int c = 0; + + opts.samples = RAWENTROPY_SAMPLES; + opts.debugfs_file = DEBUGFS_INTERFACE; + + while (1) + { + int opt_index = 0; + static struct option options[] = + { + {"samples", required_argument, 0, 's'}, + {"debugfs-file", required_argument, 0, 'f'}, + {0, 0, 0, 0} + }; + c = getopt_long(argc, argv, "f:s:", options, &opt_index); + if (c == -1) + break; + switch (c) { + case 0: + switch (opt_index) { + case 0: + opts.samples = strtoul(optarg, NULL, 10); + if (opts.samples == ULONG_MAX) + return -EINVAL; + break; + case 1: + opts.debugfs_file = optarg; + break; + } + break; + + case 's': + opts.samples = strtoul(optarg, NULL, 10); + if (opts.samples == ULONG_MAX) + return -EINVAL; + break; + case 'f': + opts.debugfs_file = optarg; + break; + default: + return -EINVAL; + } + } + + return getrawentropy(&opts); +} diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/CMakeLists.txt b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/CMakeLists.txt new file mode 100644 index 0000000000..13d02c0bd4 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.14) + +project(jitterentropy C) +set(CMAKE_C_STANDARD 99) + +function(testprogram name) + add_executable(${name} ${name}.c) + target_link_libraries(${name} ${PROJECT_NAME}) + target_link_directories(${name} PUBLIC + $) + target_include_directories(${name} PUBLIC + $ + $) + if(NOT MSVC) + target_compile_options(${name} PRIVATE -Wno-unused-parameter) + endif() + include(GNUInstallDirs) + install(TARGETS ${name}) +endfunction() + +testprogram(jitterentropy-hashtime) diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE new file mode 100644 index 0000000000..fcd1b3c527 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE @@ -0,0 +1,33 @@ +Copyright (C) 2016 - 2024, Stephan Mueller + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, and the entire permission notice in its entirety, + including the disclaimer of warranties. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +ALTERNATIVELY, this product may be distributed under the terms of +the GNU General Public License, in which case the provisions of the GPL2 +are required INSTEAD OF the above restrictions. (This clause is +necessary due to a potential bad interaction between the GPL and +the restrictions contained in a BSD-style copyright.) + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF +WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE.bsd b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE.bsd new file mode 100644 index 0000000000..8a70427190 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE.bsd @@ -0,0 +1,26 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE.gplv2 b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE.gplv2 new file mode 100644 index 0000000000..3912109b5c --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/LICENSE.gplv2 @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.foldtime b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.foldtime new file mode 100644 index 0000000000..bd2dffda23 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.foldtime @@ -0,0 +1,33 @@ +# Compile Noise Source as user space application + +CC ?= gcc +override CFLAGS +=-pedantic -Wall -DCONFIG_CRYPTO_CPU_JITTERENTROPY_STAT -DROUNDS=10000000 -I../../ -O0 -Wno-long-long + +program_NAME := jitterentropy-foldtime +#program_C_SRCS := $(wildcard *.c) +program_C_SRCS := jitterentropy-base.c jitterentropy-foldtime.c jitterentropy-stat.c +program_C_OBJS := ${program_C_SRCS:.c=.o} +program_OBJS := $(program_C_OBJS) + +program_INCLUDE_DIRS := +program_LIBRARY_DIRS := +ifneq (Darwin,$(shell uname)) +program_LIBRARIES := rt +endif + +CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(program_NAME) + +$(program_NAME): $(program_OBJS) + $(CC) $(program_OBJS) -o $(program_NAME) $(LDFLAGS) + +clean: + @- $(RM) $(program_NAME) + @- $(RM) $(program_OBJS) + +distclean: clean diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.hashtime b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.hashtime new file mode 100644 index 0000000000..ae599ee284 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.hashtime @@ -0,0 +1,58 @@ +# Compile Noise Source as user space application + +CC ?= gcc +CFLAGS +=-Wextra -Wall -pedantic -fPIC -O0 +#Hardening +CFLAGS +=-fwrapv --param ssp-buffer-size=4 -fvisibility=hidden -fPIE -Wcast-align -Wmissing-field-initializers -Wshadow -Wswitch-enum +ifneq (Darwin,$(shell uname)) +LDFLAGS +=-Wl,-z,relro,-z,now +endif + +# Enable internal timer support +CFLAGS += -DJENT_CONF_ENABLE_INTERNAL_TIMER + +GCCVERSIONFORMAT := $(shell echo `$(CC) -dumpversion | sed 's/\./\n/g' | wc -l`) +ifeq "$(GCCVERSIONFORMAT)" "3" + GCC_GTEQ_490 := $(shell expr `$(CC) -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/'` \>= 40900) +else + GCC_GTEQ_490 := $(shell expr `$(CC) -dumpfullversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/'` \>= 40900) +endif + +ifeq "$(GCC_GTEQ_490)" "1" + CFLAGS += -fstack-protector-strong +else + CFLAGS += -fstack-protector-all +endif + +JENT_DIR := jitterentropy + +program_NAME := jitterentropy-hashtime +#program_C_SRCS := $(wildcard *.c) +program_C_SRCS := jitterentropy-hashtime.c +program_C_OBJS := ${program_C_SRCS:.c=.o} +program_OBJS := $(program_C_OBJS) + +program_INCLUDE_DIRS := $(JENT_DIR) $(JENT_DIR)/src +program_LIBRARY_DIRS := +ifeq (Darwin,$(shell uname)) +program_LIBRARIES := pthread +else +program_LIBRARIES := rt pthread +endif + +CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(program_NAME) + +$(program_NAME): $(program_OBJS) + $(CC) $(program_OBJS) -o $(program_NAME) $(LDFLAGS) + +clean: + @- $(RM) $(program_NAME) + @- $(RM) $(program_OBJS) + +distclean: clean diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.lfsrtime b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.lfsrtime new file mode 100644 index 0000000000..3fcf39c037 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.lfsrtime @@ -0,0 +1,40 @@ +# Compile Noise Source as user space application + +CC ?= gcc +CFLAGS +=-Wextra -Wall -pedantic -fPIC -O0 +#Hardening +CFLAGS +=-fstack-protector-all -fwrapv --param ssp-buffer-size=4 +ifneq (Darwin,$(shell uname)) +LDFLAGS +=-Wl,-z,relro,-z,now +endif + +program_NAME := jitterentropy-lfsrtime +#program_C_SRCS := $(wildcard *.c) +program_C_SRCS := jitterentropy-lfsrtime.c +program_C_OBJS := ${program_C_SRCS:.c=.o} +program_OBJS := $(program_C_OBJS) + +program_INCLUDE_DIRS := +program_LIBRARY_DIRS := +ifeq (Darwin,$(shell uname)) +program_LIBRARIES := pthread +else +program_LIBRARIES := rt pthread +endif + +CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(program_NAME) + +$(program_NAME): $(program_OBJS) + $(CC) $(program_OBJS) -o $(program_NAME) $(LDFLAGS) + +clean: + @- $(RM) $(program_NAME) + @- $(RM) $(program_OBJS) + +distclean: clean diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.osr b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.osr new file mode 100644 index 0000000000..704af03dab --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.osr @@ -0,0 +1,49 @@ +# Compile Noise Source as user space application + +CC ?= gcc +CFLAGS +=-Wextra -Wall -pedantic -fPIC -O0 -DCONFIG_CRYPTO_CPU_JITTERENTROPY_SECURE_MEMORY +#Hardening +CFLAGS +=-fwrapv --param ssp-buffer-size=4 +LDFLAGS +=-Wl,-z,relro,-z,now -lm + +GCCVERSIONFORMAT := $(shell echo `$(CC) -dumpversion | sed 's/\./\n/g' | wc -l`) +ifeq "$(GCCVERSIONFORMAT)" "3" + GCC_GTEQ_490 := $(shell expr `$(CC) -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/'` \>= 40900) +else + GCC_GTEQ_490 := $(shell expr `$(CC) -dumpfullversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/'` \>= 40900) +endif + +ifeq "$(GCC_GTEQ_490)" "1" + CFLAGS += -fstack-protector-strong +else + CFLAGS += -fstack-protector-all +endif + +JENT_DIR := jitterentropy +JENT_SRCS := $(wildcard $(JENT_DIR)/src/*.c) + +NAME := jitterentropy-osr +C_SRCS := $(JENT_SRCS) jitterentropy-osr.c +C_OBJS := ${C_SRCS:.c=.o} +OBJS := $(C_OBJS) + +INCLUDE_DIRS := $(JENT_DIR) $(JENT_DIR)/src +LIBRARY_DIRS := +LIBRARIES := rt pthread + +CFLAGS += $(foreach includedir,$(INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(NAME) + +$(NAME): $(OBJS) + $(CC) $(OBJS) -o $(NAME) $(LDFLAGS) + +clean: + @- $(RM) $(NAME) + @- $(RM) $(OBJS) + +distclean: clean diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.rng b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.rng new file mode 100644 index 0000000000..5903389aaf --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/Makefile.rng @@ -0,0 +1,51 @@ +# Compile Noise Source as user space application + +CC ?= gcc +CFLAGS +=-Wextra -Wall -pedantic -fPIC -O0 -DCONFIG_CRYPTO_CPU_JITTERENTROPY_SECURE_MEMORY +#Hardening +CFLAGS +=-fwrapv --param ssp-buffer-size=4 +ifneq (Darwin,$(shell uname)) +LDFLAGS +=-Wl,-z,relro,-z,now +endif + +GCCVERSIONFORMAT := $(shell echo `$(CC) -dumpversion | sed 's/\./\n/g' | wc -l`) +ifeq "$(GCCVERSIONFORMAT)" "3" + GCC_GTEQ_490 := $(shell expr `$(CC) -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/'` \>= 40900) +else + GCC_GTEQ_490 := $(shell expr `$(CC) -dumpfullversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/'` \>= 40900) +endif + +ifeq "$(GCC_GTEQ_490)" "1" + CFLAGS += -fstack-protector-strong +else + CFLAGS += -fstack-protector-all +endif + +JENT_DIR := jitterentropy +JENT_SRCS := $(wildcard $(JENT_DIR)/src/*.c) + +NAME := jitterentropy-rng +C_SRCS := $(JENT_SRCS) jitterentropy-rng.c +C_OBJS := ${C_SRCS:.c=.o} +OBJS := $(C_OBJS) + +INCLUDE_DIRS := $(JENT_DIR) $(JENT_DIR)/src +LIBRARY_DIRS := +LIBRARIES := rt pthread + +CFLAGS += $(foreach includedir,$(INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(NAME) + +$(NAME): $(OBJS) + $(CC) $(OBJS) -o $(NAME) $(LDFLAGS) + +clean: + @- $(RM) $(NAME) + @- $(RM) $(OBJS) + +distclean: clean diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/README.md b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/README.md new file mode 100644 index 0000000000..ac59089eb8 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/README.md @@ -0,0 +1,95 @@ +# 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`. + +Before executing the script, the following files from the used Jitter RNG +noise source shall be copied into this directory: + + * jitterentropy-base.c + + * jitterentropy.h + + * jitterentropy-base-user.h + +The results are stored in `../results-measurements` which then needs to be +processed with the `validation-runtime` and `validation-restart` logic. + +## 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 1.x and older: make -f Makefile.foldtime + + * Jitter RNG 2.x: make -f Makefile.lfsrtime + + * Jitter RNG 3.x: make -f Makefile.hashtime + +The test is now invoked with the following command: + + * Jitter RNG 1.x and older: + + ./jitterentropy-foldtime > /dev/shm/jent-raw.data + + * Jitter RNG 2.x: + + ./jitterentropy-lfsrtime > /dev/shm/jent-raw.data + + * 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 recording program collects two sets of sample of time deltas obtained +from the Jitter RNG: + + * var: this is the normal behavior of the Jitter RNG. The time delta + is not only used to feed the pool, but also to determine the + number of LFSR operations (1 to 15 in the current configuration) + that will be performed before returning each bit to the pool. + The different number of cycles used on each bit produce + variations in the memory access time, increasing the entropy of + the noise source. + + * single: in this case, there is only one cycle of LFSR operations per + bit. This is the worst case scenario forced by the recording + program in order to have the lowest minimum entropy estimation. + +The program is compiled to collect two samples of 10000000 events each (see +the ROUNDS parameter in Makefile). The file contains one line per item, each +line contains two decimal numbers: the first is for the var noise source, +the second for the single noise source. + diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/analyze_options.sh b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/analyze_options.sh new file mode 100755 index 0000000000..9a8e22425e --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/analyze_options.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# +# Tool to generate test results for various Jitter RNG memory settings +# +# This tool is only needed if you have insufficient entropy. See ../README.md +# for details +# + +OUTDIR="../results-measurements" + +if (grep JENT_RANDOM_MEMACCESS ../../../jitterentropy.h | head -n 1 | grep -q define) +then + for bits in 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + do + export CFLAGS="-DJENT_MEMORY_BITS=$bits" + + ./invoke_testing.sh + + mv $OUTDIR $OUTDIR-random_memaccess-${bits}bits + + done +else + + for memsize in 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864 134217728 268435456 536870912 + do + for blocks in 64 128 256 512 1024 2048 4096 8192 16384 + do + for blocksize in 32 64 128 256 512 1024 2048 4096 8192 16384 + do + export CFLAGS="-DJENT_MEMORY_BLOCKS=$blocks -DJENT_MEMORY_BLOCKSIZE=$blocksize -DJENT_MEMORY_SIZE=$memsize" + + ./invoke_testing.sh + + mv $OUTDIR $OUTDIR-${blocks}blocks-${blocksize}blocksize-${memsize}bytes + done + done + done +fi diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/invoke_testing.sh b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/invoke_testing.sh new file mode 100755 index 0000000000..540a161ddb --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/invoke_testing.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +# Directory where to store the measurements +OUTDIR="../results-measurements" + +# Maximum number of entries to be extracted from the original file +NUM_EVENTS=1000000 + +# Number of restart tests +NUM_EVENTS_RESTART=1000 +NUM_RESTART=1000 + +NONIID_RESTART_DATA="jent-raw-noise-restart" +NONIID_DATA="jent-raw-noise" +IID_DATA="jent-conditioned.data" + +# Define the maximum memory size +# 0 -> use default +# 1 -> JENT_MAX_MEMSIZE_32kB +# ... +# 15 -> JENT_MAX_MEMSIZE_512MB +MAX_MEMORY_SIZE=0 + +# If this variable is set to any value, the timer-less entropy source +# is forced and tested +FORCE_NOTIME_NOISE_SOURCE="" + +initialization() +{ + if [ ! -d $OUTDIR ] + then + mkdir $OUTDIR + if [ $? -ne 0 ] + then + echo "Creation of $OUTDIR failed" + exit 1 + fi + fi + + trap "make -s -f Makefile.rng clean; make -s -f Makefile.hashtime clean; exit" 0 1 2 3 15 +} + +lfsroutput() +{ + echo "Obtaining $NUM_EVENTS blocks of output from Jitter RNG" + + make -s -f Makefile.rng + + local cmdopts="--max-mem $MAX_MEMORY_SIZE" + + if [ -n "$FORCE_NOTIME_NOISE_SOURCE" ] + then + cmdopts="$cmdopts --disable-internal-timer" + fi + + ./jitterentropy-rng $NUM_EVENTS $cmdopts > $OUTDIR/$IID_DATA + + make -s -f Makefile.rng clean +} + +raw_entropy_restart() +{ + echo "Obtaining $NUM_RESTART raw entropy measurement with $NUM_EVENTS_RESTART restarts from Jitter RNG" + + make -s -f Makefile.hashtime + + ./jitterentropy-hashtime $NUM_EVENTS_RESTART $NUM_RESTART $OUTDIR/$NONIID_RESTART_DATA $MAX_MEMORY_SIZE $FORCE_NOTIME_NOISE_SOURCE + + make -s -f Makefile.hashtime clean +} + +raw_entropy() +{ + echo "Obtaining $NUM_EVENTS raw entropy measurement from Jitter RNG" + + make -s -f Makefile.hashtime + + ./jitterentropy-hashtime $NUM_EVENTS 1 $OUTDIR/$NONIID_DATA $MAX_MEMORY_SIZE $FORCE_NOTIME_NOISE_SOURCE + + make -s -f Makefile.hashtime clean +} + +initialization +#lfsroutput +raw_entropy +raw_entropy_restart diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy new file mode 160000 index 0000000000..16c9e5c93e --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy @@ -0,0 +1 @@ +Subproject commit 16c9e5c93e614f0df25f1cb30d0730102e6f4e41 diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-foldtime.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-foldtime.c new file mode 100644 index 0000000000..c144f4bf3a --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-foldtime.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include +#include +#include + +#include "jitterentropy.h" +#ifndef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT +#error This program is meaningless without CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT +#endif + +int main(int argc, char * argv[]) +{ +#ifdef ROUNDS + size_t size = 0; + struct rand_data *ec; + + ec = jent_entropy_collector_alloc(0, 0); + if(!ec) + return 1; + + while(size < ROUNDS) +#else + while(1) +#endif + { + __u64 duration = 0; + __u64 duration_min = 0; + /* When enabling the for loops, you effectively get a cache + * and TLB flush -- but tests show that flushing the cache + * does not change the results, considering that you want to + * remove the outliers from the dataset before processing it + * as you do not want to have measurements based interferred + * by interrupts, etc. + */ +/* int i = 0; + for(i=0; i<1000; i++) */ +/* mb(); */ + duration = jent_fold_var_stat(ec, 0); +/* mb(); */ +/* for(i=0; i<1000; i++) */ + duration_min = jent_fold_var_stat(ec, 1); +/* mb(); */ + printf("%llu %llu\n", duration, duration_min); +#ifdef ROUNDS + size++; +#endif + } + + return 0; +} + diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-hashtime.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-hashtime.c new file mode 100644 index 0000000000..10d9d01398 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-hashtime.c @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "jitterentropy-sha3.c" +#include "jitterentropy-gcd.c" +#include "jitterentropy-health.c" +#include "jitterentropy-noise.c" +#include "jitterentropy-timer.c" +#include "jitterentropy-base.c" + +#ifndef REPORT_COUNTER_TICKS +#define REPORT_COUNTER_TICKS 1 +#endif + +/*************************************************************************** + * Statistical test logic not compiled for regular operation + ***************************************************************************/ +static int jent_one_test(const char *pathname, unsigned long rounds, + unsigned int flags, int report_counter_ticks) +{ + unsigned long size = 0; + struct rand_data *ec = NULL; + uint64_t *duration; +#ifdef JENT_CONF_DISABLE_LOOP_SHUFFLE + #ifdef JENT_TEST_BINARY_OUTPUT + size_t recordsWritten; + #endif +#else + struct rand_data *ec_min = NULL; + uint64_t *duration_min; +#endif + + FILE *out = NULL; + int ret = 0; + unsigned int health_test_result; + + duration = calloc(rounds, sizeof(uint64_t)); + if (!duration) + return 1; + +#ifndef JENT_CONF_DISABLE_LOOP_SHUFFLE + duration_min = calloc(rounds, sizeof(uint64_t)); + if (!duration_min) { + free(duration); + return 1; + } +#endif + + printf("Processing %s\n", pathname); + + out = fopen(pathname, "w"); + if (!out) { + ret = 1; + goto out; + } + + ret = jent_entropy_init(); + if (ret) { + printf("The initialization failed with error code %d\n", ret); + goto out; + } + ec = jent_entropy_collector_alloc(0, flags); + if (!ec) { + ret = 1; + goto out; + } + +#ifndef JENT_CONF_DISABLE_LOOP_SHUFFLE + ec_min = jent_entropy_collector_alloc(0, flags); + if (!ec_min) { + ret = 1; + goto out; + } +#endif + + if (!report_counter_ticks) { + /* + * For this analysis, we want the raw values, not values that + * have had common factors removed. + */ + ec->jent_common_timer_gcd = 1; + +#ifndef JENT_CONF_DISABLE_LOOP_SHUFFLE + ec_min->jent_common_timer_gcd = 1; +#endif + } + + if (ec->enable_notime) { + jent_notime_settick(ec); +#ifndef JENT_CONF_DISABLE_LOOP_SHUFFLE + jent_notime_settick(ec_min); +#endif + } + + /* Enable full SP800-90B health test handling */ + ec->fips_enabled = 1; +#ifndef JENT_CONF_DISABLE_LOOP_SHUFFLE + ec_min->fips_enabled = 1; +#endif + +#ifdef JENT_RANDOM_MEMACCESS + /* Print the size of the memory region. */ + printf("Memory size: %" PRIu32 "\n", ec->memmask + 1); +#endif + + + /* Prime the test */ + jent_measure_jitter(ec, 0, NULL); + for (size = 0; size < rounds; size++) { + /* Disregard stuck indicator */ + jent_measure_jitter(ec, 0, &duration[size]); + } + +#ifndef JENT_CONF_DISABLE_LOOP_SHUFFLE + jent_measure_jitter(ec_min, 0, NULL); + for (size = 0; size < rounds; size++) { + /* Disregard stuck indicator */ + jent_measure_jitter(ec_min, 1, &duration_min[size]); + } +#endif + + +#ifdef JENT_CONF_DISABLE_LOOP_SHUFFLE + #ifdef JENT_TEST_BINARY_OUTPUT + recordsWritten = fwrite(duration, sizeof(uint64_t), rounds, out); + if(recordsWritten != rounds) fprintf(stderr, "Can't output data.\n"); + #else + for (size = 0; size < rounds; size++) + fprintf(out, "%" PRIu64 "\n", duration[size]); + #endif +#else + for (size = 0; size < rounds; size++) + fprintf(out, "%" PRIu64 " %" PRIu64 "\n", duration[size], duration_min[size]); +#endif + + if ((health_test_result = jent_health_failure(ec))) { + printf("The main context encountered the following health testing failure(s):"); + if (health_test_result & JENT_RCT_FAILURE) printf(" RCT"); + if (health_test_result & JENT_APT_FAILURE) printf(" APT"); + if (health_test_result & JENT_LAG_FAILURE) printf(" Lag"); + printf("\n"); + } + +#ifndef JENT_CONF_DISABLE_LOOP_SHUFFLE + if ((health_test_result = jent_health_failure(ec_min))) { + printf("The minimum context encountered the following health testing failure(s):"); + if (health_test_result & JENT_RCT_FAILURE) printf(" RCT"); + if (health_test_result & JENT_APT_FAILURE) printf(" APT"); + if (health_test_result & JENT_LAG_FAILURE) printf(" Lag"); + printf("\n"); + } +#endif + +out: + free(duration); +#ifndef JENT_CONF_DISABLE_LOOP_SHUFFLE + free(duration_min); +#endif + if (flags & JENT_FORCE_INTERNAL_TIMER) { + if (ec) + jent_notime_unsettick(ec); +#ifndef JENT_CONF_DISABLE_LOOP_SHUFFLE + if (ec_min) + jent_notime_unsettick(ec_min); +#endif + } + if (out) + fclose(out); + + if (ec) + jent_entropy_collector_free(ec); +#ifndef JENT_CONF_DISABLE_LOOP_SHUFFLE + if (ec_min) + jent_entropy_collector_free(ec_min); +#endif + + return ret; +} + +/* + * Invoke the application with + * argv[1]: number of raw entropy measurements to be obtained for one + * entropy collector instance. + * argv[2]: number of test repetitions with a new entropy estimator + * allocated for each round - this satisfies the restart tests + * defined in SP800-90B section 3.1.4.3 and FIPS IG 7.18. + * argv[3]: File name of the output data + */ +int main(int argc, char * argv[]) +{ + unsigned long i, rounds, repeats; + unsigned int flags = 0; + int ret; + char pathname[4096]; + + if (argc != 4 && argc != 5 && argc != 6) { + printf("%s \n", argv[0]); + return 1; + } + + rounds = strtoul(argv[1], NULL, 10); + if (rounds >= UINT_MAX) + return 1; + + repeats = strtoul(argv[2], NULL, 10); + if (repeats >= UINT_MAX) + return 1; + + if (argc >= 5) { + unsigned long val = strtoul(argv[4], NULL, 10); + + switch (val) { + case 0: + /* Allow to set no option */ + break; + case 1: + flags |= JENT_MAX_MEMSIZE_32kB; + break; + case 2: + flags |= JENT_MAX_MEMSIZE_64kB; + break; + case 3: + flags |= JENT_MAX_MEMSIZE_128kB; + break; + case 4: + flags |= JENT_MAX_MEMSIZE_256kB; + break; + case 5: + flags |= JENT_MAX_MEMSIZE_512kB; + break; + case 6: + flags |= JENT_MAX_MEMSIZE_1MB; + break; + case 7: + flags |= JENT_MAX_MEMSIZE_2MB; + break; + case 8: + flags |= JENT_MAX_MEMSIZE_4MB; + break; + case 9: + flags |= JENT_MAX_MEMSIZE_8MB; + break; + case 10: + flags |= JENT_MAX_MEMSIZE_16MB; + break; + case 11: + flags |= JENT_MAX_MEMSIZE_32MB; + break; + case 12: + flags |= JENT_MAX_MEMSIZE_64MB; + break; + case 13: + flags |= JENT_MAX_MEMSIZE_128MB; + break; + case 14: + flags |= JENT_MAX_MEMSIZE_256MB; + break; + case 15: + flags |= JENT_MAX_MEMSIZE_512MB; + break; + default: + printf("Unknown maximum memory value\n"); + return 1; + } + } + + if (argc == 6) + flags |= JENT_FORCE_INTERNAL_TIMER; + + for (i = 1; i <= repeats; i++) { +#if defined(JENT_TEST_BINARY_OUTPUT) && defined(JENT_CONF_DISABLE_LOOP_SHUFFLE) + snprintf(pathname, sizeof(pathname), "%s-%.4lu-u64.bin", argv[3], i); +#else + snprintf(pathname, sizeof(pathname), "%s-%.4lu.data", argv[3], i); +#endif + + ret = jent_one_test(pathname, rounds, flags, + REPORT_COUNTER_TICKS); + + if (ret) + return ret; + } + + return 0; +} diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-lfsrtime.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-lfsrtime.c new file mode 100644 index 0000000000..7ed77f8a29 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-lfsrtime.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include "jitterentropy-base.c" + +/*************************************************************************** + * Statistical test logic not compiled for regular operation + ***************************************************************************/ +/* + * Statistical test: return the time duration for the folding operation. If min + * is set, perform the given number of LFSR ops. Otherwise, allow the + * loop count shuffling to define the number of LFSR ops. + */ +static uint64_t jent_lfsr_var_stat(struct rand_data *ec, unsigned int min) +{ + uint64_t time = 0; + uint64_t time2 = 0; + + jent_get_nstime(&time); + + jent_memaccess(ec, min); + jent_stuck(ec, time); + jent_lfsr_time(ec, time, min, 0); + jent_get_nstime(&time2); + + return ((time2 - time)); +} + +static int jent_one_test(const char *pathname, unsigned long rounds) +{ + unsigned long size = 0; + struct rand_data *ec = NULL; + FILE *out = NULL; + int ret = 0; + + printf("Processing %s\n", pathname); + + out = fopen(pathname, "w"); + if (!out) { + ret = 1; + goto out; + } + + ec = jent_entropy_collector_alloc(0, 0); + if(!ec) { + ret = 1; + goto out; + } + + /* Enable full SP800-90B health test handling */ + ec->fips_enabled = 1; + + for (size = 0; size < rounds; size++) { + uint64_t duration = 0; + uint64_t duration_min = 0; + + duration = jent_lfsr_var_stat(ec, 0); + duration_min = jent_lfsr_var_stat(ec, 1); + fprintf(out, "%lu %lu\n", duration, duration_min); + } + +out: + if (out) + fclose(out); + + if (ec) + jent_entropy_collector_free(ec); + + return ret; +} + +/* + * Invoke the application with + * argv[1]: number of raw entropy measurements to be obtained for one + * entropy collector instance. + * argv[2]: number of test repetitions with a new entropy estimator + * allocated for each round - this satisfies the restart tests + * defined in SP800-90B section 3.1.4.3 and FIPS IG 7.18. + * argv[3]: File name of the output data + */ +int main(int argc, char * argv[]) +{ + unsigned long i, rounds, repeats; + int ret; + char pathname[4096]; + + if (argc != 4) { + printf("%s \n", argv[0]); + return 1; + } + + rounds = strtoul(argv[1], NULL, 10); + if (rounds >= UINT_MAX) + return 1; + + repeats = strtoul(argv[2], NULL, 10); + if (repeats >= UINT_MAX) + return 1; + + for (i = 1; i <= repeats; i++) { + snprintf(pathname, sizeof(pathname), "%s-%.4lu.data", argv[3], + i); + ret = jent_one_test(pathname, rounds); + if (ret) + return ret; + } + + return 0; +} + diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-osr.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-osr.c new file mode 100644 index 0000000000..922a4a854f --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-osr.c @@ -0,0 +1,338 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "jitterentropy.h" + +/* We use a linear interpolation to estimate where the value is going to be. + * The way these variable are named, this is technically the inverse function + * for the resulting line, as we are trying to get the expected osr for a + * provided time. + * + * Recall that point-point form for a line is + * y - y1 = ((y2 - y1)/(x2 - x1))*(x - x1) + * which is valid for non-vertical lines (i.e., so long as x1 != x2) + * We actually want the functional inverse of this, so solving for x, we get + * (y - y1) * ((x2 - x1) / (y2 - y1)) + x1 = x + * This is valid so long as y2 != y1. + * This functional inverse is the form that we use here. + */ +double linearInverse(double y, double x1, double y1, double x2, double y2) { + assert(fabs(y1-y2)>=DBL_EPSILON); + return (y-y1)*((x2-x1)/(y2-y1)) + x1; +} + +/* Returns the number of nanoseconds per output for the selected flags and osr. */ +uint64_t jent_output_time(unsigned int rounds, unsigned int osr, unsigned int flags) +{ + struct rand_data *ec_nostir; + struct timespec start, finish; + uint64_t runtime; + int ret; + + ret = jent_entropy_init_ex(osr, flags); + if (ret) { + fprintf(stderr, "The initialization failed with error code %d\n", ret); + return ret; + } + + ec_nostir = jent_entropy_collector_alloc(osr, flags); + + clock_gettime(CLOCK_REALTIME, &start); + + if (!ec_nostir) { + fprintf(stderr, "Jitter RNG handle cannot be allocated\n"); + return 1; + } + + for (unsigned long size = 0; size < rounds; size++) { + char tmp[32]; + + if (0 > jent_read_entropy_safe(&ec_nostir, tmp, sizeof(tmp))) { + fprintf(stderr, "FIPS 140-2 continuous test failed\n"); + return 1; + } + } + + clock_gettime(CLOCK_REALTIME, &finish); + runtime = ((uint64_t)finish.tv_sec * UINT64_C(1000000000) + (uint64_t)finish.tv_nsec) - ((uint64_t)start.tv_sec * UINT64_C(1000000000) + (uint64_t)start.tv_nsec); + + jent_entropy_collector_free(ec_nostir); + + return runtime / (uint64_t)rounds; +} + +int main(int argc, char * argv[]) +{ + unsigned long rounds; + unsigned int flags = 0; + char *endtimeparam; + double timeBoundIn; + uint64_t timeBound; + unsigned int maxBound, minBound, firstLinearGuess, secondLinearGuess; + uint64_t minTime, maxTime, firstLinearTime, secondLinearTime; + + if (argc < 2) { + fprintf(stderr, "%s [--force-fips|--disable-memory-access|--disable-internal-timer|--force-internal-timer|--max-mem ]\n", argv[0]); + return 1; + } + + rounds = strtoul(argv[1], NULL, 10); + if ((rounds >= UINT_MAX) || (rounds == 0)) + return 1; + argc--; + argv++; + + timeBoundIn = strtod(argv[1], &endtimeparam); + if ((timeBoundIn <= 0.0) || (*endtimeparam != '\0')) + return 1; + + /* The time upper bound, expressed as an integer number of nanoseconds. */ + timeBound = (uint64_t)floor(timeBoundIn * 1000000000.0); + argc--; + argv++; + + while (argc > 1) { + if (!strncmp(argv[1], "--force-fips", 12)) + flags |= JENT_FORCE_FIPS; + else if (!strncmp(argv[1], "--disable-memory-access", 23)) + flags |= JENT_DISABLE_MEMORY_ACCESS; + else if (!strncmp(argv[1], "--disable-internal-timer", 24)) + flags |= JENT_DISABLE_INTERNAL_TIMER; + else if (!strncmp(argv[1], "--force-internal-timer", 22)) + flags |= JENT_FORCE_INTERNAL_TIMER; + else if (!strncmp(argv[1], "--max-mem", 9)) { + unsigned long val; + + argc--; + argv++; + if (argc <= 1) { + fprintf(stderr, "Maximum memory value missing.\n"); + return 1; + } + + val = strtoul(argv[1], NULL, 10); + switch (val) { + case 0: + /* Allow to set no option */ + break; + case 1: + flags |= JENT_MAX_MEMSIZE_32kB; + break; + case 2: + flags |= JENT_MAX_MEMSIZE_64kB; + break; + case 3: + flags |= JENT_MAX_MEMSIZE_128kB; + break; + case 4: + flags |= JENT_MAX_MEMSIZE_256kB; + break; + case 5: + flags |= JENT_MAX_MEMSIZE_512kB; + break; + case 6: + flags |= JENT_MAX_MEMSIZE_1MB; + break; + case 7: + flags |= JENT_MAX_MEMSIZE_2MB; + break; + case 8: + flags |= JENT_MAX_MEMSIZE_4MB; + break; + case 9: + flags |= JENT_MAX_MEMSIZE_8MB; + break; + case 10: + flags |= JENT_MAX_MEMSIZE_16MB; + break; + case 11: + flags |= JENT_MAX_MEMSIZE_32MB; + break; + case 12: + flags |= JENT_MAX_MEMSIZE_64MB; + break; + case 13: + flags |= JENT_MAX_MEMSIZE_128MB; + break; + case 14: + flags |= JENT_MAX_MEMSIZE_256MB; + break; + case 15: + flags |= JENT_MAX_MEMSIZE_512MB; + break; + default: + fprintf(stderr, "Unknown maximum memory value\n"); + return 1; + } + } else { + fprintf(stderr, "Unknown option %s\n", argv[1]); + return 1; + } + + argc--; + argv++; + } + + /* We don't start with a maxBound. */ + maxBound = 0; + maxTime = 0; + + /* Verify the first invariant: generation using minBound occurs in less than or equal time than the targeted time. */ + minBound = JENT_MIN_OSR; + if((minTime = jent_output_time(rounds, minBound, flags)) > timeBound) { + fprintf(stderr, "Minimum osr %u exceeds the target time. Invariant not met.\n", minBound); + return 1; + } else + fprintf(stderr, "A minimum was found: osr upper bound is >= %u.\n", minBound); + + /* If there were no constant value in the linear expression, then we could estimate a cutoff + * using only this timing. We imagine that there is a fixed cost, so simple division overestimates + * the time cost per osr, and so this produces a likely underestimate. + */ + firstLinearGuess = (unsigned int)(timeBound / (1U + minTime / minBound)); + fprintf(stderr, "The initial linear estimate is osr=%u\n", firstLinearGuess); + firstLinearTime = jent_output_time(rounds, firstLinearGuess, flags); + + /* We now have two points (minBound, minTime) and (firstLinearGuess, firstLinearTime), so we can + * perform a full linear interpolation. + * We are presently looking for an overestimate, so let's round up here. + */ + secondLinearGuess = (unsigned int)ceil(linearInverse((double)timeBound, (double)minBound, (double)minTime, (double)firstLinearGuess, (double)firstLinearTime)); + fprintf(stderr, "Linear interpolation suggests a cutoff of %u\n", secondLinearGuess); + + /* These estimates were done in two related ways, but they could have produced the same value. + * Looking at the timing of two identical guesses isn't helpful, so adjust the result in this case.*/ + if(secondLinearGuess == firstLinearGuess) { + secondLinearGuess++; + } + secondLinearTime = jent_output_time(rounds, secondLinearGuess, flags); + + /* We now expect that secondLinearGuess > firstLinearGuess but weird things could have occurred. + * They can't be equal, by the above adjustment. + * Exchange them if they don't have the expected relationship. + */ + if(secondLinearGuess < firstLinearGuess) { + uint64_t tmpTime; + unsigned int tmpGuess; + + tmpGuess = firstLinearGuess; + tmpTime = firstLinearTime; + + firstLinearGuess = secondLinearGuess; + firstLinearTime = secondLinearTime; + + secondLinearGuess = tmpGuess; + secondLinearTime = tmpTime; + } + + /* Now secondLinearGuess > firstLinearGuess, and the time values should have a similar relationship. */ + assert(secondLinearTime > firstLinearTime); + + /* Use the linear interpolation guesses as bounds where possible. */ + if(firstLinearTime > timeBound) { + /* Here, we have timeBound < firstLinearTime < secondLinearTime. + * In this case, the linear interpolations didn't yield a minBound + * so we'll proceed with the initial minBound. + */ + maxBound = firstLinearGuess; + maxTime = firstLinearTime; + } else if(secondLinearTime > timeBound) { + /* Here, we have firstLinearTime <= timeBound < secondLinearTime. + * so the linear interpolations provide both a minBound and maxBound. */ + minBound = firstLinearGuess; + minTime = firstLinearTime; + maxBound = secondLinearGuess; + maxTime = secondLinearTime; + } else { + /* here, we have know that firstLinearTime < secondLinearTime <= timeBound */ + /* so linear interpolation didn't supply a maxBound, and will have to look for it. */ + minBound = secondLinearGuess; + minTime = secondLinearTime; + } + + /* If we don't yet have a maxBound, find one. This will also adjust minBound up as the search goes.*/ + if(maxBound == 0) { + maxBound = minBound*2; + fprintf(stderr, "Trying to find a maximum: %u", maxBound); + /* Locate the maxBound */ + while((maxTime = jent_output_time(rounds, maxBound, flags)) <= timeBound) { + minBound = maxBound; + minTime = maxTime; + maxBound = maxBound * 2; + fprintf(stderr, " %u", maxBound); + assert(maxBound > minBound); + } + fprintf(stderr, ".\nMaximum found: osr upper bound is < %u.\n", maxBound); + } + + fprintf(stderr, "Desired osr upper bound is in [%u, %u)\n", minBound, maxBound); + assert(maxBound > minBound); + assert(maxTime > minTime); + assert(maxTime > timeBound); + assert(minTime <= timeBound); + + /* All invariants are now verified: + * maxBound > minBound + * maxTime > timeBound >= minTime + * + * We now perform a binary search (if necessary). + */ + while(maxBound - minBound > 1) { + unsigned int curosr; + uint64_t curTime; + /* Calculate (minBound + maxBound)/2 without risk of overflow. */ + curosr = minBound + (maxBound - minBound) / 2; + assert(curosr > minBound); + assert(curosr < maxBound); + + fprintf(stderr, "Trying osr=%u. ", curosr); + curTime = jent_output_time(rounds, curosr, flags); + assert(curTime > minTime); + assert(curTime < maxTime); + + if(curTime <= timeBound) { + fprintf(stderr, "Timing is less than or equal to the target time. "); + minBound = curosr; + minTime = curTime; + } else { + fprintf(stderr, "Timing is greater than the target time. "); + maxBound = curosr; + maxTime = curTime; + } + + fprintf(stderr, "Desired osr upper bound is in [%u, %u)\n", minBound, maxBound); + assert(maxBound > minBound); + assert(maxTime > minTime); + assert(maxTime > timeBound); + assert(minTime <= timeBound); + } + + printf("%u\n", minBound); + + return 0; +} diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-rng.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-rng.c new file mode 100644 index 0000000000..212b0a47dc --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/recording_userspace/jitterentropy-rng.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include +#include +#include +#include + +#include "jitterentropy.h" + +int main(int argc, char * argv[]) +{ + unsigned long size, rounds; + int ret = 0; + unsigned int flags = 0, osr = 0; + struct rand_data *ec_nostir; + + if (argc < 2) { + printf("%s [--force-fips|--disable-memory-access|--disable-internal-timer|--force-internal-timer|--osr |--max-mem ]\n", argv[0]); + return 1; + } + + rounds = strtoul(argv[1], NULL, 10); + if (rounds >= UINT_MAX) + return 1; + argc--; + argv++; + + while (argc > 1) { + if (!strncmp(argv[1], "--force-fips", 12)) + flags |= JENT_FORCE_FIPS; + else if (!strncmp(argv[1], "--disable-memory-access", 23)) + flags |= JENT_DISABLE_MEMORY_ACCESS; + else if (!strncmp(argv[1], "--disable-internal-timer", 24)) + flags |= JENT_DISABLE_INTERNAL_TIMER; + else if (!strncmp(argv[1], "--force-internal-timer", 22)) + flags |= JENT_FORCE_INTERNAL_TIMER; + else if (!strncmp(argv[1], "--osr", 5)) { + unsigned long val; + + argc--; + argv++; + if (argc <= 1) { + printf("OSR value missing\n"); + return 1; + } + + val = strtoul(argv[1], NULL, 10); + if (val >= UINT_MAX) + return 1; + osr = (unsigned int)val; + } else if (!strncmp(argv[1], "--max-mem", 9)) { + unsigned long val; + + argc--; + argv++; + if (argc <= 1) { + printf("Maximum memory value missing\n"); + return 1; + } + + val = strtoul(argv[1], NULL, 10); + switch (val) { + case 0: + /* Allow to set no option */ + break; + case 1: + flags |= JENT_MAX_MEMSIZE_32kB; + break; + case 2: + flags |= JENT_MAX_MEMSIZE_64kB; + break; + case 3: + flags |= JENT_MAX_MEMSIZE_128kB; + break; + case 4: + flags |= JENT_MAX_MEMSIZE_256kB; + break; + case 5: + flags |= JENT_MAX_MEMSIZE_512kB; + break; + case 6: + flags |= JENT_MAX_MEMSIZE_1MB; + break; + case 7: + flags |= JENT_MAX_MEMSIZE_2MB; + break; + case 8: + flags |= JENT_MAX_MEMSIZE_4MB; + break; + case 9: + flags |= JENT_MAX_MEMSIZE_8MB; + break; + case 10: + flags |= JENT_MAX_MEMSIZE_16MB; + break; + case 11: + flags |= JENT_MAX_MEMSIZE_32MB; + break; + case 12: + flags |= JENT_MAX_MEMSIZE_64MB; + break; + case 13: + flags |= JENT_MAX_MEMSIZE_128MB; + break; + case 14: + flags |= JENT_MAX_MEMSIZE_256MB; + break; + case 15: + flags |= JENT_MAX_MEMSIZE_512MB; + break; + default: + printf("Unknown maximum memory value\n"); + return 1; + } + } else { + printf("Unknown option %s\n", argv[1]); + return 1; + } + + argc--; + argv++; + } + + ret = jent_entropy_init_ex(osr, flags); + if (ret) { + printf("The initialization failed with error code %d\n", ret); + return ret; + } + + ec_nostir = jent_entropy_collector_alloc(osr, flags); + if (!ec_nostir) { + printf("Jitter RNG handle cannot be allocated\n"); + return 1; + } + + for (size = 0; size < rounds; size++) { + char tmp[32]; + + if (0 > jent_read_entropy_safe(&ec_nostir, tmp, sizeof(tmp))) { + fprintf(stderr, "FIPS 140-2 continuous test failed\n"); + return 1; + } + fwrite(&tmp, sizeof(tmp), 1, stdout); + } + + jent_entropy_collector_free(ec_nostir); + + return 0; +} diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/Makefile b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/Makefile new file mode 100644 index 0000000000..58d837f66c --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/Makefile @@ -0,0 +1,31 @@ +# Compile Noise Source as user space application + +CC ?= gcc +override CFLAGS +=-pedantic -Wall -Wextra -O2 + +program_NAME := extractlsb +#program_C_SRCS := $(wildcard *.c) +program_C_SRCS := extractlsb.c +program_C_OBJS := ${program_C_SRCS:.c=.o} +program_OBJS := $(program_C_OBJS) + +program_INCLUDE_DIRS := +program_LIBRARY_DIRS := +program_LIBRARIES := + +CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(program_NAME) + +$(program_NAME): $(program_OBJS) + $(CC) $(program_OBJS) -o $(program_NAME) $(LDFLAGS) + +clean: + @- $(RM) $(program_NAME) + @- $(RM) $(program_OBJS) + +distclean: clean diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/README.md b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/README.md new file mode 100644 index 0000000000..912b2e584d --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/README.md @@ -0,0 +1,67 @@ +# Validation of Raw Entropy Data Restart Test + +This validation tool processes the restart raw entropy data compliant to +SP800-90B section 3.1.4. + +Each restart must be recorded in a single file where each raw entropy +value is stored on one line. + +## Prerequisites + +To execute the testing, you need: + + * NIST SP800-90B tool from: + https://github.com/usnistgov/SP800-90B_EntropyAssessment + + * Obtain the sample data recorded on the target platforms + + * Configure processdata.sh with proper parameter values + + +### Parameters of processdata.sh + +ENTROPYDATA_DIR: Location of the sample data files (with .data extension) + +RESULTS_DIR: Location for the interim data bit streams and results. + +LOGFILE: Name of the log file. The default is $RESULTS_DIR/processdata.log. + +EATOOL: Path of the program used from the Entropy Assessment restart tool +(usually, ea_restart). + +BUILD_EXTRACT: Indicates whether the script will build the extractlsb program. +The default is "yes". + +MASK_LIST: Indicates the extraction method from each sample item. You can +indicate one or more methods; the script will generate one bit stream data +file for each extraction method. See below for a more detailed explanation. + +SAMPLES: the number of samples (time deltas) that will be extracted from the +data. The default is 1000, as specified in SP800-90B. + +RESTARTS: the number of test runs to be concatenated. The default is 1000, as +specified in SP 800-90B Each test run should be stored in a distinct file, from +jent_raw_noise_restart.00000.data to jent_raw_noise_restart.00999.data. + +## Conclusion + +The conclusion you have to draw is the following: To generate a 256 bit block, +the Jitter RNG obtains 256 time deltas (one time delta per bit at least, unless +the Jitter RNG performs oversampling). So, if you obtain a result that the +minimum entropy is more than 1 bit of entropy (per time delta), the one block +of 64 data bits is believed to have (close to) 64 bits of entropy. Otherwise it +will have relatively less entropy. + +Please note that the minimum collision entropy value for 8 bits may be smaller +than the 4 bit values due to the inclusion of leading zeros. This, however is +a data processing problem that should be considered when drawing conclusions. +One can see the effect of these leading zeros by compressing the 4 bit and +8 bit data streams. Whereas the 4 bit data stream may not be compressable, +the 8 bit data stream may be compressed + +This may also occur when the least significant bits in the time delta do not +change. You need to refine the extraction method to reach to the right +calculation. + + +[1] https://github.com/usnistgov/SP800-90B_EntropyAssessment diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/extractlsb.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/extractlsb.c new file mode 100644 index 0000000000..539cb8fda2 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/extractlsb.c @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* + * The tool extracts the 4 or 8 LSB of the high-res time stamp and + * concatenates them to form a binary data stream. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define BITS_PER_SAMPLE 64 + +/* + Extract bits from sample based on significant bit mask +*/ + +static unsigned char extract(uint64_t sample, uint64_t mask) +{ + unsigned char byte = 0; + int i, j = 0; + + for (i = 0; i < BITS_PER_SAMPLE && mask; i++) { + if (mask & 1) { + byte |= (sample & 1) << j; + j++; + } + mask >>= 1; + sample >>= 1; + } + return byte; +} + +/* + Convert mask in hexadecimal format to binary +*/ + +static int hextolong(char *p_strmask, uint64_t *p_mask) +{ + + uint64_t mask = 0; + int count = 0; + + while (*p_strmask) { + count++; + mask <<= 4; + + if ((*p_strmask >= '0') && (*p_strmask <= '9')) + mask |= *p_strmask - '0'; + else if ((*p_strmask >= 'A') && (*p_strmask <= 'F')) + mask |= *p_strmask - 'A' + 10; + else if ((*p_strmask >= '0') && (*p_strmask <= '9')) + mask |= *p_strmask - 'a' + 10; + else + return -1; + + p_strmask++; + } + + if (count > 16) + return -1; + + *p_mask = mask; + return 0; +} + +/* + Count the number of bits on +*/ + +static int bitcount(uint64_t mask) +{ + int i, j = 0; + + for (i = 0; i < BITS_PER_SAMPLE && mask; i++) { + if (mask & 1) { + j++; + } + mask >>= 1; + } + return j; +} + +/* + Print 64 bits of long word masking with '-' those not matching value +*/ + +static char *printbits(uint64_t sample, int value) +{ + static char buf[BITS_PER_SAMPLE + 9]; + char *p_buf = buf + sizeof(buf) - 1; + int i; + *p_buf-- = '\0'; + for (i = 0; i < BITS_PER_SAMPLE; i++) { + if (i % 8 == 0) + *p_buf-- = ' '; + + if ((sample & 1) ^ value) + *p_buf = '-'; + else + *p_buf = '0' + value; + p_buf--; + sample >>= 1; + } + + return buf; +} + + +int main(int argc, char *argv[]) +{ + FILE *f = NULL; + char buf[64]; + int outfd = -1; + uint32_t count; + uint32_t i = 0; + int prev_timestamp_set = 0; + uint64_t prev_timestamp = 0; + + uint64_t mask; + uint64_t unchanged0s, unchanged1s; + int rc; + + if (argc != 5) { + printf("Usage: %s inputfile outfile samples mask\n", argv[0]); + return 1; + } + + f = fopen(argv[1], "r"); + if (!f) { + printf("File %s cannot be opened for read\n", argv[1]); + return 1; + } + + outfd = open(argv[2], O_CREAT|O_WRONLY|O_APPEND, 0777); + if (outfd < 0) { + printf("File %s cannot be opened for write\n", argv[2]); + fclose(f); + return 1; + } + + count = strtoul(argv[3], NULL, 10); + rc = hextolong(argv[4], &mask); + + if (rc) { + printf("Mask value is incorrect [%s], use up to 16 hexadecimal characters\n", argv[5]); + fclose(f); + close(outfd); + return 1; + } + + if (bitcount(mask) > 8) { + printf("SP800-90B tool only supports up to 8 bits. Check the mask value\n"); + fclose(f); + close(outfd); + return 1; + } + + unchanged0s = 0; + unchanged1s = ~0; + + while (fgets(buf, sizeof(buf), f)) { + uint64_t timestamp, delta; + unsigned char extracted; + + // Ignore empty lines. + if (buf[0] == '\0' || buf[0] == '\n' || buf[0] == '\r') { + continue; + } + + timestamp = strtoul(buf, NULL, 10); + if (!prev_timestamp_set) { + prev_timestamp = timestamp; + prev_timestamp_set = 1; + continue; + } + delta = (timestamp > prev_timestamp) ? + timestamp - prev_timestamp : + timestamp - prev_timestamp; + prev_timestamp = timestamp; + + unchanged0s |= delta; + unchanged1s &= delta; + extracted = extract(delta, mask); + write(outfd, &extracted, sizeof(extracted)); + + i += 1; + if (i == count) + break; + } + + if (i < count) { + printf("Attempted to extract %d samples from %s but only got %d samples\n", count, argv[0], i); + fclose(f); + close(outfd); + return 1; + } + + printf("Processed %d samples from %s with mask [0x%016llx] significant bits [%d]\n", i, argv[0], (unsigned long long)mask, bitcount(mask)); + + printf("Constant 0s in sample: \n%s\n", printbits(unchanged0s, 0)); + printf("Constant 1s in sample: \n%s\n", printbits(unchanged1s, 1)); + + fclose(f); + close(outfd); + return 0; +} diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/processdata.sh b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/processdata.sh new file mode 100644 index 0000000000..85b1464d9c --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart-kernel/processdata.sh @@ -0,0 +1,149 @@ +#!/bin/bash +# +# Process the entropy data + +############################################################ +# Configuration values # +############################################################ + +# point to the directory that contains the results from the entropy collection +ENTROPYDATA_DIR=${ENTROPYDATA_DIR:-"../results-measurements"} + +# this is where the resulting data and the entropy analysis will be stored +RESULTS_DIR=${RESULTS_DIR:-"../results-analysis-restart"} + +# location of log file +LOGFILE="$RESULTS_DIR/processdata.log" + +# point to the min entropy tool +EATOOL="../SP800-90B_EntropyAssessment/cpp/ea_restart" + +# specify if you want to compile the extractlsb program in this script +BUILD_EXTRACT=${BUILD_EXTRACT:-"yes"} + +# specify the list of significant bits and length that you want to analize. +# Indicate first the mask in hexa format and then the number of +# bits separated by a colon. +# The tool generates one set of var and single data files, and the EA results +# for each element. +# The mask can have a maximum of 8 bits on, the EA tool only manages samples +# up to one byte. + +# List of masks usually analyzed (4 and 8 LSB) +MASK_LIST="0F:4 FF:8" + +# List used for ARM Cortext A9 and A7 processors +#MASK_LIST="FF:4,8 7F8:4,8" + +# Number of samples to be extracted from the original file +SAMPLES=1000 + +# Number of test runs to be concatenated +RESTARTS=1000 + +############################################################ +# Code only after this line -- do not change # +############################################################ + +############################# +# Preparation +############################# +EXTRACT="extractlsb" +CFILE="extractlsb.c" + +if [ ! -d $ENTROPYDATA_DIR ] +then + echo "ERROR: Directory with raw entropy data $ENTROPYDATA_DIR is missing" + exit 1 +fi + +if [ ! -d $RESULTS_DIR ] +then + mkdir $RESULTS_DIR + if [ $? -ne 0 ] + then + echo "ERROR: Directory for results $RESULTS_DIR could not be created" + exit 1 + fi +fi + +if [ ! -f $EATOOL ] +then + echo "ERROR: Path of Entropy Data tool $EATOOL is missing" + exit 1 +fi + + +rm -f $RESULTS_DIR/*.txt $RESULTS_DIR/*.data $RESULTS_DIR/*.log + +trap "if [ "$BUILD_EXTRACT" = "yes" ]; then make clean; fi" 0 1 2 3 15 + +if [ "$BUILD_EXTRACT" = "yes" ] +then + echo "Building $EXTRACT ..." + make clean + make +fi + +if [ ! -x $EXTRACT ] +then + echo "ERROR: Cannot execute $EXTRACT program" + exit 1 +fi + +############################# +# Actual data processing +############################# + +# +# Step 1: Concatenate all individual restart files into single file and convert +# +for item in $MASK_LIST +do + mask=${item%:*} + + echo "Converting recorded entropy data into different bit output with mask $mask..." | tee -a $LOGFILE + out_file=$RESULTS_DIR/raw_noise_restart_all.${mask}bitout.data + rm -f $out_file + + for i in `seq -f "%05g" 0 $(($RESTARTS-1))` + do + in_file=$ENTROPYDATA_DIR/jent_raw_noise_restart.$i.data + if [ ! -f $in_file ] + then + echo "ERROR: File $in_file not found" + exit 1 + fi + + echo "Converting recorded entropy data $in_file into different bit output with mask $mask" >> $LOGFILE + ./$EXTRACT $in_file $out_file $SAMPLES $mask >> $LOGFILE 2>&1 + done +done + +echo "" | tee -a $LOGFILE +echo "Extraction finished. Now analyzing entropy for noise source ..." | tee -a $LOGFILE +echo "" | tee -a $LOGFILE + +# +# Step 2: Perform SP800-90B analysis +# +for item in $MASK_LIST +do + mask=${item%:*} + bits_field=${item#*:} + bits_list=`echo $bits_field | sed -e "s/,/ /g"` + + in_file=$RESULTS_DIR/raw_noise_restart_all.${mask}bitout.data + + for bits in $bits_list + do + out_file=$RESULTS_DIR/raw_noise_restart_all.minentropy_${mask}_${bits}bits.txt + if [ ! -f $out_file ] + then + echo "Analyzing entropy for $out_file ${bits}-bit..." | tee -a $LOGFILE + $EATOOL -n -v $in_file ${bits} 1.0 > $out_file + else + echo "File $out_file already generated" + fi + done +done diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/Makefile b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/Makefile new file mode 100644 index 0000000000..0b87761794 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/Makefile @@ -0,0 +1,31 @@ +# Compile Noise Source as user space application + +CC ?= gcc +override CFLAGS +=-pedantic -Wall -Wextra -O2 + +program_NAME := extractlsb +#program_C_SRCS := $(wildcard *.c) +program_C_SRCS := extractlsb.c +program_C_OBJS := ${program_C_SRCS:.c=.o} +program_OBJS := $(program_C_OBJS) + +program_INCLUDE_DIRS := +program_LIBRARY_DIRS := +program_LIBRARIES := rt + +CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(program_NAME) + +$(program_NAME): $(program_OBJS) + $(CC) $(program_OBJS) -o $(program_NAME) $(LDFLAGS) + +clean: + @- $(RM) $(program_NAME) + @- $(RM) $(program_OBJS) + +distclean: clean diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/README.md b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/README.md new file mode 100644 index 0000000000..f93aa02131 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/README.md @@ -0,0 +1,68 @@ +# Validation of Raw Entropy Data Restart Test + +This validation tool processes the restart raw entropy data compliant to +SP800-90B section 3.1.4. + +Each restart must be recorded in a single file where each raw entropy +value is stored on one line. + +## Prerequisites + +To execute the testing, you need: + + * NIST SP800-90B tool from: + https://github.com/usnistgov/SP800-90B_EntropyAssessment + + * Obtain the sample data recorded on the target platforms + + * Configure processdata.sh with proper parameter values + + +### Parameters of processdata.sh + +ENTROPYDATA_DIR: Location of the sample data files (with .data extension) + +RESULTS_DIR: Location for the interim data bit streams (var and single), +and results. + +LOGFILE: Name of the log file. The default is $RESULTS_DIR/processdata.log. + +EATOOL: Path of the program used from the Entropy Assessment restart tool +(usually, ea_restart). + +BUILD_EXTRACT: Indicates whether the script will build the extractlsb program. +The default is "yes". + +MASK_LIST: Indicates the extraction method from each sample item. You can +indicate one or more methods; the script will generate one bit stream data +file set (var and single) for each extraction method. See below for a more +detailed explanation. + +MAX_EVENTS: the size of the sample that will be extracted from the sample data. +The default is 100000 (a 1% of the size of the sample file specified in the +ROUNDS define macro). Notice that the minimum value suggested by SP800-90B is +1000000, so you'll have to increase the default value (notice that this +severely impacts in the performance and memory requirements of the python tool). + +## Conclusion + +The conclusion you have to draw is the following: To generate a 256 bit block, +the Jitter RNG obtains 256 time deltas (one time delta per bit at least, unless +the Jitter RNG performs oversampling). So, if you obtain a result that the +minimum entropy is more than 1 bit of entropy (per time delta), the one block +of 64 data bits is believed to have (close to) 64 bits of entropy. Otherwise it +will have relatively less entropy. + +Please note that the minimum collision entropy value for 8 bits may be smaller +than the 4 bit values due to the inclusion of leading zeros. This, however is +a data processing problem that should be considered when drawing conclusions. +One can see the effect of these leading zeros by compressing the 4 bit and +8 bit data streams. Whereas the 4 bit data stream may not be compressable, +the 8 bit data stream may be compressed + +This may also occur when the least significant bits in the time delta do not +change. You need to refine the extraction method to reach to the right +calculation. + + +[1] https://github.com/usnistgov/SP800-90B_EntropyAssessment diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/analyze_options.sh b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/analyze_options.sh new file mode 100755 index 0000000000..a48d05568f --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/analyze_options.sh @@ -0,0 +1,118 @@ +#!/bin/bash +# +# Tool to validaets the test results for various Jitter RNG memory settings +# +# This tool is only needed if you have insufficient entropy. See ../README.md +# for details +# + +RESULT="../results-restart-multi" +ENT_DIR="../results-measurements" +RES_DIR="../results-analysis-restart" +NUM_CPU=1 +USED_CPUS=0 + +echo -e "Number of blocks\tBlocksize\tmin entropy" > $RESULT + +trap "make clean" 0 1 2 3 15 +make clean +make + +crunch_numbers() { + local source=$1 + local target=$2 + + if [ $USED_CPUS -eq $NUM_CPU ] + then + # wait for all + wait + USED_CPUS=0 + fi + + if [ ! -d $target ] + then + USED_CPUS=$(($USED_CPUS+1)) + + ( BUILD_EXTRACT="no" ENTROPYDATA_DIR=$source RESULTS_DIR=$target ./processdata.sh ) & + fi +} + +linearmem_written=0 +calc() { + local crunch=$1 + + for memsize in 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864 134217728 268435456 536870912 + do + for blocks in 64 128 256 512 1024 2048 4096 8192 16384 + do + for blocksize in 32 64 128 256 512 1024 2048 4096 8192 16384 + do + local target="$RES_DIR-${blocks}blocks-${blocksize}blocksize-${memsize}bytes" + local source="$ENT_DIR-${blocks}blocks-${blocksize}blocksize-${memsize}bytes" + + if [ ! -d "$source" ] + then + continue + fi + + if [ $linearmem_written -eq 0 ] + then + echo -e "Max memory size\tNumber of blocks\tBlocksize\tmin entropy" > $RESULT + linearmem_written=1 + fi + + if [ $crunch -eq 0 ] + then + ent=$(grep min $target/jent-raw-noise-restart-consolidated.minentropy_FF_8bits.var.txt | cut -d ":" -f 2) + echo -e "$memsize\t$blocks\t$blocksize\t$ent" >> $RESULT + else + crunch_numbers $source $target + fi + done + done + done +} + +randmem_written=0 +calc_randmem() { + local crunch=$1 + + for bits in 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + do + local target="$RES_DIR-random_memaccess-${bits}bits-${memsize}bytes" + local source="$ENT_DIR-random_memaccess-${bits}bits-${memsize}bytes" + + if [ ! -d "$source" ] + then + continue + fi + + if [ $randmem_written -eq 0 ] + then + echo -e "Number of bits\tmin entropy" > $RESULT + randmem_written=1 + fi + + if [ $crunch -eq 0 ] + then + ent=$(grep min $target/jent-raw-noise-restart-consolidated.minentropy_FF_8bits.var.txt | cut -d ":" -f 2) + echo -e "$bits\t$ent" >> $RESULT + else + crunch_numbers $source $target + fi + done +} + +if [ -f /proc/cpuinfo ] +then + NUM_CPU=$(cat /proc/cpuinfo | grep processor | tail -n1 | cut -d":" -f 2) + NUM_CPU=$(($NUM_CPU+1)) +fi + +calc_randmem 1 +wait +calc_randmem 0 + +calc 1 +wait +calc 0 diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/extractlsb.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/extractlsb.c new file mode 100644 index 0000000000..4b11ceb28c --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/extractlsb.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* + * The tool extracts the 4 or 8 LSB of the high-res time stamp and + * concatenates them to form a binary data stream. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define BITS_PER_SAMPLE 64 + +/* + Extract bits from sample based on significant bit mask +*/ + +static unsigned char extract(uint64_t sample, uint64_t mask) +{ + unsigned char byte = 0; + int i, j = 0; + + for (i = 0; i < BITS_PER_SAMPLE && mask; i++) { + if (mask & 1) { + byte |= (sample & 1) << j; + j++; + } + mask >>= 1; + sample >>= 1; + } + return (byte); +} + +/* + Convert mask in hexadecimal format to binary +*/ + +static int hextolong(char *p_strmask, uint64_t *p_mask) +{ + + uint64_t mask = 0; + int count = 0; + + while (*p_strmask) { + count++; + mask <<= 4; + + if ((*p_strmask >= '0') && (*p_strmask <= '9')) + mask |= *p_strmask - '0'; + else if ((*p_strmask >= 'A') && (*p_strmask <= 'F')) + mask |= *p_strmask - 'A' + 10; + else if ((*p_strmask >= '0') && (*p_strmask <= '9')) + mask |= *p_strmask - 'a' + 10; + else + return -1; + + p_strmask++; + } + + if (count > 16) + return(-1); + + *p_mask = mask; + return(0); +} + +/* + Count the number of bits on +*/ + +static int bitcount(uint64_t mask) +{ + int i, j = 0; + + for (i = 0; i < BITS_PER_SAMPLE && mask; i++) { + if (mask & 1) { + j++; + } + mask >>= 1; + } + return (j); +} + +/* + Print 64 bits of long word masking with '-' those not matching value +*/ + +static char *printbits(uint64_t sample, int value) +{ + static char buf[BITS_PER_SAMPLE + 9]; + char *p_buf = buf + sizeof(buf) - 1; + int i; + *p_buf-- = '\0'; + for (i = 0; i < BITS_PER_SAMPLE; i++) { + if (i % 8 == 0) + *p_buf-- = ' '; + + if ((sample & 1) ^ value) + *p_buf = '-'; + else + *p_buf = '0' + value; + p_buf--; + sample >>= 1; + } + + return buf; +} + + +int main(int argc, char *argv[]) +{ + FILE *f = NULL; + char buf[64]; + int varfd = -1; + int singlefd = -1; + uint32_t count; + uint32_t i = 0; + + uint64_t mask; + uint64_t var_unchanged0s, var_unchanged1s; + uint64_t single_unchanged0s, single_unchanged1s; + int rc; + + if (argc != 6) { + printf("Usage: %s inputfile varoutfile singleoutfile maxevents mask\n", argv[0]); + return 1; + } + + f = fopen(argv[1], "r"); + if (!f) { + printf("File %s cannot be opened for read\n", argv[1]); + return 1; + } + + varfd = open(argv[2], O_CREAT|O_WRONLY|O_EXCL, 0777); + if (varfd < 0) { + printf("File %s cannot be opened for write\n", argv[2]); + fclose(f); + return 1; + } + + singlefd = open(argv[3], O_CREAT|O_WRONLY|O_EXCL, 0777); + if (singlefd < 0) { + printf("File %s cannot be opened for write\n", argv[3]); + fclose(f); + close(varfd); + return 1; + } + + count = strtoul(argv[4], NULL, 10); + rc = hextolong(argv[5], &mask); + + if (rc) { + printf("Mask value is incorrect [%s], use up to 16 hexadecimal characters", argv[5]); + return 1; + } + + if (bitcount(mask) > 8) { + printf("SP800-90B tool only supports up to 8 bits. Check the mask value"); + return 1; + } + + var_unchanged0s = 0; + var_unchanged1s = ~0; + single_unchanged0s = 0; + single_unchanged1s = ~0; + + while (fgets(buf, sizeof(buf), f)) { + uint64_t sample; + unsigned char var, single; + char *saveptr = NULL; + char *res = NULL; + + i++; + + res = strtok_r(buf, " ", &saveptr); + if (!res) { + printf("strtok_r error (%s)\n", buf); + return 1; + } + + sample = strtoul(res, NULL, 10); + var_unchanged0s |= sample; + var_unchanged1s &= sample; + + var = extract(sample, mask); + write(varfd, &var, sizeof(var)); + + res = strtok_r(NULL, " ", &saveptr); + if (!res) { + printf("strtok_r error (%s)\n", buf); + return 1; + } + + sample = strtoul(res, NULL, 10); + single_unchanged0s |= sample; + single_unchanged1s &= sample; + + single = extract(sample, mask); + write(singlefd, &single, sizeof(single)); + + if (i >= count) + break; + } + + printf("Processed %d items from %s samples with mask [0x%016llx] significant bits [%d]\n", i, argv[0], (unsigned long long)mask, bitcount(mask)); + + printf("Constant 0s in var sample: \n%s\n", printbits(var_unchanged0s, 0)); + printf("Constant 1s in var sample: \n%s\n", printbits(var_unchanged1s, 1)); + printf("Constant 0s in single sample: \n%s\n", printbits(single_unchanged0s, 0)); + printf("Constant 1s in single sample: \n%s\n", printbits(single_unchanged1s, 1)); + + fclose(f); + close(varfd); + close(singlefd); + return 0; +} diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/processdata.sh b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/processdata.sh new file mode 100755 index 0000000000..18dfb004ca --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-restart/processdata.sh @@ -0,0 +1,170 @@ +#!/bin/bash +# +# Process the entropy data + +############################################################ +# Configuration values # +############################################################ + +# point to the directory that contains the results from the entropy collection +ENTROPYDATA_DIR=${ENTROPYDATA_DIR:-"../results-measurements"} + +# this is where the resulting data and the entropy analysis will be stored +RESULTS_DIR=${RESULTS_DIR:-"../results-analysis-restart"} + +# location of log file +LOGFILE="$RESULTS_DIR/processdata.log" + +# point to the min entropy tool +EATOOL_NONIID="../../SP800-90B_EntropyAssessment/cpp/ea_restart" + +# specify if you want to compile the extractlsb program in this script +BUILD_EXTRACT=${BUILD_EXTRACT:-"yes"} + +# specify the list of significant bits and length that you want to analize. +# Indicate first the mask in hexa format and then the number of +# bits separated by a colon. +# The tool generates one set of var and single data files, and the EA results +# for each element. +# The mask can have a maximum of 8 bits on, the EA tool only manages samples +# up to one byte. + +# List of masks usually analyzed (4 and 8 LSB) +MASK_LIST="0F:4 FF:8" + +# List used for ARM Cortext A9 and A7 processors +#MASK_LIST="FF:4,8 7F8:4,8" + +# Maximum number of entries to be extracted from the original file +MAX_EVENTS=1000000 + +############################################################ +# Code only after this line -- do not change # +############################################################ + +############################# +# Preparation +############################# +INPUT="$ENTROPYDATA_DIR/jent-raw-noise-restart*.data" +INPUTCONSOLIDATED="$RESULTS_DIR/jent-raw-noise-restart-consolidated.data" + +EXTRACT="extractlsb" +CFILE="extractlsb.c" + +if [ ! -d $ENTROPYDATA_DIR ] +then + echo "Directory with raw entropy data $ENTROPYDATA_DIR is missing" + exit 1 +fi + +if [ ! -d $RESULTS_DIR ] +then + mkdir $RESULTS_DIR + if [ $? -ne 0 ] + then + echo "Directory for results $RESULTS_DIR cannot be created" + exit 1 + fi +fi + +if [ ! -f $EA_TOOL ] +then + echo "ERROR: Path of Entropy Data tool $EA_TOOL is missing" + exit 1 +fi + + +trap "if [ "$BUILD_EXTRACT" = "yes" ]; then make clean; fi" 0 1 2 3 15 + +rm -f $EXEC +if [ "$BUILD_EXTRACT" = "yes" ] +then + echo "Building $EXTRACT ..." + make clean + make +fi + +if [ ! -x $EXTRACT ] +then + echo "ERROR: Cannot execute $EXTRACT program" + exit 1 +fi + +############################# +# Actual data processing +############################# +# +# Step 1: Concatenate all individual restart files into single file +# +rm -f $INPUTCONSOLIDATED +for i in $INPUT +do + echo "Process recorded entropy data $i" + + cat $i >> $INPUTCONSOLIDATED +done + +# +# Step 2: extract data +# +for file in $INPUTCONSOLIDATED +do + filepath=$RESULTS_DIR/`basename ${file%%.data}` + echo "Converting recorded entropy data $file into different bit output" | tee -a $LOGFILE + + for item in $MASK_LIST + do + mask=${item%:*} + bits=${item#*:} + + ./$EXTRACT $file $filepath.${mask}bitout.var.data $filepath.${mask}bitout.single.data $MAX_EVENTS $mask 2>&1 | tee -a $LOGFILE + done +done + +# +# Step 3: Calculate SP800-90B +# +# Just like in step 2, we calculate the entropy column-wise +# + +echo "" | tee -a $LOGFILE +echo "Extraction finished. Now analyzing entropy for noise source ..." | tee -a $LOGFILE +echo "" | tee -a $LOGFILE + +for file in $INPUTCONSOLIDATED +do + filepath=$RESULTS_DIR/`basename ${file%%.data}` + + for item in $MASK_LIST + do + mask=${item%:*} + bits_field=${item#*:} + bits_list=`echo $bits_field | sed -e "s/,/ /g"` + + infilesingle=$filepath.${mask}bitout.single.data + infilevar=$filepath.${mask}bitout.var.data + + for bits in $bits_list + do + outfile=${filepath}.minentropy_${mask}_${bits}bits.single.txt + inprocess_file=$outfile + if [ ! -f $outfile ] + then + echo "Analyzing entropy for $infilesingle ${bits}-bit single" | tee -a $LOGFILE + $EATOOL_NONIID -n -v $infilesingle ${bits} 0.333 > $outfile + else + echo "File $outfile already generated" + fi + + outfile=${filepath}.minentropy_${mask}_${bits}bits.var.txt + inprocess_file=$outfile + if [ ! -f $outfile ] + then + echo "Analyzing entropy for $infilevar ${bits}-bit var" | tee -a $LOGFILE + $EATOOL_NONIID -n -v $infilevar ${bits} 0.333 > $outfile + else + echo "File $outfile already generated" + fi + done + done +done diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/Makefile b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/Makefile new file mode 100644 index 0000000000..58d837f66c --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/Makefile @@ -0,0 +1,31 @@ +# Compile Noise Source as user space application + +CC ?= gcc +override CFLAGS +=-pedantic -Wall -Wextra -O2 + +program_NAME := extractlsb +#program_C_SRCS := $(wildcard *.c) +program_C_SRCS := extractlsb.c +program_C_OBJS := ${program_C_SRCS:.c=.o} +program_OBJS := $(program_C_OBJS) + +program_INCLUDE_DIRS := +program_LIBRARY_DIRS := +program_LIBRARIES := + +CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(program_NAME) + +$(program_NAME): $(program_OBJS) + $(CC) $(program_OBJS) -o $(program_NAME) $(LDFLAGS) + +clean: + @- $(RM) $(program_NAME) + @- $(RM) $(program_OBJS) + +distclean: clean diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/README.md b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/README.md new file mode 100644 index 0000000000..e16dfaf858 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/README.md @@ -0,0 +1,239 @@ +# Validation of Raw Entropy Data - Kernel + +This tool is used to calculate the minimum entropy values +compliant to SP800-90B for the gathered data. + +The validation operation of the raw entropy data is invoked with the +processdata.sh script. + +The sampling data from the recording operation must be post-processed. This is +because you need to determine which part of the sample elements contain the +high-resolution part of the time delta provided by the Jitter RNG. Usually, +this occurs in the 4 to 8 least significant bits of the sample element, but it +may vary depending on the processor. + +The first step is performed by the extractlsb program, which reads the input +data, extracts the significant bits from each sample item (using a mask that +you provide) and outputs it to a bit stream file. + +In the second step, the binary data streams are processed with the SP800-90B +entropy assessment tool, which calculates the min entropy. + +The resulting minimum entropy for each data stream is provided in the +*.minentropy file. The log file contains a summary of the steps performed and +the output of the extractlsb program. + + +## Prerequisites + +To execute the testing, you need: + + * NIST SP800-90B tool from: + https://github.com/usnistgov/SP800-90B_EntropyAssessment + + * Obtain the sample data recorded on the target platforms + + * Configure processdata.sh with proper parameter values + + +### Parameters of processdata.sh + +ENTROPYDATA_DIR: Location of the sample data files (with .data extension) + +RESULTS_DIR: Location for the interim data bit streams and results. + +LOGFILE: Name of the log file. The default is $RESULTS_DIR/processdata.log. + +EATOOL: Path of the python program used from the Entropy Assessment tool +(usually, ea_noniid). + +BUILD_EXTRACT: Indicates whether the script will build the extractlsb program. +The default is "yes". + +MASK_LIST: Indicates the extraction method from each sample item. You can +indicate one or more methods; the script will generate one bit stream data +file set for each extraction method. See below for a more detailed explanation. + +SAMPLES: the number of samples (time deltas) that will be extracted from the +data. The default is 1000000, as specified in SP800-90B. + +### Extraction method + +The kernel patch extracts raw time stamps. They are converted into time deltas +by `extractlsb.c` to obtain the time deltas uses to insert into the entropy +pool of the Jitter RNG. + +Although the samples elements collected from the JitterRNG (time deltas) have +a size 64 bits, the entropy will likely be provided on the high resolution +part, which is usually the least significant bits. + +Also, the python script that performs the SP800-90B entropy analysis has two +limitations: + + * although the SP800-90B standard allows alphabets of any size, the + script only processes alphabets up to 8 bits. + + * the script expects each sample to be contained in one byte. + Therefore, if you want to use only the 4 LSB of each sample item, + you'll need to generate one byte per each 4-bit symbol. + +You need to analyze the sample and determine which bit positions provide +the high-resolution time deltas that will feed the entropy analysis. + +Usually, you can assume that the high-resolution time delta is represented +in the least significant 4 or 8 bits. So you specify the MASK_LIST parameter +as follows: + + MASK_LIST="0F:4 FF:8" + +This parameter value means the following: + + * There will be two extractions methods for each data set. + + * The first method takes the 4 LSB from each sample item, generates + one byte per sample item, and uses a 4-bit alphabet for analyzing + entropy. + + * The second method takes the 8 LSB from each sample item, generates + one byte per item, and uses an 8-bit alphabet for analyzing entropy. + +The parameter is a list of extraction methods. Each extraction method is +represented by two fields separated by a colon: + + * A mask in hexadecimal format, that indicates which bits are + significant. If the bit is on in a given position, this bit will be + considered to form the final byte. Otherwise, it'll be discarded. + For instance, a mask of "F8" means that the 3 LSB will be discarded, + and the bits 4 to 8 will be used; a mask of "7F8", means that the + 3 LSB will be discarded, and bits 4 to 10 will be used. The bit + values are shifted so all bit positions in the final byte are used. + + * The second value is the alphabet size in bits. This is redundant but + required to avoid complex calculations in bash. + +You can start with the default values, and then refine your extraction methods +if necessary. You may find that the LSB of the samples do not provide entropy, +then use a different mask to discard them. + +The output of the extractlsb program can be used to detect this scenarios. The +program shows a summary of the extraction, indicating the bit positions that +have not changed in any of the samples. For example, this is the output of +the extraction program. + +Processed 1000000 items from ./extractlsb samples with +mask [0x00000000000000ff] significant bits [8] + +Constant 0s in sample: +00000000 00000000 00000000 00000000 --000-00 0---0--- -------- -----000 + +Constant 1s in sample: +-------- -------- -------- -------- -------- -------- -------- -------- + +You can see here that the 3 LSB of the samples always show zeroes (the minus +means that this position is variable). There you can easily determine which +positions you should consider. In this particular case, you should use a mask of +"78:4" and "7F8:8" to analyze the samples with 4-bit and 8-bit alphabets, +discarding the 3 LSB. + + +## Conclusion + +The conclusion you have to draw is the following: To generate a 64 bit block, +the Jitter RNG obtains 64 time deltas (one time delta per bit at least, unless +the Jitter RNG performs oversampling). So, if you obtain a result that the +minimum entropy is more than 1 bit of entropy (per time delta), the one block +of 64 data bits is believed to have (close to) 64 bits of entropy. Otherwise it +will have relatively less entropy. + +Please note that the minimum collision entropy value for 8 bits may be smaller +than the 4 bit values due to the inclusion of leading zeros. This, however is +a data processing problem that should be considered when drawing conclusions. +One can see the effect of these leading zeros by compressing the 4 bit and +8 bit data streams. Whereas the 4 bit data stream may not be compressable, +the 8 bit data stream may be compressed + +This may also occur when the least significant bits in the time delta do not +change. You need to refine the extraction method to reach to the right +calculation. + + +# Example Assessment of Results + +The file foldtime.O0 contains test results for the non-optimized binary code +that is the basis for the Jitter RNG. To understand what it shows, we have to +understand what the Jitter RNG really does: it simply measures the execution +time of a fixed code fragment. The test does the same, i.e. it measures what +the Jitter RNG would measure. Each time delta is simply recorded. + +Each time delta is expected to contribute entropy to the entropy pool. But how +much? We can use the SP800-90B tool set provided by NIST at [1]. This tool, +however, can only process input data with a window size of a few bits at most. +Thus, we take the 4 LSB of each time delta, hoping that they contain already +sufficient entropy. + +Using the tool [1], we get the following output: + +Number of Binary Symbols: 4000000 + +Symbol alphabet consists of 16 unique symbols + +Running non-IID tests... + +Running Most Common Value Estimate... + Most Common Value Estimate (bit string) = 0.997853 / 1 bit(s) + +Running Entropic Statistic Estimates (bit strings only)... + Collision Test Estimate (bit string) = 0.933346 / 1 bit(s) + Markov Test Estimate (bit string) = 0.999810 / 1 bit(s) + Compression Test Estimate (bit string) = 0.749885 / 1 bit(s) + +Running Tuple Estimates... + T-Tuple Test Estimate (bit string) = 0.927240 / 1 bit(s) + LRS Test Estimate (bit string) = 0.997939 / 1 bit(s) + +Running Predictor Estimates... + Multi Most Common in Window (MultiMCW) Prediction Test Estimate (bit string) = 0.998260 / 1 bit(s) + Lag Prediction Test Estimate (bit string) = 0.998753 / 1 bit(s) + Multi Markov Model with Counting (MultiMMC) Prediction Test Estimate (bit string) = 0.998283 / 1 bit(s) + LZ78Y Prediction Test Estimate (bit string) = 0.999020 / 1 bit(s) + +h': 0.749885 + +The last line is the key: it contains the minimum entropy in one bit of the 4 +bit snapshot + +- we have 0.749885 bits of entropy per data bit + +- as we analyzed 4 bits of each time delta, we get 4 * 0.749885 = 2.99954 bits +of entropy per four bit time delta + +- assuming the worst case that all other bits in the time delta have no +entropy, we have 2.99954 bits of entropy per time delta + +- the Jitter RNG gathers 64 time deltas for returning 64 bits of random data +and it uses an LFSR with a primitive and irreducible polynomial which is +entropy preserving. Thus, the Jitter RNG collected 64 * 2.99954 = 191.97056 bits +of entropy for its 64 bit output. + +- as the Jitter RNG maintains a 64 bit entropy pool, its entropy content +cannot be larger than the pool itself. Thus, the entropy content in the pool +after collecting 64 time deltas is max(64 bits, 191.97056 bits) = 64 bits + +This implies that the Jitter RNG data has (close to) 64 bits of entropy per +data bit. + +Bottom line: When the Jitter RNG injects 64 bits of data into the Linux /dev/ +random via the IOCTL, it is appropriate that the entropy estimator increases +by 64 bits. + +Bottom line: From my perspective, I see no issue in using the Jitter RNG as a +noise source in your environments. + + +Note, applying the Shannon-Entropy formula to the data, we will get much +higher entropy values. + +Note II: This assessment complies with the entropy assessments to be done for +a NIST FIP 140-2 validation compliant to FIPS 140-2 IG 7.15 + +[1] https://github.com/usnistgov/SP800-90B_EntropyAssessment diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/extractlsb.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/extractlsb.c new file mode 100644 index 0000000000..8199938bfe --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/extractlsb.c @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* + * The tool extracts the 4 or 8 LSB of the high-res time stamp and + * concatenates them to form a binary data stream. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define BITS_PER_SAMPLE 64 + +/* + Extract bits from sample based on significant bit mask +*/ + +static unsigned char extract(uint64_t sample, uint64_t mask) +{ + unsigned char byte = 0; + int i, j = 0; + + for (i = 0; i < BITS_PER_SAMPLE && mask; i++) { + if (mask & 1) { + byte |= (sample & 1) << j; + j++; + } + mask >>= 1; + sample >>= 1; + } + return byte; +} + +/* + Convert mask in hexadecimal format to binary +*/ + +static int hextolong(char *p_strmask, uint64_t *p_mask) +{ + + uint64_t mask = 0; + int count = 0; + + while (*p_strmask) { + count++; + mask <<= 4; + + if ((*p_strmask >= '0') && (*p_strmask <= '9')) + mask |= *p_strmask - '0'; + else if ((*p_strmask >= 'A') && (*p_strmask <= 'F')) + mask |= *p_strmask - 'A' + 10; + else if ((*p_strmask >= '0') && (*p_strmask <= '9')) + mask |= *p_strmask - 'a' + 10; + else + return -1; + + p_strmask++; + } + + if (count > 16) + return -1; + + *p_mask = mask; + return 0; +} + +/* + Count the number of bits on +*/ + +static int bitcount(uint64_t mask) +{ + int i, j = 0; + + for (i = 0; i < BITS_PER_SAMPLE && mask; i++) { + if (mask & 1) { + j++; + } + mask >>= 1; + } + return j; +} + +/* + Print 64 bits of long word masking with '-' those not matching value +*/ + +static char *printbits(uint64_t sample, int value) +{ + static char buf[BITS_PER_SAMPLE + 9]; + char *p_buf = buf + sizeof(buf) - 1; + int i; + *p_buf-- = '\0'; + for (i = 0; i < BITS_PER_SAMPLE; i++) { + if (i % 8 == 0) + *p_buf-- = ' '; + + if ((sample & 1) ^ value) + *p_buf = '-'; + else + *p_buf = '0' + value; + p_buf--; + sample >>= 1; + } + + return buf; +} + + +int main(int argc, char *argv[]) +{ + FILE *f = NULL; + char buf[64]; + int outfd = -1; + uint32_t count; + uint32_t i = 0; + int prev_timestamp_set = 0; + uint64_t prev_timestamp = 0; + + uint64_t mask; + uint64_t unchanged0s, unchanged1s; + int rc; + + if (argc != 5) { + printf("Usage: %s inputfile outfile samples mask\n", argv[0]); + return 1; + } + + f = fopen(argv[1], "r"); + if (!f) { + printf("File %s cannot be opened for read\n", argv[1]); + return 1; + } + + outfd = open(argv[2], O_CREAT|O_WRONLY|O_EXCL, 0777); + if (outfd < 0) { + printf("File %s cannot be opened for write\n", argv[2]); + fclose(f); + return 1; + } + + count = strtoul(argv[3], NULL, 10); + rc = hextolong(argv[4], &mask); + + if (rc) { + printf("Mask value is incorrect [%s], use up to 16 hexadecimal characters\n", argv[5]); + fclose(f); + close(outfd); + return 1; + } + + if (bitcount(mask) > 8) { + printf("SP800-90B tool only supports up to 8 bits. Check the mask value\n"); + fclose(f); + close(outfd); + return 1; + } + + unchanged0s = 0; + unchanged1s = ~0; + + while (fgets(buf, sizeof(buf), f)) { + uint64_t timestamp, delta; + unsigned char extracted; + + // Ignore empty lines. + if (buf[0] == '\0' || buf[0] == '\n' || buf[0] == '\r') { + continue; + } + + timestamp = strtoul(buf, NULL, 10); + if (!prev_timestamp_set) { + prev_timestamp = timestamp; + prev_timestamp_set = 1; + continue; + } + delta = (timestamp > prev_timestamp) ? + timestamp - prev_timestamp : + timestamp - prev_timestamp; + prev_timestamp = timestamp; + + unchanged0s |= delta; + unchanged1s &= delta; + extracted = extract(delta, mask); + write(outfd, &extracted, sizeof(extracted)); + + i += 1; + if (i == count) + break; + } + + if (i < count) { + printf("Attempted to extract %d samples from %s but only got %d samples\n", count, argv[0], i); + fclose(f); + close(outfd); + return 1; + } + + printf("Processed %d samples from %s with mask [0x%016llx] significant bits [%d]\n", i, argv[0], (unsigned long long)mask, bitcount(mask)); + + printf("Constant 0s in sample: \n%s\n", printbits(unchanged0s, 0)); + printf("Constant 1s in sample: \n%s\n", printbits(unchanged1s, 1)); + + fclose(f); + close(outfd); + return 0; +} diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/processdata.sh b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/processdata.sh new file mode 100755 index 0000000000..6b77276da9 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime-kernel/processdata.sh @@ -0,0 +1,144 @@ +#!/bin/bash +# +# Process the entropy data + +############################################################ +# Configuration values # +############################################################ + +# point to the directory that contains the results from the entropy collection +ENTROPYDATA_DIR=${ENTROPYDATA_DIR:-"../results-measurements"} + +# this is where the resulting data and the entropy analysis will be stored +RESULTS_DIR=${RESULTS_DIR:-"../results-analysis-runtime"} + +# location of log file +LOGFILE="$RESULTS_DIR/processdata.log" + +# point to the min entropy tool +EATOOL="../SP800-90B_EntropyAssessment/cpp/ea_non_iid" + +# specify if you want to compile the extractlsb program in this script +BUILD_EXTRACT=${BUILD_EXTRACT:-"yes"} + +# specify the list of significant bits and length that you want to analize. +# Indicate first the mask in hexa format and then the number of +# bits separated by a colon. +# The tool generates one set of var and single data files, and the EA results +# for each element. +# The mask can have a maximum of 8 bits on, the EA tool only manages samples +# up to one byte. + +# List of masks usually analyzed (4 and 8 LSB) +MASK_LIST="0F:4 FF:8" + +# List used for ARM Cortext A9 and A7 processors +#MASK_LIST="FF:4,8 7F8:4,8" + +# Number of samples to be extracted from the original file +SAMPLES=1000000 + +############################################################ +# Code only after this line -- do not change # +############################################################ + +############################# +# Preparation +############################# +EXTRACT="extractlsb" +CFILE="extractlsb.c" + +if [ ! -d $ENTROPYDATA_DIR ] +then + echo "ERROR: Directory with raw entropy data $ENTROPYDATA_DIR is missing" + exit 1 +fi + +if [ ! -d $RESULTS_DIR ] +then + mkdir $RESULTS_DIR + if [ $? -ne 0 ] + then + echo "ERROR: Directory for results $RESULTS_DIR could not be created" + exit 1 + fi +fi + +if [ ! -f $EATOOL ] +then + echo "ERROR: Path of Entropy Data tool $EATOOL is missing" + exit 1 +fi + + +rm -f $RESULTS_DIR/*.txt $RESULTS_DIR/*.data $RESULTS_DIR/*.log + +trap "if [ "$BUILD_EXTRACT" = "yes" ]; then make clean; fi" 0 1 2 3 15 + + +if [ "$BUILD_EXTRACT" = "yes" ] +then + echo "Building $EXTRACT ..." + make clean + make +fi + +if [ ! -x $EXTRACT ] +then + echo "ERROR: Cannot execute $EXTRACT program" + exit 1 +fi + +############################# +# Actual data processing +############################# + +# +# Step 1: Convert input file +# +for item in $MASK_LIST +do + mask=${item%:*} + + echo "Converting recorded entropy data into different bit output with mask $mask..." | tee -a $LOGFILE + out_file=$RESULTS_DIR/raw_noise.${mask}bitout.data + rm -f $out_file + + in_file=$ENTROPYDATA_DIR/jent_raw_noise.data + if [ ! -f $in_file ] + then + echo "ERROR: File $in_file not found" + exit 1 + fi + + echo "Converting recorded entropy data $in_file into different bit output with mask $mask" >> $LOGFILE + ./$EXTRACT $in_file $out_file $SAMPLES $mask >> $LOGFILE 2>&1 +done + +echo "" | tee -a $LOGFILE +echo "Extraction finished. Now analyzing entropy for noise source ..." | tee -a $LOGFILE +echo "" | tee -a $LOGFILE + +# +# Step 2: Perform SP800-90B analysis +# +for item in $MASK_LIST +do + mask=${item%:*} + bits_field=${item#*:} + bits_list=`echo $bits_field | sed -e "s/,/ /g"` + + in_file=$RESULTS_DIR/raw_noise.${mask}bitout.data + + for bits in $bits_list + do + out_file=$RESULTS_DIR/raw_noise.minentropy_${mask}_${bits}bits.txt + if [ ! -f $out_file ] + then + echo "Analyzing entropy for $out_file ${bits}-bit..." | tee -a $LOGFILE + $EATOOL $in_file ${bits} -i -a -v > $out_file + else + echo "File $out_file already generated" + fi + done +done diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/Makefile b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/Makefile new file mode 100644 index 0000000000..0b87761794 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/Makefile @@ -0,0 +1,31 @@ +# Compile Noise Source as user space application + +CC ?= gcc +override CFLAGS +=-pedantic -Wall -Wextra -O2 + +program_NAME := extractlsb +#program_C_SRCS := $(wildcard *.c) +program_C_SRCS := extractlsb.c +program_C_OBJS := ${program_C_SRCS:.c=.o} +program_OBJS := $(program_C_OBJS) + +program_INCLUDE_DIRS := +program_LIBRARY_DIRS := +program_LIBRARIES := rt + +CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(program_NAME) + +$(program_NAME): $(program_OBJS) + $(CC) $(program_OBJS) -o $(program_NAME) $(LDFLAGS) + +clean: + @- $(RM) $(program_NAME) + @- $(RM) $(program_OBJS) + +distclean: clean diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/README.md b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/README.md new file mode 100644 index 0000000000..99944f22b7 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/README.md @@ -0,0 +1,248 @@ +# Validation of Raw Entropy Data + +This tool is used to calculate the minimum entropy values +compliant to SP800-90B for the gathered data. + +The validation operation of the raw entropy data is invoked with the +processdata.sh script. + +The sampling data from the recording operation must be post-processed. This is +because you need to determine which part of the sample elements contain the +high-resolution part of the time delta provided by the Jitter RNG. Usually, +this occurs in the 4 to 8 least significant bits of the sample element, but it +may vary depending on the processor. + +The first step is performed by the extractlsb program, which reads the input +data, extracts the significant bits from each sample item (using a mask that +you provide) and split it in two bit stream files, one containing the var +sample, and the other the single sample. + +In the second step, the binary data streams are processed with the SP800-90B +entropy assessment tool, which calculates the min entropy. + +The resulting minimum entropy for each data stream is provided in the +*.minentropy file. The log file contains a summary of the steps performed and +the output of the extractlsb program. + + +## Prerequisites + +To execute the testing, you need: + + * NIST SP800-90B tool from: + https://github.com/usnistgov/SP800-90B_EntropyAssessment + + * Obtain the sample data recorded on the target platforms + + * Configure processdata.sh with proper parameter values + + +### Parameters of processdata.sh + +ENTROPYDATA_DIR: Location of the sample data files (with .data extension) + +RESULTS_DIR: Location for the interim data bit streams (var and single), +and results. + +LOGFILE: Name of the log file. The default is $RESULTS_DIR/processdata.log. + +EATOOL: Path of the python program used from the Entropy Assessment tool +(usually, noniid_main.py). + +BUILD_EXTRACT: Indicates whether the script will build the extractlsb program. +The default is "yes". + +MASK_LIST: Indicates the extraction method from each sample item. You can +indicate one or more methods; the script will generate one bit stream data +file set (var and single) for each extraction method. See below for a more +detailed explanation. + +MAX_EVENTS: the size of the sample that will be extracted from the sample data. +The default is 100000 (a 1% of the size of the sample file specified in the +ROUNDS define macro). Notice that the minimum value suggested by SP800-90B is +1000000, so you'll have to increase the default value (notice that this +severily impacts in the performance and memory requirements of the python tool). + + +### Extraction method + +Although the samples elements collected from the JitterRNG (time deltas) have +a size 64 bits, the entropy will likely be provided on the high resolution +part, which is usually the least significant bits. + +Also, the python script that performs the SP800-90B entropy analysis has two +limitations: + + * although the SP800-90B standard allows alphabets of any size, the + script only processes alphabets up to 8 bits. + + * the script expects each sample to be contained in one byte. + Therefore, if you want to use only the 4 LSB of each sample item, + you'll need to generate one byte per each 4-bit symbol. + +You need to analyze the sample and determine which bit positions provide +the high-resolution time deltas that will feed the entropy analysis. + +Usually, you can assume that the high-resolution time delta is represented +in the least significant 4 or 8 bits. So you specify the MASK_LIST parameter +as follows: + + MASK_LIST="0F:4 FF:8" + +This parameter value means the following: + + * There will be two extractions methods for each data set. + + * The first method takes the 4 LSB from each sample item, generates + one byte per sample item, and uses a 4-bit alphabet for analyzing + entropy. + + * The second method takes the 8 LSB from each sample item, generates + one byte per item, and uses an 8-bit alphabet for analyzing entropy. + +The parameter is a list of extraction methods. Each extraction method is +represented by two fields separated by a colon: + + * A mask in hexadecimal format, that indicates which bits are + significant. If the bit is on in a given position, this bit will be + considered to form the final byte. Otherwise, it'll be discarded. + For instance, a mask of "F8" means that the 3 LSB will be discarded, + and the bits 4 to 8 will be used; a mask of "7F8", means that the + 3 LSB will be discarded, and bits 4 to 10 will be used. The bit + values are shifted so all bit positions in the final byte are used. + + * The second value is the alphabet size in bits. This is redundant but + required to avoid complex calculations in bash. + +You can start with the default values, and then refine your extraction methods +if necessary. You may find that the LSB of the samples do not provide entropy, +then use a different mask to discard them. + +The output of the extractlsb program can be used to detect this scenarios. The +program shows a summary of the extraction, indicating the bit positions that +have not changed in any of the samples. For example, this is the output of +the extraction program. + +Processed 1000000 items from ./extractlsb samples with +mask [0x00000000000000ff] significant bits [8] + +Constant 0s in var sample: +00000000 00000000 00000000 00000000 --000-00 0---0--- -------- -----000 + +Constant 1s in var sample: +-------- -------- -------- -------- -------- -------- -------- -------- + +Constant 0s in single sample: +00000000 00000000 00000000 00000000 --000-00 0--00--- -------- -----000 + +Constant 1s in single sample: +-------- -------- -------- -------- -------- -------- -------- -------- + +You can see here that the 3 LSB of both samples (var and single) always +show zeroes (the minus means that this position is variable). There you can +easily determine which positions you should consider. In this particular +case, you should use a mask of "78:4" and "7F8:8" to analyze the samples +with 4-bit and 8-bit alphabets, discarding the 3 LSB. + + +## Conclusion + +The conclusion you have to draw is the following: To generate a 64 bit block, +the Jitter RNG obtains 64 time deltas (one time delta per bit at least, unless +the Jitter RNG performs oversampling). So, if you obtain a result that the +minimum entropy is more than 1 bit of entropy (per time delta), the one block +of 64 data bits is believed to have (close to) 64 bits of entropy. Otherwise it +will have relatively less entropy. + +Please note that the minimum collision entropy value for 8 bits may be smaller +than the 4 bit values due to the inclusion of leading zeros. This, however is +a data processing problem that should be considered when drawing conclusions. +One can see the effect of these leading zeros by compressing the 4 bit and +8 bit data streams. Whereas the 4 bit data stream may not be compressable, +the 8 bit data stream may be compressed + +This may also occur when the least significant bits in the time delta do not +change. You need to refine the extraction method to reach to the right +calculation. + + +# Example Assessment of Results + +The file foldtime.O0 contains test results for the non-optimized binary code +that is the basis for the Jitter RNG. To understand what it shows, we have to +understand what the Jitter RNG really does: it simply measures the execution +time of a fixed code fragment. The test does the same, i.e. it measures what +the Jitter RNG would measure. Each time delta is simply recorded. + +Each time delta is expected to contribute entropy to the entropy pool. But how +much? We can use the SP800-90B tool set provided by NIST at [1]. This tool, +however, can only process input data with a window size of a few bits at most. +Thus, we take the 4 LSB of each time delta, hoping that they contain already +sufficient entropy. + +Using the tool [1], we get the following output: + +Number of Binary Symbols: 4000000 + +Symbol alphabet consists of 16 unique symbols + +Running non-IID tests... + +Running Most Common Value Estimate... + Most Common Value Estimate (bit string) = 0.997853 / 1 bit(s) + +Running Entropic Statistic Estimates (bit strings only)... + Collision Test Estimate (bit string) = 0.933346 / 1 bit(s) + Markov Test Estimate (bit string) = 0.999810 / 1 bit(s) + Compression Test Estimate (bit string) = 0.749885 / 1 bit(s) + +Running Tuple Estimates... + T-Tuple Test Estimate (bit string) = 0.927240 / 1 bit(s) + LRS Test Estimate (bit string) = 0.997939 / 1 bit(s) + +Running Predictor Estimates... + Multi Most Common in Window (MultiMCW) Prediction Test Estimate (bit string) = 0.998260 / 1 bit(s) + Lag Prediction Test Estimate (bit string) = 0.998753 / 1 bit(s) + Multi Markov Model with Counting (MultiMMC) Prediction Test Estimate (bit string) = 0.998283 / 1 bit(s) + LZ78Y Prediction Test Estimate (bit string) = 0.999020 / 1 bit(s) + +h': 0.749885 + +The last line is the key: it contains the minimum entropy in one bit of the 4 +bit snapshot + +- we have 0.749885 bits of entropy per data bit + +- as we analyzed 4 bits of each time delta, we get 4 * 0.749885 = 2.99954 bits +of entropy per four bit time delta + +- assuming the worst case that all other bits in the time delta have no +entropy, we have 2.99954 bits of entropy per time delta + +- the Jitter RNG gathers 64 time deltas for returning 64 bits of random data +and it uses an LFSR with a primitive and irreducible polynomial which is +entropy preserving. Thus, the Jitter RNG collected 64 * 2.99954 = 191.97056 bits +of entropy for its 64 bit output. + +- as the Jitter RNG maintains a 64 bit entropy pool, its entropy content +cannot be larger than the pool itself. Thus, the entropy content in the pool +after collecting 64 time deltas is max(64 bits, 191.97056 bits) = 64 bits + +This implies that the Jitter RNG data has (close to) 64 bits of entropy per +data bit. + +Bottom line: When the Jitter RNG injects 64 bits of data into the Linux /dev/ +random via the IOCTL, it is appropriate that the entropy estimator increases +by 64 bits. + +Bottom line: From my perspective, I see no issue in using the Jitter RNG as a +noise source in your environments. + + +Note, applying the Shannon-Entropy formula to the data, we will get much +higher entropy values. + +Note II: This assessment complies with the entropy assessments to be done for +a NIST FIP 140-2 validation compliant to FIPS 140-2 IG 7.15 + +[1] https://github.com/usnistgov/SP800-90B_EntropyAssessment diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/analyze_options.sh b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/analyze_options.sh new file mode 100755 index 0000000000..ae277150d3 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/analyze_options.sh @@ -0,0 +1,116 @@ +#!/bin/bash +# +# Tool to validate the test results for various Jitter RNG memory settings +# +# This tool is only needed if you have insufficient entropy. See ../README.md +# for details +# + +RESULT="../results-runtime-multi" +ENT_DIR="../results-measurements" +RES_DIR="../results-analysis-runtime" +NUM_CPU=1 +USED_CPUS=0 + +trap "make clean" 0 1 2 3 15 +make clean +make + +crunch_numbers() { + local source=$1 + local target=$2 + + if [ $USED_CPUS -eq $NUM_CPU ] + then + # wait for all + wait + USED_CPUS=0 + fi + + if [ ! -d $target ] + then + USED_CPUS=$(($USED_CPUS+1)) + + ( BUILD_EXTRACT="no" ENTROPYDATA_DIR=$source RESULTS_DIR=$target ./processdata.sh ) & + fi +} + +linearmem_written=0 +calc() { + local crunch=$1 + + for memsize in 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864 134217728 268435456 536870912 + do + for blocks in 64 128 256 512 1024 2048 4096 8192 16384 + do + for blocksize in 32 64 128 256 512 1024 2048 4096 8192 16384 + do + local target="$RES_DIR-${blocks}blocks-${blocksize}blocksize-${memsize}bytes" + local source="$ENT_DIR-${blocks}blocks-${blocksize}blocksize-${memsize}bytes" + + if [ ! -d "$source" ] + then + continue + fi + + if [ $linearmem_written -eq 0 ] + then + echo -e "Max memory size\tNumber of blocks\tBlocksize\tmin entropy" > $RESULT + linearmem_written=1 + fi + + if [ $crunch -eq 0 ] + then + ent=$(grep min $target/jent-raw-noise-0001.minentropy_FF_8bits.var.txt | cut -d ":" -f 2) + echo -e "$memsize\t$blocks\t$blocksize\t$ent" >> $RESULT + else + crunch_numbers $source $target + fi + done + done + done +} + +randmem_written=0 +calc_randmem() { + local crunch=$1 + + for bits in 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + do + local target="$RES_DIR-random_memaccess-${bits}bits" + local source="$ENT_DIR-random_memaccess-${bits}bits" + + if [ ! -d "$source" ] + then + continue + fi + + if [ $randmem_written -eq 0 ] + then + echo -e "Number of bits\tmin entropy" > $RESULT + randmem_written=1 + fi + + if [ $crunch -eq 0 ] + then + ent=$(grep min $target/jent-raw-noise-0001.minentropy_FF_8bits.var.txt | cut -d ":" -f 2) + echo -e "$bits\t$ent" >> $RESULT + else + crunch_numbers $source $target + fi + done +} + +if [ -f /proc/cpuinfo ] +then + NUM_CPU=$(cat /proc/cpuinfo | grep processor | tail -n1 | cut -d":" -f 2) + NUM_CPU=$(($NUM_CPU+1)) +fi + +calc_randmem 1 +wait +calc_randmem 0 + +calc 1 +wait +calc 0 diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/draw_graph_analyze_options.r b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/draw_graph_analyze_options.r new file mode 100644 index 0000000000..0904ecd427 --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/draw_graph_analyze_options.r @@ -0,0 +1,41 @@ +# Plot data from IRQ duration table +# +# 1. create results-runtime-multi with analyze_options.sh: +# +# $ cat results-runtime-multi +# Number of bits min entropy +# 10 0.406505 +# 11 0.445082 +# 12 0.402972 +# 13 0.459021 +# 14 0.436911 +# 15 0.578995 +# 16 0.643272 +# 17 0.573532 +# 18 0.627915 +# 19 0.503923 +# 20 0.720609 +# 21 1.871527 +# 22 2.491569 +# 23 2.481533 +# 24 2.493987 +# 25 2.491303 +# 26 2.495017 +# +# 2. Generate plot: Rscript --vanilla draw_graph_analyze_options.r results-runtime-multi +# + +args <- commandArgs(trailingOnly = TRUE) + +if (length(args) != 1) { + stop("Invoke with ") +} + +file <- args[1] + +data <- read.csv(file=file, header=TRUE, sep="\t") + +pdf("memory_access_times.pdf", width=8, height=5, pointsize=10) + +# print software +plot(data[,1], data[,2], type="b", col="red", main="Memory Access Time Variations", pch=19, xlab="Memory size in powers of 2", ylab="SP800-90B Min Entropy", ylim=c(min(data[,2]), max(data[,2]))) diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/extractlsb.c b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/extractlsb.c new file mode 100644 index 0000000000..c0993580bc --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/extractlsb.c @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2019 - 2024, Stephan Mueller + * + * License: see LICENSE file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* + * The tool extracts the 4 or 8 LSB of the high-res time stamp and + * concatenates them to form a binary data stream. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define BITS_PER_SAMPLE 64 + +/* + Extract bits from sample based on significant bit mask +*/ + +static unsigned char extract(uint64_t sample, uint64_t mask) +{ + unsigned char byte = 0; + int i, j = 0; + + for (i = 0; i < BITS_PER_SAMPLE && mask; i++) { + if (mask & 1) { + byte |= (sample & 1) << j; + j++; + } + mask >>= 1; + sample >>= 1; + } + return (byte); +} + +/* + Convert mask in hexadecimal format to binary +*/ + +static int hextolong(char *p_strmask, uint64_t *p_mask) +{ + + uint64_t mask = 0; + int count = 0; + + while (*p_strmask) { + count++; + mask <<= 4; + + if ((*p_strmask >= '0') && (*p_strmask <= '9')) + mask |= *p_strmask - '0'; + else if ((*p_strmask >= 'A') && (*p_strmask <= 'F')) + mask |= *p_strmask - 'A' + 10; + else if ((*p_strmask >= '0') && (*p_strmask <= '9')) + mask |= *p_strmask - 'a' + 10; + else + return -1; + + p_strmask++; + } + + if (count > 16) + return(-1); + + *p_mask = mask; + return(0); +} + +/* + Count the number of bits on +*/ + +static int bitcount(uint64_t mask) +{ + int i, j = 0; + + for (i = 0; i < BITS_PER_SAMPLE && mask; i++) { + if (mask & 1) { + j++; + } + mask >>= 1; + } + return (j); +} + +/* + Print 64 bits of long word masking with '-' those not matching value +*/ + +static char *printbits(uint64_t sample, int value) +{ + static char buf[BITS_PER_SAMPLE + 9]; + char *p_buf = buf + sizeof(buf) - 1; + int i; + *p_buf-- = '\0'; + for (i = 0; i < BITS_PER_SAMPLE; i++) { + if (i % 8 == 0) + *p_buf-- = ' '; + + if ((sample & 1) ^ value) + *p_buf = '-'; + else + *p_buf = '0' + value; + p_buf--; + sample >>= 1; + } + + return buf; +} + + +int main(int argc, char *argv[]) +{ + FILE *f = NULL; + char buf[64]; + int varfd = -1; + int singlefd = -1; + uint32_t count; + uint32_t i = 0; + + uint64_t mask; + uint64_t var_unchanged0s, var_unchanged1s; + uint64_t single_unchanged0s, single_unchanged1s; + int rc; + + if (argc != 6) { + printf("Usage: %s inputfile varoutfile singleoutfile maxevents mask\n", argv[0]); + return 1; + } + + f = fopen(argv[1], "r"); + if (!f) { + printf("File %s cannot be opened for read\n", argv[1]); + return 1; + } + + varfd = open(argv[2], O_CREAT|O_WRONLY|O_EXCL, 0777); + if (varfd < 0) { + printf("File %s cannot be opened for write\n", argv[2]); + fclose(f); + return 1; + } + + singlefd = open(argv[3], O_CREAT|O_WRONLY|O_EXCL, 0777); + if (singlefd < 0) { + printf("File %s cannot be opened for write\n", argv[3]); + fclose(f); + close(varfd); + return 1; + } + + count = strtoul(argv[4], NULL, 10); + rc = hextolong(argv[5], &mask); + + if (rc) { + printf("Mask value is incorrect [%s], use up to 16 hexadecimal characters", argv[5]); + return 1; + } + + if (bitcount(mask) > 8) { + printf("SP800-90B tool only supports up to 8 bits. Check the mask value"); + return 1; + } + + var_unchanged0s = 0; + var_unchanged1s = ~0; + single_unchanged0s = 0; + single_unchanged1s = ~0; + + while (fgets(buf, sizeof(buf), f)) { + uint64_t sample; + unsigned char var, single; + char *saveptr = NULL; + char *res = NULL; + + i++; + + res = strtok_r(buf, " ", &saveptr); + if (!res) { + printf("strtok_r error\n"); + return 1; + } + + sample = strtoul(res, NULL, 10); + var_unchanged0s |= sample; + var_unchanged1s &= sample; + + var = extract(sample, mask); + write(varfd, &var, sizeof(var)); + + res = strtok_r(NULL, " ", &saveptr); + if (res) { + sample = strtoul(res, NULL, 10); + single_unchanged0s |= sample; + single_unchanged1s &= sample; + + single = extract(sample, mask); + write(singlefd, &single, sizeof(single)); + } + + if (i >= count) + break; + } + + printf("Processed %d items from %s samples with mask [0x%016llx] significant bits [%d]\n", i, argv[0], (unsigned long long)mask, bitcount(mask)); + + printf("Constant 0s in var sample: \n%s\n", printbits(var_unchanged0s, 0)); + printf("Constant 1s in var sample: \n%s\n", printbits(var_unchanged1s, 1)); + printf("Constant 0s in single sample: \n%s\n", printbits(single_unchanged0s, 0)); + printf("Constant 1s in single sample: \n%s\n", printbits(single_unchanged1s, 1)); + + fclose(f); + close(varfd); + close(singlefd); + return 0; +} diff --git a/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/processdata.sh b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/processdata.sh new file mode 100755 index 0000000000..dd92e1062f --- /dev/null +++ b/third_party/jitterentropy/jitterentropy-library/tests/raw-entropy/validation-runtime/processdata.sh @@ -0,0 +1,180 @@ +#!/bin/bash +# +# Process the entropy data + +############################################################ +# Configuration values # +############################################################ + +# point to the directory that contains the results from the entropy collection +ENTROPYDATA_DIR=${ENTROPYDATA_DIR:-"../results-measurements"} + +NONIID_DATA="jent-raw-noise-0001.data" +IID_DATA="jent-conditioned.data" + +# this is where the resulting data and the entropy analysis will be stored +RESULTS_DIR=${RESULTS_DIR:-"../results-analysis-runtime"} + +# location of log file +LOGFILE="$RESULTS_DIR/processdata.log" + +# point to the min entropy tool +EATOOL_NONIID="../../SP800-90B_EntropyAssessment/cpp/ea_non_iid" +EATOOL_IID="../../SP800-90B_EntropyAssessment/cpp/ea_iid" + +# specify if you want to compile the extractlsb program in this script +BUILD_EXTRACT=${BUILD_EXTRACT:-"yes"} + +# specify the list of significant bits and length that you want to analize. +# Indicate first the mask in hexa format and then the number of +# bits separated by a colon. +# The tool generates one set of var and single data files, and the EA results +# for each element. +# The mask can have a maximum of 8 bits on, the EA tool only manages samples +# up to one byte. + +# List of masks usually analyzed (4 and 8 LSB) +MASK_LIST="0F:4 FF:8" + +# List used for ARM Cortext A9 and A7 processors +#MASK_LIST="FF:4,8 7F8:4,8" + +# Maximum number of entries to be extracted from the original file +MAX_EVENTS=1000000 + +############################################################ +# Code only after this line -- do not change # +############################################################ + +EXTRACT="extractlsb" +CFILE="extractlsb.c" + +if [ ! -d $ENTROPYDATA_DIR ] +then + echo "ERROR: Directory with raw entropy data $ENTROPYDATA_DIR is missing" + exit 1 +fi + +if [ ! -d $RESULTS_DIR ] +then + mkdir $RESULTS_DIR + if [ $? -ne 0 ] + then + echo "ERROR: Directory with raw entropy data $RESULTS_DIR could not be created" + exit 1 + fi +fi + +if [ ! -f $EA_TOOL ] +then + echo "ERROR: Path of Entropy Data tool $EA_TOOL is missing" + exit 1 +fi + + +rm -f $RESULTS_DIR/*.txt $RESULTS_DIR/*.data $RESULTS_DIR/*.log + +trap "if [ "$BUILD_EXTRACT" = "yes" ]; then make clean; fi" 0 1 2 3 15 + + +if [ "$BUILD_EXTRACT" = "yes" ] +then + echo "Building $EXTRACT ..." + make clean + make +fi + +if [ ! -x $EXTRACT ] +then + echo "ERROR: Cannot execute $EXTRACT program" + exit 1 +fi + +for file in $ENTROPYDATA_DIR/$NONIID_DATA +do + filepath=$RESULTS_DIR/`basename ${file%%.data}` + echo "Converting recorded entropy data $file into different bit output" | tee -a $LOGFILE + + for item in $MASK_LIST + do + mask=${item%:*} + bits=${item#*:} + + ./$EXTRACT $file $filepath.${mask}bitout.var.data $filepath.${mask}bitout.single.data $MAX_EVENTS $mask 2>&1 | tee -a $LOGFILE + + done +done + +echo "" | tee -a $LOGFILE +echo "Extraction finished. Now analyzing entropy for noise source ..." | tee -a $LOGFILE +echo "" | tee -a $LOGFILE + +for file in $ENTROPYDATA_DIR/$NONIID_DATA +do + filepath=$RESULTS_DIR/`basename ${file%%.data}` + + for item in $MASK_LIST + do + mask=${item%:*} + bits_field=${item#*:} + bits_list=`echo $bits_field | sed -e "s/,/ /g"` + + infilesingle=$filepath.${mask}bitout.single.data + infilevar=$filepath.${mask}bitout.var.data + + for bits in $bits_list + do + outfile=${filepath}.minentropy_${mask}_${bits}bits.single.txt + inprocess_file=$outfile + if [ ! -f $outfile ] + then + echo "Analyzing entropy for $infilesingle ${bits}-bit single" | tee -a $LOGFILE + #python -u $EATOOL_NONIID -v $infilesingle $bits > $outfile + $EATOOL_NONIID $infilesingle ${bits} -i -a -v > $outfile + else + echo "File $outfile already generated" + fi + + outfile=${filepath}.minentropy_${mask}_${bits}bits.var.txt + inprocess_file=$outfile + if [ ! -f $outfile ] + then + echo "Analyzing entropy for $infilevar ${bits}-bit single" | tee -a $LOGFILE + #python -u $EATOOL_NONIID -v $infilevar $bits > $outfile + $EATOOL_NONIID $infilevar ${bits} -i -a -v > $outfile + else + echo "File $outfile already generated" + fi + done + done +done + +echo "" | tee -a $LOGFILE +echo "Now analyzing entropy for conditioned data..." | tee -a $LOGFILE +echo "" | tee -a $LOGFILE + +for file in $ENTROPYDATA_DIR/$IID_DATA +do + bits=8 + infile=$file + + if [ ! -f $infile ] + then + continue + fi + + filepath=`basename ${file%%.data}` + outfile=$RESULTS_DIR/${filepath}.minentropy_${bits}.var.txt + inprocess_file=$outfile + if [ ! -f $outfile ] + then + echo "Analyzing entropy for $infile ${bits}-bit var" | tee -a $LOGFILE + #python -u $EATOOL_IID -v $infile $bits > $outfile + $EATOOL_IID $infile ${bits} -i -a -v > $outfile + else + echo "File $outfile already generated" + fi +done + +inprocess_file="" + diff --git a/tool/bssl_bm.h b/tool/bssl_bm.h index 1f58a66a8a..73fd6048ff 100644 --- a/tool/bssl_bm.h +++ b/tool/bssl_bm.h @@ -30,7 +30,7 @@ #if defined(INTERNAL_TOOL) #include <../crypto/ec_extra/internal.h> #include <../crypto/trust_token/internal.h> -#include "../third_party/jitterentropy/jitterentropy.h" +#include "../third_party/jitterentropy/jitterentropy-library/jitterentropy.h" #endif // INTERNAL_TOOL #define BM_NAMESPACE bssl