From eb18ce3283dd67014e4b63d009cbbce83d6d9eb0 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 16 Oct 2020 12:06:57 +0100 Subject: [PATCH] plat/arm: juno: Condition Juno entropy source with CRC instructions The Juno Trusted Entropy Source has a bias, which makes the generated raw numbers fail a FIPS 140-2 statistic test. To improve the quality of the numbers, we can use the CPU's CRC instructions, which do a decent job on conditioning the bits. This adds a *very* simple version of arm_acle.h, which is typically provided by the compiler, and contains the CRC instrinsics definitions we need. We need the original version by using -nostdinc. Change-Id: I83d3e6902d6a1164aacd5060ac13a38f0057bd1a Signed-off-by: Andre Przywara --- include/lib/libc/arm_acle.h | 22 ++++++++++++++++++++++ plat/arm/board/juno/juno_trng.c | 17 ++++++++++------- plat/arm/board/juno/platform.mk | 6 ++++++ 3 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 include/lib/libc/arm_acle.h diff --git a/include/lib/libc/arm_acle.h b/include/lib/libc/arm_acle.h new file mode 100644 index 000000000..953933f1d --- /dev/null +++ b/include/lib/libc/arm_acle.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 ARM Limited + * + * SPDX-License-Identifier: BSD-3-Clause + * + * The definitions below are a subset of what we would normally get by using + * the compiler's version of arm_acle.h. We can't use that directly because + * we specify -nostdinc in the Makefiles. + * + * We just define the functions we need so far. + */ + +#ifndef ARM_ACLE_H +#define ARM_ACLE_H + +#if !defined(__aarch64__) || defined(__clang__) +# define __crc32w __builtin_arm_crc32w +#else +# define __crc32w __builtin_aarch64_crc32w +#endif + +#endif /* ARM_ACLE_H */ diff --git a/plat/arm/board/juno/juno_trng.c b/plat/arm/board/juno/juno_trng.c index b38e49f45..1af6deb72 100644 --- a/plat/arm/board/juno/juno_trng.c +++ b/plat/arm/board/juno/juno_trng.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include #include @@ -35,6 +36,8 @@ static bool output_valid(void) return false; /* No output data available. */ } +static uint32_t crc_value = ~0U; + /* * This function fills `buf` with 8 bytes of entropy. * It uses the Trusted Entropy Source peripheral on Juno. @@ -69,14 +72,14 @@ bool juno_getentropy(uint64_t *buf) return false; } - /* XOR each two 32-bit registers together, combine the pairs */ - ret = mmio_read_32(TRNG_BASE + 0); - ret ^= mmio_read_32(TRNG_BASE + 4); - ret <<= 32; + /* CRC each two 32-bit registers together, combine the pairs */ + crc_value = __crc32w(crc_value, mmio_read_32(TRNG_BASE + 0)); + crc_value = __crc32w(crc_value, mmio_read_32(TRNG_BASE + 4)); + ret = (uint64_t)crc_value << 32; - ret |= mmio_read_32(TRNG_BASE + 8); - ret ^= mmio_read_32(TRNG_BASE + 12); - *buf = ret; + crc_value = __crc32w(crc_value, mmio_read_32(TRNG_BASE + 8)); + crc_value = __crc32w(crc_value, mmio_read_32(TRNG_BASE + 12)); + *buf = ret | crc_value; /* Acknowledge current cycle, clear output registers. */ mmio_write_32(TRNG_BASE + TRNG_STATUS, 1); diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index 61cfb610c..537352c5a 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -164,6 +164,12 @@ ifeq (${ALLOW_RO_XLAT_TABLES}, 1) endif endif +BL1_CPPFLAGS += -march=armv8-a+crc +BL2_CPPFLAGS += -march=armv8-a+crc +BL2U_CPPFLAGS += -march=armv8-a+crc +BL31_CPPFLAGS += -march=armv8-a+crc +BL32_CPPFLAGS += -march=armv8-a+crc + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts \ plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts