Some highlights from NEWS: ** Added OpenSSL 3.0 compatibility. ** Removed OpenSSL 1.0 compatibility. ** Support for FIDO 2.1 "minPinLength" extension. ** Support for COSE_EDDSA, COSE_ES256, and COSE_RS1 attestation. ** Support for TPM 2.0 attestation. ** Support for device timeouts; see fido_dev_set_timeout(). ** New API calls: - es256_pk_from_EVP_PKEY; - fido_cred_attstmt_len; - fido_cred_attstmt_ptr; - fido_cred_pin_minlen; - fido_cred_set_attstmt; - fido_cred_set_pin_minlen; - fido_dev_set_pin_minlen_rpid; - fido_dev_set_timeout; - rs256_pk_from_EVP_PKEY. ** Reliability and portability fixes. ** Better handling of HID devices without identification strings; gh#381. Relnotes: Yes Sponsored by: The FreeBSD Foundation
80 lines
1.7 KiB
C
80 lines
1.7 KiB
C
/*
|
|
* 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.
|
|
*/
|
|
|
|
#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));
|
|
}
|