Skip to main content

rtc_crypto/
traits.rs

1use std::sync::Arc;
2
3use crate::{
4    AeadAlgorithm, BlockCipherAlgorithm, CbcAlgorithm, CryptoAlgorithm, CryptoError, HashAlgorithm,
5    HmacAlgorithm, KeyExchangeAlgorithm, PublicKey, SecretVec, SignatureScheme,
6    StreamCipherAlgorithm,
7};
8
9/// A bundle of cryptographic operations and cryptographically secure randomness.
10pub trait RTCCryptoProvider: Send + Sync {
11    /// Returns a non-secret diagnostic name.
12    fn name(&self) -> &'static str;
13
14    /// Returns the cryptographic operations implementation.
15    fn crypto(&self) -> &dyn RTCCrypto;
16
17    /// Returns the cryptographically secure random source.
18    fn random(&self) -> &dyn RTCRandom;
19}
20
21/// A cryptographically secure random byte generator.
22pub trait RTCRandom: Send + Sync {
23    /// Fills all of `output` with random bytes.
24    fn fill(&self, output: &mut [u8]) -> Result<(), CryptoError>;
25}
26
27/// Provider-neutral cryptographic operations.
28pub trait RTCCrypto: Send + Sync {
29    /// Reports whether an operation is implemented.
30    fn supports(&self, algorithm: CryptoAlgorithm) -> bool;
31
32    /// Hashes `data`.
33    fn hash(&self, algorithm: HashAlgorithm, _data: &[u8]) -> Result<Vec<u8>, CryptoError> {
34        Err(CryptoError::UnsupportedAlgorithm(CryptoAlgorithm::Hash(
35            algorithm,
36        )))
37    }
38
39    /// Encrypts exactly one block in place.
40    fn block_encrypt(
41        &self,
42        algorithm: BlockCipherAlgorithm,
43        _key: &[u8],
44        _block: &mut [u8],
45    ) -> Result<(), CryptoError> {
46        Err(CryptoError::UnsupportedAlgorithm(
47            CryptoAlgorithm::BlockCipher(algorithm),
48        ))
49    }
50
51    /// Creates a keyed MAC.
52    ///
53    /// This is the only HMAC entry point. Deriving the key schedule is the expensive part, so it
54    /// happens here rather than per message; a caller that authenticates many messages with one
55    /// key holds the returned [`Mac`]. One-shot callers simply drop it after a single `sign` or
56    /// `verify`.
57    fn new_hmac(&self, algorithm: HmacAlgorithm, _key: &[u8]) -> Result<Box<dyn Mac>, CryptoError> {
58        Err(CryptoError::UnsupportedAlgorithm(CryptoAlgorithm::Hmac(
59            algorithm,
60        )))
61    }
62
63    /// Creates a keyed stream cipher.
64    fn new_stream_cipher(
65        &self,
66        algorithm: StreamCipherAlgorithm,
67        _key: &[u8],
68    ) -> Result<Box<dyn StreamCipher>, CryptoError> {
69        Err(CryptoError::UnsupportedAlgorithm(
70            CryptoAlgorithm::StreamCipher(algorithm),
71        ))
72    }
73
74    /// Creates a keyed AEAD cipher.
75    fn new_aead(
76        &self,
77        algorithm: AeadAlgorithm,
78        _key: &[u8],
79    ) -> Result<Box<dyn AeadCipher>, CryptoError> {
80        Err(CryptoError::UnsupportedAlgorithm(CryptoAlgorithm::Aead(
81            algorithm,
82        )))
83    }
84
85    /// Creates a keyed CBC cipher.
86    fn new_cbc(
87        &self,
88        algorithm: CbcAlgorithm,
89        _key: &[u8],
90    ) -> Result<Box<dyn CbcCipher>, CryptoError> {
91        Err(CryptoError::UnsupportedAlgorithm(CryptoAlgorithm::Cbc(
92            algorithm,
93        )))
94    }
95
96    /// Starts a one-shot ephemeral key exchange.
97    fn start_key_exchange(
98        &self,
99        algorithm: KeyExchangeAlgorithm,
100    ) -> Result<Box<dyn ActiveKeyExchange>, CryptoError> {
101        Err(CryptoError::UnsupportedAlgorithm(
102            CryptoAlgorithm::KeyExchange(algorithm),
103        ))
104    }
105
106    /// Generates an exportable signing key.
107    fn generate_signing_key(
108        &self,
109        scheme: SignatureScheme,
110    ) -> Result<Arc<dyn SigningKey>, CryptoError> {
111        Err(CryptoError::UnsupportedAlgorithm(
112            CryptoAlgorithm::SigningKeyGeneration(scheme),
113        ))
114    }
115
116    /// Imports an exportable PKCS#8 signing key.
117    fn import_signing_key(
118        &self,
119        scheme: SignatureScheme,
120        _pkcs8_der: &[u8],
121    ) -> Result<Arc<dyn SigningKey>, CryptoError> {
122        Err(CryptoError::UnsupportedAlgorithm(
123            CryptoAlgorithm::SigningKeyImport(scheme),
124        ))
125    }
126
127    /// Verifies a signature.
128    fn verify_signature(
129        &self,
130        scheme: SignatureScheme,
131        _public_key: PublicKey<'_>,
132        _message: &[u8],
133        _signature: &[u8],
134    ) -> Result<(), CryptoError> {
135        Err(CryptoError::UnsupportedAlgorithm(
136            CryptoAlgorithm::Signature(scheme),
137        ))
138    }
139}
140
141/// A keyed message authentication code with a reusable key schedule.
142///
143/// Created once per key by [`RTCCrypto::new_hmac`] and used for every message authenticated with
144/// that key, so the ipad/opad derivation is paid once rather than per packet.
145///
146/// `Send` and mutable, like the keyed cipher traits, and for the same reason: `&mut self` lets an
147/// implementation carry per-message state — a reused streaming context, a hardware session
148/// handle — without interior mutability, and does not impose `Sync` on implementors that cannot
149/// offer it. A caller whose own signature is fixed to `&self`, such as STUN's `Setter::add_to`,
150/// can still create a local `Mac` per message and use it mutably.
151pub trait Mac: Send {
152    /// Returns the untruncated tag length in bytes.
153    fn output_len(&self) -> usize;
154
155    /// Writes the tag over the concatenation of `input` into `output`.
156    ///
157    /// `output` must be exactly [`output_len`](Self::output_len) bytes. Protocols that transmit a
158    /// truncated tag — SRTP sends 80 or 32 bits of an SHA-1 tag — truncate the result themselves.
159    fn sign(&mut self, input: &[&[u8]], output: &mut [u8]) -> Result<(), CryptoError>;
160
161    /// Verifies a complete untruncated tag in constant time.
162    fn verify(&mut self, input: &[&[u8]], expected: &[u8]) -> Result<(), CryptoError>;
163}
164
165/// A keyed stream cipher with a reusable expanded key.
166pub trait StreamCipher: Send {
167    /// Applies the keystream in place with a fresh IV.
168    fn apply_keystream(&mut self, iv: &[u8], data: &mut [u8]) -> Result<(), CryptoError>;
169}
170
171/// A keyed authenticated cipher with detached tags.
172pub trait AeadCipher: Send {
173    /// Returns the detached tag length in bytes.
174    fn tag_len(&self) -> usize;
175
176    /// Encrypts and authenticates a caller-owned buffer.
177    fn seal_in_place(
178        &mut self,
179        nonce: &[u8],
180        aad: &[u8],
181        plaintext_and_ciphertext: &mut [u8],
182        tag_out: &mut [u8],
183    ) -> Result<(), CryptoError>;
184
185    /// Authenticates and decrypts a caller-owned buffer.
186    fn open_in_place(
187        &mut self,
188        nonce: &[u8],
189        aad: &[u8],
190        ciphertext_and_plaintext: &mut [u8],
191        tag: &[u8],
192    ) -> Result<(), CryptoError>;
193}
194
195/// A keyed CBC block cipher with a reusable expanded key.
196pub trait CbcCipher: Send {
197    /// Returns the block and IV length in bytes.
198    fn block_len(&self) -> usize;
199
200    /// Encrypts whole blocks in place without applying padding.
201    fn encrypt_blocks(&mut self, iv: &[u8], blocks: &mut [u8]) -> Result<(), CryptoError>;
202
203    /// Decrypts whole blocks in place without removing padding.
204    fn decrypt_blocks(&mut self, iv: &[u8], blocks: &mut [u8]) -> Result<(), CryptoError>;
205}
206
207/// Provider-owned one-shot ephemeral key exchange.
208pub trait ActiveKeyExchange: Send {
209    /// Returns the key-exchange algorithm.
210    fn algorithm(&self) -> KeyExchangeAlgorithm;
211
212    /// Returns the encoded wire public key.
213    fn public_key(&self) -> &[u8];
214
215    /// Consumes the private key and derives the shared secret.
216    fn complete(self: Box<Self>, peer_public_key: &[u8]) -> Result<SecretVec, CryptoError>;
217}
218
219/// A provider-owned signing key, including external or non-exportable keys.
220pub trait SigningKey: Send + Sync {
221    /// Reports whether this key can sign with `scheme`.
222    fn supports(&self, scheme: SignatureScheme) -> bool;
223
224    /// Returns the public key with explicit encoding.
225    fn public_key(&self) -> PublicKey<'_>;
226
227    /// Signs `message`.
228    fn sign(&self, scheme: SignatureScheme, message: &[u8]) -> Result<Vec<u8>, CryptoError>;
229
230    /// Exports PKCS#8 when supported. `Ok(None)` means the key is non-exportable.
231    fn to_pkcs8_der(&self) -> Result<Option<SecretVec>, CryptoError> {
232        Ok(None)
233    }
234}