From 07613d80b80a521849d71b2dc1e281b2311ff4bf Mon Sep 17 00:00:00 2001 From: Filippo Cremonese Date: Sun, 9 Feb 2020 22:06:10 +0100 Subject: [PATCH] Added fuzzer target --- fido2/version.c | 10 ++- fuzz/Makefile | 39 +++++++++ fuzz/app.h | 43 ++++++++++ fuzz/fuzztarget.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 fuzz/Makefile create mode 100644 fuzz/app.h create mode 100644 fuzz/fuzztarget.c diff --git a/fido2/version.c b/fido2/version.c index d8c2252e..2af6914b 100644 --- a/fido2/version.c +++ b/fido2/version.c @@ -1,12 +1,20 @@ #include "version.h" - +#ifndef FUZZING const version_t firmware_version __attribute__ ((section (".flag"))) __attribute__ ((__used__)) = { .major = SOLO_VERSION_MAJ, .minor = SOLO_VERSION_MIN, .patch = SOLO_VERSION_PATCH, .reserved = 0 }; +#else +const version_t firmware_version __attribute__ ((__used__)) = { + .major = SOLO_VERSION_MAJ, + .minor = SOLO_VERSION_MIN, + .patch = SOLO_VERSION_PATCH, + .reserved = 0 +}; +#endif // from tinycbor, for a quick static_assert #include diff --git a/fuzz/Makefile b/fuzz/Makefile new file mode 100644 index 00000000..2e12fd74 --- /dev/null +++ b/fuzz/Makefile @@ -0,0 +1,39 @@ +CC=afl-gcc +OPTLEVEL=2 + +#define uECC_arch_other 0 +#define uECC_x86 1 +#define uECC_x86_64 2 +#define uECC_arm 3 +#define uECC_arm_thumb 4 +#define uECC_arm_thumb2 5 +#define uECC_arm64 6 +#define uECC_avr 7 +ecc_platform=2 + +CFLAGS = -O$(OPTLEVEL) -fdata-sections -ffunction-sections -g +ECC_CFLAGS = -O$(OPTLEVEL) -fdata-sections -ffunction-sections -DuECC_PLATFORM=$(ecc_platform) + +INCLUDES = -I../fido2/ -I../tinycbor/src -I../fuzz + +CFLAGS += $(INCLUDES) +CFLAGS += -DAES256=1 -DSOLO_EXPERIMENTAL=1 -DDEBUG_LEVEL=1 + +LIBS = ../fido2/libsolo.a ../tinycbor/lib/libtinycbor.a + + +.PHONY: libsolo libcbor clean + +fuzztarget: libsolo libcbor + $(CC) $(CFLAGS) $(INCLUDES) -o $@ $(@).c $(LIBS) + +libsolo: + cd ../fido2/ && $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)" ECC_CFLAGS="$(ECC_CFLAGS)" APP_CONFIG=app.h -j8 + +libcbor: + cd ../tinycbor/ && $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS='' -j8 + +clean: + rm fuzztarget + cd ../tinycbor/ && $(MAKE) clean + cd ../fido2/ && $(MAKE) clean diff --git a/fuzz/app.h b/fuzz/app.h new file mode 100644 index 00000000..b5e8bd2b --- /dev/null +++ b/fuzz/app.h @@ -0,0 +1,43 @@ +// Copyright 2019 SoloKeys Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#ifndef SRC_APP_H_ +#define SRC_APP_H_ +#include + +#define USING_DEV_BOARD + +#define USING_PC + +#define DEBUG_LEVEL 1 + +#define ENABLE_U2F +#define ENABLE_U2F_EXTENSIONS +//#define BRIDGE_TO_WALLET + +void printing_init(); + +extern bool use_udp; + +// 0xRRGGBB +#define LED_INIT_VALUE 0x000800 +#define LED_WINK_VALUE 0x000008 +#define LED_MAX_SCALER 30 +#define LED_MIN_SCALER 1 +// # of ms between each change in LED +#define HEARTBEAT_PERIOD 100 +// Each LED channel will be multiplied by a integer between LED_MAX_SCALER +// and LED_MIN_SCALER to cause the slow pulse. E.g. +// #define LED_INIT_VALUE 0x301000 +// #define LED_MAX_SCALER 30 +// #define LED_MIN_SCALER 1 +// #define HEARTBEAT_PERIOD 8 +// Will pulse from 0x301000 to 0x903000 to 0x301000 ... +// Which will take ~8 * (30)*2 ms + + +#endif /* SRC_APP_H_ */ diff --git a/fuzz/fuzztarget.c b/fuzz/fuzztarget.c new file mode 100644 index 00000000..d79da32e --- /dev/null +++ b/fuzz/fuzztarget.c @@ -0,0 +1,197 @@ +// Copyright 2019 SoloKeys Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. +#include +#include +#include +#include +#include +#include + +#include "cbor.h" +#include "device.h" +#include "ctaphid.h" +//#include "bsp.h" +#include "util.h" +#include "log.h" +#include "ctap.h" +#include "app.h" + +#define FUZZBUF_SZ 512 +#define HIDMSG_SZ 64 +#define STDIN 0 +#define RK_NUM 50 + +const char * state_file = "authenticator_state.bin"; +const char * rk_file = "resident_keys.bin"; + +struct ResidentKeyStore { + CTAP_residentKey rks[RK_NUM]; +} RK_STORE; + + +uint32_t millis() { return 0; } +void usbhid_send(uint8_t *msg) { return; } + +static void sync_rk() +{ + FILE * f = fopen(rk_file, "wb+"); + if (f== NULL) + { + perror("fopen"); + exit(1); + } + + int ret = fwrite(&RK_STORE, 1, sizeof(RK_STORE), f); + fclose(f); + if (ret != sizeof(RK_STORE)) + { + perror("fwrite"); + exit(1); + } +} + +void authenticator_initialize() +{ + uint8_t header[16]; + FILE * f; + int ret; + uint8_t * mem; + if (access(state_file, F_OK) != -1) + { + // printf("state file exists\n"); + f = fopen(state_file, "rb"); + if (f== NULL) + { + perror("fopen"); + exit(1); + } + + ret = fread(header, 1, sizeof(header), f); + fclose(f); + if(ret != sizeof(header)) + { + perror("fwrite"); + exit(1); + } + + // resident_keys + f = fopen(rk_file, "rb"); + if (f== NULL) + { + perror("fopen"); + exit(1); + } + ret = fread(&RK_STORE, 1, sizeof(RK_STORE), f); + fclose(f); + if(ret != sizeof(RK_STORE)) + { + perror("fwrite"); + exit(1); + } + + } + else + { + printf("state file does not exist, creating it\n"); + f = fopen(state_file, "wb+"); + if (f== NULL) + { + perror("fopen"); + exit(1); + } + mem = malloc(sizeof(AuthenticatorState)); + memset(mem,0xff,sizeof(AuthenticatorState)); + ret = fwrite(mem, 1, sizeof(AuthenticatorState), f); + free(mem); + fclose(f); + if (ret != sizeof(AuthenticatorState)) + { + perror("fwrite"); + exit(1); + } + + // resident_keys + memset(&RK_STORE,0xff,sizeof(RK_STORE)); + sync_rk(); + + } +} + +int ctap_generate_rng(uint8_t * dst, size_t num) +{ + int ret; + FILE * urand = fopen("/dev/urandom","r"); + if (urand == NULL) + { + perror("fopen"); + exit(1); + } + if (fread(dst, 1, num, urand) != num) + { + perror("fread"); + } + + fclose(urand); + + return 1; +} + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + authenticator_initialize(); + ctaphid_init(); + ctap_init( 1 ); + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + const uint8_t *data_end = Data + Size; + + for (uint8_t *pkt_raw=Data; pkt_raw