|
|
|
@ -89,7 +89,8 @@ void fuzzer_reset_state(void) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void crash(void) {
|
|
|
|
|
// intentionally exit the program, which is picked up as a crash by the fuzzer framework
|
|
|
|
|
// intentionally exit the program, which is picked up as a crash by the fuzzer
|
|
|
|
|
// framework
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -280,13 +281,12 @@ int fuzz_xmr_base58_addr_decode_check(void) {
|
|
|
|
|
char in_buffer[XMR_BASE58_ADDR_DECODE_MAX_INPUT_LEN] = {0};
|
|
|
|
|
char out_buffer[XMR_BASE58_ADDR_DECODE_MAX_INPUT_LEN] = {0};
|
|
|
|
|
size_t outlen = sizeof(out_buffer);
|
|
|
|
|
uint64_t tag = 0;
|
|
|
|
|
size_t raw_inlen = fuzzer_length;
|
|
|
|
|
|
|
|
|
|
// mutate in_buffer
|
|
|
|
|
size_t raw_inlen = fuzzer_length;
|
|
|
|
|
memcpy(&in_buffer, fuzzer_ptr, raw_inlen);
|
|
|
|
|
fuzzer_input(raw_inlen);
|
|
|
|
|
memcpy(&in_buffer, fuzzer_input(raw_inlen), raw_inlen);
|
|
|
|
|
|
|
|
|
|
uint64_t tag;
|
|
|
|
|
xmr_base58_addr_decode_check(in_buffer, raw_inlen, &tag, out_buffer, outlen);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -382,18 +382,18 @@ int fuzz_nem_validate_address(void) {
|
|
|
|
|
|
|
|
|
|
int fuzz_nem_get_address(void) {
|
|
|
|
|
unsigned char ed25519_public_key_fuzz[32] = {0};
|
|
|
|
|
uint32_t network = 0;
|
|
|
|
|
uint8_t version = 0;
|
|
|
|
|
|
|
|
|
|
if (fuzzer_length != (sizeof(ed25519_public_key_fuzz) + sizeof(network))) {
|
|
|
|
|
if (fuzzer_length != (sizeof(ed25519_public_key_fuzz) + sizeof(version))) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char address[NEM_ADDRESS_SIZE + 1] = {0};
|
|
|
|
|
|
|
|
|
|
memcpy(ed25519_public_key_fuzz, fuzzer_input(32), 32);
|
|
|
|
|
memcpy(&network, fuzzer_input(4), 4);
|
|
|
|
|
memcpy(&version, fuzzer_input(1), 1);
|
|
|
|
|
|
|
|
|
|
nem_get_address(ed25519_public_key_fuzz, network, address);
|
|
|
|
|
nem_get_address(ed25519_public_key_fuzz, version, address);
|
|
|
|
|
|
|
|
|
|
#if defined(__has_feature)
|
|
|
|
|
#if __has_feature(memory_sanitizer)
|
|
|
|
@ -615,20 +615,26 @@ int fuzz_slip39_word_completion_mask(void) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int fuzz_mnemonic_to_bits(void) {
|
|
|
|
|
// regular MAX_MNEMONIC_LEN is 240, try some extra bytes
|
|
|
|
|
#define MAX_MNEMONIC_FUZZ_LENGTH 256
|
|
|
|
|
|
|
|
|
|
int fuzz_mnemonic_check(void) {
|
|
|
|
|
if (fuzzer_length < MAX_MNEMONIC_FUZZ_LENGTH) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char mnemonic[MAX_MNEMONIC_FUZZ_LENGTH + 1] = {0};
|
|
|
|
|
memcpy(&mnemonic, fuzzer_ptr, MAX_MNEMONIC_FUZZ_LENGTH);
|
|
|
|
|
uint8_t mnemonic_bits[32 + 1] = {0};
|
|
|
|
|
|
|
|
|
|
mnemonic_to_bits((const char *)&mnemonic, mnemonic_bits);
|
|
|
|
|
// TODO what can be checked about the result, computing a checksum?
|
|
|
|
|
// as of 11/2021, mnemonic_check() internally calls mnemonic_to_bits() and
|
|
|
|
|
// checks the result
|
|
|
|
|
int ret = mnemonic_check(mnemonic);
|
|
|
|
|
|
|
|
|
|
(void)ret;
|
|
|
|
|
/*
|
|
|
|
|
if(ret == 1) {
|
|
|
|
|
// correct result
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -643,7 +649,8 @@ int fuzz_mnemonic_from_data(void) {
|
|
|
|
|
int res = mnemonic_check(mnemo_result);
|
|
|
|
|
if (res == 0) {
|
|
|
|
|
// TODO the mnemonic_check() function is currently incorrectly rejecting
|
|
|
|
|
// valid 15 and 21 word seeds - remove this workaround limitation later
|
|
|
|
|
// valid 15 and 21 word seeds
|
|
|
|
|
// remove this workaround limitation later
|
|
|
|
|
if (fuzzer_length != 20 && fuzzer_length != 28) {
|
|
|
|
|
// the generated mnemonic has an invalid format
|
|
|
|
|
crash();
|
|
|
|
@ -655,6 +662,27 @@ int fuzz_mnemonic_from_data(void) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// passphrase normally has a 64 or 256 byte length maximum
|
|
|
|
|
#define MAX_PASSPHRASE_FUZZ_LENGTH 257
|
|
|
|
|
int fuzz_mnemonic_to_seed(void) {
|
|
|
|
|
if (fuzzer_length < MAX_MNEMONIC_FUZZ_LENGTH + MAX_PASSPHRASE_FUZZ_LENGTH) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char mnemonic[MAX_PASSPHRASE_FUZZ_LENGTH + 1] = {0};
|
|
|
|
|
char passphrase[MAX_MNEMONIC_FUZZ_LENGTH + 1] = {0};
|
|
|
|
|
uint8_t seed[512 / 8] = {0};
|
|
|
|
|
|
|
|
|
|
memcpy(&mnemonic, fuzzer_input(MAX_MNEMONIC_FUZZ_LENGTH),
|
|
|
|
|
MAX_MNEMONIC_FUZZ_LENGTH);
|
|
|
|
|
memcpy(&passphrase, fuzzer_input(MAX_PASSPHRASE_FUZZ_LENGTH),
|
|
|
|
|
MAX_PASSPHRASE_FUZZ_LENGTH);
|
|
|
|
|
|
|
|
|
|
mnemonic_to_seed(mnemonic, passphrase, seed, NULL);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int fuzz_aes(void) {
|
|
|
|
|
if (fuzzer_length < 1 + 16 + 16 + 32) {
|
|
|
|
|
return 0;
|
|
|
|
@ -859,6 +887,9 @@ int fuzz_schnorr_sign_digest(void) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO zkp_bip340_sign, see test_check.c
|
|
|
|
|
// TODO zkp_bip340_verify, see test_check.c
|
|
|
|
|
|
|
|
|
|
int fuzz_chacha_drbg(void) {
|
|
|
|
|
#define CHACHA_DRBG_ENTROPY_LENGTH 32
|
|
|
|
|
#define CHACHA_DRBG_RESEED_LENGTH 32
|
|
|
|
@ -1022,7 +1053,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
|
|
|
|
fuzz_slip39_word_completion_mask();
|
|
|
|
|
break;
|
|
|
|
|
case 17:
|
|
|
|
|
fuzz_mnemonic_to_bits();
|
|
|
|
|
fuzz_mnemonic_check();
|
|
|
|
|
break;
|
|
|
|
|
case 18:
|
|
|
|
|
#ifdef FUZZ_ALLOW_SLOW
|
|
|
|
@ -1053,6 +1084,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
|
|
|
|
case 25:
|
|
|
|
|
fuzz_mnemonic_from_data();
|
|
|
|
|
break;
|
|
|
|
|
case 26:
|
|
|
|
|
fuzz_mnemonic_to_seed();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
// do nothing
|
|
|
|
|