Move SHA algos to metadata (#3991)

This commit is contained in:
Dániel Buga 2025-08-26 16:38:48 +02:00 committed by GitHub
parent 5089c291bf
commit b8b7793bd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 381 additions and 263 deletions

View File

@ -8,15 +8,15 @@
//! ## Configuration
//! This driver allows you to perform cryptographic hash operations using
//! various hash algorithms supported by the SHA peripheral, such as:
//! * SHA-1
//! * SHA-224
//! * SHA-256
//! * SHA-384
//! * SHA-512
//! * SHA-1
//! * SHA-224
//! * SHA-256
//! * SHA-384
//! * SHA-512
//!
//! The driver supports two working modes:
//! * Typical SHA
//! * DMA-SHA
//! * Typical SHA (CPU-driven)
//! * DMA-SHA (not supported yet)
//!
//! It provides functions to update the hash calculation with input data, finish
//! the hash calculation and retrieve the resulting hash value. The SHA
@ -54,8 +54,6 @@
//!
//! # {after_snippet}
//! ```
//! ## Implementation State
//! - DMA-SHA Mode is not supported.
use core::{borrow::Borrow, convert::Infallible, marker::PhantomData, mem::size_of};
@ -540,146 +538,55 @@ impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::FixedOutput for ShaDigest<
}
}
/// This macro implements the Sha<'a, Dm> trait for a specified Sha algorithm
/// and a set of parameters
macro_rules! impl_sha {
($name: ident, $digest_length: literal) => {
/// A SHA implementation struct.
///
/// This struct is generated by the macro and represents a specific SHA hashing
/// algorithm (e.g., SHA-256, SHA-1). It manages the context and state required
/// for processing data using the selected hashing algorithm.
///
/// The struct provides various functionalities such as initializing the hashing
/// process, updating the internal state with new data, and finalizing the
/// hashing operation to generate the final digest.
for_each_sha_algorithm! {
(algos $( ( $name:ident, $full_name:literal $sizes:tt $security:tt, $mode_bits:literal ) ),*) => {
/// Specifies particular SHA algorithm.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub struct $name;
impl crate::private::Sealed for $name {}
impl $crate::sha::ShaAlgorithm for $name {
const ALGORITHM: &'static str = stringify!($name);
const ALGORITHM_KIND: ShaAlgorithmKind = ShaAlgorithmKind::$name;
const CHUNK_LENGTH: usize = Self::ALGORITHM_KIND.chunk_length();
const DIGEST_LENGTH: usize = $digest_length;
// We use paste to append `U` to the digest size to match a const defined in
// digest
type DigestOutputSize = paste::paste!(digest::consts::[< U $digest_length >]);
pub enum ShaAlgorithmKind {
$(
#[doc = concat!("The ", $full_name, " algorithm.")]
$name,
)*
}
};
}
/// Specifies particular SHA algorithm.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub enum ShaAlgorithmKind {
/// The SHA-1 algorithm.
///
/// Note that this algorithm is known to be insecure against collision attacks and length
/// extension attacks.
#[cfg(sha_algo_sha_1)]
Sha1,
for_each_sha_algorithm! {
(algos $( ( $name:ident, $full_name:literal (sizes: $block_size:literal, $digest_words:literal, $message_length_bytes:literal) $security:tt, $mode_bits:literal ) ),*) => {
impl ShaAlgorithmKind {
#[cfg(not(esp32))]
const fn mode_bits(self) -> u8 {
match self {
$(ShaAlgorithmKind::$name => $mode_bits,)*
}
}
/// The SHA-224 algorithm.
///
/// Note that this algorithm is known to be insecure against length extension attacks.
#[cfg(sha_algo_sha_224)]
Sha224,
const fn chunk_length(self) -> usize {
match self {
$(ShaAlgorithmKind::$name => $block_size,)*
}
}
/// The SHA-256 algorithm.
///
/// Note that this algorithm is known to be insecure against length extension attacks.
#[cfg(sha_algo_sha_256)]
Sha256,
/// Bytes needed to represent the length of the longest possible message.
const fn message_length_bytes(self) -> usize {
match self {
$(ShaAlgorithmKind::$name => $message_length_bytes,)*
}
}
/// The SHA-384 algorithm.
#[cfg(sha_algo_sha_384)]
Sha384,
/// The SHA-512 algorithm.
///
/// Note that this algorithm is known to be insecure against length extension attacks.
#[cfg(sha_algo_sha_512)]
Sha512,
/// The SHA-512/224 algorithm.
#[cfg(sha_algo_sha_512_224)]
Sha512_224,
/// The SHA-512/256 algorithm.
#[cfg(sha_algo_sha_512_256)]
Sha512_256,
// TODO
// #[allow(non_camel_case_types)]
// #[cfg(sha_algo_sha_512_t)]
// Sha512_t(u16),
const fn digest_length(self) -> usize {
match self {
$(ShaAlgorithmKind::$name => $digest_words,)*
}
}
}
};
}
impl ShaAlgorithmKind {
#[cfg(not(esp32))]
const fn mode_bits(self) -> u8 {
match self {
#[cfg(sha_algo_sha_1)]
ShaAlgorithmKind::Sha1 => 0,
#[cfg(sha_algo_sha_224)]
ShaAlgorithmKind::Sha224 => 1,
#[cfg(sha_algo_sha_256)]
ShaAlgorithmKind::Sha256 => 2,
#[cfg(sha_algo_sha_384)]
ShaAlgorithmKind::Sha384 => 3,
#[cfg(sha_algo_sha_512)]
ShaAlgorithmKind::Sha512 => 4,
#[cfg(sha_algo_sha_512_224)]
ShaAlgorithmKind::Sha512_224 => 5,
#[cfg(sha_algo_sha_512_256)]
ShaAlgorithmKind::Sha512_256 => 6,
}
}
const fn chunk_length(self) -> usize {
match self {
#[cfg(sha_algo_sha_1)]
ShaAlgorithmKind::Sha1 => 64,
#[cfg(sha_algo_sha_224)]
ShaAlgorithmKind::Sha224 => 64,
#[cfg(sha_algo_sha_256)]
ShaAlgorithmKind::Sha256 => 64,
#[cfg(sha_algo_sha_384)]
ShaAlgorithmKind::Sha384 => 128,
#[cfg(sha_algo_sha_512)]
ShaAlgorithmKind::Sha512 => 128,
#[cfg(sha_algo_sha_512_224)]
ShaAlgorithmKind::Sha512_224 => 128,
#[cfg(sha_algo_sha_512_256)]
ShaAlgorithmKind::Sha512_256 => 128,
}
}
/// Bytes needed to represent the length of the longest possible message.
const fn message_length_bytes(self) -> usize {
match self {
#[cfg(sha_algo_sha_1)]
ShaAlgorithmKind::Sha1 => 8,
#[cfg(sha_algo_sha_224)]
ShaAlgorithmKind::Sha224 => 8,
#[cfg(sha_algo_sha_256)]
ShaAlgorithmKind::Sha256 => 8,
#[cfg(sha_algo_sha_384)]
ShaAlgorithmKind::Sha384 => 16,
#[cfg(sha_algo_sha_512)]
ShaAlgorithmKind::Sha512 => 16,
#[cfg(sha_algo_sha_512_224)]
ShaAlgorithmKind::Sha512_224 => 16,
#[cfg(sha_algo_sha_512_256)]
ShaAlgorithmKind::Sha512_256 => 16,
}
}
fn start(self, sha: &crate::peripherals::SHA<'_>) {
let regs = sha.register_block();
cfg_if::cfg_if! {
@ -753,33 +660,36 @@ impl ShaAlgorithmKind {
}
}
// All the hash algorithms introduced in FIPS PUB 180-4 Spec.
// SHA-1
// SHA-224
// SHA-256
// SHA-384
// SHA-512
// SHA-512/224
// SHA-512/256
// SHA-512/t (not implemented yet)
// Two working modes
// Typical SHA
// DMA-SHA (not implemented yet)
#[cfg(sha_algo_sha_1)]
impl_sha!(Sha1, 20);
#[cfg(sha_algo_sha_224)]
impl_sha!(Sha224, 28);
#[cfg(sha_algo_sha_256)]
impl_sha!(Sha256, 32);
#[cfg(sha_algo_sha_384)]
impl_sha!(Sha384, 48);
#[cfg(sha_algo_sha_512)]
impl_sha!(Sha512, 64);
#[cfg(sha_algo_sha_512_224)]
impl_sha!(Sha512_224, 28);
#[cfg(sha_algo_sha_512_256)]
impl_sha!(Sha512_256, 32);
// TODO: Allow/Implement SHA512_(u16)
// This macro call creates Sha algorithm structs that implement the ShaAlgorithm trait.
for_each_sha_algorithm! {
( $name:ident, $full_name:literal (sizes: $block_size:literal, $digest_words:literal, $message_length_bytes:literal) (insecure_against: $($attack_kind:literal),*), $mode_bits:literal ) => {
#[doc = concat!("Hardware-accelerated ", $full_name, " implementation")]
///
/// This struct manages the context and state required for processing data using the selected hashing algorithm.
///
/// The struct provides various functionalities such as initializing the hashing
/// process, updating the internal state with new data, and finalizing the
/// hashing operation to generate the final digest.
$(
#[doc = ""]
#[doc = concat!(" > ⚠️ Note that this algorithm is known to be insecure against ", $attack_kind, " attacks.")]
)*
#[non_exhaustive]
pub struct $name;
impl crate::private::Sealed for $name {}
impl ShaAlgorithm for $name {
const ALGORITHM: &'static str = stringify!($name);
const ALGORITHM_KIND: ShaAlgorithmKind = ShaAlgorithmKind::$name;
const CHUNK_LENGTH: usize = Self::ALGORITHM_KIND.chunk_length();
const DIGEST_LENGTH: usize = Self::ALGORITHM_KIND.digest_length();
type DigestOutputSize = paste::paste!(digest::consts::[< U $digest_words >]);
}
};
}
fn h_mem(sha: &crate::peripherals::SHA<'_>, index: usize) -> *mut u32 {
let sha = sha.register_block();

View File

@ -289,10 +289,6 @@ impl Chip {
"rng_apb_cycle_wait_num=\"16\"",
"rsa_size_increment=\"512\"",
"rsa_memory_size_bytes=\"512\"",
"sha_algo_sha_1",
"sha_algo_sha_256",
"sha_algo_sha_384",
"sha_algo_sha_512",
"timergroup_timg_has_timer1",
"uart_ram_size=\"128\"",
"has_dram_region",
@ -447,10 +443,6 @@ impl Chip {
"cargo:rustc-cfg=rng_apb_cycle_wait_num=\"16\"",
"cargo:rustc-cfg=rsa_size_increment=\"512\"",
"cargo:rustc-cfg=rsa_memory_size_bytes=\"512\"",
"cargo:rustc-cfg=sha_algo_sha_1",
"cargo:rustc-cfg=sha_algo_sha_256",
"cargo:rustc-cfg=sha_algo_sha_384",
"cargo:rustc-cfg=sha_algo_sha_512",
"cargo:rustc-cfg=timergroup_timg_has_timer1",
"cargo:rustc-cfg=uart_ram_size=\"128\"",
"cargo:rustc-cfg=has_dram_region",
@ -566,9 +558,6 @@ impl Chip {
"interrupts_status_registers=\"2\"",
"rng_apb_cycle_wait_num=\"16\"",
"sha_dma",
"sha_algo_sha_1",
"sha_algo_sha_224",
"sha_algo_sha_256",
"timergroup_timg_has_divcnt_rst",
"timergroup_default_clock_source=\"0\"",
"timergroup_default_clock_source_is_set",
@ -684,9 +673,6 @@ impl Chip {
"cargo:rustc-cfg=interrupts_status_registers=\"2\"",
"cargo:rustc-cfg=rng_apb_cycle_wait_num=\"16\"",
"cargo:rustc-cfg=sha_dma",
"cargo:rustc-cfg=sha_algo_sha_1",
"cargo:rustc-cfg=sha_algo_sha_224",
"cargo:rustc-cfg=sha_algo_sha_256",
"cargo:rustc-cfg=timergroup_timg_has_divcnt_rst",
"cargo:rustc-cfg=timergroup_default_clock_source=\"0\"",
"cargo:rustc-cfg=timergroup_default_clock_source_is_set",
@ -836,9 +822,6 @@ impl Chip {
"rsa_size_increment=\"32\"",
"rsa_memory_size_bytes=\"384\"",
"sha_dma",
"sha_algo_sha_1",
"sha_algo_sha_224",
"sha_algo_sha_256",
"timergroup_timg_has_divcnt_rst",
"timergroup_default_clock_source=\"0\"",
"timergroup_default_clock_source_is_set",
@ -984,9 +967,6 @@ impl Chip {
"cargo:rustc-cfg=rsa_size_increment=\"32\"",
"cargo:rustc-cfg=rsa_memory_size_bytes=\"384\"",
"cargo:rustc-cfg=sha_dma",
"cargo:rustc-cfg=sha_algo_sha_1",
"cargo:rustc-cfg=sha_algo_sha_224",
"cargo:rustc-cfg=sha_algo_sha_256",
"cargo:rustc-cfg=timergroup_timg_has_divcnt_rst",
"cargo:rustc-cfg=timergroup_default_clock_source=\"0\"",
"cargo:rustc-cfg=timergroup_default_clock_source_is_set",
@ -1189,9 +1169,6 @@ impl Chip {
"rsa_size_increment=\"32\"",
"rsa_memory_size_bytes=\"384\"",
"sha_dma",
"sha_algo_sha_1",
"sha_algo_sha_224",
"sha_algo_sha_256",
"timergroup_timg_has_divcnt_rst",
"timergroup_default_clock_source=\"1\"",
"timergroup_default_clock_source_is_set",
@ -1392,9 +1369,6 @@ impl Chip {
"cargo:rustc-cfg=rsa_size_increment=\"32\"",
"cargo:rustc-cfg=rsa_memory_size_bytes=\"384\"",
"cargo:rustc-cfg=sha_dma",
"cargo:rustc-cfg=sha_algo_sha_1",
"cargo:rustc-cfg=sha_algo_sha_224",
"cargo:rustc-cfg=sha_algo_sha_256",
"cargo:rustc-cfg=timergroup_timg_has_divcnt_rst",
"cargo:rustc-cfg=timergroup_default_clock_source=\"1\"",
"cargo:rustc-cfg=timergroup_default_clock_source_is_set",
@ -1576,9 +1550,6 @@ impl Chip {
"rsa_size_increment=\"32\"",
"rsa_memory_size_bytes=\"384\"",
"sha_dma",
"sha_algo_sha_1",
"sha_algo_sha_224",
"sha_algo_sha_256",
"timergroup_timg_has_divcnt_rst",
"timergroup_default_clock_source=\"2\"",
"timergroup_default_clock_source_is_set",
@ -1754,9 +1725,6 @@ impl Chip {
"cargo:rustc-cfg=rsa_size_increment=\"32\"",
"cargo:rustc-cfg=rsa_memory_size_bytes=\"384\"",
"cargo:rustc-cfg=sha_dma",
"cargo:rustc-cfg=sha_algo_sha_1",
"cargo:rustc-cfg=sha_algo_sha_224",
"cargo:rustc-cfg=sha_algo_sha_256",
"cargo:rustc-cfg=timergroup_timg_has_divcnt_rst",
"cargo:rustc-cfg=timergroup_default_clock_source=\"2\"",
"cargo:rustc-cfg=timergroup_default_clock_source_is_set",
@ -1928,14 +1896,6 @@ impl Chip {
"rsa_size_increment=\"32\"",
"rsa_memory_size_bytes=\"512\"",
"sha_dma",
"sha_algo_sha_1",
"sha_algo_sha_224",
"sha_algo_sha_256",
"sha_algo_sha_384",
"sha_algo_sha_512",
"sha_algo_sha_512_224",
"sha_algo_sha_512_256",
"sha_algo_sha_512_t",
"spi_master_has_octal",
"timergroup_timg_has_timer1",
"timergroup_default_clock_source=\"0\"",
@ -2102,14 +2062,6 @@ impl Chip {
"cargo:rustc-cfg=rsa_size_increment=\"32\"",
"cargo:rustc-cfg=rsa_memory_size_bytes=\"512\"",
"cargo:rustc-cfg=sha_dma",
"cargo:rustc-cfg=sha_algo_sha_1",
"cargo:rustc-cfg=sha_algo_sha_224",
"cargo:rustc-cfg=sha_algo_sha_256",
"cargo:rustc-cfg=sha_algo_sha_384",
"cargo:rustc-cfg=sha_algo_sha_512",
"cargo:rustc-cfg=sha_algo_sha_512_224",
"cargo:rustc-cfg=sha_algo_sha_512_256",
"cargo:rustc-cfg=sha_algo_sha_512_t",
"cargo:rustc-cfg=spi_master_has_octal",
"cargo:rustc-cfg=timergroup_timg_has_timer1",
"cargo:rustc-cfg=timergroup_default_clock_source=\"0\"",
@ -2296,14 +2248,6 @@ impl Chip {
"rsa_size_increment=\"32\"",
"rsa_memory_size_bytes=\"512\"",
"sha_dma",
"sha_algo_sha_1",
"sha_algo_sha_224",
"sha_algo_sha_256",
"sha_algo_sha_384",
"sha_algo_sha_512",
"sha_algo_sha_512_224",
"sha_algo_sha_512_256",
"sha_algo_sha_512_t",
"spi_master_has_octal",
"timergroup_timg_has_timer1",
"timergroup_default_clock_source=\"0\"",
@ -2486,14 +2430,6 @@ impl Chip {
"cargo:rustc-cfg=rsa_size_increment=\"32\"",
"cargo:rustc-cfg=rsa_memory_size_bytes=\"512\"",
"cargo:rustc-cfg=sha_dma",
"cargo:rustc-cfg=sha_algo_sha_1",
"cargo:rustc-cfg=sha_algo_sha_224",
"cargo:rustc-cfg=sha_algo_sha_256",
"cargo:rustc-cfg=sha_algo_sha_384",
"cargo:rustc-cfg=sha_algo_sha_512",
"cargo:rustc-cfg=sha_algo_sha_512_224",
"cargo:rustc-cfg=sha_algo_sha_512_256",
"cargo:rustc-cfg=sha_algo_sha_512_t",
"cargo:rustc-cfg=spi_master_has_octal",
"cargo:rustc-cfg=timergroup_timg_has_timer1",
"cargo:rustc-cfg=timergroup_default_clock_source=\"0\"",
@ -2644,10 +2580,6 @@ impl Config {
println!("cargo:rustc-check-cfg=cfg(gpio_remap_iomux_pin_registers)");
println!("cargo:rustc-check-cfg=cfg(i2c_master_separate_filter_config_registers)");
println!("cargo:rustc-check-cfg=cfg(i2c_master_i2c0_data_register_ahb_address_is_set)");
println!("cargo:rustc-check-cfg=cfg(sha_algo_sha_1)");
println!("cargo:rustc-check-cfg=cfg(sha_algo_sha_256)");
println!("cargo:rustc-check-cfg=cfg(sha_algo_sha_384)");
println!("cargo:rustc-check-cfg=cfg(sha_algo_sha_512)");
println!("cargo:rustc-check-cfg=cfg(timergroup_timg_has_timer1)");
println!("cargo:rustc-check-cfg=cfg(esp32c2)");
println!("cargo:rustc-check-cfg=cfg(riscv)");
@ -2692,7 +2624,6 @@ impl Config {
println!("cargo:rustc-check-cfg=cfg(i2c_master_has_tx_fifo_watermark)");
println!("cargo:rustc-check-cfg=cfg(i2c_master_bus_timeout_is_exponential)");
println!("cargo:rustc-check-cfg=cfg(sha_dma)");
println!("cargo:rustc-check-cfg=cfg(sha_algo_sha_224)");
println!("cargo:rustc-check-cfg=cfg(timergroup_timg_has_divcnt_rst)");
println!("cargo:rustc-check-cfg=cfg(timergroup_default_clock_source_is_set)");
println!("cargo:rustc-check-cfg=cfg(timergroup_default_wdt_clock_source_is_set)");
@ -2785,9 +2716,6 @@ impl Config {
println!("cargo:rustc-check-cfg=cfg(riscv_coproc_supported)");
println!("cargo:rustc-check-cfg=cfg(usb_otg)");
println!("cargo:rustc-check-cfg=cfg(aes_dma_mode_gcm)");
println!("cargo:rustc-check-cfg=cfg(sha_algo_sha_512_224)");
println!("cargo:rustc-check-cfg=cfg(sha_algo_sha_512_256)");
println!("cargo:rustc-check-cfg=cfg(sha_algo_sha_512_t)");
println!("cargo:rustc-check-cfg=cfg(spi_master_has_octal)");
println!("cargo:rustc-check-cfg=cfg(esp32s3)");
println!("cargo:rustc-check-cfg=cfg(soc_has_interrupt_core1)");

View File

@ -268,6 +268,23 @@ macro_rules! for_each_rsa_multiplication {
_for_each_inner!((2048)); _for_each_inner!((all(512), (1024), (1536), (2048)));
};
}
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))]
macro_rules! for_each_sha_algorithm {
($($pattern:tt => $code:tt;)*) => {
macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} }
_for_each_inner!((Sha1, "SHA-1"(sizes : 64, 20, 8) (insecure_against :
"collision", "length extension"), 0)); _for_each_inner!((Sha256, "SHA-256"(sizes
: 64, 32, 8) (insecure_against : "length extension"), 0));
_for_each_inner!((Sha384, "SHA-384"(sizes : 128, 48, 16) (insecure_against :),
0)); _for_each_inner!((Sha512, "SHA-512"(sizes : 128, 64, 16) (insecure_against :
"length extension"), 0)); _for_each_inner!((algos(Sha1, "SHA-1"(sizes : 64, 20,
8) (insecure_against : "collision", "length extension"), 0), (Sha256,
"SHA-256"(sizes : 64, 32, 8) (insecure_against : "length extension"), 0),
(Sha384, "SHA-384"(sizes : 128, 48, 16) (insecure_against :), 0), (Sha512,
"SHA-512"(sizes : 128, 64, 16) (insecure_against : "length extension"), 0)));
};
}
/// This macro can be used to generate code for each peripheral instance of the I2C master driver.
///
/// For an explanation on the general syntax, as well as usage of individual/repeated

View File

@ -210,6 +210,22 @@ macro_rules! for_each_soc_xtal_options {
(40)));
};
}
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))]
macro_rules! for_each_sha_algorithm {
($($pattern:tt => $code:tt;)*) => {
macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} }
_for_each_inner!((Sha1, "SHA-1"(sizes : 64, 20, 8) (insecure_against :
"collision", "length extension"), 0)); _for_each_inner!((Sha224, "SHA-224"(sizes
: 64, 28, 8) (insecure_against : "length extension"), 1));
_for_each_inner!((Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against :
"length extension"), 2)); _for_each_inner!((algos(Sha1, "SHA-1"(sizes : 64, 20,
8) (insecure_against : "collision", "length extension"), 0), (Sha224,
"SHA-224"(sizes : 64, 28, 8) (insecure_against : "length extension"), 1),
(Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against : "length extension"),
2)));
};
}
/// This macro can be used to generate code for each peripheral instance of the I2C master driver.
///
/// For an explanation on the general syntax, as well as usage of individual/repeated

View File

@ -332,6 +332,22 @@ macro_rules! for_each_rsa_multiplication {
(1344), (1376), (1408), (1440), (1472), (1504), (1536)));
};
}
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))]
macro_rules! for_each_sha_algorithm {
($($pattern:tt => $code:tt;)*) => {
macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} }
_for_each_inner!((Sha1, "SHA-1"(sizes : 64, 20, 8) (insecure_against :
"collision", "length extension"), 0)); _for_each_inner!((Sha224, "SHA-224"(sizes
: 64, 28, 8) (insecure_against : "length extension"), 1));
_for_each_inner!((Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against :
"length extension"), 2)); _for_each_inner!((algos(Sha1, "SHA-1"(sizes : 64, 20,
8) (insecure_against : "collision", "length extension"), 0), (Sha224,
"SHA-224"(sizes : 64, 28, 8) (insecure_against : "length extension"), 1),
(Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against : "length extension"),
2)));
};
}
/// This macro can be used to generate code for each peripheral instance of the I2C master driver.
///
/// For an explanation on the general syntax, as well as usage of individual/repeated

View File

@ -344,6 +344,22 @@ macro_rules! for_each_rsa_multiplication {
(1344), (1376), (1408), (1440), (1472), (1504), (1536)));
};
}
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))]
macro_rules! for_each_sha_algorithm {
($($pattern:tt => $code:tt;)*) => {
macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} }
_for_each_inner!((Sha1, "SHA-1"(sizes : 64, 20, 8) (insecure_against :
"collision", "length extension"), 0)); _for_each_inner!((Sha224, "SHA-224"(sizes
: 64, 28, 8) (insecure_against : "length extension"), 1));
_for_each_inner!((Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against :
"length extension"), 2)); _for_each_inner!((algos(Sha1, "SHA-1"(sizes : 64, 20,
8) (insecure_against : "collision", "length extension"), 0), (Sha224,
"SHA-224"(sizes : 64, 28, 8) (insecure_against : "length extension"), 1),
(Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against : "length extension"),
2)));
};
}
/// This macro can be used to generate code for each peripheral instance of the I2C master driver.
///
/// For an explanation on the general syntax, as well as usage of individual/repeated

View File

@ -329,6 +329,22 @@ macro_rules! for_each_rsa_multiplication {
(1344), (1376), (1408), (1440), (1472), (1504), (1536)));
};
}
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))]
macro_rules! for_each_sha_algorithm {
($($pattern:tt => $code:tt;)*) => {
macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} }
_for_each_inner!((Sha1, "SHA-1"(sizes : 64, 20, 8) (insecure_against :
"collision", "length extension"), 0)); _for_each_inner!((Sha224, "SHA-224"(sizes
: 64, 28, 8) (insecure_against : "length extension"), 1));
_for_each_inner!((Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against :
"length extension"), 2)); _for_each_inner!((algos(Sha1, "SHA-1"(sizes : 64, 20,
8) (insecure_against : "collision", "length extension"), 0), (Sha224,
"SHA-224"(sizes : 64, 28, 8) (insecure_against : "length extension"), 1),
(Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against : "length extension"),
2)));
};
}
/// This macro can be used to generate code for each peripheral instance of the I2C master driver.
///
/// For an explanation on the general syntax, as well as usage of individual/repeated

View File

@ -354,6 +354,31 @@ macro_rules! for_each_rsa_multiplication {
(1856), (1888), (1920), (1952), (1984), (2016), (2048)));
};
}
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))]
macro_rules! for_each_sha_algorithm {
($($pattern:tt => $code:tt;)*) => {
macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} }
_for_each_inner!((Sha1, "SHA-1"(sizes : 64, 20, 8) (insecure_against :
"collision", "length extension"), 0)); _for_each_inner!((Sha224, "SHA-224"(sizes
: 64, 28, 8) (insecure_against : "length extension"), 1));
_for_each_inner!((Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against :
"length extension"), 2)); _for_each_inner!((Sha384, "SHA-384"(sizes : 128, 48,
16) (insecure_against :), 3)); _for_each_inner!((Sha512, "SHA-512"(sizes : 128,
64, 16) (insecure_against : "length extension"), 4));
_for_each_inner!((Sha512_224, "SHA-512/224"(sizes : 128, 28, 16)
(insecure_against :), 5)); _for_each_inner!((Sha512_256, "SHA-512/256"(sizes :
128, 32, 16) (insecure_against :), 6)); _for_each_inner!((algos(Sha1,
"SHA-1"(sizes : 64, 20, 8) (insecure_against : "collision", "length extension"),
0), (Sha224, "SHA-224"(sizes : 64, 28, 8) (insecure_against :
"length extension"), 1), (Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against
: "length extension"), 2), (Sha384, "SHA-384"(sizes : 128, 48, 16)
(insecure_against :), 3), (Sha512, "SHA-512"(sizes : 128, 64, 16)
(insecure_against : "length extension"), 4), (Sha512_224, "SHA-512/224"(sizes :
128, 28, 16) (insecure_against :), 5), (Sha512_256, "SHA-512/256"(sizes : 128,
32, 16) (insecure_against :), 6)));
};
}
/// This macro can be used to generate code for each peripheral instance of the I2C master driver.
///
/// For an explanation on the general syntax, as well as usage of individual/repeated

View File

@ -347,6 +347,31 @@ macro_rules! for_each_rsa_multiplication {
(1856), (1888), (1920), (1952), (1984), (2016), (2048)));
};
}
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))]
macro_rules! for_each_sha_algorithm {
($($pattern:tt => $code:tt;)*) => {
macro_rules! _for_each_inner { $(($pattern) => $code;)* ($other : tt) => {} }
_for_each_inner!((Sha1, "SHA-1"(sizes : 64, 20, 8) (insecure_against :
"collision", "length extension"), 0)); _for_each_inner!((Sha224, "SHA-224"(sizes
: 64, 28, 8) (insecure_against : "length extension"), 1));
_for_each_inner!((Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against :
"length extension"), 2)); _for_each_inner!((Sha384, "SHA-384"(sizes : 128, 48,
16) (insecure_against :), 3)); _for_each_inner!((Sha512, "SHA-512"(sizes : 128,
64, 16) (insecure_against : "length extension"), 4));
_for_each_inner!((Sha512_224, "SHA-512/224"(sizes : 128, 28, 16)
(insecure_against :), 5)); _for_each_inner!((Sha512_256, "SHA-512/256"(sizes :
128, 32, 16) (insecure_against :), 6)); _for_each_inner!((algos(Sha1,
"SHA-1"(sizes : 64, 20, 8) (insecure_against : "collision", "length extension"),
0), (Sha224, "SHA-224"(sizes : 64, 28, 8) (insecure_against :
"length extension"), 1), (Sha256, "SHA-256"(sizes : 64, 32, 8) (insecure_against
: "length extension"), 2), (Sha384, "SHA-384"(sizes : 128, 48, 16)
(insecure_against :), 3), (Sha512, "SHA-512"(sizes : 128, 64, 16)
(insecure_against : "length extension"), 4), (Sha512_224, "SHA-512/224"(sizes :
128, 28, 16) (insecure_against :), 5), (Sha512_256, "SHA-512/256"(sizes : 128,
32, 16) (insecure_against :), 6)));
};
}
/// This macro can be used to generate code for each peripheral instance of the I2C master driver.
///
/// For an explanation on the general syntax, as well as usage of individual/repeated

View File

@ -608,7 +608,7 @@ memory_size_bytes = 512
[device.sha]
support_status = "partial"
algo = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"]
algo = { sha1 = 0, sha256 = 0, sha384 = 0, sha512 = 0 } # fake mode bits, ESP32 has separate register sets
[device.spi_master]
support_status = "supported"

View File

@ -252,7 +252,7 @@ status_registers = 2
[device.sha]
support_status = "partial"
dma = true
algo = ["SHA-1", "SHA-224", "SHA-256"]
algo = { sha1 = 0, sha224 = 1, sha256 = 2 }
[device.spi_master]
support_status = "supported"

View File

@ -314,7 +314,7 @@ memory_size_bytes = 384
[device.sha]
support_status = "partial"
dma = true
algo = ["SHA-1", "SHA-224", "SHA-256"]
algo = { sha1 = 0, sha224 = 1, sha256 = 2 }
[device.spi_master]
support_status = "supported"

View File

@ -469,7 +469,7 @@ memory_size_bytes = 384
[device.sha]
support_status = "partial"
dma = true
algo = ["SHA-1", "SHA-224", "SHA-256"]
algo = { sha1 = 0, sha224 = 1, sha256 = 2 }
[device.spi_master]
support_status = "supported"

View File

@ -386,7 +386,7 @@ memory_size_bytes = 384
[device.sha]
support_status = "partial"
dma = true
algo = ["SHA-1", "SHA-224", "SHA-256"]
algo = { sha1 = 0, sha224 = 1, sha256 = 2 }
[device.spi_master]
support_status = "supported"

View File

@ -430,16 +430,7 @@ memory_size_bytes = 512
[device.sha]
support_status = "partial"
dma = true
algo = [
"SHA-1",
"SHA-224",
"SHA-256",
"SHA-384",
"SHA-512",
"SHA-512/224",
"SHA-512/256",
"SHA-512/t",
]
algo = { sha1 = 0, sha224 = 1, sha256 = 2, sha384 = 3, sha512 = 4, sha512_224 = 5, sha512_256 = 6, sha512_t = 7 }
[device.spi_master]
support_status = "supported"

View File

@ -606,16 +606,7 @@ memory_size_bytes = 512
[device.sha]
support_status = "partial"
dma = true
algo = [
"SHA-1",
"SHA-224",
"SHA-256",
"SHA-384",
"SHA-512",
"SHA-512/224",
"SHA-512/256",
"SHA-512/t",
]
algo = { sha1 = 0, sha224 = 1, sha256 = 2, sha384 = 3, sha512 = 4, sha512_224 = 5, sha512_256 = 6, sha512_t = 7 }
[device.spi_master]
support_status = "supported"

View File

@ -2,6 +2,7 @@ pub(crate) mod aes;
pub(crate) mod gpio;
pub(crate) mod i2c_master;
pub(crate) mod rsa;
pub(crate) mod sha;
pub(crate) mod soc;
pub(crate) mod spi_master;
pub(crate) mod spi_slave;
@ -10,6 +11,7 @@ pub(crate) mod uart;
pub(crate) use aes::*;
pub(crate) use gpio::*;
pub(crate) use i2c_master::*;
pub(crate) use sha::*;
pub(crate) use spi_master::*;
pub(crate) use spi_slave::*;
pub(crate) use uart::*;
@ -510,7 +512,7 @@ driver_configs![
#[serde(default)]
dma: bool,
#[serde(default)]
algo: Vec<String>,
algo: ShaAlgoMap,
}
},
SpiMasterProperties<SpiMasterInstanceConfig> {

165
esp-metadata/src/cfg/sha.rs Normal file
View File

@ -0,0 +1,165 @@
use proc_macro2::Ident;
use quote::{ToTokens, format_ident, quote};
use serde::{Deserialize, Serialize};
use crate::{generate_for_each_macro, number};
struct ShaAlgo {
name: &'static str,
ident: Ident,
digest_words: u32,
block_size: u32,
message_len_bytes: u32,
// These bits come from <https://en.wikipedia.org/wiki/Secure_Hash_Algorithms#Comparison_of_SHA_functions>
insecure_against_collision: bool,
insecure_against_length_extension: bool,
}
#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize)]
pub struct ShaAlgoMap {
sha1: Option<u32>,
sha224: Option<u32>,
sha256: Option<u32>,
sha384: Option<u32>,
sha512: Option<u32>,
sha512_224: Option<u32>,
sha512_256: Option<u32>,
sha512_t: Option<u32>,
}
impl super::GenericProperty for ShaAlgoMap {
fn for_each_macro(&self) -> Option<proc_macro2::TokenStream> {
let modes = [
("SHA-1", self.sha1),
("SHA-224", self.sha224),
("SHA-256", self.sha256),
("SHA-384", self.sha384),
("SHA-512", self.sha512),
("SHA-512/224", self.sha512_224),
("SHA-512/256", self.sha512_256),
("SHA-512/t", self.sha512_t),
];
let algos = modes
.into_iter()
.filter_map(|(name, mode)| mode.map(|m| (name, m)))
.filter_map(|(name, mode)| ShaAlgo::new(name).map(|name| (name, mode)))
.map(|(algo, mode)| {
let mode = number(mode);
quote! { #algo, #mode }
})
.collect::<Vec<_>>();
Some(generate_for_each_macro(
"sha_algorithm",
&[("algos", &algos)],
))
}
}
impl ShaAlgo {
fn new(algo: &str) -> Option<Self> {
let known = [
Self {
name: "SHA-1",
ident: format_ident!("Sha1"),
digest_words: 20,
block_size: 64,
message_len_bytes: 8,
insecure_against_collision: true,
insecure_against_length_extension: true,
},
Self {
name: "SHA-224",
ident: format_ident!("Sha224"),
digest_words: 28,
block_size: 64,
message_len_bytes: 8,
insecure_against_collision: false,
insecure_against_length_extension: true,
},
Self {
name: "SHA-256",
ident: format_ident!("Sha256"),
digest_words: 32,
block_size: 64,
message_len_bytes: 8,
insecure_against_collision: false,
insecure_against_length_extension: true,
},
Self {
name: "SHA-384",
ident: format_ident!("Sha384"),
digest_words: 48,
block_size: 128,
message_len_bytes: 16,
insecure_against_collision: false,
insecure_against_length_extension: false,
},
Self {
name: "SHA-512",
ident: format_ident!("Sha512"),
digest_words: 64,
block_size: 128,
message_len_bytes: 16,
insecure_against_collision: false,
insecure_against_length_extension: true,
},
Self {
name: "SHA-512/224",
ident: format_ident!("Sha512_224"),
digest_words: 28,
block_size: 128,
message_len_bytes: 16,
insecure_against_collision: false,
insecure_against_length_extension: false,
},
Self {
name: "SHA-512/256",
ident: format_ident!("Sha512_256"),
digest_words: 32,
block_size: 128,
message_len_bytes: 16,
insecure_against_collision: false,
insecure_against_length_extension: false,
},
];
for a in known {
if a.name == algo {
return Some(a);
}
}
// Special-case (ignore) general truncated algo until we figure out how to describe its
// `digest_words`.
if algo == "SHA-512/t" {
return None;
}
panic!("Unknown SHA algorithm: {algo}")
}
}
impl ToTokens for ShaAlgo {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let ident = &self.ident;
let name = &self.name;
let digest_words = number(self.digest_words);
let block_size = number(self.block_size);
let message_len_bytes = number(self.message_len_bytes);
let mut insecure = vec![];
if self.insecure_against_collision {
insecure.push("collision");
}
if self.insecure_against_length_extension {
insecure.push("length extension");
}
tokens.extend(
quote! { #ident, #name (sizes: #block_size, #digest_words, #message_len_bytes) (insecure_against: #(#insecure),*) },
);
}
}