diff options
Diffstat (limited to 'fuzz')
33 files changed, 8393 insertions, 0 deletions
diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt new file mode 100644 index 0000000..52355c1 --- /dev/null +++ b/fuzz/CMakeLists.txt @@ -0,0 +1,70 @@ +# Copyright (c) 2019 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. +# SPDX-License-Identifier: BSD-2-Clause + +list(APPEND COMPAT_SOURCES + ../openbsd-compat/strlcpy.c + ../openbsd-compat/strlcat.c +) + +list(APPEND COMMON_SOURCES + libfuzzer.c + mutator_aux.c +) + +set(FUZZ_LDFLAGS "-fsanitize=fuzzer") + +# fuzz_cred +add_executable(fuzz_cred fuzz_cred.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +target_compile_options(fuzz_cred PRIVATE ${FUZZ_LDFLAGS}) +set_target_properties(fuzz_cred PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS}) +target_link_libraries(fuzz_cred fido2_shared) + +# fuzz_assert +add_executable(fuzz_assert fuzz_assert.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +target_compile_options(fuzz_assert PRIVATE ${FUZZ_LDFLAGS}) +set_target_properties(fuzz_assert PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS}) +target_link_libraries(fuzz_assert fido2_shared) + +# fuzz_mgmt +add_executable(fuzz_mgmt fuzz_mgmt.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +target_compile_options(fuzz_mgmt PRIVATE ${FUZZ_LDFLAGS}) +set_target_properties(fuzz_mgmt PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS}) +target_link_libraries(fuzz_mgmt fido2_shared) + +# fuzz_credman +add_executable(fuzz_credman fuzz_credman.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +target_compile_options(fuzz_credman PRIVATE ${FUZZ_LDFLAGS}) +set_target_properties(fuzz_credman PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS}) +target_link_libraries(fuzz_credman fido2_shared) + +# fuzz_bio +add_executable(fuzz_bio fuzz_bio.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +target_compile_options(fuzz_bio PRIVATE ${FUZZ_LDFLAGS}) +set_target_properties(fuzz_bio PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS}) +target_link_libraries(fuzz_bio fido2_shared) + +# fuzz_hid +add_executable(fuzz_hid fuzz_hid.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +target_compile_options(fuzz_hid PRIVATE ${FUZZ_LDFLAGS}) +set_target_properties(fuzz_hid PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS}) +target_link_libraries(fuzz_hid fido2_shared) + +# fuzz_netlink +add_executable(fuzz_netlink fuzz_netlink.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +target_compile_options(fuzz_netlink PRIVATE ${FUZZ_LDFLAGS}) +set_target_properties(fuzz_netlink PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS}) +target_link_libraries(fuzz_netlink fido2_shared) + +# fuzz_largeblob +add_executable(fuzz_largeblob fuzz_largeblob.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +target_compile_options(fuzz_largeblob PRIVATE ${FUZZ_LDFLAGS}) +set_target_properties(fuzz_largeblob PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS}) +target_link_libraries(fuzz_largeblob fido2_shared) + +# fuzz_pcsc +add_executable(fuzz_pcsc fuzz_pcsc.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +target_compile_options(fuzz_pcsc PRIVATE ${FUZZ_LDFLAGS}) +set_target_properties(fuzz_pcsc PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS}) +target_link_libraries(fuzz_pcsc fido2_shared) diff --git a/fuzz/Dockerfile b/fuzz/Dockerfile new file mode 100644 index 0000000..0c99f2c --- /dev/null +++ b/fuzz/Dockerfile @@ -0,0 +1,16 @@ +# Copyright (c) 2019-2022 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. +# SPDX-License-Identifier: BSD-2-Clause + +FROM alpine:latest +ENV CC=clang +ENV CXX=clang++ +RUN apk -q update +RUN apk add build-base clang clang-analyzer cmake compiler-rt coreutils +RUN apk add eudev-dev git linux-headers llvm openssl-dev pcsc-lite-dev +RUN apk add sudo tar zlib-dev +RUN git clone --branch v0.9.0 --depth=1 https://github.com/PJK/libcbor +RUN git clone --depth=1 https://github.com/yubico/libfido2 +WORKDIR /libfido2 +RUN ./fuzz/build-coverage /libcbor /libfido2 diff --git a/fuzz/Makefile b/fuzz/Makefile new file mode 100644 index 0000000..857c89e --- /dev/null +++ b/fuzz/Makefile @@ -0,0 +1,90 @@ +# Copyright (c) 2019-2022 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. +# SPDX-License-Identifier: BSD-2-Clause + +IMAGE := libfido2-coverage:1.12.2 +RUNNER := libfido2-runner +PROFDATA := llvm-profdata +COV := llvm-cov +TARGETS := fuzz_assert fuzz_bio fuzz_cred fuzz_credman fuzz_hid \ + fuzz_largeblob fuzz_netlink fuzz_mgmt fuzz_pcsc +CORPORA := $(foreach f,${TARGETS},${f}/corpus) +MINIFY := $(foreach f,${TARGETS},/minify/${f}/corpus) +REMOTE := gs://libfido2-corpus.clusterfuzz-external.appspot.com +.DEFAULT_GOAL := all + +all: ${TARGETS} + +build: + docker build -t ${IMAGE} - < Dockerfile + +run: build + -docker run -it -d --name ${RUNNER} ${IMAGE} + docker start ${RUNNER} + +sync: run + tar Ccf .. - src fuzz | docker exec -i ${RUNNER} tar Cxf /libfido2 - + docker exec ${RUNNER} make -C /libfido2/build + +corpus: sync + docker exec ${RUNNER} /bin/sh -c 'cd /libfido2/fuzz && rm -rf ${TARGETS}' + docker exec ${RUNNER} tar Czxf /libfido2/fuzz /libfido2/fuzz/corpus.tgz + +${TARGETS}: corpus sync + docker exec -e LLVM_PROFILE_FILE=/profraw/$@ ${RUNNER} \ + /bin/sh -c 'rm -f /profraw/$@ && /libfido2/build/fuzz/$@ \ + -runs=1 /libfido2/fuzz/$@' + +${MINIFY}: /minify/%/corpus: % + docker exec ${RUNNER} /bin/sh -c 'rm -rf $@ && mkdir -p $@ && \ + /libfido2/build/fuzz/$< -use_value_profile=1 -merge=1 $@ \ + /libfido2/fuzz/$</corpus' + +corpus.tgz-: ${MINIFY} + docker exec -i ${RUNNER} tar Czcf /minify - ${TARGETS} > $@ + +profdata: run + docker exec ${RUNNER} /bin/sh -c 'rm -f /$@ && ${PROFDATA} \ + merge -sparse /profraw/* -o /$@' + +report.tgz: profdata + docker exec ${RUNNER} /bin/sh -c 'rm -rf /report && mkdir /report && \ + ${COV} show -format=html -tab-size=8 -instr-profile=/$< \ + -ignore-filename-regex=pcsclite.h --show-branch-summary=false \ + -output-dir=/report /libfido2/build/src/libfido2.so' + docker exec -i ${RUNNER} tar Czcf / - report > $@ + +summary.txt: profdata + docker exec ${RUNNER} ${COV} report -use-color=false \ + -ignore-filename-regex=pcsclite.h --show-branch-summary=false \ + /libfido2/build/src/libfido2.so -instr-profile=/$< > $@ + +functions.txt: profdata + docker exec ${RUNNER} /bin/sh -c '${COV} report -use-color=false \ + -ignore-filename-regex=pcsclite.h -show-functions \ + --show-branch-summary=false -instr-profile=/$< \ + /libfido2/build/src/libfido2.so /libfido2/src/*.[ch]' > $@ + +clean: run + docker exec ${RUNNER} /bin/sh -c 'rm -rf /profraw /profdata && \ + make -C /libfido2/build clean' + -docker stop ${RUNNER} + rm -rf ${TARGETS} + +${CORPORA}: + -mkdir -p $@ + gsutil -q -m rsync -d -r ${REMOTE}/libFuzzer/libfido2_$(@:/corpus=) $@ + +fetch-oss-fuzz: ${CORPORA} + find ${TARGETS} -type f -size +8192c -print0 | xargs -0 rm + +fetch-franz: + ssh franz tar -C corpus -cf- . | tar -xf- + +corpus.tgz: + tar zcf $@ ${TARGETS} + +.PHONY: build run sync corpus ${TARGETS} ${CORPORA} +.PHONY: report.tgz summary.txt functions.txt +.PHONY: fetch-oss-fuzz fetch-franz corpus.tgz diff --git a/fuzz/README b/fuzz/README new file mode 100644 index 0000000..2e88db7 --- /dev/null +++ b/fuzz/README @@ -0,0 +1,40 @@ +libfido2 can be fuzzed using AFL or libFuzzer, with or without +ASAN/MSAN/UBSAN. + +AFL is more convenient when fuzzing the path from the authenticator to +libfido2 in an existing application. To do so, use preload-snoop.c with a real +authenticator to obtain an initial corpus, rebuild libfido2 with -DFUZZ=ON, and +use preload-fuzz.c to read device data from stdin. + +libFuzzer is better suited for bespoke fuzzers; see fuzz_cred.c, fuzz_credman.c, +fuzz_assert.c, fuzz_hid.c, and fuzz_mgmt.c for examples. To build these +harnesses, use -DFUZZ=ON -DLIBFUZZER=ON. + +If -DFUZZ=ON is enabled, symbols listed in wrapped.sym are wrapped in the +resulting shared object. The wrapper functions simulate failure according to a +deterministic RNG and probabilities defined in wrap.c. Harnesses wishing to +use this functionality should call prng_init() with a seed obtained from the +corpus. To mutate only the seed part of a libFuzzer harness's corpora, +use '-reduce_inputs=0 --fido-mutate=seed'. + +To run under ASAN/MSAN/UBSAN, libfido2 needs to be linked against flavours of +libcbor and OpenSSL built with the respective sanitiser. In order to keep +memory utilisation at a manageable level, you can either enforce limits at +the OS level (e.g. cgroups on Linux), or patch libcbor with the diff below. + +diff --git src/cbor/internal/memory_utils.c src/cbor/internal/memory_utils.c +index aa049a2..e294b38 100644 +--- src/cbor/internal/memory_utils.c ++++ src/cbor/internal/memory_utils.c +@@ -28,7 +28,10 @@ bool _cbor_safe_to_multiply(size_t a, size_t b) { + + void* _cbor_alloc_multiple(size_t item_size, size_t item_count) { + if (_cbor_safe_to_multiply(item_size, item_count)) { +- return _CBOR_MALLOC(item_size * item_count); ++ if (item_count > 1000) { ++ return NULL; ++ } else ++ return _CBOR_MALLOC(item_size * item_count); + } else { + return NULL; + } diff --git a/fuzz/build-coverage b/fuzz/build-coverage new file mode 100755 index 0000000..8c989fc --- /dev/null +++ b/fuzz/build-coverage @@ -0,0 +1,32 @@ +#!/bin/sh -eux + +# Copyright (c) 2019 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. +# SPDX-License-Identifier: BSD-2-Clause + +LIBCBOR="$1" +LIBFIDO2="$2" + +CC="${CC:-clang}" +CXX="${CXX:-clang++}" +PKG_CONFIG_PATH="${PKG_CONFIG_PATH:-${LIBCBOR}/install/lib/pkgconfig}" +export CC PKG_CONFIG_PATH + +# Clean up. +rm -rf "${LIBCBOR}/build" "${LIBCBOR}/install" "${LIBFIDO2}/build" + +# Patch, build, and install libcbor. +(cd "${LIBCBOR}" && patch -N -l -s -p0 < "${LIBFIDO2}/fuzz/README") || true +mkdir "${LIBCBOR}/build" "${LIBCBOR}/install" +(cd "${LIBCBOR}/build" && cmake -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_INSTALL_PREFIX="${LIBCBOR}/install" ..) +make -C "${LIBCBOR}/build" VERBOSE=1 all install + +# Build libfido2. +mkdir -p "${LIBFIDO2}/build" +export CFLAGS="-fprofile-instr-generate -fcoverage-mapping" +export LDFLAGS="${CFLAGS}" +(cd "${LIBFIDO2}/build" && cmake -DFUZZ=ON -DLIBFUZZER=ON \ + -DCMAKE_BUILD_TYPE=Debug ..) +make -C "${LIBFIDO2}/build" diff --git a/fuzz/clock.c b/fuzz/clock.c new file mode 100644 index 0000000..bd758ea --- /dev/null +++ b/fuzz/clock.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <stdint.h> +#include <time.h> + +#include "mutator_aux.h" + +/* + * A pseudo-random monotonic clock with a probabilistic discontinuity to + * the end of time (as measured by struct timespec). + */ + +extern int prng_up; +extern int __wrap_clock_gettime(clockid_t, struct timespec *); +extern int __real_clock_gettime(clockid_t, struct timespec *); +extern int __wrap_usleep(unsigned int); +static TLS struct timespec fuzz_clock; + +static void +tick(unsigned int usec) +{ + long long drift; + + /* + * Simulate a jump to the end of time with 0.125% probability. + * This condition should be gracefully handled by callers of + * clock_gettime(). + */ + if (uniform_random(800) < 1) { + fuzz_clock.tv_sec = LLONG_MAX; + fuzz_clock.tv_nsec = LONG_MAX; + return; + } + + drift = usec * 1000LL + (long long)uniform_random(10000000); /* 10ms */ + if (LLONG_MAX - drift < (long long)fuzz_clock.tv_nsec) { + fuzz_clock_reset(); /* Not much we can do here. */ + } else if (drift + (long long)fuzz_clock.tv_nsec < 1000000000) { + fuzz_clock.tv_nsec += (long)(drift); + } else { + fuzz_clock.tv_sec += (long)(drift / 1000000000); + fuzz_clock.tv_nsec += (long)(drift % 1000000000); + } +} + +int +__wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + if (!prng_up || clk_id != CLOCK_MONOTONIC) + return __real_clock_gettime(clk_id, tp); + if (uniform_random(400) < 1) + return -1; + + tick(0); + *tp = fuzz_clock; + + return 0; +} + +int +__wrap_usleep(unsigned int usec) +{ + if (uniform_random(400) < 1) + return -1; + + tick(usec); + + return 0; +} + +void +fuzz_clock_reset(void) +{ + memset(&fuzz_clock, 0, sizeof(fuzz_clock)); +} diff --git a/fuzz/dummy.h b/fuzz/dummy.h new file mode 100644 index 0000000..fc4bfc5 --- /dev/null +++ b/fuzz/dummy.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2020-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _DUMMY_H +#define _DUMMY_H + +#include <stdint.h> + +const char dummy_name[] = "finger1"; +const char dummy_pin1[] = "skepp cg0u3;Y.."; +const char dummy_pin2[] = "bastilha 6rJrfQZI."; +const char dummy_pin[] = "9}4gT:8d=A37Dh}U"; +const char dummy_rp_id[] = "localhost"; +const char dummy_rp_name[] = "sweet home localhost"; +const char dummy_user_icon[] = "an icon"; +const char dummy_user_name[] = "john smith"; +const char dummy_user_nick[] = "jsmith"; +const char dummy_pcsc_list[] = "reader1\0reader2\0reader3\0\0"; +const char dummy_pcsc_path[] = "pcsc://slot7"; +const uint8_t dummy_id[] = { 0x5e, 0xd2 }; + +const uint8_t dummy_user_id[] = { + 0x78, 0x1c, 0x78, 0x60, 0xad, 0x88, 0xd2, 0x63, + 0x32, 0x62, 0x2a, 0xf1, 0x74, 0x5d, 0xed, 0xb2, + 0xe7, 0xa4, 0x2b, 0x44, 0x89, 0x29, 0x39, 0xc5, + 0x56, 0x64, 0x01, 0x27, 0x0d, 0xbb, 0xc4, 0x49, +}; + +const uint8_t dummy_cred_id[] = { + 0x4f, 0x72, 0x98, 0x42, 0x4a, 0xe1, 0x17, 0xa5, + 0x85, 0xa0, 0xef, 0x3b, 0x11, 0x24, 0x4a, 0x3d, +}; + +const uint8_t dummy_cdh[] = { + 0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7, + 0x82, 0x34, 0xaa, 0xca, 0x07, 0xa1, 0xf6, 0x56, + 0x42, 0x1c, 0xb6, 0xf6, 0xb3, 0x00, 0x86, 0x52, + 0x35, 0x2d, 0xa2, 0x62, 0x4a, 0xbe, 0x89, 0x76, +}; + +const uint8_t dummy_es256[] = { + 0xcc, 0x1b, 0x50, 0xac, 0xc4, 0x19, 0xf8, 0x3a, + 0xee, 0x0a, 0x77, 0xd6, 0xf3, 0x53, 0xdb, 0xef, + 0xf2, 0xb9, 0x5c, 0x2d, 0x8b, 0x1e, 0x52, 0x58, + 0x88, 0xf4, 0x0b, 0x85, 0x1f, 0x40, 0x6d, 0x18, + 0x15, 0xb3, 0xcc, 0x25, 0x7c, 0x38, 0x3d, 0xec, + 0xdf, 0xad, 0xbd, 0x46, 0x91, 0xc3, 0xac, 0x30, + 0x94, 0x2a, 0xf7, 0x78, 0x35, 0x70, 0x59, 0x6f, + 0x28, 0xcb, 0x8e, 0x07, 0x85, 0xb5, 0x91, 0x96, +}; + +const uint8_t dummy_rs256[] = { + 0xd2, 0xa8, 0xc0, 0x11, 0x82, 0x9e, 0x57, 0x2e, + 0x60, 0xae, 0x8c, 0xb0, 0x09, 0xe1, 0x58, 0x2b, + 0x99, 0xec, 0xc3, 0x11, 0x1b, 0xef, 0x81, 0x49, + 0x34, 0x53, 0x6a, 0x01, 0x65, 0x2c, 0x24, 0x09, + 0x30, 0x87, 0x98, 0x51, 0x6e, 0x30, 0x4f, 0x60, + 0xbd, 0x54, 0xd2, 0x54, 0xbd, 0x94, 0x42, 0xdd, + 0x63, 0xe5, 0x2c, 0xc6, 0x04, 0x32, 0xc0, 0x8f, + 0x72, 0xd5, 0xb4, 0xf0, 0x4f, 0x42, 0xe5, 0xb0, + 0xa2, 0x95, 0x11, 0xfe, 0xd8, 0xb0, 0x65, 0x34, + 0xff, 0xfb, 0x44, 0x97, 0x52, 0xfc, 0x67, 0x23, + 0x0b, 0xad, 0xf3, 0x3a, 0x82, 0xd4, 0x96, 0x10, + 0x87, 0x6b, 0xfa, 0xd6, 0x51, 0x60, 0x3e, 0x1c, + 0xae, 0x19, 0xb8, 0xce, 0x08, 0xae, 0x9a, 0xee, + 0x78, 0x16, 0x22, 0xcc, 0x92, 0xcb, 0xa8, 0x95, + 0x34, 0xe5, 0xb9, 0x42, 0x6a, 0xf0, 0x2e, 0x82, + 0x1f, 0x4c, 0x7d, 0x84, 0x94, 0x68, 0x7b, 0x97, + 0x2b, 0xf7, 0x7d, 0x67, 0x83, 0xbb, 0xc7, 0x8a, + 0x31, 0x5a, 0xf3, 0x2a, 0x95, 0xdf, 0x63, 0xe7, + 0x4e, 0xee, 0x26, 0xda, 0x87, 0x00, 0xe2, 0x23, + 0x4a, 0x33, 0x9a, 0xa0, 0x1b, 0xce, 0x60, 0x1f, + 0x98, 0xa1, 0xb0, 0xdb, 0xbf, 0x20, 0x59, 0x27, + 0xf2, 0x06, 0xd9, 0xbe, 0x37, 0xa4, 0x03, 0x6b, + 0x6a, 0x4e, 0xaf, 0x22, 0x68, 0xf3, 0xff, 0x28, + 0x59, 0x05, 0xc9, 0xf1, 0x28, 0xf4, 0xbb, 0x35, + 0xe0, 0xc2, 0x68, 0xc2, 0xaa, 0x54, 0xac, 0x8c, + 0xc1, 0x69, 0x9e, 0x4b, 0x32, 0xfc, 0x53, 0x58, + 0x85, 0x7d, 0x3f, 0x51, 0xd1, 0xc9, 0x03, 0x02, + 0x13, 0x61, 0x62, 0xda, 0xf8, 0xfe, 0x3e, 0xc8, + 0x95, 0x12, 0xfb, 0x0c, 0xdf, 0x06, 0x65, 0x6f, + 0x23, 0xc7, 0x83, 0x7c, 0x50, 0x2d, 0x27, 0x25, + 0x4d, 0xbf, 0x94, 0xf0, 0x89, 0x04, 0xb9, 0x2d, + 0xc4, 0xa5, 0x32, 0xa9, 0x25, 0x0a, 0x99, 0x59, + 0x01, 0x00, 0x01, +}; + +const uint8_t dummy_eddsa[] = { + 0xfe, 0x8b, 0x61, 0x50, 0x31, 0x7a, 0xe6, 0xdf, + 0xb1, 0x04, 0x9d, 0x4d, 0xb5, 0x7a, 0x5e, 0x96, + 0x4c, 0xb2, 0xf9, 0x5f, 0x72, 0x47, 0xb5, 0x18, + 0xe2, 0x39, 0xdf, 0x2f, 0x87, 0x19, 0xb3, 0x02, +}; + +const uint8_t dummy_netlink_wiredata[] = { + 0xd8, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00, + 0x01, 0x02, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x6e, 0x66, 0x63, 0x00, 0x06, 0x00, 0x01, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0x00, + 0x14, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x05, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x06, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x09, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0c, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0e, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x10, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x11, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x13, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x07, 0x00, + 0x18, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x9d, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9d, 0x2e, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x05, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x07, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x93, 0xb9, 0x25, 0x00 +}; + +#endif /* !_DUMMY_H */ diff --git a/fuzz/export.gnu b/fuzz/export.gnu new file mode 100644 index 0000000..f0fb840 --- /dev/null +++ b/fuzz/export.gnu @@ -0,0 +1,283 @@ +{ + global: + eddsa_pk_free; + eddsa_pk_from_EVP_PKEY; + eddsa_pk_from_ptr; + eddsa_pk_new; + eddsa_pk_to_EVP_PKEY; + es256_pk_free; + es256_pk_from_EC_KEY; + es256_pk_from_EVP_PKEY; + es256_pk_from_ptr; + es256_pk_new; + es256_pk_to_EVP_PKEY; + es384_pk_free; + es384_pk_from_EC_KEY; + es384_pk_from_EVP_PKEY; + es384_pk_from_ptr; + es384_pk_new; + es384_pk_to_EVP_PKEY; + fido_assert_allow_cred; + fido_assert_authdata_len; + fido_assert_authdata_ptr; + fido_assert_blob_len; + fido_assert_blob_ptr; + fido_assert_clientdata_hash_len; + fido_assert_clientdata_hash_ptr; + fido_assert_count; + fido_assert_flags; + fido_assert_free; + fido_assert_hmac_secret_len; + fido_assert_hmac_secret_ptr; + fido_assert_id_len; + fido_assert_id_ptr; + fido_assert_largeblob_key_len; + fido_assert_largeblob_key_ptr; + fido_assert_new; + fido_assert_rp_id; + fido_assert_set_authdata; + fido_assert_set_authdata_raw; + fido_assert_set_clientdata; + fido_assert_set_clientdata_hash; + fido_assert_set_count; + fido_assert_set_extensions; + fido_assert_set_hmac_salt; + fido_assert_set_hmac_secret; + fido_assert_set_options; + fido_assert_set_rp; + fido_assert_set_sig; + fido_assert_set_up; + fido_assert_set_uv; + fido_assert_sigcount; + fido_assert_sig_len; + fido_assert_sig_ptr; + fido_assert_user_display_name; + fido_assert_user_icon; + fido_assert_user_id_len; + fido_assert_user_id_ptr; + fido_assert_user_name; + fido_assert_verify; + fido_bio_dev_enroll_begin; + fido_bio_dev_enroll_cancel; + fido_bio_dev_enroll_continue; + fido_bio_dev_enroll_remove; + fido_bio_dev_get_info; + fido_bio_dev_get_template_array; + fido_bio_dev_set_template_name; + fido_bio_enroll_free; + fido_bio_enroll_last_status; + fido_bio_enroll_new; + fido_bio_enroll_remaining_samples; + fido_bio_info_free; + fido_bio_info_max_samples; + fido_bio_info_new; + fido_bio_info_type; + fido_bio_template; + fido_bio_template_array_count; + fido_bio_template_array_free; + fido_bio_template_array_new; + fido_bio_template_free; + fido_bio_template_id_len; + fido_bio_template_id_ptr; + fido_bio_template_name; + fido_bio_template_new; + fido_bio_template_set_id; + fido_bio_template_set_name; + fido_cbor_info_aaguid_len; + fido_cbor_info_aaguid_ptr; + fido_cbor_info_algorithm_cose; + fido_cbor_info_algorithm_count; + fido_cbor_info_algorithm_type; + fido_cbor_info_certs_len; + fido_cbor_info_certs_name_ptr; + fido_cbor_info_certs_value_ptr; + fido_cbor_info_extensions_len; + fido_cbor_info_extensions_ptr; + fido_cbor_info_free; + fido_cbor_info_fwversion; + fido_cbor_info_maxcredbloblen; + fido_cbor_info_maxcredcntlst; + fido_cbor_info_maxcredidlen; + fido_cbor_info_maxlargeblob; + fido_cbor_info_maxmsgsiz; + fido_cbor_info_maxrpid_minpinlen; + fido_cbor_info_minpinlen; + fido_cbor_info_new; + fido_cbor_info_new_pin_required; + fido_cbor_info_options_len; + fido_cbor_info_options_name_ptr; + fido_cbor_info_options_value_ptr; + fido_cbor_info_protocols_len; + fido_cbor_info_protocols_ptr; + fido_cbor_info_rk_remaining; + fido_cbor_info_transports_len; + fido_cbor_info_transports_ptr; + fido_cbor_info_uv_attempts; + fido_cbor_info_uv_modality; + fido_cbor_info_versions_len; + fido_cbor_info_versions_ptr; + fido_cred_attstmt_len; + fido_cred_attstmt_ptr; + fido_cred_authdata_len; + fido_cred_authdata_ptr; + fido_cred_authdata_raw_len; + fido_cred_authdata_raw_ptr; + fido_cred_clientdata_hash_len; + fido_cred_clientdata_hash_ptr; + fido_cred_display_name; + fido_cred_exclude; + fido_cred_flags; + fido_cred_largeblob_key_len; + fido_cred_largeblob_key_ptr; + fido_cred_sigcount; + fido_cred_fmt; + fido_cred_free; + fido_cred_id_len; + fido_cred_id_ptr; + fido_cred_aaguid_len; + fido_cred_aaguid_ptr; + fido_credman_del_dev_rk; + fido_credman_get_dev_metadata; + fido_credman_get_dev_rk; + fido_credman_get_dev_rp; + fido_credman_metadata_free; + fido_credman_metadata_new; + fido_credman_rk; + fido_credman_rk_count; + fido_credman_rk_existing; + fido_credman_rk_free; + fido_credman_rk_new; + fido_credman_rk_remaining; + fido_credman_rp_count; + fido_credman_rp_free; + fido_credman_rp_id; + fido_credman_rp_id_hash_len; + fido_credman_rp_id_hash_ptr; + fido_credman_rp_name; + fido_credman_rp_new; + fido_credman_set_dev_rk; + fido_cred_new; + fido_cred_pin_minlen; + fido_cred_prot; + fido_cred_pubkey_len; + fido_cred_pubkey_ptr; + fido_cred_rp_id; + fido_cred_rp_name; + fido_cred_set_attstmt; + fido_cred_set_authdata; + fido_cred_set_authdata_raw; + fido_cred_set_blob; + fido_cred_set_clientdata; + fido_cred_set_clientdata_hash; + fido_cred_set_extensions; + fido_cred_set_fmt; + fido_cred_set_id; + fido_cred_set_options; + fido_cred_set_pin_minlen; + fido_cred_set_prot; + fido_cred_set_rk; + fido_cred_set_rp; + fido_cred_set_sig; + fido_cred_set_type; + fido_cred_set_user; + fido_cred_set_uv; + fido_cred_set_x509; + fido_cred_sig_len; + fido_cred_sig_ptr; + fido_cred_type; + fido_cred_user_id_len; + fido_cred_user_id_ptr; + fido_cred_user_name; + fido_cred_verify; + fido_cred_verify_self; + fido_cred_x5c_len; + fido_cred_x5c_ptr; + fido_dev_build; + fido_dev_cancel; + fido_dev_close; + fido_dev_enable_entattest; + fido_dev_flags; + fido_dev_force_fido2; + fido_dev_force_pin_change; + fido_dev_force_u2f; + fido_dev_free; + fido_dev_get_assert; + fido_dev_get_cbor_info; + fido_dev_get_retry_count; + fido_dev_get_uv_retry_count; + fido_dev_get_touch_begin; + fido_dev_get_touch_status; + fido_dev_has_pin; + fido_dev_has_uv; + fido_dev_info_free; + fido_dev_info_manifest; + fido_dev_info_manufacturer_string; + fido_dev_info_new; + fido_dev_info_path; + fido_dev_info_product; + fido_dev_info_product_string; + fido_dev_info_ptr; + fido_dev_info_set; + fido_dev_info_vendor; + fido_dev_is_fido2; + fido_dev_major; + fido_dev_make_cred; + fido_dev_minor; + fido_dev_new; + fido_dev_open; + fido_dev_protocol; + fido_dev_reset; + fido_dev_set_io_functions; + fido_dev_set_pcsc; + fido_dev_set_pin; + fido_dev_set_pin_minlen; + fido_dev_set_pin_minlen_rpid; + fido_dev_set_timeout; + fido_dev_set_transport_functions; + fido_dev_supports_cred_prot; + fido_dev_supports_credman; + fido_dev_supports_permissions; + fido_dev_supports_pin; + fido_dev_supports_uv; + fido_dev_toggle_always_uv; + fido_dev_largeblob_get; + fido_dev_largeblob_get_array; + fido_dev_largeblob_remove; + fido_dev_largeblob_set; + fido_dev_largeblob_set_array; + fido_hid_get_report_len; + fido_hid_get_usage; + fido_init; + fido_nfc_rx; + fido_nfc_tx; + fido_nl_free; + fido_nl_get_nfc_target; + fido_nl_new; + fido_nl_power_nfc; + fido_pcsc_close; + fido_pcsc_manifest; + fido_pcsc_open; + fido_pcsc_read; + fido_pcsc_rx; + fido_pcsc_tx; + fido_pcsc_write; + fido_set_log_handler; + fido_strerr; + rs256_pk_free; + rs256_pk_from_ptr; + rs256_pk_from_EVP_PKEY; + rs256_pk_from_RSA; + rs256_pk_new; + rs256_pk_to_EVP_PKEY; + prng_init; + prng_up; + fuzz_clock_reset; + fuzz_save_corpus; + set_netlink_io_functions; + set_pcsc_parameters; + set_pcsc_io_functions; + set_udev_parameters; + uniform_random; + local: + *; +}; diff --git a/fuzz/functions.txt b/fuzz/functions.txt new file mode 100644 index 0000000..da7f058 --- /dev/null +++ b/fuzz/functions.txt @@ -0,0 +1,949 @@ +File '/libfido2/src/aes256.c': +Name Regions Miss Cover Lines Miss Cover +-------------------------------------------------------------------------------------------------------- +aes256_cbc_enc 4 0 100.00% 4 0 100.00% +aes256_cbc_dec 4 0 100.00% 4 0 100.00% +aes256_gcm_enc 1 0 100.00% 3 0 100.00% +aes256_gcm_dec 1 0 100.00% 3 0 100.00% +aes256.c:aes256_cbc_fips 26 1 96.15% 42 4 90.48% +aes256.c:aes256_cbc 29 1 96.55% 36 3 91.67% +aes256.c:aes256_cbc_proto1 1 0 100.00% 5 0 100.00% +aes256.c:aes256_gcm 52 1 98.08% 60 4 93.33% +-------------------------------------------------------------------------------------------------------- +TOTAL 118 3 97.46% 157 11 92.99% + +File '/libfido2/src/assert.c': +Name Regions Miss Cover Lines Miss Cover +----------------------------------------------------------------------------------------------------------------- +fido_dev_get_assert 40 0 100.00% 35 0 100.00% +fido_check_flags 13 0 100.00% 15 0 100.00% +fido_get_signed_hash 20 1 95.00% 34 3 91.18% +fido_assert_verify 50 4 92.00% 70 7 90.00% +fido_assert_set_clientdata 12 12 0.00% 11 11 0.00% +fido_assert_set_clientdata_hash 8 0 100.00% 6 0 100.00% +fido_assert_set_hmac_salt 10 0 100.00% 6 0 100.00% +fido_assert_set_hmac_secret 12 12 0.00% 7 7 0.00% +fido_assert_set_rp 12 0 100.00% 11 0 100.00% +fido_assert_allow_cred 13 2 84.62% 22 3 86.36% +fido_assert_set_extensions 14 0 100.00% 10 0 100.00% +fido_assert_set_options 8 8 0.00% 5 5 0.00% +fido_assert_set_up 2 0 100.00% 4 0 100.00% +fido_assert_set_uv 2 0 100.00% 4 0 100.00% +fido_assert_clientdata_hash_ptr 1 0 100.00% 3 0 100.00% +fido_assert_clientdata_hash_len 1 0 100.00% 3 0 100.00% +fido_assert_new 1 0 100.00% 3 0 100.00% +fido_assert_reset_tx 1 0 100.00% 12 0 100.00% +fido_assert_reset_rx 4 0 100.00% 19 0 100.00% +fido_assert_free 6 0 100.00% 9 0 100.00% +fido_assert_count 1 0 100.00% 3 0 100.00% +fido_assert_rp_id 1 0 100.00% 3 0 100.00% +fido_assert_flags 4 0 100.00% 5 0 100.00% +fido_assert_sigcount 4 0 100.00% 5 0 100.00% +fido_assert_authdata_ptr 4 0 100.00% 5 0 100.00% +fido_assert_authdata_len 4 0 100.00% 5 0 100.00% +fido_assert_sig_ptr 4 0 100.00% 5 0 100.00% +fido_assert_sig_len 4 0 100.00% 5 0 100.00% +fido_assert_id_ptr 4 0 100.00% 5 0 100.00% +fido_assert_id_len 4 0 100.00% 5 0 100.00% +fido_assert_user_id_ptr 4 0 100.00% 5 0 100.00% +fido_assert_user_id_len 4 0 100.00% 5 0 100.00% +fido_assert_user_icon 4 0 100.00% 5 0 100.00% +fido_assert_user_name 4 0 100.00% 5 0 100.00% +fido_assert_user_display_name 4 0 100.00% 5 0 100.00% +fido_assert_hmac_secret_ptr 4 0 100.00% 5 0 100.00% +fido_assert_hmac_secret_len 4 0 100.00% 5 0 100.00% +fido_assert_largeblob_key_ptr 4 0 100.00% 5 0 100.00% +fido_assert_largeblob_key_len 4 0 100.00% 5 0 100.00% +fido_assert_blob_ptr 4 0 100.00% 5 0 100.00% +fido_assert_blob_len 4 0 100.00% 5 0 100.00% +fido_assert_set_authdata 24 0 100.00% 28 0 100.00% +fido_assert_set_authdata_raw 24 0 100.00% 27 0 100.00% +fido_assert_set_sig 14 0 100.00% 7 0 100.00% +fido_assert_set_count 10 0 100.00% 17 0 100.00% +assert.c:fido_dev_get_assert_wait 21 0 100.00% 14 0 100.00% +assert.c:fido_dev_get_assert_tx 56 2 96.43% 62 5 91.94% +assert.c:fido_dev_get_assert_rx 27 0 100.00% 36 0 100.00% +assert.c:adjust_assert_count 24 0 100.00% 26 0 100.00% +assert.c:parse_assert_reply 12 0 100.00% 24 0 100.00% +assert.c:fido_get_next_assert_tx 8 0 100.00% 8 0 100.00% +assert.c:fido_get_next_assert_rx 23 2 91.30% 29 5 82.76% +assert.c:decrypt_hmac_secrets 9 0 100.00% 15 0 100.00% +assert.c:get_es256_hash 16 0 100.00% 17 0 100.00% +assert.c:get_es384_hash 16 0 100.00% 17 0 100.00% +assert.c:get_eddsa_hash 6 0 100.00% 9 0 100.00% +assert.c:check_extensions 5 0 100.00% 9 0 100.00% +assert.c:fido_assert_reset_extattr 1 0 100.00% 5 0 100.00% +assert.c:fido_assert_clean_authdata 1 0 100.00% 5 0 100.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 605 43 92.89% 745 46 93.83% + +File '/libfido2/src/authkey.c': +Name Regions Miss Cover Lines Miss Cover +----------------------------------------------------------------------------------------------------------------- +fido_dev_authkey 1 0 100.00% 3 0 100.00% +authkey.c:fido_dev_authkey_wait 10 0 100.00% 7 0 100.00% +authkey.c:fido_dev_authkey_tx 19 0 100.00% 25 0 100.00% +authkey.c:fido_dev_authkey_rx 14 0 100.00% 21 0 100.00% +authkey.c:parse_authkey 8 0 100.00% 10 0 100.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 52 0 100.00% 66 0 100.00% + +File '/libfido2/src/bio.c': +Name Regions Miss Cover Lines Miss Cover +----------------------------------------------------------------------------------------------------------------- +fido_bio_dev_get_template_array 5 2 60.00% 6 1 83.33% +fido_bio_dev_set_template_name 7 0 100.00% 6 0 100.00% +fido_bio_dev_enroll_begin 25 2 92.00% 31 1 96.77% +fido_bio_dev_enroll_continue 5 2 60.00% 6 1 83.33% +fido_bio_dev_enroll_cancel 1 1 0.00% 4 4 0.00% +fido_bio_dev_enroll_remove 1 0 100.00% 4 0 100.00% +fido_bio_dev_get_info 1 0 100.00% 4 0 100.00% +fido_bio_template_name 1 0 100.00% 3 0 100.00% +fido_bio_template_id_ptr 1 0 100.00% 3 0 100.00% +fido_bio_template_id_len 1 0 100.00% 3 0 100.00% +fido_bio_template_array_count 1 0 100.00% 3 0 100.00% +fido_bio_template_array_new 1 0 100.00% 3 0 100.00% +fido_bio_template_new 1 0 100.00% 3 0 100.00% +fido_bio_template_array_free 6 0 100.00% 8 0 100.00% +fido_bio_template_free 6 0 100.00% 8 0 100.00% +fido_bio_template_set_name 8 0 100.00% 7 0 100.00% +fido_bio_template_set_id 8 0 100.00% 6 0 100.00% +fido_bio_template 4 0 100.00% 5 0 100.00% +fido_bio_enroll_new 1 0 100.00% 3 0 100.00% +fido_bio_info_new 1 0 100.00% 3 0 100.00% +fido_bio_info_type 1 0 100.00% 3 0 100.00% +fido_bio_info_max_samples 1 0 100.00% 3 0 100.00% +fido_bio_enroll_free 6 0 100.00% 8 0 100.00% +fido_bio_info_free 6 0 100.00% 7 0 100.00% +fido_bio_enroll_remaining_samples 1 0 100.00% 3 0 100.00% +fido_bio_enroll_last_status 1 0 100.00% 3 0 100.00% +bio.c:bio_get_template_array_wait 11 0 100.00% 7 0 100.00% +bio.c:bio_tx 43 0 100.00% 55 0 100.00% +bio.c:bio_prepare_hmac 18 0 100.00% 29 0 100.00% +bio.c:bio_rx_template_array 19 0 100.00% 24 0 100.00% +bio.c:bio_parse_template_array 26 1 96.15% 27 4 85.19% +bio.c:decode_template_array 12 1 91.67% 18 3 83.33% +bio.c:decode_template 9 0 100.00% 15 0 100.00% +bio.c:bio_set_template_name_wait 19 0 100.00% 20 0 100.00% +bio.c:bio_enroll_begin_wait 17 0 100.00% 19 0 100.00% +bio.c:bio_rx_enroll_begin 23 0 100.00% 31 0 100.00% +bio.c:bio_parse_enroll_status 20 0 100.00% 28 0 100.00% +bio.c:bio_parse_template_id 8 0 100.00% 10 0 100.00% +bio.c:bio_enroll_continue_wait 19 0 100.00% 20 0 100.00% +bio.c:bio_rx_enroll_continue 19 0 100.00% 25 0 100.00% +bio.c:bio_enroll_cancel_wait 11 11 0.00% 10 10 0.00% +bio.c:bio_enroll_remove_wait 17 0 100.00% 19 0 100.00% +bio.c:bio_get_info_wait 11 0 100.00% 10 0 100.00% +bio.c:bio_rx_info 19 0 100.00% 24 0 100.00% +bio.c:bio_reset_info 1 0 100.00% 4 0 100.00% +bio.c:bio_parse_info 20 0 100.00% 28 0 100.00% +bio.c:bio_reset_template_array 4 0 100.00% 7 0 100.00% +bio.c:bio_reset_template 1 0 100.00% 5 0 100.00% +bio.c:bio_reset_enroll 3 0 100.00% 6 0 100.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 451 20 95.57% 587 24 95.91% + +File '/libfido2/src/blob.c': +Name Regions Miss Cover Lines Miss Cover +----------------------------------------------------------------------------------------------------------------- +fido_blob_new 1 0 100.00% 3 0 100.00% +fido_blob_reset 1 0 100.00% 4 0 100.00% +fido_blob_set 9 0 100.00% 15 0 100.00% +fido_blob_append 12 1 91.67% 20 3 85.00% +fido_blob_free 6 0 100.00% 8 0 100.00% +fido_free_blob_array 7 0 100.00% 12 0 100.00% +fido_blob_encode 6 0 100.00% 5 0 100.00% +fido_blob_decode 1 0 100.00% 3 0 100.00% +fido_blob_is_empty 3 0 100.00% 3 0 100.00% +fido_blob_serialise 7 1 85.71% 10 1 90.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 53 2 96.23% 83 4 95.18% + +File '/libfido2/src/buf.c': +Name Regions Miss Cover Lines Miss Cover +----------------------------------------------------------------------------------------------------------------- +fido_buf_read 4 0 100.00% 8 0 100.00% +fido_buf_write 4 1 75.00% 8 1 87.50% +----------------------------------------------------------------------------------------------------------------- +TOTAL 8 1 87.50% 16 1 93.75% + +File '/libfido2/src/cbor.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------ +cbor_map_iter 20 1 95.00% 26 4 84.62% +cbor_array_iter 12 0 100.00% 16 0 100.00% +cbor_parse_reply 27 0 100.00% 36 0 100.00% +cbor_vector_free 6 0 100.00% 5 0 100.00% +cbor_bytestring_copy 14 0 100.00% 18 0 100.00% +cbor_string_copy 14 0 100.00% 18 0 100.00% +cbor_add_bytestring 14 0 100.00% 21 0 100.00% +cbor_add_string 14 0 100.00% 21 0 100.00% +cbor_add_bool 14 0 100.00% 21 0 100.00% +cbor_flatten_vector 14 1 92.86% 16 1 93.75% +cbor_build_frame 15 0 100.00% 25 0 100.00% +cbor_encode_rp_entity 13 0 100.00% 11 0 100.00% +cbor_encode_user_entity 21 0 100.00% 15 0 100.00% +cbor_encode_pubkey_param 36 0 100.00% 39 0 100.00% +cbor_encode_pubkey 10 0 100.00% 11 0 100.00% +cbor_encode_pubkey_list 18 0 100.00% 19 0 100.00% +cbor_encode_str_array 18 0 100.00% 19 0 100.00% +cbor_encode_cred_ext 55 0 100.00% 50 0 100.00% +cbor_encode_cred_opt 13 0 100.00% 11 0 100.00% +cbor_encode_assert_opt 13 0 100.00% 11 0 100.00% +cbor_encode_pin_auth 21 1 95.24% 22 3 86.36% +cbor_encode_pin_opt 4 0 100.00% 8 0 100.00% +cbor_encode_change_pin_auth 32 1 96.88% 36 3 91.67% +cbor_encode_assert_ext 33 0 100.00% 32 0 100.00% +cbor_decode_fmt 13 0 100.00% 15 0 100.00% +cbor_decode_pubkey 26 1 96.15% 36 2 94.44% +cbor_decode_cred_authdata 31 1 96.77% 35 3 91.43% +cbor_decode_assert_authdata 21 0 100.00% 32 0 100.00% +cbor_decode_attstmt 13 0 100.00% 16 0 100.00% +cbor_decode_uint64 4 0 100.00% 8 0 100.00% +cbor_decode_cred_id 8 0 100.00% 9 0 100.00% +cbor_decode_user 8 0 100.00% 9 0 100.00% +cbor_decode_rp_entity 8 0 100.00% 9 0 100.00% +cbor_decode_bool 10 0 100.00% 11 0 100.00% +cbor_build_uint 10 1 90.00% 9 1 88.89% +cbor_array_append 17 0 100.00% 21 0 100.00% +cbor_array_drop 18 0 100.00% 17 0 100.00% +cbor.c:ctap_check_cbor 28 0 100.00% 26 0 100.00% +cbor.c:check_key_type 8 0 100.00% 7 0 100.00% +cbor.c:cbor_add_arg 13 0 100.00% 21 0 100.00% +cbor.c:cbor_add_uint8 14 0 100.00% 21 0 100.00% +cbor.c:cbor_encode_largeblob_key_ext 6 0 100.00% 6 0 100.00% +cbor.c:cbor_encode_hmac_secret_param 59 4 93.22% 66 8 87.88% +cbor.c:get_cose_alg 46 1 97.83% 45 3 93.33% +cbor.c:find_cose_alg 35 0 100.00% 33 0 100.00% +cbor.c:decode_attcred 25 0 100.00% 44 0 100.00% +cbor.c:decode_cred_extensions 14 0 100.00% 24 0 100.00% +cbor.c:decode_cred_extension 41 1 97.56% 45 3 93.33% +cbor.c:decode_assert_extensions 14 0 100.00% 23 0 100.00% +cbor.c:decode_assert_extension 19 0 100.00% 27 0 100.00% +cbor.c:decode_attstmt_entry 56 0 100.00% 51 0 100.00% +cbor.c:decode_x5c 4 0 100.00% 6 0 100.00% +cbor.c:decode_cred_id_entry 10 0 100.00% 19 0 100.00% +cbor.c:decode_user_entry 25 0 100.00% 35 0 100.00% +cbor.c:decode_rp_entity_entry 15 0 100.00% 25 0 100.00% +------------------------------------------------------------------------------------------------------------------ +TOTAL 1070 13 98.79% 1258 31 97.54% + +File '/libfido2/src/compress.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------ +fido_compress 1 0 100.00% 3 0 100.00% +fido_uncompress 6 0 100.00% 5 0 100.00% +compress.c:rfc1951_deflate 33 4 87.88% 47 6 87.23% +compress.c:rfc1950_inflate 27 2 92.59% 22 4 81.82% +compress.c:rfc1951_inflate 38 8 78.95% 45 14 68.89% +------------------------------------------------------------------------------------------------------------------ +TOTAL 105 14 86.67% 122 24 80.33% + +File '/libfido2/src/config.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_dev_enable_entattest 1 0 100.00% 4 0 100.00% +fido_dev_toggle_always_uv 1 0 100.00% 4 0 100.00% +fido_dev_set_pin_minlen 1 0 100.00% 4 0 100.00% +fido_dev_force_pin_change 1 0 100.00% 4 0 100.00% +fido_dev_set_pin_minlen_rpid 6 0 100.00% 15 0 100.00% +config.c:config_enable_entattest_wait 6 0 100.00% 7 0 100.00% +config.c:config_tx 41 0 100.00% 49 0 100.00% +config.c:config_prepare_hmac 8 0 100.00% 19 0 100.00% +config.c:config_toggle_always_uv_wait 6 0 100.00% 7 0 100.00% +config.c:config_pin_minlen 5 0 100.00% 7 0 100.00% +config.c:config_pin_minlen_tx 36 0 100.00% 32 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 112 0 100.00% 152 0 100.00% + +File '/libfido2/src/cred.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_dev_make_cred 12 0 100.00% 10 0 100.00% +fido_check_rp_id 4 0 100.00% 11 0 100.00% +fido_cred_verify 59 2 96.61% 75 4 94.67% +fido_cred_verify_self 60 6 90.00% 87 11 87.36% +fido_cred_new 1 0 100.00% 3 0 100.00% +fido_cred_reset_tx 1 0 100.00% 19 0 100.00% +fido_cred_reset_rx 1 0 100.00% 7 0 100.00% +fido_cred_free 6 0 100.00% 9 0 100.00% +fido_cred_set_authdata 23 0 100.00% 28 0 100.00% +fido_cred_set_authdata_raw 25 0 100.00% 29 0 100.00% +fido_cred_set_id 6 0 100.00% 5 0 100.00% +fido_cred_set_x509 6 0 100.00% 5 0 100.00% +fido_cred_set_sig 6 0 100.00% 5 0 100.00% +fido_cred_set_attstmt 20 0 100.00% 23 0 100.00% +fido_cred_exclude 14 2 85.71% 19 3 84.21% +fido_cred_set_clientdata 12 12 0.00% 11 11 0.00% +fido_cred_set_clientdata_hash 8 0 100.00% 6 0 100.00% +fido_cred_set_rp 18 0 100.00% 22 0 100.00% +fido_cred_set_user 32 0 100.00% 41 0 100.00% +fido_cred_set_extensions 16 0 100.00% 10 0 100.00% +fido_cred_set_options 8 8 0.00% 5 5 0.00% +fido_cred_set_rk 2 0 100.00% 4 0 100.00% +fido_cred_set_uv 2 0 100.00% 4 0 100.00% +fido_cred_set_prot 21 0 100.00% 14 0 100.00% +fido_cred_set_pin_minlen 7 0 100.00% 8 0 100.00% +fido_cred_set_blob 13 0 100.00% 8 0 100.00% +fido_cred_set_fmt 20 4 80.00% 12 2 83.33% +fido_cred_set_type 23 2 91.30% 9 1 88.89% +fido_cred_type 1 0 100.00% 3 0 100.00% +fido_cred_flags 1 0 100.00% 3 0 100.00% +fido_cred_sigcount 1 0 100.00% 3 0 100.00% +fido_cred_clientdata_hash_ptr 1 0 100.00% 3 0 100.00% +fido_cred_clientdata_hash_len 1 0 100.00% 3 0 100.00% +fido_cred_x5c_ptr 1 0 100.00% 3 0 100.00% +fido_cred_x5c_len 1 0 100.00% 3 0 100.00% +fido_cred_sig_ptr 1 0 100.00% 3 0 100.00% +fido_cred_sig_len 1 0 100.00% 3 0 100.00% +fido_cred_authdata_ptr 1 0 100.00% 3 0 100.00% +fido_cred_authdata_len 1 0 100.00% 3 0 100.00% +fido_cred_authdata_raw_ptr 1 0 100.00% 3 0 100.00% +fido_cred_authdata_raw_len 1 0 100.00% 3 0 100.00% +fido_cred_attstmt_ptr 1 0 100.00% 3 0 100.00% +fido_cred_attstmt_len 1 0 100.00% 3 0 100.00% +fido_cred_pubkey_ptr 11 0 100.00% 21 0 100.00% +fido_cred_pubkey_len 11 0 100.00% 21 0 100.00% +fido_cred_id_ptr 1 0 100.00% 3 0 100.00% +fido_cred_id_len 1 0 100.00% 3 0 100.00% +fido_cred_aaguid_ptr 1 0 100.00% 3 0 100.00% +fido_cred_aaguid_len 1 0 100.00% 3 0 100.00% +fido_cred_prot 1 0 100.00% 3 0 100.00% +fido_cred_pin_minlen 1 0 100.00% 3 0 100.00% +fido_cred_fmt 1 0 100.00% 3 0 100.00% +fido_cred_rp_id 1 0 100.00% 3 0 100.00% +fido_cred_rp_name 1 0 100.00% 3 0 100.00% +fido_cred_user_name 1 0 100.00% 3 0 100.00% +fido_cred_display_name 1 0 100.00% 3 0 100.00% +fido_cred_user_id_ptr 1 0 100.00% 3 0 100.00% +fido_cred_user_id_len 1 0 100.00% 3 0 100.00% +fido_cred_largeblob_key_ptr 1 0 100.00% 3 0 100.00% +fido_cred_largeblob_key_len 1 0 100.00% 3 0 100.00% +cred.c:fido_dev_make_cred_wait 10 0 100.00% 7 0 100.00% +cred.c:fido_dev_make_cred_tx 64 0 100.00% 70 0 100.00% +cred.c:fido_dev_make_cred_rx 29 0 100.00% 32 0 100.00% +cred.c:parse_makecred_reply 14 0 100.00% 27 0 100.00% +cred.c:check_extensions 2 0 100.00% 6 0 100.00% +cred.c:get_signed_hash_u2f 27 0 100.00% 27 0 100.00% +cred.c:verify_attstmt 25 2 92.00% 43 6 86.05% +cred.c:fido_cred_clean_authdata 1 0 100.00% 8 0 100.00% +cred.c:fido_cred_clean_attstmt 1 0 100.00% 8 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 651 38 94.16% 849 43 94.94% + +File '/libfido2/src/credman.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_credman_get_dev_metadata 1 0 100.00% 4 0 100.00% +fido_credman_get_dev_rk 1 0 100.00% 4 0 100.00% +fido_credman_del_dev_rk 1 0 100.00% 4 0 100.00% +fido_credman_get_dev_rp 1 0 100.00% 4 0 100.00% +fido_credman_set_dev_rk 1 0 100.00% 4 0 100.00% +fido_credman_rk_new 1 0 100.00% 3 0 100.00% +fido_credman_rk_free 6 1 83.33% 8 1 87.50% +fido_credman_rk_count 1 0 100.00% 3 0 100.00% +fido_credman_rk 4 0 100.00% 5 0 100.00% +fido_credman_metadata_new 1 0 100.00% 3 0 100.00% +fido_credman_metadata_free 6 1 83.33% 7 1 85.71% +fido_credman_rk_existing 1 0 100.00% 3 0 100.00% +fido_credman_rk_remaining 1 0 100.00% 3 0 100.00% +fido_credman_rp_new 1 0 100.00% 3 0 100.00% +fido_credman_rp_free 6 1 83.33% 8 1 87.50% +fido_credman_rp_count 1 0 100.00% 3 0 100.00% +fido_credman_rp_id 4 0 100.00% 5 0 100.00% +fido_credman_rp_name 4 0 100.00% 5 0 100.00% +fido_credman_rp_id_hash_len 4 0 100.00% 5 0 100.00% +fido_credman_rp_id_hash_ptr 4 0 100.00% 5 0 100.00% +credman.c:credman_get_metadata_wait 11 0 100.00% 8 0 100.00% +credman.c:credman_tx 36 0 100.00% 50 0 100.00% +credman.c:credman_prepare_hmac 31 1 96.77% 50 2 96.00% +credman.c:credman_rx_metadata 19 0 100.00% 24 0 100.00% +credman.c:credman_parse_metadata 9 0 100.00% 17 0 100.00% +credman.c:credman_get_rk_wait 27 0 100.00% 23 0 100.00% +credman.c:credman_rx_rk 27 0 100.00% 35 0 100.00% +credman.c:credman_parse_rk_count 16 0 100.00% 20 0 100.00% +credman.c:credman_grow_array 17 2 88.24% 21 5 76.19% +credman.c:credman_parse_rk 23 0 100.00% 31 0 100.00% +credman.c:credman_rx_next_rk 23 2 91.30% 29 5 82.76% +credman.c:credman_del_rk_wait 16 0 100.00% 15 0 100.00% +credman.c:credman_get_rp_wait 23 0 100.00% 15 0 100.00% +credman.c:credman_rx_rp 27 0 100.00% 35 0 100.00% +credman.c:credman_parse_rp_count 16 0 100.00% 20 0 100.00% +credman.c:credman_parse_rp 9 0 100.00% 17 0 100.00% +credman.c:credman_rx_next_rp 23 2 91.30% 29 5 82.76% +credman.c:credman_set_dev_rk_wait 11 0 100.00% 8 0 100.00% +credman.c:credman_reset_rk 4 0 100.00% 9 0 100.00% +credman.c:credman_reset_rp 4 0 100.00% 12 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 422 10 97.63% 557 20 96.41% + +File '/libfido2/src/dev.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_dev_info_manifest 2 0 100.00% 11 0 100.00% +fido_dev_open_with_info 5 5 0.00% 6 6 0.00% +fido_dev_open 13 4 69.23% 16 6 62.50% +fido_dev_close 9 2 77.78% 8 1 87.50% +fido_dev_set_sigmask 18 18 0.00% 11 11 0.00% +fido_dev_cancel 11 0 100.00% 8 0 100.00% +fido_dev_set_io_functions 18 4 77.78% 14 6 57.14% +fido_dev_set_transport_functions 6 2 66.67% 9 3 66.67% +fido_dev_io_handle 1 1 0.00% 3 3 0.00% +fido_init 8 1 87.50% 5 0 100.00% +fido_dev_new 5 0 100.00% 14 0 100.00% +fido_dev_new_with_info 10 10 0.00% 16 16 0.00% +fido_dev_free 6 0 100.00% 8 0 100.00% +fido_dev_protocol 1 0 100.00% 3 0 100.00% +fido_dev_major 1 0 100.00% 3 0 100.00% +fido_dev_minor 1 0 100.00% 3 0 100.00% +fido_dev_build 1 0 100.00% 3 0 100.00% +fido_dev_flags 1 0 100.00% 3 0 100.00% +fido_dev_is_fido2 2 0 100.00% 3 0 100.00% +fido_dev_is_winhello 2 2 0.00% 3 3 0.00% +fido_dev_supports_pin 3 0 100.00% 3 0 100.00% +fido_dev_has_pin 2 0 100.00% 3 0 100.00% +fido_dev_supports_cred_prot 2 0 100.00% 3 0 100.00% +fido_dev_supports_credman 2 0 100.00% 3 0 100.00% +fido_dev_supports_uv 3 0 100.00% 3 0 100.00% +fido_dev_has_uv 2 0 100.00% 3 0 100.00% +fido_dev_supports_permissions 2 0 100.00% 3 0 100.00% +fido_dev_force_u2f 2 0 100.00% 4 0 100.00% +fido_dev_force_fido2 2 2 0.00% 3 3 0.00% +fido_dev_get_pin_protocol 11 0 100.00% 7 0 100.00% +fido_dev_maxmsgsize 1 0 100.00% 3 0 100.00% +fido_dev_set_timeout 6 2 66.67% 6 1 83.33% +dev.c:run_manifest 10 0 100.00% 13 0 100.00% +dev.c:fido_dev_open_wait 10 0 100.00% 7 0 100.00% +dev.c:fido_dev_open_tx 56 11 80.36% 56 20 64.29% +dev.c:set_random_report_len 11 0 100.00% 6 0 100.00% +dev.c:fido_dev_open_rx 36 1 97.22% 53 1 98.11% +dev.c:fido_dev_set_flags 1 0 100.00% 5 0 100.00% +dev.c:fido_dev_set_extension_flags 7 0 100.00% 7 0 100.00% +dev.c:fido_dev_set_option_flags 31 0 100.00% 20 0 100.00% +dev.c:fido_dev_set_protocol_flags 11 0 100.00% 17 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 332 65 80.42% 378 80 78.84% + +File '/libfido2/src/ecdh.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_do_ecdh 29 0 100.00% 36 0 100.00% +ecdh.c:do_ecdh 37 0 100.00% 44 0 100.00% +ecdh.c:kdf 19 1 94.74% 28 2 92.86% +ecdh.c:hkdf_sha256 32 1 96.88% 38 3 92.11% +------------------------------------------------------------------------------------------------------------------- +TOTAL 117 2 98.29% 146 5 96.58% + +File '/libfido2/src/eddsa.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +eddsa_pk_decode 8 0 100.00% 9 0 100.00% +eddsa_pk_new 1 0 100.00% 3 0 100.00% +eddsa_pk_free 6 0 100.00% 7 0 100.00% +eddsa_pk_from_ptr 10 0 100.00% 12 0 100.00% +eddsa_pk_to_EVP_PKEY 3 0 100.00% 7 0 100.00% +eddsa_pk_from_EVP_PKEY 18 2 88.89% 12 1 91.67% +eddsa_verify_sig 19 2 89.47% 30 6 80.00% +eddsa_pk_verify_sig 7 1 85.71% 13 2 84.62% +eddsa.c:decode_pubkey_point 8 0 100.00% 11 0 100.00% +eddsa.c:decode_coord 8 0 100.00% 10 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 88 5 94.32% 114 9 92.11% + +File '/libfido2/src/err.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_strerr 122 10 91.80% 126 10 92.06% +------------------------------------------------------------------------------------------------------------------- +TOTAL 122 10 91.80% 126 10 92.06% + +File '/libfido2/src/es256.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +es256_pk_decode 8 0 100.00% 9 0 100.00% +es256_pk_encode 56 0 100.00% 48 0 100.00% +es256_sk_new 1 0 100.00% 3 0 100.00% +es256_sk_free 6 0 100.00% 7 0 100.00% +es256_pk_new 1 0 100.00% 3 0 100.00% +es256_pk_free 6 0 100.00% 7 0 100.00% +es256_pk_from_ptr 15 0 100.00% 17 0 100.00% +es256_pk_set_x 1 0 100.00% 4 0 100.00% +es256_pk_set_y 1 0 100.00% 4 0 100.00% +es256_sk_create 39 0 100.00% 40 0 100.00% +es256_pk_to_EVP_PKEY 42 0 100.00% 53 0 100.00% +es256_pk_from_EC_KEY 42 2 95.24% 47 4 91.49% +es256_pk_from_EVP_PKEY 8 2 75.00% 7 1 85.71% +es256_sk_to_EVP_PKEY 28 0 100.00% 39 0 100.00% +es256_derive_pk 25 0 100.00% 29 0 100.00% +es256_verify_sig 12 2 83.33% 19 5 73.68% +es256_pk_verify_sig 7 1 85.71% 13 2 84.62% +es256.c:decode_pubkey_point 9 0 100.00% 13 0 100.00% +es256.c:decode_coord 8 0 100.00% 10 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 315 7 97.78% 372 12 96.77% + +File '/libfido2/src/es384.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +es384_pk_decode 8 0 100.00% 9 0 100.00% +es384_pk_new 1 0 100.00% 3 0 100.00% +es384_pk_free 6 0 100.00% 7 0 100.00% +es384_pk_from_ptr 15 0 100.00% 17 0 100.00% +es384_pk_to_EVP_PKEY 42 0 100.00% 53 0 100.00% +es384_pk_from_EC_KEY 42 2 95.24% 47 4 91.49% +es384_pk_from_EVP_PKEY 8 2 75.00% 7 1 85.71% +es384_verify_sig 12 2 83.33% 19 5 73.68% +es384_pk_verify_sig 7 1 85.71% 13 2 84.62% +es384.c:decode_pubkey_point 9 0 100.00% 13 0 100.00% +es384.c:decode_coord 8 1 87.50% 10 3 70.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 158 8 94.94% 198 15 92.42% + +File '/libfido2/src/extern.h': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- + +File '/libfido2/src/fallthrough.h': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- + +File '/libfido2/src/fido.h': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- + +File '/libfido2/src/hid.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_hid_get_usage 13 0 100.00% 22 0 100.00% +fido_hid_get_report_len 19 0 100.00% 27 0 100.00% +fido_dev_info_new 1 0 100.00% 3 0 100.00% +fido_dev_info_free 9 0 100.00% 9 0 100.00% +fido_dev_info_ptr 1 0 100.00% 3 0 100.00% +fido_dev_info_set 26 2 92.31% 30 3 90.00% +fido_dev_info_path 1 0 100.00% 3 0 100.00% +fido_dev_info_vendor 1 0 100.00% 3 0 100.00% +fido_dev_info_product 1 0 100.00% 3 0 100.00% +fido_dev_info_manufacturer_string 1 0 100.00% 3 0 100.00% +fido_dev_info_product_string 1 0 100.00% 3 0 100.00% +hid.c:get_key_len 6 0 100.00% 12 0 100.00% +hid.c:get_key_val 6 0 100.00% 18 0 100.00% +hid.c:fido_dev_info_reset 1 0 100.00% 6 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 87 2 97.70% 145 3 97.93% + +File '/libfido2/src/hid_linux.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_hid_manifest 35 4 88.57% 41 2 95.12% +fido_hid_open 33 33 0.00% 51 51 0.00% +fido_hid_close 3 3 0.00% 6 6 0.00% +fido_hid_set_sigmask 2 2 0.00% 6 6 0.00% +fido_hid_read 15 15 0.00% 21 21 0.00% +fido_hid_write 12 12 0.00% 17 17 0.00% +fido_hid_report_in_len 1 1 0.00% 4 4 0.00% +fido_hid_report_out_len 1 1 0.00% 4 4 0.00% +hid_linux.c:copy_info 34 0 100.00% 44 0 100.00% +hid_linux.c:is_fido 15 1 93.33% 16 1 93.75% +hid_linux.c:get_parent_attr 6 0 100.00% 9 0 100.00% +hid_linux.c:parse_uevent 12 0 100.00% 24 0 100.00% +hid_linux.c:get_usb_attr 1 0 100.00% 3 0 100.00% +hid_linux.c:get_report_descriptor 14 1 92.86% 17 3 82.35% +------------------------------------------------------------------------------------------------------------------- +TOTAL 184 73 60.33% 263 115 56.27% + +File '/libfido2/src/hid_unix.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_hid_unix_open 18 11 38.89% 22 14 36.36% +fido_hid_unix_wait 11 10 9.09% 21 12 42.86% +------------------------------------------------------------------------------------------------------------------- +TOTAL 29 21 27.59% 43 26 39.53% + +File '/libfido2/src/info.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_dev_get_cbor_info_wait 10 0 100.00% 7 0 100.00% +fido_dev_get_cbor_info 1 0 100.00% 4 0 100.00% +fido_cbor_info_new 4 0 100.00% 7 0 100.00% +fido_cbor_info_reset 1 0 100.00% 10 0 100.00% +fido_cbor_info_free 6 0 100.00% 8 0 100.00% +fido_cbor_info_versions_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_versions_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_extensions_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_extensions_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_transports_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_transports_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_aaguid_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_aaguid_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_options_name_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_options_value_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_options_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxcredbloblen 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxmsgsiz 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxcredcntlst 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxcredidlen 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxlargeblob 1 0 100.00% 3 0 100.00% +fido_cbor_info_fwversion 1 0 100.00% 3 0 100.00% +fido_cbor_info_minpinlen 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxrpid_minpinlen 1 0 100.00% 3 0 100.00% +fido_cbor_info_uv_attempts 1 0 100.00% 3 0 100.00% +fido_cbor_info_uv_modality 1 0 100.00% 3 0 100.00% +fido_cbor_info_rk_remaining 1 0 100.00% 3 0 100.00% +fido_cbor_info_protocols_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_protocols_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_algorithm_count 1 0 100.00% 3 0 100.00% +fido_cbor_info_algorithm_type 4 0 100.00% 5 0 100.00% +fido_cbor_info_algorithm_cose 4 0 100.00% 5 0 100.00% +fido_cbor_info_new_pin_required 1 0 100.00% 3 0 100.00% +fido_cbor_info_certs_name_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_certs_value_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_certs_len 1 0 100.00% 3 0 100.00% +info.c:fido_dev_get_cbor_info_tx 8 0 100.00% 9 0 100.00% +info.c:fido_dev_get_cbor_info_rx 14 0 100.00% 21 0 100.00% +info.c:parse_reply_element 32 0 100.00% 59 0 100.00% +info.c:decode_string_array 12 0 100.00% 17 0 100.00% +info.c:decode_string 4 0 100.00% 10 0 100.00% +info.c:decode_aaguid 8 0 100.00% 10 0 100.00% +info.c:decode_options 11 0 100.00% 15 0 100.00% +info.c:decode_option 7 0 100.00% 15 0 100.00% +info.c:decode_protocols 12 0 100.00% 17 0 100.00% +info.c:decode_protocol 6 0 100.00% 12 0 100.00% +info.c:decode_algorithms 12 0 100.00% 17 0 100.00% +info.c:decode_algorithm 9 0 100.00% 17 0 100.00% +info.c:decode_algorithm_entry 20 0 100.00% 27 0 100.00% +info.c:decode_certs 11 0 100.00% 15 0 100.00% +info.c:decode_cert 7 0 100.00% 15 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 232 0 100.00% 409 0 100.00% + +File '/libfido2/src/io.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_tx 14 0 100.00% 11 0 100.00% +fido_rx 13 1 92.31% 14 3 78.57% +fido_rx_cbor_status 16 0 100.00% 19 0 100.00% +io.c:transport_tx 7 0 100.00% 10 0 100.00% +io.c:tx_empty 9 0 100.00% 14 0 100.00% +io.c:tx_pkt 7 0 100.00% 10 0 100.00% +io.c:tx 13 0 100.00% 19 0 100.00% +io.c:tx_preamble 17 1 94.12% 20 1 95.00% +io.c:tx_frame 16 1 93.75% 18 1 94.44% +io.c:transport_rx 7 0 100.00% 10 0 100.00% +io.c:rx 40 2 95.00% 52 2 96.15% +io.c:rx_preamble 23 2 91.30% 22 5 77.27% +io.c:rx_frame 11 0 100.00% 11 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 193 7 96.37% 230 12 94.78% + +File '/libfido2/src/iso7816.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +iso7816_new 4 0 100.00% 16 0 100.00% +iso7816_free 6 0 100.00% 7 0 100.00% +iso7816_add 6 1 83.33% 8 1 87.50% +iso7816_ptr 1 0 100.00% 3 0 100.00% +iso7816_len 1 0 100.00% 4 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 18 1 94.44% 38 1 97.37% + +File '/libfido2/src/largeblob.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_dev_largeblob_get 26 2 92.31% 38 4 89.47% +fido_dev_largeblob_set 27 0 100.00% 36 0 100.00% +fido_dev_largeblob_remove 12 0 100.00% 18 0 100.00% +fido_dev_largeblob_get_array 15 2 86.67% 27 4 85.19% +fido_dev_largeblob_set_array 14 0 100.00% 19 0 100.00% +largeblob.c:largeblob_get_array 32 0 100.00% 36 0 100.00% +largeblob.c:get_chunklen 10 1 90.00% 9 1 88.89% +largeblob.c:largeblob_get_tx 19 0 100.00% 24 0 100.00% +largeblob.c:largeblob_get_rx 26 0 100.00% 30 0 100.00% +largeblob.c:parse_largeblob_reply 8 0 100.00% 9 0 100.00% +largeblob.c:largeblob_array_check 7 0 100.00% 16 0 100.00% +largeblob.c:largeblob_array_digest 10 0 100.00% 9 0 100.00% +largeblob.c:largeblob_array_load 14 2 85.71% 19 7 63.16% +largeblob.c:largeblob_array_lookup 25 0 100.00% 33 0 100.00% +largeblob.c:largeblob_decode 16 2 87.50% 16 6 62.50% +largeblob.c:largeblob_do_decode 27 3 88.89% 30 7 76.67% +largeblob.c:largeblob_decrypt 15 0 100.00% 24 0 100.00% +largeblob.c:largeblob_aad 1 0 100.00% 10 0 100.00% +largeblob.c:largeblob_reset 1 0 100.00% 5 0 100.00% +largeblob.c:largeblob_encode 16 0 100.00% 21 0 100.00% +largeblob.c:largeblob_new 1 0 100.00% 3 0 100.00% +largeblob.c:largeblob_seal 20 0 100.00% 32 0 100.00% +largeblob.c:largeblob_get_nonce 8 0 100.00% 16 0 100.00% +largeblob.c:largeblob_free 6 0 100.00% 8 0 100.00% +largeblob.c:largeblob_add 27 2 92.59% 35 3 91.43% +largeblob.c:largeblob_drop 21 0 100.00% 27 0 100.00% +largeblob.c:largeblob_set_array 54 2 96.30% 61 4 93.44% +largeblob.c:largeblob_get_uv_token 19 0 100.00% 23 0 100.00% +largeblob.c:largeblob_set_tx 35 0 100.00% 36 0 100.00% +largeblob.c:prepare_hmac 13 2 84.62% 23 7 69.57% +------------------------------------------------------------------------------------------------------------------- +TOTAL 525 18 96.57% 693 43 93.80% + +File '/libfido2/src/log.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_log_init 1 0 100.00% 4 0 100.00% +fido_log_debug 6 1 83.33% 8 1 87.50% +fido_log_xxd 16 1 93.75% 24 1 95.83% +fido_log_error 8 2 75.00% 11 2 81.82% +fido_set_log_handler 3 0 100.00% 4 0 100.00% +log.c:log_on_stderr 1 1 0.00% 3 3 0.00% +log.c:do_log 4 0 100.00% 9 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 39 5 87.18% 63 7 88.89% + +File '/libfido2/src/netlink.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_nl_power_nfc 18 0 100.00% 24 0 100.00% +fido_nl_get_nfc_target 17 0 100.00% 31 0 100.00% +fido_nl_free 10 2 80.00% 9 2 77.78% +fido_nl_new 16 1 93.75% 26 3 88.46% +set_netlink_io_functions 1 0 100.00% 4 0 100.00% +netlink.c:nlmsg_new 8 0 100.00% 15 0 100.00% +netlink.c:nlmsg_set_genl 1 0 100.00% 7 0 100.00% +netlink.c:nlmsg_write 6 1 83.33% 7 1 85.71% +netlink.c:nlmsg_set_u32 1 0 100.00% 3 0 100.00% +netlink.c:nlmsg_setattr 15 1 93.33% 17 0 100.00% +netlink.c:nlmsg_tx 10 1 90.00% 13 3 76.92% +netlink.c:nlmsg_ptr 1 0 100.00% 3 0 100.00% +netlink.c:nlmsg_len 1 0 100.00% 3 0 100.00% +netlink.c:nlmsg_rx 11 2 81.82% 17 6 64.71% +netlink.c:nl_parse_reply 20 0 100.00% 28 0 100.00% +netlink.c:nlmsg_from_buf 15 0 100.00% 17 0 100.00% +netlink.c:nlmsg_type 1 0 100.00% 3 0 100.00% +netlink.c:nlmsg_get_status 8 0 100.00% 8 0 100.00% +netlink.c:nlmsg_read 6 0 100.00% 7 0 100.00% +netlink.c:nlmsg_get_genl 6 0 100.00% 7 0 100.00% +netlink.c:nlmsg_iter 6 0 100.00% 13 0 100.00% +netlink.c:nlmsg_getattr 1 0 100.00% 3 0 100.00% +netlink.c:nla_from_buf 17 0 100.00% 21 0 100.00% +netlink.c:nl_nfc_poll 18 0 100.00% 25 0 100.00% +netlink.c:parse_nfc_event 10 0 100.00% 17 0 100.00% +netlink.c:nla_type 1 0 100.00% 3 0 100.00% +netlink.c:nla_get_u32 1 0 100.00% 3 0 100.00% +netlink.c:nla_read 6 0 100.00% 7 0 100.00% +netlink.c:nl_dump_nfc_target 19 0 100.00% 31 0 100.00% +netlink.c:parse_target 9 0 100.00% 13 0 100.00% +netlink.c:nl_get_nfc_family 23 0 100.00% 33 0 100.00% +netlink.c:nlmsg_set_u16 1 0 100.00% 3 0 100.00% +netlink.c:nlmsg_set_str 1 0 100.00% 3 0 100.00% +netlink.c:parse_family 10 0 100.00% 17 0 100.00% +netlink.c:nla_get_u16 1 0 100.00% 3 0 100.00% +netlink.c:nla_iter 6 0 100.00% 13 0 100.00% +netlink.c:nla_getattr 1 0 100.00% 3 0 100.00% +netlink.c:parse_mcastgrps 1 0 100.00% 3 0 100.00% +netlink.c:parse_mcastgrp 15 0 100.00% 24 0 100.00% +netlink.c:nla_get_str 10 0 100.00% 11 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 329 8 97.57% 498 15 96.99% + +File '/libfido2/src/nfc.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_nfc_tx 28 0 100.00% 43 0 100.00% +fido_nfc_rx 8 0 100.00% 13 0 100.00% +nfc_is_fido 13 1 92.31% 21 3 85.71% +fido_is_nfc 3 0 100.00% 3 0 100.00% +fido_dev_set_nfc 4 1 75.00% 18 3 83.33% +nfc.c:nfc_do_tx 20 0 100.00% 25 0 100.00% +nfc.c:tx_short_apdu 14 0 100.00% 32 0 100.00% +nfc.c:rx_init 25 0 100.00% 27 0 100.00% +nfc.c:rx_cbor 4 0 100.00% 6 0 100.00% +nfc.c:rx_msg 18 2 88.89% 23 6 73.91% +nfc.c:rx_apdu 14 1 92.86% 22 3 86.36% +nfc.c:tx_get_response 4 0 100.00% 11 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 155 5 96.77% 244 15 93.85% + +File '/libfido2/src/nfc_linux.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_nfc_manifest 35 7 80.00% 45 15 66.67% +fido_nfc_open 20 3 85.00% 23 4 82.61% +fido_nfc_close 1 1 0.00% 4 4 0.00% +fido_nfc_set_sigmask 2 2 0.00% 6 6 0.00% +fido_nfc_read 14 14 0.00% 30 30 0.00% +fido_nfc_write 12 12 0.00% 18 18 0.00% +nfc_linux.c:copy_info 39 22 43.59% 44 16 63.64% +nfc_linux.c:get_usb_attr 1 1 0.00% 3 3 0.00% +nfc_linux.c:get_parent_attr 6 6 0.00% 9 9 0.00% +nfc_linux.c:sysnum_from_syspath 15 0 100.00% 17 0 100.00% +nfc_linux.c:nfc_new 6 0 100.00% 11 0 100.00% +nfc_linux.c:nfc_target_connect 9 9 0.00% 21 21 0.00% +nfc_linux.c:nfc_free 12 0 100.00% 11 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 172 77 55.23% 242 126 47.93% + +File '/libfido2/src/pcsc.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_pcsc_manifest 51 0 100.00% 55 0 100.00% +fido_pcsc_open 32 0 100.00% 43 0 100.00% +fido_pcsc_close 6 0 100.00% 9 0 100.00% +fido_pcsc_read 8 0 100.00% 16 0 100.00% +fido_pcsc_write 8 0 100.00% 22 0 100.00% +fido_pcsc_tx 1 0 100.00% 3 0 100.00% +fido_pcsc_rx 1 0 100.00% 3 0 100.00% +fido_is_pcsc 3 0 100.00% 3 0 100.00% +fido_dev_set_pcsc 4 1 75.00% 18 3 83.33% +pcsc.c:list_readers 24 0 100.00% 24 0 100.00% +pcsc.c:copy_info 30 0 100.00% 41 0 100.00% +pcsc.c:get_reader 25 0 100.00% 28 0 100.00% +pcsc.c:prepare_io_request 11 0 100.00% 17 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 204 1 99.51% 282 3 98.94% + +File '/libfido2/src/pin.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_sha256 7 0 100.00% 10 0 100.00% +fido_dev_get_uv_token 1 0 100.00% 3 0 100.00% +fido_dev_set_pin 1 0 100.00% 4 0 100.00% +fido_dev_get_retry_count 1 0 100.00% 4 0 100.00% +fido_dev_get_uv_retry_count 1 0 100.00% 4 0 100.00% +cbor_add_uv_params 17 0 100.00% 23 0 100.00% +pin.c:uv_token_wait 14 2 85.71% 12 1 91.67% +pin.c:ctap21_uv_token_tx 49 0 100.00% 53 0 100.00% +pin.c:pin_sha256_enc 19 0 100.00% 24 0 100.00% +pin.c:encode_uv_permission 20 1 95.00% 19 3 84.21% +pin.c:ctap20_uv_token_tx 37 0 100.00% 45 0 100.00% +pin.c:uv_token_rx 27 0 100.00% 34 0 100.00% +pin.c:parse_uv_token 8 0 100.00% 10 0 100.00% +pin.c:fido_dev_set_pin_wait 21 0 100.00% 24 0 100.00% +pin.c:fido_dev_change_pin_tx 45 0 100.00% 56 0 100.00% +pin.c:pin_pad64_enc 15 0 100.00% 21 0 100.00% +pin.c:pad64 18 0 100.00% 20 0 100.00% +pin.c:fido_dev_set_pin_tx 33 0 100.00% 41 0 100.00% +pin.c:fido_dev_get_pin_retry_count_wait 10 0 100.00% 7 0 100.00% +pin.c:fido_dev_get_retry_count_tx 19 0 100.00% 23 0 100.00% +pin.c:fido_dev_get_pin_retry_count_rx 19 0 100.00% 24 0 100.00% +pin.c:parse_pin_retry_count 1 0 100.00% 3 0 100.00% +pin.c:parse_retry_count 13 0 100.00% 16 0 100.00% +pin.c:fido_dev_get_uv_retry_count_wait 10 0 100.00% 7 0 100.00% +pin.c:fido_dev_get_uv_retry_count_rx 19 0 100.00% 24 0 100.00% +pin.c:parse_uv_retry_count 1 0 100.00% 3 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 426 3 99.30% 514 4 99.22% + +File '/libfido2/src/random.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_get_random 6 0 100.00% 6 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 6 0 100.00% 6 0 100.00% + +File '/libfido2/src/reset.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_dev_reset 1 0 100.00% 4 0 100.00% +reset.c:fido_dev_reset_wait 15 0 100.00% 11 0 100.00% +reset.c:fido_dev_reset_tx 8 0 100.00% 8 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 24 0 100.00% 23 0 100.00% + +File '/libfido2/src/rs1.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +rs1_verify_sig 20 1 95.00% 30 3 90.00% +rs1.c:rs1_get_EVP_MD 4 0 100.00% 6 0 100.00% +rs1.c:rs1_free_EVP_MD 1 0 100.00% 3 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 25 1 96.00% 39 3 92.31% + +File '/libfido2/src/rs256.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +rs256_pk_decode 8 0 100.00% 9 0 100.00% +rs256_pk_new 1 0 100.00% 3 0 100.00% +rs256_pk_free 6 0 100.00% 7 0 100.00% +rs256_pk_from_ptr 10 0 100.00% 12 0 100.00% +rs256_pk_to_EVP_PKEY 35 0 100.00% 43 0 100.00% +rs256_pk_from_RSA 32 6 81.25% 26 9 65.38% +rs256_pk_from_EVP_PKEY 8 2 75.00% 7 1 85.71% +rs256_verify_sig 20 1 95.00% 30 2 93.33% +rs256_pk_verify_sig 7 1 85.71% 13 2 84.62% +rs256.c:decode_rsa_pubkey 9 0 100.00% 13 0 100.00% +rs256.c:decode_bignum 8 0 100.00% 10 0 100.00% +rs256.c:rs256_get_EVP_MD 4 0 100.00% 6 0 100.00% +rs256.c:rs256_free_EVP_MD 1 0 100.00% 3 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 149 10 93.29% 182 14 92.31% + +File '/libfido2/src/time.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_time_now 4 0 100.00% 7 0 100.00% +fido_time_delta 23 1 95.65% 23 0 100.00% +time.c:timespec_to_ms 16 2 87.50% 13 2 84.62% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 43 3 93.02% 43 2 95.35% + +File '/libfido2/src/touch.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_dev_get_touch_begin 50 0 100.00% 59 0 100.00% +fido_dev_get_touch_status 17 0 100.00% 20 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 67 0 100.00% 79 0 100.00% + +File '/libfido2/src/tpm.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_get_signed_hash_tpm 25 0 100.00% 39 0 100.00% +tpm.c:check_es256_pubarea 19 0 100.00% 30 0 100.00% +tpm.c:bswap_es256_pubarea 1 0 100.00% 12 0 100.00% +tpm.c:check_rs256_pubarea 17 0 100.00% 28 0 100.00% +tpm.c:bswap_rs256_pubarea 1 0 100.00% 10 0 100.00% +tpm.c:check_sha1_certinfo 15 0 100.00% 38 0 100.00% +tpm.c:get_signed_sha1 17 0 100.00% 19 0 100.00% +tpm.c:get_signed_name 7 0 100.00% 10 0 100.00% +tpm.c:bswap_sha1_certinfo 1 0 100.00% 8 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 103 0 100.00% 194 0 100.00% + +File '/libfido2/src/types.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_str_array_free 4 0 100.00% 7 0 100.00% +fido_opt_array_free 4 0 100.00% 9 0 100.00% +fido_byte_array_free 1 0 100.00% 5 0 100.00% +fido_algo_free 1 0 100.00% 5 0 100.00% +fido_algo_array_free 4 0 100.00% 7 0 100.00% +fido_cert_array_free 4 0 100.00% 9 0 100.00% +fido_str_array_pack 11 0 100.00% 14 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 29 0 100.00% 56 0 100.00% + +File '/libfido2/src/u2f.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +u2f_register 76 0 100.00% 81 0 100.00% +u2f_authenticate 33 0 100.00% 37 0 100.00% +u2f_get_touch_begin 37 0 100.00% 45 0 100.00% +u2f_get_touch_status 26 0 100.00% 36 0 100.00% +u2f.c:key_lookup 51 0 100.00% 65 0 100.00% +u2f.c:send_dummy_register 37 0 100.00% 45 0 100.00% +u2f.c:delay_ms 13 1 92.31% 15 3 80.00% +u2f.c:parse_register_reply 49 0 100.00% 62 0 100.00% +u2f.c:x5c_get 21 1 95.24% 26 3 88.46% +u2f.c:sig_get 6 0 100.00% 10 0 100.00% +u2f.c:encode_cred_attstmt 45 0 100.00% 52 0 100.00% +u2f.c:encode_cred_authdata 33 2 93.94% 61 6 90.16% +u2f.c:cbor_blob_from_ec_point 22 0 100.00% 31 0 100.00% +u2f.c:u2f_authenticate_single 32 0 100.00% 43 0 100.00% +u2f.c:do_auth 56 0 100.00% 67 0 100.00% +u2f.c:parse_auth_reply 23 0 100.00% 23 0 100.00% +u2f.c:authdata_fake 12 0 100.00% 27 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 572 4 99.30% 726 12 98.35% + +File '/libfido2/src/util.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_to_uint64 14 1 92.86% 14 1 92.86% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 14 1 92.86% 14 1 92.86% diff --git a/fuzz/fuzz_assert.c b/fuzz/fuzz_assert.c new file mode 100644 index 0000000..603957e --- /dev/null +++ b/fuzz/fuzz_assert.c @@ -0,0 +1,532 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "wiredata_u2f.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +/* Parameter set defining a FIDO2 get assertion operation. */ +struct param { + char pin[MAXSTR]; + char rp_id[MAXSTR]; + int ext; + int seed; + struct blob cdh; + struct blob cred; + struct blob es256; + struct blob rs256; + struct blob eddsa; + struct blob wire_data; + uint8_t cred_count; + uint8_t type; + uint8_t opt; + uint8_t up; + uint8_t uv; +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * get assertion using the example parameters above. + */ +static const uint8_t dummy_wire_data_fido[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_ASSERT, +}; + +/* + * Collection of HID reports from an authenticator issued with a U2F + * authentication using the example parameters above. + */ +static const uint8_t dummy_wire_data_u2f[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_AUTH, +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 15 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_byte(v[0], &p->uv) < 0 || + unpack_byte(v[1], &p->up) < 0 || + unpack_byte(v[2], &p->opt) < 0 || + unpack_byte(v[3], &p->type) < 0 || + unpack_byte(v[4], &p->cred_count) < 0 || + unpack_int(v[5], &p->ext) < 0 || + unpack_int(v[6], &p->seed) < 0 || + unpack_string(v[7], p->rp_id) < 0 || + unpack_string(v[8], p->pin) < 0 || + unpack_blob(v[9], &p->wire_data) < 0 || + unpack_blob(v[10], &p->rs256) < 0 || + unpack_blob(v[11], &p->es256) < 0 || + unpack_blob(v[12], &p->eddsa) < 0 || + unpack_blob(v[13], &p->cred) < 0 || + unpack_blob(v[14], &p->cdh) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[15], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(15)) == NULL || + (argv[0] = pack_byte(p->uv)) == NULL || + (argv[1] = pack_byte(p->up)) == NULL || + (argv[2] = pack_byte(p->opt)) == NULL || + (argv[3] = pack_byte(p->type)) == NULL || + (argv[4] = pack_byte(p->cred_count)) == NULL || + (argv[5] = pack_int(p->ext)) == NULL || + (argv[6] = pack_int(p->seed)) == NULL || + (argv[7] = pack_string(p->rp_id)) == NULL || + (argv[8] = pack_string(p->pin)) == NULL || + (argv[9] = pack_blob(&p->wire_data)) == NULL || + (argv[10] = pack_blob(&p->rs256)) == NULL || + (argv[11] = pack_blob(&p->es256)) == NULL || + (argv[12] = pack_blob(&p->eddsa)) == NULL || + (argv[13] = pack_blob(&p->cred)) == NULL || + (argv[14] = pack_blob(&p->cdh)) == NULL) + goto fail; + + for (size_t i = 0; i < 15; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 15; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + dummy.type = 1; /* rsa */ + dummy.ext = FIDO_EXT_HMAC_SECRET; + + strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); + strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id)); + + dummy.cred.len = sizeof(dummy_cdh); /* XXX */ + dummy.cdh.len = sizeof(dummy_cdh); + dummy.es256.len = sizeof(dummy_es256); + dummy.rs256.len = sizeof(dummy_rs256); + dummy.eddsa.len = sizeof(dummy_eddsa); + dummy.wire_data.len = sizeof(dummy_wire_data_fido); + + memcpy(&dummy.cred.body, &dummy_cdh, dummy.cred.len); /* XXX */ + memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len); + memcpy(&dummy.wire_data.body, &dummy_wire_data_fido, + dummy.wire_data.len); + memcpy(&dummy.es256.body, &dummy_es256, dummy.es256.len); + memcpy(&dummy.rs256.body, &dummy_rs256, dummy.rs256.len); + memcpy(&dummy.eddsa.body, &dummy_eddsa, dummy.eddsa.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static void +get_assert(fido_assert_t *assert, uint8_t opt, const struct blob *cdh, + const char *rp_id, int ext, uint8_t up, uint8_t uv, const char *pin, + uint8_t cred_count, const struct blob *cred) +{ + fido_dev_t *dev; + + if ((dev = open_dev(opt & 2)) == NULL) + return; + if (opt & 1) + fido_dev_force_u2f(dev); + if (ext & FIDO_EXT_HMAC_SECRET) + fido_assert_set_extensions(assert, FIDO_EXT_HMAC_SECRET); + if (ext & FIDO_EXT_CRED_BLOB) + fido_assert_set_extensions(assert, FIDO_EXT_CRED_BLOB); + if (ext & FIDO_EXT_LARGEBLOB_KEY) + fido_assert_set_extensions(assert, FIDO_EXT_LARGEBLOB_KEY); + if (up & 1) + fido_assert_set_up(assert, FIDO_OPT_TRUE); + else if (opt & 1) + fido_assert_set_up(assert, FIDO_OPT_FALSE); + if (uv & 1) + fido_assert_set_uv(assert, FIDO_OPT_TRUE); + + for (uint8_t i = 0; i < cred_count; i++) + fido_assert_allow_cred(assert, cred->body, cred->len); + + fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len); + fido_assert_set_rp(assert, rp_id); + /* XXX reuse cred as hmac salt */ + fido_assert_set_hmac_salt(assert, cred->body, cred->len); + + /* repeat memory operations to trigger reallocation paths */ + fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len); + fido_assert_set_rp(assert, rp_id); + fido_assert_set_hmac_salt(assert, cred->body, cred->len); + + if (strlen(pin) == 0) + pin = NULL; + + fido_dev_get_assert(dev, assert, (opt & 1) ? NULL : pin); + + fido_dev_cancel(dev); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +verify_assert(int type, const unsigned char *cdh_ptr, size_t cdh_len, + const char *rp_id, const unsigned char *authdata_ptr, size_t authdata_len, + const unsigned char *sig_ptr, size_t sig_len, uint8_t up, uint8_t uv, + int ext, void *pk) +{ + fido_assert_t *assert = NULL; + int r; + + if ((assert = fido_assert_new()) == NULL) + return; + + fido_assert_set_clientdata_hash(assert, cdh_ptr, cdh_len); + fido_assert_set_rp(assert, rp_id); + fido_assert_set_count(assert, 1); + + if (fido_assert_set_authdata(assert, 0, authdata_ptr, + authdata_len) != FIDO_OK) { + fido_assert_set_authdata_raw(assert, 0, authdata_ptr, + authdata_len); + } + + if (up & 1) + fido_assert_set_up(assert, FIDO_OPT_TRUE); + if (uv & 1) + fido_assert_set_uv(assert, FIDO_OPT_TRUE); + + fido_assert_set_extensions(assert, ext); + fido_assert_set_sig(assert, 0, sig_ptr, sig_len); + + /* repeat memory operations to trigger reallocation paths */ + if (fido_assert_set_authdata(assert, 0, authdata_ptr, + authdata_len) != FIDO_OK) { + fido_assert_set_authdata_raw(assert, 0, authdata_ptr, + authdata_len); + } + fido_assert_set_sig(assert, 0, sig_ptr, sig_len); + + r = fido_assert_verify(assert, 0, type, pk); + consume(&r, sizeof(r)); + + fido_assert_free(&assert); +} + +/* + * Do a dummy conversion to exercise es256_pk_from_EVP_PKEY(). + */ +static void +es256_convert(const es256_pk_t *k) +{ + EVP_PKEY *pkey = NULL; + es256_pk_t *pk = NULL; + int r; + + if ((pkey = es256_pk_to_EVP_PKEY(k)) == NULL || + (pk = es256_pk_new()) == NULL) + goto out; + + r = es256_pk_from_EVP_PKEY(pk, pkey); + consume(&r, sizeof(r)); +out: + es256_pk_free(&pk); + EVP_PKEY_free(pkey); +} + +/* + * Do a dummy conversion to exercise es384_pk_from_EVP_PKEY(). + */ +static void +es384_convert(const es384_pk_t *k) +{ + EVP_PKEY *pkey = NULL; + es384_pk_t *pk = NULL; + int r; + + if ((pkey = es384_pk_to_EVP_PKEY(k)) == NULL || + (pk = es384_pk_new()) == NULL) + goto out; + + r = es384_pk_from_EVP_PKEY(pk, pkey); + consume(&r, sizeof(r)); +out: + es384_pk_free(&pk); + EVP_PKEY_free(pkey); +} + +/* + * Do a dummy conversion to exercise rs256_pk_from_EVP_PKEY(). + */ +static void +rs256_convert(const rs256_pk_t *k) +{ + EVP_PKEY *pkey = NULL; + rs256_pk_t *pk = NULL; + int r; + + if ((pkey = rs256_pk_to_EVP_PKEY(k)) == NULL || + (pk = rs256_pk_new()) == NULL) + goto out; + + r = rs256_pk_from_EVP_PKEY(pk, pkey); + consume(&r, sizeof(r)); +out: + rs256_pk_free(&pk); + EVP_PKEY_free(pkey); +} + +/* + * Do a dummy conversion to exercise eddsa_pk_from_EVP_PKEY(). + */ +static void +eddsa_convert(const eddsa_pk_t *k) +{ + EVP_PKEY *pkey = NULL; + eddsa_pk_t *pk = NULL; + int r; + + if ((pkey = eddsa_pk_to_EVP_PKEY(k)) == NULL || + (pk = eddsa_pk_new()) == NULL) + goto out; + + r = eddsa_pk_from_EVP_PKEY(pk, pkey); + consume(&r, sizeof(r)); +out: + if (pk) + eddsa_pk_free(&pk); + if (pkey) + EVP_PKEY_free(pkey); +} + +void +test(const struct param *p) +{ + fido_assert_t *assert = NULL; + es256_pk_t *es256_pk = NULL; + es384_pk_t *es384_pk = NULL; + rs256_pk_t *rs256_pk = NULL; + eddsa_pk_t *eddsa_pk = NULL; + uint8_t flags; + uint32_t sigcount; + int cose_alg = 0; + void *pk; + + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + switch (p->type & 3) { + case 0: + cose_alg = COSE_ES256; + + if ((es256_pk = es256_pk_new()) == NULL) + return; + + es256_pk_from_ptr(es256_pk, p->es256.body, p->es256.len); + pk = es256_pk; + + es256_convert(pk); + + break; + case 1: + cose_alg = COSE_RS256; + + if ((rs256_pk = rs256_pk_new()) == NULL) + return; + + rs256_pk_from_ptr(rs256_pk, p->rs256.body, p->rs256.len); + pk = rs256_pk; + + rs256_convert(pk); + + break; + case 2: + cose_alg = COSE_ES384; + + if ((es384_pk = es384_pk_new()) == NULL) + return; + + /* XXX reuse p->es256 as es384 */ + es384_pk_from_ptr(es384_pk, p->es256.body, p->es256.len); + pk = es384_pk; + + es384_convert(pk); + + break; + default: + cose_alg = COSE_EDDSA; + + if ((eddsa_pk = eddsa_pk_new()) == NULL) + return; + + eddsa_pk_from_ptr(eddsa_pk, p->eddsa.body, p->eddsa.len); + pk = eddsa_pk; + + eddsa_convert(pk); + + break; + } + + if ((assert = fido_assert_new()) == NULL) + goto out; + + set_wire_data(p->wire_data.body, p->wire_data.len); + + get_assert(assert, p->opt, &p->cdh, p->rp_id, p->ext, p->up, p->uv, + p->pin, p->cred_count, &p->cred); + + /* XXX +1 on purpose */ + for (size_t i = 0; i <= fido_assert_count(assert); i++) { + verify_assert(cose_alg, + fido_assert_clientdata_hash_ptr(assert), + fido_assert_clientdata_hash_len(assert), + fido_assert_rp_id(assert), + fido_assert_authdata_ptr(assert, i), + fido_assert_authdata_len(assert, i), + fido_assert_sig_ptr(assert, i), + fido_assert_sig_len(assert, i), p->up, p->uv, p->ext, pk); + consume(fido_assert_id_ptr(assert, i), + fido_assert_id_len(assert, i)); + consume(fido_assert_user_id_ptr(assert, i), + fido_assert_user_id_len(assert, i)); + consume(fido_assert_hmac_secret_ptr(assert, i), + fido_assert_hmac_secret_len(assert, i)); + consume_str(fido_assert_user_icon(assert, i)); + consume_str(fido_assert_user_name(assert, i)); + consume_str(fido_assert_user_display_name(assert, i)); + consume(fido_assert_blob_ptr(assert, i), + fido_assert_blob_len(assert, i)); + consume(fido_assert_largeblob_key_ptr(assert, i), + fido_assert_largeblob_key_len(assert, i)); + flags = fido_assert_flags(assert, i); + consume(&flags, sizeof(flags)); + sigcount = fido_assert_sigcount(assert, i); + consume(&sigcount, sizeof(sigcount)); + } + +out: + es256_pk_free(&es256_pk); + es384_pk_free(&es384_pk); + rs256_pk_free(&rs256_pk); + eddsa_pk_free(&eddsa_pk); + + fido_assert_free(&assert); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_byte(&p->uv); + mutate_byte(&p->up); + mutate_byte(&p->opt); + mutate_byte(&p->type); + mutate_byte(&p->cred_count); + mutate_int(&p->ext); + mutate_blob(&p->rs256); + mutate_blob(&p->es256); + mutate_blob(&p->eddsa); + mutate_blob(&p->cred); + mutate_blob(&p->cdh); + mutate_string(p->rp_id); + mutate_string(p->pin); + } + + if (flags & MUTATE_WIREDATA) { + if (p->opt & 1) { + p->wire_data.len = sizeof(dummy_wire_data_u2f); + memcpy(&p->wire_data.body, &dummy_wire_data_u2f, + p->wire_data.len); + } else { + p->wire_data.len = sizeof(dummy_wire_data_fido); + memcpy(&p->wire_data.body, &dummy_wire_data_fido, + p->wire_data.len); + } + mutate_blob(&p->wire_data); + } +} diff --git a/fuzz/fuzz_bio.c b/fuzz/fuzz_bio.c new file mode 100644 index 0000000..6ebfd15 --- /dev/null +++ b/fuzz/fuzz_bio.c @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2019 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +/* Parameter set defining a FIDO2 credential management operation. */ +struct param { + char pin[MAXSTR]; + char name[MAXSTR]; + int seed; + struct blob id; + struct blob info_wire_data; + struct blob enroll_wire_data; + struct blob list_wire_data; + struct blob set_name_wire_data; + struct blob remove_wire_data; +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'getFingerprintSensorInfo' bio enrollment command. + */ +static const uint8_t dummy_info_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_BIO_INFO, +}; + +/* + * Collection of HID reports from an authenticator issued with FIDO2 + * 'enrollBegin' + 'enrollCaptureNextSample' bio enrollment commands. + */ +static const uint8_t dummy_enroll_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_BIO_ENROLL, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'enumerateEnrollments' bio enrollment command. + */ +static const uint8_t dummy_list_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_BIO_ENUM, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'setFriendlyName' bio enrollment command. + */ +static const uint8_t dummy_set_name_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_STATUS, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'removeEnrollment' bio enrollment command. + */ +static const uint8_t dummy_remove_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_STATUS, +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 9 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->pin) < 0 || + unpack_string(v[2], p->name) < 0 || + unpack_blob(v[3], &p->id) < 0 || + unpack_blob(v[4], &p->info_wire_data) < 0 || + unpack_blob(v[5], &p->enroll_wire_data) < 0 || + unpack_blob(v[6], &p->list_wire_data) < 0 || + unpack_blob(v[7], &p->set_name_wire_data) < 0 || + unpack_blob(v[8], &p->remove_wire_data) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[9], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(9)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->pin)) == NULL || + (argv[2] = pack_string(p->name)) == NULL || + (argv[3] = pack_blob(&p->id)) == NULL || + (argv[4] = pack_blob(&p->info_wire_data)) == NULL || + (argv[5] = pack_blob(&p->enroll_wire_data)) == NULL || + (argv[6] = pack_blob(&p->list_wire_data)) == NULL || + (argv[7] = pack_blob(&p->set_name_wire_data)) == NULL || + (argv[8] = pack_blob(&p->remove_wire_data)) == NULL) + goto fail; + + for (size_t i = 0; i < 9; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 9; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); + strlcpy(dummy.name, dummy_name, sizeof(dummy.name)); + + dummy.info_wire_data.len = sizeof(dummy_info_wire_data); + dummy.enroll_wire_data.len = sizeof(dummy_enroll_wire_data); + dummy.list_wire_data.len = sizeof(dummy_list_wire_data); + dummy.set_name_wire_data.len = sizeof(dummy_set_name_wire_data); + dummy.remove_wire_data.len = sizeof(dummy_remove_wire_data); + dummy.id.len = sizeof(dummy_id); + + memcpy(&dummy.info_wire_data.body, &dummy_info_wire_data, + dummy.info_wire_data.len); + memcpy(&dummy.enroll_wire_data.body, &dummy_enroll_wire_data, + dummy.enroll_wire_data.len); + memcpy(&dummy.list_wire_data.body, &dummy_list_wire_data, + dummy.list_wire_data.len); + memcpy(&dummy.set_name_wire_data.body, &dummy_set_name_wire_data, + dummy.set_name_wire_data.len); + memcpy(&dummy.remove_wire_data.body, &dummy_remove_wire_data, + dummy.remove_wire_data.len); + memcpy(&dummy.id.body, &dummy_id, dummy.id.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static fido_dev_t * +prepare_dev(void) +{ + fido_dev_t *dev; + bool x; + + if ((dev = open_dev(0)) == NULL) + return NULL; + + x = fido_dev_is_fido2(dev); + consume(&x, sizeof(x)); + x = fido_dev_supports_pin(dev); + consume(&x, sizeof(x)); + x = fido_dev_has_pin(dev); + consume(&x, sizeof(x)); + x = fido_dev_supports_uv(dev); + consume(&x, sizeof(x)); + x = fido_dev_has_uv(dev); + consume(&x, sizeof(x)); + + return dev; +} + +static void +get_info(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_info_t *i = NULL; + uint8_t type; + uint8_t max_samples; + int r; + + set_wire_data(p->info_wire_data.body, p->info_wire_data.len); + + if ((dev = prepare_dev()) == NULL || (i = fido_bio_info_new()) == NULL) + goto done; + + r = fido_bio_dev_get_info(dev, i); + consume_str(fido_strerr(r)); + + type = fido_bio_info_type(i); + max_samples = fido_bio_info_max_samples(i); + consume(&type, sizeof(type)); + consume(&max_samples, sizeof(max_samples)); + +done: + if (dev) + fido_dev_close(dev); + + fido_dev_free(&dev); + fido_bio_info_free(&i); +} + +static void +consume_template(const fido_bio_template_t *t) +{ + consume_str(fido_bio_template_name(t)); + consume(fido_bio_template_id_ptr(t), fido_bio_template_id_len(t)); +} + +static void +consume_enroll(fido_bio_enroll_t *e) +{ + uint8_t last_status; + uint8_t remaining_samples; + + last_status = fido_bio_enroll_last_status(e); + remaining_samples = fido_bio_enroll_remaining_samples(e); + consume(&last_status, sizeof(last_status)); + consume(&remaining_samples, sizeof(remaining_samples)); +} + +static void +enroll(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_template_t *t = NULL; + fido_bio_enroll_t *e = NULL; + size_t cnt = 0; + + set_wire_data(p->enroll_wire_data.body, p->enroll_wire_data.len); + + if ((dev = prepare_dev()) == NULL || + (t = fido_bio_template_new()) == NULL || + (e = fido_bio_enroll_new()) == NULL) + goto done; + + fido_bio_dev_enroll_begin(dev, t, e, (uint32_t)p->seed, p->pin); + + consume_template(t); + consume_enroll(e); + + while (fido_bio_enroll_remaining_samples(e) > 0 && cnt++ < 5) { + fido_bio_dev_enroll_continue(dev, t, e, p->seed); + consume_template(t); + consume_enroll(e); + } + +done: + if (dev) + fido_dev_close(dev); + + fido_dev_free(&dev); + fido_bio_template_free(&t); + fido_bio_enroll_free(&e); +} + +static void +list(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_template_array_t *ta = NULL; + const fido_bio_template_t *t = NULL; + + set_wire_data(p->list_wire_data.body, p->list_wire_data.len); + + if ((dev = prepare_dev()) == NULL || + (ta = fido_bio_template_array_new()) == NULL) + goto done; + + fido_bio_dev_get_template_array(dev, ta, p->pin); + + /* +1 on purpose */ + for (size_t i = 0; i < fido_bio_template_array_count(ta) + 1; i++) + if ((t = fido_bio_template(ta, i)) != NULL) + consume_template(t); + +done: + if (dev) + fido_dev_close(dev); + + fido_dev_free(&dev); + fido_bio_template_array_free(&ta); +} + +static void +set_name(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_template_t *t = NULL; + + set_wire_data(p->set_name_wire_data.body, p->set_name_wire_data.len); + + if ((dev = prepare_dev()) == NULL || + (t = fido_bio_template_new()) == NULL) + goto done; + + fido_bio_template_set_name(t, p->name); + fido_bio_template_set_id(t, p->id.body, p->id.len); + consume_template(t); + + fido_bio_dev_set_template_name(dev, t, p->pin); + +done: + if (dev) + fido_dev_close(dev); + + fido_dev_free(&dev); + fido_bio_template_free(&t); +} + +static void +del(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_template_t *t = NULL; + int r; + + set_wire_data(p->remove_wire_data.body, p->remove_wire_data.len); + + if ((dev = prepare_dev()) == NULL || + (t = fido_bio_template_new()) == NULL) + goto done; + + r = fido_bio_template_set_id(t, p->id.body, p->id.len); + consume_template(t); + consume_str(fido_strerr(r)); + + fido_bio_dev_enroll_remove(dev, t, p->pin); + +done: + if (dev) + fido_dev_close(dev); + + fido_dev_free(&dev); + fido_bio_template_free(&t); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + get_info(p); + enroll(p); + list(p); + set_name(p); + del(p); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_blob(&p->id); + mutate_string(p->pin); + mutate_string(p->name); + } + + if (flags & MUTATE_WIREDATA) { + mutate_blob(&p->info_wire_data); + mutate_blob(&p->enroll_wire_data); + mutate_blob(&p->list_wire_data); + mutate_blob(&p->set_name_wire_data); + mutate_blob(&p->remove_wire_data); + } +} diff --git a/fuzz/fuzz_cred.c b/fuzz/fuzz_cred.c new file mode 100644 index 0000000..a0866dc --- /dev/null +++ b/fuzz/fuzz_cred.c @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "wiredata_u2f.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +/* Parameter set defining a FIDO2 make credential operation. */ +struct param { + char pin[MAXSTR]; + char rp_id[MAXSTR]; + char rp_name[MAXSTR]; + char user_icon[MAXSTR]; + char user_name[MAXSTR]; + char user_nick[MAXSTR]; + int ext; + int seed; + struct blob cdh; + struct blob excl_cred; + struct blob user_id; + struct blob wire_data; + uint8_t excl_count; + uint8_t rk; + uint8_t type; + uint8_t opt; + uint8_t uv; +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * make credential using the example parameters above. + */ +static const uint8_t dummy_wire_data_fido[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_CBOR_CRED, +}; + +/* + * Collection of HID reports from an authenticator issued with a U2F + * registration using the example parameters above. + */ +static const uint8_t dummy_wire_data_u2f[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_REGISTER, +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 17 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_byte(v[0], &p->rk) < 0 || + unpack_byte(v[1], &p->type) < 0 || + unpack_byte(v[2], &p->opt) < 0 || + unpack_byte(v[3], &p->uv) < 0 || + unpack_byte(v[4], &p->excl_count) < 0 || + unpack_int(v[5], &p->ext) < 0 || + unpack_int(v[6], &p->seed) < 0 || + unpack_string(v[7], p->pin) < 0 || + unpack_string(v[8], p->rp_id) < 0 || + unpack_string(v[9], p->rp_name) < 0 || + unpack_string(v[10], p->user_icon) < 0 || + unpack_string(v[11], p->user_name) < 0 || + unpack_string(v[12], p->user_nick) < 0 || + unpack_blob(v[13], &p->cdh) < 0 || + unpack_blob(v[14], &p->user_id) < 0 || + unpack_blob(v[15], &p->wire_data) < 0 || + unpack_blob(v[16], &p->excl_cred) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[17], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(17)) == NULL || + (argv[0] = pack_byte(p->rk)) == NULL || + (argv[1] = pack_byte(p->type)) == NULL || + (argv[2] = pack_byte(p->opt)) == NULL || + (argv[3] = pack_byte(p->uv)) == NULL || + (argv[4] = pack_byte(p->excl_count)) == NULL || + (argv[5] = pack_int(p->ext)) == NULL || + (argv[6] = pack_int(p->seed)) == NULL || + (argv[7] = pack_string(p->pin)) == NULL || + (argv[8] = pack_string(p->rp_id)) == NULL || + (argv[9] = pack_string(p->rp_name)) == NULL || + (argv[10] = pack_string(p->user_icon)) == NULL || + (argv[11] = pack_string(p->user_name)) == NULL || + (argv[12] = pack_string(p->user_nick)) == NULL || + (argv[13] = pack_blob(&p->cdh)) == NULL || + (argv[14] = pack_blob(&p->user_id)) == NULL || + (argv[15] = pack_blob(&p->wire_data)) == NULL || + (argv[16] = pack_blob(&p->excl_cred)) == NULL) + goto fail; + + for (size_t i = 0; i < 17; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 17; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + dummy.type = 1; + dummy.ext = FIDO_EXT_HMAC_SECRET; + + strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); + strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id)); + strlcpy(dummy.rp_name, dummy_rp_name, sizeof(dummy.rp_name)); + strlcpy(dummy.user_icon, dummy_user_icon, sizeof(dummy.user_icon)); + strlcpy(dummy.user_name, dummy_user_name, sizeof(dummy.user_name)); + strlcpy(dummy.user_nick, dummy_user_nick, sizeof(dummy.user_nick)); + + dummy.cdh.len = sizeof(dummy_cdh); + dummy.user_id.len = sizeof(dummy_user_id); + dummy.wire_data.len = sizeof(dummy_wire_data_fido); + + memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len); + memcpy(&dummy.user_id.body, &dummy_user_id, dummy.user_id.len); + memcpy(&dummy.wire_data.body, &dummy_wire_data_fido, + dummy.wire_data.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static void +make_cred(fido_cred_t *cred, uint8_t opt, int type, const struct blob *cdh, + const char *rp_id, const char *rp_name, const struct blob *user_id, + const char *user_name, const char *user_nick, const char *user_icon, + int ext, uint8_t rk, uint8_t uv, const char *pin, uint8_t excl_count, + const struct blob *excl_cred) +{ + fido_dev_t *dev; + + if ((dev = open_dev(opt & 2)) == NULL) + return; + if (opt & 1) + fido_dev_force_u2f(dev); + + for (uint8_t i = 0; i < excl_count; i++) + fido_cred_exclude(cred, excl_cred->body, excl_cred->len); + + fido_cred_set_type(cred, type); + fido_cred_set_clientdata_hash(cred, cdh->body, cdh->len); + fido_cred_set_rp(cred, rp_id, rp_name); + fido_cred_set_user(cred, user_id->body, user_id->len, user_name, + user_nick, user_icon); + + if (ext & FIDO_EXT_HMAC_SECRET) + fido_cred_set_extensions(cred, FIDO_EXT_HMAC_SECRET); + if (ext & FIDO_EXT_CRED_BLOB) + fido_cred_set_blob(cred, user_id->body, user_id->len); + if (ext & FIDO_EXT_LARGEBLOB_KEY) + fido_cred_set_extensions(cred, FIDO_EXT_LARGEBLOB_KEY); + if (ext & FIDO_EXT_MINPINLEN) + fido_cred_set_pin_minlen(cred, strlen(pin)); + + if (rk & 1) + fido_cred_set_rk(cred, FIDO_OPT_TRUE); + if (uv & 1) + fido_cred_set_uv(cred, FIDO_OPT_TRUE); + if (user_id->len) + fido_cred_set_prot(cred, user_id->body[0] & 0x03); + + /* repeat memory operations to trigger reallocation paths */ + fido_cred_set_type(cred, type); + fido_cred_set_clientdata_hash(cred, cdh->body, cdh->len); + fido_cred_set_rp(cred, rp_id, rp_name); + fido_cred_set_user(cred, user_id->body, user_id->len, user_name, + user_nick, user_icon); + + if (strlen(pin) == 0) + pin = NULL; + + fido_dev_make_cred(dev, cred, (opt & 1) ? NULL : pin); + + fido_dev_cancel(dev); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len, + const char *rp_id, const char *rp_name, const unsigned char *authdata_ptr, + size_t authdata_len, const unsigned char *authdata_raw_ptr, + size_t authdata_raw_len, int ext, uint8_t rk, uint8_t uv, + const unsigned char *x5c_ptr, size_t x5c_len, const unsigned char *sig_ptr, + size_t sig_len, const unsigned char *attstmt_ptr, size_t attstmt_len, + const char *fmt, int prot, size_t minpinlen) +{ + fido_cred_t *cred; + uint8_t flags; + uint32_t sigcount; + int r; + + if ((cred = fido_cred_new()) == NULL) + return; + + fido_cred_set_type(cred, type); + fido_cred_set_clientdata_hash(cred, cdh_ptr, cdh_len); + fido_cred_set_rp(cred, rp_id, rp_name); + consume(authdata_ptr, authdata_len); + consume(authdata_raw_ptr, authdata_raw_len); + consume(x5c_ptr, x5c_len); + consume(sig_ptr, sig_len); + consume(attstmt_ptr, attstmt_len); + if (fido_cred_set_authdata(cred, authdata_ptr, authdata_len) != FIDO_OK) + fido_cred_set_authdata_raw(cred, authdata_raw_ptr, + authdata_raw_len); + fido_cred_set_extensions(cred, ext); + if (fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len) != FIDO_OK) { + fido_cred_set_x509(cred, x5c_ptr, x5c_len); + fido_cred_set_sig(cred, sig_ptr, sig_len); + } + fido_cred_set_prot(cred, prot); + fido_cred_set_pin_minlen(cred, minpinlen); + + if (rk & 1) + fido_cred_set_rk(cred, FIDO_OPT_TRUE); + if (uv & 1) + fido_cred_set_uv(cred, FIDO_OPT_TRUE); + if (fmt) + fido_cred_set_fmt(cred, fmt); + + /* repeat memory operations to trigger reallocation paths */ + if (fido_cred_set_authdata(cred, authdata_ptr, authdata_len) != FIDO_OK) + fido_cred_set_authdata_raw(cred, authdata_raw_ptr, + authdata_raw_len); + if (fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len) != FIDO_OK) { + fido_cred_set_x509(cred, x5c_ptr, x5c_len); + fido_cred_set_sig(cred, sig_ptr, sig_len); + } + fido_cred_set_x509(cred, x5c_ptr, x5c_len); + fido_cred_set_sig(cred, sig_ptr, sig_len); + + r = fido_cred_verify(cred); + consume(&r, sizeof(r)); + r = fido_cred_verify_self(cred); + consume(&r, sizeof(r)); + + consume(fido_cred_pubkey_ptr(cred), fido_cred_pubkey_len(cred)); + consume(fido_cred_id_ptr(cred), fido_cred_id_len(cred)); + consume(fido_cred_aaguid_ptr(cred), fido_cred_aaguid_len(cred)); + consume(fido_cred_user_id_ptr(cred), fido_cred_user_id_len(cred)); + consume_str(fido_cred_user_name(cred)); + consume_str(fido_cred_display_name(cred)); + consume(fido_cred_largeblob_key_ptr(cred), + fido_cred_largeblob_key_len(cred)); + + flags = fido_cred_flags(cred); + consume(&flags, sizeof(flags)); + sigcount = fido_cred_sigcount(cred); + consume(&sigcount, sizeof(sigcount)); + type = fido_cred_type(cred); + consume(&type, sizeof(type)); + minpinlen = fido_cred_pin_minlen(cred); + consume(&minpinlen, sizeof(minpinlen)); + + fido_cred_free(&cred); +} + +static void +test_cred(const struct param *p) +{ + fido_cred_t *cred = NULL; + int cose_alg = 0; + + if ((cred = fido_cred_new()) == NULL) + return; + + switch (p->type & 3) { + case 0: + cose_alg = COSE_ES256; + break; + case 1: + cose_alg = COSE_RS256; + break; + case 2: + cose_alg = COSE_ES384; + break; + default: + cose_alg = COSE_EDDSA; + break; + } + + set_wire_data(p->wire_data.body, p->wire_data.len); + + make_cred(cred, p->opt, cose_alg, &p->cdh, p->rp_id, p->rp_name, + &p->user_id, p->user_name, p->user_nick, p->user_icon, p->ext, + p->rk, p->uv, p->pin, p->excl_count, &p->excl_cred); + + verify_cred(cose_alg, + fido_cred_clientdata_hash_ptr(cred), + fido_cred_clientdata_hash_len(cred), fido_cred_rp_id(cred), + fido_cred_rp_name(cred), fido_cred_authdata_ptr(cred), + fido_cred_authdata_len(cred), fido_cred_authdata_raw_ptr(cred), + fido_cred_authdata_raw_len(cred), p->ext, p->rk, p->uv, + fido_cred_x5c_ptr(cred), fido_cred_x5c_len(cred), + fido_cred_sig_ptr(cred), fido_cred_sig_len(cred), + fido_cred_attstmt_ptr(cred), fido_cred_attstmt_len(cred), + fido_cred_fmt(cred), fido_cred_prot(cred), + fido_cred_pin_minlen(cred)); + + fido_cred_free(&cred); +} + +static void +test_touch(const struct param *p) +{ + fido_dev_t *dev; + int r; + int touched; + + set_wire_data(p->wire_data.body, p->wire_data.len); + + if ((dev = open_dev(p->opt & 2)) == NULL) + return; + if (p->opt & 1) + fido_dev_force_u2f(dev); + + r = fido_dev_get_touch_begin(dev); + consume_str(fido_strerr(r)); + r = fido_dev_get_touch_status(dev, &touched, -1); + consume_str(fido_strerr(r)); + consume(&touched, sizeof(touched)); + + fido_dev_cancel(dev); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +test_misc(const struct param *p) +{ + fido_cred_t *cred = NULL; + + if ((cred = fido_cred_new()) == NULL) + return; + + /* reuse user id as credential id */ + fido_cred_set_id(cred, p->user_id.body, p->user_id.len); + consume(fido_cred_id_ptr(cred), fido_cred_id_len(cred)); + fido_cred_free(&cred); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + test_cred(p); + test_touch(p); + test_misc(p); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_byte(&p->rk); + mutate_byte(&p->type); + mutate_byte(&p->opt); + mutate_byte(&p->uv); + mutate_byte(&p->excl_count); + mutate_int(&p->ext); + mutate_blob(&p->cdh); + mutate_blob(&p->user_id); + mutate_blob(&p->excl_cred); + mutate_string(p->pin); + mutate_string(p->user_icon); + mutate_string(p->user_name); + mutate_string(p->user_nick); + mutate_string(p->rp_id); + mutate_string(p->rp_name); + } + + if (flags & MUTATE_WIREDATA) { + if (p->opt & 1) { + p->wire_data.len = sizeof(dummy_wire_data_u2f); + memcpy(&p->wire_data.body, &dummy_wire_data_u2f, + p->wire_data.len); + } else { + p->wire_data.len = sizeof(dummy_wire_data_fido); + memcpy(&p->wire_data.body, &dummy_wire_data_fido, + p->wire_data.len); + } + mutate_blob(&p->wire_data); + } +} diff --git a/fuzz/fuzz_credman.c b/fuzz/fuzz_credman.c new file mode 100644 index 0000000..1cb95dc --- /dev/null +++ b/fuzz/fuzz_credman.c @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2019-2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +/* Parameter set defining a FIDO2 credential management operation. */ +struct param { + char pin[MAXSTR]; + char rp_id[MAXSTR]; + int seed; + struct blob cred_id; + struct blob del_wire_data; + struct blob meta_wire_data; + struct blob rk_wire_data; + struct blob rp_wire_data; +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'getCredsMetadata' credential management command. + */ +static const uint8_t dummy_meta_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_CREDMAN_META, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'enumerateRPsBegin' credential management command. + */ +static const uint8_t dummy_rp_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_CREDMAN_RPLIST, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'enumerateCredentialsBegin' credential management command. + */ +static const uint8_t dummy_rk_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_CREDMAN_RKLIST, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'deleteCredential' credential management command. + */ +static const uint8_t dummy_del_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_STATUS, +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 8 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->pin) < 0 || + unpack_string(v[2], p->rp_id) < 0 || + unpack_blob(v[3], &p->cred_id) < 0 || + unpack_blob(v[4], &p->meta_wire_data) < 0 || + unpack_blob(v[5], &p->rp_wire_data) < 0 || + unpack_blob(v[6], &p->rk_wire_data) < 0 || + unpack_blob(v[7], &p->del_wire_data) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[8], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(8)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->pin)) == NULL || + (argv[2] = pack_string(p->rp_id)) == NULL || + (argv[3] = pack_blob(&p->cred_id)) == NULL || + (argv[4] = pack_blob(&p->meta_wire_data)) == NULL || + (argv[5] = pack_blob(&p->rp_wire_data)) == NULL || + (argv[6] = pack_blob(&p->rk_wire_data)) == NULL || + (argv[7] = pack_blob(&p->del_wire_data)) == NULL) + goto fail; + + for (size_t i = 0; i < 8; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 8; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); + strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id)); + + dummy.meta_wire_data.len = sizeof(dummy_meta_wire_data); + dummy.rp_wire_data.len = sizeof(dummy_rp_wire_data); + dummy.rk_wire_data.len = sizeof(dummy_rk_wire_data); + dummy.del_wire_data.len = sizeof(dummy_del_wire_data); + dummy.cred_id.len = sizeof(dummy_cred_id); + + memcpy(&dummy.meta_wire_data.body, &dummy_meta_wire_data, + dummy.meta_wire_data.len); + memcpy(&dummy.rp_wire_data.body, &dummy_rp_wire_data, + dummy.rp_wire_data.len); + memcpy(&dummy.rk_wire_data.body, &dummy_rk_wire_data, + dummy.rk_wire_data.len); + memcpy(&dummy.del_wire_data.body, &dummy_del_wire_data, + dummy.del_wire_data.len); + memcpy(&dummy.cred_id.body, &dummy_cred_id, dummy.cred_id.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static fido_dev_t * +prepare_dev(void) +{ + fido_dev_t *dev; + bool x; + + if ((dev = open_dev(0)) == NULL) + return NULL; + + x = fido_dev_is_fido2(dev); + consume(&x, sizeof(x)); + x = fido_dev_supports_cred_prot(dev); + consume(&x, sizeof(x)); + x = fido_dev_supports_credman(dev); + consume(&x, sizeof(x)); + + return dev; +} + +static void +get_metadata(const struct param *p) +{ + fido_dev_t *dev; + fido_credman_metadata_t *metadata; + uint64_t existing; + uint64_t remaining; + + set_wire_data(p->meta_wire_data.body, p->meta_wire_data.len); + + if ((dev = prepare_dev()) == NULL) + return; + + if ((metadata = fido_credman_metadata_new()) == NULL) { + fido_dev_close(dev); + fido_dev_free(&dev); + return; + } + + fido_credman_get_dev_metadata(dev, metadata, p->pin); + + existing = fido_credman_rk_existing(metadata); + remaining = fido_credman_rk_remaining(metadata); + consume(&existing, sizeof(existing)); + consume(&remaining, sizeof(remaining)); + + fido_credman_metadata_free(&metadata); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +get_rp_list(const struct param *p) +{ + fido_dev_t *dev; + fido_credman_rp_t *rp; + + set_wire_data(p->rp_wire_data.body, p->rp_wire_data.len); + + if ((dev = prepare_dev()) == NULL) + return; + + if ((rp = fido_credman_rp_new()) == NULL) { + fido_dev_close(dev); + fido_dev_free(&dev); + return; + } + + fido_credman_get_dev_rp(dev, rp, p->pin); + + /* +1 on purpose */ + for (size_t i = 0; i < fido_credman_rp_count(rp) + 1; i++) { + consume(fido_credman_rp_id_hash_ptr(rp, i), + fido_credman_rp_id_hash_len(rp, i)); + consume_str(fido_credman_rp_id(rp, i)); + consume_str(fido_credman_rp_name(rp, i)); + } + + fido_credman_rp_free(&rp); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +get_rk_list(const struct param *p) +{ + fido_dev_t *dev; + fido_credman_rk_t *rk; + const fido_cred_t *cred; + int val; + + set_wire_data(p->rk_wire_data.body, p->rk_wire_data.len); + + if ((dev = prepare_dev()) == NULL) + return; + + if ((rk = fido_credman_rk_new()) == NULL) { + fido_dev_close(dev); + fido_dev_free(&dev); + return; + } + + fido_credman_get_dev_rk(dev, p->rp_id, rk, p->pin); + + /* +1 on purpose */ + for (size_t i = 0; i < fido_credman_rk_count(rk) + 1; i++) { + if ((cred = fido_credman_rk(rk, i)) == NULL) { + assert(i >= fido_credman_rk_count(rk)); + continue; + } + val = fido_cred_type(cred); + consume(&val, sizeof(val)); + consume(fido_cred_id_ptr(cred), fido_cred_id_len(cred)); + consume(fido_cred_pubkey_ptr(cred), fido_cred_pubkey_len(cred)); + consume(fido_cred_user_id_ptr(cred), + fido_cred_user_id_len(cred)); + consume_str(fido_cred_user_name(cred)); + consume_str(fido_cred_display_name(cred)); + val = fido_cred_prot(cred); + consume(&val, sizeof(val)); + } + + fido_credman_rk_free(&rk); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +del_rk(const struct param *p) +{ + fido_dev_t *dev; + + set_wire_data(p->del_wire_data.body, p->del_wire_data.len); + + if ((dev = prepare_dev()) == NULL) + return; + + fido_credman_del_dev_rk(dev, p->cred_id.body, p->cred_id.len, p->pin); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +set_rk(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_cred_t *cred = NULL; + const char *pin = p->pin; + int r0, r1, r2; + + set_wire_data(p->del_wire_data.body, p->del_wire_data.len); + + if ((dev = prepare_dev()) == NULL) + return; + if ((cred = fido_cred_new()) == NULL) + goto out; + r0 = fido_cred_set_id(cred, p->cred_id.body, p->cred_id.len); + r1 = fido_cred_set_user(cred, p->cred_id.body, p->cred_id.len, p->rp_id, + NULL, NULL); + if (strlen(pin) == 0) + pin = NULL; + r2 = fido_credman_set_dev_rk(dev, cred, pin); + consume(&r0, sizeof(r0)); + consume(&r1, sizeof(r1)); + consume(&r2, sizeof(r2)); +out: + fido_dev_close(dev); + fido_dev_free(&dev); + fido_cred_free(&cred); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + get_metadata(p); + get_rp_list(p); + get_rk_list(p); + del_rk(p); + set_rk(p); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_blob(&p->cred_id); + mutate_string(p->pin); + mutate_string(p->rp_id); + } + + if (flags & MUTATE_WIREDATA) { + mutate_blob(&p->meta_wire_data); + mutate_blob(&p->rp_wire_data); + mutate_blob(&p->rk_wire_data); + mutate_blob(&p->del_wire_data); + } +} diff --git a/fuzz/fuzz_hid.c b/fuzz/fuzz_hid.c new file mode 100644 index 0000000..27ccb2f --- /dev/null +++ b/fuzz/fuzz_hid.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2020-2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include "../openbsd-compat/openbsd-compat.h" +#include "mutator_aux.h" +#include "dummy.h" + +extern int fido_hid_get_usage(const uint8_t *, size_t, uint32_t *); +extern int fido_hid_get_report_len(const uint8_t *, size_t, size_t *, size_t *); +extern void set_udev_parameters(const char *, const struct blob *); + +struct param { + int seed; + char uevent[MAXSTR]; + struct blob report_descriptor; + struct blob netlink_wiredata; +}; + +/* + * Sample HID report descriptor from the FIDO HID interface of a YubiKey 5. + */ +static const uint8_t dummy_report_descriptor[] = { + 0x06, 0xd0, 0xf1, 0x09, 0x01, 0xa1, 0x01, 0x09, + 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, + 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, + 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x40, 0x91, + 0x02, 0xc0 +}; + +/* + * Sample uevent file from a Yubico Security Key. + */ +static const char dummy_uevent[] = + "DRIVER=hid-generic\n" + "HID_ID=0003:00001050:00000120\n" + "HID_NAME=Yubico Security Key by Yubico\n" + "HID_PHYS=usb-0000:00:14.0-3/input0\n" + "HID_UNIQ=\n" + "MODALIAS=hid:b0003g0001v00001050p00000120\n"; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 4 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->uevent) < 0 || + unpack_blob(v[2], &p->report_descriptor) < 0 || + unpack_blob(v[3], &p->netlink_wiredata) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[4], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(4)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->uevent)) == NULL || + (argv[2] = pack_blob(&p->report_descriptor)) == NULL || + (argv[3] = pack_blob(&p->netlink_wiredata)) == NULL) + goto fail; + + for (size_t i = 0; i < 4; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 4; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + dummy.report_descriptor.len = sizeof(dummy_report_descriptor); + strlcpy(dummy.uevent, dummy_uevent, sizeof(dummy.uevent)); + memcpy(&dummy.report_descriptor.body, &dummy_report_descriptor, + dummy.report_descriptor.len); + dummy.netlink_wiredata.len = sizeof(dummy_netlink_wiredata); + memcpy(&dummy.netlink_wiredata.body, &dummy_netlink_wiredata, + dummy.netlink_wiredata.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + if (blob_len > len) + blob_len = len; + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static void +get_usage(const struct param *p) +{ + uint32_t usage_page = 0; + + fido_hid_get_usage(p->report_descriptor.body, p->report_descriptor.len, + &usage_page); + consume(&usage_page, sizeof(usage_page)); +} + +static void +get_report_len(const struct param *p) +{ + size_t report_in_len = 0; + size_t report_out_len = 0; + + fido_hid_get_report_len(p->report_descriptor.body, + p->report_descriptor.len, &report_in_len, &report_out_len); + consume(&report_in_len, sizeof(report_in_len)); + consume(&report_out_len, sizeof(report_out_len)); +} + +static void +manifest(const struct param *p) +{ + size_t ndevs, nfound; + fido_dev_info_t *devlist = NULL, *devlist_set = NULL; + int16_t vendor_id, product_id; + fido_dev_io_t io; + fido_dev_transport_t t; + + memset(&io, 0, sizeof(io)); + memset(&t, 0, sizeof(t)); + set_netlink_io_functions(fd_read, fd_write); + set_wire_data(p->netlink_wiredata.body, p->netlink_wiredata.len); + set_udev_parameters(p->uevent, &p->report_descriptor); + + ndevs = uniform_random(64); + if ((devlist = fido_dev_info_new(ndevs)) == NULL || + (devlist_set = fido_dev_info_new(1)) == NULL || + fido_dev_info_manifest(devlist, ndevs, &nfound) != FIDO_OK) + goto out; + for (size_t i = 0; i < nfound; i++) { + const fido_dev_info_t *di = fido_dev_info_ptr(devlist, i); + consume_str(fido_dev_info_path(di)); + consume_str(fido_dev_info_manufacturer_string(di)); + consume_str(fido_dev_info_product_string(di)); + vendor_id = fido_dev_info_vendor(di); + product_id = fido_dev_info_product(di); + consume(&vendor_id, sizeof(vendor_id)); + consume(&product_id, sizeof(product_id)); + fido_dev_info_set(devlist_set, 0, fido_dev_info_path(di), + fido_dev_info_manufacturer_string(di), + fido_dev_info_product_string(di), &io, &t); + } +out: + fido_dev_info_free(&devlist, ndevs); + fido_dev_info_free(&devlist_set, 1); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + get_usage(p); + get_report_len(p); + manifest(p); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_blob(&p->report_descriptor); + mutate_string(p->uevent); + } + + if (flags & MUTATE_WIREDATA) + mutate_blob(&p->netlink_wiredata); +} diff --git a/fuzz/fuzz_largeblob.c b/fuzz/fuzz_largeblob.c new file mode 100644 index 0000000..4326296 --- /dev/null +++ b/fuzz/fuzz_largeblob.c @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2020 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +/* Parameter set defining a FIDO2 "large blob" operation. */ +struct param { + char pin[MAXSTR]; + int seed; + struct blob key; + struct blob get_wiredata; + struct blob set_wiredata; +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'authenticatorLargeBlobs' 'get' command. + */ +static const uint8_t dummy_get_wiredata[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'authenticatorLargeBlobs' 'set' command. + */ +static const uint8_t dummy_set_wiredata[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_STATUS +}; + +/* + * XXX this needs to match the encrypted blob embedded in + * WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY. + */ +static const uint8_t dummy_key[] = { + 0xa9, 0x1b, 0xc4, 0xdd, 0xfc, 0x9a, 0x93, 0x79, + 0x75, 0xba, 0xf7, 0x7f, 0x4d, 0x57, 0xfc, 0xa6, + 0xe1, 0xf8, 0x06, 0x43, 0x23, 0x99, 0x51, 0x32, + 0xce, 0x6e, 0x19, 0x84, 0x50, 0x13, 0x2d, 0x7b +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 5 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->pin) < 0 || + unpack_blob(v[2], &p->key) < 0 || + unpack_blob(v[3], &p->get_wiredata) < 0 || + unpack_blob(v[4], &p->set_wiredata) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[5], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(5)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->pin)) == NULL || + (argv[2] = pack_blob(&p->key)) == NULL || + (argv[3] = pack_blob(&p->get_wiredata)) == NULL || + (argv[4] = pack_blob(&p->set_wiredata)) == NULL) + goto fail; + + for (size_t i = 0; i < 5; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 5; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); + + dummy.get_wiredata.len = sizeof(dummy_get_wiredata); + dummy.set_wiredata.len = sizeof(dummy_set_wiredata); + dummy.key.len = sizeof(dummy_key); + + memcpy(&dummy.get_wiredata.body, &dummy_get_wiredata, + dummy.get_wiredata.len); + memcpy(&dummy.set_wiredata.body, &dummy_set_wiredata, + dummy.set_wiredata.len); + memcpy(&dummy.key.body, &dummy_key, dummy.key.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static fido_dev_t * +prepare_dev(void) +{ + fido_dev_t *dev; + + if ((dev = open_dev(0)) == NULL) + return NULL; + + return dev; +} + +static void +get_blob(const struct param *p, int array) +{ + fido_dev_t *dev; + u_char *ptr = NULL; + size_t len = 0; + + set_wire_data(p->get_wiredata.body, p->get_wiredata.len); + + if ((dev = prepare_dev()) == NULL) + return; + + if (array) + fido_dev_largeblob_get_array(dev, &ptr, &len); + else + fido_dev_largeblob_get(dev, p->key.body, p->key.len, &ptr, &len); + consume(ptr, len); + free(ptr); + + fido_dev_close(dev); + fido_dev_free(&dev); +} + + +static void +set_blob(const struct param *p, int op) +{ + fido_dev_t *dev; + const char *pin; + + set_wire_data(p->set_wiredata.body, p->set_wiredata.len); + + if ((dev = prepare_dev()) == NULL) + return; + pin = p->pin; + if (strlen(pin) == 0) + pin = NULL; + + switch (op) { + case 0: + fido_dev_largeblob_remove(dev, p->key.body, p->key.len, pin); + break; + case 1: + /* XXX reuse p->get_wiredata as the blob to be set */ + fido_dev_largeblob_set(dev, p->key.body, p->key.len, + p->get_wiredata.body, p->get_wiredata.len, pin); + break; + case 2: + /* XXX reuse p->get_wiredata as the body of the cbor array */ + fido_dev_largeblob_set_array(dev, p->get_wiredata.body, + p->get_wiredata.len, pin); + } + + fido_dev_close(dev); + fido_dev_free(&dev); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + get_blob(p, 0); + get_blob(p, 1); + set_blob(p, 0); + set_blob(p, 1); + set_blob(p, 2); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_blob(&p->key); + mutate_string(p->pin); + } + + if (flags & MUTATE_WIREDATA) { + mutate_blob(&p->get_wiredata); + mutate_blob(&p->set_wiredata); + } +} diff --git a/fuzz/fuzz_mgmt.c b/fuzz/fuzz_mgmt.c new file mode 100644 index 0000000..6a5e7b6 --- /dev/null +++ b/fuzz/fuzz_mgmt.c @@ -0,0 +1,528 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +#define MAXRPID 64 + +struct param { + char pin1[MAXSTR]; + char pin2[MAXSTR]; + struct blob reset_wire_data; + struct blob info_wire_data; + struct blob set_pin_wire_data; + struct blob change_pin_wire_data; + struct blob retry_wire_data; + struct blob config_wire_data; + int seed; +}; + +static const uint8_t dummy_reset_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_CBOR_STATUS, +}; + +static const uint8_t dummy_info_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_INFO, +}; + +static const uint8_t dummy_set_pin_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_STATUS, +}; + +static const uint8_t dummy_change_pin_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_STATUS, +}; + +static const uint8_t dummy_retry_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_RETRIES, +}; + +static const uint8_t dummy_config_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_STATUS, +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 9 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->pin1) < 0 || + unpack_string(v[2], p->pin2) < 0 || + unpack_blob(v[3], &p->reset_wire_data) < 0 || + unpack_blob(v[4], &p->info_wire_data) < 0 || + unpack_blob(v[5], &p->set_pin_wire_data) < 0 || + unpack_blob(v[6], &p->change_pin_wire_data) < 0 || + unpack_blob(v[7], &p->retry_wire_data) < 0 || + unpack_blob(v[8], &p->config_wire_data) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[9], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(9)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->pin1)) == NULL || + (argv[2] = pack_string(p->pin2)) == NULL || + (argv[3] = pack_blob(&p->reset_wire_data)) == NULL || + (argv[4] = pack_blob(&p->info_wire_data)) == NULL || + (argv[5] = pack_blob(&p->set_pin_wire_data)) == NULL || + (argv[6] = pack_blob(&p->change_pin_wire_data)) == NULL || + (argv[7] = pack_blob(&p->retry_wire_data)) == NULL || + (argv[8] = pack_blob(&p->config_wire_data)) == NULL) + goto fail; + + for (size_t i = 0; i < 9; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 9; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + strlcpy(dummy.pin1, dummy_pin1, sizeof(dummy.pin1)); + strlcpy(dummy.pin2, dummy_pin2, sizeof(dummy.pin2)); + + dummy.reset_wire_data.len = sizeof(dummy_reset_wire_data); + dummy.info_wire_data.len = sizeof(dummy_info_wire_data); + dummy.set_pin_wire_data.len = sizeof(dummy_set_pin_wire_data); + dummy.change_pin_wire_data.len = sizeof(dummy_change_pin_wire_data); + dummy.retry_wire_data.len = sizeof(dummy_retry_wire_data); + dummy.config_wire_data.len = sizeof(dummy_config_wire_data); + + memcpy(&dummy.reset_wire_data.body, &dummy_reset_wire_data, + dummy.reset_wire_data.len); + memcpy(&dummy.info_wire_data.body, &dummy_info_wire_data, + dummy.info_wire_data.len); + memcpy(&dummy.set_pin_wire_data.body, &dummy_set_pin_wire_data, + dummy.set_pin_wire_data.len); + memcpy(&dummy.change_pin_wire_data.body, &dummy_change_pin_wire_data, + dummy.change_pin_wire_data.len); + memcpy(&dummy.retry_wire_data.body, &dummy_retry_wire_data, + dummy.retry_wire_data.len); + memcpy(&dummy.config_wire_data.body, &dummy_config_wire_data, + dummy.config_wire_data.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static void +dev_reset(const struct param *p) +{ + fido_dev_t *dev; + + set_wire_data(p->reset_wire_data.body, p->reset_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + fido_dev_reset(dev); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_get_cbor_info(const struct param *p) +{ + fido_dev_t *dev; + fido_cbor_info_t *ci; + uint64_t n; + uint8_t proto, major, minor, build, flags; + bool v; + + set_wire_data(p->info_wire_data.body, p->info_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + proto = fido_dev_protocol(dev); + major = fido_dev_major(dev); + minor = fido_dev_minor(dev); + build = fido_dev_build(dev); + flags = fido_dev_flags(dev); + + consume(&proto, sizeof(proto)); + consume(&major, sizeof(major)); + consume(&minor, sizeof(minor)); + consume(&build, sizeof(build)); + consume(&flags, sizeof(flags)); + + if ((ci = fido_cbor_info_new()) == NULL) + goto out; + + fido_dev_get_cbor_info(dev, ci); + + for (size_t i = 0; i < fido_cbor_info_versions_len(ci); i++) { + char * const *sa = fido_cbor_info_versions_ptr(ci); + consume(sa[i], strlen(sa[i])); + } + + for (size_t i = 0; i < fido_cbor_info_extensions_len(ci); i++) { + char * const *sa = fido_cbor_info_extensions_ptr(ci); + consume(sa[i], strlen(sa[i])); + } + + for (size_t i = 0; i < fido_cbor_info_transports_len(ci); i++) { + char * const *sa = fido_cbor_info_transports_ptr(ci); + consume(sa[i], strlen(sa[i])); + } + + for (size_t i = 0; i < fido_cbor_info_options_len(ci); i++) { + char * const *sa = fido_cbor_info_options_name_ptr(ci); + const bool *va = fido_cbor_info_options_value_ptr(ci); + consume(sa[i], strlen(sa[i])); + consume(&va[i], sizeof(va[i])); + } + + /* +1 on purpose */ + for (size_t i = 0; i <= fido_cbor_info_algorithm_count(ci); i++) { + const char *type = fido_cbor_info_algorithm_type(ci, i); + int cose = fido_cbor_info_algorithm_cose(ci, i); + consume_str(type); + consume(&cose, sizeof(cose)); + } + + for (size_t i = 0; i < fido_cbor_info_certs_len(ci); i++) { + char * const *na = fido_cbor_info_certs_name_ptr(ci); + const uint64_t *va = fido_cbor_info_certs_value_ptr(ci); + consume(na[i], strlen(na[i])); + consume(&va[i], sizeof(va[i])); + } + + n = fido_cbor_info_maxmsgsiz(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_maxcredbloblen(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_maxcredcntlst(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_maxcredidlen(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_maxlargeblob(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_fwversion(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_minpinlen(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_maxrpid_minpinlen(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_uv_attempts(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_uv_modality(ci); + consume(&n, sizeof(n)); + n = (uint64_t)fido_cbor_info_rk_remaining(ci); + consume(&n, sizeof(n)); + + consume(fido_cbor_info_aaguid_ptr(ci), fido_cbor_info_aaguid_len(ci)); + consume(fido_cbor_info_protocols_ptr(ci), + fido_cbor_info_protocols_len(ci)); + + v = fido_cbor_info_new_pin_required(ci); + consume(&v, sizeof(v)); + +out: + fido_dev_close(dev); + fido_dev_free(&dev); + + fido_cbor_info_free(&ci); +} + +static void +dev_set_pin(const struct param *p) +{ + fido_dev_t *dev; + + set_wire_data(p->set_pin_wire_data.body, p->set_pin_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + fido_dev_set_pin(dev, p->pin1, NULL); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_change_pin(const struct param *p) +{ + fido_dev_t *dev; + + set_wire_data(p->change_pin_wire_data.body, p->change_pin_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + fido_dev_set_pin(dev, p->pin2, p->pin1); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_get_retry_count(const struct param *p) +{ + fido_dev_t *dev; + int n = 0; + + set_wire_data(p->retry_wire_data.body, p->retry_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + fido_dev_get_retry_count(dev, &n); + consume(&n, sizeof(n)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_get_uv_retry_count(const struct param *p) +{ + fido_dev_t *dev; + int n = 0; + + set_wire_data(p->retry_wire_data.body, p->retry_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + fido_dev_get_uv_retry_count(dev, &n); + consume(&n, sizeof(n)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_enable_entattest(const struct param *p) +{ + fido_dev_t *dev; + const char *pin; + int r; + + set_wire_data(p->config_wire_data.body, p->config_wire_data.len); + if ((dev = open_dev(0)) == NULL) + return; + pin = p->pin1; + if (strlen(pin) == 0) + pin = NULL; + r = fido_dev_enable_entattest(dev, pin); + consume_str(fido_strerr(r)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_toggle_always_uv(const struct param *p) +{ + fido_dev_t *dev; + const char *pin; + int r; + + set_wire_data(p->config_wire_data.body, p->config_wire_data.len); + if ((dev = open_dev(0)) == NULL) + return; + pin = p->pin1; + if (strlen(pin) == 0) + pin = NULL; + r = fido_dev_toggle_always_uv(dev, pin); + consume_str(fido_strerr(r)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_force_pin_change(const struct param *p) +{ + fido_dev_t *dev; + const char *pin; + int r; + + set_wire_data(p->config_wire_data.body, p->config_wire_data.len); + if ((dev = open_dev(0)) == NULL) + return; + pin = p->pin1; + if (strlen(pin) == 0) + pin = NULL; + r = fido_dev_force_pin_change(dev, pin); + consume_str(fido_strerr(r)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_set_pin_minlen(const struct param *p) +{ + fido_dev_t *dev; + const char *pin; + int r; + + set_wire_data(p->config_wire_data.body, p->config_wire_data.len); + if ((dev = open_dev(0)) == NULL) + return; + pin = p->pin1; + if (strlen(pin) == 0) + pin = NULL; + r = fido_dev_set_pin_minlen(dev, strlen(p->pin2), pin); + consume_str(fido_strerr(r)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_set_pin_minlen_rpid(const struct param *p) +{ + fido_dev_t *dev; + const char *rpid[MAXRPID]; + const char *pin; + size_t n; + int r; + + set_wire_data(p->config_wire_data.body, p->config_wire_data.len); + if ((dev = open_dev(0)) == NULL) + return; + n = uniform_random(MAXRPID); + for (size_t i = 0; i < n; i++) + rpid[i] = dummy_rp_id; + pin = p->pin1; + if (strlen(pin) == 0) + pin = NULL; + r = fido_dev_set_pin_minlen_rpid(dev, rpid, n, pin); + consume_str(fido_strerr(r)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + dev_reset(p); + dev_get_cbor_info(p); + dev_set_pin(p); + dev_change_pin(p); + dev_get_retry_count(p); + dev_get_uv_retry_count(p); + dev_enable_entattest(p); + dev_toggle_always_uv(p); + dev_force_pin_change(p); + dev_set_pin_minlen(p); + dev_set_pin_minlen_rpid(p); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_string(p->pin1); + mutate_string(p->pin2); + } + + if (flags & MUTATE_WIREDATA) { + mutate_blob(&p->reset_wire_data); + mutate_blob(&p->info_wire_data); + mutate_blob(&p->set_pin_wire_data); + mutate_blob(&p->change_pin_wire_data); + mutate_blob(&p->retry_wire_data); + } +} diff --git a/fuzz/fuzz_netlink.c b/fuzz/fuzz_netlink.c new file mode 100644 index 0000000..2fa897e --- /dev/null +++ b/fuzz/fuzz_netlink.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2020 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include "../openbsd-compat/openbsd-compat.h" +#include "mutator_aux.h" +#include "dummy.h" + +struct param { + int seed; + int dev; + struct blob wiredata; +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 3 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_int(v[1], &p->dev) < 0 || + unpack_blob(v[2], &p->wiredata) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[3], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(3)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_int(p->dev)) == NULL || + (argv[2] = pack_blob(&p->wiredata)) == NULL) + goto fail; + + for (size_t i = 0; i < 3; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 3; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + dummy.wiredata.len = sizeof(dummy_netlink_wiredata); + memcpy(&dummy.wiredata.body, &dummy_netlink_wiredata, + dummy.wiredata.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +void +test(const struct param *p) +{ + fido_nl_t *nl; + uint32_t target; + + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + set_netlink_io_functions(fd_read, fd_write); + set_wire_data(p->wiredata.body, p->wiredata.len); + + if ((nl = fido_nl_new()) == NULL) + return; + + consume(&nl->fd, sizeof(nl->fd)); + consume(&nl->nfc_type, sizeof(nl->nfc_type)); + consume(&nl->nfc_mcastgrp, sizeof(nl->nfc_mcastgrp)); + consume(&nl->saddr, sizeof(nl->saddr)); + + fido_nl_power_nfc(nl, (uint32_t)p->dev); + + if (fido_nl_get_nfc_target(nl, (uint32_t)p->dev, &target) == 0) + consume(&target, sizeof(target)); + + fido_nl_free(&nl); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) + mutate_int(&p->dev); + + if (flags & MUTATE_WIREDATA) + mutate_blob(&p->wiredata); +} diff --git a/fuzz/fuzz_pcsc.c b/fuzz/fuzz_pcsc.c new file mode 100644 index 0000000..f0f6cca --- /dev/null +++ b/fuzz/fuzz_pcsc.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#define _FIDO_INTERNAL + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <winscard.h> + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "dummy.h" + +#include "../src/extern.h" + +struct param { + int seed; + char path[MAXSTR]; + struct blob pcsc_list; + struct blob tx_apdu; + struct blob wiredata_init; + struct blob wiredata_msg; +}; + +static const uint8_t dummy_tx_apdu[] = { WIREDATA_CTAP_EXTENDED_APDU }; +static const uint8_t dummy_wiredata_init[] = { WIREDATA_CTAP_NFC_INIT }; +static const uint8_t dummy_wiredata_msg[] = { WIREDATA_CTAP_NFC_MSG }; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 6 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->path) < 0 || + unpack_blob(v[2], &p->pcsc_list) < 0 || + unpack_blob(v[3], &p->tx_apdu) < 0 || + unpack_blob(v[4], &p->wiredata_init) < 0 || + unpack_blob(v[5], &p->wiredata_msg) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[6], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(6)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->path)) == NULL || + (argv[2] = pack_blob(&p->pcsc_list)) == NULL || + (argv[3] = pack_blob(&p->tx_apdu)) == NULL || + (argv[4] = pack_blob(&p->wiredata_init)) == NULL || + (argv[5] = pack_blob(&p->wiredata_msg)) == NULL) + goto fail; + + for (size_t i = 0; i < 6; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 6; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + strlcpy(dummy.path, dummy_pcsc_path, sizeof(dummy.path)); + + dummy.pcsc_list.len = sizeof(dummy_pcsc_list); + memcpy(&dummy.pcsc_list.body, &dummy_pcsc_list, dummy.pcsc_list.len); + + dummy.tx_apdu.len = sizeof(dummy_tx_apdu); + memcpy(&dummy.tx_apdu.body, &dummy_tx_apdu, dummy.tx_apdu.len); + + dummy.wiredata_init.len = sizeof(dummy_wiredata_init); + memcpy(&dummy.wiredata_init.body, &dummy_wiredata_init, + dummy.wiredata_init.len); + + dummy.wiredata_msg.len = sizeof(dummy_wiredata_msg); + memcpy(&dummy.wiredata_msg.body, &dummy_wiredata_msg, + dummy.wiredata_msg.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static void +test_manifest(void) +{ + size_t ndevs, nfound; + fido_dev_info_t *devlist = NULL; + int16_t vendor_id, product_id; + int r; + + r = fido_pcsc_manifest(NULL, 0, &nfound); + assert(r == FIDO_OK && nfound == 0); + r = fido_pcsc_manifest(NULL, 1, &nfound); + assert(r == FIDO_ERR_INVALID_ARGUMENT); + + ndevs = uniform_random(64); + if ((devlist = fido_dev_info_new(ndevs)) == NULL || + fido_pcsc_manifest(devlist, ndevs, &nfound) != FIDO_OK) + goto out; + + for (size_t i = 0; i < nfound; i++) { + const fido_dev_info_t *di = fido_dev_info_ptr(devlist, i); + consume_str(fido_dev_info_path(di)); + consume_str(fido_dev_info_manufacturer_string(di)); + consume_str(fido_dev_info_product_string(di)); + vendor_id = fido_dev_info_vendor(di); + product_id = fido_dev_info_product(di); + consume(&vendor_id, sizeof(vendor_id)); + consume(&product_id, sizeof(product_id)); + } + +out: + fido_dev_info_free(&devlist, ndevs); +} + +static void +test_tx(const char *path, const struct blob *apdu, uint8_t cmd, u_char *rx_buf, + size_t rx_len) +{ + fido_dev_t dev; + const u_char *tx_ptr = NULL; + size_t tx_len = 0; + int n; + + memset(&dev, 0, sizeof(dev)); + + if (fido_dev_set_pcsc(&dev) < 0) + return; + if ((dev.io_handle = fido_pcsc_open(path)) == NULL) + return; + + if (apdu) { + tx_ptr = apdu->body; + tx_len = apdu->len; + } + + fido_pcsc_tx(&dev, cmd, tx_ptr, tx_len); + + if ((n = fido_pcsc_rx(&dev, cmd, rx_buf, rx_len, -1)) >= 0) + consume(rx_buf, n); + + fido_pcsc_close(dev.io_handle); +} + +static void +test_misc(void) +{ + assert(fido_pcsc_open(NULL) == NULL); + assert(fido_pcsc_write(NULL, NULL, INT_MAX + 1LL) == -1); +} + +void +test(const struct param *p) +{ + u_char buf[512]; + + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + set_pcsc_parameters(&p->pcsc_list); + set_pcsc_io_functions(nfc_read, nfc_write, consume); + + set_wire_data(p->wiredata_init.body, p->wiredata_init.len); + test_manifest(); + + test_misc(); + + set_wire_data(p->wiredata_init.body, p->wiredata_init.len); + test_tx(p->path, NULL, CTAP_CMD_INIT, buf, uniform_random(20)); + + set_wire_data(p->wiredata_msg.body, p->wiredata_msg.len); + test_tx(p->path, &p->tx_apdu, CTAP_CMD_MSG, buf, sizeof(buf)); + + set_wire_data(p->wiredata_msg.body, p->wiredata_msg.len); + test_tx(p->path, &p->tx_apdu, CTAP_CMD_CBOR, buf, sizeof(buf)); + + set_wire_data(p->wiredata_msg.body, p->wiredata_msg.len); + test_tx(p->path, &p->tx_apdu, CTAP_CMD_LOCK, buf, sizeof(buf)); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_string(p->path); + mutate_blob(&p->pcsc_list); + mutate_blob(&p->tx_apdu); + } + + if (flags & MUTATE_WIREDATA) { + mutate_blob(&p->wiredata_init); + mutate_blob(&p->wiredata_msg); + } +} diff --git a/fuzz/libfuzzer.c b/fuzz/libfuzzer.c new file mode 100644 index 0000000..073ebe6 --- /dev/null +++ b/fuzz/libfuzzer.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <openssl/sha.h> + +#include <err.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "mutator_aux.h" + +extern int fuzz_save_corpus; + +static bool debug; +static unsigned int flags = MUTATE_ALL; +static unsigned long long test_fail; +static unsigned long long test_total; +static unsigned long long mutate_fail; +static unsigned long long mutate_total; + +int LLVMFuzzerInitialize(int *, char ***); +int LLVMFuzzerTestOneInput(const uint8_t *, size_t); +size_t LLVMFuzzerCustomMutator(uint8_t *, size_t, size_t, unsigned int); + +static int +save_seed(const char *opt) +{ + const char *path; + int fd = -1, status = 1; + void *buf = NULL; + const size_t buflen = MAXCORPUS; + size_t n; + struct param *p = NULL; + + if ((path = strchr(opt, '=')) == NULL || strlen(++path) == 0) { + warnx("usage: --fido-save-seed=<path>"); + goto fail; + } + + if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, 0644)) == -1) { + warn("open %s", path); + goto fail; + } + + if ((buf = malloc(buflen)) == NULL) { + warn("malloc"); + goto fail; + } + + n = pack_dummy(buf, buflen); + + if ((p = unpack(buf, n)) == NULL) { + warnx("unpack"); + goto fail; + } + + if (write(fd, buf, n) != (ssize_t)n) { + warn("write %s", path); + goto fail; + } + + status = 0; +fail: + if (fd != -1) + close(fd); + free(buf); + free(p); + + return status; +} + +static int +save_corpus(const struct param *p) +{ + uint8_t blob[MAXCORPUS], dgst[SHA256_DIGEST_LENGTH]; + size_t blob_len; + char path[PATH_MAX]; + int r, fd; + + if ((blob_len = pack(blob, sizeof(blob), p)) == 0 || + blob_len > sizeof(blob)) { + warnx("pack"); + return -1; + } + + if (SHA256(blob, blob_len, dgst) != dgst) { + warnx("sha256"); + return -1; + } + + if ((r = snprintf(path, sizeof(path), "saved_corpus_%02x%02x%02x%02x" + "%02x%02x%02x%02x", dgst[0], dgst[1], dgst[2], dgst[3], dgst[4], + dgst[5], dgst[6], dgst[7])) < 0 || (size_t)r >= sizeof(path)) { + warnx("snprintf"); + return -1; + } + + if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, 0644)) == -1) { + warn("open %s", path); + return -1; + } + + if (write(fd, blob, blob_len) != (ssize_t)blob_len) { + warn("write"); + r = -1; + } else { + warnx("wrote %s", path); + r = 0; + } + + close(fd); + + return r; +} + +static void +parse_mutate_flags(const char *opt, unsigned int *mutate_flags) +{ + const char *f; + + if ((f = strchr(opt, '=')) == NULL || strlen(++f) == 0) + errx(1, "usage: --fido-mutate=<flag>"); + + if (strcmp(f, "seed") == 0) + *mutate_flags |= MUTATE_SEED; + else if (strcmp(f, "param") == 0) + *mutate_flags |= MUTATE_PARAM; + else if (strcmp(f, "wiredata") == 0) + *mutate_flags |= MUTATE_WIREDATA; + else + errx(1, "--fido-mutate: unknown flag '%s'", f); +} + +int +LLVMFuzzerInitialize(int *argc, char ***argv) +{ + unsigned int mutate_flags = 0; + + for (int i = 0; i < *argc; i++) + if (strcmp((*argv)[i], "--fido-debug") == 0) { + debug = 1; + } else if (strncmp((*argv)[i], "--fido-save-seed=", 17) == 0) { + exit(save_seed((*argv)[i])); + } else if (strncmp((*argv)[i], "--fido-mutate=", 14) == 0) { + parse_mutate_flags((*argv)[i], &mutate_flags); + } + + if (mutate_flags) + flags = mutate_flags; + + return 0; +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct param *p; + + if (size > MAXCORPUS) + return 0; + + if (++test_total % 100000 == 0 && debug) { + double r = (double)test_fail/(double)test_total * 100.0; + fprintf(stderr, "%s: %llu/%llu (%.2f%%)\n", __func__, + test_fail, test_total, r); + } + + if ((p = unpack(data, size)) == NULL) + test_fail++; + else { + fuzz_save_corpus = 0; + test(p); + if (fuzz_save_corpus && save_corpus(p) < 0) + fprintf(stderr, "%s: failed to save corpus\n", + __func__); + free(p); + } + + return 0; +} + +size_t +LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxsize, + unsigned int seed) NO_MSAN +{ + struct param *p; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&p, 0, sizeof(p)); + +#ifdef WITH_MSAN + __msan_unpoison(data, maxsize); +#endif + + if (++mutate_total % 100000 == 0 && debug) { + double r = (double)mutate_fail/(double)mutate_total * 100.0; + fprintf(stderr, "%s: %llu/%llu (%.2f%%)\n", __func__, + mutate_fail, mutate_total, r); + } + + if ((p = unpack(data, size)) == NULL) { + mutate_fail++; + return pack_dummy(data, maxsize); + } + + mutate(p, seed, flags); + + if ((blob_len = pack(blob, sizeof(blob), p)) == 0 || + blob_len > sizeof(blob) || blob_len > maxsize) { + mutate_fail++; + free(p); + return 0; + } + + free(p); + + memcpy(data, blob, blob_len); + + return blob_len; +} diff --git a/fuzz/mutator_aux.c b/fuzz/mutator_aux.c new file mode 100644 index 0000000..64c633f --- /dev/null +++ b/fuzz/mutator_aux.c @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <assert.h> +#include <cbor.h> +#include <errno.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mutator_aux.h" + +int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int); +int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t); +size_t LLVMFuzzerMutate(uint8_t *, size_t, size_t); + +extern int prng_up; +static const uint8_t *wire_data_ptr = NULL; +static size_t wire_data_len = 0; + +void +consume(const void *body, size_t len) +{ + const volatile uint8_t *ptr = body; + volatile uint8_t x = 0; + +#ifdef WITH_MSAN + __msan_check_mem_is_initialized(body, len); +#endif + + while (len--) + x ^= *ptr++; + + (void)x; +} + +void +consume_str(const char *str) +{ + if (str != NULL) + consume(str, strlen(str) + 1); +} + +int +unpack_int(cbor_item_t *item, int *v) +{ + if (cbor_is_int(item) == false || + cbor_int_get_width(item) != CBOR_INT_64) + return -1; + + if (cbor_isa_uint(item)) + *v = (int)cbor_get_uint64(item); + else + *v = (int)(-cbor_get_uint64(item) - 1); + + return 0; +} + +int +unpack_string(cbor_item_t *item, char *v) +{ + size_t len; + + if (cbor_isa_bytestring(item) == false || + (len = cbor_bytestring_length(item)) >= MAXSTR) + return -1; + + memcpy(v, cbor_bytestring_handle(item), len); + v[len] = '\0'; + + return 0; +} + +int +unpack_byte(cbor_item_t *item, uint8_t *v) +{ + if (cbor_isa_uint(item) == false || + cbor_int_get_width(item) != CBOR_INT_8) + return -1; + + *v = cbor_get_uint8(item); + + return 0; +} + +int +unpack_blob(cbor_item_t *item, struct blob *v) +{ + if (cbor_isa_bytestring(item) == false || + (v->len = cbor_bytestring_length(item)) > sizeof(v->body)) + return -1; + + memcpy(v->body, cbor_bytestring_handle(item), v->len); + + return 0; +} + +cbor_item_t * +pack_int(int v) NO_MSAN +{ + if (v < 0) + return cbor_build_negint64((uint64_t)(-(int64_t)v - 1)); + else + return cbor_build_uint64((uint64_t)v); +} + +cbor_item_t * +pack_string(const char *v) NO_MSAN +{ + if (strlen(v) >= MAXSTR) + return NULL; + + return cbor_build_bytestring((const unsigned char *)v, strlen(v)); +} + +cbor_item_t * +pack_byte(uint8_t v) NO_MSAN +{ + return cbor_build_uint8(v); +} + +cbor_item_t * +pack_blob(const struct blob *v) NO_MSAN +{ + return cbor_build_bytestring(v->body, v->len); +} + +void +mutate_byte(uint8_t *b) +{ + LLVMFuzzerMutate(b, sizeof(*b), sizeof(*b)); +} + +void +mutate_int(int *i) +{ + LLVMFuzzerMutate((uint8_t *)i, sizeof(*i), sizeof(*i)); +} + +void +mutate_blob(struct blob *blob) +{ + blob->len = LLVMFuzzerMutate((uint8_t *)blob->body, blob->len, + sizeof(blob->body)); +} + +void +mutate_string(char *s) +{ + size_t n; + + n = LLVMFuzzerMutate((uint8_t *)s, strlen(s), MAXSTR - 1); + s[n] = '\0'; +} + +static int +buf_read(unsigned char *ptr, size_t len, int ms) +{ + size_t n; + + (void)ms; + + if (prng_up && uniform_random(400) < 1) { + errno = EIO; + return -1; + } + + if (wire_data_len < len) + n = wire_data_len; + else + n = len; + + memcpy(ptr, wire_data_ptr, n); + + wire_data_ptr += n; + wire_data_len -= n; + + return (int)n; +} + +static int +buf_write(const unsigned char *ptr, size_t len) +{ + consume(ptr, len); + + if (prng_up && uniform_random(400) < 1) { + errno = EIO; + return -1; + } + + return (int)len; +} + +static void * +hid_open(const char *path) +{ + (void)path; + + return (void *)HID_DEV_HANDLE; +} + +static void +hid_close(void *handle) +{ + assert(handle == (void *)HID_DEV_HANDLE); +} + +static int +hid_read(void *handle, unsigned char *ptr, size_t len, int ms) +{ + assert(handle == (void *)HID_DEV_HANDLE); + assert(len >= CTAP_MIN_REPORT_LEN && len <= CTAP_MAX_REPORT_LEN); + + return buf_read(ptr, len, ms); +} + +static int +hid_write(void *handle, const unsigned char *ptr, size_t len) +{ + assert(handle == (void *)HID_DEV_HANDLE); + assert(len >= CTAP_MIN_REPORT_LEN + 1 && + len <= CTAP_MAX_REPORT_LEN + 1); + + return buf_write(ptr, len); +} + +static void * +nfc_open(const char *path) +{ + (void)path; + + return (void *)NFC_DEV_HANDLE; +} + +static void +nfc_close(void *handle) +{ + assert(handle == (void *)NFC_DEV_HANDLE); +} + +int +nfc_read(void *handle, unsigned char *ptr, size_t len, int ms) +{ + assert(handle == (void *)NFC_DEV_HANDLE); + assert(len > 0 && len <= 264); + + return buf_read(ptr, len, ms); +} + +int +nfc_write(void *handle, const unsigned char *ptr, size_t len) +{ + assert(handle == (void *)NFC_DEV_HANDLE); + assert(len > 0 && len <= 256 + 2); + + return buf_write(ptr, len); +} + +ssize_t +fd_read(int fd, void *ptr, size_t len) +{ + assert(fd != -1); + + return buf_read(ptr, len, -1); +} + +ssize_t +fd_write(int fd, const void *ptr, size_t len) +{ + assert(fd != -1); + + return buf_write(ptr, len); +} + +fido_dev_t * +open_dev(int nfc) +{ + fido_dev_t *dev; + fido_dev_io_t io; + fido_dev_transport_t t; + + memset(&io, 0, sizeof(io)); + memset(&t, 0, sizeof(t)); + + if ((dev = fido_dev_new()) == NULL) + return NULL; + + if (nfc) { + io.open = nfc_open; + io.close = nfc_close; + io.read = nfc_read; + io.write = nfc_write; + } else { + io.open = hid_open; + io.close = hid_close; + io.read = hid_read; + io.write = hid_write; + } + + if (fido_dev_set_io_functions(dev, &io) != FIDO_OK) + goto fail; + + if (nfc) { + t.rx = fido_nfc_rx; + t.tx = fido_nfc_tx; + if (fido_dev_set_transport_functions(dev, &t) != FIDO_OK) + goto fail; + } + + if (fido_dev_set_timeout(dev, 300) != FIDO_OK || + fido_dev_open(dev, "nodev") != FIDO_OK) + goto fail; + + return dev; +fail: + fido_dev_free(&dev); + + return NULL; +} + +void +set_wire_data(const uint8_t *ptr, size_t len) +{ + wire_data_ptr = ptr; + wire_data_len = len; +} diff --git a/fuzz/mutator_aux.h b/fuzz/mutator_aux.h new file mode 100644 index 0000000..5ad5661 --- /dev/null +++ b/fuzz/mutator_aux.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _MUTATOR_AUX_H +#define _MUTATOR_AUX_H + +#include <sys/types.h> + +#include <stddef.h> +#include <stdint.h> +#include <cbor.h> + +#include "../src/fido.h" +#include "../src/fido/bio.h" +#include "../src/fido/config.h" +#include "../src/fido/credman.h" +#include "../src/fido/eddsa.h" +#include "../src/fido/es256.h" +#include "../src/fido/es384.h" +#include "../src/fido/rs256.h" +#include "../src/netlink.h" + +/* + * As of LLVM 10.0.0, MSAN support in libFuzzer was still experimental. + * We therefore have to be careful when using our custom mutator, or + * MSAN will flag uninitialised reads on memory populated by libFuzzer. + * Since there is no way to suppress MSAN without regenerating object + * code (in which case you might as well rebuild libFuzzer with MSAN), + * we adjust our mutator to make it less accurate while allowing + * fuzzing to proceed. + */ + +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) +# include <sanitizer/msan_interface.h> +# define NO_MSAN __attribute__((no_sanitize("memory"))) +# define WITH_MSAN 1 +# endif +#endif + +#if !defined(WITH_MSAN) +# define NO_MSAN +#endif + +#define MUTATE_SEED 0x01 +#define MUTATE_PARAM 0x02 +#define MUTATE_WIREDATA 0x04 +#define MUTATE_ALL (MUTATE_SEED | MUTATE_PARAM | MUTATE_WIREDATA) + +#define MAXSTR 1024 +#define MAXBLOB 3600 +#define MAXCORPUS 8192 + +#define HID_DEV_HANDLE 0x68696421 +#define NFC_DEV_HANDLE 0x6e666321 + +struct blob { + uint8_t body[MAXBLOB]; + size_t len; +}; + +struct param; + +struct param *unpack(const uint8_t *, size_t); +size_t pack(uint8_t *, size_t, const struct param *); +size_t pack_dummy(uint8_t *, size_t); +void mutate(struct param *, unsigned int, unsigned int); +void test(const struct param *); + +void consume(const void *, size_t); +void consume_str(const char *); + +int unpack_blob(cbor_item_t *, struct blob *); +int unpack_byte(cbor_item_t *, uint8_t *); +int unpack_int(cbor_item_t *, int *); +int unpack_string(cbor_item_t *, char *); + +cbor_item_t *pack_blob(const struct blob *); +cbor_item_t *pack_byte(uint8_t); +cbor_item_t *pack_int(int); +cbor_item_t *pack_string(const char *); + +void mutate_byte(uint8_t *); +void mutate_int(int *); +void mutate_blob(struct blob *); +void mutate_string(char *); + +ssize_t fd_read(int, void *, size_t); +ssize_t fd_write(int, const void *, size_t); + +int nfc_read(void *, unsigned char *, size_t, int); +int nfc_write(void *, const unsigned char *, size_t); + +fido_dev_t *open_dev(int); +void set_wire_data(const uint8_t *, size_t); + +void fuzz_clock_reset(void); +void prng_init(unsigned long); +unsigned long prng_uint32(void); + +uint32_t uniform_random(uint32_t); + +void set_pcsc_parameters(const struct blob *); +void set_pcsc_io_functions(int (*)(void *, u_char *, size_t, int), + int (*)(void *, const u_char *, size_t), void (*)(const void *, size_t)); + +#endif /* !_MUTATOR_AUX_H */ diff --git a/fuzz/pcsc.c b/fuzz/pcsc.c new file mode 100644 index 0000000..f6a3e9b --- /dev/null +++ b/fuzz/pcsc.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <winscard.h> + +#include "mutator_aux.h" + +static const struct blob *reader_list; +static int (*xread)(void *, u_char *, size_t, int); +static int (*xwrite)(void *, const u_char *, size_t); +static void (*xconsume)(const void *, size_t); + +LONG __wrap_SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT); +LONG __wrap_SCardListReaders(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD); +LONG __wrap_SCardReleaseContext(SCARDCONTEXT); +LONG __wrap_SCardConnect(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE, + LPDWORD); +LONG __wrap_SCardDisconnect(SCARDHANDLE, DWORD); +LONG __wrap_SCardTransmit(SCARDHANDLE, const SCARD_IO_REQUEST *, LPCBYTE, + DWORD, SCARD_IO_REQUEST *, LPBYTE, LPDWORD); + +LONG +__wrap_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, + LPCVOID pvReserved2, LPSCARDCONTEXT phContext) +{ + assert(dwScope == SCARD_SCOPE_SYSTEM); + assert(pvReserved1 == NULL); + assert(pvReserved2 == NULL); + + *phContext = 1; + + if (uniform_random(400) < 1) + return SCARD_E_NO_SERVICE; + if (uniform_random(400) < 1) + return SCARD_E_NO_SMARTCARD; + if (uniform_random(400) < 1) + return SCARD_E_NO_MEMORY; + if (uniform_random(400) < 1) + *phContext = 0; + + return SCARD_S_SUCCESS; +} + +LONG +__wrap_SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, + LPSTR mszReaders, LPDWORD pcchReaders) +{ + assert(hContext == 1); + assert(mszGroups == NULL); + assert(mszReaders != NULL); + assert(pcchReaders != 0); + + if (reader_list == NULL || uniform_random(400) < 1) + return SCARD_E_NO_READERS_AVAILABLE; + if (uniform_random(400) < 1) + return SCARD_E_NO_MEMORY; + + memcpy(mszReaders, reader_list->body, reader_list->len > *pcchReaders ? + *pcchReaders : reader_list->len); + *pcchReaders = (DWORD)reader_list->len; /* on purpose */ + + return SCARD_S_SUCCESS; +} + +LONG +__wrap_SCardReleaseContext(SCARDCONTEXT hContext) +{ + assert(hContext == 1); + + return SCARD_S_SUCCESS; +} + +LONG +__wrap_SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, + DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) +{ + uint32_t r; + + assert(hContext == 1); + xconsume(szReader, strlen(szReader) + 1); + assert(dwShareMode == SCARD_SHARE_SHARED); + assert(dwPreferredProtocols == SCARD_PROTOCOL_ANY); + assert(phCard != NULL); + assert(pdwActiveProtocol != NULL); + + if ((r = uniform_random(400)) < 1) + return SCARD_E_UNEXPECTED; + + *phCard = 1; + *pdwActiveProtocol = (r & 1) ? SCARD_PROTOCOL_T0 : SCARD_PROTOCOL_T1; + + if (uniform_random(400) < 1) + *pdwActiveProtocol = SCARD_PROTOCOL_RAW; + + return SCARD_S_SUCCESS; +} + +LONG +__wrap_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) +{ + assert(hCard == 1); + assert(dwDisposition == SCARD_LEAVE_CARD); + + return SCARD_S_SUCCESS; +} + +extern void consume(const void *body, size_t len); + +LONG +__wrap_SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, + LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci, + LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) +{ + void *ioh = (void *)NFC_DEV_HANDLE; + int n; + + assert(hCard == 1); + xconsume(pioSendPci, sizeof(*pioSendPci)); + xwrite(ioh, pbSendBuffer, cbSendLength); + assert(pioRecvPci == NULL); + + if (uniform_random(400) < 1 || + (n = xread(ioh, pbRecvBuffer, *pcbRecvLength, -1)) == -1) + return SCARD_E_UNEXPECTED; + *pcbRecvLength = (DWORD)n; + + return SCARD_S_SUCCESS; +} + +void +set_pcsc_parameters(const struct blob *reader_list_ptr) +{ + reader_list = reader_list_ptr; +} + +void +set_pcsc_io_functions(int (*read_f)(void *, u_char *, size_t, int), + int (*write_f)(void *, const u_char *, size_t), + void (*consume_f)(const void *, size_t)) +{ + xread = read_f; + xwrite = write_f; + xconsume = consume_f; +} diff --git a/fuzz/preload-fuzz.c b/fuzz/preload-fuzz.c new file mode 100644 index 0000000..f18848d --- /dev/null +++ b/fuzz/preload-fuzz.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2019 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * cc -fPIC -D_GNU_SOURCE -shared -o preload-fuzz.so preload-fuzz.c + * LD_PRELOAD=$(realpath preload-fuzz.so) + */ + +#include <sys/types.h> +#include <sys/stat.h> + +#include <dlfcn.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define FUZZ_DEV_PREFIX "nodev" + +static int fd_fuzz = -1; +static int (*open_f)(const char *, int, mode_t); +static int (*close_f)(int); +static ssize_t (*write_f)(int, const void *, size_t); + +int +open(const char *path, int flags, ...) +{ + va_list ap; + mode_t mode; + + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + + if (open_f == NULL) { + open_f = dlsym(RTLD_NEXT, "open"); + if (open_f == NULL) { + warnx("%s: dlsym", __func__); + errno = EACCES; + return (-1); + } + } + + if (strncmp(path, FUZZ_DEV_PREFIX, strlen(FUZZ_DEV_PREFIX)) != 0) + return (open_f(path, flags, mode)); + + if (fd_fuzz != -1) { + warnx("%s: fd_fuzz != -1", __func__); + errno = EACCES; + return (-1); + } + + if ((fd_fuzz = dup(STDIN_FILENO)) < 0) { + warn("%s: dup", __func__); + errno = EACCES; + return (-1); + } + + return (fd_fuzz); +} + +int +close(int fd) +{ + if (close_f == NULL) { + close_f = dlsym(RTLD_NEXT, "close"); + if (close_f == NULL) { + warnx("%s: dlsym", __func__); + errno = EACCES; + return (-1); + } + } + + if (fd == fd_fuzz) + fd_fuzz = -1; + + return (close_f(fd)); +} + +ssize_t +write(int fd, const void *buf, size_t nbytes) +{ + if (write_f == NULL) { + write_f = dlsym(RTLD_NEXT, "write"); + if (write_f == NULL) { + warnx("%s: dlsym", __func__); + errno = EBADF; + return (-1); + } + } + + if (fd != fd_fuzz) + return (write_f(fd, buf, nbytes)); + + return (nbytes); +} diff --git a/fuzz/preload-snoop.c b/fuzz/preload-snoop.c new file mode 100644 index 0000000..34d57ad --- /dev/null +++ b/fuzz/preload-snoop.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2019 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * cc -fPIC -D_GNU_SOURCE -shared -o preload-snoop.so preload-snoop.c + * LD_PRELOAD=$(realpath preload-snoop.so) + */ + +#include <sys/types.h> +#include <sys/stat.h> + +#include <dlfcn.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define SNOOP_DEV_PREFIX "/dev/hidraw" + +struct fd_tuple { + int snoop_in; + int snoop_out; + int real_dev; +}; + +static struct fd_tuple *fd_tuple; +static int (*open_f)(const char *, int, mode_t); +static int (*close_f)(int); +static ssize_t (*read_f)(int, void *, size_t); +static ssize_t (*write_f)(int, const void *, size_t); + +static int +get_fd(const char *hid_path, const char *suffix) +{ + char *s = NULL; + char path[PATH_MAX]; + int fd; + int r; + + if ((s = strdup(hid_path)) == NULL) { + warnx("%s: strdup", __func__); + return (-1); + } + + for (size_t i = 0; i < strlen(s); i++) + if (s[i] == '/') + s[i] = '_'; + + if ((r = snprintf(path, sizeof(path), "%s-%s", s, suffix)) < 0 || + (size_t)r >= sizeof(path)) { + warnx("%s: snprintf", __func__); + free(s); + return (-1); + } + + free(s); + s = NULL; + + if ((fd = open_f(path, O_CREAT | O_WRONLY, 0644)) < 0) { + warn("%s: open", __func__); + return (-1); + } + + return (fd); +} + +int +open(const char *path, int flags, ...) +{ + va_list ap; + mode_t mode; + + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + + if (open_f == NULL) { + open_f = dlsym(RTLD_NEXT, "open"); + if (open_f == NULL) { + warnx("%s: dlsym", __func__); + errno = EACCES; + return (-1); + } + } + + if (strncmp(path, SNOOP_DEV_PREFIX, strlen(SNOOP_DEV_PREFIX)) != 0) + return (open_f(path, flags, mode)); + + if (fd_tuple != NULL) { + warnx("%s: fd_tuple != NULL", __func__); + errno = EACCES; + return (-1); + } + + if ((fd_tuple = calloc(1, sizeof(*fd_tuple))) == NULL) { + warn("%s: calloc", __func__); + errno = ENOMEM; + return (-1); + } + + fd_tuple->snoop_in = -1; + fd_tuple->snoop_out = -1; + fd_tuple->real_dev = -1; + + if ((fd_tuple->snoop_in = get_fd(path, "in")) < 0 || + (fd_tuple->snoop_out = get_fd(path, "out")) < 0 || + (fd_tuple->real_dev = open_f(path, flags, mode)) < 0) { + warn("%s: get_fd/open", __func__); + goto fail; + } + + return (fd_tuple->real_dev); +fail: + if (fd_tuple->snoop_in != -1) + close(fd_tuple->snoop_in); + if (fd_tuple->snoop_out != -1) + close(fd_tuple->snoop_out); + if (fd_tuple->real_dev != -1) + close(fd_tuple->real_dev); + + free(fd_tuple); + fd_tuple = NULL; + + errno = EACCES; + + return (-1); +} + +int +close(int fd) +{ + if (close_f == NULL) { + close_f = dlsym(RTLD_NEXT, "close"); + if (close_f == NULL) { + warnx("%s: dlsym", __func__); + errno = EBADF; + return (-1); + } + } + + if (fd_tuple == NULL || fd_tuple->real_dev != fd) + return (close_f(fd)); + + close_f(fd_tuple->snoop_in); + close_f(fd_tuple->snoop_out); + close_f(fd_tuple->real_dev); + + free(fd_tuple); + fd_tuple = NULL; + + return (0); +} + +ssize_t +read(int fd, void *buf, size_t nbytes) +{ + ssize_t n; + + if (read_f == NULL) { + read_f = dlsym(RTLD_NEXT, "read"); + if (read_f == NULL) { + warnx("%s: dlsym", __func__); + errno = EBADF; + return (-1); + } + } + + if (write_f == NULL) { + write_f = dlsym(RTLD_NEXT, "write"); + if (write_f == NULL) { + warnx("%s: dlsym", __func__); + errno = EBADF; + return (-1); + } + } + + if (fd_tuple == NULL || fd_tuple->real_dev != fd) + return (read_f(fd, buf, nbytes)); + + if ((n = read_f(fd, buf, nbytes)) < 0 || + write_f(fd_tuple->snoop_in, buf, n) != n) + return (-1); + + return (n); +} + +ssize_t +write(int fd, const void *buf, size_t nbytes) +{ + ssize_t n; + + if (write_f == NULL) { + write_f = dlsym(RTLD_NEXT, "write"); + if (write_f == NULL) { + warnx("%s: dlsym", __func__); + errno = EBADF; + return (-1); + } + } + + if (fd_tuple == NULL || fd_tuple->real_dev != fd) + return (write_f(fd, buf, nbytes)); + + if ((n = write_f(fd, buf, nbytes)) < 0 || + write_f(fd_tuple->snoop_out, buf, n) != n) + return (-1); + + return (n); +} diff --git a/fuzz/prng.c b/fuzz/prng.c new file mode 100644 index 0000000..61114ac --- /dev/null +++ b/fuzz/prng.c @@ -0,0 +1,113 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include "mutator_aux.h" + +#define init_genrand prng_init +#define genrand_int32 prng_uint32 + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +int prng_up = 0; +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti<N; mti++) { + mt[mti] = + (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + + (unsigned long)mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } + prng_up = 1; +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) +{ + unsigned long y; + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + assert(mti != N+1); + + for (kk=0;kk<N-M;kk++) { + y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); + mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL]; + } + for (;kk<N-1;kk++) { + y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); + mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} diff --git a/fuzz/report.tgz b/fuzz/report.tgz Binary files differnew file mode 100644 index 0000000..e984ee9 --- /dev/null +++ b/fuzz/report.tgz diff --git a/fuzz/summary.txt b/fuzz/summary.txt new file mode 100644 index 0000000..0f79600 --- /dev/null +++ b/fuzz/summary.txt @@ -0,0 +1,64 @@ +Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +fuzz/clock.c 24 1 95.83% 4 0 100.00% 35 1 97.14% +fuzz/pcsc.c 59 0 100.00% 8 0 100.00% 75 12 84.00% +fuzz/prng.c 31 0 100.00% 2 0 100.00% 35 1 97.14% +fuzz/udev.c 110 2 98.18% 17 0 100.00% 126 12 90.48% +fuzz/uniform_random.c 7 1 85.71% 1 0 100.00% 12 1 91.67% +fuzz/wrap.c 23 0 100.00% 3 0 100.00% 29 0 100.00% +openbsd-compat/explicit_bzero.c 4 0 100.00% 1 0 100.00% 7 0 100.00% +openbsd-compat/freezero.c 4 0 100.00% 1 0 100.00% 6 0 100.00% +openbsd-compat/recallocarray.c 41 7 82.93% 1 0 100.00% 36 7 80.56% +openbsd-compat/timingsafe_bcmp.c 4 0 100.00% 1 0 100.00% 7 0 100.00% +src/aes256.c 118 3 97.46% 8 0 100.00% 157 11 92.99% +src/assert.c 605 43 92.89% 59 3 94.92% 745 46 93.83% +src/authkey.c 52 0 100.00% 5 0 100.00% 66 0 100.00% +src/bio.c 451 20 95.57% 49 2 95.92% 587 24 95.91% +src/blob.c 53 2 96.23% 10 0 100.00% 83 4 95.18% +src/buf.c 8 1 87.50% 2 0 100.00% 16 1 93.75% +src/cbor.c 1070 13 98.79% 55 0 100.00% 1258 31 97.54% +src/compress.c 105 14 86.67% 5 0 100.00% 122 24 80.33% +src/config.c 112 0 100.00% 11 0 100.00% 152 0 100.00% +src/cred.c 651 38 94.16% 69 2 97.10% 849 43 94.94% +src/credman.c 422 10 97.63% 40 0 100.00% 557 20 96.41% +src/dev.c 332 65 80.42% 41 6 85.37% 378 80 78.84% +src/ecdh.c 117 2 98.29% 4 0 100.00% 146 5 96.58% +src/eddsa.c 88 5 94.32% 10 0 100.00% 114 9 92.11% +src/err.c 122 10 91.80% 1 0 100.00% 126 10 92.06% +src/es256.c 315 7 97.78% 19 0 100.00% 372 12 96.77% +src/es384.c 158 8 94.94% 11 0 100.00% 198 15 92.42% +src/hid.c 87 2 97.70% 14 0 100.00% 145 3 97.93% +src/hid_linux.c 184 73 60.33% 14 7 50.00% 263 115 56.27% +src/hid_unix.c 29 21 27.59% 2 0 100.00% 43 26 39.53% +src/info.c 232 0 100.00% 51 0 100.00% 409 0 100.00% +src/io.c 193 7 96.37% 13 0 100.00% 230 12 94.78% +src/iso7816.c 18 1 94.44% 5 0 100.00% 38 1 97.37% +src/largeblob.c 525 18 96.57% 30 0 100.00% 693 43 93.80% +src/log.c 39 5 87.18% 7 1 85.71% 63 7 88.89% +src/netlink.c 329 8 97.57% 40 0 100.00% 498 15 96.99% +src/nfc.c 155 5 96.77% 12 0 100.00% 244 15 93.85% +src/nfc_linux.c 172 77 55.23% 13 7 46.15% 242 126 47.93% +src/pcsc.c 204 1 99.51% 13 0 100.00% 282 3 98.94% +src/pin.c 426 3 99.30% 26 0 100.00% 514 4 99.22% +src/random.c 6 0 100.00% 1 0 100.00% 6 0 100.00% +src/reset.c 24 0 100.00% 3 0 100.00% 23 0 100.00% +src/rs1.c 25 1 96.00% 3 0 100.00% 39 3 92.31% +src/rs256.c 149 10 93.29% 13 0 100.00% 182 14 92.31% +src/time.c 43 3 93.02% 3 0 100.00% 43 2 95.35% +src/touch.c 67 0 100.00% 2 0 100.00% 79 0 100.00% +src/tpm.c 103 0 100.00% 9 0 100.00% 194 0 100.00% +src/types.c 29 0 100.00% 7 0 100.00% 56 0 100.00% +src/u2f.c 572 4 99.30% 17 0 100.00% 726 12 98.35% +src/util.c 14 1 92.86% 1 0 100.00% 14 1 92.86% + +Files which contain no functions: +fuzz/mutator_aux.h 0 0 - 0 0 - 0 0 - +openbsd-compat/openbsd-compat.h 0 0 - 0 0 - 0 0 - +openbsd-compat/time.h 0 0 - 0 0 - 0 0 - +src/extern.h 0 0 - 0 0 - 0 0 - +src/fallthrough.h 0 0 - 0 0 - 0 0 - +src/fido.h 0 0 - 0 0 - 0 0 - +src/fido/err.h 0 0 - 0 0 - 0 0 - +src/fido/param.h 0 0 - 0 0 - 0 0 - +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +TOTAL 8711 492 94.35% 737 28 96.20% 11320 771 93.19% diff --git a/fuzz/udev.c b/fuzz/udev.c new file mode 100644 index 0000000..3194012 --- /dev/null +++ b/fuzz/udev.c @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/types.h> + +#include <linux/hidraw.h> +#include <linux/input.h> + +#include <assert.h> +#include <errno.h> +#include <libudev.h> +#include <stdlib.h> + +#include "mutator_aux.h" + +struct udev { + int magic; +}; + +struct udev_enumerate { + int magic; + struct udev_list_entry *list_entry; +}; + +struct udev_list_entry { + int magic; +}; + +struct udev_device { + int magic; + struct udev_device *parent; +}; + +#define UDEV_MAGIC 0x584492cc +#define UDEV_DEVICE_MAGIC 0x569180dd +#define UDEV_LIST_ENTRY_MAGIC 0x497422ee +#define UDEV_ENUM_MAGIC 0x583570ff + +#define ASSERT_TYPE(x, m) assert((x) != NULL && (x)->magic == (m)) +#define ASSERT_UDEV(x) ASSERT_TYPE((x), UDEV_MAGIC) +#define ASSERT_UDEV_ENUM(x) ASSERT_TYPE((x), UDEV_ENUM_MAGIC) +#define ASSERT_UDEV_LIST_ENTRY(x) ASSERT_TYPE((x), UDEV_LIST_ENTRY_MAGIC) +#define ASSERT_UDEV_DEVICE(x) ASSERT_TYPE((x), UDEV_DEVICE_MAGIC) + +static const char *uevent; +static const struct blob *report_descriptor; + +struct udev *__wrap_udev_new(void); +struct udev_device *__wrap_udev_device_get_parent_with_subsystem_devtype( + struct udev_device *, const char *, const char *); +struct udev_device *__wrap_udev_device_new_from_syspath(struct udev *, + const char *); +struct udev_enumerate *__wrap_udev_enumerate_new(struct udev *); +struct udev_list_entry *__wrap_udev_enumerate_get_list_entry( + struct udev_enumerate *); +struct udev_list_entry *__wrap_udev_list_entry_get_next( + struct udev_list_entry *); +const char *__wrap_udev_device_get_sysattr_value(struct udev_device *, + const char *); +const char *__wrap_udev_list_entry_get_name(struct udev_list_entry *); +const char *__wrap_udev_device_get_devnode(struct udev_device *); +const char *__wrap_udev_device_get_sysnum(struct udev_device *); +int __wrap_udev_enumerate_add_match_subsystem(struct udev_enumerate *, + const char *); +int __wrap_udev_enumerate_scan_devices(struct udev_enumerate *); +int __wrap_ioctl(int, unsigned long , ...); +void __wrap_udev_device_unref(struct udev_device *); +void __wrap_udev_enumerate_unref(struct udev_enumerate *); +void __wrap_udev_unref(struct udev *); +void set_udev_parameters(const char *, const struct blob *); + +struct udev_device * +__wrap_udev_device_get_parent_with_subsystem_devtype(struct udev_device *child, + const char *subsystem, const char *devtype) +{ + ASSERT_UDEV_DEVICE(child); + fido_log_debug("%s", subsystem); /* XXX consume */ + fido_log_debug("%s", devtype); /* XXX consume */ + if (child->parent != NULL) + return child->parent; + if ((child->parent = calloc(1, sizeof(*child->parent))) == NULL) + return NULL; + child->parent->magic = UDEV_DEVICE_MAGIC; + + return child->parent; +} + +const char * +__wrap_udev_device_get_sysattr_value(struct udev_device *udev_device, + const char *sysattr) +{ + ASSERT_UDEV_DEVICE(udev_device); + if (uniform_random(400) < 1) + return NULL; + if (!strcmp(sysattr, "manufacturer") || !strcmp(sysattr, "product")) + return "product info"; /* XXX randomise? */ + else if (!strcmp(sysattr, "uevent")) + return uevent; + + return NULL; +} + +const char * +__wrap_udev_list_entry_get_name(struct udev_list_entry *entry) +{ + ASSERT_UDEV_LIST_ENTRY(entry); + return uniform_random(400) < 1 ? NULL : "name"; /* XXX randomise? */ +} + +struct udev_device * +__wrap_udev_device_new_from_syspath(struct udev *udev, const char *syspath) +{ + struct udev_device *udev_device; + + ASSERT_UDEV(udev); + fido_log_debug("%s", syspath); + if ((udev_device = calloc(1, sizeof(*udev_device))) == NULL) + return NULL; + udev_device->magic = UDEV_DEVICE_MAGIC; + + return udev_device; +} + +const char * +__wrap_udev_device_get_devnode(struct udev_device *udev_device) +{ + ASSERT_UDEV_DEVICE(udev_device); + return uniform_random(400) < 1 ? NULL : "/dev/zero"; +} + +const char * +__wrap_udev_device_get_sysnum(struct udev_device *udev_device) +{ + ASSERT_UDEV_DEVICE(udev_device); + return uniform_random(400) < 1 ? NULL : "101010"; /* XXX randomise? */ +} + +void +__wrap_udev_device_unref(struct udev_device *udev_device) +{ + ASSERT_UDEV_DEVICE(udev_device); + if (udev_device->parent) { + ASSERT_UDEV_DEVICE(udev_device->parent); + free(udev_device->parent); + } + free(udev_device); +} + +struct udev * +__wrap_udev_new(void) +{ + struct udev *udev; + + if ((udev = calloc(1, sizeof(*udev))) == NULL) + return NULL; + udev->magic = UDEV_MAGIC; + + return udev; +} + +struct udev_enumerate * +__wrap_udev_enumerate_new(struct udev *udev) +{ + struct udev_enumerate *udev_enum; + + ASSERT_UDEV(udev); + if ((udev_enum = calloc(1, sizeof(*udev_enum))) == NULL) + return NULL; + udev_enum->magic = UDEV_ENUM_MAGIC; + + return udev_enum; +} + +int +__wrap_udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enum, + const char *subsystem) +{ + ASSERT_UDEV_ENUM(udev_enum); + fido_log_debug("%s:", subsystem); + return uniform_random(400) < 1 ? -EINVAL : 0; +} + +int +__wrap_udev_enumerate_scan_devices(struct udev_enumerate *udev_enum) +{ + ASSERT_UDEV_ENUM(udev_enum); + return uniform_random(400) < 1 ? -EINVAL : 0; +} + +struct udev_list_entry * +__wrap_udev_enumerate_get_list_entry(struct udev_enumerate *udev_enum) +{ + ASSERT_UDEV_ENUM(udev_enum); + if ((udev_enum->list_entry = calloc(1, + sizeof(*udev_enum->list_entry))) == NULL) + return NULL; + udev_enum->list_entry->magic = UDEV_LIST_ENTRY_MAGIC; + + return udev_enum->list_entry; +} + +struct udev_list_entry * +__wrap_udev_list_entry_get_next(struct udev_list_entry *udev_list_entry) +{ + ASSERT_UDEV_LIST_ENTRY(udev_list_entry); + return uniform_random(400) < 1 ? NULL : udev_list_entry; +} + +void +__wrap_udev_enumerate_unref(struct udev_enumerate *udev_enum) +{ + ASSERT_UDEV_ENUM(udev_enum); + if (udev_enum->list_entry) + ASSERT_UDEV_LIST_ENTRY(udev_enum->list_entry); + free(udev_enum->list_entry); + free(udev_enum); +} + +void +__wrap_udev_unref(struct udev *udev) +{ + ASSERT_UDEV(udev); + free(udev); +} + +int +__wrap_ioctl(int fd, unsigned long request, ...) +{ + va_list ap; + struct hidraw_report_descriptor *hrd; + + (void)fd; + + if (uniform_random(400) < 1) { + errno = EINVAL; + return -1; + } + + va_start(ap, request); + + switch (IOCTL_REQ(request)) { + case IOCTL_REQ(HIDIOCGRDESCSIZE): + *va_arg(ap, int *) = (int)report_descriptor->len; + break; + case IOCTL_REQ(HIDIOCGRDESC): + hrd = va_arg(ap, struct hidraw_report_descriptor *); + assert(hrd->size == report_descriptor->len); + memcpy(hrd->value, report_descriptor->body, hrd->size); + break; + default: + warnx("%s: unknown request 0x%lx", __func__, request); + abort(); + } + + va_end(ap); + + return 0; +} + +void +set_udev_parameters(const char *uevent_ptr, + const struct blob *report_descriptor_ptr) +{ + uevent = uevent_ptr; + report_descriptor = report_descriptor_ptr; +} diff --git a/fuzz/uniform_random.c b/fuzz/uniform_random.c new file mode 100644 index 0000000..357091c --- /dev/null +++ b/fuzz/uniform_random.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2008, Damien Miller <djm@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdint.h> +#include <stdlib.h> + +uint32_t uniform_random(uint32_t); +unsigned long prng_uint32(void); + +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +uint32_t +uniform_random(uint32_t upper_bound) +{ + uint32_t r, min; + + if (upper_bound < 2) + return 0; + + /* 2**32 % x == (2**32 - x) % x */ + min = -upper_bound % upper_bound; + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + for (;;) { + r = (uint32_t)prng_uint32(); + if (r >= min) + break; + } + + return r % upper_bound; +} diff --git a/fuzz/wiredata_fido2.h b/fuzz/wiredata_fido2.h new file mode 100644 index 0000000..6c66c54 --- /dev/null +++ b/fuzz/wiredata_fido2.h @@ -0,0 +1,708 @@ +/* + * Copyright (c) 2020-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _WIREDATA_FIDO2_H +#define _WIREDATA_FIDO2_H + +#define WIREDATA_CTAP_INIT \ + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x80, \ + 0x43, 0x56, 0x40, 0xb1, 0x4e, 0xd9, 0x2d, 0x00, \ + 0x22, 0x00, 0x02, 0x02, 0x05, 0x02, 0x01, 0x05, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_KEEPALIVE \ + 0x00, 0x22, 0x00, 0x02, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_INFO \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0xb9, 0x00, \ + 0xa9, 0x01, 0x83, 0x66, 0x55, 0x32, 0x46, 0x5f, \ + 0x56, 0x32, 0x68, 0x46, 0x49, 0x44, 0x4f, 0x5f, \ + 0x32, 0x5f, 0x30, 0x6c, 0x46, 0x49, 0x44, 0x4f, \ + 0x5f, 0x32, 0x5f, 0x31, 0x5f, 0x50, 0x52, 0x45, \ + 0x02, 0x82, 0x6b, 0x63, 0x72, 0x65, 0x64, 0x50, \ + 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x6b, 0x68, \ + 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x65, 0x63, 0x72, \ + 0x00, 0x22, 0x00, 0x02, 0x00, 0x65, 0x74, 0x03, \ + 0x50, 0x19, 0x56, 0xe5, 0xbd, 0xa3, 0x74, 0x45, \ + 0xf1, 0xa8, 0x14, 0x35, 0x64, 0x03, 0xfd, 0xbc, \ + 0x18, 0x04, 0xa5, 0x62, 0x72, 0x6b, 0xf5, 0x62, \ + 0x75, 0x70, 0xf5, 0x64, 0x70, 0x6c, 0x61, 0x74, \ + 0xf4, 0x69, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, \ + 0x50, 0x69, 0x6e, 0xf4, 0x75, 0x63, 0x72, 0x65, \ + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4d, \ + 0x00, 0x22, 0x00, 0x02, 0x01, 0x67, 0x6d, 0x74, \ + 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0xf5, \ + 0x05, 0x19, 0x04, 0xb0, 0x06, 0x81, 0x01, 0x07, \ + 0x08, 0x08, 0x18, 0x80, 0x0a, 0x82, 0xa2, 0x63, \ + 0x61, 0x6c, 0x67, 0x26, 0x64, 0x74, 0x79, 0x70, \ + 0x65, 0x6a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, \ + 0x2d, 0x6b, 0x65, 0x79, 0xa2, 0x63, 0x61, 0x6c, \ + 0x67, 0x27, 0x64, 0x74, 0x79, 0x70, 0x65, 0x6a, \ + 0x00, 0x22, 0x00, 0x02, 0x02, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_AUTHKEY \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0x51, 0x00, \ + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, \ + 0x20, 0x01, 0x21, 0x58, 0x20, 0x2a, 0xb8, 0x2d, \ + 0x36, 0x69, 0xab, 0x30, 0x9d, 0xe3, 0x5e, 0x9b, \ + 0xfb, 0x94, 0xfc, 0x1d, 0x92, 0x95, 0xaf, 0x01, \ + 0x47, 0xfe, 0x4b, 0x87, 0xe5, 0xcf, 0x3f, 0x05, \ + 0x0b, 0x39, 0xda, 0x17, 0x49, 0x22, 0x58, 0x20, \ + 0x15, 0x1b, 0xbe, 0x08, 0x78, 0x60, 0x4d, 0x3c, \ + 0x00, 0x22, 0x00, 0x02, 0x00, 0x3f, 0xf1, 0x60, \ + 0xa6, 0xd8, 0xf8, 0xed, 0xce, 0x4a, 0x30, 0x5d, \ + 0x1a, 0xaf, 0x80, 0xc4, 0x0a, 0xd2, 0x6f, 0x77, \ + 0x38, 0x12, 0x97, 0xaa, 0xbd, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_PINTOKEN \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0x14, 0x00, \ + 0xa1, 0x02, 0x50, 0xee, 0x40, 0x4c, 0x85, 0xd7, \ + 0xa1, 0x2f, 0x56, 0xc4, 0x4e, 0xc5, 0x93, 0x41, \ + 0xd0, 0x3b, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_STATUS \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0x01, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_RETRIES \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0x04, 0x00, \ + 0xa1, 0x03, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_ASSERT \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0xcb, 0x00, \ + 0xa3, 0x01, 0xa2, 0x62, 0x69, 0x64, 0x58, 0x40, \ + 0x4a, 0x4c, 0x9e, 0xcc, 0x81, 0x7d, 0x42, 0x03, \ + 0x2b, 0x41, 0xd1, 0x38, 0xd3, 0x49, 0xb4, 0xfc, \ + 0xfb, 0xe4, 0x4e, 0xe4, 0xff, 0x76, 0x34, 0x16, \ + 0x68, 0x06, 0x9d, 0xa6, 0x01, 0x32, 0xb9, 0xff, \ + 0xc2, 0x35, 0x0d, 0x89, 0x43, 0x66, 0x12, 0xf8, \ + 0x8e, 0x5b, 0xde, 0xf4, 0xcc, 0xec, 0x9d, 0x03, \ + 0x00, 0x92, 0x00, 0x0e, 0x00, 0x85, 0xc2, 0xf5, \ + 0xe6, 0x8e, 0xeb, 0x3f, 0x3a, 0xec, 0xc3, 0x1d, \ + 0x04, 0x6e, 0xf3, 0x5b, 0x88, 0x64, 0x74, 0x79, \ + 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, 0x6c, 0x69, \ + 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x02, 0x58, 0x25, \ + 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, 0x8c, 0x68, \ + 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, 0x60, 0x5b, \ + 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, 0x32, 0xc7, \ + 0x00, 0x92, 0x00, 0x0e, 0x01, 0x99, 0x5c, 0xf3, \ + 0xba, 0x83, 0x1d, 0x97, 0x63, 0x04, 0x00, 0x00, \ + 0x00, 0x09, 0x03, 0x58, 0x47, 0x30, 0x45, 0x02, \ + 0x21, 0x00, 0xcf, 0x3f, 0x36, 0x0e, 0x1f, 0x6f, \ + 0xd6, 0xa0, 0x9d, 0x13, 0xcf, 0x55, 0xf7, 0x49, \ + 0x8f, 0xc8, 0xc9, 0x03, 0x12, 0x76, 0x41, 0x75, \ + 0x7b, 0xb5, 0x0a, 0x90, 0xa5, 0x82, 0x26, 0xf1, \ + 0x6b, 0x80, 0x02, 0x20, 0x34, 0x9b, 0x7a, 0x82, \ + 0x00, 0x92, 0x00, 0x0e, 0x02, 0xd3, 0xe1, 0x79, \ + 0x49, 0x55, 0x41, 0x9f, 0xa4, 0x06, 0x06, 0xbd, \ + 0xc8, 0xb9, 0x2b, 0x5f, 0xe1, 0xa7, 0x99, 0x1c, \ + 0xa1, 0xfc, 0x7e, 0x3e, 0xd5, 0x85, 0x2e, 0x11, \ + 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_CRED \ + 0x00, 0x91, 0x00, 0x03, 0x90, 0x03, 0xe1, 0x00, \ + 0xa3, 0x01, 0x66, 0x70, 0x61, 0x63, 0x6b, 0x65, \ + 0x64, 0x02, 0x58, 0xc4, 0x49, 0x96, 0x0d, 0xe5, \ + 0x88, 0x0e, 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, \ + 0x64, 0x76, 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, \ + 0xa2, 0x86, 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, \ + 0x83, 0x1d, 0x97, 0x63, 0x45, 0x00, 0x00, 0x00, \ + 0x00, 0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, \ + 0x00, 0x91, 0x00, 0x03, 0x00, 0x15, 0x80, 0x06, \ + 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x00, 0x40, \ + 0xed, 0x88, 0x48, 0xa1, 0xdb, 0x56, 0x4d, 0x0f, \ + 0x0d, 0xc8, 0x8f, 0x0f, 0xe9, 0x16, 0xb1, 0x78, \ + 0xa9, 0x40, 0x98, 0x71, 0xa0, 0xb3, 0xf2, 0xcf, \ + 0x05, 0x73, 0x6c, 0x12, 0xbf, 0x00, 0x96, 0xf3, \ + 0x7b, 0x93, 0xba, 0x49, 0xee, 0x23, 0xb4, 0x78, \ + 0x2e, 0xfb, 0xce, 0x27, 0xa8, 0xc2, 0x26, 0x78, \ + 0x00, 0x91, 0x00, 0x03, 0x01, 0xcc, 0x95, 0x2d, \ + 0x40, 0xdb, 0xd1, 0x40, 0x3d, 0x2b, 0xa3, 0x31, \ + 0xa0, 0x75, 0x82, 0x63, 0xf0, 0xa5, 0x01, 0x02, \ + 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0x9d, \ + 0x95, 0xa1, 0xb5, 0xd6, 0x11, 0xbf, 0xe2, 0x28, \ + 0xa0, 0x7f, 0xca, 0x1e, 0xd9, 0x09, 0x0f, 0x0d, \ + 0xe7, 0x8e, 0x29, 0xe8, 0x2e, 0x11, 0xdb, 0x55, \ + 0x62, 0x13, 0xd7, 0x26, 0xc2, 0x7e, 0x2b, 0x22, \ + 0x00, 0x91, 0x00, 0x03, 0x02, 0x58, 0x20, 0xbe, \ + 0x74, 0x2a, 0xac, 0xde, 0x11, 0x40, 0x76, 0x31, \ + 0x0b, 0xed, 0x55, 0xde, 0xf3, 0x03, 0xe4, 0x1c, \ + 0xac, 0x42, 0x63, 0x8f, 0xe8, 0x30, 0x63, 0xb7, \ + 0x07, 0x4e, 0x5d, 0xfb, 0x17, 0x5e, 0x9b, 0x03, \ + 0xa3, 0x63, 0x61, 0x6c, 0x67, 0x26, 0x63, 0x73, \ + 0x69, 0x67, 0x58, 0x48, 0x30, 0x46, 0x02, 0x21, \ + 0x00, 0xfb, 0xd1, 0x26, 0x76, 0x34, 0x74, 0xac, \ + 0x00, 0x91, 0x00, 0x03, 0x03, 0xf6, 0xd8, 0x5c, \ + 0x5d, 0xbc, 0xda, 0xe0, 0x43, 0xe0, 0xa5, 0x42, \ + 0x9f, 0xc7, 0xe2, 0x18, 0x3e, 0xe2, 0x2c, 0x94, \ + 0x78, 0xbf, 0x9c, 0xeb, 0x3e, 0x9d, 0x02, 0x21, \ + 0x00, 0xab, 0x21, 0x1b, 0xc4, 0x30, 0x69, 0xee, \ + 0x7f, 0x09, 0xe6, 0x6b, 0x99, 0x98, 0x34, 0x07, \ + 0x7b, 0x9a, 0x58, 0xb2, 0xe8, 0x77, 0xe0, 0xba, \ + 0x7d, 0xab, 0x65, 0xf8, 0xba, 0x2a, 0xcb, 0x9a, \ + 0x00, 0x91, 0x00, 0x03, 0x04, 0x41, 0x63, 0x78, \ + 0x35, 0x63, 0x81, 0x59, 0x02, 0xb3, 0x30, 0x82, \ + 0x02, 0xaf, 0x30, 0x82, 0x01, 0x97, 0xa0, 0x03, \ + 0x02, 0x01, 0x02, 0x02, 0x04, 0x48, 0x5b, 0x3d, \ + 0xb6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, \ + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, \ + 0x30, 0x21, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, \ + 0x55, 0x04, 0x03, 0x0c, 0x16, 0x59, 0x75, 0x62, \ + 0x00, 0x91, 0x00, 0x03, 0x05, 0x69, 0x63, 0x6f, \ + 0x20, 0x46, 0x49, 0x44, 0x4f, 0x20, 0x50, 0x72, \ + 0x65, 0x76, 0x69, 0x65, 0x77, 0x20, 0x43, 0x41, \ + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x34, \ + 0x31, 0x32, 0x31, 0x30, 0x35, 0x37, 0x31, 0x30, \ + 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x31, 0x32, 0x33, \ + 0x31, 0x31, 0x30, 0x35, 0x37, 0x31, 0x30, 0x5a, \ + 0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ + 0x00, 0x91, 0x00, 0x03, 0x06, 0x55, 0x04, 0x06, \ + 0x13, 0x02, 0x53, 0x45, 0x31, 0x12, 0x30, 0x10, \ + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x59, \ + 0x75, 0x62, 0x69, 0x63, 0x6f, 0x20, 0x41, 0x42, \ + 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, \ + 0x0b, 0x0c, 0x19, 0x41, 0x75, 0x74, 0x68, 0x65, \ + 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, \ + 0x20, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, \ + 0x00, 0x91, 0x00, 0x03, 0x07, 0x74, 0x69, 0x6f, \ + 0x6e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, \ + 0x04, 0x03, 0x0c, 0x1f, 0x59, 0x75, 0x62, 0x69, \ + 0x63, 0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x45, \ + 0x45, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, \ + 0x20, 0x31, 0x32, 0x31, 0x33, 0x39, 0x33, 0x39, \ + 0x31, 0x32, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, \ + 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, \ + 0x00, 0x91, 0x00, 0x03, 0x08, 0x06, 0x08, 0x2a, \ + 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, \ + 0x42, 0x00, 0x04, 0xfb, 0x2c, 0xdd, 0x30, 0x43, \ + 0x28, 0xc5, 0x72, 0x4a, 0x50, 0xcc, 0xe6, 0xf6, \ + 0x0b, 0xad, 0x7d, 0x27, 0xa9, 0x1b, 0x59, 0xe1, \ + 0xe6, 0x6f, 0x29, 0x7b, 0x89, 0xc9, 0xd4, 0x3d, \ + 0xc2, 0xb2, 0xc7, 0x78, 0x89, 0xb4, 0xf0, 0xff, \ + 0x9d, 0x02, 0x28, 0xcb, 0x94, 0x6d, 0xfc, 0xe0, \ + 0x00, 0x91, 0x00, 0x03, 0x09, 0x1b, 0x19, 0x58, \ + 0x9b, 0x67, 0x80, 0x4a, 0xac, 0x97, 0x7f, 0x28, \ + 0x18, 0x9c, 0xcd, 0xb3, 0x25, 0x74, 0xca, 0x28, \ + 0xa3, 0x6c, 0x30, 0x6a, 0x30, 0x22, 0x06, 0x09, \ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xc4, 0x0a, \ + 0x02, 0x04, 0x15, 0x31, 0x2e, 0x33, 0x2e, 0x36, \ + 0x2e, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e, 0x34, \ + 0x31, 0x34, 0x38, 0x32, 0x2e, 0x31, 0x2e, 0x36, \ + 0x00, 0x91, 0x00, 0x03, 0x0a, 0x30, 0x13, 0x06, \ + 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xe5, \ + 0x1c, 0x02, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, \ + 0x04, 0x30, 0x30, 0x21, 0x06, 0x0b, 0x2b, 0x06, \ + 0x01, 0x04, 0x01, 0x82, 0xe5, 0x1c, 0x01, 0x01, \ + 0x04, 0x04, 0x12, 0x04, 0x10, 0xf8, 0xa0, 0x11, \ + 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, \ + 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x30, 0x0c, 0x06, \ + 0x00, 0x91, 0x00, 0x03, 0x0b, 0x03, 0x55, 0x1d, \ + 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, \ + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, \ + 0x82, 0x01, 0x01, 0x00, 0x32, 0xf3, 0xe4, 0xbd, \ + 0x58, 0xd7, 0x42, 0x2b, 0xaf, 0x49, 0x99, 0x86, \ + 0x08, 0x1f, 0x0d, 0xa9, 0x3b, 0xc6, 0xaa, 0x1c, \ + 0x72, 0x11, 0xf9, 0x28, 0x53, 0xeb, 0xf3, 0xeb, \ + 0x00, 0x91, 0x00, 0x03, 0x0c, 0x73, 0xda, 0x69, \ + 0x3b, 0x06, 0xde, 0x31, 0x33, 0x8e, 0x5d, 0x02, \ + 0xec, 0xf6, 0x76, 0xe9, 0x5c, 0x42, 0xbe, 0xa5, \ + 0x8f, 0x25, 0xd3, 0x37, 0x3f, 0x77, 0xbb, 0x2a, \ + 0x9d, 0x7c, 0xb2, 0x3e, 0x11, 0x8c, 0x41, 0xd4, \ + 0x9a, 0x4c, 0x9a, 0xd8, 0xf3, 0xe2, 0xa4, 0xec, \ + 0x01, 0x77, 0x7a, 0x74, 0xa8, 0xc4, 0x12, 0x43, \ + 0xc3, 0x1e, 0xce, 0x20, 0x8f, 0x2d, 0x0f, 0x6e, \ + 0x00, 0x91, 0x00, 0x03, 0x0d, 0xbc, 0x61, 0x9b, \ + 0xe1, 0x84, 0xa1, 0x72, 0xf6, 0xa9, 0xac, 0xcb, \ + 0xf8, 0x73, 0x6d, 0x5b, 0xe2, 0x98, 0xb3, 0x6b, \ + 0xec, 0xe7, 0x1e, 0x77, 0x8d, 0x0a, 0x69, 0xaa, \ + 0xf9, 0x94, 0xb8, 0x63, 0x6d, 0xe8, 0xfa, 0xf6, \ + 0x2f, 0xd3, 0xce, 0x7f, 0x04, 0x4c, 0x32, 0x2c, \ + 0xf7, 0x26, 0x3e, 0x34, 0x99, 0xe6, 0xa5, 0xb2, \ + 0xb0, 0x2a, 0xbb, 0xad, 0x5b, 0xd9, 0xec, 0xe5, \ + 0x00, 0x91, 0x00, 0x03, 0x0e, 0xb0, 0x71, 0x4d, \ + 0x73, 0xbb, 0x94, 0x61, 0x49, 0x9c, 0x94, 0x2a, \ + 0x5f, 0x1d, 0xcc, 0xaf, 0x65, 0x03, 0x3b, 0x39, \ + 0x39, 0xd4, 0x47, 0xd9, 0xfc, 0xc4, 0x7b, 0x0b, \ + 0x16, 0xd8, 0xe9, 0x01, 0xfc, 0xec, 0x3f, 0x8c, \ + 0x1b, 0xc0, 0xc6, 0xac, 0x0b, 0x5d, 0x74, 0xc7, \ + 0xbb, 0x03, 0x05, 0x69, 0x17, 0xe9, 0x98, 0x1a, \ + 0x19, 0xb9, 0x09, 0x5c, 0xa1, 0xf4, 0xab, 0x9f, \ + 0x00, 0x91, 0x00, 0x03, 0x0f, 0x02, 0x7c, 0x28, \ + 0x0f, 0x8a, 0xf9, 0xed, 0x1d, 0x29, 0x3c, 0xf6, \ + 0xcc, 0x2f, 0x04, 0x6d, 0x9a, 0xd6, 0x62, 0xb4, \ + 0xa9, 0x6e, 0xb1, 0xca, 0xca, 0xac, 0x5e, 0x05, \ + 0x3e, 0x83, 0x91, 0x47, 0x7c, 0x1f, 0x8b, 0x60, \ + 0x01, 0xde, 0x65, 0x3a, 0xbf, 0xf2, 0xaa, 0xbb, \ + 0x55, 0x98, 0x86, 0x91, 0x7e, 0xad, 0x3b, 0x36, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_CREDMAN_META \ + 0x00, 0x12, 0x00, 0x04, 0x90, 0x00, 0x07, 0x00, \ + 0xa2, 0x01, 0x00, 0x02, 0x18, 0x19, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_CREDMAN_RPLIST \ + 0x00, 0x15, 0x00, 0x02, 0x90, 0x00, 0x37, 0x00, \ + 0xa3, 0x03, 0xa1, 0x62, 0x69, 0x64, 0x6a, 0x79, \ + 0x75, 0x62, 0x69, 0x63, 0x6f, 0x2e, 0x63, 0x6f, \ + 0x6d, 0x04, 0x58, 0x20, 0x37, 0x82, 0x09, 0xb7, \ + 0x2d, 0xef, 0xcb, 0xa9, 0x1d, 0xcb, 0xf8, 0x54, \ + 0xed, 0xb4, 0xda, 0xa6, 0x48, 0x82, 0x8a, 0x2c, \ + 0xbd, 0x18, 0x0a, 0xfc, 0x77, 0xa7, 0x44, 0x34, \ + 0x65, 0x5a, 0x1c, 0x7d, 0x05, 0x03, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x02, 0x90, 0x00, 0x36, 0x00, \ + 0xa2, 0x03, 0xa1, 0x62, 0x69, 0x64, 0x6b, 0x79, \ + 0x75, 0x62, 0x69, 0x6b, 0x65, 0x79, 0x2e, 0x6f, \ + 0x72, 0x67, 0x04, 0x58, 0x20, 0x12, 0x6b, 0xba, \ + 0x6a, 0x2d, 0x7a, 0x81, 0x84, 0x25, 0x7b, 0x74, \ + 0xdd, 0x1d, 0xdd, 0x46, 0xb6, 0x2a, 0x8c, 0xa2, \ + 0xa7, 0x83, 0xfe, 0xdb, 0x5b, 0x19, 0x48, 0x73, \ + 0x55, 0xb7, 0xe3, 0x46, 0x09, 0x00, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x02, 0x90, 0x00, 0x37, 0x00, \ + 0xa2, 0x03, 0xa1, 0x62, 0x69, 0x64, 0x6c, 0x77, \ + 0x65, 0x62, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x2e, \ + 0x64, 0x65, 0x76, 0x04, 0x58, 0x20, 0xd6, 0x32, \ + 0x7d, 0x8c, 0x6a, 0x5d, 0xe6, 0xae, 0x0e, 0x33, \ + 0xd0, 0xa3, 0x31, 0xfb, 0x67, 0x77, 0xb9, 0x4e, \ + 0xf4, 0x73, 0x19, 0xfe, 0x7e, 0xfd, 0xfa, 0x82, \ + 0x70, 0x8e, 0x1f, 0xbb, 0xa2, 0x55, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_CREDMAN_RKLIST \ + 0x00, 0x15, 0x00, 0x04, 0x90, 0x00, 0xc5, 0x00, \ + 0xa5, 0x06, 0xa3, 0x62, 0x69, 0x64, 0x58, 0x20, \ + 0xe4, 0xe1, 0x06, 0x31, 0xde, 0x00, 0x0f, 0x4f, \ + 0x12, 0x6e, 0xc9, 0x68, 0x2d, 0x43, 0x3f, 0xf1, \ + 0x02, 0x2c, 0x6e, 0xe6, 0x96, 0x10, 0xbf, 0x73, \ + 0x35, 0xc9, 0x20, 0x27, 0x06, 0xba, 0x39, 0x09, \ + 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x6a, 0x62, 0x6f, \ + 0x62, 0x20, 0x62, 0x61, 0x6e, 0x61, 0x6e, 0x61, \ + 0x00, 0x15, 0x00, 0x04, 0x00, 0x6b, 0x64, 0x69, \ + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, \ + 0x65, 0x67, 0x62, 0x62, 0x61, 0x6e, 0x61, 0x6e, \ + 0x61, 0x07, 0xa2, 0x62, 0x69, 0x64, 0x50, 0x19, \ + 0xf7, 0x78, 0x0c, 0xa0, 0xbc, 0xb9, 0xa6, 0xd5, \ + 0x1e, 0xd7, 0x87, 0xfb, 0x6c, 0x80, 0x03, 0x64, \ + 0x74, 0x79, 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x08, \ + 0x00, 0x15, 0x00, 0x04, 0x01, 0xa5, 0x01, 0x02, \ + 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0x81, \ + 0x6c, 0xdd, 0x8c, 0x8f, 0x8c, 0xc8, 0x43, 0xa7, \ + 0xbb, 0x79, 0x51, 0x09, 0xb1, 0xdf, 0xbe, 0xc4, \ + 0xa5, 0x54, 0x16, 0x9e, 0x58, 0x56, 0xb3, 0x0b, \ + 0x34, 0x4f, 0xa5, 0x6c, 0x05, 0xa2, 0x21, 0x22, \ + 0x58, 0x20, 0xcd, 0xc2, 0x0c, 0x99, 0x83, 0x5a, \ + 0x61, 0x73, 0xd8, 0xe0, 0x74, 0x23, 0x46, 0x64, \ + 0x00, 0x15, 0x00, 0x04, 0x02, 0x39, 0x4c, 0xb0, \ + 0xf4, 0x6c, 0x0a, 0x37, 0x72, 0xaa, 0xa8, 0xea, \ + 0x58, 0xd3, 0xd4, 0xe0, 0x51, 0xb2, 0x28, 0x09, \ + 0x05, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x04, 0x90, 0x00, 0xa0, 0x00, \ + 0xa4, 0x06, 0xa3, 0x62, 0x69, 0x64, 0x58, 0x20, \ + 0x56, 0xa1, 0x3c, 0x06, 0x2b, 0xad, 0xa2, 0x21, \ + 0x7d, 0xcd, 0x91, 0x08, 0x47, 0xa8, 0x8a, 0x06, \ + 0x06, 0xf6, 0x66, 0x91, 0xf6, 0xeb, 0x89, 0xe4, \ + 0xdf, 0x26, 0xbc, 0x46, 0x59, 0xc3, 0x7d, 0xc0, \ + 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x6a, 0x62, 0x6f, \ + 0x62, 0x20, 0x62, 0x61, 0x6e, 0x61, 0x6e, 0x61, \ + 0x00, 0x15, 0x00, 0x04, 0x00, 0x6b, 0x64, 0x69, \ + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, \ + 0x65, 0x67, 0x62, 0x62, 0x61, 0x6e, 0x61, 0x6e, \ + 0x61, 0x07, 0xa2, 0x62, 0x69, 0x64, 0x50, 0xd8, \ + 0x27, 0x4b, 0x25, 0xed, 0x19, 0xef, 0x11, 0xaf, \ + 0xa6, 0x89, 0x7b, 0x84, 0x50, 0xe7, 0x62, 0x64, \ + 0x74, 0x79, 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x08, \ + 0x00, 0x15, 0x00, 0x04, 0x01, 0xa4, 0x01, 0x01, \ + 0x03, 0x27, 0x20, 0x06, 0x21, 0x58, 0x20, 0x8d, \ + 0xfe, 0x45, 0xd5, 0x7d, 0xb6, 0x17, 0xab, 0x86, \ + 0x2d, 0x32, 0xf6, 0x85, 0xf0, 0x92, 0x76, 0xb7, \ + 0xce, 0x73, 0xca, 0x4e, 0x0e, 0xfd, 0xd5, 0xdb, \ + 0x2a, 0x1d, 0x55, 0x90, 0x96, 0x52, 0xc2, 0x0a, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x04, 0x90, 0x00, 0xa0, 0x00, \ + 0xa4, 0x06, 0xa3, 0x62, 0x69, 0x64, 0x58, 0x20, \ + 0x04, 0x0e, 0x0f, 0xa0, 0xcd, 0x60, 0x35, 0x9a, \ + 0xba, 0x47, 0x0c, 0x10, 0xb6, 0x82, 0x6e, 0x2f, \ + 0x66, 0xb9, 0xa7, 0xcf, 0xd8, 0x47, 0xb4, 0x3d, \ + 0xfd, 0x77, 0x1a, 0x38, 0x22, 0xa1, 0xda, 0xa5, \ + 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x6a, 0x62, 0x6f, \ + 0x62, 0x20, 0x62, 0x61, 0x6e, 0x61, 0x6e, 0x61, \ + 0x00, 0x15, 0x00, 0x04, 0x00, 0x6b, 0x64, 0x69, \ + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, \ + 0x65, 0x67, 0x62, 0x62, 0x61, 0x6e, 0x61, 0x6e, \ + 0x61, 0x07, 0xa2, 0x62, 0x69, 0x64, 0x50, 0x00, \ + 0x5d, 0xdf, 0xef, 0xe2, 0xf3, 0x06, 0xb2, 0xa5, \ + 0x46, 0x4d, 0x98, 0xbc, 0x14, 0x65, 0xc1, 0x64, \ + 0x74, 0x79, 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x08, \ + 0x00, 0x15, 0x00, 0x04, 0x01, 0xa4, 0x01, 0x01, \ + 0x03, 0x27, 0x20, 0x06, 0x21, 0x58, 0x20, 0x72, \ + 0x79, 0x14, 0x69, 0xdf, 0xcb, 0x64, 0x75, 0xee, \ + 0xd4, 0x45, 0x94, 0xbc, 0x48, 0x4d, 0x2a, 0x9f, \ + 0xc9, 0xf4, 0xb5, 0x1b, 0x05, 0xa6, 0x5b, 0x54, \ + 0x9a, 0xac, 0x6c, 0x2e, 0xc6, 0x90, 0x62, 0x0a, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x04, 0x90, 0x00, 0xc3, 0x00, \ + 0xa4, 0x06, 0xa3, 0x62, 0x69, 0x64, 0x58, 0x20, \ + 0xce, 0x32, 0xd8, 0x79, 0xdd, 0x86, 0xa2, 0x42, \ + 0x7c, 0xc3, 0xe1, 0x95, 0x12, 0x93, 0x1a, 0x03, \ + 0xe6, 0x70, 0xb8, 0xff, 0xcd, 0xa5, 0xdf, 0x15, \ + 0xfc, 0x88, 0x2a, 0xf5, 0x44, 0xf1, 0x33, 0x9c, \ + 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x6a, 0x62, 0x6f, \ + 0x62, 0x20, 0x62, 0x61, 0x6e, 0x61, 0x6e, 0x61, \ + 0x00, 0x15, 0x00, 0x04, 0x00, 0x6b, 0x64, 0x69, \ + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, \ + 0x65, 0x67, 0x62, 0x62, 0x61, 0x6e, 0x61, 0x6e, \ + 0x61, 0x07, 0xa2, 0x62, 0x69, 0x64, 0x50, 0x0a, \ + 0x26, 0x5b, 0x7e, 0x1a, 0x2a, 0xba, 0x70, 0x5f, \ + 0x18, 0x26, 0x14, 0xb2, 0x71, 0xca, 0x98, 0x64, \ + 0x74, 0x79, 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x08, \ + 0x00, 0x15, 0x00, 0x04, 0x01, 0xa5, 0x01, 0x02, \ + 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0x8b, \ + 0x48, 0xf0, 0x69, 0xfb, 0x22, 0xfb, 0xf3, 0x86, \ + 0x57, 0x7c, 0xdd, 0x82, 0x2c, 0x1c, 0x0c, 0xdc, \ + 0x27, 0xe2, 0x6a, 0x4c, 0x1a, 0x10, 0x04, 0x27, \ + 0x51, 0x3e, 0x2a, 0x9d, 0x3a, 0xb6, 0xb5, 0x22, \ + 0x58, 0x20, 0x70, 0xfe, 0x91, 0x67, 0x64, 0x53, \ + 0x63, 0x83, 0x72, 0x31, 0xe9, 0xe5, 0x20, 0xb7, \ + 0x00, 0x15, 0x00, 0x04, 0x02, 0xee, 0xc9, 0xfb, \ + 0x63, 0xd7, 0xe4, 0x76, 0x39, 0x80, 0x82, 0x74, \ + 0xb8, 0xfa, 0x67, 0xf5, 0x1b, 0x8f, 0xe0, 0x0a, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x04, 0x90, 0x00, 0xc3, 0x00, \ + 0xa4, 0x06, 0xa3, 0x62, 0x69, 0x64, 0x58, 0x20, \ + 0xf9, 0xa3, 0x67, 0xbf, 0x5e, 0x80, 0x95, 0xdb, \ + 0x4c, 0xc5, 0x8f, 0x65, 0x36, 0xc5, 0xaf, 0xdd, \ + 0x90, 0x2e, 0x62, 0x68, 0x67, 0x9c, 0xa2, 0x26, \ + 0x2f, 0x2a, 0xf9, 0x3a, 0xda, 0x15, 0xf2, 0x27, \ + 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x6a, 0x62, 0x6f, \ + 0x62, 0x20, 0x62, 0x61, 0x6e, 0x61, 0x6e, 0x61, \ + 0x00, 0x15, 0x00, 0x04, 0x00, 0x6b, 0x64, 0x69, \ + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, \ + 0x65, 0x67, 0x62, 0x62, 0x61, 0x6e, 0x61, 0x6e, \ + 0x61, 0x07, 0xa2, 0x62, 0x69, 0x64, 0x50, 0xfb, \ + 0xa6, 0xbe, 0xc1, 0x01, 0xf6, 0x7a, 0x81, 0xf9, \ + 0xcd, 0x6d, 0x20, 0x41, 0x7a, 0x1c, 0x40, 0x64, \ + 0x74, 0x79, 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x08, \ + 0x00, 0x15, 0x00, 0x04, 0x01, 0xa5, 0x01, 0x02, \ + 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0xda, \ + 0x2b, 0x53, 0xc3, 0xbe, 0x48, 0xf8, 0xab, 0xbd, \ + 0x06, 0x28, 0x46, 0xfa, 0x35, 0xab, 0xf9, 0xc5, \ + 0x2e, 0xfd, 0x3c, 0x38, 0x88, 0xb3, 0xe1, 0xa7, \ + 0xc5, 0xc6, 0xed, 0x72, 0x54, 0x37, 0x93, 0x22, \ + 0x58, 0x20, 0x12, 0x82, 0x32, 0x2d, 0xab, 0xbc, \ + 0x64, 0xb3, 0xed, 0xcc, 0xd5, 0x22, 0xec, 0x79, \ + 0x00, 0x15, 0x00, 0x04, 0x02, 0x4b, 0xe2, 0x4d, \ + 0x0c, 0x4b, 0x8d, 0x31, 0x4c, 0xb4, 0x0f, 0xd4, \ + 0xa9, 0xbe, 0x0c, 0xab, 0x9e, 0x0a, 0xc9, 0x0a, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_BIO_INFO \ + 0x00, 0x10, 0x00, 0x04, 0x90, 0x00, 0x06, 0x00, \ + 0xa2, 0x02, 0x01, 0x03, 0x04, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_BIO_ENROLL \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0x90, 0x00, 0x0a, 0x00, \ + 0xa3, 0x04, 0x42, 0x68, 0x96, 0x05, 0x00, 0x06, \ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0x90, 0x00, 0x06, 0x00, \ + 0xa2, 0x05, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0x90, 0x00, 0x06, 0x00, \ + 0xa2, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_BIO_ENUM \ + 0x00, 0x10, 0x00, 0x0f, 0x90, 0x00, 0x2e, 0x00, \ + 0xa1, 0x07, 0x83, 0xa2, 0x01, 0x42, 0xce, 0xa3, \ + 0x02, 0x67, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, \ + 0x31, 0xa2, 0x01, 0x42, 0xbf, 0x5e, 0x02, 0x67, \ + 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x32, 0xa2, \ + 0x01, 0x42, 0x5e, 0xd2, 0x02, 0x67, 0x66, 0x69, \ + 0x6e, 0x67, 0x65, 0x72, 0x33, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY \ + 0x89, 0xc9, 0x8d, 0x28, 0x90, 0x01, 0xe6, 0x00, \ + 0xa1, 0x01, 0x59, 0x01, 0xe0, 0x81, 0xa3, 0x01, \ + 0x59, 0x01, 0xb8, 0xb3, 0x26, 0x24, 0x99, 0xde, \ + 0x06, 0x3f, 0xca, 0xde, 0x98, 0x8d, 0x9d, 0xc5, \ + 0x3f, 0x26, 0x6c, 0xc7, 0x40, 0x93, 0xc4, 0x88, \ + 0x06, 0x51, 0x4f, 0xb9, 0x61, 0xf2, 0xc9, 0x8d, \ + 0xbc, 0xce, 0x79, 0x08, 0xec, 0x90, 0xc5, 0x5b, \ + 0xe5, 0x0a, 0x72, 0x08, 0x7b, 0xe1, 0xf9, 0x16, \ + 0x89, 0xc9, 0x8d, 0x28, 0x00, 0x06, 0x8b, 0x76, \ + 0x32, 0xa0, 0xae, 0x55, 0xb2, 0x39, 0x71, 0xce, \ + 0x34, 0x4b, 0x6e, 0x6b, 0x89, 0xa6, 0x5e, 0x69, \ + 0x07, 0xac, 0xf6, 0x01, 0x3c, 0xba, 0x45, 0x7a, \ + 0x75, 0x25, 0x3a, 0xbd, 0x95, 0x22, 0x9d, 0xc3, \ + 0xe4, 0x42, 0x31, 0x5c, 0xb5, 0xf4, 0x64, 0x6a, \ + 0x56, 0x1d, 0xab, 0xc7, 0x6e, 0x96, 0x75, 0xe7, \ + 0xb3, 0x22, 0x0b, 0x82, 0xac, 0x57, 0x78, 0xdf, \ + 0x89, 0xc9, 0x8d, 0x28, 0x01, 0x57, 0x06, 0xc5, \ + 0x4b, 0x61, 0x0b, 0x4d, 0xa1, 0x66, 0xa0, 0x89, \ + 0xad, 0x19, 0x8f, 0xd8, 0x96, 0x55, 0x22, 0x5f, \ + 0xca, 0x2e, 0xc1, 0xd7, 0xbd, 0xa1, 0x83, 0x66, \ + 0x4d, 0x85, 0xcb, 0x01, 0x60, 0x3f, 0xf7, 0xf7, \ + 0xa3, 0x7a, 0xfa, 0x99, 0xa0, 0x1e, 0x25, 0x90, \ + 0xd0, 0xd0, 0x3b, 0x54, 0x90, 0x77, 0x94, 0xa6, \ + 0x88, 0xea, 0xc3, 0x6b, 0xa0, 0x59, 0x5e, 0x69, \ + 0x89, 0xc9, 0x8d, 0x28, 0x02, 0x78, 0x0b, 0x2b, \ + 0xab, 0x5b, 0x04, 0x2f, 0x78, 0x15, 0x86, 0x2b, \ + 0x0f, 0x63, 0xb2, 0xd7, 0xc9, 0xe9, 0xac, 0x0e, \ + 0xbc, 0x17, 0xe4, 0x19, 0x88, 0xe0, 0xe6, 0x13, \ + 0xf8, 0x15, 0x08, 0xa7, 0xe1, 0x6e, 0x71, 0x5c, \ + 0xef, 0x3e, 0xc1, 0x0f, 0x74, 0xdb, 0xdc, 0x52, \ + 0x9c, 0xfc, 0xe9, 0xa9, 0xf3, 0x0d, 0x52, 0xbc, \ + 0x0c, 0xe8, 0xba, 0xd1, 0x76, 0x46, 0x87, 0xb5, \ + 0x89, 0xc9, 0x8d, 0x28, 0x03, 0x30, 0xe6, 0x9d, \ + 0xa1, 0x2b, 0xa5, 0x9e, 0x3b, 0x86, 0xb3, 0x5f, \ + 0xe3, 0x81, 0xa6, 0x76, 0x32, 0x9d, 0xf9, 0xc5, \ + 0x07, 0x93, 0xb3, 0xdf, 0x64, 0xe2, 0x78, 0x9c, \ + 0x00, 0xc7, 0x86, 0x79, 0xd6, 0x67, 0xa2, 0xfb, \ + 0xf2, 0x8d, 0xea, 0xe9, 0xc8, 0xfc, 0x43, 0xd2, \ + 0x0f, 0x2f, 0x7d, 0x9d, 0xd3, 0x8f, 0x9c, 0xdd, \ + 0xa2, 0x9f, 0x42, 0x76, 0x40, 0xcc, 0x4a, 0xd0, \ + 0x89, 0xc9, 0x8d, 0x28, 0x04, 0xb4, 0x87, 0x18, \ + 0x06, 0xc3, 0xc7, 0x89, 0x98, 0x72, 0xcc, 0x1a, \ + 0xd1, 0xd8, 0x78, 0xb9, 0x75, 0x0b, 0x92, 0xe3, \ + 0xcc, 0xed, 0x38, 0x39, 0x4b, 0xa9, 0xcf, 0x30, \ + 0xd6, 0xb5, 0xa1, 0x3f, 0xfa, 0x4f, 0x29, 0x99, \ + 0xa9, 0x03, 0x77, 0xf6, 0x53, 0xfa, 0xd8, 0x32, \ + 0xce, 0xf4, 0xf6, 0x0a, 0x3c, 0xe8, 0x9c, 0x3d, \ + 0xaa, 0xe0, 0x7b, 0x2c, 0xa5, 0x28, 0xe1, 0xdd, \ + 0x89, 0xc9, 0x8d, 0x28, 0x05, 0x51, 0xbf, 0xe1, \ + 0xd4, 0xf5, 0x5e, 0x38, 0x2c, 0xec, 0xab, 0xdd, \ + 0xb8, 0x5c, 0x13, 0x43, 0x62, 0xc2, 0xb6, 0x02, \ + 0x18, 0xce, 0x9a, 0x62, 0x67, 0x6a, 0xeb, 0x99, \ + 0xf6, 0x2f, 0xf1, 0xf1, 0xec, 0x3e, 0x74, 0xfa, \ + 0xf8, 0x16, 0x43, 0xea, 0x1e, 0xef, 0x5d, 0x37, \ + 0x6c, 0x13, 0xf9, 0x7f, 0x65, 0x09, 0xab, 0x60, \ + 0x38, 0xda, 0x0f, 0xe7, 0xfa, 0x9e, 0x17, 0x10, \ + 0x89, 0xc9, 0x8d, 0x28, 0x06, 0xdc, 0x4c, 0x4d, \ + 0xae, 0x5c, 0xb4, 0x0d, 0x6b, 0x05, 0x6d, 0x25, \ + 0x3f, 0x78, 0x5d, 0xf3, 0x34, 0x33, 0xa4, 0x89, \ + 0x34, 0x0e, 0x88, 0x66, 0x40, 0x57, 0x6b, 0x34, \ + 0x83, 0xfd, 0x39, 0xe7, 0xfb, 0x84, 0x09, 0xb3, \ + 0x16, 0x8f, 0x80, 0xdf, 0x1b, 0xe0, 0x02, 0x4c, \ + 0xde, 0x31, 0x2a, 0x32, 0x58, 0x5b, 0xa3, 0x23, \ + 0x8e, 0x2a, 0xa6, 0xaf, 0x03, 0x19, 0x02, 0x7a, \ + 0x89, 0xc9, 0x8d, 0x28, 0x07, 0xf8, 0xbf, 0xa6, \ + 0xad, 0xf9, 0xd1, 0xdc, 0xbd, 0x6e, 0xb3, 0xc1, \ + 0xfb, 0x65, 0xd8, 0x5f, 0x2e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_NFC_INIT \ + 0x55, 0x32, 0x46, 0x5f, 0x56, 0x32, 0x90, 0x00 + +#define WIREDATA_CTAP_NFC_MSG \ + 0x90, 0x00, 0x90, 0x00, 0x90, 0x00, 0x90, 0x00 + +#define WIREDATA_CTAP_EXTENDED_APDU \ + 0x00, 0xa4, 0x04, 0x00, 0x00, 0x02, 0x00, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, \ + 0x00 + +#endif /* _WIREDATA_FIDO2_H */ diff --git a/fuzz/wiredata_u2f.h b/fuzz/wiredata_u2f.h new file mode 100644 index 0000000..3be22d3 --- /dev/null +++ b/fuzz/wiredata_u2f.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2020 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _WIREDATA_U2F_H +#define _WIREDATA_U2F_H + +#define WIREDATA_CTAP_U2F_6985 \ + 0x00, 0x00, 0x99, 0x01, 0x83, 0x00, 0x02, 0x69, \ + 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_U2F_AUTH \ + 0x00, 0x00, 0x99, 0x01, 0x83, 0x00, 0x4e, 0x01, \ + 0x00, 0x00, 0x00, 0x2c, 0x30, 0x45, 0x02, 0x20, \ + 0x1c, 0xf5, 0x7c, 0xf6, 0xde, 0xbe, 0xe9, 0x86, \ + 0xee, 0x97, 0xb7, 0x64, 0xa3, 0x4e, 0x7a, 0x70, \ + 0x85, 0xd0, 0x66, 0xf9, 0xf0, 0xcd, 0x04, 0x5d, \ + 0x97, 0xf2, 0x3c, 0x22, 0xe3, 0x0e, 0x61, 0xc8, \ + 0x02, 0x21, 0x00, 0x97, 0xef, 0xae, 0x36, 0xe6, \ + 0x17, 0x9f, 0x5e, 0x2d, 0xd7, 0x8c, 0x34, 0xa7, \ + 0x00, 0x00, 0x99, 0x01, 0x00, 0xa1, 0xe9, 0xfb, \ + 0x8f, 0x86, 0x8c, 0xe3, 0x1e, 0xde, 0x3f, 0x4e, \ + 0x1b, 0xe1, 0x2f, 0x8f, 0x2f, 0xca, 0x42, 0x26, \ + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_U2F_REGISTER \ + 0x00, 0x00, 0x99, 0x01, 0x83, 0x03, 0x1e, 0x05, \ + 0x04, 0x9f, 0xa0, 0xf9, 0x0d, 0x4c, 0xf4, 0xae, \ + 0x96, 0x3c, 0xb7, 0x46, 0xb7, 0x5c, 0x9d, 0x8b, \ + 0x48, 0x19, 0xdf, 0xc4, 0xad, 0xea, 0xb2, 0x70, \ + 0x58, 0x72, 0xd9, 0xce, 0x75, 0xf5, 0xe6, 0x8e, \ + 0x0f, 0x9c, 0x0e, 0x2e, 0x62, 0x3e, 0x91, 0xd3, \ + 0x7b, 0x97, 0x46, 0x60, 0xb9, 0x57, 0x13, 0x97, \ + 0x26, 0xae, 0x0f, 0xb3, 0x8f, 0x2e, 0x9b, 0x3f, \ + 0x00, 0x00, 0x99, 0x01, 0x00, 0xa5, 0x55, 0xec, \ + 0x8c, 0x25, 0x7c, 0x65, 0xb7, 0x09, 0x40, 0x48, \ + 0xae, 0xa8, 0xcb, 0xa1, 0x91, 0xac, 0x40, 0x24, \ + 0xf2, 0x34, 0x6e, 0x3a, 0x8f, 0xa5, 0xb7, 0x48, \ + 0x54, 0x6e, 0xfb, 0xf4, 0x37, 0x88, 0x69, 0x79, \ + 0x6f, 0x12, 0xc1, 0x32, 0xdf, 0x15, 0x5d, 0x6e, \ + 0x82, 0x54, 0xc0, 0x6e, 0x56, 0x4f, 0x3a, 0x9c, \ + 0xc3, 0x96, 0x7a, 0xde, 0xa5, 0xfe, 0xec, 0xd1, \ + 0x00, 0x00, 0x99, 0x01, 0x01, 0x5a, 0x21, 0x85, \ + 0x0e, 0x25, 0x7b, 0x8d, 0x6e, 0x1d, 0x32, 0x29, \ + 0xdb, 0x21, 0xb0, 0xa3, 0x30, 0x82, 0x02, 0x4f, \ + 0x30, 0x82, 0x01, 0x37, 0xa0, 0x03, 0x02, 0x01, \ + 0x02, 0x02, 0x04, 0x2a, 0xd9, 0x6a, 0xf3, 0x30, \ + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, \ + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x2e, \ + 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, \ + 0x00, 0x00, 0x99, 0x01, 0x02, 0x03, 0x13, 0x23, \ + 0x59, 0x75, 0x62, 0x69, 0x63, 0x6f, 0x20, 0x55, \ + 0x32, 0x46, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, \ + 0x43, 0x41, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, \ + 0x6c, 0x20, 0x34, 0x35, 0x37, 0x32, 0x30, 0x30, \ + 0x36, 0x33, 0x31, 0x30, 0x20, 0x17, 0x0d, 0x31, \ + 0x34, 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x30, \ + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, \ + 0x00, 0x00, 0x99, 0x01, 0x03, 0x35, 0x30, 0x30, \ + 0x39, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, \ + 0x30, 0x5a, 0x30, 0x31, 0x31, 0x2f, 0x30, 0x2d, \ + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x26, 0x59, \ + 0x75, 0x62, 0x69, 0x63, 0x6f, 0x20, 0x55, 0x32, \ + 0x46, 0x20, 0x45, 0x45, 0x20, 0x53, 0x65, 0x72, \ + 0x69, 0x61, 0x6c, 0x20, 0x32, 0x33, 0x39, 0x32, \ + 0x35, 0x37, 0x33, 0x34, 0x35, 0x31, 0x36, 0x35, \ + 0x00, 0x00, 0x99, 0x01, 0x04, 0x35, 0x30, 0x33, \ + 0x38, 0x37, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, \ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, \ + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, \ + 0x07, 0x03, 0x42, 0x00, 0x04, 0x2f, 0xe1, 0xa2, \ + 0x3e, 0xbf, 0xa5, 0x5b, 0x3e, 0x46, 0x1d, 0x59, \ + 0xa4, 0x35, 0x22, 0xd7, 0x97, 0x48, 0x98, 0x1c, \ + 0xba, 0x6d, 0x28, 0x9a, 0x98, 0xf1, 0xbd, 0x7d, \ + 0x00, 0x00, 0x99, 0x01, 0x05, 0xff, 0x65, 0x66, \ + 0x80, 0xdb, 0xbb, 0xed, 0xbc, 0x2b, 0xae, 0x60, \ + 0x7e, 0x6e, 0xf7, 0x72, 0xf5, 0x76, 0xb0, 0x4d, \ + 0x54, 0xc4, 0xe5, 0xf3, 0x2f, 0x59, 0x6f, 0x26, \ + 0xe6, 0x11, 0x15, 0xc7, 0x27, 0x2c, 0xf6, 0xca, \ + 0x75, 0x94, 0xa3, 0x3b, 0x30, 0x39, 0x30, 0x22, \ + 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, \ + 0xc4, 0x0a, 0x02, 0x04, 0x15, 0x31, 0x2e, 0x33, \ + 0x00, 0x00, 0x99, 0x01, 0x06, 0x2e, 0x36, 0x2e, \ + 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e, 0x34, 0x31, \ + 0x34, 0x38, 0x32, 0x2e, 0x31, 0x2e, 0x32, 0x30, \ + 0x13, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, \ + 0x82, 0xe5, 0x1c, 0x02, 0x01, 0x01, 0x04, 0x04, \ + 0x03, 0x02, 0x04, 0x30, 0x30, 0x0d, 0x06, 0x09, \ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, \ + 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, \ + 0x00, 0x00, 0x99, 0x01, 0x07, 0x85, 0x6a, 0xfa, \ + 0x8b, 0xcf, 0x4f, 0x3f, 0x62, 0x5f, 0x29, 0x1b, \ + 0xc1, 0x15, 0x8e, 0x3c, 0x7e, 0xbd, 0x25, 0x52, \ + 0xbc, 0xf7, 0x57, 0x07, 0x53, 0xf5, 0x12, 0x1d, \ + 0xa6, 0xa5, 0x4d, 0x24, 0xcc, 0xcf, 0xae, 0x27, \ + 0xce, 0xd6, 0xab, 0x31, 0x12, 0x8c, 0x29, 0x7e, \ + 0x5b, 0x5b, 0x89, 0x05, 0xdd, 0xa0, 0x20, 0x17, \ + 0x93, 0x1f, 0x1f, 0x5f, 0x59, 0x25, 0x93, 0x59, \ + 0x00, 0x00, 0x99, 0x01, 0x08, 0x51, 0xfc, 0x00, \ + 0x4b, 0xcb, 0xe2, 0x0a, 0xdd, 0x7d, 0x8d, 0x05, \ + 0x2f, 0x95, 0x43, 0xb3, 0x49, 0x6c, 0x15, 0xb8, \ + 0x31, 0x0e, 0x10, 0xcb, 0xd9, 0xbb, 0x05, 0x38, \ + 0x27, 0x4f, 0x58, 0x3e, 0xad, 0x1f, 0x45, 0x12, \ + 0x88, 0xc3, 0xea, 0x76, 0xd0, 0x70, 0xad, 0x44, \ + 0xe5, 0x3a, 0xfe, 0xa8, 0xf2, 0x2d, 0x1f, 0x73, \ + 0x62, 0x5f, 0xf2, 0xd5, 0x89, 0xfe, 0x30, 0xdf, \ + 0x00, 0x00, 0x99, 0x01, 0x09, 0x26, 0x62, 0xcb, \ + 0x7c, 0xbb, 0x7c, 0x99, 0x61, 0x80, 0xad, 0xcf, \ + 0xa9, 0x8a, 0x4d, 0x01, 0x2c, 0xf3, 0x13, 0x46, \ + 0xcd, 0x11, 0x74, 0x6a, 0x58, 0x48, 0xe8, 0xbe, \ + 0xed, 0xf3, 0xe3, 0x0c, 0xcb, 0xd9, 0xc1, 0xdd, \ + 0x22, 0x16, 0x71, 0xb2, 0x83, 0x88, 0x61, 0xf6, \ + 0x5a, 0x45, 0x36, 0x23, 0xb5, 0x18, 0xd5, 0x56, \ + 0x7f, 0xa8, 0xf0, 0xa3, 0xce, 0x10, 0x5d, 0xf4, \ + 0x00, 0x00, 0x99, 0x01, 0x0a, 0xf1, 0x39, 0x53, \ + 0xe1, 0x14, 0xea, 0x59, 0xe0, 0xa7, 0xf2, 0xfe, \ + 0x66, 0x88, 0x67, 0x43, 0x2e, 0x52, 0xfd, 0x6a, \ + 0x2f, 0x64, 0xf7, 0x3c, 0x48, 0xcd, 0x9b, 0x38, \ + 0xf2, 0xdf, 0xba, 0x2c, 0x7a, 0x4b, 0x3b, 0x11, \ + 0x28, 0xdf, 0x26, 0xd6, 0x6a, 0x24, 0xf8, 0x95, \ + 0xdd, 0xa0, 0xb6, 0x11, 0x80, 0xf4, 0x14, 0x4f, \ + 0x6b, 0x70, 0x75, 0xc3, 0x18, 0xa4, 0x9a, 0xe0, \ + 0x00, 0x00, 0x99, 0x01, 0x0b, 0x8b, 0x58, 0xd3, \ + 0x6a, 0xdb, 0x1e, 0x30, 0x53, 0x67, 0x2b, 0x17, \ + 0xc5, 0xa1, 0x9f, 0x7f, 0x0a, 0x22, 0xf1, 0x0e, \ + 0x94, 0x30, 0x44, 0x02, 0x20, 0x07, 0x5c, 0x4f, \ + 0xd2, 0x83, 0xb6, 0x9f, 0x0a, 0x4a, 0x4d, 0x4b, \ + 0x08, 0x35, 0xeb, 0xc0, 0x7e, 0x4a, 0x14, 0x2e, \ + 0xc7, 0x8c, 0xd6, 0x64, 0x2f, 0xd3, 0x1e, 0xcc, \ + 0xb5, 0xe8, 0x42, 0xea, 0xf6, 0x02, 0x20, 0x6b, \ + 0x00, 0x00, 0x99, 0x01, 0x0c, 0x5a, 0xba, 0x4a, \ + 0xc8, 0xd7, 0x89, 0xcc, 0x77, 0xe6, 0xb9, 0xa3, \ + 0x34, 0xea, 0x06, 0x85, 0x72, 0xc6, 0x28, 0xa8, \ + 0x7a, 0xaa, 0x19, 0x88, 0x34, 0xbb, 0xdc, 0x64, \ + 0x90, 0x0a, 0xdb, 0x39, 0x90, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#endif /* !_WIREDATA_U2F_H */ diff --git a/fuzz/wrap.c b/fuzz/wrap.c new file mode 100644 index 0000000..6f40ea1 --- /dev/null +++ b/fuzz/wrap.c @@ -0,0 +1,700 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/types.h> +#include <sys/random.h> +#include <sys/socket.h> + +#include <openssl/bn.h> +#include <openssl/evp.h> +#include <openssl/sha.h> + +#include <cbor.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <zlib.h> + +#include "mutator_aux.h" + +extern int prng_up; + +int fuzz_save_corpus; + +/* + * Build wrappers around functions of interest, and have them fail + * in a pseudo-random manner. A uniform probability of 0.25% (1/400) + * allows for a depth of log(0.5)/log(399/400) > 276 operations + * before simulated errors become statistically more likely. + */ + +#define WRAP(type, name, args, retval, param, prob) \ +extern type __wrap_##name args; \ +extern type __real_##name args; \ +type __wrap_##name args { \ + if (prng_up && uniform_random(400) < (prob)) { \ + return (retval); \ + } \ + \ + return (__real_##name param); \ +} + +WRAP(void *, + malloc, + (size_t size), + NULL, + (size), + 1 +) + +WRAP(void *, + calloc, + (size_t nmemb, size_t size), + NULL, + (nmemb, size), + 1 +) + +WRAP(void *, + realloc, + (void *ptr, size_t size), + NULL, + (ptr, size), + 1 +) + +WRAP(char *, + strdup, + (const char *s), + NULL, + (s), + 1 +) + +WRAP(ssize_t, + getrandom, + (void *buf, size_t buflen, unsigned int flags), + -1, + (buf, buflen, flags), + 1 +) + +WRAP(int, + EVP_Cipher, + (EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, + unsigned int inl), + -1, + (ctx, out, in, inl), + 1 +) + +WRAP(int, + EVP_CIPHER_CTX_ctrl, + (EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr), + 0, + (ctx, type, arg, ptr), + 1 +) + +WRAP(EVP_CIPHER_CTX *, + EVP_CIPHER_CTX_new, + (void), + NULL, + (), + 1 +) + +WRAP(int, + EVP_CipherInit, + (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc), + 0, + (ctx, cipher, key, iv, enc), + 1 +) + +WRAP(RSA *, + EVP_PKEY_get0_RSA, + (EVP_PKEY *pkey), + NULL, + (pkey), + 1 +) + +WRAP(EC_KEY *, + EVP_PKEY_get0_EC_KEY, + (EVP_PKEY *pkey), + NULL, + (pkey), + 1 +) + +WRAP(int, + EVP_PKEY_get_raw_public_key, + (const EVP_PKEY *pkey, unsigned char *pub, size_t *len), + 0, + (pkey, pub, len), + 1 +) + +WRAP(EVP_MD_CTX *, + EVP_MD_CTX_new, + (void), + NULL, + (), + 1 +) + +WRAP(int, + EVP_DigestVerifyInit, + (EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey), + 0, + (ctx, pctx, type, e, pkey), + 1 +) + +WRAP(int, + EVP_DigestInit_ex, + (EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl), + 0, + (ctx, type, impl), + 1 +) + +WRAP(int, + EVP_DigestUpdate, + (EVP_MD_CTX *ctx, const void *data, size_t count), + 0, + (ctx, data, count), + 1 +) + +WRAP(int, + EVP_DigestFinal_ex, + (EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize), + 0, + (ctx, md, isize), + 1 +) + +WRAP(BIGNUM *, + BN_bin2bn, + (const unsigned char *s, int len, BIGNUM *ret), + NULL, + (s, len, ret), + 1 +) + +WRAP(int, + BN_bn2bin, + (const BIGNUM *a, unsigned char *to), + -1, + (a, to), + 1 +) + +WRAP(BIGNUM *, + BN_CTX_get, + (BN_CTX *ctx), + NULL, + (ctx), + 1 +) + +WRAP(BN_CTX *, + BN_CTX_new, + (void), + NULL, + (), + 1 +) + +WRAP(BIGNUM *, + BN_new, + (void), + NULL, + (), + 1 +) + +WRAP(RSA *, + RSA_new, + (void), + NULL, + (), + 1 +) + +WRAP(int, + RSA_set0_key, + (RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d), + 0, + (r, n, e, d), + 1 +) + +WRAP(int, + RSA_pkey_ctx_ctrl, + (EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2), + -1, + (ctx, optype, cmd, p1, p2), + 1 +) + +WRAP(EC_KEY *, + EC_KEY_new_by_curve_name, + (int nid), + NULL, + (nid), + 1 +) + +WRAP(const EC_GROUP *, + EC_KEY_get0_group, + (const EC_KEY *key), + NULL, + (key), + 1 +) + +WRAP(const BIGNUM *, + EC_KEY_get0_private_key, + (const EC_KEY *key), + NULL, + (key), + 1 +) + +WRAP(EC_POINT *, + EC_POINT_new, + (const EC_GROUP *group), + NULL, + (group), + 1 +) + +WRAP(int, + EC_POINT_get_affine_coordinates_GFp, + (const EC_GROUP *group, const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx), + 0, + (group, p, x, y, ctx), + 1 +) + +WRAP(EVP_PKEY *, + EVP_PKEY_new, + (void), + NULL, + (), + 1 +) + +WRAP(int, + EVP_PKEY_assign, + (EVP_PKEY *pkey, int type, void *key), + 0, + (pkey, type, key), + 1 +) + +WRAP(int, + EVP_PKEY_keygen_init, + (EVP_PKEY_CTX *ctx), + 0, + (ctx), + 1 +) + +WRAP(int, + EVP_PKEY_keygen, + (EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey), + 0, + (ctx, ppkey), + 1 +) + +WRAP(int, + EVP_PKEY_paramgen_init, + (EVP_PKEY_CTX *ctx), + 0, + (ctx), + 1 +) + +WRAP(int, + EVP_PKEY_paramgen, + (EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey), + 0, + (ctx, ppkey), + 1 +) + +WRAP(EVP_PKEY *, + EVP_PKEY_new_raw_public_key, + (int type, ENGINE *e, const unsigned char *key, size_t keylen), + NULL, + (type, e, key, keylen), + 1 +) + +WRAP(EVP_PKEY_CTX *, + EVP_PKEY_CTX_new, + (EVP_PKEY *pkey, ENGINE *e), + NULL, + (pkey, e), + 1 +) + +WRAP(EVP_PKEY_CTX *, + EVP_PKEY_CTX_new_id, + (int id, ENGINE *e), + NULL, + (id, e), + 1 +) + +WRAP(int, + EVP_PKEY_derive, + (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen), + 0, + (ctx, key, pkeylen), + 1 +) + +WRAP(int, + EVP_PKEY_derive_init, + (EVP_PKEY_CTX *ctx), + 0, + (ctx), + 1 +) + +WRAP(int, + EVP_PKEY_derive_set_peer, + (EVP_PKEY_CTX *ctx, EVP_PKEY *peer), + 0, + (ctx, peer), + 1 +) + +WRAP(int, + EVP_PKEY_verify_init, + (EVP_PKEY_CTX *ctx), + 0, + (ctx), + 1 +) + +WRAP(int, + EVP_PKEY_CTX_ctrl, + (EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2), + -1, + (ctx, keytype, optype, cmd, p1, p2), + 1 +) + +WRAP(const EVP_MD *, + EVP_sha1, + (void), + NULL, + (), + 1 +) + +WRAP(const EVP_MD *, + EVP_sha256, + (void), + NULL, + (), + 1 +) + +WRAP(const EVP_CIPHER *, + EVP_aes_256_cbc, + (void), + NULL, + (), + 1 +) + +WRAP(const EVP_CIPHER *, + EVP_aes_256_gcm, + (void), + NULL, + (), + 1 +) + +WRAP(unsigned char *, + HMAC, + (const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, int n, unsigned char *md, + unsigned int *md_len), + NULL, + (evp_md, key, key_len, d, n, md, md_len), + 1 +) + +WRAP(HMAC_CTX *, + HMAC_CTX_new, + (void), + NULL, + (), + 1 +) + +WRAP(int, + HMAC_Init_ex, + (HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, + ENGINE *impl), + 0, + (ctx, key, key_len, md, impl), + 1 +) + +WRAP(int, + HMAC_Update, + (HMAC_CTX *ctx, const unsigned char *data, int len), + 0, + (ctx, data, len), + 1 +) + +WRAP(int, + HMAC_Final, + (HMAC_CTX *ctx, unsigned char *md, unsigned int *len), + 0, + (ctx, md, len), + 1 +) + +WRAP(unsigned char *, + SHA1, + (const unsigned char *d, size_t n, unsigned char *md), + NULL, + (d, n, md), + 1 +) + +WRAP(unsigned char *, + SHA256, + (const unsigned char *d, size_t n, unsigned char *md), + NULL, + (d, n, md), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_string, + (const char *val), + NULL, + (val), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_bytestring, + (cbor_data handle, size_t length), + NULL, + (handle, length), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_bool, + (bool value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_negint8, + (uint8_t value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_negint16, + (uint16_t value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_load, + (cbor_data source, size_t source_size, struct cbor_load_result *result), + NULL, + (source, source_size, result), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_uint8, + (uint8_t value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_uint16, + (uint16_t value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_uint32, + (uint32_t value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_uint64, + (uint64_t value), + NULL, + (value), + 1 +) + +WRAP(struct cbor_pair *, + cbor_map_handle, + (const cbor_item_t *item), + NULL, + (item), + 1 +) + +WRAP(cbor_item_t **, + cbor_array_handle, + (const cbor_item_t *item), + NULL, + (item), + 1 +) + +WRAP(bool, + cbor_array_push, + (cbor_item_t *array, cbor_item_t *pushee), + false, + (array, pushee), + 1 +) + +WRAP(bool, + cbor_map_add, + (cbor_item_t *item, struct cbor_pair pair), + false, + (item, pair), + 1 +) + +WRAP(cbor_item_t *, + cbor_new_definite_map, + (size_t size), + NULL, + (size), + 1 +) + +WRAP(cbor_item_t *, + cbor_new_definite_array, + (size_t size), + NULL, + (size), + 1 +) + +WRAP(cbor_item_t *, + cbor_new_definite_bytestring, + (void), + NULL, + (), + 1 +) + +WRAP(size_t, + cbor_serialize_alloc, + (const cbor_item_t *item, cbor_mutable_data *buffer, + size_t *buffer_size), + 0, + (item, buffer, buffer_size), + 1 +) + +WRAP(int, + fido_tx, + (fido_dev_t *d, uint8_t cmd, const void *buf, size_t count, int *ms), + -1, + (d, cmd, buf, count, ms), + 1 +) + +WRAP(int, + bind, + (int sockfd, const struct sockaddr *addr, socklen_t addrlen), + -1, + (sockfd, addr, addrlen), + 1 +) + +WRAP(int, + deflateInit2_, + (z_streamp strm, int level, int method, int windowBits, int memLevel, + int strategy, const char *version, int stream_size), + Z_STREAM_ERROR, + (strm, level, method, windowBits, memLevel, strategy, version, + stream_size), + 1 +) + +int __wrap_deflate(z_streamp, int); +int __real_deflate(z_streamp, int); + +int +__wrap_deflate(z_streamp strm, int flush) +{ + if (prng_up && uniform_random(400) < 1) { + return Z_BUF_ERROR; + } + /* should never happen, but we check for it */ + if (prng_up && uniform_random(400) < 1) { + strm->avail_out = UINT_MAX; + return Z_STREAM_END; + } + + return __real_deflate(strm, flush); +} + +int __wrap_asprintf(char **, const char *, ...); + +int +__wrap_asprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + int r; + + if (prng_up && uniform_random(400) < 1) { + *strp = (void *)0xdeadbeef; + return -1; + } + + va_start(ap, fmt); + r = vasprintf(strp, fmt, ap); + va_end(ap); + + return r; +} diff --git a/fuzz/wrapped.sym b/fuzz/wrapped.sym new file mode 100644 index 0000000..219a0d8 --- /dev/null +++ b/fuzz/wrapped.sym @@ -0,0 +1,102 @@ +asprintf +bind +BN_bin2bn +BN_bn2bin +BN_CTX_get +BN_CTX_new +BN_new +calloc +cbor_array_handle +cbor_array_push +cbor_build_bool +cbor_build_bytestring +cbor_build_negint16 +cbor_build_negint8 +cbor_build_string +cbor_build_uint16 +cbor_build_uint32 +cbor_build_uint64 +cbor_build_uint8 +cbor_load +cbor_map_add +cbor_map_handle +cbor_new_definite_array +cbor_new_definite_bytestring +cbor_new_definite_map +cbor_serialize_alloc +clock_gettime +deflate +deflateInit2_ +EC_KEY_get0_group +EC_KEY_get0_private_key +EC_KEY_new_by_curve_name +EC_POINT_get_affine_coordinates_GFp +EC_POINT_new +EVP_aes_256_cbc +EVP_aes_256_gcm +EVP_Cipher +EVP_CIPHER_CTX_ctrl +EVP_CIPHER_CTX_new +EVP_CipherInit +EVP_DigestFinal_ex +EVP_DigestInit_ex +EVP_DigestUpdate +EVP_DigestVerifyInit +EVP_MD_CTX_new +EVP_PKEY_assign +EVP_PKEY_CTX_ctrl +EVP_PKEY_CTX_new +EVP_PKEY_CTX_new_id +EVP_PKEY_derive +EVP_PKEY_derive_init +EVP_PKEY_derive_set_peer +EVP_PKEY_get0_EC_KEY +EVP_PKEY_get0_RSA +EVP_PKEY_get_raw_public_key +EVP_PKEY_keygen +EVP_PKEY_keygen_init +EVP_PKEY_new +EVP_PKEY_new_raw_public_key +EVP_PKEY_paramgen +EVP_PKEY_paramgen_init +EVP_PKEY_verify_init +EVP_sha1 +EVP_sha256 +fido_tx +getrandom +HMAC +HMAC_CTX_new +HMAC_Final +HMAC_Init_ex +HMAC_Update +ioctl +malloc +realloc +RSA_new +RSA_pkey_ctx_ctrl +RSA_set0_key +SCardConnect +SCardDisconnect +SCardEstablishContext +SCardListReaders +SCardReleaseContext +SCardTransmit +SHA1 +SHA256 +strdup +udev_device_get_devnode +udev_device_get_parent_with_subsystem_devtype +udev_device_get_sysattr_value +udev_device_get_sysnum +udev_device_new_from_syspath +udev_device_unref +udev_enumerate_add_match_subsystem +udev_enumerate_get_list_entry +udev_enumerate_new +udev_enumerate_scan_devices +udev_enumerate_unref +udev_list_entry_get_name +udev_list_entry_get_next +udev_new +udev_unref +usleep |