Skip to content

infnoise-provider

build CIFuzz cppcheck CodeQL sanitizers OpenSSF Best Practices OpenSSF Scorecard Coverity Scan SLSA 3 Language: C License: GPL v2+

Infinite Noise TRNG
Photo: leetronics.de

OpenSSL 3.x provider for the Infinite Noise TRNG USB hardware random number generator.

This provider registers an OSSL_OP_RAND seed source backed by the Infinite Noise TRNG, a USB true random number generator based on modular entropy multiplication. When configured as the DRBG seed source, all OpenSSL cryptographic operations (key generation, signatures, TLS handshakes) are seeded with hardware entropy.

Written from scratch for the OpenSSL 3.x Provider API. A legacy ENGINE implementation by Tim Skipper exists at tinskip/infnoise-openssl (dormant since 2020); this provider shares no code with it.

Independent implementation. This project is not affiliated with or endorsed by the upstream Infinite Noise TRNG project (waywardgeek/infnoise) or the vendor I bought it from (https://leetronics.de/en/shop/infinite-noise-trng/).

Alpha software (current tag: v0.0.2-alpha). Passes a 29-test integration harness, four libFuzzer harnesses at 96.1% line coverage, a 24-hour endurance run, and the ASan / UBSan / TSan / allocator-failure sanitiser matrix — but has not been independently audited. Do not use this to seed production key material without your own review. See SECURITY.md for the disclosure policy, docs/Security_Review.txt for the brief prepared for an external reviewer, and docs/TODO.txt for the path to beta.

Requirements

  • OpenSSL 3.x (tested with 3.4+)
  • libinfnoise and its dependency libftdi1. The provider requires a libinfnoise build whose header defines INFNOISE_KECCAK_STATE_SIZE — per-context Keccak/health state and signed-int32_t readData() return. Both patches merged into waywardgeek/infnoise master on 2026-05-15 (#121, #122); any libinfnoise built from upstream master onwards works. The build will fail with a clear #error if linked against an older libinfnoise.
  • Infinite Noise TRNG USB device connected
  • GCC with C11 support
  • pkg-config (used by the Makefile to locate libcrypto and libftdi1)
  • Linux (tested on Arch Linux; should work on any distro with the above)

Arch Linux

# libftdi1 is in the official repos
pacman -S libftdi openssl pkgconf

# libinfnoise from upstream master (carries the required patches as of
# waywardgeek/infnoise#121 and #122).  Distro packages may lag until
# they pick up a release tag containing those commits.
git clone https://github.com/waywardgeek/infnoise /tmp/infnoise
make -C /tmp/infnoise/software -f Makefile.linux libinfnoise.so
sudo make -C /tmp/infnoise/software -f Makefile.linux PREFIX=/usr install-lib
sudo ldconfig

Debian / Ubuntu

apt install libftdi1-dev libssl-dev pkg-config build-essential

# libinfnoise from upstream master, same reason as above.
git clone https://github.com/waywardgeek/infnoise /tmp/infnoise
make -C /tmp/infnoise/software -f Makefile.linux libinfnoise.so
sudo make -C /tmp/infnoise/software -f Makefile.linux PREFIX=/usr install-lib
sudo ldconfig

Building

make

This produces infnoise.so — a hardened shared library (Full RELRO, stack canary, CET/IBT, NX, PIE, stripped).

To install into the OpenSSL modules directory (typically /usr/lib/ossl-modules/):

sudo make install

Optional — build and install the manpage (requires pandoc):

make man
sudo make install-man   # → /usr/share/man/man7/OSSL_PROVIDER-infnoise.7
man OSSL_PROVIDER-infnoise

Configuration

Copy or symlink conf/infnoise-provider.cnf and point OpenSSL at it:

export OPENSSL_CONF=conf/infnoise-provider.cnf

Or append the relevant sections to your system /etc/ssl/openssl.cnf:

[provider_sect]
default = default_sect
infnoise = infnoise_sect

[default_sect]
activate = 1

[infnoise_sect]
module = /usr/lib/ossl-modules/infnoise.so
activate = 1

[random_sect]
seed = infnoise

Verifying the hardware

Confirm the TRNG is detected:

# List USB devices — should show "13-37.org / Infinite Noise TRNG"
lsusb | grep 0403:6015

# Quick test with the infnoise CLI (from upstream package)
infnoise --list-devices

Verify the provider loads and generates entropy:

# Check provider is recognized
openssl list -providers -provider-path /usr/lib/ossl-modules -provider infnoise

# Generate random bytes through the provider
OPENSSL_CONF=conf/infnoise-provider.cnf openssl rand -hex 64

# Statistical quality check (requires ent)
OPENSSL_CONF=conf/infnoise-provider.cnf openssl rand 1000000 | ent

Generate keys using hardware entropy:

OPENSSL_CONF=conf/infnoise-provider.cnf openssl genrsa 4096
OPENSSL_CONF=conf/infnoise-provider.cnf openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256

Testing

The test arsenal:

  • make test — 29-test integration harness across 5 layers (hardware, provider API, integration, statistical, memory safety).
  • make test-asan / test-ubsan / test-valgrind — sanitiser builds against the integration harness.
  • make test-tsan — ThreadSanitizer concurrency stress, 4 threads × 20 000 iterations × 2 scenarios. No hardware needed.
  • make test-allocCRYPTO_set_mem_functions failure injection at four alloc sites. No hardware needed.
  • make fuzz FUZZ_CC=clang — four libFuzzer harnesses (dispatch / ossl_params / spill_oracle / provider_init) under tests/fuzz/. Coverage 294 of 306 lines (96.1%); 23 of 23 functions executed. See docs/Fuzz_Coverage.txt.
  • make test-soak / test-soak-short — 24-hour / 1-hour endurance run through the provider; details below.
  • make lint — cppcheck + gcc -fanalyzer static analysis.
  • make sbom — SPDX-2.3 software bill of materials at sbom.spdx.txt.

See docs/Testing.txt for invocations and the per-layer breakdown.

24-hour endurance run

make test-soak drove EVP_RAND continuously for 24 hours: 14 698 generate calls, 4.21 GiB produced (49.9 KiB/s sustained), 0 errors, 95 instantiate / uninstantiate cycles. RSS peaked at +1.2 MiB and ended 1.0 MiB below start — bounded growth, no leaks.

The two plots below visualise the same entropy stream from two angles. The pair-wise scatter is the most striking: raw TRNG output exposes the Modular Entropy Multiplier's preferred bit states as a regular grid; after Keccak whitening the structure is gone and the byte plane fills uniformly.

24-hour endurance run: pair-wise byte distribution

The byte-value heatmap shows each byte as a coloured pixel (0 black → 255 white). Raw output has warmer clumps where the multiplier favours mid-range values; whitening flattens the texture into uniform fine-grain noise.

24-hour endurance run: byte-value heatmap

These plots show that whitening removes visible structure — statistical uniformity, not min-entropy. A uniform-looking byte plane is necessary but not sufficient for unpredictability; a hash of a counter would look identical. DRBG strength is governed by the seed's measured min-entropy, which is why get_seed sizes seeds by min-entropy (~3 bits per output byte) rather than by how random the output looks. See docs/ARCHITECTURE.txt ("Seed entropy accounting").

USB permissions

By default, the FTDI device requires root access. To use without root, create a udev rule:

# /etc/udev/rules.d/75-infnoise.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6015", \
  GROUP="plugdev", MODE="0664", TAG+="uaccess"

Then reload udev and add your user to the group:

sudo udevadm control --reload-rules
sudo usermod -aG plugdev $USER
# Log out and back in for group change to take effect

Project layout

Path Description
src/infnoise_prov.c Provider implementation
tests/test_infnoise_prov.c Integration test harness (29 tests)
tests/test_infnoise_tsan.c ThreadSanitizer concurrency stress (make test-tsan)
tests/test_infnoise_alloc.c Allocator-failure injection (make test-alloc)
tests/test_infnoise_soak.c 24-hour soak: drives EVP_RAND through every spill-buffer phase, cycles instantiate/uninstantiate, tracks RSS for leaks, dumps rolling samples for ent/rngtest/dieharder
tests/fuzz/ 4 libFuzzer harnesses (see docs/Fuzz_Coverage.txt) plus the mock libinfnoise stub for fuzz and test builds
tests/fuzz/corpus/ Persistent fuzz corpus per harness, committed for replay
tests/fuzz/regressions/ Inputs that triggered fixed bugs, replayed first by CIFuzz
tests/mutation/ + mull.yml Mull mutation-testing harness (release-prep, make mutation)
examples/ Drop-in usage examples (Python keygen, systemd scoping)
conf/infnoise-provider.cnf OpenSSL configuration
conf/openssl.supp Valgrind suppressions
docs/ARCHITECTURE.txt Design decisions and security analysis
docs/Build_Security.txt Binary hardening + runtime security properties
docs/CONTRIBUTING.txt Contribution guidelines
docs/FAQ.txt Common questions
docs/Fuzz_Coverage.txt Per-function fuzz coverage report
docs/Governance.txt Maintainer model, authentication, signing-key plan
docs/OSSL_PROVIDER-infnoise.7.md Pandoc source for the section-7 manpage
docs/Security_Review.txt Brief for an external cryptographic reviewer
docs/Testing.txt Test harness layers and invocations
docs/TODO.txt Deferred work toward beta
.github/ Issue and pull-request templates, CI workflows
.editorconfig Editor style rules
SECURITY.md Vulnerability disclosure policy
CHANGELOG.md Keep-a-Changelog 1.1.0
CODE_OF_CONDUCT.md Contributor Covenant 2.1
CONTRIBUTING.md Shim pointing at docs/CONTRIBUTING.txt
Makefile Build system
LICENSE GPL-2.0-or-later

Security

Full binary hardening (RELRO, stack canary, CET/IBT, NX, PIE, FORTIFY_SOURCE=3, stripped), entropy-buffer cleansing on all paths, secure-heap seed allocation (OPENSSL_secure_mallocmlock'd when the application initialises OpenSSL's secure heap before the first call; see docs/ARCHITECTURE.txt §5), bounded request sizes, and thread-safe dispatch. See docs/Build_Security.txt for the full list and docs/ARCHITECTURE.txt for the design rationale. Vulnerability disclosure: SECURITY.md. Maintainer / signing model: docs/Governance.txt.

Known limitations

  • One open handle per physical device. FTDI USB exclusion applies regardless of provider configuration; multiple EVP_RAND_CTX instances against the same TRNG would race for the device. The provider serialises a single shared context via CRYPTO_RWLOCK.
  • Throughput ~50 KB/s (USB bulk transfer speed bound). Suitable for seeding DRBGs and key generation; not suitable for bulk random data production.

Contributing

Patches, bug reports, and feature proposals are welcome. See docs/CONTRIBUTING.txt for style, build / test expectations, and the security invariants that any change must preserve. All participation is governed by the Code of Conduct.

For suspected vulnerabilities, please follow SECURITY.md rather than opening a public issue.

License

GPL-2.0-or-later. See LICENSE for details.

This provider links OpenSSL (Apache 2.0). Pure GPL-2.0 is incompatible with Apache 2.0; the "or later" clause elevates the effective license to GPL-3.0 at distribution time, which is explicitly Apache-2.0-compatible.

Copyright (C) 2025-2026 Avinash H. Duduskar.

About

OpenSSL 3.x provider for the Infinite Noise hardware TRNG

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages