Skip to content

Commit 39f456c

Browse files
rusty1968FerralCoder
authored andcommitted
feat: Add key vault integration for ECDSA and MAC operations
- Add KeyStore, KeyLifecycle, and KeyLocking traits for key management - Implement generate_and_store_keypair function for ECDSA-vault integration - Add compute_mac_with_vault function for MAC-vault integration - Fix PrivateKey trait to use curve parameter in validate method - Export key_vault module in HAL public API Enables secure key storage integration across cryptographic modules while maintaining existing HAL design patterns.
1 parent c0102c0 commit 39f456c

File tree

4 files changed

+370
-3
lines changed

4 files changed

+370
-3
lines changed

hal/blocking/src/ecdsa.rs

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ pub trait PrivateKey<C: Curve>: Zeroize {
348348
/// - `Ok(())`: The private key is valid
349349
/// - `Err(ErrorKind::WeakKey)`: The key is zero, equal to curve order, or otherwise weak
350350
/// - `Err(ErrorKind::InvalidKeyFormat)`: The key format is invalid
351-
fn validate(&self) -> Result<(), ErrorKind>;
351+
fn validate(&self, curve: &C) -> Result<(), ErrorKind>;
352352
}
353353

354354
/// A trait representing an abstract elliptic curve with associated types for cryptographic operations.
@@ -579,18 +579,21 @@ pub trait SerializableSignature<C: Curve>: Signature<C> + IntoBytes + FromBytes
579579
/// Trait for ECDSA key generation over a specific elliptic curve.
580580
///
581581
/// This trait enables generation of cryptographically secure ECDSA key pairs
582-
/// using a cryptographic random number generator.
582+
/// using a cryptographic random number generator. Keys can be generated either
583+
/// as standalone objects or stored directly in a key vault for enhanced security.
583584
///
584585
/// # Security Requirements
585586
///
586587
/// - Must use a cryptographically secure random number generator
587588
/// - Generated keys must be uniformly distributed over the valid scalar range
588589
/// - Private keys must be properly zeroized after use
590+
/// - Key vault storage should be preferred for hardware-backed security
589591
///
590592
/// # Example
591593
///
592594
/// ```rust,ignore
593-
/// use openprot_hal_blocking::ecdsa::{EcdsaKeyGen, Curve, ErrorKind};
595+
/// use openprot_hal_blocking::ecdsa::{EcdsaKeyGen, Curve, generate_and_store_keypair};
596+
/// use openprot_hal_blocking::key_vault::{KeyLifecycle, KeyStore};
594597
/// use rand_core::{RngCore, CryptoRng};
595598
///
596599
/// struct MyKeyGenerator;
@@ -608,6 +611,20 @@ pub trait SerializableSignature<C: Curve>: Signature<C> + IntoBytes + FromBytes
608611
/// unimplemented!()
609612
/// }
610613
/// }
614+
///
615+
/// // Usage example with standalone function:
616+
/// let mut key_gen = MyKeyGenerator;
617+
/// let mut vault = MyKeyVault::new();
618+
/// let mut rng = MyRng::new();
619+
///
620+
/// let public_key = generate_and_store_keypair(
621+
/// &mut key_gen,
622+
/// &mut vault,
623+
/// KeyId::new(42),
624+
/// KeyUsage::SIGNING,
625+
/// KeyMetadata::default(),
626+
/// &mut rng
627+
/// )?;
611628
/// ```
612629
pub trait EcdsaKeyGen<C: Curve>: ErrorType {
613630
/// The type representing the private key for the curve.
@@ -630,6 +647,76 @@ pub trait EcdsaKeyGen<C: Curve>: ErrorType {
630647
R: rand_core::RngCore + rand_core::CryptoRng;
631648
}
632649

650+
/// Generates an ECDSA key pair and stores the private key in a key vault.
651+
///
652+
/// This function provides integrated key generation and secure storage, ensuring
653+
/// that private keys are immediately stored in a secure vault rather than
654+
/// being exposed in memory. Only the public key is returned to the caller.
655+
///
656+
/// # Parameters
657+
/// - `key_gen`: The key generator implementation
658+
/// - `vault`: The key vault for secure private key storage
659+
/// - `key_id`: Unique identifier for the key in the vault
660+
/// - `usage`: Usage permissions for the stored key
661+
/// - `metadata`: Additional metadata to store with the key
662+
/// - `rng`: A cryptographically secure random number generator
663+
///
664+
/// # Returns
665+
/// The generated public key (private key is securely stored in vault)
666+
///
667+
/// # Security Benefits
668+
/// - Private key is never exposed to caller
669+
/// - Immediate secure storage reduces attack surface
670+
/// - Usage permissions are set atomically with storage
671+
/// - Vault locking mechanisms can be applied immediately
672+
///
673+
/// # Example
674+
/// ```rust,ignore
675+
/// use openprot_hal_blocking::ecdsa::{generate_and_store_keypair, P256};
676+
/// use openprot_hal_blocking::key_vault::{KeyLifecycle, KeyStore};
677+
///
678+
/// let mut key_gen = MyKeyGenerator::new();
679+
/// let mut vault = MyKeyVault::new();
680+
/// let mut rng = MyRng::new();
681+
///
682+
/// let public_key = generate_and_store_keypair::<P256, _, _, _>(
683+
/// &mut key_gen,
684+
/// &mut vault,
685+
/// KeyId::new(42),
686+
/// KeyUsage::SIGNING,
687+
/// KeyMetadata::default(),
688+
/// &mut rng
689+
/// )?;
690+
/// ```
691+
pub fn generate_and_store_keypair<C, G, V, R>(
692+
key_gen: &mut G,
693+
vault: &mut V,
694+
key_id: <V as crate::key_vault::KeyStore>::KeyId,
695+
usage: <V as crate::key_vault::KeyStore>::KeyUsage,
696+
metadata: <V as crate::key_vault::KeyLifecycle>::KeyMetadata,
697+
rng: &mut R,
698+
) -> Result<G::PublicKey, G::Error>
699+
where
700+
C: Curve,
701+
G: EcdsaKeyGen<C>,
702+
R: rand_core::RngCore + rand_core::CryptoRng,
703+
V: crate::key_vault::KeyLifecycle<KeyData = G::PrivateKey> + crate::key_vault::KeyStore,
704+
<V as crate::key_vault::KeyLifecycle>::KeyId: From<<V as crate::key_vault::KeyStore>::KeyId>,
705+
G::Error: From<V::Error>,
706+
{
707+
// Generate key pair
708+
let (private_key, public_key) = key_gen.generate_keypair(rng)?;
709+
710+
// Store private key in vault with metadata
711+
let lifecycle_key_id = <V as crate::key_vault::KeyLifecycle>::KeyId::from(key_id);
712+
vault
713+
.store_key(lifecycle_key_id, private_key, metadata)
714+
.map_err(G::Error::from)?;
715+
vault.set_key_usage(key_id, usage).map_err(G::Error::from)?;
716+
717+
Ok(public_key)
718+
}
719+
633720
/// Trait for ECDSA signing using a digest algorithm.
634721
///
635722
/// This trait provides ECDSA signature generation from message digests.

hal/blocking/src/key_vault.rs

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
// Licensed under the Apache-2.0 license
2+
3+
/// Error kind for key management operations.
4+
///
5+
/// This represents a common set of key management operation errors that can occur across
6+
/// different implementations. The enum is `#[non_exhaustive]` to allow for future
7+
/// additions without breaking API compatibility.
8+
///
9+
/// Implementations are free to define more specific or additional error types.
10+
/// However, by providing a mapping to these common errors through the [`Error::kind`]
11+
/// method, generic code can still react to them appropriately.
12+
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
13+
#[non_exhaustive]
14+
pub enum ErrorKind {
15+
/// The operation is busy and cannot be completed
16+
///
17+
/// This indicates that the hardware or implementation is currently
18+
/// busy with another operation. The caller should retry later.
19+
Busy,
20+
21+
/// The specified key was not found
22+
///
23+
/// Returned when attempting to access a key that does not exist
24+
/// in the storage backend.
25+
KeyNotFound,
26+
27+
/// Access to the key was denied
28+
///
29+
/// This could indicate insufficient permissions, key usage policy
30+
/// violations, or other access control restrictions.
31+
AccessDenied,
32+
33+
/// Invalid key usage specification
34+
///
35+
/// Returned when the specified key usage constraints are invalid
36+
/// or incompatible with the key or storage backend.
37+
InvalidUsage,
38+
39+
/// Hardware fault or failure
40+
///
41+
/// Indicates a hardware-level error in secure storage elements,
42+
/// HSMs, or other hardware-backed key storage.
43+
HardwareFault,
44+
45+
/// Other implementation-specific error
46+
///
47+
/// Catch-all for errors that don't fit other categories.
48+
Other,
49+
}
50+
51+
impl core::fmt::Display for ErrorKind {
52+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
53+
match self {
54+
Self::Busy => write!(f, "key storage hardware is busy"),
55+
Self::KeyNotFound => write!(f, "specified key was not found"),
56+
Self::AccessDenied => write!(f, "access to key was denied"),
57+
Self::InvalidUsage => write!(f, "invalid key usage specification"),
58+
Self::HardwareFault => write!(f, "hardware fault during key operation"),
59+
Self::Other => write!(f, "key management operation failed"),
60+
}
61+
}
62+
}
63+
/// Common interface for key management errors.
64+
///
65+
/// This trait provides a standardized way to categorize and handle errors
66+
/// from different key management implementations.
67+
pub trait Error: core::fmt::Debug {
68+
/// Convert error to a generic error kind
69+
///
70+
/// By using this method, errors freely defined by HAL implementations
71+
/// can be converted to a set of generic errors upon which generic
72+
/// code can act.
73+
fn kind(&self) -> ErrorKind;
74+
}
75+
76+
/// Trait for associating a type with a key management error type.
77+
///
78+
/// This trait is used throughout the key management module to associate operations
79+
/// with their specific error types while maintaining type safety.
80+
pub trait ErrorType {
81+
/// Error type.
82+
type Error: Error;
83+
}
84+
85+
/// Configuration and setup operations for key vaults
86+
///
87+
/// This trait provides methods for configuring key vault implementations
88+
/// with runtime parameters and checking their configuration state.
89+
pub trait KeyVaultSetup: ErrorType {
90+
/// Configuration type for the key vault
91+
///
92+
/// This type contains all the runtime parameters needed to configure
93+
/// the key vault implementation.
94+
type KeyVaultConfig;
95+
96+
/// Configure the key vault with runtime parameters
97+
///
98+
/// This method applies the provided configuration to the key vault,
99+
/// setting up any necessary resources, security policies, or hardware
100+
/// initialization required for operation.
101+
///
102+
/// # Parameters
103+
///
104+
/// - `config`: Configuration parameters specific to this key vault implementation
105+
///
106+
/// # Errors
107+
///
108+
/// - `ErrorKind::InvalidUsage`: Invalid configuration parameters
109+
/// - `ErrorKind::HardwareFault`: Hardware initialization failed
110+
/// - `ErrorKind::AccessDenied`: Insufficient permissions for configuration
111+
/// - `ErrorKind::Busy`: Key vault is currently busy and cannot be reconfigured
112+
fn configure(&mut self, config: Self::KeyVaultConfig) -> Result<(), Self::Error>;
113+
114+
/// Check if the key vault is properly configured
115+
///
116+
/// Returns `true` if the key vault has been successfully configured
117+
/// and is ready for key operations, `false` otherwise.
118+
///
119+
/// # Note
120+
///
121+
/// This method is infallible as it only checks internal state.
122+
/// It does not perform any hardware operations that could fail.
123+
fn is_configured(&self) -> bool;
124+
}
125+
126+
/// Core key vault operations
127+
pub trait KeyStore: ErrorType {
128+
/// Type representing a key identifier
129+
type KeyId: Copy + Clone + PartialEq + Eq;
130+
/// Type representing key usage permissions
131+
type KeyUsage: Copy + Clone + PartialEq + Eq;
132+
133+
/// Erase a specific key
134+
fn erase_key(&mut self, id: Self::KeyId) -> Result<(), Self::Error>;
135+
136+
/// Erase all keys that are not locked
137+
fn erase_all_keys(&mut self) -> Result<(), Self::Error>;
138+
139+
/// Check if a key exists and is valid
140+
fn key_exists(&self, id: Self::KeyId) -> Result<bool, Self::Error>;
141+
142+
/// Get the usage permissions for a key
143+
fn get_key_usage(&self, id: Self::KeyId) -> Result<Self::KeyUsage, Self::Error>;
144+
145+
/// Set the usage permissions for a key
146+
fn set_key_usage(&mut self, id: Self::KeyId, usage: Self::KeyUsage) -> Result<(), Self::Error>;
147+
}
148+
149+
/// Key locking mechanisms for security
150+
pub trait KeyLocking: ErrorType {
151+
/// Type representing a key identifier
152+
type KeyId: Copy + Clone + PartialEq + Eq;
153+
154+
/// Check if key has write lock
155+
fn is_write_locked(&self, id: Self::KeyId) -> Result<bool, Self::Error>;
156+
157+
/// Set write lock on key
158+
fn set_write_lock(&mut self, id: Self::KeyId) -> Result<(), Self::Error>;
159+
160+
/// Clear write lock on key
161+
fn clear_write_lock(&mut self, id: Self::KeyId) -> Result<(), Self::Error>;
162+
163+
/// Check if key has use lock
164+
fn is_use_locked(&self, id: Self::KeyId) -> Result<bool, Self::Error>;
165+
166+
/// Set use lock on key
167+
fn set_use_lock(&mut self, id: Self::KeyId) -> Result<(), Self::Error>;
168+
169+
/// Clear use lock on key
170+
fn clear_use_lock(&mut self, id: Self::KeyId) -> Result<(), Self::Error>;
171+
}
172+
173+
/// Key lifecycle management
174+
/// Complete key lifecycle from creation to retrieval
175+
pub trait KeyLifecycle: ErrorType {
176+
/// Type representing a key identifier
177+
type KeyId: Copy + Clone + PartialEq + Eq;
178+
179+
/// Type representing key data
180+
type KeyData;
181+
182+
/// Type representing key metadata
183+
type KeyMetadata;
184+
185+
/// Store a key with metadata
186+
fn store_key(
187+
&mut self,
188+
id: Self::KeyId,
189+
data: Self::KeyData,
190+
metadata: Self::KeyMetadata,
191+
) -> Result<(), Self::Error>;
192+
193+
/// Retrieve key data (if permitted)
194+
fn retrieve_key(&self, id: Self::KeyId) -> Result<Self::KeyData, Self::Error>;
195+
196+
/// Get key metadata
197+
fn get_key_metadata(&self, id: Self::KeyId) -> Result<Self::KeyMetadata, Self::Error>;
198+
199+
/// Update key metadata
200+
fn update_key_metadata(
201+
&mut self,
202+
id: Self::KeyId,
203+
metadata: Self::KeyMetadata,
204+
) -> Result<(), Self::Error>;
205+
}
206+
207+
/// Blanket trait implementation for types that implement key vsault setup, core operations, and locking
208+
pub trait KeyVault: KeyVaultSetup + KeyStore + KeyLocking {}
209+
impl<T> KeyVault for T where T: KeyVaultSetup + KeyStore + KeyLocking {}

hal/blocking/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ pub mod mac;
2929
/// Reset and clocking traits for OpenPRoT HAL
3030
pub mod system_control;
3131

32+
/// Key management traits
33+
pub mod key_vault;
34+
3235
// Re-export embedded-hal 1.0 traits
3336
pub use embedded_hal::delay::DelayNs;
3437
pub use embedded_hal::digital::{InputPin, OutputPin, StatefulOutputPin};

0 commit comments

Comments
 (0)