JITTERENTROPY(3)

πŸ“¦
version 3.7.0 Β· 4 versions
, in arch rolling, centos-stream 10, centos-stream 9, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable

πŸŽ€ NAME πŸŽ€

jitterentropy β€” the CPU Jitter Random Number Generator. yes bestie, that's the whole vibe: your CPU is out here being chaotic and we're collecting that chaos as entropy πŸ’–


✨ SYNOPSIS ✨

okay so here's literally every way you can talk to this library:

#include <jitterentropy.h>

int jent_entropy_switch_notime_impl(struct jent_notime_thread *new_thread);

int jent_set_fips_failure_callback(jent_fips_failure_cb cb);

int jent_entropy_init(void);

int jent_entropy_init_ex(unsigned int osr, unsigned int flags);

struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
                                               unsigned int flags);

void jent_entropy_collector_free(struct rand_data *entropy_collector);

ssize_t jent_read_entropy(struct rand_data *entropy_collector,
                          char *data, size_t len);

ssize_t jent_read_entropy_safe(struct rand_data **entropy_collector,
                               char *data, size_t len);

#define JENT_MAJVERSION x

#define JENT_MINVERSION y

#define JENT_PATCHLEVEL z

#define JENT_VERSION (...)

unsigned int jent_version(void);

πŸ’« DESCRIPTION πŸ’«

so the jitterentropy library gives you a source of good entropy by collecting CPU executing time jitter. basically the CPU can't do the exact same thing in the exact same amount of time twice, and that wobble? that's the good stuff πŸ¦‹. The entropy hiding in that CPU execution time jitter gets magnified by the CPU Jitter Random Number Generator. And the CPU Jitter Random Number Generator takes that CPU execution timing jitter and turns it into a bit stream that complies with different statistical measurements which determine that the bit stream is random. slay.

The CPU Jitter Random Number Generator delivers entropy that 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. one for one, no inflation, no cap πŸ’…

and here's the best part: 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 /dev/random or /dev/urandom. no middleman, we generate our own destiny ✨


jent_entropy_switch_notime_impl() lets the caller set a thread handler that the Jitter RNG uses if it operates in the timer-less mode. go look at jitterentropy.h for the documentation of new_thread. And listen: this function must be called before jent_entropy_init(), because after that call, the change of the thread handler is denied. periodt. πŸ™ˆ


jent_set_fips_failure_callback() lets the caller set a callback that gets invoked by the Jitter RNG when a health test failure is detected. The callback you specify with the parameter cb to the API function receives the Jitter RNG state with the parameter ec and the FIPS health test failure with the parameter health_failure. This function also must be called before jent_entropy_init() β€” after that call, the change of the callback is denied. same energy, same rule πŸŽ€


jent_entropy_init() initializes the CPU Jitter Random Number Generator. It runs statistical tests to verify that the underlying system offers the properties needed for measuring and collecting entropy. If the initialization is successful β€” which means the statistical tests indicate the underlying system is appropriate β€” the call returns with 0.

A return code other than 0 indicates a failure where the calling application MUST NOT use the CPU Jitter Random Number Generator. Also note that, specifically the error codes ERCT and EHEALTH indicate a health test failure. 😭

jent_entropy_init_ex() behaves identically to jent_entropy_init() except it lets the caller provide the osr and flags parameters, which should be identical to the subsequent invocation of jent_entropy_collector_alloc(). When you specify an oversampling rate osr different than the default, the startup test honors this value and adjusts the self-test cut-off thresholds to the same values as used at runtime. consistency, we love her πŸ‘‘


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 NULL. It needs two arguments: the oversampling rate osr and a set of flags with flags. The osr value defines how much oversampling the entropy collector performs. Usually a caller wants to give the value 0 here to apply the default oversampling. The call ensures that any value lower than JENT_MIN_OSR is converted to JENT_MIN_OSR automatically. so if you under-ask, she just bumps you up, no drama 🫢

The flags value is either zero or one or more of the following flags.

🌸 the flags, bestie 🌸

  • 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. So disabling memory accesses and relying only on the CPU complexity should only be done if you really know what you are doing. πŸ”₯
fr fr, this one is not a casual toggle. it's giving "i read the source code for fun" energy.
  • 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 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 entropy_collector data structure. πŸ’…
  • 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 JENT_FORCE_INTERNAL_TIMER this is treated as an error and the allocation returns NULL. Also, in case jent_entropy_init() detects that the internal timer shall be used but the disable flag is set, the allocation returns NULL. conflicting vibes = instant rejection πŸ’€
  • JENT_FORCE_FIPS β€” Force full FIPS 140 and SP800-90B compliance irrespective of the FIPS setting of the underlying operating system.
  • JENT_NTG1 β€” Enable the BSI AIS 20/31 v3.0 NTG.1 compliant behavior. πŸ‡©πŸ‡ͺ✨
  • 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.

jent_entropy_collector_free() zeroizes and frees the given CPU Jitter entropy collector instance. clean up after yourself, it's the bare minimum 🧚


jent_read_entropy() generates a random bit stream and returns it to the caller. entropy_collector is the CPU Jitter entropy collector instance which shall be used to obtain random numbers. data is the destination memory location where the random bit stream is written to β€” and that memory must have already been allocated by the caller. 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 data is at least as big as len indicates. πŸ‘‘

The function returns the number of bytes generated when the request is successfully completed. And now the error codes, listen closely bestie:

  • -1 β€” the caller handed in a non-initialized (i.e. NULL value) for the entropy collector.
  • -2 β€” the SP800-90B repetition count online health test failed.
  • -3 β€” the SP800-90B adaptive proportion online health test failed.
  • -4 β€” the internal timer generator cannot be initialized.
  • -5 β€” the LAG predictor health test failed.
  • -6 β€” the Repetitive Count Test (RCT) failed permanently.
  • -7 β€” the Adaptive Proportion Test (APT) failed permanently.
  • -8 β€” the LAG prediction test failed permanently.

When either online health test fails, the Jitter RNG will not have any data provided in data. The entropy collector instance will remain in an error state. To recover, the entropy collector instance MUST be deallocated and a fresh instance must be allocated. It is recommended that you increase the osr value at least by one when newly allocating the Jitter RNG with 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. 🩹

so basically: health test said no β†’ throw the whole collector away β†’ come back with a bigger osr. it's giving "we don't fix, we replace" 😭

jent_read_entropy_safe() is a service function to β€” and therefore operates identically to β€” 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.

Note the function returns with a 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. 🚨

The function jent_read_entropy_safe() has the same error codes as jent_read_entropy().


🌈 the version numbers, because they MATTER 🌈

  • JENT_MAJVERSION β€” indicates API / ABI incompatible changes, functional changes that require the consumer to be updated. big changes, everybody update πŸ’…
  • JENT_MINVERSION β€” indicates API compatible, ABI may change, functional enhancements only, consumer can be left unchanged if enhancements are not considered.
  • 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. πŸŽ€
  • 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.
  • jent_version() β€” returns JENT_VERSION. that's it. that's the function. short queen ⭐

and that's part one, bestie β€” there's more coming, so stay tuned πŸ’–


🌈 FIPS 140-3 Considerations 🌈

okay so if you want your Jitter RNG to actually be FIPS 140-3 compliant β€” and like, by extension SP800-90B and SP800-90C compliant too β€” there's a whole checklist bestie. Do not skip steps. πŸ’…

✨ Enable FIPS mode ✨

You turn FIPS mode on by passing the JENT_FORCE_FIPS flag when you initialize the Jitter RNG library. That's the move. 🫢

And on Linux? The FIPS mode gets enabled transparently if the whole operating system was booted in FIPS mode β€” usually that means someone used the "fips=1" Linux kernel command line parameter. So like, if the OS is already in its FIPS era, you're covered. πŸ‘‘

✨ Perform heursitic entropy analysis ✨

The test tool set that ships as part of the Jitter RNG library source distribution has a helper that grabs raw noise data both at runtime and at initialization time, so you can calculate the SP800-90B entropy rate. πŸ“Š

That rate has to be above 0.333 β€” that's the implied heuristic minimum of the Jitter RNG library. Below that? Not the vibe. 😭

✨ Resolve insufficient entropy ✨

If the SP800-90B analysis says your entropy is not enough, no worries β€” the test tool set also has a helper that analyzes the optimal settings. Check the test tool set for raw entropy for the deets. πŸ”

The configuration values you get out of that are expected to be used with the flags parameter of the calls jent_entropy_collector_alloc() and jent_entropy_init_ex(). And honestly? It's recommended that you use the jent_read_entropy_safe() API call for generating random numbers. That's the main character move. ⭐


πŸ“ NOTES πŸ“

So aside from just using the generated random bit stream directly for cryptographic operations, you can also use the output of jent_read_entropy() for seeding a deterministic random number generator. Two uses, one icon. πŸ’–


πŸ‘€ SEE ALSO πŸ‘€

  • http://www.chronox.de β€” it's got the design description, the entropy and statistical analyses, and a whole bunch of test cases. Go look, fr fr. πŸ¦‹

and that's the whole page bestie!! 🌸 this edition of JITTERENTROPY(3) is dated 2021-03-08 β€” manifesting that date for you and your entropy forever, mwah πŸ’œπŸŽ€

πŸ“¦ where this page comes from