diff options
| -rw-r--r-- | embassy-stm32/CHANGELOG.md | 5 | ||||
| -rw-r--r-- | embassy-stm32/Cargo.toml | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/hash/mod.rs | 16 | ||||
| -rw-r--r-- | embassy-time/src/delay.rs | 14 | ||||
| -rw-r--r-- | tests/stm32/Cargo.toml | 5 | ||||
| -rw-r--r-- | tests/stm32/src/bin/hash.rs | 48 |
6 files changed, 73 insertions, 23 deletions
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 26b643aa0..301c20055 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md | |||
| @@ -8,8 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | 10 | ||
| 11 | - fix: Fix vrefbuf building with log feature | ||
| 12 | - fix: stm32/i2c: pull-down was enabled instead of pull-none when no internal pull-up was needed. | 11 | - fix: stm32/i2c: pull-down was enabled instead of pull-none when no internal pull-up was needed. |
| 12 | - feat: Improve blocking hash speed | ||
| 13 | - fix: Fix vrefbuf building with log feature | ||
| 14 | - fix: Fix performing a hash after performing a hmac | ||
| 15 | - chore: Updated stm32-metapac and stm32-data dependencies | ||
| 13 | 16 | ||
| 14 | ## 0.3.0 - 2025-08-12 | 17 | ## 0.3.0 - 2025-08-12 |
| 15 | 18 | ||
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 691ce3b90..45b351acf 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -80,8 +80,8 @@ cortex-m = "0.7.6" | |||
| 80 | futures-util = { version = "0.3.30", default-features = false } | 80 | futures-util = { version = "0.3.30", default-features = false } |
| 81 | sdio-host = "0.9.0" | 81 | sdio-host = "0.9.0" |
| 82 | critical-section = "1.1" | 82 | critical-section = "1.1" |
| 83 | stm32-metapac = { version = "17" } | 83 | # stm32-metapac = { version = "17" } |
| 84 | # stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9941f338734a2e6c1652267f64b13f7b35d8c9db" } | 84 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ecb93d42a6cbcd9e09cab74873908a2ca22327f7" } |
| 85 | 85 | ||
| 86 | vcell = "0.1.3" | 86 | vcell = "0.1.3" |
| 87 | nb = "1.0.0" | 87 | nb = "1.0.0" |
| @@ -109,8 +109,8 @@ proptest-state-machine = "0.3.0" | |||
| 109 | proc-macro2 = "1.0.36" | 109 | proc-macro2 = "1.0.36" |
| 110 | quote = "1.0.15" | 110 | quote = "1.0.15" |
| 111 | 111 | ||
| 112 | stm32-metapac = { version = "17", default-features = false, features = ["metadata"]} | 112 | # stm32-metapac = { version = "17", default-features = false, features = ["metadata"]} |
| 113 | #stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9941f338734a2e6c1652267f64b13f7b35d8c9db", default-features = false, features = ["metadata"] } | 113 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ecb93d42a6cbcd9e09cab74873908a2ca22327f7", default-features = false, features = ["metadata"] } |
| 114 | 114 | ||
| 115 | [features] | 115 | [features] |
| 116 | default = ["rt"] | 116 | default = ["rt"] |
diff --git a/embassy-stm32/src/hash/mod.rs b/embassy-stm32/src/hash/mod.rs index e62151bb5..90c06c0d8 100644 --- a/embassy-stm32/src/hash/mod.rs +++ b/embassy-stm32/src/hash/mod.rs | |||
| @@ -198,6 +198,8 @@ impl<'d, T: Instance, M: Mode> Hash<'d, T, M> { | |||
| 198 | if key.len() > 64 { | 198 | if key.len() > 64 { |
| 199 | T::regs().cr().modify(|w| w.set_lkey(true)); | 199 | T::regs().cr().modify(|w| w.set_lkey(true)); |
| 200 | } | 200 | } |
| 201 | } else { | ||
| 202 | T::regs().cr().modify(|w| w.set_mode(false)); | ||
| 201 | } | 203 | } |
| 202 | 204 | ||
| 203 | T::regs().cr().modify(|w| w.set_init(true)); | 205 | T::regs().cr().modify(|w| w.set_init(true)); |
| @@ -351,13 +353,17 @@ impl<'d, T: Instance, M: Mode> Hash<'d, T, M> { | |||
| 351 | let num_valid_bits: u8 = (8 * (input.len() % 4)) as u8; | 353 | let num_valid_bits: u8 = (8 * (input.len() % 4)) as u8; |
| 352 | T::regs().str().modify(|w| w.set_nblw(num_valid_bits)); | 354 | T::regs().str().modify(|w| w.set_nblw(num_valid_bits)); |
| 353 | 355 | ||
| 354 | let mut i = 0; | 356 | let mut chunks = input.chunks_exact(4); |
| 355 | while i < input.len() { | 357 | for chunk in &mut chunks { |
| 358 | T::regs() | ||
| 359 | .din() | ||
| 360 | .write_value(u32::from_ne_bytes(chunk.try_into().unwrap())); | ||
| 361 | } | ||
| 362 | let rem = chunks.remainder(); | ||
| 363 | if !rem.is_empty() { | ||
| 356 | let mut word: [u8; 4] = [0; 4]; | 364 | let mut word: [u8; 4] = [0; 4]; |
| 357 | let copy_idx = min(i + 4, input.len()); | 365 | word[0..rem.len()].copy_from_slice(rem); |
| 358 | word[0..copy_idx - i].copy_from_slice(&input[i..copy_idx]); | ||
| 359 | T::regs().din().write_value(u32::from_ne_bytes(word)); | 366 | T::regs().din().write_value(u32::from_ne_bytes(word)); |
| 360 | i += 4; | ||
| 361 | } | 367 | } |
| 362 | } | 368 | } |
| 363 | 369 | ||
diff --git a/embassy-time/src/delay.rs b/embassy-time/src/delay.rs index 67345f726..11b54b098 100644 --- a/embassy-time/src/delay.rs +++ b/embassy-time/src/delay.rs | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | use core::future::Future; | ||
| 2 | |||
| 1 | use super::{Duration, Instant}; | 3 | use super::{Duration, Instant}; |
| 2 | use crate::Timer; | 4 | use crate::Timer; |
| 3 | 5 | ||
| @@ -32,16 +34,16 @@ impl embedded_hal_1::delay::DelayNs for Delay { | |||
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | impl embedded_hal_async::delay::DelayNs for Delay { | 36 | impl embedded_hal_async::delay::DelayNs for Delay { |
| 35 | async fn delay_ns(&mut self, ns: u32) { | 37 | fn delay_ns(&mut self, ns: u32) -> impl Future<Output = ()> { |
| 36 | Timer::after_nanos(ns as _).await | 38 | Timer::after_nanos(ns as _) |
| 37 | } | 39 | } |
| 38 | 40 | ||
| 39 | async fn delay_us(&mut self, us: u32) { | 41 | fn delay_us(&mut self, us: u32) -> impl Future<Output = ()> { |
| 40 | Timer::after_micros(us as _).await | 42 | Timer::after_micros(us as _) |
| 41 | } | 43 | } |
| 42 | 44 | ||
| 43 | async fn delay_ms(&mut self, ms: u32) { | 45 | fn delay_ms(&mut self, ms: u32) -> impl Future<Output = ()> { |
| 44 | Timer::after_millis(ms as _).await | 46 | Timer::after_millis(ms as _) |
| 45 | } | 47 | } |
| 46 | } | 48 | } |
| 47 | 49 | ||
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 96b49f027..c011a6d7d 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -16,7 +16,7 @@ stm32f446re = ["embassy-stm32/stm32f446re", "spi-v1", "chrono", "stop", "can", " | |||
| 16 | stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng", "single-bank"] | 16 | stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng", "single-bank"] |
| 17 | stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"] | 17 | stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"] |
| 18 | stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"] | 18 | stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan", "cordic"] |
| 19 | stm32h563zi = ["embassy-stm32/stm32h563zi", "spi-v345", "chrono", "eth", "rng", "fdcan", "hash", "cordic", "stop"] | 19 | stm32h563zi = ["embassy-stm32/stm32h563zi", "spi-v345", "chrono", "eth", "rng", "fdcan", "hash-v34", "cordic", "stop"] |
| 20 | stm32h753zi = ["embassy-stm32/stm32h753zi", "spi-v345", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"] | 20 | stm32h753zi = ["embassy-stm32/stm32h753zi", "spi-v345", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"] |
| 21 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "spi-v345", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"] | 21 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "spi-v345", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"] |
| 22 | stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "spi-v345", "not-gpdma", "rng", "fdcan"] | 22 | stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "spi-v345", "not-gpdma", "rng", "fdcan"] |
| @@ -33,13 +33,14 @@ stm32wba52cg = ["embassy-stm32/stm32wba52cg", "spi-v345", "chrono", "rng", "hash | |||
| 33 | stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] | 33 | stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] |
| 34 | stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"] | 34 | stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"] |
| 35 | stm32h503rb = ["embassy-stm32/stm32h503rb", "spi-v345", "rng", "stop"] | 35 | stm32h503rb = ["embassy-stm32/stm32h503rb", "spi-v345", "rng", "stop"] |
| 36 | stm32h7s3l8 = ["embassy-stm32/stm32h7s3l8", "spi-v345", "rng", "cordic", "hash"] # TODO: fdcan crashes, cryp dma hangs. | 36 | stm32h7s3l8 = ["embassy-stm32/stm32h7s3l8", "spi-v345", "rng", "cordic", "hash-v34"] # TODO: fdcan crashes, cryp dma hangs. |
| 37 | stm32u083rc = ["embassy-stm32/stm32u083rc", "cm0", "rng", "chrono"] | 37 | stm32u083rc = ["embassy-stm32/stm32u083rc", "cm0", "rng", "chrono"] |
| 38 | 38 | ||
| 39 | spi-v1 = [] | 39 | spi-v1 = [] |
| 40 | spi-v345 = [] | 40 | spi-v345 = [] |
| 41 | cryp = [] | 41 | cryp = [] |
| 42 | hash = [] | 42 | hash = [] |
| 43 | hash-v34 = ["hash"] | ||
| 43 | eth = [] | 44 | eth = [] |
| 44 | rng = [] | 45 | rng = [] |
| 45 | sdmmc = [] | 46 | sdmmc = [] |
diff --git a/tests/stm32/src/bin/hash.rs b/tests/stm32/src/bin/hash.rs index 52b84a499..bb08d0cf1 100644 --- a/tests/stm32/src/bin/hash.rs +++ b/tests/stm32/src/bin/hash.rs | |||
| @@ -7,6 +7,7 @@ mod common; | |||
| 7 | use common::*; | 7 | use common::*; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::hash::*; | 9 | use embassy_stm32::hash::*; |
| 10 | use embassy_stm32::mode::Blocking; | ||
| 10 | use embassy_stm32::{bind_interrupts, hash, peripherals}; | 11 | use embassy_stm32::{bind_interrupts, hash, peripherals}; |
| 11 | use hmac::{Hmac, Mac}; | 12 | use hmac::{Hmac, Mac}; |
| 12 | use sha2::{Digest, Sha224, Sha256}; | 13 | use sha2::{Digest, Sha224, Sha256}; |
| @@ -32,11 +33,7 @@ bind_interrupts!(struct Irqs { | |||
| 32 | HASH => hash::InterruptHandler<peripherals::HASH>; | 33 | HASH => hash::InterruptHandler<peripherals::HASH>; |
| 33 | }); | 34 | }); |
| 34 | 35 | ||
| 35 | #[embassy_executor::main] | 36 | fn test_interrupt(hw_hasher: &mut Hash<'_, peripherals::HASH, Blocking>) { |
| 36 | async fn main(_spawner: Spawner) { | ||
| 37 | let p: embassy_stm32::Peripherals = init(); | ||
| 38 | let mut hw_hasher = Hash::new_blocking(p.HASH, Irqs); | ||
| 39 | |||
| 40 | let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; | 37 | let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; |
| 41 | let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr"; | 38 | let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr"; |
| 42 | let test_3: &[u8] = b"a.ewtkluGWEBR.KAJRBTA,RMNRBG,FDMGB.kger.tkasjrbt.akrjtba.krjtba.ktmyna,nmbvtyliasd;gdrtba,sfvs.kgjzshd.gkbsr.tksejb.SDkfBSE.gkfgb>ESkfbSE>gkJSBESE>kbSE>fk"; | 39 | let test_3: &[u8] = b"a.ewtkluGWEBR.KAJRBTA,RMNRBG,FDMGB.kger.tkasjrbt.akrjtba.krjtba.ktmyna,nmbvtyliasd;gdrtba,sfvs.kgjzshd.gkbsr.tksejb.SDkfBSE.gkfgb>ESkfbSE>gkJSBESE>kbSE>fk"; |
| @@ -95,6 +92,47 @@ async fn main(_spawner: Spawner) { | |||
| 95 | info!("Hardware HMAC: {:?}", hw_hmac); | 92 | info!("Hardware HMAC: {:?}", hw_hmac); |
| 96 | info!("Software HMAC: {:?}", sw_hmac[..]); | 93 | info!("Software HMAC: {:?}", sw_hmac[..]); |
| 97 | defmt::assert!(hw_hmac == sw_hmac[..]); | 94 | defmt::assert!(hw_hmac == sw_hmac[..]); |
| 95 | } | ||
| 96 | |||
| 97 | // This uses sha512, so only supported on hash_v3 and up | ||
| 98 | #[cfg(feature = "hash-v34")] | ||
| 99 | fn test_sizes(hw_hasher: &mut Hash<'_, peripherals::HASH, Blocking>) { | ||
| 100 | let in1 = b"4BPuGudaDK"; | ||
| 101 | let in2 = b"cfFIGf0XSNhFBQ5LaIqzjnRKDRkoWweJI06HLUcicIUGjpuDNfOTQNSrRxDoveDPlazeZtt06SIYO5CvHvsJ98XSfO9yJEMHoDpDAmNQtwZOPlKmdiagRXsJ7w7IjdKpQH6I2t"; | ||
| 102 | |||
| 103 | for i in 1..10 { | ||
| 104 | // sha512 block size is 128, so test around there | ||
| 105 | for j in [1, 1, 2, 3, 4, 5, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133] { | ||
| 106 | info!("test_sizes i {} j {}", i, j); | ||
| 107 | let mut sw = sha2::Sha512::new(); | ||
| 108 | let mut ctx = hw_hasher.start(Algorithm::SHA512, DataType::Width8, None); | ||
| 109 | |||
| 110 | sw.update(&in1[..i]); | ||
| 111 | sw.update(&in2[..j]); | ||
| 112 | hw_hasher.update_blocking(&mut ctx, &in1[..i]); | ||
| 113 | hw_hasher.update_blocking(&mut ctx, &in2[..j]); | ||
| 114 | |||
| 115 | let sw_digest = sw.finalize(); | ||
| 116 | let mut hw_digest = [0u8; 64]; | ||
| 117 | hw_hasher.finish_blocking(ctx, &mut hw_digest); | ||
| 118 | info!("Hardware: {:?}", hw_digest); | ||
| 119 | info!("Software: {:?}", sw_digest[..]); | ||
| 120 | defmt::assert!(hw_digest == *sw_digest); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | #[embassy_executor::main] | ||
| 126 | async fn main(_spawner: Spawner) { | ||
| 127 | let p: embassy_stm32::Peripherals = init(); | ||
| 128 | let mut hw_hasher = Hash::new_blocking(p.HASH, Irqs); | ||
| 129 | |||
| 130 | test_interrupt(&mut hw_hasher); | ||
| 131 | // Run it a second time to check hash-after-hmac | ||
| 132 | test_interrupt(&mut hw_hasher); | ||
| 133 | |||
| 134 | #[cfg(feature = "hash-v34")] | ||
| 135 | test_sizes(&mut hw_hasher); | ||
| 98 | 136 | ||
| 99 | info!("Test OK"); | 137 | info!("Test OK"); |
| 100 | cortex_m::asm::bkpt(); | 138 | cortex_m::asm::bkpt(); |
