From 5ea033566bf44ff3907502d1d1c35b10d98791b7 Mon Sep 17 00:00:00 2001 From: "Matthias J. Kannwischer" Date: Mon, 28 Oct 2024 11:13:36 +0800 Subject: [PATCH] remove randombytes.c and add notrandombytes.c This removes our current randombytes() implementation and replaces it with a deterministic randombytes() based on surf (https://cr.yp.to/hash.html#surf). Resolves #260. As per pq-code-package/tsc#86, the consensus of the PQCP TCP is that a secure implementation of randombytes() should be provided by the software consuming code from the PQCP. For testing, we should use a deterministic randombytes() that no one is going to put into a production system. I propose to use the popular implementation by Daniel J. Bernstein based on surf (https://cr.yp.to/hash.html#surf). This implementation is clearly not secure which hopefully decreases the risk of someone just taking it. I called it notrandombytes.c and moved it into the test folder to decrease the risk of misuse. Signed-off-by: Matthias J. Kannwischer --- mk/crypto.mk | 4 +- randombytes/randombytes.c | 91 ------------------- test/notrandombytes/notrandombytes.c | 78 ++++++++++++++++ .../notrandombytes}/randombytes.h | 0 4 files changed, 80 insertions(+), 93 deletions(-) delete mode 100644 randombytes/randombytes.c create mode 100644 test/notrandombytes/notrandombytes.c rename {randombytes => test/notrandombytes}/randombytes.h (100%) diff --git a/mk/crypto.mk b/mk/crypto.mk index 13d777f7e..2425b6f47 100644 --- a/mk/crypto.mk +++ b/mk/crypto.mk @@ -12,7 +12,7 @@ ifeq ($(RNG),NISTRNG) else LIBDEPS += $(LIB_DIR)/librng.a LDLIBS += -lrng - CPPFLAGS += -Irandombytes + CPPFLAGS += -Itest/notrandombytes endif FIPS202_SRCS = $(wildcard fips202/*.c) @@ -21,7 +21,7 @@ ifeq ($(OPT),1) CPPFLAGS += -DMLKEM_USE_NATIVE endif -$(LIB_DIR)/librng.a: $(call OBJS,$(wildcard randombytes/*.c)) +$(LIB_DIR)/librng.a: $(call OBJS,$(wildcard test/notrandombytes/*.c)) $(LIB_DIR)/libnistrng.a: CFLAGS += -Wno-unused-result -O3 -fomit-frame-pointer $(LIB_DIR)/libnistrng.a: $(call OBJS,$(wildcard test/nistrng/*.c)) diff --git a/randombytes/randombytes.c b/randombytes/randombytes.c deleted file mode 100644 index a4fc837f4..000000000 --- a/randombytes/randombytes.c +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -#if defined(__linux__) -#if !defined(_GNU_SOURCE) -/* Ensure that syscall() is declared even when compiling with -std=c99 */ -#define _GNU_SOURCE -#endif -#endif - -#include "randombytes.h" -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#else -#include -#include -#include -#include -#endif - -#ifdef _WIN32 -void randombytes(uint8_t *out, size_t outlen) { - HCRYPTPROV ctx; - size_t len; - - if (!CryptAcquireContext(&ctx, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - abort(); - } - - while (outlen > 0) { - len = (outlen > 1048576) ? 1048576 : outlen; - if (!CryptGenRandom(ctx, len, (BYTE *)out)) { - abort(); - } - - out += len; - outlen -= len; - } - - if (!CryptReleaseContext(ctx, 0)) { - abort(); - } -} -#elif defined(__linux__) && defined(SYS_getrandom) -void randombytes(uint8_t *out, size_t outlen) { - ssize_t ret; - - while (outlen > 0) { - ret = syscall(SYS_getrandom, out, outlen, 0); - if (ret == -1 && errno == EINTR) { - continue; - } else if (ret == -1) { - abort(); - } - - out += ret; - outlen -= ret; - } -} -#else -void randombytes(uint8_t *out, size_t outlen) { - static int fd = -1; - ssize_t ret; - - while (fd == -1) { - fd = open("/dev/urandom", O_RDONLY); - if (fd == -1 && errno == EINTR) { - continue; - } else if (fd == -1) { - abort(); - } - } - - while (outlen > 0) { - ret = read(fd, out, outlen); - if (ret == -1 && errno == EINTR) { - continue; - } else if (ret == -1) { - abort(); - } - - out += ret; - outlen -= ret; - } -} -#endif diff --git a/test/notrandombytes/notrandombytes.c b/test/notrandombytes/notrandombytes.c new file mode 100644 index 000000000..9636cbb45 --- /dev/null +++ b/test/notrandombytes/notrandombytes.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: LicenseRef-PD-hp OR CC0-1.0 OR 0BSD OR MIT-0 OR MIT +// Based on https://cr.yp.to/papers.html#surf by Daniel. J. Bernstein + +/** + * WARNING + * + * The randombytes() implementation in this file is for TESTING ONLY. + * You MUST NOT use this implementation outside of testing. + * + */ + +#include +#include "randombytes.h" + +static uint32_t seed[32] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, + 2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3, 2, 7, 9, 5}; +static uint32_t in[12]; +static uint32_t out[8]; +static int32_t outleft = 0; + +#define ROTATE(x, b) (((x) << (b)) | ((x) >> (32 - (b)))) +#define MUSH(i, b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x, b)); + +static void surf(void) { + uint32_t t[12]; + uint32_t x; + uint32_t sum = 0; + int32_t r; + int32_t i; + int32_t loop; + + for (i = 0; i < 12; ++i) { + t[i] = in[i] ^ seed[12 + i]; + } + for (i = 0; i < 8; ++i) { + out[i] = seed[24 + i]; + } + x = t[11]; + for (loop = 0; loop < 2; ++loop) { + for (r = 0; r < 16; ++r) { + sum += 0x9e3779b9; + MUSH(0, 5) + MUSH(1, 7) + MUSH(2, 9) + MUSH(3, 13) + MUSH(4, 5) + MUSH(5, 7) + MUSH(6, 9) + MUSH(7, 13) + MUSH(8, 5) + MUSH(9, 7) + MUSH(10, 9) + MUSH(11, 13) + } + for (i = 0; i < 8; ++i) { + out[i] ^= t[i + 4]; + } + } +} + +void randombytes(uint8_t *buf, size_t n) { + while (n > 0) { + if (!outleft) { + if (!++in[0]) { + if (!++in[1]) { + if (!++in[2]) { + ++in[3]; + } + } + } + surf(); + outleft = 8; + } + *buf = (uint8_t)out[--outleft]; + ++buf; + --n; + } +} diff --git a/randombytes/randombytes.h b/test/notrandombytes/randombytes.h similarity index 100% rename from randombytes/randombytes.h rename to test/notrandombytes/randombytes.h