diff --git a/src/errors.rs b/src/errors.rs index cc1cb8d..11432b2 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -13,6 +13,32 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum RvError { + #[error("EC key generation failed.")] + ErrCryptoPKeyECKeyGenFailed, + #[error("RSA key generation failed.")] + ErrCryptoPKeyRSAKeyGenFailed, + #[error("Public key encryption failed.")] + ErrCryptoPKeyEncFailed, + #[error("Public key decryption failed.")] + ErrCryptoPKeyDecFailed, + #[error("Public key encryption init failed.")] + ErrCryptoPKeyEncInitFailed, + #[error("Public key decryption init failed.")] + ErrCryptoPKeyDecInitFailed, + #[error("Crypro module internal error.")] + ErrCryptoPKeyInternalError, + #[error("Verification failed.")] + ErrCryptoPKeyVerifyFailed, + #[error("Verification initialization failed.")] + ErrCryptoPKeyVerifyInitFailed, + #[error("Signing failed.")] + ErrCryptoPKeySignFailed, + #[error("Signing initialization failed.")] + ErrCryptoPKeySignInitFailed, + #[error("Invalid RSA key size.")] + ErrCryptoPKeyInvalidRSASize, + #[error("Public key operation not supported.")] + ErrCryptoPKeyOPNotSupported, #[error("Cipher operation update failed.")] ErrCryptoCipherUpdateFailed, #[error("Cipher operation finalization failed.")] diff --git a/src/modules/crypto/crypto_adaptors/openssl_adaptor.rs b/src/modules/crypto/crypto_adaptors/openssl_adaptor.rs index 7466947..6edc2bc 100644 --- a/src/modules/crypto/crypto_adaptors/openssl_adaptor.rs +++ b/src/modules/crypto/crypto_adaptors/openssl_adaptor.rs @@ -1,14 +1,24 @@ //! This is the OpenSSL adaptor. +use crate::{ + errors::RvError, + modules::crypto::{ + crypto_adaptors::common, AEADCipher, AESKeySize, BlockCipher, CipherMode, ECCurveName, Encryption, PublicKey, + PublicKeyType, RSAKeySize, Signature, AES, ECDSA, RSA, + }, +}; + use openssl::{ + ec::{EcGroup, EcKey}, + nid::Nid, + pkey::{PKey, Private}, + pkey_ctx::PkeyCtx, rand::rand_priv_bytes, + rsa::{Padding, Rsa}, symm::{decrypt, decrypt_aead, encrypt, encrypt_aead, Cipher, Crypter, Mode}, }; -use crate::{ - errors::RvError, - modules::crypto::{crypto_adaptors::common, AEADCipher, AESKeySize, BlockCipher, CipherMode, AES}, -}; +use zeroize::{Zeroize, Zeroizing}; pub struct AdaptorCTX { ctx: Crypter, @@ -81,3 +91,239 @@ impl AEADCipher for AES { common_aes_set_tag!(self, tag); } } + +pub struct AdaptorPKeyCTX { + // The private key in OpenSSL context contains also the public key + private_key: PKey, +} + +// Simply do nothing since OpenSSL will safely clean the memory of a PKEY object (Drop trait) +impl Zeroize for AdaptorPKeyCTX { + fn zeroize(&mut self) {} +} + +impl RSA { + /// This function is the constructor of the RSA struct, it returns a new RSA object on success. + /// + /// size: RSA key size. Valid options are RSA2048 (default), RSA3072, RSA4096, RSA8192. + /// prime: for multi-prime RSA usage (RFC 8017), default is 2. + pub fn new(prime: Option, size: Option) -> Result { + Ok(RSA { + key_type: PublicKeyType::RSA, + prime: prime.unwrap_or(2), + size: size.unwrap_or(RSAKeySize::RSA2048), + ctx: None, + }) + } +} + +impl PublicKey for RSA { + fn keygen(&mut self) -> Result<(), RvError> { + let bits: u32; + match &self.size { + RSAKeySize::RSA2048 => bits = 2048, + RSAKeySize::RSA3072 => bits = 3072, + RSAKeySize::RSA4096 => bits = 4096, + RSAKeySize::RSA8192 => bits = 8192, + } + + let rsa = match Rsa::generate(bits) { + Ok(r) => r, + Err(_e) => return Err(RvError::ErrCryptoPKeyRSAKeyGenFailed), + }; + + let pkey = match PKey::from_rsa(rsa) { + Ok(r) => r, + Err(_e) => return Err(RvError::ErrCryptoPKeyRSAKeyGenFailed), + }; + + let adaptor_ctx = AdaptorPKeyCTX { private_key: pkey }; + self.ctx = Some(adaptor_ctx); + + return Ok(()); + } + + fn get_key_type(&self) -> Result<&PublicKeyType, RvError> { + return Ok(&self.key_type); + } +} + +impl Signature for RSA { + fn sign(&self, data: &Vec) -> Result, RvError> { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(&key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.sign_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeySignInitFailed), + } + + let mut signature: Vec = Vec::new(); + match ctx.sign_to_vec(data, &mut signature) { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeySignFailed), + } + + return Ok(signature); + } + + fn verify(&self, data: &Vec, sig: &Vec) -> Result { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(&key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.verify_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyInitFailed), + } + + let valid = match ctx.verify(data, sig) { + Ok(ret) => ret, + Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyFailed), + }; + + return Ok(valid); + } +} + +impl Encryption for RSA { + fn encrypt(&self, plaintext: &Vec) -> Result, RvError> { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(&key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.encrypt_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyEncInitFailed), + } + + let mut ciphertext: Vec = Vec::new(); + match ctx.encrypt_to_vec(plaintext, &mut ciphertext) { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyEncFailed), + } + + return Ok(ciphertext); + } + + fn decrypt(&self, ciphertext: &Vec) -> Result, RvError> { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(&key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.decrypt_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyDecInitFailed), + } + + let mut plaintext: Vec = Vec::new(); + match ctx.decrypt_to_vec(ciphertext, &mut plaintext) { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyDecFailed), + } + + return Ok(plaintext); + } +} + +impl ECDSA { + /// This function is the constructor of the ECDSA struct, it returns a new ECDSA object + /// on success. + /// + /// curve: RSA key size. Valid options are RSA2048 (default), RSA3072, RSA4096, RSA8192. + /// prime: for multi-prime RSA usage (RFC 8017), default is 2. + pub fn new(curve: Option) -> Result { + return Ok(ECDSA { + key_type: PublicKeyType::ECDSA, + curve: curve.unwrap_or(ECCurveName::Prime256v1), + ctx: None, + }); + } +} + +impl PublicKey for ECDSA { + fn keygen(&mut self) -> Result<(), RvError> { + let nid: Nid; + match &self.curve { + ECCurveName::Prime256v1 => nid = Nid::X9_62_PRIME256V1, + } + + let group = EcGroup::from_curve_name(nid)?; + let ec = match EcKey::generate(&group) { + Ok(r) => r, + Err(_e) => return Err(RvError::ErrCryptoPKeyECKeyGenFailed), + }; + + let pkey = match PKey::from_ec_key(ec) { + Ok(r) => r, + Err(_e) => return Err(RvError::ErrCryptoPKeyECKeyGenFailed), + }; + + let adaptor_ctx = AdaptorPKeyCTX { private_key: pkey }; + self.ctx = Some(adaptor_ctx); + + return Ok(()); + } + + fn get_key_type(&self) -> Result<&PublicKeyType, RvError> { + return Ok(&self.key_type); + } +} + +impl Signature for ECDSA { + fn sign(&self, data: &Vec) -> Result, RvError> { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.sign_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeySignInitFailed), + } + + let mut signature: Vec = Vec::new(); + match ctx.sign_to_vec(data, &mut signature) { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeySignFailed), + } + + return Ok(signature); + } + + fn verify(&self, data: &Vec, sig: &Vec) -> Result { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.verify_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyInitFailed), + } + + let valid = match ctx.verify(data, sig) { + Ok(ret) => ret, + Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyFailed), + }; + + Ok(valid) + } +} diff --git a/src/modules/crypto/crypto_adaptors/tongsuo_adaptor.rs b/src/modules/crypto/crypto_adaptors/tongsuo_adaptor.rs index 3d54222..15246c0 100644 --- a/src/modules/crypto/crypto_adaptors/tongsuo_adaptor.rs +++ b/src/modules/crypto/crypto_adaptors/tongsuo_adaptor.rs @@ -1,15 +1,25 @@ //! This is the Tongsuo adaptor. use openssl::{ + ec::{EcGroup, EcKey}, + nid::Nid, + pkey::{PKey, Private}, + pkey_ctx::PkeyCtx, rand::rand_priv_bytes, + rsa::{Padding, Rsa}, symm::{decrypt, decrypt_aead, encrypt, encrypt_aead, Cipher, Crypter, Mode}, }; use crate::{ errors::RvError, - modules::crypto::{crypto_adaptors::common, AEADCipher, AESKeySize, BlockCipher, CipherMode, AES, SM4}, + modules::crypto::{ + crypto_adaptors::common, AEADCipher, AESKeySize, BlockCipher, CipherMode, ECCurveName, Encryption, PublicKey, + PublicKeyType, RSAKeySize, Signature, AES, ECDSA, RSA, SM4, + }, }; +use zeroize::{Zeroize, Zeroizing}; + pub struct AdaptorCTX { ctx: Crypter, tag_set: bool, @@ -349,3 +359,241 @@ impl AEADCipher for SM4 { Ok(()) } } + +pub struct AdaptorPKeyCTX { + // The private key in OpenSSL context contains also the public key + private_key: PKey, +} + +// Simply do nothing since OpenSSL will safely clean the memory of a PKEY object (Drop trait) +impl Zeroize for AdaptorPKeyCTX { + fn zeroize(&mut self) {} +} + +impl RSA { + /// This function is the constructor of the RSA struct, it returns a new RSA object on success. + /// + /// size: RSA key size. Valid options are RSA2048 (default), RSA3072, RSA4096, RSA8192. + /// prime: for multi-prime RSA usage (RFC 8017), default is 2. + pub fn new(prime: Option, size: Option) -> Result { + return Ok(RSA { + key_type: PublicKeyType::RSA, + prime: prime.unwrap_or(2), + size: size.unwrap_or(RSAKeySize::RSA2048), + ctx: None, + }); + } +} + +impl PublicKey for RSA { + fn keygen(&mut self) -> Result<(), RvError> { + let bits: u32; + match &self.size { + RSAKeySize::RSA2048 => bits = 2048, + RSAKeySize::RSA3072 => bits = 3072, + RSAKeySize::RSA4096 => bits = 4096, + RSAKeySize::RSA8192 => bits = 8192, + } + + let rsa = match Rsa::generate(bits) { + Ok(r) => r, + Err(_e) => return Err(RvError::ErrCryptoPKeyRSAKeyGenFailed), + }; + + let pkey = match PKey::from_rsa(rsa) { + Ok(r) => r, + Err(_e) => return Err(RvError::ErrCryptoPKeyRSAKeyGenFailed), + }; + + let adaptor_ctx = AdaptorPKeyCTX { private_key: pkey }; + self.ctx = Some(adaptor_ctx); + + return Ok(()); + } + + fn get_key_type(&self) -> Result<&PublicKeyType, RvError> { + return Ok(&self.key_type); + } +} + +impl Signature for RSA { + fn sign(&self, data: &Vec) -> Result, RvError> { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(&key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.sign_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeySignInitFailed), + } + + let mut signature: Vec = Vec::new(); + match ctx.sign_to_vec(data, &mut signature) { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeySignFailed), + } + + return Ok(signature); + } + + fn verify(&self, data: &Vec, sig: &Vec) -> Result { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(&key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.verify_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyInitFailed), + } + + let valid = match ctx.verify(data, sig) { + Ok(ret) => ret, + Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyFailed), + }; + + return Ok(valid); + } +} + +impl Encryption for RSA { + fn encrypt(&self, plaintext: &Vec) -> Result, RvError> { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(&key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.encrypt_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyEncInitFailed), + } + + let mut ciphertext: Vec = Vec::new(); + match ctx.encrypt_to_vec(plaintext, &mut ciphertext) { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyEncFailed), + } + + return Ok(ciphertext); + } + + fn decrypt(&self, ciphertext: &Vec) -> Result, RvError> { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(&key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.decrypt_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyDecInitFailed), + } + + let mut plaintext: Vec = Vec::new(); + match ctx.decrypt_to_vec(ciphertext, &mut plaintext) { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyDecFailed), + } + + return Ok(plaintext); + } +} + +impl ECDSA { + /// This function is the constructor of the ECDSA struct, it returns a new ECDSA object + /// on success. + /// + /// curve: RSA key size. Valid options are RSA2048 (default), RSA3072, RSA4096, RSA8192. + /// prime: for multi-prime RSA usage (RFC 8017), default is 2. + pub fn new(curve: Option) -> Result { + return Ok(ECDSA { + key_type: PublicKeyType::ECDSA, + curve: curve.unwrap_or(ECCurveName::Prime256v1), + ctx: None, + }); + } +} + +impl PublicKey for ECDSA { + fn keygen(&mut self) -> Result<(), RvError> { + let nid: Nid; + match &self.curve { + ECCurveName::Prime256v1 => nid = Nid::X9_62_PRIME256V1, + } + + let group = EcGroup::from_curve_name(nid)?; + let ec = match EcKey::generate(&group) { + Ok(r) => r, + Err(_e) => return Err(RvError::ErrCryptoPKeyECKeyGenFailed), + }; + + let pkey = match PKey::from_ec_key(ec) { + Ok(r) => r, + Err(_e) => return Err(RvError::ErrCryptoPKeyECKeyGenFailed), + }; + + let adaptor_ctx = AdaptorPKeyCTX { private_key: pkey }; + self.ctx = Some(adaptor_ctx); + + return Ok(()); + } + + fn get_key_type(&self) -> Result<&PublicKeyType, RvError> { + return Ok(&self.key_type); + } +} + +impl Signature for ECDSA { + fn sign(&self, data: &Vec) -> Result, RvError> { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(&key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.sign_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeySignInitFailed), + } + + let mut signature: Vec = Vec::new(); + match ctx.sign_to_vec(data, &mut signature) { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeySignFailed), + } + + return Ok(signature); + } + + fn verify(&self, data: &Vec, sig: &Vec) -> Result { + let key = &self.ctx.as_ref().unwrap().private_key; + + let mut ctx = match PkeyCtx::new(&key) { + Ok(ctx) => ctx, + Err(_e) => return Err(RvError::ErrCryptoPKeyInternalError), + }; + + match ctx.verify_init() { + Ok(_ret) => {} + Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyInitFailed), + } + + let valid = match ctx.verify(data, sig) { + Ok(ret) => ret, + Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyFailed), + }; + + return Ok(valid); + } +} + +// TODO: implement SM2 after necessary functions are supported in rust-tongsuo diff --git a/src/modules/crypto/mod.rs b/src/modules/crypto/mod.rs index b983fb1..7b04c9e 100644 --- a/src/modules/crypto/mod.rs +++ b/src/modules/crypto/mod.rs @@ -56,9 +56,11 @@ //! ~~~ #[cfg(feature = "crypto_adaptor_openssl")] -use crypto_adaptors::openssl_adaptor::AdaptorCTX; +use crypto_adaptors::openssl_adaptor::{AdaptorCTX, AdaptorPKeyCTX}; #[cfg(feature = "crypto_adaptor_tongsuo")] -use crypto_adaptors::tongsuo_adaptor::AdaptorCTX; +use crypto_adaptors::tongsuo_adaptor::{AdaptorCTX, AdaptorPKeyCTX}; + +use zeroize::{Zeroize, Zeroizing}; use crate::errors::RvError; @@ -83,9 +85,23 @@ pub enum AESKeySize { pub enum PublicKeyType { RSA, ECDSA, + EdDSA, SM2, } +/// This enum defines different RSA key size +pub enum RSAKeySize { + RSA2048, + RSA3072, + RSA4096, + RSA8192, +} + +/// This enum defines various EC curve names +pub enum ECCurveName { + Prime256v1, +} + // All structs are defined here. Every struct represents a type of cryptography algorithm. /// The AES block cipher structure. @@ -112,6 +128,27 @@ pub struct SM4 { ctx: Option, } +/// The RSA public key structure +#[allow(dead_code)] +#[derive(Zeroize)] +#[zeroize(drop)] +pub struct RSA { + key_type: PublicKeyType, + size: RSAKeySize, + prime: u8, + ctx: Option, +} + +/// The EC public key structure +#[allow(dead_code)] +#[derive(Zeroize)] +#[zeroize(drop)] +pub struct ECDSA { + key_type: PublicKeyType, + curve: ECCurveName, + ctx: Option, +} + /// BlockCipher is the 'base' trait for all kinds of block cipher alogrithms. In this trait, /// neccessary methods are defined. Cryptography adaptors need to implement this trait to provide /// real algorithms. @@ -369,7 +406,10 @@ pub trait AEADCipher: BlockCipher { /// algorithms usually refer to signature or encryption algorithms such as RSA, SM2 and so forth. pub trait PublicKey { /// Generate a pair of public and private key, based on specific algorithm type. - fn keygen() -> Result<(), RvError>; + fn keygen(&mut self) -> Result<(), RvError>; + + /// Return the public key type of an object. + fn get_key_type(&self) -> Result<&PublicKeyType, RvError>; } /// The Signature trait defines a signature algorithm, such as RSA, ECDSA or SM2. @@ -378,33 +418,51 @@ pub trait Signature: PublicKey { /// Sign a piece of data and returns the generated signature value. /// /// This operation uses the private key of a specific algorithm. - fn sign(&mut self, data: &Vec) -> Result, RvError>; + fn sign(&self, data: &Vec) -> Result, RvError>; /// Verify a piece of data against a signature and returns the verification result. /// /// This operation uses the public key of a specific algorithm. - fn verify(&mut self, data: &Vec, sig: &Vec) -> Result; + fn verify(&self, data: &Vec, sig: &Vec) -> Result; } -/// The Encryption trait defines an public key encryption algorithm, such as RSA and SM4. +/// The Encryption trait defines an public key encryption algorithm, such as RSA and SM2. /// This trait is a sub-trait of PublicKey trait. pub trait Encryption: PublicKey { /// Encrypt a piece of data using the private key. /// /// The ciphertext is returned on success. - fn encrypt(&mut self, plaintext: &Vec) -> Result, RvError>; + fn encrypt(&self, plaintext: &Vec) -> Result, RvError>; /// Decrypt a piece of data using the public key. /// /// The plaintext is returned on success. - fn decrypt(&mut self, ciphertext: &Vec) -> Result, RvError>; + fn decrypt(&self, ciphertext: &Vec) -> Result, RvError>; +} + +// It's not very necessary for current PublicKey structures to be zeroized since every sensitive +// data is safely cleared by OpenSSL because the rust-openssl crate implements the 'Drop' trait. +impl Zeroize for PublicKeyType { + fn zeroize(&mut self) {} +} + +impl Zeroize for RSAKeySize { + fn zeroize(&mut self) {} +} + +impl Zeroize for ECCurveName { + fn zeroize(&mut self) {} } #[cfg(test)] mod crypto_test { + use crate::modules::crypto::{ + AEADCipher, AESKeySize, BlockCipher, CipherMode, ECCurveName, Encryption, PublicKey, PublicKeyType, RSAKeySize, + Signature, AES, ECDSA, RSA, + }; + #[cfg(feature = "crypto_adaptor_tongsuo")] use crate::modules::crypto::SM4; - use crate::modules::crypto::{AEADCipher, AESKeySize, BlockCipher, CipherMode, AES}; #[test] fn test_aes_keygen() { @@ -725,4 +783,52 @@ mod crypto_test { // evaluate the result. assert_eq!(data2.to_vec(), pt); } + + #[test] + fn test_rsa_sign_verify() { + let mut rsa = RSA::new(Some(2), Some(RSAKeySize::RSA4096)).unwrap(); + rsa.keygen().unwrap(); + let data = b"The best way to not feel hopeless is to get up and do something.".to_vec(); + let sig = rsa.sign(&data).unwrap(); + let valid = rsa.verify(&data, &sig).unwrap(); + assert_eq!(valid, true); + } + + #[test] + fn test_rsa_encrypt_decrypt() { + let mut rsa = RSA::new(None, None).unwrap(); + rsa.keygen().unwrap(); + let data = b"The best way to not feel hopeless is to get up and do something.".to_vec(); + let ct = rsa.encrypt(&data).unwrap(); + let pt = rsa.decrypt(&ct).unwrap(); + assert_eq!(data, pt); + } + + #[test] + fn test_ecdsa_sign_verify() { + let mut ecdsa = ECDSA::new(None).unwrap(); + ecdsa.keygen().unwrap(); + let data = b"The best way to not feel hopeless is to get up and do something.".to_vec(); + let sig = ecdsa.sign(&data).unwrap(); + let valid = ecdsa.verify(&data, &sig).unwrap(); + assert_eq!(valid, true); + } + + #[cfg(feature = "crypto_adaptor_tongsuo")] + #[test] + fn test_sm2_keygen() { + assert_eq!(1, 1); + } + + #[cfg(feature = "crypto_adaptor_tongsuo")] + #[test] + fn test_sm2_sign_decrypt() { + assert_eq!(1, 1); + } + + #[cfg(feature = "crypto_adaptor_tongsuo")] + #[test] + fn test_sm2_encrypt_decrypt() { + assert_eq!(1, 1); + } }