test: unify unit-test/simulator mocks and fakes into library
What changed, and why it matters
This commit is a pure test-infrastructure refactoring. It merges duplicate mock and fake hardware-implementation files that previously existed separately for unit tests and the simulator into a single shared library called 'hardware-mocks'. It also adjusts Rust build flags so RTT logging only compiles for the real firmware target (target_os='none'). There is no change to the actual device firmware or to any security-critical runtime behavior.
No security action required. Treat as normal build/test maintenance. If reviewing further, verify that the unified hardware-mocks library is only linked into test/simulator targets and not into the cross-compiled firmware binary.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff consolidates duplicated C mock/fake files from test/unit-test/framework and test/simulator/framework into a new test/hardware-mocks static library. CMakeLists are updated to build that library, link it into both unit-test and simulator targets, and remove the old per-target mock sources. The Rust side changes cfg(feature=’rtt’) to cfg(all(feature=’rtt’, target_os=’none’)) so RTT code is excluded from host test/simulator builds, and the bitbox02/build.rs linker script is removed in favor of passing linker flags via RUSTFLAGS_TESTS. The deleted eh_personality.c stubs are no longer needed because Rust c-unit-tests now build with -Zbuild-std. No production firmware source files are modified.
Changed components
test/hardware-mocks (new shared test library)test/unit-test/CMakeLists.txttest/simulator/CMakeLists.txtCMakeLists.txtsrc/CMakeLists.txtsrc/rust/bitbox02-rust-c/src/lib.rssrc/rust/bitbox02-sys/build.rssrc/rust/util/src/log.rsInspect captured patch +1151 / −1639
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 26bb85d..8d6c131 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -350,6 +350,14 @@ if (PROTOC STREQUAL "PROTOC-NOTFOUND")
message(FATAL_ERROR "Could not find 'protoc'.")
endif()
+# We use FindPkgConfig instead of FindPackage because it finds libraries in
+# both linux and macos
+find_package(PkgConfig REQUIRED)
+
+# Unit testing uses CMocka (rust unit testing is in `src`, which is why we load
+# it already here.)
+pkg_check_modules(CMOCKA REQUIRED cmocka)
+
#-----------------------------------------------------------------------------
# Build
@@ -389,6 +397,7 @@ if(CMAKE_CROSSCOMPILING)
add_dependencies(doc rust-docs)
else()
include(CTest)
+ add_subdirectory(test/hardware-mocks)
add_subdirectory(test/unit-test)
add_subdirectory(test/simulator)
if(COVERAGE)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6307d1c..a2676e5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -277,6 +277,8 @@ add_custom_target(rust-cbindgen
# Test rust crates that contain business logic. Avoid testing crates that depend on hardware.
if(NOT CMAKE_CROSSCOMPILING)
+ set(RUSTFLAGS_TESTS ${RUSTFLAGS} -L${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} ${CMOCKA_LDFLAGS} -lbitbox_merged -lwallycore -lsecp256k1 -lfatfs -lhardware-mocks)
+
# Since we build with all features we need to use a separate build directory.
# Otherwise we invalidate the result from the normal compilation that uses a
# different set of features.
@@ -286,14 +288,12 @@ if(NOT CMAKE_CROSSCOMPILING)
CMAKE_SYSROOT=${CMAKE_SYSROOT}
CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
FIRMWARE_VERSION_SHORT=${FIRMWARE_VERSION}
+ RUSTFLAGS="${RUSTFLAGS_TESTS}"
# only one test thread because of unsafe concurrent access to `SafeData`, `mock_sd()` and `mock_memory()`. Using mutexes instead leads to mutex poisoning and very messy output in case of a unit test failure.
${CARGO} test $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-v> --all-features --target-dir ${RUST_BINARY_DIR}/all-features ${RUST_CARGO_FLAGS} -- --nocapture --test-threads 1
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/rust/
)
- add_dependencies(rust-test generate-protobufs)
- if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
- add_dependencies(rust-test bitbox_merged)
- endif()
+ add_dependencies(rust-test generate-protobufs bitbox_merged libwally-core fatfs)
add_custom_target(rust-clippy
COMMAND
@@ -379,6 +379,11 @@ endif()
# * firmware-btc_rust_c
# * factory-setup_rust_c
foreach(type ${RUST_LIBS})
+ # We build the rust standard libs so that everything from the rust runtime
+ # is included (like eh_personality).
+ if(type STREQUAL "c-unit-tests")
+ set(RUST_CARGO_FLAGS ${RUST_CARGO_FLAGS} -Zbuild-std)
+ endif()
set(lib ${RUST_BINARY_DIR}/feature-${type}/${RUST_TARGET_ARCH_DIR}/${RUST_PROFILE}/libbitbox02_rust_c.a)
# The dummy output is to always trigger rebuild (cargo is clever enough to
# only rebuild if something changed)
diff --git a/src/rust/bitbox02-rust-c/src/lib.rs b/src/rust/bitbox02-rust-c/src/lib.rs
index 222f71a..9b44817 100644
--- a/src/rust/bitbox02-rust-c/src/lib.rs
+++ b/src/rust/bitbox02-rust-c/src/lib.rs
@@ -69,9 +69,9 @@ pub extern "C" fn rust_rtt_flush() {
///
/// The pointer `ptr` must point to a null terminated string
#[no_mangle]
-#[cfg_attr(not(feature = "rtt"), allow(unused))]
+#[cfg_attr(not(all(feature = "rtt", target_os = "none")), allow(unused))]
pub unsafe extern "C" fn rust_log(ptr: *const ::util::c_types::c_char) {
- #[cfg(feature = "rtt")]
+ #[cfg(all(feature = "rtt", target_os = "none"))]
{
if ptr.is_null() {
panic!("`ptr` must be a valid pointer");
@@ -143,9 +143,9 @@ pub unsafe extern "C" fn rust_secp256k1_get_private_key(
/// The pointer `data` must point to a buffer of length `len`.
#[no_mangle]
#[allow(static_mut_refs)]
-#[cfg_attr(not(feature = "rtt"), allow(unused))]
+#[cfg_attr(not(all(feature = "rtt", target_os = "none")), allow(unused))]
pub unsafe extern "C" fn rust_rtt_ch1_write(data: *const u8, len: usize) {
- #[cfg(feature = "rtt")]
+ #[cfg(all(feature = "rtt", target_os = "none"))]
{
let buf = unsafe { core::slice::from_raw_parts(data, len) };
let channel = unsafe { ::util::log::CH1_UP.as_mut().unwrap() };
@@ -161,14 +161,14 @@ pub unsafe extern "C" fn rust_rtt_ch1_write(data: *const u8, len: usize) {
/// The pointer `data` must point to a buffer of length `len`.
#[no_mangle]
#[allow(static_mut_refs)]
-#[cfg_attr(not(feature = "rtt"), allow(unused))]
+#[cfg_attr(not(all(feature = "rtt", target_os = "none")), allow(unused))]
pub unsafe extern "C" fn rust_rtt_ch0_read(data: *mut u8, len: usize) -> usize {
- #[cfg(feature = "rtt")]
+ #[cfg(all(feature = "rtt", target_os = "none"))]
{
let buf = unsafe { core::slice::from_raw_parts_mut(data, len) };
let channel = unsafe { ::util::log::CH0_DOWN.as_mut().unwrap() };
channel.read(buf)
}
- #[cfg(not(feature = "rtt"))]
+ #[cfg(not(all(feature = "rtt", target_os = "none")))]
0
}
diff --git a/src/rust/bitbox02-sys/build.rs b/src/rust/bitbox02-sys/build.rs
index 20e0757..c2ac455 100644
--- a/src/rust/bitbox02-sys/build.rs
+++ b/src/rust/bitbox02-sys/build.rs
@@ -257,7 +257,7 @@ pub fn main() -> Result<(), &'static str> {
]);
} else {
// unit test framework includes
- includes.push("../../../test/unit-test/framework/includes")
+ includes.push("../../../test/hardware-mocks/include")
}
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs");
diff --git a/src/rust/bitbox02/build.rs b/src/rust/bitbox02/build.rs
deleted file mode 100644
index 478f73e..0000000
--- a/src/rust/bitbox02/build.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-fn main() {
- #[cfg(feature = "testing")]
- {
- if let Ok(cmake_dir) = std::env::var("CMAKE_CURRENT_BINARY_DIR") {
- println!("cargo::rustc-link-search={}/../lib", cmake_dir);
- // c and rust code merged :O
- println!("cargo::rustc-link-lib=bitbox_merged");
- println!(
- "cargo::rerun-if-changed={}/../lib/libbitbox_merged.a",
- cmake_dir
- );
- println!("cargo::rerun-if-changed=build.rs");
-
- // external libs
- println!("cargo::rustc-link-lib=wallycore");
- println!("cargo::rustc-link-lib=secp256k1");
- println!("cargo::rustc-link-lib=fatfs");
- println!("cargo::rustc-link-lib=sd-mock");
-
- // system libs
- println!("cargo::rustc-link-lib=cmocka");
- } else {
- // This is useful in case project is built by tool that doesn't need to link the final
- // target, like rust-analyzer and clippy.
- println!(
- "cargo::warning=Missing env variable CMAKE_CURRENT_BINARY_DIR, linking will fail"
- );
- }
- }
-}
diff --git a/src/rust/util/src/log.rs b/src/rust/util/src/log.rs
index 6581949..730d869 100644
--- a/src/rust/util/src/log.rs
+++ b/src/rust/util/src/log.rs
@@ -1,5 +1,5 @@
// Re-export rtt_target so that it is available to the macro user
-#[cfg(feature = "rtt")]
+#[cfg(all(feature = "rtt", target_os = "none"))]
pub use ::rtt_target;
/// Macro to log over RTT if `rtt` feature is set, otherwise noop
@@ -11,13 +11,13 @@ macro_rules! log {
// Make log macro usable in crate
pub use log;
-#[cfg(feature = "rtt")]
+#[cfg(all(feature = "rtt", target_os = "none"))]
pub static mut CH1_UP: Option<rtt_target::UpChannel> = None;
-#[cfg(feature = "rtt")]
+#[cfg(all(feature = "rtt", target_os = "none"))]
pub static mut CH0_DOWN: Option<rtt_target::DownChannel> = None;
pub fn rtt_init() {
- #[cfg(feature = "rtt")]
+ #[cfg(all(feature = "rtt", target_os = "none"))]
{
let channels = rtt_target::rtt_init! {
up: {
@@ -56,6 +56,6 @@ pub fn rtt_init() {
/// Wait until all messages have been read by host
pub fn rtt_flush() {
- #[cfg(feature = "rtt")]
+ #[cfg(all(feature = "rtt", target_os = "none"))]
rtt_target::with_terminal_channel(|c| c.flush());
}
diff --git a/test/hardware-mocks/CMakeLists.txt b/test/hardware-mocks/CMakeLists.txt
new file mode 100644
index 0000000..fe0dfa2
--- /dev/null
+++ b/test/hardware-mocks/CMakeLists.txt
@@ -0,0 +1,71 @@
+# Copyright 2024 Shift Cryptosecurity AG
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter -Wno-missing-prototypes -Wno-missing-declarations -Wno-implicit-function-declaration -Wno-bad-function-cast")
+
+set(HARDWARE-MOCKS-SOURCES
+ src/mock_cipher.c
+ src/mock_diskio.c
+ src/mock_memory.c
+ src/mock_screen.c
+ src/mock_securechip.c
+ src/mock_smarteeprom.c
+ src/mock_spi_mem.c
+ src/mock_component.c
+ src/mock_delay.c
+ src/mock_gestures.c
+ src/mock_qtouch.c
+ src/mock_screen_stack.c
+)
+
+add_library(hardware-mocks
+ STATIC
+ ${HARDWARE-MOCKS-SOURCES}
+)
+
+add_dependencies(hardware-mocks rust-cbindgen)
+
+target_compile_definitions(hardware-mocks PUBLIC
+ TESTING
+ _UNIT_TEST_
+ PRODUCT_BITBOX_MULTI=1
+ APP_BTC=1
+ APP_LTC=1
+ APP_U2F=1
+ APP_ETH=1
+)
+
+target_include_directories(
+ hardware-mocks
+ PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+)
+target_include_directories(
+ hardware-mocks
+ PRIVATE
+ ${INCLUDES}
+ ${CMAKE_BINARY_DIR}/src
+ ${CMOCKA_INCLUDE_DIRS}
+ $<TARGET_PROPERTY:fatfs,INTERFACE_INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:wallycore,INTERFACE_INCLUDE_DIRECTORIES>
+)
+
+target_link_libraries(hardware-mocks PUBLIC wallycore ${CMOCKA_LDFLAGS})
+
+if(SANITIZE_ADDRESS)
+ target_compile_options(hardware-mocks PUBLIC "-fsanitize=address")
+endif()
+if(SANTIZE_UNDEFINED)
+ target_compile_options(hardware-mocks PUBLIC "-fsanitize=undefined")
+endif()
diff --git a/test/hardware-mocks/README.md b/test/hardware-mocks/README.md
new file mode 100644
index 0000000..7682ded
--- /dev/null
+++ b/test/hardware-mocks/README.md
@@ -0,0 +1,6 @@
+# Hardware mocks and fakes
+
+This library is used for c unit tests and the c simulator.
+
+Some of the files depend on cmocka to provide mocks. Some of the files are only
+fakes.
diff --git a/test/hardware-mocks/include/mock_cipher.h b/test/hardware-mocks/include/mock_cipher.h
new file mode 100644
index 0000000..8c73acd
--- /dev/null
+++ b/test/hardware-mocks/include/mock_cipher.h
@@ -0,0 +1,22 @@
+// Copyright 2023 Shift Crypto AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _MOCK_CIPHER_H_
+#define _MOCK_CIPHER_H_
+
+#include <stdint.h>
+
+void cipher_mock_iv(uint8_t* iv_out);
+
+#endif
diff --git a/test/hardware-mocks/include/mock_component.h b/test/hardware-mocks/include/mock_component.h
new file mode 100644
index 0000000..db863fb
--- /dev/null
+++ b/test/hardware-mocks/include/mock_component.h
@@ -0,0 +1,30 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _MOCK_COMPONENT_H_
+#define _MOCK_COMPONENT_H_
+
+#include <ui/component.h>
+
+/********************************** Create Instance **********************************/
+
+/**
+ * Creates a label with the given font either upside down or normal.
+ * @param[in] text The text of the label.
+ * @param[in] upside_down Whether the text should be rotated 180 degree or not.
+ * @param[in] font The font of the label.
+ */
+component_t* mock_component_create(void);
+
+#endif
diff --git a/test/hardware-mocks/include/mock_dap.h b/test/hardware-mocks/include/mock_dap.h
new file mode 100644
index 0000000..bcab573
--- /dev/null
+++ b/test/hardware-mocks/include/mock_dap.h
@@ -0,0 +1,37 @@
+// Copyright 2025 Shift Crypto AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef MOCK_DAP_H
+#define MOCK_DAP_H
+#include <stdbool.h>
+#include <stdint.h>
+
+void dap_init(void);
+void dap_connect(void);
+void dap_disconnect(void);
+uint32_t dap_read_word(uint32_t addr);
+uint16_t dap_read_hword(uint32_t addr);
+void dap_write_word(uint32_t addr, uint32_t data);
+void dap_write_hword(uint32_t addr, uint16_t data);
+void dap_reset_link(void);
+uint32_t dap_read_idcode(void);
+bool dap_target_prepare(int32_t timeout);
+
+// Target operations
+void dap_target_select(void);
+void dap_target_deselect(void);
+void dap_target_erase(void);
+void dap_target_lock(void);
+void dap_target_erase_row(uint32_t addr);
+#endif
diff --git a/test/hardware-mocks/include/mock_gestures.h b/test/hardware-mocks/include/mock_gestures.h
new file mode 100644
index 0000000..76c7364
--- /dev/null
+++ b/test/hardware-mocks/include/mock_gestures.h
@@ -0,0 +1,44 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _MOCK_GESTURES_H_
+#define _MOCK_GESTURES_H_
+
+#include <screen.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <touch/gestures.h>
+
+/**
+ * Mocks the sensors for sliding and tap or hold detection.
+ * The flag 'expect_slide_detection' indicates whether the caller expects that the mocked gesture
+ * detection returns after detecting a slide gesture. This flag needs to be set to false if the
+ * caller requires mocking of the sensor node signal and sensor node reference driver functions.
+ * @param[in] screen_position The position at which the touch slider was touched (between 0 and
+ * 255).
+ */
+void mock_gestures_touch(slider_location_t location, uint8_t screen_position);
+
+/**
+ * Mocks the sensors for slider release detection.
+ */
+void mock_gestures_touch_release(void);
+
+/**
+ * Initializes the touch detection by resetting the detection history.
+ */
+void mock_gestures_touch_init(void);
+
+#endif
diff --git a/test/hardware-mocks/include/mock_memory.h b/test/hardware-mocks/include/mock_memory.h
new file mode 100644
index 0000000..b050aad
--- /dev/null
+++ b/test/hardware-mocks/include/mock_memory.h
@@ -0,0 +1,32 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _MOCK_MEMORY_H_
+#define _MOCK_MEMORY_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <flags.h>
+
+void mock_memory_factoryreset(void);
+bool memory_write_to_address_mock(uint32_t base, uint32_t addr, const uint8_t* chunk);
+bool memory_write_chunk_mock(uint32_t chunk_num, const uint8_t* chunk);
+void memory_read_chunk_mock(uint32_t chunk_num, uint8_t* chunk_out);
+// Size: `FLASH_SHARED_DATA_LEN`.
+void memory_read_shared_bootdata_mock(uint8_t* chunk_out);
+void mock_memory_set_salt_root(const uint8_t* salt_root);
+void memory_bootloader_hash_mock(uint8_t* hash_out);
+void memory_set_bootloader_hash_mock(const uint8_t* mock_hash);
+#endif
diff --git a/test/hardware-mocks/include/mock_qtouch.h b/test/hardware-mocks/include/mock_qtouch.h
new file mode 100644
index 0000000..eff3c10
--- /dev/null
+++ b/test/hardware-mocks/include/mock_qtouch.h
@@ -0,0 +1,34 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _QTOUCH_H_
+#define _QTOUCH_H_
+
+#include <stdint.h>
+
+void __wrap_qtouch_process(void);
+
+uint8_t __wrap_qtouch_get_scroller_is_active(uint16_t sensor_node);
+
+uint16_t __wrap_qtouch_get_scroller_position(uint16_t sensor_node);
+
+void qtouch_process(void);
+
+uint8_t qtouch_is_scroller_active(uint16_t sensor_node);
+
+uint16_t qtouch_get_scroller_position(uint16_t sensor_node);
+
+void qtouch_force_calibrate(void);
+
+#endif
diff --git a/test/hardware-mocks/include/mock_screen_stack.h b/test/hardware-mocks/include/mock_screen_stack.h
new file mode 100644
index 0000000..ab91907
--- /dev/null
+++ b/test/hardware-mocks/include/mock_screen_stack.h
@@ -0,0 +1,19 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _TEST_SCREEN_STACK_H
+#define _TEST_SCREEN_STACK_H
+
+void mock_screen_stack_assert_clean(void);
+#endif
diff --git a/test/hardware-mocks/include/mock_uart.h b/test/hardware-mocks/include/mock_uart.h
new file mode 100644
index 0000000..2913ecf
--- /dev/null
+++ b/test/hardware-mocks/include/mock_uart.h
@@ -0,0 +1,13 @@
+// Copyright 2025 Shift Crypto AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
diff --git a/test/hardware-mocks/include/test_random.h b/test/hardware-mocks/include/test_random.h
new file mode 100644
index 0000000..e32bd87
--- /dev/null
+++ b/test/hardware-mocks/include/test_random.h
@@ -0,0 +1,21 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef _TEST_RANDOM_H
+#define _TEST_RANDOM_H
+
+int __wrap_rand(void);
+int __wrap_rust_sha256(const unsigned char* data, size_t len, unsigned char* out);
+
+#endif
diff --git a/test/hardware-mocks/src/mock_cipher.c b/test/hardware-mocks/src/mock_cipher.c
new file mode 100644
index 0000000..a18c3b3
--- /dev/null
+++ b/test/hardware-mocks/src/mock_cipher.c
@@ -0,0 +1,22 @@
+// Copyright 2023 Shift Crypto AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string.h>
+
+#include <mock_cipher.h>
+
+void cipher_mock_iv(uint8_t* iv_out)
+{
+ memset(iv_out, 'a', 32);
+}
diff --git a/test/hardware-mocks/src/mock_component.c b/test/hardware-mocks/src/mock_component.c
new file mode 100644
index 0000000..09cfdc8
--- /dev/null
+++ b/test/hardware-mocks/src/mock_component.c
@@ -0,0 +1,53 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string.h>
+
+#include <screen.h>
+#include <stdlib.h>
+#include <ui/ui_util.h>
+
+#include "mock_component.h"
+
+/********************************** Label Functions **********************************/
+
+/**
+ * Collects all component functions.
+ */
+static const component_functions_t MOCK_COMPONENT_FUNCTIONS = {
+ .cleanup = ui_util_component_cleanup,
+ .render = ui_util_component_render_subcomponents,
+ .on_event = ui_util_on_event_noop};
+
+/********************************** Create Instance **********************************/
+
+/**
+ * Creates a label with the given font either upside down or normal.
+ * @param[in] text The text of the label.
+ * @param[in] upside_down Whether the text should be rotated 180 degree or not.
+ * @param[in] font The font of the label.
+ */
+component_t* mock_component_create(void)
+{
+ component_t* mock = malloc(sizeof(component_t));
+ memset(mock, 0, sizeof(component_t));
+ mock->f = &MOCK_COMPONENT_FUNCTIONS;
+
+ mock->dimension.width = SCREEN_WIDTH;
+ mock->dimension.height = SCREEN_HEIGHT;
+ mock->position.left = 0;
+ mock->position.top = 0;
+
+ return mock;
+}
diff --git a/test/hardware-mocks/src/mock_delay.c b/test/hardware-mocks/src/mock_delay.c
new file mode 100644
index 0000000..e539f5b
--- /dev/null
+++ b/test/hardware-mocks/src/mock_delay.c
@@ -0,0 +1,26 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stdint.h>
+#include <unistd.h>
+
+void delay_ms(const uint16_t ms)
+{
+ usleep(1000 * ms);
+}
+
+void delay_us(const uint16_t us)
+{
+ usleep(us);
+}
diff --git a/test/hardware-mocks/src/mock_diskio.c b/test/hardware-mocks/src/mock_diskio.c
new file mode 100644
index 0000000..bb2fc7f
--- /dev/null
+++ b/test/hardware-mocks/src/mock_diskio.c
@@ -0,0 +1,82 @@
+// Copyright 2021 Shift Crypto AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stdint.h>
+#include <string.h>
+
+// Must be included before diskio.h, see http://elm-chan.org/fsw/ff/bd/?show=3626
+#include <ff.h>
+
+#include <diskio.h>
+
+// This file is the disk middleware for use in tests, replacing sdmmc_diskio.c used in the firmware
+// to write to microSD cards.
+//
+// It writes and reads from RAM instead of to a card or disk so that unit tests can exercise all
+// sd-card related functionality.
+
+// 100mb with 512 bytes per sector
+#define SECTOR_SIZE 512
+#define SECTOR_COUNT 204800
+static uint8_t _data[SECTOR_SIZE * SECTOR_COUNT] = {0};
+
+DSTATUS disk_initialize(uint8_t drv)
+{
+ (void)drv;
+ return 0;
+}
+
+DSTATUS disk_status(uint8_t drv)
+{
+ (void)drv;
+ return 0;
+}
+
+DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count)
+{
+ (void)pdrv;
+ for (UINT i = 0; i < count; i++) {
+ memcpy(&buff[SECTOR_SIZE * i], &_data[SECTOR_SIZE * sector + SECTOR_SIZE * i], SECTOR_SIZE);
+ }
+ return RES_OK;
+}
+
+DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count)
+{
+ for (UINT i = 0; i < count; i++) {
+ memcpy(&_data[SECTOR_SIZE * sector + SECTOR_SIZE * i], &buff[SECTOR_SIZE * i], SECTOR_SIZE);
+ }
+ return RES_OK;
+}
+
+DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff)
+{
+ (void)pdrv;
+ switch (cmd) {
+ case CTRL_SYNC:
+ // Already synced (RAM).
+ return RES_OK;
+ case GET_BLOCK_SIZE:
+ *(DWORD*)buff = 1;
+ return RES_OK;
+ case GET_SECTOR_SIZE:
+ *(LBA_t*)buff = SECTOR_SIZE;
+ return RES_OK;
+ case GET_SECTOR_COUNT:
+ *(LBA_t*)buff = SECTOR_COUNT;
+ return RES_OK;
+ default:
+ return RES_PARERR;
+ }
+}
diff --git a/test/hardware-mocks/src/mock_gestures.c b/test/hardware-mocks/src/mock_gestures.c
new file mode 100644
index 0000000..47c25e5
--- /dev/null
+++ b/test/hardware-mocks/src/mock_gestures.c
@@ -0,0 +1,86 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <cmocka.h>
+
+#include "mock_gestures.h"
+#include "mock_qtouch.h"
+#include <util.h>
+
+#define MEASUREMENT_PERIOD 125
+
+static bool gestures_history_reset = false;
+
+/********************************** POSITIONING **********************************/
+
+/**
+ * Converts the screen position into the slider position.
+ */
+// TODO: clean up eventually. This is copied form gestures.c
+static uint16_t _screen_to_slider_position(uint8_t screen_position)
+{
+ uint16_t slider_position = ((float)screen_position / (float)SCREEN_WIDTH) * MAX_SLIDER_POS;
+ return slider_position;
+}
+
+/**
+ * Mocks the sensors for sliding and tap or hold detection.
+ * The flag 'expect_slide_detection' indicates whether the caller expects that the mocked gesture
+ * detection returns after detecting a slide gesture. This flag needs to be set to false if the
+ * caller requires mocking of the sensor node signal and sensor node reference driver functions.
+ * @param[in] pos The position at which the touch slider was touched (between 0 and 255).
+ */
+void mock_gestures_touch(slider_location_t location, uint8_t screen_position)
+{
+ for (int j = 0; j < MEASUREMENT_PERIOD; j++) {
+ for (int i = 0; i < TOUCH_NUM_SLIDERS; i++) {
+ if (i == location) {
+ will_return(qtouch_is_scroller_active, 129);
+ uint8_t measured_position = _screen_to_slider_position(screen_position);
+ if (location == bottom_slider) {
+ measured_position = MAX_SLIDER_POS - measured_position;
+ }
+ will_return(qtouch_get_scroller_position, measured_position);
+ } else {
+ will_return(qtouch_is_scroller_active, 0);
+ }
+ }
+ gestures_detect(gestures_history_reset, true);
+ gestures_history_reset = false;
+ }
+}
+
+/**
+ * Mocks the sensors for slider release detection.
+ */
+void mock_gestures_touch_release(void)
+{
+ for (int i = 0; i < TOUCH_NUM_SLIDERS; i++) {
+ will_return(qtouch_is_scroller_active, 0);
+ }
+ gestures_detect(gestures_history_reset, true);
+ gestures_history_reset = false;
+}
+
+/**
+ * Initializes the touch detection by resetting the detection history.
+ */
+void mock_gestures_touch_init(void)
+{
+ gestures_history_reset = true;
+}
diff --git a/test/hardware-mocks/src/mock_memory.c b/test/hardware-mocks/src/mock_memory.c
new file mode 100644
index 0000000..559c6f9
--- /dev/null
+++ b/test/hardware-mocks/src/mock_memory.c
@@ -0,0 +1,150 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <cmocka.h>
+
+#include <flags.h>
+#include <memory/memory.h>
+#include <mock_memory.h>
+#include <stdio.h>
+#include <string.h>
+
+static uint8_t _memory_shared_data[FLASH_SHARED_DATA_LEN] = {0};
+static uint8_t _memory_app_data[FLASH_APPDATA_LEN] = {0};
+static uint8_t _memory_smarteeprom[SMARTEEPROM_RESERVED_FLASH_PAGES * FLASH_PAGE_SIZE] = {0};
+
+void mock_memory_factoryreset(void)
+{
+ memset(_memory_shared_data, 0xff, sizeof(_memory_shared_data));
+ memset(_memory_app_data, 0xff, sizeof(_memory_app_data));
+ memset(_memory_smarteeprom, 0xff, sizeof(_memory_smarteeprom));
+}
+
+static uint8_t* _get_memory(uint32_t base)
+{
+ switch (base) {
+ case FLASH_SHARED_DATA_START:
+ return _memory_shared_data;
+ case FLASH_APPDATA_START:
+ return _memory_app_data;
+ case FLASH_SMARTEEPROM_START:
+ return _memory_smarteeprom;
+ default:
+ return NULL;
+ }
+}
+
+bool memory_write_to_address_mock(uint32_t base, uint32_t addr, const uint8_t* chunk)
+{
+ if (chunk == NULL) {
+ memset(_get_memory(base) + addr, 0xff, (size_t)CHUNK_SIZE);
+ } else {
+ memcpy(_get_memory(base) + addr, chunk, (size_t)CHUNK_SIZE);
+ }
+ return true;
+}
+
+bool memory_write_chunk_mock(uint32_t chunk_num, const uint8_t* chunk)
+{
+ return memory_write_to_address_mock(FLASH_APPDATA_START, chunk_num * (size_t)CHUNK_SIZE, chunk);
+}
+
+void memory_read_chunk_mock(uint32_t chunk_num, uint8_t* chunk_out)
+{
+ memcpy(chunk_out, _memory_app_data + chunk_num * (size_t)CHUNK_SIZE, (size_t)CHUNK_SIZE);
+}
+
+void memory_read_shared_bootdata_mock(uint8_t* chunk_out)
+{
+ memcpy(chunk_out, _memory_shared_data, (size_t)FLASH_SHARED_DATA_LEN);
+}
+
+bool __wrap_memory_is_initialized(void)
+{
+ return mock();
+}
+
+bool __wrap_memory_is_seeded(void)
+{
+ return mock();
+}
+
+static uint8_t _encrypted_seed_and_hmac[96];
+static uint8_t _encrypted_seed_and_hmac_len;
+
+bool __wrap_memory_set_encrypted_seed_and_hmac(uint8_t* encrypted_seed_and_hmac, uint8_t len)
+{
+ memcpy(_encrypted_seed_and_hmac, encrypted_seed_and_hmac, len);
+ _encrypted_seed_and_hmac_len = len;
+ return true;
+}
+
+bool __wrap_memory_get_encrypted_seed_and_hmac(
+ uint8_t* encrypted_seed_and_hmac_out,
+ uint8_t* len_out)
+{
+ *len_out = _encrypted_seed_and_hmac_len;
+ memcpy(encrypted_seed_and_hmac_out, _encrypted_seed_and_hmac, *len_out);
+ return true;
+}
+
+void __wrap_memory_get_device_name(char* name_out)
+{
+ snprintf(name_out, MEMORY_DEVICE_NAME_MAX_LEN, "%s", (const char*)mock());
+}
+
+bool __wrap_memory_set_device_name(const char* name)
+{
+ return mock();
+}
+
+bool __wrap_memory_set_mnemonic_passphrase_enabled(bool enabled)
+{
+ check_expected(enabled);
+ return mock();
+}
+
+static uint8_t _salt_root[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+};
+void mock_memory_set_salt_root(const uint8_t* salt_root)
+{
+ memcpy(_salt_root, salt_root, 32);
+}
+bool __wrap_memory_get_salt_root(uint8_t* salt_root_out)
+{
+ memcpy(salt_root_out, _salt_root, 32);
+ return true;
+}
+
+// Arbitrary value.
+static uint8_t _bootloader_hash[32] =
+ "\x71\x3d\xf0\xd5\x8c\x71\x7d\x40\x31\x78\x7c\xdc\x8f\xa3\x5b\x90\x25\x82\xbe\x6a\xb6\xa2\x2e"
+ "\x09\xde\x44\x77\xd3\x0e\x22\x30\xfc";
+
+void memory_bootloader_hash_mock(uint8_t* hash_out)
+{
+ memcpy(hash_out, _bootloader_hash, 32);
+}
+
+void memory_set_bootloader_hash_mock(const uint8_t* mock_hash)
+{
+ // NOLINTNEXTLINE(bugprone-not-null-terminated-result)
+ memcpy(_bootloader_hash, mock_hash, sizeof(_bootloader_hash));
+}
diff --git a/test/hardware-mocks/src/mock_qtouch.c b/test/hardware-mocks/src/mock_qtouch.c
new file mode 100644
index 0000000..58772d9
--- /dev/null
+++ b/test/hardware-mocks/src/mock_qtouch.c
@@ -0,0 +1,37 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <cmocka.h>
+
+#include "mock_qtouch.h"
+
+volatile bool measurement_done_touch = true;
+
+uint8_t qtouch_is_scroller_active(uint16_t sensor_node)
+{
+ return (uint8_t)mock();
+}
+
+uint16_t qtouch_get_scroller_position(uint16_t sensor_node)
+{
+ return (uint16_t)mock();
+}
+
+void qtouch_process(void) {}
+
+void qtouch_force_calibrate(void) {}
diff --git a/test/hardware-mocks/src/mock_screen.c b/test/hardware-mocks/src/mock_screen.c
new file mode 100644
index 0000000..45d81ca
--- /dev/null
+++ b/test/hardware-mocks/src/mock_screen.c
@@ -0,0 +1,46 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <screen.h>
+
+UG_COLOR screen_front_color = C_WHITE;
+UG_COLOR screen_back_color = C_BLACK;
+
+slider_location_t top_slider = 1;
+slider_location_t bottom_slider = 0;
+
+void screen_print_debug(const char* message, int duration)
+{
+ printf("%s\n", message);
+}
+
+void screen_splash(void)
+{
+ puts("screen splash\n");
+}
+
+void screen_rotate(void) {}
+
+bool screen_is_upside_down(void)
+{
+ return false;
+}
+
+void screen_clear(void) {}
diff --git a/test/hardware-mocks/src/mock_screen_stack.c b/test/hardware-mocks/src/mock_screen_stack.c
new file mode 100644
index 0000000..31ff935
--- /dev/null
+++ b/test/hardware-mocks/src/mock_screen_stack.c
@@ -0,0 +1,38 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <cmocka.h>
+
+#include <ui/screen_stack.h>
+
+static int _stack_counter = 0;
+void __wrap_ui_screen_stack_push(component_t* component)
+{
+ _stack_counter++;
+ check_expected(component);
+}
+
+void __wrap_ui_screen_stack_pop(void)
+{
+ _stack_counter--;
+ assert_true(_stack_counter >= 0);
+}
+
+void mock_screen_stack_assert_clean(void)
+{
+ assert_int_equal(_stack_counter, 0);
+}
diff --git a/test/hardware-mocks/src/mock_securechip.c b/test/hardware-mocks/src/mock_securechip.c
new file mode 100644
index 0000000..1a5e141
--- /dev/null
+++ b/test/hardware-mocks/src/mock_securechip.c
@@ -0,0 +1,88 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <cmocka.h>
+
+#include <salt.h>
+#include <securechip/securechip.h>
+#include <stdio.h>
+#include <string.h>
+#include <wally_crypto.h>
+
+static uint32_t _u2f_counter;
+
+// Mocked contents of the secure chip rollkey slot.
+static const uint8_t _rollkey[32] =
+ "\x9d\xd1\x34\x1f\x6b\x4b\x26\xb1\x72\x89\xa1\xa3\x92\x71\x5c\xf0\xd0\x57\x8c\x84\xdb\x9a\x51"
+ "\xeb\xde\x14\x24\x06\x69\xd1\xd0\x5e";
+
+// Mocked contents of the securechip kdf slot.
+static const uint8_t _kdfkey[32] =
+ "\xd2\xe1\xe6\xb1\x8b\x6c\x6b\x08\x43\x3e\xdb\xc1\xd1\x68\xc1\xa0\x04\x37\x74\xa4\x22\x18\x77"
+ "\xe7\x9e\xd5\x66\x84\xbe\x5a\xc0\x1b";
+
+int securechip_kdf(const uint8_t* msg, size_t len, uint8_t* kdf_out)
+{
+ wally_hmac_sha256(_kdfkey, 32, msg, len, kdf_out, 32);
+ return 0;
+}
+int securechip_kdf_rollkey(const uint8_t* msg, size_t len, uint8_t* kdf_out)
+{
+ wally_hmac_sha256(_rollkey, 32, msg, len, kdf_out, 32);
+ return 0;
+}
+int securechip_init_new_password(const char* password)
+{
+ (void)password;
+ return 0;
+}
+int securechip_stretch_password(const char* password, uint8_t* stretched_out)
+{
+ uint8_t key[9] = "unit-test";
+ wally_hmac_sha256(
+ key, sizeof(key), (const uint8_t*)password, strlen(password), stretched_out, 32);
+ return 0;
+}
+bool securechip_u2f_counter_set(uint32_t counter)
+{
+ _u2f_counter = counter;
+ return true;
+}
+
+bool securechip_u2f_counter_inc(uint32_t* counter)
+{
+ *counter = _u2f_counter++;
+ return true;
+}
+
+bool securechip_attestation_sign(const uint8_t* msg, uint8_t* signature_out)
+{
+ return false;
+}
+
+bool securechip_monotonic_increments_remaining(uint32_t* remaining_out)
+{
+ *remaining_out = 1;
+ return true;
+}
+
+bool securechip_model(securechip_model_t* model_out)
+{
+ *model_out = ATECC_ATECC608B;
+ return true;
+}
diff --git a/test/hardware-mocks/src/mock_smarteeprom.c b/test/hardware-mocks/src/mock_smarteeprom.c
new file mode 100644
index 0000000..b5cf2ce
--- /dev/null
+++ b/test/hardware-mocks/src/mock_smarteeprom.c
@@ -0,0 +1,101 @@
+// Copyright 2019 Shift Cryptosecurity AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * Mock for the SmartEEPROM functions.
+ */
+#include <memory/smarteeprom.h>
+
+#include <assert.h>
+#include <string.h>
+
+static char* _mem_image = NULL;
+static size_t _allocated_space = 0;
+static size_t _enabled = 0;
+
+void smarteeprom_setup(void)
+{
+ /* Allocate an equivalent amount of raw memory */
+ size_t n_virtual_pages = SMARTEEPROM_ALLOCATED_BLOCKS * 8192 / SMARTEEPROM_PAGE_SIZE;
+ /*
+ * The maximum number of virtual pages is limited to 128.
+ * Ref. SAMD5x/E5x Family Data Sheet sec. 25.6.8.3
+ */
+ if (n_virtual_pages > 128) {
+ n_virtual_pages = 128;
+ }
+ _allocated_space = n_virtual_pages * SMARTEEPROM_PAGE_SIZE;
+ _mem_image = malloc(_allocated_space);
+ if (!_mem_image) {
+ abort();
+ }
+ memset(_mem_image, 0xFF, _allocated_space);
+ _enabled = 1;
+}
+
+/**
+ * Reads N contiguous bytes from the SmartEEPROM, starting at
+ * the specified address.
+ *
+ * @param[in] address Start address.
+ * @param[in] size Number of bytes to read.
+ * @param[out] out_buffer Buffer in which to read.
+ * Must be at least size bytes wide.
+ */
+void smarteeprom_read(size_t address, size_t bytes, uint8_t* out_buffer)
+{
+ assert(address + bytes < _allocated_space);
+ assert(_enabled);
+ memcpy(out_buffer, _mem_image + address, bytes);
+}
+
+/**
+ * Writes N contiguous bytes to the SmartEEPROM, starting at
+ * the specified address.
+ *
+ * Note that this will not affect the write endurance of the
+ * underlying memory, unless the content currently stored at
+ * the specified address has some bits that must be flipped from
+ * "0" to "1". Use this wisely!
+ *
+ * @param[in] address Start address.
+ * @param[in] size Number of bytes to write.
+ * @param[in] buffer Buffer from which to read the data.
+ * Must be at least size bytes wide.
+ */
+void smarteeprom_write(size_t address, size_t bytes, const uint8_t* buffer)
+{
+ assert(_allocated_space > bytes && address < _allocated_space - bytes);
+ assert(_enabled);
+ memcpy(_mem_image + address, buffer, bytes);
+}
+
+bool smarteeprom_is_enabled(void)
+{
+ return _enabled;
+}
+
+void smarteeprom_disable(void)
+{
+ _enabled = 0;
+ _allocated_space = 0;
+ free(_mem_image);
+}
+
+void smarteeprom_bb02_config(void)
+{
+ if (!_enabled) {
+ smarteeprom_setup();
+ }
+}
diff --git a/test/hardware-mocks/src/mock_spi_mem.c b/test/hardware-mocks/src/mock_spi_mem.c
new file mode 100644
index 0000000..17c5fde
--- /dev/null
+++ b/test/hardware-mocks/src/mock_spi_mem.c
@@ -0,0 +1,50 @@
+// Copyright 2025 Shift Crypto AG
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <memory/spi_mem.h>
+#include <stdlib.h>
+#include <string.h>
+
+__extension__ static uint8_t _memory[] = {[0 ... SPI_MEM_MEMORY_SIZE] = 0xFF};
+
+bool spi_mem_full_erase(void)
+{
+ memset(_memory, 0xFF, sizeof(_memory));
+ return true;
+}
+
+bool spi_mem_write(uint32_t address, const uint8_t* input, size_t size)
+{
+ memcpy(&_memory[address], input, size);
+ return true;
+}
+
+uint8_t* spi_mem_read(uint32_t address, size_t size)
+{
+ uint8_t* result = (uint8_t*)malloc(size);
+ if (!result) {
+ return NULL;
+ }
+ memcpy(result, &_memory[address], size);
+ return result;
+}
+
+void spi_mem_protected_area_lock(void) {}
+
+void spi_mem_protected_area_unlock(void) {}
+
+bool spi_mem_protected_area_write(uint32_t address, const uint8_t* input, size_t size)
+{
+ return spi_mem_write(address, input, size);
+}
diff --git a/test/simulator/CMakeLists.txt b/test/simulator/CMakeLists.txt
index 45f0881..761b084 100644
--- a/test/simulator/CMakeLists.txt
+++ b/test/simulator/CMakeLists.txt
@@ -44,17 +44,6 @@ endforeach()
message("FILTERED SOURCES: ${DBB-FILTERED-SOURCES}")
-add_library(sd-mock-simulator
- STATIC EXCLUDE_FROM_ALL
- framework/mock_diskio.c
-)
-target_include_directories(
- sd-mock-simulator
- PUBLIC
- $<TARGET_PROPERTY:fatfs,INTERFACE_INCLUDE_DIRECTORIES>
-)
-
-
# We create a CMake "object library" to track all the compiled sources so that
# they can be reused between a normal library and the manually crafted "merged"
# library.
@@ -63,12 +52,6 @@ add_library(bitbox_objects-simulator
OBJECT EXCLUDE_FROM_ALL
${DBB-FILTERED-SOURCES}
${ETHEREUM-SOURCES}
- framework/mock_cipher.c
- framework/mock_memory.c
- framework/mock_spi_mem.c
- framework/mock_screen.c
- framework/mock_smarteeprom.c
- framework/mock_securechip.c
)
add_library(bitbox-simulator
@@ -109,7 +92,6 @@ target_include_directories(
bitbox_objects-simulator
PUBLIC
${INCLUDES}
- ${CMAKE_CURRENT_SOURCE_DIR}/../unit-test/framework/includes
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_BINARY_DIR}/src
)
@@ -129,7 +111,6 @@ target_include_directories(
bitbox-simulator
PUBLIC
${INCLUDES}
- ${CMAKE_CURRENT_SOURCE_DIR}/../unit-test/framework/includes
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_BINARY_DIR}/src
)
@@ -139,8 +120,8 @@ add_dependencies(bitbox_objects-simulator
wallycore
secp256k1
fatfs
- sd-mock-simulator
)
+target_link_libraries(bitbox_objects-simulator PUBLIC hardware-mocks)
target_link_libraries(bitbox-simulator PRIVATE ${LIBBITBOX02_RUST} "-lm")
# _UNIT_TEST_ is used by ASF4 to not cross compile
@@ -160,7 +141,6 @@ target_link_libraries(bitbox-simulator
PRIVATE
wallycore
fatfs
- sd-mock-simulator
)
if(SANITIZE_ADDRESS)
@@ -175,7 +155,7 @@ endif()
#-----------------------------------------------------------------------------
# Simulator
-add_executable(simulator EXCLUDE_FROM_ALL simulator.c framework/eh_personality.c)
+add_executable(simulator EXCLUDE_FROM_ALL simulator.c)
# asan must be first library in linking order
target_link_libraries(simulator PRIVATE
$<$<BOOL:${SANITIZE_ADDRESS}>:asan>
@@ -183,6 +163,8 @@ target_link_libraries(simulator PRIVATE
$<$<NOT:$<PLATFORM_ID:Darwin>>:-Wl,--start-group>
c-unit-tests_rust_c
bitbox-simulator
+ hardware-mocks
+ fatfs
$<$<NOT:$<PLATFORM_ID:Darwin>>:-Wl,--end-group>
""
)
diff --git a/test/simulator/framework/eh_personality.c b/test/simulator/framework/eh_personality.c
deleted file mode 100644
index 04b45c9..0000000
--- a/test/simulator/framework/eh_personality.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2022 Shift Crypto AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Needed to link the simulator executable in /test/simulator, which link to
-// bitbox_merged-simulator. `rust_eh_personality` is provided by Rust when building the firmware or
-// running Rust unit tests.
-void rust_eh_personality(void);
-void rust_eh_personality(void) {}
diff --git a/test/simulator/framework/mock_cipher.c b/test/simulator/framework/mock_cipher.c
deleted file mode 100644
index a18c3b3..0000000
--- a/test/simulator/framework/mock_cipher.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2023 Shift Crypto AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <string.h>
-
-#include <mock_cipher.h>
-
-void cipher_mock_iv(uint8_t* iv_out)
-{
- memset(iv_out, 'a', 32);
-}
diff --git a/test/simulator/framework/mock_diskio.c b/test/simulator/framework/mock_diskio.c
deleted file mode 100644
index bb2fc7f..0000000
--- a/test/simulator/framework/mock_diskio.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2021 Shift Crypto AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <stdint.h>
-#include <string.h>
-
-// Must be included before diskio.h, see http://elm-chan.org/fsw/ff/bd/?show=3626
-#include <ff.h>
-
-#include <diskio.h>
-
-// This file is the disk middleware for use in tests, replacing sdmmc_diskio.c used in the firmware
-// to write to microSD cards.
-//
-// It writes and reads from RAM instead of to a card or disk so that unit tests can exercise all
-// sd-card related functionality.
-
-// 100mb with 512 bytes per sector
-#define SECTOR_SIZE 512
-#define SECTOR_COUNT 204800
-static uint8_t _data[SECTOR_SIZE * SECTOR_COUNT] = {0};
-
-DSTATUS disk_initialize(uint8_t drv)
-{
- (void)drv;
- return 0;
-}
-
-DSTATUS disk_status(uint8_t drv)
-{
- (void)drv;
- return 0;
-}
-
-DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count)
-{
- (void)pdrv;
- for (UINT i = 0; i < count; i++) {
- memcpy(&buff[SECTOR_SIZE * i], &_data[SECTOR_SIZE * sector + SECTOR_SIZE * i], SECTOR_SIZE);
- }
- return RES_OK;
-}
-
-DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count)
-{
- for (UINT i = 0; i < count; i++) {
- memcpy(&_data[SECTOR_SIZE * sector + SECTOR_SIZE * i], &buff[SECTOR_SIZE * i], SECTOR_SIZE);
- }
- return RES_OK;
-}
-
-DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff)
-{
- (void)pdrv;
- switch (cmd) {
- case CTRL_SYNC:
- // Already synced (RAM).
- return RES_OK;
- case GET_BLOCK_SIZE:
- *(DWORD*)buff = 1;
- return RES_OK;
- case GET_SECTOR_SIZE:
- *(LBA_t*)buff = SECTOR_SIZE;
- return RES_OK;
- case GET_SECTOR_COUNT:
- *(LBA_t*)buff = SECTOR_COUNT;
- return RES_OK;
- default:
- return RES_PARERR;
- }
-}
diff --git a/test/simulator/framework/mock_memory.c b/test/simulator/framework/mock_memory.c
deleted file mode 100644
index 2395ee2..0000000
--- a/test/simulator/framework/mock_memory.c
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <setjmp.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-#include <flags.h>
-#include <memory/memory.h>
-#include <mock_memory.h>
-#include <stdio.h>
-#include <string.h>
-
-static uint8_t _memory_shared_data[FLASH_SHARED_DATA_LEN] = {0};
-static uint8_t _memory_app_data[FLASH_APPDATA_LEN] = {0};
-static uint8_t _memory_smarteeprom[SMARTEEPROM_RESERVED_FLASH_PAGES * FLASH_PAGE_SIZE] = {0};
-
-void mock_memory_factoryreset(void)
-{
- memset(_memory_shared_data, 0xff, sizeof(_memory_shared_data));
- memset(_memory_app_data, 0xff, sizeof(_memory_app_data));
- memset(_memory_smarteeprom, 0xff, sizeof(_memory_smarteeprom));
-}
-
-static uint8_t* _get_memory(uint32_t base)
-{
- switch (base) {
- case FLASH_SHARED_DATA_START:
- return _memory_shared_data;
- case FLASH_APPDATA_START:
- return _memory_app_data;
- case FLASH_SMARTEEPROM_START:
- return _memory_smarteeprom;
- default:
- return NULL;
- }
-}
-
-bool memory_write_to_address_mock(uint32_t base, uint32_t addr, const uint8_t* chunk)
-{
- if (chunk == NULL) {
- memset(_get_memory(base) + addr, 0xff, (size_t)CHUNK_SIZE);
- } else {
- memcpy(_get_memory(base) + addr, chunk, (size_t)CHUNK_SIZE);
- }
- return true;
-}
-
-bool memory_write_chunk_mock(uint32_t chunk_num, const uint8_t* chunk)
-{
- return memory_write_to_address_mock(FLASH_APPDATA_START, chunk_num * (size_t)CHUNK_SIZE, chunk);
-}
-
-void memory_read_chunk_mock(uint32_t chunk_num, uint8_t* chunk_out)
-{
- memcpy(chunk_out, _memory_app_data + chunk_num * (size_t)CHUNK_SIZE, (size_t)CHUNK_SIZE);
-}
-
-void memory_read_shared_bootdata_mock(uint8_t* chunk_out)
-{
- memcpy(chunk_out, _memory_shared_data, (size_t)FLASH_SHARED_DATA_LEN);
-}
-
-// Arbitrary value.
-static uint8_t _bootloader_hash[32] =
- "\x71\x3d\xf0\xd5\x8c\x71\x7d\x40\x31\x78\x7c\xdc\x8f\xa3\x5b\x90\x25\x82\xbe\x6a\xb6\xa2\x2e"
- "\x09\xde\x44\x77\xd3\x0e\x22\x30\xfc";
-
-void memory_bootloader_hash_mock(uint8_t* hash_out)
-{
- // NOLINTNEXTLINE(bugprone-not-null-terminated-result)
- memcpy(hash_out, _bootloader_hash, 32);
-}
diff --git a/test/simulator/framework/mock_screen.c b/test/simulator/framework/mock_screen.c
deleted file mode 100644
index 7e0e8fa..0000000
--- a/test/simulator/framework/mock_screen.c
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <screen.h>
-
-UG_COLOR screen_front_color = C_WHITE;
-UG_COLOR screen_back_color = C_BLACK;
-
-slider_location_t top_slider = 1;
-slider_location_t bottom_slider = 0;
-
-void screen_print_debug(const char* message, int duration)
-{
- printf("%s\n", message);
-}
-
-void screen_splash(void)
-{
- puts("screen splash\n");
-}
-
-void screen_rotate(void) {}
-
-bool screen_is_upside_down(void)
-{
- return false;
-}
diff --git a/test/simulator/framework/mock_securechip.c b/test/simulator/framework/mock_securechip.c
deleted file mode 100644
index 4bc0e5c..0000000
--- a/test/simulator/framework/mock_securechip.c
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <setjmp.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-#include <securechip/securechip.h>
-#include <stdio.h>
-#include <string.h>
-#include <wally_crypto.h>
-
-static uint32_t _u2f_counter;
-
-// Mocked contents of the securechip kdf slot.
-static const uint8_t _kdfkey[32] =
- "\xd2\xe1\xe6\xb1\x8b\x6c\x6b\x08\x43\x3e\xdb\xc1\xd1\x68\xc1\xa0\x04\x37\x74\xa4\x22\x18\x77"
- "\xe7\x9e\xd5\x66\x84\xbe\x5a\xc0\x1b";
-
-int securechip_kdf(const uint8_t* msg, size_t len, uint8_t* kdf_out)
-{
- wally_hmac_sha256(_kdfkey, 32, msg, len, kdf_out, 32);
- return 0;
-}
-int securechip_init_new_password(const char* password)
-{
- (void)password;
- return 0;
-}
-int securechip_stretch_password(const char* password, uint8_t* stretched_out)
-{
- memset(stretched_out, 0, 32);
- return 0;
-}
-
-bool securechip_u2f_counter_set(uint32_t counter)
-{
- _u2f_counter = counter;
- return true;
-}
-
-bool securechip_u2f_counter_inc(uint32_t* counter)
-{
- *counter = _u2f_counter++;
- return true;
-}
-
-bool securechip_attestation_sign(const uint8_t* msg, uint8_t* signature_out)
-{
- return false;
-}
-
-bool securechip_monotonic_increments_remaining(uint32_t* remaining_out)
-{
- *remaining_out = 1;
- return true;
-}
-
-bool securechip_model(securechip_model_t* model_out)
-{
- *model_out = ATECC_ATECC608B;
- return true;
-}
diff --git a/test/simulator/framework/mock_smarteeprom.c b/test/simulator/framework/mock_smarteeprom.c
deleted file mode 100644
index b5cf2ce..0000000
--- a/test/simulator/framework/mock_smarteeprom.c
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * Mock for the SmartEEPROM functions.
- */
-#include <memory/smarteeprom.h>
-
-#include <assert.h>
-#include <string.h>
-
-static char* _mem_image = NULL;
-static size_t _allocated_space = 0;
-static size_t _enabled = 0;
-
-void smarteeprom_setup(void)
-{
- /* Allocate an equivalent amount of raw memory */
- size_t n_virtual_pages = SMARTEEPROM_ALLOCATED_BLOCKS * 8192 / SMARTEEPROM_PAGE_SIZE;
- /*
- * The maximum number of virtual pages is limited to 128.
- * Ref. SAMD5x/E5x Family Data Sheet sec. 25.6.8.3
- */
- if (n_virtual_pages > 128) {
- n_virtual_pages = 128;
- }
- _allocated_space = n_virtual_pages * SMARTEEPROM_PAGE_SIZE;
- _mem_image = malloc(_allocated_space);
- if (!_mem_image) {
- abort();
- }
- memset(_mem_image, 0xFF, _allocated_space);
- _enabled = 1;
-}
-
-/**
- * Reads N contiguous bytes from the SmartEEPROM, starting at
- * the specified address.
- *
- * @param[in] address Start address.
- * @param[in] size Number of bytes to read.
- * @param[out] out_buffer Buffer in which to read.
- * Must be at least size bytes wide.
- */
-void smarteeprom_read(size_t address, size_t bytes, uint8_t* out_buffer)
-{
- assert(address + bytes < _allocated_space);
- assert(_enabled);
- memcpy(out_buffer, _mem_image + address, bytes);
-}
-
-/**
- * Writes N contiguous bytes to the SmartEEPROM, starting at
- * the specified address.
- *
- * Note that this will not affect the write endurance of the
- * underlying memory, unless the content currently stored at
- * the specified address has some bits that must be flipped from
- * "0" to "1". Use this wisely!
- *
- * @param[in] address Start address.
- * @param[in] size Number of bytes to write.
- * @param[in] buffer Buffer from which to read the data.
- * Must be at least size bytes wide.
- */
-void smarteeprom_write(size_t address, size_t bytes, const uint8_t* buffer)
-{
- assert(_allocated_space > bytes && address < _allocated_space - bytes);
- assert(_enabled);
- memcpy(_mem_image + address, buffer, bytes);
-}
-
-bool smarteeprom_is_enabled(void)
-{
- return _enabled;
-}
-
-void smarteeprom_disable(void)
-{
- _enabled = 0;
- _allocated_space = 0;
- free(_mem_image);
-}
-
-void smarteeprom_bb02_config(void)
-{
- if (!_enabled) {
- smarteeprom_setup();
- }
-}
diff --git a/test/simulator/framework/mock_spi_mem.c b/test/simulator/framework/mock_spi_mem.c
deleted file mode 100644
index 17c5fde..0000000
--- a/test/simulator/framework/mock_spi_mem.c
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2025 Shift Crypto AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <memory/spi_mem.h>
-#include <stdlib.h>
-#include <string.h>
-
-__extension__ static uint8_t _memory[] = {[0 ... SPI_MEM_MEMORY_SIZE] = 0xFF};
-
-bool spi_mem_full_erase(void)
-{
- memset(_memory, 0xFF, sizeof(_memory));
- return true;
-}
-
-bool spi_mem_write(uint32_t address, const uint8_t* input, size_t size)
-{
- memcpy(&_memory[address], input, size);
- return true;
-}
-
-uint8_t* spi_mem_read(uint32_t address, size_t size)
-{
- uint8_t* result = (uint8_t*)malloc(size);
- if (!result) {
- return NULL;
- }
- memcpy(result, &_memory[address], size);
- return result;
-}
-
-void spi_mem_protected_area_lock(void) {}
-
-void spi_mem_protected_area_unlock(void) {}
-
-bool spi_mem_protected_area_write(uint32_t address, const uint8_t* input, size_t size)
-{
- return spi_mem_write(address, input, size);
-}
diff --git a/test/unit-test/CMakeLists.txt b/test/unit-test/CMakeLists.txt
index 5a89176..d9f877b 100644
--- a/test/unit-test/CMakeLists.txt
+++ b/test/unit-test/CMakeLists.txt
@@ -19,8 +19,6 @@
# both linux and macos
find_package(PkgConfig REQUIRED)
-# Unit testing uses CMocka
-pkg_check_modules(CMOCKA REQUIRED cmocka)
# u2f tests with hardware uses hidapi-hidraw
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
pkg_check_modules(HIDAPI REQUIRED hidapi)
@@ -57,17 +55,6 @@ foreach(SOURCEFILE ${IGNORE_SOURCES})
list(FILTER DBB-FILTERED-SOURCES EXCLUDE REGEX ".*/${SOURCEFILE}$")
endforeach()
-add_library(sd-mock
- STATIC
- framework/mock_diskio.c
-)
-target_include_directories(
- sd-mock
- PUBLIC
- $<TARGET_PROPERTY:fatfs,INTERFACE_INCLUDE_DIRECTORIES>
-)
-
-
# We create a CMake "object library" to track all the compiled sources so that
# they can be reused between a normal library and the manually crafted "merged"
# library.
@@ -76,17 +63,6 @@ add_library(bitbox_objects
OBJECT
${DBB-FILTERED-SOURCES}
${ETHEREUM-SOURCES}
- framework/mock_cipher.c
- framework/mock_screen.c
- framework/mock_screen_stack.c
- framework/mock_memory.c
- framework/mock_spi_mem.c
- framework/mock_qtouch.c
- framework/mock_gestures.c
- framework/mock_component.c
- framework/mock_smarteeprom.c
- framework/mock_securechip.c
- framework/mock_delay.c
)
add_library(bitbox
@@ -127,10 +103,8 @@ target_include_directories(
bitbox_objects
PUBLIC
${INCLUDES}
- ${CMAKE_CURRENT_SOURCE_DIR}/framework/includes
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_BINARY_DIR}/src
- ${CMOCKA_INCLUDE_DIRS}
)
target_include_directories(
@@ -148,7 +122,6 @@ target_include_directories(
bitbox
PUBLIC
${INCLUDES}
- ${CMAKE_CURRENT_SOURCE_DIR}/framework/includes
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_BINARY_DIR}/src
)
@@ -158,8 +131,8 @@ add_dependencies(bitbox_objects
wallycore
secp256k1
fatfs
- sd-mock
)
+target_link_libraries(bitbox_objects PUBLIC hardware-mocks)
target_link_libraries(bitbox PRIVATE ${LIBBITBOX02_RUST} "-lm")
# _UNIT_TEST_ is used by ASF4 to not cross compile
@@ -176,11 +149,9 @@ target_compile_definitions(bitbox PUBLIC TESTING _UNIT_TEST_)
target_link_libraries(bitbox
PUBLIC
secp256k1
- ${CMOCKA_LDFLAGS}
PRIVATE
wallycore
fatfs
- sd-mock
)
if(SANITIZE_ADDRESS)
@@ -264,7 +235,7 @@ else()
list(GET TEST_LIST ${I} TEST_NAME)
list(GET TEST_LIST ${I2} TEST_LINK_ARGS)
set(EXE test_${TEST_NAME})
- add_executable(${EXE} test_${TEST_NAME}.c framework/eh_personality.c)
+ add_executable(${EXE} test_${TEST_NAME}.c)
# asan must be first library in linking order
target_link_libraries(${EXE} PRIVATE
$<$<BOOL:${SANITIZE_ADDRESS}>:asan>
@@ -272,6 +243,8 @@ else()
-Wl,--start-group
c-unit-tests_rust_c
bitbox
+ hardware-mocks
+ fatfs
-Wl,--end-group
${TEST_LINK_ARGS}
)
@@ -293,13 +266,15 @@ foreach(TEST_NAME ${U2F_TESTS})
set(EXE test_${TEST_NAME})
# This tests link to our code
- add_executable(${EXE} test_${TEST_NAME}.c framework/mock_hidapi.c framework/eh_personality.c)
+ add_executable(${EXE} test_${TEST_NAME}.c framework/mock_hidapi.c)
target_link_libraries(${EXE} PRIVATE
$<$<BOOL:${SANITIZE_ADDRESS}>:asan>
$<$<BOOL:${SANITIZE_UNDEFINED}>:-fsanitize=undefined>
$<$<NOT:$<PLATFORM_ID:Darwin>>:-Wl,--start-group>
c-unit-tests_rust_c
bitbox
+ hardware-mocks
+ fatfs
$<$<NOT:$<PLATFORM_ID:Darwin>>:-Wl,--end-group>
u2f-util
)
diff --git a/test/unit-test/framework/eh_personality.c b/test/unit-test/framework/eh_personality.c
deleted file mode 100644
index 8bf2f39..0000000
--- a/test/unit-test/framework/eh_personality.c
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2022 Shift Crypto AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Needed to link the C unit test executables in /test/unit-test, which link to bitbox_merged.
-// `rust_eh_personality` is provided by Rust when building the firmware or running Rust unit tests
-//
-// See
-// https://doc.rust-lang.org/unstable-book/language-features/lang-items.html#writing-an-executable-without-stdlib.
-//
-// One could get rid of this and also considerably shrink the binary size by compiling core instead
-// of using pre-built binaries. See a proof of concept implementation here:
-// https://github.com/BitBoxSwiss/bitbox02-firmware/tree/build-std-PoC. We decided against doing
-// this for now as the feature seems immature and because of the warnings against using it in
-// production:
-// https://github.com/rust-lang/wg-cargo-std-aware/tree/81765f0eb744b9c47840c16f43a32c9f61fd7f0c#mvp-implementation
-void rust_eh_personality(void);
-void rust_eh_personality(void) {}
diff --git a/test/unit-test/framework/includes/mock_cipher.h b/test/unit-test/framework/includes/mock_cipher.h
deleted file mode 100644
index 8c73acd..0000000
--- a/test/unit-test/framework/includes/mock_cipher.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2023 Shift Crypto AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef _MOCK_CIPHER_H_
-#define _MOCK_CIPHER_H_
-
-#include <stdint.h>
-
-void cipher_mock_iv(uint8_t* iv_out);
-
-#endif
diff --git a/test/unit-test/framework/includes/mock_component.h b/test/unit-test/framework/includes/mock_component.h
deleted file mode 100644
index db863fb..0000000
--- a/test/unit-test/framework/includes/mock_component.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef _MOCK_COMPONENT_H_
-#define _MOCK_COMPONENT_H_
-
-#include <ui/component.h>
-
-/********************************** Create Instance **********************************/
-
-/**
- * Creates a label with the given font either upside down or normal.
- * @param[in] text The text of the label.
- * @param[in] upside_down Whether the text should be rotated 180 degree or not.
- * @param[in] font The font of the label.
- */
-component_t* mock_component_create(void);
-
-#endif
diff --git a/test/unit-test/framework/includes/mock_dap.h b/test/unit-test/framework/includes/mock_dap.h
deleted file mode 100644
index bcab573..0000000
--- a/test/unit-test/framework/includes/mock_dap.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2025 Shift Crypto AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef MOCK_DAP_H
-#define MOCK_DAP_H
-#include <stdbool.h>
-#include <stdint.h>
-
-void dap_init(void);
-void dap_connect(void);
-void dap_disconnect(void);
-uint32_t dap_read_word(uint32_t addr);
-uint16_t dap_read_hword(uint32_t addr);
-void dap_write_word(uint32_t addr, uint32_t data);
-void dap_write_hword(uint32_t addr, uint16_t data);
-void dap_reset_link(void);
-uint32_t dap_read_idcode(void);
-bool dap_target_prepare(int32_t timeout);
-
-// Target operations
-void dap_target_select(void);
-void dap_target_deselect(void);
-void dap_target_erase(void);
-void dap_target_lock(void);
-void dap_target_erase_row(uint32_t addr);
-#endif
diff --git a/test/unit-test/framework/includes/mock_gestures.h b/test/unit-test/framework/includes/mock_gestures.h
deleted file mode 100644
index 76c7364..0000000
--- a/test/unit-test/framework/includes/mock_gestures.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef _MOCK_GESTURES_H_
-#define _MOCK_GESTURES_H_
-
-#include <screen.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#include <touch/gestures.h>
-
-/**
- * Mocks the sensors for sliding and tap or hold detection.
- * The flag 'expect_slide_detection' indicates whether the caller expects that the mocked gesture
- * detection returns after detecting a slide gesture. This flag needs to be set to false if the
- * caller requires mocking of the sensor node signal and sensor node reference driver functions.
- * @param[in] screen_position The position at which the touch slider was touched (between 0 and
- * 255).
- */
-void mock_gestures_touch(slider_location_t location, uint8_t screen_position);
-
-/**
- * Mocks the sensors for slider release detection.
- */
-void mock_gestures_touch_release(void);
-
-/**
- * Initializes the touch detection by resetting the detection history.
- */
-void mock_gestures_touch_init(void);
-
-#endif
diff --git a/test/unit-test/framework/includes/mock_memory.h b/test/unit-test/framework/includes/mock_memory.h
deleted file mode 100644
index b050aad..0000000
--- a/test/unit-test/framework/includes/mock_memory.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef _MOCK_MEMORY_H_
-#define _MOCK_MEMORY_H_
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#include <flags.h>
-
-void mock_memory_factoryreset(void);
-bool memory_write_to_address_mock(uint32_t base, uint32_t addr, const uint8_t* chunk);
-bool memory_write_chunk_mock(uint32_t chunk_num, const uint8_t* chunk);
-void memory_read_chunk_mock(uint32_t chunk_num, uint8_t* chunk_out);
-// Size: `FLASH_SHARED_DATA_LEN`.
-void memory_read_shared_bootdata_mock(uint8_t* chunk_out);
-void mock_memory_set_salt_root(const uint8_t* salt_root);
-void memory_bootloader_hash_mock(uint8_t* hash_out);
-void memory_set_bootloader_hash_mock(const uint8_t* mock_hash);
-#endif
diff --git a/test/unit-test/framework/includes/mock_qtouch.h b/test/unit-test/framework/includes/mock_qtouch.h
deleted file mode 100644
index eff3c10..0000000
--- a/test/unit-test/framework/includes/mock_qtouch.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef _QTOUCH_H_
-#define _QTOUCH_H_
-
-#include <stdint.h>
-
-void __wrap_qtouch_process(void);
-
-uint8_t __wrap_qtouch_get_scroller_is_active(uint16_t sensor_node);
-
-uint16_t __wrap_qtouch_get_scroller_position(uint16_t sensor_node);
-
-void qtouch_process(void);
-
-uint8_t qtouch_is_scroller_active(uint16_t sensor_node);
-
-uint16_t qtouch_get_scroller_position(uint16_t sensor_node);
-
-void qtouch_force_calibrate(void);
-
-#endif
diff --git a/test/unit-test/framework/includes/mock_screen_stack.h b/test/unit-test/framework/includes/mock_screen_stack.h
deleted file mode 100644
index ab91907..0000000
--- a/test/unit-test/framework/includes/mock_screen_stack.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef _TEST_SCREEN_STACK_H
-#define _TEST_SCREEN_STACK_H
-
-void mock_screen_stack_assert_clean(void);
-#endif
diff --git a/test/unit-test/framework/includes/mock_uart.h b/test/unit-test/framework/includes/mock_uart.h
deleted file mode 100644
index 2913ecf..0000000
--- a/test/unit-test/framework/includes/mock_uart.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2025 Shift Crypto AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
diff --git a/test/unit-test/framework/includes/test_random.h b/test/unit-test/framework/includes/test_random.h
deleted file mode 100644
index e32bd87..0000000
--- a/test/unit-test/framework/includes/test_random.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef _TEST_RANDOM_H
-#define _TEST_RANDOM_H
-
-int __wrap_rand(void);
-int __wrap_rust_sha256(const unsigned char* data, size_t len, unsigned char* out);
-
-#endif
diff --git a/test/unit-test/framework/mock_cipher.c b/test/unit-test/framework/mock_cipher.c
deleted file mode 100644
index a18c3b3..0000000
--- a/test/unit-test/framework/mock_cipher.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2023 Shift Crypto AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <string.h>
-
-#include <mock_cipher.h>
-
-void cipher_mock_iv(uint8_t* iv_out)
-{
- memset(iv_out, 'a', 32);
-}
diff --git a/test/unit-test/framework/mock_component.c b/test/unit-test/framework/mock_component.c
deleted file mode 100644
index 09cfdc8..0000000
--- a/test/unit-test/framework/mock_component.c
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <string.h>
-
-#include <screen.h>
-#include <stdlib.h>
-#include <ui/ui_util.h>
-
-#include "mock_component.h"
-
-/********************************** Label Functions **********************************/
-
-/**
- * Collects all component functions.
- */
-static const component_functions_t MOCK_COMPONENT_FUNCTIONS = {
- .cleanup = ui_util_component_cleanup,
- .render = ui_util_component_render_subcomponents,
- .on_event = ui_util_on_event_noop};
-
-/********************************** Create Instance **********************************/
-
-/**
- * Creates a label with the given font either upside down or normal.
- * @param[in] text The text of the label.
- * @param[in] upside_down Whether the text should be rotated 180 degree or not.
- * @param[in] font The font of the label.
- */
-component_t* mock_component_create(void)
-{
- component_t* mock = malloc(sizeof(component_t));
- memset(mock, 0, sizeof(component_t));
- mock->f = &MOCK_COMPONENT_FUNCTIONS;
-
- mock->dimension.width = SCREEN_WIDTH;
- mock->dimension.height = SCREEN_HEIGHT;
- mock->position.left = 0;
- mock->position.top = 0;
-
- return mock;
-}
diff --git a/test/unit-test/framework/mock_delay.c b/test/unit-test/framework/mock_delay.c
deleted file mode 100644
index e539f5b..0000000
--- a/test/unit-test/framework/mock_delay.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <stdint.h>
-#include <unistd.h>
-
-void delay_ms(const uint16_t ms)
-{
- usleep(1000 * ms);
-}
-
-void delay_us(const uint16_t us)
-{
- usleep(us);
-}
diff --git a/test/unit-test/framework/mock_diskio.c b/test/unit-test/framework/mock_diskio.c
deleted file mode 100644
index bb2fc7f..0000000
--- a/test/unit-test/framework/mock_diskio.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2021 Shift Crypto AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <stdint.h>
-#include <string.h>
-
-// Must be included before diskio.h, see http://elm-chan.org/fsw/ff/bd/?show=3626
-#include <ff.h>
-
-#include <diskio.h>
-
-// This file is the disk middleware for use in tests, replacing sdmmc_diskio.c used in the firmware
-// to write to microSD cards.
-//
-// It writes and reads from RAM instead of to a card or disk so that unit tests can exercise all
-// sd-card related functionality.
-
-// 100mb with 512 bytes per sector
-#define SECTOR_SIZE 512
-#define SECTOR_COUNT 204800
-static uint8_t _data[SECTOR_SIZE * SECTOR_COUNT] = {0};
-
-DSTATUS disk_initialize(uint8_t drv)
-{
- (void)drv;
- return 0;
-}
-
-DSTATUS disk_status(uint8_t drv)
-{
- (void)drv;
- return 0;
-}
-
-DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count)
-{
- (void)pdrv;
- for (UINT i = 0; i < count; i++) {
- memcpy(&buff[SECTOR_SIZE * i], &_data[SECTOR_SIZE * sector + SECTOR_SIZE * i], SECTOR_SIZE);
- }
- return RES_OK;
-}
-
-DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count)
-{
- for (UINT i = 0; i < count; i++) {
- memcpy(&_data[SECTOR_SIZE * sector + SECTOR_SIZE * i], &buff[SECTOR_SIZE * i], SECTOR_SIZE);
- }
- return RES_OK;
-}
-
-DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff)
-{
- (void)pdrv;
- switch (cmd) {
- case CTRL_SYNC:
- // Already synced (RAM).
- return RES_OK;
- case GET_BLOCK_SIZE:
- *(DWORD*)buff = 1;
- return RES_OK;
- case GET_SECTOR_SIZE:
- *(LBA_t*)buff = SECTOR_SIZE;
- return RES_OK;
- case GET_SECTOR_COUNT:
- *(LBA_t*)buff = SECTOR_COUNT;
- return RES_OK;
- default:
- return RES_PARERR;
- }
-}
diff --git a/test/unit-test/framework/mock_gestures.c b/test/unit-test/framework/mock_gestures.c
deleted file mode 100644
index 47c25e5..0000000
--- a/test/unit-test/framework/mock_gestures.c
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <setjmp.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <cmocka.h>
-
-#include "mock_gestures.h"
-#include "mock_qtouch.h"
-#include <util.h>
-
-#define MEASUREMENT_PERIOD 125
-
-static bool gestures_history_reset = false;
-
-/********************************** POSITIONING **********************************/
-
-/**
- * Converts the screen position into the slider position.
- */
-// TODO: clean up eventually. This is copied form gestures.c
-static uint16_t _screen_to_slider_position(uint8_t screen_position)
-{
- uint16_t slider_position = ((float)screen_position / (float)SCREEN_WIDTH) * MAX_SLIDER_POS;
- return slider_position;
-}
-
-/**
- * Mocks the sensors for sliding and tap or hold detection.
- * The flag 'expect_slide_detection' indicates whether the caller expects that the mocked gesture
- * detection returns after detecting a slide gesture. This flag needs to be set to false if the
- * caller requires mocking of the sensor node signal and sensor node reference driver functions.
- * @param[in] pos The position at which the touch slider was touched (between 0 and 255).
- */
-void mock_gestures_touch(slider_location_t location, uint8_t screen_position)
-{
- for (int j = 0; j < MEASUREMENT_PERIOD; j++) {
- for (int i = 0; i < TOUCH_NUM_SLIDERS; i++) {
- if (i == location) {
- will_return(qtouch_is_scroller_active, 129);
- uint8_t measured_position = _screen_to_slider_position(screen_position);
- if (location == bottom_slider) {
- measured_position = MAX_SLIDER_POS - measured_position;
- }
- will_return(qtouch_get_scroller_position, measured_position);
- } else {
- will_return(qtouch_is_scroller_active, 0);
- }
- }
- gestures_detect(gestures_history_reset, true);
- gestures_history_reset = false;
- }
-}
-
-/**
- * Mocks the sensors for slider release detection.
- */
-void mock_gestures_touch_release(void)
-{
- for (int i = 0; i < TOUCH_NUM_SLIDERS; i++) {
- will_return(qtouch_is_scroller_active, 0);
- }
- gestures_detect(gestures_history_reset, true);
- gestures_history_reset = false;
-}
-
-/**
- * Initializes the touch detection by resetting the detection history.
- */
-void mock_gestures_touch_init(void)
-{
- gestures_history_reset = true;
-}
diff --git a/test/unit-test/framework/mock_memory.c b/test/unit-test/framework/mock_memory.c
deleted file mode 100644
index 559c6f9..0000000
--- a/test/unit-test/framework/mock_memory.c
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <setjmp.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <cmocka.h>
-
-#include <flags.h>
-#include <memory/memory.h>
-#include <mock_memory.h>
-#include <stdio.h>
-#include <string.h>
-
-static uint8_t _memory_shared_data[FLASH_SHARED_DATA_LEN] = {0};
-static uint8_t _memory_app_data[FLASH_APPDATA_LEN] = {0};
-static uint8_t _memory_smarteeprom[SMARTEEPROM_RESERVED_FLASH_PAGES * FLASH_PAGE_SIZE] = {0};
-
-void mock_memory_factoryreset(void)
-{
- memset(_memory_shared_data, 0xff, sizeof(_memory_shared_data));
- memset(_memory_app_data, 0xff, sizeof(_memory_app_data));
- memset(_memory_smarteeprom, 0xff, sizeof(_memory_smarteeprom));
-}
-
-static uint8_t* _get_memory(uint32_t base)
-{
- switch (base) {
- case FLASH_SHARED_DATA_START:
- return _memory_shared_data;
- case FLASH_APPDATA_START:
- return _memory_app_data;
- case FLASH_SMARTEEPROM_START:
- return _memory_smarteeprom;
- default:
- return NULL;
- }
-}
-
-bool memory_write_to_address_mock(uint32_t base, uint32_t addr, const uint8_t* chunk)
-{
- if (chunk == NULL) {
- memset(_get_memory(base) + addr, 0xff, (size_t)CHUNK_SIZE);
- } else {
- memcpy(_get_memory(base) + addr, chunk, (size_t)CHUNK_SIZE);
- }
- return true;
-}
-
-bool memory_write_chunk_mock(uint32_t chunk_num, const uint8_t* chunk)
-{
- return memory_write_to_address_mock(FLASH_APPDATA_START, chunk_num * (size_t)CHUNK_SIZE, chunk);
-}
-
-void memory_read_chunk_mock(uint32_t chunk_num, uint8_t* chunk_out)
-{
- memcpy(chunk_out, _memory_app_data + chunk_num * (size_t)CHUNK_SIZE, (size_t)CHUNK_SIZE);
-}
-
-void memory_read_shared_bootdata_mock(uint8_t* chunk_out)
-{
- memcpy(chunk_out, _memory_shared_data, (size_t)FLASH_SHARED_DATA_LEN);
-}
-
-bool __wrap_memory_is_initialized(void)
-{
- return mock();
-}
-
-bool __wrap_memory_is_seeded(void)
-{
- return mock();
-}
-
-static uint8_t _encrypted_seed_and_hmac[96];
-static uint8_t _encrypted_seed_and_hmac_len;
-
-bool __wrap_memory_set_encrypted_seed_and_hmac(uint8_t* encrypted_seed_and_hmac, uint8_t len)
-{
- memcpy(_encrypted_seed_and_hmac, encrypted_seed_and_hmac, len);
- _encrypted_seed_and_hmac_len = len;
- return true;
-}
-
-bool __wrap_memory_get_encrypted_seed_and_hmac(
- uint8_t* encrypted_seed_and_hmac_out,
- uint8_t* len_out)
-{
- *len_out = _encrypted_seed_and_hmac_len;
- memcpy(encrypted_seed_and_hmac_out, _encrypted_seed_and_hmac, *len_out);
- return true;
-}
-
-void __wrap_memory_get_device_name(char* name_out)
-{
- snprintf(name_out, MEMORY_DEVICE_NAME_MAX_LEN, "%s", (const char*)mock());
-}
-
-bool __wrap_memory_set_device_name(const char* name)
-{
- return mock();
-}
-
-bool __wrap_memory_set_mnemonic_passphrase_enabled(bool enabled)
-{
- check_expected(enabled);
- return mock();
-}
-
-static uint8_t _salt_root[32] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-};
-void mock_memory_set_salt_root(const uint8_t* salt_root)
-{
- memcpy(_salt_root, salt_root, 32);
-}
-bool __wrap_memory_get_salt_root(uint8_t* salt_root_out)
-{
- memcpy(salt_root_out, _salt_root, 32);
- return true;
-}
-
-// Arbitrary value.
-static uint8_t _bootloader_hash[32] =
- "\x71\x3d\xf0\xd5\x8c\x71\x7d\x40\x31\x78\x7c\xdc\x8f\xa3\x5b\x90\x25\x82\xbe\x6a\xb6\xa2\x2e"
- "\x09\xde\x44\x77\xd3\x0e\x22\x30\xfc";
-
-void memory_bootloader_hash_mock(uint8_t* hash_out)
-{
- memcpy(hash_out, _bootloader_hash, 32);
-}
-
-void memory_set_bootloader_hash_mock(const uint8_t* mock_hash)
-{
- // NOLINTNEXTLINE(bugprone-not-null-terminated-result)
- memcpy(_bootloader_hash, mock_hash, sizeof(_bootloader_hash));
-}
diff --git a/test/unit-test/framework/mock_qtouch.c b/test/unit-test/framework/mock_qtouch.c
deleted file mode 100644
index 58772d9..0000000
--- a/test/unit-test/framework/mock_qtouch.c
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <setjmp.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <cmocka.h>
-
-#include "mock_qtouch.h"
-
-volatile bool measurement_done_touch = true;
-
-uint8_t qtouch_is_scroller_active(uint16_t sensor_node)
-{
- return (uint8_t)mock();
-}
-
-uint16_t qtouch_get_scroller_position(uint16_t sensor_node)
-{
- return (uint16_t)mock();
-}
-
-void qtouch_process(void) {}
-
-void qtouch_force_calibrate(void) {}
diff --git a/test/unit-test/framework/mock_screen.c b/test/unit-test/framework/mock_screen.c
deleted file mode 100644
index 45d81ca..0000000
--- a/test/unit-test/framework/mock_screen.c
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <screen.h>
-
-UG_COLOR screen_front_color = C_WHITE;
-UG_COLOR screen_back_color = C_BLACK;
-
-slider_location_t top_slider = 1;
-slider_location_t bottom_slider = 0;
-
-void screen_print_debug(const char* message, int duration)
-{
- printf("%s\n", message);
-}
-
-void screen_splash(void)
-{
- puts("screen splash\n");
-}
-
-void screen_rotate(void) {}
-
-bool screen_is_upside_down(void)
-{
- return false;
-}
-
-void screen_clear(void) {}
diff --git a/test/unit-test/framework/mock_screen_stack.c b/test/unit-test/framework/mock_screen_stack.c
deleted file mode 100644
index 31ff935..0000000
--- a/test/unit-test/framework/mock_screen_stack.c
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <setjmp.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <cmocka.h>
-
-#include <ui/screen_stack.h>
-
-static int _stack_counter = 0;
-void __wrap_ui_screen_stack_push(component_t* component)
-{
- _stack_counter++;
- check_expected(component);
-}
-
-void __wrap_ui_screen_stack_pop(void)
-{
- _stack_counter--;
- assert_true(_stack_counter >= 0);
-}
-
-void mock_screen_stack_assert_clean(void)
-{
- assert_int_equal(_stack_counter, 0);
-}
diff --git a/test/unit-test/framework/mock_securechip.c b/test/unit-test/framework/mock_securechip.c
deleted file mode 100644
index 1a5e141..0000000
--- a/test/unit-test/framework/mock_securechip.c
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <setjmp.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <cmocka.h>
-
-#include <salt.h>
-#include <securechip/securechip.h>
-#include <stdio.h>
-#include <string.h>
-#include <wally_crypto.h>
-
-static uint32_t _u2f_counter;
-
-// Mocked contents of the secure chip rollkey slot.
-static const uint8_t _rollkey[32] =
- "\x9d\xd1\x34\x1f\x6b\x4b\x26\xb1\x72\x89\xa1\xa3\x92\x71\x5c\xf0\xd0\x57\x8c\x84\xdb\x9a\x51"
- "\xeb\xde\x14\x24\x06\x69\xd1\xd0\x5e";
-
-// Mocked contents of the securechip kdf slot.
-static const uint8_t _kdfkey[32] =
- "\xd2\xe1\xe6\xb1\x8b\x6c\x6b\x08\x43\x3e\xdb\xc1\xd1\x68\xc1\xa0\x04\x37\x74\xa4\x22\x18\x77"
- "\xe7\x9e\xd5\x66\x84\xbe\x5a\xc0\x1b";
-
-int securechip_kdf(const uint8_t* msg, size_t len, uint8_t* kdf_out)
-{
- wally_hmac_sha256(_kdfkey, 32, msg, len, kdf_out, 32);
- return 0;
-}
-int securechip_kdf_rollkey(const uint8_t* msg, size_t len, uint8_t* kdf_out)
-{
- wally_hmac_sha256(_rollkey, 32, msg, len, kdf_out, 32);
- return 0;
-}
-int securechip_init_new_password(const char* password)
-{
- (void)password;
- return 0;
-}
-int securechip_stretch_password(const char* password, uint8_t* stretched_out)
-{
- uint8_t key[9] = "unit-test";
- wally_hmac_sha256(
- key, sizeof(key), (const uint8_t*)password, strlen(password), stretched_out, 32);
- return 0;
-}
-bool securechip_u2f_counter_set(uint32_t counter)
-{
- _u2f_counter = counter;
- return true;
-}
-
-bool securechip_u2f_counter_inc(uint32_t* counter)
-{
- *counter = _u2f_counter++;
- return true;
-}
-
-bool securechip_attestation_sign(const uint8_t* msg, uint8_t* signature_out)
-{
- return false;
-}
-
-bool securechip_monotonic_increments_remaining(uint32_t* remaining_out)
-{
- *remaining_out = 1;
- return true;
-}
-
-bool securechip_model(securechip_model_t* model_out)
-{
- *model_out = ATECC_ATECC608B;
- return true;
-}
diff --git a/test/unit-test/framework/mock_smarteeprom.c b/test/unit-test/framework/mock_smarteeprom.c
deleted file mode 100644
index b5cf2ce..0000000
--- a/test/unit-test/framework/mock_smarteeprom.c
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2019 Shift Cryptosecurity AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/**
- * Mock for the SmartEEPROM functions.
- */
-#include <memory/smarteeprom.h>
-
-#include <assert.h>
-#include <string.h>
-
-static char* _mem_image = NULL;
-static size_t _allocated_space = 0;
-static size_t _enabled = 0;
-
-void smarteeprom_setup(void)
-{
- /* Allocate an equivalent amount of raw memory */
- size_t n_virtual_pages = SMARTEEPROM_ALLOCATED_BLOCKS * 8192 / SMARTEEPROM_PAGE_SIZE;
- /*
- * The maximum number of virtual pages is limited to 128.
- * Ref. SAMD5x/E5x Family Data Sheet sec. 25.6.8.3
- */
- if (n_virtual_pages > 128) {
- n_virtual_pages = 128;
- }
- _allocated_space = n_virtual_pages * SMARTEEPROM_PAGE_SIZE;
- _mem_image = malloc(_allocated_space);
- if (!_mem_image) {
- abort();
- }
- memset(_mem_image, 0xFF, _allocated_space);
- _enabled = 1;
-}
-
-/**
- * Reads N contiguous bytes from the SmartEEPROM, starting at
- * the specified address.
- *
- * @param[in] address Start address.
- * @param[in] size Number of bytes to read.
- * @param[out] out_buffer Buffer in which to read.
- * Must be at least size bytes wide.
- */
-void smarteeprom_read(size_t address, size_t bytes, uint8_t* out_buffer)
-{
- assert(address + bytes < _allocated_space);
- assert(_enabled);
- memcpy(out_buffer, _mem_image + address, bytes);
-}
-
-/**
- * Writes N contiguous bytes to the SmartEEPROM, starting at
- * the specified address.
- *
- * Note that this will not affect the write endurance of the
- * underlying memory, unless the content currently stored at
- * the specified address has some bits that must be flipped from
- * "0" to "1". Use this wisely!
- *
- * @param[in] address Start address.
- * @param[in] size Number of bytes to write.
- * @param[in] buffer Buffer from which to read the data.
- * Must be at least size bytes wide.
- */
-void smarteeprom_write(size_t address, size_t bytes, const uint8_t* buffer)
-{
- assert(_allocated_space > bytes && address < _allocated_space - bytes);
- assert(_enabled);
- memcpy(_mem_image + address, buffer, bytes);
-}
-
-bool smarteeprom_is_enabled(void)
-{
- return _enabled;
-}
-
-void smarteeprom_disable(void)
-{
- _enabled = 0;
- _allocated_space = 0;
- free(_mem_image);
-}
-
-void smarteeprom_bb02_config(void)
-{
- if (!_enabled) {
- smarteeprom_setup();
- }
-}
diff --git a/test/unit-test/framework/mock_spi_mem.c b/test/unit-test/framework/mock_spi_mem.c
deleted file mode 100644
index 17c5fde..0000000
--- a/test/unit-test/framework/mock_spi_mem.c
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2025 Shift Crypto AG
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <memory/spi_mem.h>
-#include <stdlib.h>
-#include <string.h>
-
-__extension__ static uint8_t _memory[] = {[0 ... SPI_MEM_MEMORY_SIZE] = 0xFF};
-
-bool spi_mem_full_erase(void)
-{
- memset(_memory, 0xFF, sizeof(_memory));
- return true;
-}
-
-bool spi_mem_write(uint32_t address, const uint8_t* input, size_t size)
-{
- memcpy(&_memory[address], input, size);
- return true;
-}
-
-uint8_t* spi_mem_read(uint32_t address, size_t size)
-{
- uint8_t* result = (uint8_t*)malloc(size);
- if (!result) {
- return NULL;
- }
- memcpy(result, &_memory[address], size);
- return result;
-}
-
-void spi_mem_protected_area_lock(void) {}
-
-void spi_mem_protected_area_unlock(void) {}
-
-bool spi_mem_protected_area_write(uint32_t address, const uint8_t* input, size_t size)
-{
- return spi_mem_write(address, input, size);
-}
Why this scored 15/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.