diff --git a/Cargo.toml b/Cargo.toml index 46060dc..876e261 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,20 +15,45 @@ edition = "2021" # This is slightly mumbo-jumboey, but in short: # Features with a -resolver suffix simply enables the existence of a specific resolver, # and -accelerated suffix means that this resolver will be the default used by the Builder. +# +# If default features are disabled and default-resolver is used, required crypto primitives +# must be enabled individually. [features] -default = ["default-resolver"] -default-resolver = ["aes-gcm", "chacha20poly1305", "blake2", "sha2", "curve25519-dalek"] +default = ["default-resolver", "default-resolver-crypto", "std"] +default-resolver = [] +default-resolver-crypto = ["use-aes-gcm", "use-chacha20poly1305", "use-blake2", "use-sha2", "use-curve25519-dalek"] nightly = ["blake2/simd_opt", "subtle/nightly"] -ring-resolver = ["ring"] -ring-accelerated = ["ring-resolver", "default-resolver"] -libsodium-resolver = ["sodiumoxide", "byteorder"] -libsodium-accelerated = ["libsodium-resolver", "default-resolver"] +ring-resolver = ["ring", "std"] +ring-accelerated = ["ring-resolver", "default-resolver", "std"] +libsodium-resolver = ["sodiumoxide", "byteorder", "std"] +libsodium-accelerated = ["libsodium-resolver", "default-resolver", "std"] vector-tests = [] hfs = [] -pqclean_kyber1024 = ["pqcrypto-kyber", "pqcrypto-traits", "hfs", "default-resolver"] -xchachapoly = ["chacha20poly1305", "default-resolver"] risky-raw-split = [] +# Backwards-compatibility aliases +pqclean_kyber1024 = ["use-pqcrypto-kyber1024"] +xchachapoly = ["use-xchacha20poly1305"] + +# Enable std features on dependencies if possible. +std = [ + "rand_core/std", + "subtle/std", + "ring/std", + "blake2/std", + "sha2/std", + "byteorder/std", + ] + +# Crypto primitives for default-resolver. +use-curve25519-dalek = ["curve25519-dalek", "default-resolver"] +use-chacha20poly1305 = ["chacha20poly1305", "default-resolver"] +use-xchacha20poly1305 = ["chacha20poly1305", "default-resolver"] +use-blake2 = ["blake2", "default-resolver"] +use-sha2 = ["sha2", "default-resolver"] +use-aes-gcm = ["aes-gcm", "default-resolver"] +use-pqcrypto-kyber1024 = ["pqcrypto-kyber", "pqcrypto-traits", "hfs", "default-resolver"] + [[bench]] name = "benches" harness = false @@ -37,24 +62,24 @@ harness = false travis-ci = { repository = "mcginty/snow", branch = "master" } [dependencies] -rand_core = { version = "0.6", features = ["std", "getrandom"] } -subtle = "2.4" +rand_core = { version = "0.6", default-features = false, features = ["getrandom"] } +subtle = { version = "2.4", default-features = false } # default crypto provider -aes-gcm = { version = "0.10", optional = true } -chacha20poly1305 = { version = "0.10", optional = true } -blake2 = { version = "0.10", optional = true } -sha2 = { version = "0.10", optional = true } -curve25519-dalek = { version = "4", optional = true } +aes-gcm = { version = "0.10", optional = true, default-features = false, features = ["aes"] } +chacha20poly1305 = { version = "0.10", optional = true, default-features = false } +blake2 = { version = "0.10", optional = true, default-features = false } +sha2 = { version = "0.10", optional = true, default-features = false } +curve25519-dalek = { version = "4", optional = true, default-features = false } pqcrypto-kyber = { version = "0.8", optional = true } pqcrypto-traits = { version = "0.3", optional = true } # ring crypto provider -ring = { version = "0.17", optional = true, features = ["std"] } +ring = { version = "0.17", optional = true } # libsodium crypto provider -sodiumoxide = { version = "0.2", optional = true } -byteorder = { version = "1.4", optional = true } +sodiumoxide = { version = "0.2", optional = true, default-features = false } +byteorder = { version = "1.4", optional = true, default-features = false } [dev-dependencies] criterion = "0.5" diff --git a/README.md b/README.md index 6e2226c..7a3b682 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,69 @@ crypto implementations when available. | BLAKE2s | ✔ | | | BLAKE2b | ✔ | | +## `no_std` support and feature selection + +Snow can be used in `no_std` environments if `alloc` is provided. + +By default Snow uses the standard library, default cyprot resolver and a selected collection +of crypto primitives. To use Snow in `no_std` environments or make other kinds of customized +setups, use Snow with `default-features = false`. This way you will individually select +the components you wish to use. `default-resolver` is the only built-in resolver that +currently supports `no_std`. + +To use a custom setup with `default-resolver`, enable your desired selection of cryptographic primitives: + +| Primitive | Feature flag | +| :----------- | ---------------------: | +| **DH** | +| 25519 | `use-curve25519-dalek` | +| **Cipher** | +| AESGCM | `use-aes-gcm` | +| ChaChaPoly | `use-chacha20poly1305` | +| XChaChaPoly* | `use-xchacha20poly1305`| +| **Hash** | +| SHA256 | `use-sha2` | +| SHA512 | `use-sha2` | +| BLAKE2s | `use-blake2` | +| BLAKE2b | `use-blake2` | + +\* *XChaChaPoly*, an extended nonce variant of *ChaChaPoly*, is not in the official specification of Noise! + +### Example configurations + +**25519 + AES-GCM + SHA** with standard library features. +```toml +default-features = false +features = [ + "use-curve25519-dalek", + "use-aes-gcm", + "use-sha2", + "std", +] +``` + +**25519 + ChaChaPoly + BLAKE2** without standard library. +```toml +default-features = false +features = [ + "use-curve25519-dalek", + "use-chacha20poly1305", + "use-blake2", +] +``` + +### `getrandom` support + +Most crypto implementations supported by `default-resolver` will require +[`getrandom`](getrandom). + +If your target platform is not directly supported +you might have to provide a custom implementation in your crate root. +Check out their [documentation](getrandom-custom) for details. + +[getrandom]: https://crates.io/crates/getrandom +[getrandom-custom]: https://docs.rs/getrandom/0.2.15/getrandom/macro.register_custom_getrandom.html + ## License Licensed under either of: diff --git a/ci-tests.sh b/ci-tests.sh index a49562d..e9e1725 100755 --- a/ci-tests.sh +++ b/ci-tests.sh @@ -7,12 +7,15 @@ COMMON_FEATURES="xchachapoly vector-tests" set -x cargo check --benches cargo test $TARGET --no-default-features -cargo test $TARGET --features "$COMMON_FEATURES" +# Custom set of crypto without std +cargo test $TARGET --no-default-features --features "default-resolver use-curve25519-dalek use-blake2 use-chacha20poly1305" +# Custom set of crypto with std +cargo test $TARGET --no-default-features --features "default-resolver use-curve25519-dalek use-sha2 use-chacha20poly1305" cargo test $TARGET --features "ring-resolver $COMMON_FEATURES" cargo test $TARGET --features "ring-accelerated $COMMON_FEATURES" if ! rustc -vV | grep 'host: .*windows' &> /dev/null; then - cargo test $TARGET --features "hfs pqclean_kyber1024 $COMMON_FEATURES" - cargo test $TARGET --features "ring-resolver hfs pqclean_kyber1024 $COMMON_FEATURES" + cargo test $TARGET --features "hfs use-pqcrypto-kyber1024 $COMMON_FEATURES" + cargo test $TARGET --features "ring-resolver hfs use-pqcrypto-kyber1024 $COMMON_FEATURES" fi cargo test $TARGET --features "libsodium-resolver $COMMON_FEATURES" cargo test $TARGET --features "libsodium-accelerated $COMMON_FEATURES" diff --git a/src/builder.rs b/src/builder.rs index 07f8aaf..df5aa3f 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1,4 +1,7 @@ -use std::fmt::Debug; +use core::fmt::Debug; + +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, vec, vec::Vec}; #[cfg(feature = "hfs")] use crate::params::HandshakeModifier; @@ -45,7 +48,7 @@ impl PartialEq for Keypair { /// # use snow::Builder; /// # let my_long_term_key = [0u8; 32]; /// # let their_pub_key = [0u8; 32]; -/// # #[cfg(any(feature = "default-resolver", feature = "ring-accelerated"))] +/// # #[cfg(any(feature = "default-resolver-crypto", feature = "ring-accelerated"))] /// let noise = Builder::new("Noise_XX_25519_ChaChaPoly_BLAKE2s".parse()?) /// .local_private_key(&my_long_term_key)? /// .remote_public_key(&their_pub_key)? @@ -65,7 +68,7 @@ pub struct Builder<'builder> { } impl<'builder> Debug for Builder<'builder> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("Builder").field("params", &self.params.name).finish_non_exhaustive() } } @@ -317,8 +320,12 @@ impl<'builder> Builder<'builder> { } } + #[cfg(test)] -#[cfg(any(feature = "default-resolver", feature = "ring-accelerated"))] +#[cfg(all( + feature = "std", + any(feature = "default-resolver-crypto", feature = "ring-accelerated") +))] mod tests { use super::*; type TestResult = Result<(), Box>; diff --git a/src/cipherstate.rs b/src/cipherstate.rs index fa29dc4..d065d1a 100644 --- a/src/cipherstate.rs +++ b/src/cipherstate.rs @@ -1,3 +1,6 @@ +#[cfg(not(feature = "std"))] +use alloc::boxed::Box; + use crate::{ constants::{CIPHERKEYLEN, TAGLEN}, error::{Error, InitStage, StateProblem}, diff --git a/src/error.rs b/src/error.rs index 8734ec4..acda40f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,6 @@ //! All error types used by Snow operations. -use std::fmt; +use core::fmt; /// `snow` provides decently detailed errors, exposed as the [`Error`] enum, /// to allow developers to react to errors in a more actionable way. @@ -181,4 +181,5 @@ impl fmt::Display for Error { } } +#[cfg(feature = "std")] impl std::error::Error for Error {} diff --git a/src/handshakestate.rs b/src/handshakestate.rs index 671b55d..69dd17e 100644 --- a/src/handshakestate.rs +++ b/src/handshakestate.rs @@ -15,7 +15,9 @@ use crate::{ types::{Dh, Hash, Random}, utils::Toggle, }; -use std::{ +#[cfg(not(feature = "std"))] +use alloc::boxed::Box; +use core::{ convert::{TryFrom, TryInto}, fmt, }; diff --git a/src/lib.rs b/src/lib.rs index 53365dc..4db71e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,7 @@ //! ``` //! # use snow::Error; //! # -//! # #[cfg(any(feature = "default-resolver", feature = "ring-accelerated"))] +//! # #[cfg(any(feature = "default-resolver-crypto", feature = "ring-accelerated"))] //! # fn try_main() -> Result<(), Error> { //! static PATTERN: &'static str = "Noise_NN_25519_ChaChaPoly_BLAKE2s"; //! @@ -43,7 +43,7 @@ //! # Ok(()) //! # } //! # -//! # #[cfg(not(any(feature = "default-resolver", feature = "ring-accelerated")))] +//! # #[cfg(not(any(feature = "default-resolver-crypto", feature = "ring-accelerated")))] //! # fn try_main() -> Result<(), ()> { Ok(()) } //! # //! # fn main() { @@ -54,6 +54,26 @@ //! See `examples/simple.rs` for a more complete TCP client/server example with static keys. #![warn(missing_docs)] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(not(feature = "std"))] +extern crate alloc; + +// Make sure the user is running a supported configuration. +#[cfg(feature = "default-resolver")] +#[cfg(any( + not(any(feature = "use-curve25519-dalek")), + not(any( + feature = "use-aes-gcm", + feature = "use-chacha20poly1305", + feature = "use-xchacha20poly1305" + )), + not(any(feature = "use-sha2", feature = "use-blake2")) +))] +compile_error!( + "Valid selection of crypto primitived must be enabled when using feature 'default-resolver'. + Enable at least one DH feature, one Cipher feature and one Hash feature. Check README.md for details." +); macro_rules! copy_slices { ($inslice:expr, $outslice:expr) => { diff --git a/src/params/mod.rs b/src/params/mod.rs index f8d7463..5dbd8a5 100644 --- a/src/params/mod.rs +++ b/src/params/mod.rs @@ -4,8 +4,11 @@ //! All structures related to Noise parameter definitions (cryptographic primitive choices, protocol //! patterns/names) +#[cfg(not(feature = "std"))] +use alloc::{borrow::ToOwned, string::String}; + use crate::error::{Error, PatternProblem}; -use std::str::FromStr; +use core::str::FromStr; mod patterns; pub use self::patterns::{ @@ -61,7 +64,7 @@ impl FromStr for DHChoice { pub enum CipherChoice { /// The ChaCha20Poly1305 AEAD. ChaChaPoly, - #[cfg(feature = "xchachapoly")] + #[cfg(feature = "use-xchacha20poly1305")] /// The XChaCha20Poly1305 AEAD, an extended nonce variant of ChaCha20Poly1305. /// This variant is hidden behind a feature flag to highlight that it is not in the /// official specification of the Noise Protocol. @@ -77,7 +80,7 @@ impl FromStr for CipherChoice { use self::CipherChoice::*; match s { "ChaChaPoly" => Ok(ChaChaPoly), - #[cfg(feature = "xchachapoly")] + #[cfg(feature = "use-xchacha20poly1305")] "XChaChaPoly" => Ok(XChaChaPoly), "AESGCM" => Ok(AESGCM), _ => Err(PatternProblem::UnsupportedCipherType.into()), @@ -257,7 +260,7 @@ impl FromStr for NoiseParams { #[cfg(test)] mod tests { use super::*; - use std::convert::TryFrom; + use core::convert::TryFrom; #[test] fn test_simple_handshake() { diff --git a/src/params/patterns.rs b/src/params/patterns.rs index ffff241..a279071 100644 --- a/src/params/patterns.rs +++ b/src/params/patterns.rs @@ -1,7 +1,10 @@ #![allow(clippy::enum_glob_use)] +#[cfg(not(feature = "std"))] +use alloc::{vec, vec::Vec}; + use crate::error::{Error, PatternProblem}; -use std::{convert::TryFrom, str::FromStr}; +use core::{convert::TryFrom, str::FromStr}; /// A small helper macro that behaves similar to the `vec![]` standard macro, /// except it allocates a bit extra to avoid resizing. diff --git a/src/resolvers/default.rs b/src/resolvers/default.rs index 93ed5b6..dce7e34 100644 --- a/src/resolvers/default.rs +++ b/src/resolvers/default.rs @@ -1,26 +1,51 @@ -use blake2::{Blake2b, Blake2b512, Blake2s, Blake2s256}; -#[cfg(feature = "xchachapoly")] -use chacha20poly1305::XChaCha20Poly1305; -use chacha20poly1305::{aead::AeadInPlace, ChaCha20Poly1305, KeyInit}; +#[cfg(not(feature = "std"))] +use alloc::boxed::Box; + +// DH +#[cfg(feature = "use-curve25519-dalek")] use curve25519_dalek::montgomery::MontgomeryPoint; -#[cfg(feature = "pqclean_kyber1024")] + +// Hashes +#[cfg(feature = "use-blake2")] +use blake2::{Blake2b, Blake2b512, Blake2s, Blake2s256, Digest as BlakeDigest}; +#[cfg(feature = "use-sha2")] +#[allow(unused)] +// `blake2` and `sha2` both try to export `digest::Digest`. +// We will import those with different aliases to prevent name clashes. +use sha2::{Digest as ShaDigest, Sha256, Sha512}; + + +// Ciphers +#[cfg(feature = "use-chacha20poly1305")] +use chacha20poly1305::ChaCha20Poly1305; +#[cfg(feature = "use-xchacha20poly1305")] +use chacha20poly1305::XChaCha20Poly1305; + +#[cfg(any(feature = "use-chacha20poly1305", feature = "use-xchacha20poly1305"))] +use chacha20poly1305::{aead::AeadInPlace, KeyInit}; + +#[cfg(feature = "use-aes-gcm")] +use aes_gcm::Aes256Gcm; + + +// PQ +#[cfg(feature = "use-pqcrypto-kyber1024")] +use crate::params::KemChoice; +#[cfg(feature = "use-pqcrypto-kyber1024")] +use crate::types::Kem; +#[cfg(feature = "use-pqcrypto-kyber1024")] use pqcrypto_kyber::kyber1024; -#[cfg(feature = "pqclean_kyber1024")] +#[cfg(feature = "use-pqcrypto-kyber1024")] use pqcrypto_traits::kem::{Ciphertext, PublicKey, SecretKey, SharedSecret}; -use rand_core::OsRng; -use sha2::{Digest, Sha256, Sha512}; use super::CryptoResolver; -#[cfg(feature = "pqclean_kyber1024")] -use crate::params::KemChoice; -#[cfg(feature = "pqclean_kyber1024")] -use crate::types::Kem; use crate::{ constants::{CIPHERKEYLEN, TAGLEN}, params::{CipherChoice, DHChoice, HashChoice}, types::{Cipher, Dh, Hash, Random}, Error, }; +use rand_core::OsRng; /// The default resolver provided by snow. This resolver is designed to /// support as many of the Noise spec primitives as possible with @@ -36,30 +61,41 @@ impl CryptoResolver for DefaultResolver { fn resolve_dh(&self, choice: &DHChoice) -> Option> { match *choice { + #[cfg(feature = "use-curve25519-dalek")] DHChoice::Curve25519 => Some(Box::::default()), - DHChoice::Curve448 => None, + _ => None, } } + #[allow(unreachable_patterns)] fn resolve_hash(&self, choice: &HashChoice) -> Option> { match *choice { + #[cfg(feature = "use-sha2")] HashChoice::SHA256 => Some(Box::::default()), + #[cfg(feature = "use-sha2")] HashChoice::SHA512 => Some(Box::::default()), + #[cfg(feature = "use-blake2")] HashChoice::Blake2s => Some(Box::::default()), + #[cfg(feature = "use-blake2")] HashChoice::Blake2b => Some(Box::::default()), + _ => None, } } + #[allow(unreachable_patterns)] fn resolve_cipher(&self, choice: &CipherChoice) -> Option> { match *choice { + #[cfg(feature = "use-chacha20poly1305")] CipherChoice::ChaChaPoly => Some(Box::::default()), - #[cfg(feature = "xchachapoly")] + #[cfg(feature = "use-xchacha20poly1305")] CipherChoice::XChaChaPoly => Some(Box::new(CipherXChaChaPoly::default())), + #[cfg(feature = "use-aes-gcm")] CipherChoice::AESGCM => Some(Box::::default()), + _ => None, } } - #[cfg(feature = "pqclean_kyber1024")] + #[cfg(feature = "use-pqcrypto-kyber1024")] fn resolve_kem(&self, choice: &KemChoice) -> Option> { match *choice { KemChoice::Kyber1024 => Some(Box::new(Kyber1024::default())), @@ -68,6 +104,7 @@ impl CryptoResolver for DefaultResolver { } /// Wraps x25519-dalek. +#[cfg(feature = "use-curve25519-dalek")] #[derive(Default)] struct Dh25519 { privkey: [u8; 32], @@ -75,48 +112,54 @@ struct Dh25519 { } /// Wraps `aes-gcm`'s AES256-GCM implementation. +#[cfg(feature = "use-aes-gcm")] #[derive(Default)] struct CipherAesGcm { key: [u8; CIPHERKEYLEN], } /// Wraps `chacha20_poly1305_aead`'s `ChaCha20Poly1305` implementation. +#[cfg(feature = "use-chacha20poly1305")] #[derive(Default)] struct CipherChaChaPoly { key: [u8; CIPHERKEYLEN], } /// Wraps `chachapoly1305`'s XChaCha20Poly1305 implementation. -#[cfg(feature = "xchachapoly")] +#[cfg(feature = "use-xchacha20poly1305")] #[derive(Default)] struct CipherXChaChaPoly { key: [u8; CIPHERKEYLEN], } /// Wraps `RustCrypto`'s SHA-256 implementation. +#[cfg(feature = "use-sha2")] struct HashSHA256 { hasher: Sha256, } /// Wraps `RustCrypto`'s SHA-512 implementation. +#[cfg(feature = "use-sha2")] struct HashSHA512 { hasher: Sha512, } /// Wraps `blake2-rfc`'s implementation. +#[cfg(feature = "use-blake2")] #[derive(Default)] struct HashBLAKE2b { hasher: Blake2b512, } /// Wraps `blake2-rfc`'s implementation. +#[cfg(feature = "use-blake2")] #[derive(Default)] struct HashBLAKE2s { hasher: Blake2s256, } /// Wraps `kyber1024`'s implementation -#[cfg(feature = "pqclean_kyber1024")] +#[cfg(feature = "use-pqcrypto-kyber1024")] struct Kyber1024 { privkey: kyber1024::SecretKey, pubkey: kyber1024::PublicKey, @@ -124,6 +167,7 @@ struct Kyber1024 { impl Random for OsRng {} +#[cfg(feature = "use-curve25519-dalek")] impl Dh25519 { fn derive_pubkey(&mut self) { let point = MontgomeryPoint::mul_base_clamped(self.privkey); @@ -131,6 +175,7 @@ impl Dh25519 { } } +#[cfg(feature = "use-curve25519-dalek")] impl Dh for Dh25519 { fn name(&self) -> &'static str { "25519" @@ -175,6 +220,7 @@ impl Dh for Dh25519 { } } +#[cfg(feature = "use-aes-gcm")] impl Cipher for CipherAesGcm { fn name(&self) -> &'static str { "AESGCM" @@ -185,7 +231,7 @@ impl Cipher for CipherAesGcm { } fn encrypt(&self, nonce: u64, authtext: &[u8], plaintext: &[u8], out: &mut [u8]) -> usize { - let aead = aes_gcm::Aes256Gcm::new(&self.key.into()); + let aead = Aes256Gcm::new(&self.key.into()); let mut nonce_bytes = [0u8; 12]; copy_slices!(nonce.to_be_bytes(), &mut nonce_bytes[4..]); @@ -228,6 +274,7 @@ impl Cipher for CipherAesGcm { } } +#[cfg(feature = "use-chacha20poly1305")] impl Cipher for CipherChaChaPoly { fn name(&self) -> &'static str { "ChaChaPoly" @@ -279,7 +326,7 @@ impl Cipher for CipherChaChaPoly { } } -#[cfg(feature = "xchachapoly")] +#[cfg(feature = "use-xchacha20poly1305")] impl Cipher for CipherXChaChaPoly { fn name(&self) -> &'static str { "XChaChaPoly" @@ -331,12 +378,14 @@ impl Cipher for CipherXChaChaPoly { } } +#[cfg(feature = "use-sha2")] impl Default for HashSHA256 { fn default() -> HashSHA256 { HashSHA256 { hasher: Sha256::new() } } } +#[cfg(feature = "use-sha2")] impl Hash for HashSHA256 { fn block_len(&self) -> usize { 64 @@ -364,12 +413,14 @@ impl Hash for HashSHA256 { } } +#[cfg(feature = "use-sha2")] impl Default for HashSHA512 { fn default() -> HashSHA512 { HashSHA512 { hasher: Sha512::new() } } } +#[cfg(feature = "use-sha2")] impl Hash for HashSHA512 { fn name(&self) -> &'static str { "SHA512" @@ -397,6 +448,7 @@ impl Hash for HashSHA512 { } } +#[cfg(feature = "use-blake2")] impl Hash for HashBLAKE2b { fn name(&self) -> &'static str { "BLAKE2b" @@ -424,6 +476,7 @@ impl Hash for HashBLAKE2b { } } +#[cfg(feature = "use-blake2")] impl Hash for HashBLAKE2s { fn name(&self) -> &'static str { "BLAKE2s" @@ -451,7 +504,7 @@ impl Hash for HashBLAKE2s { } } -#[cfg(feature = "pqclean_kyber1024")] +#[cfg(feature = "use-pqcrypto-kyber1024")] impl Default for Kyber1024 { fn default() -> Self { Kyber1024 { @@ -461,7 +514,7 @@ impl Default for Kyber1024 { } } -#[cfg(feature = "pqclean_kyber1024")] +#[cfg(feature = "use-pqcrypto-kyber1024")] impl Kem for Kyber1024 { fn name(&self) -> &'static str { "Kyber1024" @@ -521,11 +574,16 @@ impl Kem for Kyber1024 { } #[cfg(test)] +#[allow(unused)] mod tests { use super::*; use hex::FromHex; + #[cfg(not(feature = "std"))] + use alloc::vec::Vec; + #[test] + #[cfg(feature = "use-sha2")] fn test_sha256() { let mut output = [0u8; 32]; let mut hasher = HashSHA256::default(); @@ -538,6 +596,7 @@ mod tests { } #[test] + #[cfg(feature = "use-sha2")] fn test_hmac_sha256_sha512() { let key = Vec::::from_hex("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(); let data = Vec::::from_hex( @@ -565,6 +624,7 @@ mod tests { } #[test] + #[cfg(feature = "use-blake2")] fn test_blake2b() { // BLAKE2b test - draft-saarinen-blake2-06 let mut output = [0u8; 64]; @@ -581,6 +641,7 @@ mod tests { } #[test] + #[cfg(feature = "use-blake2")] fn test_blake2s() { // BLAKE2s test - draft-saarinen-blake2-06 let mut output = [0u8; 32]; @@ -595,6 +656,7 @@ mod tests { } #[test] + #[cfg(feature = "use-curve25519-dalek")] fn test_curve25519() { // Curve25519 test - draft-curves-10 let mut keypair = Dh25519::default(); @@ -614,6 +676,7 @@ mod tests { } #[test] + #[cfg(feature = "use-aes-gcm")] fn test_aesgcm() { // AES256-GCM tests - gcm-spec.pdf // Test Case 13 @@ -656,6 +719,7 @@ mod tests { } #[test] + #[cfg(feature = "use-chacha20poly1305")] fn test_chachapoly_empty() { //ChaChaPoly round-trip test, empty plaintext let key = [0u8; 32]; @@ -677,6 +741,7 @@ mod tests { } #[test] + #[cfg(feature = "use-chacha20poly1305")] fn test_chachapoly_nonempty() { //ChaChaPoly round-trip test, non-empty plaintext let key = [0u8; 32]; @@ -695,8 +760,8 @@ mod tests { assert!(hex::encode(resulttext) == hex::encode(plaintext)); } - #[cfg(feature = "xchachapoly")] #[test] + #[cfg(feature = "use-xchacha20poly1305")] fn test_xchachapoly_nonempty() { //XChaChaPoly round-trip test, non-empty plaintext let key = [0u8; 32]; @@ -716,6 +781,7 @@ mod tests { } #[test] + #[cfg(feature = "use-chacha20poly1305")] fn test_chachapoly_known_answer() { //ChaChaPoly known-answer test - RFC 7539 let key = <[u8; 32]>::from_hex( @@ -782,7 +848,7 @@ mod tests { } #[test] - #[cfg(feature = "pqclean_kyber1024")] + #[cfg(feature = "use-pqcrypto-kyber1024")] fn test_kyber1024() { let mut rng = OsRng::default(); let mut kem_1 = Kyber1024::default(); @@ -805,7 +871,7 @@ mod tests { } #[test] - #[cfg(feature = "pqclean_kyber1024")] + #[cfg(feature = "use-pqcrypto-kyber1024")] fn test_kyber1024_fail() { let mut rng = OsRng::default(); let mut kem_1 = Kyber1024::default(); diff --git a/src/resolvers/mod.rs b/src/resolvers/mod.rs index e6c15dd..66d988f 100644 --- a/src/resolvers/mod.rs +++ b/src/resolvers/mod.rs @@ -1,5 +1,8 @@ //! The wrappers around the default collection of cryptography and entropy providers. +#[cfg(not(feature = "std"))] +use alloc::boxed::Box; + /// The default primitive resolver. #[cfg(feature = "default-resolver")] mod default; diff --git a/src/resolvers/ring.rs b/src/resolvers/ring.rs index 83180fb..8af880b 100644 --- a/src/resolvers/ring.rs +++ b/src/resolvers/ring.rs @@ -39,7 +39,7 @@ impl CryptoResolver for RingResolver { match *choice { CipherChoice::AESGCM => Some(Box::new(CipherAESGCM::default())), CipherChoice::ChaChaPoly => Some(Box::new(CipherChaChaPoly::default())), - #[cfg(feature = "xchachapoly")] + #[cfg(feature = "use-xchacha20poly1305")] CipherChoice::XChaChaPoly => None, } } diff --git a/src/stateless_transportstate.rs b/src/stateless_transportstate.rs index 904ab4a..1fd5201 100644 --- a/src/stateless_transportstate.rs +++ b/src/stateless_transportstate.rs @@ -6,7 +6,7 @@ use crate::{ params::HandshakePattern, utils::Toggle, }; -use std::{convert::TryFrom, fmt}; +use core::{convert::TryFrom, fmt}; /// A state machine encompassing the transport phase of a Noise session, using the two /// `CipherState`s (for sending and receiving) that were spawned from the `SymmetricState`'s diff --git a/src/symmetricstate.rs b/src/symmetricstate.rs index 7114cd3..bd8d801 100644 --- a/src/symmetricstate.rs +++ b/src/symmetricstate.rs @@ -1,3 +1,6 @@ +#[cfg(not(feature = "std"))] +use alloc::boxed::Box; + use crate::{ cipherstate::CipherState, constants::{CIPHERKEYLEN, MAXHASHLEN}, diff --git a/src/transportstate.rs b/src/transportstate.rs index b927b37..47e7943 100644 --- a/src/transportstate.rs +++ b/src/transportstate.rs @@ -6,7 +6,7 @@ use crate::{ params::HandshakePattern, utils::Toggle, }; -use std::{convert::TryFrom, fmt}; +use core::{convert::TryFrom, fmt}; /// A state machine encompassing the transport phase of a Noise session, using the two /// `CipherState`s (for sending and receiving) that were spawned from the `SymmetricState`'s diff --git a/src/utils.rs b/src/utils.rs index 633bea9..4e6efb4 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,4 @@ -use std::ops::{Deref, DerefMut}; +use core::ops::{Deref, DerefMut}; /// Toggle is similar to Option, except that even in the Off/"None" case, there is still /// an owned allocated inner object. This is useful for holding onto pre-allocated objects diff --git a/tests/general.rs b/tests/general.rs index d97662b..9c5a42b 100644 --- a/tests/general.rs +++ b/tests/general.rs @@ -1,4 +1,5 @@ -#![cfg(any(feature = "default-resolver", feature = "ring-accelerated"))] +#![cfg(feature = "std")] +#![cfg(any(feature = "default-resolver-crypto", feature = "ring-accelerated"))] #![allow(clippy::needless_range_loop)] #![allow(non_snake_case)] @@ -263,7 +264,7 @@ fn test_Xpsk0_expected_value() -> TestResult { #[test] #[cfg(feature = "hfs")] -#[cfg(feature = "pqclean_kyber1024")] +#[cfg(feature = "use-pqcrypto-kyber1024")] fn test_NNhfs_sanity_session() -> TestResult { // Due to how PQClean is implemented, we cannot do deterministic testing of the protocol. // Instead, we will see if the protocol runs smoothly.