//! Holds the implementation of [`Signer`] and [`Decryptor`] for [`KeyPair`].
//!
//! [`Signer`]: ../../asymmetric/trait.Signer.html
//! [`Decryptor`]: ../../asymmetric/trait.Decryptor.html
//! [`KeyPair`]: ../../asymmetric/struct.KeyPair.html
use std::convert::TryFrom;
use std::time::SystemTime;
use x25519_dalek_ng as x25519_dalek;
use num_bigint_dig::{traits::ModInverse, BigUint};
use rsa::traits::{PrivateKeyParts, PublicKeyParts};
use rsa::{Pkcs1v15Encrypt, RsaPublicKey, RsaPrivateKey, Pkcs1v15Sign};
use crate::{Error, Result};
use crate::crypto::asymmetric::{KeyPair, Decryptor, Signer};
use crate::crypto::backend::interface::Asymmetric;
use crate::crypto::mem::Protected;
use crate::crypto::mpi::{self, MPI, ProtectedMPI};
use crate::crypto::SessionKey;
use crate::crypto::pad_truncating;
use crate::packet::{key, Key};
use crate::packet::key::{Key4, SecretParts};
use crate::types::{Curve, HashAlgorithm, PublicKeyAlgorithm};
use super::GenericArrayExt;
const CURVE25519_SIZE: usize = 32;
impl Asymmetric for super::Backend {
fn x25519_generate_key() -> Result<(Protected, [u8; 32])> {
use x25519_dalek::{StaticSecret, PublicKey};
// x25519_dalek v1.1 doesn't reexport OsRng. It
// depends on rand 0.8.
use rand::rngs::OsRng;
let secret = StaticSecret::new(&mut OsRng);
let public = PublicKey::from(&secret);
let mut secret_bytes = secret.to_bytes();
let secret = secret_bytes.as_ref().into();
unsafe {
memsec::memzero(secret_bytes.as_mut_ptr(), secret_bytes.len());
}
Ok((secret, public.to_bytes()))
}
fn x25519_derive_public(secret: &Protected) -> Result<[u8; 32]> {
use x25519_dalek::{PublicKey, StaticSecret};
let secret = StaticSecret::from(<[u8; 32]>::try_from(&secret[..])?);
Ok(*PublicKey::from(&secret).as_bytes())
}
fn x25519_shared_point(secret: &Protected, public: &[u8; 32])
-> Result<Protected> {
use x25519_dalek::{StaticSecret, PublicKey};
let secret = StaticSecret::from(<[u8; 32]>::try_from(&secret[..])?);
let public = PublicKey::from(public.clone());
Ok((&secret.diffie_hellman(&public).as_bytes()[..]).into())
}
fn ed25519_generate_key() -> Result<(Protected, [u8; 32])> {
// ed25519_dalek v1.0.1 doesn't reexport OsRng. It
// depends on 0.7.
use rand07::rngs::OsRng as OsRng;
let pair = ed25519_dalek::Keypair::generate(&mut OsRng);
Ok((pair.secret.as_bytes().as_slice().into(), pair.secret.to_bytes()))
}
fn ed25519_derive_public(secret: &Protected) -> Result<[u8; 32]> {
use ed25519_dalek::{PublicKey, SecretKey};
let secret = SecretKey::from_bytes(secret).map_err(|e| {
Error::InvalidKey(e.to_string())
})?;
let public = PublicKey::from(&secret);
Ok(public.to_bytes())
}
fn ed25519_sign(secret: &Protected, public: &[u8; 32], digest: &[u8])
-> Result<[u8; 64]> {
use ed25519_dalek::{Keypair, Signer};
use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH};
if secret.len() != SECRET_KEY_LENGTH {
return Err(crate::Error::InvalidArgument(
"Bad Ed25519 secret length".into()).into());
}
let mut keypair = Protected::from(
vec![0u8; SECRET_KEY_LENGTH + PUBLIC_KEY_LENGTH]
);
keypair.as_mut()[..SECRET_KEY_LENGTH].copy_from_slice(secret);
keypair.<