rc_crypto/
ece_crypto.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use crate::{
6    aead,
7    agreement::{self, Curve, EcKey, UnparsedPublicKey},
8    digest, hkdf, hmac, rand,
9};
10use ece::crypto::{Cryptographer, EcKeyComponents, LocalKeyPair, RemotePublicKey};
11
12impl From<crate::Error> for ece::Error {
13    fn from(_: crate::Error) -> Self {
14        ece::Error::CryptoError
15    }
16}
17
18pub struct RcCryptoLocalKeyPair {
19    wrapped: agreement::KeyPair<agreement::Static>,
20}
21// SECKEYPrivateKeyStr and SECKEYPublicKeyStr are Sync.
22unsafe impl Sync for RcCryptoLocalKeyPair {}
23
24impl RcCryptoLocalKeyPair {
25    pub fn from_raw_components(components: &EcKeyComponents) -> Result<Self, ece::Error> {
26        let ec_key = EcKey::new(
27            Curve::P256,
28            components.private_key(),
29            components.public_key(),
30        );
31        let priv_key = agreement::PrivateKey::<agreement::Static>::import(&ec_key)?;
32        let wrapped = agreement::KeyPair::<agreement::Static>::from_private_key(priv_key)?;
33        Ok(RcCryptoLocalKeyPair { wrapped })
34    }
35
36    pub fn generate_random() -> Result<Self, ece::Error> {
37        let wrapped = agreement::KeyPair::<agreement::Static>::generate(&agreement::ECDH_P256)?;
38        Ok(RcCryptoLocalKeyPair { wrapped })
39    }
40
41    fn agree(&self, peer: &RcCryptoRemotePublicKey) -> Result<Vec<u8>, ece::Error> {
42        let peer_public_key_raw_bytes = &peer.as_raw()?;
43        let peer_public_key =
44            UnparsedPublicKey::new(&agreement::ECDH_P256, peer_public_key_raw_bytes);
45        self.wrapped
46            .private_key()
47            .agree_static(&peer_public_key)?
48            .derive(|z| Ok(z.to_vec()))
49    }
50}
51
52impl LocalKeyPair for RcCryptoLocalKeyPair {
53    fn raw_components(&self) -> Result<EcKeyComponents, ece::Error> {
54        let ec_key = self.wrapped.private_key().export()?;
55        Ok(EcKeyComponents::new(
56            ec_key.private_key(),
57            ec_key.public_key(),
58        ))
59    }
60
61    fn pub_as_raw(&self) -> Result<Vec<u8>, ece::Error> {
62        let bytes = self.wrapped.public_key().to_bytes()?;
63        Ok(bytes.to_vec())
64    }
65
66    fn as_any(&self) -> &dyn std::any::Any {
67        self
68    }
69}
70pub struct RcCryptoRemotePublicKey {
71    raw: Vec<u8>,
72}
73
74impl RcCryptoRemotePublicKey {
75    pub fn from_raw(bytes: &[u8]) -> Result<RcCryptoRemotePublicKey, ece::Error> {
76        Ok(RcCryptoRemotePublicKey {
77            raw: bytes.to_owned(),
78        })
79    }
80}
81
82impl RemotePublicKey for RcCryptoRemotePublicKey {
83    fn as_raw(&self) -> Result<Vec<u8>, ece::Error> {
84        Ok(self.raw.to_vec())
85    }
86
87    fn as_any(&self) -> &dyn std::any::Any {
88        self
89    }
90}
91
92pub(crate) struct RcCryptoCryptographer;
93
94impl Cryptographer for RcCryptoCryptographer {
95    fn generate_ephemeral_keypair(&self) -> Result<Box<dyn LocalKeyPair>, ece::Error> {
96        Ok(Box::new(RcCryptoLocalKeyPair::generate_random()?))
97    }
98
99    fn import_key_pair(
100        &self,
101        components: &EcKeyComponents,
102    ) -> Result<Box<dyn LocalKeyPair>, ece::Error> {
103        Ok(Box::new(RcCryptoLocalKeyPair::from_raw_components(
104            components,
105        )?))
106    }
107
108    fn import_public_key(&self, raw: &[u8]) -> Result<Box<dyn RemotePublicKey>, ece::Error> {
109        Ok(Box::new(RcCryptoRemotePublicKey::from_raw(raw)?))
110    }
111
112    fn compute_ecdh_secret(
113        &self,
114        remote: &dyn RemotePublicKey,
115        local: &dyn LocalKeyPair,
116    ) -> Result<Vec<u8>, ece::Error> {
117        let local_any = local.as_any();
118        let local = local_any.downcast_ref::<RcCryptoLocalKeyPair>().unwrap();
119        let remote_any = remote.as_any();
120        let remote = remote_any
121            .downcast_ref::<RcCryptoRemotePublicKey>()
122            .unwrap();
123        local.agree(remote)
124    }
125
126    fn hkdf_sha256(
127        &self,
128        salt: &[u8],
129        secret: &[u8],
130        info: &[u8],
131        len: usize,
132    ) -> Result<Vec<u8>, ece::Error> {
133        let salt = hmac::SigningKey::new(&digest::SHA256, salt);
134        let mut out = vec![0u8; len];
135        hkdf::extract_and_expand(&salt, secret, info, &mut out)?;
136        Ok(out)
137    }
138
139    fn aes_gcm_128_encrypt(
140        &self,
141        key: &[u8],
142        iv: &[u8],
143        data: &[u8],
144    ) -> Result<Vec<u8>, ece::Error> {
145        let key = aead::SealingKey::new(&aead::AES_128_GCM, key)?;
146        let nonce = aead::Nonce::try_assume_unique_for_key(&aead::AES_128_GCM, iv)?;
147        Ok(aead::seal(&key, nonce, aead::Aad::empty(), data)?)
148    }
149
150    fn aes_gcm_128_decrypt(
151        &self,
152        key: &[u8],
153        iv: &[u8],
154        ciphertext_and_tag: &[u8],
155    ) -> Result<Vec<u8>, ece::Error> {
156        let key = aead::OpeningKey::new(&aead::AES_128_GCM, key)?;
157        let nonce = aead::Nonce::try_assume_unique_for_key(&aead::AES_128_GCM, iv)?;
158        Ok(aead::open(
159            &key,
160            nonce,
161            aead::Aad::empty(),
162            ciphertext_and_tag,
163        )?)
164    }
165
166    fn random_bytes(&self, dest: &mut [u8]) -> Result<(), ece::Error> {
167        Ok(rand::fill(dest)?)
168    }
169}
170
171// Please call `rc_crypto::ensure_initialized()` instead of calling
172// this function directly.
173pub(crate) fn init() {
174    ece::crypto::set_cryptographer(&crate::ece_crypto::RcCryptoCryptographer)
175        .expect("Failed to initialize `ece` cryptographer!")
176}
177
178#[cfg(test)]
179mod tests {
180    use super::*;
181
182    #[test]
183    fn test_cryptographer_backend() {
184        nss::ensure_initialized();
185        crate::ensure_initialized();
186        ece::crypto::test_cryptographer(RcCryptoCryptographer);
187    }
188}