From 2b182947ce4050b88b6cb9b8554d344f9bc6f48d Mon Sep 17 00:00:00 2001 From: Token2 Date: Fri, 24 May 2024 11:47:45 +0200 Subject: [PATCH] Add files via upload --- examples/CMakeLists.txt | 59 +++ examples/README.adoc | 100 +++++ examples/assert.c | 349 +++++++++++++++ examples/cred.c | 331 ++++++++++++++ examples/extern.h | 27 ++ examples/info.c | 382 ++++++++++++++++ examples/manifest.c | 42 ++ examples/reset.c | 49 ++ examples/retries.c | 49 ++ examples/select.c | 215 +++++++++ examples/setpin.c | 55 +++ examples/util.c | 444 +++++++++++++++++++ fuzz/CMakeLists.txt | 89 ++++ fuzz/Dockerfile | 16 + fuzz/Makefile | 90 ++++ fuzz/README | 43 ++ fuzz/build-coverage | 34 ++ fuzz/clock.c | 80 ++++ fuzz/dummy.h | 182 ++++++++ fuzz/export.gnu | 289 ++++++++++++ fuzz/functions.txt | 956 ++++++++++++++++++++++++++++++++++++++++ fuzz/fuzz_assert.c | 534 ++++++++++++++++++++++ fuzz/fuzz_attobj.c | 333 ++++++++++++++ fuzz/fuzz_bio.c | 442 +++++++++++++++++++ fuzz/fuzz_cred.c | 487 ++++++++++++++++++++ fuzz/fuzz_credman.c | 407 +++++++++++++++++ fuzz/fuzz_hid.c | 239 ++++++++++ fuzz/fuzz_largeblob.c | 272 ++++++++++++ fuzz/fuzz_mgmt.c | 528 ++++++++++++++++++++++ fuzz/fuzz_netlink.c | 164 +++++++ fuzz/fuzz_pcsc.c | 269 +++++++++++ fuzz/libfuzzer.c | 231 ++++++++++ fuzz/mutator_aux.c | 338 ++++++++++++++ fuzz/mutator_aux.h | 111 +++++ fuzz/pcsc.c | 153 +++++++ fuzz/preload-fuzz.c | 105 +++++ fuzz/preload-snoop.c | 218 +++++++++ fuzz/prng.c | 113 +++++ fuzz/report.tgz | Bin 0 -> 365288 bytes fuzz/summary.txt | 64 +++ fuzz/udev.c | 270 ++++++++++++ fuzz/uniform_random.c | 57 +++ fuzz/wiredata_fido2.h | 708 +++++++++++++++++++++++++++++ fuzz/wiredata_u2f.h | 153 +++++++ fuzz/wrap.c | 700 +++++++++++++++++++++++++++++ fuzz/wrapped.sym | 102 +++++ 46 files changed, 10879 insertions(+) create mode 100644 examples/CMakeLists.txt create mode 100644 examples/README.adoc create mode 100644 examples/assert.c create mode 100644 examples/cred.c create mode 100644 examples/extern.h create mode 100644 examples/info.c create mode 100644 examples/manifest.c create mode 100644 examples/reset.c create mode 100644 examples/retries.c create mode 100644 examples/select.c create mode 100644 examples/setpin.c create mode 100644 examples/util.c create mode 100644 fuzz/CMakeLists.txt create mode 100644 fuzz/Dockerfile create mode 100644 fuzz/Makefile create mode 100644 fuzz/README create mode 100644 fuzz/build-coverage create mode 100644 fuzz/clock.c create mode 100644 fuzz/dummy.h create mode 100644 fuzz/export.gnu create mode 100644 fuzz/functions.txt create mode 100644 fuzz/fuzz_assert.c create mode 100644 fuzz/fuzz_attobj.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_hid.c create mode 100644 fuzz/fuzz_largeblob.c create mode 100644 fuzz/fuzz_mgmt.c create mode 100644 fuzz/fuzz_netlink.c create mode 100644 fuzz/fuzz_pcsc.c create mode 100644 fuzz/libfuzzer.c create mode 100644 fuzz/mutator_aux.c create mode 100644 fuzz/mutator_aux.h create mode 100644 fuzz/pcsc.c create mode 100644 fuzz/preload-fuzz.c create mode 100644 fuzz/preload-snoop.c create mode 100644 fuzz/prng.c create mode 100644 fuzz/report.tgz create mode 100644 fuzz/summary.txt create mode 100644 fuzz/udev.c create mode 100644 fuzz/uniform_random.c create mode 100644 fuzz/wiredata_fido2.h create mode 100644 fuzz/wiredata_u2f.h create mode 100644 fuzz/wrap.c create mode 100644 fuzz/wrapped.sym diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..f013df4 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,59 @@ +# Copyright (c) 2018 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. +# SPDX-License-Identifier: BSD-2-Clause + +list(APPEND COMPAT_SOURCES + ../openbsd-compat/clock_gettime.c + ../openbsd-compat/getopt_long.c + ../openbsd-compat/strlcat.c + ../openbsd-compat/strlcpy.c +) + +if(WIN32 AND BUILD_SHARED_LIBS AND NOT CYGWIN AND NOT MSYS) + list(APPEND COMPAT_SOURCES ../openbsd-compat/posix_win.c) +endif() + +# enable -Wconversion -Wsign-conversion +if(NOT MSVC) + set_source_files_properties(assert.c cred.c info.c manifest.c reset.c + retries.c setpin.c util.c PROPERTIES COMPILE_FLAGS + "-Wconversion -Wsign-conversion") +endif() + +# manifest +add_executable(manifest manifest.c ${COMPAT_SOURCES}) +target_link_libraries(manifest ${_FIDO2_LIBRARY}) + +# info +add_executable(info info.c ${COMPAT_SOURCES}) +target_link_libraries(info ${_FIDO2_LIBRARY}) + +# reset +add_executable(reset reset.c util.c ${COMPAT_SOURCES}) +target_link_libraries(reset ${_FIDO2_LIBRARY}) + +# cred +add_executable(cred cred.c util.c ${COMPAT_SOURCES}) +target_link_libraries(cred ${_FIDO2_LIBRARY}) + +# assert +add_executable(assert assert.c util.c ${COMPAT_SOURCES}) +target_link_libraries(assert ${_FIDO2_LIBRARY}) + +# setpin +add_executable(setpin setpin.c ${COMPAT_SOURCES}) +target_link_libraries(setpin ${_FIDO2_LIBRARY}) + +# retries +add_executable(retries retries.c ${COMPAT_SOURCES}) +target_link_libraries(retries ${_FIDO2_LIBRARY}) + +# select +add_executable(select select.c ${COMPAT_SOURCES}) +target_link_libraries(select ${_FIDO2_LIBRARY}) + +if(MINGW) + # needed for nanosleep() in mingw + target_link_libraries(select winpthread) +endif() diff --git a/examples/README.adoc b/examples/README.adoc new file mode 100644 index 0000000..6151b70 --- /dev/null +++ b/examples/README.adoc @@ -0,0 +1,100 @@ += Examples + +=== Definitions + +The following definitions are used in the description below: + +- + + The file system path or subsystem-specific identification string of a + FIDO device. + +- , [oldpin] + + Strings passed directly in the executed command's argument vector. + +- + + The file system path of a file containing a FIDO credential ID in + binary representation. + +- + + The file system path of a file containing a public key in PEM format. + +- + + A credential's associated CTAP 2.1 "largeBlob" symmetric key. + +=== Description + +The following examples are provided: + +- manifest + + Prints a list of configured FIDO devices. + +- info + + Prints information about . + +- reset + + Performs a factory reset on . + +- setpin [oldpin] + + Configures as the new PIN of . If [oldpin] is provided, + the device's PIN is changed from [oldpin] to . + +- cred [-t es256|es384|rs256|eddsa] [-k pubkey] [-ei cred_id] [-P pin] + [-T seconds] [-b blobkey] [-hruv] [-c cred_protect] + + Creates a new credential on and verify that the credential + was signed by the authenticator. The device's attestation certificate + is not verified. If option -k is specified, the credential's public + key is stored in . If option -i is specified, the credential + ID is stored in . The -e option may be used to add + to the list of excluded credentials. If option -h is specified, + the hmac-secret FIDO2 extension is enabled on the generated + credential. If option -r is specified, the generated credential + will involve a resident key. User verification may be requested + through the -v option. If option -u is specified, the credential + is generated using U2F (CTAP1) instead of FIDO2 (CTAP2) commands. + The -T option may be used to enforce a timeout of . If the + option -b is specified, the credential's "largeBlob" key is stored in + . If the option -c is specified the the generated credential + will be bound by the specified protection policy. + +- assert [-t es256|es384|rs256|eddsa] [-a cred_id] [-h hmac_secret] [-P pin] + [-s hmac_salt] [-T seconds] [-b blobkey] [-puv] + + Asks for a FIDO2 assertion corresponding to [cred_id], + which may be omitted for resident keys. The obtained assertion + is verified using . The -p option requests that the user + be present and checks whether the user presence bit was signed by the + authenticator. The -v option requests user verification and checks + whether the user verification bit was signed by the authenticator. + If option -u is specified, the assertion is generated using + U2F (CTAP1) instead of FIDO2 (CTAP2) commands. If option -s is + specified, a FIDO2 hmac-secret is requested from the authenticator, + and the contents of are used as the salt. If option -h + is specified, the resulting hmac-secret is stored in . + The -T option may be used to enforce a timeout of . If the + option -b specified, the credential's "largeBlob" key is stored in + . + +- retries + Get the number of PIN attempts left on before lockout. + +- select + + Enumerates available FIDO devices and, if more than one is present, + simultaneously requests touch on all of them, printing information + about the device touched. + +Debugging is possible through the use of the FIDO_DEBUG environment variable. +If set, libfido2 will produce a log of its transactions with the authenticator. + +Additionally, an example of a WebAuthn client using libfido2 is available at +https://github.com/martelletto/fido2-webauthn-client. diff --git a/examples/assert.c b/examples/assert.c new file mode 100644 index 0000000..32ba97b --- /dev/null +++ b/examples/assert.c @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2018-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "../openbsd-compat/openbsd-compat.h" +#include "extern.h" + +static const unsigned char cd[32] = { + 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 void +usage(void) +{ + fprintf(stderr, "usage: assert [-t es256|es384|rs256|eddsa] " + "[-a cred_id] [-h hmac_secret] [-s hmac_salt] [-P pin] " + "[-T seconds] [-b blobkey] [-puv] \n"); + exit(EXIT_FAILURE); +} + +static void +verify_assert(int type, const unsigned char *authdata_ptr, size_t authdata_len, + const unsigned char *sig_ptr, size_t sig_len, bool up, bool uv, int ext, + const char *key) +{ + fido_assert_t *assert = NULL; + EC_KEY *ec = NULL; + RSA *rsa = NULL; + EVP_PKEY *eddsa = NULL; + es256_pk_t *es256_pk = NULL; + es384_pk_t *es384_pk = NULL; + rs256_pk_t *rs256_pk = NULL; + eddsa_pk_t *eddsa_pk = NULL; + void *pk; + int r; + + /* credential pubkey */ + switch (type) { + case COSE_ES256: + if ((ec = read_ec_pubkey(key)) == NULL) + errx(1, "read_ec_pubkey"); + + if ((es256_pk = es256_pk_new()) == NULL) + errx(1, "es256_pk_new"); + + if (es256_pk_from_EC_KEY(es256_pk, ec) != FIDO_OK) + errx(1, "es256_pk_from_EC_KEY"); + + pk = es256_pk; + EC_KEY_free(ec); + ec = NULL; + + break; + case COSE_ES384: + if ((ec = read_ec_pubkey(key)) == NULL) + errx(1, "read_ec_pubkey"); + + if ((es384_pk = es384_pk_new()) == NULL) + errx(1, "es384_pk_new"); + + if (es384_pk_from_EC_KEY(es384_pk, ec) != FIDO_OK) + errx(1, "es384_pk_from_EC_KEY"); + + pk = es384_pk; + EC_KEY_free(ec); + ec = NULL; + + break; + case COSE_RS256: + if ((rsa = read_rsa_pubkey(key)) == NULL) + errx(1, "read_rsa_pubkey"); + + if ((rs256_pk = rs256_pk_new()) == NULL) + errx(1, "rs256_pk_new"); + + if (rs256_pk_from_RSA(rs256_pk, rsa) != FIDO_OK) + errx(1, "rs256_pk_from_RSA"); + + pk = rs256_pk; + RSA_free(rsa); + rsa = NULL; + + break; + case COSE_EDDSA: + if ((eddsa = read_eddsa_pubkey(key)) == NULL) + errx(1, "read_eddsa_pubkey"); + + if ((eddsa_pk = eddsa_pk_new()) == NULL) + errx(1, "eddsa_pk_new"); + + if (eddsa_pk_from_EVP_PKEY(eddsa_pk, eddsa) != FIDO_OK) + errx(1, "eddsa_pk_from_EVP_PKEY"); + + pk = eddsa_pk; + EVP_PKEY_free(eddsa); + eddsa = NULL; + + break; + default: + errx(1, "unknown credential type %d", type); + } + + if ((assert = fido_assert_new()) == NULL) + errx(1, "fido_assert_new"); + + /* client data hash */ + r = fido_assert_set_clientdata(assert, cd, sizeof(cd)); + if (r != FIDO_OK) + errx(1, "fido_assert_set_clientdata: %s (0x%x)", fido_strerr(r), r); + + /* relying party */ + r = fido_assert_set_rp(assert, "localhost"); + if (r != FIDO_OK) + errx(1, "fido_assert_set_rp: %s (0x%x)", fido_strerr(r), r); + + /* authdata */ + r = fido_assert_set_count(assert, 1); + if (r != FIDO_OK) + errx(1, "fido_assert_set_count: %s (0x%x)", fido_strerr(r), r); + r = fido_assert_set_authdata(assert, 0, authdata_ptr, authdata_len); + if (r != FIDO_OK) + errx(1, "fido_assert_set_authdata: %s (0x%x)", fido_strerr(r), r); + + /* extension */ + r = fido_assert_set_extensions(assert, ext); + if (r != FIDO_OK) + errx(1, "fido_assert_set_extensions: %s (0x%x)", fido_strerr(r), + r); + + /* user presence */ + if (up && (r = fido_assert_set_up(assert, FIDO_OPT_TRUE)) != FIDO_OK) + errx(1, "fido_assert_set_up: %s (0x%x)", fido_strerr(r), r); + + /* user verification */ + if (uv && (r = fido_assert_set_uv(assert, FIDO_OPT_TRUE)) != FIDO_OK) + errx(1, "fido_assert_set_uv: %s (0x%x)", fido_strerr(r), r); + + /* sig */ + r = fido_assert_set_sig(assert, 0, sig_ptr, sig_len); + if (r != FIDO_OK) + errx(1, "fido_assert_set_sig: %s (0x%x)", fido_strerr(r), r); + + r = fido_assert_verify(assert, 0, type, pk); + if (r != FIDO_OK) + errx(1, "fido_assert_verify: %s (0x%x)", fido_strerr(r), r); + + es256_pk_free(&es256_pk); + es384_pk_free(&es384_pk); + rs256_pk_free(&rs256_pk); + eddsa_pk_free(&eddsa_pk); + + fido_assert_free(&assert); +} + +int +main(int argc, char **argv) +{ + bool up = false; + bool uv = false; + bool u2f = false; + fido_dev_t *dev = NULL; + fido_assert_t *assert = NULL; + const char *pin = NULL; + const char *blobkey_out = NULL; + const char *hmac_out = NULL; + unsigned char *body = NULL; + long long ms = 0; + size_t len; + int type = COSE_ES256; + int ext = 0; + int ch; + int r; + + if ((assert = fido_assert_new()) == NULL) + errx(1, "fido_assert_new"); + + while ((ch = getopt(argc, argv, "P:T:a:b:h:ps:t:uv")) != -1) { + switch (ch) { + case 'P': + pin = optarg; + break; + case 'T': + if (base10(optarg, &ms) < 0) + errx(1, "base10: %s", optarg); + if (ms <= 0 || ms > 30) + errx(1, "-T: %s must be in (0,30]", optarg); + ms *= 1000; /* seconds to milliseconds */ + break; + case 'a': + if (read_blob(optarg, &body, &len) < 0) + errx(1, "read_blob: %s", optarg); + if ((r = fido_assert_allow_cred(assert, body, + len)) != FIDO_OK) + errx(1, "fido_assert_allow_cred: %s (0x%x)", + fido_strerr(r), r); + free(body); + body = NULL; + break; + case 'b': + ext |= FIDO_EXT_LARGEBLOB_KEY; + blobkey_out = optarg; + break; + case 'h': + hmac_out = optarg; + break; + case 'p': + up = true; + break; + case 's': + ext |= FIDO_EXT_HMAC_SECRET; + if (read_blob(optarg, &body, &len) < 0) + errx(1, "read_blob: %s", optarg); + if ((r = fido_assert_set_hmac_salt(assert, body, + len)) != FIDO_OK) + errx(1, "fido_assert_set_hmac_salt: %s (0x%x)", + fido_strerr(r), r); + free(body); + body = NULL; + break; + case 't': + if (strcmp(optarg, "es256") == 0) + type = COSE_ES256; + else if (strcmp(optarg, "es384") == 0) + type = COSE_ES384; + else if (strcmp(optarg, "rs256") == 0) + type = COSE_RS256; + else if (strcmp(optarg, "eddsa") == 0) + type = COSE_EDDSA; + else + errx(1, "unknown type %s", optarg); + break; + case 'u': + u2f = true; + break; + case 'v': + uv = true; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc != 2) + usage(); + + fido_init(0); + + if ((dev = fido_dev_new()) == NULL) + errx(1, "fido_dev_new"); + + r = fido_dev_open(dev, argv[1]); + if (r != FIDO_OK) + errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r); + if (u2f) + fido_dev_force_u2f(dev); + + /* client data hash */ + r = fido_assert_set_clientdata(assert, cd, sizeof(cd)); + if (r != FIDO_OK) + errx(1, "fido_assert_set_clientdata: %s (0x%x)", fido_strerr(r), r); + + /* relying party */ + r = fido_assert_set_rp(assert, "localhost"); + if (r != FIDO_OK) + errx(1, "fido_assert_set_rp: %s (0x%x)", fido_strerr(r), r); + + /* extensions */ + r = fido_assert_set_extensions(assert, ext); + if (r != FIDO_OK) + errx(1, "fido_assert_set_extensions: %s (0x%x)", fido_strerr(r), + r); + + /* user presence */ + if (up && (r = fido_assert_set_up(assert, FIDO_OPT_TRUE)) != FIDO_OK) + errx(1, "fido_assert_set_up: %s (0x%x)", fido_strerr(r), r); + + /* user verification */ + if (uv && (r = fido_assert_set_uv(assert, FIDO_OPT_TRUE)) != FIDO_OK) + errx(1, "fido_assert_set_uv: %s (0x%x)", fido_strerr(r), r); + + /* timeout */ + if (ms != 0 && (r = fido_dev_set_timeout(dev, (int)ms)) != FIDO_OK) + errx(1, "fido_dev_set_timeout: %s (0x%x)", fido_strerr(r), r); + + if ((r = fido_dev_get_assert(dev, assert, pin)) != FIDO_OK) { + fido_dev_cancel(dev); + errx(1, "fido_dev_get_assert: %s (0x%x)", fido_strerr(r), r); + } + + r = fido_dev_close(dev); + if (r != FIDO_OK) + errx(1, "fido_dev_close: %s (0x%x)", fido_strerr(r), r); + + fido_dev_free(&dev); + + if (fido_assert_count(assert) != 1) + errx(1, "fido_assert_count: %d signatures returned", + (int)fido_assert_count(assert)); + + /* when verifying, pin implies uv */ + if (pin) + uv = true; + + verify_assert(type, fido_assert_authdata_ptr(assert, 0), + fido_assert_authdata_len(assert, 0), fido_assert_sig_ptr(assert, 0), + fido_assert_sig_len(assert, 0), up, uv, ext, argv[0]); + + if (hmac_out != NULL) { + /* extract the hmac secret */ + if (write_blob(hmac_out, fido_assert_hmac_secret_ptr(assert, 0), + fido_assert_hmac_secret_len(assert, 0)) < 0) + errx(1, "write_blob"); + } + + if (blobkey_out != NULL) { + /* extract the hmac secret */ + if (write_blob(blobkey_out, + fido_assert_largeblob_key_ptr(assert, 0), + fido_assert_largeblob_key_len(assert, 0)) < 0) + errx(1, "write_blob"); + } + + fido_assert_free(&assert); + + exit(0); +} diff --git a/examples/cred.c b/examples/cred.c new file mode 100644 index 0000000..5a2a27f --- /dev/null +++ b/examples/cred.c @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2018-2023 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "../openbsd-compat/openbsd-compat.h" +#include "extern.h" + +static const unsigned char cd[32] = { + 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 unsigned char user_id[32] = { + 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, +}; + +static void +usage(void) +{ + fprintf(stderr, "usage: cred [-t es256|es384|rs256|eddsa] [-k pubkey] " + "[-ei cred_id] [-P pin] [-T seconds] [-b blobkey] [-c cred_protect] [-hruv] " + "\n"); + exit(EXIT_FAILURE); +} + +static void +verify_cred(int type, const char *fmt, const unsigned char *authdata_ptr, + size_t authdata_len, const unsigned char *attstmt_ptr, size_t attstmt_len, + bool rk, bool uv, int ext, int cred_protect, const char *key_out, + const char *id_out) +{ + fido_cred_t *cred; + int r; + + if ((cred = fido_cred_new()) == NULL) + errx(1, "fido_cred_new"); + + /* type */ + r = fido_cred_set_type(cred, type); + if (r != FIDO_OK) + errx(1, "fido_cred_set_type: %s (0x%x)", fido_strerr(r), r); + + /* client data */ + r = fido_cred_set_clientdata(cred, cd, sizeof(cd)); + if (r != FIDO_OK) + errx(1, "fido_cred_set_clientdata: %s (0x%x)", fido_strerr(r), r); + + /* relying party */ + r = fido_cred_set_rp(cred, "localhost", "sweet home localhost"); + if (r != FIDO_OK) + errx(1, "fido_cred_set_rp: %s (0x%x)", fido_strerr(r), r); + + /* authdata */ + r = fido_cred_set_authdata(cred, authdata_ptr, authdata_len); + if (r != FIDO_OK) + errx(1, "fido_cred_set_authdata: %s (0x%x)", fido_strerr(r), r); + + /* extensions */ + r = fido_cred_set_extensions(cred, ext); + if (r != FIDO_OK) + errx(1, "fido_cred_set_extensions: %s (0x%x)", fido_strerr(r), r); + + /* resident key */ + if (rk && (r = fido_cred_set_rk(cred, FIDO_OPT_TRUE)) != FIDO_OK) + errx(1, "fido_cred_set_rk: %s (0x%x)", fido_strerr(r), r); + + /* user verification */ + if (uv && (r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK) + errx(1, "fido_cred_set_uv: %s (0x%x)", fido_strerr(r), r); + + /* credProt */ + if (cred_protect != 0 && (r = fido_cred_set_prot(cred, + cred_protect)) != FIDO_OK) + errx(1, "fido_cred_set_prot: %s (0x%x)", fido_strerr(r), r); + + /* fmt */ + r = fido_cred_set_fmt(cred, fmt); + if (r != FIDO_OK) + errx(1, "fido_cred_set_fmt: %s (0x%x)", fido_strerr(r), r); + + if (!strcmp(fido_cred_fmt(cred), "none")) { + warnx("no attestation data, skipping credential verification"); + goto out; + } + + /* attestation statement */ + r = fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len); + if (r != FIDO_OK) + errx(1, "fido_cred_set_attstmt: %s (0x%x)", fido_strerr(r), r); + + r = fido_cred_verify(cred); + if (r != FIDO_OK) + errx(1, "fido_cred_verify: %s (0x%x)", fido_strerr(r), r); + +out: + if (key_out != NULL) { + /* extract the credential pubkey */ + if (type == COSE_ES256) { + if (write_es256_pubkey(key_out, + fido_cred_pubkey_ptr(cred), + fido_cred_pubkey_len(cred)) < 0) + errx(1, "write_es256_pubkey"); + } else if (type == COSE_ES384) { + if (write_es384_pubkey(key_out, + fido_cred_pubkey_ptr(cred), + fido_cred_pubkey_len(cred)) < 0) + errx(1, "write_es384_pubkey"); + } else if (type == COSE_RS256) { + if (write_rs256_pubkey(key_out, + fido_cred_pubkey_ptr(cred), + fido_cred_pubkey_len(cred)) < 0) + errx(1, "write_rs256_pubkey"); + } else if (type == COSE_EDDSA) { + if (write_eddsa_pubkey(key_out, + fido_cred_pubkey_ptr(cred), + fido_cred_pubkey_len(cred)) < 0) + errx(1, "write_eddsa_pubkey"); + } + } + + if (id_out != NULL) { + /* extract the credential id */ + if (write_blob(id_out, fido_cred_id_ptr(cred), + fido_cred_id_len(cred)) < 0) + errx(1, "write_blob"); + } + + fido_cred_free(&cred); +} + +int +main(int argc, char **argv) +{ + bool rk = false; + bool uv = false; + bool u2f = false; + fido_dev_t *dev; + fido_cred_t *cred = NULL; + const char *pin = NULL; + const char *blobkey_out = NULL; + const char *key_out = NULL; + const char *id_out = NULL; + unsigned char *body = NULL; + long long ms = 0; + size_t len; + int type = COSE_ES256; + int ext = 0; + int ch; + int r; + long long cred_protect = 0; + + if ((cred = fido_cred_new()) == NULL) + errx(1, "fido_cred_new"); + + while ((ch = getopt(argc, argv, "P:T:b:e:hi:k:rt:uvc:")) != -1) { + switch (ch) { + case 'P': + pin = optarg; + break; + case 'T': + if (base10(optarg, &ms) < 0) + errx(1, "base10: %s", optarg); + if (ms <= 0 || ms > 30) + errx(1, "-T: %s must be in (0,30]", optarg); + ms *= 1000; /* seconds to milliseconds */ + break; + case 'b': + ext |= FIDO_EXT_LARGEBLOB_KEY; + blobkey_out = optarg; + break; + case 'e': + if (read_blob(optarg, &body, &len) < 0) + errx(1, "read_blob: %s", optarg); + r = fido_cred_exclude(cred, body, len); + if (r != FIDO_OK) + errx(1, "fido_cred_exclude: %s (0x%x)", + fido_strerr(r), r); + free(body); + body = NULL; + break; + case 'h': + ext |= FIDO_EXT_HMAC_SECRET; + break; + case 'c': + if (base10(optarg, &cred_protect) < 0) + errx(1, "base10: %s", optarg); + if (cred_protect <= 0 || cred_protect > 3) + errx(1, "-c: %s must be in (1,3)", optarg); + ext |= FIDO_EXT_CRED_PROTECT; + break; + case 'i': + id_out = optarg; + break; + case 'k': + key_out = optarg; + break; + case 'r': + rk = true; + break; + case 't': + if (strcmp(optarg, "es256") == 0) + type = COSE_ES256; + else if (strcmp(optarg, "es384") == 0) + type = COSE_ES384; + else if (strcmp(optarg, "rs256") == 0) + type = COSE_RS256; + else if (strcmp(optarg, "eddsa") == 0) + type = COSE_EDDSA; + else + errx(1, "unknown type %s", optarg); + break; + case 'u': + u2f = true; + break; + case 'v': + uv = true; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + fido_init(0); + + if ((dev = fido_dev_new()) == NULL) + errx(1, "fido_dev_new"); + + r = fido_dev_open(dev, argv[0]); + if (r != FIDO_OK) + errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r); + if (u2f) + fido_dev_force_u2f(dev); + + /* type */ + r = fido_cred_set_type(cred, type); + if (r != FIDO_OK) + errx(1, "fido_cred_set_type: %s (0x%x)", fido_strerr(r), r); + + /* client data */ + r = fido_cred_set_clientdata(cred, cd, sizeof(cd)); + if (r != FIDO_OK) + errx(1, "fido_cred_set_clientdata: %s (0x%x)", fido_strerr(r), r); + + /* relying party */ + r = fido_cred_set_rp(cred, "localhost", "sweet home localhost"); + if (r != FIDO_OK) + errx(1, "fido_cred_set_rp: %s (0x%x)", fido_strerr(r), r); + + /* user */ + r = fido_cred_set_user(cred, user_id, sizeof(user_id), "john smith", + "jsmith", NULL); + if (r != FIDO_OK) + errx(1, "fido_cred_set_user: %s (0x%x)", fido_strerr(r), r); + + /* extensions */ + r = fido_cred_set_extensions(cred, ext); + if (r != FIDO_OK) + errx(1, "fido_cred_set_extensions: %s (0x%x)", fido_strerr(r), r); + + /* resident key */ + if (rk && (r = fido_cred_set_rk(cred, FIDO_OPT_TRUE)) != FIDO_OK) + errx(1, "fido_cred_set_rk: %s (0x%x)", fido_strerr(r), r); + + /* user verification */ + if (uv && (r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK) + errx(1, "fido_cred_set_uv: %s (0x%x)", fido_strerr(r), r); + + /* credProt */ + if (cred_protect != 0 && (r = fido_cred_set_prot(cred, + (int)cred_protect)) != FIDO_OK) + errx(1, "fido_cred_set_prot: %s (0x%x)", fido_strerr(r), r); + + /* timeout */ + if (ms != 0 && (r = fido_dev_set_timeout(dev, (int)ms)) != FIDO_OK) + errx(1, "fido_dev_set_timeout: %s (0x%x)", fido_strerr(r), r); + + if ((r = fido_dev_make_cred(dev, cred, pin)) != FIDO_OK) { + fido_dev_cancel(dev); + errx(1, "fido_makecred: %s (0x%x)", fido_strerr(r), r); + } + + r = fido_dev_close(dev); + if (r != FIDO_OK) + errx(1, "fido_dev_close: %s (0x%x)", fido_strerr(r), r); + + fido_dev_free(&dev); + + /* when verifying, pin implies uv */ + if (pin) + uv = true; + + verify_cred(type, fido_cred_fmt(cred), fido_cred_authdata_ptr(cred), + fido_cred_authdata_len(cred), fido_cred_attstmt_ptr(cred), + fido_cred_attstmt_len(cred), rk, uv, ext, fido_cred_prot(cred), + key_out, id_out); + + if (blobkey_out != NULL) { + /* extract the "largeBlob" key */ + if (write_blob(blobkey_out, fido_cred_largeblob_key_ptr(cred), + fido_cred_largeblob_key_len(cred)) < 0) + errx(1, "write_blob"); + } + + fido_cred_free(&cred); + + exit(0); +} diff --git a/examples/extern.h b/examples/extern.h new file mode 100644 index 0000000..5cffd7f --- /dev/null +++ b/examples/extern.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _EXTERN_H_ +#define _EXTERN_H_ + +#include +#include +#include + +/* util.c */ +EC_KEY *read_ec_pubkey(const char *); +RSA *read_rsa_pubkey(const char *); +EVP_PKEY *read_eddsa_pubkey(const char *); +int base10(const char *, long long *); +int read_blob(const char *, unsigned char **, size_t *); +int write_blob(const char *, const unsigned char *, size_t); +int write_es256_pubkey(const char *, const void *, size_t); +int write_es384_pubkey(const char *, const void *, size_t); +int write_rs256_pubkey(const char *, const void *, size_t); +int write_eddsa_pubkey(const char *, const void *, size_t); + +#endif /* _EXTERN_H_ */ diff --git a/examples/info.c b/examples/info.c new file mode 100644 index 0000000..a10a50c --- /dev/null +++ b/examples/info.c @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2018-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include + +#include "../openbsd-compat/openbsd-compat.h" + +/* + * Pretty-print a device's capabilities flags and return the result. + */ +static void +format_flags(char *ret, size_t retlen, uint8_t flags) +{ + memset(ret, 0, retlen); + + if (flags & FIDO_CAP_WINK) { + if (strlcat(ret, "wink,", retlen) >= retlen) + goto toolong; + } else { + if (strlcat(ret, "nowink,", retlen) >= retlen) + goto toolong; + } + + if (flags & FIDO_CAP_CBOR) { + if (strlcat(ret, " cbor,", retlen) >= retlen) + goto toolong; + } else { + if (strlcat(ret, " nocbor,", retlen) >= retlen) + goto toolong; + } + + if (flags & FIDO_CAP_NMSG) { + if (strlcat(ret, " nomsg", retlen) >= retlen) + goto toolong; + } else { + if (strlcat(ret, " msg", retlen) >= retlen) + goto toolong; + } + + return; +toolong: + strlcpy(ret, "toolong", retlen); +} + +/* + * Print a FIDO device's attributes on stdout. + */ +static void +print_attr(const fido_dev_t *dev) +{ + char flags_txt[128]; + + printf("proto: 0x%02x\n", fido_dev_protocol(dev)); + printf("major: 0x%02x\n", fido_dev_major(dev)); + printf("minor: 0x%02x\n", fido_dev_minor(dev)); + printf("build: 0x%02x\n", fido_dev_build(dev)); + + format_flags(flags_txt, sizeof(flags_txt), fido_dev_flags(dev)); + printf("caps: 0x%02x (%s)\n", fido_dev_flags(dev), flags_txt); +} + +/* + * Auxiliary function to print an array of strings on stdout. + */ +static void +print_str_array(const char *label, char * const *sa, size_t len) +{ + if (len == 0) + return; + + printf("%s strings: ", label); + + for (size_t i = 0; i < len; i++) + printf("%s%s", i > 0 ? ", " : "", sa[i]); + + printf("\n"); +} + +/* + * Auxiliary function to print (char *, bool) pairs on stdout. + */ +static void +print_opt_array(const char *label, char * const *name, const bool *value, + size_t len) +{ + if (len == 0) + return; + + printf("%s: ", label); + + for (size_t i = 0; i < len; i++) + printf("%s%s%s", i > 0 ? ", " : "", + value[i] ? "" : "no", name[i]); + + printf("\n"); +} + +/* + * Auxiliary function to print (char *, uint64_t) pairs on stdout. + */ +static void +print_cert_array(const char *label, char * const *name, const uint64_t *value, + size_t len) +{ + if (len == 0) + return; + + printf("%s: ", label); + + for (size_t i = 0; i < len; i++) + printf("%s%s %llu", i > 0 ? ", " : "", name[i], + (unsigned long long)value[i]); + + printf("\n"); +} + +/* + * Auxiliary function to print a list of supported COSE algorithms on stdout. + */ +static void +print_algorithms(const fido_cbor_info_t *ci) +{ + const char *cose, *type; + size_t len; + + if ((len = fido_cbor_info_algorithm_count(ci)) == 0) + return; + + printf("algorithms: "); + + for (size_t i = 0; i < len; i++) { + cose = type = "unknown"; + switch (fido_cbor_info_algorithm_cose(ci, i)) { + case COSE_ES256: + cose = "es256"; + break; + case COSE_ES384: + cose = "es384"; + break; + case COSE_RS256: + cose = "rs256"; + break; + case COSE_EDDSA: + cose = "eddsa"; + break; + } + if (fido_cbor_info_algorithm_type(ci, i) != NULL) + type = fido_cbor_info_algorithm_type(ci, i); + printf("%s%s (%s)", i > 0 ? ", " : "", cose, type); + } + + printf("\n"); +} + +/* + * Auxiliary function to print an authenticator's AAGUID on stdout. + */ +static void +print_aaguid(const unsigned char *buf, size_t buflen) +{ + printf("aaguid: "); + + while (buflen--) + printf("%02x", *buf++); + + printf("\n"); +} + +/* + * Auxiliary function to print an authenticator's maximum message size on + * stdout. + */ +static void +print_maxmsgsiz(uint64_t maxmsgsiz) +{ + printf("maxmsgsiz: %d\n", (int)maxmsgsiz); +} + +/* + * Auxiliary function to print an authenticator's maximum number of credentials + * in a credential list on stdout. + */ +static void +print_maxcredcntlst(uint64_t maxcredcntlst) +{ + printf("maxcredcntlst: %d\n", (int)maxcredcntlst); +} + +/* + * Auxiliary function to print an authenticator's maximum credential ID length + * on stdout. + */ +static void +print_maxcredidlen(uint64_t maxcredidlen) +{ + printf("maxcredlen: %d\n", (int)maxcredidlen); +} + +/* + * Auxiliary function to print the maximum size of an authenticator's + * serialized largeBlob array. + */ +static void +print_maxlargeblob(uint64_t maxlargeblob) +{ + printf("maxlargeblob: %d\n", (int)maxlargeblob); +} + +/* + * Auxiliary function to print the authenticator's estimated number of + * remaining resident credentials. + */ +static void +print_rk_remaining(int64_t rk_remaining) +{ + printf("remaining rk(s): "); + + if (rk_remaining == -1) + printf("undefined\n"); + else + printf("%d\n", (int)rk_remaining); +} + +/* + * Auxiliary function to print the minimum pin length observed by the + * authenticator. + */ +static void +print_minpinlen(uint64_t minpinlen) +{ + printf("minpinlen: %d\n", (int)minpinlen); +} + +/* + * Auxiliary function to print the authenticator's preferred (platform) + * UV attempts. + */ +static void +print_uv_attempts(uint64_t uv_attempts) +{ + printf("platform uv attempt(s): %d\n", (int)uv_attempts); +} + +/* + * Auxiliary function to print an authenticator's firmware version on stdout. + */ +static void +print_fwversion(uint64_t fwversion) +{ + printf("fwversion: 0x%x\n", (int)fwversion); +} + +/* + * Auxiliary function to print an array of bytes on stdout. + */ +static void +print_byte_array(const char *label, const uint8_t *ba, size_t len) +{ + if (len == 0) + return; + + printf("%s: ", label); + + for (size_t i = 0; i < len; i++) + printf("%s%u", i > 0 ? ", " : "", (unsigned)ba[i]); + + printf("\n"); +} + +static void +getinfo(const char *path) +{ + fido_dev_t *dev; + fido_cbor_info_t *ci; + int r; + + fido_init(0); + + if ((dev = fido_dev_new()) == NULL) + errx(1, "fido_dev_new"); + if ((r = fido_dev_open(dev, path)) != FIDO_OK) + errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r); + + print_attr(dev); + + if (fido_dev_is_fido2(dev) == false) + goto end; + if ((ci = fido_cbor_info_new()) == NULL) + errx(1, "fido_cbor_info_new"); + if ((r = fido_dev_get_cbor_info(dev, ci)) != FIDO_OK) + errx(1, "fido_dev_get_cbor_info: %s (0x%x)", fido_strerr(r), r); + + /* print supported protocol versions */ + print_str_array("version", fido_cbor_info_versions_ptr(ci), + fido_cbor_info_versions_len(ci)); + + /* print supported extensions */ + print_str_array("extension", fido_cbor_info_extensions_ptr(ci), + fido_cbor_info_extensions_len(ci)); + + /* print supported transports */ + print_str_array("transport", fido_cbor_info_transports_ptr(ci), + fido_cbor_info_transports_len(ci)); + + /* print supported algorithms */ + print_algorithms(ci); + + /* print aaguid */ + print_aaguid(fido_cbor_info_aaguid_ptr(ci), + fido_cbor_info_aaguid_len(ci)); + + /* print supported options */ + print_opt_array("options", fido_cbor_info_options_name_ptr(ci), + fido_cbor_info_options_value_ptr(ci), + fido_cbor_info_options_len(ci)); + + /* print certifications */ + print_cert_array("certifications", fido_cbor_info_certs_name_ptr(ci), + fido_cbor_info_certs_value_ptr(ci), + fido_cbor_info_certs_len(ci)); + + /* print firmware version */ + print_fwversion(fido_cbor_info_fwversion(ci)); + + /* print maximum message size */ + print_maxmsgsiz(fido_cbor_info_maxmsgsiz(ci)); + + /* print maximum number of credentials allowed in credential lists */ + print_maxcredcntlst(fido_cbor_info_maxcredcntlst(ci)); + + /* print maximum length of a credential ID */ + print_maxcredidlen(fido_cbor_info_maxcredidlen(ci)); + + /* print maximum length of largeBlob array */ + print_maxlargeblob(fido_cbor_info_maxlargeblob(ci)); + + /* print number of remaining resident credentials */ + print_rk_remaining(fido_cbor_info_rk_remaining(ci)); + + /* print minimum pin length */ + print_minpinlen(fido_cbor_info_minpinlen(ci)); + + /* print supported pin protocols */ + print_byte_array("pin protocols", fido_cbor_info_protocols_ptr(ci), + fido_cbor_info_protocols_len(ci)); + + /* print whether a new pin is required */ + printf("pin change required: %s\n", + fido_cbor_info_new_pin_required(ci) ? "true" : "false"); + + /* print platform uv attempts */ + print_uv_attempts(fido_cbor_info_uv_attempts(ci)); + + fido_cbor_info_free(&ci); +end: + if ((r = fido_dev_close(dev)) != FIDO_OK) + errx(1, "fido_dev_close: %s (0x%x)", fido_strerr(r), r); + + fido_dev_free(&dev); +} + +int +main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "usage: info \n"); + exit(EXIT_FAILURE); + } + + getinfo(argv[1]); + + exit(0); +} diff --git a/examples/manifest.c b/examples/manifest.c new file mode 100644 index 0000000..c2b3bf1 --- /dev/null +++ b/examples/manifest.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +#include "../openbsd-compat/openbsd-compat.h" + +int +main(void) +{ + fido_dev_info_t *devlist; + size_t ndevs; + int r; + + fido_init(0); + + if ((devlist = fido_dev_info_new(64)) == NULL) + errx(1, "fido_dev_info_new"); + + if ((r = fido_dev_info_manifest(devlist, 64, &ndevs)) != FIDO_OK) + errx(1, "fido_dev_info_manifest: %s (0x%x)", fido_strerr(r), r); + + for (size_t i = 0; i < ndevs; i++) { + const fido_dev_info_t *di = fido_dev_info_ptr(devlist, i); + printf("%s: vendor=0x%04x, product=0x%04x (%s %s)\n", + fido_dev_info_path(di), + (uint16_t)fido_dev_info_vendor(di), + (uint16_t)fido_dev_info_product(di), + fido_dev_info_manufacturer_string(di), + fido_dev_info_product_string(di)); + } + + fido_dev_info_free(&devlist, ndevs); + + exit(0); +} diff --git a/examples/reset.c b/examples/reset.c new file mode 100644 index 0000000..767a162 --- /dev/null +++ b/examples/reset.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Perform a factory reset on a given authenticator. + */ + +#include +#include +#include + +#include "../openbsd-compat/openbsd-compat.h" +#include "extern.h" + +int +main(int argc, char **argv) +{ + fido_dev_t *dev; + int r; + + if (argc != 2) { + fprintf(stderr, "usage: reset \n"); + exit(EXIT_FAILURE); + } + + fido_init(0); + + if ((dev = fido_dev_new()) == NULL) + errx(1, "fido_dev_new"); + + if ((r = fido_dev_open(dev, argv[1])) != FIDO_OK) + errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r); + + if ((r = fido_dev_reset(dev)) != FIDO_OK) { + fido_dev_cancel(dev); + errx(1, "fido_dev_reset: %s (0x%x)", fido_strerr(r), r); + } + + if ((r = fido_dev_close(dev)) != FIDO_OK) + errx(1, "fido_dev_close: %s (0x%x)", fido_strerr(r), r); + + fido_dev_free(&dev); + + exit(0); +} diff --git a/examples/retries.c b/examples/retries.c new file mode 100644 index 0000000..a0610fe --- /dev/null +++ b/examples/retries.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Get an authenticator's number of PIN attempts left. + */ + +#include +#include +#include + +#include "../openbsd-compat/openbsd-compat.h" + +int +main(int argc, char **argv) +{ + fido_dev_t *dev; + int n; + int r; + + if (argc != 2) { + fprintf(stderr, "usage: retries \n"); + exit(EXIT_FAILURE); + } + + fido_init(0); + + if ((dev = fido_dev_new()) == NULL) + errx(1, "fido_dev_new"); + + if ((r = fido_dev_open(dev, argv[1])) != FIDO_OK) + errx(1, "fido_open: %s (0x%x)", fido_strerr(r), r); + + if ((r = fido_dev_get_retry_count(dev, &n)) != FIDO_OK) + errx(1, "fido_dev_get_retry_count: %s (0x%x)", fido_strerr(r), r); + + if ((r = fido_dev_close(dev)) != FIDO_OK) + errx(1, "fido_close: %s (0x%x)", fido_strerr(r), r); + + fido_dev_free(&dev); + + printf("%d\n", n); + + exit(0); +} diff --git a/examples/select.c b/examples/select.c new file mode 100644 index 0000000..008eb2e --- /dev/null +++ b/examples/select.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2020-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include "../openbsd-compat/openbsd-compat.h" + +#define FIDO_POLL_MS 50 + +#if defined(_MSC_VER) +static int +nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +{ + if (rmtp != NULL) { + errno = EINVAL; + return (-1); + } + + Sleep((DWORD)(rqtp->tv_sec * 1000) + (DWORD)(rqtp->tv_nsec / 1000000)); + + return (0); +} +#endif + +static fido_dev_t * +open_dev(const fido_dev_info_t *di) +{ + fido_dev_t *dev; + int r; + + if ((dev = fido_dev_new()) == NULL) { + warnx("%s: fido_dev_new", __func__); + return (NULL); + } + + if ((r = fido_dev_open(dev, fido_dev_info_path(di))) != FIDO_OK) { + warnx("%s: fido_dev_open %s: %s", __func__, + fido_dev_info_path(di), fido_strerr(r)); + fido_dev_free(&dev); + return (NULL); + } + + printf("%s (0x%04x:0x%04x) is %s\n", fido_dev_info_path(di), + fido_dev_info_vendor(di), fido_dev_info_product(di), + fido_dev_is_fido2(dev) ? "fido2" : "u2f"); + + return (dev); +} + +static int +select_dev(const fido_dev_info_t *devlist, size_t ndevs, fido_dev_t **dev, + size_t *idx, int secs) +{ + const fido_dev_info_t *di; + fido_dev_t **devtab; + struct timespec ts_start; + struct timespec ts_now; + struct timespec ts_delta; + struct timespec ts_pause; + size_t nopen = 0; + int touched; + int r; + long ms_remain; + + *dev = NULL; + *idx = 0; + + printf("%u authenticator(s) detected\n", (unsigned)ndevs); + + if (ndevs == 0) + return (0); /* nothing to do */ + + if ((devtab = calloc(ndevs, sizeof(*devtab))) == NULL) { + warn("%s: calloc", __func__); + return (-1); + } + + for (size_t i = 0; i < ndevs; i++) { + di = fido_dev_info_ptr(devlist, i); + if ((devtab[i] = open_dev(di)) != NULL) { + *idx = i; + nopen++; + } + } + + printf("%u authenticator(s) opened\n", (unsigned)nopen); + + if (nopen < 2) { + if (nopen == 1) + *dev = devtab[*idx]; /* single candidate */ + r = 0; + goto out; + } + + for (size_t i = 0; i < ndevs; i++) { + di = fido_dev_info_ptr(devlist, i); + if (devtab[i] == NULL) + continue; /* failed to open */ + if ((r = fido_dev_get_touch_begin(devtab[i])) != FIDO_OK) { + warnx("%s: fido_dev_get_touch_begin %s: %s", __func__, + fido_dev_info_path(di), fido_strerr(r)); + r = -1; + goto out; + } + } + + if (clock_gettime(CLOCK_MONOTONIC, &ts_start) != 0) { + warn("%s: clock_gettime", __func__); + r = -1; + goto out; + } + + ts_pause.tv_sec = 0; + ts_pause.tv_nsec = 200000000; /* 200ms */ + + do { + nanosleep(&ts_pause, NULL); + + for (size_t i = 0; i < ndevs; i++) { + di = fido_dev_info_ptr(devlist, i); + if (devtab[i] == NULL) { + /* failed to open or discarded */ + continue; + } + if ((r = fido_dev_get_touch_status(devtab[i], &touched, + FIDO_POLL_MS)) != FIDO_OK) { + warnx("%s: fido_dev_get_touch_status %s: %s", + __func__, fido_dev_info_path(di), + fido_strerr(r)); + fido_dev_close(devtab[i]); + fido_dev_free(&devtab[i]); + continue; /* discard */ + } + if (touched) { + *dev = devtab[i]; + *idx = i; + r = 0; + goto out; + } + } + + if (clock_gettime(CLOCK_MONOTONIC, &ts_now) != 0) { + warn("%s: clock_gettime", __func__); + r = -1; + goto out; + } + + timespecsub(&ts_now, &ts_start, &ts_delta); + ms_remain = (secs * 1000) - ((long)ts_delta.tv_sec * 1000) + + ((long)ts_delta.tv_nsec / 1000000); + } while (ms_remain > FIDO_POLL_MS); + + printf("timeout after %d seconds\n", secs); + r = -1; +out: + if (r != 0) { + *dev = NULL; + *idx = 0; + } + + for (size_t i = 0; i < ndevs; i++) { + if (devtab[i] && devtab[i] != *dev) { + fido_dev_cancel(devtab[i]); + fido_dev_close(devtab[i]); + fido_dev_free(&devtab[i]); + } + } + + free(devtab); + + return (r); +} + +int +main(void) +{ + const fido_dev_info_t *di; + fido_dev_info_t *devlist; + fido_dev_t *dev; + size_t idx; + size_t ndevs; + int r; + + fido_init(0); + + if ((devlist = fido_dev_info_new(64)) == NULL) + errx(1, "fido_dev_info_new"); + + if ((r = fido_dev_info_manifest(devlist, 64, &ndevs)) != FIDO_OK) + errx(1, "fido_dev_info_manifest: %s (0x%x)", fido_strerr(r), r); + if (select_dev(devlist, ndevs, &dev, &idx, 15) != 0) + errx(1, "select_dev"); + if (dev == NULL) + errx(1, "no authenticator found"); + + di = fido_dev_info_ptr(devlist, idx); + printf("%s: %s by %s (PIN %sset)\n", fido_dev_info_path(di), + fido_dev_info_product_string(di), + fido_dev_info_manufacturer_string(di), + fido_dev_has_pin(dev) ? "" : "un"); + + fido_dev_close(dev); + fido_dev_free(&dev); + fido_dev_info_free(&devlist, ndevs); + + exit(0); +} diff --git a/examples/setpin.c b/examples/setpin.c new file mode 100644 index 0000000..72e08e4 --- /dev/null +++ b/examples/setpin.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Configure a PIN on a given authenticator. + */ + +#include +#include +#include + +#include "../openbsd-compat/openbsd-compat.h" + +static void +setpin(const char *path, const char *pin, const char *oldpin) +{ + fido_dev_t *dev; + int r; + + fido_init(0); + + if ((dev = fido_dev_new()) == NULL) + errx(1, "fido_dev_new"); + + if ((r = fido_dev_open(dev, path)) != FIDO_OK) + errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r); + + if ((r = fido_dev_set_pin(dev, pin, oldpin)) != FIDO_OK) + errx(1, "fido_dev_set_pin: %s (0x%x)", fido_strerr(r), r); + + if ((r = fido_dev_close(dev)) != FIDO_OK) + errx(1, "fido_dev_close: %s (0x%x)", fido_strerr(r), r); + + fido_dev_free(&dev); +} + +int +main(int argc, char **argv) +{ + if (argc < 3 || argc > 4) { + fprintf(stderr, "usage: setpin [oldpin] \n"); + exit(EXIT_FAILURE); + } + + if (argc == 3) + setpin(argv[2], argv[1], NULL); + else + setpin(argv[3], argv[1], argv[2]); + + exit(0); +} diff --git a/examples/util.c b/examples/util.c new file mode 100644 index 0000000..0c0c77a --- /dev/null +++ b/examples/util.c @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2018-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef _MSC_VER +#include "../openbsd-compat/posix_win.h" +#endif +#include "../openbsd-compat/openbsd-compat.h" +#include "extern.h" + +int +base10(const char *str, long long *ll) +{ + char *ep; + + *ll = strtoll(str, &ep, 10); + if (str == ep || *ep != '\0') + return (-1); + else if (*ll == LLONG_MIN && errno == ERANGE) + return (-1); + else if (*ll == LLONG_MAX && errno == ERANGE) + return (-1); + + return (0); +} + +int +write_blob(const char *path, const unsigned char *ptr, size_t len) +{ + int fd, ok = -1; + ssize_t n; + + if ((fd = open(path, O_WRONLY | O_CREAT, 0600)) < 0) { + warn("open %s", path); + goto fail; + } + + if ((n = write(fd, ptr, len)) < 0) { + warn("write"); + goto fail; + } + if ((size_t)n != len) { + warnx("write"); + goto fail; + } + + ok = 0; +fail: + if (fd != -1) { + close(fd); + } + + return (ok); +} + +int +read_blob(const char *path, unsigned char **ptr, size_t *len) +{ + int fd, ok = -1; + struct stat st; + ssize_t n; + + *ptr = NULL; + *len = 0; + + if ((fd = open(path, O_RDONLY)) < 0) { + warn("open %s", path); + goto fail; + } + if (fstat(fd, &st) < 0) { + warn("stat %s", path); + goto fail; + } + if (st.st_size < 0) { + warnx("stat %s: invalid size", path); + goto fail; + } + *len = (size_t)st.st_size; + if ((*ptr = malloc(*len)) == NULL) { + warn("malloc"); + goto fail; + } + if ((n = read(fd, *ptr, *len)) < 0) { + warn("read"); + goto fail; + } + if ((size_t)n != *len) { + warnx("read"); + goto fail; + } + + ok = 0; +fail: + if (fd != -1) { + close(fd); + } + if (ok < 0) { + free(*ptr); + *ptr = NULL; + *len = 0; + } + + return (ok); +} + +EC_KEY * +read_ec_pubkey(const char *path) +{ + FILE *fp = NULL; + EVP_PKEY *pkey = NULL; + EC_KEY *ec = NULL; + + if ((fp = fopen(path, "r")) == NULL) { + warn("fopen"); + goto fail; + } + + if ((pkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) { + warnx("PEM_read_PUBKEY"); + goto fail; + } + if ((ec = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) { + warnx("EVP_PKEY_get1_EC_KEY"); + goto fail; + } + +fail: + if (fp != NULL) { + fclose(fp); + } + if (pkey != NULL) { + EVP_PKEY_free(pkey); + } + + return (ec); +} + +int +write_es256_pubkey(const char *path, const void *ptr, size_t len) +{ + FILE *fp = NULL; + EVP_PKEY *pkey = NULL; + es256_pk_t *pk = NULL; + int fd = -1; + int ok = -1; + + if ((pk = es256_pk_new()) == NULL) { + warnx("es256_pk_new"); + goto fail; + } + + if (es256_pk_from_ptr(pk, ptr, len) != FIDO_OK) { + warnx("es256_pk_from_ptr"); + goto fail; + } + + if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) < 0) { + warn("open %s", path); + goto fail; + } + + if ((fp = fdopen(fd, "w")) == NULL) { + warn("fdopen"); + goto fail; + } + fd = -1; /* owned by fp now */ + + if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL) { + warnx("es256_pk_to_EVP_PKEY"); + goto fail; + } + + if (PEM_write_PUBKEY(fp, pkey) == 0) { + warnx("PEM_write_PUBKEY"); + goto fail; + } + + ok = 0; +fail: + es256_pk_free(&pk); + + if (fp != NULL) { + fclose(fp); + } + if (fd != -1) { + close(fd); + } + if (pkey != NULL) { + EVP_PKEY_free(pkey); + } + + return (ok); +} + +int +write_es384_pubkey(const char *path, const void *ptr, size_t len) +{ + FILE *fp = NULL; + EVP_PKEY *pkey = NULL; + es384_pk_t *pk = NULL; + int fd = -1; + int ok = -1; + + if ((pk = es384_pk_new()) == NULL) { + warnx("es384_pk_new"); + goto fail; + } + + if (es384_pk_from_ptr(pk, ptr, len) != FIDO_OK) { + warnx("es384_pk_from_ptr"); + goto fail; + } + + if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) < 0) { + warn("open %s", path); + goto fail; + } + + if ((fp = fdopen(fd, "w")) == NULL) { + warn("fdopen"); + goto fail; + } + fd = -1; /* owned by fp now */ + + if ((pkey = es384_pk_to_EVP_PKEY(pk)) == NULL) { + warnx("es384_pk_to_EVP_PKEY"); + goto fail; + } + + if (PEM_write_PUBKEY(fp, pkey) == 0) { + warnx("PEM_write_PUBKEY"); + goto fail; + } + + ok = 0; +fail: + es384_pk_free(&pk); + + if (fp != NULL) { + fclose(fp); + } + if (fd != -1) { + close(fd); + } + if (pkey != NULL) { + EVP_PKEY_free(pkey); + } + + return (ok); +} + +RSA * +read_rsa_pubkey(const char *path) +{ + FILE *fp = NULL; + EVP_PKEY *pkey = NULL; + RSA *rsa = NULL; + + if ((fp = fopen(path, "r")) == NULL) { + warn("fopen"); + goto fail; + } + + if ((pkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) { + warnx("PEM_read_PUBKEY"); + goto fail; + } + if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL) { + warnx("EVP_PKEY_get1_RSA"); + goto fail; + } + +fail: + if (fp != NULL) { + fclose(fp); + } + if (pkey != NULL) { + EVP_PKEY_free(pkey); + } + + return (rsa); +} + +int +write_rs256_pubkey(const char *path, const void *ptr, size_t len) +{ + FILE *fp = NULL; + EVP_PKEY *pkey = NULL; + rs256_pk_t *pk = NULL; + int fd = -1; + int ok = -1; + + if ((pk = rs256_pk_new()) == NULL) { + warnx("rs256_pk_new"); + goto fail; + } + + if (rs256_pk_from_ptr(pk, ptr, len) != FIDO_OK) { + warnx("rs256_pk_from_ptr"); + goto fail; + } + + if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) < 0) { + warn("open %s", path); + goto fail; + } + + if ((fp = fdopen(fd, "w")) == NULL) { + warn("fdopen"); + goto fail; + } + fd = -1; /* owned by fp now */ + + if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL) { + warnx("rs256_pk_to_EVP_PKEY"); + goto fail; + } + + if (PEM_write_PUBKEY(fp, pkey) == 0) { + warnx("PEM_write_PUBKEY"); + goto fail; + } + + ok = 0; +fail: + rs256_pk_free(&pk); + + if (fp != NULL) { + fclose(fp); + } + if (fd != -1) { + close(fd); + } + if (pkey != NULL) { + EVP_PKEY_free(pkey); + } + + return (ok); +} + +EVP_PKEY * +read_eddsa_pubkey(const char *path) +{ + FILE *fp = NULL; + EVP_PKEY *pkey = NULL; + + if ((fp = fopen(path, "r")) == NULL) { + warn("fopen"); + goto fail; + } + + if ((pkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) { + warnx("PEM_read_PUBKEY"); + goto fail; + } + +fail: + if (fp) { + fclose(fp); + } + + return (pkey); +} + +int +write_eddsa_pubkey(const char *path, const void *ptr, size_t len) +{ + FILE *fp = NULL; + EVP_PKEY *pkey = NULL; + eddsa_pk_t *pk = NULL; + int fd = -1; + int ok = -1; + + if ((pk = eddsa_pk_new()) == NULL) { + warnx("eddsa_pk_new"); + goto fail; + } + + if (eddsa_pk_from_ptr(pk, ptr, len) != FIDO_OK) { + warnx("eddsa_pk_from_ptr"); + goto fail; + } + + if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) < 0) { + warn("open %s", path); + goto fail; + } + + if ((fp = fdopen(fd, "w")) == NULL) { + warn("fdopen"); + goto fail; + } + fd = -1; /* owned by fp now */ + + if ((pkey = eddsa_pk_to_EVP_PKEY(pk)) == NULL) { + warnx("eddsa_pk_to_EVP_PKEY"); + goto fail; + } + + if (PEM_write_PUBKEY(fp, pkey) == 0) { + warnx("PEM_write_PUBKEY"); + goto fail; + } + + ok = 0; +fail: + eddsa_pk_free(&pk); + + if (fp != NULL) { + fclose(fp); + } + if (fd != -1) { + close(fd); + } + if (pkey != NULL) { + EVP_PKEY_free(pkey); + } + + return (ok); +} diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt new file mode 100644 index 0000000..ca272bb --- /dev/null +++ b/fuzz/CMakeLists.txt @@ -0,0 +1,89 @@ +# Copyright (c) 2019-2024 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. +# SPDX-License-Identifier: BSD-2-Clause + +list(APPEND COMPAT_SOURCES + ../openbsd-compat/strlcpy.c + ../openbsd-compat/strlcat.c +) + +list(APPEND COMMON_SOURCES + libfuzzer.c + mutator_aux.c +) + +# XXX: OSS-Fuzz require linking using CXX +set(FUZZ_LINKER_LANGUAGE "C" CACHE STRING "Linker language for fuzz harnesses") +mark_as_advanced(FUZZ_LINKER_LANGUAGE) +enable_language(${FUZZ_LINKER_LANGUAGE}) + +# fuzz_cred +add_executable(fuzz_cred fuzz_cred.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +set_target_properties(fuzz_cred PROPERTIES + LINK_FLAGS ${FUZZ_LDFLAGS} + LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE}) +target_link_libraries(fuzz_cred fido2_shared) + +# fuzz_assert +add_executable(fuzz_assert fuzz_assert.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +set_target_properties(fuzz_assert PROPERTIES + LINK_FLAGS ${FUZZ_LDFLAGS} + LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE}) +target_link_libraries(fuzz_assert fido2_shared) + +# fuzz_mgmt +add_executable(fuzz_mgmt fuzz_mgmt.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +set_target_properties(fuzz_mgmt PROPERTIES + LINK_FLAGS ${FUZZ_LDFLAGS} + LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE}) +target_link_libraries(fuzz_mgmt fido2_shared) + +# fuzz_credman +add_executable(fuzz_credman fuzz_credman.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +set_target_properties(fuzz_credman PROPERTIES + LINK_FLAGS ${FUZZ_LDFLAGS} + LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE}) +target_link_libraries(fuzz_credman fido2_shared) + +# fuzz_bio +add_executable(fuzz_bio fuzz_bio.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +set_target_properties(fuzz_bio PROPERTIES + LINK_FLAGS ${FUZZ_LDFLAGS} + LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE}) +target_link_libraries(fuzz_bio fido2_shared) + +# fuzz_hid +add_executable(fuzz_hid fuzz_hid.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +set_target_properties(fuzz_hid PROPERTIES + LINK_FLAGS ${FUZZ_LDFLAGS} + LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE}) +target_link_libraries(fuzz_hid fido2_shared) + +# fuzz_netlink +add_executable(fuzz_netlink fuzz_netlink.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +set_target_properties(fuzz_netlink PROPERTIES + LINK_FLAGS ${FUZZ_LDFLAGS} + LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE}) +target_link_libraries(fuzz_netlink fido2_shared) + +# fuzz_largeblob +add_executable(fuzz_largeblob fuzz_largeblob.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +set_target_properties(fuzz_largeblob PROPERTIES + LINK_FLAGS ${FUZZ_LDFLAGS} + LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE}) +target_link_libraries(fuzz_largeblob fido2_shared) + +# fuzz_pcsc +add_executable(fuzz_pcsc fuzz_pcsc.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +set_target_properties(fuzz_pcsc PROPERTIES + LINK_FLAGS ${FUZZ_LDFLAGS} + LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE}) +target_link_libraries(fuzz_pcsc fido2_shared) + +# fuzz_attobj +add_executable(fuzz_attobj fuzz_attobj.c ${COMMON_SOURCES} ${COMPAT_SOURCES}) +set_target_properties(fuzz_attobj PROPERTIES + LINK_FLAGS ${FUZZ_LDFLAGS} + LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE}) +target_link_libraries(fuzz_attobj fido2_shared) diff --git a/fuzz/Dockerfile b/fuzz/Dockerfile new file mode 100644 index 0000000..68d40fa --- /dev/null +++ b/fuzz/Dockerfile @@ -0,0 +1,16 @@ +# Copyright (c) 2019-2023 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. +# SPDX-License-Identifier: BSD-2-Clause + +FROM alpine:latest +ENV CC=clang +ENV CXX=clang++ +RUN apk -q update +RUN apk add build-base clang clang-analyzer cmake compiler-rt coreutils +RUN apk add eudev-dev git linux-headers llvm openssl-dev pcsc-lite-dev +RUN apk add sudo tar zlib-dev +RUN git clone --branch v0.11.0 --depth=1 https://github.com/PJK/libcbor +RUN git clone --depth=1 https://github.com/yubico/libfido2 +WORKDIR /libfido2 +RUN ./fuzz/build-coverage /libcbor /libfido2 diff --git a/fuzz/Makefile b/fuzz/Makefile new file mode 100644 index 0000000..ab84b99 --- /dev/null +++ b/fuzz/Makefile @@ -0,0 +1,90 @@ +# Copyright (c) 2019-2023 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. +# SPDX-License-Identifier: BSD-2-Clause + +IMAGE := libfido2-coverage:1.15.0 +RUNNER := libfido2-runner +PROFDATA := llvm-profdata +COV := llvm-cov +TARGETS := fuzz_assert fuzz_bio fuzz_cred fuzz_credman fuzz_hid \ + fuzz_largeblob fuzz_netlink fuzz_mgmt fuzz_pcsc +CORPORA := $(foreach f,${TARGETS},${f}/corpus) +MINIFY := $(foreach f,${TARGETS},/minify/${f}/corpus) +REMOTE := gs://libfido2-corpus.clusterfuzz-external.appspot.com +.DEFAULT_GOAL := all + +all: ${TARGETS} + +build: + docker build -t ${IMAGE} - < Dockerfile + +run: build + -docker run -it -d --name ${RUNNER} ${IMAGE} + docker start ${RUNNER} + +sync: run + tar Ccf .. - src fuzz | docker exec -i ${RUNNER} tar Cxf /libfido2 - + docker exec ${RUNNER} make -C /libfido2/build + +corpus: sync + docker exec ${RUNNER} /bin/sh -c 'cd /libfido2/fuzz && rm -rf ${TARGETS}' + docker exec ${RUNNER} tar Czxf /libfido2/fuzz /libfido2/fuzz/corpus.tgz + +${TARGETS}: corpus sync + docker exec -e LLVM_PROFILE_FILE=/profraw/$@ ${RUNNER} \ + /bin/sh -c 'rm -f /profraw/$@ && /libfido2/build/fuzz/$@ \ + -runs=1 /libfido2/fuzz/$@' + +${MINIFY}: /minify/%/corpus: % + docker exec ${RUNNER} /bin/sh -c 'rm -rf $@ && mkdir -p $@ && \ + /libfido2/build/fuzz/$< -use_value_profile=1 -merge=1 $@ \ + /libfido2/fuzz/$ $@ + +profdata: run + docker exec ${RUNNER} /bin/sh -c 'rm -f /$@ && ${PROFDATA} \ + merge -sparse /profraw/* -o /$@' + +report.tgz: profdata + docker exec ${RUNNER} /bin/sh -c 'rm -rf /report && mkdir /report && \ + ${COV} show -format=html -tab-size=8 -instr-profile=/$< \ + -ignore-filename-regex=pcsclite.h --show-branch-summary=false \ + -output-dir=/report /libfido2/build/src/libfido2.so' + docker exec -i ${RUNNER} tar Czcf / - report > $@ + +summary.txt: profdata + docker exec ${RUNNER} ${COV} report -use-color=false \ + -ignore-filename-regex=pcsclite.h --show-branch-summary=false \ + /libfido2/build/src/libfido2.so -instr-profile=/$< > $@ + +functions.txt: profdata + docker exec ${RUNNER} /bin/sh -c '${COV} report -use-color=false \ + -ignore-filename-regex=pcsclite.h -show-functions \ + --show-branch-summary=false -instr-profile=/$< \ + /libfido2/build/src/libfido2.so /libfido2/src/*.[ch]' > $@ + +clean: run + docker exec ${RUNNER} /bin/sh -c 'rm -rf /profraw /profdata && \ + make -C /libfido2/build clean' + -docker stop ${RUNNER} + rm -rf ${TARGETS} + +${CORPORA}: + -mkdir -p $@ + gsutil -q -m rsync -d -r ${REMOTE}/libFuzzer/libfido2_$(@:/corpus=) $@ + +fetch-oss-fuzz: ${CORPORA} + find ${TARGETS} -type f -size +8192c -print0 | xargs -0 rm + +fetch-franz: + ssh franz tar -C corpus -cf- . | tar -xf- + +corpus.tgz: + tar zcf $@ ${TARGETS} + +.PHONY: build run sync corpus ${TARGETS} ${CORPORA} +.PHONY: report.tgz summary.txt functions.txt +.PHONY: fetch-oss-fuzz fetch-franz corpus.tgz diff --git a/fuzz/README b/fuzz/README new file mode 100644 index 0000000..427625c --- /dev/null +++ b/fuzz/README @@ -0,0 +1,43 @@ +libfido2 can be fuzzed using AFL or libFuzzer, with or without +ASAN/MSAN/UBSAN. + +AFL is more convenient when fuzzing the path from the authenticator to +libfido2 in an existing application. To do so, use preload-snoop.c with a real +authenticator to obtain an initial corpus, rebuild libfido2 with -DFUZZ=ON, and +use preload-fuzz.c to read device data from stdin. + +libFuzzer is better suited for bespoke fuzzers; see fuzz_cred.c, fuzz_credman.c, +fuzz_assert.c, fuzz_hid.c, and fuzz_mgmt.c for examples. To build these +harnesses, use -DCMAKE_C_FLAGS=-fsanitize=fuzzer-no-link +-DFUZZ_LDFLAGS=-fsanitize=fuzzer -DFUZZ=ON. + +If -DFUZZ=ON is enabled, symbols listed in wrapped.sym are wrapped in the +resulting shared object. The wrapper functions simulate failure according to a +deterministic RNG and probabilities defined in wrap.c. Harnesses wishing to +use this functionality should call prng_init() with a seed obtained from the +corpus. To mutate only the seed part of a libFuzzer harness's corpora, +use '-reduce_inputs=0 --fido-mutate=seed'. + +To run under ASAN/MSAN/UBSAN, libfido2 needs to be linked against flavours of +libcbor and OpenSSL built with the respective sanitiser. In order to keep +memory utilisation at a manageable level, you can either enforce limits at +the OS level (e.g. cgroups on Linux), or patch libcbor with the diff below. +N.B., the patch below is relative to libcbor 0.10.1. + +diff --git src/cbor/internal/memory_utils.c src/cbor/internal/memory_utils.c +index bbea63c..3f7c9af 100644 +--- src/cbor/internal/memory_utils.c ++++ src/cbor/internal/memory_utils.c +@@ -41,7 +41,11 @@ size_t _cbor_safe_signaling_add(size_t a, size_t b) { + + void* _cbor_alloc_multiple(size_t item_size, size_t item_count) { + if (_cbor_safe_to_multiply(item_size, item_count)) { +- return _cbor_malloc(item_size * item_count); ++ if (item_count > 1000) { ++ return NULL; ++ } else { ++ return _cbor_malloc(item_size * item_count); ++ } + } else { + return NULL; + } diff --git a/fuzz/build-coverage b/fuzz/build-coverage new file mode 100644 index 0000000..6cc5041 --- /dev/null +++ b/fuzz/build-coverage @@ -0,0 +1,34 @@ +#!/bin/sh -eux + +# Copyright (c) 2019 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. +# SPDX-License-Identifier: BSD-2-Clause + +LIBCBOR="$1" +LIBFIDO2="$2" + +CC="${CC:-clang}" +CXX="${CXX:-clang++}" +PKG_CONFIG_PATH="${PKG_CONFIG_PATH:-${LIBCBOR}/install/lib/pkgconfig}" +export CC PKG_CONFIG_PATH + +# Clean up. +rm -rf "${LIBCBOR}/build" "${LIBCBOR}/install" "${LIBFIDO2}/build" + +# Patch, build, and install libcbor. +(cd "${LIBCBOR}" && patch -N -l -s -p0 < "${LIBFIDO2}/fuzz/README") || true +mkdir "${LIBCBOR}/build" "${LIBCBOR}/install" +(cd "${LIBCBOR}/build" && cmake -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_INSTALL_PREFIX="${LIBCBOR}/install" ..) +make -C "${LIBCBOR}/build" VERBOSE=1 all install + +# Build libfido2. +mkdir -p "${LIBFIDO2}/build" +export CFLAGS="-fprofile-instr-generate -fcoverage-mapping" +export CFLAGS="${CFLAGS} -fsanitize=fuzzer-no-link" +export LDFLAGS="${CFLAGS}" +export FUZZ_LDFLAGS="${LDFLAGS} -fsanitize=fuzzer" +(cd "${LIBFIDO2}/build" && cmake -DFUZZ=ON -DFUZZ_LDFLAGS="${FUZZ_LDFLAGS}" \ + -DCMAKE_BUILD_TYPE=Debug ..) +make -C "${LIBFIDO2}/build" diff --git a/fuzz/clock.c b/fuzz/clock.c new file mode 100644 index 0000000..bd758ea --- /dev/null +++ b/fuzz/clock.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +#include "mutator_aux.h" + +/* + * A pseudo-random monotonic clock with a probabilistic discontinuity to + * the end of time (as measured by struct timespec). + */ + +extern int prng_up; +extern int __wrap_clock_gettime(clockid_t, struct timespec *); +extern int __real_clock_gettime(clockid_t, struct timespec *); +extern int __wrap_usleep(unsigned int); +static TLS struct timespec fuzz_clock; + +static void +tick(unsigned int usec) +{ + long long drift; + + /* + * Simulate a jump to the end of time with 0.125% probability. + * This condition should be gracefully handled by callers of + * clock_gettime(). + */ + if (uniform_random(800) < 1) { + fuzz_clock.tv_sec = LLONG_MAX; + fuzz_clock.tv_nsec = LONG_MAX; + return; + } + + drift = usec * 1000LL + (long long)uniform_random(10000000); /* 10ms */ + if (LLONG_MAX - drift < (long long)fuzz_clock.tv_nsec) { + fuzz_clock_reset(); /* Not much we can do here. */ + } else if (drift + (long long)fuzz_clock.tv_nsec < 1000000000) { + fuzz_clock.tv_nsec += (long)(drift); + } else { + fuzz_clock.tv_sec += (long)(drift / 1000000000); + fuzz_clock.tv_nsec += (long)(drift % 1000000000); + } +} + +int +__wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + if (!prng_up || clk_id != CLOCK_MONOTONIC) + return __real_clock_gettime(clk_id, tp); + if (uniform_random(400) < 1) + return -1; + + tick(0); + *tp = fuzz_clock; + + return 0; +} + +int +__wrap_usleep(unsigned int usec) +{ + if (uniform_random(400) < 1) + return -1; + + tick(usec); + + return 0; +} + +void +fuzz_clock_reset(void) +{ + memset(&fuzz_clock, 0, sizeof(fuzz_clock)); +} diff --git a/fuzz/dummy.h b/fuzz/dummy.h new file mode 100644 index 0000000..fc4bfc5 --- /dev/null +++ b/fuzz/dummy.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2020-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _DUMMY_H +#define _DUMMY_H + +#include + +const char dummy_name[] = "finger1"; +const char dummy_pin1[] = "skepp cg0u3;Y.."; +const char dummy_pin2[] = "bastilha 6rJrfQZI."; +const char dummy_pin[] = "9}4gT:8d=A37Dh}U"; +const char dummy_rp_id[] = "localhost"; +const char dummy_rp_name[] = "sweet home localhost"; +const char dummy_user_icon[] = "an icon"; +const char dummy_user_name[] = "john smith"; +const char dummy_user_nick[] = "jsmith"; +const char dummy_pcsc_list[] = "reader1\0reader2\0reader3\0\0"; +const char dummy_pcsc_path[] = "pcsc://slot7"; +const uint8_t dummy_id[] = { 0x5e, 0xd2 }; + +const uint8_t dummy_user_id[] = { + 0x78, 0x1c, 0x78, 0x60, 0xad, 0x88, 0xd2, 0x63, + 0x32, 0x62, 0x2a, 0xf1, 0x74, 0x5d, 0xed, 0xb2, + 0xe7, 0xa4, 0x2b, 0x44, 0x89, 0x29, 0x39, 0xc5, + 0x56, 0x64, 0x01, 0x27, 0x0d, 0xbb, 0xc4, 0x49, +}; + +const uint8_t dummy_cred_id[] = { + 0x4f, 0x72, 0x98, 0x42, 0x4a, 0xe1, 0x17, 0xa5, + 0x85, 0xa0, 0xef, 0x3b, 0x11, 0x24, 0x4a, 0x3d, +}; + +const uint8_t dummy_cdh[] = { + 0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7, + 0x82, 0x34, 0xaa, 0xca, 0x07, 0xa1, 0xf6, 0x56, + 0x42, 0x1c, 0xb6, 0xf6, 0xb3, 0x00, 0x86, 0x52, + 0x35, 0x2d, 0xa2, 0x62, 0x4a, 0xbe, 0x89, 0x76, +}; + +const uint8_t dummy_es256[] = { + 0xcc, 0x1b, 0x50, 0xac, 0xc4, 0x19, 0xf8, 0x3a, + 0xee, 0x0a, 0x77, 0xd6, 0xf3, 0x53, 0xdb, 0xef, + 0xf2, 0xb9, 0x5c, 0x2d, 0x8b, 0x1e, 0x52, 0x58, + 0x88, 0xf4, 0x0b, 0x85, 0x1f, 0x40, 0x6d, 0x18, + 0x15, 0xb3, 0xcc, 0x25, 0x7c, 0x38, 0x3d, 0xec, + 0xdf, 0xad, 0xbd, 0x46, 0x91, 0xc3, 0xac, 0x30, + 0x94, 0x2a, 0xf7, 0x78, 0x35, 0x70, 0x59, 0x6f, + 0x28, 0xcb, 0x8e, 0x07, 0x85, 0xb5, 0x91, 0x96, +}; + +const uint8_t dummy_rs256[] = { + 0xd2, 0xa8, 0xc0, 0x11, 0x82, 0x9e, 0x57, 0x2e, + 0x60, 0xae, 0x8c, 0xb0, 0x09, 0xe1, 0x58, 0x2b, + 0x99, 0xec, 0xc3, 0x11, 0x1b, 0xef, 0x81, 0x49, + 0x34, 0x53, 0x6a, 0x01, 0x65, 0x2c, 0x24, 0x09, + 0x30, 0x87, 0x98, 0x51, 0x6e, 0x30, 0x4f, 0x60, + 0xbd, 0x54, 0xd2, 0x54, 0xbd, 0x94, 0x42, 0xdd, + 0x63, 0xe5, 0x2c, 0xc6, 0x04, 0x32, 0xc0, 0x8f, + 0x72, 0xd5, 0xb4, 0xf0, 0x4f, 0x42, 0xe5, 0xb0, + 0xa2, 0x95, 0x11, 0xfe, 0xd8, 0xb0, 0x65, 0x34, + 0xff, 0xfb, 0x44, 0x97, 0x52, 0xfc, 0x67, 0x23, + 0x0b, 0xad, 0xf3, 0x3a, 0x82, 0xd4, 0x96, 0x10, + 0x87, 0x6b, 0xfa, 0xd6, 0x51, 0x60, 0x3e, 0x1c, + 0xae, 0x19, 0xb8, 0xce, 0x08, 0xae, 0x9a, 0xee, + 0x78, 0x16, 0x22, 0xcc, 0x92, 0xcb, 0xa8, 0x95, + 0x34, 0xe5, 0xb9, 0x42, 0x6a, 0xf0, 0x2e, 0x82, + 0x1f, 0x4c, 0x7d, 0x84, 0x94, 0x68, 0x7b, 0x97, + 0x2b, 0xf7, 0x7d, 0x67, 0x83, 0xbb, 0xc7, 0x8a, + 0x31, 0x5a, 0xf3, 0x2a, 0x95, 0xdf, 0x63, 0xe7, + 0x4e, 0xee, 0x26, 0xda, 0x87, 0x00, 0xe2, 0x23, + 0x4a, 0x33, 0x9a, 0xa0, 0x1b, 0xce, 0x60, 0x1f, + 0x98, 0xa1, 0xb0, 0xdb, 0xbf, 0x20, 0x59, 0x27, + 0xf2, 0x06, 0xd9, 0xbe, 0x37, 0xa4, 0x03, 0x6b, + 0x6a, 0x4e, 0xaf, 0x22, 0x68, 0xf3, 0xff, 0x28, + 0x59, 0x05, 0xc9, 0xf1, 0x28, 0xf4, 0xbb, 0x35, + 0xe0, 0xc2, 0x68, 0xc2, 0xaa, 0x54, 0xac, 0x8c, + 0xc1, 0x69, 0x9e, 0x4b, 0x32, 0xfc, 0x53, 0x58, + 0x85, 0x7d, 0x3f, 0x51, 0xd1, 0xc9, 0x03, 0x02, + 0x13, 0x61, 0x62, 0xda, 0xf8, 0xfe, 0x3e, 0xc8, + 0x95, 0x12, 0xfb, 0x0c, 0xdf, 0x06, 0x65, 0x6f, + 0x23, 0xc7, 0x83, 0x7c, 0x50, 0x2d, 0x27, 0x25, + 0x4d, 0xbf, 0x94, 0xf0, 0x89, 0x04, 0xb9, 0x2d, + 0xc4, 0xa5, 0x32, 0xa9, 0x25, 0x0a, 0x99, 0x59, + 0x01, 0x00, 0x01, +}; + +const uint8_t dummy_eddsa[] = { + 0xfe, 0x8b, 0x61, 0x50, 0x31, 0x7a, 0xe6, 0xdf, + 0xb1, 0x04, 0x9d, 0x4d, 0xb5, 0x7a, 0x5e, 0x96, + 0x4c, 0xb2, 0xf9, 0x5f, 0x72, 0x47, 0xb5, 0x18, + 0xe2, 0x39, 0xdf, 0x2f, 0x87, 0x19, 0xb3, 0x02, +}; + +const uint8_t dummy_netlink_wiredata[] = { + 0xd8, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00, + 0x01, 0x02, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x6e, 0x66, 0x63, 0x00, 0x06, 0x00, 0x01, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0x00, + 0x14, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x05, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x06, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x09, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0c, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0e, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x10, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x11, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x13, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x07, 0x00, + 0x18, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x9d, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9d, 0x2e, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x05, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x07, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x93, 0xb9, 0x25, 0x00 +}; + +#endif /* !_DUMMY_H */ diff --git a/fuzz/export.gnu b/fuzz/export.gnu new file mode 100644 index 0000000..c23831c --- /dev/null +++ b/fuzz/export.gnu @@ -0,0 +1,289 @@ +{ + global: + eddsa_pk_free; + eddsa_pk_from_EVP_PKEY; + eddsa_pk_from_ptr; + eddsa_pk_new; + eddsa_pk_to_EVP_PKEY; + es256_pk_free; + es256_pk_from_EC_KEY; + es256_pk_from_EVP_PKEY; + es256_pk_from_ptr; + es256_pk_new; + es256_pk_to_EVP_PKEY; + es384_pk_free; + es384_pk_from_EC_KEY; + es384_pk_from_EVP_PKEY; + es384_pk_from_ptr; + es384_pk_new; + es384_pk_to_EVP_PKEY; + fido_assert_allow_cred; + fido_assert_authdata_len; + fido_assert_authdata_ptr; + fido_assert_authdata_raw_len; + fido_assert_authdata_raw_ptr; + fido_assert_blob_len; + fido_assert_blob_ptr; + fido_assert_clientdata_hash_len; + fido_assert_clientdata_hash_ptr; + fido_assert_count; + fido_assert_flags; + fido_assert_free; + fido_assert_hmac_secret_len; + fido_assert_hmac_secret_ptr; + fido_assert_id_len; + fido_assert_id_ptr; + fido_assert_largeblob_key_len; + fido_assert_largeblob_key_ptr; + fido_assert_new; + fido_assert_rp_id; + fido_assert_set_authdata; + fido_assert_set_authdata_raw; + fido_assert_set_clientdata; + fido_assert_set_clientdata_hash; + fido_assert_set_count; + fido_assert_set_extensions; + fido_assert_set_hmac_salt; + fido_assert_set_hmac_secret; + fido_assert_set_options; + fido_assert_set_rp; + fido_assert_set_sig; + fido_assert_set_up; + fido_assert_set_uv; + fido_assert_sigcount; + fido_assert_sig_len; + fido_assert_sig_ptr; + fido_assert_user_display_name; + fido_assert_user_icon; + fido_assert_user_id_len; + fido_assert_user_id_ptr; + fido_assert_user_name; + fido_assert_verify; + fido_bio_dev_enroll_begin; + fido_bio_dev_enroll_cancel; + fido_bio_dev_enroll_continue; + fido_bio_dev_enroll_remove; + fido_bio_dev_get_info; + fido_bio_dev_get_template_array; + fido_bio_dev_set_template_name; + fido_bio_enroll_free; + fido_bio_enroll_last_status; + fido_bio_enroll_new; + fido_bio_enroll_remaining_samples; + fido_bio_info_free; + fido_bio_info_max_samples; + fido_bio_info_new; + fido_bio_info_type; + fido_bio_template; + fido_bio_template_array_count; + fido_bio_template_array_free; + fido_bio_template_array_new; + fido_bio_template_free; + fido_bio_template_id_len; + fido_bio_template_id_ptr; + fido_bio_template_name; + fido_bio_template_new; + fido_bio_template_set_id; + fido_bio_template_set_name; + fido_cbor_info_aaguid_len; + fido_cbor_info_aaguid_ptr; + fido_cbor_info_algorithm_cose; + fido_cbor_info_algorithm_count; + fido_cbor_info_algorithm_type; + fido_cbor_info_certs_len; + fido_cbor_info_certs_name_ptr; + fido_cbor_info_certs_value_ptr; + fido_cbor_info_extensions_len; + fido_cbor_info_extensions_ptr; + fido_cbor_info_free; + fido_cbor_info_fwversion; + fido_cbor_info_maxcredbloblen; + fido_cbor_info_maxcredcntlst; + fido_cbor_info_maxcredidlen; + fido_cbor_info_maxlargeblob; + fido_cbor_info_maxmsgsiz; + fido_cbor_info_maxrpid_minpinlen; + fido_cbor_info_minpinlen; + fido_cbor_info_new; + fido_cbor_info_new_pin_required; + fido_cbor_info_options_len; + fido_cbor_info_options_name_ptr; + fido_cbor_info_options_value_ptr; + fido_cbor_info_protocols_len; + fido_cbor_info_protocols_ptr; + fido_cbor_info_rk_remaining; + fido_cbor_info_transports_len; + fido_cbor_info_transports_ptr; + fido_cbor_info_uv_attempts; + fido_cbor_info_uv_modality; + fido_cbor_info_versions_len; + fido_cbor_info_versions_ptr; + fido_cred_attstmt_len; + fido_cred_attstmt_ptr; + fido_cred_authdata_len; + fido_cred_authdata_ptr; + fido_cred_authdata_raw_len; + fido_cred_authdata_raw_ptr; + fido_cred_clientdata_hash_len; + fido_cred_clientdata_hash_ptr; + fido_cred_display_name; + fido_cred_exclude; + fido_cred_flags; + fido_cred_largeblob_key_len; + fido_cred_largeblob_key_ptr; + fido_cred_sigcount; + fido_cred_fmt; + fido_cred_free; + fido_cred_id_len; + fido_cred_id_ptr; + fido_cred_aaguid_len; + fido_cred_aaguid_ptr; + fido_credman_del_dev_rk; + fido_credman_get_dev_metadata; + fido_credman_get_dev_rk; + fido_credman_get_dev_rp; + fido_credman_metadata_free; + fido_credman_metadata_new; + fido_credman_rk; + fido_credman_rk_count; + fido_credman_rk_existing; + fido_credman_rk_free; + fido_credman_rk_new; + fido_credman_rk_remaining; + fido_credman_rp_count; + fido_credman_rp_free; + fido_credman_rp_id; + fido_credman_rp_id_hash_len; + fido_credman_rp_id_hash_ptr; + fido_credman_rp_name; + fido_credman_rp_new; + fido_credman_set_dev_rk; + fido_cred_new; + fido_cred_pin_minlen; + fido_cred_prot; + fido_cred_pubkey_len; + fido_cred_pubkey_ptr; + fido_cred_rp_id; + fido_cred_rp_name; + fido_cred_set_attstmt; + fido_cred_set_attobj; + fido_cred_set_authdata; + fido_cred_set_authdata_raw; + fido_cred_set_blob; + fido_cred_set_clientdata; + fido_cred_set_clientdata_hash; + fido_cred_set_extensions; + fido_cred_set_fmt; + fido_cred_set_id; + fido_cred_set_options; + fido_cred_set_pin_minlen; + fido_cred_set_prot; + fido_cred_set_rk; + fido_cred_set_rp; + fido_cred_set_sig; + fido_cred_set_type; + fido_cred_set_user; + fido_cred_set_uv; + fido_cred_set_x509; + fido_cred_sig_len; + fido_cred_sig_ptr; + fido_cred_type; + fido_cred_user_id_len; + fido_cred_user_id_ptr; + fido_cred_user_name; + fido_cred_verify; + fido_cred_verify_self; + fido_cred_x5c_len; + fido_cred_x5c_list_count; + fido_cred_x5c_list_len; + fido_cred_x5c_list_ptr; + fido_cred_x5c_ptr; + fido_dev_build; + fido_dev_cancel; + fido_dev_close; + fido_dev_enable_entattest; + fido_dev_flags; + fido_dev_force_fido2; + fido_dev_force_pin_change; + fido_dev_force_u2f; + fido_dev_free; + fido_dev_get_assert; + fido_dev_get_cbor_info; + fido_dev_get_retry_count; + fido_dev_get_uv_retry_count; + fido_dev_get_touch_begin; + fido_dev_get_touch_status; + fido_dev_has_pin; + fido_dev_has_uv; + fido_dev_info_free; + fido_dev_info_manifest; + fido_dev_info_manufacturer_string; + fido_dev_info_new; + fido_dev_info_path; + fido_dev_info_product; + fido_dev_info_product_string; + fido_dev_info_ptr; + fido_dev_info_set; + fido_dev_info_vendor; + fido_dev_is_fido2; + fido_dev_major; + fido_dev_make_cred; + fido_dev_minor; + fido_dev_new; + fido_dev_open; + fido_dev_protocol; + fido_dev_reset; + fido_dev_set_io_functions; + fido_dev_set_pcsc; + fido_dev_set_pin; + fido_dev_set_pin_minlen; + fido_dev_set_pin_minlen_rpid; + fido_dev_set_timeout; + fido_dev_set_transport_functions; + fido_dev_supports_cred_prot; + fido_dev_supports_credman; + fido_dev_supports_permissions; + fido_dev_supports_pin; + fido_dev_supports_uv; + fido_dev_toggle_always_uv; + fido_dev_largeblob_get; + fido_dev_largeblob_get_array; + fido_dev_largeblob_remove; + fido_dev_largeblob_set; + fido_dev_largeblob_set_array; + fido_hid_get_report_len; + fido_hid_get_usage; + fido_init; + fido_nfc_rx; + fido_nfc_tx; + fido_nl_free; + fido_nl_get_nfc_target; + fido_nl_new; + fido_nl_power_nfc; + fido_pcsc_close; + fido_pcsc_manifest; + fido_pcsc_open; + fido_pcsc_read; + fido_pcsc_rx; + fido_pcsc_tx; + fido_pcsc_write; + fido_set_log_handler; + fido_strerr; + rs256_pk_free; + rs256_pk_from_ptr; + rs256_pk_from_EVP_PKEY; + rs256_pk_from_RSA; + rs256_pk_new; + rs256_pk_to_EVP_PKEY; + prng_init; + prng_up; + fuzz_clock_reset; + fuzz_save_corpus; + set_netlink_io_functions; + set_pcsc_parameters; + set_pcsc_io_functions; + set_udev_parameters; + uniform_random; + local: + *; +}; diff --git a/fuzz/functions.txt b/fuzz/functions.txt new file mode 100644 index 0000000..a96618c --- /dev/null +++ b/fuzz/functions.txt @@ -0,0 +1,956 @@ +File '/libfido2/src/aes256.c': +Name Regions Miss Cover Lines Miss Cover +-------------------------------------------------------------------------------------------------------- +aes256_cbc_enc 4 0 100.00% 4 0 100.00% +aes256_cbc_dec 4 0 100.00% 4 0 100.00% +aes256_gcm_enc 1 0 100.00% 3 0 100.00% +aes256_gcm_dec 1 0 100.00% 3 0 100.00% +aes256.c:aes256_cbc_fips 26 1 96.15% 42 4 90.48% +aes256.c:aes256_cbc 29 1 96.55% 36 3 91.67% +aes256.c:aes256_cbc_proto1 1 0 100.00% 5 0 100.00% +aes256.c:aes256_gcm 52 1 98.08% 60 4 93.33% +-------------------------------------------------------------------------------------------------------- +TOTAL 118 3 97.46% 157 11 92.99% + +File '/libfido2/src/assert.c': +Name Regions Miss Cover Lines Miss Cover +----------------------------------------------------------------------------------------------------------------- +fido_dev_get_assert 40 0 100.00% 35 0 100.00% +fido_check_flags 13 0 100.00% 15 0 100.00% +fido_get_signed_hash 20 1 95.00% 34 3 91.18% +fido_assert_verify 50 4 92.00% 70 7 90.00% +fido_assert_set_clientdata 12 12 0.00% 11 11 0.00% +fido_assert_set_clientdata_hash 8 0 100.00% 6 0 100.00% +fido_assert_set_hmac_salt 10 0 100.00% 6 0 100.00% +fido_assert_set_hmac_secret 12 12 0.00% 7 7 0.00% +fido_assert_set_rp 12 0 100.00% 11 0 100.00% +fido_assert_set_winhello_appid 2 2 0.00% 5 5 0.00% +fido_assert_allow_cred 13 2 84.62% 22 3 86.36% +fido_assert_empty_allow_list 2 0 100.00% 5 0 100.00% +fido_assert_set_extensions 14 0 100.00% 10 0 100.00% +fido_assert_set_options 8 8 0.00% 5 5 0.00% +fido_assert_set_up 2 0 100.00% 4 0 100.00% +fido_assert_set_uv 2 0 100.00% 4 0 100.00% +fido_assert_clientdata_hash_ptr 1 0 100.00% 3 0 100.00% +fido_assert_clientdata_hash_len 1 0 100.00% 3 0 100.00% +fido_assert_new 1 0 100.00% 3 0 100.00% +fido_assert_reset_tx 1 0 100.00% 13 0 100.00% +fido_assert_reset_rx 4 0 100.00% 20 0 100.00% +fido_assert_free 6 0 100.00% 9 0 100.00% +fido_assert_count 1 0 100.00% 3 0 100.00% +fido_assert_rp_id 1 0 100.00% 3 0 100.00% +fido_assert_flags 4 0 100.00% 5 0 100.00% +fido_assert_sigcount 4 0 100.00% 5 0 100.00% +fido_assert_authdata_ptr 4 0 100.00% 5 0 100.00% +fido_assert_authdata_len 4 0 100.00% 5 0 100.00% +fido_assert_authdata_raw_ptr 4 0 100.00% 5 0 100.00% +fido_assert_authdata_raw_len 4 0 100.00% 5 0 100.00% +fido_assert_sig_ptr 4 0 100.00% 5 0 100.00% +fido_assert_sig_len 4 0 100.00% 5 0 100.00% +fido_assert_id_ptr 4 0 100.00% 5 0 100.00% +fido_assert_id_len 4 0 100.00% 5 0 100.00% +fido_assert_user_id_ptr 4 0 100.00% 5 0 100.00% +fido_assert_user_id_len 4 0 100.00% 5 0 100.00% +fido_assert_user_icon 4 0 100.00% 5 0 100.00% +fido_assert_user_name 4 0 100.00% 5 0 100.00% +fido_assert_user_display_name 4 0 100.00% 5 0 100.00% +fido_assert_hmac_secret_ptr 4 0 100.00% 5 0 100.00% +fido_assert_hmac_secret_len 4 0 100.00% 5 0 100.00% +fido_assert_largeblob_key_ptr 4 0 100.00% 5 0 100.00% +fido_assert_largeblob_key_len 4 0 100.00% 5 0 100.00% +fido_assert_blob_ptr 4 0 100.00% 5 0 100.00% +fido_assert_blob_len 4 0 100.00% 5 0 100.00% +fido_assert_set_authdata 28 0 100.00% 33 0 100.00% +fido_assert_set_authdata_raw 28 0 100.00% 32 0 100.00% +fido_assert_set_sig 14 0 100.00% 7 0 100.00% +fido_assert_set_count 10 0 100.00% 17 0 100.00% +assert.c:fido_dev_get_assert_wait 21 0 100.00% 14 0 100.00% +assert.c:fido_dev_get_assert_tx 56 2 96.43% 62 5 91.94% +assert.c:fido_dev_get_assert_rx 27 0 100.00% 36 0 100.00% +assert.c:adjust_assert_count 24 0 100.00% 26 0 100.00% +assert.c:parse_assert_reply 15 0 100.00% 28 0 100.00% +assert.c:fido_get_next_assert_tx 8 0 100.00% 8 0 100.00% +assert.c:fido_get_next_assert_rx 23 2 91.30% 29 5 82.76% +assert.c:decrypt_hmac_secrets 9 0 100.00% 15 0 100.00% +assert.c:get_es256_hash 16 0 100.00% 17 0 100.00% +assert.c:get_es384_hash 16 0 100.00% 17 0 100.00% +assert.c:get_eddsa_hash 6 0 100.00% 9 0 100.00% +assert.c:check_extensions 5 0 100.00% 9 0 100.00% +assert.c:fido_assert_reset_extattr 1 0 100.00% 5 0 100.00% +assert.c:fido_assert_clean_authdata 1 0 100.00% 6 0 100.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 628 45 92.83% 782 51 93.48% + +File '/libfido2/src/authkey.c': +Name Regions Miss Cover Lines Miss Cover +----------------------------------------------------------------------------------------------------------------- +fido_dev_authkey 1 0 100.00% 3 0 100.00% +authkey.c:fido_dev_authkey_wait 10 0 100.00% 7 0 100.00% +authkey.c:fido_dev_authkey_tx 19 0 100.00% 25 0 100.00% +authkey.c:fido_dev_authkey_rx 14 0 100.00% 21 0 100.00% +authkey.c:parse_authkey 8 0 100.00% 10 0 100.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 52 0 100.00% 66 0 100.00% + +File '/libfido2/src/bio.c': +Name Regions Miss Cover Lines Miss Cover +----------------------------------------------------------------------------------------------------------------- +fido_bio_dev_get_template_array 5 2 60.00% 6 1 83.33% +fido_bio_dev_set_template_name 7 0 100.00% 6 0 100.00% +fido_bio_dev_enroll_begin 25 2 92.00% 31 1 96.77% +fido_bio_dev_enroll_continue 5 2 60.00% 6 1 83.33% +fido_bio_dev_enroll_cancel 1 1 0.00% 4 4 0.00% +fido_bio_dev_enroll_remove 1 0 100.00% 4 0 100.00% +fido_bio_dev_get_info 1 0 100.00% 4 0 100.00% +fido_bio_template_name 1 0 100.00% 3 0 100.00% +fido_bio_template_id_ptr 1 0 100.00% 3 0 100.00% +fido_bio_template_id_len 1 0 100.00% 3 0 100.00% +fido_bio_template_array_count 1 0 100.00% 3 0 100.00% +fido_bio_template_array_new 1 0 100.00% 3 0 100.00% +fido_bio_template_new 1 0 100.00% 3 0 100.00% +fido_bio_template_array_free 6 0 100.00% 8 0 100.00% +fido_bio_template_free 6 0 100.00% 8 0 100.00% +fido_bio_template_set_name 8 0 100.00% 7 0 100.00% +fido_bio_template_set_id 8 0 100.00% 6 0 100.00% +fido_bio_template 4 0 100.00% 5 0 100.00% +fido_bio_enroll_new 1 0 100.00% 3 0 100.00% +fido_bio_info_new 1 0 100.00% 3 0 100.00% +fido_bio_info_type 1 0 100.00% 3 0 100.00% +fido_bio_info_max_samples 1 0 100.00% 3 0 100.00% +fido_bio_enroll_free 6 0 100.00% 8 0 100.00% +fido_bio_info_free 6 0 100.00% 7 0 100.00% +fido_bio_enroll_remaining_samples 1 0 100.00% 3 0 100.00% +fido_bio_enroll_last_status 1 0 100.00% 3 0 100.00% +bio.c:bio_get_template_array_wait 11 0 100.00% 7 0 100.00% +bio.c:bio_tx 42 0 100.00% 55 0 100.00% +bio.c:bio_get_cmd 8 0 100.00% 5 0 100.00% +bio.c:bio_prepare_hmac 18 0 100.00% 29 0 100.00% +bio.c:bio_rx_template_array 19 0 100.00% 24 0 100.00% +bio.c:bio_parse_template_array 26 1 96.15% 27 4 85.19% +bio.c:decode_template_array 12 1 91.67% 18 3 83.33% +bio.c:decode_template 9 0 100.00% 15 0 100.00% +bio.c:bio_set_template_name_wait 19 0 100.00% 20 0 100.00% +bio.c:bio_enroll_begin_wait 17 0 100.00% 19 0 100.00% +bio.c:bio_rx_enroll_begin 23 0 100.00% 31 0 100.00% +bio.c:bio_parse_enroll_status 20 0 100.00% 28 0 100.00% +bio.c:bio_parse_template_id 8 0 100.00% 10 0 100.00% +bio.c:bio_enroll_continue_wait 19 0 100.00% 20 0 100.00% +bio.c:bio_rx_enroll_continue 19 0 100.00% 25 0 100.00% +bio.c:bio_enroll_cancel_wait 11 11 0.00% 10 10 0.00% +bio.c:bio_enroll_remove_wait 17 0 100.00% 19 0 100.00% +bio.c:bio_get_info_wait 11 0 100.00% 10 0 100.00% +bio.c:bio_rx_info 19 0 100.00% 24 0 100.00% +bio.c:bio_reset_info 1 0 100.00% 4 0 100.00% +bio.c:bio_parse_info 20 0 100.00% 28 0 100.00% +bio.c:bio_reset_template_array 4 0 100.00% 7 0 100.00% +bio.c:bio_reset_template 1 0 100.00% 5 0 100.00% +bio.c:bio_reset_enroll 3 0 100.00% 6 0 100.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 458 20 95.63% 592 24 95.95% + +File '/libfido2/src/blob.c': +Name Regions Miss Cover Lines Miss Cover +----------------------------------------------------------------------------------------------------------------- +fido_blob_new 1 0 100.00% 3 0 100.00% +fido_blob_reset 1 0 100.00% 4 0 100.00% +fido_blob_set 9 0 100.00% 15 0 100.00% +fido_blob_append 12 1 91.67% 20 3 85.00% +fido_blob_free 6 0 100.00% 8 0 100.00% +fido_free_blob_array 7 0 100.00% 12 0 100.00% +fido_blob_encode 6 0 100.00% 5 0 100.00% +fido_blob_decode 1 0 100.00% 3 0 100.00% +fido_blob_is_empty 3 0 100.00% 3 0 100.00% +fido_blob_serialise 7 1 85.71% 10 1 90.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 53 2 96.23% 83 4 95.18% + +File '/libfido2/src/buf.c': +Name Regions Miss Cover Lines Miss Cover +----------------------------------------------------------------------------------------------------------------- +fido_buf_read 4 0 100.00% 8 0 100.00% +fido_buf_write 4 0 100.00% 8 0 100.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 8 0 100.00% 16 0 100.00% + +File '/libfido2/src/cbor.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------ +cbor_map_iter 20 1 95.00% 26 4 84.62% +cbor_array_iter 12 0 100.00% 16 0 100.00% +cbor_parse_reply 27 0 100.00% 36 0 100.00% +cbor_vector_free 6 0 100.00% 5 0 100.00% +cbor_bytestring_copy 14 0 100.00% 18 0 100.00% +cbor_string_copy 14 0 100.00% 18 0 100.00% +cbor_add_bytestring 14 0 100.00% 21 0 100.00% +cbor_add_string 14 0 100.00% 21 0 100.00% +cbor_add_bool 14 0 100.00% 21 0 100.00% +cbor_flatten_vector 14 1 92.86% 16 1 93.75% +cbor_build_frame 15 0 100.00% 25 0 100.00% +cbor_encode_rp_entity 13 0 100.00% 11 0 100.00% +cbor_encode_user_entity 21 0 100.00% 15 0 100.00% +cbor_encode_pubkey_param 36 0 100.00% 39 0 100.00% +cbor_encode_pubkey 10 0 100.00% 11 0 100.00% +cbor_encode_pubkey_list 18 0 100.00% 19 0 100.00% +cbor_encode_str_array 18 0 100.00% 19 0 100.00% +cbor_encode_cred_ext 55 0 100.00% 50 0 100.00% +cbor_encode_cred_opt 13 0 100.00% 11 0 100.00% +cbor_encode_assert_opt 13 0 100.00% 11 0 100.00% +cbor_encode_pin_auth 21 1 95.24% 22 3 86.36% +cbor_encode_pin_opt 4 0 100.00% 8 0 100.00% +cbor_encode_change_pin_auth 32 1 96.88% 36 3 91.67% +cbor_encode_assert_ext 33 0 100.00% 32 0 100.00% +cbor_decode_fmt 13 0 100.00% 15 0 100.00% +cbor_decode_pubkey 26 1 96.15% 36 2 94.44% +cbor_decode_cred_authdata 31 1 96.77% 35 3 91.43% +cbor_decode_assert_authdata 21 1 95.24% 32 3 90.62% +cbor_decode_attstmt 13 0 100.00% 16 0 100.00% +cbor_decode_uint64 4 0 100.00% 8 0 100.00% +cbor_decode_cred_id 8 0 100.00% 9 0 100.00% +cbor_decode_user 8 0 100.00% 9 0 100.00% +cbor_decode_rp_entity 8 0 100.00% 9 0 100.00% +cbor_decode_bool 10 0 100.00% 11 0 100.00% +cbor_build_uint 10 1 90.00% 9 1 88.89% +cbor_array_append 17 0 100.00% 21 0 100.00% +cbor_array_drop 18 0 100.00% 17 0 100.00% +cbor.c:ctap_check_cbor 28 0 100.00% 26 0 100.00% +cbor.c:check_key_type 8 0 100.00% 7 0 100.00% +cbor.c:cbor_add_arg 13 0 100.00% 21 0 100.00% +cbor.c:cbor_add_uint8 14 0 100.00% 21 0 100.00% +cbor.c:cbor_encode_largeblob_key_ext 6 0 100.00% 6 0 100.00% +cbor.c:cbor_encode_hmac_secret_param 59 4 93.22% 66 8 87.88% +cbor.c:get_cose_alg 46 0 100.00% 45 0 100.00% +cbor.c:find_cose_alg 35 0 100.00% 33 0 100.00% +cbor.c:decode_attcred 25 0 100.00% 44 0 100.00% +cbor.c:decode_cred_extensions 14 0 100.00% 24 0 100.00% +cbor.c:decode_cred_extension 41 0 100.00% 45 0 100.00% +cbor.c:decode_assert_extensions 14 0 100.00% 23 0 100.00% +cbor.c:decode_assert_extension 19 0 100.00% 27 0 100.00% +cbor.c:decode_attstmt_entry 56 0 100.00% 51 0 100.00% +cbor.c:decode_x5c 4 0 100.00% 6 0 100.00% +cbor.c:decode_cred_id_entry 10 0 100.00% 19 0 100.00% +cbor.c:decode_user_entry 25 0 100.00% 35 0 100.00% +cbor.c:decode_rp_entity_entry 15 0 100.00% 25 0 100.00% +------------------------------------------------------------------------------------------------------------------ +TOTAL 1070 12 98.88% 1258 28 97.77% + +File '/libfido2/src/compress.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------ +fido_compress 1 0 100.00% 3 0 100.00% +fido_uncompress 6 0 100.00% 5 0 100.00% +compress.c:rfc1951_deflate 33 4 87.88% 47 6 87.23% +compress.c:rfc1950_inflate 27 2 92.59% 22 4 81.82% +compress.c:rfc1951_inflate 38 8 78.95% 45 14 68.89% +------------------------------------------------------------------------------------------------------------------ +TOTAL 105 14 86.67% 122 24 80.33% + +File '/libfido2/src/config.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_dev_enable_entattest 1 0 100.00% 4 0 100.00% +fido_dev_toggle_always_uv 1 0 100.00% 4 0 100.00% +fido_dev_set_pin_minlen 1 0 100.00% 4 0 100.00% +fido_dev_force_pin_change 1 0 100.00% 4 0 100.00% +fido_dev_set_pin_minlen_rpid 6 0 100.00% 15 0 100.00% +config.c:config_enable_entattest_wait 6 0 100.00% 7 0 100.00% +config.c:config_tx 39 0 100.00% 49 0 100.00% +config.c:config_prepare_hmac 10 0 100.00% 21 0 100.00% +config.c:config_toggle_always_uv_wait 6 0 100.00% 7 0 100.00% +config.c:config_pin_minlen 5 0 100.00% 7 0 100.00% +config.c:config_pin_minlen_tx 36 0 100.00% 32 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 112 0 100.00% 154 0 100.00% + +File '/libfido2/src/cred.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_dev_make_cred 12 0 100.00% 10 0 100.00% +fido_check_rp_id 4 0 100.00% 11 0 100.00% +fido_cred_verify 59 2 96.61% 75 4 94.67% +fido_cred_verify_self 60 4 93.33% 87 7 91.95% +fido_cred_new 1 0 100.00% 3 0 100.00% +fido_cred_reset_tx 1 0 100.00% 18 0 100.00% +fido_cred_reset_rx 1 0 100.00% 7 0 100.00% +fido_cred_free 6 0 100.00% 9 0 100.00% +fido_cred_set_authdata 23 0 100.00% 28 0 100.00% +fido_cred_set_authdata_raw 25 0 100.00% 29 0 100.00% +fido_cred_set_id 6 0 100.00% 5 0 100.00% +fido_cred_set_x509 6 0 100.00% 5 0 100.00% +fido_cred_set_sig 6 0 100.00% 5 0 100.00% +fido_cred_set_attstmt 20 0 100.00% 23 0 100.00% +fido_cred_exclude 14 2 85.71% 19 3 84.21% +fido_cred_empty_exclude_list 2 0 100.00% 5 0 100.00% +fido_cred_set_clientdata 12 12 0.00% 11 11 0.00% +fido_cred_set_clientdata_hash 8 0 100.00% 6 0 100.00% +fido_cred_set_rp 18 0 100.00% 22 0 100.00% +fido_cred_set_user 32 0 100.00% 41 0 100.00% +fido_cred_set_extensions 16 0 100.00% 10 0 100.00% +fido_cred_set_options 8 8 0.00% 5 5 0.00% +fido_cred_set_rk 2 0 100.00% 4 0 100.00% +fido_cred_set_uv 2 0 100.00% 4 0 100.00% +fido_cred_set_prot 21 0 100.00% 14 0 100.00% +fido_cred_set_pin_minlen 7 0 100.00% 8 0 100.00% +fido_cred_set_blob 13 0 100.00% 8 0 100.00% +fido_cred_set_fmt 20 4 80.00% 12 2 83.33% +fido_cred_set_type 23 2 91.30% 9 1 88.89% +fido_cred_type 1 0 100.00% 3 0 100.00% +fido_cred_flags 1 0 100.00% 3 0 100.00% +fido_cred_sigcount 1 0 100.00% 3 0 100.00% +fido_cred_clientdata_hash_ptr 1 0 100.00% 3 0 100.00% +fido_cred_clientdata_hash_len 1 0 100.00% 3 0 100.00% +fido_cred_x5c_ptr 1 0 100.00% 3 0 100.00% +fido_cred_x5c_len 1 0 100.00% 3 0 100.00% +fido_cred_sig_ptr 1 0 100.00% 3 0 100.00% +fido_cred_sig_len 1 0 100.00% 3 0 100.00% +fido_cred_authdata_ptr 1 0 100.00% 3 0 100.00% +fido_cred_authdata_len 1 0 100.00% 3 0 100.00% +fido_cred_authdata_raw_ptr 1 0 100.00% 3 0 100.00% +fido_cred_authdata_raw_len 1 0 100.00% 3 0 100.00% +fido_cred_attstmt_ptr 1 0 100.00% 3 0 100.00% +fido_cred_attstmt_len 1 0 100.00% 3 0 100.00% +fido_cred_pubkey_ptr 11 0 100.00% 21 0 100.00% +fido_cred_pubkey_len 11 0 100.00% 21 0 100.00% +fido_cred_id_ptr 1 0 100.00% 3 0 100.00% +fido_cred_id_len 1 0 100.00% 3 0 100.00% +fido_cred_aaguid_ptr 1 0 100.00% 3 0 100.00% +fido_cred_aaguid_len 1 0 100.00% 3 0 100.00% +fido_cred_prot 1 0 100.00% 3 0 100.00% +fido_cred_pin_minlen 1 0 100.00% 3 0 100.00% +fido_cred_fmt 1 0 100.00% 3 0 100.00% +fido_cred_rp_id 1 0 100.00% 3 0 100.00% +fido_cred_rp_name 1 0 100.00% 3 0 100.00% +fido_cred_user_name 1 0 100.00% 3 0 100.00% +fido_cred_display_name 1 0 100.00% 3 0 100.00% +fido_cred_user_id_ptr 1 0 100.00% 3 0 100.00% +fido_cred_user_id_len 1 0 100.00% 3 0 100.00% +fido_cred_largeblob_key_ptr 1 0 100.00% 3 0 100.00% +fido_cred_largeblob_key_len 1 0 100.00% 3 0 100.00% +cred.c:fido_dev_make_cred_wait 10 0 100.00% 7 0 100.00% +cred.c:fido_dev_make_cred_tx 64 0 100.00% 70 0 100.00% +cred.c:fido_dev_make_cred_rx 29 0 100.00% 32 0 100.00% +cred.c:parse_makecred_reply 14 0 100.00% 27 0 100.00% +cred.c:check_extensions 2 0 100.00% 6 0 100.00% +cred.c:get_signed_hash_u2f 27 0 100.00% 27 0 100.00% +cred.c:verify_attstmt 25 2 92.00% 43 6 86.05% +cred.c:fido_cred_clean_authdata 1 0 100.00% 8 0 100.00% +cred.c:fido_cred_clean_attstmt 1 0 100.00% 8 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 653 36 94.49% 853 39 95.43% + +File '/libfido2/src/credman.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_credman_get_dev_metadata 1 0 100.00% 4 0 100.00% +fido_credman_get_dev_rk 1 0 100.00% 4 0 100.00% +fido_credman_del_dev_rk 1 0 100.00% 4 0 100.00% +fido_credman_get_dev_rp 1 0 100.00% 4 0 100.00% +fido_credman_set_dev_rk 1 0 100.00% 4 0 100.00% +fido_credman_rk_new 1 0 100.00% 3 0 100.00% +fido_credman_rk_free 6 1 83.33% 8 1 87.50% +fido_credman_rk_count 1 0 100.00% 3 0 100.00% +fido_credman_rk 4 0 100.00% 5 0 100.00% +fido_credman_metadata_new 1 0 100.00% 3 0 100.00% +fido_credman_metadata_free 6 1 83.33% 7 1 85.71% +fido_credman_rk_existing 1 0 100.00% 3 0 100.00% +fido_credman_rk_remaining 1 0 100.00% 3 0 100.00% +fido_credman_rp_new 1 0 100.00% 3 0 100.00% +fido_credman_rp_free 6 1 83.33% 8 1 87.50% +fido_credman_rp_count 1 0 100.00% 3 0 100.00% +fido_credman_rp_id 4 0 100.00% 5 0 100.00% +fido_credman_rp_name 4 0 100.00% 5 0 100.00% +fido_credman_rp_id_hash_len 4 0 100.00% 5 0 100.00% +fido_credman_rp_id_hash_ptr 4 0 100.00% 5 0 100.00% +credman.c:credman_get_metadata_wait 11 0 100.00% 8 0 100.00% +credman.c:credman_tx 35 0 100.00% 50 0 100.00% +credman.c:credman_get_cmd 7 0 100.00% 5 0 100.00% +credman.c:credman_prepare_hmac 31 1 96.77% 50 2 96.00% +credman.c:credman_rx_metadata 19 0 100.00% 24 0 100.00% +credman.c:credman_parse_metadata 9 0 100.00% 17 0 100.00% +credman.c:credman_get_rk_wait 27 0 100.00% 23 0 100.00% +credman.c:credman_rx_rk 27 0 100.00% 35 0 100.00% +credman.c:credman_parse_rk_count 16 0 100.00% 20 0 100.00% +credman.c:credman_grow_array 17 2 88.24% 21 5 76.19% +credman.c:credman_parse_rk 23 0 100.00% 31 0 100.00% +credman.c:credman_rx_next_rk 23 2 91.30% 29 5 82.76% +credman.c:credman_del_rk_wait 16 0 100.00% 15 0 100.00% +credman.c:credman_get_rp_wait 23 0 100.00% 15 0 100.00% +credman.c:credman_rx_rp 27 0 100.00% 35 0 100.00% +credman.c:credman_parse_rp_count 16 0 100.00% 20 0 100.00% +credman.c:credman_parse_rp 9 0 100.00% 17 0 100.00% +credman.c:credman_rx_next_rp 23 2 91.30% 29 5 82.76% +credman.c:credman_set_dev_rk_wait 11 0 100.00% 8 0 100.00% +credman.c:credman_reset_rk 4 0 100.00% 9 0 100.00% +credman.c:credman_reset_rp 4 0 100.00% 12 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 428 10 97.66% 562 20 96.44% + +File '/libfido2/src/dev.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_dev_info_manifest 2 0 100.00% 11 0 100.00% +fido_dev_open_with_info 5 5 0.00% 6 6 0.00% +fido_dev_open 13 4 69.23% 16 6 62.50% +fido_dev_close 9 2 77.78% 8 1 87.50% +fido_dev_set_sigmask 18 18 0.00% 11 11 0.00% +fido_dev_cancel 11 0 100.00% 8 0 100.00% +fido_dev_set_io_functions 18 4 77.78% 14 6 57.14% +fido_dev_set_transport_functions 6 2 66.67% 9 3 66.67% +fido_dev_io_handle 1 1 0.00% 3 3 0.00% +fido_init 8 1 87.50% 5 0 100.00% +fido_dev_new 5 0 100.00% 14 0 100.00% +fido_dev_new_with_info 10 10 0.00% 16 16 0.00% +fido_dev_free 6 0 100.00% 8 0 100.00% +fido_dev_protocol 1 0 100.00% 3 0 100.00% +fido_dev_major 1 0 100.00% 3 0 100.00% +fido_dev_minor 1 0 100.00% 3 0 100.00% +fido_dev_build 1 0 100.00% 3 0 100.00% +fido_dev_flags 1 0 100.00% 3 0 100.00% +fido_dev_is_fido2 2 0 100.00% 3 0 100.00% +fido_dev_is_winhello 2 2 0.00% 3 3 0.00% +fido_dev_supports_pin 3 0 100.00% 3 0 100.00% +fido_dev_has_pin 2 0 100.00% 3 0 100.00% +fido_dev_supports_cred_prot 2 0 100.00% 3 0 100.00% +fido_dev_supports_credman 3 0 100.00% 3 0 100.00% +fido_dev_supports_uv 3 0 100.00% 3 0 100.00% +fido_dev_has_uv 2 0 100.00% 3 0 100.00% +fido_dev_supports_permissions 2 0 100.00% 3 0 100.00% +fido_dev_force_u2f 2 0 100.00% 4 0 100.00% +fido_dev_force_fido2 2 2 0.00% 3 3 0.00% +fido_dev_get_pin_protocol 11 0 100.00% 7 0 100.00% +fido_dev_maxmsgsize 1 0 100.00% 3 0 100.00% +fido_dev_set_timeout 6 2 66.67% 6 1 83.33% +dev.c:run_manifest 10 0 100.00% 13 0 100.00% +dev.c:fido_dev_open_wait 10 0 100.00% 7 0 100.00% +dev.c:fido_dev_open_tx 56 11 80.36% 56 20 64.29% +dev.c:set_random_report_len 11 0 100.00% 6 0 100.00% +dev.c:fido_dev_open_rx 36 1 97.22% 53 1 98.11% +dev.c:fido_dev_set_flags 1 0 100.00% 5 0 100.00% +dev.c:fido_dev_set_extension_flags 7 0 100.00% 7 0 100.00% +dev.c:fido_dev_set_option_flags 42 0 100.00% 25 0 100.00% +dev.c:fido_dev_set_protocol_flags 11 0 100.00% 17 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 344 65 81.10% 383 80 79.11% + +File '/libfido2/src/ecdh.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_do_ecdh 29 0 100.00% 36 0 100.00% +ecdh.c:do_ecdh 37 0 100.00% 44 0 100.00% +ecdh.c:kdf 19 1 94.74% 28 2 92.86% +ecdh.c:hkdf_sha256 32 1 96.88% 38 3 92.11% +------------------------------------------------------------------------------------------------------------------- +TOTAL 117 2 98.29% 146 5 96.58% + +File '/libfido2/src/eddsa.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +eddsa_pk_decode 8 0 100.00% 9 0 100.00% +eddsa_pk_new 1 0 100.00% 3 0 100.00% +eddsa_pk_free 6 0 100.00% 7 0 100.00% +eddsa_pk_from_ptr 10 0 100.00% 12 0 100.00% +eddsa_pk_to_EVP_PKEY 3 0 100.00% 7 0 100.00% +eddsa_pk_from_EVP_PKEY 18 2 88.89% 12 1 91.67% +eddsa_verify_sig 19 2 89.47% 30 6 80.00% +eddsa_pk_verify_sig 7 1 85.71% 13 2 84.62% +eddsa.c:decode_pubkey_point 8 0 100.00% 11 0 100.00% +eddsa.c:decode_coord 8 0 100.00% 10 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 88 5 94.32% 114 9 92.11% + +File '/libfido2/src/err.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_strerr 122 10 91.80% 126 10 92.06% +------------------------------------------------------------------------------------------------------------------- +TOTAL 122 10 91.80% 126 10 92.06% + +File '/libfido2/src/es256.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +es256_pk_decode 8 0 100.00% 9 0 100.00% +es256_pk_encode 56 0 100.00% 48 0 100.00% +es256_sk_new 1 0 100.00% 3 0 100.00% +es256_sk_free 6 0 100.00% 7 0 100.00% +es256_pk_new 1 0 100.00% 3 0 100.00% +es256_pk_free 6 0 100.00% 7 0 100.00% +es256_pk_from_ptr 15 0 100.00% 17 0 100.00% +es256_pk_set_x 1 0 100.00% 4 0 100.00% +es256_pk_set_y 1 0 100.00% 4 0 100.00% +es256_sk_create 39 0 100.00% 40 0 100.00% +es256_pk_to_EVP_PKEY 42 0 100.00% 53 0 100.00% +es256_pk_from_EC_KEY 42 2 95.24% 47 4 91.49% +es256_pk_from_EVP_PKEY 8 0 100.00% 7 0 100.00% +es256_sk_to_EVP_PKEY 28 0 100.00% 39 0 100.00% +es256_derive_pk 25 0 100.00% 29 0 100.00% +es256_verify_sig 12 2 83.33% 19 5 73.68% +es256_pk_verify_sig 7 1 85.71% 13 2 84.62% +es256.c:decode_pubkey_point 9 0 100.00% 13 0 100.00% +es256.c:decode_coord 8 0 100.00% 10 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 315 5 98.41% 372 11 97.04% + +File '/libfido2/src/es384.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +es384_pk_decode 8 0 100.00% 9 0 100.00% +es384_pk_new 1 0 100.00% 3 0 100.00% +es384_pk_free 6 0 100.00% 7 0 100.00% +es384_pk_from_ptr 15 0 100.00% 17 0 100.00% +es384_pk_to_EVP_PKEY 42 0 100.00% 53 0 100.00% +es384_pk_from_EC_KEY 42 2 95.24% 47 4 91.49% +es384_pk_from_EVP_PKEY 8 0 100.00% 7 0 100.00% +es384_verify_sig 12 2 83.33% 19 5 73.68% +es384_pk_verify_sig 7 1 85.71% 13 2 84.62% +es384.c:decode_pubkey_point 9 0 100.00% 13 0 100.00% +es384.c:decode_coord 8 0 100.00% 10 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 158 5 96.84% 198 11 94.44% + +File '/libfido2/src/extern.h': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- + +File '/libfido2/src/fallthrough.h': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- + +File '/libfido2/src/fido.h': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- + +File '/libfido2/src/hid.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_hid_get_usage 13 0 100.00% 22 0 100.00% +fido_hid_get_report_len 19 0 100.00% 27 0 100.00% +fido_dev_info_new 1 0 100.00% 3 0 100.00% +fido_dev_info_free 9 0 100.00% 9 0 100.00% +fido_dev_info_ptr 1 0 100.00% 3 0 100.00% +fido_dev_info_set 26 2 92.31% 30 3 90.00% +fido_dev_info_path 1 0 100.00% 3 0 100.00% +fido_dev_info_vendor 1 0 100.00% 3 0 100.00% +fido_dev_info_product 1 0 100.00% 3 0 100.00% +fido_dev_info_manufacturer_string 1 0 100.00% 3 0 100.00% +fido_dev_info_product_string 1 0 100.00% 3 0 100.00% +hid.c:get_key_len 6 0 100.00% 12 0 100.00% +hid.c:get_key_val 6 0 100.00% 18 0 100.00% +hid.c:fido_dev_info_reset 1 0 100.00% 6 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 87 2 97.70% 145 3 97.93% + +File '/libfido2/src/hid_linux.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_hid_manifest 35 4 88.57% 41 2 95.12% +fido_hid_open 33 33 0.00% 51 51 0.00% +fido_hid_close 3 3 0.00% 6 6 0.00% +fido_hid_set_sigmask 2 2 0.00% 6 6 0.00% +fido_hid_read 15 15 0.00% 21 21 0.00% +fido_hid_write 12 12 0.00% 17 17 0.00% +fido_hid_report_in_len 1 1 0.00% 4 4 0.00% +fido_hid_report_out_len 1 1 0.00% 4 4 0.00% +hid_linux.c:copy_info 38 0 100.00% 53 0 100.00% +hid_linux.c:is_fido 15 1 93.33% 16 1 93.75% +hid_linux.c:get_parent_attr 6 0 100.00% 9 0 100.00% +hid_linux.c:parse_uevent 26 0 100.00% 29 0 100.00% +hid_linux.c:get_usb_attr 1 0 100.00% 3 0 100.00% +hid_linux.c:get_report_descriptor 14 1 92.86% 17 3 82.35% +------------------------------------------------------------------------------------------------------------------- +TOTAL 202 73 63.86% 277 115 58.48% + +File '/libfido2/src/hid_unix.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_hid_unix_open 18 11 38.89% 22 14 36.36% +fido_hid_unix_wait 11 10 9.09% 21 12 42.86% +------------------------------------------------------------------------------------------------------------------- +TOTAL 29 21 27.59% 43 26 39.53% + +File '/libfido2/src/info.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_dev_get_cbor_info_wait 10 0 100.00% 7 0 100.00% +fido_dev_get_cbor_info 1 0 100.00% 4 0 100.00% +fido_cbor_info_new 4 0 100.00% 7 0 100.00% +fido_cbor_info_reset 1 0 100.00% 10 0 100.00% +fido_cbor_info_free 6 0 100.00% 8 0 100.00% +fido_cbor_info_versions_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_versions_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_extensions_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_extensions_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_transports_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_transports_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_aaguid_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_aaguid_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_options_name_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_options_value_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_options_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxcredbloblen 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxmsgsiz 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxcredcntlst 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxcredidlen 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxlargeblob 1 0 100.00% 3 0 100.00% +fido_cbor_info_fwversion 1 0 100.00% 3 0 100.00% +fido_cbor_info_minpinlen 1 0 100.00% 3 0 100.00% +fido_cbor_info_maxrpid_minpinlen 1 0 100.00% 3 0 100.00% +fido_cbor_info_uv_attempts 1 0 100.00% 3 0 100.00% +fido_cbor_info_uv_modality 1 0 100.00% 3 0 100.00% +fido_cbor_info_rk_remaining 1 0 100.00% 3 0 100.00% +fido_cbor_info_protocols_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_protocols_len 1 0 100.00% 3 0 100.00% +fido_cbor_info_algorithm_count 1 0 100.00% 3 0 100.00% +fido_cbor_info_algorithm_type 4 0 100.00% 5 0 100.00% +fido_cbor_info_algorithm_cose 4 0 100.00% 5 0 100.00% +fido_cbor_info_new_pin_required 1 0 100.00% 3 0 100.00% +fido_cbor_info_certs_name_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_certs_value_ptr 1 0 100.00% 3 0 100.00% +fido_cbor_info_certs_len 1 0 100.00% 3 0 100.00% +info.c:fido_dev_get_cbor_info_tx 8 0 100.00% 9 0 100.00% +info.c:fido_dev_get_cbor_info_rx 14 0 100.00% 21 0 100.00% +info.c:parse_reply_element 32 0 100.00% 59 0 100.00% +info.c:decode_string_array 12 0 100.00% 17 0 100.00% +info.c:decode_string 4 0 100.00% 10 0 100.00% +info.c:decode_aaguid 8 0 100.00% 10 0 100.00% +info.c:decode_options 11 0 100.00% 15 0 100.00% +info.c:decode_option 7 0 100.00% 15 0 100.00% +info.c:decode_protocols 12 0 100.00% 17 0 100.00% +info.c:decode_protocol 6 0 100.00% 12 0 100.00% +info.c:decode_algorithms 12 0 100.00% 17 0 100.00% +info.c:decode_algorithm 9 0 100.00% 17 0 100.00% +info.c:decode_algorithm_entry 20 0 100.00% 27 0 100.00% +info.c:decode_certs 11 0 100.00% 15 0 100.00% +info.c:decode_cert 7 0 100.00% 15 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 232 0 100.00% 409 0 100.00% + +File '/libfido2/src/io.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_tx 14 0 100.00% 11 0 100.00% +fido_rx 13 1 92.31% 14 3 78.57% +fido_rx_cbor_status 16 0 100.00% 19 0 100.00% +io.c:transport_tx 7 0 100.00% 10 0 100.00% +io.c:tx_empty 9 0 100.00% 14 0 100.00% +io.c:tx_pkt 7 0 100.00% 10 0 100.00% +io.c:tx 13 0 100.00% 19 0 100.00% +io.c:tx_preamble 17 1 94.12% 20 1 95.00% +io.c:tx_frame 16 1 93.75% 18 1 94.44% +io.c:transport_rx 7 0 100.00% 10 0 100.00% +io.c:rx 40 2 95.00% 52 2 96.15% +io.c:rx_preamble 23 2 91.30% 22 5 77.27% +io.c:rx_frame 11 0 100.00% 11 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 193 7 96.37% 230 12 94.78% + +File '/libfido2/src/iso7816.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +iso7816_new 4 0 100.00% 16 0 100.00% +iso7816_free 6 0 100.00% 7 0 100.00% +iso7816_add 6 1 83.33% 8 1 87.50% +iso7816_ptr 1 0 100.00% 3 0 100.00% +iso7816_len 1 0 100.00% 4 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 18 1 94.44% 38 1 97.37% + +File '/libfido2/src/largeblob.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_dev_largeblob_get 26 2 92.31% 38 4 89.47% +fido_dev_largeblob_set 27 0 100.00% 36 0 100.00% +fido_dev_largeblob_remove 12 0 100.00% 18 0 100.00% +fido_dev_largeblob_get_array 15 2 86.67% 27 4 85.19% +fido_dev_largeblob_set_array 14 0 100.00% 19 0 100.00% +largeblob.c:largeblob_get_array 32 0 100.00% 36 0 100.00% +largeblob.c:get_chunklen 10 1 90.00% 9 1 88.89% +largeblob.c:largeblob_get_tx 19 0 100.00% 24 0 100.00% +largeblob.c:largeblob_get_rx 26 0 100.00% 30 0 100.00% +largeblob.c:parse_largeblob_reply 8 0 100.00% 9 0 100.00% +largeblob.c:largeblob_array_check 7 0 100.00% 16 0 100.00% +largeblob.c:largeblob_array_digest 10 0 100.00% 9 0 100.00% +largeblob.c:largeblob_array_load 14 2 85.71% 19 7 63.16% +largeblob.c:largeblob_array_lookup 25 0 100.00% 33 0 100.00% +largeblob.c:largeblob_decode 16 2 87.50% 16 6 62.50% +largeblob.c:largeblob_do_decode 27 3 88.89% 30 7 76.67% +largeblob.c:largeblob_decrypt 15 0 100.00% 24 0 100.00% +largeblob.c:largeblob_aad 1 0 100.00% 10 0 100.00% +largeblob.c:largeblob_reset 1 0 100.00% 5 0 100.00% +largeblob.c:largeblob_encode 16 0 100.00% 21 0 100.00% +largeblob.c:largeblob_new 1 0 100.00% 3 0 100.00% +largeblob.c:largeblob_seal 20 0 100.00% 32 0 100.00% +largeblob.c:largeblob_get_nonce 8 0 100.00% 16 0 100.00% +largeblob.c:largeblob_free 6 0 100.00% 8 0 100.00% +largeblob.c:largeblob_add 27 2 92.59% 35 3 91.43% +largeblob.c:largeblob_drop 21 0 100.00% 27 0 100.00% +largeblob.c:largeblob_set_array 54 2 96.30% 61 4 93.44% +largeblob.c:largeblob_get_uv_token 19 0 100.00% 23 0 100.00% +largeblob.c:largeblob_set_tx 35 0 100.00% 36 0 100.00% +largeblob.c:prepare_hmac 13 2 84.62% 23 7 69.57% +------------------------------------------------------------------------------------------------------------------- +TOTAL 525 18 96.57% 693 43 93.80% + +File '/libfido2/src/log.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_log_init 1 0 100.00% 4 0 100.00% +fido_log_debug 6 1 83.33% 8 1 87.50% +fido_log_xxd 16 1 93.75% 24 1 95.83% +fido_log_error 8 2 75.00% 11 2 81.82% +fido_set_log_handler 3 0 100.00% 4 0 100.00% +log.c:log_on_stderr 1 1 0.00% 3 3 0.00% +log.c:do_log 4 0 100.00% 9 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 39 5 87.18% 63 7 88.89% + +File '/libfido2/src/netlink.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_nl_power_nfc 18 0 100.00% 24 0 100.00% +fido_nl_get_nfc_target 17 0 100.00% 31 0 100.00% +fido_nl_free 10 2 80.00% 9 2 77.78% +fido_nl_new 16 1 93.75% 26 3 88.46% +set_netlink_io_functions 1 0 100.00% 4 0 100.00% +netlink.c:nlmsg_new 8 0 100.00% 15 0 100.00% +netlink.c:nlmsg_set_genl 1 0 100.00% 7 0 100.00% +netlink.c:nlmsg_write 6 1 83.33% 7 1 85.71% +netlink.c:nlmsg_set_u32 1 0 100.00% 3 0 100.00% +netlink.c:nlmsg_setattr 15 1 93.33% 17 0 100.00% +netlink.c:nlmsg_tx 10 1 90.00% 13 3 76.92% +netlink.c:nlmsg_ptr 1 0 100.00% 3 0 100.00% +netlink.c:nlmsg_len 1 0 100.00% 3 0 100.00% +netlink.c:nlmsg_rx 11 2 81.82% 17 6 64.71% +netlink.c:nl_parse_reply 20 0 100.00% 28 0 100.00% +netlink.c:nlmsg_from_buf 15 0 100.00% 17 0 100.00% +netlink.c:nlmsg_type 1 0 100.00% 3 0 100.00% +netlink.c:nlmsg_get_status 8 0 100.00% 8 0 100.00% +netlink.c:nlmsg_read 6 0 100.00% 7 0 100.00% +netlink.c:nlmsg_get_genl 6 0 100.00% 7 0 100.00% +netlink.c:nlmsg_iter 6 0 100.00% 13 0 100.00% +netlink.c:nlmsg_getattr 1 0 100.00% 3 0 100.00% +netlink.c:nla_from_buf 17 0 100.00% 21 0 100.00% +netlink.c:nl_nfc_poll 18 0 100.00% 25 0 100.00% +netlink.c:parse_nfc_event 10 0 100.00% 17 0 100.00% +netlink.c:nla_type 1 0 100.00% 3 0 100.00% +netlink.c:nla_get_u32 1 0 100.00% 3 0 100.00% +netlink.c:nla_read 6 0 100.00% 7 0 100.00% +netlink.c:nl_dump_nfc_target 19 0 100.00% 31 0 100.00% +netlink.c:parse_target 9 0 100.00% 13 0 100.00% +netlink.c:nl_get_nfc_family 23 0 100.00% 33 0 100.00% +netlink.c:nlmsg_set_u16 1 0 100.00% 3 0 100.00% +netlink.c:nlmsg_set_str 1 0 100.00% 3 0 100.00% +netlink.c:parse_family 10 0 100.00% 17 0 100.00% +netlink.c:nla_get_u16 1 0 100.00% 3 0 100.00% +netlink.c:nla_iter 6 0 100.00% 13 0 100.00% +netlink.c:nla_getattr 1 0 100.00% 3 0 100.00% +netlink.c:parse_mcastgrps 1 0 100.00% 3 0 100.00% +netlink.c:parse_mcastgrp 15 0 100.00% 24 0 100.00% +netlink.c:nla_get_str 10 0 100.00% 11 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 329 8 97.57% 498 15 96.99% + +File '/libfido2/src/nfc.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_nfc_tx 28 0 100.00% 43 0 100.00% +fido_nfc_rx 8 0 100.00% 13 0 100.00% +nfc_is_fido 13 1 92.31% 21 3 85.71% +fido_is_nfc 3 0 100.00% 3 0 100.00% +fido_dev_set_nfc 4 1 75.00% 18 3 83.33% +nfc.c:nfc_do_tx 20 0 100.00% 25 0 100.00% +nfc.c:tx_short_apdu 14 0 100.00% 32 0 100.00% +nfc.c:rx_init 25 0 100.00% 27 0 100.00% +nfc.c:rx_cbor 4 0 100.00% 6 0 100.00% +nfc.c:rx_msg 18 1 94.44% 23 3 86.96% +nfc.c:rx_apdu 14 0 100.00% 22 0 100.00% +nfc.c:tx_get_response 4 0 100.00% 11 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 155 3 98.06% 244 9 96.31% + +File '/libfido2/src/nfc_linux.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_nfc_manifest 35 7 80.00% 45 15 66.67% +fido_nfc_open 20 2 90.00% 23 4 82.61% +fido_nfc_close 1 1 0.00% 4 4 0.00% +fido_nfc_set_sigmask 2 2 0.00% 6 6 0.00% +fido_nfc_read 14 14 0.00% 30 30 0.00% +fido_nfc_write 12 12 0.00% 18 18 0.00% +nfc_linux.c:copy_info 39 22 43.59% 44 16 63.64% +nfc_linux.c:get_usb_attr 1 1 0.00% 3 3 0.00% +nfc_linux.c:get_parent_attr 6 6 0.00% 9 9 0.00% +nfc_linux.c:sysnum_from_syspath 15 0 100.00% 17 0 100.00% +nfc_linux.c:nfc_new 6 0 100.00% 11 0 100.00% +nfc_linux.c:nfc_target_connect 9 6 33.33% 21 9 57.14% +nfc_linux.c:nfc_free 12 0 100.00% 11 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 172 73 57.56% 242 114 52.89% + +File '/libfido2/src/pcsc.c': +Name Regions Miss Cover Lines Miss Cover +------------------------------------------------------------------------------------------------------------------- +fido_pcsc_manifest 51 0 100.00% 55 0 100.00% +fido_pcsc_open 32 0 100.00% 43 0 100.00% +fido_pcsc_close 6 0 100.00% 9 0 100.00% +fido_pcsc_read 8 0 100.00% 16 0 100.00% +fido_pcsc_write 8 0 100.00% 22 0 100.00% +fido_pcsc_tx 1 0 100.00% 3 0 100.00% +fido_pcsc_rx 1 0 100.00% 3 0 100.00% +fido_is_pcsc 3 0 100.00% 3 0 100.00% +fido_dev_set_pcsc 4 1 75.00% 18 3 83.33% +pcsc.c:list_readers 24 0 100.00% 24 0 100.00% +pcsc.c:copy_info 30 0 100.00% 41 0 100.00% +pcsc.c:get_reader 25 0 100.00% 28 0 100.00% +pcsc.c:prepare_io_request 11 0 100.00% 17 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 204 1 99.51% 282 3 98.94% + +File '/libfido2/src/pin.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_sha256 7 0 100.00% 10 0 100.00% +fido_dev_get_uv_token 1 0 100.00% 3 0 100.00% +fido_dev_set_pin 1 0 100.00% 4 0 100.00% +fido_dev_get_retry_count 1 0 100.00% 4 0 100.00% +fido_dev_get_uv_retry_count 1 0 100.00% 4 0 100.00% +cbor_add_uv_params 17 0 100.00% 23 0 100.00% +pin.c:uv_token_wait 14 2 85.71% 12 1 91.67% +pin.c:ctap21_uv_token_tx 49 0 100.00% 53 0 100.00% +pin.c:pin_sha256_enc 19 0 100.00% 24 0 100.00% +pin.c:encode_uv_permission 24 1 95.83% 21 3 85.71% +pin.c:ctap20_uv_token_tx 37 0 100.00% 45 0 100.00% +pin.c:uv_token_rx 27 0 100.00% 34 0 100.00% +pin.c:parse_uv_token 8 0 100.00% 10 0 100.00% +pin.c:fido_dev_set_pin_wait 21 0 100.00% 24 0 100.00% +pin.c:fido_dev_change_pin_tx 45 0 100.00% 56 0 100.00% +pin.c:pin_pad64_enc 15 0 100.00% 21 0 100.00% +pin.c:pad64 18 0 100.00% 20 0 100.00% +pin.c:fido_dev_set_pin_tx 33 0 100.00% 41 0 100.00% +pin.c:fido_dev_get_pin_retry_count_wait 10 0 100.00% 7 0 100.00% +pin.c:fido_dev_get_retry_count_tx 19 0 100.00% 23 0 100.00% +pin.c:fido_dev_get_pin_retry_count_rx 19 0 100.00% 24 0 100.00% +pin.c:parse_pin_retry_count 1 0 100.00% 3 0 100.00% +pin.c:parse_retry_count 13 0 100.00% 16 0 100.00% +pin.c:fido_dev_get_uv_retry_count_wait 10 0 100.00% 7 0 100.00% +pin.c:fido_dev_get_uv_retry_count_rx 19 0 100.00% 24 0 100.00% +pin.c:parse_uv_retry_count 1 0 100.00% 3 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 430 3 99.30% 516 4 99.22% + +File '/libfido2/src/random.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_get_random 6 0 100.00% 6 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 6 0 100.00% 6 0 100.00% + +File '/libfido2/src/reset.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_dev_reset 1 0 100.00% 4 0 100.00% +reset.c:fido_dev_reset_wait 15 0 100.00% 11 0 100.00% +reset.c:fido_dev_reset_tx 8 0 100.00% 8 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 24 0 100.00% 23 0 100.00% + +File '/libfido2/src/rs1.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +rs1_verify_sig 20 2 90.00% 30 6 80.00% +rs1.c:rs1_get_EVP_MD 1 0 100.00% 3 0 100.00% +rs1.c:rs1_free_EVP_MD 1 0 100.00% 3 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 22 2 90.91% 36 6 83.33% + +File '/libfido2/src/rs256.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +rs256_pk_decode 8 0 100.00% 9 0 100.00% +rs256_pk_new 1 0 100.00% 3 0 100.00% +rs256_pk_free 6 0 100.00% 7 0 100.00% +rs256_pk_from_ptr 10 0 100.00% 12 0 100.00% +rs256_pk_to_EVP_PKEY 35 0 100.00% 43 0 100.00% +rs256_pk_from_RSA 32 6 81.25% 26 9 65.38% +rs256_pk_from_EVP_PKEY 8 0 100.00% 7 0 100.00% +rs256_verify_sig 20 2 90.00% 30 5 83.33% +rs256_pk_verify_sig 7 1 85.71% 13 2 84.62% +rs256.c:decode_rsa_pubkey 9 0 100.00% 13 0 100.00% +rs256.c:decode_bignum 8 0 100.00% 10 0 100.00% +rs256.c:rs256_get_EVP_MD 1 0 100.00% 3 0 100.00% +rs256.c:rs256_free_EVP_MD 1 0 100.00% 3 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 146 9 93.84% 179 16 91.06% + +File '/libfido2/src/time.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_time_now 4 0 100.00% 7 0 100.00% +fido_time_delta 23 1 95.65% 23 0 100.00% +time.c:timespec_to_ms 16 2 87.50% 13 2 84.62% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 43 3 93.02% 43 2 95.35% + +File '/libfido2/src/touch.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_dev_get_touch_begin 50 0 100.00% 59 0 100.00% +fido_dev_get_touch_status 17 0 100.00% 20 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 67 0 100.00% 79 0 100.00% + +File '/libfido2/src/tpm.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_get_signed_hash_tpm 25 0 100.00% 39 0 100.00% +tpm.c:check_es256_pubarea 19 0 100.00% 30 0 100.00% +tpm.c:bswap_es256_pubarea 1 0 100.00% 12 0 100.00% +tpm.c:check_rs256_pubarea 17 0 100.00% 28 0 100.00% +tpm.c:bswap_rs256_pubarea 1 0 100.00% 10 0 100.00% +tpm.c:check_sha1_certinfo 15 0 100.00% 38 0 100.00% +tpm.c:get_signed_sha1 17 0 100.00% 19 0 100.00% +tpm.c:get_signed_name 7 0 100.00% 10 0 100.00% +tpm.c:bswap_sha1_certinfo 1 0 100.00% 8 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 103 0 100.00% 194 0 100.00% + +File '/libfido2/src/types.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_str_array_free 4 0 100.00% 7 0 100.00% +fido_opt_array_free 4 0 100.00% 9 0 100.00% +fido_byte_array_free 1 0 100.00% 5 0 100.00% +fido_algo_free 1 0 100.00% 5 0 100.00% +fido_algo_array_free 4 0 100.00% 7 0 100.00% +fido_cert_array_free 4 0 100.00% 9 0 100.00% +fido_str_array_pack 11 0 100.00% 14 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 29 0 100.00% 56 0 100.00% + +File '/libfido2/src/u2f.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +u2f_register 76 0 100.00% 81 0 100.00% +u2f_authenticate 33 0 100.00% 37 0 100.00% +u2f_get_touch_begin 37 0 100.00% 45 0 100.00% +u2f_get_touch_status 26 0 100.00% 36 0 100.00% +u2f.c:key_lookup 51 0 100.00% 65 0 100.00% +u2f.c:send_dummy_register 37 0 100.00% 45 0 100.00% +u2f.c:delay_ms 13 1 92.31% 15 3 80.00% +u2f.c:parse_register_reply 49 0 100.00% 62 0 100.00% +u2f.c:x5c_get 21 1 95.24% 26 3 88.46% +u2f.c:sig_get 6 0 100.00% 10 0 100.00% +u2f.c:encode_cred_attstmt 45 0 100.00% 52 0 100.00% +u2f.c:encode_cred_authdata 33 2 93.94% 61 6 90.16% +u2f.c:cbor_blob_from_ec_point 22 0 100.00% 31 0 100.00% +u2f.c:u2f_authenticate_single 32 0 100.00% 43 0 100.00% +u2f.c:do_auth 56 0 100.00% 67 0 100.00% +u2f.c:parse_auth_reply 23 0 100.00% 23 0 100.00% +u2f.c:authdata_fake 12 0 100.00% 27 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 572 4 99.30% 726 12 98.35% + +File '/libfido2/src/util.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_to_uint64 14 1 92.86% 14 1 92.86% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 14 1 92.86% 14 1 92.86% diff --git a/fuzz/fuzz_assert.c b/fuzz/fuzz_assert.c new file mode 100644 index 0000000..03cb51c --- /dev/null +++ b/fuzz/fuzz_assert.c @@ -0,0 +1,534 @@ +/* + * Copyright (c) 2019-2023 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "wiredata_u2f.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +/* Parameter set defining a FIDO2 get assertion operation. */ +struct param { + char pin[MAXSTR]; + char rp_id[MAXSTR]; + int ext; + int seed; + struct blob cdh; + struct blob cred; + struct blob es256; + struct blob rs256; + struct blob eddsa; + struct blob wire_data; + uint8_t cred_count; + uint8_t type; + uint8_t opt; + uint8_t up; + uint8_t uv; +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * get assertion using the example parameters above. + */ +static const uint8_t dummy_wire_data_fido[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_ASSERT, +}; + +/* + * Collection of HID reports from an authenticator issued with a U2F + * authentication using the example parameters above. + */ +static const uint8_t dummy_wire_data_u2f[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_AUTH, +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 15 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_byte(v[0], &p->uv) < 0 || + unpack_byte(v[1], &p->up) < 0 || + unpack_byte(v[2], &p->opt) < 0 || + unpack_byte(v[3], &p->type) < 0 || + unpack_byte(v[4], &p->cred_count) < 0 || + unpack_int(v[5], &p->ext) < 0 || + unpack_int(v[6], &p->seed) < 0 || + unpack_string(v[7], p->rp_id) < 0 || + unpack_string(v[8], p->pin) < 0 || + unpack_blob(v[9], &p->wire_data) < 0 || + unpack_blob(v[10], &p->rs256) < 0 || + unpack_blob(v[11], &p->es256) < 0 || + unpack_blob(v[12], &p->eddsa) < 0 || + unpack_blob(v[13], &p->cred) < 0 || + unpack_blob(v[14], &p->cdh) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[15], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(15)) == NULL || + (argv[0] = pack_byte(p->uv)) == NULL || + (argv[1] = pack_byte(p->up)) == NULL || + (argv[2] = pack_byte(p->opt)) == NULL || + (argv[3] = pack_byte(p->type)) == NULL || + (argv[4] = pack_byte(p->cred_count)) == NULL || + (argv[5] = pack_int(p->ext)) == NULL || + (argv[6] = pack_int(p->seed)) == NULL || + (argv[7] = pack_string(p->rp_id)) == NULL || + (argv[8] = pack_string(p->pin)) == NULL || + (argv[9] = pack_blob(&p->wire_data)) == NULL || + (argv[10] = pack_blob(&p->rs256)) == NULL || + (argv[11] = pack_blob(&p->es256)) == NULL || + (argv[12] = pack_blob(&p->eddsa)) == NULL || + (argv[13] = pack_blob(&p->cred)) == NULL || + (argv[14] = pack_blob(&p->cdh)) == NULL) + goto fail; + + for (size_t i = 0; i < 15; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) == 0 || cbor_len > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 15; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + dummy.type = 1; /* rsa */ + dummy.ext = FIDO_EXT_HMAC_SECRET; + + strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); + strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id)); + + dummy.cred.len = sizeof(dummy_cdh); /* XXX */ + dummy.cdh.len = sizeof(dummy_cdh); + dummy.es256.len = sizeof(dummy_es256); + dummy.rs256.len = sizeof(dummy_rs256); + dummy.eddsa.len = sizeof(dummy_eddsa); + dummy.wire_data.len = sizeof(dummy_wire_data_fido); + + memcpy(&dummy.cred.body, &dummy_cdh, dummy.cred.len); /* XXX */ + memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len); + memcpy(&dummy.wire_data.body, &dummy_wire_data_fido, + dummy.wire_data.len); + memcpy(&dummy.es256.body, &dummy_es256, dummy.es256.len); + memcpy(&dummy.rs256.body, &dummy_rs256, dummy.rs256.len); + memcpy(&dummy.eddsa.body, &dummy_eddsa, dummy.eddsa.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static void +get_assert(fido_assert_t *assert, uint8_t opt, const struct blob *cdh, + const char *rp_id, int ext, uint8_t up, uint8_t uv, const char *pin, + uint8_t cred_count, const struct blob *cred) +{ + fido_dev_t *dev; + + if ((dev = open_dev(opt & 2)) == NULL) + return; + if (opt & 1) + fido_dev_force_u2f(dev); + if (ext & FIDO_EXT_HMAC_SECRET) + fido_assert_set_extensions(assert, FIDO_EXT_HMAC_SECRET); + if (ext & FIDO_EXT_CRED_BLOB) + fido_assert_set_extensions(assert, FIDO_EXT_CRED_BLOB); + if (ext & FIDO_EXT_LARGEBLOB_KEY) + fido_assert_set_extensions(assert, FIDO_EXT_LARGEBLOB_KEY); + if (up & 1) + fido_assert_set_up(assert, FIDO_OPT_TRUE); + else if (opt & 1) + fido_assert_set_up(assert, FIDO_OPT_FALSE); + if (uv & 1) + fido_assert_set_uv(assert, FIDO_OPT_TRUE); + + for (uint8_t i = 0; i < cred_count; i++) + fido_assert_allow_cred(assert, cred->body, cred->len); + + fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len); + fido_assert_set_rp(assert, rp_id); + /* XXX reuse cred as hmac salt */ + fido_assert_set_hmac_salt(assert, cred->body, cred->len); + + /* repeat memory operations to trigger reallocation paths */ + fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len); + fido_assert_set_rp(assert, rp_id); + fido_assert_set_hmac_salt(assert, cred->body, cred->len); + + if (strlen(pin) == 0) + pin = NULL; + + fido_dev_get_assert(dev, assert, (opt & 1) ? NULL : pin); + + fido_dev_cancel(dev); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +verify_assert(int type, const unsigned char *cdh_ptr, size_t cdh_len, + const char *rp_id, const unsigned char *authdata_ptr, size_t authdata_len, + const unsigned char *sig_ptr, size_t sig_len, uint8_t up, uint8_t uv, + int ext, void *pk) +{ + fido_assert_t *assert = NULL; + int r; + + if ((assert = fido_assert_new()) == NULL) + return; + + fido_assert_set_clientdata_hash(assert, cdh_ptr, cdh_len); + fido_assert_set_rp(assert, rp_id); + fido_assert_set_count(assert, 1); + + if (fido_assert_set_authdata(assert, 0, authdata_ptr, + authdata_len) != FIDO_OK) { + fido_assert_set_authdata_raw(assert, 0, authdata_ptr, + authdata_len); + } + + if (up & 1) + fido_assert_set_up(assert, FIDO_OPT_TRUE); + if (uv & 1) + fido_assert_set_uv(assert, FIDO_OPT_TRUE); + + fido_assert_set_extensions(assert, ext); + fido_assert_set_sig(assert, 0, sig_ptr, sig_len); + + /* repeat memory operations to trigger reallocation paths */ + if (fido_assert_set_authdata(assert, 0, authdata_ptr, + authdata_len) != FIDO_OK) { + fido_assert_set_authdata_raw(assert, 0, authdata_ptr, + authdata_len); + } + fido_assert_set_sig(assert, 0, sig_ptr, sig_len); + + r = fido_assert_verify(assert, 0, type, pk); + consume(&r, sizeof(r)); + + fido_assert_free(&assert); +} + +/* + * Do a dummy conversion to exercise es256_pk_from_EVP_PKEY(). + */ +static void +es256_convert(const es256_pk_t *k) +{ + EVP_PKEY *pkey = NULL; + es256_pk_t *pk = NULL; + int r; + + if ((pkey = es256_pk_to_EVP_PKEY(k)) == NULL || + (pk = es256_pk_new()) == NULL) + goto out; + + r = es256_pk_from_EVP_PKEY(pk, pkey); + consume(&r, sizeof(r)); +out: + es256_pk_free(&pk); + EVP_PKEY_free(pkey); +} + +/* + * Do a dummy conversion to exercise es384_pk_from_EVP_PKEY(). + */ +static void +es384_convert(const es384_pk_t *k) +{ + EVP_PKEY *pkey = NULL; + es384_pk_t *pk = NULL; + int r; + + if ((pkey = es384_pk_to_EVP_PKEY(k)) == NULL || + (pk = es384_pk_new()) == NULL) + goto out; + + r = es384_pk_from_EVP_PKEY(pk, pkey); + consume(&r, sizeof(r)); +out: + es384_pk_free(&pk); + EVP_PKEY_free(pkey); +} + +/* + * Do a dummy conversion to exercise rs256_pk_from_EVP_PKEY(). + */ +static void +rs256_convert(const rs256_pk_t *k) +{ + EVP_PKEY *pkey = NULL; + rs256_pk_t *pk = NULL; + int r; + + if ((pkey = rs256_pk_to_EVP_PKEY(k)) == NULL || + (pk = rs256_pk_new()) == NULL) + goto out; + + r = rs256_pk_from_EVP_PKEY(pk, pkey); + consume(&r, sizeof(r)); +out: + rs256_pk_free(&pk); + EVP_PKEY_free(pkey); +} + +/* + * Do a dummy conversion to exercise eddsa_pk_from_EVP_PKEY(). + */ +static void +eddsa_convert(const eddsa_pk_t *k) +{ + EVP_PKEY *pkey = NULL; + eddsa_pk_t *pk = NULL; + int r; + + if ((pkey = eddsa_pk_to_EVP_PKEY(k)) == NULL || + (pk = eddsa_pk_new()) == NULL) + goto out; + + r = eddsa_pk_from_EVP_PKEY(pk, pkey); + consume(&r, sizeof(r)); +out: + if (pk) + eddsa_pk_free(&pk); + if (pkey) + EVP_PKEY_free(pkey); +} + +void +test(const struct param *p) +{ + fido_assert_t *assert = NULL; + es256_pk_t *es256_pk = NULL; + es384_pk_t *es384_pk = NULL; + rs256_pk_t *rs256_pk = NULL; + eddsa_pk_t *eddsa_pk = NULL; + uint8_t flags; + uint32_t sigcount; + int cose_alg = 0; + void *pk; + + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + switch (p->type & 3) { + case 0: + cose_alg = COSE_ES256; + + if ((es256_pk = es256_pk_new()) == NULL) + return; + + es256_pk_from_ptr(es256_pk, p->es256.body, p->es256.len); + pk = es256_pk; + + es256_convert(pk); + + break; + case 1: + cose_alg = COSE_RS256; + + if ((rs256_pk = rs256_pk_new()) == NULL) + return; + + rs256_pk_from_ptr(rs256_pk, p->rs256.body, p->rs256.len); + pk = rs256_pk; + + rs256_convert(pk); + + break; + case 2: + cose_alg = COSE_ES384; + + if ((es384_pk = es384_pk_new()) == NULL) + return; + + /* XXX reuse p->es256 as es384 */ + es384_pk_from_ptr(es384_pk, p->es256.body, p->es256.len); + pk = es384_pk; + + es384_convert(pk); + + break; + default: + cose_alg = COSE_EDDSA; + + if ((eddsa_pk = eddsa_pk_new()) == NULL) + return; + + eddsa_pk_from_ptr(eddsa_pk, p->eddsa.body, p->eddsa.len); + pk = eddsa_pk; + + eddsa_convert(pk); + + break; + } + + if ((assert = fido_assert_new()) == NULL) + goto out; + + set_wire_data(p->wire_data.body, p->wire_data.len); + + get_assert(assert, p->opt, &p->cdh, p->rp_id, p->ext, p->up, p->uv, + p->pin, p->cred_count, &p->cred); + + /* XXX +1 on purpose */ + for (size_t i = 0; i <= fido_assert_count(assert); i++) { + verify_assert(cose_alg, + fido_assert_clientdata_hash_ptr(assert), + fido_assert_clientdata_hash_len(assert), + fido_assert_rp_id(assert), + fido_assert_authdata_ptr(assert, i), + fido_assert_authdata_len(assert, i), + fido_assert_sig_ptr(assert, i), + fido_assert_sig_len(assert, i), p->up, p->uv, p->ext, pk); + consume(fido_assert_authdata_raw_ptr(assert, i), + fido_assert_authdata_raw_len(assert, i)); + consume(fido_assert_id_ptr(assert, i), + fido_assert_id_len(assert, i)); + consume(fido_assert_user_id_ptr(assert, i), + fido_assert_user_id_len(assert, i)); + consume(fido_assert_hmac_secret_ptr(assert, i), + fido_assert_hmac_secret_len(assert, i)); + consume_str(fido_assert_user_icon(assert, i)); + consume_str(fido_assert_user_name(assert, i)); + consume_str(fido_assert_user_display_name(assert, i)); + consume(fido_assert_blob_ptr(assert, i), + fido_assert_blob_len(assert, i)); + consume(fido_assert_largeblob_key_ptr(assert, i), + fido_assert_largeblob_key_len(assert, i)); + flags = fido_assert_flags(assert, i); + consume(&flags, sizeof(flags)); + sigcount = fido_assert_sigcount(assert, i); + consume(&sigcount, sizeof(sigcount)); + } + +out: + es256_pk_free(&es256_pk); + es384_pk_free(&es384_pk); + rs256_pk_free(&rs256_pk); + eddsa_pk_free(&eddsa_pk); + + fido_assert_free(&assert); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_byte(&p->uv); + mutate_byte(&p->up); + mutate_byte(&p->opt); + mutate_byte(&p->type); + mutate_byte(&p->cred_count); + mutate_int(&p->ext); + mutate_blob(&p->rs256); + mutate_blob(&p->es256); + mutate_blob(&p->eddsa); + mutate_blob(&p->cred); + mutate_blob(&p->cdh); + mutate_string(p->rp_id); + mutate_string(p->pin); + } + + if (flags & MUTATE_WIREDATA) { + if (p->opt & 1) { + p->wire_data.len = sizeof(dummy_wire_data_u2f); + memcpy(&p->wire_data.body, &dummy_wire_data_u2f, + p->wire_data.len); + } else { + p->wire_data.len = sizeof(dummy_wire_data_fido); + memcpy(&p->wire_data.body, &dummy_wire_data_fido, + p->wire_data.len); + } + mutate_blob(&p->wire_data); + } +} diff --git a/fuzz/fuzz_attobj.c b/fuzz/fuzz_attobj.c new file mode 100644 index 0000000..4fddc0f --- /dev/null +++ b/fuzz/fuzz_attobj.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2024 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "wiredata_u2f.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +struct param { + int seed; + char rp_id[MAXSTR]; + struct blob cdh; + struct blob attobj; + uint8_t type; +}; + +static const uint8_t dummy_attestation_object[] = { + 0xa3, 0x63, 0x66, 0x6d, 0x74, 0x66, 0x70, 0x61, + 0x63, 0x6b, 0x65, 0x64, 0x67, 0x61, 0x74, 0x74, + 0x53, 0x74, 0x6d, 0x74, 0xa3, 0x63, 0x61, 0x6c, + 0x67, 0x26, 0x63, 0x73, 0x69, 0x67, 0x58, 0x46, + 0x30, 0x44, 0x02, 0x20, 0x54, 0x92, 0x28, 0x3b, + 0x83, 0x33, 0x47, 0x56, 0x68, 0x79, 0xb2, 0x0c, + 0x84, 0x80, 0xcc, 0x67, 0x27, 0x8b, 0xfa, 0x48, + 0x43, 0x0d, 0x3c, 0xb4, 0x02, 0x36, 0x87, 0x97, + 0x3e, 0xdf, 0x2f, 0x65, 0x02, 0x20, 0x1b, 0x56, + 0x17, 0x06, 0xe2, 0x26, 0x0f, 0x6a, 0xe9, 0xa9, + 0x70, 0x99, 0x62, 0xeb, 0x3a, 0x04, 0x1a, 0xc4, + 0xa7, 0x03, 0x28, 0x56, 0x7c, 0xed, 0x47, 0x08, + 0x68, 0x73, 0x6a, 0xb6, 0x89, 0x0d, 0x63, 0x78, + 0x35, 0x63, 0x81, 0x59, 0x02, 0xe6, 0x30, 0x82, + 0x02, 0xe2, 0x30, 0x81, 0xcb, 0x02, 0x01, 0x01, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, + 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x59, 0x75, 0x62, 0x69, + 0x63, 0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x54, + 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x34, 0x30, 0x35, 0x31, 0x35, + 0x31, 0x32, 0x35, 0x38, 0x35, 0x34, 0x5a, 0x17, + 0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x34, 0x31, + 0x32, 0x35, 0x38, 0x35, 0x34, 0x5a, 0x30, 0x1d, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x12, 0x59, 0x75, 0x62, 0x69, 0x63, + 0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x54, 0x65, + 0x73, 0x74, 0x20, 0x45, 0x45, 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, + 0xdb, 0x0a, 0xdb, 0xf5, 0x21, 0xc7, 0x5c, 0xce, + 0x63, 0xdc, 0xa6, 0xe1, 0xe8, 0x25, 0x06, 0x0d, + 0x94, 0xe6, 0x27, 0x54, 0x19, 0x4f, 0x9d, 0x24, + 0xaf, 0x26, 0x1a, 0xbe, 0xad, 0x99, 0x44, 0x1f, + 0x95, 0xa3, 0x71, 0x91, 0x0a, 0x3a, 0x20, 0xe7, + 0x3e, 0x91, 0x5e, 0x13, 0xe8, 0xbe, 0x38, 0x05, + 0x7a, 0xd5, 0x7a, 0xa3, 0x7e, 0x76, 0x90, 0x8f, + 0xaf, 0xe2, 0x8a, 0x94, 0xb6, 0x30, 0xeb, 0x9d, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, + 0x82, 0x02, 0x01, 0x00, 0x95, 0x40, 0x6b, 0x50, + 0x61, 0x7d, 0xad, 0x84, 0xa3, 0xb4, 0xeb, 0x88, + 0x0f, 0xe3, 0x30, 0x0f, 0x2d, 0xa2, 0x0a, 0x00, + 0xd9, 0x25, 0x04, 0xee, 0x72, 0xfa, 0x67, 0xdf, + 0x58, 0x51, 0x0f, 0x0b, 0x47, 0x02, 0x9c, 0x3e, + 0x41, 0x29, 0x4a, 0x93, 0xac, 0x29, 0x85, 0x89, + 0x2d, 0xa4, 0x7a, 0x81, 0x32, 0x28, 0x57, 0x71, + 0x01, 0xef, 0xa8, 0x42, 0x88, 0x16, 0x96, 0x37, + 0x91, 0xd5, 0xdf, 0xe0, 0x8f, 0xc9, 0x3c, 0x8d, + 0xb0, 0xcd, 0x89, 0x70, 0x82, 0xec, 0x79, 0xd3, + 0xc6, 0x78, 0x73, 0x29, 0x32, 0xe5, 0xab, 0x6c, + 0xbd, 0x56, 0x9f, 0xd5, 0x45, 0x91, 0xce, 0xc1, + 0xdd, 0x8d, 0x64, 0xdc, 0xe9, 0x9c, 0x1f, 0x5e, + 0x3c, 0xd2, 0xaf, 0x51, 0xa5, 0x82, 0x18, 0xaf, + 0xe0, 0x37, 0xe7, 0x32, 0x9e, 0x76, 0x05, 0x77, + 0x02, 0x7b, 0xe6, 0x24, 0xa0, 0x31, 0x56, 0x1b, + 0xfd, 0x19, 0xc5, 0x71, 0xd3, 0xf0, 0x9e, 0xc0, + 0x73, 0x05, 0x4e, 0xbc, 0x85, 0xb8, 0x53, 0x9e, + 0xef, 0xc5, 0xbc, 0x9c, 0x56, 0xa3, 0xba, 0xd9, + 0x27, 0x6a, 0xbb, 0xa9, 0x7a, 0x40, 0xd7, 0x47, + 0x8b, 0x55, 0x72, 0x6b, 0xe3, 0xfe, 0x28, 0x49, + 0x71, 0x24, 0xf4, 0x8f, 0xf4, 0x20, 0x81, 0xea, + 0x38, 0xff, 0x7c, 0x0a, 0x4f, 0xdf, 0x02, 0x82, + 0x39, 0x81, 0x82, 0x3b, 0xca, 0x09, 0xdd, 0xca, + 0xaa, 0x0f, 0x27, 0xf5, 0xa4, 0x83, 0x55, 0x6c, + 0x9a, 0x39, 0x9b, 0x15, 0x3a, 0x16, 0x63, 0xdc, + 0x5b, 0xf9, 0xac, 0x5b, 0xbc, 0xf7, 0x9f, 0xbe, + 0x0f, 0x8a, 0xa2, 0x3c, 0x31, 0x13, 0xa3, 0x32, + 0x48, 0xca, 0x58, 0x87, 0xf8, 0x7b, 0xa0, 0xa1, + 0x0a, 0x6a, 0x60, 0x96, 0x93, 0x5f, 0x5d, 0x26, + 0x9e, 0x63, 0x1d, 0x09, 0xae, 0x9a, 0x41, 0xe5, + 0xbd, 0x08, 0x47, 0xfe, 0xe5, 0x09, 0x9b, 0x20, + 0xfd, 0x12, 0xe2, 0xe6, 0x40, 0x7f, 0xba, 0x4a, + 0x61, 0x33, 0x66, 0x0d, 0x0e, 0x73, 0xdb, 0xb0, + 0xd5, 0xa2, 0x9a, 0x9a, 0x17, 0x0d, 0x34, 0x30, + 0x85, 0x6a, 0x42, 0x46, 0x9e, 0xff, 0x34, 0x8f, + 0x5f, 0x87, 0x6c, 0x35, 0xe7, 0xa8, 0x4d, 0x35, + 0xeb, 0xc1, 0x41, 0xaa, 0x8a, 0xd2, 0xda, 0x19, + 0xaa, 0x79, 0xa2, 0x5f, 0x35, 0x2c, 0xa0, 0xfd, + 0x25, 0xd3, 0xf7, 0x9d, 0x25, 0x18, 0x2d, 0xfa, + 0xb4, 0xbc, 0xbb, 0x07, 0x34, 0x3c, 0x8d, 0x81, + 0xbd, 0xf4, 0xe9, 0x37, 0xdb, 0x39, 0xe9, 0xd1, + 0x45, 0x5b, 0x20, 0x41, 0x2f, 0x2d, 0x27, 0x22, + 0xdc, 0x92, 0x74, 0x8a, 0x92, 0xd5, 0x83, 0xfd, + 0x09, 0xfb, 0x13, 0x9b, 0xe3, 0x39, 0x7a, 0x6b, + 0x5c, 0xfa, 0xe6, 0x76, 0x9e, 0xe0, 0xe4, 0xe3, + 0xef, 0xad, 0xbc, 0xfd, 0x42, 0x45, 0x9a, 0xd4, + 0x94, 0xd1, 0x7e, 0x8d, 0xa7, 0xd8, 0x05, 0xd5, + 0xd3, 0x62, 0xcf, 0x15, 0xcf, 0x94, 0x7d, 0x1f, + 0x5b, 0x58, 0x20, 0x44, 0x20, 0x90, 0x71, 0xbe, + 0x66, 0xe9, 0x9a, 0xab, 0x74, 0x32, 0x70, 0x53, + 0x1d, 0x69, 0xed, 0x87, 0x66, 0xf4, 0x09, 0x4f, + 0xca, 0x25, 0x30, 0xc2, 0x63, 0x79, 0x00, 0x3c, + 0xb1, 0x9b, 0x39, 0x3f, 0x00, 0xe0, 0xa8, 0x88, + 0xef, 0x7a, 0x51, 0x5b, 0xe7, 0xbd, 0x49, 0x64, + 0xda, 0x41, 0x7b, 0x24, 0xc3, 0x71, 0x22, 0xfd, + 0xd1, 0xd1, 0x20, 0xb3, 0x3f, 0x97, 0xd3, 0x97, + 0xb2, 0xaa, 0x18, 0x1c, 0x9e, 0x03, 0x77, 0x7b, + 0x5b, 0x7e, 0xf9, 0xa3, 0xa0, 0xd6, 0x20, 0x81, + 0x2c, 0x38, 0x8f, 0x9d, 0x25, 0xde, 0xe9, 0xc8, + 0xf5, 0xdd, 0x6a, 0x47, 0x9c, 0x65, 0x04, 0x5a, + 0x56, 0xe6, 0xc2, 0xeb, 0xf2, 0x02, 0x97, 0xe1, + 0xb9, 0xd8, 0xe1, 0x24, 0x76, 0x9f, 0x23, 0x62, + 0x39, 0x03, 0x4b, 0xc8, 0xf7, 0x34, 0x07, 0x49, + 0xd6, 0xe7, 0x4d, 0x9a, 0x68, 0x61, 0x75, 0x74, + 0x68, 0x44, 0x61, 0x74, 0x61, 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, 0x41, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa0, 0x11, 0xf3, + 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11, + 0x1f, 0x9e, 0xdc, 0x7d, 0x00, 0x40, 0x53, 0xfb, + 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47, + 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, 0xa8, 0xbf, + 0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, 0xe0, 0x0d, + 0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, 0x70, 0x85, + 0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, 0xef, 0x44, + 0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, 0x6e, 0x7b, + 0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, 0x34, 0xe3, + 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, 0xa5, 0x01, + 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, + 0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c, + 0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c, + 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5, + 0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6, + 0x22, 0x58, 0x20, 0x87, 0x5f, 0x90, 0xe6, 0xfd, + 0x71, 0x27, 0x9f, 0xeb, 0xe3, 0x03, 0x44, 0xbc, + 0x8d, 0x49, 0xc6, 0x1c, 0x31, 0x3b, 0x72, 0xae, + 0xd4, 0x53, 0xb1, 0xfe, 0x5d, 0xe1, 0x30, 0xfc, + 0x2b, 0x1e, 0xd2 +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 5 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->rp_id) < 0 || + unpack_blob(v[2], &p->cdh) < 0 || + unpack_blob(v[3], &p->attobj) < 0 || + unpack_byte(v[4], &p->type) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[5], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(17)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->rp_id)) == NULL || + (argv[2] = pack_blob(&p->cdh)) == NULL || + (argv[3] = pack_blob(&p->attobj)) == NULL || + (argv[4] = pack_byte(p->type)) == NULL) + goto fail; + + for (size_t i = 0; i < 5; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) == 0 || cbor_len > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 5; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + dummy.type = 1; + + strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id)); + + dummy.cdh.len = sizeof(dummy_cdh); + dummy.attobj.len = sizeof(dummy_attestation_object); + + memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len); + memcpy(&dummy.attobj.body, dummy_attestation_object, dummy.attobj.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_byte(&p->type); + p->attobj.len = sizeof(dummy_attestation_object); + memcpy(&p->attobj.body, &dummy_attestation_object, + p->attobj.len); + mutate_blob(&p->attobj); + } +} + +void +test(const struct param *p) +{ + fido_cred_t *cred = NULL; + int r, cose_alg; + + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + if ((cred = fido_cred_new()) == NULL) + return; + + switch (p->type & 3) { + case 0: + cose_alg = COSE_ES256; + break; + case 1: + cose_alg = COSE_RS256; + break; + case 2: + cose_alg = COSE_ES384; + break; + default: + cose_alg = COSE_EDDSA; + break; + } + + r = fido_cred_set_type(cred, cose_alg); + consume(&r, sizeof(r)); + r = fido_cred_set_rp(cred, p->rp_id, NULL); + consume(&r, sizeof(r)); + r = fido_cred_set_clientdata_hash(cred, p->cdh.body, p->cdh.len); + consume(&r, sizeof(r)); + r = fido_cred_set_attobj(cred, p->attobj.body, p->attobj.len); + consume(&r, sizeof(r)); + + consume_str(fido_cred_fmt(cred)); + consume(fido_cred_attstmt_ptr(cred), fido_cred_attstmt_len(cred)); + consume(fido_cred_authdata_ptr(cred), fido_cred_authdata_len(cred)); + r = fido_cred_verify(cred); + consume(&r, sizeof(r)); + + fido_cred_free(&cred); +} diff --git a/fuzz/fuzz_bio.c b/fuzz/fuzz_bio.c new file mode 100644 index 0000000..0c6b12c --- /dev/null +++ b/fuzz/fuzz_bio.c @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2019 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +/* Parameter set defining a FIDO2 credential management operation. */ +struct param { + char pin[MAXSTR]; + char name[MAXSTR]; + int seed; + struct blob id; + struct blob info_wire_data; + struct blob enroll_wire_data; + struct blob list_wire_data; + struct blob set_name_wire_data; + struct blob remove_wire_data; +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'getFingerprintSensorInfo' bio enrollment command. + */ +static const uint8_t dummy_info_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_BIO_INFO, +}; + +/* + * Collection of HID reports from an authenticator issued with FIDO2 + * 'enrollBegin' + 'enrollCaptureNextSample' bio enrollment commands. + */ +static const uint8_t dummy_enroll_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_BIO_ENROLL, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'enumerateEnrollments' bio enrollment command. + */ +static const uint8_t dummy_list_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_BIO_ENUM, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'setFriendlyName' bio enrollment command. + */ +static const uint8_t dummy_set_name_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_STATUS, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'removeEnrollment' bio enrollment command. + */ +static const uint8_t dummy_remove_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_STATUS, +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 9 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->pin) < 0 || + unpack_string(v[2], p->name) < 0 || + unpack_blob(v[3], &p->id) < 0 || + unpack_blob(v[4], &p->info_wire_data) < 0 || + unpack_blob(v[5], &p->enroll_wire_data) < 0 || + unpack_blob(v[6], &p->list_wire_data) < 0 || + unpack_blob(v[7], &p->set_name_wire_data) < 0 || + unpack_blob(v[8], &p->remove_wire_data) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[9], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(9)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->pin)) == NULL || + (argv[2] = pack_string(p->name)) == NULL || + (argv[3] = pack_blob(&p->id)) == NULL || + (argv[4] = pack_blob(&p->info_wire_data)) == NULL || + (argv[5] = pack_blob(&p->enroll_wire_data)) == NULL || + (argv[6] = pack_blob(&p->list_wire_data)) == NULL || + (argv[7] = pack_blob(&p->set_name_wire_data)) == NULL || + (argv[8] = pack_blob(&p->remove_wire_data)) == NULL) + goto fail; + + for (size_t i = 0; i < 9; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) == 0 || cbor_len > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 9; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); + strlcpy(dummy.name, dummy_name, sizeof(dummy.name)); + + dummy.info_wire_data.len = sizeof(dummy_info_wire_data); + dummy.enroll_wire_data.len = sizeof(dummy_enroll_wire_data); + dummy.list_wire_data.len = sizeof(dummy_list_wire_data); + dummy.set_name_wire_data.len = sizeof(dummy_set_name_wire_data); + dummy.remove_wire_data.len = sizeof(dummy_remove_wire_data); + dummy.id.len = sizeof(dummy_id); + + memcpy(&dummy.info_wire_data.body, &dummy_info_wire_data, + dummy.info_wire_data.len); + memcpy(&dummy.enroll_wire_data.body, &dummy_enroll_wire_data, + dummy.enroll_wire_data.len); + memcpy(&dummy.list_wire_data.body, &dummy_list_wire_data, + dummy.list_wire_data.len); + memcpy(&dummy.set_name_wire_data.body, &dummy_set_name_wire_data, + dummy.set_name_wire_data.len); + memcpy(&dummy.remove_wire_data.body, &dummy_remove_wire_data, + dummy.remove_wire_data.len); + memcpy(&dummy.id.body, &dummy_id, dummy.id.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static fido_dev_t * +prepare_dev(void) +{ + fido_dev_t *dev; + bool x; + + if ((dev = open_dev(0)) == NULL) + return NULL; + + x = fido_dev_is_fido2(dev); + consume(&x, sizeof(x)); + x = fido_dev_supports_pin(dev); + consume(&x, sizeof(x)); + x = fido_dev_has_pin(dev); + consume(&x, sizeof(x)); + x = fido_dev_supports_uv(dev); + consume(&x, sizeof(x)); + x = fido_dev_has_uv(dev); + consume(&x, sizeof(x)); + + return dev; +} + +static void +get_info(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_info_t *i = NULL; + uint8_t type; + uint8_t max_samples; + int r; + + set_wire_data(p->info_wire_data.body, p->info_wire_data.len); + + if ((dev = prepare_dev()) == NULL || (i = fido_bio_info_new()) == NULL) + goto done; + + r = fido_bio_dev_get_info(dev, i); + consume_str(fido_strerr(r)); + + type = fido_bio_info_type(i); + max_samples = fido_bio_info_max_samples(i); + consume(&type, sizeof(type)); + consume(&max_samples, sizeof(max_samples)); + +done: + if (dev) + fido_dev_close(dev); + + fido_dev_free(&dev); + fido_bio_info_free(&i); +} + +static void +consume_template(const fido_bio_template_t *t) +{ + consume_str(fido_bio_template_name(t)); + consume(fido_bio_template_id_ptr(t), fido_bio_template_id_len(t)); +} + +static void +consume_enroll(fido_bio_enroll_t *e) +{ + uint8_t last_status; + uint8_t remaining_samples; + + last_status = fido_bio_enroll_last_status(e); + remaining_samples = fido_bio_enroll_remaining_samples(e); + consume(&last_status, sizeof(last_status)); + consume(&remaining_samples, sizeof(remaining_samples)); +} + +static void +enroll(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_template_t *t = NULL; + fido_bio_enroll_t *e = NULL; + size_t cnt = 0; + + set_wire_data(p->enroll_wire_data.body, p->enroll_wire_data.len); + + if ((dev = prepare_dev()) == NULL || + (t = fido_bio_template_new()) == NULL || + (e = fido_bio_enroll_new()) == NULL) + goto done; + + fido_bio_dev_enroll_begin(dev, t, e, (uint32_t)p->seed, p->pin); + + consume_template(t); + consume_enroll(e); + + while (fido_bio_enroll_remaining_samples(e) > 0 && cnt++ < 5) { + fido_bio_dev_enroll_continue(dev, t, e, p->seed); + consume_template(t); + consume_enroll(e); + } + +done: + if (dev) + fido_dev_close(dev); + + fido_dev_free(&dev); + fido_bio_template_free(&t); + fido_bio_enroll_free(&e); +} + +static void +list(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_template_array_t *ta = NULL; + const fido_bio_template_t *t = NULL; + + set_wire_data(p->list_wire_data.body, p->list_wire_data.len); + + if ((dev = prepare_dev()) == NULL || + (ta = fido_bio_template_array_new()) == NULL) + goto done; + + fido_bio_dev_get_template_array(dev, ta, p->pin); + + /* +1 on purpose */ + for (size_t i = 0; i < fido_bio_template_array_count(ta) + 1; i++) + if ((t = fido_bio_template(ta, i)) != NULL) + consume_template(t); + +done: + if (dev) + fido_dev_close(dev); + + fido_dev_free(&dev); + fido_bio_template_array_free(&ta); +} + +static void +set_name(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_template_t *t = NULL; + + set_wire_data(p->set_name_wire_data.body, p->set_name_wire_data.len); + + if ((dev = prepare_dev()) == NULL || + (t = fido_bio_template_new()) == NULL) + goto done; + + fido_bio_template_set_name(t, p->name); + fido_bio_template_set_id(t, p->id.body, p->id.len); + consume_template(t); + + fido_bio_dev_set_template_name(dev, t, p->pin); + +done: + if (dev) + fido_dev_close(dev); + + fido_dev_free(&dev); + fido_bio_template_free(&t); +} + +static void +del(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_bio_template_t *t = NULL; + int r; + + set_wire_data(p->remove_wire_data.body, p->remove_wire_data.len); + + if ((dev = prepare_dev()) == NULL || + (t = fido_bio_template_new()) == NULL) + goto done; + + r = fido_bio_template_set_id(t, p->id.body, p->id.len); + consume_template(t); + consume_str(fido_strerr(r)); + + fido_bio_dev_enroll_remove(dev, t, p->pin); + +done: + if (dev) + fido_dev_close(dev); + + fido_dev_free(&dev); + fido_bio_template_free(&t); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + get_info(p); + enroll(p); + list(p); + set_name(p); + del(p); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_blob(&p->id); + mutate_string(p->pin); + mutate_string(p->name); + } + + if (flags & MUTATE_WIREDATA) { + mutate_blob(&p->info_wire_data); + mutate_blob(&p->enroll_wire_data); + mutate_blob(&p->list_wire_data); + mutate_blob(&p->set_name_wire_data); + mutate_blob(&p->remove_wire_data); + } +} diff --git a/fuzz/fuzz_cred.c b/fuzz/fuzz_cred.c new file mode 100644 index 0000000..f1fc928 --- /dev/null +++ b/fuzz/fuzz_cred.c @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "wiredata_u2f.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +/* Parameter set defining a FIDO2 make credential operation. */ +struct param { + char pin[MAXSTR]; + char rp_id[MAXSTR]; + char rp_name[MAXSTR]; + char user_icon[MAXSTR]; + char user_name[MAXSTR]; + char user_nick[MAXSTR]; + int ext; + int seed; + struct blob cdh; + struct blob excl_cred; + struct blob user_id; + struct blob wire_data; + uint8_t excl_count; + uint8_t rk; + uint8_t type; + uint8_t opt; + uint8_t uv; +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * make credential using the example parameters above. + */ +static const uint8_t dummy_wire_data_fido[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_CBOR_CRED, +}; + +/* + * Collection of HID reports from an authenticator issued with a U2F + * registration using the example parameters above. + */ +static const uint8_t dummy_wire_data_u2f[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_6985, + WIREDATA_CTAP_U2F_REGISTER, +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 17 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_byte(v[0], &p->rk) < 0 || + unpack_byte(v[1], &p->type) < 0 || + unpack_byte(v[2], &p->opt) < 0 || + unpack_byte(v[3], &p->uv) < 0 || + unpack_byte(v[4], &p->excl_count) < 0 || + unpack_int(v[5], &p->ext) < 0 || + unpack_int(v[6], &p->seed) < 0 || + unpack_string(v[7], p->pin) < 0 || + unpack_string(v[8], p->rp_id) < 0 || + unpack_string(v[9], p->rp_name) < 0 || + unpack_string(v[10], p->user_icon) < 0 || + unpack_string(v[11], p->user_name) < 0 || + unpack_string(v[12], p->user_nick) < 0 || + unpack_blob(v[13], &p->cdh) < 0 || + unpack_blob(v[14], &p->user_id) < 0 || + unpack_blob(v[15], &p->wire_data) < 0 || + unpack_blob(v[16], &p->excl_cred) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[17], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(17)) == NULL || + (argv[0] = pack_byte(p->rk)) == NULL || + (argv[1] = pack_byte(p->type)) == NULL || + (argv[2] = pack_byte(p->opt)) == NULL || + (argv[3] = pack_byte(p->uv)) == NULL || + (argv[4] = pack_byte(p->excl_count)) == NULL || + (argv[5] = pack_int(p->ext)) == NULL || + (argv[6] = pack_int(p->seed)) == NULL || + (argv[7] = pack_string(p->pin)) == NULL || + (argv[8] = pack_string(p->rp_id)) == NULL || + (argv[9] = pack_string(p->rp_name)) == NULL || + (argv[10] = pack_string(p->user_icon)) == NULL || + (argv[11] = pack_string(p->user_name)) == NULL || + (argv[12] = pack_string(p->user_nick)) == NULL || + (argv[13] = pack_blob(&p->cdh)) == NULL || + (argv[14] = pack_blob(&p->user_id)) == NULL || + (argv[15] = pack_blob(&p->wire_data)) == NULL || + (argv[16] = pack_blob(&p->excl_cred)) == NULL) + goto fail; + + for (size_t i = 0; i < 17; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) == 0 || cbor_len > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 17; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + dummy.type = 1; + dummy.ext = FIDO_EXT_HMAC_SECRET; + + strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); + strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id)); + strlcpy(dummy.rp_name, dummy_rp_name, sizeof(dummy.rp_name)); + strlcpy(dummy.user_icon, dummy_user_icon, sizeof(dummy.user_icon)); + strlcpy(dummy.user_name, dummy_user_name, sizeof(dummy.user_name)); + strlcpy(dummy.user_nick, dummy_user_nick, sizeof(dummy.user_nick)); + + dummy.cdh.len = sizeof(dummy_cdh); + dummy.user_id.len = sizeof(dummy_user_id); + dummy.wire_data.len = sizeof(dummy_wire_data_fido); + + memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len); + memcpy(&dummy.user_id.body, &dummy_user_id, dummy.user_id.len); + memcpy(&dummy.wire_data.body, &dummy_wire_data_fido, + dummy.wire_data.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static void +make_cred(fido_cred_t *cred, uint8_t opt, int type, const struct blob *cdh, + const char *rp_id, const char *rp_name, const struct blob *user_id, + const char *user_name, const char *user_nick, const char *user_icon, + int ext, uint8_t rk, uint8_t uv, const char *pin, uint8_t excl_count, + const struct blob *excl_cred) +{ + fido_dev_t *dev; + + if ((dev = open_dev(opt & 2)) == NULL) + return; + if (opt & 1) + fido_dev_force_u2f(dev); + + for (uint8_t i = 0; i < excl_count; i++) + fido_cred_exclude(cred, excl_cred->body, excl_cred->len); + + fido_cred_set_type(cred, type); + fido_cred_set_clientdata_hash(cred, cdh->body, cdh->len); + fido_cred_set_rp(cred, rp_id, rp_name); + fido_cred_set_user(cred, user_id->body, user_id->len, user_name, + user_nick, user_icon); + + if (ext & FIDO_EXT_HMAC_SECRET) + fido_cred_set_extensions(cred, FIDO_EXT_HMAC_SECRET); + if (ext & FIDO_EXT_CRED_BLOB) + fido_cred_set_blob(cred, user_id->body, user_id->len); + if (ext & FIDO_EXT_LARGEBLOB_KEY) + fido_cred_set_extensions(cred, FIDO_EXT_LARGEBLOB_KEY); + if (ext & FIDO_EXT_MINPINLEN) + fido_cred_set_pin_minlen(cred, strlen(pin)); + + if (rk & 1) + fido_cred_set_rk(cred, FIDO_OPT_TRUE); + if (uv & 1) + fido_cred_set_uv(cred, FIDO_OPT_TRUE); + if (user_id->len) + fido_cred_set_prot(cred, user_id->body[0] & 0x03); + + /* repeat memory operations to trigger reallocation paths */ + fido_cred_set_type(cred, type); + fido_cred_set_clientdata_hash(cred, cdh->body, cdh->len); + fido_cred_set_rp(cred, rp_id, rp_name); + fido_cred_set_user(cred, user_id->body, user_id->len, user_name, + user_nick, user_icon); + + if (strlen(pin) == 0) + pin = NULL; + + fido_dev_make_cred(dev, cred, (opt & 1) ? NULL : pin); + + fido_dev_cancel(dev); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len, + const char *rp_id, const char *rp_name, const unsigned char *authdata_ptr, + size_t authdata_len, const unsigned char *authdata_raw_ptr, + size_t authdata_raw_len, int ext, uint8_t rk, uint8_t uv, + const unsigned char *x5c_ptr, size_t x5c_len, const unsigned char *sig_ptr, + size_t sig_len, const unsigned char *attstmt_ptr, size_t attstmt_len, + const char *fmt, int prot, size_t minpinlen) +{ + fido_cred_t *cred; + uint8_t flags; + uint32_t sigcount; + int r; + + if ((cred = fido_cred_new()) == NULL) + return; + + fido_cred_set_type(cred, type); + fido_cred_set_clientdata_hash(cred, cdh_ptr, cdh_len); + fido_cred_set_rp(cred, rp_id, rp_name); + consume(authdata_ptr, authdata_len); + consume(authdata_raw_ptr, authdata_raw_len); + consume(x5c_ptr, x5c_len); + consume(sig_ptr, sig_len); + consume(attstmt_ptr, attstmt_len); + if (fido_cred_set_authdata(cred, authdata_ptr, authdata_len) != FIDO_OK) + fido_cred_set_authdata_raw(cred, authdata_raw_ptr, + authdata_raw_len); + fido_cred_set_extensions(cred, ext); + if (fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len) != FIDO_OK) { + fido_cred_set_x509(cred, x5c_ptr, x5c_len); + fido_cred_set_sig(cred, sig_ptr, sig_len); + } + fido_cred_set_prot(cred, prot); + fido_cred_set_pin_minlen(cred, minpinlen); + + if (rk & 1) + fido_cred_set_rk(cred, FIDO_OPT_TRUE); + if (uv & 1) + fido_cred_set_uv(cred, FIDO_OPT_TRUE); + if (fmt) + fido_cred_set_fmt(cred, fmt); + + /* XXX +1 on purpose */ + for (size_t i = 0; i < fido_cred_x5c_list_count(cred) + 1; i++) + consume(fido_cred_x5c_list_ptr(cred, i), + fido_cred_x5c_list_len(cred, i)); + + /* repeat memory operations to trigger reallocation paths */ + if (fido_cred_set_authdata(cred, authdata_ptr, authdata_len) != FIDO_OK) + fido_cred_set_authdata_raw(cred, authdata_raw_ptr, + authdata_raw_len); + if (fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len) != FIDO_OK) { + fido_cred_set_x509(cred, x5c_ptr, x5c_len); + fido_cred_set_sig(cred, sig_ptr, sig_len); + } + fido_cred_set_x509(cred, x5c_ptr, x5c_len); + fido_cred_set_sig(cred, sig_ptr, sig_len); + + r = fido_cred_verify(cred); + consume(&r, sizeof(r)); + r = fido_cred_verify_self(cred); + consume(&r, sizeof(r)); + + consume(fido_cred_pubkey_ptr(cred), fido_cred_pubkey_len(cred)); + consume(fido_cred_id_ptr(cred), fido_cred_id_len(cred)); + consume(fido_cred_aaguid_ptr(cred), fido_cred_aaguid_len(cred)); + consume(fido_cred_user_id_ptr(cred), fido_cred_user_id_len(cred)); + consume_str(fido_cred_user_name(cred)); + consume_str(fido_cred_display_name(cred)); + consume(fido_cred_largeblob_key_ptr(cred), + fido_cred_largeblob_key_len(cred)); + + flags = fido_cred_flags(cred); + consume(&flags, sizeof(flags)); + sigcount = fido_cred_sigcount(cred); + consume(&sigcount, sizeof(sigcount)); + type = fido_cred_type(cred); + consume(&type, sizeof(type)); + minpinlen = fido_cred_pin_minlen(cred); + consume(&minpinlen, sizeof(minpinlen)); + + fido_cred_free(&cred); +} + +static void +test_cred(const struct param *p) +{ + fido_cred_t *cred = NULL; + int cose_alg = 0; + + if ((cred = fido_cred_new()) == NULL) + return; + + switch (p->type & 3) { + case 0: + cose_alg = COSE_ES256; + break; + case 1: + cose_alg = COSE_RS256; + break; + case 2: + cose_alg = COSE_ES384; + break; + default: + cose_alg = COSE_EDDSA; + break; + } + + set_wire_data(p->wire_data.body, p->wire_data.len); + + make_cred(cred, p->opt, cose_alg, &p->cdh, p->rp_id, p->rp_name, + &p->user_id, p->user_name, p->user_nick, p->user_icon, p->ext, + p->rk, p->uv, p->pin, p->excl_count, &p->excl_cred); + + verify_cred(cose_alg, + fido_cred_clientdata_hash_ptr(cred), + fido_cred_clientdata_hash_len(cred), fido_cred_rp_id(cred), + fido_cred_rp_name(cred), fido_cred_authdata_ptr(cred), + fido_cred_authdata_len(cred), fido_cred_authdata_raw_ptr(cred), + fido_cred_authdata_raw_len(cred), p->ext, p->rk, p->uv, + fido_cred_x5c_ptr(cred), fido_cred_x5c_len(cred), + fido_cred_sig_ptr(cred), fido_cred_sig_len(cred), + fido_cred_attstmt_ptr(cred), fido_cred_attstmt_len(cred), + fido_cred_fmt(cred), fido_cred_prot(cred), + fido_cred_pin_minlen(cred)); + + fido_cred_free(&cred); +} + +static void +test_touch(const struct param *p) +{ + fido_dev_t *dev; + int r; + int touched; + + set_wire_data(p->wire_data.body, p->wire_data.len); + + if ((dev = open_dev(p->opt & 2)) == NULL) + return; + if (p->opt & 1) + fido_dev_force_u2f(dev); + + r = fido_dev_get_touch_begin(dev); + consume_str(fido_strerr(r)); + r = fido_dev_get_touch_status(dev, &touched, -1); + consume_str(fido_strerr(r)); + consume(&touched, sizeof(touched)); + + fido_dev_cancel(dev); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +test_misc(const struct param *p) +{ + fido_cred_t *cred = NULL; + + if ((cred = fido_cred_new()) == NULL) + return; + + /* reuse user id as credential id */ + fido_cred_set_id(cred, p->user_id.body, p->user_id.len); + consume(fido_cred_id_ptr(cred), fido_cred_id_len(cred)); + fido_cred_free(&cred); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + test_cred(p); + test_touch(p); + test_misc(p); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_byte(&p->rk); + mutate_byte(&p->type); + mutate_byte(&p->opt); + mutate_byte(&p->uv); + mutate_byte(&p->excl_count); + mutate_int(&p->ext); + mutate_blob(&p->cdh); + mutate_blob(&p->user_id); + mutate_blob(&p->excl_cred); + mutate_string(p->pin); + mutate_string(p->user_icon); + mutate_string(p->user_name); + mutate_string(p->user_nick); + mutate_string(p->rp_id); + mutate_string(p->rp_name); + } + + if (flags & MUTATE_WIREDATA) { + if (p->opt & 1) { + p->wire_data.len = sizeof(dummy_wire_data_u2f); + memcpy(&p->wire_data.body, &dummy_wire_data_u2f, + p->wire_data.len); + } else { + p->wire_data.len = sizeof(dummy_wire_data_fido); + memcpy(&p->wire_data.body, &dummy_wire_data_fido, + p->wire_data.len); + } + mutate_blob(&p->wire_data); + } +} diff --git a/fuzz/fuzz_credman.c b/fuzz/fuzz_credman.c new file mode 100644 index 0000000..ef21475 --- /dev/null +++ b/fuzz/fuzz_credman.c @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2019-2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +/* Parameter set defining a FIDO2 credential management operation. */ +struct param { + char pin[MAXSTR]; + char rp_id[MAXSTR]; + int seed; + struct blob cred_id; + struct blob del_wire_data; + struct blob meta_wire_data; + struct blob rk_wire_data; + struct blob rp_wire_data; +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'getCredsMetadata' credential management command. + */ +static const uint8_t dummy_meta_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_CREDMAN_META, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'enumerateRPsBegin' credential management command. + */ +static const uint8_t dummy_rp_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_CREDMAN_RPLIST, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'enumerateCredentialsBegin' credential management command. + */ +static const uint8_t dummy_rk_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_CREDMAN_RKLIST, +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'deleteCredential' credential management command. + */ +static const uint8_t dummy_del_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_STATUS, +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 8 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->pin) < 0 || + unpack_string(v[2], p->rp_id) < 0 || + unpack_blob(v[3], &p->cred_id) < 0 || + unpack_blob(v[4], &p->meta_wire_data) < 0 || + unpack_blob(v[5], &p->rp_wire_data) < 0 || + unpack_blob(v[6], &p->rk_wire_data) < 0 || + unpack_blob(v[7], &p->del_wire_data) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[8], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(8)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->pin)) == NULL || + (argv[2] = pack_string(p->rp_id)) == NULL || + (argv[3] = pack_blob(&p->cred_id)) == NULL || + (argv[4] = pack_blob(&p->meta_wire_data)) == NULL || + (argv[5] = pack_blob(&p->rp_wire_data)) == NULL || + (argv[6] = pack_blob(&p->rk_wire_data)) == NULL || + (argv[7] = pack_blob(&p->del_wire_data)) == NULL) + goto fail; + + for (size_t i = 0; i < 8; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) == 0 || cbor_len > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 8; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); + strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id)); + + dummy.meta_wire_data.len = sizeof(dummy_meta_wire_data); + dummy.rp_wire_data.len = sizeof(dummy_rp_wire_data); + dummy.rk_wire_data.len = sizeof(dummy_rk_wire_data); + dummy.del_wire_data.len = sizeof(dummy_del_wire_data); + dummy.cred_id.len = sizeof(dummy_cred_id); + + memcpy(&dummy.meta_wire_data.body, &dummy_meta_wire_data, + dummy.meta_wire_data.len); + memcpy(&dummy.rp_wire_data.body, &dummy_rp_wire_data, + dummy.rp_wire_data.len); + memcpy(&dummy.rk_wire_data.body, &dummy_rk_wire_data, + dummy.rk_wire_data.len); + memcpy(&dummy.del_wire_data.body, &dummy_del_wire_data, + dummy.del_wire_data.len); + memcpy(&dummy.cred_id.body, &dummy_cred_id, dummy.cred_id.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static fido_dev_t * +prepare_dev(void) +{ + fido_dev_t *dev; + bool x; + + if ((dev = open_dev(0)) == NULL) + return NULL; + + x = fido_dev_is_fido2(dev); + consume(&x, sizeof(x)); + x = fido_dev_supports_cred_prot(dev); + consume(&x, sizeof(x)); + x = fido_dev_supports_credman(dev); + consume(&x, sizeof(x)); + + return dev; +} + +static void +get_metadata(const struct param *p) +{ + fido_dev_t *dev; + fido_credman_metadata_t *metadata; + uint64_t existing; + uint64_t remaining; + + set_wire_data(p->meta_wire_data.body, p->meta_wire_data.len); + + if ((dev = prepare_dev()) == NULL) + return; + + if ((metadata = fido_credman_metadata_new()) == NULL) { + fido_dev_close(dev); + fido_dev_free(&dev); + return; + } + + fido_credman_get_dev_metadata(dev, metadata, p->pin); + + existing = fido_credman_rk_existing(metadata); + remaining = fido_credman_rk_remaining(metadata); + consume(&existing, sizeof(existing)); + consume(&remaining, sizeof(remaining)); + + fido_credman_metadata_free(&metadata); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +get_rp_list(const struct param *p) +{ + fido_dev_t *dev; + fido_credman_rp_t *rp; + + set_wire_data(p->rp_wire_data.body, p->rp_wire_data.len); + + if ((dev = prepare_dev()) == NULL) + return; + + if ((rp = fido_credman_rp_new()) == NULL) { + fido_dev_close(dev); + fido_dev_free(&dev); + return; + } + + fido_credman_get_dev_rp(dev, rp, p->pin); + + /* +1 on purpose */ + for (size_t i = 0; i < fido_credman_rp_count(rp) + 1; i++) { + consume(fido_credman_rp_id_hash_ptr(rp, i), + fido_credman_rp_id_hash_len(rp, i)); + consume_str(fido_credman_rp_id(rp, i)); + consume_str(fido_credman_rp_name(rp, i)); + } + + fido_credman_rp_free(&rp); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +get_rk_list(const struct param *p) +{ + fido_dev_t *dev; + fido_credman_rk_t *rk; + const fido_cred_t *cred; + int val; + + set_wire_data(p->rk_wire_data.body, p->rk_wire_data.len); + + if ((dev = prepare_dev()) == NULL) + return; + + if ((rk = fido_credman_rk_new()) == NULL) { + fido_dev_close(dev); + fido_dev_free(&dev); + return; + } + + fido_credman_get_dev_rk(dev, p->rp_id, rk, p->pin); + + /* +1 on purpose */ + for (size_t i = 0; i < fido_credman_rk_count(rk) + 1; i++) { + if ((cred = fido_credman_rk(rk, i)) == NULL) { + assert(i >= fido_credman_rk_count(rk)); + continue; + } + val = fido_cred_type(cred); + consume(&val, sizeof(val)); + consume(fido_cred_id_ptr(cred), fido_cred_id_len(cred)); + consume(fido_cred_pubkey_ptr(cred), fido_cred_pubkey_len(cred)); + consume(fido_cred_user_id_ptr(cred), + fido_cred_user_id_len(cred)); + consume_str(fido_cred_user_name(cred)); + consume_str(fido_cred_display_name(cred)); + val = fido_cred_prot(cred); + consume(&val, sizeof(val)); + } + + fido_credman_rk_free(&rk); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +del_rk(const struct param *p) +{ + fido_dev_t *dev; + + set_wire_data(p->del_wire_data.body, p->del_wire_data.len); + + if ((dev = prepare_dev()) == NULL) + return; + + fido_credman_del_dev_rk(dev, p->cred_id.body, p->cred_id.len, p->pin); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +set_rk(const struct param *p) +{ + fido_dev_t *dev = NULL; + fido_cred_t *cred = NULL; + const char *pin = p->pin; + int r0, r1, r2; + + set_wire_data(p->del_wire_data.body, p->del_wire_data.len); + + if ((dev = prepare_dev()) == NULL) + return; + if ((cred = fido_cred_new()) == NULL) + goto out; + r0 = fido_cred_set_id(cred, p->cred_id.body, p->cred_id.len); + r1 = fido_cred_set_user(cred, p->cred_id.body, p->cred_id.len, p->rp_id, + NULL, NULL); + if (strlen(pin) == 0) + pin = NULL; + r2 = fido_credman_set_dev_rk(dev, cred, pin); + consume(&r0, sizeof(r0)); + consume(&r1, sizeof(r1)); + consume(&r2, sizeof(r2)); +out: + fido_dev_close(dev); + fido_dev_free(&dev); + fido_cred_free(&cred); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + get_metadata(p); + get_rp_list(p); + get_rk_list(p); + del_rk(p); + set_rk(p); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_blob(&p->cred_id); + mutate_string(p->pin); + mutate_string(p->rp_id); + } + + if (flags & MUTATE_WIREDATA) { + mutate_blob(&p->meta_wire_data); + mutate_blob(&p->rp_wire_data); + mutate_blob(&p->rk_wire_data); + mutate_blob(&p->del_wire_data); + } +} diff --git a/fuzz/fuzz_hid.c b/fuzz/fuzz_hid.c new file mode 100644 index 0000000..daaadad --- /dev/null +++ b/fuzz/fuzz_hid.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2020-2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include "../openbsd-compat/openbsd-compat.h" +#include "mutator_aux.h" +#include "dummy.h" + +extern int fido_hid_get_usage(const uint8_t *, size_t, uint32_t *); +extern int fido_hid_get_report_len(const uint8_t *, size_t, size_t *, size_t *); +extern void set_udev_parameters(const char *, const struct blob *); + +struct param { + int seed; + char uevent[MAXSTR]; + struct blob report_descriptor; + struct blob netlink_wiredata; +}; + +/* + * Sample HID report descriptor from the FIDO HID interface of a YubiKey 5. + */ +static const uint8_t dummy_report_descriptor[] = { + 0x06, 0xd0, 0xf1, 0x09, 0x01, 0xa1, 0x01, 0x09, + 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, + 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, + 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x40, 0x91, + 0x02, 0xc0 +}; + +/* + * Sample uevent file from a Yubico Security Key. + */ +static const char dummy_uevent[] = + "DRIVER=hid-generic\n" + "HID_ID=0003:00001050:00000120\n" + "HID_NAME=Yubico Security Key by Yubico\n" + "HID_PHYS=usb-0000:00:14.0-3/input0\n" + "HID_UNIQ=\n" + "MODALIAS=hid:b0003g0001v00001050p00000120\n"; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 4 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->uevent) < 0 || + unpack_blob(v[2], &p->report_descriptor) < 0 || + unpack_blob(v[3], &p->netlink_wiredata) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[4], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(4)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->uevent)) == NULL || + (argv[2] = pack_blob(&p->report_descriptor)) == NULL || + (argv[3] = pack_blob(&p->netlink_wiredata)) == NULL) + goto fail; + + for (size_t i = 0; i < 4; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) == 0 || cbor_len > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 4; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + dummy.report_descriptor.len = sizeof(dummy_report_descriptor); + strlcpy(dummy.uevent, dummy_uevent, sizeof(dummy.uevent)); + memcpy(&dummy.report_descriptor.body, &dummy_report_descriptor, + dummy.report_descriptor.len); + dummy.netlink_wiredata.len = sizeof(dummy_netlink_wiredata); + memcpy(&dummy.netlink_wiredata.body, &dummy_netlink_wiredata, + dummy.netlink_wiredata.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + if (blob_len > len) + blob_len = len; + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static void +get_usage(const struct param *p) +{ + uint32_t usage_page = 0; + + fido_hid_get_usage(p->report_descriptor.body, p->report_descriptor.len, + &usage_page); + consume(&usage_page, sizeof(usage_page)); +} + +static void +get_report_len(const struct param *p) +{ + size_t report_in_len = 0; + size_t report_out_len = 0; + + fido_hid_get_report_len(p->report_descriptor.body, + p->report_descriptor.len, &report_in_len, &report_out_len); + consume(&report_in_len, sizeof(report_in_len)); + consume(&report_out_len, sizeof(report_out_len)); +} + +static void +manifest(const struct param *p) +{ + size_t ndevs, nfound; + fido_dev_info_t *devlist = NULL, *devlist_set = NULL; + int16_t vendor_id, product_id; + fido_dev_io_t io; + fido_dev_transport_t t; + + memset(&io, 0, sizeof(io)); + memset(&t, 0, sizeof(t)); + set_netlink_io_functions(fd_read, fd_write); + set_wire_data(p->netlink_wiredata.body, p->netlink_wiredata.len); + set_udev_parameters(p->uevent, &p->report_descriptor); + + ndevs = uniform_random(64); + if ((devlist = fido_dev_info_new(ndevs)) == NULL || + (devlist_set = fido_dev_info_new(1)) == NULL || + fido_dev_info_manifest(devlist, ndevs, &nfound) != FIDO_OK) + goto out; + for (size_t i = 0; i < nfound; i++) { + const fido_dev_info_t *di = fido_dev_info_ptr(devlist, i); + consume_str(fido_dev_info_path(di)); + consume_str(fido_dev_info_manufacturer_string(di)); + consume_str(fido_dev_info_product_string(di)); + vendor_id = fido_dev_info_vendor(di); + product_id = fido_dev_info_product(di); + consume(&vendor_id, sizeof(vendor_id)); + consume(&product_id, sizeof(product_id)); + fido_dev_info_set(devlist_set, 0, fido_dev_info_path(di), + fido_dev_info_manufacturer_string(di), + fido_dev_info_product_string(di), &io, &t); + } +out: + fido_dev_info_free(&devlist, ndevs); + fido_dev_info_free(&devlist_set, 1); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + get_usage(p); + get_report_len(p); + manifest(p); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_blob(&p->report_descriptor); + mutate_string(p->uevent); + } + + if (flags & MUTATE_WIREDATA) + mutate_blob(&p->netlink_wiredata); +} diff --git a/fuzz/fuzz_largeblob.c b/fuzz/fuzz_largeblob.c new file mode 100644 index 0000000..6cdc0c0 --- /dev/null +++ b/fuzz/fuzz_largeblob.c @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2020 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +/* Parameter set defining a FIDO2 "large blob" operation. */ +struct param { + char pin[MAXSTR]; + int seed; + struct blob key; + struct blob get_wiredata; + struct blob set_wiredata; +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'authenticatorLargeBlobs' 'get' command. + */ +static const uint8_t dummy_get_wiredata[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY +}; + +/* + * Collection of HID reports from an authenticator issued with a FIDO2 + * 'authenticatorLargeBlobs' 'set' command. + */ +static const uint8_t dummy_set_wiredata[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_PINTOKEN, + WIREDATA_CTAP_CBOR_STATUS +}; + +/* + * XXX this needs to match the encrypted blob embedded in + * WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY. + */ +static const uint8_t dummy_key[] = { + 0xa9, 0x1b, 0xc4, 0xdd, 0xfc, 0x9a, 0x93, 0x79, + 0x75, 0xba, 0xf7, 0x7f, 0x4d, 0x57, 0xfc, 0xa6, + 0xe1, 0xf8, 0x06, 0x43, 0x23, 0x99, 0x51, 0x32, + 0xce, 0x6e, 0x19, 0x84, 0x50, 0x13, 0x2d, 0x7b +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 5 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->pin) < 0 || + unpack_blob(v[2], &p->key) < 0 || + unpack_blob(v[3], &p->get_wiredata) < 0 || + unpack_blob(v[4], &p->set_wiredata) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[5], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(5)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->pin)) == NULL || + (argv[2] = pack_blob(&p->key)) == NULL || + (argv[3] = pack_blob(&p->get_wiredata)) == NULL || + (argv[4] = pack_blob(&p->set_wiredata)) == NULL) + goto fail; + + for (size_t i = 0; i < 5; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) == 0 || cbor_len > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 5; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); + + dummy.get_wiredata.len = sizeof(dummy_get_wiredata); + dummy.set_wiredata.len = sizeof(dummy_set_wiredata); + dummy.key.len = sizeof(dummy_key); + + memcpy(&dummy.get_wiredata.body, &dummy_get_wiredata, + dummy.get_wiredata.len); + memcpy(&dummy.set_wiredata.body, &dummy_set_wiredata, + dummy.set_wiredata.len); + memcpy(&dummy.key.body, &dummy_key, dummy.key.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static fido_dev_t * +prepare_dev(void) +{ + fido_dev_t *dev; + + if ((dev = open_dev(0)) == NULL) + return NULL; + + return dev; +} + +static void +get_blob(const struct param *p, int array) +{ + fido_dev_t *dev; + u_char *ptr = NULL; + size_t len = 0; + + set_wire_data(p->get_wiredata.body, p->get_wiredata.len); + + if ((dev = prepare_dev()) == NULL) + return; + + if (array) + fido_dev_largeblob_get_array(dev, &ptr, &len); + else + fido_dev_largeblob_get(dev, p->key.body, p->key.len, &ptr, &len); + consume(ptr, len); + free(ptr); + + fido_dev_close(dev); + fido_dev_free(&dev); +} + + +static void +set_blob(const struct param *p, int op) +{ + fido_dev_t *dev; + const char *pin; + + set_wire_data(p->set_wiredata.body, p->set_wiredata.len); + + if ((dev = prepare_dev()) == NULL) + return; + pin = p->pin; + if (strlen(pin) == 0) + pin = NULL; + + switch (op) { + case 0: + fido_dev_largeblob_remove(dev, p->key.body, p->key.len, pin); + break; + case 1: + /* XXX reuse p->get_wiredata as the blob to be set */ + fido_dev_largeblob_set(dev, p->key.body, p->key.len, + p->get_wiredata.body, p->get_wiredata.len, pin); + break; + case 2: + /* XXX reuse p->get_wiredata as the body of the cbor array */ + fido_dev_largeblob_set_array(dev, p->get_wiredata.body, + p->get_wiredata.len, pin); + } + + fido_dev_close(dev); + fido_dev_free(&dev); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + get_blob(p, 0); + get_blob(p, 1); + set_blob(p, 0); + set_blob(p, 1); + set_blob(p, 2); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_blob(&p->key); + mutate_string(p->pin); + } + + if (flags & MUTATE_WIREDATA) { + mutate_blob(&p->get_wiredata); + mutate_blob(&p->set_wiredata); + } +} diff --git a/fuzz/fuzz_mgmt.c b/fuzz/fuzz_mgmt.c new file mode 100644 index 0000000..cbc313d --- /dev/null +++ b/fuzz/fuzz_mgmt.c @@ -0,0 +1,528 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "dummy.h" + +#include "../openbsd-compat/openbsd-compat.h" + +#define MAXRPID 64 + +struct param { + char pin1[MAXSTR]; + char pin2[MAXSTR]; + struct blob reset_wire_data; + struct blob info_wire_data; + struct blob set_pin_wire_data; + struct blob change_pin_wire_data; + struct blob retry_wire_data; + struct blob config_wire_data; + int seed; +}; + +static const uint8_t dummy_reset_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_CBOR_STATUS, +}; + +static const uint8_t dummy_info_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_INFO, +}; + +static const uint8_t dummy_set_pin_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_STATUS, +}; + +static const uint8_t dummy_change_pin_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_STATUS, +}; + +static const uint8_t dummy_retry_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_RETRIES, +}; + +static const uint8_t dummy_config_wire_data[] = { + WIREDATA_CTAP_INIT, + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_STATUS, +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 9 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->pin1) < 0 || + unpack_string(v[2], p->pin2) < 0 || + unpack_blob(v[3], &p->reset_wire_data) < 0 || + unpack_blob(v[4], &p->info_wire_data) < 0 || + unpack_blob(v[5], &p->set_pin_wire_data) < 0 || + unpack_blob(v[6], &p->change_pin_wire_data) < 0 || + unpack_blob(v[7], &p->retry_wire_data) < 0 || + unpack_blob(v[8], &p->config_wire_data) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[9], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(9)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->pin1)) == NULL || + (argv[2] = pack_string(p->pin2)) == NULL || + (argv[3] = pack_blob(&p->reset_wire_data)) == NULL || + (argv[4] = pack_blob(&p->info_wire_data)) == NULL || + (argv[5] = pack_blob(&p->set_pin_wire_data)) == NULL || + (argv[6] = pack_blob(&p->change_pin_wire_data)) == NULL || + (argv[7] = pack_blob(&p->retry_wire_data)) == NULL || + (argv[8] = pack_blob(&p->config_wire_data)) == NULL) + goto fail; + + for (size_t i = 0; i < 9; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) == 0 || cbor_len > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 9; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + strlcpy(dummy.pin1, dummy_pin1, sizeof(dummy.pin1)); + strlcpy(dummy.pin2, dummy_pin2, sizeof(dummy.pin2)); + + dummy.reset_wire_data.len = sizeof(dummy_reset_wire_data); + dummy.info_wire_data.len = sizeof(dummy_info_wire_data); + dummy.set_pin_wire_data.len = sizeof(dummy_set_pin_wire_data); + dummy.change_pin_wire_data.len = sizeof(dummy_change_pin_wire_data); + dummy.retry_wire_data.len = sizeof(dummy_retry_wire_data); + dummy.config_wire_data.len = sizeof(dummy_config_wire_data); + + memcpy(&dummy.reset_wire_data.body, &dummy_reset_wire_data, + dummy.reset_wire_data.len); + memcpy(&dummy.info_wire_data.body, &dummy_info_wire_data, + dummy.info_wire_data.len); + memcpy(&dummy.set_pin_wire_data.body, &dummy_set_pin_wire_data, + dummy.set_pin_wire_data.len); + memcpy(&dummy.change_pin_wire_data.body, &dummy_change_pin_wire_data, + dummy.change_pin_wire_data.len); + memcpy(&dummy.retry_wire_data.body, &dummy_retry_wire_data, + dummy.retry_wire_data.len); + memcpy(&dummy.config_wire_data.body, &dummy_config_wire_data, + dummy.config_wire_data.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static void +dev_reset(const struct param *p) +{ + fido_dev_t *dev; + + set_wire_data(p->reset_wire_data.body, p->reset_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + fido_dev_reset(dev); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_get_cbor_info(const struct param *p) +{ + fido_dev_t *dev; + fido_cbor_info_t *ci; + uint64_t n; + uint8_t proto, major, minor, build, flags; + bool v; + + set_wire_data(p->info_wire_data.body, p->info_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + proto = fido_dev_protocol(dev); + major = fido_dev_major(dev); + minor = fido_dev_minor(dev); + build = fido_dev_build(dev); + flags = fido_dev_flags(dev); + + consume(&proto, sizeof(proto)); + consume(&major, sizeof(major)); + consume(&minor, sizeof(minor)); + consume(&build, sizeof(build)); + consume(&flags, sizeof(flags)); + + if ((ci = fido_cbor_info_new()) == NULL) + goto out; + + fido_dev_get_cbor_info(dev, ci); + + for (size_t i = 0; i < fido_cbor_info_versions_len(ci); i++) { + char * const *sa = fido_cbor_info_versions_ptr(ci); + consume(sa[i], strlen(sa[i])); + } + + for (size_t i = 0; i < fido_cbor_info_extensions_len(ci); i++) { + char * const *sa = fido_cbor_info_extensions_ptr(ci); + consume(sa[i], strlen(sa[i])); + } + + for (size_t i = 0; i < fido_cbor_info_transports_len(ci); i++) { + char * const *sa = fido_cbor_info_transports_ptr(ci); + consume(sa[i], strlen(sa[i])); + } + + for (size_t i = 0; i < fido_cbor_info_options_len(ci); i++) { + char * const *sa = fido_cbor_info_options_name_ptr(ci); + const bool *va = fido_cbor_info_options_value_ptr(ci); + consume(sa[i], strlen(sa[i])); + consume(&va[i], sizeof(va[i])); + } + + /* +1 on purpose */ + for (size_t i = 0; i <= fido_cbor_info_algorithm_count(ci); i++) { + const char *type = fido_cbor_info_algorithm_type(ci, i); + int cose = fido_cbor_info_algorithm_cose(ci, i); + consume_str(type); + consume(&cose, sizeof(cose)); + } + + for (size_t i = 0; i < fido_cbor_info_certs_len(ci); i++) { + char * const *na = fido_cbor_info_certs_name_ptr(ci); + const uint64_t *va = fido_cbor_info_certs_value_ptr(ci); + consume(na[i], strlen(na[i])); + consume(&va[i], sizeof(va[i])); + } + + n = fido_cbor_info_maxmsgsiz(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_maxcredbloblen(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_maxcredcntlst(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_maxcredidlen(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_maxlargeblob(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_fwversion(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_minpinlen(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_maxrpid_minpinlen(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_uv_attempts(ci); + consume(&n, sizeof(n)); + n = fido_cbor_info_uv_modality(ci); + consume(&n, sizeof(n)); + n = (uint64_t)fido_cbor_info_rk_remaining(ci); + consume(&n, sizeof(n)); + + consume(fido_cbor_info_aaguid_ptr(ci), fido_cbor_info_aaguid_len(ci)); + consume(fido_cbor_info_protocols_ptr(ci), + fido_cbor_info_protocols_len(ci)); + + v = fido_cbor_info_new_pin_required(ci); + consume(&v, sizeof(v)); + +out: + fido_dev_close(dev); + fido_dev_free(&dev); + + fido_cbor_info_free(&ci); +} + +static void +dev_set_pin(const struct param *p) +{ + fido_dev_t *dev; + + set_wire_data(p->set_pin_wire_data.body, p->set_pin_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + fido_dev_set_pin(dev, p->pin1, NULL); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_change_pin(const struct param *p) +{ + fido_dev_t *dev; + + set_wire_data(p->change_pin_wire_data.body, p->change_pin_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + fido_dev_set_pin(dev, p->pin2, p->pin1); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_get_retry_count(const struct param *p) +{ + fido_dev_t *dev; + int n = 0; + + set_wire_data(p->retry_wire_data.body, p->retry_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + fido_dev_get_retry_count(dev, &n); + consume(&n, sizeof(n)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_get_uv_retry_count(const struct param *p) +{ + fido_dev_t *dev; + int n = 0; + + set_wire_data(p->retry_wire_data.body, p->retry_wire_data.len); + + if ((dev = open_dev(0)) == NULL) + return; + + fido_dev_get_uv_retry_count(dev, &n); + consume(&n, sizeof(n)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_enable_entattest(const struct param *p) +{ + fido_dev_t *dev; + const char *pin; + int r; + + set_wire_data(p->config_wire_data.body, p->config_wire_data.len); + if ((dev = open_dev(0)) == NULL) + return; + pin = p->pin1; + if (strlen(pin) == 0) + pin = NULL; + r = fido_dev_enable_entattest(dev, pin); + consume_str(fido_strerr(r)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_toggle_always_uv(const struct param *p) +{ + fido_dev_t *dev; + const char *pin; + int r; + + set_wire_data(p->config_wire_data.body, p->config_wire_data.len); + if ((dev = open_dev(0)) == NULL) + return; + pin = p->pin1; + if (strlen(pin) == 0) + pin = NULL; + r = fido_dev_toggle_always_uv(dev, pin); + consume_str(fido_strerr(r)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_force_pin_change(const struct param *p) +{ + fido_dev_t *dev; + const char *pin; + int r; + + set_wire_data(p->config_wire_data.body, p->config_wire_data.len); + if ((dev = open_dev(0)) == NULL) + return; + pin = p->pin1; + if (strlen(pin) == 0) + pin = NULL; + r = fido_dev_force_pin_change(dev, pin); + consume_str(fido_strerr(r)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_set_pin_minlen(const struct param *p) +{ + fido_dev_t *dev; + const char *pin; + int r; + + set_wire_data(p->config_wire_data.body, p->config_wire_data.len); + if ((dev = open_dev(0)) == NULL) + return; + pin = p->pin1; + if (strlen(pin) == 0) + pin = NULL; + r = fido_dev_set_pin_minlen(dev, strlen(p->pin2), pin); + consume_str(fido_strerr(r)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +static void +dev_set_pin_minlen_rpid(const struct param *p) +{ + fido_dev_t *dev; + const char *rpid[MAXRPID]; + const char *pin; + size_t n; + int r; + + set_wire_data(p->config_wire_data.body, p->config_wire_data.len); + if ((dev = open_dev(0)) == NULL) + return; + n = uniform_random(MAXRPID); + for (size_t i = 0; i < n; i++) + rpid[i] = dummy_rp_id; + pin = p->pin1; + if (strlen(pin) == 0) + pin = NULL; + r = fido_dev_set_pin_minlen_rpid(dev, rpid, n, pin); + consume_str(fido_strerr(r)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + +void +test(const struct param *p) +{ + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + dev_reset(p); + dev_get_cbor_info(p); + dev_set_pin(p); + dev_change_pin(p); + dev_get_retry_count(p); + dev_get_uv_retry_count(p); + dev_enable_entattest(p); + dev_toggle_always_uv(p); + dev_force_pin_change(p); + dev_set_pin_minlen(p); + dev_set_pin_minlen_rpid(p); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_string(p->pin1); + mutate_string(p->pin2); + } + + if (flags & MUTATE_WIREDATA) { + mutate_blob(&p->reset_wire_data); + mutate_blob(&p->info_wire_data); + mutate_blob(&p->set_pin_wire_data); + mutate_blob(&p->change_pin_wire_data); + mutate_blob(&p->retry_wire_data); + } +} diff --git a/fuzz/fuzz_netlink.c b/fuzz/fuzz_netlink.c new file mode 100644 index 0000000..4d28129 --- /dev/null +++ b/fuzz/fuzz_netlink.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2020 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include "../openbsd-compat/openbsd-compat.h" +#include "mutator_aux.h" +#include "dummy.h" + +struct param { + int seed; + int dev; + struct blob wiredata; +}; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 3 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_int(v[1], &p->dev) < 0 || + unpack_blob(v[2], &p->wiredata) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[3], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(3)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_int(p->dev)) == NULL || + (argv[2] = pack_blob(&p->wiredata)) == NULL) + goto fail; + + for (size_t i = 0; i < 3; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) == 0 || cbor_len > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 3; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + dummy.wiredata.len = sizeof(dummy_netlink_wiredata); + memcpy(&dummy.wiredata.body, &dummy_netlink_wiredata, + dummy.wiredata.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +void +test(const struct param *p) +{ + fido_nl_t *nl; + uint32_t target; + + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + set_netlink_io_functions(fd_read, fd_write); + set_wire_data(p->wiredata.body, p->wiredata.len); + + if ((nl = fido_nl_new()) == NULL) + return; + + consume(&nl->fd, sizeof(nl->fd)); + consume(&nl->nfc_type, sizeof(nl->nfc_type)); + consume(&nl->nfc_mcastgrp, sizeof(nl->nfc_mcastgrp)); + consume(&nl->saddr, sizeof(nl->saddr)); + + fido_nl_power_nfc(nl, (uint32_t)p->dev); + + if (fido_nl_get_nfc_target(nl, (uint32_t)p->dev, &target) == 0) + consume(&target, sizeof(target)); + + fido_nl_free(&nl); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) + mutate_int(&p->dev); + + if (flags & MUTATE_WIREDATA) + mutate_blob(&p->wiredata); +} diff --git a/fuzz/fuzz_pcsc.c b/fuzz/fuzz_pcsc.c new file mode 100644 index 0000000..cf6210b --- /dev/null +++ b/fuzz/fuzz_pcsc.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#define _FIDO_INTERNAL + +#include +#include +#include +#include +#include +#include + +#include "mutator_aux.h" +#include "wiredata_fido2.h" +#include "dummy.h" + +#include "../src/extern.h" + +struct param { + int seed; + char path[MAXSTR]; + struct blob pcsc_list; + struct blob tx_apdu; + struct blob wiredata_init; + struct blob wiredata_msg; +}; + +static const uint8_t dummy_tx_apdu[] = { WIREDATA_CTAP_EXTENDED_APDU }; +static const uint8_t dummy_wiredata_init[] = { WIREDATA_CTAP_NFC_INIT }; +static const uint8_t dummy_wiredata_msg[] = { WIREDATA_CTAP_NFC_MSG }; + +struct param * +unpack(const uint8_t *ptr, size_t len) +{ + cbor_item_t *item = NULL, **v; + struct cbor_load_result cbor; + struct param *p; + int ok = -1; + + if ((p = calloc(1, sizeof(*p))) == NULL || + (item = cbor_load(ptr, len, &cbor)) == NULL || + cbor.read != len || + cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false || + cbor_array_size(item) != 6 || + (v = cbor_array_handle(item)) == NULL) + goto fail; + + if (unpack_int(v[0], &p->seed) < 0 || + unpack_string(v[1], p->path) < 0 || + unpack_blob(v[2], &p->pcsc_list) < 0 || + unpack_blob(v[3], &p->tx_apdu) < 0 || + unpack_blob(v[4], &p->wiredata_init) < 0 || + unpack_blob(v[5], &p->wiredata_msg) < 0) + goto fail; + + ok = 0; +fail: + if (ok < 0) { + free(p); + p = NULL; + } + + if (item) + cbor_decref(&item); + + return p; +} + +size_t +pack(uint8_t *ptr, size_t len, const struct param *p) +{ + cbor_item_t *argv[6], *array = NULL; + size_t cbor_alloc_len, cbor_len = 0; + unsigned char *cbor = NULL; + + memset(argv, 0, sizeof(argv)); + + if ((array = cbor_new_definite_array(6)) == NULL || + (argv[0] = pack_int(p->seed)) == NULL || + (argv[1] = pack_string(p->path)) == NULL || + (argv[2] = pack_blob(&p->pcsc_list)) == NULL || + (argv[3] = pack_blob(&p->tx_apdu)) == NULL || + (argv[4] = pack_blob(&p->wiredata_init)) == NULL || + (argv[5] = pack_blob(&p->wiredata_msg)) == NULL) + goto fail; + + for (size_t i = 0; i < 6; i++) + if (cbor_array_push(array, argv[i]) == false) + goto fail; + + if ((cbor_len = cbor_serialize_alloc(array, &cbor, + &cbor_alloc_len)) == 0 || cbor_len > len) { + cbor_len = 0; + goto fail; + } + + memcpy(ptr, cbor, cbor_len); +fail: + for (size_t i = 0; i < 6; i++) + if (argv[i]) + cbor_decref(&argv[i]); + + if (array) + cbor_decref(&array); + + free(cbor); + + return cbor_len; +} + +size_t +pack_dummy(uint8_t *ptr, size_t len) +{ + struct param dummy; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&dummy, 0, sizeof(dummy)); + + strlcpy(dummy.path, dummy_pcsc_path, sizeof(dummy.path)); + + dummy.pcsc_list.len = sizeof(dummy_pcsc_list); + memcpy(&dummy.pcsc_list.body, &dummy_pcsc_list, dummy.pcsc_list.len); + + dummy.tx_apdu.len = sizeof(dummy_tx_apdu); + memcpy(&dummy.tx_apdu.body, &dummy_tx_apdu, dummy.tx_apdu.len); + + dummy.wiredata_init.len = sizeof(dummy_wiredata_init); + memcpy(&dummy.wiredata_init.body, &dummy_wiredata_init, + dummy.wiredata_init.len); + + dummy.wiredata_msg.len = sizeof(dummy_wiredata_msg); + memcpy(&dummy.wiredata_msg.body, &dummy_wiredata_msg, + dummy.wiredata_msg.len); + + assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); + + if (blob_len > len) { + memcpy(ptr, blob, len); + return len; + } + + memcpy(ptr, blob, blob_len); + + return blob_len; +} + +static void +test_manifest(void) +{ + size_t ndevs, nfound; + fido_dev_info_t *devlist = NULL; + int16_t vendor_id, product_id; + int r; + + r = fido_pcsc_manifest(NULL, 0, &nfound); + assert(r == FIDO_OK && nfound == 0); + r = fido_pcsc_manifest(NULL, 1, &nfound); + assert(r == FIDO_ERR_INVALID_ARGUMENT); + + ndevs = uniform_random(64); + if ((devlist = fido_dev_info_new(ndevs)) == NULL || + fido_pcsc_manifest(devlist, ndevs, &nfound) != FIDO_OK) + goto out; + + for (size_t i = 0; i < nfound; i++) { + const fido_dev_info_t *di = fido_dev_info_ptr(devlist, i); + consume_str(fido_dev_info_path(di)); + consume_str(fido_dev_info_manufacturer_string(di)); + consume_str(fido_dev_info_product_string(di)); + vendor_id = fido_dev_info_vendor(di); + product_id = fido_dev_info_product(di); + consume(&vendor_id, sizeof(vendor_id)); + consume(&product_id, sizeof(product_id)); + } + +out: + fido_dev_info_free(&devlist, ndevs); +} + +static void +test_tx(const char *path, const struct blob *apdu, uint8_t cmd, u_char *rx_buf, + size_t rx_len) +{ + fido_dev_t dev; + const u_char *tx_ptr = NULL; + size_t tx_len = 0; + int n; + + memset(&dev, 0, sizeof(dev)); + + if (fido_dev_set_pcsc(&dev) < 0) + return; + if ((dev.io_handle = fido_pcsc_open(path)) == NULL) + return; + + if (apdu) { + tx_ptr = apdu->body; + tx_len = apdu->len; + } + + fido_pcsc_tx(&dev, cmd, tx_ptr, tx_len); + + if ((n = fido_pcsc_rx(&dev, cmd, rx_buf, rx_len, -1)) >= 0) + consume(rx_buf, n); + + fido_pcsc_close(dev.io_handle); +} + +static void +test_misc(void) +{ + assert(fido_pcsc_open(NULL) == NULL); + assert(fido_pcsc_write(NULL, NULL, INT_MAX + 1LL) == -1); +} + +void +test(const struct param *p) +{ + u_char buf[512]; + + prng_init((unsigned int)p->seed); + fuzz_clock_reset(); + fido_init(FIDO_DEBUG); + fido_set_log_handler(consume_str); + + set_pcsc_parameters(&p->pcsc_list); + set_pcsc_io_functions(nfc_read, nfc_write, consume); + + set_wire_data(p->wiredata_init.body, p->wiredata_init.len); + test_manifest(); + + test_misc(); + + set_wire_data(p->wiredata_init.body, p->wiredata_init.len); + test_tx(p->path, NULL, CTAP_CMD_INIT, buf, uniform_random(20)); + + set_wire_data(p->wiredata_msg.body, p->wiredata_msg.len); + test_tx(p->path, &p->tx_apdu, CTAP_CMD_MSG, buf, sizeof(buf)); + + set_wire_data(p->wiredata_msg.body, p->wiredata_msg.len); + test_tx(p->path, &p->tx_apdu, CTAP_CMD_CBOR, buf, sizeof(buf)); + + set_wire_data(p->wiredata_msg.body, p->wiredata_msg.len); + test_tx(p->path, &p->tx_apdu, CTAP_CMD_LOCK, buf, sizeof(buf)); +} + +void +mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN +{ + if (flags & MUTATE_SEED) + p->seed = (int)seed; + + if (flags & MUTATE_PARAM) { + mutate_string(p->path); + mutate_blob(&p->pcsc_list); + mutate_blob(&p->tx_apdu); + } + + if (flags & MUTATE_WIREDATA) { + mutate_blob(&p->wiredata_init); + mutate_blob(&p->wiredata_msg); + } +} diff --git a/fuzz/libfuzzer.c b/fuzz/libfuzzer.c new file mode 100644 index 0000000..d712aa6 --- /dev/null +++ b/fuzz/libfuzzer.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mutator_aux.h" + +extern int fuzz_save_corpus; + +static bool debug; +static unsigned int flags = MUTATE_ALL; +static unsigned long long test_fail; +static unsigned long long test_total; +static unsigned long long mutate_fail; +static unsigned long long mutate_total; + +int LLVMFuzzerInitialize(int *, char ***); +int LLVMFuzzerTestOneInput(const uint8_t *, size_t); +size_t LLVMFuzzerCustomMutator(uint8_t *, size_t, size_t, unsigned int); + +static int +save_seed(const char *opt) +{ + const char *path; + int fd = -1, status = 1; + void *buf = NULL; + const size_t buflen = MAXCORPUS; + size_t n; + struct param *p = NULL; + + if ((path = strchr(opt, '=')) == NULL || strlen(++path) == 0) { + warnx("usage: --fido-save-seed="); + goto fail; + } + + if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, 0644)) == -1) { + warn("open %s", path); + goto fail; + } + + if ((buf = malloc(buflen)) == NULL) { + warn("malloc"); + goto fail; + } + + n = pack_dummy(buf, buflen); + + if ((p = unpack(buf, n)) == NULL) { + warnx("unpack"); + goto fail; + } + + if (write(fd, buf, n) != (ssize_t)n) { + warn("write %s", path); + goto fail; + } + + status = 0; +fail: + if (fd != -1) + close(fd); + free(buf); + free(p); + + return status; +} + +static int +save_corpus(const struct param *p) +{ + uint8_t blob[MAXCORPUS], dgst[SHA256_DIGEST_LENGTH]; + size_t blob_len; + char path[PATH_MAX]; + int r, fd; + + if ((blob_len = pack(blob, sizeof(blob), p)) == 0 || + blob_len > sizeof(blob)) { + warnx("pack"); + return -1; + } + + if (SHA256(blob, blob_len, dgst) != dgst) { + warnx("sha256"); + return -1; + } + + if ((r = snprintf(path, sizeof(path), "saved_corpus_%02x%02x%02x%02x" + "%02x%02x%02x%02x", dgst[0], dgst[1], dgst[2], dgst[3], dgst[4], + dgst[5], dgst[6], dgst[7])) < 0 || (size_t)r >= sizeof(path)) { + warnx("snprintf"); + return -1; + } + + if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, 0644)) == -1) { + warn("open %s", path); + return -1; + } + + if (write(fd, blob, blob_len) != (ssize_t)blob_len) { + warn("write"); + r = -1; + } else { + warnx("wrote %s", path); + r = 0; + } + + close(fd); + + return r; +} + +static void +parse_mutate_flags(const char *opt, unsigned int *mutate_flags) +{ + const char *f; + + if ((f = strchr(opt, '=')) == NULL || strlen(++f) == 0) + errx(1, "usage: --fido-mutate="); + + if (strcmp(f, "seed") == 0) + *mutate_flags |= MUTATE_SEED; + else if (strcmp(f, "param") == 0) + *mutate_flags |= MUTATE_PARAM; + else if (strcmp(f, "wiredata") == 0) + *mutate_flags |= MUTATE_WIREDATA; + else + errx(1, "--fido-mutate: unknown flag '%s'", f); +} + +int +LLVMFuzzerInitialize(int *argc, char ***argv) +{ + unsigned int mutate_flags = 0; + + for (int i = 0; i < *argc; i++) + if (strcmp((*argv)[i], "--fido-debug") == 0) { + debug = 1; + } else if (strncmp((*argv)[i], "--fido-save-seed=", 17) == 0) { + exit(save_seed((*argv)[i])); + } else if (strncmp((*argv)[i], "--fido-mutate=", 14) == 0) { + parse_mutate_flags((*argv)[i], &mutate_flags); + } + + if (mutate_flags) + flags = mutate_flags; + + return 0; +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct param *p; + + if (size > MAXCORPUS) + return 0; + + if (++test_total % 100000 == 0 && debug) { + double r = (double)test_fail/(double)test_total * 100.0; + fprintf(stderr, "%s: %llu/%llu (%.2f%%)\n", __func__, + test_fail, test_total, r); + } + + if ((p = unpack(data, size)) == NULL) + test_fail++; + else { + fuzz_save_corpus = 0; + test(p); + if (fuzz_save_corpus && save_corpus(p) < 0) + fprintf(stderr, "%s: failed to save corpus\n", + __func__); + free(p); + } + + return 0; +} + +size_t +LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxsize, + unsigned int seed) NO_MSAN +{ + struct param *p; + uint8_t blob[MAXCORPUS]; + size_t blob_len; + + memset(&p, 0, sizeof(p)); + +#ifdef WITH_MSAN + __msan_unpoison(data, maxsize); +#endif + + if (++mutate_total % 100000 == 0 && debug) { + double r = (double)mutate_fail/(double)mutate_total * 100.0; + fprintf(stderr, "%s: %llu/%llu (%.2f%%)\n", __func__, + mutate_fail, mutate_total, r); + } + + if ((p = unpack(data, size)) == NULL) { + mutate_fail++; + return pack_dummy(data, maxsize); + } + + mutate(p, seed, flags); + + if ((blob_len = pack(blob, sizeof(blob), p)) == 0 || + blob_len > sizeof(blob) || blob_len > maxsize) { + mutate_fail++; + free(p); + return 0; + } + + free(p); + + memcpy(data, blob, blob_len); + + return blob_len; +} diff --git a/fuzz/mutator_aux.c b/fuzz/mutator_aux.c new file mode 100644 index 0000000..ebddf10 --- /dev/null +++ b/fuzz/mutator_aux.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mutator_aux.h" + +int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int); +int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t); +size_t LLVMFuzzerMutate(uint8_t *, size_t, size_t); + +extern int prng_up; +static const uint8_t *wire_data_ptr = NULL; +static size_t wire_data_len = 0; + +void +consume(const void *body, size_t len) +{ + const volatile uint8_t *ptr = body; + volatile uint8_t x = 0; + +#ifdef WITH_MSAN + __msan_check_mem_is_initialized(body, len); +#endif + + while (len--) + x ^= *ptr++; + + (void)x; +} + +void +consume_str(const char *str) +{ + if (str != NULL) + consume(str, strlen(str) + 1); +} + +int +unpack_int(cbor_item_t *item, int *v) +{ + if (cbor_is_int(item) == false || + cbor_int_get_width(item) != CBOR_INT_64) + return -1; + + if (cbor_isa_uint(item)) + *v = (int)cbor_get_uint64(item); + else + *v = (int)(-cbor_get_uint64(item) - 1); + + return 0; +} + +int +unpack_string(cbor_item_t *item, char *v) +{ + size_t len; + + if (cbor_isa_bytestring(item) == false || + (len = cbor_bytestring_length(item)) >= MAXSTR) + return -1; + + memcpy(v, cbor_bytestring_handle(item), len); + v[len] = '\0'; + + return 0; +} + +int +unpack_byte(cbor_item_t *item, uint8_t *v) +{ + if (cbor_isa_uint(item) == false || + cbor_int_get_width(item) != CBOR_INT_8) + return -1; + + *v = cbor_get_uint8(item); + + return 0; +} + +int +unpack_blob(cbor_item_t *item, struct blob *v) +{ + if (cbor_isa_bytestring(item) == false || + (v->len = cbor_bytestring_length(item)) > sizeof(v->body)) + return -1; + + memcpy(v->body, cbor_bytestring_handle(item), v->len); + + return 0; +} + +cbor_item_t * +pack_int(int v) NO_MSAN +{ + if (v < 0) + return cbor_build_negint64((uint64_t)(-(int64_t)v - 1)); + else + return cbor_build_uint64((uint64_t)v); +} + +cbor_item_t * +pack_string(const char *v) NO_MSAN +{ + if (strlen(v) >= MAXSTR) + return NULL; + + return cbor_build_bytestring((const unsigned char *)v, strlen(v)); +} + +cbor_item_t * +pack_byte(uint8_t v) NO_MSAN +{ + return cbor_build_uint8(v); +} + +cbor_item_t * +pack_blob(const struct blob *v) NO_MSAN +{ + return cbor_build_bytestring(v->body, v->len); +} + +void +mutate_byte(uint8_t *b) +{ + LLVMFuzzerMutate(b, sizeof(*b), sizeof(*b)); +#ifdef WITH_MSAN + __msan_unpoison(b, sizeof(*b)); +#endif +} + +void +mutate_int(int *i) +{ + LLVMFuzzerMutate((uint8_t *)i, sizeof(*i), sizeof(*i)); +#ifdef WITH_MSAN + __msan_unpoison(i, sizeof(*i)); +#endif +} + +void +mutate_blob(struct blob *blob) +{ + blob->len = LLVMFuzzerMutate((uint8_t *)blob->body, blob->len, + sizeof(blob->body)); +} + +void +mutate_string(char *s) +{ + size_t n; + + n = LLVMFuzzerMutate((uint8_t *)s, strlen(s), MAXSTR - 1); + s[n] = '\0'; +} + +static int +buf_read(unsigned char *ptr, size_t len, int ms) +{ + size_t n; + + (void)ms; + + if (prng_up && uniform_random(400) < 1) { + errno = EIO; + return -1; + } + + if (wire_data_len < len) + n = wire_data_len; + else + n = len; + + memcpy(ptr, wire_data_ptr, n); + + wire_data_ptr += n; + wire_data_len -= n; + + return (int)n; +} + +static int +buf_write(const unsigned char *ptr, size_t len) +{ + consume(ptr, len); + + if (prng_up && uniform_random(400) < 1) { + errno = EIO; + return -1; + } + + return (int)len; +} + +static void * +hid_open(const char *path) +{ + (void)path; + + return (void *)HID_DEV_HANDLE; +} + +static void +hid_close(void *handle) +{ + assert(handle == (void *)HID_DEV_HANDLE); +} + +static int +hid_read(void *handle, unsigned char *ptr, size_t len, int ms) +{ + assert(handle == (void *)HID_DEV_HANDLE); + assert(len >= CTAP_MIN_REPORT_LEN && len <= CTAP_MAX_REPORT_LEN); + + return buf_read(ptr, len, ms); +} + +static int +hid_write(void *handle, const unsigned char *ptr, size_t len) +{ + assert(handle == (void *)HID_DEV_HANDLE); + assert(len >= CTAP_MIN_REPORT_LEN + 1 && + len <= CTAP_MAX_REPORT_LEN + 1); + + return buf_write(ptr, len); +} + +static void * +nfc_open(const char *path) +{ + (void)path; + + return (void *)NFC_DEV_HANDLE; +} + +static void +nfc_close(void *handle) +{ + assert(handle == (void *)NFC_DEV_HANDLE); +} + +int +nfc_read(void *handle, unsigned char *ptr, size_t len, int ms) +{ + assert(handle == (void *)NFC_DEV_HANDLE); + assert(len > 0 && len <= 264); + + return buf_read(ptr, len, ms); +} + +int +nfc_write(void *handle, const unsigned char *ptr, size_t len) +{ + assert(handle == (void *)NFC_DEV_HANDLE); + assert(len > 0 && len <= 256 + 2); + + return buf_write(ptr, len); +} + +ssize_t +fd_read(int fd, void *ptr, size_t len) +{ + assert(fd != -1); + + return buf_read(ptr, len, -1); +} + +ssize_t +fd_write(int fd, const void *ptr, size_t len) +{ + assert(fd != -1); + + return buf_write(ptr, len); +} + +fido_dev_t * +open_dev(int nfc) +{ + fido_dev_t *dev; + fido_dev_io_t io; + fido_dev_transport_t t; + + memset(&io, 0, sizeof(io)); + memset(&t, 0, sizeof(t)); + + if ((dev = fido_dev_new()) == NULL) + return NULL; + + if (nfc) { + io.open = nfc_open; + io.close = nfc_close; + io.read = nfc_read; + io.write = nfc_write; + } else { + io.open = hid_open; + io.close = hid_close; + io.read = hid_read; + io.write = hid_write; + } + + if (fido_dev_set_io_functions(dev, &io) != FIDO_OK) + goto fail; + + if (nfc) { + t.rx = fido_nfc_rx; + t.tx = fido_nfc_tx; + if (fido_dev_set_transport_functions(dev, &t) != FIDO_OK) + goto fail; + } + + if (fido_dev_set_timeout(dev, 300) != FIDO_OK || + fido_dev_open(dev, "nodev") != FIDO_OK) + goto fail; + + return dev; +fail: + fido_dev_free(&dev); + + return NULL; +} + +void +set_wire_data(const uint8_t *ptr, size_t len) +{ + wire_data_ptr = ptr; + wire_data_len = len; +} diff --git a/fuzz/mutator_aux.h b/fuzz/mutator_aux.h new file mode 100644 index 0000000..5ad5661 --- /dev/null +++ b/fuzz/mutator_aux.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _MUTATOR_AUX_H +#define _MUTATOR_AUX_H + +#include + +#include +#include +#include + +#include "../src/fido.h" +#include "../src/fido/bio.h" +#include "../src/fido/config.h" +#include "../src/fido/credman.h" +#include "../src/fido/eddsa.h" +#include "../src/fido/es256.h" +#include "../src/fido/es384.h" +#include "../src/fido/rs256.h" +#include "../src/netlink.h" + +/* + * As of LLVM 10.0.0, MSAN support in libFuzzer was still experimental. + * We therefore have to be careful when using our custom mutator, or + * MSAN will flag uninitialised reads on memory populated by libFuzzer. + * Since there is no way to suppress MSAN without regenerating object + * code (in which case you might as well rebuild libFuzzer with MSAN), + * we adjust our mutator to make it less accurate while allowing + * fuzzing to proceed. + */ + +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) +# include +# define NO_MSAN __attribute__((no_sanitize("memory"))) +# define WITH_MSAN 1 +# endif +#endif + +#if !defined(WITH_MSAN) +# define NO_MSAN +#endif + +#define MUTATE_SEED 0x01 +#define MUTATE_PARAM 0x02 +#define MUTATE_WIREDATA 0x04 +#define MUTATE_ALL (MUTATE_SEED | MUTATE_PARAM | MUTATE_WIREDATA) + +#define MAXSTR 1024 +#define MAXBLOB 3600 +#define MAXCORPUS 8192 + +#define HID_DEV_HANDLE 0x68696421 +#define NFC_DEV_HANDLE 0x6e666321 + +struct blob { + uint8_t body[MAXBLOB]; + size_t len; +}; + +struct param; + +struct param *unpack(const uint8_t *, size_t); +size_t pack(uint8_t *, size_t, const struct param *); +size_t pack_dummy(uint8_t *, size_t); +void mutate(struct param *, unsigned int, unsigned int); +void test(const struct param *); + +void consume(const void *, size_t); +void consume_str(const char *); + +int unpack_blob(cbor_item_t *, struct blob *); +int unpack_byte(cbor_item_t *, uint8_t *); +int unpack_int(cbor_item_t *, int *); +int unpack_string(cbor_item_t *, char *); + +cbor_item_t *pack_blob(const struct blob *); +cbor_item_t *pack_byte(uint8_t); +cbor_item_t *pack_int(int); +cbor_item_t *pack_string(const char *); + +void mutate_byte(uint8_t *); +void mutate_int(int *); +void mutate_blob(struct blob *); +void mutate_string(char *); + +ssize_t fd_read(int, void *, size_t); +ssize_t fd_write(int, const void *, size_t); + +int nfc_read(void *, unsigned char *, size_t, int); +int nfc_write(void *, const unsigned char *, size_t); + +fido_dev_t *open_dev(int); +void set_wire_data(const uint8_t *, size_t); + +void fuzz_clock_reset(void); +void prng_init(unsigned long); +unsigned long prng_uint32(void); + +uint32_t uniform_random(uint32_t); + +void set_pcsc_parameters(const struct blob *); +void set_pcsc_io_functions(int (*)(void *, u_char *, size_t, int), + int (*)(void *, const u_char *, size_t), void (*)(const void *, size_t)); + +#endif /* !_MUTATOR_AUX_H */ diff --git a/fuzz/pcsc.c b/fuzz/pcsc.c new file mode 100644 index 0000000..f6a3e9b --- /dev/null +++ b/fuzz/pcsc.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include + +#include "mutator_aux.h" + +static const struct blob *reader_list; +static int (*xread)(void *, u_char *, size_t, int); +static int (*xwrite)(void *, const u_char *, size_t); +static void (*xconsume)(const void *, size_t); + +LONG __wrap_SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT); +LONG __wrap_SCardListReaders(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD); +LONG __wrap_SCardReleaseContext(SCARDCONTEXT); +LONG __wrap_SCardConnect(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE, + LPDWORD); +LONG __wrap_SCardDisconnect(SCARDHANDLE, DWORD); +LONG __wrap_SCardTransmit(SCARDHANDLE, const SCARD_IO_REQUEST *, LPCBYTE, + DWORD, SCARD_IO_REQUEST *, LPBYTE, LPDWORD); + +LONG +__wrap_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, + LPCVOID pvReserved2, LPSCARDCONTEXT phContext) +{ + assert(dwScope == SCARD_SCOPE_SYSTEM); + assert(pvReserved1 == NULL); + assert(pvReserved2 == NULL); + + *phContext = 1; + + if (uniform_random(400) < 1) + return SCARD_E_NO_SERVICE; + if (uniform_random(400) < 1) + return SCARD_E_NO_SMARTCARD; + if (uniform_random(400) < 1) + return SCARD_E_NO_MEMORY; + if (uniform_random(400) < 1) + *phContext = 0; + + return SCARD_S_SUCCESS; +} + +LONG +__wrap_SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, + LPSTR mszReaders, LPDWORD pcchReaders) +{ + assert(hContext == 1); + assert(mszGroups == NULL); + assert(mszReaders != NULL); + assert(pcchReaders != 0); + + if (reader_list == NULL || uniform_random(400) < 1) + return SCARD_E_NO_READERS_AVAILABLE; + if (uniform_random(400) < 1) + return SCARD_E_NO_MEMORY; + + memcpy(mszReaders, reader_list->body, reader_list->len > *pcchReaders ? + *pcchReaders : reader_list->len); + *pcchReaders = (DWORD)reader_list->len; /* on purpose */ + + return SCARD_S_SUCCESS; +} + +LONG +__wrap_SCardReleaseContext(SCARDCONTEXT hContext) +{ + assert(hContext == 1); + + return SCARD_S_SUCCESS; +} + +LONG +__wrap_SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, + DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) +{ + uint32_t r; + + assert(hContext == 1); + xconsume(szReader, strlen(szReader) + 1); + assert(dwShareMode == SCARD_SHARE_SHARED); + assert(dwPreferredProtocols == SCARD_PROTOCOL_ANY); + assert(phCard != NULL); + assert(pdwActiveProtocol != NULL); + + if ((r = uniform_random(400)) < 1) + return SCARD_E_UNEXPECTED; + + *phCard = 1; + *pdwActiveProtocol = (r & 1) ? SCARD_PROTOCOL_T0 : SCARD_PROTOCOL_T1; + + if (uniform_random(400) < 1) + *pdwActiveProtocol = SCARD_PROTOCOL_RAW; + + return SCARD_S_SUCCESS; +} + +LONG +__wrap_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) +{ + assert(hCard == 1); + assert(dwDisposition == SCARD_LEAVE_CARD); + + return SCARD_S_SUCCESS; +} + +extern void consume(const void *body, size_t len); + +LONG +__wrap_SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, + LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci, + LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) +{ + void *ioh = (void *)NFC_DEV_HANDLE; + int n; + + assert(hCard == 1); + xconsume(pioSendPci, sizeof(*pioSendPci)); + xwrite(ioh, pbSendBuffer, cbSendLength); + assert(pioRecvPci == NULL); + + if (uniform_random(400) < 1 || + (n = xread(ioh, pbRecvBuffer, *pcbRecvLength, -1)) == -1) + return SCARD_E_UNEXPECTED; + *pcbRecvLength = (DWORD)n; + + return SCARD_S_SUCCESS; +} + +void +set_pcsc_parameters(const struct blob *reader_list_ptr) +{ + reader_list = reader_list_ptr; +} + +void +set_pcsc_io_functions(int (*read_f)(void *, u_char *, size_t, int), + int (*write_f)(void *, const u_char *, size_t), + void (*consume_f)(const void *, size_t)) +{ + xread = read_f; + xwrite = write_f; + xconsume = consume_f; +} diff --git a/fuzz/preload-fuzz.c b/fuzz/preload-fuzz.c new file mode 100644 index 0000000..f18848d --- /dev/null +++ b/fuzz/preload-fuzz.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2019 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * cc -fPIC -D_GNU_SOURCE -shared -o preload-fuzz.so preload-fuzz.c + * LD_PRELOAD=$(realpath preload-fuzz.so) + */ + +#include +#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..34d57ad --- /dev/null +++ b/fuzz/preload-snoop.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2019 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * cc -fPIC -D_GNU_SOURCE -shared -o preload-snoop.so preload-snoop.c + * LD_PRELOAD=$(realpath preload-snoop.so) + */ + +#include +#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/prng.c b/fuzz/prng.c new file mode 100644 index 0000000..61114ac --- /dev/null +++ b/fuzz/prng.c @@ -0,0 +1,113 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +#include +#include +#include +#include "mutator_aux.h" + +#define init_genrand prng_init +#define genrand_int32 prng_uint32 + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +int prng_up = 0; +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti> 30)) + + (unsigned long)mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } + prng_up = 1; +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) +{ + unsigned long y; + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + assert(mti != N+1); + + for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + } + for (;kk> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} diff --git a/fuzz/report.tgz b/fuzz/report.tgz new file mode 100644 index 0000000000000000000000000000000000000000..221648f28d3fef2816267494e7a524da1a6531cf GIT binary patch literal 365288 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

#} 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�|b^6@ei^@giQIkS^YS( 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 oJDVNs)!sWsX*jEGo2MIhb)c^nh literal 0 HcmV?d00001 diff --git a/fuzz/summary.txt b/fuzz/summary.txt new file mode 100644 index 0000000..011ce02 --- /dev/null +++ b/fuzz/summary.txt @@ -0,0 +1,64 @@ +Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +fuzz/clock.c 24 1 95.83% 4 0 100.00% 35 1 97.14% +fuzz/pcsc.c 59 0 100.00% 8 0 100.00% 75 12 84.00% +fuzz/prng.c 31 0 100.00% 2 0 100.00% 35 1 97.14% +fuzz/udev.c 110 2 98.18% 17 0 100.00% 126 12 90.48% +fuzz/uniform_random.c 7 1 85.71% 1 0 100.00% 12 1 91.67% +fuzz/wrap.c 23 0 100.00% 3 0 100.00% 29 0 100.00% +openbsd-compat/explicit_bzero.c 4 0 100.00% 1 0 100.00% 7 0 100.00% +openbsd-compat/freezero.c 4 0 100.00% 1 0 100.00% 6 0 100.00% +openbsd-compat/recallocarray.c 41 7 82.93% 1 0 100.00% 36 7 80.56% +openbsd-compat/timingsafe_bcmp.c 4 0 100.00% 1 0 100.00% 7 0 100.00% +src/aes256.c 118 3 97.46% 8 0 100.00% 157 11 92.99% +src/assert.c 628 45 92.83% 63 4 93.65% 782 51 93.48% +src/authkey.c 52 0 100.00% 5 0 100.00% 66 0 100.00% +src/bio.c 458 20 95.63% 50 2 96.00% 592 24 95.95% +src/blob.c 53 2 96.23% 10 0 100.00% 83 4 95.18% +src/buf.c 8 0 100.00% 2 0 100.00% 16 0 100.00% +src/cbor.c 1070 12 98.88% 55 0 100.00% 1258 28 97.77% +src/compress.c 105 14 86.67% 5 0 100.00% 122 24 80.33% +src/config.c 112 0 100.00% 11 0 100.00% 154 0 100.00% +src/cred.c 653 36 94.49% 70 2 97.14% 853 39 95.43% +src/credman.c 428 10 97.66% 41 0 100.00% 562 20 96.44% +src/dev.c 344 65 81.10% 41 6 85.37% 383 80 79.11% +src/ecdh.c 117 2 98.29% 4 0 100.00% 146 5 96.58% +src/eddsa.c 88 5 94.32% 10 0 100.00% 114 9 92.11% +src/err.c 122 10 91.80% 1 0 100.00% 126 10 92.06% +src/es256.c 315 5 98.41% 19 0 100.00% 372 11 97.04% +src/es384.c 158 5 96.84% 11 0 100.00% 198 11 94.44% +src/hid.c 87 2 97.70% 14 0 100.00% 145 3 97.93% +src/hid_linux.c 202 73 63.86% 14 7 50.00% 277 115 58.48% +src/hid_unix.c 29 21 27.59% 2 0 100.00% 43 26 39.53% +src/info.c 232 0 100.00% 51 0 100.00% 409 0 100.00% +src/io.c 193 7 96.37% 13 0 100.00% 230 12 94.78% +src/iso7816.c 18 1 94.44% 5 0 100.00% 38 1 97.37% +src/largeblob.c 525 18 96.57% 30 0 100.00% 693 43 93.80% +src/log.c 39 5 87.18% 7 1 85.71% 63 7 88.89% +src/netlink.c 329 8 97.57% 40 0 100.00% 498 15 96.99% +src/nfc.c 155 3 98.06% 12 0 100.00% 244 9 96.31% +src/nfc_linux.c 172 73 57.56% 13 6 53.85% 242 114 52.89% +src/pcsc.c 204 1 99.51% 13 0 100.00% 282 3 98.94% +src/pin.c 430 3 99.30% 26 0 100.00% 516 4 99.22% +src/random.c 6 0 100.00% 1 0 100.00% 6 0 100.00% +src/reset.c 24 0 100.00% 3 0 100.00% 23 0 100.00% +src/rs1.c 22 2 90.91% 3 0 100.00% 36 6 83.33% +src/rs256.c 146 9 93.84% 13 0 100.00% 179 16 91.06% +src/time.c 43 3 93.02% 3 0 100.00% 43 2 95.35% +src/touch.c 67 0 100.00% 2 0 100.00% 79 0 100.00% +src/tpm.c 103 0 100.00% 9 0 100.00% 194 0 100.00% +src/types.c 29 0 100.00% 7 0 100.00% 56 0 100.00% +src/u2f.c 572 4 99.30% 17 0 100.00% 726 12 98.35% +src/util.c 14 1 92.86% 1 0 100.00% 14 1 92.86% + +Files which contain no functions: +fuzz/mutator_aux.h 0 0 - 0 0 - 0 0 - +openbsd-compat/openbsd-compat.h 0 0 - 0 0 - 0 0 - +openbsd-compat/time.h 0 0 - 0 0 - 0 0 - +src/extern.h 0 0 - 0 0 - 0 0 - +src/fallthrough.h 0 0 - 0 0 - 0 0 - +src/fido.h 0 0 - 0 0 - 0 0 - +src/fido/err.h 0 0 - 0 0 - 0 0 - +src/fido/param.h 0 0 - 0 0 - 0 0 - +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +TOTAL 8777 479 94.54% 744 28 96.24% 11388 750 93.41% diff --git a/fuzz/udev.c b/fuzz/udev.c new file mode 100644 index 0000000..3194012 --- /dev/null +++ b/fuzz/udev.c @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "mutator_aux.h" + +struct udev { + int magic; +}; + +struct udev_enumerate { + int magic; + struct udev_list_entry *list_entry; +}; + +struct udev_list_entry { + int magic; +}; + +struct udev_device { + int magic; + struct udev_device *parent; +}; + +#define UDEV_MAGIC 0x584492cc +#define UDEV_DEVICE_MAGIC 0x569180dd +#define UDEV_LIST_ENTRY_MAGIC 0x497422ee +#define UDEV_ENUM_MAGIC 0x583570ff + +#define ASSERT_TYPE(x, m) assert((x) != NULL && (x)->magic == (m)) +#define ASSERT_UDEV(x) ASSERT_TYPE((x), UDEV_MAGIC) +#define ASSERT_UDEV_ENUM(x) ASSERT_TYPE((x), UDEV_ENUM_MAGIC) +#define ASSERT_UDEV_LIST_ENTRY(x) ASSERT_TYPE((x), UDEV_LIST_ENTRY_MAGIC) +#define ASSERT_UDEV_DEVICE(x) ASSERT_TYPE((x), UDEV_DEVICE_MAGIC) + +static const char *uevent; +static const struct blob *report_descriptor; + +struct udev *__wrap_udev_new(void); +struct udev_device *__wrap_udev_device_get_parent_with_subsystem_devtype( + struct udev_device *, const char *, const char *); +struct udev_device *__wrap_udev_device_new_from_syspath(struct udev *, + const char *); +struct udev_enumerate *__wrap_udev_enumerate_new(struct udev *); +struct udev_list_entry *__wrap_udev_enumerate_get_list_entry( + struct udev_enumerate *); +struct udev_list_entry *__wrap_udev_list_entry_get_next( + struct udev_list_entry *); +const char *__wrap_udev_device_get_sysattr_value(struct udev_device *, + const char *); +const char *__wrap_udev_list_entry_get_name(struct udev_list_entry *); +const char *__wrap_udev_device_get_devnode(struct udev_device *); +const char *__wrap_udev_device_get_sysnum(struct udev_device *); +int __wrap_udev_enumerate_add_match_subsystem(struct udev_enumerate *, + const char *); +int __wrap_udev_enumerate_scan_devices(struct udev_enumerate *); +int __wrap_ioctl(int, unsigned long , ...); +void __wrap_udev_device_unref(struct udev_device *); +void __wrap_udev_enumerate_unref(struct udev_enumerate *); +void __wrap_udev_unref(struct udev *); +void set_udev_parameters(const char *, const struct blob *); + +struct udev_device * +__wrap_udev_device_get_parent_with_subsystem_devtype(struct udev_device *child, + const char *subsystem, const char *devtype) +{ + ASSERT_UDEV_DEVICE(child); + fido_log_debug("%s", subsystem); /* XXX consume */ + fido_log_debug("%s", devtype); /* XXX consume */ + if (child->parent != NULL) + return child->parent; + if ((child->parent = calloc(1, sizeof(*child->parent))) == NULL) + return NULL; + child->parent->magic = UDEV_DEVICE_MAGIC; + + return child->parent; +} + +const char * +__wrap_udev_device_get_sysattr_value(struct udev_device *udev_device, + const char *sysattr) +{ + ASSERT_UDEV_DEVICE(udev_device); + if (uniform_random(400) < 1) + return NULL; + if (!strcmp(sysattr, "manufacturer") || !strcmp(sysattr, "product")) + return "product info"; /* XXX randomise? */ + else if (!strcmp(sysattr, "uevent")) + return uevent; + + return NULL; +} + +const char * +__wrap_udev_list_entry_get_name(struct udev_list_entry *entry) +{ + ASSERT_UDEV_LIST_ENTRY(entry); + return uniform_random(400) < 1 ? NULL : "name"; /* XXX randomise? */ +} + +struct udev_device * +__wrap_udev_device_new_from_syspath(struct udev *udev, const char *syspath) +{ + struct udev_device *udev_device; + + ASSERT_UDEV(udev); + fido_log_debug("%s", syspath); + if ((udev_device = calloc(1, sizeof(*udev_device))) == NULL) + return NULL; + udev_device->magic = UDEV_DEVICE_MAGIC; + + return udev_device; +} + +const char * +__wrap_udev_device_get_devnode(struct udev_device *udev_device) +{ + ASSERT_UDEV_DEVICE(udev_device); + return uniform_random(400) < 1 ? NULL : "/dev/zero"; +} + +const char * +__wrap_udev_device_get_sysnum(struct udev_device *udev_device) +{ + ASSERT_UDEV_DEVICE(udev_device); + return uniform_random(400) < 1 ? NULL : "101010"; /* XXX randomise? */ +} + +void +__wrap_udev_device_unref(struct udev_device *udev_device) +{ + ASSERT_UDEV_DEVICE(udev_device); + if (udev_device->parent) { + ASSERT_UDEV_DEVICE(udev_device->parent); + free(udev_device->parent); + } + free(udev_device); +} + +struct udev * +__wrap_udev_new(void) +{ + struct udev *udev; + + if ((udev = calloc(1, sizeof(*udev))) == NULL) + return NULL; + udev->magic = UDEV_MAGIC; + + return udev; +} + +struct udev_enumerate * +__wrap_udev_enumerate_new(struct udev *udev) +{ + struct udev_enumerate *udev_enum; + + ASSERT_UDEV(udev); + if ((udev_enum = calloc(1, sizeof(*udev_enum))) == NULL) + return NULL; + udev_enum->magic = UDEV_ENUM_MAGIC; + + return udev_enum; +} + +int +__wrap_udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enum, + const char *subsystem) +{ + ASSERT_UDEV_ENUM(udev_enum); + fido_log_debug("%s:", subsystem); + return uniform_random(400) < 1 ? -EINVAL : 0; +} + +int +__wrap_udev_enumerate_scan_devices(struct udev_enumerate *udev_enum) +{ + ASSERT_UDEV_ENUM(udev_enum); + return uniform_random(400) < 1 ? -EINVAL : 0; +} + +struct udev_list_entry * +__wrap_udev_enumerate_get_list_entry(struct udev_enumerate *udev_enum) +{ + ASSERT_UDEV_ENUM(udev_enum); + if ((udev_enum->list_entry = calloc(1, + sizeof(*udev_enum->list_entry))) == NULL) + return NULL; + udev_enum->list_entry->magic = UDEV_LIST_ENTRY_MAGIC; + + return udev_enum->list_entry; +} + +struct udev_list_entry * +__wrap_udev_list_entry_get_next(struct udev_list_entry *udev_list_entry) +{ + ASSERT_UDEV_LIST_ENTRY(udev_list_entry); + return uniform_random(400) < 1 ? NULL : udev_list_entry; +} + +void +__wrap_udev_enumerate_unref(struct udev_enumerate *udev_enum) +{ + ASSERT_UDEV_ENUM(udev_enum); + if (udev_enum->list_entry) + ASSERT_UDEV_LIST_ENTRY(udev_enum->list_entry); + free(udev_enum->list_entry); + free(udev_enum); +} + +void +__wrap_udev_unref(struct udev *udev) +{ + ASSERT_UDEV(udev); + free(udev); +} + +int +__wrap_ioctl(int fd, unsigned long request, ...) +{ + va_list ap; + struct hidraw_report_descriptor *hrd; + + (void)fd; + + if (uniform_random(400) < 1) { + errno = EINVAL; + return -1; + } + + va_start(ap, request); + + switch (IOCTL_REQ(request)) { + case IOCTL_REQ(HIDIOCGRDESCSIZE): + *va_arg(ap, int *) = (int)report_descriptor->len; + break; + case IOCTL_REQ(HIDIOCGRDESC): + hrd = va_arg(ap, struct hidraw_report_descriptor *); + assert(hrd->size == report_descriptor->len); + memcpy(hrd->value, report_descriptor->body, hrd->size); + break; + default: + warnx("%s: unknown request 0x%lx", __func__, request); + abort(); + } + + va_end(ap); + + return 0; +} + +void +set_udev_parameters(const char *uevent_ptr, + const struct blob *report_descriptor_ptr) +{ + uevent = uevent_ptr; + report_descriptor = report_descriptor_ptr; +} diff --git a/fuzz/uniform_random.c b/fuzz/uniform_random.c new file mode 100644 index 0000000..357091c --- /dev/null +++ b/fuzz/uniform_random.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2008, Damien Miller + * + * 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); +unsigned long prng_uint32(void); + +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +uint32_t +uniform_random(uint32_t upper_bound) +{ + uint32_t r, min; + + if (upper_bound < 2) + return 0; + + /* 2**32 % x == (2**32 - x) % x */ + min = -upper_bound % upper_bound; + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + for (;;) { + r = (uint32_t)prng_uint32(); + if (r >= min) + break; + } + + return r % upper_bound; +} diff --git a/fuzz/wiredata_fido2.h b/fuzz/wiredata_fido2.h new file mode 100644 index 0000000..6c66c54 --- /dev/null +++ b/fuzz/wiredata_fido2.h @@ -0,0 +1,708 @@ +/* + * Copyright (c) 2020-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _WIREDATA_FIDO2_H +#define _WIREDATA_FIDO2_H + +#define WIREDATA_CTAP_INIT \ + 0xff, 0xff, 0xff, 0xff, 0x86, 0x00, 0x11, 0x80, \ + 0x43, 0x56, 0x40, 0xb1, 0x4e, 0xd9, 0x2d, 0x00, \ + 0x22, 0x00, 0x02, 0x02, 0x05, 0x02, 0x01, 0x05, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_KEEPALIVE \ + 0x00, 0x22, 0x00, 0x02, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_INFO \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0xb9, 0x00, \ + 0xa9, 0x01, 0x83, 0x66, 0x55, 0x32, 0x46, 0x5f, \ + 0x56, 0x32, 0x68, 0x46, 0x49, 0x44, 0x4f, 0x5f, \ + 0x32, 0x5f, 0x30, 0x6c, 0x46, 0x49, 0x44, 0x4f, \ + 0x5f, 0x32, 0x5f, 0x31, 0x5f, 0x50, 0x52, 0x45, \ + 0x02, 0x82, 0x6b, 0x63, 0x72, 0x65, 0x64, 0x50, \ + 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x6b, 0x68, \ + 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x65, 0x63, 0x72, \ + 0x00, 0x22, 0x00, 0x02, 0x00, 0x65, 0x74, 0x03, \ + 0x50, 0x19, 0x56, 0xe5, 0xbd, 0xa3, 0x74, 0x45, \ + 0xf1, 0xa8, 0x14, 0x35, 0x64, 0x03, 0xfd, 0xbc, \ + 0x18, 0x04, 0xa5, 0x62, 0x72, 0x6b, 0xf5, 0x62, \ + 0x75, 0x70, 0xf5, 0x64, 0x70, 0x6c, 0x61, 0x74, \ + 0xf4, 0x69, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, \ + 0x50, 0x69, 0x6e, 0xf4, 0x75, 0x63, 0x72, 0x65, \ + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x4d, \ + 0x00, 0x22, 0x00, 0x02, 0x01, 0x67, 0x6d, 0x74, \ + 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0xf5, \ + 0x05, 0x19, 0x04, 0xb0, 0x06, 0x81, 0x01, 0x07, \ + 0x08, 0x08, 0x18, 0x80, 0x0a, 0x82, 0xa2, 0x63, \ + 0x61, 0x6c, 0x67, 0x26, 0x64, 0x74, 0x79, 0x70, \ + 0x65, 0x6a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, \ + 0x2d, 0x6b, 0x65, 0x79, 0xa2, 0x63, 0x61, 0x6c, \ + 0x67, 0x27, 0x64, 0x74, 0x79, 0x70, 0x65, 0x6a, \ + 0x00, 0x22, 0x00, 0x02, 0x02, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_AUTHKEY \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0x51, 0x00, \ + 0xa1, 0x01, 0xa5, 0x01, 0x02, 0x03, 0x38, 0x18, \ + 0x20, 0x01, 0x21, 0x58, 0x20, 0x2a, 0xb8, 0x2d, \ + 0x36, 0x69, 0xab, 0x30, 0x9d, 0xe3, 0x5e, 0x9b, \ + 0xfb, 0x94, 0xfc, 0x1d, 0x92, 0x95, 0xaf, 0x01, \ + 0x47, 0xfe, 0x4b, 0x87, 0xe5, 0xcf, 0x3f, 0x05, \ + 0x0b, 0x39, 0xda, 0x17, 0x49, 0x22, 0x58, 0x20, \ + 0x15, 0x1b, 0xbe, 0x08, 0x78, 0x60, 0x4d, 0x3c, \ + 0x00, 0x22, 0x00, 0x02, 0x00, 0x3f, 0xf1, 0x60, \ + 0xa6, 0xd8, 0xf8, 0xed, 0xce, 0x4a, 0x30, 0x5d, \ + 0x1a, 0xaf, 0x80, 0xc4, 0x0a, 0xd2, 0x6f, 0x77, \ + 0x38, 0x12, 0x97, 0xaa, 0xbd, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_PINTOKEN \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0x14, 0x00, \ + 0xa1, 0x02, 0x50, 0xee, 0x40, 0x4c, 0x85, 0xd7, \ + 0xa1, 0x2f, 0x56, 0xc4, 0x4e, 0xc5, 0x93, 0x41, \ + 0xd0, 0x3b, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_STATUS \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0x01, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_RETRIES \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0x04, 0x00, \ + 0xa1, 0x03, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_ASSERT \ + 0x00, 0x22, 0x00, 0x02, 0x90, 0x00, 0xcb, 0x00, \ + 0xa3, 0x01, 0xa2, 0x62, 0x69, 0x64, 0x58, 0x40, \ + 0x4a, 0x4c, 0x9e, 0xcc, 0x81, 0x7d, 0x42, 0x03, \ + 0x2b, 0x41, 0xd1, 0x38, 0xd3, 0x49, 0xb4, 0xfc, \ + 0xfb, 0xe4, 0x4e, 0xe4, 0xff, 0x76, 0x34, 0x16, \ + 0x68, 0x06, 0x9d, 0xa6, 0x01, 0x32, 0xb9, 0xff, \ + 0xc2, 0x35, 0x0d, 0x89, 0x43, 0x66, 0x12, 0xf8, \ + 0x8e, 0x5b, 0xde, 0xf4, 0xcc, 0xec, 0x9d, 0x03, \ + 0x00, 0x92, 0x00, 0x0e, 0x00, 0x85, 0xc2, 0xf5, \ + 0xe6, 0x8e, 0xeb, 0x3f, 0x3a, 0xec, 0xc3, 0x1d, \ + 0x04, 0x6e, 0xf3, 0x5b, 0x88, 0x64, 0x74, 0x79, \ + 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, 0x6c, 0x69, \ + 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x02, 0x58, 0x25, \ + 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, 0x8c, 0x68, \ + 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, 0x60, 0x5b, \ + 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, 0x32, 0xc7, \ + 0x00, 0x92, 0x00, 0x0e, 0x01, 0x99, 0x5c, 0xf3, \ + 0xba, 0x83, 0x1d, 0x97, 0x63, 0x04, 0x00, 0x00, \ + 0x00, 0x09, 0x03, 0x58, 0x47, 0x30, 0x45, 0x02, \ + 0x21, 0x00, 0xcf, 0x3f, 0x36, 0x0e, 0x1f, 0x6f, \ + 0xd6, 0xa0, 0x9d, 0x13, 0xcf, 0x55, 0xf7, 0x49, \ + 0x8f, 0xc8, 0xc9, 0x03, 0x12, 0x76, 0x41, 0x75, \ + 0x7b, 0xb5, 0x0a, 0x90, 0xa5, 0x82, 0x26, 0xf1, \ + 0x6b, 0x80, 0x02, 0x20, 0x34, 0x9b, 0x7a, 0x82, \ + 0x00, 0x92, 0x00, 0x0e, 0x02, 0xd3, 0xe1, 0x79, \ + 0x49, 0x55, 0x41, 0x9f, 0xa4, 0x06, 0x06, 0xbd, \ + 0xc8, 0xb9, 0x2b, 0x5f, 0xe1, 0xa7, 0x99, 0x1c, \ + 0xa1, 0xfc, 0x7e, 0x3e, 0xd5, 0x85, 0x2e, 0x11, \ + 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_CRED \ + 0x00, 0x91, 0x00, 0x03, 0x90, 0x03, 0xe1, 0x00, \ + 0xa3, 0x01, 0x66, 0x70, 0x61, 0x63, 0x6b, 0x65, \ + 0x64, 0x02, 0x58, 0xc4, 0x49, 0x96, 0x0d, 0xe5, \ + 0x88, 0x0e, 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, \ + 0x64, 0x76, 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, \ + 0xa2, 0x86, 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, \ + 0x83, 0x1d, 0x97, 0x63, 0x45, 0x00, 0x00, 0x00, \ + 0x00, 0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, \ + 0x00, 0x91, 0x00, 0x03, 0x00, 0x15, 0x80, 0x06, \ + 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x00, 0x40, \ + 0xed, 0x88, 0x48, 0xa1, 0xdb, 0x56, 0x4d, 0x0f, \ + 0x0d, 0xc8, 0x8f, 0x0f, 0xe9, 0x16, 0xb1, 0x78, \ + 0xa9, 0x40, 0x98, 0x71, 0xa0, 0xb3, 0xf2, 0xcf, \ + 0x05, 0x73, 0x6c, 0x12, 0xbf, 0x00, 0x96, 0xf3, \ + 0x7b, 0x93, 0xba, 0x49, 0xee, 0x23, 0xb4, 0x78, \ + 0x2e, 0xfb, 0xce, 0x27, 0xa8, 0xc2, 0x26, 0x78, \ + 0x00, 0x91, 0x00, 0x03, 0x01, 0xcc, 0x95, 0x2d, \ + 0x40, 0xdb, 0xd1, 0x40, 0x3d, 0x2b, 0xa3, 0x31, \ + 0xa0, 0x75, 0x82, 0x63, 0xf0, 0xa5, 0x01, 0x02, \ + 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0x9d, \ + 0x95, 0xa1, 0xb5, 0xd6, 0x11, 0xbf, 0xe2, 0x28, \ + 0xa0, 0x7f, 0xca, 0x1e, 0xd9, 0x09, 0x0f, 0x0d, \ + 0xe7, 0x8e, 0x29, 0xe8, 0x2e, 0x11, 0xdb, 0x55, \ + 0x62, 0x13, 0xd7, 0x26, 0xc2, 0x7e, 0x2b, 0x22, \ + 0x00, 0x91, 0x00, 0x03, 0x02, 0x58, 0x20, 0xbe, \ + 0x74, 0x2a, 0xac, 0xde, 0x11, 0x40, 0x76, 0x31, \ + 0x0b, 0xed, 0x55, 0xde, 0xf3, 0x03, 0xe4, 0x1c, \ + 0xac, 0x42, 0x63, 0x8f, 0xe8, 0x30, 0x63, 0xb7, \ + 0x07, 0x4e, 0x5d, 0xfb, 0x17, 0x5e, 0x9b, 0x03, \ + 0xa3, 0x63, 0x61, 0x6c, 0x67, 0x26, 0x63, 0x73, \ + 0x69, 0x67, 0x58, 0x48, 0x30, 0x46, 0x02, 0x21, \ + 0x00, 0xfb, 0xd1, 0x26, 0x76, 0x34, 0x74, 0xac, \ + 0x00, 0x91, 0x00, 0x03, 0x03, 0xf6, 0xd8, 0x5c, \ + 0x5d, 0xbc, 0xda, 0xe0, 0x43, 0xe0, 0xa5, 0x42, \ + 0x9f, 0xc7, 0xe2, 0x18, 0x3e, 0xe2, 0x2c, 0x94, \ + 0x78, 0xbf, 0x9c, 0xeb, 0x3e, 0x9d, 0x02, 0x21, \ + 0x00, 0xab, 0x21, 0x1b, 0xc4, 0x30, 0x69, 0xee, \ + 0x7f, 0x09, 0xe6, 0x6b, 0x99, 0x98, 0x34, 0x07, \ + 0x7b, 0x9a, 0x58, 0xb2, 0xe8, 0x77, 0xe0, 0xba, \ + 0x7d, 0xab, 0x65, 0xf8, 0xba, 0x2a, 0xcb, 0x9a, \ + 0x00, 0x91, 0x00, 0x03, 0x04, 0x41, 0x63, 0x78, \ + 0x35, 0x63, 0x81, 0x59, 0x02, 0xb3, 0x30, 0x82, \ + 0x02, 0xaf, 0x30, 0x82, 0x01, 0x97, 0xa0, 0x03, \ + 0x02, 0x01, 0x02, 0x02, 0x04, 0x48, 0x5b, 0x3d, \ + 0xb6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, \ + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, \ + 0x30, 0x21, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, \ + 0x55, 0x04, 0x03, 0x0c, 0x16, 0x59, 0x75, 0x62, \ + 0x00, 0x91, 0x00, 0x03, 0x05, 0x69, 0x63, 0x6f, \ + 0x20, 0x46, 0x49, 0x44, 0x4f, 0x20, 0x50, 0x72, \ + 0x65, 0x76, 0x69, 0x65, 0x77, 0x20, 0x43, 0x41, \ + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x34, \ + 0x31, 0x32, 0x31, 0x30, 0x35, 0x37, 0x31, 0x30, \ + 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x31, 0x32, 0x33, \ + 0x31, 0x31, 0x30, 0x35, 0x37, 0x31, 0x30, 0x5a, \ + 0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ + 0x00, 0x91, 0x00, 0x03, 0x06, 0x55, 0x04, 0x06, \ + 0x13, 0x02, 0x53, 0x45, 0x31, 0x12, 0x30, 0x10, \ + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x59, \ + 0x75, 0x62, 0x69, 0x63, 0x6f, 0x20, 0x41, 0x42, \ + 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, \ + 0x0b, 0x0c, 0x19, 0x41, 0x75, 0x74, 0x68, 0x65, \ + 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, \ + 0x20, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, \ + 0x00, 0x91, 0x00, 0x03, 0x07, 0x74, 0x69, 0x6f, \ + 0x6e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, \ + 0x04, 0x03, 0x0c, 0x1f, 0x59, 0x75, 0x62, 0x69, \ + 0x63, 0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x45, \ + 0x45, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, \ + 0x20, 0x31, 0x32, 0x31, 0x33, 0x39, 0x33, 0x39, \ + 0x31, 0x32, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, \ + 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, \ + 0x00, 0x91, 0x00, 0x03, 0x08, 0x06, 0x08, 0x2a, \ + 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, \ + 0x42, 0x00, 0x04, 0xfb, 0x2c, 0xdd, 0x30, 0x43, \ + 0x28, 0xc5, 0x72, 0x4a, 0x50, 0xcc, 0xe6, 0xf6, \ + 0x0b, 0xad, 0x7d, 0x27, 0xa9, 0x1b, 0x59, 0xe1, \ + 0xe6, 0x6f, 0x29, 0x7b, 0x89, 0xc9, 0xd4, 0x3d, \ + 0xc2, 0xb2, 0xc7, 0x78, 0x89, 0xb4, 0xf0, 0xff, \ + 0x9d, 0x02, 0x28, 0xcb, 0x94, 0x6d, 0xfc, 0xe0, \ + 0x00, 0x91, 0x00, 0x03, 0x09, 0x1b, 0x19, 0x58, \ + 0x9b, 0x67, 0x80, 0x4a, 0xac, 0x97, 0x7f, 0x28, \ + 0x18, 0x9c, 0xcd, 0xb3, 0x25, 0x74, 0xca, 0x28, \ + 0xa3, 0x6c, 0x30, 0x6a, 0x30, 0x22, 0x06, 0x09, \ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xc4, 0x0a, \ + 0x02, 0x04, 0x15, 0x31, 0x2e, 0x33, 0x2e, 0x36, \ + 0x2e, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e, 0x34, \ + 0x31, 0x34, 0x38, 0x32, 0x2e, 0x31, 0x2e, 0x36, \ + 0x00, 0x91, 0x00, 0x03, 0x0a, 0x30, 0x13, 0x06, \ + 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xe5, \ + 0x1c, 0x02, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, \ + 0x04, 0x30, 0x30, 0x21, 0x06, 0x0b, 0x2b, 0x06, \ + 0x01, 0x04, 0x01, 0x82, 0xe5, 0x1c, 0x01, 0x01, \ + 0x04, 0x04, 0x12, 0x04, 0x10, 0xf8, 0xa0, 0x11, \ + 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, \ + 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x30, 0x0c, 0x06, \ + 0x00, 0x91, 0x00, 0x03, 0x0b, 0x03, 0x55, 0x1d, \ + 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, \ + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, \ + 0x82, 0x01, 0x01, 0x00, 0x32, 0xf3, 0xe4, 0xbd, \ + 0x58, 0xd7, 0x42, 0x2b, 0xaf, 0x49, 0x99, 0x86, \ + 0x08, 0x1f, 0x0d, 0xa9, 0x3b, 0xc6, 0xaa, 0x1c, \ + 0x72, 0x11, 0xf9, 0x28, 0x53, 0xeb, 0xf3, 0xeb, \ + 0x00, 0x91, 0x00, 0x03, 0x0c, 0x73, 0xda, 0x69, \ + 0x3b, 0x06, 0xde, 0x31, 0x33, 0x8e, 0x5d, 0x02, \ + 0xec, 0xf6, 0x76, 0xe9, 0x5c, 0x42, 0xbe, 0xa5, \ + 0x8f, 0x25, 0xd3, 0x37, 0x3f, 0x77, 0xbb, 0x2a, \ + 0x9d, 0x7c, 0xb2, 0x3e, 0x11, 0x8c, 0x41, 0xd4, \ + 0x9a, 0x4c, 0x9a, 0xd8, 0xf3, 0xe2, 0xa4, 0xec, \ + 0x01, 0x77, 0x7a, 0x74, 0xa8, 0xc4, 0x12, 0x43, \ + 0xc3, 0x1e, 0xce, 0x20, 0x8f, 0x2d, 0x0f, 0x6e, \ + 0x00, 0x91, 0x00, 0x03, 0x0d, 0xbc, 0x61, 0x9b, \ + 0xe1, 0x84, 0xa1, 0x72, 0xf6, 0xa9, 0xac, 0xcb, \ + 0xf8, 0x73, 0x6d, 0x5b, 0xe2, 0x98, 0xb3, 0x6b, \ + 0xec, 0xe7, 0x1e, 0x77, 0x8d, 0x0a, 0x69, 0xaa, \ + 0xf9, 0x94, 0xb8, 0x63, 0x6d, 0xe8, 0xfa, 0xf6, \ + 0x2f, 0xd3, 0xce, 0x7f, 0x04, 0x4c, 0x32, 0x2c, \ + 0xf7, 0x26, 0x3e, 0x34, 0x99, 0xe6, 0xa5, 0xb2, \ + 0xb0, 0x2a, 0xbb, 0xad, 0x5b, 0xd9, 0xec, 0xe5, \ + 0x00, 0x91, 0x00, 0x03, 0x0e, 0xb0, 0x71, 0x4d, \ + 0x73, 0xbb, 0x94, 0x61, 0x49, 0x9c, 0x94, 0x2a, \ + 0x5f, 0x1d, 0xcc, 0xaf, 0x65, 0x03, 0x3b, 0x39, \ + 0x39, 0xd4, 0x47, 0xd9, 0xfc, 0xc4, 0x7b, 0x0b, \ + 0x16, 0xd8, 0xe9, 0x01, 0xfc, 0xec, 0x3f, 0x8c, \ + 0x1b, 0xc0, 0xc6, 0xac, 0x0b, 0x5d, 0x74, 0xc7, \ + 0xbb, 0x03, 0x05, 0x69, 0x17, 0xe9, 0x98, 0x1a, \ + 0x19, 0xb9, 0x09, 0x5c, 0xa1, 0xf4, 0xab, 0x9f, \ + 0x00, 0x91, 0x00, 0x03, 0x0f, 0x02, 0x7c, 0x28, \ + 0x0f, 0x8a, 0xf9, 0xed, 0x1d, 0x29, 0x3c, 0xf6, \ + 0xcc, 0x2f, 0x04, 0x6d, 0x9a, 0xd6, 0x62, 0xb4, \ + 0xa9, 0x6e, 0xb1, 0xca, 0xca, 0xac, 0x5e, 0x05, \ + 0x3e, 0x83, 0x91, 0x47, 0x7c, 0x1f, 0x8b, 0x60, \ + 0x01, 0xde, 0x65, 0x3a, 0xbf, 0xf2, 0xaa, 0xbb, \ + 0x55, 0x98, 0x86, 0x91, 0x7e, 0xad, 0x3b, 0x36, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_CREDMAN_META \ + 0x00, 0x12, 0x00, 0x04, 0x90, 0x00, 0x07, 0x00, \ + 0xa2, 0x01, 0x00, 0x02, 0x18, 0x19, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_CREDMAN_RPLIST \ + 0x00, 0x15, 0x00, 0x02, 0x90, 0x00, 0x37, 0x00, \ + 0xa3, 0x03, 0xa1, 0x62, 0x69, 0x64, 0x6a, 0x79, \ + 0x75, 0x62, 0x69, 0x63, 0x6f, 0x2e, 0x63, 0x6f, \ + 0x6d, 0x04, 0x58, 0x20, 0x37, 0x82, 0x09, 0xb7, \ + 0x2d, 0xef, 0xcb, 0xa9, 0x1d, 0xcb, 0xf8, 0x54, \ + 0xed, 0xb4, 0xda, 0xa6, 0x48, 0x82, 0x8a, 0x2c, \ + 0xbd, 0x18, 0x0a, 0xfc, 0x77, 0xa7, 0x44, 0x34, \ + 0x65, 0x5a, 0x1c, 0x7d, 0x05, 0x03, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x02, 0x90, 0x00, 0x36, 0x00, \ + 0xa2, 0x03, 0xa1, 0x62, 0x69, 0x64, 0x6b, 0x79, \ + 0x75, 0x62, 0x69, 0x6b, 0x65, 0x79, 0x2e, 0x6f, \ + 0x72, 0x67, 0x04, 0x58, 0x20, 0x12, 0x6b, 0xba, \ + 0x6a, 0x2d, 0x7a, 0x81, 0x84, 0x25, 0x7b, 0x74, \ + 0xdd, 0x1d, 0xdd, 0x46, 0xb6, 0x2a, 0x8c, 0xa2, \ + 0xa7, 0x83, 0xfe, 0xdb, 0x5b, 0x19, 0x48, 0x73, \ + 0x55, 0xb7, 0xe3, 0x46, 0x09, 0x00, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x02, 0x90, 0x00, 0x37, 0x00, \ + 0xa2, 0x03, 0xa1, 0x62, 0x69, 0x64, 0x6c, 0x77, \ + 0x65, 0x62, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x2e, \ + 0x64, 0x65, 0x76, 0x04, 0x58, 0x20, 0xd6, 0x32, \ + 0x7d, 0x8c, 0x6a, 0x5d, 0xe6, 0xae, 0x0e, 0x33, \ + 0xd0, 0xa3, 0x31, 0xfb, 0x67, 0x77, 0xb9, 0x4e, \ + 0xf4, 0x73, 0x19, 0xfe, 0x7e, 0xfd, 0xfa, 0x82, \ + 0x70, 0x8e, 0x1f, 0xbb, 0xa2, 0x55, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_CREDMAN_RKLIST \ + 0x00, 0x15, 0x00, 0x04, 0x90, 0x00, 0xc5, 0x00, \ + 0xa5, 0x06, 0xa3, 0x62, 0x69, 0x64, 0x58, 0x20, \ + 0xe4, 0xe1, 0x06, 0x31, 0xde, 0x00, 0x0f, 0x4f, \ + 0x12, 0x6e, 0xc9, 0x68, 0x2d, 0x43, 0x3f, 0xf1, \ + 0x02, 0x2c, 0x6e, 0xe6, 0x96, 0x10, 0xbf, 0x73, \ + 0x35, 0xc9, 0x20, 0x27, 0x06, 0xba, 0x39, 0x09, \ + 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x6a, 0x62, 0x6f, \ + 0x62, 0x20, 0x62, 0x61, 0x6e, 0x61, 0x6e, 0x61, \ + 0x00, 0x15, 0x00, 0x04, 0x00, 0x6b, 0x64, 0x69, \ + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, \ + 0x65, 0x67, 0x62, 0x62, 0x61, 0x6e, 0x61, 0x6e, \ + 0x61, 0x07, 0xa2, 0x62, 0x69, 0x64, 0x50, 0x19, \ + 0xf7, 0x78, 0x0c, 0xa0, 0xbc, 0xb9, 0xa6, 0xd5, \ + 0x1e, 0xd7, 0x87, 0xfb, 0x6c, 0x80, 0x03, 0x64, \ + 0x74, 0x79, 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x08, \ + 0x00, 0x15, 0x00, 0x04, 0x01, 0xa5, 0x01, 0x02, \ + 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0x81, \ + 0x6c, 0xdd, 0x8c, 0x8f, 0x8c, 0xc8, 0x43, 0xa7, \ + 0xbb, 0x79, 0x51, 0x09, 0xb1, 0xdf, 0xbe, 0xc4, \ + 0xa5, 0x54, 0x16, 0x9e, 0x58, 0x56, 0xb3, 0x0b, \ + 0x34, 0x4f, 0xa5, 0x6c, 0x05, 0xa2, 0x21, 0x22, \ + 0x58, 0x20, 0xcd, 0xc2, 0x0c, 0x99, 0x83, 0x5a, \ + 0x61, 0x73, 0xd8, 0xe0, 0x74, 0x23, 0x46, 0x64, \ + 0x00, 0x15, 0x00, 0x04, 0x02, 0x39, 0x4c, 0xb0, \ + 0xf4, 0x6c, 0x0a, 0x37, 0x72, 0xaa, 0xa8, 0xea, \ + 0x58, 0xd3, 0xd4, 0xe0, 0x51, 0xb2, 0x28, 0x09, \ + 0x05, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x04, 0x90, 0x00, 0xa0, 0x00, \ + 0xa4, 0x06, 0xa3, 0x62, 0x69, 0x64, 0x58, 0x20, \ + 0x56, 0xa1, 0x3c, 0x06, 0x2b, 0xad, 0xa2, 0x21, \ + 0x7d, 0xcd, 0x91, 0x08, 0x47, 0xa8, 0x8a, 0x06, \ + 0x06, 0xf6, 0x66, 0x91, 0xf6, 0xeb, 0x89, 0xe4, \ + 0xdf, 0x26, 0xbc, 0x46, 0x59, 0xc3, 0x7d, 0xc0, \ + 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x6a, 0x62, 0x6f, \ + 0x62, 0x20, 0x62, 0x61, 0x6e, 0x61, 0x6e, 0x61, \ + 0x00, 0x15, 0x00, 0x04, 0x00, 0x6b, 0x64, 0x69, \ + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, \ + 0x65, 0x67, 0x62, 0x62, 0x61, 0x6e, 0x61, 0x6e, \ + 0x61, 0x07, 0xa2, 0x62, 0x69, 0x64, 0x50, 0xd8, \ + 0x27, 0x4b, 0x25, 0xed, 0x19, 0xef, 0x11, 0xaf, \ + 0xa6, 0x89, 0x7b, 0x84, 0x50, 0xe7, 0x62, 0x64, \ + 0x74, 0x79, 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x08, \ + 0x00, 0x15, 0x00, 0x04, 0x01, 0xa4, 0x01, 0x01, \ + 0x03, 0x27, 0x20, 0x06, 0x21, 0x58, 0x20, 0x8d, \ + 0xfe, 0x45, 0xd5, 0x7d, 0xb6, 0x17, 0xab, 0x86, \ + 0x2d, 0x32, 0xf6, 0x85, 0xf0, 0x92, 0x76, 0xb7, \ + 0xce, 0x73, 0xca, 0x4e, 0x0e, 0xfd, 0xd5, 0xdb, \ + 0x2a, 0x1d, 0x55, 0x90, 0x96, 0x52, 0xc2, 0x0a, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x04, 0x90, 0x00, 0xa0, 0x00, \ + 0xa4, 0x06, 0xa3, 0x62, 0x69, 0x64, 0x58, 0x20, \ + 0x04, 0x0e, 0x0f, 0xa0, 0xcd, 0x60, 0x35, 0x9a, \ + 0xba, 0x47, 0x0c, 0x10, 0xb6, 0x82, 0x6e, 0x2f, \ + 0x66, 0xb9, 0xa7, 0xcf, 0xd8, 0x47, 0xb4, 0x3d, \ + 0xfd, 0x77, 0x1a, 0x38, 0x22, 0xa1, 0xda, 0xa5, \ + 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x6a, 0x62, 0x6f, \ + 0x62, 0x20, 0x62, 0x61, 0x6e, 0x61, 0x6e, 0x61, \ + 0x00, 0x15, 0x00, 0x04, 0x00, 0x6b, 0x64, 0x69, \ + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, \ + 0x65, 0x67, 0x62, 0x62, 0x61, 0x6e, 0x61, 0x6e, \ + 0x61, 0x07, 0xa2, 0x62, 0x69, 0x64, 0x50, 0x00, \ + 0x5d, 0xdf, 0xef, 0xe2, 0xf3, 0x06, 0xb2, 0xa5, \ + 0x46, 0x4d, 0x98, 0xbc, 0x14, 0x65, 0xc1, 0x64, \ + 0x74, 0x79, 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x08, \ + 0x00, 0x15, 0x00, 0x04, 0x01, 0xa4, 0x01, 0x01, \ + 0x03, 0x27, 0x20, 0x06, 0x21, 0x58, 0x20, 0x72, \ + 0x79, 0x14, 0x69, 0xdf, 0xcb, 0x64, 0x75, 0xee, \ + 0xd4, 0x45, 0x94, 0xbc, 0x48, 0x4d, 0x2a, 0x9f, \ + 0xc9, 0xf4, 0xb5, 0x1b, 0x05, 0xa6, 0x5b, 0x54, \ + 0x9a, 0xac, 0x6c, 0x2e, 0xc6, 0x90, 0x62, 0x0a, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x04, 0x90, 0x00, 0xc3, 0x00, \ + 0xa4, 0x06, 0xa3, 0x62, 0x69, 0x64, 0x58, 0x20, \ + 0xce, 0x32, 0xd8, 0x79, 0xdd, 0x86, 0xa2, 0x42, \ + 0x7c, 0xc3, 0xe1, 0x95, 0x12, 0x93, 0x1a, 0x03, \ + 0xe6, 0x70, 0xb8, 0xff, 0xcd, 0xa5, 0xdf, 0x15, \ + 0xfc, 0x88, 0x2a, 0xf5, 0x44, 0xf1, 0x33, 0x9c, \ + 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x6a, 0x62, 0x6f, \ + 0x62, 0x20, 0x62, 0x61, 0x6e, 0x61, 0x6e, 0x61, \ + 0x00, 0x15, 0x00, 0x04, 0x00, 0x6b, 0x64, 0x69, \ + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, \ + 0x65, 0x67, 0x62, 0x62, 0x61, 0x6e, 0x61, 0x6e, \ + 0x61, 0x07, 0xa2, 0x62, 0x69, 0x64, 0x50, 0x0a, \ + 0x26, 0x5b, 0x7e, 0x1a, 0x2a, 0xba, 0x70, 0x5f, \ + 0x18, 0x26, 0x14, 0xb2, 0x71, 0xca, 0x98, 0x64, \ + 0x74, 0x79, 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x08, \ + 0x00, 0x15, 0x00, 0x04, 0x01, 0xa5, 0x01, 0x02, \ + 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0x8b, \ + 0x48, 0xf0, 0x69, 0xfb, 0x22, 0xfb, 0xf3, 0x86, \ + 0x57, 0x7c, 0xdd, 0x82, 0x2c, 0x1c, 0x0c, 0xdc, \ + 0x27, 0xe2, 0x6a, 0x4c, 0x1a, 0x10, 0x04, 0x27, \ + 0x51, 0x3e, 0x2a, 0x9d, 0x3a, 0xb6, 0xb5, 0x22, \ + 0x58, 0x20, 0x70, 0xfe, 0x91, 0x67, 0x64, 0x53, \ + 0x63, 0x83, 0x72, 0x31, 0xe9, 0xe5, 0x20, 0xb7, \ + 0x00, 0x15, 0x00, 0x04, 0x02, 0xee, 0xc9, 0xfb, \ + 0x63, 0xd7, 0xe4, 0x76, 0x39, 0x80, 0x82, 0x74, \ + 0xb8, 0xfa, 0x67, 0xf5, 0x1b, 0x8f, 0xe0, 0x0a, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x15, 0x00, 0x04, 0x90, 0x00, 0xc3, 0x00, \ + 0xa4, 0x06, 0xa3, 0x62, 0x69, 0x64, 0x58, 0x20, \ + 0xf9, 0xa3, 0x67, 0xbf, 0x5e, 0x80, 0x95, 0xdb, \ + 0x4c, 0xc5, 0x8f, 0x65, 0x36, 0xc5, 0xaf, 0xdd, \ + 0x90, 0x2e, 0x62, 0x68, 0x67, 0x9c, 0xa2, 0x26, \ + 0x2f, 0x2a, 0xf9, 0x3a, 0xda, 0x15, 0xf2, 0x27, \ + 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x6a, 0x62, 0x6f, \ + 0x62, 0x20, 0x62, 0x61, 0x6e, 0x61, 0x6e, 0x61, \ + 0x00, 0x15, 0x00, 0x04, 0x00, 0x6b, 0x64, 0x69, \ + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, \ + 0x65, 0x67, 0x62, 0x62, 0x61, 0x6e, 0x61, 0x6e, \ + 0x61, 0x07, 0xa2, 0x62, 0x69, 0x64, 0x50, 0xfb, \ + 0xa6, 0xbe, 0xc1, 0x01, 0xf6, 0x7a, 0x81, 0xf9, \ + 0xcd, 0x6d, 0x20, 0x41, 0x7a, 0x1c, 0x40, 0x64, \ + 0x74, 0x79, 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, \ + 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x08, \ + 0x00, 0x15, 0x00, 0x04, 0x01, 0xa5, 0x01, 0x02, \ + 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0xda, \ + 0x2b, 0x53, 0xc3, 0xbe, 0x48, 0xf8, 0xab, 0xbd, \ + 0x06, 0x28, 0x46, 0xfa, 0x35, 0xab, 0xf9, 0xc5, \ + 0x2e, 0xfd, 0x3c, 0x38, 0x88, 0xb3, 0xe1, 0xa7, \ + 0xc5, 0xc6, 0xed, 0x72, 0x54, 0x37, 0x93, 0x22, \ + 0x58, 0x20, 0x12, 0x82, 0x32, 0x2d, 0xab, 0xbc, \ + 0x64, 0xb3, 0xed, 0xcc, 0xd5, 0x22, 0xec, 0x79, \ + 0x00, 0x15, 0x00, 0x04, 0x02, 0x4b, 0xe2, 0x4d, \ + 0x0c, 0x4b, 0x8d, 0x31, 0x4c, 0xb4, 0x0f, 0xd4, \ + 0xa9, 0xbe, 0x0c, 0xab, 0x9e, 0x0a, 0xc9, 0x0a, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_BIO_INFO \ + 0x00, 0x10, 0x00, 0x04, 0x90, 0x00, 0x06, 0x00, \ + 0xa2, 0x02, 0x01, 0x03, 0x04, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_BIO_ENROLL \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0x90, 0x00, 0x0a, 0x00, \ + 0xa3, 0x04, 0x42, 0x68, 0x96, 0x05, 0x00, 0x06, \ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0x90, 0x00, 0x06, 0x00, \ + 0xa2, 0x05, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0xbb, 0x00, 0x01, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x0a, 0x00, 0x05, 0x90, 0x00, 0x06, 0x00, \ + 0xa2, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_BIO_ENUM \ + 0x00, 0x10, 0x00, 0x0f, 0x90, 0x00, 0x2e, 0x00, \ + 0xa1, 0x07, 0x83, 0xa2, 0x01, 0x42, 0xce, 0xa3, \ + 0x02, 0x67, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, \ + 0x31, 0xa2, 0x01, 0x42, 0xbf, 0x5e, 0x02, 0x67, \ + 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x32, 0xa2, \ + 0x01, 0x42, 0x5e, 0xd2, 0x02, 0x67, 0x66, 0x69, \ + 0x6e, 0x67, 0x65, 0x72, 0x33, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY \ + 0x89, 0xc9, 0x8d, 0x28, 0x90, 0x01, 0xe6, 0x00, \ + 0xa1, 0x01, 0x59, 0x01, 0xe0, 0x81, 0xa3, 0x01, \ + 0x59, 0x01, 0xb8, 0xb3, 0x26, 0x24, 0x99, 0xde, \ + 0x06, 0x3f, 0xca, 0xde, 0x98, 0x8d, 0x9d, 0xc5, \ + 0x3f, 0x26, 0x6c, 0xc7, 0x40, 0x93, 0xc4, 0x88, \ + 0x06, 0x51, 0x4f, 0xb9, 0x61, 0xf2, 0xc9, 0x8d, \ + 0xbc, 0xce, 0x79, 0x08, 0xec, 0x90, 0xc5, 0x5b, \ + 0xe5, 0x0a, 0x72, 0x08, 0x7b, 0xe1, 0xf9, 0x16, \ + 0x89, 0xc9, 0x8d, 0x28, 0x00, 0x06, 0x8b, 0x76, \ + 0x32, 0xa0, 0xae, 0x55, 0xb2, 0x39, 0x71, 0xce, \ + 0x34, 0x4b, 0x6e, 0x6b, 0x89, 0xa6, 0x5e, 0x69, \ + 0x07, 0xac, 0xf6, 0x01, 0x3c, 0xba, 0x45, 0x7a, \ + 0x75, 0x25, 0x3a, 0xbd, 0x95, 0x22, 0x9d, 0xc3, \ + 0xe4, 0x42, 0x31, 0x5c, 0xb5, 0xf4, 0x64, 0x6a, \ + 0x56, 0x1d, 0xab, 0xc7, 0x6e, 0x96, 0x75, 0xe7, \ + 0xb3, 0x22, 0x0b, 0x82, 0xac, 0x57, 0x78, 0xdf, \ + 0x89, 0xc9, 0x8d, 0x28, 0x01, 0x57, 0x06, 0xc5, \ + 0x4b, 0x61, 0x0b, 0x4d, 0xa1, 0x66, 0xa0, 0x89, \ + 0xad, 0x19, 0x8f, 0xd8, 0x96, 0x55, 0x22, 0x5f, \ + 0xca, 0x2e, 0xc1, 0xd7, 0xbd, 0xa1, 0x83, 0x66, \ + 0x4d, 0x85, 0xcb, 0x01, 0x60, 0x3f, 0xf7, 0xf7, \ + 0xa3, 0x7a, 0xfa, 0x99, 0xa0, 0x1e, 0x25, 0x90, \ + 0xd0, 0xd0, 0x3b, 0x54, 0x90, 0x77, 0x94, 0xa6, \ + 0x88, 0xea, 0xc3, 0x6b, 0xa0, 0x59, 0x5e, 0x69, \ + 0x89, 0xc9, 0x8d, 0x28, 0x02, 0x78, 0x0b, 0x2b, \ + 0xab, 0x5b, 0x04, 0x2f, 0x78, 0x15, 0x86, 0x2b, \ + 0x0f, 0x63, 0xb2, 0xd7, 0xc9, 0xe9, 0xac, 0x0e, \ + 0xbc, 0x17, 0xe4, 0x19, 0x88, 0xe0, 0xe6, 0x13, \ + 0xf8, 0x15, 0x08, 0xa7, 0xe1, 0x6e, 0x71, 0x5c, \ + 0xef, 0x3e, 0xc1, 0x0f, 0x74, 0xdb, 0xdc, 0x52, \ + 0x9c, 0xfc, 0xe9, 0xa9, 0xf3, 0x0d, 0x52, 0xbc, \ + 0x0c, 0xe8, 0xba, 0xd1, 0x76, 0x46, 0x87, 0xb5, \ + 0x89, 0xc9, 0x8d, 0x28, 0x03, 0x30, 0xe6, 0x9d, \ + 0xa1, 0x2b, 0xa5, 0x9e, 0x3b, 0x86, 0xb3, 0x5f, \ + 0xe3, 0x81, 0xa6, 0x76, 0x32, 0x9d, 0xf9, 0xc5, \ + 0x07, 0x93, 0xb3, 0xdf, 0x64, 0xe2, 0x78, 0x9c, \ + 0x00, 0xc7, 0x86, 0x79, 0xd6, 0x67, 0xa2, 0xfb, \ + 0xf2, 0x8d, 0xea, 0xe9, 0xc8, 0xfc, 0x43, 0xd2, \ + 0x0f, 0x2f, 0x7d, 0x9d, 0xd3, 0x8f, 0x9c, 0xdd, \ + 0xa2, 0x9f, 0x42, 0x76, 0x40, 0xcc, 0x4a, 0xd0, \ + 0x89, 0xc9, 0x8d, 0x28, 0x04, 0xb4, 0x87, 0x18, \ + 0x06, 0xc3, 0xc7, 0x89, 0x98, 0x72, 0xcc, 0x1a, \ + 0xd1, 0xd8, 0x78, 0xb9, 0x75, 0x0b, 0x92, 0xe3, \ + 0xcc, 0xed, 0x38, 0x39, 0x4b, 0xa9, 0xcf, 0x30, \ + 0xd6, 0xb5, 0xa1, 0x3f, 0xfa, 0x4f, 0x29, 0x99, \ + 0xa9, 0x03, 0x77, 0xf6, 0x53, 0xfa, 0xd8, 0x32, \ + 0xce, 0xf4, 0xf6, 0x0a, 0x3c, 0xe8, 0x9c, 0x3d, \ + 0xaa, 0xe0, 0x7b, 0x2c, 0xa5, 0x28, 0xe1, 0xdd, \ + 0x89, 0xc9, 0x8d, 0x28, 0x05, 0x51, 0xbf, 0xe1, \ + 0xd4, 0xf5, 0x5e, 0x38, 0x2c, 0xec, 0xab, 0xdd, \ + 0xb8, 0x5c, 0x13, 0x43, 0x62, 0xc2, 0xb6, 0x02, \ + 0x18, 0xce, 0x9a, 0x62, 0x67, 0x6a, 0xeb, 0x99, \ + 0xf6, 0x2f, 0xf1, 0xf1, 0xec, 0x3e, 0x74, 0xfa, \ + 0xf8, 0x16, 0x43, 0xea, 0x1e, 0xef, 0x5d, 0x37, \ + 0x6c, 0x13, 0xf9, 0x7f, 0x65, 0x09, 0xab, 0x60, \ + 0x38, 0xda, 0x0f, 0xe7, 0xfa, 0x9e, 0x17, 0x10, \ + 0x89, 0xc9, 0x8d, 0x28, 0x06, 0xdc, 0x4c, 0x4d, \ + 0xae, 0x5c, 0xb4, 0x0d, 0x6b, 0x05, 0x6d, 0x25, \ + 0x3f, 0x78, 0x5d, 0xf3, 0x34, 0x33, 0xa4, 0x89, \ + 0x34, 0x0e, 0x88, 0x66, 0x40, 0x57, 0x6b, 0x34, \ + 0x83, 0xfd, 0x39, 0xe7, 0xfb, 0x84, 0x09, 0xb3, \ + 0x16, 0x8f, 0x80, 0xdf, 0x1b, 0xe0, 0x02, 0x4c, \ + 0xde, 0x31, 0x2a, 0x32, 0x58, 0x5b, 0xa3, 0x23, \ + 0x8e, 0x2a, 0xa6, 0xaf, 0x03, 0x19, 0x02, 0x7a, \ + 0x89, 0xc9, 0x8d, 0x28, 0x07, 0xf8, 0xbf, 0xa6, \ + 0xad, 0xf9, 0xd1, 0xdc, 0xbd, 0x6e, 0xb3, 0xc1, \ + 0xfb, 0x65, 0xd8, 0x5f, 0x2e, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_NFC_INIT \ + 0x55, 0x32, 0x46, 0x5f, 0x56, 0x32, 0x90, 0x00 + +#define WIREDATA_CTAP_NFC_MSG \ + 0x90, 0x00, 0x90, 0x00, 0x90, 0x00, 0x90, 0x00 + +#define WIREDATA_CTAP_EXTENDED_APDU \ + 0x00, 0xa4, 0x04, 0x00, 0x00, 0x02, 0x00, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, \ + 0x00 + +#endif /* _WIREDATA_FIDO2_H */ diff --git a/fuzz/wiredata_u2f.h b/fuzz/wiredata_u2f.h new file mode 100644 index 0000000..3be22d3 --- /dev/null +++ b/fuzz/wiredata_u2f.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2020 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _WIREDATA_U2F_H +#define _WIREDATA_U2F_H + +#define WIREDATA_CTAP_U2F_6985 \ + 0x00, 0x00, 0x99, 0x01, 0x83, 0x00, 0x02, 0x69, \ + 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_U2F_AUTH \ + 0x00, 0x00, 0x99, 0x01, 0x83, 0x00, 0x4e, 0x01, \ + 0x00, 0x00, 0x00, 0x2c, 0x30, 0x45, 0x02, 0x20, \ + 0x1c, 0xf5, 0x7c, 0xf6, 0xde, 0xbe, 0xe9, 0x86, \ + 0xee, 0x97, 0xb7, 0x64, 0xa3, 0x4e, 0x7a, 0x70, \ + 0x85, 0xd0, 0x66, 0xf9, 0xf0, 0xcd, 0x04, 0x5d, \ + 0x97, 0xf2, 0x3c, 0x22, 0xe3, 0x0e, 0x61, 0xc8, \ + 0x02, 0x21, 0x00, 0x97, 0xef, 0xae, 0x36, 0xe6, \ + 0x17, 0x9f, 0x5e, 0x2d, 0xd7, 0x8c, 0x34, 0xa7, \ + 0x00, 0x00, 0x99, 0x01, 0x00, 0xa1, 0xe9, 0xfb, \ + 0x8f, 0x86, 0x8c, 0xe3, 0x1e, 0xde, 0x3f, 0x4e, \ + 0x1b, 0xe1, 0x2f, 0x8f, 0x2f, 0xca, 0x42, 0x26, \ + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define WIREDATA_CTAP_U2F_REGISTER \ + 0x00, 0x00, 0x99, 0x01, 0x83, 0x03, 0x1e, 0x05, \ + 0x04, 0x9f, 0xa0, 0xf9, 0x0d, 0x4c, 0xf4, 0xae, \ + 0x96, 0x3c, 0xb7, 0x46, 0xb7, 0x5c, 0x9d, 0x8b, \ + 0x48, 0x19, 0xdf, 0xc4, 0xad, 0xea, 0xb2, 0x70, \ + 0x58, 0x72, 0xd9, 0xce, 0x75, 0xf5, 0xe6, 0x8e, \ + 0x0f, 0x9c, 0x0e, 0x2e, 0x62, 0x3e, 0x91, 0xd3, \ + 0x7b, 0x97, 0x46, 0x60, 0xb9, 0x57, 0x13, 0x97, \ + 0x26, 0xae, 0x0f, 0xb3, 0x8f, 0x2e, 0x9b, 0x3f, \ + 0x00, 0x00, 0x99, 0x01, 0x00, 0xa5, 0x55, 0xec, \ + 0x8c, 0x25, 0x7c, 0x65, 0xb7, 0x09, 0x40, 0x48, \ + 0xae, 0xa8, 0xcb, 0xa1, 0x91, 0xac, 0x40, 0x24, \ + 0xf2, 0x34, 0x6e, 0x3a, 0x8f, 0xa5, 0xb7, 0x48, \ + 0x54, 0x6e, 0xfb, 0xf4, 0x37, 0x88, 0x69, 0x79, \ + 0x6f, 0x12, 0xc1, 0x32, 0xdf, 0x15, 0x5d, 0x6e, \ + 0x82, 0x54, 0xc0, 0x6e, 0x56, 0x4f, 0x3a, 0x9c, \ + 0xc3, 0x96, 0x7a, 0xde, 0xa5, 0xfe, 0xec, 0xd1, \ + 0x00, 0x00, 0x99, 0x01, 0x01, 0x5a, 0x21, 0x85, \ + 0x0e, 0x25, 0x7b, 0x8d, 0x6e, 0x1d, 0x32, 0x29, \ + 0xdb, 0x21, 0xb0, 0xa3, 0x30, 0x82, 0x02, 0x4f, \ + 0x30, 0x82, 0x01, 0x37, 0xa0, 0x03, 0x02, 0x01, \ + 0x02, 0x02, 0x04, 0x2a, 0xd9, 0x6a, 0xf3, 0x30, \ + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, \ + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x2e, \ + 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, \ + 0x00, 0x00, 0x99, 0x01, 0x02, 0x03, 0x13, 0x23, \ + 0x59, 0x75, 0x62, 0x69, 0x63, 0x6f, 0x20, 0x55, \ + 0x32, 0x46, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, \ + 0x43, 0x41, 0x20, 0x53, 0x65, 0x72, 0x69, 0x61, \ + 0x6c, 0x20, 0x34, 0x35, 0x37, 0x32, 0x30, 0x30, \ + 0x36, 0x33, 0x31, 0x30, 0x20, 0x17, 0x0d, 0x31, \ + 0x34, 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x30, \ + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, \ + 0x00, 0x00, 0x99, 0x01, 0x03, 0x35, 0x30, 0x30, \ + 0x39, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, \ + 0x30, 0x5a, 0x30, 0x31, 0x31, 0x2f, 0x30, 0x2d, \ + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x26, 0x59, \ + 0x75, 0x62, 0x69, 0x63, 0x6f, 0x20, 0x55, 0x32, \ + 0x46, 0x20, 0x45, 0x45, 0x20, 0x53, 0x65, 0x72, \ + 0x69, 0x61, 0x6c, 0x20, 0x32, 0x33, 0x39, 0x32, \ + 0x35, 0x37, 0x33, 0x34, 0x35, 0x31, 0x36, 0x35, \ + 0x00, 0x00, 0x99, 0x01, 0x04, 0x35, 0x30, 0x33, \ + 0x38, 0x37, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, \ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, \ + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, \ + 0x07, 0x03, 0x42, 0x00, 0x04, 0x2f, 0xe1, 0xa2, \ + 0x3e, 0xbf, 0xa5, 0x5b, 0x3e, 0x46, 0x1d, 0x59, \ + 0xa4, 0x35, 0x22, 0xd7, 0x97, 0x48, 0x98, 0x1c, \ + 0xba, 0x6d, 0x28, 0x9a, 0x98, 0xf1, 0xbd, 0x7d, \ + 0x00, 0x00, 0x99, 0x01, 0x05, 0xff, 0x65, 0x66, \ + 0x80, 0xdb, 0xbb, 0xed, 0xbc, 0x2b, 0xae, 0x60, \ + 0x7e, 0x6e, 0xf7, 0x72, 0xf5, 0x76, 0xb0, 0x4d, \ + 0x54, 0xc4, 0xe5, 0xf3, 0x2f, 0x59, 0x6f, 0x26, \ + 0xe6, 0x11, 0x15, 0xc7, 0x27, 0x2c, 0xf6, 0xca, \ + 0x75, 0x94, 0xa3, 0x3b, 0x30, 0x39, 0x30, 0x22, \ + 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, \ + 0xc4, 0x0a, 0x02, 0x04, 0x15, 0x31, 0x2e, 0x33, \ + 0x00, 0x00, 0x99, 0x01, 0x06, 0x2e, 0x36, 0x2e, \ + 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e, 0x34, 0x31, \ + 0x34, 0x38, 0x32, 0x2e, 0x31, 0x2e, 0x32, 0x30, \ + 0x13, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, \ + 0x82, 0xe5, 0x1c, 0x02, 0x01, 0x01, 0x04, 0x04, \ + 0x03, 0x02, 0x04, 0x30, 0x30, 0x0d, 0x06, 0x09, \ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, \ + 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, \ + 0x00, 0x00, 0x99, 0x01, 0x07, 0x85, 0x6a, 0xfa, \ + 0x8b, 0xcf, 0x4f, 0x3f, 0x62, 0x5f, 0x29, 0x1b, \ + 0xc1, 0x15, 0x8e, 0x3c, 0x7e, 0xbd, 0x25, 0x52, \ + 0xbc, 0xf7, 0x57, 0x07, 0x53, 0xf5, 0x12, 0x1d, \ + 0xa6, 0xa5, 0x4d, 0x24, 0xcc, 0xcf, 0xae, 0x27, \ + 0xce, 0xd6, 0xab, 0x31, 0x12, 0x8c, 0x29, 0x7e, \ + 0x5b, 0x5b, 0x89, 0x05, 0xdd, 0xa0, 0x20, 0x17, \ + 0x93, 0x1f, 0x1f, 0x5f, 0x59, 0x25, 0x93, 0x59, \ + 0x00, 0x00, 0x99, 0x01, 0x08, 0x51, 0xfc, 0x00, \ + 0x4b, 0xcb, 0xe2, 0x0a, 0xdd, 0x7d, 0x8d, 0x05, \ + 0x2f, 0x95, 0x43, 0xb3, 0x49, 0x6c, 0x15, 0xb8, \ + 0x31, 0x0e, 0x10, 0xcb, 0xd9, 0xbb, 0x05, 0x38, \ + 0x27, 0x4f, 0x58, 0x3e, 0xad, 0x1f, 0x45, 0x12, \ + 0x88, 0xc3, 0xea, 0x76, 0xd0, 0x70, 0xad, 0x44, \ + 0xe5, 0x3a, 0xfe, 0xa8, 0xf2, 0x2d, 0x1f, 0x73, \ + 0x62, 0x5f, 0xf2, 0xd5, 0x89, 0xfe, 0x30, 0xdf, \ + 0x00, 0x00, 0x99, 0x01, 0x09, 0x26, 0x62, 0xcb, \ + 0x7c, 0xbb, 0x7c, 0x99, 0x61, 0x80, 0xad, 0xcf, \ + 0xa9, 0x8a, 0x4d, 0x01, 0x2c, 0xf3, 0x13, 0x46, \ + 0xcd, 0x11, 0x74, 0x6a, 0x58, 0x48, 0xe8, 0xbe, \ + 0xed, 0xf3, 0xe3, 0x0c, 0xcb, 0xd9, 0xc1, 0xdd, \ + 0x22, 0x16, 0x71, 0xb2, 0x83, 0x88, 0x61, 0xf6, \ + 0x5a, 0x45, 0x36, 0x23, 0xb5, 0x18, 0xd5, 0x56, \ + 0x7f, 0xa8, 0xf0, 0xa3, 0xce, 0x10, 0x5d, 0xf4, \ + 0x00, 0x00, 0x99, 0x01, 0x0a, 0xf1, 0x39, 0x53, \ + 0xe1, 0x14, 0xea, 0x59, 0xe0, 0xa7, 0xf2, 0xfe, \ + 0x66, 0x88, 0x67, 0x43, 0x2e, 0x52, 0xfd, 0x6a, \ + 0x2f, 0x64, 0xf7, 0x3c, 0x48, 0xcd, 0x9b, 0x38, \ + 0xf2, 0xdf, 0xba, 0x2c, 0x7a, 0x4b, 0x3b, 0x11, \ + 0x28, 0xdf, 0x26, 0xd6, 0x6a, 0x24, 0xf8, 0x95, \ + 0xdd, 0xa0, 0xb6, 0x11, 0x80, 0xf4, 0x14, 0x4f, \ + 0x6b, 0x70, 0x75, 0xc3, 0x18, 0xa4, 0x9a, 0xe0, \ + 0x00, 0x00, 0x99, 0x01, 0x0b, 0x8b, 0x58, 0xd3, \ + 0x6a, 0xdb, 0x1e, 0x30, 0x53, 0x67, 0x2b, 0x17, \ + 0xc5, 0xa1, 0x9f, 0x7f, 0x0a, 0x22, 0xf1, 0x0e, \ + 0x94, 0x30, 0x44, 0x02, 0x20, 0x07, 0x5c, 0x4f, \ + 0xd2, 0x83, 0xb6, 0x9f, 0x0a, 0x4a, 0x4d, 0x4b, \ + 0x08, 0x35, 0xeb, 0xc0, 0x7e, 0x4a, 0x14, 0x2e, \ + 0xc7, 0x8c, 0xd6, 0x64, 0x2f, 0xd3, 0x1e, 0xcc, \ + 0xb5, 0xe8, 0x42, 0xea, 0xf6, 0x02, 0x20, 0x6b, \ + 0x00, 0x00, 0x99, 0x01, 0x0c, 0x5a, 0xba, 0x4a, \ + 0xc8, 0xd7, 0x89, 0xcc, 0x77, 0xe6, 0xb9, 0xa3, \ + 0x34, 0xea, 0x06, 0x85, 0x72, 0xc6, 0x28, 0xa8, \ + 0x7a, 0xaa, 0x19, 0x88, 0x34, 0xbb, 0xdc, 0x64, \ + 0x90, 0x0a, 0xdb, 0x39, 0x90, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#endif /* !_WIREDATA_U2F_H */ diff --git a/fuzz/wrap.c b/fuzz/wrap.c new file mode 100644 index 0000000..6f40ea1 --- /dev/null +++ b/fuzz/wrap.c @@ -0,0 +1,700 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "mutator_aux.h" + +extern int prng_up; + +int fuzz_save_corpus; + +/* + * Build wrappers around functions of interest, and have them fail + * in a pseudo-random manner. A uniform probability of 0.25% (1/400) + * allows for a depth of log(0.5)/log(399/400) > 276 operations + * before simulated errors become statistically more likely. + */ + +#define WRAP(type, name, args, retval, param, prob) \ +extern type __wrap_##name args; \ +extern type __real_##name args; \ +type __wrap_##name args { \ + if (prng_up && uniform_random(400) < (prob)) { \ + return (retval); \ + } \ + \ + return (__real_##name param); \ +} + +WRAP(void *, + malloc, + (size_t size), + NULL, + (size), + 1 +) + +WRAP(void *, + calloc, + (size_t nmemb, size_t size), + NULL, + (nmemb, size), + 1 +) + +WRAP(void *, + realloc, + (void *ptr, size_t size), + NULL, + (ptr, size), + 1 +) + +WRAP(char *, + strdup, + (const char *s), + NULL, + (s), + 1 +) + +WRAP(ssize_t, + getrandom, + (void *buf, size_t buflen, unsigned int flags), + -1, + (buf, buflen, flags), + 1 +) + +WRAP(int, + EVP_Cipher, + (EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, + unsigned int inl), + -1, + (ctx, out, in, inl), + 1 +) + +WRAP(int, + EVP_CIPHER_CTX_ctrl, + (EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr), + 0, + (ctx, type, arg, ptr), + 1 +) + +WRAP(EVP_CIPHER_CTX *, + EVP_CIPHER_CTX_new, + (void), + NULL, + (), + 1 +) + +WRAP(int, + EVP_CipherInit, + (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc), + 0, + (ctx, cipher, key, iv, enc), + 1 +) + +WRAP(RSA *, + EVP_PKEY_get0_RSA, + (EVP_PKEY *pkey), + NULL, + (pkey), + 1 +) + +WRAP(EC_KEY *, + EVP_PKEY_get0_EC_KEY, + (EVP_PKEY *pkey), + NULL, + (pkey), + 1 +) + +WRAP(int, + EVP_PKEY_get_raw_public_key, + (const EVP_PKEY *pkey, unsigned char *pub, size_t *len), + 0, + (pkey, pub, len), + 1 +) + +WRAP(EVP_MD_CTX *, + EVP_MD_CTX_new, + (void), + NULL, + (), + 1 +) + +WRAP(int, + EVP_DigestVerifyInit, + (EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey), + 0, + (ctx, pctx, type, e, pkey), + 1 +) + +WRAP(int, + EVP_DigestInit_ex, + (EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl), + 0, + (ctx, type, impl), + 1 +) + +WRAP(int, + EVP_DigestUpdate, + (EVP_MD_CTX *ctx, const void *data, size_t count), + 0, + (ctx, data, count), + 1 +) + +WRAP(int, + EVP_DigestFinal_ex, + (EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize), + 0, + (ctx, md, isize), + 1 +) + +WRAP(BIGNUM *, + BN_bin2bn, + (const unsigned char *s, int len, BIGNUM *ret), + NULL, + (s, len, ret), + 1 +) + +WRAP(int, + BN_bn2bin, + (const BIGNUM *a, unsigned char *to), + -1, + (a, to), + 1 +) + +WRAP(BIGNUM *, + BN_CTX_get, + (BN_CTX *ctx), + NULL, + (ctx), + 1 +) + +WRAP(BN_CTX *, + BN_CTX_new, + (void), + NULL, + (), + 1 +) + +WRAP(BIGNUM *, + BN_new, + (void), + NULL, + (), + 1 +) + +WRAP(RSA *, + RSA_new, + (void), + NULL, + (), + 1 +) + +WRAP(int, + RSA_set0_key, + (RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d), + 0, + (r, n, e, d), + 1 +) + +WRAP(int, + RSA_pkey_ctx_ctrl, + (EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2), + -1, + (ctx, optype, cmd, p1, p2), + 1 +) + +WRAP(EC_KEY *, + EC_KEY_new_by_curve_name, + (int nid), + NULL, + (nid), + 1 +) + +WRAP(const EC_GROUP *, + EC_KEY_get0_group, + (const EC_KEY *key), + NULL, + (key), + 1 +) + +WRAP(const BIGNUM *, + EC_KEY_get0_private_key, + (const EC_KEY *key), + NULL, + (key), + 1 +) + +WRAP(EC_POINT *, + EC_POINT_new, + (const EC_GROUP *group), + NULL, + (group), + 1 +) + +WRAP(int, + EC_POINT_get_affine_coordinates_GFp, + (const EC_GROUP *group, const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx), + 0, + (group, p, x, y, ctx), + 1 +) + +WRAP(EVP_PKEY *, + EVP_PKEY_new, + (void), + NULL, + (), + 1 +) + +WRAP(int, + EVP_PKEY_assign, + (EVP_PKEY *pkey, int type, void *key), + 0, + (pkey, type, key), + 1 +) + +WRAP(int, + EVP_PKEY_keygen_init, + (EVP_PKEY_CTX *ctx), + 0, + (ctx), + 1 +) + +WRAP(int, + EVP_PKEY_keygen, + (EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey), + 0, + (ctx, ppkey), + 1 +) + +WRAP(int, + EVP_PKEY_paramgen_init, + (EVP_PKEY_CTX *ctx), + 0, + (ctx), + 1 +) + +WRAP(int, + EVP_PKEY_paramgen, + (EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey), + 0, + (ctx, ppkey), + 1 +) + +WRAP(EVP_PKEY *, + EVP_PKEY_new_raw_public_key, + (int type, ENGINE *e, const unsigned char *key, size_t keylen), + NULL, + (type, e, key, keylen), + 1 +) + +WRAP(EVP_PKEY_CTX *, + EVP_PKEY_CTX_new, + (EVP_PKEY *pkey, ENGINE *e), + NULL, + (pkey, e), + 1 +) + +WRAP(EVP_PKEY_CTX *, + EVP_PKEY_CTX_new_id, + (int id, ENGINE *e), + NULL, + (id, e), + 1 +) + +WRAP(int, + EVP_PKEY_derive, + (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen), + 0, + (ctx, key, pkeylen), + 1 +) + +WRAP(int, + EVP_PKEY_derive_init, + (EVP_PKEY_CTX *ctx), + 0, + (ctx), + 1 +) + +WRAP(int, + EVP_PKEY_derive_set_peer, + (EVP_PKEY_CTX *ctx, EVP_PKEY *peer), + 0, + (ctx, peer), + 1 +) + +WRAP(int, + EVP_PKEY_verify_init, + (EVP_PKEY_CTX *ctx), + 0, + (ctx), + 1 +) + +WRAP(int, + EVP_PKEY_CTX_ctrl, + (EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2), + -1, + (ctx, keytype, optype, cmd, p1, p2), + 1 +) + +WRAP(const EVP_MD *, + EVP_sha1, + (void), + NULL, + (), + 1 +) + +WRAP(const EVP_MD *, + EVP_sha256, + (void), + NULL, + (), + 1 +) + +WRAP(const EVP_CIPHER *, + EVP_aes_256_cbc, + (void), + NULL, + (), + 1 +) + +WRAP(const EVP_CIPHER *, + EVP_aes_256_gcm, + (void), + NULL, + (), + 1 +) + +WRAP(unsigned char *, + HMAC, + (const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, int n, unsigned char *md, + unsigned int *md_len), + NULL, + (evp_md, key, key_len, d, n, md, md_len), + 1 +) + +WRAP(HMAC_CTX *, + HMAC_CTX_new, + (void), + NULL, + (), + 1 +) + +WRAP(int, + HMAC_Init_ex, + (HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, + ENGINE *impl), + 0, + (ctx, key, key_len, md, impl), + 1 +) + +WRAP(int, + HMAC_Update, + (HMAC_CTX *ctx, const unsigned char *data, int len), + 0, + (ctx, data, len), + 1 +) + +WRAP(int, + HMAC_Final, + (HMAC_CTX *ctx, unsigned char *md, unsigned int *len), + 0, + (ctx, md, len), + 1 +) + +WRAP(unsigned char *, + SHA1, + (const unsigned char *d, size_t n, unsigned char *md), + NULL, + (d, n, md), + 1 +) + +WRAP(unsigned char *, + SHA256, + (const unsigned char *d, size_t n, unsigned char *md), + NULL, + (d, n, md), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_string, + (const char *val), + NULL, + (val), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_bytestring, + (cbor_data handle, size_t length), + NULL, + (handle, length), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_bool, + (bool value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_negint8, + (uint8_t value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_negint16, + (uint16_t value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_load, + (cbor_data source, size_t source_size, struct cbor_load_result *result), + NULL, + (source, source_size, result), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_uint8, + (uint8_t value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_uint16, + (uint16_t value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_uint32, + (uint32_t value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, + cbor_build_uint64, + (uint64_t value), + NULL, + (value), + 1 +) + +WRAP(struct cbor_pair *, + cbor_map_handle, + (const cbor_item_t *item), + NULL, + (item), + 1 +) + +WRAP(cbor_item_t **, + cbor_array_handle, + (const cbor_item_t *item), + NULL, + (item), + 1 +) + +WRAP(bool, + cbor_array_push, + (cbor_item_t *array, cbor_item_t *pushee), + false, + (array, pushee), + 1 +) + +WRAP(bool, + cbor_map_add, + (cbor_item_t *item, struct cbor_pair pair), + false, + (item, pair), + 1 +) + +WRAP(cbor_item_t *, + cbor_new_definite_map, + (size_t size), + NULL, + (size), + 1 +) + +WRAP(cbor_item_t *, + cbor_new_definite_array, + (size_t size), + NULL, + (size), + 1 +) + +WRAP(cbor_item_t *, + cbor_new_definite_bytestring, + (void), + NULL, + (), + 1 +) + +WRAP(size_t, + cbor_serialize_alloc, + (const cbor_item_t *item, cbor_mutable_data *buffer, + size_t *buffer_size), + 0, + (item, buffer, buffer_size), + 1 +) + +WRAP(int, + fido_tx, + (fido_dev_t *d, uint8_t cmd, const void *buf, size_t count, int *ms), + -1, + (d, cmd, buf, count, ms), + 1 +) + +WRAP(int, + bind, + (int sockfd, const struct sockaddr *addr, socklen_t addrlen), + -1, + (sockfd, addr, addrlen), + 1 +) + +WRAP(int, + deflateInit2_, + (z_streamp strm, int level, int method, int windowBits, int memLevel, + int strategy, const char *version, int stream_size), + Z_STREAM_ERROR, + (strm, level, method, windowBits, memLevel, strategy, version, + stream_size), + 1 +) + +int __wrap_deflate(z_streamp, int); +int __real_deflate(z_streamp, int); + +int +__wrap_deflate(z_streamp strm, int flush) +{ + if (prng_up && uniform_random(400) < 1) { + return Z_BUF_ERROR; + } + /* should never happen, but we check for it */ + if (prng_up && uniform_random(400) < 1) { + strm->avail_out = UINT_MAX; + return Z_STREAM_END; + } + + return __real_deflate(strm, flush); +} + +int __wrap_asprintf(char **, const char *, ...); + +int +__wrap_asprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + int r; + + if (prng_up && uniform_random(400) < 1) { + *strp = (void *)0xdeadbeef; + return -1; + } + + va_start(ap, fmt); + r = vasprintf(strp, fmt, ap); + va_end(ap); + + return r; +} diff --git a/fuzz/wrapped.sym b/fuzz/wrapped.sym new file mode 100644 index 0000000..219a0d8 --- /dev/null +++ b/fuzz/wrapped.sym @@ -0,0 +1,102 @@ +asprintf +bind +BN_bin2bn +BN_bn2bin +BN_CTX_get +BN_CTX_new +BN_new +calloc +cbor_array_handle +cbor_array_push +cbor_build_bool +cbor_build_bytestring +cbor_build_negint16 +cbor_build_negint8 +cbor_build_string +cbor_build_uint16 +cbor_build_uint32 +cbor_build_uint64 +cbor_build_uint8 +cbor_load +cbor_map_add +cbor_map_handle +cbor_new_definite_array +cbor_new_definite_bytestring +cbor_new_definite_map +cbor_serialize_alloc +clock_gettime +deflate +deflateInit2_ +EC_KEY_get0_group +EC_KEY_get0_private_key +EC_KEY_new_by_curve_name +EC_POINT_get_affine_coordinates_GFp +EC_POINT_new +EVP_aes_256_cbc +EVP_aes_256_gcm +EVP_Cipher +EVP_CIPHER_CTX_ctrl +EVP_CIPHER_CTX_new +EVP_CipherInit +EVP_DigestFinal_ex +EVP_DigestInit_ex +EVP_DigestUpdate +EVP_DigestVerifyInit +EVP_MD_CTX_new +EVP_PKEY_assign +EVP_PKEY_CTX_ctrl +EVP_PKEY_CTX_new +EVP_PKEY_CTX_new_id +EVP_PKEY_derive +EVP_PKEY_derive_init +EVP_PKEY_derive_set_peer +EVP_PKEY_get0_EC_KEY +EVP_PKEY_get0_RSA +EVP_PKEY_get_raw_public_key +EVP_PKEY_keygen +EVP_PKEY_keygen_init +EVP_PKEY_new +EVP_PKEY_new_raw_public_key +EVP_PKEY_paramgen +EVP_PKEY_paramgen_init +EVP_PKEY_verify_init +EVP_sha1 +EVP_sha256 +fido_tx +getrandom +HMAC +HMAC_CTX_new +HMAC_Final +HMAC_Init_ex +HMAC_Update +ioctl +malloc +realloc +RSA_new +RSA_pkey_ctx_ctrl +RSA_set0_key +SCardConnect +SCardDisconnect +SCardEstablishContext +SCardListReaders +SCardReleaseContext +SCardTransmit +SHA1 +SHA256 +strdup +udev_device_get_devnode +udev_device_get_parent_with_subsystem_devtype +udev_device_get_sysattr_value +udev_device_get_sysnum +udev_device_new_from_syspath +udev_device_unref +udev_enumerate_add_match_subsystem +udev_enumerate_get_list_entry +udev_enumerate_new +udev_enumerate_scan_devices +udev_enumerate_unref +udev_list_entry_get_name +udev_list_entry_get_next +udev_new +udev_unref +usleep