ssh/algorithm/key_exchange/
curve25519.rs

1use super::{super::hash::HashType, KeyExchange};
2use crate::error::SshError;
3use crate::SshResult;
4use ring::agreement::{EphemeralPrivateKey, PublicKey, UnparsedPublicKey, X25519};
5
6pub(super) struct CURVE25519 {
7    pub private_key: EphemeralPrivateKey,
8    pub public_key: PublicKey,
9}
10
11impl KeyExchange for CURVE25519 {
12    fn new() -> SshResult<Self> {
13        let rng = ring::rand::SystemRandom::new();
14        let private_key = match EphemeralPrivateKey::generate(&X25519, &rng) {
15            Ok(v) => v,
16            Err(e) => return Err(SshError::KexError(e.to_string())),
17        };
18        match private_key.compute_public_key() {
19            Ok(public_key) => Ok(CURVE25519 {
20                private_key,
21                public_key,
22            }),
23            Err(e) => Err(SshError::KexError(e.to_string())),
24        }
25    }
26
27    fn get_public_key(&self) -> &[u8] {
28        self.public_key.as_ref()
29    }
30
31    fn get_shared_secret(&self, puk: Vec<u8>) -> SshResult<Vec<u8>> {
32        let mut public_key = [0u8; 32];
33        public_key.copy_from_slice(&puk);
34
35        let server_pub = UnparsedPublicKey::new(&X25519, public_key);
36        let private_key = unsafe { (&self.private_key as *const EphemeralPrivateKey).read() };
37        crate::algorithm::key_exchange::agree_ephemeral(private_key, &server_pub)
38    }
39
40    fn get_hash_type(&self) -> HashType {
41        HashType::SHA256
42    }
43}