From c79050aa44b8836d836c5dd22a383a073c28b74b Mon Sep 17 00:00:00 2001 From: nicoo Date: Wed, 12 Feb 2020 13:42:22 +0100 Subject: Import upstream release 1.3.0 Closes: #951184 --- fuzz/CMakeLists.txt | 44 ++ fuzz/README | 157 +++++++ fuzz/corpus.tgz | Bin 0 -> 1131788 bytes fuzz/functions.txt | 564 ++++++++++++++++++++++++ fuzz/fuzz_assert.c | 664 ++++++++++++++++++++++++++++ fuzz/fuzz_bio.c | 755 ++++++++++++++++++++++++++++++++ fuzz/fuzz_cred.c | 925 ++++++++++++++++++++++++++++++++++++++++ fuzz/fuzz_credman.c | 667 +++++++++++++++++++++++++++++ fuzz/fuzz_mgmt.c | 529 +++++++++++++++++++++++ fuzz/harnesses/assert | 32 ++ fuzz/harnesses/assert-rsa-h-p | 33 ++ fuzz/harnesses/assert-u2f | 32 ++ fuzz/harnesses/cred | 31 ++ fuzz/harnesses/cred-rsa-h-p | 32 ++ fuzz/harnesses/cred-u2f | 31 ++ fuzz/harnesses/cred-u2f-exclude | 33 ++ fuzz/harnesses/fido2-assert-G | 31 ++ fuzz/harnesses/fido2-assert-V | 32 ++ fuzz/harnesses/fido2-cred-M | 31 ++ fuzz/harnesses/fido2-cred-V | 31 ++ fuzz/harnesses/fuzz_assert | 29 ++ fuzz/harnesses/fuzz_bio | 29 ++ fuzz/harnesses/fuzz_cred | 28 ++ fuzz/harnesses/fuzz_credman | 28 ++ fuzz/harnesses/fuzz_mgmt | 29 ++ fuzz/mutator_aux.c | 314 ++++++++++++++ fuzz/mutator_aux.h | 65 +++ fuzz/preload-fuzz.c | 104 +++++ fuzz/preload-snoop.c | 217 ++++++++++ fuzz/report | 80 ++++ fuzz/summary.txt | 39 ++ fuzz/uniform_random.c | 56 +++ fuzz/wrap.c | 419 ++++++++++++++++++ fuzz/wrapped.sym | 47 ++ 34 files changed, 6138 insertions(+) create mode 100644 fuzz/CMakeLists.txt create mode 100644 fuzz/README create mode 100644 fuzz/corpus.tgz create mode 100644 fuzz/functions.txt create mode 100644 fuzz/fuzz_assert.c create mode 100644 fuzz/fuzz_bio.c create mode 100644 fuzz/fuzz_cred.c create mode 100644 fuzz/fuzz_credman.c create mode 100644 fuzz/fuzz_mgmt.c create mode 100755 fuzz/harnesses/assert create mode 100755 fuzz/harnesses/assert-rsa-h-p create mode 100755 fuzz/harnesses/assert-u2f create mode 100755 fuzz/harnesses/cred create mode 100755 fuzz/harnesses/cred-rsa-h-p create mode 100755 fuzz/harnesses/cred-u2f create mode 100755 fuzz/harnesses/cred-u2f-exclude create mode 100755 fuzz/harnesses/fido2-assert-G create mode 100755 fuzz/harnesses/fido2-assert-V create mode 100755 fuzz/harnesses/fido2-cred-M create mode 100755 fuzz/harnesses/fido2-cred-V create mode 100755 fuzz/harnesses/fuzz_assert create mode 100755 fuzz/harnesses/fuzz_bio create mode 100755 fuzz/harnesses/fuzz_cred create mode 100755 fuzz/harnesses/fuzz_credman create mode 100755 fuzz/harnesses/fuzz_mgmt create mode 100644 fuzz/mutator_aux.c create mode 100644 fuzz/mutator_aux.h create mode 100644 fuzz/preload-fuzz.c create mode 100644 fuzz/preload-snoop.c create mode 100755 fuzz/report create mode 100644 fuzz/summary.txt create mode 100644 fuzz/uniform_random.c create mode 100644 fuzz/wrap.c create mode 100644 fuzz/wrapped.sym (limited to 'fuzz') diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt new file mode 100644 index 0000000..ad30aa3 --- /dev/null +++ b/fuzz/CMakeLists.txt @@ -0,0 +1,44 @@ +# 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. + +list(APPEND COMPAT_SOURCES + ../openbsd-compat/strlcpy.c + ../openbsd-compat/strlcat.c +) + +list(APPEND COMMON_SOURCES + mutator_aux.c + uniform_random.c +) + + +# 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) diff --git a/fuzz/README b/fuzz/README new file mode 100644 index 0000000..ecb02bb --- /dev/null +++ b/fuzz/README @@ -0,0 +1,157 @@ +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=1 +-DAFL=1, and use preload-fuzz.c to read device data from stdin. Examples of +this approach can be found in the harnesses under fuzz/harnesses/ that fuzz +the standalone examples and tools bundled with libfido2. + +libFuzzer is better suited for bespoke fuzzers; see fuzz_cred.c, fuzz_credman.c, +fuzz_assert.c, and fuzz_mgmt.c for examples. To build these harnesses, +use -DFUZZ=1 -DLIBFUZZER=1. + +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, alternatively, patch libcbor with +the diff at the bottom of this file. + +1. Using ASAN + UBSAN + +- Make sure you have libcbor built with -fsanitize=address; +- Make sure you have OpenSSL built with -fsanitize=address; +- Rebuild libfido2 with -DASAN=1 -DUBSAN=1. + +1.1 Decide where your workspace will live + +$ export FAKEROOT=/home/pedro/fakeroot +$ mkdir -p ${FAKEROOT}/src + +1.2 Building libcbor with ASAN + +$ git clone https://github.com/pjk/libcbor ${FAKEROOT}/src/libcbor +$ cd ${FAKEROOT}/src/libcbor + +Assuming libfido2 is under ${FAKEROOT}/src/libfido2: + +$ patch -p0 < ${FAKEROOT}/src/libfido2/fuzz/README +$ mkdir build +$ cd build +$ cmake -DCMAKE_C_FLAGS_DEBUG="-g2 -fno-omit-frame-pointer" \ + -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX=${FAKEROOT} -DSANITIZE=ON \ + -DCMAKE_INSTALL_LIBDIR=lib .. +$ make +$ make install + +1.3 Building OpenSSL with ASAN + +$ git clone https://github.com/openssl/openssl ${FAKEROOT}/src/openssl +$ cd ${FAKEROOT}/src/openssl +$ ./Configure linux-x86_64-clang enable-asan --prefix=${FAKEROOT} \ + --openssldir=${FAKEROOT}/openssl +$ make clean +$ make +$ make install_sw + +1.4 Building libfido2 with libFuzzer and ASAN + UBSAN + +$ cd ${FAKEROOT}/src/libfido2 +$ mkdir build +$ cd build +$ cmake -DFUZZ=1 -DLIBFUZZER=1 -DASAN=1 -DUBSAN=1 -DCMAKE_C_COMPILER=clang \ + -DCRYPTO_INCLUDE_DIRS=${FAKEROOT}/include \ + -DCRYPTO_LIBRARY_DIRS=${FAKEROOT}/lib \ + -DCBOR_INCLUDE_DIRS=${FAKEROOT}/include \ + -DCBOR_LIBRARY_DIRS=${FAKEROOT}/lib \ + -DCMAKE_BUILD_TYPE=Debug .. +$ make + +2. Using MSAN + UBSAN + +- Make sure you have libcbor built with -fsanitize=memory; +- Make sure you have OpenSSL built with -fsanitize=memory; +- Rebuild libfido2 with -DMSAN=1 -DUBSAN=1. + +2.1 Decide where your workspace will live + +$ export FAKEROOT=/home/pedro/fakeroot +$ mkdir -p ${FAKEROOT}/src + +2.2 Building libcbor with MSAN + +$ git clone https://github.com/pjk/libcbor ${FAKEROOT}/src/libcbor +$ cd ${FAKEROOT}/src/libcbor + +Assuming libfido2 is under ${FAKEROOT}/src/libfido2: + +$ patch -p0 < ${FAKEROOT}/src/libfido2/fuzz/README +$ mkdir build +$ cd build +$ cmake -DCMAKE_C_FLAGS_DEBUG="-fsanitize=memory,undefined -g2 -fno-omit-frame-pointer" \ + -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX=${FAKEROOT} -DSANITIZE=OFF \ + -DCMAKE_INSTALL_LIBDIR=lib .. +$ make +$ make install + +2.2 Building OpenSSL with MSAN + +$ mkdir -p ${FAKEROOT}/src +$ git clone https://github.com/openssl/openssl ${FAKEROOT}/src/openssl +$ cd ${FAKEROOT}/src/openssl +$ ./Configure linux-x86_64-clang enable-msan --prefix=${FAKEROOT} \ + --openssldir=${FAKEROOT}/openssl +$ make clean +$ make +$ make install_sw + +2.3 Building libfido2 with libFuzzer and MSAN + UBSAN + +$ cd ${FAKEROOT}/src/libfido2 +$ mkdir build +$ cd build +$ cmake -DFUZZ=1 -DLIBFUZZER=1 -DMSAN=1 -DUBSAN=1 -DCMAKE_C_COMPILER=clang \ + -DCRYPTO_INCLUDE_DIRS=${FAKEROOT}/include \ + -DCRYPTO_LIBRARY_DIRS=${FAKEROOT}/lib \ + -DCBOR_INCLUDE_DIRS=${FAKEROOT}/include \ + -DCBOR_LIBRARY_DIRS=${FAKEROOT}/lib \ + -DCMAKE_BUILD_TYPE=Debug .. +$ make + +3. Running the libFuzzer harnesses + +When running under ASAN, you may want to set ASAN_OPTIONS to +'allocator_may_return_null=1:detect_stack_use_after_return=1'. + +The recommended way to run the harnesses is: + +$ fuzz_{assert,cred,credman,mgmt} -use_value_profile=1 -reload=30 \ + -print_pcs=1 -print_funcs=30 -timeout=10 -max_len=17408 CORPUS_DIR + +You may want to use -jobs or -workers depending on the number of logical +cores available for fuzzing. + +4. Auxiliary scripts + +A set of harnesses and auxiliary scripts can be found under harnesses/. To +compile coverage reports, adjust the harnesses to your setup and run 'report'. + +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/corpus.tgz b/fuzz/corpus.tgz new file mode 100644 index 0000000..9da3099 Binary files /dev/null and b/fuzz/corpus.tgz differ diff --git a/fuzz/functions.txt b/fuzz/functions.txt new file mode 100644 index 0000000..cd652f2 --- /dev/null +++ b/fuzz/functions.txt @@ -0,0 +1,564 @@ +File '/home/pedro/projects/libfido2/src/aes256.c': +Name Regions Miss Cover Lines Miss Cover +----------------------------------------------------------------------------- +aes256_cbc_enc 28 0 100.00% 41 0 100.00% +aes256_cbc_dec 28 0 100.00% 41 0 100.00% +----------------------------------------------------------------------------- +TOTAL 56 0 100.00% 82 0 100.00% + +File '/home/pedro/projects/libfido2/src/assert.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_dev_get_assert 35 3 91.43% 38 4 89.47% +fido_check_flags 13 0 100.00% 18 0 100.00% +fido_verify_sig_es256 17 2 88.24% 31 7 77.42% +fido_verify_sig_rs256 17 2 88.24% 31 7 77.42% +fido_verify_sig_eddsa 23 2 91.30% 43 7 83.72% +fido_assert_verify 48 4 91.67% 79 4 94.94% +fido_assert_set_clientdata_hash 6 0 100.00% 6 0 100.00% +fido_assert_set_hmac_salt 10 0 100.00% 7 0 100.00% +fido_assert_set_rp 12 1 91.67% 14 3 78.57% +fido_assert_allow_cred 13 2 84.62% 29 3 89.66% +fido_assert_set_extensions 9 0 100.00% 8 0 100.00% +fido_assert_set_options 6 6 0.00% 6 6 0.00% +fido_assert_set_up 2 0 100.00% 5 0 100.00% +fido_assert_set_uv 2 0 100.00% 5 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% 15 0 100.00% +fido_assert_reset_rx 6 0 100.00% 24 0 100.00% +fido_assert_free 6 0 100.00% 13 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% 6 0 100.00% +fido_assert_sigcount 4 0 100.00% 6 0 100.00% +fido_assert_authdata_ptr 4 0 100.00% 6 0 100.00% +fido_assert_authdata_len 4 0 100.00% 6 0 100.00% +fido_assert_sig_ptr 4 0 100.00% 6 0 100.00% +fido_assert_sig_len 4 0 100.00% 6 0 100.00% +fido_assert_id_ptr 4 0 100.00% 6 0 100.00% +fido_assert_id_len 4 0 100.00% 6 0 100.00% +fido_assert_user_id_ptr 4 0 100.00% 6 0 100.00% +fido_assert_user_id_len 4 0 100.00% 6 0 100.00% +fido_assert_user_icon 4 0 100.00% 6 0 100.00% +fido_assert_user_name 4 0 100.00% 6 0 100.00% +fido_assert_user_display_name 4 0 100.00% 6 0 100.00% +fido_assert_hmac_secret_ptr 4 0 100.00% 6 0 100.00% +fido_assert_hmac_secret_len 4 0 100.00% 6 0 100.00% +fido_assert_set_authdata 24 0 100.00% 35 0 100.00% +fido_assert_set_authdata_raw 24 0 100.00% 34 0 100.00% +fido_assert_set_sig 14 0 100.00% 17 0 100.00% +fido_assert_set_count 10 0 100.00% 21 0 100.00% +assert.c:fido_dev_get_assert_wait 21 0 100.00% 16 0 100.00% +assert.c:fido_dev_get_assert_tx 58 4 93.10% 84 11 86.90% +assert.c:fido_dev_get_assert_rx 20 0 100.00% 38 0 100.00% +assert.c:adjust_assert_count 24 0 100.00% 33 0 100.00% +assert.c:parse_assert_reply 11 0 100.00% 25 0 100.00% +assert.c:fido_get_next_assert_tx 9 0 100.00% 11 0 100.00% +assert.c:fido_get_next_assert_rx 16 2 87.50% 26 4 84.62% +assert.c:decrypt_hmac_secrets 9 1 88.89% 15 4 73.33% +assert.c:check_extensions 4 0 100.00% 9 0 100.00% +assert.c:get_signed_hash 32 0 100.00% 46 0 100.00% +assert.c:fido_assert_clean_authdata 1 0 100.00% 9 0 100.00% +assert.c:fido_assert_clean_sig 1 0 100.00% 5 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 569 29 94.90% 901 60 93.34% + +File '/home/pedro/projects/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% 9 0 100.00% +authkey.c:fido_dev_authkey_tx 19 0 100.00% 33 0 100.00% +authkey.c:fido_dev_authkey_rx 7 0 100.00% 18 0 100.00% +authkey.c:parse_authkey 8 0 100.00% 12 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 45 0 100.00% 75 0 100.00% + +File '/home/pedro/projects/libfido2/src/bio.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_bio_dev_get_template_array 5 2 60.00% 6 0 100.00% +fido_bio_dev_set_template_name 7 0 100.00% 6 0 100.00% +fido_bio_dev_enroll_begin 24 2 91.67% 36 0 100.00% +fido_bio_dev_enroll_continue 5 2 60.00% 6 0 100.00% +fido_bio_dev_enroll_cancel 1 1 0.00% 3 3 0.00% +fido_bio_dev_enroll_remove 1 0 100.00% 3 0 100.00% +fido_bio_dev_get_info 1 0 100.00% 3 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% 10 0 100.00% +fido_bio_template_free 6 0 100.00% 10 0 100.00% +fido_bio_template_set_name 8 0 100.00% 9 0 100.00% +fido_bio_template_set_id 8 0 100.00% 10 0 100.00% +fido_bio_template 4 0 100.00% 6 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% 11 0 100.00% +fido_bio_info_free 6 0 100.00% 9 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% 9 0 100.00% +bio.c:bio_tx 43 0 100.00% 65 0 100.00% +bio.c:bio_prepare_hmac 18 0 100.00% 36 0 100.00% +bio.c:bio_rx_template_array 12 0 100.00% 21 0 100.00% +bio.c:bio_parse_template_array 26 1 96.15% 34 4 88.24% +bio.c:decode_template_array 12 1 91.67% 23 3 86.96% +bio.c:decode_template 9 0 100.00% 18 0 100.00% +bio.c:bio_set_template_name_wait 19 0 100.00% 24 0 100.00% +bio.c:bio_enroll_begin_wait 17 1 94.12% 24 3 87.50% +bio.c:bio_rx_enroll_begin 16 0 100.00% 29 0 100.00% +bio.c:bio_parse_enroll_status 20 0 100.00% 31 0 100.00% +bio.c:bio_parse_template_id 8 0 100.00% 12 0 100.00% +bio.c:bio_enroll_continue_wait 19 0 100.00% 25 0 100.00% +bio.c:bio_rx_enroll_continue 12 0 100.00% 22 0 100.00% +bio.c:bio_enroll_cancel_wait 11 11 0.00% 12 12 0.00% +bio.c:bio_enroll_remove_wait 17 0 100.00% 24 0 100.00% +bio.c:bio_get_info_wait 11 0 100.00% 11 0 100.00% +bio.c:bio_rx_info 12 0 100.00% 21 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% 31 0 100.00% +bio.c:bio_reset_template_array 4 0 100.00% 8 0 100.00% +bio.c:bio_reset_template 1 0 100.00% 6 0 100.00% +bio.c:bio_reset_enroll 3 0 100.00% 7 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 422 21 95.02% 661 25 96.22% + +File '/home/pedro/projects/libfido2/src/blob.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_blob_new 1 0 100.00% 3 0 100.00% +fido_blob_set 11 1 90.91% 25 4 84.00% +fido_blob_free 8 0 100.00% 16 0 100.00% +fido_free_blob_array 9 0 100.00% 17 0 100.00% +fido_blob_encode 6 0 100.00% 6 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% +--------------------------------------------------------------------------------------- +TOTAL 39 1 97.44% 73 4 94.52% + +File '/home/pedro/projects/libfido2/src/buf.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_buf_read 4 0 100.00% 10 0 100.00% +fido_buf_write 4 1 75.00% 10 1 90.00% +--------------------------------------------------------------------------------------- +TOTAL 8 1 87.50% 20 1 95.00% + +File '/home/pedro/projects/libfido2/src/cbor.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +cbor_map_iter 20 1 95.00% 30 4 86.67% +cbor_array_iter 12 0 100.00% 20 0 100.00% +cbor_parse_reply 27 0 100.00% 43 0 100.00% +cbor_vector_free 6 0 100.00% 5 0 100.00% +cbor_bytestring_copy 14 0 100.00% 22 0 100.00% +cbor_string_copy 14 0 100.00% 23 0 100.00% +cbor_add_bytestring 14 0 100.00% 26 0 100.00% +cbor_add_string 14 0 100.00% 26 0 100.00% +cbor_add_bool 14 0 100.00% 26 0 100.00% +cbor_flatten_vector 14 1 92.86% 21 1 95.24% +cbor_build_frame 15 0 100.00% 32 0 100.00% +cbor_encode_rp_entity 13 0 100.00% 14 0 100.00% +cbor_encode_user_entity 21 0 100.00% 18 0 100.00% +cbor_encode_pubkey_param 36 0 100.00% 48 0 100.00% +cbor_encode_pubkey 10 0 100.00% 13 0 100.00% +cbor_encode_pubkey_list 18 2 88.89% 23 0 100.00% +cbor_encode_extensions 13 1 92.31% 16 0 100.00% +cbor_encode_options 13 0 100.00% 14 0 100.00% +cbor_encode_assert_options 13 0 100.00% 14 0 100.00% +cbor_encode_pin_auth 8 0 100.00% 12 0 100.00% +cbor_encode_pin_opt 1 0 100.00% 3 0 100.00% +cbor_encode_pin_enc 4 0 100.00% 12 0 100.00% +cbor_encode_change_pin_auth 44 1 97.73% 69 3 95.65% +cbor_encode_set_pin_auth 17 0 100.00% 28 0 100.00% +cbor_encode_pin_hash_enc 15 0 100.00% 27 0 100.00% +cbor_encode_hmac_secret_param 41 1 97.56% 66 4 93.94% +cbor_decode_fmt 9 0 100.00% 18 0 100.00% +cbor_decode_pubkey 21 1 95.24% 32 2 93.75% +cbor_decode_cred_authdata 31 0 100.00% 46 0 100.00% +cbor_decode_assert_authdata 23 0 100.00% 44 0 100.00% +cbor_decode_attstmt 8 0 100.00% 10 0 100.00% +cbor_decode_uint64 4 0 100.00% 10 0 100.00% +cbor_decode_cred_id 8 0 100.00% 10 0 100.00% +cbor_decode_user 8 0 100.00% 10 0 100.00% +cbor_decode_rp_entity 8 0 100.00% 10 0 100.00% +cbor.c:ctap_check_cbor 28 0 100.00% 32 0 100.00% +cbor.c:check_key_type 8 0 100.00% 9 0 100.00% +cbor.c:cbor_add_arg 13 0 100.00% 28 0 100.00% +cbor.c:sha256 7 0 100.00% 15 0 100.00% +cbor.c:get_cose_alg 36 0 100.00% 48 0 100.00% +cbor.c:find_cose_alg 35 0 100.00% 40 0 100.00% +cbor.c:decode_attcred 25 0 100.00% 58 0 100.00% +cbor.c:decode_extensions 16 4 75.00% 34 6 82.35% +cbor.c:decode_extension 19 19 0.00% 27 27 0.00% +cbor.c:decode_hmac_secret 16 0 100.00% 32 0 100.00% +cbor.c:decode_hmac_secret_aux 7 0 100.00% 17 0 100.00% +cbor.c:decode_attstmt_entry 29 0 100.00% 39 0 100.00% +cbor.c:decode_x5c 4 0 100.00% 8 0 100.00% +cbor.c:decode_cred_id_entry 10 0 100.00% 23 0 100.00% +cbor.c:decode_user_entry 25 0 100.00% 39 0 100.00% +cbor.c:decode_rp_entity_entry 15 0 100.00% 29 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 844 31 96.33% 1319 47 96.44% + +File '/home/pedro/projects/libfido2/src/cred.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_dev_make_cred 12 0 100.00% 9 0 100.00% +fido_check_rp_id 4 0 100.00% 14 0 100.00% +fido_cred_verify 45 0 100.00% 71 0 100.00% +fido_cred_verify_self 54 10 81.48% 90 14 84.44% +fido_cred_new 1 0 100.00% 3 0 100.00% +fido_cred_reset_tx 1 0 100.00% 20 0 100.00% +fido_cred_reset_rx 1 0 100.00% 8 0 100.00% +fido_cred_free 6 1 83.33% 13 0 100.00% +fido_cred_set_authdata 22 0 100.00% 36 0 100.00% +fido_cred_set_authdata_raw 22 2 90.91% 35 4 88.57% +fido_cred_set_x509 12 0 100.00% 16 0 100.00% +fido_cred_set_sig 12 0 100.00% 16 0 100.00% +fido_cred_exclude 14 2 85.71% 25 3 88.00% +fido_cred_set_clientdata_hash 6 0 100.00% 6 0 100.00% +fido_cred_set_rp 18 2 88.89% 26 6 76.92% +fido_cred_set_user 33 4 87.88% 50 13 74.00% +fido_cred_set_extensions 9 0 100.00% 8 0 100.00% +fido_cred_set_options 6 6 0.00% 6 6 0.00% +fido_cred_set_rk 2 0 100.00% 5 0 100.00% +fido_cred_set_uv 2 0 100.00% 5 0 100.00% +fido_cred_set_fmt 16 4 75.00% 15 1 93.33% +fido_cred_set_type 17 2 88.24% 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_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_pubkey_ptr 9 0 100.00% 20 0 100.00% +fido_cred_pubkey_len 9 0 100.00% 20 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_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% +cred.c:fido_dev_make_cred_wait 10 0 100.00% 9 0 100.00% +cred.c:fido_dev_make_cred_tx 59 0 100.00% 81 0 100.00% +cred.c:fido_dev_make_cred_rx 22 0 100.00% 28 0 100.00% +cred.c:parse_makecred_reply 10 0 100.00% 23 0 100.00% +cred.c:check_extensions 4 0 100.00% 9 0 100.00% +cred.c:get_signed_hash_packed 23 1 95.65% 38 3 92.11% +cred.c:get_signed_hash_u2f 22 0 100.00% 20 0 100.00% +cred.c:verify_sig 27 1 96.30% 40 4 90.00% +cred.c:fido_cred_clean_authdata 1 0 100.00% 9 0 100.00% +cred.c:fido_cred_clean_x509 1 0 100.00% 5 0 100.00% +cred.c:fido_cred_clean_sig 1 0 100.00% 5 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 532 35 93.42% 850 55 93.53% + +File '/home/pedro/projects/libfido2/src/credman.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_credman_get_dev_metadata 9 2 77.78% 8 0 100.00% +fido_credman_get_dev_rk 9 2 77.78% 8 0 100.00% +fido_credman_del_dev_rk 9 2 77.78% 8 0 100.00% +fido_credman_get_dev_rp 9 2 77.78% 8 0 100.00% +fido_credman_rk_new 1 0 100.00% 3 0 100.00% +fido_credman_rk_free 6 1 83.33% 10 0 100.00% +fido_credman_rk_count 1 0 100.00% 3 0 100.00% +fido_credman_rk 4 0 100.00% 6 0 100.00% +fido_credman_metadata_new 1 0 100.00% 3 0 100.00% +fido_credman_metadata_free 6 1 83.33% 9 0 100.00% +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% 10 0 100.00% +fido_credman_rp_count 1 0 100.00% 3 0 100.00% +fido_credman_rp_id 4 0 100.00% 6 0 100.00% +fido_credman_rp_name 4 0 100.00% 6 0 100.00% +fido_credman_rp_id_hash_len 4 0 100.00% 6 0 100.00% +fido_credman_rp_id_hash_ptr 4 0 100.00% 6 0 100.00% +credman.c:credman_get_metadata_wait 11 0 100.00% 9 0 100.00% +credman.c:credman_tx 30 0 100.00% 53 0 100.00% +credman.c:credman_prepare_hmac 21 1 95.24% 43 2 95.35% +credman.c:credman_rx_metadata 12 0 100.00% 21 0 100.00% +credman.c:credman_parse_metadata 9 0 100.00% 19 0 100.00% +credman.c:credman_get_rk_wait 27 0 100.00% 26 0 100.00% +credman.c:credman_rx_rk 20 0 100.00% 36 0 100.00% +credman.c:credman_parse_rk_count 16 0 100.00% 25 0 100.00% +credman.c:credman_grow_array 17 2 88.24% 28 5 82.14% +credman.c:credman_parse_rk 13 0 100.00% 25 0 100.00% +credman.c:credman_rx_next_rk 16 2 87.50% 26 4 84.62% +credman.c:credman_del_rk_wait 16 0 100.00% 19 0 100.00% +credman.c:credman_get_rp_wait 23 0 100.00% 16 0 100.00% +credman.c:credman_rx_rp 20 0 100.00% 36 0 100.00% +credman.c:credman_parse_rp_count 16 0 100.00% 25 0 100.00% +credman.c:credman_parse_rp 9 0 100.00% 19 0 100.00% +credman.c:credman_rx_next_rp 16 2 87.50% 26 4 84.62% +credman.c:credman_reset_rk 4 0 100.00% 10 0 100.00% +credman.c:credman_reset_rp 4 0 100.00% 15 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 381 18 95.28% 589 15 97.45% + +File '/home/pedro/projects/libfido2/src/dev.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_dev_open 1 0 100.00% 3 0 100.00% +fido_dev_close 8 2 75.00% 9 0 100.00% +fido_dev_cancel 8 2 75.00% 6 3 50.00% +fido_dev_set_io_functions 18 4 77.78% 19 6 68.42% +fido_init 7 1 85.71% 4 0 100.00% +fido_dev_new 9 1 88.89% 22 4 81.82% +fido_dev_free 6 0 100.00% 10 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_force_u2f 2 0 100.00% 3 0 100.00% +fido_dev_force_fido2 2 2 0.00% 3 3 0.00% +dev.c:fido_dev_open_wait 10 0 100.00% 9 0 100.00% +dev.c:fido_dev_open_tx 26 8 69.23% 32 12 62.50% +dev.c:obtain_nonce 13 2 84.62% 18 2 88.89% +dev.c:fido_dev_open_rx 14 0 100.00% 27 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 131 22 83.21% 183 30 83.61% + +File '/home/pedro/projects/libfido2/src/ecdh.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_do_ecdh 29 0 100.00% 44 0 100.00% +ecdh.c:do_ecdh 39 0 100.00% 60 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 68 0 100.00% 104 0 100.00% + +File '/home/pedro/projects/libfido2/src/eddsa.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +eddsa_pk_decode 8 0 100.00% 10 0 100.00% +eddsa_pk_new 1 0 100.00% 3 0 100.00% +eddsa_pk_free 6 0 100.00% 11 0 100.00% +eddsa_pk_from_ptr 6 0 100.00% 8 0 100.00% +eddsa_pk_to_EVP_PKEY 3 0 100.00% 9 0 100.00% +eddsa_pk_from_EVP_PKEY 14 4 71.43% 12 2 83.33% +eddsa.c:decode_pubkey_point 8 0 100.00% 14 0 100.00% +eddsa.c:decode_coord 8 0 100.00% 12 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 54 4 92.59% 79 2 97.47% + +File '/home/pedro/projects/libfido2/src/err.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_strerr 108 108 0.00% 112 112 0.00% +--------------------------------------------------------------------------------------- +TOTAL 108 108 0.00% 112 112 0.00% + +File '/home/pedro/projects/libfido2/src/es256.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +es256_pk_decode 8 0 100.00% 10 0 100.00% +es256_pk_encode 56 0 100.00% 70 0 100.00% +es256_sk_new 1 0 100.00% 3 0 100.00% +es256_sk_free 6 0 100.00% 11 0 100.00% +es256_pk_new 1 0 100.00% 3 0 100.00% +es256_pk_free 6 0 100.00% 11 0 100.00% +es256_pk_from_ptr 6 0 100.00% 8 0 100.00% +es256_pk_set_x 1 0 100.00% 5 0 100.00% +es256_pk_set_y 1 0 100.00% 5 0 100.00% +es256_sk_create 39 2 94.87% 46 6 86.96% +es256_pk_to_EVP_PKEY 41 0 100.00% 58 0 100.00% +es256_pk_from_EC_KEY 38 2 94.74% 39 7 82.05% +es256_sk_to_EVP_PKEY 27 0 100.00% 41 0 100.00% +es256_derive_pk 25 0 100.00% 34 0 100.00% +es256.c:decode_pubkey_point 9 0 100.00% 16 0 100.00% +es256.c:decode_coord 8 0 100.00% 12 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 273 4 98.53% 372 13 96.51% + +File '/home/pedro/projects/libfido2/src/extern.h': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- + +File '/home/pedro/projects/libfido2/src/fido.h': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- + +File '/home/pedro/projects/libfido2/src/hid.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_dev_info_new 1 1 0.00% 3 3 0.00% +fido_dev_info_free 9 9 0.00% 17 17 0.00% +fido_dev_info_ptr 1 1 0.00% 3 3 0.00% +fido_dev_info_path 1 1 0.00% 3 3 0.00% +fido_dev_info_vendor 1 1 0.00% 3 3 0.00% +fido_dev_info_product 1 1 0.00% 3 3 0.00% +fido_dev_info_manufacturer_string 1 1 0.00% 3 3 0.00% +fido_dev_info_product_string 1 1 0.00% 3 3 0.00% +--------------------------------------------------------------------------------------- +TOTAL 16 16 0.00% 38 38 0.00% + +File '/home/pedro/projects/libfido2/src/hid_linux.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_dev_info_manifest 33 33 0.00% 40 40 0.00% +fido_hid_open 6 6 0.00% 11 11 0.00% +fido_hid_close 1 1 0.00% 6 6 0.00% +fido_hid_read 12 12 0.00% 16 16 0.00% +fido_hid_write 12 12 0.00% 16 16 0.00% +hid_linux.c:copy_info 35 35 0.00% 56 56 0.00% +hid_linux.c:is_fido 6 6 0.00% 14 14 0.00% +hid_linux.c:get_report_descriptor 17 17 0.00% 31 31 0.00% +hid_linux.c:get_usage_info 16 16 0.00% 33 33 0.00% +hid_linux.c:get_key_len 6 6 0.00% 14 14 0.00% +hid_linux.c:get_key_val 6 6 0.00% 20 20 0.00% +hid_linux.c:parse_uevent 16 16 0.00% 30 30 0.00% +--------------------------------------------------------------------------------------- +TOTAL 166 166 0.00% 287 287 0.00% + +File '/home/pedro/projects/libfido2/src/info.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_dev_get_cbor_info 1 0 100.00% 3 0 100.00% +fido_cbor_info_new 1 0 100.00% 3 0 100.00% +fido_cbor_info_free 6 1 83.33% 14 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_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_maxmsgsiz 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% +info.c:fido_dev_get_cbor_info_wait 10 0 100.00% 9 0 100.00% +info.c:fido_dev_get_cbor_info_tx 9 0 100.00% 13 0 100.00% +info.c:fido_dev_get_cbor_info_rx 7 0 100.00% 18 0 100.00% +info.c:parse_reply_element 13 0 100.00% 27 0 100.00% +info.c:decode_versions 12 0 100.00% 21 0 100.00% +info.c:decode_version 4 0 100.00% 14 0 100.00% +info.c:decode_extensions 12 0 100.00% 21 0 100.00% +info.c:decode_extension 4 0 100.00% 14 0 100.00% +info.c:decode_aaguid 8 0 100.00% 12 0 100.00% +info.c:decode_options 11 0 100.00% 18 0 100.00% +info.c:decode_option 11 0 100.00% 22 0 100.00% +info.c:decode_protocols 12 0 100.00% 21 0 100.00% +info.c:decode_protocol 6 0 100.00% 16 0 100.00% +info.c:free_str_array 4 0 100.00% 8 0 100.00% +info.c:free_opt_array 4 0 100.00% 9 0 100.00% +info.c:free_byte_array 1 0 100.00% 6 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 148 1 99.32% 305 0 100.00% + +File '/home/pedro/projects/libfido2/src/io.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_tx 18 0 100.00% 35 0 100.00% +fido_rx 34 3 91.18% 84 12 85.71% +fido_rx_cbor_status 9 0 100.00% 13 0 100.00% +io.c:tx_preamble 16 1 93.75% 24 1 95.83% +io.c:tx_frame 16 1 93.75% 21 0 100.00% +io.c:rx_preamble 11 0 100.00% 12 0 100.00% +io.c:rx_frame 9 1 88.89% 12 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 113 6 94.69% 201 13 93.53% + +File '/home/pedro/projects/libfido2/src/iso7816.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +iso7816_new 4 0 100.00% 19 0 100.00% +iso7816_free 6 0 100.00% 11 0 100.00% +iso7816_add 6 1 83.33% 10 0 100.00% +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% 47 0 100.00% + +File '/home/pedro/projects/libfido2/src/log.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_log_init 1 1 0.00% 3 3 0.00% +fido_log_xxd 11 8 27.27% 18 12 33.33% +fido_log_debug 4 1 75.00% 13 8 38.46% +--------------------------------------------------------------------------------------- +TOTAL 16 10 37.50% 34 23 32.35% + +File '/home/pedro/projects/libfido2/src/pin.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_dev_get_pin_token 1 0 100.00% 3 0 100.00% +fido_dev_set_pin 1 0 100.00% 3 0 100.00% +fido_dev_get_retry_count 1 0 100.00% 3 0 100.00% +cbor_add_pin_params 17 0 100.00% 27 0 100.00% +pin.c:fido_dev_get_pin_token_wait 10 0 100.00% 9 0 100.00% +pin.c:fido_dev_get_pin_token_tx 29 0 100.00% 40 0 100.00% +pin.c:fido_dev_get_pin_token_rx 21 0 100.00% 36 0 100.00% +pin.c:parse_pintoken 8 0 100.00% 12 0 100.00% +pin.c:fido_dev_set_pin_wait 16 0 100.00% 22 0 100.00% +pin.c:fido_dev_change_pin_tx 41 0 100.00% 59 0 100.00% +pin.c:pad64 18 0 100.00% 24 0 100.00% +pin.c:fido_dev_set_pin_tx 33 0 100.00% 48 0 100.00% +pin.c:fido_dev_get_retry_count_wait 10 0 100.00% 9 0 100.00% +pin.c:fido_dev_get_retry_count_tx 19 0 100.00% 28 0 100.00% +pin.c:fido_dev_get_retry_count_rx 12 0 100.00% 21 0 100.00% +pin.c:parse_retry_count 13 0 100.00% 20 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 250 0 100.00% 364 0 100.00% + +File '/home/pedro/projects/libfido2/src/reset.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +fido_dev_reset 1 0 100.00% 3 0 100.00% +reset.c:fido_dev_reset_wait 10 0 100.00% 9 0 100.00% +reset.c:fido_dev_reset_tx 9 0 100.00% 11 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 20 0 100.00% 23 0 100.00% + +File '/home/pedro/projects/libfido2/src/rs256.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +rs256_pk_decode 8 0 100.00% 10 0 100.00% +rs256_pk_new 1 0 100.00% 3 0 100.00% +rs256_pk_free 6 0 100.00% 11 0 100.00% +rs256_pk_from_ptr 6 0 100.00% 8 0 100.00% +rs256_pk_to_EVP_PKEY 32 0 100.00% 48 0 100.00% +rs256_pk_from_RSA 32 6 81.25% 32 9 71.88% +rs256.c:decode_rsa_pubkey 9 0 100.00% 16 0 100.00% +rs256.c:decode_bignum 8 0 100.00% 12 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 102 6 94.12% 140 9 93.57% + +File '/home/pedro/projects/libfido2/src/u2f.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------- +u2f_register 70 1 98.57% 89 0 100.00% +u2f_authenticate 27 0 100.00% 33 0 100.00% +u2f.c:key_lookup 44 0 100.00% 69 0 100.00% +u2f.c:send_dummy_register 31 1 96.77% 50 0 100.00% +u2f.c:parse_register_reply 57 0 100.00% 83 0 100.00% +u2f.c:x5c_get 21 1 95.24% 37 3 91.89% +u2f.c:sig_get 8 1 87.50% 16 6 62.50% +u2f.c:encode_cred_authdata 37 2 94.59% 82 6 92.68% +u2f.c:cbor_blob_from_ec_point 22 0 100.00% 39 0 100.00% +u2f.c:u2f_authenticate_single 34 2 94.12% 53 4 92.45% +u2f.c:do_auth 50 1 98.00% 72 0 100.00% +u2f.c:parse_auth_reply 23 2 91.30% 29 3 89.66% +u2f.c:authdata_fake 12 0 100.00% 34 0 100.00% +--------------------------------------------------------------------------------------- +TOTAL 436 11 97.48% 686 22 96.79% diff --git a/fuzz/fuzz_assert.c b/fuzz/fuzz_assert.c new file mode 100644 index 0000000..0395345 --- /dev/null +++ b/fuzz/fuzz_assert.c @@ -0,0 +1,664 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "fido.h" +#include "fido/es256.h" +#include "fido/rs256.h" +#include "fido/eddsa.h" + +#include "../openbsd-compat/openbsd-compat.h" + +#define TAG_U2F 0x01 +#define TAG_TYPE 0x02 +#define TAG_CDH 0x03 +#define TAG_RP_ID 0x04 +#define TAG_EXT 0x05 +#define TAG_SEED 0x06 +#define TAG_UP 0x07 +#define TAG_UV 0x08 +#define TAG_WIRE_DATA 0x09 +#define TAG_CRED_COUNT 0x0a +#define TAG_CRED 0x0b +#define TAG_ES256 0x0c +#define TAG_RS256 0x0d +#define TAG_PIN 0x0e +#define TAG_EDDSA 0x0f + +/* 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 u2f; + uint8_t up; + uint8_t uv; +}; + +/* Example parameters. */ +static const char dummy_rp_id[] = "localhost"; +static const char dummy_pin[] = "9}4gT:8d=A37Dh}U"; + +static 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, +}; + +static 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, +}; + +static 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, +}; + +static 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, +}; + +/* + * 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[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0xf7, + 0x6f, 0xda, 0x52, 0xfd, 0xcb, 0xb6, 0x24, 0x00, + 0x92, 0x00, 0x0e, 0x02, 0x05, 0x00, 0x02, 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, + 0x00, 0x92, 0x00, 0x0e, 0x90, 0x00, 0x51, 0x00, + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, + 0x20, 0x01, 0x21, 0x58, 0x20, 0xe9, 0x1d, 0x9b, + 0xac, 0x14, 0x25, 0x5f, 0xda, 0x1e, 0x11, 0xdb, + 0xae, 0xc2, 0x90, 0x22, 0xca, 0x32, 0xec, 0x32, + 0xe6, 0x05, 0x15, 0x44, 0xe5, 0xe8, 0xbc, 0x4f, + 0x0a, 0xb6, 0x1a, 0xeb, 0x11, 0x22, 0x58, 0x20, + 0xcc, 0x72, 0xf0, 0x22, 0xe8, 0x28, 0x82, 0xc5, + 0x00, 0x92, 0x00, 0x0e, 0x00, 0xa6, 0x65, 0x6e, + 0xff, 0x1e, 0xe3, 0x7f, 0x27, 0x44, 0x2d, 0xfb, + 0x8d, 0x41, 0xfa, 0x85, 0x0e, 0xcb, 0xda, 0x95, + 0x64, 0x64, 0x9b, 0x1f, 0x34, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x0e, 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, + 0x00, 0x92, 0x00, 0x0e, 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 +}; + +/* + * 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[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x0f, + 0x26, 0x9c, 0xd3, 0x87, 0x0d, 0x7b, 0xf6, 0x00, + 0x00, 0x99, 0x01, 0x02, 0x01, 0x01, 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, 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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 +}; + +int LLVMFuzzerTestOneInput(const uint8_t *, size_t); +size_t LLVMFuzzerCustomMutator(uint8_t *, size_t, size_t, unsigned int); + +static int +unpack(const uint8_t *ptr, size_t len, struct param *p) NO_MSAN +{ + uint8_t **pp = (void *)&ptr; + + if (unpack_byte(TAG_UV, pp, &len, &p->uv) < 0 || + unpack_byte(TAG_UP, pp, &len, &p->up) < 0 || + unpack_byte(TAG_U2F, pp, &len, &p->u2f) < 0 || + unpack_byte(TAG_TYPE, pp, &len, &p->type) < 0 || + unpack_byte(TAG_CRED_COUNT, pp, &len, &p->cred_count) < 0 || + unpack_int(TAG_EXT, pp, &len, &p->ext) < 0 || + unpack_int(TAG_SEED, pp, &len, &p->seed) < 0 || + unpack_string(TAG_RP_ID, pp, &len, p->rp_id) < 0 || + unpack_string(TAG_PIN, pp, &len, p->pin) < 0 || + unpack_blob(TAG_WIRE_DATA, pp, &len, &p->wire_data) < 0 || + unpack_blob(TAG_RS256, pp, &len, &p->rs256) < 0 || + unpack_blob(TAG_ES256, pp, &len, &p->es256) < 0 || + unpack_blob(TAG_EDDSA, pp, &len, &p->eddsa) < 0 || + unpack_blob(TAG_CRED, pp, &len, &p->cred) < 0 || + unpack_blob(TAG_CDH, pp, &len, &p->cdh) < 0) + return (-1); + + return (0); +} + +static size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + const size_t max = len; + + if (pack_byte(TAG_UV, &ptr, &len, p->uv) < 0 || + pack_byte(TAG_UP, &ptr, &len, p->up) < 0 || + pack_byte(TAG_U2F, &ptr, &len, p->u2f) < 0 || + pack_byte(TAG_TYPE, &ptr, &len, p->type) < 0 || + pack_byte(TAG_CRED_COUNT, &ptr, &len, p->cred_count) < 0 || + pack_int(TAG_EXT, &ptr, &len, p->ext) < 0 || + pack_int(TAG_SEED, &ptr, &len, p->seed) < 0 || + pack_string(TAG_RP_ID, &ptr, &len, p->rp_id) < 0 || + pack_string(TAG_PIN, &ptr, &len, p->pin) < 0 || + pack_blob(TAG_WIRE_DATA, &ptr, &len, &p->wire_data) < 0 || + pack_blob(TAG_RS256, &ptr, &len, &p->rs256) < 0 || + pack_blob(TAG_ES256, &ptr, &len, &p->es256) < 0 || + pack_blob(TAG_EDDSA, &ptr, &len, &p->eddsa) < 0 || + pack_blob(TAG_CRED, &ptr, &len, &p->cred) < 0 || + pack_blob(TAG_CDH, &ptr, &len, &p->cdh) < 0) + return (0); + + return (max - len); +} + +static void +get_assert(fido_assert_t *assert, uint8_t u2f, const struct blob *cdh, + const char *rp_id, int ext, uint8_t up, uint8_t uv, const char *pin, + uint8_t cred_count, struct blob *cred) +{ + fido_dev_t *dev; + fido_dev_io_t io; + + io.open = dev_open; + io.close = dev_close; + io.read = dev_read; + io.write = dev_write; + + if ((dev = fido_dev_new()) == NULL || fido_dev_set_io_functions(dev, + &io) != FIDO_OK || fido_dev_open(dev, "nodev") != FIDO_OK) { + fido_dev_free(&dev); + return; + } + + if (u2f & 1) + fido_dev_force_u2f(dev); + + 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); + if (ext & 1) + fido_assert_set_extensions(assert, FIDO_EXT_HMAC_SECRET); + if (up & 1) + fido_assert_set_up(assert, FIDO_OPT_TRUE); + if (uv & 1) + fido_assert_set_uv(assert, FIDO_OPT_TRUE); + /* XXX reuse cred as hmac salt to keep struct param small */ + fido_assert_set_hmac_salt(assert, cred->body, cred->len); + + fido_dev_get_assert(dev, assert, u2f & 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; + + 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); + } + fido_assert_set_extensions(assert, ext); + 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_sig(assert, 0, sig_ptr, sig_len); + fido_assert_verify(assert, 0, type, pk); + + fido_assert_free(&assert); +} + +/* + * Do a dummy conversion to exercise rs256_pk_from_RSA(). + */ +static void +rs256_convert(const rs256_pk_t *k) +{ + EVP_PKEY *pkey = NULL; + rs256_pk_t *pk = NULL; + RSA *rsa = NULL; + volatile int r; + + if ((pkey = rs256_pk_to_EVP_PKEY(k)) == NULL || + (pk = rs256_pk_new()) == NULL || + (rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) + goto out; + + r = rs256_pk_from_RSA(pk, rsa); +out: + if (pk) + rs256_pk_free(&pk); + if (pkey) + 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; + volatile 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); +out: + if (pk) + eddsa_pk_free(&pk); + if (pkey) + EVP_PKEY_free(pkey); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct param p; + fido_assert_t *assert = NULL; + es256_pk_t *es256_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; + + memset(&p, 0, sizeof(p)); + + if (unpack(data, size, &p) < 0) + return (0); + + srandom((unsigned int)p.seed); + + fido_init(0); + + switch (p.type & 3) { + case 0: + cose_alg = COSE_ES256; + + if ((es256_pk = es256_pk_new()) == NULL) + return (0); + + es256_pk_from_ptr(es256_pk, p.es256.body, p.es256.len); + pk = es256_pk; + + break; + case 1: + cose_alg = COSE_RS256; + + if ((rs256_pk = rs256_pk_new()) == NULL) + return (0); + + rs256_pk_from_ptr(rs256_pk, p.rs256.body, p.rs256.len); + pk = rs256_pk; + + rs256_convert(pk); + + break; + default: + cose_alg = COSE_EDDSA; + + if ((eddsa_pk = eddsa_pk_new()) == NULL) + return (0); + + 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.u2f, &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(fido_assert_user_icon(assert, i), + xstrlen(fido_assert_user_icon(assert, i))); + consume(fido_assert_user_name(assert, i), + xstrlen(fido_assert_user_name(assert, i))); + consume(fido_assert_user_display_name(assert, i), + xstrlen(fido_assert_user_display_name(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); + rs256_pk_free(&rs256_pk); + eddsa_pk_free(&eddsa_pk); + + fido_assert_free(&assert); + + return (0); +} + +static size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[16384]; + 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)); + + 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.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); + + blob_len = pack(blob, sizeof(blob), &dummy); + assert(blob_len != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return (len); + } + + memcpy(ptr, blob, blob_len); + + return (blob_len); +} + +size_t +LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxsize, + unsigned int seed) NO_MSAN +{ + struct param p; + uint8_t blob[16384]; + size_t blob_len; + + (void)seed; + + memset(&p, 0, sizeof(p)); + + if (unpack(data, size, &p) < 0) + return (pack_dummy(data, maxsize)); + + mutate_byte(&p.uv); + mutate_byte(&p.up); + mutate_byte(&p.u2f); + mutate_byte(&p.type); + mutate_byte(&p.cred_count); + + mutate_int(&p.ext); + p.seed = (int)seed; + + if (p.u2f & 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); + 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); + + blob_len = pack(blob, sizeof(blob), &p); + + if (blob_len == 0 || blob_len > maxsize) + return (0); + + memcpy(data, blob, blob_len); + + return (blob_len); +} diff --git a/fuzz/fuzz_bio.c b/fuzz/fuzz_bio.c new file mode 100644 index 0000000..f1596a7 --- /dev/null +++ b/fuzz/fuzz_bio.c @@ -0,0 +1,755 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "fido.h" +#include "fido/bio.h" + +#include "../openbsd-compat/openbsd-compat.h" + +#define TAG_PIN 0x01 +#define TAG_NAME 0x02 +#define TAG_SEED 0x03 +#define TAG_ID 0x04 +#define TAG_INFO_WIRE_DATA 0x05 +#define TAG_ENROLL_WIRE_DATA 0x06 +#define TAG_LIST_WIRE_DATA 0x07 +#define TAG_SET_NAME_WIRE_DATA 0x08 +#define TAG_REMOVE_WIRE_DATA 0x09 + +/* 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; +}; + +/* Example parameters. */ +static const uint8_t dummy_id[] = { 0x5e, 0xd2, }; +static const char dummy_pin[] = "3Q;I){TAx"; +static const char dummy_name[] = "finger1"; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'getFingerprintSensorInfo' bio enrollment command. + */ +static const uint8_t dummy_info_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0xf0, + 0x08, 0xc1, 0x8f, 0x76, 0x4b, 0x8f, 0xa9, 0x00, + 0x10, 0x00, 0x04, 0x02, 0x00, 0x04, 0x06, 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, + 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, +}; + +/* + * Collection of HID reports from an authenticator issued with FIDO2 + * 'enrollBegin' + 'enrollCaptureNextSample' bio enrollment commands. + */ +static const uint8_t dummy_enroll_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x06, + 0xb4, 0xba, 0x2e, 0xb3, 0x88, 0x24, 0x38, 0x00, + 0x0a, 0x00, 0x05, 0x02, 0x00, 0x04, 0x06, 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, + 0x00, 0x0a, 0x00, 0x05, 0x90, 0x00, 0x51, 0x00, + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, + 0x20, 0x01, 0x21, 0x58, 0x20, 0xc9, 0x12, 0x01, + 0xab, 0x88, 0xd7, 0x0a, 0x24, 0xdd, 0xdc, 0xde, + 0x16, 0x27, 0x50, 0x77, 0x37, 0x06, 0xd3, 0x48, + 0xe6, 0xf9, 0xdb, 0xaa, 0x10, 0x83, 0x81, 0xac, + 0x13, 0x3c, 0xf9, 0x77, 0x2d, 0x22, 0x58, 0x20, + 0xda, 0x20, 0x71, 0x03, 0x01, 0x40, 0xac, 0xd0, + 0x00, 0x0a, 0x00, 0x05, 0x00, 0xb8, 0xdf, 0x2a, + 0x95, 0xd3, 0x88, 0x1c, 0x06, 0x34, 0x30, 0xf1, + 0xf3, 0xcd, 0x27, 0x40, 0x90, 0x5c, 0xc6, 0x74, + 0x66, 0xff, 0x10, 0xde, 0xb6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 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, 0x14, 0x00, + 0xa1, 0x02, 0x50, 0x18, 0x81, 0xff, 0xf2, 0xf5, + 0xde, 0x74, 0x43, 0xd5, 0xe0, 0x77, 0x37, 0x6b, + 0x6c, 0x18, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 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, 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, 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, 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, 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, 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, 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, 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, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'enumerateEnrollments' bio enrollment command. + */ +static const uint8_t dummy_list_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0xae, + 0x21, 0x88, 0x51, 0x09, 0x6f, 0xd7, 0xbb, 0x00, + 0x10, 0x00, 0x0f, 0x02, 0x00, 0x04, 0x06, 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, + 0x00, 0x10, 0x00, 0x0f, 0x90, 0x00, 0x51, 0x00, + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, + 0x20, 0x01, 0x21, 0x58, 0x20, 0x5a, 0x70, 0x63, + 0x11, 0x5b, 0xa6, 0xe1, 0x8e, 0x4a, 0xb0, 0x75, + 0xe7, 0xfd, 0x39, 0x26, 0x29, 0xed, 0x69, 0xb0, + 0xc1, 0x1f, 0xa5, 0x7d, 0xcb, 0x64, 0x1e, 0x7c, + 0x9f, 0x60, 0x5e, 0xb2, 0xf8, 0x22, 0x58, 0x20, + 0xec, 0xe9, 0x1b, 0x11, 0xac, 0x2a, 0x0d, 0xd5, + 0x00, 0x10, 0x00, 0x0f, 0x00, 0x3b, 0x9f, 0xba, + 0x0f, 0x25, 0xd5, 0x24, 0x33, 0x4c, 0x5d, 0x0f, + 0x63, 0xbf, 0xf1, 0xf3, 0x64, 0x55, 0x78, 0x1a, + 0x59, 0x6e, 0x65, 0x59, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x0f, 0x90, 0x00, 0x14, 0x00, + 0xa1, 0x02, 0x50, 0xb9, 0x31, 0x34, 0xe2, 0x71, + 0x6a, 0x8e, 0xa3, 0x60, 0xec, 0x5e, 0xd2, 0x13, + 0x2e, 0x19, 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, 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 +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'setFriendlyName' bio enrollment command. + */ +static const uint8_t dummy_set_name_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0xac, + 0x48, 0xfd, 0xbd, 0xdd, 0x36, 0x24, 0x4d, 0x00, + 0x10, 0x00, 0x10, 0x02, 0x00, 0x04, 0x06, 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, + 0x00, 0x10, 0x00, 0x10, 0x90, 0x00, 0x51, 0x00, + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, + 0x20, 0x01, 0x21, 0x58, 0x20, 0x5a, 0x70, 0x63, + 0x11, 0x5b, 0xa6, 0xe1, 0x8e, 0x4a, 0xb0, 0x75, + 0xe7, 0xfd, 0x39, 0x26, 0x29, 0xed, 0x69, 0xb0, + 0xc1, 0x1f, 0xa5, 0x7d, 0xcb, 0x64, 0x1e, 0x7c, + 0x9f, 0x60, 0x5e, 0xb2, 0xf8, 0x22, 0x58, 0x20, + 0xec, 0xe9, 0x1b, 0x11, 0xac, 0x2a, 0x0d, 0xd5, + 0x00, 0x10, 0x00, 0x10, 0x00, 0x3b, 0x9f, 0xba, + 0x0f, 0x25, 0xd5, 0x24, 0x33, 0x4c, 0x5d, 0x0f, + 0x63, 0xbf, 0xf1, 0xf3, 0x64, 0x55, 0x78, 0x1a, + 0x59, 0x6e, 0x65, 0x59, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x10, 0x90, 0x00, 0x14, 0x00, + 0xa1, 0x02, 0x50, 0x40, 0x95, 0xf3, 0xcb, 0xae, + 0xf2, 0x8d, 0xd9, 0xe0, 0xe0, 0x8a, 0xbd, 0xc3, + 0x03, 0x58, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x10, 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, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'removeEnrollment' bio enrollment command. + */ +static const uint8_t dummy_remove_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x4b, + 0x24, 0xde, 0xd9, 0x06, 0x57, 0x1a, 0xbd, 0x00, + 0x10, 0x00, 0x15, 0x02, 0x00, 0x04, 0x06, 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, + 0x00, 0x10, 0x00, 0x15, 0x90, 0x00, 0x51, 0x00, + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, + 0x20, 0x01, 0x21, 0x58, 0x20, 0x5a, 0x70, 0x63, + 0x11, 0x5b, 0xa6, 0xe1, 0x8e, 0x4a, 0xb0, 0x75, + 0xe7, 0xfd, 0x39, 0x26, 0x29, 0xed, 0x69, 0xb0, + 0xc1, 0x1f, 0xa5, 0x7d, 0xcb, 0x64, 0x1e, 0x7c, + 0x9f, 0x60, 0x5e, 0xb2, 0xf8, 0x22, 0x58, 0x20, + 0xec, 0xe9, 0x1b, 0x11, 0xac, 0x2a, 0x0d, 0xd5, + 0x00, 0x10, 0x00, 0x15, 0x00, 0x3b, 0x9f, 0xba, + 0x0f, 0x25, 0xd5, 0x24, 0x33, 0x4c, 0x5d, 0x0f, + 0x63, 0xbf, 0xf1, 0xf3, 0x64, 0x55, 0x78, 0x1a, + 0x59, 0x6e, 0x65, 0x59, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x15, 0x90, 0x00, 0x14, 0x00, + 0xa1, 0x02, 0x50, 0xb0, 0xd0, 0x71, 0x2f, 0xa7, + 0x8b, 0x89, 0xbd, 0xca, 0xa4, 0x1e, 0x6c, 0x43, + 0xa1, 0x71, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x15, 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, +}; + +int LLVMFuzzerTestOneInput(const uint8_t *, size_t); +size_t LLVMFuzzerCustomMutator(uint8_t *, size_t, size_t, unsigned int); + +static int +unpack(const uint8_t *ptr, size_t len, struct param *p) NO_MSAN +{ + uint8_t **pp = (void *)&ptr; + + if (unpack_string(TAG_PIN, pp, &len, p->pin) < 0 || + unpack_string(TAG_NAME, pp, &len, p->name) < 0 || + unpack_int(TAG_SEED, pp, &len, &p->seed) < 0 || + unpack_blob(TAG_ID, pp, &len, &p->id) < 0 || + unpack_blob(TAG_INFO_WIRE_DATA, pp, &len, &p->info_wire_data) < 0 || + unpack_blob(TAG_ENROLL_WIRE_DATA, pp, &len, &p->enroll_wire_data) < 0 || + unpack_blob(TAG_LIST_WIRE_DATA, pp, &len, &p->list_wire_data) < 0 || + unpack_blob(TAG_SET_NAME_WIRE_DATA, pp, &len, &p->set_name_wire_data) < 0 || + unpack_blob(TAG_REMOVE_WIRE_DATA, pp, &len, &p->remove_wire_data) < 0) + return (-1); + + return (0); +} + +static size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + const size_t max = len; + + if (pack_string(TAG_PIN, &ptr, &len, p->pin) < 0 || + pack_string(TAG_NAME, &ptr, &len, p->name) < 0 || + pack_int(TAG_SEED, &ptr, &len, p->seed) < 0 || + pack_blob(TAG_ID, &ptr, &len, &p->id) < 0 || + pack_blob(TAG_INFO_WIRE_DATA, &ptr, &len, &p->info_wire_data) < 0 || + pack_blob(TAG_ENROLL_WIRE_DATA, &ptr, &len, &p->enroll_wire_data) < 0 || + pack_blob(TAG_LIST_WIRE_DATA, &ptr, &len, &p->list_wire_data) < 0 || + pack_blob(TAG_SET_NAME_WIRE_DATA, &ptr, &len, &p->set_name_wire_data) < 0 || + pack_blob(TAG_REMOVE_WIRE_DATA, &ptr, &len, &p->remove_wire_data) < 0) + return (0); + + return (max - len); +} + +static fido_dev_t * +prepare_dev() +{ + fido_dev_t *dev; + fido_dev_io_t io; + + io.open = dev_open; + io.close = dev_close; + io.read = dev_read; + io.write = dev_write; + + if ((dev = fido_dev_new()) == NULL || fido_dev_set_io_functions(dev, + &io) != FIDO_OK || fido_dev_open(dev, "nodev") != FIDO_OK) { + fido_dev_free(&dev); + return (NULL); + } + + return (dev); +} + +static void +get_info(struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_info_t *i = NULL; + uint8_t type; + uint8_t max_samples; + + 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; + + fido_bio_dev_get_info(dev, i); + + 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(fido_bio_template_name(t), xstrlen(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(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, 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(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(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(struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_template_t *t = NULL; + + 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; + + fido_bio_template_set_id(t, p->id.body, p->id.len); + consume_template(t); + + 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); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct param p; + + memset(&p, 0, sizeof(p)); + + if (unpack(data, size, &p) < 0) + return (0); + + srandom((unsigned int)p.seed); + + fido_init(0); + + get_info(&p); + enroll(&p); + list(&p); + set_name(&p); + del(&p); + + return (0); +} + +static size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[32768]; + 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); + + blob_len = pack(blob, sizeof(blob), &dummy); + assert(blob_len != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return (len); + } + + memcpy(ptr, blob, blob_len); + + return (blob_len); +} + +size_t +LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxsize, + unsigned int seed) NO_MSAN +{ + struct param p; + uint8_t blob[16384]; + size_t blob_len; + + memset(&p, 0, sizeof(p)); + + if (unpack(data, size, &p) < 0) + return (pack_dummy(data, maxsize)); + + p.seed = (int)seed; + + mutate_blob(&p.id); + 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); + + mutate_string(p.pin); + mutate_string(p.name); + + blob_len = pack(blob, sizeof(blob), &p); + + if (blob_len == 0 || blob_len > maxsize) + return (0); + + memcpy(data, blob, blob_len); + + return (blob_len); +} diff --git a/fuzz/fuzz_cred.c b/fuzz/fuzz_cred.c new file mode 100644 index 0000000..7bd1d3c --- /dev/null +++ b/fuzz/fuzz_cred.c @@ -0,0 +1,925 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "fido.h" + +#include "../openbsd-compat/openbsd-compat.h" + +#define TAG_U2F 0x01 +#define TAG_TYPE 0x02 +#define TAG_CDH 0x03 +#define TAG_RP_ID 0x04 +#define TAG_RP_NAME 0x05 +#define TAG_USER_ID 0x06 +#define TAG_USER_NAME 0x07 +#define TAG_USER_NICK 0x08 +#define TAG_USER_ICON 0x09 +#define TAG_EXT 0x0a +#define TAG_SEED 0x0b +#define TAG_RK 0x0c +#define TAG_UV 0x0d +#define TAG_PIN 0x0e +#define TAG_WIRE_DATA 0x0f +#define TAG_EXCL_COUNT 0x10 +#define TAG_EXCL_CRED 0x11 + +/* 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 u2f; + uint8_t uv; +}; + +/* Example parameters. */ +static const char dummy_rp_id[] = "localhost"; +static const char dummy_rp_name[] = "sweet home localhost"; +static const char dummy_pin[] = "9}4gT:8d=A37Dh}U"; +static const char dummy_user_icon[] = "an icon"; +static const char dummy_user_name[] = "john smith"; +static const char dummy_user_nick[] = "jsmith"; + +static const uint8_t dummy_cdh[] = { + 0xf9, 0x64, 0x57, 0xe7, 0x2d, 0x97, 0xf6, 0xbb, + 0xdd, 0xd7, 0xfb, 0x06, 0x37, 0x62, 0xea, 0x26, + 0x20, 0x44, 0x8e, 0x69, 0x7c, 0x03, 0xf2, 0x31, + 0x2f, 0x99, 0xdc, 0xaf, 0x3e, 0x8a, 0x91, 0x6b, +}; + +static 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, +}; + +/* + * 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[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0xb0, + 0x84, 0xeb, 0xec, 0x4d, 0x97, 0x72, 0x09, 0x00, + 0x91, 0x00, 0x03, 0x02, 0x05, 0x00, 0x02, 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, + 0x00, 0x91, 0x00, 0x03, 0x90, 0x00, 0x51, 0x00, + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, + 0x20, 0x01, 0x21, 0x58, 0x20, 0x69, 0xf2, 0x7d, + 0x37, 0x57, 0xda, 0x11, 0xba, 0x42, 0xde, 0x79, + 0xe4, 0xab, 0x8d, 0x73, 0x63, 0xee, 0x66, 0x9e, + 0x8a, 0x70, 0xa9, 0xb5, 0xf6, 0x38, 0x4f, 0x5b, + 0xdf, 0xe1, 0xa0, 0xa4, 0xff, 0x22, 0x58, 0x20, + 0x8a, 0xcb, 0x23, 0x2e, 0x93, 0xdb, 0xe0, 0xa4, + 0x00, 0x91, 0x00, 0x03, 0x00, 0xbb, 0xb5, 0x60, + 0x19, 0x18, 0x8b, 0x4d, 0xb8, 0x88, 0x6e, 0x13, + 0x75, 0xac, 0x00, 0x19, 0x27, 0x80, 0xcc, 0x63, + 0xc4, 0xbf, 0xfe, 0x4b, 0x4a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x03, 0x90, 0x00, 0x14, 0x00, + 0xa1, 0x02, 0x50, 0x10, 0x89, 0x77, 0x43, 0x3a, + 0x58, 0xa2, 0xc9, 0x98, 0x18, 0x1a, 0xb1, 0xcc, + 0x09, 0x6b, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x03, 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, 0x91, 0x00, 0x03, 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, 0x91, 0x00, 0x03, 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, 0x91, 0x00, 0x03, 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, 0x91, 0x00, 0x03, 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, 0x91, 0x00, 0x03, 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, 0x91, 0x00, 0x03, 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, 0x91, 0x00, 0x03, 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, 0x91, 0x00, 0x03, 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, 0x91, 0x00, 0x03, 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, 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, +}; + +/* + * 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[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x8e, + 0x80, 0xd0, 0xe2, 0x3b, 0x24, 0x93, 0xea, 0x00, + 0x00, 0x99, 0x01, 0x02, 0x01, 0x01, 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, 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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 +}; + +int LLVMFuzzerTestOneInput(const uint8_t *, size_t); +size_t LLVMFuzzerCustomMutator(uint8_t *, size_t, size_t, unsigned int); + +static int +unpack(const uint8_t *ptr, size_t len, struct param *p) NO_MSAN +{ + uint8_t **pp = (void *)&ptr; + + if (unpack_byte(TAG_RK, pp, &len, &p->rk) < 0 || + unpack_byte(TAG_TYPE, pp, &len, &p->type) < 0 || + unpack_byte(TAG_U2F, pp, &len, &p->u2f) < 0 || + unpack_byte(TAG_UV, pp, &len, &p->uv) < 0 || + unpack_byte(TAG_EXCL_COUNT, pp, &len, &p->excl_count) < 0 || + unpack_string(TAG_PIN, pp, &len, p->pin) < 0 || + unpack_string(TAG_RP_ID, pp, &len, p->rp_id) < 0 || + unpack_string(TAG_RP_NAME, pp, &len, p->rp_name) < 0 || + unpack_string(TAG_USER_ICON, pp, &len, p->user_icon) < 0 || + unpack_string(TAG_USER_NAME, pp, &len, p->user_name) < 0 || + unpack_string(TAG_USER_NICK, pp, &len, p->user_nick) < 0 || + unpack_int(TAG_EXT, pp, &len, &p->ext) < 0 || + unpack_int(TAG_SEED, pp, &len, &p->seed) < 0 || + unpack_blob(TAG_CDH, pp, &len, &p->cdh) < 0 || + unpack_blob(TAG_USER_ID, pp, &len, &p->user_id) < 0 || + unpack_blob(TAG_WIRE_DATA, pp, &len, &p->wire_data) < 0 || + unpack_blob(TAG_EXCL_CRED, pp, &len, &p->excl_cred) < 0) + return (-1); + + return (0); +} + +static size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + const size_t max = len; + + if (pack_byte(TAG_RK, &ptr, &len, p->rk) < 0 || + pack_byte(TAG_TYPE, &ptr, &len, p->type) < 0 || + pack_byte(TAG_U2F, &ptr, &len, p->u2f) < 0 || + pack_byte(TAG_UV, &ptr, &len, p->uv) < 0 || + pack_byte(TAG_EXCL_COUNT, &ptr, &len, p->excl_count) < 0 || + pack_string(TAG_PIN, &ptr, &len, p->pin) < 0 || + pack_string(TAG_RP_ID, &ptr, &len, p->rp_id) < 0 || + pack_string(TAG_RP_NAME, &ptr, &len, p->rp_name) < 0 || + pack_string(TAG_USER_ICON, &ptr, &len, p->user_icon) < 0 || + pack_string(TAG_USER_NAME, &ptr, &len, p->user_name) < 0 || + pack_string(TAG_USER_NICK, &ptr, &len, p->user_nick) < 0 || + pack_int(TAG_EXT, &ptr, &len, p->ext) < 0 || + pack_int(TAG_SEED, &ptr, &len, p->seed) < 0 || + pack_blob(TAG_CDH, &ptr, &len, &p->cdh) < 0 || + pack_blob(TAG_USER_ID, &ptr, &len, &p->user_id) < 0 || + pack_blob(TAG_WIRE_DATA, &ptr, &len, &p->wire_data) < 0 || + pack_blob(TAG_EXCL_CRED, &ptr, &len, &p->excl_cred) < 0) + return (0); + + return (max - len); +} + +static void +make_cred(fido_cred_t *cred, uint8_t u2f, int type, const struct blob *cdh, + const char *rp_id, const char *rp_name, 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, + struct blob *excl_cred) +{ + fido_dev_t *dev; + fido_dev_io_t io; + + io.open = dev_open; + io.close = dev_close; + io.read = dev_read; + io.write = dev_write; + + if ((dev = fido_dev_new()) == NULL || fido_dev_set_io_functions(dev, + &io) != FIDO_OK || fido_dev_open(dev, "nodev") != FIDO_OK) { + fido_dev_free(&dev); + return; + } + + if (u2f & 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); + fido_cred_set_extensions(cred, ext); + if (rk & 1) + fido_cred_set_rk(cred, FIDO_OPT_TRUE); + if (uv & 1) + fido_cred_set_uv(cred, FIDO_OPT_TRUE); + + fido_dev_make_cred(dev, cred, u2f & 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, 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 char *fmt) +{ + fido_cred_t *cred; + uint8_t flags; + + if ((cred = fido_cred_new()) == NULL) { + warnx("%s: fido_cred_new", __func__); + 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); + if (fido_cred_set_authdata(cred, authdata_ptr, authdata_len) != FIDO_OK) + fido_cred_set_authdata_raw(cred, authdata_ptr, authdata_len); + fido_cred_set_extensions(cred, ext); + fido_cred_set_x509(cred, x5c_ptr, x5c_len); + fido_cred_set_sig(cred, sig_ptr, sig_len); + + 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); + + fido_cred_verify(cred); + fido_cred_verify_self(cred); + + 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_user_id_ptr(cred), fido_cred_user_id_len(cred)); + consume(fido_cred_user_name(cred), xstrlen(fido_cred_user_name(cred))); + consume(fido_cred_display_name(cred), + xstrlen(fido_cred_display_name(cred))); + + flags = fido_cred_flags(cred); + consume(&flags, sizeof(flags)); + type = fido_cred_type(cred); + consume(&type, sizeof(type)); + + fido_cred_free(&cred); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct param p; + fido_cred_t *cred = NULL; + int cose_alg = 0; + + memset(&p, 0, sizeof(p)); + + if (unpack(data, size, &p) < 0) + return (0); + + srandom((unsigned int)p.seed); + + fido_init(0); + + if ((cred = fido_cred_new()) == NULL) + return (0); + + set_wire_data(p.wire_data.body, p.wire_data.len); + + switch (p.type & 3) { + case 0: + cose_alg = COSE_ES256; + break; + case 1: + cose_alg = COSE_RS256; + break; + default: + cose_alg = COSE_EDDSA; + break; + } + + make_cred(cred, p.u2f, 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), 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_fmt(cred)); + + fido_cred_free(&cred); + + return (0); +} + +static size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[16384]; + 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); + + blob_len = pack(blob, sizeof(blob), &dummy); + assert(blob_len != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return (len); + } + + memcpy(ptr, blob, blob_len); + + return (blob_len); +} + +size_t +LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxsize, + unsigned int seed) NO_MSAN +{ + struct param p; + uint8_t blob[16384]; + size_t blob_len; + + memset(&p, 0, sizeof(p)); + + if (unpack(data, size, &p) < 0) + return (pack_dummy(data, maxsize)); + + mutate_byte(&p.rk); + mutate_byte(&p.type); + mutate_byte(&p.u2f); + mutate_byte(&p.uv); + mutate_byte(&p.excl_count); + + mutate_int(&p.ext); + p.seed = (int)seed; + + mutate_blob(&p.cdh); + mutate_blob(&p.user_id); + + if (p.u2f & 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); + 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); + + blob_len = pack(blob, sizeof(blob), &p); + + if (blob_len == 0 || blob_len > maxsize) + return (0); + + memcpy(data, blob, blob_len); + + return (blob_len); +} diff --git a/fuzz/fuzz_credman.c b/fuzz/fuzz_credman.c new file mode 100644 index 0000000..4359938 --- /dev/null +++ b/fuzz/fuzz_credman.c @@ -0,0 +1,667 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "fido.h" +#include "fido/credman.h" + +#include "../openbsd-compat/openbsd-compat.h" + +#define TAG_META_WIRE_DATA 0x01 +#define TAG_RP_WIRE_DATA 0x02 +#define TAG_RK_WIRE_DATA 0x03 +#define TAG_DEL_WIRE_DATA 0x04 +#define TAG_CRED_ID 0x05 +#define TAG_PIN 0x06 +#define TAG_RP_ID 0x07 +#define TAG_SEED 0x08 + +/* 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; +}; + +/* Example parameters. */ +static const uint8_t dummy_cred_id[] = { + 0x4f, 0x72, 0x98, 0x42, 0x4a, 0xe1, 0x17, 0xa5, + 0x85, 0xa0, 0xef, 0x3b, 0x11, 0x24, 0x4a, 0x3d, +}; +static const char dummy_pin[] = "[n#899:~m"; +static const char dummy_rp_id[] = "yubico.com"; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'getCredsMetadata' credential management command. + */ +static const uint8_t dummy_meta_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0xc5, + 0xb7, 0x89, 0xba, 0x8d, 0x5f, 0x94, 0x1b, 0x00, + 0x12, 0x00, 0x04, 0x02, 0x00, 0x04, 0x05, 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, + 0x00, 0x12, 0x00, 0x04, 0x90, 0x00, 0x51, 0x00, + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, + 0x20, 0x01, 0x21, 0x58, 0x20, 0x93, 0xc5, 0x64, + 0x71, 0xe9, 0xd1, 0xb8, 0xed, 0xf6, 0xd5, 0xf3, + 0xa7, 0xd5, 0x96, 0x70, 0xbb, 0xd5, 0x20, 0xa1, + 0xa3, 0xd3, 0x93, 0x4c, 0x5c, 0x20, 0x5c, 0x22, + 0xeb, 0xb0, 0x6a, 0x27, 0x59, 0x22, 0x58, 0x20, + 0x63, 0x02, 0x33, 0xa8, 0xed, 0x3c, 0xbc, 0xe9, + 0x00, 0x12, 0x00, 0x04, 0x00, 0xda, 0x44, 0xf5, + 0xed, 0xda, 0xe6, 0xa4, 0xad, 0x3f, 0x9e, 0xf8, + 0x50, 0x8d, 0x01, 0x47, 0x6c, 0x4e, 0x72, 0xa4, + 0x04, 0x13, 0xa8, 0x65, 0x97, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x04, 0x90, 0x00, 0x14, 0x00, + 0xa1, 0x02, 0x50, 0x6f, 0x11, 0x96, 0x21, 0x92, + 0x52, 0xf1, 0x6b, 0xd4, 0x2c, 0xe3, 0xf8, 0xc9, + 0x8c, 0x47, 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, 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, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'enumerateRPsBegin' credential management command. + */ +static const uint8_t dummy_rp_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x87, + 0xbf, 0xc6, 0x7f, 0x36, 0xf5, 0xe2, 0x49, 0x00, + 0x15, 0x00, 0x02, 0x02, 0x00, 0x04, 0x05, 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, + 0x00, 0x15, 0x00, 0x02, 0x90, 0x00, 0x51, 0x00, + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, + 0x20, 0x01, 0x21, 0x58, 0x20, 0x12, 0xc1, 0x81, + 0x6b, 0x92, 0x6a, 0x56, 0x05, 0xfe, 0xdb, 0xab, + 0x90, 0x2f, 0x57, 0x0b, 0x3d, 0x85, 0x3e, 0x3f, + 0xbc, 0xe5, 0xd3, 0xb6, 0x86, 0xdf, 0x10, 0x43, + 0xc2, 0xaf, 0x87, 0x34, 0x0e, 0x22, 0x58, 0x20, + 0xd3, 0x0f, 0x7e, 0x5d, 0x10, 0x33, 0x57, 0x24, + 0x00, 0x15, 0x00, 0x02, 0x00, 0x6e, 0x90, 0x58, + 0x61, 0x2a, 0xd2, 0xc2, 0x1e, 0x08, 0xea, 0x91, + 0xcb, 0x44, 0x66, 0x73, 0x29, 0x92, 0x29, 0x59, + 0x91, 0xa3, 0x4d, 0x2c, 0xbb, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 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, 0x02, 0x90, 0x00, 0x14, 0x00, + 0xa1, 0x02, 0x50, 0x6d, 0x95, 0x0e, 0x73, 0x78, + 0x46, 0x13, 0x2e, 0x07, 0xbf, 0xeb, 0x61, 0x31, + 0x37, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 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, 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, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'enumerateCredentialsBegin' credential management command. + */ +static const uint8_t dummy_rk_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x35, + 0x3b, 0x34, 0xb9, 0xcb, 0xeb, 0x40, 0x55, 0x00, + 0x15, 0x00, 0x04, 0x02, 0x00, 0x04, 0x05, 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, + 0x00, 0x15, 0x00, 0x04, 0x90, 0x00, 0x51, 0x00, + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, + 0x20, 0x01, 0x21, 0x58, 0x20, 0x12, 0xc1, 0x81, + 0x6b, 0x92, 0x6a, 0x56, 0x05, 0xfe, 0xdb, 0xab, + 0x90, 0x2f, 0x57, 0x0b, 0x3d, 0x85, 0x3e, 0x3f, + 0xbc, 0xe5, 0xd3, 0xb6, 0x86, 0xdf, 0x10, 0x43, + 0xc2, 0xaf, 0x87, 0x34, 0x0e, 0x22, 0x58, 0x20, + 0xd3, 0x0f, 0x7e, 0x5d, 0x10, 0x33, 0x57, 0x24, + 0x00, 0x15, 0x00, 0x04, 0x00, 0x6e, 0x90, 0x58, + 0x61, 0x2a, 0xd2, 0xc2, 0x1e, 0x08, 0xea, 0x91, + 0xcb, 0x44, 0x66, 0x73, 0x29, 0x92, 0x29, 0x59, + 0x91, 0xa3, 0x4d, 0x2c, 0xbb, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 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, 0x14, 0x00, + 0xa1, 0x02, 0x50, 0x1b, 0xf0, 0x01, 0x0d, 0x32, + 0xee, 0x28, 0xa4, 0x5a, 0x7f, 0x56, 0x5b, 0x28, + 0xfd, 0x1f, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 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, 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, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'deleteCredential' credential management command. + */ +static const uint8_t dummy_del_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x8b, + 0xe1, 0xf0, 0x3a, 0x18, 0xa5, 0xda, 0x59, 0x00, + 0x15, 0x00, 0x05, 0x02, 0x00, 0x04, 0x05, 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, + 0x00, 0x15, 0x00, 0x05, 0x90, 0x00, 0x51, 0x00, + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, + 0x20, 0x01, 0x21, 0x58, 0x20, 0x12, 0xc1, 0x81, + 0x6b, 0x92, 0x6a, 0x56, 0x05, 0xfe, 0xdb, 0xab, + 0x90, 0x2f, 0x57, 0x0b, 0x3d, 0x85, 0x3e, 0x3f, + 0xbc, 0xe5, 0xd3, 0xb6, 0x86, 0xdf, 0x10, 0x43, + 0xc2, 0xaf, 0x87, 0x34, 0x0e, 0x22, 0x58, 0x20, + 0xd3, 0x0f, 0x7e, 0x5d, 0x10, 0x33, 0x57, 0x24, + 0x00, 0x15, 0x00, 0x05, 0x00, 0x6e, 0x90, 0x58, + 0x61, 0x2a, 0xd2, 0xc2, 0x1e, 0x08, 0xea, 0x91, + 0xcb, 0x44, 0x66, 0x73, 0x29, 0x92, 0x29, 0x59, + 0x91, 0xa3, 0x4d, 0x2c, 0xbb, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 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, 0x05, 0x90, 0x00, 0x14, 0x00, + 0xa1, 0x02, 0x50, 0x33, 0xf1, 0x3b, 0xde, 0x1e, + 0xa5, 0xd1, 0xbf, 0xf6, 0x5d, 0x63, 0xb6, 0xfc, + 0xd2, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 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, 0x05, 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, +}; + +int LLVMFuzzerTestOneInput(const uint8_t *, size_t); +size_t LLVMFuzzerCustomMutator(uint8_t *, size_t, size_t, unsigned int); + +static int +unpack(const uint8_t *ptr, size_t len, struct param *p) NO_MSAN +{ + uint8_t **pp = (void *)&ptr; + + if (unpack_string(TAG_PIN, pp, &len, p->pin) < 0 || + unpack_string(TAG_RP_ID, pp, &len, p->rp_id) < 0 || + unpack_blob(TAG_CRED_ID, pp, &len, &p->cred_id) < 0 || + unpack_blob(TAG_META_WIRE_DATA, pp, &len, &p->meta_wire_data) < 0 || + unpack_blob(TAG_RP_WIRE_DATA, pp, &len, &p->rp_wire_data) < 0 || + unpack_blob(TAG_RK_WIRE_DATA, pp, &len, &p->rk_wire_data) < 0 || + unpack_blob(TAG_DEL_WIRE_DATA, pp, &len, &p->del_wire_data) < 0 || + unpack_int(TAG_SEED, pp, &len, &p->seed) < 0) + return (-1); + + return (0); +} + +static size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + const size_t max = len; + + if (pack_string(TAG_PIN, &ptr, &len, p->pin) < 0 || + pack_string(TAG_RP_ID, &ptr, &len, p->rp_id) < 0 || + pack_blob(TAG_CRED_ID, &ptr, &len, &p->cred_id) < 0 || + pack_blob(TAG_META_WIRE_DATA, &ptr, &len, &p->meta_wire_data) < 0 || + pack_blob(TAG_RP_WIRE_DATA, &ptr, &len, &p->rp_wire_data) < 0 || + pack_blob(TAG_RK_WIRE_DATA, &ptr, &len, &p->rk_wire_data) < 0 || + pack_blob(TAG_DEL_WIRE_DATA, &ptr, &len, &p->del_wire_data) < 0 || + pack_int(TAG_SEED, &ptr, &len, p->seed) < 0) + return (0); + + return (max - len); +} + +static fido_dev_t * +prepare_dev() +{ + fido_dev_t *dev; + fido_dev_io_t io; + + io.open = dev_open; + io.close = dev_close; + io.read = dev_read; + io.write = dev_write; + + if ((dev = fido_dev_new()) == NULL || fido_dev_set_io_functions(dev, + &io) != FIDO_OK || fido_dev_open(dev, "nodev") != FIDO_OK) { + fido_dev_free(&dev); + return (NULL); + } + + return (dev); +} + +static void +get_metadata(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(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(fido_credman_rp_id(rp, i), + xstrlen(fido_credman_rp_id(rp, i))); + consume(fido_credman_rp_name(rp, i), + xstrlen(fido_credman_rp_name(rp, i))); + } + + fido_credman_rp_free(&rp); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +get_rk_list(struct param *p) +{ + fido_dev_t *dev; + fido_credman_rk_t *rk; + const fido_cred_t *cred; + int type; + + 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; + } + type = fido_cred_type(cred); + consume(&type, sizeof(type)); + 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(fido_cred_user_name(cred), + xstrlen(fido_cred_user_name(cred))); + consume(fido_cred_display_name(cred), + xstrlen(fido_cred_display_name(cred))); + } + + fido_credman_rk_free(&rk); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +del_rk(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); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct param p; + + memset(&p, 0, sizeof(p)); + + if (unpack(data, size, &p) < 0) + return (0); + + srandom((unsigned int)p.seed); + + fido_init(0); + + get_metadata(&p); + get_rp_list(&p); + get_rk_list(&p); + del_rk(&p); + + return (0); +} + +static size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[32768]; + 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); + + blob_len = pack(blob, sizeof(blob), &dummy); + assert(blob_len != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return (len); + } + + memcpy(ptr, blob, blob_len); + + return (blob_len); +} + +size_t +LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxsize, + unsigned int seed) NO_MSAN +{ + struct param p; + uint8_t blob[16384]; + size_t blob_len; + + memset(&p, 0, sizeof(p)); + + if (unpack(data, size, &p) < 0) + return (pack_dummy(data, maxsize)); + + p.seed = (int)seed; + + mutate_blob(&p.cred_id); + mutate_blob(&p.meta_wire_data); + mutate_blob(&p.rp_wire_data); + mutate_blob(&p.rk_wire_data); + mutate_blob(&p.del_wire_data); + + mutate_string(p.pin); + mutate_string(p.rp_id); + + blob_len = pack(blob, sizeof(blob), &p); + + if (blob_len == 0 || blob_len > maxsize) + return (0); + + memcpy(data, blob, blob_len); + + return (blob_len); +} diff --git a/fuzz/fuzz_mgmt.c b/fuzz/fuzz_mgmt.c new file mode 100644 index 0000000..741b375 --- /dev/null +++ b/fuzz/fuzz_mgmt.c @@ -0,0 +1,529 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "fido.h" + +#include "../openbsd-compat/openbsd-compat.h" + +#define TAG_PIN1 0x01 +#define TAG_PIN2 0x02 +#define TAG_RESET_WIRE_DATA 0x03 +#define TAG_INFO_WIRE_DATA 0x04 +#define TAG_SET_PIN_WIRE_DATA 0x05 +#define TAG_CHANGE_PIN_WIRE_DATA 0x06 +#define TAG_RETRY_WIRE_DATA 0x07 +#define TAG_SEED 0x08 + +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; + int seed; +}; + +/* Example parameters. */ +static const char dummy_pin1[] = "skepp cg0u3;Y.."; +static const char dummy_pin2[] = "bastilha 6rJrfQZI."; + +static const uint8_t dummy_reset_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x91, + 0xef, 0xbe, 0x74, 0x39, 0x1a, 0x1c, 0x4a, 0x00, + 0x22, 0x00, 0x01, 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, + 0x00, 0x22, 0x00, 0x01, 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, 0x22, 0x00, 0x01, 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, 0x22, 0x00, 0x01, 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, 0x22, 0x00, 0x01, 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, 0x22, 0x00, 0x01, 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, 0x22, 0x00, 0x01, 0xbb, 0x00, 0x01, 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, 0x22, 0x00, 0x01, 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 +}; + +static const uint8_t dummy_info_wire_data[] = { + 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, + 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 +}; + +static const uint8_t dummy_set_pin_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x59, + 0x50, 0x8c, 0x27, 0x14, 0x83, 0x43, 0xd5, 0x00, + 0x22, 0x00, 0x03, 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, + 0x00, 0x22, 0x00, 0x03, 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, 0x03, 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, + 0x00, 0x22, 0x00, 0x03, 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 +}; + +static const uint8_t dummy_change_pin_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x48, + 0xfd, 0xf9, 0xde, 0x28, 0x21, 0x99, 0xd5, 0x00, + 0x22, 0x00, 0x04, 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, + 0x00, 0x22, 0x00, 0x04, 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, 0x04, 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, + 0x00, 0x22, 0x00, 0x04, 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 +}; + +static const uint8_t dummy_retry_wire_data[] = { + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x7f, + 0xaa, 0x73, 0x3e, 0x95, 0x98, 0xa8, 0x60, 0x00, + 0x22, 0x00, 0x05, 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, + 0x00, 0x22, 0x00, 0x05, 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 +}; + +int LLVMFuzzerTestOneInput(const uint8_t *, size_t); +size_t LLVMFuzzerCustomMutator(uint8_t *, size_t, size_t, unsigned int); + +static int +unpack(const uint8_t *ptr, size_t len, struct param *p) NO_MSAN +{ + uint8_t **pp = (void *)&ptr; + + if (unpack_string(TAG_PIN1, pp, &len, p->pin1) < 0 || + unpack_string(TAG_PIN2, pp, &len, p->pin2) < 0 || + unpack_blob(TAG_RESET_WIRE_DATA, pp, &len, &p->reset_wire_data) < 0 || + unpack_blob(TAG_INFO_WIRE_DATA, pp, &len, &p->info_wire_data) < 0 || + unpack_blob(TAG_SET_PIN_WIRE_DATA, pp, &len, &p->set_pin_wire_data) < 0 || + unpack_blob(TAG_CHANGE_PIN_WIRE_DATA, pp, &len, &p->change_pin_wire_data) < 0 || + unpack_blob(TAG_RETRY_WIRE_DATA, pp, &len, &p->retry_wire_data) < 0 || + unpack_int(TAG_SEED, pp, &len, &p->seed) < 0) + return (-1); + + return (0); +} + +static size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + const size_t max = len; + + if (pack_string(TAG_PIN1, &ptr, &len, p->pin1) < 0 || + pack_string(TAG_PIN2, &ptr, &len, p->pin2) < 0 || + pack_blob(TAG_RESET_WIRE_DATA, &ptr, &len, &p->reset_wire_data) < 0 || + pack_blob(TAG_INFO_WIRE_DATA, &ptr, &len, &p->info_wire_data) < 0 || + pack_blob(TAG_SET_PIN_WIRE_DATA, &ptr, &len, &p->set_pin_wire_data) < 0 || + pack_blob(TAG_CHANGE_PIN_WIRE_DATA, &ptr, &len, &p->change_pin_wire_data) < 0 || + pack_blob(TAG_RETRY_WIRE_DATA, &ptr, &len, &p->retry_wire_data) < 0 || + pack_int(TAG_SEED, &ptr, &len, p->seed) < 0) + return (0); + + return (max - len); +} + +static fido_dev_t * +prepare_dev() +{ + fido_dev_t *dev; + fido_dev_io_t io; + + io.open = dev_open; + io.close = dev_close; + io.read = dev_read; + io.write = dev_write; + + if ((dev = fido_dev_new()) == NULL || fido_dev_set_io_functions(dev, + &io) != FIDO_OK || fido_dev_open(dev, "nodev") != FIDO_OK) { + fido_dev_free(&dev); + return (NULL); + } + + return (dev); +} + +static void +dev_reset(struct param *p) +{ + fido_dev_t *dev; + + set_wire_data(p->reset_wire_data.body, p->reset_wire_data.len); + + if ((dev = prepare_dev()) == NULL) { + return; + } + + fido_dev_reset(dev); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_get_cbor_info(struct param *p) +{ + fido_dev_t *dev; + fido_cbor_info_t *ci; + uint64_t n; + uint8_t proto; + uint8_t major; + uint8_t minor; + uint8_t build; + uint8_t flags; + + set_wire_data(p->info_wire_data.body, p->info_wire_data.len); + + if ((dev = prepare_dev()) == 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) { + fido_dev_close(dev); + fido_dev_free(&dev); + return; + } + + fido_dev_get_cbor_info(dev, ci); + fido_dev_close(dev); + fido_dev_free(&dev); + + 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_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])); + } + + n = fido_cbor_info_maxmsgsiz(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)); + + fido_cbor_info_free(&ci); +} + +static void +dev_set_pin(struct param *p) +{ + fido_dev_t *dev; + + set_wire_data(p->set_pin_wire_data.body, p->set_pin_wire_data.len); + + if ((dev = prepare_dev()) == NULL) { + return; + } + + fido_dev_set_pin(dev, p->pin1, NULL); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_change_pin(struct param *p) +{ + fido_dev_t *dev; + + set_wire_data(p->change_pin_wire_data.body, p->change_pin_wire_data.len); + + if ((dev = prepare_dev()) == 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(struct param *p) +{ + fido_dev_t *dev; + int n; + + set_wire_data(p->retry_wire_data.body, p->retry_wire_data.len); + + if ((dev = prepare_dev()) == NULL) { + return; + } + + fido_dev_get_retry_count(dev, &n); + consume(&n, sizeof(n)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct param p; + + memset(&p, 0, sizeof(p)); + + if (unpack(data, size, &p) < 0) + return (0); + + srandom((unsigned int)p.seed); + + fido_init(0); + + dev_reset(&p); + dev_get_cbor_info(&p); + dev_set_pin(&p); + dev_change_pin(&p); + dev_get_retry_count(&p); + + return (0); +} + +static size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[16384]; + 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); + + 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); + + blob_len = pack(blob, sizeof(blob), &dummy); + assert(blob_len != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return (len); + } + + memcpy(ptr, blob, blob_len); + + return (blob_len); +} + +size_t +LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxsize, + unsigned int seed) +{ + struct param p; + uint8_t blob[16384]; + size_t blob_len; + + memset(&p, 0, sizeof(p)); + + if (unpack(data, size, &p) < 0) + return (pack_dummy(data, maxsize)); + + p.seed = (int)seed; + + mutate_string(p.pin1); + mutate_string(p.pin2); + + 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); + + blob_len = pack(blob, sizeof(blob), &p); + + if (blob_len == 0 || blob_len > maxsize) + return (0); + + memcpy(data, blob, blob_len); + + return (blob_len); +} diff --git a/fuzz/harnesses/assert b/fuzz/harnesses/assert new file mode 100755 index 0000000..55cd889 --- /dev/null +++ b/fuzz/harnesses/assert @@ -0,0 +1,32 @@ +#!/bin/bash -u +# 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. + +T=assert + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T}/afl-out && tar -cf- queue ../pubkey" | \ + tar -C ${T} -xf- +} + +run() { + find ${T}/queue -type f | while read f; do + cat "${f}" | LD_PRELOAD=${PRELOAD} build/examples/assert \ + ${T}/pubkey nodev 2>/dev/null 1>&2 + done +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/assert-rsa-h-p b/fuzz/harnesses/assert-rsa-h-p new file mode 100755 index 0000000..8eb9ea6 --- /dev/null +++ b/fuzz/harnesses/assert-rsa-h-p @@ -0,0 +1,33 @@ +#!/bin/bash -u +# 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. + +T=assert-rsa-h-p + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T}/afl-out && tar -cf- queue ../pubkey ../hmac-salt" | \ + tar -C ${T} -xf- +} + +run() { + find ${T}/queue -type f | while read f; do + cat "${f}" | LD_PRELOAD=${PRELOAD} build/examples/assert \ + -t rsa -h ${T}/hmac-out -s ${T}/hmac-salt \ + -p ${T}/pubkey nodev 2>/dev/null 1>&2 + done +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/assert-u2f b/fuzz/harnesses/assert-u2f new file mode 100755 index 0000000..257d1d6 --- /dev/null +++ b/fuzz/harnesses/assert-u2f @@ -0,0 +1,32 @@ +#!/bin/bash -u +# 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. + +T=assert-u2f + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T}/afl-out && tar -cf- queue ../cred_id ../pubkey" | \ + tar -C ${T} -xf- +} + +run() { + find ${T}/queue -type f | while read f; do + cat "${f}" | LD_PRELOAD=${PRELOAD} build/examples/assert -up \ + -a ${T}/cred_id ${T}/pubkey nodev 2>/dev/null 1>&2 + done +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/cred b/fuzz/harnesses/cred new file mode 100755 index 0000000..71ee845 --- /dev/null +++ b/fuzz/harnesses/cred @@ -0,0 +1,31 @@ +#!/bin/bash -u +# 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. + +T=cred + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T}/afl-out && tar -cf- queue" | tar -C ${T} -xf- +} + +run() { + find ${T}/queue -type f | while read f; do + cat "${f}" | LD_PRELOAD=${PRELOAD} build/examples/cred \ + -k ${T}/pubkey -i ${T}/cred_id nodev 2>/dev/null 1>&2 + done +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/cred-rsa-h-p b/fuzz/harnesses/cred-rsa-h-p new file mode 100755 index 0000000..bb14c23 --- /dev/null +++ b/fuzz/harnesses/cred-rsa-h-p @@ -0,0 +1,32 @@ +#!/bin/bash -u +# 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. + +T=cred-rsa-h-p + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T}/afl-out && tar -cf- queue" | tar -C ${T} -xf- +} + +run() { + find ${T}/queue -type f | while read f; do + cat "${f}" | LD_PRELOAD=${PRELOAD} build/examples/cred \ + -t rsa -r -k ${T}/pubkey -i ${T}/cred_id -h nodev \ + 2>/dev/null 1>&2 + done +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/cred-u2f b/fuzz/harnesses/cred-u2f new file mode 100755 index 0000000..3af4393 --- /dev/null +++ b/fuzz/harnesses/cred-u2f @@ -0,0 +1,31 @@ +#!/bin/bash -u +# 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. + +T=cred-u2f + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T}/afl-out && tar -cf- queue" | tar -C ${T} -xf- +} + +run() { + find ${T}/queue -type f | while read f; do + cat "${f}" | LD_PRELOAD=${PRELOAD} build/examples/cred \ + -k ${T}/pubkey -i ${T}/cred_id -u nodev 2>/dev/null 1>&2 + done +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/cred-u2f-exclude b/fuzz/harnesses/cred-u2f-exclude new file mode 100755 index 0000000..3777134 --- /dev/null +++ b/fuzz/harnesses/cred-u2f-exclude @@ -0,0 +1,33 @@ +#!/bin/bash -u +# 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. + +T=cred-u2f-exclude + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T}/afl-out && tar -cf- queue ../excl_id" | \ + tar -C ${T} -xf- +} + +run() { + find ${T}/queue -type f | while read f; do + cat "${f}" | LD_PRELOAD=${PRELOAD} build/examples/cred \ + -k ${T}/pubkey -i ${T}/cred_id -e ${T}/excl_id \ + -u nodev 2>/dev/null 1>&2 + done +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/fido2-assert-G b/fuzz/harnesses/fido2-assert-G new file mode 100755 index 0000000..6671449 --- /dev/null +++ b/fuzz/harnesses/fido2-assert-G @@ -0,0 +1,31 @@ +#!/bin/bash -u +# 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. + +T=fido2-assert-G + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T}/afl-out && tar -cf- queue" | tar -C ${T} -xf- +} + +run() { + find ${T}/queue -type f | while read f; do + cat "${f}" | LD_PRELOAD=${PRELOAD} build/tools/fido2-assert \ + -G -i - nodev 2>/dev/null 1>&2 + done +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/fido2-assert-V b/fuzz/harnesses/fido2-assert-V new file mode 100755 index 0000000..898cb0f --- /dev/null +++ b/fuzz/harnesses/fido2-assert-V @@ -0,0 +1,32 @@ +#!/bin/bash -u +# 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. + +T=fido2-assert-V + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T}/afl-out && tar -cf- queue ../pubkey" | \ + tar -C ${T} -xf- +} + +run() { + find ${T}/queue -type f | while read f; do + cat "${f}" | LD_PRELOAD=${PRELOAD} build/tools/fido2-assert -V \ + pubkey es256 2>/dev/null 1>&2 + done +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/fido2-cred-M b/fuzz/harnesses/fido2-cred-M new file mode 100755 index 0000000..f82fbf7 --- /dev/null +++ b/fuzz/harnesses/fido2-cred-M @@ -0,0 +1,31 @@ +#!/bin/bash -u +# 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. + +T=fido2-cred-M + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T}/afl-out && tar -cf- queue" | tar -C ${T} -xf- +} + +run() { + find ${T}/queue -type f | while read f; do + cat "${f}" | LD_PRELOAD=${PRELOAD} build/tools/fido2-cred -M \ + -q -i - nodev 2>/dev/null 1>&2 + done +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/fido2-cred-V b/fuzz/harnesses/fido2-cred-V new file mode 100755 index 0000000..13a648f --- /dev/null +++ b/fuzz/harnesses/fido2-cred-V @@ -0,0 +1,31 @@ +#!/bin/bash -u +# 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. + +T=fido2-cred-V + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T}/afl-out && tar -cf- queue" | tar -C ${T} -xf- +} + +run() { + find ${T}/queue -type f | while read f; do + cat "${f}" | LD_PRELOAD=${PRELOAD} build/tools/fido2-cred -V \ + -o cred 2>/dev/null 1>&2 + done +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/fuzz_assert b/fuzz/harnesses/fuzz_assert new file mode 100755 index 0000000..6a0baa9 --- /dev/null +++ b/fuzz/harnesses/fuzz_assert @@ -0,0 +1,29 @@ +#!/bin/bash -u +# 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. + +T=fuzz_assert + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T} && tar -cf- corpus" | tar -C ${T} -xf- +} + +run() { + build/fuzz/fuzz_assert -max_len=17408 -runs=1 ${T}/corpus \ + 2>/dev/null 1>&2 +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/fuzz_bio b/fuzz/harnesses/fuzz_bio new file mode 100755 index 0000000..f4bab19 --- /dev/null +++ b/fuzz/harnesses/fuzz_bio @@ -0,0 +1,29 @@ +#!/bin/bash -u +# 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. + +T=fuzz_bio + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T} && tar -cf- corpus" | tar -C ${T} -xf- +} + +run() { + build/fuzz/fuzz_bio -max_len=17408 -runs=1 ${T}/corpus \ + 2>/dev/null 1>&2 +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/fuzz_cred b/fuzz/harnesses/fuzz_cred new file mode 100755 index 0000000..8dfb168 --- /dev/null +++ b/fuzz/harnesses/fuzz_cred @@ -0,0 +1,28 @@ +#!/bin/bash -u +# 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. + +T=fuzz_cred + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T} && tar -cf- corpus" | tar -C ${T} -xf- +} + +run() { + build/fuzz/fuzz_cred -max_len=17408 -runs=1 ${T}/corpus 2>/dev/null 1>&2 +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/fuzz_credman b/fuzz/harnesses/fuzz_credman new file mode 100755 index 0000000..7721a58 --- /dev/null +++ b/fuzz/harnesses/fuzz_credman @@ -0,0 +1,28 @@ +#!/bin/bash -u +# 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. + +T=fuzz_credman + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T} && tar -cf- corpus" | tar -C ${T} -xf- +} + +run() { + build/fuzz/fuzz_credman -max_len=17408 -runs=1 ${T}/corpus 2>/dev/null 1>&2 +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/harnesses/fuzz_mgmt b/fuzz/harnesses/fuzz_mgmt new file mode 100755 index 0000000..9224eea --- /dev/null +++ b/fuzz/harnesses/fuzz_mgmt @@ -0,0 +1,29 @@ +#!/bin/bash -u +# 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. + +T=fuzz_mgmt + +sync() { + mkdir ${T} + ssh "${REMOTE}" "cd ${T} && tar -cf- corpus" | tar -C ${T} -xf- +} + +run() { + build/fuzz/fuzz_mgmt -max_len=17408 -runs=1 ${T}/corpus \ + 2>/dev/null 1>&2 +} + +case "$1" in +sync) + sync + ;; +run) + run + exit 0 + ;; +*) + echo unknown command "$1" + exit 1 +esac diff --git a/fuzz/mutator_aux.c b/fuzz/mutator_aux.c new file mode 100644 index 0000000..24aa716 --- /dev/null +++ b/fuzz/mutator_aux.c @@ -0,0 +1,314 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "mutator_aux.h" + +size_t LLVMFuzzerMutate(uint8_t *, size_t, size_t); + +static uint8_t *wire_data_ptr = NULL; +static size_t wire_data_len = 0; + +size_t +xstrlen(const char *s) +{ + if (s == NULL) + return (0); + + return (strlen(s)); +} + +void +consume(const void *body, size_t len) +{ + const volatile uint8_t *ptr = body; + volatile uint8_t x = 0; + + while (len--) + x ^= *ptr++; +} + +int +unpack_int(uint8_t t, uint8_t **ptr, size_t *len, int *v) NO_MSAN +{ + size_t l; + + if (*len < sizeof(t) || **ptr != t) + return (-1); + + *ptr += sizeof(t); + *len -= sizeof(t); + + if (*len < sizeof(l)) + return (-1); + + memcpy(&l, *ptr, sizeof(l)); + *ptr += sizeof(l); + *len -= sizeof(l); + + if (l != sizeof(*v) || *len < l) + return (-1); + + memcpy(v, *ptr, sizeof(*v)); + *ptr += sizeof(*v); + *len -= sizeof(*v); + + return (0); +} + +int +unpack_string(uint8_t t, uint8_t **ptr, size_t *len, char *v) NO_MSAN +{ + size_t l; + + if (*len < sizeof(t) || **ptr != t) + return (-1); + + *ptr += sizeof(t); + *len -= sizeof(t); + + if (*len < sizeof(l)) + return (-1); + + memcpy(&l, *ptr, sizeof(l)); + *ptr += sizeof(l); + *len -= sizeof(l); + + if (*len < l || l >= MAXSTR) + return (-1); + + memcpy(v, *ptr, l); + v[l] = '\0'; + + *ptr += l; + *len -= l; + + return (0); +} + +int +unpack_byte(uint8_t t, uint8_t **ptr, size_t *len, uint8_t *v) NO_MSAN +{ + size_t l; + + if (*len < sizeof(t) || **ptr != t) + return (-1); + + *ptr += sizeof(t); + *len -= sizeof(t); + + if (*len < sizeof(l)) + return (-1); + + memcpy(&l, *ptr, sizeof(l)); + *ptr += sizeof(l); + *len -= sizeof(l); + + if (l != sizeof(*v) || *len < l) + return (-1); + + memcpy(v, *ptr, sizeof(*v)); + *ptr += sizeof(*v); + *len -= sizeof(*v); + + return (0); +} + +int +unpack_blob(uint8_t t, uint8_t **ptr, size_t *len, struct blob *v) NO_MSAN +{ + size_t l; + + v->len = 0; + + if (*len < sizeof(t) || **ptr != t) + return (-1); + + *ptr += sizeof(t); + *len -= sizeof(t); + + if (*len < sizeof(l)) + return (-1); + + memcpy(&l, *ptr, sizeof(l)); + *ptr += sizeof(l); + *len -= sizeof(l); + + if (*len < l || l > sizeof(v->body)) + return (-1); + + memcpy(v->body, *ptr, l); + *ptr += l; + *len -= l; + + v->len = l; + + return (0); +} + +int +pack_int(uint8_t t, uint8_t **ptr, size_t *len, int v) NO_MSAN +{ + const size_t l = sizeof(v); + + if (*len < sizeof(t) + sizeof(l) + l) + return (-1); + + (*ptr)[0] = t; + memcpy(&(*ptr)[sizeof(t)], &l, sizeof(l)); + memcpy(&(*ptr)[sizeof(t) + sizeof(l)], &v, l); + + *ptr += sizeof(t) + sizeof(l) + l; + *len -= sizeof(t) + sizeof(l) + l; + + return (0); +} + +int +pack_string(uint8_t t, uint8_t **ptr, size_t *len, const char *v) NO_MSAN +{ + const size_t l = strlen(v); + + if (*len < sizeof(t) + sizeof(l) + l) + return (-1); + + (*ptr)[0] = t; + memcpy(&(*ptr)[sizeof(t)], &l, sizeof(l)); + memcpy(&(*ptr)[sizeof(t) + sizeof(l)], v, l); + + *ptr += sizeof(t) + sizeof(l) + l; + *len -= sizeof(t) + sizeof(l) + l; + + return (0); +} + +int +pack_byte(uint8_t t, uint8_t **ptr, size_t *len, uint8_t v) NO_MSAN +{ + const size_t l = sizeof(v); + + if (*len < sizeof(t) + sizeof(l) + l) + return (-1); + + (*ptr)[0] = t; + memcpy(&(*ptr)[sizeof(t)], &l, sizeof(l)); + memcpy(&(*ptr)[sizeof(t) + sizeof(l)], &v, l); + + *ptr += sizeof(t) + sizeof(l) + l; + *len -= sizeof(t) + sizeof(l) + l; + + return (0); +} + +int +pack_blob(uint8_t t, uint8_t **ptr, size_t *len, const struct blob *v) NO_MSAN +{ + const size_t l = v->len; + + if (*len < sizeof(t) + sizeof(l) + l) + return (-1); + + (*ptr)[0] = t; + memcpy(&(*ptr)[sizeof(t)], &l, sizeof(l)); + memcpy(&(*ptr)[sizeof(t) + sizeof(l)], v->body, l); + + *ptr += sizeof(t) + sizeof(l) + l; + *len -= sizeof(t) + sizeof(l) + l; + + return (0); +} + +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'; +} + +void * +dev_open(const char *path) +{ + (void)path; + + return ((void *)0xdeadbeef); +} + +void +dev_close(void *handle) +{ + assert(handle == (void *)0xdeadbeef); +} + +int +dev_read(void *handle, unsigned char *ptr, size_t len, int ms) +{ + size_t n; + + (void)ms; + + assert(handle == (void *)0xdeadbeef); + assert(len == 64); + + 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); +} + +int +dev_write(void *handle, const unsigned char *ptr, size_t len) +{ + assert(handle == (void *)0xdeadbeef); + assert(len == 64 + 1); + + consume(ptr, len); + + if (uniform_random(400) < 1) + return (-1); + + return ((int)len); +} + +void +set_wire_data(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..687f130 --- /dev/null +++ b/fuzz/mutator_aux.h @@ -0,0 +1,65 @@ +/* + * 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. + */ + +#ifndef _MUTATOR_AUX_H +#define _MUTATOR_AUX_H + +/* + * As of LLVM 7.0.1, 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) +# define NO_MSAN __attribute__((no_sanitize("memory"))) +# define WITH_MSAN 1 +# endif +#endif + +#if !defined(WITH_MSAN) +# define NO_MSAN +#endif + +#define MAXSTR 1024 +#define MAXBLOB 3072 + +struct blob { + uint8_t body[MAXBLOB]; + size_t len; +}; + +size_t xstrlen(const char *); +void consume(const void *, size_t); + +int unpack_blob(uint8_t, uint8_t **, size_t *, struct blob *); +int unpack_byte(uint8_t, uint8_t **, size_t *, uint8_t *); +int unpack_int(uint8_t, uint8_t **, size_t *, int *); +int unpack_string(uint8_t, uint8_t **, size_t *, char *); + +int pack_blob(uint8_t, uint8_t **, size_t *, const struct blob *); +int pack_byte(uint8_t, uint8_t **, size_t *, uint8_t); +int pack_int(uint8_t, uint8_t **, size_t *, int); +int pack_string(uint8_t, uint8_t **, size_t *, const char *); + +void mutate_byte(uint8_t *); +void mutate_int(int *); +void mutate_blob(struct blob *); +void mutate_string(char *); + +void * dev_open(const char *); +void dev_close(void *); +void set_wire_data(uint8_t *, size_t); +int dev_read(void *, unsigned char *, size_t, int); +int dev_write(void *, const unsigned char *, size_t); + +uint32_t uniform_random(uint32_t); + +#endif /* !_MUTATOR_AUX_H */ diff --git a/fuzz/preload-fuzz.c b/fuzz/preload-fuzz.c new file mode 100644 index 0000000..efcb8c6 --- /dev/null +++ b/fuzz/preload-fuzz.c @@ -0,0 +1,104 @@ +/* + * 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. + */ + +/* + * cc -fPIC -D_GNU_SOURCE -shared -o preload-fuzz.so preload-fuzz.c + * LD_PRELOAD=$(realpath preload-fuzz.so) + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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..373acc5 --- /dev/null +++ b/fuzz/preload-snoop.c @@ -0,0 +1,217 @@ +/* + * 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. + */ + +/* + * cc -fPIC -D_GNU_SOURCE -shared -o preload-snoop.so preload-snoop.c + * LD_PRELOAD=$(realpath preload-snoop.so) + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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/report b/fuzz/report new file mode 100755 index 0000000..bebb0ca --- /dev/null +++ b/fuzz/report @@ -0,0 +1,80 @@ +#!/bin/bash -e +# 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. +# +# XXX This should really be a Makefile. + +T="" +#T+=" harnesses/assert" +#T+=" harnesses/assert-rsa-h-p" +#T+=" harnesses/assert-u2f" +#T+=" harnesses/cred" +#T+=" harnesses/cred-rsa-h-p" +#T+=" harnesses/cred-u2f" +#T+=" harnesses/cred-u2f-exclude" +#T+=" harnesses/fido2-assert-G" +#T+=" harnesses/fido2-assert-V" +#T+=" harnesses/fido2-cred-M" +#T+=" harnesses/fido2-cred-V" +T+=" harnesses/fuzz_assert" +T+=" harnesses/fuzz_bio" +T+=" harnesses/fuzz_cred" +T+=" harnesses/fuzz_credman" +T+=" harnesses/fuzz_mgmt" + +clean() { + echo cleaning + rm -rf obj + mkdir obj +} + +build() { + echo building + mkdir obj/build + (cd obj/build && cmake -DFUZZ=1 -DLIBFUZZER=1 -DCMAKE_C_COMPILER=clang \ + -DCOVERAGE=1 -DCMAKE_BUILD_TYPE=Debug ../../..) 2>/dev/null 1>&2 + make -C obj/build 2>/dev/null 1>&2 + cc -fPIC -D_GNU_SOURCE -shared -o obj/preload-fuzz.so preload-fuzz.c +} + +sync() { + if [ -n "${REMOTE}" ]; then + for t in ${T}; do + echo syncing ${t} + (cd obj && REMOTE="${REMOTE}" ../${t} sync) + done + else + tar -C obj -zxf corpus.tgz + fi +} + +run() { + export LLVM_PROFILE_FILE="profraw/%h-%p.profraw" + export PRELOAD=$(realpath obj/preload-fuzz.so) + + for t in ${T}; do + echo running ${t} + (cd obj && ../${t} run) + done +} + +merge() { + echo merging + (cd obj && \ + llvm-profdata merge -sparse profraw/*.profraw \ + -o libfido2.profdata && + llvm-cov show -format=html -tab-size=8 build/src/libfido2.so \ + -instr-profile=libfido2.profdata > report.html && + llvm-cov report -use-color=false build/src/libfido2.so \ + -instr-profile=libfido2.profdata > summary.txt && + llvm-cov report -use-color=false -show-functions \ + -instr-profile=libfido2.profdata build/src/libfido2.so \ + ../../src/*.[ch] > functions.txt) +} + +clean +build +sync +run +merge diff --git a/fuzz/summary.txt b/fuzz/summary.txt new file mode 100644 index 0000000..e494865 --- /dev/null +++ b/fuzz/summary.txt @@ -0,0 +1,39 @@ +Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +fuzz/uniform_random.c 7 1 85.71% 1 0 100.00% 23 1 95.65% +fuzz/wrap.c 4 0 100.00% 1 0 100.00% 7 0 100.00% +openbsd-compat/explicit_bzero.c 4 0 100.00% 1 0 100.00% 12 0 100.00% +openbsd-compat/recallocarray.c 41 7 82.93% 1 0 100.00% 49 7 85.71% +openbsd-compat/timingsafe_bcmp.c 4 0 100.00% 1 0 100.00% 8 0 100.00% +src/aes256.c 56 0 100.00% 2 0 100.00% 82 0 100.00% +src/assert.c 569 29 94.90% 53 1 98.11% 901 60 93.34% +src/authkey.c 45 0 100.00% 5 0 100.00% 75 0 100.00% +src/bio.c 422 21 95.02% 49 2 95.92% 661 25 96.22% +src/blob.c 39 1 97.44% 7 0 100.00% 73 4 94.52% +src/buf.c 8 1 87.50% 2 0 100.00% 20 1 95.00% +src/cbor.c 844 31 96.33% 51 1 98.04% 1319 47 96.44% +src/cred.c 532 35 93.42% 54 1 98.15% 850 55 93.53% +src/credman.c 381 18 95.28% 38 0 100.00% 589 15 97.45% +src/dev.c 131 22 83.21% 19 1 94.74% 183 30 83.61% +src/ecdh.c 68 0 100.00% 2 0 100.00% 104 0 100.00% +src/eddsa.c 54 4 92.59% 8 0 100.00% 79 2 97.47% +src/err.c 108 108 0.00% 1 1 0.00% 112 112 0.00% +src/es256.c 273 4 98.53% 16 0 100.00% 372 13 96.51% +src/hid.c 16 16 0.00% 8 8 0.00% 38 38 0.00% +src/hid_linux.c 166 166 0.00% 12 12 0.00% 287 287 0.00% +src/info.c 148 1 99.32% 31 0 100.00% 305 0 100.00% +src/io.c 113 6 94.69% 7 0 100.00% 201 13 93.53% +src/iso7816.c 18 1 94.44% 5 0 100.00% 47 0 100.00% +src/log.c 16 10 37.50% 3 1 66.67% 34 23 32.35% +src/pin.c 250 0 100.00% 16 0 100.00% 364 0 100.00% +src/reset.c 20 0 100.00% 3 0 100.00% 23 0 100.00% +src/rs256.c 102 6 94.12% 8 0 100.00% 140 9 93.57% +src/u2f.c 436 11 97.48% 13 0 100.00% 686 22 96.79% + +Files which contain no functions: +src/extern.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 4875 499 89.76% 418 28 93.30% 7644 764 90.01% diff --git a/fuzz/uniform_random.c b/fuzz/uniform_random.c new file mode 100644 index 0000000..7711d69 --- /dev/null +++ b/fuzz/uniform_random.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2008, Damien Miller + * + * 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 +#include + +uint32_t uniform_random(uint32_t); + +/* + * 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)random(); + if (r >= min) + break; + } + + return r % upper_bound; +} diff --git a/fuzz/wrap.c b/fuzz/wrap.c new file mode 100644 index 0000000..8ff7ee7 --- /dev/null +++ b/fuzz/wrap.c @@ -0,0 +1,419 @@ +/* + * 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. + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "mutator_aux.h" + +/* + * Build wrappers around functions of interest, and have them fail + * in a pseudo-random manner. + */ + +#define WRAP(type, name, args, retval, param, prob) \ +extern type __wrap_##name args; \ +extern type __real_##name args; \ +type __wrap_##name args { \ + if (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(char *, + strdup, + (const char *s), + NULL, + (s), + 1 +) + +WRAP(EVP_CIPHER_CTX *, + EVP_CIPHER_CTX_new, + (void), + NULL, + (), + 1 +) + +WRAP(int, EVP_EncryptInit_ex, + (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, + const unsigned char *key, const unsigned char *iv), + 0, + (ctx, type, impl, key, iv), + 1 +) + +WRAP(int, + EVP_CIPHER_CTX_set_padding, + (EVP_CIPHER_CTX *x, int padding), + 0, + (x, padding), + 1 +) + +WRAP(int, + EVP_EncryptUpdate, + (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl), + 0, + (ctx, out, outl, in, inl), + 1 +) + +WRAP(int, + EVP_DecryptInit_ex, + (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, + const unsigned char *key, const unsigned char *iv), + 0, + (ctx, type, impl, key, iv), + 1 +) + +WRAP(int, + EVP_DecryptUpdate, + (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl), + 0, + (ctx, out, outl, in, inl), + 1 +) + +WRAP(int, + SHA256_Init, + (SHA256_CTX *c), + 0, + (c), + 1 +) + +WRAP(int, + SHA256_Update, + (SHA256_CTX *c, const void *data, size_t len), + 0, + (c, data, len), + 1 +) + +WRAP(int, + SHA256_Final, + (unsigned char *md, SHA256_CTX *c), + 0, + (md, c), + 1 +) + +WRAP(RSA *, + EVP_PKEY_get0_RSA, + (EVP_PKEY *pkey), + NULL, + (pkey), + 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(BIGNUM *, + BN_bin2bn, + (const unsigned char *s, int len, BIGNUM *ret), + NULL, + (s, len, ret), + 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(int, + RSA_set0_key, + (RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d), + 0, + (r, n, e, d), + 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(EC_POINT *, + EC_POINT_new, + (const EC_GROUP *group), + NULL, + (group), + 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(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(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(const EVP_MD *, + EVP_sha256, + (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 *, + 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_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(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_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(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), + -1, + (d, cmd, buf, count), + 1 +) + +WRAP(int, + usleep, + (unsigned int usec), + -1, + (usec), + 1 +) diff --git a/fuzz/wrapped.sym b/fuzz/wrapped.sym new file mode 100644 index 0000000..3679f91 --- /dev/null +++ b/fuzz/wrapped.sym @@ -0,0 +1,47 @@ +BN_bin2bn +BN_CTX_get +BN_CTX_new +BN_new +calloc +cbor_array_handle +cbor_build_bytestring +cbor_build_string +cbor_build_uint8 +cbor_load +cbor_map_add +cbor_map_handle +cbor_new_definite_map +cbor_serialize_alloc +EC_KEY_get0_group +EC_KEY_new_by_curve_name +EC_POINT_new +EVP_CIPHER_CTX_new +EVP_CIPHER_CTX_set_padding +EVP_DecryptInit_ex +EVP_DecryptUpdate +EVP_DigestVerifyInit +EVP_EncryptInit_ex +EVP_EncryptUpdate +EVP_MD_CTX_new +EVP_PKEY_assign +EVP_PKEY_CTX_new +EVP_PKEY_derive_init +EVP_PKEY_derive_set_peer +EVP_PKEY_get0_RSA +EVP_PKEY_new +EVP_PKEY_new_raw_public_key +EVP_sha256 +fido_tx +HMAC +HMAC_CTX_new +HMAC_Final +HMAC_Init_ex +HMAC_Update +malloc +RSA_set0_key +SHA256 +SHA256_Final +SHA256_Init +SHA256_Update +strdup +usleep -- cgit v1.2.3