rc_crypto/
ece_crypto.rs
1use 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}
21unsafe 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
171pub(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}