Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions tests/fuzzing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ set(DEFINES
HAVE_NFT_SUPPORT
HAVE_DYNAMIC_NETWORKS
HAVE_WEB3_CHECKS
HAVE_EIP7702
HAVE_EIP7702_WHITELIST
explicit_bzero=bzero # Fix for https://github.com/google/sanitizers/issues/1507
)

Expand Down Expand Up @@ -190,6 +192,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/../../src_features/signMessageEIP712/
${CMAKE_SOURCE_DIR}/../../src_features/provide_proxy_info/
${CMAKE_SOURCE_DIR}/../../src_features/provide_tx_simulation/
${CMAKE_SOURCE_DIR}/../../src_features/signAuthorizationEIP7702/
${BOLOS_SDK}/include
${BOLOS_SDK}/target/${TARGET_DEVICE}/include
${BOLOS_SDK}/lib_cxng/include
Expand All @@ -209,6 +212,7 @@ FILE(GLOB_RECURSE SOURCES
${CMAKE_SOURCE_DIR}/../../src_features/provideNFTInformation/*.c
${CMAKE_SOURCE_DIR}/../../src_features/provide_proxy_info/*.c
${CMAKE_SOURCE_DIR}/../../src_features/provide_tx_simulation/*.c
${CMAKE_SOURCE_DIR}/../../src_features/signAuthorizationEIP7702/*.c
${CMAKE_SOURCE_DIR}/../../src/mem.c
${CMAKE_SOURCE_DIR}/../../src/mem_utils.c
${CMAKE_SOURCE_DIR}/../../src/network.c
Expand Down
31 changes: 30 additions & 1 deletion tests/fuzzing/src/fuzzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include "gtp_tx_info.h"
#include "enum_value.h"

#include "auth_7702.h"
#include "commands_7702.h"

#include "shared_context.h"
#include "tlv.h"
#include "mem.h"
Expand All @@ -26,6 +29,7 @@
typedef int (*harness)(const uint8_t *data, size_t size);

// Global state required by the app features
cx_sha3_t global_sha3;
cx_sha3_t sha3;
unsigned char G_io_apdu_buffer[260];
tmpContent_t tmpContent;
Expand All @@ -39,7 +43,12 @@ const chain_config_t *chainConfig = &config;
uint8_t appState;
tmpCtx_t tmpCtx;
strings_t strings;
const internalStorage_t N_storage_real = {.w3c_enable = true, .w3c_opt_in = true};
// Mock the storage to enable wanted features
const internalStorage_t N_storage_real = {
.w3c_enable = true,
.w3c_opt_in = true,
.eip7702_enable = true,
};

int fuzzGenericParserFieldCmd(const uint8_t *data, size_t size) {
s_field field = {0};
Expand Down Expand Up @@ -160,6 +169,24 @@ int fuzzCalldata(const uint8_t *data, size_t size) {
return 0;
}

int fuzzEIP7702(const uint8_t *data, size_t size) {
size_t offset = 0;
size_t len = 0;
uint8_t p1;
unsigned int flags;

while (size - offset > 3) {
if (data[offset++] == 0) break;
p1 = data[offset++];
len = data[offset++];
if (size - offset < len) return 0;
if (handleSignEIP7702Authorization(p1, data + offset, len, &flags) != APDU_RESPONSE_OK)
return 1;
offset += len;
}
return 0;
}

// Array of fuzzing harness functions
harness harnesses[] = {
fuzzGenericParserFieldCmd,
Expand All @@ -171,6 +198,7 @@ harness harnesses[] = {
fuzzProxyInfo,
fuzzTxSimulation,
fuzzCalldata,
fuzzEIP7702,
};

/* Main fuzzing handler called by libfuzzer */
Expand All @@ -183,6 +211,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
explicit_bzero(&strings, sizeof(strings_t));
explicit_bzero(&G_io_apdu_buffer, 260);
explicit_bzero(&sha3, sizeof(sha3));
explicit_bzero(&global_sha3, sizeof(global_sha3));

calldata_cleanup();
mem_reset();
Expand Down
106 changes: 106 additions & 0 deletions tests/fuzzing/src/mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "buffer.h"
#include "lcx_ecfp.h"

#include "bip32_utils.h"

/** MemorySanitizer does not wrap explicit_bzero https://github.com/google/sanitizers/issues/1507
* which results in false positives when running MemorySanitizer.
*/
Expand Down Expand Up @@ -184,16 +186,120 @@ int io_send_response_buffers(const buffer_t *rdatalist, size_t count, uint16_t s
}

uint16_t io_seproxyhal_send_status(uint16_t sw, uint32_t tx, bool reset, bool idle) {
UNUSED(sw);
UNUSED(tx);
UNUSED(reset);
UNUSED(idle);
return 0;
}

uint32_t os_pki_get_info(uint8_t *key_usage,
uint8_t *trusted_name,
size_t *trusted_name_len,
cx_ecfp_384_public_key_t *public_key) {
UNUSED(key_usage);
UNUSED(trusted_name_len);
UNUSED(public_key);
memcpy(trusted_name, "trusted name", sizeof("trusted name"));
return 0;
}

void ui_tx_simulation_opt_in(bool response_expected) {
UNUSED(response_expected);
}

void ui_error_no_7702(void) {
}

void ui_error_no_7702_whitelist(void) {
}

void ui_sign_7702_auth(void) {
}

void ui_sign_7702_revocation(void) {
}

cx_err_t cx_keccak_init_no_throw(cx_sha3_t *hash PLENGTH(sizeof(cx_sha3_t)), size_t size) {
UNUSED(size);
memset_s(hash, 0, sizeof(cx_sha3_t));
return CX_OK;
}

cx_err_t bip32_derive_with_seed_get_pubkey_256(unsigned int derivation_mode,
cx_curve_t curve,
const uint32_t *path,
size_t path_len,
uint8_t raw_pubkey[static 65],
uint8_t *chain_code,
cx_md_t hashID,
unsigned char *seed,
size_t seed_len) {
UNUSED(derivation_mode);
UNUSED(curve);
UNUSED(path);
UNUSED(path_len);
UNUSED(chain_code);
UNUSED(hashID);
UNUSED(seed);
UNUSED(seed_len);
memset(raw_pubkey, 0, 65);
return CX_OK;
}

cx_err_t bip32_derive_with_seed_ecdsa_sign_rs_hash_256(unsigned int derivation_mode,
cx_curve_t curve,
const uint32_t *path,
size_t path_len,
uint32_t sign_mode,
cx_md_t hashID,
const uint8_t *hash,
size_t hash_len,
uint8_t sig_r[static 32],
uint8_t sig_s[static 32],
uint32_t *info,
unsigned char *seed,
size_t seed_len) {
UNUSED(derivation_mode);
UNUSED(curve);
UNUSED(path);
UNUSED(path_len);
UNUSED(sign_mode);
UNUSED(hashID);
UNUSED(hash);
UNUSED(hash_len);
UNUSED(info);
UNUSED(seed);
UNUSED(seed_len);
memset(sig_r, 0, 32);
memset(sig_s, 0, 32);
return CX_OK;
}

// Duplicate from main.c...
const uint8_t *parseBip32(const uint8_t *dataBuffer, uint8_t *dataLength, bip32_path_t *bip32) {
if (*dataLength < 1) {
PRINTF("Invalid data\n");
return NULL;
}

bip32->length = *dataBuffer;

dataBuffer++;
(*dataLength)--;

if (*dataLength < sizeof(uint32_t) * (bip32->length)) {
PRINTF("Invalid data\n");
return NULL;
}

if (bip32_path_read(dataBuffer, (size_t) dataLength, bip32->path, (size_t) bip32->length) ==
false) {
PRINTF("Invalid Path data\n");
return NULL;
}
dataBuffer += bip32->length * sizeof(uint32_t);
*dataLength -= bip32->length * sizeof(uint32_t);

return dataBuffer;
}
Loading