Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fuzzer target #371

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion fido2/version.c
Original file line number Diff line number Diff line change
@@ -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 <compilersupport_p.h>
Expand Down
39 changes: 39 additions & 0 deletions fuzz/Makefile
Original file line number Diff line number Diff line change
@@ -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
43 changes: 43 additions & 0 deletions fuzz/app.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, 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 <stdbool.h>

#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_ */
197 changes: 197 additions & 0 deletions fuzz/fuzztarget.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
// Copyright 2019 SoloKeys Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <time.h>

#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<data_end; pkt_raw += HIDMSG_SZ) {
ctaphid_handle_packet(pkt_raw);
}
return 0;
}

int main(int argc, char *argv[]) {
uint8_t fuzzbuf[FUZZBUF_SZ];


set_logging_mask(
// TAG_GEN|
// TAG_MC |
// TAG_GA |
TAG_WALLET |
TAG_STOR |
//TAG_NFC_APDU |
TAG_NFC |
// TAG_CP |
// TAG_CTAP|
// TAG_HID|
TAG_U2F|
// TAG_PARSE |
//TAG_TIME|
// TAG_DUMP|
// TAG_DUMP2|
TAG_GREEN|
TAG_RED|
TAG_EXT|
TAG_CCID|
TAG_ERR
);


LLVMFuzzerInitialize(&argc, &argv);

ssize_t bytes_read = read(STDIN, fuzzbuf, FUZZBUF_SZ);

// Ignore last packet which may not be 64 bytes long
bytes_read -= bytes_read % HIDMSG_SZ;

LLVMFuzzerTestOneInput(fuzzbuf, bytes_read);

return 0;
}