What changed, and why it matters
This commit swaps one internal cryptography library for another when computing HMAC-SHA256 in the factory-setup code. The goal is to reduce firmware size by reusing an existing SHA-256 implementation, not to fix a security bug. New test vectors were added to confirm the new implementation still produces the correct answers.
No immediate security action required. Reviewers should verify that the new RustCrypto HMAC implementation is compiled with the same side-channel and constant-time properties expected for the target hardware, and confirm the added tests cover all production key lengths. Consider replacing the `.unwrap()` with an explicit error path for defensive coding.
Security signals we found
Cryptographic implementation change in HMAC-SHA256 helper
Use of `.unwrap()` on `new_from_slice`, which can panic if key length is unsupported; for HMAC-SHA256 the RustCrypto `new_from_slice` accepts any key length, so this is effectively safe but still a panic path
No removal of existing call sites; normal firmware still uses `bitcoin_hashes` for other callers
Added known-answer unit tests for edge cases
Evidence from the diff
The change replaces bitcoin::hashes::{HmacEngine, Hmac} with hmac::{Hmac, Mac} from RustCrypto in src/rust/util/src/sha2.rs. The helper hmac_sha256_result now constructs Hmac::<Sha256>::new_from_slice(key), feeds data, and returns the finalized bytes. Cargo manifests and lockfiles are updated to pull in the hmac crate. Two known-answer tests (empty key/empty message, and a 131-byte key) are added to guard against implementation drift.
Changed components
src/rust/util/src/sha2.rsfactory-setup firmware imageRustCrypto `hmac` and `sha2` cratesInspect captured patch +24 / −5
### src/rust/Cargo.lock
@@ -1598,6 +1598,7 @@ dependencies = [
"critical-section",
"hex",
"hex_lit",
+ "hmac",
"num-bigint",
"p256",
"rtt-target",
### src/rust/util/Cargo.toml
@@ -13,6 +13,7 @@ rtt-target = { version = "0.6.2", optional = true }
cortex-m = { workspace = true }
hex = {workspace = true}
sha2 = { workspace = true, optional = true }
+hmac = { workspace = true }
p256 = { version = "0.13.2", default-features = false, features = ["arithmetic", "ecdsa"], optional = true }
bitcoin = { workspace = true }
critical-section = { workspace = true }
### src/rust/util/src/sha2.rs
@@ -12,12 +12,12 @@ fn sha256_result(data: &[u8]) -> [u8; 32] {
}
fn hmac_sha256_result(key: &[u8], data: &[u8]) -> [u8; 32] {
- use bitcoin::hashes::{Hash, HashEngine, Hmac, HmacEngine, sha256};
+ // Reuse the SHA-256 backend above to avoid linking a second implementation into factory setup.
+ use hmac::{Hmac, Mac};
- let mut engine = HmacEngine::<sha256::Hash>::new(key);
- engine.input(data);
- let hmac_result: Hmac<sha256::Hash> = Hmac::from_engine(engine);
- hmac_result.to_byte_array()
+ let mut engine = Hmac::<Sha256>::new_from_slice(key).unwrap();
+ engine.update(data);
+ engine.finalize().into_bytes().into()
}
unsafe fn write_output(out: *mut c_uchar, value: &[u8]) {
@@ -199,6 +199,21 @@ mod tests {
);
}
+ #[test]
+ fn test_hmac_sha256_result() {
+ assert_eq!(
+ hmac_sha256_result(b"", b""),
+ hex!("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"),
+ );
+ assert_eq!(
+ hmac_sha256_result(
+ &[0xaa; 131],
+ b"Test Using Larger Than Block-Size Key - Hash Key First",
+ ),
+ hex!("60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54"),
+ );
+ }
+
#[test]
fn test_hmac_sha256() {
let key = [0x0b_u8; 20];
### test/simulator-graphical-bb03/Cargo.lock
@@ -3399,6 +3399,7 @@ dependencies = [
"cortex-m",
"critical-section",
"hex",
+ "hmac",
"num-bigint",
"sha2",
"time",
### test/simulator-graphical/Cargo.lock
@@ -3354,6 +3354,7 @@ dependencies = [
"cortex-m",
"critical-section",
"hex",
+ "hmac",
"num-bigint",
"sha2",
"time",Why this scored 18/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.