Skip to content

Commit

Permalink
Merge pull request #580 from ionut-arm/ts-asym-encr-v3
Browse files Browse the repository at this point in the history
Add asymmetric encryption to TS provider
  • Loading branch information
ionut-arm authored Feb 9, 2022
2 parents 985d3bb + 0e589dc commit 006c8d6
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 21 deletions.
4 changes: 3 additions & 1 deletion ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ setup_mappings() {
reload_service
}

# Use the newest version of the Rust toolchain
rustup update

# Parse arguments
NO_CARGO_CLEAN=
NO_STRESS_TEST=
Expand Down Expand Up @@ -288,7 +291,6 @@ if [ "$PROVIDER_NAME" = "cargo-check" ]; then
# - openSUSE Tumbleweed
# - openSUSE Leap 15.3
# The oldest is currently in openSUSE Leap 15.3 and is 1.53.0.
rustup update

rustup toolchain install 1.53.0
# The "jwt-svid-authenticator" can not be compiled on 1.53.0
Expand Down
14 changes: 7 additions & 7 deletions e2e_tests/docker_image/parsec-service-test-all.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ RUN rm -rf tpm2-tss
# Download and install TPM 2.0 Tools verison 4.1.1
RUN git clone https://github.com/tpm2-software/tpm2-tools.git --branch 4.1.1
RUN cd tpm2-tools \
&& ./bootstrap \
&& ./configure --prefix=/usr \
&& make -j$(nproc) \
&& make install
&& ./bootstrap \
&& ./configure --prefix=/usr \
&& make -j$(nproc) \
&& make install
RUN rm -rf tpm2-tools

# Download and install software TPM
Expand All @@ -48,7 +48,7 @@ RUN mkdir -p $ibmtpm_name \
WORKDIR $ibmtpm_name/src
RUN sed -i 's/-DTPM_NUVOTON/-DTPM_NUVOTON $(CFLAGS)/' makefile
RUN CFLAGS="-DNV_MEMORY_SIZE=32768 -DMIN_EVICT_OBJECTS=7" make -j$(nproc) \
&& cp tpm_server /usr/local/bin
&& cp tpm_server /usr/local/bin
RUN rm -rf $ibmtpm_name/src $ibmtpm_name

# Download and install SoftHSMv2
Expand Down Expand Up @@ -90,13 +90,13 @@ RUN git config --global user.email "some@email.com"
RUN git config --global user.name "Parsec Team"
RUN git clone https://git.trustedfirmware.org/TS/trusted-services.git --branch integration \
&& cd trusted-services \
&& git reset --hard c1cf9120e4ab0b359a27176b079769b9a7e6bb87
&& git reset --hard 389b50624f25dae860bbbf8b16f75b32f1589c8d
# Install correct python dependencies
RUN pip3 install -r trusted-services/requirements.txt
RUN cd trusted-services/deployments/libts/linux-pc/ \
&& cmake . \
&& make \
&& cp libts.so nanopb_install/lib/libprotobuf-nanopb.a mbedtls_install/lib/libmbedcrypto.a /usr/local/lib/
&& cp libts.so* nanopb_install/lib/libprotobuf-nanopb.a mbedtls_install/lib/libmbedcrypto.a /usr/local/lib/
RUN rm -rf trusted-services

# Create a new token in a new slot. The slot number assigned will be random
Expand Down
7 changes: 2 additions & 5 deletions src/providers/mbed_crypto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,10 @@ impl Provider {
}
};
for key_identity in to_remove.iter() {
if mbed_crypto_provider
mbed_crypto_provider
.key_info_store
.remove_key_info(key_identity)
.is_err()
{
return None;
}
.ok()?;
}
}
mbed_crypto_provider.id_counter.store(max_key_id, Relaxed);
Expand Down
70 changes: 70 additions & 0 deletions src/providers/trusted_service/asym_encryption.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use super::Provider;
use crate::authenticators::ApplicationIdentity;
use crate::key_info_managers::KeyIdentity;
use log::error;
use parsec_interface::operations::{psa_asymmetric_decrypt, psa_asymmetric_encrypt};
use parsec_interface::requests::Result;

impl Provider {
pub(super) fn psa_asymmetric_encrypt_internal(
&self,
application_identity: &ApplicationIdentity,
op: psa_asymmetric_encrypt::Operation,
) -> Result<psa_asymmetric_encrypt::Result> {
let key_identity = KeyIdentity::new(
application_identity.clone(),
self.provider_identity.clone(),
op.key_name.clone(),
);
let key_id = self.key_info_store.get_key_id(&key_identity)?;
let salt_buff = match &op.salt {
Some(salt) => salt.to_vec(),
None => Vec::new(),
};

match self
.context
.asym_encrypt(key_id, op.alg, op.plaintext.to_vec(), salt_buff)
{
Ok(ciphertext) => Ok(psa_asymmetric_encrypt::Result {
ciphertext: ciphertext.into(),
}),
Err(error) => {
error!("Encrypt failed with status: {}", error);
Err(error)
}
}
}

pub(super) fn psa_asymmetric_decrypt_internal(
&self,
application_identity: &ApplicationIdentity,
op: psa_asymmetric_decrypt::Operation,
) -> Result<psa_asymmetric_decrypt::Result> {
let key_identity = KeyIdentity::new(
application_identity.clone(),
self.provider_identity.clone(),
op.key_name.clone(),
);
let key_id = self.key_info_store.get_key_id(&key_identity)?;
let salt_buff = match &op.salt {
Some(salt) => salt.to_vec(),
None => Vec::new(),
};

match self
.context
.asym_decrypt(key_id, op.alg, op.ciphertext.to_vec(), salt_buff)
{
Ok(plaintext) => Ok(psa_asymmetric_decrypt::Result {
plaintext: plaintext.into(),
}),
Err(error) => {
error!("Decrypt failed with status: {}", error);
Err(error)
}
}
}
}
58 changes: 58 additions & 0 deletions src/providers/trusted_service/context/asym_encryption.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use super::ts_protobuf::{
AsymmetricDecryptIn, AsymmetricDecryptOut, AsymmetricEncryptIn, AsymmetricEncryptOut,
};
use super::Context;
use parsec_interface::operations::psa_algorithm::AsymmetricEncryption;
use parsec_interface::requests::ResponseStatus;
use std::convert::TryInto;
use zeroize::Zeroize;

impl Context {
pub fn asym_encrypt(
&self,
key_id: u32,
alg: AsymmetricEncryption,
mut plaintext: Vec<u8>,
mut salt: Vec<u8>,
) -> Result<Vec<u8>, ResponseStatus> {
let alg = alg.try_into().map_err(|e| {
plaintext.zeroize();
salt.zeroize();
e
})?;
let req = AsymmetricEncryptIn {
id: key_id,
alg,
plaintext,
salt,
};
let AsymmetricEncryptOut { ciphertext } = self.send_request(&req)?;

Ok(ciphertext)
}

pub fn asym_decrypt(
&self,
key_id: u32,
alg: AsymmetricEncryption,
mut ciphertext: Vec<u8>,
mut salt: Vec<u8>,
) -> Result<Vec<u8>, ResponseStatus> {
let alg = alg.try_into().map_err(|e| {
ciphertext.zeroize();
salt.zeroize();
e
})?;
let req = AsymmetricDecryptIn {
id: key_id,
alg,
ciphertext,
salt,
};
let AsymmetricDecryptOut { plaintext } = self.send_request(&req)?;

Ok(plaintext)
}
}
5 changes: 5 additions & 0 deletions src/providers/trusted_service/context/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ pub enum WrapperError {
CallBufferNull,
/// serialization or deserialization of protobuf message failed
FailedPbConversion,
/// invalid operation status value
InvalidOpStatus,
/// a parameter passed to the function was invalid
InvalidParam,
}
Expand All @@ -196,6 +198,9 @@ impl fmt::Display for WrapperError {
WrapperError::InvalidParam => {
write!(f, "a parameter passed to the function was invalid")
}
WrapperError::InvalidOpStatus => {
write!(f, "the RPC layer returned an invalid operation status")
}
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/providers/trusted_service/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use error::{Error, WrapperError};
use log::{error, info, trace};
use prost::Message;
use std::convert::TryInto;
use std::convert::{TryFrom, TryInto};
use std::ffi::{c_void, CString};
use std::io::{self};
use std::ptr::null_mut;
Expand All @@ -27,9 +27,11 @@ use ts_protobuf::GetOpcode;
unused_qualifications
)]
pub mod ts_binding {
#![allow(deref_nullptr)]
include!(concat!(env!("OUT_DIR"), "/ts_bindings.rs"));
}

mod asym_encryption;
mod asym_sign;
pub mod error;
mod generate_random;
Expand Down Expand Up @@ -158,7 +160,11 @@ impl Context {
&mut resp_buf_size,
)
};
Error::from_status_opstatus(status, opstatus).map_err(|e| {
Error::from_status_opstatus(
status,
i32::try_from(opstatus).map_err(|_| Error::Wrapper(WrapperError::InvalidOpStatus))?,
)
.map_err(|e| {
unsafe { rpc_caller_end(self.rpc_caller, call_handle) };
e
})?;
Expand Down
2 changes: 2 additions & 0 deletions src/providers/trusted_service/context/ts_protobuf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ opcode_impl!(ImportKeyIn, ImportKeyOut, ImportKey);
opcode_impl!(ExportPublicKeyIn, ExportPublicKeyOut, ExportPublicKey);
opcode_impl!(ExportKeyIn, ExportKeyOut, ExportKey);
opcode_impl!(GenerateRandomIn, GenerateRandomOut, GenerateRandom);
opcode_impl!(AsymmetricDecryptIn, AsymmetricDecryptOut, AsymmetricDecrypt);
opcode_impl!(AsymmetricEncryptIn, AsymmetricEncryptOut, AsymmetricEncrypt);

impl Drop for ImportKeyIn {
fn drop(&mut self) {
Expand Down
3 changes: 2 additions & 1 deletion src/providers/trusted_service/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ impl From<WrapperError> for ResponseStatus {
WrapperError::CallBufferNull
| WrapperError::CallHandleNull
| WrapperError::FailedPbConversion
| WrapperError::InvalidParam => ResponseStatus::PsaErrorCommunicationFailure,
| WrapperError::InvalidParam
| WrapperError::InvalidOpStatus => ResponseStatus::PsaErrorCommunicationFailure,
}
}
}
Expand Down
28 changes: 25 additions & 3 deletions src/providers/trusted_service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,25 @@ use derivative::Derivative;
use log::{error, trace};
use parsec_interface::operations::list_providers::ProviderInfo;
use parsec_interface::operations::{
can_do_crypto, list_clients, list_keys, psa_destroy_key, psa_export_key, psa_export_public_key,
psa_generate_key, psa_generate_random, psa_import_key, psa_sign_hash, psa_verify_hash,
can_do_crypto, list_clients, list_keys, psa_asymmetric_decrypt, psa_asymmetric_encrypt,
psa_destroy_key, psa_export_key, psa_export_public_key, psa_generate_key, psa_generate_random,
psa_import_key, psa_sign_hash, psa_verify_hash,
};
use parsec_interface::requests::{Opcode, ProviderId, Result};
use psa_crypto::types::key;
use std::collections::HashSet;
use std::sync::atomic::{AtomicU32, Ordering};
use uuid::Uuid;

mod asym_encryption;
mod asym_sign;
mod capability_discovery;
mod context;
mod error;
mod generate_random;
mod key_management;

const SUPPORTED_OPCODES: [Opcode; 9] = [
const SUPPORTED_OPCODES: [Opcode; 11] = [
Opcode::PsaDestroyKey,
Opcode::PsaGenerateKey,
Opcode::PsaSignHash,
Expand All @@ -38,6 +40,8 @@ const SUPPORTED_OPCODES: [Opcode; 9] = [
Opcode::PsaExportKey,
Opcode::PsaGenerateRandom,
Opcode::CanDoCrypto,
Opcode::PsaAsymmetricEncrypt,
Opcode::PsaAsymmetricDecrypt,
];
/// Trusted Service provider structure
///
Expand Down Expand Up @@ -239,6 +243,24 @@ impl Provide for Provider {
trace!("can_do_crypto ingress");
self.can_do_crypto_main(application_identity, op)
}

fn psa_asymmetric_encrypt(
&self,
application_identity: &ApplicationIdentity,
op: psa_asymmetric_encrypt::Operation,
) -> Result<psa_asymmetric_encrypt::Result> {
trace!("psa_asymmetric_encrypt ingress");
self.psa_asymmetric_encrypt_internal(application_identity, op)
}

fn psa_asymmetric_decrypt(
&self,
application_identity: &ApplicationIdentity,
op: psa_asymmetric_decrypt::Operation,
) -> Result<psa_asymmetric_decrypt::Result> {
trace!("psa_asymmetric_decrypt ingress");
self.psa_asymmetric_decrypt_internal(application_identity, op)
}
}

/// Trusted Service provider builder
Expand Down
2 changes: 1 addition & 1 deletion src/utils/service_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ unsafe fn get_provider(
}
#[cfg(feature = "trusted-service-provider")]
ProviderConfig::TrustedService { .. } => {
info!("Creating a TPM Provider.");
info!("Creating a Trusted Service Provider.");
let provider_identity = ProviderIdentity::new(
TrustedServiceProvider::PROVIDER_UUID.to_string(),
config.provider_name()?,
Expand Down
2 changes: 1 addition & 1 deletion trusted-services-vendor
Submodule trusted-services-vendor updated from c1cf91 to 389b50

0 comments on commit 006c8d6

Please sign in to comment.