What changed, and why it matters
This commit is a software architecture cleanup: it moves some type definitions and helper functions so that secure-chip code (ATECC/Optiga) no longer depends directly on the BitBox02-specific memory module. The goal stated by the developer is to make those modules reusable in a future BitBox03. There is no direct evidence in the commit that it fixes a security vulnerability, changes cryptographic behavior, or introduces a bug.
No security action required. Treat as normal code-review item: verify that the new enum mappings and FFI wrappers are exercised by existing tests and that no stale `memory.h` includes remain in the secure-chip layer.
Security signals we found
No security-relevant signal: pure refactoring/abstraction change with equivalent runtime behavior.
Enum values for password-stretch algorithms are preserved (V0/V1 map one-to-one).
No new input parsing, no buffer size changes, no privilege changes, no cryptographic algorithm changes.
No vendor disclosure, CVE, or researcher attribution present in commit or references.
Evidence from the diff
The patch decouples src/atecc/atecc.c, src/optiga/optiga.c, and src/securechip/securechip.c/h from memory/memory.h. It introduces a new securechip_password_stretch_algo_t enum in securechip.h that mirrors the old memory_password_stretch_algo_t, and replaces all uses in the secure-chip layer. It also adds Rust HAL abstractions (OptigaConfigVersion, get_optiga_config_version, set_optiga_config_version) and C FFI wrappers (rust_memory_optiga_config_is_v1_or_higher, rust_memory_set_optiga_config_version_v1) so the Optiga module can query/set configuration state without including BB02 memory headers. Unit tests and hardware fakes are updated to use the new enum names. The logic of password stretching, KDF, and Optiga configuration remains functionally identical.
Changed components
src/atecc/atecc.csrc/atecc/atecc.hsrc/optiga/optiga.csrc/optiga/optiga.hsrc/securechip/securechip.csrc/securechip/securechip.hsrc/rust/bitbox-hal/src/memory.rssrc/rust/bitbox02-rust-c/src/firmware_c_api.rssrc/rust/bitbox02-rust/src/hal/testing/memory.rssrc/rust/bitbox02-sys/build.rssrc/rust/bitbox02/src/hal/memory.rssrc/rust/bitbox02/src/hal/securechip.rssrc/rust/bitbox02/src/memory.rssrc/rust/bitbox02/src/securechip.rstest/hardware-fakes/src/fake_securechip.ctest/unit-test/test_optiga.cInspect captured patch +217 / −58
diff --git a/src/atecc/atecc.c b/src/atecc/atecc.c
index b43011d..a68dae9 100644
--- a/src/atecc/atecc.c
+++ b/src/atecc/atecc.c
@@ -4,7 +4,6 @@
#include "hardfault.h"
#include "securechip/securechip.h"
#include <i2c_ecc.h>
-#include <memory/memory.h>
#include <rust/rust.h>
#include <util.h>
@@ -574,11 +573,11 @@ int atecc_kdf(const uint8_t* msg, size_t len, uint8_t* kdf_out)
int atecc_init_new_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out)
{
(void)password;
- if (password_stretch_algo != MEMORY_PASSWORD_STRETCH_ALGO_V0) {
+ if (password_stretch_algo != SECURECHIP_PASSWORD_STRETCH_ALGO_V0) {
return SC_ERR_INVALID_PASSWORD_STRETCH_ALGO;
}
if (!atecc_reset_keys()) {
@@ -589,10 +588,10 @@ int atecc_init_new_password(
int atecc_stretch_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out)
{
- if (password_stretch_algo != MEMORY_PASSWORD_STRETCH_ALGO_V0) {
+ if (password_stretch_algo != SECURECHIP_PASSWORD_STRETCH_ALGO_V0) {
return SC_ERR_INVALID_PASSWORD_STRETCH_ALGO;
}
diff --git a/src/atecc/atecc.h b/src/atecc/atecc.h
index 93185e6..69228d8 100644
--- a/src/atecc/atecc.h
+++ b/src/atecc/atecc.h
@@ -17,11 +17,11 @@ USE_RESULT int atecc_setup(const securechip_interface_functions_t* ifs);
USE_RESULT int atecc_kdf(const uint8_t* msg, size_t len, uint8_t* kdf_out);
USE_RESULT int atecc_init_new_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out);
USE_RESULT int atecc_stretch_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out);
USE_RESULT bool atecc_reset_keys(void);
USE_RESULT bool atecc_gen_attestation_key(uint8_t* pubkey_out);
diff --git a/src/optiga/optiga.c b/src/optiga/optiga.c
index 7e93f26..8f7f3a4 100644
--- a/src/optiga/optiga.c
+++ b/src/optiga/optiga.c
@@ -9,8 +9,6 @@
#include "pal/pal_os_timer.h"
#include <hardfault.h>
-#include <memory/bitbox02_smarteeprom.h>
-#include <memory/memory.h>
#include <optiga_crypt.h>
#include <optiga_util.h>
#include <rust/rust.h>
@@ -1054,12 +1052,12 @@ static int _verify_metadata(
// Updates Optiga config to V1 if not already done.
static int _maybe_update_config_v1(void)
{
- memory_optiga_config_version_t config_version;
- if (!memory_get_optiga_config_version(&config_version)) {
+ bool config_is_v1_or_higher = false;
+ if (!rust_memory_optiga_config_is_v1_or_higher(&config_is_v1_or_higher)) {
return SC_ERR_MEMORY;
}
- if (config_version >= MEMORY_OPTIGA_CONFIG_V1) {
+ if (config_is_v1_or_higher) {
if (FINAL_LCSO_STATE_V1 >= LCSO_STATE_OPERATIONAL) {
// Already configured
util_log("optiga: config v1 already configured");
@@ -1114,7 +1112,7 @@ static int _maybe_update_config_v1(void)
}
if (FINAL_LCSO_STATE_V1 >= LCSO_STATE_OPERATIONAL) {
- if (!memory_set_optiga_config_version(MEMORY_OPTIGA_CONFIG_V1)) {
+ if (!rust_memory_set_optiga_config_version_v1()) {
return SC_ERR_MEMORY;
}
}
@@ -1332,10 +1330,10 @@ static int _v1_combine(
int optiga_init_new_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out)
{
- if (password_stretch_algo != MEMORY_PASSWORD_STRETCH_ALGO_V1) {
+ if (password_stretch_algo != SECURECHIP_PASSWORD_STRETCH_ALGO_V1) {
// New passwords must use the latest algo.
return SC_ERR_INVALID_PASSWORD_STRETCH_ALGO;
}
@@ -1410,7 +1408,7 @@ bool optiga_reset_keys(void)
// We reset using V1, the latest algorithm. It covers resetting everything from V0 as well.
uint8_t stretched[32];
- return optiga_init_new_password("", MEMORY_PASSWORD_STRETCH_ALGO_V1, stretched) == 0;
+ return optiga_init_new_password("", SECURECHIP_PASSWORD_STRETCH_ALGO_V1, stretched) == 0;
}
static int _optiga_verify_password_v0(const char* password, uint8_t* password_secret_out)
@@ -1795,14 +1793,14 @@ static int _stretch_password_v1(const char* password, uint8_t* stretched_out)
int optiga_stretch_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out)
{
switch (password_stretch_algo) {
- case MEMORY_PASSWORD_STRETCH_ALGO_V0:
+ case SECURECHIP_PASSWORD_STRETCH_ALGO_V0:
util_log("stretching password using algo v0");
return _stretch_password_v0(password, stretched_out);
- case MEMORY_PASSWORD_STRETCH_ALGO_V1:
+ case SECURECHIP_PASSWORD_STRETCH_ALGO_V1:
util_log("stretching password using algo v1");
return _stretch_password_v1(password, stretched_out);
default:
diff --git a/src/optiga/optiga.h b/src/optiga/optiga.h
index 85fcb70..d3f6fa6 100644
--- a/src/optiga/optiga.h
+++ b/src/optiga/optiga.h
@@ -8,8 +8,6 @@
#include "compiler_util.h"
#include "securechip/securechip.h"
-#include <memory/bitbox02_smarteeprom.h>
-#include <memory/memory.h>
#include <platform/platform_config.h>
#include <stdbool.h>
#include <stddef.h>
@@ -85,11 +83,11 @@ USE_RESULT int optiga_setup(const securechip_interface_functions_t* ifs);
USE_RESULT int optiga_kdf_external(const uint8_t* msg, size_t len, uint8_t* mac_out);
USE_RESULT int optiga_init_new_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out);
USE_RESULT int optiga_stretch_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out);
USE_RESULT bool optiga_reset_keys(void);
USE_RESULT bool optiga_gen_attestation_key(uint8_t* pubkey_out);
diff --git a/src/rust/bitbox-hal/src/memory.rs b/src/rust/bitbox-hal/src/memory.rs
index 4ec3b37..1845088 100644
--- a/src/rust/bitbox-hal/src/memory.rs
+++ b/src/rust/bitbox-hal/src/memory.rs
@@ -17,6 +17,12 @@ pub enum PasswordStretchAlgo {
V1,
}
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd)]
+pub enum OptigaConfigVersion {
+ V0,
+ V1,
+}
+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum SecurechipType {
Atecc,
@@ -68,6 +74,8 @@ pub trait Memory {
fn ble_get_metadata(&mut self) -> BleMetadata;
fn set_ble_metadata(&mut self, metadata: &BleMetadata) -> Result<(), Error>;
fn get_securechip_type(&mut self) -> Result<SecurechipType, ()>;
+ fn get_optiga_config_version(&mut self) -> Result<OptigaConfigVersion, ()>;
+ fn set_optiga_config_version(&mut self, version: OptigaConfigVersion) -> Result<(), ()>;
fn get_platform(&mut self) -> Result<Platform, ()>;
fn get_device_name(&mut self) -> String;
/// `name` must be non-empty and at most [`DEVICE_NAME_MAX_LEN`] bytes long.
diff --git a/src/rust/bitbox02-rust-c/src/firmware_c_api.rs b/src/rust/bitbox02-rust-c/src/firmware_c_api.rs
index 37eec41..b1f7f51 100644
--- a/src/rust/bitbox02-rust-c/src/firmware_c_api.rs
+++ b/src/rust/bitbox02-rust-c/src/firmware_c_api.rs
@@ -3,7 +3,7 @@
use core::ffi::c_char;
use util::bytes::{Bytes, BytesMut};
-use bitbox_hal::Hal;
+use bitbox_hal::{Hal, Memory, memory::OptigaConfigVersion};
#[cfg(not(any(feature = "c-unit-testing", feature = "simulator-graphical")))]
#[unsafe(no_mangle)]
@@ -34,6 +34,35 @@ pub unsafe extern "C" fn rust_salt_hash_data(
}
}
+/// # Safety
+///
+/// `result_out` must be a valid pointer.
+#[unsafe(no_mangle)]
+pub unsafe extern "C" fn rust_memory_optiga_config_is_v1_or_higher(result_out: *mut bool) -> bool {
+ if result_out.is_null() {
+ return false;
+ }
+
+ let mut hal = crate::HalImpl::new();
+ match hal.memory().get_optiga_config_version() {
+ Ok(version) => {
+ unsafe {
+ *result_out = version >= OptigaConfigVersion::V1;
+ }
+ true
+ }
+ Err(()) => false,
+ }
+}
+
+#[unsafe(no_mangle)]
+pub extern "C" fn rust_memory_set_optiga_config_version_v1() -> bool {
+ let mut hal = crate::HalImpl::new();
+ hal.memory()
+ .set_optiga_config_version(OptigaConfigVersion::V1)
+ .is_ok()
+}
+
#[cfg(feature = "app-u2f")]
#[unsafe(no_mangle)]
pub extern "C" fn rust_keystore_get_u2f_seed(mut seed_out: util::bytes::BytesMut) -> bool {
@@ -45,3 +74,36 @@ pub extern "C" fn rust_keystore_get_u2f_seed(mut seed_out: util::bytes::BytesMut
Err(_) => false,
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use bitbox02::memory::{
+ OptigaConfigVersion as MemoryOptigaConfigVersion, set_optiga_config_version,
+ };
+
+ fn setup_memory() {
+ set_optiga_config_version(MemoryOptigaConfigVersion::MEMORY_OPTIGA_CONFIG_V0).unwrap();
+ }
+
+ #[test]
+ fn test_rust_memory_optiga_config_is_v1_or_higher() {
+ setup_memory();
+
+ let mut is_v1_or_higher = false;
+ assert!(unsafe { rust_memory_optiga_config_is_v1_or_higher(&mut is_v1_or_higher) });
+ assert!(!is_v1_or_higher);
+
+ assert!(rust_memory_set_optiga_config_version_v1());
+
+ let mut is_v1_or_higher = false;
+ assert!(unsafe { rust_memory_optiga_config_is_v1_or_higher(&mut is_v1_or_higher) });
+ assert!(is_v1_or_higher);
+ }
+
+ #[test]
+ fn test_rust_memory_optiga_config_is_v1_or_higher_null_pointer() {
+ setup_memory();
+ assert!(!unsafe { rust_memory_optiga_config_is_v1_or_higher(core::ptr::null_mut()) });
+ }
+}
diff --git a/src/rust/bitbox02-rust/src/hal/testing/memory.rs b/src/rust/bitbox02-rust/src/hal/testing/memory.rs
index a3efbc9..6d6a725 100644
--- a/src/rust/bitbox02-rust/src/hal/testing/memory.rs
+++ b/src/rust/bitbox02-rust/src/hal/testing/memory.rs
@@ -4,7 +4,8 @@ use alloc::string::String;
use alloc::vec::Vec;
use crate::hal::memory::{
- BleFirmwareSlot, BleMetadata, Error, PasswordStretchAlgo, Platform, SecurechipType,
+ BleFirmwareSlot, BleMetadata, Error, OptigaConfigVersion, PasswordStretchAlgo, Platform,
+ SecurechipType,
};
pub struct TestingMemory {
@@ -13,6 +14,7 @@ pub struct TestingMemory {
ble_firmware_slots: [Vec<u8>; 2],
active_ble_firmware_version: String,
securechip_type: SecurechipType,
+ optiga_config_version: OptigaConfigVersion,
platform: Platform,
initialized: bool,
is_seeded: bool,
@@ -48,6 +50,7 @@ impl TestingMemory {
],
active_ble_firmware_version: "0.0.0".into(),
securechip_type: SecurechipType::Optiga,
+ optiga_config_version: OptigaConfigVersion::V0,
platform: Platform::BitBox02,
initialized: false,
is_seeded: false,
@@ -161,6 +164,15 @@ impl crate::hal::Memory for TestingMemory {
Ok(self.securechip_type)
}
+ fn get_optiga_config_version(&mut self) -> Result<OptigaConfigVersion, ()> {
+ Ok(self.optiga_config_version)
+ }
+
+ fn set_optiga_config_version(&mut self, version: OptigaConfigVersion) -> Result<(), ()> {
+ self.optiga_config_version = version;
+ Ok(())
+ }
+
fn get_platform(&mut self) -> Result<Platform, ()> {
Ok(self.platform)
}
diff --git a/src/rust/bitbox02-sys/build.rs b/src/rust/bitbox02-sys/build.rs
index 99bd089..565f1ea 100644
--- a/src/rust/bitbox02-sys/build.rs
+++ b/src/rust/bitbox02-sys/build.rs
@@ -203,6 +203,7 @@ const RUSTIFIED_ENUMS: &[&str] = &[
"memory_optiga_config_version_t",
"memory_password_stretch_algo_t",
"memory_result_t",
+ "securechip_password_stretch_algo_t",
"multisig_script_type_t",
"output_type_t",
"securechip_error_t",
diff --git a/src/rust/bitbox02/src/hal/memory.rs b/src/rust/bitbox02/src/hal/memory.rs
index 444df07..3ea4995 100644
--- a/src/rust/bitbox02/src/hal/memory.rs
+++ b/src/rust/bitbox02/src/hal/memory.rs
@@ -5,7 +5,8 @@ use alloc::vec::Vec;
use bitbox_hal::Memory;
use bitbox_hal::memory::{
- BleFirmwareSlot, BleMetadata, Error, PasswordStretchAlgo, Platform, SecurechipType,
+ BleFirmwareSlot, BleMetadata, Error, OptigaConfigVersion, PasswordStretchAlgo, Platform,
+ SecurechipType,
};
pub struct BitBox02Memory;
@@ -35,6 +36,15 @@ fn to_hal_password_stretch_algo(algo: crate::memory::PasswordStretchAlgo) -> Pas
}
}
+fn to_hal_optiga_config_version(
+ version: crate::memory::OptigaConfigVersion,
+) -> OptigaConfigVersion {
+ match version {
+ crate::memory::OptigaConfigVersion::MEMORY_OPTIGA_CONFIG_V0 => OptigaConfigVersion::V0,
+ crate::memory::OptigaConfigVersion::MEMORY_OPTIGA_CONFIG_V1 => OptigaConfigVersion::V1,
+ }
+}
+
fn to_hal_error(error: crate::memory::MemoryError) -> Error {
match error {
crate::memory::MemoryError::MEMORY_OK => {
@@ -69,6 +79,15 @@ pub(super) fn to_bitbox02_password_stretch_algo(
}
}
+fn to_bitbox02_optiga_config_version(
+ version: OptigaConfigVersion,
+) -> crate::memory::OptigaConfigVersion {
+ match version {
+ OptigaConfigVersion::V0 => crate::memory::OptigaConfigVersion::MEMORY_OPTIGA_CONFIG_V0,
+ OptigaConfigVersion::V1 => crate::memory::OptigaConfigVersion::MEMORY_OPTIGA_CONFIG_V1,
+ }
+}
+
fn to_bitbox02_ble_metadata(metadata: &BleMetadata) -> crate::memory::BleMetadata {
crate::memory::BleMetadata {
allowed_firmware_hash: metadata.allowed_firmware_hash,
@@ -128,6 +147,14 @@ impl Memory for BitBox02Memory {
crate::memory::get_securechip_type().map(to_hal_securechip_type)
}
+ fn get_optiga_config_version(&mut self) -> Result<OptigaConfigVersion, ()> {
+ crate::memory::get_optiga_config_version().map(to_hal_optiga_config_version)
+ }
+
+ fn set_optiga_config_version(&mut self, version: OptigaConfigVersion) -> Result<(), ()> {
+ crate::memory::set_optiga_config_version(to_bitbox02_optiga_config_version(version))
+ }
+
fn get_platform(&mut self) -> Result<Platform, ()> {
crate::memory::get_platform().map(to_hal_platform)
}
@@ -310,6 +337,30 @@ mod tests {
);
}
+ #[test]
+ fn test_optiga_config_version_mappings() {
+ assert_eq!(
+ to_hal_optiga_config_version(
+ crate::memory::OptigaConfigVersion::MEMORY_OPTIGA_CONFIG_V0,
+ ),
+ OptigaConfigVersion::V0,
+ );
+ assert_eq!(
+ to_hal_optiga_config_version(
+ crate::memory::OptigaConfigVersion::MEMORY_OPTIGA_CONFIG_V1,
+ ),
+ OptigaConfigVersion::V1,
+ );
+ assert_eq!(
+ to_bitbox02_optiga_config_version(OptigaConfigVersion::V0) as i32,
+ crate::memory::OptigaConfigVersion::MEMORY_OPTIGA_CONFIG_V0 as i32,
+ );
+ assert_eq!(
+ to_bitbox02_optiga_config_version(OptigaConfigVersion::V1) as i32,
+ crate::memory::OptigaConfigVersion::MEMORY_OPTIGA_CONFIG_V1 as i32,
+ );
+ }
+
#[test]
fn test_to_hal_ble_metadata() {
let input = crate::memory::BleMetadata {
diff --git a/src/rust/bitbox02/src/hal/securechip.rs b/src/rust/bitbox02/src/hal/securechip.rs
index abf900d..ef681d6 100644
--- a/src/rust/bitbox02/src/hal/securechip.rs
+++ b/src/rust/bitbox02/src/hal/securechip.rs
@@ -65,6 +65,17 @@ fn to_hal_error(error: crate::securechip::Error) -> Error {
}
}
+fn to_c_password_stretch_algo(algo: PasswordStretchAlgo) -> crate::securechip::PasswordStretchAlgo {
+ match algo {
+ PasswordStretchAlgo::V0 => {
+ crate::securechip::PasswordStretchAlgo::SECURECHIP_PASSWORD_STRETCH_ALGO_V0
+ }
+ PasswordStretchAlgo::V1 => {
+ crate::securechip::PasswordStretchAlgo::SECURECHIP_PASSWORD_STRETCH_ALGO_V1
+ }
+ }
+}
+
impl SecureChip for BitBox02SecureChip {
fn init_new_password(
&mut self,
@@ -73,7 +84,7 @@ impl SecureChip for BitBox02SecureChip {
) -> Result<zeroize::Zeroizing<Vec<u8>>, Error> {
crate::securechip::init_new_password(
password,
- super::memory::to_bitbox02_password_stretch_algo(password_stretch_algo),
+ to_c_password_stretch_algo(password_stretch_algo),
)
.map_err(to_hal_error)
}
@@ -85,7 +96,7 @@ impl SecureChip for BitBox02SecureChip {
) -> Result<zeroize::Zeroizing<Vec<u8>>, Error> {
crate::securechip::stretch_password(
password,
- super::memory::to_bitbox02_password_stretch_algo(password_stretch_algo),
+ to_c_password_stretch_algo(password_stretch_algo),
)
.map_err(to_hal_error)
}
@@ -227,4 +238,16 @@ mod tests {
Error::Status(7)
);
}
+
+ #[test]
+ fn test_to_c_password_stretch_algo() {
+ assert_eq!(
+ to_c_password_stretch_algo(PasswordStretchAlgo::V0),
+ crate::securechip::PasswordStretchAlgo::SECURECHIP_PASSWORD_STRETCH_ALGO_V0,
+ );
+ assert_eq!(
+ to_c_password_stretch_algo(PasswordStretchAlgo::V1),
+ crate::securechip::PasswordStretchAlgo::SECURECHIP_PASSWORD_STRETCH_ALGO_V1,
+ );
+ }
}
diff --git a/src/rust/bitbox02/src/memory.rs b/src/rust/bitbox02/src/memory.rs
index 5ec8358..b4ce8df 100644
--- a/src/rust/bitbox02/src/memory.rs
+++ b/src/rust/bitbox02/src/memory.rs
@@ -365,8 +365,7 @@ fn set_attestation_bootloader_hash(hash: &[u8; 32]) -> bool {
unsafe { bitbox02_sys::memory_set_attestation_bootloader_hash(hash.as_ptr()) }
}
-#[cfg(test)]
-fn get_optiga_config_version() -> Result<OptigaConfigVersion, ()> {
+pub fn get_optiga_config_version() -> Result<OptigaConfigVersion, ()> {
let mut version = core::mem::MaybeUninit::uninit();
unsafe {
match bitbox02_sys::memory_get_optiga_config_version(version.as_mut_ptr()) {
@@ -376,8 +375,7 @@ fn get_optiga_config_version() -> Result<OptigaConfigVersion, ()> {
}
}
-#[cfg(test)]
-fn set_optiga_config_version(version: OptigaConfigVersion) -> Result<(), ()> {
+pub fn set_optiga_config_version(version: OptigaConfigVersion) -> Result<(), ()> {
match unsafe { bitbox02_sys::memory_set_optiga_config_version(version) } {
true => Ok(()),
false => Err(()),
diff --git a/src/rust/bitbox02/src/securechip.rs b/src/rust/bitbox02/src/securechip.rs
index a2cd1db..3b6e35e 100644
--- a/src/rust/bitbox02/src/securechip.rs
+++ b/src/rust/bitbox02/src/securechip.rs
@@ -7,8 +7,7 @@ use zeroize::Zeroizing;
pub use bitbox02_sys::securechip_error_t as SecureChipError;
pub use bitbox02_sys::securechip_model_t as Model;
-
-use crate::memory::PasswordStretchAlgo;
+pub use bitbox02_sys::securechip_password_stretch_algo_t as PasswordStretchAlgo;
#[derive(Debug, PartialEq, Eq)]
pub enum Error {
diff --git a/src/securechip/securechip.c b/src/securechip/securechip.c
index 9a5d2dc..023b8ad 100644
--- a/src/securechip/securechip.c
+++ b/src/securechip/securechip.c
@@ -13,11 +13,11 @@ typedef struct {
int (*kdf)(const uint8_t* msg, size_t msg_len, uint8_t* kdf_out);
int (*init_new_password)(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out);
int (*stretch_password)(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out);
bool (*reset_keys)(void);
bool (*gen_attestation_key)(uint8_t* pubkey_out);
@@ -101,7 +101,7 @@ int securechip_kdf(const uint8_t* msg, size_t msg_len, uint8_t* mac_out)
int securechip_init_new_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out)
{
ABORT_IF_NULL(init_new_password);
@@ -110,7 +110,7 @@ int securechip_init_new_password(
int securechip_stretch_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out)
{
ABORT_IF_NULL(stretch_password);
diff --git a/src/securechip/securechip.h b/src/securechip/securechip.h
index 141614f..94ed188 100644
--- a/src/securechip/securechip.h
+++ b/src/securechip/securechip.h
@@ -4,7 +4,6 @@
#define _SECURECHIP_H_
#include "compiler_util.h"
-#include <memory/memory.h>
#include <platform/platform_config.h>
#include <stdbool.h>
#include <stddef.h>
@@ -40,6 +39,14 @@ typedef enum {
SC_OPTIGA_ERR_UNEXPECTED_LEN = -206,
} securechip_error_t;
+typedef enum {
+ // Legacy/initial value for BitBox02 and BitBox02 Nova using the initial stretch algo in
+ // ATECC/Optiga.
+ SECURECHIP_PASSWORD_STRETCH_ALGO_V0,
+ // Currently used only by Optiga.
+ SECURECHIP_PASSWORD_STRETCH_ALGO_V1,
+} securechip_password_stretch_algo_t;
+
typedef struct {
/**
* @param[out] key_out must be of size 32
@@ -98,7 +105,7 @@ USE_RESULT int securechip_kdf(const uint8_t* msg, size_t len, uint8_t* kdf_out);
*/
USE_RESULT int securechip_init_new_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out);
/**
@@ -112,7 +119,7 @@ USE_RESULT int securechip_init_new_password(
*/
USE_RESULT int securechip_stretch_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out);
/**
diff --git a/test/hardware-fakes/src/fake_securechip.c b/test/hardware-fakes/src/fake_securechip.c
index 0591b7e..d25620e 100644
--- a/test/hardware-fakes/src/fake_securechip.c
+++ b/test/hardware-fakes/src/fake_securechip.c
@@ -20,10 +20,10 @@ int securechip_kdf(const uint8_t* msg, size_t len, uint8_t* kdf_out)
int securechip_init_new_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out)
{
- if (password_stretch_algo != MEMORY_PASSWORD_STRETCH_ALGO_V1) {
+ if (password_stretch_algo != SECURECHIP_PASSWORD_STRETCH_ALGO_V1) {
// New passwords must use the latest algo.
return SC_ERR_INVALID_PASSWORD_STRETCH_ALGO;
}
@@ -31,7 +31,7 @@ int securechip_init_new_password(
}
int securechip_stretch_password(
const char* password,
- memory_password_stretch_algo_t password_stretch_algo,
+ securechip_password_stretch_algo_t password_stretch_algo,
uint8_t* stretched_out)
{
(void)password_stretch_algo;
diff --git a/test/unit-test/test_optiga.c b/test/unit-test/test_optiga.c
index 69293eb..a786c48 100644
--- a/test/unit-test/test_optiga.c
+++ b/test/unit-test/test_optiga.c
@@ -754,7 +754,7 @@ static void test_optiga_stretch_password_v0_success(void** state)
uint8_t stretched_out[32] = {0};
assert_int_equal(
- optiga_stretch_password("pw", MEMORY_PASSWORD_STRETCH_ALGO_V0, stretched_out), 0);
+ optiga_stretch_password("pw", SECURECHIP_PASSWORD_STRETCH_ALGO_V0, stretched_out), 0);
assert_memory_equal(
stretched_out, _expected_stretched_out_v0, sizeof(_expected_stretched_out_v0));
// Successful password verification resets the small monotonic counter/threshold.
@@ -779,25 +779,25 @@ static void test_optiga_stretch_password_v0_attempt_counter(void** state)
uint8_t stretched_out[32] = {0};
assert_int_equal(
- optiga_stretch_password("wrong", MEMORY_PASSWORD_STRETCH_ALGO_V0, stretched_out),
+ optiga_stretch_password("wrong", SECURECHIP_PASSWORD_STRETCH_ALGO_V0, stretched_out),
SC_ERR_INCORRECT_PASSWORD);
assert_int_equal(_get_counter(OID_COUNTER_PASSWORD), 1);
assert_int_equal(_get_threshold(OID_COUNTER_PASSWORD), SMALL_MONOTONIC_COUNTER_MAX_USE);
assert_int_equal(
- optiga_stretch_password("wrong", MEMORY_PASSWORD_STRETCH_ALGO_V0, stretched_out),
+ optiga_stretch_password("wrong", SECURECHIP_PASSWORD_STRETCH_ALGO_V0, stretched_out),
SC_ERR_INCORRECT_PASSWORD);
assert_int_equal(_get_counter(OID_COUNTER_PASSWORD), 2);
assert_int_equal(_get_threshold(OID_COUNTER_PASSWORD), SMALL_MONOTONIC_COUNTER_MAX_USE);
assert_int_equal(
- optiga_stretch_password("pw", MEMORY_PASSWORD_STRETCH_ALGO_V0, stretched_out), 0);
+ optiga_stretch_password("pw", SECURECHIP_PASSWORD_STRETCH_ALGO_V0, stretched_out), 0);
assert_int_equal(_get_counter(OID_COUNTER_PASSWORD), 0);
assert_int_equal(_get_threshold(OID_COUNTER_PASSWORD), SMALL_MONOTONIC_COUNTER_MAX_USE);
for (int i = 0; i < SMALL_MONOTONIC_COUNTER_MAX_USE; i++) {
assert_int_equal(
- optiga_stretch_password("wrong", MEMORY_PASSWORD_STRETCH_ALGO_V0, stretched_out),
+ optiga_stretch_password("wrong", SECURECHIP_PASSWORD_STRETCH_ALGO_V0, stretched_out),
SC_ERR_INCORRECT_PASSWORD);
}
assert_int_equal(
@@ -805,7 +805,7 @@ static void test_optiga_stretch_password_v0_attempt_counter(void** state)
// After exhausting all allowed attempts, a correct password fails as well.
assert_int_equal(
- optiga_stretch_password("pw", MEMORY_PASSWORD_STRETCH_ALGO_V0, stretched_out),
+ optiga_stretch_password("pw", SECURECHIP_PASSWORD_STRETCH_ALGO_V0, stretched_out),
SC_ERR_INCORRECT_PASSWORD);
assert_int_equal(
optiga_common_get_uint32(&_oid_counter_password_buf[0]), SMALL_MONOTONIC_COUNTER_MAX_USE);
@@ -820,7 +820,8 @@ static void test_optiga_password_v1_stretch_exhaust_fails_after_init(void** stat
_setup_test();
uint8_t stretched[32] = {0};
- assert_int_equal(optiga_init_new_password("pw", MEMORY_PASSWORD_STRETCH_ALGO_V1, stretched), 0);
+ assert_int_equal(
+ optiga_init_new_password("pw", SECURECHIP_PASSWORD_STRETCH_ALGO_V1, stretched), 0);
assert_memory_equal(stretched, _expected_stretched_out_v1, sizeof(_expected_stretched_out_v1));
// Counter & threshold of password counter. After init, it is at 1, but the threshold is
@@ -835,7 +836,7 @@ static void test_optiga_password_v1_stretch_exhaust_fails_after_init(void** stat
// Exhaust all attempts.
for (int i = 1; i <= SMALL_MONOTONIC_COUNTER_MAX_USE; i++) {
assert_int_equal(
- optiga_stretch_password("wrong", MEMORY_PASSWORD_STRETCH_ALGO_V1, stretched),
+ optiga_stretch_password("wrong", SECURECHIP_PASSWORD_STRETCH_ALGO_V1, stretched),
SC_ERR_INCORRECT_PASSWORD);
// Counter & threshold of password counter.
@@ -850,7 +851,7 @@ static void test_optiga_password_v1_stretch_exhaust_fails_after_init(void** stat
// Even a correct password doesn't work.
memset(stretched, 0x00, sizeof(stretched));
assert_int_equal(
- optiga_stretch_password("pw", MEMORY_PASSWORD_STRETCH_ALGO_V1, stretched),
+ optiga_stretch_password("pw", SECURECHIP_PASSWORD_STRETCH_ALGO_V1, stretched),
SC_ERR_INCORRECT_PASSWORD);
uint8_t zero[32] = {0};
assert_memory_equal(stretched, zero, sizeof(stretched));
@@ -864,7 +865,8 @@ static void test_optiga_password_v1(void** state)
_setup_test();
uint8_t stretched[32] = {0};
- assert_int_equal(optiga_init_new_password("pw", MEMORY_PASSWORD_STRETCH_ALGO_V1, stretched), 0);
+ assert_int_equal(
+ optiga_init_new_password("pw", SECURECHIP_PASSWORD_STRETCH_ALGO_V1, stretched), 0);
assert_memory_equal(stretched, _expected_stretched_out_v1, sizeof(_expected_stretched_out_v1));
// Counter & threshold of password counter. After init, it is at 1, but the threshold is
@@ -879,7 +881,7 @@ static void test_optiga_password_v1(void** state)
// A few failed attempts:
for (int i = 1; i <= 2; i++) {
assert_int_equal(
- optiga_stretch_password("wrong", MEMORY_PASSWORD_STRETCH_ALGO_V1, stretched),
+ optiga_stretch_password("wrong", SECURECHIP_PASSWORD_STRETCH_ALGO_V1, stretched),
SC_ERR_INCORRECT_PASSWORD);
// Counter & threshold of password counter.
@@ -893,7 +895,8 @@ static void test_optiga_password_v1(void** state)
// Correct attempt gets the right stretched value and resets counters.
memset(stretched, 0x00, sizeof(stretched));
- assert_int_equal(optiga_stretch_password("pw", MEMORY_PASSWORD_STRETCH_ALGO_V1, stretched), 0);
+ assert_int_equal(
+ optiga_stretch_password("pw", SECURECHIP_PASSWORD_STRETCH_ALGO_V1, stretched), 0);
assert_memory_equal(stretched, _expected_stretched_out_v1, sizeof(_expected_stretched_out_v1));
// Counter & threshold of password counter.
assert_int_equal(_get_counter(OID_COUNTER_PASSWORD), 0);
@@ -907,7 +910,7 @@ static void test_optiga_password_v1(void** state)
// counter/threshold was reset to 0/MAX after the correct stretch attempt.
for (int i = 1; i <= SMALL_MONOTONIC_COUNTER_MAX_USE; i++) {
assert_int_equal(
- optiga_stretch_password("wrong", MEMORY_PASSWORD_STRETCH_ALGO_V1, stretched),
+ optiga_stretch_password("wrong", SECURECHIP_PASSWORD_STRETCH_ALGO_V1, stretched),
SC_ERR_INCORRECT_PASSWORD);
// Counter & threshold of password counter.
@@ -922,7 +925,7 @@ static void test_optiga_password_v1(void** state)
// Even a correct password doesn't work anymore.
memset(stretched, 0x00, sizeof(stretched));
assert_int_equal(
- optiga_stretch_password("pw", MEMORY_PASSWORD_STRETCH_ALGO_V1, stretched),
+ optiga_stretch_password("pw", SECURECHIP_PASSWORD_STRETCH_ALGO_V1, stretched),
SC_ERR_INCORRECT_PASSWORD);
uint8_t zero[32] = {0};
assert_memory_equal(stretched, zero, sizeof(stretched));
Why this scored 17/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.