blob: 94c6d32596d0399d090a37984c3d94de28feaeb0 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::crypto_provider::{
AsymmetricProviderKey, CryptoProvider, CryptoProviderError, ProviderKey, SealingProviderKey,
};
use fidl_fuchsia_kms::AsymmetricKeyAlgorithm;
use mundane::hash::*;
use mundane::public::ec::ecdsa::EcdsaHash;
use mundane::public::ec::*;
use mundane::public::rsa::*;
use mundane::public::*;
#[derive(Debug, Clone)]
pub struct MundaneSoftwareProvider {}
pub struct MundaneAsymmetricPrivateKey {
key_data: Vec<u8>,
key_algorithm: AsymmetricKeyAlgorithm,
}
impl CryptoProvider for MundaneSoftwareProvider {
fn supported_asymmetric_algorithms(&self) -> Vec<AsymmetricKeyAlgorithm> {
vec![
AsymmetricKeyAlgorithm::EcdsaSha256P256,
AsymmetricKeyAlgorithm::EcdsaSha512P384,
AsymmetricKeyAlgorithm::EcdsaSha512P521,
AsymmetricKeyAlgorithm::RsaSsaPssSha2562048,
AsymmetricKeyAlgorithm::RsaSsaPssSha2563072,
AsymmetricKeyAlgorithm::RsaSsaPssSha5124096,
AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2562048,
AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2563072,
AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha5124096,
]
}
fn get_name(&self) -> &'static str {
"MundaneSoftwareProvider"
}
fn box_clone(&self) -> Box<dyn CryptoProvider> {
Box::new(MundaneSoftwareProvider {})
}
fn generate_asymmetric_key(
&self,
key_algorithm: AsymmetricKeyAlgorithm,
_key_name: &str,
) -> Result<Box<dyn AsymmetricProviderKey>, CryptoProviderError> {
let key_data = match key_algorithm {
AsymmetricKeyAlgorithm::EcdsaSha256P256 => generate_ec_key::<P256>(),
AsymmetricKeyAlgorithm::EcdsaSha512P384 => generate_ec_key::<P384>(),
AsymmetricKeyAlgorithm::EcdsaSha512P521 => generate_ec_key::<P521>(),
AsymmetricKeyAlgorithm::RsaSsaPssSha2562048
| AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2562048 => generate_rsa_key::<B2048>(),
AsymmetricKeyAlgorithm::RsaSsaPssSha2563072
| AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2563072 => generate_rsa_key::<B3072>(),
AsymmetricKeyAlgorithm::RsaSsaPssSha5124096
| AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha5124096 => generate_rsa_key::<B4096>(),
}?;
Ok(Box::new(MundaneAsymmetricPrivateKey { key_data, key_algorithm }))
}
fn import_asymmetric_key(
&self,
key_data: &[u8],
key_algorithm: AsymmetricKeyAlgorithm,
_key_name: &str,
) -> Result<Box<dyn AsymmetricProviderKey>, CryptoProviderError> {
self.parse_asymmetric_key(key_data, key_algorithm)
}
fn parse_asymmetric_key(
&self,
key_data: &[u8],
key_algorithm: AsymmetricKeyAlgorithm,
) -> Result<Box<dyn AsymmetricProviderKey>, CryptoProviderError> {
match key_algorithm {
AsymmetricKeyAlgorithm::EcdsaSha256P256 => {
let _ec_key =
EcPrivKey::<P256>::parse_from_der(key_data).map_err(map_operation_error)?;
}
AsymmetricKeyAlgorithm::EcdsaSha512P384 => {
let _ec_key =
EcPrivKey::<P384>::parse_from_der(key_data).map_err(map_operation_error)?;
}
AsymmetricKeyAlgorithm::EcdsaSha512P521 => {
let _ec_key =
EcPrivKey::<P521>::parse_from_der(key_data).map_err(map_operation_error)?;
}
AsymmetricKeyAlgorithm::RsaSsaPssSha2562048
| AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2562048 => {
let _rsa_key =
RsaPrivKey::<B2048>::parse_from_der(key_data).map_err(map_operation_error)?;
}
AsymmetricKeyAlgorithm::RsaSsaPssSha2563072
| AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2563072 => {
let _rsa_key =
RsaPrivKey::<B3072>::parse_from_der(key_data).map_err(map_operation_error)?;
}
AsymmetricKeyAlgorithm::RsaSsaPssSha5124096
| AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha5124096 => {
let _rsa_key =
RsaPrivKey::<B4096>::parse_from_der(key_data).map_err(map_operation_error)?;
}
}
Ok(Box::new(MundaneAsymmetricPrivateKey { key_data: key_data.to_vec(), key_algorithm }))
}
fn generate_sealing_key(
&self,
_key_name: &str,
) -> Result<Box<dyn SealingProviderKey>, CryptoProviderError> {
Err(CryptoProviderError::new("Unsupported algorithm."))
}
fn parse_sealing_key(
&self,
_key_data: &[u8],
) -> Result<Box<dyn SealingProviderKey>, CryptoProviderError> {
Err(CryptoProviderError::new("Unsupported algorithm."))
}
fn calculate_sealed_data_size(&self, _original_data_size: u64) -> u64 {
0
}
}
impl AsymmetricProviderKey for MundaneAsymmetricPrivateKey {
fn sign(&self, data: &[u8]) -> Result<Vec<u8>, CryptoProviderError> {
match self.key_algorithm {
AsymmetricKeyAlgorithm::EcdsaSha256P256 => {
sign_with_ec_key::<P256, Sha256>(&self.key_data, data)
}
AsymmetricKeyAlgorithm::EcdsaSha512P384 => {
sign_with_ec_key::<P384, Sha512>(&self.key_data, data)
}
AsymmetricKeyAlgorithm::EcdsaSha512P521 => {
sign_with_ec_key::<P521, Sha512>(&self.key_data, data)
}
AsymmetricKeyAlgorithm::RsaSsaPssSha2562048 => {
sign_with_rsa_key::<B2048, RsaPss, Sha256>(&self.key_data, data)
}
AsymmetricKeyAlgorithm::RsaSsaPssSha2563072 => {
sign_with_rsa_key::<B3072, RsaPss, Sha256>(&self.key_data, data)
}
AsymmetricKeyAlgorithm::RsaSsaPssSha5124096 => {
sign_with_rsa_key::<B4096, RsaPss, Sha512>(&self.key_data, data)
}
AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2562048 => {
sign_with_rsa_key::<B2048, RsaPkcs1v15, Sha256>(&self.key_data, data)
}
AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2563072 => {
sign_with_rsa_key::<B3072, RsaPkcs1v15, Sha256>(&self.key_data, data)
}
AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha5124096 => {
sign_with_rsa_key::<B4096, RsaPkcs1v15, Sha512>(&self.key_data, data)
}
}
}
fn get_der_public_key(&self) -> Result<Vec<u8>, CryptoProviderError> {
match self.key_algorithm {
AsymmetricKeyAlgorithm::EcdsaSha256P256 => {
marshal_ec_key_to_der::<P256>(&self.key_data)
}
AsymmetricKeyAlgorithm::EcdsaSha512P384 => {
marshal_ec_key_to_der::<P384>(&self.key_data)
}
AsymmetricKeyAlgorithm::EcdsaSha512P521 => {
marshal_ec_key_to_der::<P521>(&self.key_data)
}
AsymmetricKeyAlgorithm::RsaSsaPssSha2562048
| AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2562048 => {
marshal_rsa_key_to_der::<B2048>(&self.key_data)
}
AsymmetricKeyAlgorithm::RsaSsaPssSha2563072
| AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2563072 => {
marshal_rsa_key_to_der::<B3072>(&self.key_data)
}
AsymmetricKeyAlgorithm::RsaSsaPssSha5124096
| AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha5124096 => {
marshal_rsa_key_to_der::<B4096>(&self.key_data)
}
}
}
fn get_key_algorithm(&self) -> AsymmetricKeyAlgorithm {
self.key_algorithm
}
}
fn generate_ec_key<C: PCurve>() -> Result<Vec<u8>, CryptoProviderError> {
let ec_key = EcPrivKey::<C>::generate().map_err(map_operation_error)?;
Ok(ec_key.marshal_to_der())
}
fn generate_rsa_key<B: RsaKeyBits>() -> Result<Vec<u8>, CryptoProviderError> {
let rsa_key = RsaPrivKey::<B>::generate().map_err(map_operation_error)?;
Ok(rsa_key.marshal_to_der())
}
fn sign_with_ec_key<C: PCurve, H: Hasher + EcdsaHash<C>>(
key_data: &[u8],
data: &[u8],
) -> Result<Vec<u8>, CryptoProviderError> {
let ec_key = EcPrivKey::<C>::parse_from_der(key_data).map_err(map_operation_error)?;
let sig: ecdsa::EcdsaSignature<C, H> = ec_key.sign(data).map_err(map_operation_error)?;
Ok(sig.bytes().to_vec())
}
fn sign_with_rsa_key<B: RsaKeyBits, S: RsaSignatureScheme, H: Hasher>(
key_data: &[u8],
data: &[u8],
) -> Result<Vec<u8>, CryptoProviderError> {
let rsa_key = RsaPrivKey::<B>::parse_from_der(key_data).map_err(map_operation_error)?;
let sig: rsa::RsaSignature<B, S, H> = rsa_key.sign(data).map_err(map_operation_error)?;
Ok(sig.bytes().to_vec())
}
fn marshal_ec_key_to_der<C: PCurve>(key_data: &[u8]) -> Result<Vec<u8>, CryptoProviderError> {
let ec_key = EcPrivKey::<C>::parse_from_der(key_data).map_err(map_operation_error)?;
Ok(ec_key.public().marshal_to_der())
}
fn marshal_rsa_key_to_der<B: RsaKeyBits>(key_data: &[u8]) -> Result<Vec<u8>, CryptoProviderError> {
let rsa_key = RsaPrivKey::<B>::parse_from_der(key_data).map_err(map_operation_error)?;
Ok(rsa_key.public().marshal_to_der())
}
fn map_operation_error(err: mundane::Error) -> CryptoProviderError {
CryptoProviderError::new(&format!("Operation error: {:?}.", err))
}
impl ProviderKey for MundaneAsymmetricPrivateKey {
fn delete(&mut self) -> Result<(), CryptoProviderError> {
self.key_data.clear();
Ok(())
}
/// Get the data for the key.
fn get_key_data(&self) -> Vec<u8> {
self.key_data.clone()
}
/// Get the crypto provider name for the key.
fn get_provider_name(&self) -> &'static str {
(MundaneSoftwareProvider {}).get_name()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::common;
static TEST_KEY_NAME: &str = "TestKey";
#[test]
fn test_mundane_provider_sign() {
// Right now only this algorithm is supported.
test_mundane_provider_sign_ec_key::<P256, Sha256>(AsymmetricKeyAlgorithm::EcdsaSha256P256);
test_mundane_provider_sign_ec_key::<P384, Sha512>(AsymmetricKeyAlgorithm::EcdsaSha512P384);
test_mundane_provider_sign_ec_key::<P521, Sha512>(AsymmetricKeyAlgorithm::EcdsaSha512P521);
test_mundane_provider_sign_rsa_key::<B2048, RsaPss, Sha256>(
AsymmetricKeyAlgorithm::RsaSsaPssSha2562048,
);
test_mundane_provider_sign_rsa_key::<B3072, RsaPss, Sha256>(
AsymmetricKeyAlgorithm::RsaSsaPssSha2563072,
);
test_mundane_provider_sign_rsa_key::<B4096, RsaPss, Sha512>(
AsymmetricKeyAlgorithm::RsaSsaPssSha5124096,
);
test_mundane_provider_sign_rsa_key::<B2048, RsaPkcs1v15, Sha256>(
AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2562048,
);
test_mundane_provider_sign_rsa_key::<B3072, RsaPkcs1v15, Sha256>(
AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2563072,
);
test_mundane_provider_sign_rsa_key::<B4096, RsaPkcs1v15, Sha512>(
AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha5124096,
);
}
fn test_mundane_provider_sign_ec_key<C: PCurve, H: Hasher + EcdsaHash<C>>(
key_algorithm: AsymmetricKeyAlgorithm,
) {
let mundane_provider = MundaneSoftwareProvider {};
let key = mundane_provider.generate_asymmetric_key(key_algorithm, TEST_KEY_NAME).unwrap();
let test_input_data = common::generate_random_data(256);
let signature = key.sign(&test_input_data).unwrap();
let public_key = key.get_der_public_key().unwrap();
let ec_key = EcPubKey::<C>::parse_from_der(&public_key).unwrap();
assert_eq!(
true,
ecdsa::EcdsaSignature::<C, H>::from_bytes(&signature)
.is_valid(&ec_key, &test_input_data)
);
}
fn test_mundane_provider_sign_rsa_key<B: RsaKeyBits, S: RsaSignatureScheme, H: Hasher>(
key_algorithm: AsymmetricKeyAlgorithm,
) {
let mundane_provider = MundaneSoftwareProvider {};
let key = mundane_provider.generate_asymmetric_key(key_algorithm, TEST_KEY_NAME).unwrap();
let test_input_data = common::generate_random_data(256);
let signature = key.sign(&test_input_data).unwrap();
let public_key = key.get_der_public_key().unwrap();
let rsa_key = RsaPubKey::<B>::parse_from_der(&public_key).unwrap();
assert_eq!(
true,
rsa::RsaSignature::<B, S, H>::from_bytes(&signature)
.is_valid(&rsa_key, &test_input_data)
);
}
#[test]
fn test_mundane_provider_parse_key() {
test_mundane_provider_parse_ec_key::<P256>(AsymmetricKeyAlgorithm::EcdsaSha256P256);
test_mundane_provider_parse_ec_key::<P384>(AsymmetricKeyAlgorithm::EcdsaSha512P384);
test_mundane_provider_parse_ec_key::<P521>(AsymmetricKeyAlgorithm::EcdsaSha512P521);
test_mundane_provider_parse_rsa_key::<B2048>(AsymmetricKeyAlgorithm::RsaSsaPssSha2562048);
test_mundane_provider_parse_rsa_key::<B2048>(AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2562048);
test_mundane_provider_parse_rsa_key::<B3072>(AsymmetricKeyAlgorithm::RsaSsaPssSha2563072);
test_mundane_provider_parse_rsa_key::<B3072>(AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2563072);
test_mundane_provider_parse_rsa_key::<B4096>(AsymmetricKeyAlgorithm::RsaSsaPssSha5124096);
test_mundane_provider_parse_rsa_key::<B4096>(AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha5124096);
}
fn test_mundane_provider_parse_ec_key<C: PCurve>(key_algorithm: AsymmetricKeyAlgorithm) {
let mundane_provider = MundaneSoftwareProvider {};
let ec_key = EcPrivKey::<C>::generate().unwrap();
let ec_key_data = ec_key.marshal_to_der();
let asymmetric_key =
mundane_provider.parse_asymmetric_key(&ec_key_data, key_algorithm).unwrap();
assert_eq!(ec_key_data, asymmetric_key.get_key_data());
}
fn test_mundane_provider_parse_rsa_key<B: RsaKeyBits>(key_algorithm: AsymmetricKeyAlgorithm) {
let mundane_provider = MundaneSoftwareProvider {};
let rsa_key = RsaPrivKey::<B>::generate().unwrap();
let rsa_key_data = rsa_key.marshal_to_der();
let asymmetric_key =
mundane_provider.parse_asymmetric_key(&rsa_key_data, key_algorithm).unwrap();
assert_eq!(rsa_key_data, asymmetric_key.get_key_data());
}
}