From 8bb4b0ad5f7cb7b439ab4580d00238b3c17c4a02 Mon Sep 17 00:00:00 2001 From: "Matthias J. Kannwischer" Date: Fri, 29 Mar 2024 07:15:21 -0400 Subject: [PATCH] Add stack benchmarks (#10) * add stack benchmarks Signed-off-by: Matthias J. Kannwischer * format Signed-off-by: Matthias J. Kannwischer * change ldscript generation to make stack benchmarks work Signed-off-by: Matthias J. Kannwischer * update CI to check correct number of OKs Signed-off-by: Matthias J. Kannwischer --------- Signed-off-by: Matthias J. Kannwischer --- .github/workflows/build.yaml | 4 +- Makefile | 3 +- hal/devices.data | 3 ++ mk/opencm3.mk | 2 +- mk/schemes.mk | 7 +++ test/stack.c | 95 ++++++++++++++++++++++++++++++++++++ 6 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 hal/devices.data create mode 100644 test/stack.c diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index abe5ca2..c4db7c1 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -67,7 +67,9 @@ jobs: # check if num of ok is as expected if [[ "$file" == *"test"* ]]; then expect=$((tests*3)) - elif [[ "$file" == *"speed"* ]] then + elif [[ "$file" == *"stack"* ]]; then + expect=1 + else expect=$tests fi diff --git a/Makefile b/Makefile index b92e224..c46aacd 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ .PHONY: all -all: test speed +all: test speed stack include mk/config.mk @@ -12,6 +12,7 @@ include mk/rules.mk test: $(foreach scheme,$(KEM_SCHEMES),$(scheme)-test) speed: $(foreach scheme,$(KEM_SCHEMES),$(scheme)-speed) +stack: $(foreach scheme,$(KEM_SCHEMES),$(scheme)-stack) .PHONY: emulate clean libclean diff --git a/hal/devices.data b/hal/devices.data new file mode 100644 index 0000000..4d49226 --- /dev/null +++ b/hal/devices.data @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 +stm32f407vg stm32f4 ROM=1024K RAM=128K +stm32f4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 \ No newline at end of file diff --git a/mk/opencm3.mk b/mk/opencm3.mk index e9f7f81..febcc5a 100644 --- a/mk/opencm3.mk +++ b/mk/opencm3.mk @@ -16,7 +16,7 @@ ifeq ($(DEVICE),) $(warning no DEVICE specified for linker script generator) endif -DEVICES_DATA ?= $(OPENCM3_DIR)/ld/devices.data +DEVICES_DATA ?= hal/devices.data genlink_family :=$(shell $(OPENCM3_DIR)/scripts/genlink.py $(DEVICES_DATA) $(DEVICE) FAMILY) genlink_subfamily :=$(shell $(OPENCM3_DIR)/scripts/genlink.py $(DEVICES_DATA) $(DEVICE) SUBFAMILY) diff --git a/mk/schemes.mk b/mk/schemes.mk index 702e1a1..7303fb3 100644 --- a/mk/schemes.mk +++ b/mk/schemes.mk @@ -10,11 +10,15 @@ $(1)-test: bin/$(1)-test.hex $(1)-speed: CPPFLAGS += -DKYBER_K=$(2) -DMUPQ_NAMESPACE=$$(MUPQ_NAMESPACE) -DNTESTS=$$(NTESTS) $(1)-speed: bin/$(1)-speed.hex + +$(1)-stack: CPPFLAGS += -DKYBER_K=$(2) -DMUPQ_NAMESPACE=$$(MUPQ_NAMESPACE) +$(1)-stack: bin/$(1)-stack.hex endef define scheme-elf elf/$(1)-test.elf: obj/test/$(1)-test.o $(call OBJS,$(1)) $(LINKDEPS) elf/$(1)-speed.elf: obj/test/$(1)-speed.o $(call OBJS,$(1)) $(LINKDEPS) +elf/$(1)-stack.elf: obj/test/$(1)-stack.o $(call OBJS,$(1)) $(LINKDEPS) endef define compile-obj @@ -34,6 +38,9 @@ obj/test/$(1)-test.o: test/test.c obj/test/$(1)-speed.o: test/speed.c $$(compile-obj) + +obj/test/$(1)-stack.o: test/stack.c + $$(compile-obj) endef # iterate over schemes and params to generate targets for functional test and speed benchmark diff --git a/test/stack.c b/test/stack.c new file mode 100644 index 0000000..3fb6033 --- /dev/null +++ b/test/stack.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: Apache-2.0 or CC0-1.0 +#include "kem.h" +#include "randombytes.h" +#include "hal.h" +#include "sendfn.h" + +#include + +#ifndef MAX_STACK_SIZE +#define MAX_STACK_SIZE hal_get_stack_size() +#endif + +#ifndef STACK_SIZE_INCR +#define STACK_SIZE_INCR 0x1000 +#endif + +// https://stackoverflow.com/a/1489985/1711232 +#define PASTER(x, y) x##y +#define EVALUATOR(x, y) PASTER(x, y) +#define NAMESPACE(fun) EVALUATOR(MUPQ_NAMESPACE, fun) + +// use different names so we can have empty namespaces +#define MUPQ_CRYPTO_BYTES NAMESPACE(CRYPTO_BYTES) +#define MUPQ_CRYPTO_PUBLICKEYBYTES NAMESPACE(CRYPTO_PUBLICKEYBYTES) +#define MUPQ_CRYPTO_SECRETKEYBYTES NAMESPACE(CRYPTO_SECRETKEYBYTES) +#define MUPQ_CRYPTO_CIPHERTEXTBYTES NAMESPACE(CRYPTO_CIPHERTEXTBYTES) +#define MUPQ_CRYPTO_ALGNAME NAMESPACE(CRYPTO_ALGNAME) + +#define MUPQ_crypto_kem_keypair NAMESPACE(crypto_kem_keypair) +#define MUPQ_crypto_kem_enc NAMESPACE(crypto_kem_enc) +#define MUPQ_crypto_kem_dec NAMESPACE(crypto_kem_dec) + +#define send_stack_usage(S, U) send_unsigned((S), (U)) + +unsigned int canary_size; +volatile unsigned char *p; +unsigned int c; +uint8_t canary = 0x42; + +unsigned char key_a[MUPQ_CRYPTO_BYTES], key_b[MUPQ_CRYPTO_BYTES]; +unsigned char pk[MUPQ_CRYPTO_PUBLICKEYBYTES]; +unsigned char sendb[MUPQ_CRYPTO_CIPHERTEXTBYTES]; +unsigned char sk_a[MUPQ_CRYPTO_SECRETKEYBYTES]; +unsigned int stack_key_gen, stack_encaps, stack_decaps; + +#define FILL_STACK() \ + p = &a; \ + while (p > &a - canary_size) \ + *(p--) = canary; +#define CHECK_STACK() \ + c = canary_size; \ + p = &a - canary_size + 1; \ + while (*p == canary && p < &a) { \ + p++; \ + c--; \ + } + +static int test_keys(void) { + // Alice generates a public key + hal_spraystack(); + MUPQ_crypto_kem_keypair(pk, sk_a); + stack_key_gen = hal_checkstack(); + + // Bob derives a secret key and creates a response + hal_spraystack(); + MUPQ_crypto_kem_enc(sendb, key_b, pk); + stack_encaps = hal_checkstack(); + + // Alice uses Bobs response to get her secret key + hal_spraystack(); + MUPQ_crypto_kem_dec(key_a, sendb, sk_a); + stack_decaps = hal_checkstack(); + + if (memcmp(key_a, key_b, MUPQ_CRYPTO_BYTES)) { + return -1; + } else { + send_stack_usage("keypair stack usage:", stack_key_gen); + send_stack_usage("encaps stack usage:", stack_encaps); + send_stack_usage("decaps stack usage:", stack_decaps); + hal_send_str("OK KEYS\n"); + return 0; + } +} + +int main(void) { + hal_setup(CLOCK_FAST); + + // marker for automated benchmarks + hal_send_str("=========================="); + test_keys(); + // marker for automated benchmarks + hal_send_str("#"); + + return 0; +}