snow/resolvers/
mod.rs

1//! The wrappers around the default collection of cryptography and entropy providers.
2
3/// The default primitive resolver.
4#[cfg(feature = "default-resolver")]
5mod default;
6/// A libsodium primitive resolver.
7#[cfg(feature = "libsodium-resolver")]
8mod libsodium;
9/// A ring primitive resolver.
10#[cfg(feature = "ring-resolver")]
11mod ring;
12
13#[cfg(feature = "hfs")]
14use crate::params::KemChoice;
15#[cfg(feature = "hfs")]
16use crate::types::Kem;
17use crate::{
18    params::{CipherChoice, DHChoice, HashChoice},
19    types::{Cipher, Dh, Hash, Random},
20};
21
22#[cfg(feature = "default-resolver")]
23pub use self::default::DefaultResolver;
24#[cfg(feature = "libsodium-resolver")]
25pub use self::libsodium::SodiumResolver;
26#[cfg(feature = "ring-resolver")]
27pub use self::ring::RingResolver;
28
29/// Boxed CryptoResolver
30pub type BoxedCryptoResolver = Box<dyn CryptoResolver + Send>;
31
32/// An object that resolves the providers of Noise crypto choices
33pub trait CryptoResolver {
34    /// Provide an implementation of the Random trait or None if none available.
35    fn resolve_rng(&self) -> Option<Box<dyn Random>>;
36
37    /// Provide an implementation of the Dh trait for the given DHChoice or None if unavailable.
38    fn resolve_dh(&self, choice: &DHChoice) -> Option<Box<dyn Dh>>;
39
40    /// Provide an implementation of the Hash trait for the given HashChoice or None if unavailable.
41    fn resolve_hash(&self, choice: &HashChoice) -> Option<Box<dyn Hash>>;
42
43    /// Provide an implementation of the Cipher trait for the given CipherChoice or None if unavailable.
44    fn resolve_cipher(&self, choice: &CipherChoice) -> Option<Box<dyn Cipher>>;
45
46    /// Provide an implementation of the Kem trait for the given KemChoice or None if unavailable
47    #[cfg(feature = "hfs")]
48    fn resolve_kem(&self, _choice: &KemChoice) -> Option<Box<dyn Kem>> {
49        None
50    }
51}
52
53/// A helper resolver that can opportunistically use one resolver, but
54/// can fallback to another if the first didn't have an implementation for
55/// a given primitive.
56pub struct FallbackResolver {
57    preferred: BoxedCryptoResolver,
58    fallback:  BoxedCryptoResolver,
59}
60
61impl FallbackResolver {
62    /// Create a new `FallbackResolver` that holds the primary and secondary resolver.
63    pub fn new(preferred: BoxedCryptoResolver, fallback: BoxedCryptoResolver) -> Self {
64        Self { preferred, fallback }
65    }
66}
67
68impl CryptoResolver for FallbackResolver {
69    fn resolve_rng(&self) -> Option<Box<dyn Random>> {
70        self.preferred.resolve_rng().or_else(|| self.fallback.resolve_rng())
71    }
72
73    fn resolve_dh(&self, choice: &DHChoice) -> Option<Box<dyn Dh>> {
74        self.preferred.resolve_dh(choice).or_else(|| self.fallback.resolve_dh(choice))
75    }
76
77    fn resolve_hash(&self, choice: &HashChoice) -> Option<Box<dyn Hash>> {
78        self.preferred.resolve_hash(choice).or_else(|| self.fallback.resolve_hash(choice))
79    }
80
81    fn resolve_cipher(&self, choice: &CipherChoice) -> Option<Box<dyn Cipher>> {
82        self.preferred.resolve_cipher(choice).or_else(|| self.fallback.resolve_cipher(choice))
83    }
84
85    #[cfg(feature = "hfs")]
86    fn resolve_kem(&self, choice: &KemChoice) -> Option<Box<dyn Kem>> {
87        self.preferred.resolve_kem(choice).or_else(|| self.fallback.resolve_kem(choice))
88    }
89}