Skip to content

Commit

Permalink
Update TS submodule and add asym encryption
Browse files Browse the repository at this point in the history
This commit pulls in new changes to the upstream TS project and adds
asymmetric encryption support for the provider.

Signed-off-by: Ionut Mihalcea <ionut.mihalcea@arm.com>
  • Loading branch information
ionut-arm committed Jul 6, 2021
1 parent ae83555 commit 2c4632e
Show file tree
Hide file tree
Showing 11 changed files with 217 additions and 128 deletions.
58 changes: 29 additions & 29 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,79 +9,79 @@ jobs:
steps:
- uses: actions/checkout@v2
# Use the following step when updating the `parsec-service-test-all` image
# - name: Build the container
# run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Build the container
run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Run the container to execute the test script
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh all
# When running the container built on the CI
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh all
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh all
# When running the container built on the CI
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh all

mbed-crypto-provider:
name: Integration tests using Mbed Crypto provider
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Use the following step when updating the `parsec-service-test-all` image
# - name: Build the container
# run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Build the container
run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Run the container to execute the test script
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh mbed-crypto
# When running the container built on the CI
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh mbed-crypto
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh mbed-crypto
# When running the container built on the CI
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh mbed-crypto

pkcs11-provider:
name: Integration tests using PKCS 11 provider
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Use the following step when updating the `parsec-service-test-all` image
# - name: Build the container
# run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Build the container
run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Run the container to execute the test script
# Not running stress tests because they fail, presumably because of the same issue as #264
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh pkcs11 --no-stress-test
# When running the container built on the CI
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh pkcs11 --no-stress-test
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh pkcs11 --no-stress-test
# When running the container built on the CI
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh pkcs11 --no-stress-test

tpm-provider:
name: Integration tests using TPM provider
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Use the following step when updating the `parsec-service-test-all` image
# - name: Build the container
# run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Build the container
run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Run the container to execute the test script
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh tpm
# When running the container built on the CI
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh tpm
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh tpm
# When running the container built on the CI
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh tpm

trusted-service-provider:
name: Integration tests using Cypto Trusted Service provider
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Use the following step when updating the `parsec-service-test-all` image
# - name: Build the container
# run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Build the container
run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Run the container to execute the test script
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh trusted-service
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh trusted-service
# When running the container built on the CI
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh trusted-service
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh trusted-service

cryptoauthlib-provider:
name: Integration tests using CryptoAuthentication Library provider
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Use the following step when updating the `parsec-service-test-all` image
# - name: Build the container
# run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Build the container
run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd
- name: Run the container to execute the test script
# Not running stress tests because rust-cryptoauthlib test-interface does not support required calls
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh cryptoauthlib --no-stress-test
# When running the container built on the CI
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh cryptoauthlib --no-stress-test
# run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec ghcr.io/parallaxsecond/parsec-service-test-all /tmp/parsec/ci.sh cryptoauthlib --no-stress-test
# When running the container built on the CI
run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh cryptoauthlib --no-stress-test

fuzz-test-checker:
name: Check that the fuzz testing framework is still working
Expand Down
4 changes: 2 additions & 2 deletions e2e_tests/docker_image/parsec-service-test-all.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ RUN cd nanopb-0.4.4-linux-x86 \
RUN rm -rf nanopb-0.4.4-linux-x86 nanopb-0.4.4-linux-x86.tar.gz

# Install mock Trusted Services
RUN git clone https://git.trustedfirmware.org/TS/trusted-services.git --branch main \
RUN git clone https://git.trustedfirmware.org/TS/trusted-services.git --branch integration \
&& cd trusted-services \
&& git reset --hard 2fc7e10c7c21e4dafbf63dc9d00dfc2a7a7fddad
&& git reset --hard c1cf9120e4ab0b359a27176b079769b9a7e6bb87
# Install correct python dependencies
RUN pip3 install -r trusted-services/requirements.txt
RUN cd trusted-services/deployments/libts/linux-pc/ \
Expand Down
64 changes: 64 additions & 0 deletions src/providers/trusted_service/asym_encryption.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use super::Provider;
use crate::authenticators::ApplicationName;
use crate::key_info_managers::KeyTriple;
use log::error;
use parsec_interface::operations::{psa_asymmetric_decrypt, psa_asymmetric_encrypt};
use parsec_interface::requests::{ProviderId, Result};

impl Provider {
pub(super) fn psa_asymmetric_encrypt_internal(
&self,
app_name: ApplicationName,
op: psa_asymmetric_encrypt::Operation,
) -> Result<psa_asymmetric_encrypt::Result> {
let key_name = op.key_name.clone();

let key_triple = KeyTriple::new(app_name, ProviderId::TrustedService, key_name);
let key_id = self.key_info_store.get_key_id(&key_triple)?;
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,
app_name: ApplicationName,
op: psa_asymmetric_decrypt::Operation,
) -> Result<psa_asymmetric_decrypt::Result> {
let key_triple = KeyTriple::new(app_name, ProviderId::TrustedService, op.key_name.clone());
let key_id = self.key_info_store.get_key_id(&key_triple)?;
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)
}
}
8 changes: 4 additions & 4 deletions src/providers/trusted_service/context/asym_sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ impl Context {
) -> Result<Vec<u8>, Error> {
info!("Handling SignHash request");
let proto_req = SignHashIn {
handle: 0,
id: key_id,
hash,
alg: algorithm.try_into()?,
};
let SignHashOut { signature } = self.send_request_with_key(proto_req, key_id)?;
let SignHashOut { signature } = self.send_request(&proto_req)?;

Ok(signature)
}
Expand All @@ -36,12 +36,12 @@ impl Context {
) -> Result<(), Error> {
info!("Handling VerifyHash request");
let proto_req = VerifyHashIn {
handle: 0,
id: key_id,
hash,
signature,
alg: algorithm.try_into()?,
};
self.send_request_with_key(proto_req, key_id)?;
self.send_request(&proto_req)?;

Ok(())
}
Expand Down
42 changes: 7 additions & 35 deletions src/providers/trusted_service/context/key_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
use super::error::Error;
use super::ts_protobuf::{
CloseKeyIn, DestroyKeyIn, DestroyKeyOut, ExportPublicKeyIn, GenerateKeyIn, GenerateKeyOut,
ImportKeyIn, ImportKeyOut, KeyAttributes, KeyLifetime, KeyPolicy, OpenKeyIn, OpenKeyOut,
DestroyKeyIn, DestroyKeyOut, ExportPublicKeyIn, GenerateKeyIn, ImportKeyIn, KeyAttributes,
KeyLifetime, KeyPolicy,
};
use super::Context;
use log::info;
use psa_crypto::types::key::Attributes;
use psa_crypto::types::status::Error as PsaError;
use std::convert::{TryFrom, TryInto};
use zeroize::Zeroize;

Expand All @@ -31,10 +30,7 @@ impl Context {
}),
}),
};
let GenerateKeyOut { handle } = self.send_request(&generate_req)?;

let close_req = CloseKeyIn { handle };
self.send_request(&close_req)?;
let _ = self.send_request(&generate_req)?;

Ok(())
}
Expand Down Expand Up @@ -74,10 +70,7 @@ impl Context {
}),
data,
};
let ImportKeyOut { handle } = self.send_request(&import_req)?;

let close_req = CloseKeyIn { handle };
self.send_request(&close_req)?;
let _ = self.send_request(&import_req)?;

Ok(())
}
Expand All @@ -88,37 +81,16 @@ impl Context {
/// format.
pub fn export_public_key(&self, id: u32) -> Result<Vec<u8>, Error> {
info!("Handling ExportPublicKey request");
self.send_request_with_key(ExportPublicKeyIn::default(), id)
let req = ExportPublicKeyIn { id };
self.send_request(&req)
}

/// Destroy a key given its ID.
pub fn destroy_key(&self, key_id: u32) -> Result<(), Error> {
info!("Handling DestroyKey request");
let open_req = OpenKeyIn { id: key_id };
let OpenKeyOut { handle } = self.send_request(&open_req)?;

let destroy_req = DestroyKeyIn { handle };
let destroy_req = DestroyKeyIn { id: key_id };
let _proto_resp: DestroyKeyOut = self.send_request(&destroy_req)?;
Ok(())
}

/// Verify if a key with a given ID exists.
pub fn check_key_exists(&self, key_id: u32) -> Result<bool, Error> {
info!("Handling CheckKey request");
let open_req = OpenKeyIn { id: key_id };
match self.send_request(&open_req) {
Ok(OpenKeyOut { handle }) => {
let close_req = CloseKeyIn { handle };
self.send_request(&close_req)?;
Ok(true)
}
Err(e) => {
if e == Error::PsaCrypto(PsaError::DoesNotExist) {
Ok(false)
} else {
Err(e)
}
}
}
}
}
Loading

0 comments on commit 2c4632e

Please sign in to comment.