spdm: Improve Crypto trait dependency
Make 2 changes to the Crypto trait:
1. The not-yet-implemented FFI Crypto trait and the test Crypto trait
use unit type as the crypto types for convenience. As the result,
some methods are actually using wrong parameter types compared from
the Crypto trait definition, but isn't found out because those types
are all unit types. Change those unit types to different unit structs
that have the same convenience, but avoids messing up with different
param types.
2. Make `random_key_pair` specify different lifetime params for the
private key and public key, as they might have different lifetimes at
the call site.
BUG=b:338528575
TEST=spdm unittests
Change-Id: I3beb6b4e8aa14cf22bcba126a3f85ea69ed347d9
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/spdm/+/5526571
Reviewed-by: Vadim Sukhomlinov <sukhomlinov@google.com>
Tested-by: Howard Yang <hcyang@google.com>
Commit-Queue: ChromeOS Auto Retry <chromeos-auto-retry@chromeos-bot.iam.gserviceaccount.com>
diff --git a/spdm-requester/src/dispatch.rs b/spdm-requester/src/dispatch.rs
index 72300be..28b6d7b 100644
--- a/spdm-requester/src/dispatch.rs
+++ b/spdm-requester/src/dispatch.rs
@@ -165,7 +165,7 @@
use std::cell::RefCell;
use mocktopus::mocking::{MockContext, MockResult};
- use spdm_test_deps::{TestCrypto, TestDispatch, TestIdentity};
+ use spdm_test_deps::{HmacDerivationKeyHandle, TestCrypto, TestDispatch, TestIdentity};
use spdm_types::deps::{Crypto, CryptoError};
use super::super::*;
@@ -179,7 +179,7 @@
requester.session.session_id = Some([0xaa, 0xbb, 0xcc, 0xdd]);
requester.session.th1 = Some([0xCC; 32]);
- requester.session.handshake_secret = Some(());
+ requester.session.handshake_secret = Some(HmacDerivationKeyHandle);
let plaintext = RefCell::new(vec![]);
MockContext::new()
@@ -318,7 +318,7 @@
requester.session.session_id = Some([0xaa, 0xbb, 0xcc, 0xdd]);
requester.session.th2 = Some([0xCC; 32]);
- requester.session.main_secret = Some(());
+ requester.session.main_secret = Some(HmacDerivationKeyHandle);
let plaintext = RefCell::new(vec![]);
MockContext::new()
diff --git a/spdm-responder-ffi/src/deps.rs b/spdm-responder-ffi/src/deps.rs
index c8bf294..58db330 100644
--- a/spdm-responder-ffi/src/deps.rs
+++ b/spdm-responder-ffi/src/deps.rs
@@ -14,14 +14,19 @@
/// Implements Crypto by interacting with the static eal functions.
pub struct EalCrypto;
+pub struct Sha256HashContext;
+pub struct HmacDerivationKeyHandle;
+pub struct HmacSecretKeyHandle;
+pub struct AesGcmKeyHandle;
+
impl Crypto for EalCrypto {
/// Use raw private key for eal's private key handle.
type IdentityPrivateKeyHandle = IdentityPrivateKey;
// TODO(b/284404632): Decide some crypto types for eal.
- type Sha256HashContext = ();
- type HmacDerivationKeyHandle = ();
- type HmacSecretKeyHandle = ();
- type AesGcmKeyHandle = ();
+ type Sha256HashContext = Sha256HashContext;
+ type HmacDerivationKeyHandle = HmacDerivationKeyHandle;
+ type HmacSecretKeyHandle = HmacSecretKeyHandle;
+ type AesGcmKeyHandle = AesGcmKeyHandle;
fn sha256_init(
_ctx: Out<Self::Sha256HashContext>,
@@ -103,13 +108,13 @@
fn hmac_expand_derivation_key<'a>(
_hmac_derivation_key_handle_in: &Self::HmacDerivationKeyHandle,
_info: &[u8],
- hmac_derivation_key_handle_out: Out<'a, Self::HmacDerivationKeyHandle>,
+ _hmac_derivation_key_handle_out: Out<'a, Self::HmacDerivationKeyHandle>,
) -> CryptoResult<&'a mut Self::HmacDerivationKeyHandle> {
- Ok(hmac_derivation_key_handle_out.write(()))
+ unimplemented!()
}
fn hmac_expand_aes_gcm_key<'a>(
- _hmac_secret_key_handle: &Self::HmacSecretKeyHandle,
+ _hmac_derivation_key_handle: &Self::HmacDerivationKeyHandle,
_info: &[u8],
_aes_gcm_key: Out<'a, Self::AesGcmKeyHandle>,
) -> CryptoResult<&'a mut Self::AesGcmKeyHandle> {
@@ -117,7 +122,7 @@
}
fn hmac_expand_aes_gcm_iv<'a>(
- _hmac_secret_key_handle: &Self::HmacSecretKeyHandle,
+ _hmac_derivation_key_handle: &Self::HmacDerivationKeyHandle,
_info: &[u8],
_aes_gcm_iv: Out<'a, AesGcm128Iv>,
) -> CryptoResult<&'a mut AesGcm128Iv> {
@@ -164,12 +169,12 @@
unimplemented!()
}
- fn random_key_pair<'a>(
+ fn random_key_pair<'a, 'b>(
_private: Out<'a, Self::IdentityPrivateKeyHandle>,
- _public: Out<'a, IdentityPublicKey>,
+ _public: Out<'b, IdentityPublicKey>,
) -> CryptoResult<(
&'a mut Self::IdentityPrivateKeyHandle,
- &'a mut IdentityPublicKey,
+ &'b mut IdentityPublicKey,
)> {
unimplemented!()
}
diff --git a/spdm-responder/src/dispatch/internal.rs b/spdm-responder/src/dispatch/internal.rs
index 7ce2964..d2dcff3 100644
--- a/spdm-responder/src/dispatch/internal.rs
+++ b/spdm-responder/src/dispatch/internal.rs
@@ -201,7 +201,7 @@
#[cfg(feature = "mock")]
mod mock {
use mocktopus::mocking::{MockContext, MockResult};
- use spdm_test_deps::TestCrypto;
+ use spdm_test_deps::{HmacDerivationKeyHandle, TestCrypto};
use spdm_types::deps::Crypto;
use super::*;
@@ -220,7 +220,7 @@
let mut spdm = Responder::<TestResponderDeps>::new(TestIdentity, TestVendor);
spdm.session.session_id = Some([0xaa, 0xbb, 0xcc, 0xdd]);
spdm.session.th1 = Some([0xCC; 32]);
- spdm.session.handshake_secret = Some(());
+ spdm.session.handshake_secret = Some(HmacDerivationKeyHandle);
spdm.state = ResponderState::WaitForRequesterKey;
MockContext::new()
.mock_safe(TestCrypto::aes_gcm_decrypt, |_, _, _, _, buf| {
diff --git a/spdm-types/src/deps/crypto.rs b/spdm-types/src/deps/crypto.rs
index 7bff212..ae4571e 100644
--- a/spdm-types/src/deps/crypto.rs
+++ b/spdm-types/src/deps/crypto.rs
@@ -113,8 +113,8 @@
/// Perform HMAC expand from using `hmac_derivation_key_handle` and `info`. HMAC
/// expand uses a secret value as the HMAC key and info as the data to produce
/// another secret value, pointed by `hmac_secret_key_handle`. It is equivalent
- /// to the first `output_size` bytes of `HMAC(key, info||0x00)` because in SPDM
- /// we always expand to less than the hash size.
+ /// to the first `output_size` bytes of `HMAC(key, info||0x01)` because in SPDM
+ /// we always expand to less or equal than the hash size.
/// This expands into a HMAC secret key which can be used for performing ordinary HMAC.
fn hmac_expand_hmac_secret_key<'a>(
hmac_derivation_key_handle: &Self::HmacDerivationKeyHandle,
@@ -176,11 +176,11 @@
/// Fill `buf` with random bytes.
fn random_bytes(buf: Out<[u8]>) -> CryptoResult<&mut [u8]>;
/// Randomly generate a valid P256 EC key pair.
- fn random_key_pair<'a>(
+ fn random_key_pair<'a, 'b>(
private: Out<'a, Self::IdentityPrivateKeyHandle>,
- public: Out<'a, IdentityPublicKey>,
+ public: Out<'b, IdentityPublicKey>,
) -> CryptoResult<(
&'a mut Self::IdentityPrivateKeyHandle,
- &'a mut IdentityPublicKey,
+ &'b mut IdentityPublicKey,
)>;
}
diff --git a/test-deps/src/crypto.rs b/test-deps/src/crypto.rs
index 0ffeb8c..347d11c 100644
--- a/test-deps/src/crypto.rs
+++ b/test-deps/src/crypto.rs
@@ -30,18 +30,24 @@
pub struct TestCrypto;
+pub struct IdentityPrivateKeyHandle;
+pub struct Sha256HashContext;
+pub struct HmacDerivationKeyHandle;
+pub struct HmacSecretKeyHandle;
+pub struct AesGcmKeyHandle;
+
#[cfg_attr(feature = "mock", mockable)]
impl Crypto for TestCrypto {
- type IdentityPrivateKeyHandle = ();
- type Sha256HashContext = ();
- type HmacDerivationKeyHandle = ();
- type HmacSecretKeyHandle = ();
- type AesGcmKeyHandle = ();
+ type IdentityPrivateKeyHandle = IdentityPrivateKeyHandle;
+ type Sha256HashContext = Sha256HashContext;
+ type HmacDerivationKeyHandle = HmacDerivationKeyHandle;
+ type HmacSecretKeyHandle = HmacSecretKeyHandle;
+ type AesGcmKeyHandle = AesGcmKeyHandle;
fn sha256_init(
ctx: Out<Self::Sha256HashContext>,
) -> CryptoResult<&mut Self::Sha256HashContext> {
- Ok(ctx.write(()))
+ Ok(ctx.write(Sha256HashContext))
}
fn sha256_update(_ctx: &mut Self::Sha256HashContext, _data: &[u8]) -> CryptoStatus {
@@ -84,7 +90,7 @@
_salt: &[u8],
hmac_derivation_key_handle: Out<'a, Self::HmacDerivationKeyHandle>,
) -> CryptoResult<&'a mut Self::HmacDerivationKeyHandle> {
- Ok(hmac_derivation_key_handle.write(()))
+ Ok(hmac_derivation_key_handle.write(HmacDerivationKeyHandle))
}
fn hmac_extract_from_ecdh<'a, 'b>(
@@ -98,7 +104,7 @@
)> {
Ok((
my_public_key.write(TEST_PUBLIC_KEY),
- hmac_derivation_key_handle.write(()),
+ hmac_derivation_key_handle.write(HmacDerivationKeyHandle),
))
}
@@ -107,7 +113,7 @@
_data: &[u8],
hmac_derivation_key_handle_out: Out<'a, Self::HmacDerivationKeyHandle>,
) -> CryptoResult<&'a mut Self::HmacDerivationKeyHandle> {
- Ok(hmac_derivation_key_handle_out.write(()))
+ Ok(hmac_derivation_key_handle_out.write(HmacDerivationKeyHandle))
}
fn hmac_expand_hmac_secret_key<'a>(
@@ -115,7 +121,7 @@
_info: &[u8],
hmac_secret_key_handle: Out<'a, Self::HmacSecretKeyHandle>,
) -> CryptoResult<&'a mut Self::HmacSecretKeyHandle> {
- Ok(hmac_secret_key_handle.write(()))
+ Ok(hmac_secret_key_handle.write(HmacSecretKeyHandle))
}
fn hmac_expand_derivation_key<'a>(
@@ -123,19 +129,19 @@
_info: &[u8],
hmac_derivation_key_handle_out: Out<'a, Self::HmacDerivationKeyHandle>,
) -> CryptoResult<&'a mut Self::HmacDerivationKeyHandle> {
- Ok(hmac_derivation_key_handle_out.write(()))
+ Ok(hmac_derivation_key_handle_out.write(HmacDerivationKeyHandle))
}
fn hmac_expand_aes_gcm_key<'a>(
- _hmac_secret_key_handle: &Self::HmacSecretKeyHandle,
+ _hmac_derivation_key_handle: &Self::HmacDerivationKeyHandle,
_info: &[u8],
aes_gcm_key: Out<'a, Self::AesGcmKeyHandle>,
) -> CryptoResult<&'a mut Self::AesGcmKeyHandle> {
- Ok(aes_gcm_key.write(()))
+ Ok(aes_gcm_key.write(AesGcmKeyHandle))
}
fn hmac_expand_aes_gcm_iv<'a>(
- _hmac_secret_key_handle: &Self::HmacSecretKeyHandle,
+ _hmac_derivation_key_handle: &Self::HmacDerivationKeyHandle,
_info: &[u8],
aes_gcm_iv: Out<'a, AesGcm128Iv>,
) -> CryptoResult<&'a mut AesGcm128Iv> {
@@ -182,13 +188,16 @@
Ok(buf.fill_with_iter(repeat(0xDD)))
}
- fn random_key_pair<'a>(
+ fn random_key_pair<'a, 'b>(
private: Out<'a, Self::IdentityPrivateKeyHandle>,
- public: Out<'a, IdentityPublicKey>,
+ public: Out<'b, IdentityPublicKey>,
) -> CryptoResult<(
&'a mut Self::IdentityPrivateKeyHandle,
- &'a mut IdentityPublicKey,
+ &'b mut IdentityPublicKey,
)> {
- Ok((private.write(()), public.write(TEST_IDENTITY_PUBLIC_KEY)))
+ Ok((
+ private.write(IdentityPrivateKeyHandle),
+ public.write(TEST_IDENTITY_PUBLIC_KEY),
+ ))
}
}
diff --git a/test-deps/src/identity.rs b/test-deps/src/identity.rs
index aaaa22b..0025253 100644
--- a/test-deps/src/identity.rs
+++ b/test-deps/src/identity.rs
@@ -8,6 +8,7 @@
use spdm_types::deps::{Identity, IdentityPublicKey};
use super::crypto::TestCrypto;
+use crate::IdentityPrivateKeyHandle;
// This is not a real EC point, but that's fine for test.
pub const TEST_IDENTITY_PUBLIC_KEY: EcP256UncompressedPoint = EcP256UncompressedPoint {
@@ -25,8 +26,8 @@
&TEST_IDENTITY_PUBLIC_KEY
}
- fn identity_private_key_handle(&self) -> &() {
- &()
+ fn identity_private_key_handle(&self) -> &IdentityPrivateKeyHandle {
+ &IdentityPrivateKeyHandle
}
fn is_public_key_valid(_public_key: &EcP256UncompressedPoint) -> bool {