diff --git a/crypto/core-test-framework/src/mac.rs b/crypto/core-test-framework/src/mac.rs index 853beea1..8430507c 100644 --- a/crypto/core-test-framework/src/mac.rs +++ b/crypto/core-test-framework/src/mac.rs @@ -116,6 +116,10 @@ impl TestFrameworkMAC { low_security_key.set_key_len(64).unwrap(); // truncate should be infallible low_security_key.set_security_strength(SecurityStrength::_192bit).unwrap(); } + // `SecurityStrength` is `#[non_exhaustive]`, so this arm is required. + _ => panic!( + "unhandled SecurityStrength variant -- add a case for it in the MAC test framework" + ), }; Ok(()) }) diff --git a/crypto/core/src/errors.rs b/crypto/core/src/errors.rs index 045fcb88..7be5197e 100644 --- a/crypto/core/src/errors.rs +++ b/crypto/core/src/errors.rs @@ -2,9 +2,14 @@ //! Errors defined in this module are typically one-to-one with traits defined in [`crate::traits`]. //! //! Most errors are self-explanatory, but additional description is available on some. +//! +//! All error enums exported from this crate are tagged `#[non_exhaustive]` to indicate that they +//! are highly likely to gain more branches in the future; therefore, the compiler is to treat it as +//! an error if a caller matches exhaustively against the current set of variants. /// #[derive(Debug)] +#[non_exhaustive] pub enum HashError { /// GenericError(&'static str), @@ -20,6 +25,7 @@ pub enum HashError { /// #[derive(Debug)] +#[non_exhaustive] pub enum KeyMaterialError { /// ActingOnZeroizedKey, @@ -39,6 +45,7 @@ pub enum KeyMaterialError { /// #[derive(Debug)] +#[non_exhaustive] pub enum KDFError { /// GenericError(&'static str), @@ -54,6 +61,7 @@ pub enum KDFError { /// #[derive(Debug)] +#[non_exhaustive] pub enum KEMError { /// GenericError(&'static str), @@ -77,6 +85,7 @@ pub enum KEMError { /// #[derive(Debug)] +#[non_exhaustive] pub enum MACError { /// GenericError(&'static str), @@ -92,6 +101,7 @@ pub enum MACError { /// #[derive(Debug)] +#[non_exhaustive] pub enum RNGError { /// GenericError(&'static str), @@ -118,6 +128,7 @@ pub enum RNGError { /// #[derive(Debug)] +#[non_exhaustive] pub enum SuspendableError { /// The serialized state was produced by a library version incompatible with this one. IncompatibleVersion, @@ -127,6 +138,7 @@ pub enum SuspendableError { /// #[derive(Debug)] +#[non_exhaustive] pub enum SignatureError { /// GenericError(&'static str), @@ -150,6 +162,7 @@ pub enum SignatureError { /// #[derive(Debug)] +#[non_exhaustive] pub enum SymmetricCipherError { /// GenericError(&'static str), diff --git a/crypto/core/src/key_material.rs b/crypto/core/src/key_material.rs index fb95d71b..1e2226b8 100644 --- a/crypto/core/src/key_material.rs +++ b/crypto/core/src/key_material.rs @@ -231,9 +231,12 @@ pub struct KeyMaterial { // `SerializableState` implementations (see the `TryFrom` impl below). Pin each value to its // variant name: reordering variants is fine, but never reuse or renumber an existing discriminant, // or previously-serialized states will be misread. -/// +/// The set of possible types of a KeyMaterial object. +/// How different tagging affects the behaviour of the KeyMaterial object will vary by the cryptographic algorithm that is consuming it. +/// Additional key types may be added in the future to accommodate new types of algorithms or use cases. #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[repr(u8)] +#[non_exhaustive] pub enum KeyType { /// The KeyMaterial is zeroized and MUST NOT be used for any cryptographic operation in this state. Zeroized = 0, diff --git a/crypto/core/src/traits.rs b/crypto/core/src/traits.rs index a06b98ce..7e23d516 100644 --- a/crypto/core/src/traits.rs +++ b/crypto/core/src/traits.rs @@ -661,6 +661,7 @@ pub trait MAC: Sized { // release as a breaking change). #[derive(Eq, PartialEq, PartialOrd, Clone, Copy, Debug)] #[repr(u8)] +#[non_exhaustive] pub enum SecurityStrength { /// None = 0, diff --git a/crypto/core/tests/key_material_tests.rs b/crypto/core/tests/key_material_tests.rs index 00957677..efcc7759 100644 --- a/crypto/core/tests/key_material_tests.rs +++ b/crypto/core/tests/key_material_tests.rs @@ -841,6 +841,8 @@ mod test_key_material { Unknown => 1, CryptographicRandom => 2, Seed | MACKey | SymmetricCipherKey => 3, + // `KeyType` is `#[non_exhaustive]`, so this arm is required. + _ => panic!("unranked KeyType variant -- add it here and to `all_types`"), } } diff --git a/crypto/factory/src/hash_factory.rs b/crypto/factory/src/hash_factory.rs index 271d729a..edbfd17a 100644 --- a/crypto/factory/src/hash_factory.rs +++ b/crypto/factory/src/hash_factory.rs @@ -37,6 +37,7 @@ use bouncycastle_sha3::{SHA3_224_NAME, SHA3_256_NAME, SHA3_384_NAME, SHA3_512_NA /// Wrapper object for all algorithms that impl [`Hash`]. /// Note: no SHAKE because SHAKE is not NIST approved as a hash function. See FIPS 202 section A.2. +#[non_exhaustive] pub enum HashFactory { /// SHA224(sha2::SHA224), diff --git a/crypto/factory/src/kdf_factory.rs b/crypto/factory/src/kdf_factory.rs index d8be55a3..b5da24e7 100644 --- a/crypto/factory/src/kdf_factory.rs +++ b/crypto/factory/src/kdf_factory.rs @@ -59,6 +59,7 @@ use bouncycastle_sha3::{ }; /// Wrapper object for all algorithms that impl [`KDF`]. +#[non_exhaustive] pub enum KDFFactory { /// #[allow(non_camel_case_types)] diff --git a/crypto/factory/src/lib.rs b/crypto/factory/src/lib.rs index 8d1c1634..10195bf7 100644 --- a/crypto/factory/src/lib.rs +++ b/crypto/factory/src/lib.rs @@ -27,6 +27,10 @@ //! //! This crate compiles with STD; ie it is explicitly not tagged as `no_std` and it makes use of `Vec` and other //! dynamically-sized nice things. +//! +//! All enums exported from this crate are tagged `#[non_exhaustive]` to indicate that they +//! are highly likely to gain more branches in the future; therefore, the compiler is to treat it as +//! an error if a caller matches exhaustively against the current set of variants. #![forbid(unsafe_code)] #![forbid(missing_docs)] @@ -49,6 +53,7 @@ pub const DEFAULT_256_BIT: &str = "Default256Bit"; /// Top-level error type for Factories. #[derive(Debug)] +#[non_exhaustive] pub enum FactoryError { /// MACError(MACError), @@ -56,6 +61,7 @@ pub enum FactoryError { UnsupportedAlgorithm(String), } +// todo -- weird that MACError is the only one that we need to promote? impl From for FactoryError { fn from(e: MACError) -> FactoryError { Self::MACError(e) diff --git a/crypto/factory/src/mac_factory.rs b/crypto/factory/src/mac_factory.rs index 4b0fce60..f9a46768 100644 --- a/crypto/factory/src/mac_factory.rs +++ b/crypto/factory/src/mac_factory.rs @@ -95,6 +95,7 @@ pub const DEFAULT_256BIT_MAC_NAME: &str = HMAC_SHA256_NAME; /// Wrapper object for all algorithms that impl [`MAC`]. /// MACFactory deviates from the usual AlgorithmFactory trait because MAC objects do not have a no-arg constructor; /// instead they have a constructor that takes a [`KeyMaterialTrait`] and can return an error. +#[non_exhaustive] pub enum MACFactory { /// HMAC_SHA224(hmac::HMAC), diff --git a/crypto/factory/src/rng_factory.rs b/crypto/factory/src/rng_factory.rs index 492efecb..14329969 100644 --- a/crypto/factory/src/rng_factory.rs +++ b/crypto/factory/src/rng_factory.rs @@ -51,6 +51,7 @@ use bouncycastle_rng as rng; use bouncycastle_rng::{HASH_DRBG_SHA256_NAME, HASH_DRBG_SHA512_NAME}; /// Wrapper object for all algorithms that impl [`RNG`]. +#[non_exhaustive] pub enum RNGFactory { /// #[allow(non_camel_case_types)] diff --git a/crypto/factory/src/xof_factory.rs b/crypto/factory/src/xof_factory.rs index 16771242..c3d97473 100644 --- a/crypto/factory/src/xof_factory.rs +++ b/crypto/factory/src/xof_factory.rs @@ -48,6 +48,7 @@ pub const DEFAULT_128BIT_XOF_NAME: &str = SHAKE128_NAME; pub const DEFAULT_256BIT_XOF_NAME: &str = SHAKE256_NAME; /// Wrapper object for all algorithms that impl [`XOF`]. +#[non_exhaustive] pub enum XOFFactory { /// SHAKE128(sha3::SHAKE128), diff --git a/crypto/mlkem/src/polynomial.rs b/crypto/mlkem/src/polynomial.rs index 40025286..f9c14e18 100644 --- a/crypto/mlkem/src/polynomial.rs +++ b/crypto/mlkem/src/polynomial.rs @@ -21,8 +21,7 @@ use crate::mlkem::{N, q}; /// It is the responsibility of the caller to wrap sensitive instances in `Secret`. #[derive(Clone, Copy)] pub struct Polynomial { - /// Note: this is exposed publicly only for testing purposes and there is no good reason to use it in production code. - pub coeffs: [i16; N], + pub(crate) coeffs: [i16; N], } /// Convenience function to avoid ".0" all over the place.