mirror of
https://github.com/token2/fido2-manage.git
synced 2026-04-09 02:35:39 +00:00
Add files via upload
This commit is contained in:
59
examples/CMakeLists.txt
Normal file
59
examples/CMakeLists.txt
Normal file
@@ -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()
|
||||||
100
examples/README.adoc
Normal file
100
examples/README.adoc
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
= Examples
|
||||||
|
|
||||||
|
=== Definitions
|
||||||
|
|
||||||
|
The following definitions are used in the description below:
|
||||||
|
|
||||||
|
- <device>
|
||||||
|
|
||||||
|
The file system path or subsystem-specific identification string of a
|
||||||
|
FIDO device.
|
||||||
|
|
||||||
|
- <pin>, [oldpin]
|
||||||
|
|
||||||
|
Strings passed directly in the executed command's argument vector.
|
||||||
|
|
||||||
|
- <cred_id>
|
||||||
|
|
||||||
|
The file system path of a file containing a FIDO credential ID in
|
||||||
|
binary representation.
|
||||||
|
|
||||||
|
- <pubkey>
|
||||||
|
|
||||||
|
The file system path of a file containing a public key in PEM format.
|
||||||
|
|
||||||
|
- <blobkey>
|
||||||
|
|
||||||
|
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 <device>
|
||||||
|
|
||||||
|
Prints information about <device>.
|
||||||
|
|
||||||
|
- reset <device>
|
||||||
|
|
||||||
|
Performs a factory reset on <device>.
|
||||||
|
|
||||||
|
- setpin <pin> [oldpin] <device>
|
||||||
|
|
||||||
|
Configures <pin> as the new PIN of <device>. If [oldpin] is provided,
|
||||||
|
the device's PIN is changed from [oldpin] to <pin>.
|
||||||
|
|
||||||
|
- cred [-t es256|es384|rs256|eddsa] [-k pubkey] [-ei cred_id] [-P pin]
|
||||||
|
[-T seconds] [-b blobkey] [-hruv] [-c cred_protect] <device>
|
||||||
|
|
||||||
|
Creates a new credential on <device> 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 <pubkey>. If option -i is specified, the credential
|
||||||
|
ID is stored in <cred_id>. The -e option may be used to add <cred_id>
|
||||||
|
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 <seconds>. If the
|
||||||
|
option -b is specified, the credential's "largeBlob" key is stored in
|
||||||
|
<blobkey>. 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] <pubkey> <device>
|
||||||
|
|
||||||
|
Asks <device> for a FIDO2 assertion corresponding to [cred_id],
|
||||||
|
which may be omitted for resident keys. The obtained assertion
|
||||||
|
is verified using <pubkey>. 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 <hmac_salt> are used as the salt. If option -h
|
||||||
|
is specified, the resulting hmac-secret is stored in <hmac_secret>.
|
||||||
|
The -T option may be used to enforce a timeout of <seconds>. If the
|
||||||
|
option -b specified, the credential's "largeBlob" key is stored in
|
||||||
|
<blobkey>.
|
||||||
|
|
||||||
|
- retries <device>
|
||||||
|
Get the number of PIN attempts left on <device> 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.
|
||||||
349
examples/assert.c
Normal file
349
examples/assert.c
Normal file
@@ -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 <fido.h>
|
||||||
|
#include <fido/es256.h>
|
||||||
|
#include <fido/es384.h>
|
||||||
|
#include <fido/rs256.h>
|
||||||
|
#include <fido/eddsa.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#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] <pubkey> <device>\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);
|
||||||
|
}
|
||||||
331
examples/cred.c
Normal file
331
examples/cred.c
Normal file
@@ -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 <errno.h>
|
||||||
|
#include <fido.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#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] "
|
||||||
|
"<device>\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);
|
||||||
|
}
|
||||||
27
examples/extern.h
Normal file
27
examples/extern.h
Normal file
@@ -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 <openssl/ec.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
|
||||||
|
/* 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_ */
|
||||||
382
examples/info.c
Normal file
382
examples/info.c
Normal file
@@ -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 <fido.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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 <device>\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
getinfo(argv[1]);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
42
examples/manifest.c
Normal file
42
examples/manifest.c
Normal file
@@ -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 <fido.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
49
examples/reset.c
Normal file
49
examples/reset.c
Normal file
@@ -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 <fido.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#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 <device>\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);
|
||||||
|
}
|
||||||
49
examples/retries.c
Normal file
49
examples/retries.c
Normal file
@@ -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 <fido.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#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 <device>\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);
|
||||||
|
}
|
||||||
215
examples/select.c
Normal file
215
examples/select.c
Normal file
@@ -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 <errno.h>
|
||||||
|
#include <fido.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
55
examples/setpin.c
Normal file
55
examples/setpin.c
Normal file
@@ -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 <fido.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#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 <pin> [oldpin] <device>\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 3)
|
||||||
|
setpin(argv[2], argv[1], NULL);
|
||||||
|
else
|
||||||
|
setpin(argv[3], argv[1], argv[2]);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
444
examples/util.c
Normal file
444
examples/util.c
Normal file
@@ -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 <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <openssl/ec.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
|
||||||
|
#include <fido.h>
|
||||||
|
#include <fido/es256.h>
|
||||||
|
#include <fido/es384.h>
|
||||||
|
#include <fido/rs256.h>
|
||||||
|
#include <fido/eddsa.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#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);
|
||||||
|
}
|
||||||
89
fuzz/CMakeLists.txt
Normal file
89
fuzz/CMakeLists.txt
Normal file
@@ -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)
|
||||||
16
fuzz/Dockerfile
Normal file
16
fuzz/Dockerfile
Normal file
@@ -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
|
||||||
90
fuzz/Makefile
Normal file
90
fuzz/Makefile
Normal file
@@ -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/$</corpus'
|
||||||
|
|
||||||
|
corpus.tgz-: ${MINIFY}
|
||||||
|
docker exec -i ${RUNNER} tar Czcf /minify - ${TARGETS} > $@
|
||||||
|
|
||||||
|
profdata: run
|
||||||
|
docker exec ${RUNNER} /bin/sh -c 'rm -f /$@ && ${PROFDATA} \
|
||||||
|
merge -sparse /profraw/* -o /$@'
|
||||||
|
|
||||||
|
report.tgz: profdata
|
||||||
|
docker exec ${RUNNER} /bin/sh -c 'rm -rf /report && mkdir /report && \
|
||||||
|
${COV} show -format=html -tab-size=8 -instr-profile=/$< \
|
||||||
|
-ignore-filename-regex=pcsclite.h --show-branch-summary=false \
|
||||||
|
-output-dir=/report /libfido2/build/src/libfido2.so'
|
||||||
|
docker exec -i ${RUNNER} tar Czcf / - report > $@
|
||||||
|
|
||||||
|
summary.txt: profdata
|
||||||
|
docker exec ${RUNNER} ${COV} report -use-color=false \
|
||||||
|
-ignore-filename-regex=pcsclite.h --show-branch-summary=false \
|
||||||
|
/libfido2/build/src/libfido2.so -instr-profile=/$< > $@
|
||||||
|
|
||||||
|
functions.txt: profdata
|
||||||
|
docker exec ${RUNNER} /bin/sh -c '${COV} report -use-color=false \
|
||||||
|
-ignore-filename-regex=pcsclite.h -show-functions \
|
||||||
|
--show-branch-summary=false -instr-profile=/$< \
|
||||||
|
/libfido2/build/src/libfido2.so /libfido2/src/*.[ch]' > $@
|
||||||
|
|
||||||
|
clean: run
|
||||||
|
docker exec ${RUNNER} /bin/sh -c 'rm -rf /profraw /profdata && \
|
||||||
|
make -C /libfido2/build clean'
|
||||||
|
-docker stop ${RUNNER}
|
||||||
|
rm -rf ${TARGETS}
|
||||||
|
|
||||||
|
${CORPORA}:
|
||||||
|
-mkdir -p $@
|
||||||
|
gsutil -q -m rsync -d -r ${REMOTE}/libFuzzer/libfido2_$(@:/corpus=) $@
|
||||||
|
|
||||||
|
fetch-oss-fuzz: ${CORPORA}
|
||||||
|
find ${TARGETS} -type f -size +8192c -print0 | xargs -0 rm
|
||||||
|
|
||||||
|
fetch-franz:
|
||||||
|
ssh franz tar -C corpus -cf- . | tar -xf-
|
||||||
|
|
||||||
|
corpus.tgz:
|
||||||
|
tar zcf $@ ${TARGETS}
|
||||||
|
|
||||||
|
.PHONY: build run sync corpus ${TARGETS} ${CORPORA}
|
||||||
|
.PHONY: report.tgz summary.txt functions.txt
|
||||||
|
.PHONY: fetch-oss-fuzz fetch-franz corpus.tgz
|
||||||
43
fuzz/README
Normal file
43
fuzz/README
Normal file
@@ -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;
|
||||||
|
}
|
||||||
34
fuzz/build-coverage
Normal file
34
fuzz/build-coverage
Normal file
@@ -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"
|
||||||
80
fuzz/clock.c
Normal file
80
fuzz/clock.c
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A pseudo-random monotonic clock with a probabilistic discontinuity to
|
||||||
|
* the end of time (as measured by struct timespec).
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int prng_up;
|
||||||
|
extern int __wrap_clock_gettime(clockid_t, struct timespec *);
|
||||||
|
extern int __real_clock_gettime(clockid_t, struct timespec *);
|
||||||
|
extern int __wrap_usleep(unsigned int);
|
||||||
|
static TLS struct timespec fuzz_clock;
|
||||||
|
|
||||||
|
static void
|
||||||
|
tick(unsigned int usec)
|
||||||
|
{
|
||||||
|
long long drift;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simulate a jump to the end of time with 0.125% probability.
|
||||||
|
* This condition should be gracefully handled by callers of
|
||||||
|
* clock_gettime().
|
||||||
|
*/
|
||||||
|
if (uniform_random(800) < 1) {
|
||||||
|
fuzz_clock.tv_sec = LLONG_MAX;
|
||||||
|
fuzz_clock.tv_nsec = LONG_MAX;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
drift = usec * 1000LL + (long long)uniform_random(10000000); /* 10ms */
|
||||||
|
if (LLONG_MAX - drift < (long long)fuzz_clock.tv_nsec) {
|
||||||
|
fuzz_clock_reset(); /* Not much we can do here. */
|
||||||
|
} else if (drift + (long long)fuzz_clock.tv_nsec < 1000000000) {
|
||||||
|
fuzz_clock.tv_nsec += (long)(drift);
|
||||||
|
} else {
|
||||||
|
fuzz_clock.tv_sec += (long)(drift / 1000000000);
|
||||||
|
fuzz_clock.tv_nsec += (long)(drift % 1000000000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__wrap_clock_gettime(clockid_t clk_id, struct timespec *tp)
|
||||||
|
{
|
||||||
|
if (!prng_up || clk_id != CLOCK_MONOTONIC)
|
||||||
|
return __real_clock_gettime(clk_id, tp);
|
||||||
|
if (uniform_random(400) < 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
tick(0);
|
||||||
|
*tp = fuzz_clock;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__wrap_usleep(unsigned int usec)
|
||||||
|
{
|
||||||
|
if (uniform_random(400) < 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
tick(usec);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fuzz_clock_reset(void)
|
||||||
|
{
|
||||||
|
memset(&fuzz_clock, 0, sizeof(fuzz_clock));
|
||||||
|
}
|
||||||
182
fuzz/dummy.h
Normal file
182
fuzz/dummy.h
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2022 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DUMMY_H
|
||||||
|
#define _DUMMY_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
const char dummy_name[] = "finger1";
|
||||||
|
const char dummy_pin1[] = "skepp cg0u3;Y..";
|
||||||
|
const char dummy_pin2[] = "bastilha 6rJrfQZI.";
|
||||||
|
const char dummy_pin[] = "9}4gT:8d=A37Dh}U";
|
||||||
|
const char dummy_rp_id[] = "localhost";
|
||||||
|
const char dummy_rp_name[] = "sweet home localhost";
|
||||||
|
const char dummy_user_icon[] = "an icon";
|
||||||
|
const char dummy_user_name[] = "john smith";
|
||||||
|
const char dummy_user_nick[] = "jsmith";
|
||||||
|
const char dummy_pcsc_list[] = "reader1\0reader2\0reader3\0\0";
|
||||||
|
const char dummy_pcsc_path[] = "pcsc://slot7";
|
||||||
|
const uint8_t dummy_id[] = { 0x5e, 0xd2 };
|
||||||
|
|
||||||
|
const uint8_t dummy_user_id[] = {
|
||||||
|
0x78, 0x1c, 0x78, 0x60, 0xad, 0x88, 0xd2, 0x63,
|
||||||
|
0x32, 0x62, 0x2a, 0xf1, 0x74, 0x5d, 0xed, 0xb2,
|
||||||
|
0xe7, 0xa4, 0x2b, 0x44, 0x89, 0x29, 0x39, 0xc5,
|
||||||
|
0x56, 0x64, 0x01, 0x27, 0x0d, 0xbb, 0xc4, 0x49,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t dummy_cred_id[] = {
|
||||||
|
0x4f, 0x72, 0x98, 0x42, 0x4a, 0xe1, 0x17, 0xa5,
|
||||||
|
0x85, 0xa0, 0xef, 0x3b, 0x11, 0x24, 0x4a, 0x3d,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t dummy_cdh[] = {
|
||||||
|
0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7,
|
||||||
|
0x82, 0x34, 0xaa, 0xca, 0x07, 0xa1, 0xf6, 0x56,
|
||||||
|
0x42, 0x1c, 0xb6, 0xf6, 0xb3, 0x00, 0x86, 0x52,
|
||||||
|
0x35, 0x2d, 0xa2, 0x62, 0x4a, 0xbe, 0x89, 0x76,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t dummy_es256[] = {
|
||||||
|
0xcc, 0x1b, 0x50, 0xac, 0xc4, 0x19, 0xf8, 0x3a,
|
||||||
|
0xee, 0x0a, 0x77, 0xd6, 0xf3, 0x53, 0xdb, 0xef,
|
||||||
|
0xf2, 0xb9, 0x5c, 0x2d, 0x8b, 0x1e, 0x52, 0x58,
|
||||||
|
0x88, 0xf4, 0x0b, 0x85, 0x1f, 0x40, 0x6d, 0x18,
|
||||||
|
0x15, 0xb3, 0xcc, 0x25, 0x7c, 0x38, 0x3d, 0xec,
|
||||||
|
0xdf, 0xad, 0xbd, 0x46, 0x91, 0xc3, 0xac, 0x30,
|
||||||
|
0x94, 0x2a, 0xf7, 0x78, 0x35, 0x70, 0x59, 0x6f,
|
||||||
|
0x28, 0xcb, 0x8e, 0x07, 0x85, 0xb5, 0x91, 0x96,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t dummy_rs256[] = {
|
||||||
|
0xd2, 0xa8, 0xc0, 0x11, 0x82, 0x9e, 0x57, 0x2e,
|
||||||
|
0x60, 0xae, 0x8c, 0xb0, 0x09, 0xe1, 0x58, 0x2b,
|
||||||
|
0x99, 0xec, 0xc3, 0x11, 0x1b, 0xef, 0x81, 0x49,
|
||||||
|
0x34, 0x53, 0x6a, 0x01, 0x65, 0x2c, 0x24, 0x09,
|
||||||
|
0x30, 0x87, 0x98, 0x51, 0x6e, 0x30, 0x4f, 0x60,
|
||||||
|
0xbd, 0x54, 0xd2, 0x54, 0xbd, 0x94, 0x42, 0xdd,
|
||||||
|
0x63, 0xe5, 0x2c, 0xc6, 0x04, 0x32, 0xc0, 0x8f,
|
||||||
|
0x72, 0xd5, 0xb4, 0xf0, 0x4f, 0x42, 0xe5, 0xb0,
|
||||||
|
0xa2, 0x95, 0x11, 0xfe, 0xd8, 0xb0, 0x65, 0x34,
|
||||||
|
0xff, 0xfb, 0x44, 0x97, 0x52, 0xfc, 0x67, 0x23,
|
||||||
|
0x0b, 0xad, 0xf3, 0x3a, 0x82, 0xd4, 0x96, 0x10,
|
||||||
|
0x87, 0x6b, 0xfa, 0xd6, 0x51, 0x60, 0x3e, 0x1c,
|
||||||
|
0xae, 0x19, 0xb8, 0xce, 0x08, 0xae, 0x9a, 0xee,
|
||||||
|
0x78, 0x16, 0x22, 0xcc, 0x92, 0xcb, 0xa8, 0x95,
|
||||||
|
0x34, 0xe5, 0xb9, 0x42, 0x6a, 0xf0, 0x2e, 0x82,
|
||||||
|
0x1f, 0x4c, 0x7d, 0x84, 0x94, 0x68, 0x7b, 0x97,
|
||||||
|
0x2b, 0xf7, 0x7d, 0x67, 0x83, 0xbb, 0xc7, 0x8a,
|
||||||
|
0x31, 0x5a, 0xf3, 0x2a, 0x95, 0xdf, 0x63, 0xe7,
|
||||||
|
0x4e, 0xee, 0x26, 0xda, 0x87, 0x00, 0xe2, 0x23,
|
||||||
|
0x4a, 0x33, 0x9a, 0xa0, 0x1b, 0xce, 0x60, 0x1f,
|
||||||
|
0x98, 0xa1, 0xb0, 0xdb, 0xbf, 0x20, 0x59, 0x27,
|
||||||
|
0xf2, 0x06, 0xd9, 0xbe, 0x37, 0xa4, 0x03, 0x6b,
|
||||||
|
0x6a, 0x4e, 0xaf, 0x22, 0x68, 0xf3, 0xff, 0x28,
|
||||||
|
0x59, 0x05, 0xc9, 0xf1, 0x28, 0xf4, 0xbb, 0x35,
|
||||||
|
0xe0, 0xc2, 0x68, 0xc2, 0xaa, 0x54, 0xac, 0x8c,
|
||||||
|
0xc1, 0x69, 0x9e, 0x4b, 0x32, 0xfc, 0x53, 0x58,
|
||||||
|
0x85, 0x7d, 0x3f, 0x51, 0xd1, 0xc9, 0x03, 0x02,
|
||||||
|
0x13, 0x61, 0x62, 0xda, 0xf8, 0xfe, 0x3e, 0xc8,
|
||||||
|
0x95, 0x12, 0xfb, 0x0c, 0xdf, 0x06, 0x65, 0x6f,
|
||||||
|
0x23, 0xc7, 0x83, 0x7c, 0x50, 0x2d, 0x27, 0x25,
|
||||||
|
0x4d, 0xbf, 0x94, 0xf0, 0x89, 0x04, 0xb9, 0x2d,
|
||||||
|
0xc4, 0xa5, 0x32, 0xa9, 0x25, 0x0a, 0x99, 0x59,
|
||||||
|
0x01, 0x00, 0x01,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t dummy_eddsa[] = {
|
||||||
|
0xfe, 0x8b, 0x61, 0x50, 0x31, 0x7a, 0xe6, 0xdf,
|
||||||
|
0xb1, 0x04, 0x9d, 0x4d, 0xb5, 0x7a, 0x5e, 0x96,
|
||||||
|
0x4c, 0xb2, 0xf9, 0x5f, 0x72, 0x47, 0xb5, 0x18,
|
||||||
|
0xe2, 0x39, 0xdf, 0x2f, 0x87, 0x19, 0xb3, 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t dummy_netlink_wiredata[] = {
|
||||||
|
0xd8, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00,
|
||||||
|
0x01, 0x02, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x6e, 0x66, 0x63, 0x00, 0x06, 0x00, 0x01, 0x00,
|
||||||
|
0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00,
|
||||||
|
0x1f, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0x00,
|
||||||
|
0x14, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00,
|
||||||
|
0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x04, 0x00,
|
||||||
|
0x08, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x05, 0x00, 0x08, 0x00, 0x01, 0x00,
|
||||||
|
0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x06, 0x00,
|
||||||
|
0x08, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00,
|
||||||
|
0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00,
|
||||||
|
0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x09, 0x00, 0x08, 0x00, 0x01, 0x00,
|
||||||
|
0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0a, 0x00,
|
||||||
|
0x08, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x01, 0x00,
|
||||||
|
0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0c, 0x00,
|
||||||
|
0x08, 0x00, 0x01, 0x00, 0x15, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x01, 0x00,
|
||||||
|
0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0e, 0x00,
|
||||||
|
0x08, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x01, 0x00,
|
||||||
|
0x1a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x0c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x10, 0x00,
|
||||||
|
0x08, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x11, 0x00, 0x08, 0x00, 0x01, 0x00,
|
||||||
|
0x1c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,
|
||||||
|
0x08, 0x00, 0x01, 0x00, 0x1d, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x13, 0x00, 0x08, 0x00, 0x01, 0x00,
|
||||||
|
0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x0a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x07, 0x00,
|
||||||
|
0x18, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00,
|
||||||
|
0x05, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00,
|
||||||
|
0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x00,
|
||||||
|
0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
|
||||||
|
0x1e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x9d, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x1c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x09, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||||
|
0x1e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x9d, 0x2e, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x06, 0x00, 0x05, 0x00, 0x44, 0x00, 0x00, 0x00,
|
||||||
|
0x05, 0x00, 0x06, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||||
|
0x0b, 0x00, 0x07, 0x00, 0x27, 0x00, 0x00, 0x00,
|
||||||
|
0x93, 0xb9, 0x25, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* !_DUMMY_H */
|
||||||
289
fuzz/export.gnu
Normal file
289
fuzz/export.gnu
Normal file
@@ -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:
|
||||||
|
*;
|
||||||
|
};
|
||||||
956
fuzz/functions.txt
Normal file
956
fuzz/functions.txt
Normal file
@@ -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%
|
||||||
534
fuzz/fuzz_assert.c
Normal file
534
fuzz/fuzz_assert.c
Normal file
@@ -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 <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
#include "wiredata_fido2.h"
|
||||||
|
#include "wiredata_u2f.h"
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
|
#include "../openbsd-compat/openbsd-compat.h"
|
||||||
|
|
||||||
|
/* Parameter set defining a FIDO2 get assertion operation. */
|
||||||
|
struct param {
|
||||||
|
char pin[MAXSTR];
|
||||||
|
char rp_id[MAXSTR];
|
||||||
|
int ext;
|
||||||
|
int seed;
|
||||||
|
struct blob cdh;
|
||||||
|
struct blob cred;
|
||||||
|
struct blob es256;
|
||||||
|
struct blob rs256;
|
||||||
|
struct blob eddsa;
|
||||||
|
struct blob wire_data;
|
||||||
|
uint8_t cred_count;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t opt;
|
||||||
|
uint8_t up;
|
||||||
|
uint8_t uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* get assertion using the example parameters above.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_wire_data_fido[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_PINTOKEN,
|
||||||
|
WIREDATA_CTAP_CBOR_ASSERT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a U2F
|
||||||
|
* authentication using the example parameters above.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_wire_data_u2f[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_U2F_6985,
|
||||||
|
WIREDATA_CTAP_U2F_6985,
|
||||||
|
WIREDATA_CTAP_U2F_6985,
|
||||||
|
WIREDATA_CTAP_U2F_6985,
|
||||||
|
WIREDATA_CTAP_U2F_AUTH,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct param *
|
||||||
|
unpack(const uint8_t *ptr, size_t len)
|
||||||
|
{
|
||||||
|
cbor_item_t *item = NULL, **v;
|
||||||
|
struct cbor_load_result cbor;
|
||||||
|
struct param *p;
|
||||||
|
int ok = -1;
|
||||||
|
|
||||||
|
if ((p = calloc(1, sizeof(*p))) == NULL ||
|
||||||
|
(item = cbor_load(ptr, len, &cbor)) == NULL ||
|
||||||
|
cbor.read != len ||
|
||||||
|
cbor_isa_array(item) == false ||
|
||||||
|
cbor_array_is_definite(item) == false ||
|
||||||
|
cbor_array_size(item) != 15 ||
|
||||||
|
(v = cbor_array_handle(item)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (unpack_byte(v[0], &p->uv) < 0 ||
|
||||||
|
unpack_byte(v[1], &p->up) < 0 ||
|
||||||
|
unpack_byte(v[2], &p->opt) < 0 ||
|
||||||
|
unpack_byte(v[3], &p->type) < 0 ||
|
||||||
|
unpack_byte(v[4], &p->cred_count) < 0 ||
|
||||||
|
unpack_int(v[5], &p->ext) < 0 ||
|
||||||
|
unpack_int(v[6], &p->seed) < 0 ||
|
||||||
|
unpack_string(v[7], p->rp_id) < 0 ||
|
||||||
|
unpack_string(v[8], p->pin) < 0 ||
|
||||||
|
unpack_blob(v[9], &p->wire_data) < 0 ||
|
||||||
|
unpack_blob(v[10], &p->rs256) < 0 ||
|
||||||
|
unpack_blob(v[11], &p->es256) < 0 ||
|
||||||
|
unpack_blob(v[12], &p->eddsa) < 0 ||
|
||||||
|
unpack_blob(v[13], &p->cred) < 0 ||
|
||||||
|
unpack_blob(v[14], &p->cdh) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ok = 0;
|
||||||
|
fail:
|
||||||
|
if (ok < 0) {
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
cbor_decref(&item);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
pack(uint8_t *ptr, size_t len, const struct param *p)
|
||||||
|
{
|
||||||
|
cbor_item_t *argv[15], *array = NULL;
|
||||||
|
size_t cbor_alloc_len, cbor_len = 0;
|
||||||
|
unsigned char *cbor = NULL;
|
||||||
|
|
||||||
|
memset(argv, 0, sizeof(argv));
|
||||||
|
|
||||||
|
if ((array = cbor_new_definite_array(15)) == NULL ||
|
||||||
|
(argv[0] = pack_byte(p->uv)) == NULL ||
|
||||||
|
(argv[1] = pack_byte(p->up)) == NULL ||
|
||||||
|
(argv[2] = pack_byte(p->opt)) == NULL ||
|
||||||
|
(argv[3] = pack_byte(p->type)) == NULL ||
|
||||||
|
(argv[4] = pack_byte(p->cred_count)) == NULL ||
|
||||||
|
(argv[5] = pack_int(p->ext)) == NULL ||
|
||||||
|
(argv[6] = pack_int(p->seed)) == NULL ||
|
||||||
|
(argv[7] = pack_string(p->rp_id)) == NULL ||
|
||||||
|
(argv[8] = pack_string(p->pin)) == NULL ||
|
||||||
|
(argv[9] = pack_blob(&p->wire_data)) == NULL ||
|
||||||
|
(argv[10] = pack_blob(&p->rs256)) == NULL ||
|
||||||
|
(argv[11] = pack_blob(&p->es256)) == NULL ||
|
||||||
|
(argv[12] = pack_blob(&p->eddsa)) == NULL ||
|
||||||
|
(argv[13] = pack_blob(&p->cred)) == NULL ||
|
||||||
|
(argv[14] = pack_blob(&p->cdh)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 15; i++)
|
||||||
|
if (cbor_array_push(array, argv[i]) == false)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if ((cbor_len = cbor_serialize_alloc(array, &cbor,
|
||||||
|
&cbor_alloc_len)) == 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
333
fuzz/fuzz_attobj.c
Normal file
333
fuzz/fuzz_attobj.c
Normal file
@@ -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 <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
#include "wiredata_fido2.h"
|
||||||
|
#include "wiredata_u2f.h"
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
|
#include "../openbsd-compat/openbsd-compat.h"
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
442
fuzz/fuzz_bio.c
Normal file
442
fuzz/fuzz_bio.c
Normal file
@@ -0,0 +1,442 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
#include "wiredata_fido2.h"
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
|
#include "../openbsd-compat/openbsd-compat.h"
|
||||||
|
|
||||||
|
/* Parameter set defining a FIDO2 credential management operation. */
|
||||||
|
struct param {
|
||||||
|
char pin[MAXSTR];
|
||||||
|
char name[MAXSTR];
|
||||||
|
int seed;
|
||||||
|
struct blob id;
|
||||||
|
struct blob info_wire_data;
|
||||||
|
struct blob enroll_wire_data;
|
||||||
|
struct blob list_wire_data;
|
||||||
|
struct blob set_name_wire_data;
|
||||||
|
struct blob remove_wire_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* 'getFingerprintSensorInfo' bio enrollment command.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_info_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_BIO_INFO,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with FIDO2
|
||||||
|
* 'enrollBegin' + 'enrollCaptureNextSample' bio enrollment commands.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_enroll_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_PINTOKEN,
|
||||||
|
WIREDATA_CTAP_CBOR_BIO_ENROLL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* 'enumerateEnrollments' bio enrollment command.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_list_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_PINTOKEN,
|
||||||
|
WIREDATA_CTAP_CBOR_BIO_ENUM,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* 'setFriendlyName' bio enrollment command.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_set_name_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_PINTOKEN,
|
||||||
|
WIREDATA_CTAP_CBOR_STATUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* 'removeEnrollment' bio enrollment command.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_remove_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_PINTOKEN,
|
||||||
|
WIREDATA_CTAP_CBOR_STATUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct param *
|
||||||
|
unpack(const uint8_t *ptr, size_t len)
|
||||||
|
{
|
||||||
|
cbor_item_t *item = NULL, **v;
|
||||||
|
struct cbor_load_result cbor;
|
||||||
|
struct param *p;
|
||||||
|
int ok = -1;
|
||||||
|
|
||||||
|
if ((p = calloc(1, sizeof(*p))) == NULL ||
|
||||||
|
(item = cbor_load(ptr, len, &cbor)) == NULL ||
|
||||||
|
cbor.read != len ||
|
||||||
|
cbor_isa_array(item) == false ||
|
||||||
|
cbor_array_is_definite(item) == false ||
|
||||||
|
cbor_array_size(item) != 9 ||
|
||||||
|
(v = cbor_array_handle(item)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (unpack_int(v[0], &p->seed) < 0 ||
|
||||||
|
unpack_string(v[1], p->pin) < 0 ||
|
||||||
|
unpack_string(v[2], p->name) < 0 ||
|
||||||
|
unpack_blob(v[3], &p->id) < 0 ||
|
||||||
|
unpack_blob(v[4], &p->info_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[5], &p->enroll_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[6], &p->list_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[7], &p->set_name_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[8], &p->remove_wire_data) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ok = 0;
|
||||||
|
fail:
|
||||||
|
if (ok < 0) {
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
cbor_decref(&item);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
pack(uint8_t *ptr, size_t len, const struct param *p)
|
||||||
|
{
|
||||||
|
cbor_item_t *argv[9], *array = NULL;
|
||||||
|
size_t cbor_alloc_len, cbor_len = 0;
|
||||||
|
unsigned char *cbor = NULL;
|
||||||
|
|
||||||
|
memset(argv, 0, sizeof(argv));
|
||||||
|
|
||||||
|
if ((array = cbor_new_definite_array(9)) == NULL ||
|
||||||
|
(argv[0] = pack_int(p->seed)) == NULL ||
|
||||||
|
(argv[1] = pack_string(p->pin)) == NULL ||
|
||||||
|
(argv[2] = pack_string(p->name)) == NULL ||
|
||||||
|
(argv[3] = pack_blob(&p->id)) == NULL ||
|
||||||
|
(argv[4] = pack_blob(&p->info_wire_data)) == NULL ||
|
||||||
|
(argv[5] = pack_blob(&p->enroll_wire_data)) == NULL ||
|
||||||
|
(argv[6] = pack_blob(&p->list_wire_data)) == NULL ||
|
||||||
|
(argv[7] = pack_blob(&p->set_name_wire_data)) == NULL ||
|
||||||
|
(argv[8] = pack_blob(&p->remove_wire_data)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 9; i++)
|
||||||
|
if (cbor_array_push(array, argv[i]) == false)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if ((cbor_len = cbor_serialize_alloc(array, &cbor,
|
||||||
|
&cbor_alloc_len)) == 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
487
fuzz/fuzz_cred.c
Normal file
487
fuzz/fuzz_cred.c
Normal file
@@ -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 <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
#include "wiredata_fido2.h"
|
||||||
|
#include "wiredata_u2f.h"
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
|
#include "../openbsd-compat/openbsd-compat.h"
|
||||||
|
|
||||||
|
/* Parameter set defining a FIDO2 make credential operation. */
|
||||||
|
struct param {
|
||||||
|
char pin[MAXSTR];
|
||||||
|
char rp_id[MAXSTR];
|
||||||
|
char rp_name[MAXSTR];
|
||||||
|
char user_icon[MAXSTR];
|
||||||
|
char user_name[MAXSTR];
|
||||||
|
char user_nick[MAXSTR];
|
||||||
|
int ext;
|
||||||
|
int seed;
|
||||||
|
struct blob cdh;
|
||||||
|
struct blob excl_cred;
|
||||||
|
struct blob user_id;
|
||||||
|
struct blob wire_data;
|
||||||
|
uint8_t excl_count;
|
||||||
|
uint8_t rk;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t opt;
|
||||||
|
uint8_t uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* make credential using the example parameters above.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_wire_data_fido[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_PINTOKEN,
|
||||||
|
WIREDATA_CTAP_KEEPALIVE,
|
||||||
|
WIREDATA_CTAP_KEEPALIVE,
|
||||||
|
WIREDATA_CTAP_KEEPALIVE,
|
||||||
|
WIREDATA_CTAP_CBOR_CRED,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a U2F
|
||||||
|
* registration using the example parameters above.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_wire_data_u2f[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_U2F_6985,
|
||||||
|
WIREDATA_CTAP_U2F_6985,
|
||||||
|
WIREDATA_CTAP_U2F_6985,
|
||||||
|
WIREDATA_CTAP_U2F_6985,
|
||||||
|
WIREDATA_CTAP_U2F_6985,
|
||||||
|
WIREDATA_CTAP_U2F_REGISTER,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct param *
|
||||||
|
unpack(const uint8_t *ptr, size_t len)
|
||||||
|
{
|
||||||
|
cbor_item_t *item = NULL, **v;
|
||||||
|
struct cbor_load_result cbor;
|
||||||
|
struct param *p;
|
||||||
|
int ok = -1;
|
||||||
|
|
||||||
|
if ((p = calloc(1, sizeof(*p))) == NULL ||
|
||||||
|
(item = cbor_load(ptr, len, &cbor)) == NULL ||
|
||||||
|
cbor.read != len ||
|
||||||
|
cbor_isa_array(item) == false ||
|
||||||
|
cbor_array_is_definite(item) == false ||
|
||||||
|
cbor_array_size(item) != 17 ||
|
||||||
|
(v = cbor_array_handle(item)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (unpack_byte(v[0], &p->rk) < 0 ||
|
||||||
|
unpack_byte(v[1], &p->type) < 0 ||
|
||||||
|
unpack_byte(v[2], &p->opt) < 0 ||
|
||||||
|
unpack_byte(v[3], &p->uv) < 0 ||
|
||||||
|
unpack_byte(v[4], &p->excl_count) < 0 ||
|
||||||
|
unpack_int(v[5], &p->ext) < 0 ||
|
||||||
|
unpack_int(v[6], &p->seed) < 0 ||
|
||||||
|
unpack_string(v[7], p->pin) < 0 ||
|
||||||
|
unpack_string(v[8], p->rp_id) < 0 ||
|
||||||
|
unpack_string(v[9], p->rp_name) < 0 ||
|
||||||
|
unpack_string(v[10], p->user_icon) < 0 ||
|
||||||
|
unpack_string(v[11], p->user_name) < 0 ||
|
||||||
|
unpack_string(v[12], p->user_nick) < 0 ||
|
||||||
|
unpack_blob(v[13], &p->cdh) < 0 ||
|
||||||
|
unpack_blob(v[14], &p->user_id) < 0 ||
|
||||||
|
unpack_blob(v[15], &p->wire_data) < 0 ||
|
||||||
|
unpack_blob(v[16], &p->excl_cred) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ok = 0;
|
||||||
|
fail:
|
||||||
|
if (ok < 0) {
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
cbor_decref(&item);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
pack(uint8_t *ptr, size_t len, const struct param *p)
|
||||||
|
{
|
||||||
|
cbor_item_t *argv[17], *array = NULL;
|
||||||
|
size_t cbor_alloc_len, cbor_len = 0;
|
||||||
|
unsigned char *cbor = NULL;
|
||||||
|
|
||||||
|
memset(argv, 0, sizeof(argv));
|
||||||
|
|
||||||
|
if ((array = cbor_new_definite_array(17)) == NULL ||
|
||||||
|
(argv[0] = pack_byte(p->rk)) == NULL ||
|
||||||
|
(argv[1] = pack_byte(p->type)) == NULL ||
|
||||||
|
(argv[2] = pack_byte(p->opt)) == NULL ||
|
||||||
|
(argv[3] = pack_byte(p->uv)) == NULL ||
|
||||||
|
(argv[4] = pack_byte(p->excl_count)) == NULL ||
|
||||||
|
(argv[5] = pack_int(p->ext)) == NULL ||
|
||||||
|
(argv[6] = pack_int(p->seed)) == NULL ||
|
||||||
|
(argv[7] = pack_string(p->pin)) == NULL ||
|
||||||
|
(argv[8] = pack_string(p->rp_id)) == NULL ||
|
||||||
|
(argv[9] = pack_string(p->rp_name)) == NULL ||
|
||||||
|
(argv[10] = pack_string(p->user_icon)) == NULL ||
|
||||||
|
(argv[11] = pack_string(p->user_name)) == NULL ||
|
||||||
|
(argv[12] = pack_string(p->user_nick)) == NULL ||
|
||||||
|
(argv[13] = pack_blob(&p->cdh)) == NULL ||
|
||||||
|
(argv[14] = pack_blob(&p->user_id)) == NULL ||
|
||||||
|
(argv[15] = pack_blob(&p->wire_data)) == NULL ||
|
||||||
|
(argv[16] = pack_blob(&p->excl_cred)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 17; i++)
|
||||||
|
if (cbor_array_push(array, argv[i]) == false)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if ((cbor_len = cbor_serialize_alloc(array, &cbor,
|
||||||
|
&cbor_alloc_len)) == 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
407
fuzz/fuzz_credman.c
Normal file
407
fuzz/fuzz_credman.c
Normal file
@@ -0,0 +1,407 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2021 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
#include "wiredata_fido2.h"
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
|
#include "../openbsd-compat/openbsd-compat.h"
|
||||||
|
|
||||||
|
/* Parameter set defining a FIDO2 credential management operation. */
|
||||||
|
struct param {
|
||||||
|
char pin[MAXSTR];
|
||||||
|
char rp_id[MAXSTR];
|
||||||
|
int seed;
|
||||||
|
struct blob cred_id;
|
||||||
|
struct blob del_wire_data;
|
||||||
|
struct blob meta_wire_data;
|
||||||
|
struct blob rk_wire_data;
|
||||||
|
struct blob rp_wire_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* 'getCredsMetadata' credential management command.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_meta_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_PINTOKEN,
|
||||||
|
WIREDATA_CTAP_CBOR_CREDMAN_META,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* 'enumerateRPsBegin' credential management command.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_rp_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_PINTOKEN,
|
||||||
|
WIREDATA_CTAP_CBOR_CREDMAN_RPLIST,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* 'enumerateCredentialsBegin' credential management command.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_rk_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_PINTOKEN,
|
||||||
|
WIREDATA_CTAP_CBOR_CREDMAN_RKLIST,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* 'deleteCredential' credential management command.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_del_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_PINTOKEN,
|
||||||
|
WIREDATA_CTAP_CBOR_STATUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct param *
|
||||||
|
unpack(const uint8_t *ptr, size_t len)
|
||||||
|
{
|
||||||
|
cbor_item_t *item = NULL, **v;
|
||||||
|
struct cbor_load_result cbor;
|
||||||
|
struct param *p;
|
||||||
|
int ok = -1;
|
||||||
|
|
||||||
|
if ((p = calloc(1, sizeof(*p))) == NULL ||
|
||||||
|
(item = cbor_load(ptr, len, &cbor)) == NULL ||
|
||||||
|
cbor.read != len ||
|
||||||
|
cbor_isa_array(item) == false ||
|
||||||
|
cbor_array_is_definite(item) == false ||
|
||||||
|
cbor_array_size(item) != 8 ||
|
||||||
|
(v = cbor_array_handle(item)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (unpack_int(v[0], &p->seed) < 0 ||
|
||||||
|
unpack_string(v[1], p->pin) < 0 ||
|
||||||
|
unpack_string(v[2], p->rp_id) < 0 ||
|
||||||
|
unpack_blob(v[3], &p->cred_id) < 0 ||
|
||||||
|
unpack_blob(v[4], &p->meta_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[5], &p->rp_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[6], &p->rk_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[7], &p->del_wire_data) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ok = 0;
|
||||||
|
fail:
|
||||||
|
if (ok < 0) {
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
cbor_decref(&item);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
pack(uint8_t *ptr, size_t len, const struct param *p)
|
||||||
|
{
|
||||||
|
cbor_item_t *argv[8], *array = NULL;
|
||||||
|
size_t cbor_alloc_len, cbor_len = 0;
|
||||||
|
unsigned char *cbor = NULL;
|
||||||
|
|
||||||
|
memset(argv, 0, sizeof(argv));
|
||||||
|
|
||||||
|
if ((array = cbor_new_definite_array(8)) == NULL ||
|
||||||
|
(argv[0] = pack_int(p->seed)) == NULL ||
|
||||||
|
(argv[1] = pack_string(p->pin)) == NULL ||
|
||||||
|
(argv[2] = pack_string(p->rp_id)) == NULL ||
|
||||||
|
(argv[3] = pack_blob(&p->cred_id)) == NULL ||
|
||||||
|
(argv[4] = pack_blob(&p->meta_wire_data)) == NULL ||
|
||||||
|
(argv[5] = pack_blob(&p->rp_wire_data)) == NULL ||
|
||||||
|
(argv[6] = pack_blob(&p->rk_wire_data)) == NULL ||
|
||||||
|
(argv[7] = pack_blob(&p->del_wire_data)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 8; i++)
|
||||||
|
if (cbor_array_push(array, argv[i]) == false)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if ((cbor_len = cbor_serialize_alloc(array, &cbor,
|
||||||
|
&cbor_alloc_len)) == 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
239
fuzz/fuzz_hid.c
Normal file
239
fuzz/fuzz_hid.c
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../openbsd-compat/openbsd-compat.h"
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
|
extern int fido_hid_get_usage(const uint8_t *, size_t, uint32_t *);
|
||||||
|
extern int fido_hid_get_report_len(const uint8_t *, size_t, size_t *, size_t *);
|
||||||
|
extern void set_udev_parameters(const char *, const struct blob *);
|
||||||
|
|
||||||
|
struct param {
|
||||||
|
int seed;
|
||||||
|
char uevent[MAXSTR];
|
||||||
|
struct blob report_descriptor;
|
||||||
|
struct blob netlink_wiredata;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sample HID report descriptor from the FIDO HID interface of a YubiKey 5.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_report_descriptor[] = {
|
||||||
|
0x06, 0xd0, 0xf1, 0x09, 0x01, 0xa1, 0x01, 0x09,
|
||||||
|
0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08,
|
||||||
|
0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00,
|
||||||
|
0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x40, 0x91,
|
||||||
|
0x02, 0xc0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sample uevent file from a Yubico Security Key.
|
||||||
|
*/
|
||||||
|
static const char dummy_uevent[] =
|
||||||
|
"DRIVER=hid-generic\n"
|
||||||
|
"HID_ID=0003:00001050:00000120\n"
|
||||||
|
"HID_NAME=Yubico Security Key by Yubico\n"
|
||||||
|
"HID_PHYS=usb-0000:00:14.0-3/input0\n"
|
||||||
|
"HID_UNIQ=\n"
|
||||||
|
"MODALIAS=hid:b0003g0001v00001050p00000120\n";
|
||||||
|
|
||||||
|
struct param *
|
||||||
|
unpack(const uint8_t *ptr, size_t len)
|
||||||
|
{
|
||||||
|
cbor_item_t *item = NULL, **v;
|
||||||
|
struct cbor_load_result cbor;
|
||||||
|
struct param *p;
|
||||||
|
int ok = -1;
|
||||||
|
|
||||||
|
if ((p = calloc(1, sizeof(*p))) == NULL ||
|
||||||
|
(item = cbor_load(ptr, len, &cbor)) == NULL ||
|
||||||
|
cbor.read != len ||
|
||||||
|
cbor_isa_array(item) == false ||
|
||||||
|
cbor_array_is_definite(item) == false ||
|
||||||
|
cbor_array_size(item) != 4 ||
|
||||||
|
(v = cbor_array_handle(item)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (unpack_int(v[0], &p->seed) < 0 ||
|
||||||
|
unpack_string(v[1], p->uevent) < 0 ||
|
||||||
|
unpack_blob(v[2], &p->report_descriptor) < 0 ||
|
||||||
|
unpack_blob(v[3], &p->netlink_wiredata) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ok = 0;
|
||||||
|
fail:
|
||||||
|
if (ok < 0) {
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
cbor_decref(&item);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
pack(uint8_t *ptr, size_t len, const struct param *p)
|
||||||
|
{
|
||||||
|
cbor_item_t *argv[4], *array = NULL;
|
||||||
|
size_t cbor_alloc_len, cbor_len = 0;
|
||||||
|
unsigned char *cbor = NULL;
|
||||||
|
|
||||||
|
memset(argv, 0, sizeof(argv));
|
||||||
|
|
||||||
|
if ((array = cbor_new_definite_array(4)) == NULL ||
|
||||||
|
(argv[0] = pack_int(p->seed)) == NULL ||
|
||||||
|
(argv[1] = pack_string(p->uevent)) == NULL ||
|
||||||
|
(argv[2] = pack_blob(&p->report_descriptor)) == NULL ||
|
||||||
|
(argv[3] = pack_blob(&p->netlink_wiredata)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 4; i++)
|
||||||
|
if (cbor_array_push(array, argv[i]) == false)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if ((cbor_len = cbor_serialize_alloc(array, &cbor,
|
||||||
|
&cbor_alloc_len)) == 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);
|
||||||
|
}
|
||||||
272
fuzz/fuzz_largeblob.c
Normal file
272
fuzz/fuzz_largeblob.c
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
#include "wiredata_fido2.h"
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
|
#include "../openbsd-compat/openbsd-compat.h"
|
||||||
|
|
||||||
|
/* Parameter set defining a FIDO2 "large blob" operation. */
|
||||||
|
struct param {
|
||||||
|
char pin[MAXSTR];
|
||||||
|
int seed;
|
||||||
|
struct blob key;
|
||||||
|
struct blob get_wiredata;
|
||||||
|
struct blob set_wiredata;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* 'authenticatorLargeBlobs' 'get' command.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_get_wiredata[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collection of HID reports from an authenticator issued with a FIDO2
|
||||||
|
* 'authenticatorLargeBlobs' 'set' command.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_set_wiredata[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_PINTOKEN,
|
||||||
|
WIREDATA_CTAP_CBOR_STATUS
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX this needs to match the encrypted blob embedded in
|
||||||
|
* WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY.
|
||||||
|
*/
|
||||||
|
static const uint8_t dummy_key[] = {
|
||||||
|
0xa9, 0x1b, 0xc4, 0xdd, 0xfc, 0x9a, 0x93, 0x79,
|
||||||
|
0x75, 0xba, 0xf7, 0x7f, 0x4d, 0x57, 0xfc, 0xa6,
|
||||||
|
0xe1, 0xf8, 0x06, 0x43, 0x23, 0x99, 0x51, 0x32,
|
||||||
|
0xce, 0x6e, 0x19, 0x84, 0x50, 0x13, 0x2d, 0x7b
|
||||||
|
};
|
||||||
|
|
||||||
|
struct param *
|
||||||
|
unpack(const uint8_t *ptr, size_t len)
|
||||||
|
{
|
||||||
|
cbor_item_t *item = NULL, **v;
|
||||||
|
struct cbor_load_result cbor;
|
||||||
|
struct param *p;
|
||||||
|
int ok = -1;
|
||||||
|
|
||||||
|
if ((p = calloc(1, sizeof(*p))) == NULL ||
|
||||||
|
(item = cbor_load(ptr, len, &cbor)) == NULL ||
|
||||||
|
cbor.read != len ||
|
||||||
|
cbor_isa_array(item) == false ||
|
||||||
|
cbor_array_is_definite(item) == false ||
|
||||||
|
cbor_array_size(item) != 5 ||
|
||||||
|
(v = cbor_array_handle(item)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (unpack_int(v[0], &p->seed) < 0 ||
|
||||||
|
unpack_string(v[1], p->pin) < 0 ||
|
||||||
|
unpack_blob(v[2], &p->key) < 0 ||
|
||||||
|
unpack_blob(v[3], &p->get_wiredata) < 0 ||
|
||||||
|
unpack_blob(v[4], &p->set_wiredata) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ok = 0;
|
||||||
|
fail:
|
||||||
|
if (ok < 0) {
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
cbor_decref(&item);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
pack(uint8_t *ptr, size_t len, const struct param *p)
|
||||||
|
{
|
||||||
|
cbor_item_t *argv[5], *array = NULL;
|
||||||
|
size_t cbor_alloc_len, cbor_len = 0;
|
||||||
|
unsigned char *cbor = NULL;
|
||||||
|
|
||||||
|
memset(argv, 0, sizeof(argv));
|
||||||
|
|
||||||
|
if ((array = cbor_new_definite_array(5)) == NULL ||
|
||||||
|
(argv[0] = pack_int(p->seed)) == NULL ||
|
||||||
|
(argv[1] = pack_string(p->pin)) == NULL ||
|
||||||
|
(argv[2] = pack_blob(&p->key)) == NULL ||
|
||||||
|
(argv[3] = pack_blob(&p->get_wiredata)) == NULL ||
|
||||||
|
(argv[4] = pack_blob(&p->set_wiredata)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 5; i++)
|
||||||
|
if (cbor_array_push(array, argv[i]) == false)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if ((cbor_len = cbor_serialize_alloc(array, &cbor,
|
||||||
|
&cbor_alloc_len)) == 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
528
fuzz/fuzz_mgmt.c
Normal file
528
fuzz/fuzz_mgmt.c
Normal file
@@ -0,0 +1,528 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2022 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
#include "wiredata_fido2.h"
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
|
#include "../openbsd-compat/openbsd-compat.h"
|
||||||
|
|
||||||
|
#define MAXRPID 64
|
||||||
|
|
||||||
|
struct param {
|
||||||
|
char pin1[MAXSTR];
|
||||||
|
char pin2[MAXSTR];
|
||||||
|
struct blob reset_wire_data;
|
||||||
|
struct blob info_wire_data;
|
||||||
|
struct blob set_pin_wire_data;
|
||||||
|
struct blob change_pin_wire_data;
|
||||||
|
struct blob retry_wire_data;
|
||||||
|
struct blob config_wire_data;
|
||||||
|
int seed;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t dummy_reset_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_KEEPALIVE,
|
||||||
|
WIREDATA_CTAP_KEEPALIVE,
|
||||||
|
WIREDATA_CTAP_KEEPALIVE,
|
||||||
|
WIREDATA_CTAP_CBOR_STATUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t dummy_info_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t dummy_set_pin_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_STATUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t dummy_change_pin_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_AUTHKEY,
|
||||||
|
WIREDATA_CTAP_CBOR_STATUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t dummy_retry_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_RETRIES,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t dummy_config_wire_data[] = {
|
||||||
|
WIREDATA_CTAP_INIT,
|
||||||
|
WIREDATA_CTAP_CBOR_INFO,
|
||||||
|
WIREDATA_CTAP_CBOR_STATUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct param *
|
||||||
|
unpack(const uint8_t *ptr, size_t len)
|
||||||
|
{
|
||||||
|
cbor_item_t *item = NULL, **v;
|
||||||
|
struct cbor_load_result cbor;
|
||||||
|
struct param *p;
|
||||||
|
int ok = -1;
|
||||||
|
|
||||||
|
if ((p = calloc(1, sizeof(*p))) == NULL ||
|
||||||
|
(item = cbor_load(ptr, len, &cbor)) == NULL ||
|
||||||
|
cbor.read != len ||
|
||||||
|
cbor_isa_array(item) == false ||
|
||||||
|
cbor_array_is_definite(item) == false ||
|
||||||
|
cbor_array_size(item) != 9 ||
|
||||||
|
(v = cbor_array_handle(item)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (unpack_int(v[0], &p->seed) < 0 ||
|
||||||
|
unpack_string(v[1], p->pin1) < 0 ||
|
||||||
|
unpack_string(v[2], p->pin2) < 0 ||
|
||||||
|
unpack_blob(v[3], &p->reset_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[4], &p->info_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[5], &p->set_pin_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[6], &p->change_pin_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[7], &p->retry_wire_data) < 0 ||
|
||||||
|
unpack_blob(v[8], &p->config_wire_data) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ok = 0;
|
||||||
|
fail:
|
||||||
|
if (ok < 0) {
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
cbor_decref(&item);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
pack(uint8_t *ptr, size_t len, const struct param *p)
|
||||||
|
{
|
||||||
|
cbor_item_t *argv[9], *array = NULL;
|
||||||
|
size_t cbor_alloc_len, cbor_len = 0;
|
||||||
|
unsigned char *cbor = NULL;
|
||||||
|
|
||||||
|
memset(argv, 0, sizeof(argv));
|
||||||
|
|
||||||
|
if ((array = cbor_new_definite_array(9)) == NULL ||
|
||||||
|
(argv[0] = pack_int(p->seed)) == NULL ||
|
||||||
|
(argv[1] = pack_string(p->pin1)) == NULL ||
|
||||||
|
(argv[2] = pack_string(p->pin2)) == NULL ||
|
||||||
|
(argv[3] = pack_blob(&p->reset_wire_data)) == NULL ||
|
||||||
|
(argv[4] = pack_blob(&p->info_wire_data)) == NULL ||
|
||||||
|
(argv[5] = pack_blob(&p->set_pin_wire_data)) == NULL ||
|
||||||
|
(argv[6] = pack_blob(&p->change_pin_wire_data)) == NULL ||
|
||||||
|
(argv[7] = pack_blob(&p->retry_wire_data)) == NULL ||
|
||||||
|
(argv[8] = pack_blob(&p->config_wire_data)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 9; i++)
|
||||||
|
if (cbor_array_push(array, argv[i]) == false)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if ((cbor_len = cbor_serialize_alloc(array, &cbor,
|
||||||
|
&cbor_alloc_len)) == 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
164
fuzz/fuzz_netlink.c
Normal file
164
fuzz/fuzz_netlink.c
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../openbsd-compat/openbsd-compat.h"
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
|
struct param {
|
||||||
|
int seed;
|
||||||
|
int dev;
|
||||||
|
struct blob wiredata;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct param *
|
||||||
|
unpack(const uint8_t *ptr, size_t len)
|
||||||
|
{
|
||||||
|
cbor_item_t *item = NULL, **v;
|
||||||
|
struct cbor_load_result cbor;
|
||||||
|
struct param *p;
|
||||||
|
int ok = -1;
|
||||||
|
|
||||||
|
if ((p = calloc(1, sizeof(*p))) == NULL ||
|
||||||
|
(item = cbor_load(ptr, len, &cbor)) == NULL ||
|
||||||
|
cbor.read != len ||
|
||||||
|
cbor_isa_array(item) == false ||
|
||||||
|
cbor_array_is_definite(item) == false ||
|
||||||
|
cbor_array_size(item) != 3 ||
|
||||||
|
(v = cbor_array_handle(item)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (unpack_int(v[0], &p->seed) < 0 ||
|
||||||
|
unpack_int(v[1], &p->dev) < 0 ||
|
||||||
|
unpack_blob(v[2], &p->wiredata) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ok = 0;
|
||||||
|
fail:
|
||||||
|
if (ok < 0) {
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
cbor_decref(&item);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
pack(uint8_t *ptr, size_t len, const struct param *p)
|
||||||
|
{
|
||||||
|
cbor_item_t *argv[3], *array = NULL;
|
||||||
|
size_t cbor_alloc_len, cbor_len = 0;
|
||||||
|
unsigned char *cbor = NULL;
|
||||||
|
|
||||||
|
memset(argv, 0, sizeof(argv));
|
||||||
|
|
||||||
|
if ((array = cbor_new_definite_array(3)) == NULL ||
|
||||||
|
(argv[0] = pack_int(p->seed)) == NULL ||
|
||||||
|
(argv[1] = pack_int(p->dev)) == NULL ||
|
||||||
|
(argv[2] = pack_blob(&p->wiredata)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 3; i++)
|
||||||
|
if (cbor_array_push(array, argv[i]) == false)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if ((cbor_len = cbor_serialize_alloc(array, &cbor,
|
||||||
|
&cbor_alloc_len)) == 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);
|
||||||
|
}
|
||||||
269
fuzz/fuzz_pcsc.c
Normal file
269
fuzz/fuzz_pcsc.c
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _FIDO_INTERNAL
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <winscard.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
#include "wiredata_fido2.h"
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
|
#include "../src/extern.h"
|
||||||
|
|
||||||
|
struct param {
|
||||||
|
int seed;
|
||||||
|
char path[MAXSTR];
|
||||||
|
struct blob pcsc_list;
|
||||||
|
struct blob tx_apdu;
|
||||||
|
struct blob wiredata_init;
|
||||||
|
struct blob wiredata_msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t dummy_tx_apdu[] = { WIREDATA_CTAP_EXTENDED_APDU };
|
||||||
|
static const uint8_t dummy_wiredata_init[] = { WIREDATA_CTAP_NFC_INIT };
|
||||||
|
static const uint8_t dummy_wiredata_msg[] = { WIREDATA_CTAP_NFC_MSG };
|
||||||
|
|
||||||
|
struct param *
|
||||||
|
unpack(const uint8_t *ptr, size_t len)
|
||||||
|
{
|
||||||
|
cbor_item_t *item = NULL, **v;
|
||||||
|
struct cbor_load_result cbor;
|
||||||
|
struct param *p;
|
||||||
|
int ok = -1;
|
||||||
|
|
||||||
|
if ((p = calloc(1, sizeof(*p))) == NULL ||
|
||||||
|
(item = cbor_load(ptr, len, &cbor)) == NULL ||
|
||||||
|
cbor.read != len ||
|
||||||
|
cbor_isa_array(item) == false ||
|
||||||
|
cbor_array_is_definite(item) == false ||
|
||||||
|
cbor_array_size(item) != 6 ||
|
||||||
|
(v = cbor_array_handle(item)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (unpack_int(v[0], &p->seed) < 0 ||
|
||||||
|
unpack_string(v[1], p->path) < 0 ||
|
||||||
|
unpack_blob(v[2], &p->pcsc_list) < 0 ||
|
||||||
|
unpack_blob(v[3], &p->tx_apdu) < 0 ||
|
||||||
|
unpack_blob(v[4], &p->wiredata_init) < 0 ||
|
||||||
|
unpack_blob(v[5], &p->wiredata_msg) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ok = 0;
|
||||||
|
fail:
|
||||||
|
if (ok < 0) {
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
cbor_decref(&item);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
pack(uint8_t *ptr, size_t len, const struct param *p)
|
||||||
|
{
|
||||||
|
cbor_item_t *argv[6], *array = NULL;
|
||||||
|
size_t cbor_alloc_len, cbor_len = 0;
|
||||||
|
unsigned char *cbor = NULL;
|
||||||
|
|
||||||
|
memset(argv, 0, sizeof(argv));
|
||||||
|
|
||||||
|
if ((array = cbor_new_definite_array(6)) == NULL ||
|
||||||
|
(argv[0] = pack_int(p->seed)) == NULL ||
|
||||||
|
(argv[1] = pack_string(p->path)) == NULL ||
|
||||||
|
(argv[2] = pack_blob(&p->pcsc_list)) == NULL ||
|
||||||
|
(argv[3] = pack_blob(&p->tx_apdu)) == NULL ||
|
||||||
|
(argv[4] = pack_blob(&p->wiredata_init)) == NULL ||
|
||||||
|
(argv[5] = pack_blob(&p->wiredata_msg)) == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 6; i++)
|
||||||
|
if (cbor_array_push(array, argv[i]) == false)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if ((cbor_len = cbor_serialize_alloc(array, &cbor,
|
||||||
|
&cbor_alloc_len)) == 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
231
fuzz/libfuzzer.c
Normal file
231
fuzz/libfuzzer.c
Normal file
@@ -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 <openssl/sha.h>
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
|
||||||
|
extern int fuzz_save_corpus;
|
||||||
|
|
||||||
|
static bool debug;
|
||||||
|
static unsigned int flags = MUTATE_ALL;
|
||||||
|
static unsigned long long test_fail;
|
||||||
|
static unsigned long long test_total;
|
||||||
|
static unsigned long long mutate_fail;
|
||||||
|
static unsigned long long mutate_total;
|
||||||
|
|
||||||
|
int LLVMFuzzerInitialize(int *, char ***);
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *, size_t);
|
||||||
|
size_t LLVMFuzzerCustomMutator(uint8_t *, size_t, size_t, unsigned int);
|
||||||
|
|
||||||
|
static int
|
||||||
|
save_seed(const char *opt)
|
||||||
|
{
|
||||||
|
const char *path;
|
||||||
|
int fd = -1, status = 1;
|
||||||
|
void *buf = NULL;
|
||||||
|
const size_t buflen = MAXCORPUS;
|
||||||
|
size_t n;
|
||||||
|
struct param *p = NULL;
|
||||||
|
|
||||||
|
if ((path = strchr(opt, '=')) == NULL || strlen(++path) == 0) {
|
||||||
|
warnx("usage: --fido-save-seed=<path>");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, 0644)) == -1) {
|
||||||
|
warn("open %s", path);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((buf = malloc(buflen)) == NULL) {
|
||||||
|
warn("malloc");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = pack_dummy(buf, buflen);
|
||||||
|
|
||||||
|
if ((p = unpack(buf, n)) == NULL) {
|
||||||
|
warnx("unpack");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write(fd, buf, n) != (ssize_t)n) {
|
||||||
|
warn("write %s", path);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = 0;
|
||||||
|
fail:
|
||||||
|
if (fd != -1)
|
||||||
|
close(fd);
|
||||||
|
free(buf);
|
||||||
|
free(p);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
save_corpus(const struct param *p)
|
||||||
|
{
|
||||||
|
uint8_t blob[MAXCORPUS], dgst[SHA256_DIGEST_LENGTH];
|
||||||
|
size_t blob_len;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
int r, fd;
|
||||||
|
|
||||||
|
if ((blob_len = pack(blob, sizeof(blob), p)) == 0 ||
|
||||||
|
blob_len > sizeof(blob)) {
|
||||||
|
warnx("pack");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SHA256(blob, blob_len, dgst) != dgst) {
|
||||||
|
warnx("sha256");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((r = snprintf(path, sizeof(path), "saved_corpus_%02x%02x%02x%02x"
|
||||||
|
"%02x%02x%02x%02x", dgst[0], dgst[1], dgst[2], dgst[3], dgst[4],
|
||||||
|
dgst[5], dgst[6], dgst[7])) < 0 || (size_t)r >= sizeof(path)) {
|
||||||
|
warnx("snprintf");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, 0644)) == -1) {
|
||||||
|
warn("open %s", path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write(fd, blob, blob_len) != (ssize_t)blob_len) {
|
||||||
|
warn("write");
|
||||||
|
r = -1;
|
||||||
|
} else {
|
||||||
|
warnx("wrote %s", path);
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_mutate_flags(const char *opt, unsigned int *mutate_flags)
|
||||||
|
{
|
||||||
|
const char *f;
|
||||||
|
|
||||||
|
if ((f = strchr(opt, '=')) == NULL || strlen(++f) == 0)
|
||||||
|
errx(1, "usage: --fido-mutate=<flag>");
|
||||||
|
|
||||||
|
if (strcmp(f, "seed") == 0)
|
||||||
|
*mutate_flags |= MUTATE_SEED;
|
||||||
|
else if (strcmp(f, "param") == 0)
|
||||||
|
*mutate_flags |= MUTATE_PARAM;
|
||||||
|
else if (strcmp(f, "wiredata") == 0)
|
||||||
|
*mutate_flags |= MUTATE_WIREDATA;
|
||||||
|
else
|
||||||
|
errx(1, "--fido-mutate: unknown flag '%s'", f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
LLVMFuzzerInitialize(int *argc, char ***argv)
|
||||||
|
{
|
||||||
|
unsigned int mutate_flags = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < *argc; i++)
|
||||||
|
if (strcmp((*argv)[i], "--fido-debug") == 0) {
|
||||||
|
debug = 1;
|
||||||
|
} else if (strncmp((*argv)[i], "--fido-save-seed=", 17) == 0) {
|
||||||
|
exit(save_seed((*argv)[i]));
|
||||||
|
} else if (strncmp((*argv)[i], "--fido-mutate=", 14) == 0) {
|
||||||
|
parse_mutate_flags((*argv)[i], &mutate_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mutate_flags)
|
||||||
|
flags = mutate_flags;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||||
|
{
|
||||||
|
struct param *p;
|
||||||
|
|
||||||
|
if (size > MAXCORPUS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (++test_total % 100000 == 0 && debug) {
|
||||||
|
double r = (double)test_fail/(double)test_total * 100.0;
|
||||||
|
fprintf(stderr, "%s: %llu/%llu (%.2f%%)\n", __func__,
|
||||||
|
test_fail, test_total, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((p = unpack(data, size)) == NULL)
|
||||||
|
test_fail++;
|
||||||
|
else {
|
||||||
|
fuzz_save_corpus = 0;
|
||||||
|
test(p);
|
||||||
|
if (fuzz_save_corpus && save_corpus(p) < 0)
|
||||||
|
fprintf(stderr, "%s: failed to save corpus\n",
|
||||||
|
__func__);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxsize,
|
||||||
|
unsigned int seed) NO_MSAN
|
||||||
|
{
|
||||||
|
struct param *p;
|
||||||
|
uint8_t blob[MAXCORPUS];
|
||||||
|
size_t blob_len;
|
||||||
|
|
||||||
|
memset(&p, 0, sizeof(p));
|
||||||
|
|
||||||
|
#ifdef WITH_MSAN
|
||||||
|
__msan_unpoison(data, maxsize);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (++mutate_total % 100000 == 0 && debug) {
|
||||||
|
double r = (double)mutate_fail/(double)mutate_total * 100.0;
|
||||||
|
fprintf(stderr, "%s: %llu/%llu (%.2f%%)\n", __func__,
|
||||||
|
mutate_fail, mutate_total, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((p = unpack(data, size)) == NULL) {
|
||||||
|
mutate_fail++;
|
||||||
|
return pack_dummy(data, maxsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutate(p, seed, flags);
|
||||||
|
|
||||||
|
if ((blob_len = pack(blob, sizeof(blob), p)) == 0 ||
|
||||||
|
blob_len > sizeof(blob) || blob_len > maxsize) {
|
||||||
|
mutate_fail++;
|
||||||
|
free(p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(p);
|
||||||
|
|
||||||
|
memcpy(data, blob, blob_len);
|
||||||
|
|
||||||
|
return blob_len;
|
||||||
|
}
|
||||||
338
fuzz/mutator_aux.c
Normal file
338
fuzz/mutator_aux.c
Normal file
@@ -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 <assert.h>
|
||||||
|
#include <cbor.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
|
||||||
|
int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int);
|
||||||
|
int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t);
|
||||||
|
size_t LLVMFuzzerMutate(uint8_t *, size_t, size_t);
|
||||||
|
|
||||||
|
extern int prng_up;
|
||||||
|
static const uint8_t *wire_data_ptr = NULL;
|
||||||
|
static size_t wire_data_len = 0;
|
||||||
|
|
||||||
|
void
|
||||||
|
consume(const void *body, size_t len)
|
||||||
|
{
|
||||||
|
const volatile uint8_t *ptr = body;
|
||||||
|
volatile uint8_t x = 0;
|
||||||
|
|
||||||
|
#ifdef WITH_MSAN
|
||||||
|
__msan_check_mem_is_initialized(body, len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (len--)
|
||||||
|
x ^= *ptr++;
|
||||||
|
|
||||||
|
(void)x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
consume_str(const char *str)
|
||||||
|
{
|
||||||
|
if (str != NULL)
|
||||||
|
consume(str, strlen(str) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
unpack_int(cbor_item_t *item, int *v)
|
||||||
|
{
|
||||||
|
if (cbor_is_int(item) == false ||
|
||||||
|
cbor_int_get_width(item) != CBOR_INT_64)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (cbor_isa_uint(item))
|
||||||
|
*v = (int)cbor_get_uint64(item);
|
||||||
|
else
|
||||||
|
*v = (int)(-cbor_get_uint64(item) - 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
unpack_string(cbor_item_t *item, char *v)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (cbor_isa_bytestring(item) == false ||
|
||||||
|
(len = cbor_bytestring_length(item)) >= MAXSTR)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memcpy(v, cbor_bytestring_handle(item), len);
|
||||||
|
v[len] = '\0';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
unpack_byte(cbor_item_t *item, uint8_t *v)
|
||||||
|
{
|
||||||
|
if (cbor_isa_uint(item) == false ||
|
||||||
|
cbor_int_get_width(item) != CBOR_INT_8)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*v = cbor_get_uint8(item);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
unpack_blob(cbor_item_t *item, struct blob *v)
|
||||||
|
{
|
||||||
|
if (cbor_isa_bytestring(item) == false ||
|
||||||
|
(v->len = cbor_bytestring_length(item)) > sizeof(v->body))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memcpy(v->body, cbor_bytestring_handle(item), v->len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbor_item_t *
|
||||||
|
pack_int(int v) NO_MSAN
|
||||||
|
{
|
||||||
|
if (v < 0)
|
||||||
|
return cbor_build_negint64((uint64_t)(-(int64_t)v - 1));
|
||||||
|
else
|
||||||
|
return cbor_build_uint64((uint64_t)v);
|
||||||
|
}
|
||||||
|
|
||||||
|
cbor_item_t *
|
||||||
|
pack_string(const char *v) NO_MSAN
|
||||||
|
{
|
||||||
|
if (strlen(v) >= MAXSTR)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return cbor_build_bytestring((const unsigned char *)v, strlen(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
cbor_item_t *
|
||||||
|
pack_byte(uint8_t v) NO_MSAN
|
||||||
|
{
|
||||||
|
return cbor_build_uint8(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
cbor_item_t *
|
||||||
|
pack_blob(const struct blob *v) NO_MSAN
|
||||||
|
{
|
||||||
|
return cbor_build_bytestring(v->body, v->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mutate_byte(uint8_t *b)
|
||||||
|
{
|
||||||
|
LLVMFuzzerMutate(b, sizeof(*b), sizeof(*b));
|
||||||
|
#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;
|
||||||
|
}
|
||||||
111
fuzz/mutator_aux.h
Normal file
111
fuzz/mutator_aux.h
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2022 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MUTATOR_AUX_H
|
||||||
|
#define _MUTATOR_AUX_H
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <cbor.h>
|
||||||
|
|
||||||
|
#include "../src/fido.h"
|
||||||
|
#include "../src/fido/bio.h"
|
||||||
|
#include "../src/fido/config.h"
|
||||||
|
#include "../src/fido/credman.h"
|
||||||
|
#include "../src/fido/eddsa.h"
|
||||||
|
#include "../src/fido/es256.h"
|
||||||
|
#include "../src/fido/es384.h"
|
||||||
|
#include "../src/fido/rs256.h"
|
||||||
|
#include "../src/netlink.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As of LLVM 10.0.0, MSAN support in libFuzzer was still experimental.
|
||||||
|
* We therefore have to be careful when using our custom mutator, or
|
||||||
|
* MSAN will flag uninitialised reads on memory populated by libFuzzer.
|
||||||
|
* Since there is no way to suppress MSAN without regenerating object
|
||||||
|
* code (in which case you might as well rebuild libFuzzer with MSAN),
|
||||||
|
* we adjust our mutator to make it less accurate while allowing
|
||||||
|
* fuzzing to proceed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__has_feature)
|
||||||
|
# if __has_feature(memory_sanitizer)
|
||||||
|
# include <sanitizer/msan_interface.h>
|
||||||
|
# define NO_MSAN __attribute__((no_sanitize("memory")))
|
||||||
|
# define WITH_MSAN 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(WITH_MSAN)
|
||||||
|
# define NO_MSAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MUTATE_SEED 0x01
|
||||||
|
#define MUTATE_PARAM 0x02
|
||||||
|
#define MUTATE_WIREDATA 0x04
|
||||||
|
#define MUTATE_ALL (MUTATE_SEED | MUTATE_PARAM | MUTATE_WIREDATA)
|
||||||
|
|
||||||
|
#define MAXSTR 1024
|
||||||
|
#define MAXBLOB 3600
|
||||||
|
#define MAXCORPUS 8192
|
||||||
|
|
||||||
|
#define HID_DEV_HANDLE 0x68696421
|
||||||
|
#define NFC_DEV_HANDLE 0x6e666321
|
||||||
|
|
||||||
|
struct blob {
|
||||||
|
uint8_t body[MAXBLOB];
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct param;
|
||||||
|
|
||||||
|
struct param *unpack(const uint8_t *, size_t);
|
||||||
|
size_t pack(uint8_t *, size_t, const struct param *);
|
||||||
|
size_t pack_dummy(uint8_t *, size_t);
|
||||||
|
void mutate(struct param *, unsigned int, unsigned int);
|
||||||
|
void test(const struct param *);
|
||||||
|
|
||||||
|
void consume(const void *, size_t);
|
||||||
|
void consume_str(const char *);
|
||||||
|
|
||||||
|
int unpack_blob(cbor_item_t *, struct blob *);
|
||||||
|
int unpack_byte(cbor_item_t *, uint8_t *);
|
||||||
|
int unpack_int(cbor_item_t *, int *);
|
||||||
|
int unpack_string(cbor_item_t *, char *);
|
||||||
|
|
||||||
|
cbor_item_t *pack_blob(const struct blob *);
|
||||||
|
cbor_item_t *pack_byte(uint8_t);
|
||||||
|
cbor_item_t *pack_int(int);
|
||||||
|
cbor_item_t *pack_string(const char *);
|
||||||
|
|
||||||
|
void mutate_byte(uint8_t *);
|
||||||
|
void mutate_int(int *);
|
||||||
|
void mutate_blob(struct blob *);
|
||||||
|
void mutate_string(char *);
|
||||||
|
|
||||||
|
ssize_t fd_read(int, void *, size_t);
|
||||||
|
ssize_t fd_write(int, const void *, size_t);
|
||||||
|
|
||||||
|
int nfc_read(void *, unsigned char *, size_t, int);
|
||||||
|
int nfc_write(void *, const unsigned char *, size_t);
|
||||||
|
|
||||||
|
fido_dev_t *open_dev(int);
|
||||||
|
void set_wire_data(const uint8_t *, size_t);
|
||||||
|
|
||||||
|
void fuzz_clock_reset(void);
|
||||||
|
void prng_init(unsigned long);
|
||||||
|
unsigned long prng_uint32(void);
|
||||||
|
|
||||||
|
uint32_t uniform_random(uint32_t);
|
||||||
|
|
||||||
|
void set_pcsc_parameters(const struct blob *);
|
||||||
|
void set_pcsc_io_functions(int (*)(void *, u_char *, size_t, int),
|
||||||
|
int (*)(void *, const u_char *, size_t), void (*)(const void *, size_t));
|
||||||
|
|
||||||
|
#endif /* !_MUTATOR_AUX_H */
|
||||||
153
fuzz/pcsc.c
Normal file
153
fuzz/pcsc.c
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <winscard.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
|
||||||
|
static const struct blob *reader_list;
|
||||||
|
static int (*xread)(void *, u_char *, size_t, int);
|
||||||
|
static int (*xwrite)(void *, const u_char *, size_t);
|
||||||
|
static void (*xconsume)(const void *, size_t);
|
||||||
|
|
||||||
|
LONG __wrap_SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
|
||||||
|
LONG __wrap_SCardListReaders(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD);
|
||||||
|
LONG __wrap_SCardReleaseContext(SCARDCONTEXT);
|
||||||
|
LONG __wrap_SCardConnect(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE,
|
||||||
|
LPDWORD);
|
||||||
|
LONG __wrap_SCardDisconnect(SCARDHANDLE, DWORD);
|
||||||
|
LONG __wrap_SCardTransmit(SCARDHANDLE, const SCARD_IO_REQUEST *, LPCBYTE,
|
||||||
|
DWORD, SCARD_IO_REQUEST *, LPBYTE, LPDWORD);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
__wrap_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
|
||||||
|
LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
|
||||||
|
{
|
||||||
|
assert(dwScope == SCARD_SCOPE_SYSTEM);
|
||||||
|
assert(pvReserved1 == NULL);
|
||||||
|
assert(pvReserved2 == NULL);
|
||||||
|
|
||||||
|
*phContext = 1;
|
||||||
|
|
||||||
|
if (uniform_random(400) < 1)
|
||||||
|
return SCARD_E_NO_SERVICE;
|
||||||
|
if (uniform_random(400) < 1)
|
||||||
|
return SCARD_E_NO_SMARTCARD;
|
||||||
|
if (uniform_random(400) < 1)
|
||||||
|
return SCARD_E_NO_MEMORY;
|
||||||
|
if (uniform_random(400) < 1)
|
||||||
|
*phContext = 0;
|
||||||
|
|
||||||
|
return SCARD_S_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG
|
||||||
|
__wrap_SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
|
||||||
|
LPSTR mszReaders, LPDWORD pcchReaders)
|
||||||
|
{
|
||||||
|
assert(hContext == 1);
|
||||||
|
assert(mszGroups == NULL);
|
||||||
|
assert(mszReaders != NULL);
|
||||||
|
assert(pcchReaders != 0);
|
||||||
|
|
||||||
|
if (reader_list == NULL || uniform_random(400) < 1)
|
||||||
|
return SCARD_E_NO_READERS_AVAILABLE;
|
||||||
|
if (uniform_random(400) < 1)
|
||||||
|
return SCARD_E_NO_MEMORY;
|
||||||
|
|
||||||
|
memcpy(mszReaders, reader_list->body, reader_list->len > *pcchReaders ?
|
||||||
|
*pcchReaders : reader_list->len);
|
||||||
|
*pcchReaders = (DWORD)reader_list->len; /* on purpose */
|
||||||
|
|
||||||
|
return SCARD_S_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG
|
||||||
|
__wrap_SCardReleaseContext(SCARDCONTEXT hContext)
|
||||||
|
{
|
||||||
|
assert(hContext == 1);
|
||||||
|
|
||||||
|
return SCARD_S_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG
|
||||||
|
__wrap_SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
|
||||||
|
DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
|
||||||
|
{
|
||||||
|
uint32_t r;
|
||||||
|
|
||||||
|
assert(hContext == 1);
|
||||||
|
xconsume(szReader, strlen(szReader) + 1);
|
||||||
|
assert(dwShareMode == SCARD_SHARE_SHARED);
|
||||||
|
assert(dwPreferredProtocols == SCARD_PROTOCOL_ANY);
|
||||||
|
assert(phCard != NULL);
|
||||||
|
assert(pdwActiveProtocol != NULL);
|
||||||
|
|
||||||
|
if ((r = uniform_random(400)) < 1)
|
||||||
|
return SCARD_E_UNEXPECTED;
|
||||||
|
|
||||||
|
*phCard = 1;
|
||||||
|
*pdwActiveProtocol = (r & 1) ? SCARD_PROTOCOL_T0 : SCARD_PROTOCOL_T1;
|
||||||
|
|
||||||
|
if (uniform_random(400) < 1)
|
||||||
|
*pdwActiveProtocol = SCARD_PROTOCOL_RAW;
|
||||||
|
|
||||||
|
return SCARD_S_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG
|
||||||
|
__wrap_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
|
||||||
|
{
|
||||||
|
assert(hCard == 1);
|
||||||
|
assert(dwDisposition == SCARD_LEAVE_CARD);
|
||||||
|
|
||||||
|
return SCARD_S_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void consume(const void *body, size_t len);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
__wrap_SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
|
||||||
|
LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci,
|
||||||
|
LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
|
||||||
|
{
|
||||||
|
void *ioh = (void *)NFC_DEV_HANDLE;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
assert(hCard == 1);
|
||||||
|
xconsume(pioSendPci, sizeof(*pioSendPci));
|
||||||
|
xwrite(ioh, pbSendBuffer, cbSendLength);
|
||||||
|
assert(pioRecvPci == NULL);
|
||||||
|
|
||||||
|
if (uniform_random(400) < 1 ||
|
||||||
|
(n = xread(ioh, pbRecvBuffer, *pcbRecvLength, -1)) == -1)
|
||||||
|
return SCARD_E_UNEXPECTED;
|
||||||
|
*pcbRecvLength = (DWORD)n;
|
||||||
|
|
||||||
|
return SCARD_S_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_pcsc_parameters(const struct blob *reader_list_ptr)
|
||||||
|
{
|
||||||
|
reader_list = reader_list_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_pcsc_io_functions(int (*read_f)(void *, u_char *, size_t, int),
|
||||||
|
int (*write_f)(void *, const u_char *, size_t),
|
||||||
|
void (*consume_f)(const void *, size_t))
|
||||||
|
{
|
||||||
|
xread = read_f;
|
||||||
|
xwrite = write_f;
|
||||||
|
xconsume = consume_f;
|
||||||
|
}
|
||||||
105
fuzz/preload-fuzz.c
Normal file
105
fuzz/preload-fuzz.c
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cc -fPIC -D_GNU_SOURCE -shared -o preload-fuzz.so preload-fuzz.c
|
||||||
|
* LD_PRELOAD=$(realpath preload-fuzz.so)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define FUZZ_DEV_PREFIX "nodev"
|
||||||
|
|
||||||
|
static int fd_fuzz = -1;
|
||||||
|
static int (*open_f)(const char *, int, mode_t);
|
||||||
|
static int (*close_f)(int);
|
||||||
|
static ssize_t (*write_f)(int, const void *, size_t);
|
||||||
|
|
||||||
|
int
|
||||||
|
open(const char *path, int flags, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
mode_t mode;
|
||||||
|
|
||||||
|
va_start(ap, flags);
|
||||||
|
mode = va_arg(ap, mode_t);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (open_f == NULL) {
|
||||||
|
open_f = dlsym(RTLD_NEXT, "open");
|
||||||
|
if (open_f == NULL) {
|
||||||
|
warnx("%s: dlsym", __func__);
|
||||||
|
errno = EACCES;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(path, FUZZ_DEV_PREFIX, strlen(FUZZ_DEV_PREFIX)) != 0)
|
||||||
|
return (open_f(path, flags, mode));
|
||||||
|
|
||||||
|
if (fd_fuzz != -1) {
|
||||||
|
warnx("%s: fd_fuzz != -1", __func__);
|
||||||
|
errno = EACCES;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fd_fuzz = dup(STDIN_FILENO)) < 0) {
|
||||||
|
warn("%s: dup", __func__);
|
||||||
|
errno = EACCES;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fd_fuzz);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
close(int fd)
|
||||||
|
{
|
||||||
|
if (close_f == NULL) {
|
||||||
|
close_f = dlsym(RTLD_NEXT, "close");
|
||||||
|
if (close_f == NULL) {
|
||||||
|
warnx("%s: dlsym", __func__);
|
||||||
|
errno = EACCES;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd == fd_fuzz)
|
||||||
|
fd_fuzz = -1;
|
||||||
|
|
||||||
|
return (close_f(fd));
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
write(int fd, const void *buf, size_t nbytes)
|
||||||
|
{
|
||||||
|
if (write_f == NULL) {
|
||||||
|
write_f = dlsym(RTLD_NEXT, "write");
|
||||||
|
if (write_f == NULL) {
|
||||||
|
warnx("%s: dlsym", __func__);
|
||||||
|
errno = EBADF;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd != fd_fuzz)
|
||||||
|
return (write_f(fd, buf, nbytes));
|
||||||
|
|
||||||
|
return (nbytes);
|
||||||
|
}
|
||||||
218
fuzz/preload-snoop.c
Normal file
218
fuzz/preload-snoop.c
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cc -fPIC -D_GNU_SOURCE -shared -o preload-snoop.so preload-snoop.c
|
||||||
|
* LD_PRELOAD=$(realpath preload-snoop.so)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define SNOOP_DEV_PREFIX "/dev/hidraw"
|
||||||
|
|
||||||
|
struct fd_tuple {
|
||||||
|
int snoop_in;
|
||||||
|
int snoop_out;
|
||||||
|
int real_dev;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct fd_tuple *fd_tuple;
|
||||||
|
static int (*open_f)(const char *, int, mode_t);
|
||||||
|
static int (*close_f)(int);
|
||||||
|
static ssize_t (*read_f)(int, void *, size_t);
|
||||||
|
static ssize_t (*write_f)(int, const void *, size_t);
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_fd(const char *hid_path, const char *suffix)
|
||||||
|
{
|
||||||
|
char *s = NULL;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
int fd;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if ((s = strdup(hid_path)) == NULL) {
|
||||||
|
warnx("%s: strdup", __func__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < strlen(s); i++)
|
||||||
|
if (s[i] == '/')
|
||||||
|
s[i] = '_';
|
||||||
|
|
||||||
|
if ((r = snprintf(path, sizeof(path), "%s-%s", s, suffix)) < 0 ||
|
||||||
|
(size_t)r >= sizeof(path)) {
|
||||||
|
warnx("%s: snprintf", __func__);
|
||||||
|
free(s);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(s);
|
||||||
|
s = NULL;
|
||||||
|
|
||||||
|
if ((fd = open_f(path, O_CREAT | O_WRONLY, 0644)) < 0) {
|
||||||
|
warn("%s: open", __func__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
open(const char *path, int flags, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
mode_t mode;
|
||||||
|
|
||||||
|
va_start(ap, flags);
|
||||||
|
mode = va_arg(ap, mode_t);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (open_f == NULL) {
|
||||||
|
open_f = dlsym(RTLD_NEXT, "open");
|
||||||
|
if (open_f == NULL) {
|
||||||
|
warnx("%s: dlsym", __func__);
|
||||||
|
errno = EACCES;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(path, SNOOP_DEV_PREFIX, strlen(SNOOP_DEV_PREFIX)) != 0)
|
||||||
|
return (open_f(path, flags, mode));
|
||||||
|
|
||||||
|
if (fd_tuple != NULL) {
|
||||||
|
warnx("%s: fd_tuple != NULL", __func__);
|
||||||
|
errno = EACCES;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fd_tuple = calloc(1, sizeof(*fd_tuple))) == NULL) {
|
||||||
|
warn("%s: calloc", __func__);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_tuple->snoop_in = -1;
|
||||||
|
fd_tuple->snoop_out = -1;
|
||||||
|
fd_tuple->real_dev = -1;
|
||||||
|
|
||||||
|
if ((fd_tuple->snoop_in = get_fd(path, "in")) < 0 ||
|
||||||
|
(fd_tuple->snoop_out = get_fd(path, "out")) < 0 ||
|
||||||
|
(fd_tuple->real_dev = open_f(path, flags, mode)) < 0) {
|
||||||
|
warn("%s: get_fd/open", __func__);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fd_tuple->real_dev);
|
||||||
|
fail:
|
||||||
|
if (fd_tuple->snoop_in != -1)
|
||||||
|
close(fd_tuple->snoop_in);
|
||||||
|
if (fd_tuple->snoop_out != -1)
|
||||||
|
close(fd_tuple->snoop_out);
|
||||||
|
if (fd_tuple->real_dev != -1)
|
||||||
|
close(fd_tuple->real_dev);
|
||||||
|
|
||||||
|
free(fd_tuple);
|
||||||
|
fd_tuple = NULL;
|
||||||
|
|
||||||
|
errno = EACCES;
|
||||||
|
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
close(int fd)
|
||||||
|
{
|
||||||
|
if (close_f == NULL) {
|
||||||
|
close_f = dlsym(RTLD_NEXT, "close");
|
||||||
|
if (close_f == NULL) {
|
||||||
|
warnx("%s: dlsym", __func__);
|
||||||
|
errno = EBADF;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd_tuple == NULL || fd_tuple->real_dev != fd)
|
||||||
|
return (close_f(fd));
|
||||||
|
|
||||||
|
close_f(fd_tuple->snoop_in);
|
||||||
|
close_f(fd_tuple->snoop_out);
|
||||||
|
close_f(fd_tuple->real_dev);
|
||||||
|
|
||||||
|
free(fd_tuple);
|
||||||
|
fd_tuple = NULL;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
read(int fd, void *buf, size_t nbytes)
|
||||||
|
{
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
|
if (read_f == NULL) {
|
||||||
|
read_f = dlsym(RTLD_NEXT, "read");
|
||||||
|
if (read_f == NULL) {
|
||||||
|
warnx("%s: dlsym", __func__);
|
||||||
|
errno = EBADF;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write_f == NULL) {
|
||||||
|
write_f = dlsym(RTLD_NEXT, "write");
|
||||||
|
if (write_f == NULL) {
|
||||||
|
warnx("%s: dlsym", __func__);
|
||||||
|
errno = EBADF;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd_tuple == NULL || fd_tuple->real_dev != fd)
|
||||||
|
return (read_f(fd, buf, nbytes));
|
||||||
|
|
||||||
|
if ((n = read_f(fd, buf, nbytes)) < 0 ||
|
||||||
|
write_f(fd_tuple->snoop_in, buf, n) != n)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
return (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
write(int fd, const void *buf, size_t nbytes)
|
||||||
|
{
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
|
if (write_f == NULL) {
|
||||||
|
write_f = dlsym(RTLD_NEXT, "write");
|
||||||
|
if (write_f == NULL) {
|
||||||
|
warnx("%s: dlsym", __func__);
|
||||||
|
errno = EBADF;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd_tuple == NULL || fd_tuple->real_dev != fd)
|
||||||
|
return (write_f(fd, buf, nbytes));
|
||||||
|
|
||||||
|
if ((n = write_f(fd, buf, nbytes)) < 0 ||
|
||||||
|
write_f(fd_tuple->snoop_out, buf, n) != n)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
return (n);
|
||||||
|
}
|
||||||
113
fuzz/prng.c
Normal file
113
fuzz/prng.c
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
A C-program for MT19937, with initialization improved 2002/1/26.
|
||||||
|
Coded by Takuji Nishimura and Makoto Matsumoto.
|
||||||
|
|
||||||
|
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. The names of its contributors may not be used to endorse or promote
|
||||||
|
products derived from this software without specific prior written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
Any feedback is very welcome.
|
||||||
|
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
||||||
|
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
|
||||||
|
#define init_genrand prng_init
|
||||||
|
#define genrand_int32 prng_uint32
|
||||||
|
|
||||||
|
/* Period parameters */
|
||||||
|
#define N 624
|
||||||
|
#define M 397
|
||||||
|
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
|
||||||
|
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
|
||||||
|
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
|
||||||
|
|
||||||
|
int prng_up = 0;
|
||||||
|
static unsigned long mt[N]; /* the array for the state vector */
|
||||||
|
static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
|
||||||
|
|
||||||
|
/* initializes mt[N] with a seed */
|
||||||
|
void init_genrand(unsigned long s)
|
||||||
|
{
|
||||||
|
mt[0]= s & 0xffffffffUL;
|
||||||
|
for (mti=1; mti<N; mti++) {
|
||||||
|
mt[mti] =
|
||||||
|
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) +
|
||||||
|
(unsigned long)mti);
|
||||||
|
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
|
||||||
|
/* In the previous versions, MSBs of the seed affect */
|
||||||
|
/* only MSBs of the array mt[]. */
|
||||||
|
/* 2002/01/09 modified by Makoto Matsumoto */
|
||||||
|
mt[mti] &= 0xffffffffUL;
|
||||||
|
/* for >32 bit machines */
|
||||||
|
}
|
||||||
|
prng_up = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generates a random number on [0,0xffffffff]-interval */
|
||||||
|
unsigned long genrand_int32(void)
|
||||||
|
{
|
||||||
|
unsigned long y;
|
||||||
|
static unsigned long mag01[2]={0x0UL, MATRIX_A};
|
||||||
|
/* mag01[x] = x * MATRIX_A for x=0,1 */
|
||||||
|
|
||||||
|
if (mti >= N) { /* generate N words at one time */
|
||||||
|
int kk;
|
||||||
|
|
||||||
|
assert(mti != N+1);
|
||||||
|
|
||||||
|
for (kk=0;kk<N-M;kk++) {
|
||||||
|
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
|
||||||
|
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
|
||||||
|
}
|
||||||
|
for (;kk<N-1;kk++) {
|
||||||
|
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
|
||||||
|
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
|
||||||
|
}
|
||||||
|
y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
|
||||||
|
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
|
||||||
|
|
||||||
|
mti = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
y = mt[mti++];
|
||||||
|
|
||||||
|
/* Tempering */
|
||||||
|
y ^= (y >> 11);
|
||||||
|
y ^= (y << 7) & 0x9d2c5680UL;
|
||||||
|
y ^= (y << 15) & 0xefc60000UL;
|
||||||
|
y ^= (y >> 18);
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
BIN
fuzz/report.tgz
Normal file
BIN
fuzz/report.tgz
Normal file
Binary file not shown.
64
fuzz/summary.txt
Normal file
64
fuzz/summary.txt
Normal file
@@ -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%
|
||||||
270
fuzz/udev.c
Normal file
270
fuzz/udev.c
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <linux/hidraw.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <libudev.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
|
||||||
|
struct udev {
|
||||||
|
int magic;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct udev_enumerate {
|
||||||
|
int magic;
|
||||||
|
struct udev_list_entry *list_entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct udev_list_entry {
|
||||||
|
int magic;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct udev_device {
|
||||||
|
int magic;
|
||||||
|
struct udev_device *parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define UDEV_MAGIC 0x584492cc
|
||||||
|
#define UDEV_DEVICE_MAGIC 0x569180dd
|
||||||
|
#define UDEV_LIST_ENTRY_MAGIC 0x497422ee
|
||||||
|
#define UDEV_ENUM_MAGIC 0x583570ff
|
||||||
|
|
||||||
|
#define ASSERT_TYPE(x, m) assert((x) != NULL && (x)->magic == (m))
|
||||||
|
#define ASSERT_UDEV(x) ASSERT_TYPE((x), UDEV_MAGIC)
|
||||||
|
#define ASSERT_UDEV_ENUM(x) ASSERT_TYPE((x), UDEV_ENUM_MAGIC)
|
||||||
|
#define ASSERT_UDEV_LIST_ENTRY(x) ASSERT_TYPE((x), UDEV_LIST_ENTRY_MAGIC)
|
||||||
|
#define ASSERT_UDEV_DEVICE(x) ASSERT_TYPE((x), UDEV_DEVICE_MAGIC)
|
||||||
|
|
||||||
|
static const char *uevent;
|
||||||
|
static const struct blob *report_descriptor;
|
||||||
|
|
||||||
|
struct udev *__wrap_udev_new(void);
|
||||||
|
struct udev_device *__wrap_udev_device_get_parent_with_subsystem_devtype(
|
||||||
|
struct udev_device *, const char *, const char *);
|
||||||
|
struct udev_device *__wrap_udev_device_new_from_syspath(struct udev *,
|
||||||
|
const char *);
|
||||||
|
struct udev_enumerate *__wrap_udev_enumerate_new(struct udev *);
|
||||||
|
struct udev_list_entry *__wrap_udev_enumerate_get_list_entry(
|
||||||
|
struct udev_enumerate *);
|
||||||
|
struct udev_list_entry *__wrap_udev_list_entry_get_next(
|
||||||
|
struct udev_list_entry *);
|
||||||
|
const char *__wrap_udev_device_get_sysattr_value(struct udev_device *,
|
||||||
|
const char *);
|
||||||
|
const char *__wrap_udev_list_entry_get_name(struct udev_list_entry *);
|
||||||
|
const char *__wrap_udev_device_get_devnode(struct udev_device *);
|
||||||
|
const char *__wrap_udev_device_get_sysnum(struct udev_device *);
|
||||||
|
int __wrap_udev_enumerate_add_match_subsystem(struct udev_enumerate *,
|
||||||
|
const char *);
|
||||||
|
int __wrap_udev_enumerate_scan_devices(struct udev_enumerate *);
|
||||||
|
int __wrap_ioctl(int, unsigned long , ...);
|
||||||
|
void __wrap_udev_device_unref(struct udev_device *);
|
||||||
|
void __wrap_udev_enumerate_unref(struct udev_enumerate *);
|
||||||
|
void __wrap_udev_unref(struct udev *);
|
||||||
|
void set_udev_parameters(const char *, const struct blob *);
|
||||||
|
|
||||||
|
struct udev_device *
|
||||||
|
__wrap_udev_device_get_parent_with_subsystem_devtype(struct udev_device *child,
|
||||||
|
const char *subsystem, const char *devtype)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV_DEVICE(child);
|
||||||
|
fido_log_debug("%s", subsystem); /* XXX consume */
|
||||||
|
fido_log_debug("%s", devtype); /* XXX consume */
|
||||||
|
if (child->parent != NULL)
|
||||||
|
return child->parent;
|
||||||
|
if ((child->parent = calloc(1, sizeof(*child->parent))) == NULL)
|
||||||
|
return NULL;
|
||||||
|
child->parent->magic = UDEV_DEVICE_MAGIC;
|
||||||
|
|
||||||
|
return child->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
__wrap_udev_device_get_sysattr_value(struct udev_device *udev_device,
|
||||||
|
const char *sysattr)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV_DEVICE(udev_device);
|
||||||
|
if (uniform_random(400) < 1)
|
||||||
|
return NULL;
|
||||||
|
if (!strcmp(sysattr, "manufacturer") || !strcmp(sysattr, "product"))
|
||||||
|
return "product info"; /* XXX randomise? */
|
||||||
|
else if (!strcmp(sysattr, "uevent"))
|
||||||
|
return uevent;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
__wrap_udev_list_entry_get_name(struct udev_list_entry *entry)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV_LIST_ENTRY(entry);
|
||||||
|
return uniform_random(400) < 1 ? NULL : "name"; /* XXX randomise? */
|
||||||
|
}
|
||||||
|
|
||||||
|
struct udev_device *
|
||||||
|
__wrap_udev_device_new_from_syspath(struct udev *udev, const char *syspath)
|
||||||
|
{
|
||||||
|
struct udev_device *udev_device;
|
||||||
|
|
||||||
|
ASSERT_UDEV(udev);
|
||||||
|
fido_log_debug("%s", syspath);
|
||||||
|
if ((udev_device = calloc(1, sizeof(*udev_device))) == NULL)
|
||||||
|
return NULL;
|
||||||
|
udev_device->magic = UDEV_DEVICE_MAGIC;
|
||||||
|
|
||||||
|
return udev_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
__wrap_udev_device_get_devnode(struct udev_device *udev_device)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV_DEVICE(udev_device);
|
||||||
|
return uniform_random(400) < 1 ? NULL : "/dev/zero";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
__wrap_udev_device_get_sysnum(struct udev_device *udev_device)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV_DEVICE(udev_device);
|
||||||
|
return uniform_random(400) < 1 ? NULL : "101010"; /* XXX randomise? */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__wrap_udev_device_unref(struct udev_device *udev_device)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV_DEVICE(udev_device);
|
||||||
|
if (udev_device->parent) {
|
||||||
|
ASSERT_UDEV_DEVICE(udev_device->parent);
|
||||||
|
free(udev_device->parent);
|
||||||
|
}
|
||||||
|
free(udev_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct udev *
|
||||||
|
__wrap_udev_new(void)
|
||||||
|
{
|
||||||
|
struct udev *udev;
|
||||||
|
|
||||||
|
if ((udev = calloc(1, sizeof(*udev))) == NULL)
|
||||||
|
return NULL;
|
||||||
|
udev->magic = UDEV_MAGIC;
|
||||||
|
|
||||||
|
return udev;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct udev_enumerate *
|
||||||
|
__wrap_udev_enumerate_new(struct udev *udev)
|
||||||
|
{
|
||||||
|
struct udev_enumerate *udev_enum;
|
||||||
|
|
||||||
|
ASSERT_UDEV(udev);
|
||||||
|
if ((udev_enum = calloc(1, sizeof(*udev_enum))) == NULL)
|
||||||
|
return NULL;
|
||||||
|
udev_enum->magic = UDEV_ENUM_MAGIC;
|
||||||
|
|
||||||
|
return udev_enum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__wrap_udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enum,
|
||||||
|
const char *subsystem)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV_ENUM(udev_enum);
|
||||||
|
fido_log_debug("%s:", subsystem);
|
||||||
|
return uniform_random(400) < 1 ? -EINVAL : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__wrap_udev_enumerate_scan_devices(struct udev_enumerate *udev_enum)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV_ENUM(udev_enum);
|
||||||
|
return uniform_random(400) < 1 ? -EINVAL : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct udev_list_entry *
|
||||||
|
__wrap_udev_enumerate_get_list_entry(struct udev_enumerate *udev_enum)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV_ENUM(udev_enum);
|
||||||
|
if ((udev_enum->list_entry = calloc(1,
|
||||||
|
sizeof(*udev_enum->list_entry))) == NULL)
|
||||||
|
return NULL;
|
||||||
|
udev_enum->list_entry->magic = UDEV_LIST_ENTRY_MAGIC;
|
||||||
|
|
||||||
|
return udev_enum->list_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct udev_list_entry *
|
||||||
|
__wrap_udev_list_entry_get_next(struct udev_list_entry *udev_list_entry)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV_LIST_ENTRY(udev_list_entry);
|
||||||
|
return uniform_random(400) < 1 ? NULL : udev_list_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__wrap_udev_enumerate_unref(struct udev_enumerate *udev_enum)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV_ENUM(udev_enum);
|
||||||
|
if (udev_enum->list_entry)
|
||||||
|
ASSERT_UDEV_LIST_ENTRY(udev_enum->list_entry);
|
||||||
|
free(udev_enum->list_entry);
|
||||||
|
free(udev_enum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__wrap_udev_unref(struct udev *udev)
|
||||||
|
{
|
||||||
|
ASSERT_UDEV(udev);
|
||||||
|
free(udev);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__wrap_ioctl(int fd, unsigned long request, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
struct hidraw_report_descriptor *hrd;
|
||||||
|
|
||||||
|
(void)fd;
|
||||||
|
|
||||||
|
if (uniform_random(400) < 1) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start(ap, request);
|
||||||
|
|
||||||
|
switch (IOCTL_REQ(request)) {
|
||||||
|
case IOCTL_REQ(HIDIOCGRDESCSIZE):
|
||||||
|
*va_arg(ap, int *) = (int)report_descriptor->len;
|
||||||
|
break;
|
||||||
|
case IOCTL_REQ(HIDIOCGRDESC):
|
||||||
|
hrd = va_arg(ap, struct hidraw_report_descriptor *);
|
||||||
|
assert(hrd->size == report_descriptor->len);
|
||||||
|
memcpy(hrd->value, report_descriptor->body, hrd->size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warnx("%s: unknown request 0x%lx", __func__, request);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_udev_parameters(const char *uevent_ptr,
|
||||||
|
const struct blob *report_descriptor_ptr)
|
||||||
|
{
|
||||||
|
uevent = uevent_ptr;
|
||||||
|
report_descriptor = report_descriptor_ptr;
|
||||||
|
}
|
||||||
57
fuzz/uniform_random.c
Normal file
57
fuzz/uniform_random.c
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
uint32_t uniform_random(uint32_t);
|
||||||
|
unsigned long prng_uint32(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate a uniformly distributed random number less than upper_bound
|
||||||
|
* avoiding "modulo bias".
|
||||||
|
*
|
||||||
|
* Uniformity is achieved by generating new random numbers until the one
|
||||||
|
* returned is outside the range [0, 2**32 % upper_bound). This
|
||||||
|
* guarantees the selected random number will be inside
|
||||||
|
* [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
|
||||||
|
* after reduction modulo upper_bound.
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
uniform_random(uint32_t upper_bound)
|
||||||
|
{
|
||||||
|
uint32_t r, min;
|
||||||
|
|
||||||
|
if (upper_bound < 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* 2**32 % x == (2**32 - x) % x */
|
||||||
|
min = -upper_bound % upper_bound;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This could theoretically loop forever but each retry has
|
||||||
|
* p > 0.5 (worst case, usually far better) of selecting a
|
||||||
|
* number inside the range we need, so it should rarely need
|
||||||
|
* to re-roll.
|
||||||
|
*/
|
||||||
|
for (;;) {
|
||||||
|
r = (uint32_t)prng_uint32();
|
||||||
|
if (r >= min)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r % upper_bound;
|
||||||
|
}
|
||||||
708
fuzz/wiredata_fido2.h
Normal file
708
fuzz/wiredata_fido2.h
Normal file
@@ -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 */
|
||||||
153
fuzz/wiredata_u2f.h
Normal file
153
fuzz/wiredata_u2f.h
Normal file
@@ -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 */
|
||||||
700
fuzz/wrap.c
Normal file
700
fuzz/wrap.c
Normal file
@@ -0,0 +1,700 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2022 Yubico AB. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/random.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <openssl/bn.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
#include <cbor.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
#include "mutator_aux.h"
|
||||||
|
|
||||||
|
extern int prng_up;
|
||||||
|
|
||||||
|
int fuzz_save_corpus;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build wrappers around functions of interest, and have them fail
|
||||||
|
* in a pseudo-random manner. A uniform probability of 0.25% (1/400)
|
||||||
|
* allows for a depth of log(0.5)/log(399/400) > 276 operations
|
||||||
|
* before simulated errors become statistically more likely.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define WRAP(type, name, args, retval, param, prob) \
|
||||||
|
extern type __wrap_##name args; \
|
||||||
|
extern type __real_##name args; \
|
||||||
|
type __wrap_##name args { \
|
||||||
|
if (prng_up && uniform_random(400) < (prob)) { \
|
||||||
|
return (retval); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return (__real_##name param); \
|
||||||
|
}
|
||||||
|
|
||||||
|
WRAP(void *,
|
||||||
|
malloc,
|
||||||
|
(size_t size),
|
||||||
|
NULL,
|
||||||
|
(size),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(void *,
|
||||||
|
calloc,
|
||||||
|
(size_t nmemb, size_t size),
|
||||||
|
NULL,
|
||||||
|
(nmemb, size),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(void *,
|
||||||
|
realloc,
|
||||||
|
(void *ptr, size_t size),
|
||||||
|
NULL,
|
||||||
|
(ptr, size),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(char *,
|
||||||
|
strdup,
|
||||||
|
(const char *s),
|
||||||
|
NULL,
|
||||||
|
(s),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(ssize_t,
|
||||||
|
getrandom,
|
||||||
|
(void *buf, size_t buflen, unsigned int flags),
|
||||||
|
-1,
|
||||||
|
(buf, buflen, flags),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_Cipher,
|
||||||
|
(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
|
||||||
|
unsigned int inl),
|
||||||
|
-1,
|
||||||
|
(ctx, out, in, inl),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_CIPHER_CTX_ctrl,
|
||||||
|
(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr),
|
||||||
|
0,
|
||||||
|
(ctx, type, arg, ptr),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(EVP_CIPHER_CTX *,
|
||||||
|
EVP_CIPHER_CTX_new,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_CipherInit,
|
||||||
|
(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||||
|
const unsigned char *key, const unsigned char *iv, int enc),
|
||||||
|
0,
|
||||||
|
(ctx, cipher, key, iv, enc),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(RSA *,
|
||||||
|
EVP_PKEY_get0_RSA,
|
||||||
|
(EVP_PKEY *pkey),
|
||||||
|
NULL,
|
||||||
|
(pkey),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(EC_KEY *,
|
||||||
|
EVP_PKEY_get0_EC_KEY,
|
||||||
|
(EVP_PKEY *pkey),
|
||||||
|
NULL,
|
||||||
|
(pkey),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_PKEY_get_raw_public_key,
|
||||||
|
(const EVP_PKEY *pkey, unsigned char *pub, size_t *len),
|
||||||
|
0,
|
||||||
|
(pkey, pub, len),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(EVP_MD_CTX *,
|
||||||
|
EVP_MD_CTX_new,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_DigestVerifyInit,
|
||||||
|
(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e,
|
||||||
|
EVP_PKEY *pkey),
|
||||||
|
0,
|
||||||
|
(ctx, pctx, type, e, pkey),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_DigestInit_ex,
|
||||||
|
(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl),
|
||||||
|
0,
|
||||||
|
(ctx, type, impl),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_DigestUpdate,
|
||||||
|
(EVP_MD_CTX *ctx, const void *data, size_t count),
|
||||||
|
0,
|
||||||
|
(ctx, data, count),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_DigestFinal_ex,
|
||||||
|
(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize),
|
||||||
|
0,
|
||||||
|
(ctx, md, isize),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(BIGNUM *,
|
||||||
|
BN_bin2bn,
|
||||||
|
(const unsigned char *s, int len, BIGNUM *ret),
|
||||||
|
NULL,
|
||||||
|
(s, len, ret),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
BN_bn2bin,
|
||||||
|
(const BIGNUM *a, unsigned char *to),
|
||||||
|
-1,
|
||||||
|
(a, to),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(BIGNUM *,
|
||||||
|
BN_CTX_get,
|
||||||
|
(BN_CTX *ctx),
|
||||||
|
NULL,
|
||||||
|
(ctx),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(BN_CTX *,
|
||||||
|
BN_CTX_new,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(BIGNUM *,
|
||||||
|
BN_new,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(RSA *,
|
||||||
|
RSA_new,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
RSA_set0_key,
|
||||||
|
(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d),
|
||||||
|
0,
|
||||||
|
(r, n, e, d),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
RSA_pkey_ctx_ctrl,
|
||||||
|
(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2),
|
||||||
|
-1,
|
||||||
|
(ctx, optype, cmd, p1, p2),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(EC_KEY *,
|
||||||
|
EC_KEY_new_by_curve_name,
|
||||||
|
(int nid),
|
||||||
|
NULL,
|
||||||
|
(nid),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(const EC_GROUP *,
|
||||||
|
EC_KEY_get0_group,
|
||||||
|
(const EC_KEY *key),
|
||||||
|
NULL,
|
||||||
|
(key),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(const BIGNUM *,
|
||||||
|
EC_KEY_get0_private_key,
|
||||||
|
(const EC_KEY *key),
|
||||||
|
NULL,
|
||||||
|
(key),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(EC_POINT *,
|
||||||
|
EC_POINT_new,
|
||||||
|
(const EC_GROUP *group),
|
||||||
|
NULL,
|
||||||
|
(group),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EC_POINT_get_affine_coordinates_GFp,
|
||||||
|
(const EC_GROUP *group, const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx),
|
||||||
|
0,
|
||||||
|
(group, p, x, y, ctx),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(EVP_PKEY *,
|
||||||
|
EVP_PKEY_new,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_PKEY_assign,
|
||||||
|
(EVP_PKEY *pkey, int type, void *key),
|
||||||
|
0,
|
||||||
|
(pkey, type, key),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_PKEY_keygen_init,
|
||||||
|
(EVP_PKEY_CTX *ctx),
|
||||||
|
0,
|
||||||
|
(ctx),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_PKEY_keygen,
|
||||||
|
(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey),
|
||||||
|
0,
|
||||||
|
(ctx, ppkey),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_PKEY_paramgen_init,
|
||||||
|
(EVP_PKEY_CTX *ctx),
|
||||||
|
0,
|
||||||
|
(ctx),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_PKEY_paramgen,
|
||||||
|
(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey),
|
||||||
|
0,
|
||||||
|
(ctx, ppkey),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(EVP_PKEY *,
|
||||||
|
EVP_PKEY_new_raw_public_key,
|
||||||
|
(int type, ENGINE *e, const unsigned char *key, size_t keylen),
|
||||||
|
NULL,
|
||||||
|
(type, e, key, keylen),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(EVP_PKEY_CTX *,
|
||||||
|
EVP_PKEY_CTX_new,
|
||||||
|
(EVP_PKEY *pkey, ENGINE *e),
|
||||||
|
NULL,
|
||||||
|
(pkey, e),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(EVP_PKEY_CTX *,
|
||||||
|
EVP_PKEY_CTX_new_id,
|
||||||
|
(int id, ENGINE *e),
|
||||||
|
NULL,
|
||||||
|
(id, e),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_PKEY_derive,
|
||||||
|
(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen),
|
||||||
|
0,
|
||||||
|
(ctx, key, pkeylen),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_PKEY_derive_init,
|
||||||
|
(EVP_PKEY_CTX *ctx),
|
||||||
|
0,
|
||||||
|
(ctx),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_PKEY_derive_set_peer,
|
||||||
|
(EVP_PKEY_CTX *ctx, EVP_PKEY *peer),
|
||||||
|
0,
|
||||||
|
(ctx, peer),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_PKEY_verify_init,
|
||||||
|
(EVP_PKEY_CTX *ctx),
|
||||||
|
0,
|
||||||
|
(ctx),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
EVP_PKEY_CTX_ctrl,
|
||||||
|
(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2),
|
||||||
|
-1,
|
||||||
|
(ctx, keytype, optype, cmd, p1, p2),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(const EVP_MD *,
|
||||||
|
EVP_sha1,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(const EVP_MD *,
|
||||||
|
EVP_sha256,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(const EVP_CIPHER *,
|
||||||
|
EVP_aes_256_cbc,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(const EVP_CIPHER *,
|
||||||
|
EVP_aes_256_gcm,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(unsigned char *,
|
||||||
|
HMAC,
|
||||||
|
(const EVP_MD *evp_md, const void *key, int key_len,
|
||||||
|
const unsigned char *d, int n, unsigned char *md,
|
||||||
|
unsigned int *md_len),
|
||||||
|
NULL,
|
||||||
|
(evp_md, key, key_len, d, n, md, md_len),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(HMAC_CTX *,
|
||||||
|
HMAC_CTX_new,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
HMAC_Init_ex,
|
||||||
|
(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md,
|
||||||
|
ENGINE *impl),
|
||||||
|
0,
|
||||||
|
(ctx, key, key_len, md, impl),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
HMAC_Update,
|
||||||
|
(HMAC_CTX *ctx, const unsigned char *data, int len),
|
||||||
|
0,
|
||||||
|
(ctx, data, len),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
HMAC_Final,
|
||||||
|
(HMAC_CTX *ctx, unsigned char *md, unsigned int *len),
|
||||||
|
0,
|
||||||
|
(ctx, md, len),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(unsigned char *,
|
||||||
|
SHA1,
|
||||||
|
(const unsigned char *d, size_t n, unsigned char *md),
|
||||||
|
NULL,
|
||||||
|
(d, n, md),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(unsigned char *,
|
||||||
|
SHA256,
|
||||||
|
(const unsigned char *d, size_t n, unsigned char *md),
|
||||||
|
NULL,
|
||||||
|
(d, n, md),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_build_string,
|
||||||
|
(const char *val),
|
||||||
|
NULL,
|
||||||
|
(val),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_build_bytestring,
|
||||||
|
(cbor_data handle, size_t length),
|
||||||
|
NULL,
|
||||||
|
(handle, length),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_build_bool,
|
||||||
|
(bool value),
|
||||||
|
NULL,
|
||||||
|
(value),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_build_negint8,
|
||||||
|
(uint8_t value),
|
||||||
|
NULL,
|
||||||
|
(value),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_build_negint16,
|
||||||
|
(uint16_t value),
|
||||||
|
NULL,
|
||||||
|
(value),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_load,
|
||||||
|
(cbor_data source, size_t source_size, struct cbor_load_result *result),
|
||||||
|
NULL,
|
||||||
|
(source, source_size, result),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_build_uint8,
|
||||||
|
(uint8_t value),
|
||||||
|
NULL,
|
||||||
|
(value),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_build_uint16,
|
||||||
|
(uint16_t value),
|
||||||
|
NULL,
|
||||||
|
(value),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_build_uint32,
|
||||||
|
(uint32_t value),
|
||||||
|
NULL,
|
||||||
|
(value),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_build_uint64,
|
||||||
|
(uint64_t value),
|
||||||
|
NULL,
|
||||||
|
(value),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(struct cbor_pair *,
|
||||||
|
cbor_map_handle,
|
||||||
|
(const cbor_item_t *item),
|
||||||
|
NULL,
|
||||||
|
(item),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t **,
|
||||||
|
cbor_array_handle,
|
||||||
|
(const cbor_item_t *item),
|
||||||
|
NULL,
|
||||||
|
(item),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(bool,
|
||||||
|
cbor_array_push,
|
||||||
|
(cbor_item_t *array, cbor_item_t *pushee),
|
||||||
|
false,
|
||||||
|
(array, pushee),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(bool,
|
||||||
|
cbor_map_add,
|
||||||
|
(cbor_item_t *item, struct cbor_pair pair),
|
||||||
|
false,
|
||||||
|
(item, pair),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_new_definite_map,
|
||||||
|
(size_t size),
|
||||||
|
NULL,
|
||||||
|
(size),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_new_definite_array,
|
||||||
|
(size_t size),
|
||||||
|
NULL,
|
||||||
|
(size),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(cbor_item_t *,
|
||||||
|
cbor_new_definite_bytestring,
|
||||||
|
(void),
|
||||||
|
NULL,
|
||||||
|
(),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(size_t,
|
||||||
|
cbor_serialize_alloc,
|
||||||
|
(const cbor_item_t *item, cbor_mutable_data *buffer,
|
||||||
|
size_t *buffer_size),
|
||||||
|
0,
|
||||||
|
(item, buffer, buffer_size),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
fido_tx,
|
||||||
|
(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count, int *ms),
|
||||||
|
-1,
|
||||||
|
(d, cmd, buf, count, ms),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
bind,
|
||||||
|
(int sockfd, const struct sockaddr *addr, socklen_t addrlen),
|
||||||
|
-1,
|
||||||
|
(sockfd, addr, addrlen),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
WRAP(int,
|
||||||
|
deflateInit2_,
|
||||||
|
(z_streamp strm, int level, int method, int windowBits, int memLevel,
|
||||||
|
int strategy, const char *version, int stream_size),
|
||||||
|
Z_STREAM_ERROR,
|
||||||
|
(strm, level, method, windowBits, memLevel, strategy, version,
|
||||||
|
stream_size),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
|
||||||
|
int __wrap_deflate(z_streamp, int);
|
||||||
|
int __real_deflate(z_streamp, int);
|
||||||
|
|
||||||
|
int
|
||||||
|
__wrap_deflate(z_streamp strm, int flush)
|
||||||
|
{
|
||||||
|
if (prng_up && uniform_random(400) < 1) {
|
||||||
|
return Z_BUF_ERROR;
|
||||||
|
}
|
||||||
|
/* should never happen, but we check for it */
|
||||||
|
if (prng_up && uniform_random(400) < 1) {
|
||||||
|
strm->avail_out = UINT_MAX;
|
||||||
|
return Z_STREAM_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
return __real_deflate(strm, flush);
|
||||||
|
}
|
||||||
|
|
||||||
|
int __wrap_asprintf(char **, const char *, ...);
|
||||||
|
|
||||||
|
int
|
||||||
|
__wrap_asprintf(char **strp, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (prng_up && uniform_random(400) < 1) {
|
||||||
|
*strp = (void *)0xdeadbeef;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
r = vasprintf(strp, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
102
fuzz/wrapped.sym
Normal file
102
fuzz/wrapped.sym
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user