spdm: Support vendor command in data phase
The vendor command is just wrapping the raw application messages the
requester is sending to the responder under the hood of spdm protocol.
BUG=b:284404632
TEST=cargo test
Change-Id: I973ca819974a03644ee4a347491708aedfdc1441
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/spdm/+/5019430
Tested-by: Howard Yang <hcyang@google.com>
Commit-Queue: Howard Yang <hcyang@google.com>
Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org>
diff --git a/spdm-core/src/deps/test/mod.rs b/spdm-core/src/deps/test/mod.rs
index 8798609..1ed9a2b 100644
--- a/spdm-core/src/deps/test/mod.rs
+++ b/spdm-core/src/deps/test/mod.rs
@@ -6,14 +6,17 @@
mod crypto;
mod identity;
+mod vendor;
pub use crypto::*;
pub use identity::*;
use spdm_types::deps::SpdmDeps;
+pub use vendor::*;
pub struct SpdmTestDeps;
impl SpdmDeps for SpdmTestDeps {
type Crypto = TestCrypto;
type Identity = TestIdentity;
+ type Vendor = TestVendor;
}
diff --git a/spdm-core/src/deps/test/vendor.rs b/spdm-core/src/deps/test/vendor.rs
new file mode 100644
index 0000000..0139897
--- /dev/null
+++ b/spdm-core/src/deps/test/vendor.rs
@@ -0,0 +1,16 @@
+// Copyright 2023 The ChromiumOS Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#[cfg(feature = "mock")]
+use mocktopus::macros::*;
+use spdm_types::deps::Vendor;
+
+pub struct TestVendor;
+
+#[cfg_attr(feature = "mock", mockable)]
+impl Vendor for TestVendor {
+ fn process_vendor_request(&self, _buf: &mut [u8], req_size: usize) -> usize {
+ req_size
+ }
+}
diff --git a/spdm-core/src/dispatch/internal.rs b/spdm-core/src/dispatch/internal.rs
index fdb1eff..449795a 100644
--- a/spdm-core/src/dispatch/internal.rs
+++ b/spdm-core/src/dispatch/internal.rs
@@ -8,6 +8,7 @@
use mocktopus::macros::*;
use spdm_types::deps::{Crypto, SpdmDeps};
+use super::session_established::SessionEstablishedDispatcher;
use super::wait_for_finish::WaitForFinishDispatcher;
use super::wait_for_key_exchange::WaitForKeyExchangeDispatcher;
use super::wait_for_requester_key::WaitForRequesterKeyDispatcher;
@@ -112,7 +113,10 @@
self.session.sequence_numbers.request += 1;
let req_buf = &mut buf[REQUEST_OFFSET..];
let req_code = parse_header(&req_buf[..req_size])?;
- let resp_size = self.dispatch_request_internal(req_buf, req_size, req_code)?;
+ let resp_size = match self.dispatch_request_internal(req_buf, req_size, req_code) {
+ Ok(resp_size) => resp_size,
+ Err(err) => err.write_response(buf),
+ };
let resp_size =
encrypt_secure_message(session_id, &session_keys.response_keys, buf, resp_size)?;
self.session.sequence_numbers.response += 1;
@@ -135,8 +139,9 @@
SpdmState::WaitForFinish => {
self.dispatch_request_wait_for_finish(buf, req_size, req_code)
}
- // TODO(b/284404632): Implement SessionEstablishedDispatcher.
- SpdmState::SessionEstablished => Err(ErrorCode::Unspecified),
+ SpdmState::SessionEstablished => {
+ self.dispatch_request_session_established(buf, req_size, req_code)
+ }
}
}
}
@@ -144,7 +149,7 @@
#[cfg(test)]
mod tests {
use super::*;
- use crate::deps::{SpdmTestDeps, TestIdentity};
+ use crate::deps::{SpdmTestDeps, TestIdentity, TestVendor};
use crate::types::message::GET_PUBLIC_KEY_RESPONSE_SIZE;
use crate::types::version::SPDM_THIS_VERSION;
@@ -153,7 +158,7 @@
let mut buf = [0x10, RequestCode::GetVersion.0, 0, 0, 0, 0, 0, 0];
let req_size = 4;
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
let fake_transcript = [0xCC; 12];
// Simulate the scenario that there's already some state.
@@ -174,7 +179,7 @@
buf.extend_from_slice(&[0; 100]);
let req_size = 4;
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
let fake_transcript = [0xCC; 12];
// Simulate the scenario that there's already some state.
@@ -195,7 +200,7 @@
buf.extend_from_slice(&[0; 100]);
let req_size = 4;
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
spdm.state = SpdmState::WaitForRequesterKey;
let result = spdm.dispatch_plaintext_request(&mut buf, req_size);
assert_eq!(result, Err(ErrorCode::SessionRequired));
@@ -219,7 +224,7 @@
buf.extend_from_slice(&[0; 100]);
let req_size = 28;
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
spdm.session.session_id = Some([0xaa, 0xbb, 0xcc, 0xdd]);
spdm.session.th1 = Some([0xCC; 32]);
spdm.session.handshake_secret = Some(());
diff --git a/spdm-core/src/dispatch/mod.rs b/spdm-core/src/dispatch/mod.rs
index 922a6ae..0cf23b9 100644
--- a/spdm-core/src/dispatch/mod.rs
+++ b/spdm-core/src/dispatch/mod.rs
@@ -5,6 +5,7 @@
//! Implements the dispatcher state machine of the SPDM responder.
pub mod internal;
+mod session_established;
mod wait_for_finish;
mod wait_for_key_exchange;
mod wait_for_requester_key;
diff --git a/spdm-core/src/dispatch/session_established.rs b/spdm-core/src/dispatch/session_established.rs
new file mode 100644
index 0000000..908c039
--- /dev/null
+++ b/spdm-core/src/dispatch/session_established.rs
@@ -0,0 +1,119 @@
+// Copyright 2023 The ChromiumOS Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use spdm_types::deps::{SpdmDeps, Vendor};
+
+use crate::types::code::{RequestCode, ResponseCode};
+use crate::types::error::{ErrorCode, SpdmResult};
+use crate::Spdm;
+
+///
+/// VendorCommand request format:
+///
+/// | Byte offset | Size (bytes) | Field | Description |
+/// | :---------- | :-------------- | :------------------ | :------------------------- |
+/// | 0 | 1 | SPDMVersion | SPDM_THIS_VERSION |
+/// | 1 | 1 | RequestResponseCode | RequestCode::VendorCommand |
+/// | 2 | 1 | Param1 | Reserved |
+/// | 3 | 1 | Param2 | Reserved |
+/// | 4 | N | VendorMessage | |
+///
+/// VendorCommand response format:
+/// | Byte offset | Size (bytes) | Field | Description |
+/// | :---------- | :----------- | :------------------ | :-------------------------- |
+/// | 0 | 1 | SPDMVersion | SPDM_THIS_VERSION |
+/// | 1 | 1 | RequestResponseCode | ResponseCode::VendorCommand |
+/// | 2 | 1 | Param1 | Reserved |
+/// | 3 | 1 | Param2 | Reserved |
+/// | 4 | N | VendorMessage | |
+const VENDOR_COMMAND_HEADER_SIZE: usize = 4;
+const VENDOR_COMMAND_CODE_OFFSET: usize = 1;
+
+/// SessionEstablishedDispatcher handles the state where the session is successfully
+/// established. Only vendor commands will be processed in this phase.
+///
+/// This trait is only used for separating impl blocks of `Spdm` struct by functionality.
+pub trait SessionEstablishedDispatcher {
+ fn dispatch_request_session_established(
+ &mut self,
+ buf: &mut [u8],
+ req_size: usize,
+ req_code: RequestCode,
+ ) -> SpdmResult<usize>;
+}
+
+/// VendorCommandDispatcher handles the VendorCommand request.
+///
+/// This trait is only used for separating impl blocks of `Spdm` struct by functionality.
+pub trait VendorCommandDispatcher {
+ /// Handles the VendorCommand request and if successful, writes the VendorCommand response
+ /// to `buf`.
+ /// This is a custom command defined by this SPDM implementation. It basically carries arbitrary
+ /// message that the responder knows how to handle and respond.
+ fn dispatch_vendor_command_request(
+ &mut self,
+ buf: &mut [u8],
+ req_size: usize,
+ ) -> SpdmResult<usize>;
+}
+
+impl<D: SpdmDeps> VendorCommandDispatcher for Spdm<D> {
+ fn dispatch_vendor_command_request(
+ &mut self,
+ buf: &mut [u8],
+ req_size: usize,
+ ) -> SpdmResult<usize> {
+ if req_size < VENDOR_COMMAND_HEADER_SIZE {
+ return Err(ErrorCode::InvalidRequest);
+ }
+ let resp_size = self.vendor.process_vendor_request(
+ &mut buf[VENDOR_COMMAND_HEADER_SIZE..],
+ req_size - VENDOR_COMMAND_HEADER_SIZE,
+ ) + VENDOR_COMMAND_HEADER_SIZE;
+ buf[VENDOR_COMMAND_CODE_OFFSET] = ResponseCode::VendorCommand.0;
+ Ok(resp_size)
+ }
+}
+
+impl<D: SpdmDeps> SessionEstablishedDispatcher for Spdm<D> {
+ fn dispatch_request_session_established(
+ &mut self,
+ buf: &mut [u8],
+ req_size: usize,
+ req_code: RequestCode,
+ ) -> SpdmResult<usize> {
+ match req_code {
+ RequestCode::VendorCommand => self.dispatch_vendor_command_request(buf, req_size),
+ _ => Err(ErrorCode::UnexpectedRequest),
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::deps::{SpdmTestDeps, TestIdentity, TestVendor};
+ use crate::types::code::RequestCode;
+ use crate::types::version::SPDM_THIS_VERSION;
+
+ #[test]
+ fn give_pub_key_request() {
+ let mut buf = [
+ SPDM_THIS_VERSION,
+ RequestCode::VendorCommand.0,
+ 0,
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ ];
+ let req_size = 8;
+
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
+
+ let result = spdm.dispatch_vendor_command_request(&mut buf, req_size);
+ assert_eq!(result, Ok(8));
+ }
+}
diff --git a/spdm-core/src/dispatch/wait_for_finish.rs b/spdm-core/src/dispatch/wait_for_finish.rs
index bd72103..682f5d3 100644
--- a/spdm-core/src/dispatch/wait_for_finish.rs
+++ b/spdm-core/src/dispatch/wait_for_finish.rs
@@ -88,7 +88,7 @@
use mocktopus::mocking::{MockResult, Mockable};
use super::super::*;
- use crate::deps::{SpdmTestDeps, TestIdentity};
+ use crate::deps::{SpdmTestDeps, TestIdentity, TestVendor};
#[test]
fn finish_request() {
@@ -100,7 +100,7 @@
Spdm::<SpdmTestDeps>::validate_finish_message_hmac
.mock_safe(|_, _| MockResult::Return(Ok(())));
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
let result = spdm.dispatch_finish_request(&mut buf, FinishRequest::SIZE);
assert_eq!(result, Ok(4));
}
diff --git a/spdm-core/src/dispatch/wait_for_key_exchange/get_pub_key.rs b/spdm-core/src/dispatch/wait_for_key_exchange/get_pub_key.rs
index d1a5b9b..0f3ed5d 100644
--- a/spdm-core/src/dispatch/wait_for_key_exchange/get_pub_key.rs
+++ b/spdm-core/src/dispatch/wait_for_key_exchange/get_pub_key.rs
@@ -62,7 +62,7 @@
#[cfg(test)]
mod tests {
use super::*;
- use crate::deps::{SpdmTestDeps, TestIdentity, TEST_IDENTITY_PUBLIC_KEY};
+ use crate::deps::{SpdmTestDeps, TestIdentity, TestVendor, TEST_IDENTITY_PUBLIC_KEY};
use crate::dispatch::internal::SpdmState;
use crate::types::code::RequestCode;
use crate::types::version::SPDM_THIS_VERSION;
@@ -73,7 +73,7 @@
buf.extend_from_slice(&[0; 100]);
let req_size = 4;
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
let result = spdm.dispatch_get_pub_key_request(&mut buf, req_size);
assert_eq!(result, Ok(GET_PUBLIC_KEY_RESPONSE_SIZE));
diff --git a/spdm-core/src/dispatch/wait_for_key_exchange/get_version.rs b/spdm-core/src/dispatch/wait_for_key_exchange/get_version.rs
index eda864f..a159bb1 100644
--- a/spdm-core/src/dispatch/wait_for_key_exchange/get_version.rs
+++ b/spdm-core/src/dispatch/wait_for_key_exchange/get_version.rs
@@ -68,7 +68,7 @@
#[cfg(test)]
mod tests {
use super::*;
- use crate::deps::{SpdmTestDeps, TestIdentity};
+ use crate::deps::{SpdmTestDeps, TestIdentity, TestVendor};
use crate::dispatch::internal::SpdmState;
use crate::types::code::RequestCode;
@@ -77,7 +77,7 @@
let mut buf = [0x10, RequestCode::GetVersion.0, 0, 0, 0, 0, 0, 0];
let req_size = 4;
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
let result = spdm.dispatch_get_version_request(&mut buf, req_size);
assert_eq!(result, Ok(8));
diff --git a/spdm-core/src/dispatch/wait_for_key_exchange/key_exchange.rs b/spdm-core/src/dispatch/wait_for_key_exchange/key_exchange.rs
index 5ba5c51..111c093 100644
--- a/spdm-core/src/dispatch/wait_for_key_exchange/key_exchange.rs
+++ b/spdm-core/src/dispatch/wait_for_key_exchange/key_exchange.rs
@@ -115,7 +115,7 @@
use spdm_types::crypto::EC_P256_COORD_SIZE;
use super::*;
- use crate::deps::{SpdmTestDeps, TestIdentity};
+ use crate::deps::{SpdmTestDeps, TestIdentity, TestVendor};
use crate::dispatch::wait_for_key_exchange::get_version::GetVersionDispatcher;
use crate::types::code::RequestCode;
use crate::types::version::SPDM_THIS_VERSION;
@@ -146,7 +146,7 @@
let mut buf = get_valid_key_exchange_buffer();
let req_size = KeyExchangeRequest::SIZE;
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
// A GetVersion request must come first to initialize the transcript.
let mut get_version = [0x10, RequestCode::GetVersion.0, 0, 0, 0, 0, 0, 0];
@@ -173,7 +173,7 @@
let mut buf = get_valid_key_exchange_buffer();
let req_size = KeyExchangeRequest::SIZE;
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
let result = spdm.dispatch_key_exchange_request(&mut buf, req_size);
assert_eq!(result, Err(ErrorCode::UnexpectedRequest));
diff --git a/spdm-core/src/dispatch/wait_for_requester_key.rs b/spdm-core/src/dispatch/wait_for_requester_key.rs
index 4a9fe1b..3c1f581 100644
--- a/spdm-core/src/dispatch/wait_for_requester_key.rs
+++ b/spdm-core/src/dispatch/wait_for_requester_key.rs
@@ -36,7 +36,7 @@
/// | Byte offset | Size (bytes) | Field | Description |
/// | :---------- | :-------------- | :------------------ | :----------------------- |
/// | 0 | 1 | SPDMVersion | SPDM_THIS_VERSION |
- /// | 1 | 1 | RequestResponseCode | ResponseCode::GivePubKey |
+ /// | 1 | 1 | RequestResponseCode | RequestCode::GivePubKey |
/// | 2 | 1 | Param1 | Reserved |
/// | 3 | 1 | Param2 | Reserved |
/// | 4 | PUBLIC_KEY_SIZE | PublicKey | Public Key |
@@ -45,7 +45,7 @@
/// | Byte offset | Size (bytes) | Field | Description |
/// | :---------- | :----------- | :------------------ | :---------------------- |
/// | 0 | 1 | SPDMVersion | SPDM_THIS_VERSION |
- /// | 1 | 1 | RequestResponseCode | RequestCode::GivePubKey |
+ /// | 1 | 1 | RequestResponseCode | Response::GivePubKey |
/// | 2 | 1 | Param1 | Reserved |
/// | 3 | 1 | Param2 | Reserved |
fn dispatch_give_pub_key_request(
@@ -100,7 +100,7 @@
use zerocopy::AsBytes;
use super::*;
- use crate::deps::{SpdmTestDeps, TestIdentity, TEST_IDENTITY_PUBLIC_KEY};
+ use crate::deps::{SpdmTestDeps, TestIdentity, TestVendor, TEST_IDENTITY_PUBLIC_KEY};
use crate::dispatch::internal::SpdmState;
use crate::types::code::RequestCode;
use crate::types::version::SPDM_THIS_VERSION;
@@ -111,7 +111,7 @@
buf.extend_from_slice(TEST_IDENTITY_PUBLIC_KEY.as_bytes());
let req_size = GivePubKeyRequest::SIZE;
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
let result = spdm.dispatch_give_pub_key_request(&mut buf, req_size);
assert_eq!(result, Ok(4));
@@ -137,7 +137,7 @@
MockResult::Return(false)
})
.run(|| {
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
spdm.state = SpdmState::WaitForRequesterKey;
let result = spdm.dispatch_give_pub_key_request(&mut buf, req_size);
diff --git a/spdm-core/src/lib.rs b/spdm-core/src/lib.rs
index 7608eee..68603c9 100644
--- a/spdm-core/src/lib.rs
+++ b/spdm-core/src/lib.rs
@@ -18,14 +18,16 @@
pub struct Spdm<D: SpdmDeps> {
state: SpdmState,
identity: D::Identity,
+ vendor: D::Vendor,
session: Session<D::Crypto>,
}
impl<D: SpdmDeps> Spdm<D> {
- pub fn new(identity: D::Identity) -> Self {
+ pub fn new(identity: D::Identity, vendor: D::Vendor) -> Self {
Self {
state: SpdmState::default(),
identity,
+ vendor,
session: Session::<D::Crypto>::default(),
}
}
diff --git a/spdm-core/src/session/mod.rs b/spdm-core/src/session/mod.rs
index a1b6a1b..90c6710 100644
--- a/spdm-core/src/session/mod.rs
+++ b/spdm-core/src/session/mod.rs
@@ -407,7 +407,7 @@
use zerocopy::FromBytes;
use super::*;
- use crate::deps::{SpdmTestDeps, TestIdentity};
+ use crate::deps::{SpdmTestDeps, TestIdentity, TestVendor};
#[test]
fn init_transcript_and_sign() {
@@ -417,7 +417,7 @@
let key_exchange_response = [0xBB; 16];
let mut signature = EcdsaP256Signature::new_zeroed();
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
spdm.set_negotiation_transcript(get_version_request, version_response);
assert!(spdm
.init_transcript_hash_with_key_exchange_request(&key_exchange_request)
@@ -435,7 +435,7 @@
fn init_transcript_hash_without_transcript() {
let key_exchange_request = [0xAA; 8];
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
assert_eq!(
spdm.init_transcript_hash_with_key_exchange_request(&key_exchange_request),
Err(ErrorCode::Unspecified)
@@ -446,7 +446,7 @@
fn sign_without_transcript_hash() {
let mut signature = EcdsaP256Signature::new_zeroed();
- let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity);
+ let mut spdm = Spdm::<SpdmTestDeps>::new(TestIdentity, TestVendor);
assert_eq!(
spdm.sign_key_exchange_message(&mut signature),
Err(ErrorCode::Unspecified)
diff --git a/spdm-core/src/types/code.rs b/spdm-core/src/types/code.rs
index 61f9514..2b99cd4 100644
--- a/spdm-core/src/types/code.rs
+++ b/spdm-core/src/types/code.rs
@@ -23,6 +23,7 @@
// we don't want to parse them as vendor commands.
GetPubKey = 0xF0,
GivePubKey = 0xF1,
+ VendorCommand = 0xF2,
}
#[repr(u8)]
@@ -38,6 +39,7 @@
// we don't want to parse them as vendor commands.
GetPubKey = 0x10,
GivePubKey = 0x11,
+ VendorCommand = 0x12,
}
// `Param1` and `Param2` are 1-byte params that appear in most SPDM message formats
@@ -48,7 +50,12 @@
fn is_request_code_supported(code: RequestCode) -> bool {
matches!(
code,
- RequestCode::GetVersion | RequestCode::GetPubKey | RequestCode::KeyExchange
+ RequestCode::GetVersion
+ | RequestCode::KeyExchange
+ | RequestCode::Finish
+ | RequestCode::GetPubKey
+ | RequestCode::GivePubKey
+ | RequestCode::VendorCommand
)
}
diff --git a/spdm-types/src/deps/mod.rs b/spdm-types/src/deps/mod.rs
index 17af65a..4385b5d 100644
--- a/spdm-types/src/deps/mod.rs
+++ b/spdm-types/src/deps/mod.rs
@@ -7,13 +7,16 @@
mod crypto;
mod identity;
+mod vendor;
pub use crypto::*;
pub use identity::*;
+pub use vendor::*;
/// `SpdmDeps` defines the trait dependencies of `Spdm` so it only needs
/// to be generic on a single type with `SpdmDeps` trait bound.
pub trait SpdmDeps {
type Crypto: Crypto;
type Identity: Identity<Crypto = Self::Crypto>;
+ type Vendor: Vendor;
}
diff --git a/spdm-types/src/deps/vendor.rs b/spdm-types/src/deps/vendor.rs
new file mode 100644
index 0000000..4cf4a47
--- /dev/null
+++ b/spdm-types/src/deps/vendor.rs
@@ -0,0 +1,10 @@
+// Copyright 2023 The ChromiumOS Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/// Identity trait defines the interface to access the SPDM identity key pair.
+pub trait Vendor {
+ /// Processes the vendor request to the vendor request handler, and put the
+ /// response back into `buf`, and return the response size.
+ fn process_vendor_request(&self, buf: &mut [u8], req_size: usize) -> usize;
+}
diff --git a/src/deps.rs b/src/deps.rs
index 7cd7a92..078701e 100644
--- a/src/deps.rs
+++ b/src/deps.rs
@@ -5,7 +5,9 @@
use spdm_types::crypto::{
AesGcm128Iv, AesGcm128Tag, EcP256UncompressedPoint, EcdsaP256Signature, Sha256Hash,
};
-use spdm_types::deps::{Crypto, CryptoResult, CryptoStatus, Identity, IdentityPublicKey, SpdmDeps};
+use spdm_types::deps::{
+ Crypto, CryptoResult, CryptoStatus, Identity, IdentityPublicKey, SpdmDeps, Vendor,
+};
use uninit::prelude::*;
type IdentityPrivateKey = [u8; 32];
@@ -166,9 +168,19 @@
}
}
+/// Implements Vendor by interacting with the eal callback functions.
+pub struct EalVendor;
+
+impl Vendor for EalVendor {
+ fn process_vendor_request(&self, _buf: &mut [u8], _req_size: usize) -> usize {
+ unimplemented!()
+ }
+}
+
pub struct SpdmEalDeps;
impl SpdmDeps for SpdmEalDeps {
type Crypto = EalCrypto;
type Identity = EalIdentity;
+ type Vendor = EalVendor;
}
diff --git a/src/lib.rs b/src/lib.rs
index 6361716..74abf8b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,7 +9,7 @@
use core::mem::size_of;
-use deps::{EalIdentity, SpdmEalDeps};
+use deps::{EalIdentity, EalVendor, SpdmEalDeps};
use spdm::{Spdm, SpdmDispatcher};
#[cfg(not(feature = "std"))]
@@ -33,13 +33,14 @@
#[no_mangle]
pub unsafe extern "C" fn spdm_initialize(spdm: *mut SpdmFFI) {
let spdm: &mut Spdm<SpdmEalDeps> = &mut *spdm.cast();
- *spdm = Spdm::<SpdmEalDeps>::new(EalIdentity);
+ *spdm = Spdm::<SpdmEalDeps>::new(EalIdentity, EalVendor);
}
/// # Safety
/// - `spdm` must be valid pointer for `SpdmFFI`, and the pointed data should have
/// been initialized by `spdm_initialize` first.
/// - `buf` must be valid pointer for `req_size` bytes, and writeable for `resp_size` bytes.
+/// - `resp_size` must be non-null.
///
/// Dispatches the SPDM request to the global SPDM responder state machine.
///