Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions hal/blocking/src/cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ pub enum ErrorKind {

/// Key or IV is invalid or missing.
KeyError,

/// The hardware accelerator is busy and cannot process the cipher operation.
Busy,

/// The operation did not complete within the expected time.
Timeout,
}

/// Trait for converting implementation-specific errors into a generic [`ErrorKind`].
Expand Down Expand Up @@ -183,7 +189,6 @@ pub trait CipherInit<M: CipherMode>: SymmetricCipher {
///
/// - `key`: A reference to the key used for the cipher.
/// - `nonce`: A reference to the nonce or IV used for the cipher.
/// - `mode`: The cipher mode to use.
///
/// # Returns
///
Expand All @@ -192,7 +197,6 @@ pub trait CipherInit<M: CipherMode>: SymmetricCipher {
&'a mut self,
key: &Self::Key,
nonce: &Self::Nonce,
mode: M,
) -> Result<Self::CipherContext<'a>, Self::Error>;
}

Expand Down Expand Up @@ -232,7 +236,7 @@ pub trait ResettableCipherOp: ErrorType {
}

/// Optional trait for cipher contexts that support rekeying.
pub trait CipherRekey<K>: ErrorType {
pub trait CipherRekey: SymmetricCipher {
/// Rekeys the cipher context with a new key.
///
/// # Parameters
Expand All @@ -242,7 +246,7 @@ pub trait CipherRekey<K>: ErrorType {
/// # Returns
///
/// A result indicating success or failure.
fn rekey(&mut self, new_key: &K) -> Result<(), Self::Error>;
fn rekey(&mut self, new_key: &Self::Key) -> Result<(), Self::Error>;
}

/// Error type for block-aligned container operations.
Expand Down Expand Up @@ -410,7 +414,7 @@ impl<const BLOCK_SIZE: usize, const MAX_BLOCKS: usize> BlockAligned<BLOCK_SIZE,
/// - Security managers that don't perform encryption/decryption
/// - Key stores and vaults with secure cleanup
/// - Flexible composition with other cipher traits
pub trait SecureCipherOp: ErrorType {
pub trait SecureCipherOp {
/// Securely clear internal state and zeroize sensitive data.
///
/// This method performs a secure cleanup of all internal state, including:
Expand Down Expand Up @@ -441,9 +445,9 @@ pub trait SecureCipherOp: ErrorType {
/// ```ignore
/// let mut cipher = SecureAesCipher::new();
/// // ... perform cipher operations ...
/// cipher.clear_state()?; // Secure cleanup before dropping
/// cipher.clear_state(); // Secure cleanup before dropping
/// ```
fn clear_state(&mut self) -> Result<(), Self::Error>;
fn clear_state(&mut self);
}

/// Trait for querying cipher status and hardware state.
Expand Down Expand Up @@ -586,11 +590,6 @@ pub trait AeadCipherOp: SymmetricCipher + ErrorType {
///
/// # Common Types
///
/// - `&[u8]` for read-only associated data
/// - `[u8; N]` for fixed-size owned associated data
/// - `()` or empty slice if no associated data is needed
type AssociatedData: FromBytes + IntoBytes;

/// The authentication tag type for AEAD operations.
///
/// The authentication tag is a cryptographic checksum that provides
Expand Down Expand Up @@ -634,7 +633,7 @@ pub trait AeadCipherOp: SymmetricCipher + ErrorType {
fn encrypt_aead(
&mut self,
plaintext: Self::PlainText,
associated_data: Self::AssociatedData,
associated_data: &[u8],
) -> Result<(Self::CipherText, Self::Tag), Self::Error>;

/// Decrypts the given ciphertext with associated data and authentication tag.
Expand All @@ -651,7 +650,7 @@ pub trait AeadCipherOp: SymmetricCipher + ErrorType {
fn decrypt_aead(
&mut self,
ciphertext: Self::CipherText,
associated_data: Self::AssociatedData,
associated_data: &[u8],
tag: Self::Tag,
) -> Result<Self::PlainText, Self::Error>;
}
Expand Down
36 changes: 6 additions & 30 deletions hal/blocking/src/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
//! # impl ErrorType for MyDigestImpl { type Error = core::convert::Infallible; }
//! # impl DigestInit<Sha2_256> for MyDigestImpl {
//! # type OpContext<'a> = MyContext<'a> where Self: 'a;
//! # type Output = Digest<8>;
//! # fn init<'a>(&'a mut self, _: Sha2_256) -> Result<Self::OpContext<'a>, Self::Error> { todo!() }
//! # }
//! # struct MyContext<'a>(&'a mut MyDigestImpl);
Expand All @@ -81,7 +80,6 @@
//! # impl ErrorType for MyDigestController { type Error = core::convert::Infallible; }
//! # impl DigestInit<Sha2_256> for MyDigestController {
//! # type Context = MyOwnedContext;
//! # type Output = Digest<8>;
//! # fn init(self, _: Sha2_256) -> Result<Self::Context, Self::Error> { todo!() }
//! # }
//! # struct MyOwnedContext;
Expand Down Expand Up @@ -417,9 +415,6 @@ pub enum ErrorKind {
/// The specified hash algorithm is not supported by the hardware or software implementation.
UnsupportedAlgorithm,

/// Failed to allocate memory for the hash computation.
MemoryAllocationFailure,

/// Failed to initialize the hash computation context.
InitializationError,

Expand All @@ -435,9 +430,6 @@ pub enum ErrorKind {
/// General hardware failure during hash computation.
HardwareFailure,

/// The specified output size is not valid for the hash function.
InvalidOutputSize,

/// Insufficient permissions to access the hardware or perform the hash computation.
PermissionDenied,

Expand All @@ -450,13 +442,11 @@ impl core::fmt::Display for ErrorKind {
match self {
Self::InvalidInputLength => write!(f, "invalid input data length"),
Self::UnsupportedAlgorithm => write!(f, "unsupported hash algorithm"),
Self::MemoryAllocationFailure => write!(f, "memory allocation failed"),
Self::InitializationError => write!(f, "failed to initialize hash computation"),
Self::UpdateError => write!(f, "error updating hash computation"),
Self::FinalizationError => write!(f, "error finalizing hash computation"),
Self::Busy => write!(f, "hardware accelerator is busy"),
Self::HardwareFailure => write!(f, "hardware failure during hash computation"),
Self::InvalidOutputSize => write!(f, "invalid output size for hash function"),
Self::PermissionDenied => write!(f, "insufficient permissions to access hardware"),
Self::NotInitialized => write!(f, "hash computation context not initialized"),
}
Expand Down Expand Up @@ -549,7 +539,6 @@ pub trait ErrorType {
/// # impl ErrorType for MyDigestImpl { type Error = core::convert::Infallible; }
/// # impl DigestInit<Sha2_256> for MyDigestImpl {
/// # type OpContext<'a> = MyContext<'a> where Self: 'a;
/// # type Output = Digest<8>;
/// # fn init<'a>(&'a mut self, _: Sha2_256) -> Result<Self::OpContext<'a>, Self::Error> { todo!() }
/// # }
/// # struct MyContext<'a>(&'a mut MyDigestImpl);
Expand All @@ -571,26 +560,20 @@ pub trait DigestInit<T: DigestAlgorithm>: ErrorType {
/// This associated type represents the stateful context returned by [`init`](Self::init)
/// that can be used to perform the actual digest operations via [`DigestOp`].
/// The lifetime parameter ensures the context cannot outlive the device that created it.
type OpContext<'a>: DigestOp<Output = Self::Output>
type OpContext<'a>: DigestOp<Output = T::Digest>
where
Self: 'a;

/// The output type produced by this digest implementation.
///
/// This type must implement [`IntoBytes`] to allow conversion to byte arrays
/// for interoperability with other systems and zero-copy operations.
type Output: IntoBytes;

/// Init instance of the crypto function with the given context.
///
/// # Parameters
///
/// - `init_params`: The context or configuration parameters for the crypto function.
/// - `algorithm`: The zero-sized algorithm marker type specifying which hash function to use.
///
/// # Returns
///
/// A new instance of the hash function.
fn init(&mut self, init_params: T) -> Result<Self::OpContext<'_>, Self::Error>;
fn init(&mut self, algorithm: T) -> Result<Self::OpContext<'_>, Self::Error>;
}

/// Trait for resetting digest computation contexts.
Expand Down Expand Up @@ -748,7 +731,6 @@ pub mod owned {
/// # }
/// # impl DigestInit<Sha2_256> for MyController {
/// # type Context = MyContext;
/// # type Output = Digest<8>;
/// # fn init(self, _: Sha2_256) -> Result<Self::Context, Self::Error> { todo!() }
/// # }
/// let controller = MyController;
Expand All @@ -761,13 +743,7 @@ pub mod owned {
///
/// This context has no lifetime constraints and can be stored in structs,
/// moved between functions, and persisted across IPC boundaries.
type Context: DigestOp<Output = Self::Output, Controller = Self>;

/// The output type produced by this digest implementation.
///
/// This type must implement [`IntoBytes`] to allow conversion to byte arrays
/// for interoperability with other systems and zero-copy operations.
type Output: IntoBytes;
type Context: DigestOp<Output = T::Digest, Controller = Self>;

/// Initialize a new digest computation context.
///
Expand All @@ -776,12 +752,12 @@ pub mod owned {
///
/// # Parameters
///
/// - `init_params`: Algorithm-specific initialization parameters
/// - `algorithm`: The zero-sized algorithm marker type specifying which hash function to use.
///
/// # Returns
///
/// An owned context that can be used for digest operations.
fn init(self, init_params: T) -> Result<Self::Context, Self::Error>;
fn init(self, algorithm: T) -> Result<Self::Context, Self::Error>;
}

/// Trait for performing digest operations with owned contexts.
Expand Down
10 changes: 4 additions & 6 deletions platform/impls/baremetal/mock/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,12 @@ macro_rules! impl_scoped_sha2 {
($algo:ident) => {
impl DigestInit<$algo> for MockDigestDevice {
type OpContext<'a> = MockHasher<'a, $algo>;
type Output = <$algo as DigestAlgorithm>::Digest;

fn init(&mut self, init_params: $algo) -> Result<Self::OpContext<'_>, Self::Error> {
fn init(&mut self, algorithm: $algo) -> Result<Self::OpContext<'_>, Self::Error> {
// In a real implementation, we'd configure the hardware here
Ok(Self::OpContext {
hw: self,
_alg: init_params,
_alg: algorithm,
data_processed: 0,
})
}
Expand Down Expand Up @@ -183,14 +182,13 @@ pub mod owned {
($algo:ident) => {
impl DigestInit<$algo> for MockDigestController {
type Context = MockOwnedContext<$algo>;
type Output = <$algo as DigestAlgorithm>::Digest;

fn init(self, init_params: $algo) -> Result<Self::Context, Self::Error> {
fn init(self, algorithm: $algo) -> Result<Self::Context, Self::Error> {
// Controller moves into the context
// In hardware implementation, this might claim hardware resources
Ok(MockOwnedContext {
controller: self,
algorithm: init_params,
algorithm,
data_processed: 0,
})
}
Expand Down
3 changes: 1 addition & 2 deletions platform/impls/rustcrypto/src/cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ impl CipherInit<Aes256CtrMode> for Aes256CtrCipher {
&'a mut self,
key: &Self::Key,
nonce: &Self::Nonce,
_mode: Aes256CtrMode,
) -> Result<Self::CipherContext<'a>, Self::Error> {
// Validate key and nonce lengths (compile-time guaranteed by types)
// Create new context with the provided key and IV
Expand Down Expand Up @@ -409,7 +408,7 @@ mod tests {
#[test]
fn test_cipher_init_trait() {
let mut cipher = Aes256CtrCipher;
let result = cipher.init(&TEST_KEY, &TEST_IV, Aes256CtrMode);
let result = cipher.init(&TEST_KEY, &TEST_IV);
assert!(
result.is_ok(),
"Failed to create context via CipherInit trait"
Expand Down
5 changes: 1 addition & 4 deletions platform/impls/rustcrypto/src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl DigestError for CryptoError {
fn kind(&self) -> DigestErrorKind {
match self {
CryptoError::InvalidKeyLength => DigestErrorKind::InvalidInputLength,
CryptoError::InvalidOutputLength => DigestErrorKind::InvalidOutputSize,
CryptoError::InvalidOutputLength => DigestErrorKind::FinalizationError,
CryptoError::OperationFailed => DigestErrorKind::HardwareFailure,
}
}
Expand Down Expand Up @@ -218,7 +218,6 @@ impl MacErrorType for RustCryptoController {
// Digest initialization - creates SHA-256 context
impl DigestInit<Sha2_256> for RustCryptoController {
type Context = DigestContext256;
type Output = Digest<8>; // SHA-256 output as 8 words of 32 bits

fn init(self, _algorithm: Sha2_256) -> Result<Self::Context, Self::Error> {
Ok(DigestContext256(Sha256::new()))
Expand All @@ -228,7 +227,6 @@ impl DigestInit<Sha2_256> for RustCryptoController {
// Digest initialization - creates SHA-384 context
impl DigestInit<Sha2_384> for RustCryptoController {
type Context = DigestContext384;
type Output = Digest<12>; // SHA-384 output as 12 words of 32 bits

fn init(self, _algorithm: Sha2_384) -> Result<Self::Context, Self::Error> {
Ok(DigestContext384(Sha384::new()))
Expand All @@ -238,7 +236,6 @@ impl DigestInit<Sha2_384> for RustCryptoController {
// Digest initialization - creates SHA-512 context
impl DigestInit<Sha2_512> for RustCryptoController {
type Context = DigestContext512;
type Output = Digest<16>; // SHA-512 output as 16 words of 32 bits

fn init(self, _algorithm: Sha2_512) -> Result<Self::Context, Self::Error> {
Ok(DigestContext512(Sha512::new()))
Expand Down
11 changes: 11 additions & 0 deletions target/ast10x0/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ impl CortexMKernelConfigInterface for KernelConfig {

impl KernelConfigInterface for KernelConfig {
const SYSTEM_CLOCK_HZ: u64 = KernelConfig::SYS_TICK_HZ as u64;

// The pigweed default kernel stack is 2 KiB, which is too small for the
// bootstrap thread that runs the peripheral KAT suites. The HACE SHA-2/HMAC
// test in particular builds a single large stack frame (~3.6 KiB) plus a
// ~1.3 KiB `HaceHmacCtx` (1 KiB message buffer) and nested device locals,
// overflowing a 2 KiB stack into adjacent `.bss` (`INPUT_BUF`) and faulting
// with an unaligned access on the first case that writes that buffer
// (`sha256 stream-9000`). 16 KiB gives comfortable headroom for these
// crypto workloads. The AST10x0 has 768 KiB SRAM, so the extra kernel-stack
// RAM is negligible.
const KERNEL_STACK_SIZE_BYTES: usize = 16384;
}

pub struct NvicConfig;
Expand Down
11 changes: 11 additions & 0 deletions target/ast10x0/peripherals/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ package(default_visibility = ["//visibility:public"])
rust_library(
name = "peripherals",
srcs = [
"hace/aes.rs",
"hace/constants.rs",
"hace/context.rs",
"hace/device.rs",
"hace/digest.rs",
"hace/error.rs",
"hace/helpers.rs",
"hace/hmac.rs",
"hace/mod.rs",
"hace/registers.rs",
"i2c/constants.rs",
"i2c/controller.rs",
"i2c/error.rs",
Expand Down Expand Up @@ -77,5 +87,6 @@ rust_library(
"@rust_crates//:embedded-io",
"@rust_crates//:embedded-storage",
"@rust_crates//:nb",
"@rust_crates//:zerocopy",
],
)
Loading