Skip to main content

rtc_crypto/
lib.rs

1//! Provider-neutral cryptography for the webrtc-rs RTC stack.
2//!
3//! The open traits in this crate allow applications to supply cryptography and randomness without
4//! registering global state. Built-in providers are selected with additive Cargo features.
5
6mod algorithm;
7mod error;
8mod provider;
9mod secret;
10mod traits;
11
12#[cfg(any(feature = "crypto-ring", feature = "crypto-aws-lc-rs"))]
13mod common;
14pub mod providers;
15
16#[cfg(feature = "test-support")]
17pub mod conformance;
18
19pub use algorithm::*;
20pub use error::CryptoError;
21pub use provider::default_provider;
22pub use secret::SecretVec;
23pub use traits::*;
24
25/// Compares equal-length byte strings without data-dependent early exit.
26#[must_use]
27pub fn constant_time_eq(left: &[u8], right: &[u8]) -> bool {
28    use subtle::ConstantTimeEq;
29
30    left.len() == right.len() && bool::from(left.ct_eq(right))
31}
32
33const _: () = {
34    #[allow(dead_code)]
35    #[allow(clippy::too_many_arguments)]
36    fn assert_dyn_compatible(
37        _provider: &dyn RTCCryptoProvider,
38        _crypto: &dyn RTCCrypto,
39        _random: &dyn RTCRandom,
40        _mac: &dyn Mac,
41        _stream: &dyn StreamCipher,
42        _aead: &dyn AeadCipher,
43        _cbc: &dyn CbcCipher,
44        _exchange: &dyn ActiveKeyExchange,
45        _signing_key: &dyn SigningKey,
46    ) {
47    }
48};
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn secret_debug_is_redacted() {
56        let secret = SecretVec::new(vec![1, 2, 3, 4]);
57        let debug = format!("{secret:?}");
58        assert!(debug.contains("REDACTED"));
59        assert!(debug.contains("len: 4"));
60        assert!(!debug.contains("1, 2, 3, 4"));
61    }
62
63    #[test]
64    fn secret_into_bytes_is_explicit() {
65        let secret = SecretVec::new(vec![1, 2, 3]);
66        assert_eq!(secret.into_bytes(), vec![1, 2, 3]);
67    }
68
69    #[test]
70    fn errors_have_provider_neutral_text() {
71        assert_eq!(
72            CryptoError::AuthenticationFailed.to_string(),
73            "authentication failed"
74        );
75        assert_eq!(
76            CryptoError::InvalidSignature.to_string(),
77            "signature verification failed"
78        );
79    }
80
81    #[test]
82    fn constant_time_equality_checks_length_and_content() {
83        assert!(constant_time_eq(b"same", b"same"));
84        assert!(!constant_time_eq(b"same", b"diff"));
85        assert!(!constant_time_eq(b"same", b"same-longer"));
86    }
87}