Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.")]
Expand Down
268 changes: 264 additions & 4 deletions src/modules/crypto/crypto_adaptors/openssl_adaptor.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
//! This is the OpenSSL adaptor.

use crate::{
errors::RvError,
modules::crypto::{
AEADCipher, AESKeySize, BlockCipher,
CipherMode, AES,
RSA, RSAKeySize,
PublicKey, PublicKeyType,
Signature, Encryption,
ECDSA, ECCurveName,
crypto_adaptors::common,
},
};

use openssl::{
rand::rand_priv_bytes,
symm::{decrypt, decrypt_aead, encrypt, encrypt_aead, Cipher, Crypter, Mode},
rsa::{Rsa, Padding},
pkey::{PKey, Private},
pkey_ctx::PkeyCtx,
nid::Nid,
ec::{EcGroup, EcKey},
};

use crate::{
errors::RvError,
modules::crypto::{crypto_adaptors::common, AEADCipher, AESKeySize, BlockCipher, CipherMode, AES},
};
use zeroize::{Zeroize, Zeroizing};

pub struct AdaptorCTX {
ctx: Crypter,
Expand Down Expand Up @@ -81,3 +96,248 @@ 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<Private>,
}

// 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<u8>,
size: Option<RSAKeySize>,
) -> Result<Self, RvError> {
return Ok(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cargo clippy

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),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let rsa = Rsa::generate(bits).map_err(|_| RvError::ErrCryptoPKeyRSAKeyGenFailed)?;


let pkey = match PKey::from_rsa(rsa) {
Ok(r) => r,
Err(_e) => return Err(RvError::ErrCryptoPKeyRSAKeyGenFailed),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let pkey = PKey::from_rsa(rsa).map_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<u8>) -> Result<Vec<u8>, 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),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let mut ctx = PkeyCtx::new(&key).map_err(|_| RvError::ErrCryptoPKeyInternalError)?;


match ctx.sign_init() {
Ok(_ret) => {},
Err(_e) => return Err(RvError::ErrCryptoPKeySignInitFailed),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let _ = ctx.sign_init().map_err(|_| RvError::ErrCryptoPKeySignInitFailed)?;


let mut signature: Vec<u8> = Vec::new();
match ctx.sign_to_vec(data, &mut signature) {
Ok(_ret) => {},
Err(_e) => return Err(RvError::ErrCryptoPKeySignFailed),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ctx.sign_to_vec(data, &mut signature).map_err(|_| RvError::ErrCryptoPKeySignFailed)?;


return Ok(signature);
}

fn verify(&self, data: &Vec<u8>, sig: &Vec<u8>) -> Result<bool, 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),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


match ctx.verify_init() {
Ok(_ret) => {},
Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyInitFailed),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


let valid = match ctx.verify(data, sig) {
Ok(ret) => ret,
Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyFailed),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


return Ok(valid);
}
}

impl Encryption for RSA {
fn encrypt(&self, plaintext: &Vec<u8>) -> Result<Vec<u8>, 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),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


match ctx.encrypt_init() {
Ok(_ret) => {},
Err(_e) => return Err(RvError::ErrCryptoPKeyEncInitFailed),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


let mut ciphertext: Vec<u8> = Vec::new();
match ctx.encrypt_to_vec(plaintext, &mut ciphertext) {
Ok(_ret) => {},
Err(_e) => return Err(RvError::ErrCryptoPKeyEncFailed),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


return Ok(ciphertext);
}

fn decrypt(&self, ciphertext: &Vec<u8>) -> Result<Vec<u8>, 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),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


match ctx.decrypt_init() {
Ok(_ret) => {},
Err(_e) => return Err(RvError::ErrCryptoPKeyDecInitFailed),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

}

let mut plaintext: Vec<u8> = Vec::new();
match ctx.decrypt_to_vec(ciphertext, &mut plaintext) {
Ok(_ret) => {},
Err(_e) => return Err(RvError::ErrCryptoPKeyDecFailed),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


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<ECCurveName>,
) -> Result<Self, RvError> {
return Ok(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

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),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


let pkey = match PKey::from_ec_key(ec) {
Ok(r) => r,
Err(_e) => return Err(RvError::ErrCryptoPKeyECKeyGenFailed),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


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<u8>) -> Result<Vec<u8>, 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),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


match ctx.sign_init() {
Ok(_ret) => {},
Err(_e) => return Err(RvError::ErrCryptoPKeySignInitFailed),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


let mut signature: Vec<u8> = Vec::new();
match ctx.sign_to_vec(data, &mut signature) {
Ok(_ret) => {},
Err(_e) => return Err(RvError::ErrCryptoPKeySignFailed),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


return Ok(signature);
}

fn verify(&self, data: &Vec<u8>, sig: &Vec<u8>) -> Result<bool, 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),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


match ctx.verify_init() {
Ok(_ret) => {},
Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyInitFailed),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


let valid = match ctx.verify(data, sig) {
Ok(ret) => ret,
Err(_e) => return Err(RvError::ErrCryptoPKeyVerifyFailed),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


return Ok(valid);
}
}
Loading
Loading