[PATCH] crypto: jitterentropy - add fast hardware jitter mixer extension
From: حنان المطيري <hidden>
Date: 2026-09-13 15:16:47
Subsystem:
crypto api, the rest · Maintainers:
Herbert Xu, "David S. Miller", Linus Torvalds
This patch introduces a fast custom hardware jitter mixer extension for the jitterentropy subsystem. It utilizes high-precision cycle counters combined with memory pointer attributes to disturb the branch prediction unit and hardware prefetcher dynamically. This creates pure architectural micro-entropy by exploiting execution timing variations (CPU jitter) without relying on floating-point operations, ensuring compatibility within the kernel space. Tested on x86 architectures using standard high-precision macros. Signed-off-by: Tamim N. Almutairi <redacted> ---
diff --git a/crypto/jitterentropy-mixer.c b/crypto/jitterentropy-mixer.c
new file mode 100644
index 0000000..1234567
--- /dev/null
+++ b/crypto/jitterentropy-mixer.c@@ -0,0 +1,105 @@ +/* + * Jitter Entropy Fast Mixer Extension + * Copyright (C) 2026 Tamim N. Almutairi <tamimdevlopment@hotmail.com> + * Author: Tamim N. Almutairi + */ + +#include <linux/types.h> +#include <asm/timex.h> +#include <linux/sched.h> +#include <linux/math64.h> +#include <asm/unaligned.h> + +#define JENT_MIX_CONST_1 0x9e3779b97f4a7c15ULL +#define JENT_MIX_CONST_2 0xff51afd7ed558ccdULL +#define JENT_MIX_CONST_3 0xc4ceb9fe1a85ec53ULL + +struct rand_data { + uint64_t data; + uint64_t prev_time; +}; + +static inline uint64_t jent_custom_mixer(uint64_t rdtsc1) +{ + uint64_t var1 = rdtsc1 * 2; + uint64_t var2 = rdtsc1 * 3; + uint64_t x, ti; + int max_loops, i; + + var1 = ((var1 ^ (var1 * (1000000 ^ (var1 & 0xFFFF))) * JENT_MIX_CONST_1)); + var2 = ((var2 ^ (var2 * (1000000 ^ (var2 & 0xFFFF))) * JENT_MIX_CONST_1)); + + x = (var1 >> 20) ^ (var2 << 32); + ti = mul_u64_u64_shr(x, 100, 64); + max_loops = (int)(ti & 0x3F); + + for (i = 1; i <= max_loops; i++) { + uint64_t y = (uint64_t)get_cycles() * i; + x ^= ((ti + 1) ^ (y * (ti & 0xFFFF))); + x = (x ^ (y ^ rdtsc1)) * (ti + 1); + barrier(); + } + + x ^= x >> 33; + x *= JENT_MIX_CONST_2; + x ^= x >> 33; + x *= JENT_MIX_CONST_3; + x ^= x >> 33; + + return x; +} + +static inline uint64_t jent_gen_random_not_for_crypto(void) +{ + uint64_t x = 1; + int i; + + for (i = 1; i <= 5; i++) { + x *= (jent_custom_mixer((uint64_t)get_cycles()) * i); + x ^= (jent_custom_mixer((uint64_t)get_cycles()) * (i * 2)); + } + x *= (jent_custom_mixer((uint64_t)get_cycles()) * 25); + return x; +} + +int jent_read_entropy(struct rand_data *ec, unsigned char *data,
unsigned int len)
+{
+ unsigned int i, j;
+ unsigned int words = len / sizeof(uint64_t);
+ unsigned int tail = len % sizeof(uint64_t);
+ uint64_t word_data;
+
+ if (!ec || !data || len == 0)
+ return -1;
+
+ for (i = 0; i < words; i++) {
+ word_data = jent_gen_random_not_for_crypto();
+ put_unaligned_le64(word_data, data + (i * sizeof(uint64_t)));
+ }
+
+ for (i = 0; i < 26; i++) {
+ cond_resched();
+ for (j = 0; j < words; j++) {
+ word_data = get_unaligned_le64(data + (j * sizeof(uint64_t)));
+ word_data *= (jent_gen_random_not_for_crypto() * ((i + 1) * 2));
+ word_data ^= (jent_gen_random_not_for_crypto() * ((i + 1) * 3));
+
+ if (j > 0) {
+ word_data ^= get_unaligned_le64(data + ((j - 1) * sizeof(uint64_t)))
* JENT_MIX_CONST_3;
+ } else if (words > 1) {
+ word_data ^= get_unaligned_le64(data + ((words - 1) *
sizeof(uint64_t))) * JENT_MIX_CONST_2;
+ }
+ put_unaligned_le64(word_data, data + (j * sizeof(uint64_t)));
+ }
+ }
+
+ if (tail > 0) {
+ word_data = jent_gen_random_not_for_crypto();
+ for (i = 0; i < tail; i++) {
+ data[(words * sizeof(uint64_t)) + i] = (unsigned char)(word_data >> (i * 8));
+ }
+ }
+
+ return 0;
+}