Skip to content

Commit 06de5c9

Browse files
authored
Merge pull request #515 from ionut-arm/trans-key-ctx
Update provider to use new version fo TransKeyCtx
2 parents 48d55aa + b3bb5ad commit 06de5c9

File tree

13 files changed

+454
-284
lines changed

13 files changed

+454
-284
lines changed

Cargo.lock

Lines changed: 55 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ log = { version = "0.4.14", features = ["serde"] }
2929
cryptoki = { version = "0.2.0", optional = true, features = ["psa-crypto-conversions"] }
3030
picky-asn1-der = { version = "<=0.2.4", optional = true }
3131
picky-asn1 = { version = ">=0.3.1, <=0.3.1", optional = true }
32-
tss-esapi = { version = "6.1.0", optional = true }
32+
tss-esapi = { version = "7.0.0-alpha.1", optional = true }
3333
bincode = "1.3.1"
3434
structopt = "0.3.21"
3535
derivative = "2.2.0"

ci.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,4 +366,27 @@ else
366366
echo "Execute stress tests"
367367
RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml stress_test
368368
fi
369+
370+
# For the TPM provider we check that keys can still be used after a TPM Reset
371+
if [ "$PROVIDER_NAME" = "tpm" ]; then
372+
# We first create the keys
373+
RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml before_tpm_reset
374+
stop_service
375+
376+
# In order to reset the TPM, we need to restart the TPM server and send a Startup(CLEAR)
377+
pkill tpm_server
378+
sleep 1
379+
380+
tpm_server &
381+
TPM_SRV_PID=$!
382+
sleep 5
383+
384+
tpm2_startup -c -T mssim
385+
386+
# We then spin up the service again and check that the keys can still be used
387+
RUST_LOG=error RUST_BACKTRACE=1 cargo run --release $FEATURES -- --config $CONFIG_PATH &
388+
wait_for_service
389+
390+
RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml after_tpm_reset
391+
fi
369392
fi

e2e_tests/tests/per_provider/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
mod key_mappings;
44
mod normal_tests;
55
mod stress_test;
6+
#[cfg(feature = "tpm-provider")]
7+
mod tpm_reset;

e2e_tests/tests/per_provider/normal_tests/asym_sign_verify.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ fn asym_verify_fail_ecc_sha256() -> Result<()> {
9090
#[test]
9191
fn only_verify_from_internet() -> Result<()> {
9292
let mut client = TestClient::new();
93-
let key_name = String::from("only_verify");
93+
let key_name = String::from("only_verify_from_internet");
9494
if !client.is_operation_supported(Opcode::PsaImportKey) {
9595
return Ok(());
9696
}

e2e_tests/tests/per_provider/normal_tests/import_key.rs

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -365,43 +365,43 @@ fn failed_imported_key_should_be_removed() -> Result<()> {
365365
Ok(())
366366
}
367367

368-
#[cfg(feature = "tpm-provider")]
369-
#[test]
370-
fn import_key_pair() {
371-
let mut client = TestClient::new();
372-
let key_name = String::from("failed_imported_key_should_be_removed");
373-
374-
client
375-
.import_key(
376-
key_name,
377-
Attributes {
378-
lifetime: Lifetime::Persistent,
379-
key_type: Type::RsaKeyPair,
380-
bits: 1024,
381-
policy: Policy {
382-
usage_flags: UsageFlags {
383-
export: false,
384-
copy: false,
385-
cache: false,
386-
encrypt: false,
387-
decrypt: false,
388-
sign_message: true,
389-
sign_hash: true,
390-
verify_message: true,
391-
verify_hash: true,
392-
derive: false,
393-
},
394-
permitted_algorithms: Algorithm::AsymmetricSignature(
395-
AsymmetricSignature::RsaPkcs1v15Sign {
396-
hash_alg: Hash::Sha256.into(),
397-
},
398-
),
399-
},
400-
},
401-
KEY_PAIR_DATA.to_vec(),
402-
)
403-
.unwrap();
404-
}
368+
// #[cfg(feature = "tpm-provider")]
369+
// #[test]
370+
// fn import_key_pair() {
371+
// let mut client = TestClient::new();
372+
// let key_name = String::from("failed_imported_key_should_be_removed");
373+
374+
// client
375+
// .import_key(
376+
// key_name,
377+
// Attributes {
378+
// lifetime: Lifetime::Persistent,
379+
// key_type: Type::RsaKeyPair,
380+
// bits: 1024,
381+
// policy: Policy {
382+
// usage_flags: UsageFlags {
383+
// export: false,
384+
// copy: false,
385+
// cache: false,
386+
// encrypt: false,
387+
// decrypt: false,
388+
// sign_message: true,
389+
// sign_hash: true,
390+
// verify_message: true,
391+
// verify_hash: true,
392+
// derive: false,
393+
// },
394+
// permitted_algorithms: Algorithm::AsymmetricSignature(
395+
// AsymmetricSignature::RsaPkcs1v15Sign {
396+
// hash_alg: Hash::Sha256.into(),
397+
// },
398+
// ),
399+
// },
400+
// },
401+
// KEY_PAIR_DATA.to_vec(),
402+
// )
403+
// .unwrap();
404+
// }
405405

406406
#[cfg(any(feature = "mbed-crypto-provider", feature = "cryptoauthlib-provider"))]
407407
#[test]
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2021 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
// These tests track a potential regression where the TPM provider
5+
// was unable to handle stored keys after a TPM reset.
6+
//
7+
// `before_tpm_reset` creates keys that should be usable post-TPM-reset,
8+
// in `after_tpm_reset`.
9+
//
10+
// See: https://github.com/parallaxsecond/parsec/issues/504
11+
use e2e_tests::TestClient;
12+
13+
const RSA_KEY_NAME: &str = "tpm-reset-rsa";
14+
const ECC_KEY_NAME: &str = "tpm-reset-ecc";
15+
16+
#[test]
17+
fn before_tpm_reset() {
18+
let mut client = TestClient::new();
19+
client.do_not_destroy_keys();
20+
21+
let rsa_key_name = String::from(RSA_KEY_NAME);
22+
let ecc_key_name = String::from(ECC_KEY_NAME);
23+
24+
client.generate_rsa_sign_key(rsa_key_name.clone()).unwrap();
25+
client
26+
.generate_ecc_key_pair_secpr1_ecdsa_sha256(ecc_key_name.clone())
27+
.unwrap();
28+
}
29+
30+
#[test]
31+
fn after_tpm_reset() {
32+
let mut client = TestClient::new();
33+
34+
let rsa_key_name = String::from(RSA_KEY_NAME);
35+
let ecc_key_name = String::from(ECC_KEY_NAME);
36+
37+
let _ = client
38+
.sign_with_rsa_sha256(rsa_key_name, vec![0xff; 32])
39+
.unwrap();
40+
let _ = client
41+
.sign_with_ecdsa_sha256(ecc_key_name, vec![0xff; 32])
42+
.unwrap();
43+
}

src/key_info_managers/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,39 @@ impl KeyInfoManagerClient {
261261
}
262262
}
263263

264+
/// Replace the key info saved for a given triple
265+
///
266+
/// # Errors
267+
///
268+
/// If the key triple doesn't exist in the KIM, PsaErrorDoesNotExist is returned. For
269+
/// any other error occurring in the KIM, KeyInfoManagerError is returned.
270+
pub fn replace_key_info<T: Serialize>(
271+
&self,
272+
key_triple: KeyTriple,
273+
key_id: &T,
274+
attributes: Attributes,
275+
) -> parsec_interface::requests::Result<()> {
276+
let mut key_info_manager_impl = self
277+
.key_info_manager_impl
278+
.write()
279+
.expect("Key Info Manager lock poisoned");
280+
let key_info = KeyInfo {
281+
id: bincode::serialize(key_id)?,
282+
attributes,
283+
};
284+
285+
match key_info_manager_impl.insert(key_triple.clone(), key_info) {
286+
Ok(None) => {
287+
let _ = key_info_manager_impl
288+
.remove(&key_triple)
289+
.map_err(to_response_status)?;
290+
Err(ResponseStatus::PsaErrorDoesNotExist)
291+
}
292+
Ok(Some(_)) => Ok(()),
293+
Err(string) => Err(to_response_status(string)),
294+
}
295+
}
296+
264297
/// Returns a Vec of ApplicationName of clients having keys in the provider.
265298
///
266299
/// # Errors

src/providers/tpm/asym_encryption.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
// Copyright 2020 Contributors to the Parsec project.
22
// SPDX-License-Identifier: Apache-2.0
3-
use super::{
4-
utils::{self, PasswordContext},
5-
Provider,
6-
};
3+
use super::{utils, Provider};
74
use crate::authenticators::ApplicationName;
85
use crate::key_info_managers::KeyTriple;
96
use parsec_interface::operations::{psa_asymmetric_decrypt, psa_asymmetric_encrypt};
@@ -19,21 +16,22 @@ impl Provider {
1916
) -> Result<psa_asymmetric_encrypt::Result> {
2017
let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, op.key_name.clone());
2118

19+
let password_context = self.get_key_ctx(&key_triple)?;
20+
let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?;
21+
2222
let mut esapi_context = self
2323
.esapi_context
2424
.lock()
2525
.expect("ESAPI Context lock poisoned");
2626

27-
let password_context: PasswordContext = self.key_info_store.get_key_id(&key_triple)?;
28-
let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?;
29-
3027
op.validate(key_attributes)?;
3128

3229
match esapi_context.rsa_encrypt(
33-
password_context.context,
30+
password_context.key_material().clone(),
31+
utils::parsec_to_tpm_params(key_attributes)?,
3432
Some(
3533
password_context
36-
.auth_value
34+
.auth_value()
3735
.try_into()
3836
.map_err(utils::to_response_status)?,
3937
),
@@ -42,7 +40,6 @@ impl Provider {
4240
.clone()
4341
.try_into()
4442
.map_err(utils::to_response_status)?,
45-
utils::convert_asym_scheme_to_tpm(op.alg.into())?,
4643
match op.salt {
4744
Some(salt) => Some(
4845
salt.deref()
@@ -71,21 +68,22 @@ impl Provider {
7168
) -> Result<psa_asymmetric_decrypt::Result> {
7269
let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, op.key_name.clone());
7370

71+
let password_context = self.get_key_ctx(&key_triple)?;
72+
let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?;
73+
7474
let mut esapi_context = self
7575
.esapi_context
7676
.lock()
7777
.expect("ESAPI Context lock poisoned");
7878

79-
let password_context: PasswordContext = self.key_info_store.get_key_id(&key_triple)?;
80-
let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?;
81-
8279
op.validate(key_attributes)?;
8380

8481
match esapi_context.rsa_decrypt(
85-
password_context.context,
82+
password_context.key_material().clone(),
83+
utils::parsec_to_tpm_params(key_attributes)?,
8684
Some(
8785
password_context
88-
.auth_value
86+
.auth_value()
8987
.try_into()
9088
.map_err(utils::to_response_status)?,
9189
),
@@ -94,7 +92,6 @@ impl Provider {
9492
.clone()
9593
.try_into()
9694
.map_err(utils::to_response_status)?,
97-
utils::convert_asym_scheme_to_tpm(op.alg.into())?,
9895
match op.salt {
9996
Some(salt) => Some(
10097
salt.deref()

0 commit comments

Comments
 (0)