What changed, and why it matters
This commit changes how the BitBox02 firmware reads sensitive stored data (device name, seed birthdate, encryption keys, BLE identity, etc.). Previously, the firmware copied whole chunks from flash into RAM and then cleared them afterward. Now, for real firmware builds, it reads those fields directly from flash using typed pointers, so the data stays in flash and is not copied into RAM. This is mostly a performance and memory-usage improvement, but it removes the explicit RAM-clearing (util_zero) that used to happen after reading. That means sensitive bytes may remain longer in RAM if they are ever copied out, and any code that later reads from those RAM copies could be a concern. There is no direct vulnerability shown in the diff, but the change weakens one defensive layer (clearing sensitive RAM) and introduces more places where secrets are accessed through raw flash pointers.
Treat as a defensive-hardening refactor rather than a critical vulnerability. Review whether any downstream callers now hold sensitive values in RAM longer than necessary and re-add explicit zeroization of output buffers after use. Verify that FLASH_APPDATA_START/FLASH_SHARED_DATA_START mappings are read-only and aligned for the typed structs. Confirm the new '%.*s' length in memory_get_device_name() is correct and does not truncate valid names. Run static analysis and firmware tests to ensure no unaligned or out-of-bounds flash accesses occur.
Security signals we found
Removal of RAM zeroization (util_zero/CLEANUP_CHUNK) for many secret-bearing chunk reads
Direct flash-mapped typed pointers now used for sensitive fields in production builds
One hardening fix: device_name copy now uses bounded '%.*s' instead of unbounded '%s'
No bounds/length validation added for other memcpy-based secret reads
Refactoring only; no new crypto, no new attack surface, no privilege boundary change
Evidence from the diff
The patch refactors memory.c and memory_shared.c to provide chunk() helpers that return const typed pointers. In non-TESTING builds these pointers are cast directly from FLASH_APPDATA_START/FLASH_SHARED_DATA_START addresses, allowing field-level reads without first copying the whole chunk into a stack/RAM buffer. TESTING builds retain the old fake-read behavior with a static buffer. The change removes CLEANUP_CHUNK and util_zero calls at many call sites, because the chunk no longer lives in RAM. One functional change is visible in memory_get_device_name(), where the snprintf format changed from ‘%s’ to ‘%.s’ with an explicit length, which is a hardening improvement against missing null terminators. No other behavior changes are evident. The security-relevant side effect is reduced clearing of sensitive data in RAM and increased reliance on flash-mapped reads for secrets (e.g., io_protection_key, authorization_key, encryption_key, noise_static_private_key, salt_root, BLE IRK/identity address).
Changed components
src/memory/memory.csrc/memory/memory_shared.cDevice name storage/retrievalSeed birthdate storage/retrievalEncrypted seed and HMAC retrievalIO protection / authorization / encryption key retrievalAttestation certificate/key retrievalNoise static private key and remote pubkey storageSalt root storageMultisig configuration storageBLE metadata, IRK, identity address, bond DB, platform/screen/securechip readsInspect captured patch +164 / −143
diff --git a/src/memory/memory.c b/src/memory/memory.c
index da4ddb7..b73fef2 100644
--- a/src/memory/memory.c
+++ b/src/memory/memory.c
@@ -233,6 +233,66 @@ static void _read_chunk(uint32_t chunk_num, uint8_t* chunk_out)
#endif
}
+static const chunk_0_t* _chunk_0(void)
+{
+#ifdef TESTING
+ static chunk_0_t chunk;
+ util_zero(&chunk, sizeof(chunk));
+ _read_chunk(CHUNK_0_PERMANENT, chunk.bytes);
+ return &chunk;
+#else
+ return (const chunk_0_t*)(FLASH_APPDATA_START + CHUNK_0_PERMANENT * CHUNK_SIZE);
+#endif
+}
+
+static const chunk_1_t* _chunk_1(void)
+{
+#ifdef TESTING
+ static chunk_1_t chunk;
+ util_zero(&chunk, sizeof(chunk));
+ _read_chunk(CHUNK_1, chunk.bytes);
+ return &chunk;
+#else
+ return (const chunk_1_t*)(FLASH_APPDATA_START + CHUNK_1 * CHUNK_SIZE);
+#endif
+}
+
+static const chunk_2_t* _chunk_2(void)
+{
+#ifdef TESTING
+ static chunk_2_t chunk;
+ util_zero(&chunk, sizeof(chunk));
+ _read_chunk(CHUNK_2, chunk.bytes);
+ return &chunk;
+#else
+ return (const chunk_2_t*)(FLASH_APPDATA_START + CHUNK_2 * CHUNK_SIZE);
+#endif
+}
+
+static const chunk_7_t* _chunk_7(void)
+{
+#ifdef TESTING
+ static chunk_7_t chunk;
+ util_zero(&chunk, sizeof(chunk));
+ _read_chunk(CHUNK_7_PERMANENT, chunk.bytes);
+ return &chunk;
+#else
+ return (const chunk_7_t*)(FLASH_APPDATA_START + CHUNK_7_PERMANENT * CHUNK_SIZE);
+#endif
+}
+
+static const chunk_shared_t* _shared_chunk(void)
+{
+#ifdef TESTING
+ static chunk_shared_t chunk;
+ util_zero(&chunk, sizeof(chunk));
+ memory_read_shared_bootdata(&chunk);
+ return &chunk;
+#else
+ return (const chunk_shared_t*)FLASH_SHARED_DATA_START;
+#endif
+}
+
static const memory_interface_functions_t* _interface_functions = NULL;
/********* Exposed functions ****************/
@@ -258,11 +318,9 @@ bool memory_set_device_name(const char* name)
void memory_get_device_name(char* name_out)
{
- chunk_1_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_1, chunk_bytes);
- if (chunk.fields.device_name[0] == 0xFF ||
- !rust_util_is_name_valid(chunk.fields.device_name, MEMORY_DEVICE_MAX_LEN_WITH_NULL)) {
+ const chunk_1_t* chunk = _chunk_1();
+ if (chunk->fields.device_name[0] == 0xFF ||
+ !rust_util_is_name_valid(chunk->fields.device_name, MEMORY_DEVICE_MAX_LEN_WITH_NULL)) {
if (memory_get_platform() == MEMORY_PLATFORM_BITBOX02_PLUS) {
// For Bluetooth, we want to use an unambiguous default name so this BitBox can be
// identified if multiple BitBoxes are advertising at the same time.
@@ -271,7 +329,12 @@ void memory_get_device_name(char* name_out)
snprintf(name_out, MEMORY_DEVICE_MAX_LEN_WITH_NULL, "%s", MEMORY_DEFAULT_DEVICE_NAME);
}
} else {
- snprintf(name_out, MEMORY_DEVICE_MAX_LEN_WITH_NULL, "%s", chunk.fields.device_name);
+ snprintf(
+ name_out,
+ MEMORY_DEVICE_MAX_LEN_WITH_NULL,
+ "%.*s",
+ MEMORY_DEVICE_MAX_LEN_WITH_NULL - 1,
+ chunk->fields.device_name);
}
}
@@ -286,13 +349,11 @@ bool memory_set_seed_birthdate(uint32_t timestamp)
void memory_get_seed_birthdate(uint32_t* timestamp_out)
{
- chunk_1_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_1, chunk_bytes);
- if (chunk.fields.seed_birthdate == 0xFFFFFFFF) {
+ const chunk_1_t* chunk = _chunk_1();
+ if (chunk->fields.seed_birthdate == 0xFFFFFFFF) {
*timestamp_out = 0;
} else {
- *timestamp_out = chunk.fields.seed_birthdate;
+ *timestamp_out = chunk->fields.seed_birthdate;
}
}
@@ -411,10 +472,8 @@ bool memory_reset_hww(void)
static bool _is_bitmask_flag_set(uint8_t flag)
{
- chunk_1_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_1, chunk_bytes);
- return ~chunk.fields.bitmask & flag;
+ const chunk_1_t* chunk = _chunk_1();
+ return ~chunk->fields.bitmask & flag;
}
bool memory_is_seeded(void)
@@ -463,10 +522,8 @@ bool memory_set_mnemonic_passphrase_enabled(bool enabled)
uint8_t memory_get_failed_unlock_attempts(void)
{
- chunk_1_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_1, chunk_bytes);
- return 0xFF - chunk.fields.failed_unlock_attempts;
+ const chunk_1_t* chunk = _chunk_1();
+ return 0xFF - chunk->fields.failed_unlock_attempts;
}
bool memory_increment_failed_unlock_attempts(void)
@@ -538,16 +595,14 @@ bool memory_get_encrypted_seed_and_hmac(
if (!memory_is_seeded()) {
return false;
}
- chunk_1_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_1, chunk_bytes);
+ const chunk_1_t* chunk = _chunk_1();
memcpy(
encrypted_seed_and_hmac_out,
- chunk.fields.encrypted_seed_and_hmac,
- sizeof(chunk.fields.encrypted_seed_and_hmac));
- *len_out = chunk.fields.encrypted_seed_and_hmac_len;
+ chunk->fields.encrypted_seed_and_hmac,
+ sizeof(chunk->fields.encrypted_seed_and_hmac));
+ *len_out = chunk->fields.encrypted_seed_and_hmac_len;
- switch (chunk.fields.password_stretch_algo) {
+ switch (chunk->fields.password_stretch_algo) {
case 0xFF:
*password_stretch_algo_out = MEMORY_PASSWORD_STRETCH_ALGO_V0;
break;
@@ -563,73 +618,61 @@ bool memory_get_encrypted_seed_and_hmac(
void memory_get_io_protection_key(uint8_t* key_out)
{
- chunk_0_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_0_PERMANENT, chunk_bytes);
+ const chunk_0_t* chunk = _chunk_0();
- memcpy(key_out, chunk.fields.io_protection_key, sizeof(chunk.fields.io_protection_key));
+ memcpy(key_out, chunk->fields.io_protection_key, sizeof(chunk->fields.io_protection_key));
// xor with the second part
- chunk_shared_t shared_chunk = {0};
- CLEANUP_CHUNK(shared_chunk);
- memory_read_shared_bootdata(&shared_chunk);
+ const chunk_shared_t* shared_chunk = _shared_chunk();
// check assumption
- if (sizeof(shared_chunk.fields.io_protection_key_split) !=
- sizeof(chunk.fields.io_protection_key)) {
+ if (sizeof(shared_chunk->fields.io_protection_key_split) !=
+ sizeof(chunk->fields.io_protection_key)) {
Abort("size mismatch");
}
- for (size_t i = 0; i < sizeof(shared_chunk.fields.io_protection_key_split); i++) {
- key_out[i] ^= shared_chunk.fields.io_protection_key_split[i];
+ for (size_t i = 0; i < sizeof(shared_chunk->fields.io_protection_key_split); i++) {
+ key_out[i] ^= shared_chunk->fields.io_protection_key_split[i];
}
}
void memory_get_authorization_key(uint8_t* key_out)
{
- chunk_0_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_0_PERMANENT, chunk_bytes);
- memcpy(key_out, chunk.fields.authorization_key, sizeof(chunk.fields.authorization_key));
+ const chunk_0_t* chunk = _chunk_0();
+ memcpy(key_out, chunk->fields.authorization_key, sizeof(chunk->fields.authorization_key));
// xor with the second part
- chunk_shared_t shared_chunk = {0};
- CLEANUP_CHUNK(shared_chunk);
- memory_read_shared_bootdata(&shared_chunk);
+ const chunk_shared_t* shared_chunk = _shared_chunk();
// check assumption
- if (sizeof(shared_chunk.fields.authorization_key_split) !=
- sizeof(chunk.fields.authorization_key)) {
+ if (sizeof(shared_chunk->fields.authorization_key_split) !=
+ sizeof(chunk->fields.authorization_key)) {
Abort("size mismatch");
}
- for (size_t i = 0; i < sizeof(shared_chunk.fields.authorization_key_split); i++) {
- key_out[i] ^= shared_chunk.fields.authorization_key_split[i];
+ for (size_t i = 0; i < sizeof(shared_chunk->fields.authorization_key_split); i++) {
+ key_out[i] ^= shared_chunk->fields.authorization_key_split[i];
}
}
void memory_get_encryption_key(uint8_t* key_out)
{
- chunk_0_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_0_PERMANENT, chunk_bytes);
- memcpy(key_out, chunk.fields.encryption_key, sizeof(chunk.fields.encryption_key));
+ const chunk_0_t* chunk = _chunk_0();
+ memcpy(key_out, chunk->fields.encryption_key, sizeof(chunk->fields.encryption_key));
// xor with the second part
- chunk_shared_t shared_chunk = {0};
- CLEANUP_CHUNK(shared_chunk);
- memory_read_shared_bootdata(&shared_chunk);
+ const chunk_shared_t* shared_chunk = _shared_chunk();
// check assumption
- if (sizeof(shared_chunk.fields.encryption_key_split) != sizeof(chunk.fields.encryption_key)) {
+ if (sizeof(shared_chunk->fields.encryption_key_split) != sizeof(chunk->fields.encryption_key)) {
Abort("size mismatch");
}
- for (size_t i = 0; i < sizeof(shared_chunk.fields.encryption_key_split); i++) {
- key_out[i] ^= shared_chunk.fields.encryption_key_split[i];
+ for (size_t i = 0; i < sizeof(shared_chunk->fields.encryption_key_split); i++) {
+ key_out[i] ^= shared_chunk->fields.encryption_key_split[i];
}
}
@@ -638,13 +681,11 @@ void memory_get_encryption_key(uint8_t* key_out)
*/
static bool _is_attestation_setup_done(void)
{
- chunk_0_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_0_PERMANENT, chunk_bytes);
+ const chunk_0_t* chunk = _chunk_0();
uint8_t empty[64] = {0};
memset(empty, 0xFF, sizeof(empty));
- return !MEMEQ(chunk.fields.attestation.certificate, empty, 64);
+ return !MEMEQ(chunk->fields.attestation.certificate, empty, 64);
}
bool memory_set_attestation_bootloader_hash(const uint8_t* salt)
@@ -662,17 +703,15 @@ bool memory_set_attestation_bootloader_hash(const uint8_t* salt)
void memory_get_attestation_bootloader_hash(uint8_t* hash_out)
{
- chunk_7_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_7_PERMANENT, chunk_bytes);
+ const chunk_7_t* chunk = _chunk_7();
uint8_t empty[32];
memset(empty, 0xff, sizeof(empty));
- if (chunk.fields.attestation_bootloader_hash_set != sectrue_u8 ||
- MEMEQ(chunk.fields.attestation_bootloader_hash, empty, sizeof(empty))) {
+ if (chunk->fields.attestation_bootloader_hash_set != sectrue_u8 ||
+ MEMEQ(chunk->fields.attestation_bootloader_hash, empty, sizeof(empty))) {
memory_bootloader_hash(hash_out);
return;
}
- memcpy(hash_out, chunk.fields.attestation_bootloader_hash, 32);
+ memcpy(hash_out, chunk->fields.attestation_bootloader_hash, 32);
}
bool memory_set_attestation_device_pubkey(const uint8_t* attestation_device_pubkey)
@@ -708,21 +747,19 @@ bool memory_get_attestation_pubkey_and_certificate(
if (!_is_attestation_setup_done()) {
return false;
}
- chunk_0_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_0_PERMANENT, chunk_bytes);
+ const chunk_0_t* chunk = _chunk_0();
memcpy(
pubkey_out,
- chunk.fields.attestation.device_pubkey,
- sizeof(chunk.fields.attestation.device_pubkey));
+ chunk->fields.attestation.device_pubkey,
+ sizeof(chunk->fields.attestation.device_pubkey));
memcpy(
certificate_out,
- chunk.fields.attestation.certificate,
- sizeof(chunk.fields.attestation.certificate));
+ chunk->fields.attestation.certificate,
+ sizeof(chunk->fields.attestation.certificate));
memcpy(
root_pubkey_identifier_out,
- chunk.fields.attestation.root_pubkey_identifier,
- sizeof(chunk.fields.attestation.root_pubkey_identifier));
+ chunk->fields.attestation.root_pubkey_identifier,
+ sizeof(chunk->fields.attestation.root_pubkey_identifier));
return true;
}
@@ -781,10 +818,8 @@ bool memory_set_ble_metadata(const memory_ble_metadata_t* metadata)
bool memory_get_salt_root(uint8_t* salt_root_out)
{
- chunk_1_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_1, chunk_bytes);
- memcpy(salt_root_out, chunk.fields.salt_root, sizeof(chunk.fields.salt_root));
+ const chunk_1_t* chunk = _chunk_1();
+ memcpy(salt_root_out, chunk->fields.salt_root, sizeof(chunk->fields.salt_root));
uint8_t empty[32];
memset(empty, 0xff, sizeof(empty));
return !MEMEQ(salt_root_out, empty, sizeof(empty));
@@ -803,13 +838,11 @@ bool memory_set_salt_root(const uint8_t* salt_root)
bool memory_get_noise_static_private_key(uint8_t* private_key_out)
{
- chunk_1_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_1, chunk_bytes);
+ const chunk_1_t* chunk = _chunk_1();
memcpy(
private_key_out,
- chunk.fields.noise_static_private_key,
- sizeof(chunk.fields.noise_static_private_key));
+ chunk->fields.noise_static_private_key,
+ sizeof(chunk->fields.noise_static_private_key));
uint8_t empty[32];
memset(empty, 0xff, sizeof(empty));
return !MEMEQ(private_key_out, empty, sizeof(empty));
@@ -817,15 +850,13 @@ bool memory_get_noise_static_private_key(uint8_t* private_key_out)
bool memory_check_noise_remote_static_pubkey(const uint8_t* pubkey)
{
- chunk_1_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_1, chunk_bytes);
+ const chunk_1_t* chunk = _chunk_1();
- const size_t number_of_slots = sizeof(chunk.fields.noise_remote_static_pubkeys) /
- sizeof(chunk.fields.noise_remote_static_pubkeys[0]);
+ const size_t number_of_slots = sizeof(chunk->fields.noise_remote_static_pubkeys) /
+ sizeof(chunk->fields.noise_remote_static_pubkeys[0]);
for (size_t slot = 0; slot < number_of_slots; slot++) {
- const uint8_t* stored_pubkey = chunk.fields.noise_remote_static_pubkeys[slot];
+ const uint8_t* stored_pubkey = chunk->fields.noise_remote_static_pubkeys[slot];
if (MEMEQ(stored_pubkey, pubkey, NOISE_PUBKEY_SIZE)) {
return true;
}
@@ -930,12 +961,10 @@ memory_result_t memory_multisig_set_by_hash(const uint8_t* hash, const char* nam
bool memory_multisig_get_by_hash(const uint8_t* hash, char* name_out)
{
- chunk_2_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_2, chunk.bytes);
+ const chunk_2_t* chunk = _chunk_2();
for (size_t i = 0; i < MEMORY_MULTISIG_NUM_ENTRIES; i++) {
- const multisig_configuration_t* multisig = &chunk.fields.multisig_configs[i];
+ const multisig_configuration_t* multisig = &chunk->fields.multisig_configs[i];
if (MEMEQ(multisig->hash, hash, sizeof(multisig->hash))) {
if (name_out != NULL) {
snprintf(name_out, sizeof(multisig->name), "%s", multisig->name);
@@ -965,10 +994,8 @@ bool memory_ble_enable(bool enable)
bool memory_get_optiga_config_version(memory_optiga_config_version_t* version_out)
{
- chunk_0_t chunk = {0};
- CLEANUP_CHUNK(chunk);
- _read_chunk(CHUNK_0_PERMANENT, chunk.bytes);
- switch (chunk.fields.optiga_config_version) {
+ const chunk_0_t* chunk = _chunk_0();
+ switch (chunk->fields.optiga_config_version) {
case 0xFF:
*version_out = MEMORY_OPTIGA_CONFIG_V0;
return true;
diff --git a/src/memory/memory_shared.c b/src/memory/memory_shared.c
index cc92c08..bac9601 100644
--- a/src/memory/memory_shared.c
+++ b/src/memory/memory_shared.c
@@ -94,12 +94,22 @@ void memory_read_shared_bootdata(chunk_shared_t* chunk_out)
#endif
}
-uint8_t memory_get_screen_type(void)
+static const chunk_shared_t* _shared_chunk(void)
{
- chunk_shared_t chunk = {0};
- memory_read_shared_bootdata(&chunk);
- uint8_t screen_type = chunk.fields.screen_type;
+#ifdef TESTING
+ static chunk_shared_t chunk;
util_zero(&chunk, sizeof(chunk));
+ memory_read_shared_bootdata(&chunk);
+ return &chunk;
+#else
+ return (const chunk_shared_t*)FLASH_SHARED_DATA_START;
+#endif
+}
+
+uint8_t memory_get_screen_type(void)
+{
+ const chunk_shared_t* chunk = _shared_chunk();
+ uint8_t screen_type = chunk->fields.screen_type;
switch (screen_type) {
case MEMORY_SCREEN_TYPE_SSD1312:
return screen_type;
@@ -113,10 +123,8 @@ uint8_t memory_get_screen_type(void)
uint8_t memory_get_securechip_type(void)
{
- chunk_shared_t chunk = {0};
- memory_read_shared_bootdata(&chunk);
- uint8_t securechip_type = chunk.fields.securechip_type;
- util_zero(&chunk, sizeof(chunk));
+ const chunk_shared_t* chunk = _shared_chunk();
+ uint8_t securechip_type = chunk->fields.securechip_type;
switch (securechip_type) {
case MEMORY_SECURECHIP_TYPE_OPTIGA:
return securechip_type;
@@ -127,10 +135,8 @@ uint8_t memory_get_securechip_type(void)
uint8_t memory_get_platform(void)
{
- chunk_shared_t chunk = {0};
- memory_read_shared_bootdata(&chunk);
- uint8_t platform = chunk.fields.platform;
- util_zero(&chunk, sizeof(chunk));
+ const chunk_shared_t* chunk = _shared_chunk();
+ uint8_t platform = chunk->fields.platform;
switch (platform) {
case MEMORY_PLATFORM_BITBOX02_PLUS:
return platform;
@@ -145,11 +151,9 @@ uint8_t memory_get_platform(void)
bool memory_ble_enabled(void)
{
- chunk_shared_t chunk = {0};
- memory_read_shared_bootdata(&chunk);
- uint8_t ble_enabled = chunk.fields.ble_enabled;
+ const chunk_shared_t* chunk = _shared_chunk();
+ uint8_t ble_enabled = chunk->fields.ble_enabled;
util_log("ble enabled %x", ble_enabled);
- util_zero(&chunk, sizeof(chunk));
return ble_enabled != MEMORY_BLE_DISABLED;
}
@@ -160,14 +164,12 @@ int16_t memory_get_ble_bond_db(uint8_t* data)
// chip to always set the bond db when it has booted.
return -1;
#endif
- chunk_shared_t chunk = {0};
- memory_read_shared_bootdata(&chunk);
- int16_t len = chunk.fields.ble_bond_db_len;
+ const chunk_shared_t* chunk = _shared_chunk();
+ int16_t len = chunk->fields.ble_bond_db_len;
if (len != -1) {
- memcpy(data, &chunk.fields.ble_bond_db[0], len);
+ memcpy(data, &chunk->fields.ble_bond_db[0], len);
}
- util_zero(&chunk, sizeof(chunk));
return len;
}
@@ -194,46 +196,38 @@ bool memory_set_ble_bond_db(const uint8_t* data, int16_t data_len)
void memory_get_ble_irk(uint8_t* data)
{
- chunk_shared_t chunk = {0};
- memory_read_shared_bootdata(&chunk);
+ const chunk_shared_t* chunk = _shared_chunk();
memcpy(
data,
- &chunk.fields.ble_identity_resolving_key,
- sizeof(chunk.fields.ble_identity_resolving_key));
-
- util_zero(&chunk, sizeof(chunk));
+ &chunk->fields.ble_identity_resolving_key,
+ sizeof(chunk->fields.ble_identity_resolving_key));
}
void memory_get_ble_identity_address(uint8_t* data)
{
- chunk_shared_t chunk = {0};
- memory_read_shared_bootdata(&chunk);
+ const chunk_shared_t* chunk = _shared_chunk();
#if defined(DEBUG)
uint8_t ones[MEMORY_BLE_ADDR_LEN] = {-1, -1, -1, -1, -1, -1};
uint8_t zeros[MEMORY_BLE_ADDR_LEN] = {0};
#endif
// In case address isn't valid, factory setup / hww reset needs to be run
ASSERT(
- memcmp(&ones[0], &chunk.fields.ble_identity_address[0], sizeof(ones)) != 0 &&
- memcmp(&zeros[0], &chunk.fields.ble_identity_address[0], sizeof(zeros)) != 0);
-
- memcpy(data, &chunk.fields.ble_identity_address, sizeof(chunk.fields.ble_identity_address));
+ memcmp(&ones[0], &chunk->fields.ble_identity_address[0], sizeof(ones)) != 0 &&
+ memcmp(&zeros[0], &chunk->fields.ble_identity_address[0], sizeof(zeros)) != 0);
- util_zero(&chunk, sizeof(chunk));
+ memcpy(data, &chunk->fields.ble_identity_address, sizeof(chunk->fields.ble_identity_address));
}
void memory_get_ble_metadata(memory_ble_metadata_t* metadata_out)
{
- chunk_shared_t chunk = {0};
- memory_read_shared_bootdata(&chunk);
- metadata_out->active_index = chunk.fields.ble_active_index;
- memcpy(metadata_out->allowed_firmware_hash, chunk.fields.ble_allowed_firmware_hash, 32);
- metadata_out->firmware_sizes[0] = chunk.fields.ble_firmware_sizes[0];
- metadata_out->firmware_sizes[1] = chunk.fields.ble_firmware_sizes[1];
- metadata_out->firmware_checksums[0] = chunk.fields.ble_firmware_checksums[0];
- metadata_out->firmware_checksums[1] = chunk.fields.ble_firmware_checksums[1];
- util_zero(&chunk, sizeof(chunk));
+ const chunk_shared_t* chunk = _shared_chunk();
+ metadata_out->active_index = chunk->fields.ble_active_index;
+ memcpy(metadata_out->allowed_firmware_hash, chunk->fields.ble_allowed_firmware_hash, 32);
+ metadata_out->firmware_sizes[0] = chunk->fields.ble_firmware_sizes[0];
+ metadata_out->firmware_sizes[1] = chunk->fields.ble_firmware_sizes[1];
+ metadata_out->firmware_checksums[0] = chunk->fields.ble_firmware_checksums[0];
+ metadata_out->firmware_checksums[1] = chunk->fields.ble_firmware_checksums[1];
}
void memory_random_name(char* name_out)
Why this scored 25/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.