Files
palladum-lightning/common/randbytes.c
Rusty Russell 2086699b70 common: add randbytes() wrapper to override cryptographic entropy: $CLN_DEV_ENTROPY_SEED
Only in developer mode, ofc.

Notes:
1. We have to move the initialization before the lightningd main trace_start,
   since that uses pseudorand().
2. To make the results stable, we need to use per-caller values to randbytes().
   Otherwise external timing changes the call order.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-13 21:21:29 +10:30

63 lines
1.4 KiB
C

#include "config.h"
#include <assert.h>
#include <ccan/crypto/siphash24/siphash24.h>
#include <ccan/endian/endian.h>
#include <ccan/tal/tal.h>
#include <common/memleak.h>
#include <common/pseudorand.h>
#include <common/randbytes.h>
#include <common/utils.h>
#include <sodium/randombytes.h>
#include <stdlib.h>
#include <unistd.h>
static bool used = false;
static u64 dev_seed = 0;
bool randbytes_overridden(void)
{
return dev_seed != 0;
}
void randbytes_(void *bytes, size_t num_bytes, u64 *offset)
{
static u64 offset_init;
be64 pattern;
used = true;
if (!randbytes_overridden()) {
randombytes_buf(bytes, num_bytes); /* discouraged: use randbytes() */
return;
}
/* First time, start callers at different offsets */
if (*offset == 0) {
*offset = offset_init;
offset_init += 1000;
}
/* Somewhat recognizable pattern */
pattern = cpu_to_be64(dev_seed + (*offset)++);
for (size_t i = 0; i < num_bytes; i += sizeof(pattern)) {
size_t copy = num_bytes - i;
if (copy > sizeof(pattern))
copy = sizeof(pattern);
memcpy((u8 *)bytes + i, &pattern, copy);
}
}
/* We want different seeds for each plugin (hence argv0), and for each
* lightmingd instance, (hence seed from environment) */
void dev_override_randbytes(const char *argv0, long int seed)
{
struct siphash_seed hashseed;
assert(!used);
hashseed.u.u64[0] = seed;
hashseed.u.u64[1] = 0;
dev_seed = siphash24(&hashseed, argv0, strlen(argv0));
assert(randbytes_overridden());
}