responder
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
index 7691ac9..665a9a4 100644
--- a/MODULE.bazel.lock
+++ b/MODULE.bazel.lock
@@ -2587,7 +2587,7 @@
           "@@//third_party/crates_io/Cargo.lock": "476c8b233fa2b269018dbcb33a67157983dd2456398bf5e2742d2b8721390bed",
           "@@//third_party/crates_io/Cargo.toml": "1e902f5b20bf6ad09e1660171a2247e00570a88181bec3ecb58416343c0c2739",
           "@@//third_party/crates_io/crates_no_std/Cargo.lock": "065eb6d0f65f582caefc6d7ab585c02f83fe027155322284b3c570901aa578a4",
-          "@@//third_party/crates_io/crates_no_std/Cargo.toml": "aa7141327ff6079fa4cc5fd96e8ac8c58ff1554d2f3e01534794f8d9b4169ac8",
+          "@@//third_party/crates_io/crates_no_std/Cargo.toml": "139c6294fca5df6431e88bcbc2029519a401fc76ab8e809e910b4a6745c0bfac",
           "@@pigweed+//third_party/crates_io/crates_no_std/Cargo.lock": "d38da5fa5f942b59a8017730285afe69aaf6f741b6171f361d66202de3473bc2",
           "@@pigweed+//third_party/crates_io/crates_no_std/Cargo.toml": "00e4a621a4a49d1b269bb2e688d8b5bbabb8700eb7b583ccaa20c36a60aebf98",
           "@@pigweed+//third_party/crates_io/crates_std/Cargo.lock": "13ffbc71abd52f9c79d69ce7101aca75faddaefb314ab8b112a623ab0ea81540",
@@ -4632,7 +4632,7 @@
                 "https://static.crates.io/crates/getrandom/0.2.17/download"
               ],
               "strip_prefix": "getrandom-0.2.17",
-              "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n#     bazel mod show_repo 'opentitan_pigweed'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"getrandom\",\n    deps = [\n        \"@oot_crates_no_std__cfg-if-1.0.4//:cfg_if\",\n    ] + select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [\n            \"@oot_crates_no_std__libc-0.2.183//:libc\",  # cfg(unix)\n        ],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [\n            \"@oot_crates_no_std__libc-0.2.183//:libc\",  # cfg(unix)\n        ],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [\n            \"@oot_crates_no_std__libc-0.2.183//:libc\",  # cfg(unix)\n        ],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [\n            \"@oot_crates_no_std__libc-0.2.183//:libc\",  # cfg(unix)\n        ],\n        \"//conditions:default\": [],\n    }),\n    compile_data = glob(\n        allow_empty = True,\n        include = [\"**\"],\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2018\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    srcs = glob(\n        allow_empty = True,\n        include = [\"**/*.rs\"],\n    ),\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=getrandom\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:thumbv6m-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv7m-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"0.2.17\",\n)\n"
+              "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n#     bazel mod show_repo 'opentitan_pigweed'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"getrandom\",\n    deps = [\n        \"@oot_crates_no_std__cfg-if-1.0.4//:cfg_if\",\n    ] + select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [\n            \"@oot_crates_no_std__libc-0.2.183//:libc\",  # cfg(unix)\n        ],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [\n            \"@oot_crates_no_std__libc-0.2.183//:libc\",  # cfg(unix)\n        ],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [\n            \"@oot_crates_no_std__libc-0.2.183//:libc\",  # cfg(unix)\n        ],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [\n            \"@oot_crates_no_std__libc-0.2.183//:libc\",  # cfg(unix)\n        ],\n        \"//conditions:default\": [],\n    }),\n    compile_data = glob(\n        allow_empty = True,\n        include = [\"**\"],\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"custom\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2018\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    srcs = glob(\n        allow_empty = True,\n        include = [\"**/*.rs\"],\n    ),\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=getrandom\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:thumbv6m-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv7m-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"0.2.17\",\n)\n"
             }
           },
           "oot_crates_no_std__ghash-0.5.1": {
diff --git a/services/crypto/client/BUILD.bazel b/services/crypto/client/BUILD.bazel
index 29141c9..23e91b1 100644
--- a/services/crypto/client/BUILD.bazel
+++ b/services/crypto/client/BUILD.bazel
@@ -5,6 +5,7 @@
 rust_library(
     name = "crypto_client",
     srcs = ["src/lib.rs"],
+    crate_features = ["ecdsa"],
     edition = "2024",
     tags = ["kernel"],
     visibility = ["//visibility:public"],
diff --git a/services/crypto/client/src/lib.rs b/services/crypto/client/src/lib.rs
index 05c9325..c136b88 100644
--- a/services/crypto/client/src/lib.rs
+++ b/services/crypto/client/src/lib.rs
@@ -53,8 +53,6 @@
     CryptoError, CryptoOp, CryptoRequestHeader, CryptoResponseHeader,
     MAX_PAYLOAD_SIZE,
 };
-#[cfg(feature = "ecdsa")]
-use crypto_api::{ECDSA_P256_SIGNATURE_SIZE, ECDSA_P384_SIGNATURE_SIZE};
 use userspace::syscall;
 use userspace::time::Instant;
 
diff --git a/services/spdm/hash/BUILD.bazel b/services/spdm/hash/BUILD.bazel
index 5ba2013..ce65e90 100644
--- a/services/spdm/hash/BUILD.bazel
+++ b/services/spdm/hash/BUILD.bazel
@@ -10,7 +10,7 @@
     visibility = ["//visibility:public"],
     deps = [
         "//services/crypto/client:crypto_client",
-        "@rust_crates//:spdm-lib",
+        "@oot_crates_no_std//:spdm-lib",
     ],
 )
 
diff --git a/services/spdm/responder/BUILD.bazel b/services/spdm/responder/BUILD.bazel
index 46cc63f..35e35f8 100644
--- a/services/spdm/responder/BUILD.bazel
+++ b/services/spdm/responder/BUILD.bazel
@@ -1,21 +1,14 @@
 # Licensed under the Apache-2.0 license
 
-load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
+load("@rules_rust//rust:defs.bzl", "rust_library")
 
 rust_library(
     name = "spdm_responder_lib",
     srcs = glob(["src/**/*.rs"]),
-    crate_name = "openprot_spdm_responder",
+    crate_name = "spdm_responder",
     edition = "2024",
     visibility = ["//visibility:public"],
     deps = [
-        "//services/spdm/transport-mctp:spdm_transport_mctp",
-        "@rust_crates//:heapless",
-        "@rust_crates//:spdm-lib",
+        "@oot_crates_no_std//:spdm-lib",
     ],
 )
-
-rust_test(
-    name = "spdm_responder_test",
-    crate = ":spdm_responder_lib",
-)
diff --git a/services/spdm/responder/Cargo.toml b/services/spdm/responder/Cargo.toml
index 7a20ccd..8080708 100644
--- a/services/spdm/responder/Cargo.toml
+++ b/services/spdm/responder/Cargo.toml
@@ -1,13 +1,11 @@
 # Licensed under the Apache-2.0 license
 
 [package]
-name = "openprot-spdm-responder"
+name = "spdm-responder"
 version = "0.1.0"
 edition = "2021"
-description = "SPDM responder implementation for OpenPRoT"
+description = "SPDM responder service for OpenPRoT"
 license = "Apache-2.0"
 
 [dependencies]
-openprot-spdm-transport-mctp = { path = "../transport-mctp" }
 spdm-lib = { git = "https://github.com/9elements/spdm-lib.git", branch = "buildup" }
-heapless = { workspace = true }
diff --git a/services/spdm/responder/README.md b/services/spdm/responder/README.md
index 0f3b3c9..f21e695 100644
--- a/services/spdm/responder/README.md
+++ b/services/spdm/responder/README.md
@@ -1,31 +1,5 @@
-# openprot-spdm-responder
+# SPDM Responder Service
 
-SPDM responder (server) implementation for OpenPRoT.
+SPDM responder service for OpenPRoT - wraps spdm-lib SpdmContext for simplified message processing.
 
-## Overview
-
-This crate provides the SPDM responder role, which handles attestation requests from SPDM requesters. The responder processes requests and provides:
-- Version and capability negotiation
-- Certificate chain provisioning
-- Device measurements
-- Challenge-response attestation
-- CSR generation and certificate updates
-
-## Status
-
-This crate is in early development. Basic infrastructure is in place, but SPDM protocol operations are not yet implemented.
-
-## Dependencies
-
-- `spdm-lib` — SPDM protocol library from 9elements
-- `heapless` — `no_std` collections
-
-## Future Work
-
-- Implement SPDM 1.2+ response handlers
-- Add GET_VERSION, GET_CAPABILITIES handlers
-- Implement CHALLENGE response with signature
-- Add GET_MEASUREMENTS handler
-- Integrate with certificate storage
-- Integrate with MCTP transport layer
-- Add crypto service integration for signing operations
+See source code documentation for detailed usage.
diff --git a/services/spdm/responder/src/lib.rs b/services/spdm/responder/src/lib.rs
index d0fa403..09f3806 100644
--- a/services/spdm/responder/src/lib.rs
+++ b/services/spdm/responder/src/lib.rs
@@ -24,45 +24,292 @@
 //!             ▼
 //! ┌─────────────────────────┐
 //! │  SPDM Responder         │◄── This crate
-//! │  (request handler)      │
+//! │  (SpdmContext wrapper)  │
 //! └───────────┬─────────────┘
 //!             │
 //!             ▼
-//! ┌─────────────────────────┐
-//! │  Crypto Service         │
-//! │  Storage Service        │
-//! └─────────────────────────┘
+//! ┌─────────────────────────────────────┐
+//! │  Platform Implementations           │
+//! │  - CertStore (certificates)         │
+//! │  - Hash (SHA-384)                   │
+//! │  - RNG (random numbers)             │
+//! │  - Evidence (measurements)          │
+//! │  - Transport (MCTP)                 │
+//! └─────────────────────────────────────┘
+//! ```
+//!
+//! ## Usage
+//!
+//! ```rust,no_run
+//! use spdm_responder::SpdmResponder;
+//!
+//! // Create platform implementations
+//! let cert_store = Ast1060CertStore::new(crypto_handle);
+//! let hash = SpdmCryptoHash::new(crypto_handle);
+//! let rng = SpdmCryptoRng::new(crypto_handle);
+//! let evidence = Ast1060Evidence::new();
+//! let transport = MctpSpdmTransport::new(mctp_client);
+//!
+//! // Create responder
+//! let mut responder = SpdmResponder::new(
+//!     transport,
+//!     cert_store,
+//!     hash,
+//!     rng,
+//!     evidence,
+//! )?;
+//!
+//! // Process messages in loop
+//! loop {
+//!     responder.process_message()?;
+//! }
 //! ```
 
 #![no_std]
-#![warn(missing_docs)]
+
+use spdm_lib::cert_store::SpdmCertStore;
+use spdm_lib::codec::MessageBuf;
+use spdm_lib::context::SpdmContext;
+use spdm_lib::error::SpdmError;
+use spdm_lib::platform::evidence::SpdmEvidence;
+use spdm_lib::platform::hash::SpdmHash;
+use spdm_lib::platform::rng::SpdmRng;
+use spdm_lib::platform::transport::SpdmTransport;
+use spdm_lib::protocol::algorithms::{
+    AeadCipherSuite, AlgorithmPriorityTable, BaseAsymAlgo, BaseHashAlgo, DeviceAlgorithms,
+    DheNamedGroup, KeySchedule, LocalDeviceAlgorithms, MeasurementHashAlgo,
+    MeasurementSpecification, MelSpecification, OtherParamSupport, ReqBaseAsymAlg,
+};
+use spdm_lib::protocol::version::SpdmVersion;
+
+/// Supported SPDM versions (static to avoid lifetime issues)
+static SUPPORTED_VERSIONS: [SpdmVersion; 2] = [SpdmVersion::V12, SpdmVersion::V11];
+use spdm_lib::protocol::{CapabilityFlags, DeviceCapabilities};
+
+/// Maximum SPDM message size
+const MAX_SPDM_MSG_SIZE: usize = 4096;
+
+/// SPDM responder result type
+pub type ResponderResult<T> = Result<T, ResponderError>;
+
+/// SPDM responder errors
+#[derive(Debug)]
+pub enum ResponderError {
+    /// SPDM protocol error
+    SpdmError(SpdmError),
+    /// Message buffer error
+    BufferError,
+}
+
+impl From<SpdmError> for ResponderError {
+    fn from(e: SpdmError) -> Self {
+        ResponderError::SpdmError(e)
+    }
+}
+
+/// SPDM responder configuration
+#[derive(Debug, Clone, Copy)]
+pub struct ResponderConfig {
+    /// CT exponent for timing
+    pub ct_exponent: u8,
+    /// Data transfer size
+    pub data_transfer_size: u32,
+    /// Maximum SPDM message size
+    pub max_spdm_msg_size: u32,
+}
+
+impl Default for ResponderConfig {
+    fn default() -> Self {
+        Self {
+            ct_exponent: 0,
+            data_transfer_size: 1024,
+            max_spdm_msg_size: MAX_SPDM_MSG_SIZE as u32,
+        }
+    }
+}
 
 /// SPDM responder state and configuration.
-#[derive(Debug)]
-pub struct SpdmResponder {
-    /// Local endpoint ID for MCTP transport.
-    pub local_eid: u8,
+///
+/// This wraps the spdm-lib `SpdmContext` and provides a simplified interface
+/// for processing SPDM messages.
+pub struct SpdmResponder<'a> {
+    context: SpdmContext<'a>,
 }
 
-impl SpdmResponder {
-    /// Create a new SPDM responder with the given local endpoint ID.
-    pub fn new(local_eid: u8) -> Self {
-        Self { local_eid }
+impl<'a> SpdmResponder<'a> {
+    /// Create a new SPDM responder with platform implementations.
+    ///
+    /// # Arguments
+    ///
+    /// * `transport` - Transport layer implementation (e.g., MCTP)
+    /// * `cert_store` - Certificate store with device certificates
+    /// * `hash` - Hash implementation for protocol operations
+    /// * `m1_hash` - Hash implementation for M1 transcript
+    /// * `l1_hash` - Hash implementation for L1 transcript
+    /// * `rng` - Random number generator
+    /// * `evidence` - Evidence provider for measurements
+    /// * `config` - Optional configuration (uses defaults if None)
+    ///
+    /// # Returns
+    ///
+    /// A new `SpdmResponder` instance ready to process messages.
+    pub fn new(
+        transport: &'a mut dyn SpdmTransport,
+        cert_store: &'a mut dyn SpdmCertStore,
+        hash: &'a mut dyn SpdmHash,
+        m1_hash: &'a mut dyn SpdmHash,
+        l1_hash: &'a mut dyn SpdmHash,
+        rng: &'a mut dyn SpdmRng,
+        evidence: &'a dyn SpdmEvidence,
+        config: Option<ResponderConfig>,
+    ) -> ResponderResult<Self> {
+        let config = config.unwrap_or_default();
+
+        // Create device capabilities
+        let capabilities = create_device_capabilities(config);
+
+        // Create local algorithms
+        let algorithms = create_local_algorithms();
+
+        // Create SPDM context
+        let context = SpdmContext::new(
+            &SUPPORTED_VERSIONS,
+            transport,
+            capabilities,
+            algorithms,
+            cert_store,
+            None, // No peer cert store needed for responder
+            hash,
+            m1_hash,
+            l1_hash,
+            rng,
+            evidence,
+        )?;
+
+        Ok(Self { context })
     }
 
-    /// Get the local endpoint ID.
-    pub fn local_eid(&self) -> u8 {
-        self.local_eid
+    /// Process a single SPDM message.
+    ///
+    /// This method:
+    /// 1. Receives a request via the transport layer
+    /// 2. Processes it through the SPDM context
+    /// 3. Sends the response back via the transport layer
+    ///
+    /// # Arguments
+    ///
+    /// * `buffer` - Message buffer (must be at least MAX_SPDM_MSG_SIZE bytes)
+    ///
+    /// # Returns
+    ///
+    /// - `Ok(())` if message processed successfully
+    /// - `Err(ResponderError)` on error
+    ///
+    /// # Note
+    ///
+    /// This should be called in a loop to continuously process messages.
+    /// Transport errors indicate connection closed.
+    pub fn process_message(&mut self, buffer: &'a mut [u8]) -> ResponderResult<()> {
+        let mut message_buf = MessageBuf::new(buffer);
+        self.context.responder_process_message(&mut message_buf)?;
+        Ok(())
+    }
+
+    /// Get reference to the underlying SPDM context.
+    ///
+    /// This allows direct access to context state if needed.
+    pub fn context(&self) -> &SpdmContext<'a> {
+        &self.context
+    }
+
+    /// Get mutable reference to the underlying SPDM context.
+    ///
+    /// This allows direct manipulation of context state if needed.
+    pub fn context_mut(&mut self) -> &mut SpdmContext<'a> {
+        &mut self.context
     }
 }
 
-#[cfg(test)]
-mod tests {
-    use super::*;
+/// Create SPDM device capabilities based on configuration.
+fn create_device_capabilities(config: ResponderConfig) -> DeviceCapabilities {
+    let mut flags_value = 0u32;
 
-    #[test]
-    fn test_responder_creation() {
-        let responder = SpdmResponder::new(8);
-        assert_eq!(responder.local_eid(), 8);
+    // Certificate capability
+    flags_value |= 1 << 1; // CERT_CAP
+
+    // Challenge capability
+    flags_value |= 1 << 2; // CHAL_CAP
+
+    // Measurements capability (with signature)
+    flags_value |= 2 << 3; // MEAS_CAP (0b10 = measurements with signature)
+
+    // Measurements freshness capability
+    flags_value |= 1 << 5; // MEAS_FRESH_CAP
+
+    // Chunk capability
+    flags_value |= 1 << 17; // CHUNK_CAP
+
+    let flags = CapabilityFlags::new(flags_value);
+
+    DeviceCapabilities {
+        ct_exponent: config.ct_exponent,
+        flags,
+        data_transfer_size: config.data_transfer_size,
+        max_spdm_msg_size: config.max_spdm_msg_size,
+        include_supported_algorithms: true,
+    }
+}
+
+/// Create local device algorithms configuration.
+///
+/// Configures supported cryptographic algorithms:
+/// - Measurement: DMTF specification with SHA-384
+/// - Asymmetric: ECDSA with NIST P-384
+/// - Hash: SHA-384
+fn create_local_algorithms<'a>() -> LocalDeviceAlgorithms<'a> {
+    // Measurement specification (DMTF)
+    let mut measurement_spec = MeasurementSpecification::default();
+    measurement_spec.set_dmtf_measurement_spec(1);
+
+    // Measurement hash algorithm (SHA-384)
+    let mut measurement_hash_algo = MeasurementHashAlgo::default();
+    measurement_hash_algo.set_tpm_alg_sha_384(1);
+
+    // Base asymmetric algorithm (ECDSA P-384)
+    let mut base_asym_algo = BaseAsymAlgo::default();
+    base_asym_algo.set_tpm_alg_ecdsa_ecc_nist_p384(1);
+
+    // Base hash algorithm (SHA-384)
+    let mut base_hash_algo = BaseHashAlgo::default();
+    base_hash_algo.set_tpm_alg_sha_384(1);
+
+    let device_algorithms = DeviceAlgorithms {
+        measurement_spec,
+        other_param_support: OtherParamSupport::default(),
+        measurement_hash_algo,
+        base_asym_algo,
+        base_hash_algo,
+        mel_specification: MelSpecification::default(),
+        dhe_group: DheNamedGroup::default(),
+        aead_cipher_suite: AeadCipherSuite::default(),
+        req_base_asym_algo: ReqBaseAsymAlg::default(),
+        key_schedule: KeySchedule::default(),
+    };
+
+    let algorithm_priority_table = AlgorithmPriorityTable {
+        measurement_specification: None,
+        opaque_data_format: None,
+        base_asym_algo: None,
+        base_hash_algo: None,
+        mel_specification: None,
+        dhe_group: None,
+        aead_cipher_suite: None,
+        req_base_asym_algo: None,
+        key_schedule: None,
+    };
+
+    LocalDeviceAlgorithms {
+        device_algorithms,
+        algorithm_priority_table,
     }
 }
diff --git a/services/spdm/rng/BUILD.bazel b/services/spdm/rng/BUILD.bazel
new file mode 100644
index 0000000..2f93ea1
--- /dev/null
+++ b/services/spdm/rng/BUILD.bazel
@@ -0,0 +1,20 @@
+# Licensed under the Apache-2.0 license
+
+load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
+
+rust_library(
+    name = "spdm_rng_lib",
+    srcs = glob(["src/**/*.rs"]),
+    crate_name = "openprot_spdm_rng",
+    edition = "2024",
+    visibility = ["//visibility:public"],
+    deps = [
+        "//services/crypto/client:crypto_client",
+        "@oot_crates_no_std//:spdm-lib",
+    ],
+)
+
+rust_test(
+    name = "spdm_rng_test",
+    crate = ":spdm_rng_lib",
+)
diff --git a/services/spdm/rng/src/lib.rs b/services/spdm/rng/src/lib.rs
index 69696c0..6134f69 100644
--- a/services/spdm/rng/src/lib.rs
+++ b/services/spdm/rng/src/lib.rs
@@ -54,14 +54,14 @@
     fn get_random_bytes(&mut self, buf: &mut [u8]) -> SpdmRngResult<()> {
         self.crypto
             .get_random_bytes(buf)
-            .map_err(|_| spdm_lib::platform::rng::SpdmRngError::InternalError)
+            .map_err(|_| spdm_lib::platform::rng::SpdmRngError::InvalidSize)
     }
 
     fn generate_random_number(&mut self, random_number: &mut [u8]) -> SpdmRngResult<()> {
         // Both methods are identical in spdm-lib: fill a buffer with random bytes
         self.crypto
             .get_random_bytes(random_number)
-            .map_err(|_| spdm_lib::platform::rng::SpdmRngError::InternalError)
+            .map_err(|_| spdm_lib::platform::rng::SpdmRngError::InvalidSize)
     }
 }
 
diff --git a/services/spdm/transport-mctp/BUILD.bazel b/services/spdm/transport-mctp/BUILD.bazel
index d44ad13..6500d65 100644
--- a/services/spdm/transport-mctp/BUILD.bazel
+++ b/services/spdm/transport-mctp/BUILD.bazel
@@ -10,7 +10,7 @@
     visibility = ["//visibility:public"],
     deps = [
         "//services/mctp/api:mctp_api",
-        "@rust_crates//:spdm-lib",
+        "@oot_crates_no_std//:spdm-lib",
     ],
 )
 
diff --git a/target/ast1060-evb/TESTING.md b/target/ast1060-evb/TESTING.md
new file mode 100644
index 0000000..a8449cd
--- /dev/null
+++ b/target/ast1060-evb/TESTING.md
@@ -0,0 +1,67 @@
+README.md is a bit outdated, but before tackling that the following information will inform its rewrite:
+
+All tests for AST1060 have been done against a pair of boards on the ASPeed PRoT Fixture 3.0, which features two AST1060 boards on M.2 formfactor daughtercards.
+
+# Appearance and Organization
+
+When the board is facing you with the DB-9 connectors pointed in your direction:
+
+- The LEFT board has a JTAG pigtail installed. The RIGHT does not.
+- It is *highly recommended* that the DB-9 interfaces be replaced with direct 3-pin USB to UART headers.
+
+  Pin 1 -> TX
+
+  Pin 2 -> RX
+
+  Pin 3 -> GND
+
+The two pins directly below UART are FWSPICK, which when driven HIGH will force the ROM into UART bootloader mode.
+The two pins directly to the RIGHT are #SRST, which when driven LOW will put the processor into RESET.
+
+# Caveats
+
+There is no mechanism for external writing to internal SPI. Rewriting it requires a firmware capable of doing so.
+
+# Operation
+
+The board allows the sequence of SRST# low -> FWSPICK high -> SRST# high to reset and put the device into UART boot mode. For remote management of these pins, a Raspberry Pi is recommended as it provides the environment required to use uart_test_exec.py.
+
+## PI Wires
+```
+LEFT board: FWSPICK Pin 2 -> RPi GPIO 18
+LEFT board: SRST# Pin 1 -> RPi GPIO 23
+```
+
+These GPIO pins are coded into uart_test_exec.py as defaults.
+
+For the RIGHT board, choose your own and use the `--fwspick-pin` and `--srst-pin` command-line arguments. Recommended pins are GPIO 24 for FWSPICK and GPIO25 for SRST#
+
+## Command line examples
+
+Basic example that uploads i2c_uart.bin to the device:
+```
+python3 ./uart_test_exec.py /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AB80D84B-if00-port0 ./i2c_uart.bin
+```
+
+Basic example that uploads a reference firmware to a secondary device:
+```
+python3 ./uart_test_exec.py --fwspick-pin 24 --srst-pin 25 /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_ABSCEVVK-if00-port0 uart_zephyr.bin
+```
+
+### Advanced examples with Pigweed support
+
+The uart_test_exec.py script supports parsing of Pigweed tokenized output.
+
+To make this work, copy the ELF binary and py_tokenizer to the same machine as uart_test_exec.py and set the path to it in the environment variable PW_TOK_ROOT:
+```
+export PW_TOK_ROOT=/home/amd/pw_tokenizer
+```
+Then ensure the ELF binary is also accessible to the script, and run it:
+```
+python3 ./uart_test_exec.py --elf ./i2c.elf --notok /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AB80D84B-if00-port0 ./i2c_uart.bin
+```
+The --notok arguments hides the raw base64 tokens. Run
+```
+uart_test_exec.py --help
+```
+For more capabilities.
diff --git a/target/ast1060-evb/evidence/BUILD.bazel b/target/ast1060-evb/evidence/BUILD.bazel
new file mode 100644
index 0000000..0eac8fa
--- /dev/null
+++ b/target/ast1060-evb/evidence/BUILD.bazel
@@ -0,0 +1,23 @@
+# Licensed under the Apache-2.0 license
+
+load("@rules_rust//rust:defs.bzl", "rust_library")
+load("//target/ast1060-evb:defs.bzl", "TARGET_COMPATIBLE_WITH")
+
+# SPDM evidence implementation for AST1060-EVB
+#
+# This provides device measurements for SPDM attestation. This is a reference
+# implementation with fixed measurement values for testing.
+# Future hardware-backed implementations could integrate with TPM, boot
+# measurements, or platform-specific measurement engines.
+
+rust_library(
+    name = "evidence",
+    srcs = glob(["src/**/*.rs"]),
+    crate_name = "ast1060_evidence",
+    edition = "2024",
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+    visibility = ["//visibility:public"],
+    deps = [
+        "@oot_crates_no_std//:spdm-lib",
+    ],
+)
diff --git a/target/ast1060-evb/evidence/README.md b/target/ast1060-evb/evidence/README.md
new file mode 100644
index 0000000..94810f0
--- /dev/null
+++ b/target/ast1060-evb/evidence/README.md
@@ -0,0 +1,300 @@
+# SPDM Evidence - AST1060-EVB Reference Implementation
+
+This crate provides a **software-based reference implementation** of device measurements for SPDM attestation operations on the AST1060-EVB target.
+
+> **Note:** This is a platform-specific implementation using fixed measurement values. Future hardware-backed implementations could integrate with TPM, boot measurements, or platform-specific attestation mechanisms.
+
+## Overview
+
+The evidence implementation provides device measurements used in the SPDM GET_MEASUREMENTS command. This allows SPDM requesters to verify the integrity and authenticity of the device.
+
+## Architecture
+
+```text
+┌─────────────────────────┐
+│  SPDM Requester         │
+│  (Client)               │
+└───────────┬─────────────┘
+            │ GET_MEASUREMENTS
+            ▼
+┌─────────────────────────┐
+│  SPDM Responder         │
+└───────────┬─────────────┘
+            │ pcr_quote()
+            ▼
+┌─────────────────────────┐
+│  Ast1060Evidence        │◄── This crate
+│  - Fixed measurements   │
+│  - Format into PCR quote│
+└─────────────────────────┘
+```
+
+## Features
+
+- **Fixed measurements:** Two static string measurements for testing
+- **No hardware dependencies:** Pure software implementation
+- **Simple PCR quote format:** Easy to parse and verify
+- **No_std compatible:** Embedded-friendly design
+
+## Measurements
+
+This implementation provides two fixed measurements:
+
+1. **Measurement 0:** `"OpenPRoT SPDM Responder"` (23 bytes)
+2. **Measurement 1:** `"OCP EMEA HELLO WORLD"` (20 bytes)
+
+These are placeholder values for development and testing. Production implementations should provide real device measurements.
+
+## Usage
+
+### Basic Usage
+
+```rust
+use ast1060_evidence::Ast1060Evidence;
+use spdm_lib::platform::evidence::SpdmEvidence;
+
+// Create evidence provider
+let evidence = Ast1060Evidence::new();
+
+// Get required buffer size
+let size = evidence.pcr_quote_size(false)?;
+
+// Generate PCR quote
+let mut buffer = vec![0u8; size];
+let written = evidence.pcr_quote(&mut buffer, false)?;
+
+// Buffer now contains formatted measurements
+```
+
+### Integration with SPDM Responder
+
+```rust
+use ast1060_evidence::Ast1060Evidence;
+use spdm_lib::responder::SpdmResponder;
+
+// Create evidence provider
+let evidence = Ast1060Evidence::new();
+
+// Create SPDM responder with evidence
+let responder = SpdmResponder::new(
+    transport,
+    hash,
+    rng,
+    cert_store,
+    evidence,  // ← Our implementation
+);
+
+// Handle GET_MEASUREMENTS request
+// Responder will call evidence.pcr_quote() internally
+```
+
+## PCR Quote Format
+
+The PCR quote is formatted as follows:
+
+```
+┌────────────────────────────────────────┐
+│ Measurement Count (1 byte)             │  Value: 2
+├────────────────────────────────────────┤
+│ Measurement 0:                         │
+│   - Index (1 byte)                     │  Value: 0
+│   - Size (2 bytes, little-endian)      │  Value: 23
+│   - Data (23 bytes)                    │  "OpenPRoT SPDM Responder"
+├────────────────────────────────────────┤
+│ Measurement 1:                         │
+│   - Index (1 byte)                     │  Value: 1
+│   - Size (2 bytes, little-endian)      │  Value: 20
+│   - Data (20 bytes)                    │  "OCP EMEA HELLO WORLD"
+└────────────────────────────────────────┘
+
+Total size: 50 bytes
+```
+
+## Implementation Details
+
+### Measurement Encoding
+
+Each measurement is encoded as:
+- **Index** (1 byte): Measurement index (0-based)
+- **Size** (2 bytes): Length of measurement data (little-endian)
+- **Data** (variable): Measurement value
+
+### Memory Usage
+
+- Fixed measurements: ~43 bytes (string data)
+- Encoded output: 50 bytes
+- No dynamic allocation required
+
+### Post-Quantum Signatures
+
+Post-quantum cryptography (PQC) signatures are not supported in this version. Calling `pcr_quote()` or `pcr_quote_size()` with `with_pqc_sig = true` will return `SpdmEvidenceError::UnsupportedEvidenceType`.
+
+## Error Handling
+
+| Error | Cause |
+|-------|-------|
+| `UnsupportedEvidenceType` | PQC signatures requested (not supported) |
+| `InvalidEvidenceFormat` | Buffer too small for PCR quote |
+
+## Testing
+
+The implementation includes comprehensive unit tests:
+
+```bash
+# Build for AST1060-EVB platform
+bazel build --platforms=//target/ast1060-evb:ast1060-evb \
+    //target/ast1060-evb/evidence:evidence
+
+# Run unit tests
+bazel test --platforms=//target/ast1060-evb:ast1060-evb \
+    //target/ast1060-evb/evidence:evidence
+```
+
+### Test Coverage
+
+- ✅ Instance creation
+- ✅ PCR quote size calculation
+- ✅ PCR quote generation
+- ✅ Measurement encoding
+- ✅ Buffer validation
+- ✅ PQC rejection
+- ✅ Measurement value verification
+
+## Future Hardware-Backed Implementations
+
+When implementing hardware-backed versions:
+
+### TPM Integration
+
+```rust
+impl Ast1060Evidence {
+    fn pcr_quote(&self, buffer: &mut [u8], with_pqc_sig: bool) -> Result<usize> {
+        // Read PCR values from TPM
+        let pcr_values = platform::tpm::read_pcrs()?;
+
+        // Generate TPM quote
+        let quote = platform::tpm::quote(pcr_values)?;
+
+        // Encode into SPDM format
+        encode_tpm_quote(&quote, buffer)
+    }
+}
+```
+
+### Boot Measurement Integration
+
+```rust
+impl Ast1060Evidence {
+    fn pcr_quote(&self, buffer: &mut [u8], with_pqc_sig: bool) -> Result<usize> {
+        // Get boot measurements from measurement log
+        let measurements = platform::boot::get_measurements()?;
+
+        // Format for SPDM
+        encode_measurements(&measurements, buffer)
+    }
+}
+```
+
+### Dynamic Measurements
+
+```rust
+// Support runtime measurement updates
+impl Ast1060Evidence {
+    pub fn extend_measurement(&mut self, index: u8, data: &[u8]) -> Result<()> {
+        self.measurements[index as usize].extend(data)?;
+        Ok(())
+    }
+}
+```
+
+## SPDM Protocol Usage
+
+In SPDM protocol operations:
+
+1. **GET_MEASUREMENTS Request**
+   - Requester asks for device measurements
+   - Optionally specifies measurement indices
+
+2. **GET_MEASUREMENTS Response**
+   - Responder calls `evidence.pcr_quote()`
+   - Returns formatted measurements
+   - May include signature over measurements
+
+3. **Verification**
+   - Requester validates measurements against expected values
+   - Checks signature if present
+   - Compares with trust anchor or policy
+
+## Security Considerations
+
+⚠️ **This implementation is for testing only:**
+
+1. Fixed measurements provide no real attestation
+2. No cryptographic binding to platform state
+3. No signature over measurements
+4. No hardware root of trust
+
+### For Production:
+
+1. Use real platform measurements (boot state, firmware, etc.)
+2. Include cryptographic signatures (TPM quote signature)
+3. Bind measurements to hardware identity
+4. Implement measurement event log
+5. Support measurement policies
+6. Add anti-rollback protection
+
+## Limitations
+
+1. **Static measurements:** Values are fixed at compile time
+2. **No signatures:** Measurements not cryptographically signed
+3. **No PQC support:** Post-quantum signatures not implemented
+4. **Simple format:** Not standard TPM quote format
+5. **No measurement log:** No historical measurement tracking
+
+## Example Output
+
+When `pcr_quote()` is called, the buffer contains:
+
+```
+Offset  Value         Description
+------  -----         -----------
+0x00    0x02          Measurement count
+0x01    0x00          Measurement 0 index
+0x02    0x17 0x00     Size: 23 bytes (little-endian)
+0x04    "OpenPRoT..." Measurement 0 data
+0x1B    0x01          Measurement 1 index
+0x1C    0x14 0x00     Size: 20 bytes (little-endian)
+0x1E    "OCP EMEA..." Measurement 1 data
+```
+
+## Integration Example
+
+Complete integration with SPDM responder:
+
+```rust
+use ast1060_evidence::Ast1060Evidence;
+use ast1060_cert_store::Ast1060CertStore;
+use openprot_spdm_hash::SpdmCryptoHash;
+use openprot_spdm_rng::SpdmCryptoRng;
+
+// Create all platform implementations
+let cert_store = Ast1060CertStore::new(handle::CRYPTO);
+let hash = SpdmCryptoHash::new(handle::CRYPTO);
+let rng = SpdmCryptoRng::new(handle::CRYPTO);
+let evidence = Ast1060Evidence::new();
+
+// Create SPDM responder
+let responder = SpdmResponder::new(
+    transport,
+    hash,
+    rng,
+    cert_store,
+    evidence,
+);
+
+// Ready to handle SPDM requests
+```
+
+## License
+
+Licensed under the Apache-2.0 license.
diff --git a/target/ast1060-evb/evidence/src/lib.rs b/target/ast1060-evb/evidence/src/lib.rs
new file mode 100644
index 0000000..e35208b
--- /dev/null
+++ b/target/ast1060-evb/evidence/src/lib.rs
@@ -0,0 +1,252 @@
+// Licensed under the Apache-2.0 license
+
+//! SPDM Evidence Implementation - AST1060-EVB Reference Implementation
+//!
+//! Provides device measurements for SPDM attestation operations. This reference
+//! implementation returns fixed measurement values for testing and demonstration.
+//!
+//! ## Architecture
+//!
+//! - **Fixed measurements:** Two static string measurements
+//! - **No hardware integration:** Placeholder for development
+//! - **PCR quote generation:** Returns formatted measurement data
+//!
+//! ## Hardware-Backed Implementations
+//!
+//! This software implementation serves as a reference. Future hardware-backed
+//! versions should:
+//! - Integrate with platform boot measurements
+//! - Use TPM for PCR values and quotes
+//! - Include cryptographic signatures
+//! - Implement dynamic measurement log
+//!
+//! ## Usage
+//!
+//! ```rust,no_run
+//! use ast1060_evidence::Ast1060Evidence;
+//! use spdm_lib::platform::evidence::SpdmEvidence;
+//!
+//! let evidence = Ast1060Evidence::new();
+//!
+//! // Get PCR quote size
+//! let size = evidence.pcr_quote_size(false)?;
+//!
+//! // Generate PCR quote
+//! let mut buffer = vec![0u8; size];
+//! let written = evidence.pcr_quote(&mut buffer, false)?;
+//! ```
+
+#![no_std]
+
+use spdm_lib::platform::evidence::{SpdmEvidence, SpdmEvidenceError, SpdmEvidenceResult};
+
+/// Fixed measurement data
+const MEASUREMENT_1: &[u8] = b"OpenPRoT SPDM Responder";
+const MEASUREMENT_2: &[u8] = b"OCP EMEA HELLO WORLD";
+
+/// Total number of measurements
+const MEASUREMENT_COUNT: u8 = 2;
+
+/// SPDM evidence implementation for AST1060-EVB.
+///
+/// Provides fixed measurements for SPDM GET_MEASUREMENTS command.
+/// This is a reference implementation for testing and demonstration.
+pub struct Ast1060Evidence;
+
+impl Ast1060Evidence {
+    /// Create a new evidence provider instance.
+    pub const fn new() -> Self {
+        Self
+    }
+
+    /// Calculate the total size needed for PCR quote
+    fn calculate_quote_size(&self, with_pqc_sig: bool) -> usize {
+        // PCR quote format (simplified):
+        // - Measurement count (1 byte)
+        // - For each measurement:
+        //   - Measurement index (1 byte)
+        //   - Measurement size (2 bytes)
+        //   - Measurement data (variable)
+        // - Optional: Post-quantum signature (if with_pqc_sig)
+
+        let mut size = 1; // Measurement count
+
+        // Measurement 1
+        size += 1; // Index
+        size += 2; // Size field
+        size += MEASUREMENT_1.len(); // Data
+
+        // Measurement 2
+        size += 1; // Index
+        size += 2; // Size field
+        size += MEASUREMENT_2.len(); // Data
+
+        // Post-quantum signature (not implemented in this version)
+        if with_pqc_sig {
+            // Reserved for future PQC signature support
+            size += 0;
+        }
+
+        size
+    }
+
+    /// Encode measurements into buffer
+    fn encode_measurements(&self, buffer: &mut [u8]) -> SpdmEvidenceResult<usize> {
+        let mut offset = 0;
+
+        // Validate buffer size
+        let required_size = self.calculate_quote_size(false);
+        if buffer.len() < required_size {
+            return Err(SpdmEvidenceError::InvalidEvidenceFormat);
+        }
+
+        // Measurement count
+        buffer[offset] = MEASUREMENT_COUNT;
+        offset += 1;
+
+        // Measurement 1
+        buffer[offset] = 0; // Index 0
+        offset += 1;
+
+        let len1 = MEASUREMENT_1.len() as u16;
+        buffer[offset..offset + 2].copy_from_slice(&len1.to_le_bytes());
+        offset += 2;
+
+        buffer[offset..offset + MEASUREMENT_1.len()].copy_from_slice(MEASUREMENT_1);
+        offset += MEASUREMENT_1.len();
+
+        // Measurement 2
+        buffer[offset] = 1; // Index 1
+        offset += 1;
+
+        let len2 = MEASUREMENT_2.len() as u16;
+        buffer[offset..offset + 2].copy_from_slice(&len2.to_le_bytes());
+        offset += 2;
+
+        buffer[offset..offset + MEASUREMENT_2.len()].copy_from_slice(MEASUREMENT_2);
+        offset += MEASUREMENT_2.len();
+
+        Ok(offset)
+    }
+}
+
+impl SpdmEvidence for Ast1060Evidence {
+    fn pcr_quote(&self, buffer: &mut [u8], with_pqc_sig: bool) -> SpdmEvidenceResult<usize> {
+        if with_pqc_sig {
+            // Post-quantum signatures not implemented in this version
+            return Err(SpdmEvidenceError::UnsupportedEvidenceType);
+        }
+
+        self.encode_measurements(buffer)
+    }
+
+    fn pcr_quote_size(&self, with_pqc_sig: bool) -> SpdmEvidenceResult<usize> {
+        if with_pqc_sig {
+            // Post-quantum signatures not implemented in this version
+            return Err(SpdmEvidenceError::UnsupportedEvidenceType);
+        }
+
+        Ok(self.calculate_quote_size(false))
+    }
+}
+
+impl Default for Ast1060Evidence {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_new() {
+        let _evidence = Ast1060Evidence::new();
+    }
+
+    #[test]
+    fn test_pcr_quote_size() {
+        let evidence = Ast1060Evidence::new();
+
+        // Without PQC signature
+        let size = evidence.pcr_quote_size(false).unwrap();
+
+        // Expected size:
+        // 1 (count) + 1 (idx1) + 2 (len1) + 23 (data1) + 1 (idx2) + 2 (len2) + 20 (data2)
+        // = 1 + 26 + 23 = 50
+        assert_eq!(size, 50);
+    }
+
+    #[test]
+    fn test_pcr_quote_size_with_pqc() {
+        let evidence = Ast1060Evidence::new();
+
+        // PQC signatures not supported
+        let result = evidence.pcr_quote_size(true);
+        assert!(matches!(
+            result,
+            Err(SpdmEvidenceError::UnsupportedEvidenceType)
+        ));
+    }
+
+    #[test]
+    fn test_pcr_quote() {
+        let evidence = Ast1060Evidence::new();
+        let mut buffer = [0u8; 100];
+
+        let written = evidence.pcr_quote(&mut buffer, false).unwrap();
+        assert_eq!(written, 50);
+
+        // Verify measurement count
+        assert_eq!(buffer[0], 2);
+
+        // Verify measurement 1
+        assert_eq!(buffer[1], 0); // Index 0
+        let len1 = u16::from_le_bytes([buffer[2], buffer[3]]);
+        assert_eq!(len1, 23);
+        assert_eq!(&buffer[4..27], MEASUREMENT_1);
+
+        // Verify measurement 2
+        assert_eq!(buffer[27], 1); // Index 1
+        let len2 = u16::from_le_bytes([buffer[28], buffer[29]]);
+        assert_eq!(len2, 20);
+        assert_eq!(&buffer[30..50], MEASUREMENT_2);
+    }
+
+    #[test]
+    fn test_pcr_quote_buffer_too_small() {
+        let evidence = Ast1060Evidence::new();
+        let mut buffer = [0u8; 10]; // Too small
+
+        let result = evidence.pcr_quote(&mut buffer, false);
+        assert!(matches!(
+            result,
+            Err(SpdmEvidenceError::InvalidEvidenceFormat)
+        ));
+    }
+
+    #[test]
+    fn test_pcr_quote_with_pqc() {
+        let evidence = Ast1060Evidence::new();
+        let mut buffer = [0u8; 100];
+
+        // PQC signatures not supported
+        let result = evidence.pcr_quote(&mut buffer, true);
+        assert!(matches!(
+            result,
+            Err(SpdmEvidenceError::UnsupportedEvidenceType)
+        ));
+    }
+
+    #[test]
+    fn test_measurement_values() {
+        assert_eq!(MEASUREMENT_1, b"OpenPRoT SPDM Responder");
+        assert_eq!(MEASUREMENT_2, b"OCP EMEA HELLO WORLD");
+    }
+
+    #[test]
+    fn test_measurement_count() {
+        assert_eq!(MEASUREMENT_COUNT, 2);
+    }
+}
diff --git a/target/ast1060-evb/spdm-responder/BUILD.bazel b/target/ast1060-evb/spdm-responder/BUILD.bazel
new file mode 100644
index 0000000..2421435
--- /dev/null
+++ b/target/ast1060-evb/spdm-responder/BUILD.bazel
@@ -0,0 +1,111 @@
+# Licensed under the Apache-2.0 license
+
+load("@rules_rust//rust:defs.bzl", "rust_binary")
+load("//target/ast1060-evb:defs.bzl", "TARGET_COMPATIBLE_WITH")
+load("@pigweed//pw_kernel/tooling:system_image.bzl", "system_image", "system_image_test")
+load("@pigweed//pw_kernel/tooling:target_codegen.bzl", "target_codegen")
+load("@pigweed//pw_kernel/tooling:target_linker_script.bzl", "target_linker_script")
+load("@pigweed//pw_kernel/tooling/panic_detector:rust_binary_no_panics_test.bzl", "rust_binary_no_panics_test")
+load("@pigweed//pw_kernel/tooling:app_package.bzl", "app_package")
+
+system_image(
+    name = "spdm_responder",
+    apps = [
+        "//services/i2c/server:i2c_server",
+        "//services/mctp/server:mctp_server",
+        ":spdm_responder_app",
+        "//services/crypto/server:crypto_server",
+    ],
+    kernel = ":target",
+    platform = "//target/ast1060-evb",
+    system_config = ":system_config",
+    tags = ["kernel"],
+    visibility = ["//visibility:public"],
+)
+
+system_image_test(
+    name = "spdm_responder_test",
+    image = ":spdm_responder",
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+)
+
+rust_binary_no_panics_test(
+    name = "no_panics_test",
+    binary = ":spdm_responder",
+    tags = ["kernel"],
+)
+
+filegroup(
+    name = "system_config",
+    srcs = ["system.json5"],
+    visibility = ["//visibility:public"],
+)
+
+target_codegen(
+    name = "codegen",
+    arch = "@pigweed//pw_kernel/arch/arm_cortex_m:arch_arm_cortex_m",
+    system_config = ":system_config",
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+)
+
+target_linker_script(
+    name = "linker_script",
+    system_config = ":system_config",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+    template = "//target/ast1060-evb:linker_script_template",
+)
+
+rust_binary(
+    name = "target",
+    srcs = [
+        "target.rs",
+    ],
+    edition = "2024",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+    deps = [
+        ":codegen",
+        ":linker_script",
+        "@pigweed//pw_kernel/arch/arm_cortex_m:arch_arm_cortex_m",
+        "@pigweed//pw_kernel/kernel",
+        "//target/ast1060-evb:console_backend_uart",
+        "@pigweed//pw_kernel/target:target_common",
+        "//target/ast1060-evb:entry",
+        "@pigweed//pw_kernel/userspace",
+        "@pigweed//pw_log/rust:pw_log",
+        "@oot_crates_no_std//:cortex-m-semihosting",
+    ],
+)
+
+app_package(
+    name = "app_spdm_responder",
+    app_name = "spdm_responder",
+    edition = "2024",
+    system_config = ":system_config",
+    tags = ["kernel"],
+)
+
+rust_binary(
+    name = "spdm_responder_app",
+    srcs = [
+        "spdm_responder_app.rs",
+    ],
+    edition = "2024",
+    tags = ["kernel"],
+    target_compatible_with = TARGET_COMPATIBLE_WITH,
+    deps = [
+        ":app_spdm_responder",
+        "//target/ast1060-evb/cert-store:cert_store",
+        "//target/ast1060-evb/evidence:evidence",
+        "//services/spdm/hash:spdm_hash_lib",
+        "//services/spdm/rng:spdm_rng_lib",
+        "//services/mctp/client:mctp_client",
+        "//services/spdm/transport-mctp:spdm_transport_mctp",
+        "@pigweed//pw_kernel/syscall:syscall_user",
+        "@pigweed//pw_kernel/userspace",
+        "@pigweed//pw_log/rust:pw_log",
+        "@pigweed//pw_status/rust:pw_status",
+        "@oot_crates_no_std//:spdm-lib",
+    ],
+)
diff --git a/target/ast1060-evb/spdm-responder/README.md b/target/ast1060-evb/spdm-responder/README.md
new file mode 100644
index 0000000..af6744d
--- /dev/null
+++ b/target/ast1060-evb/spdm-responder/README.md
@@ -0,0 +1,219 @@
+# SPDM Responder Application for AST1060-EVB
+
+This is a complete SPDM (Security Protocol and Data Model) responder application for the AST1060-EVB platform. It integrates all platform-specific implementations to provide device attestation and secure communication capabilities.
+
+## Overview
+
+The SPDM responder application demonstrates the complete SPDM platform abstraction layer:
+
+- **Certificate Management**: Uses `Ast1060CertStore` for device certificates
+- **Evidence Collection**: Uses `Ast1060Evidence` for device measurements
+- **Cryptographic Operations**: Uses `SpdmCryptoHash` and `SpdmCryptoRng` via crypto service
+- **Transport Layer**: Ready for MCTP transport integration
+- **Protocol Handling**: Uses `SpdmResponder` service for message processing
+
+## Architecture
+
+```text
+┌────────────────────────────────────────────────┐
+│  SPDM Requester (External Device)             │
+└────────────────┬───────────────────────────────┘
+                 │ SPDM Protocol
+                 │ (over MCTP - TODO)
+                 ▼
+┌────────────────────────────────────────────────┐
+│  SPDM Responder Application                   │
+│  ┌──────────────────────────────────────────┐ │
+│  │  SpdmResponder Service                   │ │
+│  │  - Message processing                    │ │
+│  │  - Protocol state machine                │ │
+│  └──────────────┬───────────────────────────┘ │
+│                 │                              │
+│  ┌──────────────┴───────────────────────────┐ │
+│  │  Platform Implementations                │ │
+│  │  - Ast1060CertStore (certificates)       │ │
+│  │  - Ast1060Evidence (measurements)        │ │
+│  │  - SpdmCryptoHash (SHA-384 via IPC)      │ │
+│  │  - SpdmCryptoRng (RNG via IPC)           │ │
+│  │  - [MCTP Transport - TODO]               │ │
+│  └──────────────────────────────────────────┘ │
+└────────────────┬───────────────────────────────┘
+                 │ IPC
+                 ▼
+┌────────────────────────────────────────────────┐
+│  Crypto Service                                │
+│  - ECDSA P-384 signing                         │
+│  - SHA-384 hashing                             │
+│  - Random number generation                    │
+└────────────────────────────────────────────────┘
+```
+
+## System Configuration
+
+The application is configured in `system.json5`:
+
+- **SPDM Responder App**:
+  - Flash: 192KB (SPDM library is large)
+  - RAM: 64KB (for SPDM contexts and buffers)
+  - Stack: 16KB per thread
+  - Objects: CRYPTO (channel to crypto service)
+
+- **Crypto Server**:
+  - Flash: 128KB
+  - RAM: 64KB
+  - Stack: 8KB per thread
+  - Objects: CRYPTO (channel handler)
+
+Total memory usage: ~704KB (fits in AST1060's 768KB SRAM)
+
+## Building
+
+Build the SPDM responder system image:
+
+```bash
+bazel build --platforms=//target/ast1060-evb:ast1060-evb \
+    //target/ast1060-evb/spdm-responder:spdm_responder
+```
+
+This produces a complete system image with:
+- Kernel
+- SPDM responder application
+- Crypto service
+- All platform implementations
+
+## Running
+
+### In QEMU
+
+```bash
+bazel run --platforms=//target/ast1060-evb:ast1060-evb \
+    //target/ast1060-evb/spdm-responder:spdm_responder_test
+```
+
+### On Hardware
+
+Flash the system image to AST1060-EVB and connect via UART to see logs.
+
+## SPDM Protocol Support
+
+The responder supports the following SPDM commands:
+
+1. **GET_VERSION** - Returns supported SPDM versions (1.2, 1.1)
+2. **GET_CAPABILITIES** - Returns device capabilities
+3. **NEGOTIATE_ALGORITHMS** - Negotiates cryptographic algorithms
+4. **GET_DIGESTS** - Returns certificate chain digests
+5. **GET_CERTIFICATE** - Returns certificate chains (with chunking support)
+6. **CHALLENGE** - Challenge-response authentication
+7. **GET_MEASUREMENTS** - Returns device measurements
+
+## Capabilities
+
+The responder advertises:
+
+- **CERT_CAP**: Certificate provisioning
+- **CHAL_CAP**: Challenge-response authentication
+- **MEAS_CAP**: Measurements with signatures
+- **MEAS_FRESH_CAP**: Fresh measurements
+- **CHUNK_CAP**: Large message chunking
+
+## Algorithms
+
+Supported cryptographic algorithms:
+
+- **Hash**: SHA-384 (TPM_ALG_SHA_384)
+- **Asymmetric**: ECDSA with NIST P-384 (TPM_ALG_ECDSA_ECC_NIST_P384)
+- **Measurement**: DMTF Measurement Specification
+
+## Current Status
+
+✅ **Implemented:**
+- Complete platform abstraction layer
+- All SPDM traits implemented
+- Integration with crypto service
+- Application structure and build configuration
+
+⚠️ **TODO:**
+- MCTP transport integration (currently commented out)
+- End-to-end testing with SPDM requester
+- Real certificate provisioning (currently using placeholder data)
+
+## Testing
+
+Run the system image test:
+
+```bash
+bazel test --platforms=//target/ast1060-evb:ast1060-evb \
+    //target/ast1060-evb/spdm-responder:spdm_responder_test
+```
+
+Check for panics:
+
+```bash
+bazel test --platforms=//target/ast1060-evb:ast1060-evb \
+    //target/ast1060-evb/spdm-responder:no_panics_test
+```
+
+## Logs
+
+The application uses pw_log for logging:
+
+```
+[INFO] SPDM Responder App starting
+[INFO] SPDM Responder starting...
+[INFO] Platform implementations initialized
+[INFO] SPDM responder configuration: ResponderConfig { ... }
+[INFO] SPDM Responder initialized (waiting for MCTP transport)
+[INFO] SPDM Responder thread spawned
+```
+
+## Next Steps
+
+To make this fully functional:
+
+1. **Add MCTP Transport**:
+   - Implement MCTP service
+   - Create `MctpSpdmTransport` wrapper
+   - Add MCTP object to system.json5
+   - Uncomment transport code in spdm_responder_app.rs
+
+2. **Provision Real Certificates**:
+   - Replace placeholder data in cert-store
+   - Generate device-specific keys
+   - Include real X.509 certificate chain
+
+3. **Add Real Measurements**:
+   - Integrate with boot measurements
+   - Add measurement event log
+   - Include platform-specific measurements
+
+4. **End-to-End Testing**:
+   - Set up SPDM requester
+   - Test full protocol flow
+   - Verify attestation and authentication
+
+## Integration with Other Components
+
+The SPDM responder integrates with:
+
+- **Crypto Service** (`services/crypto/server`): Provides cryptographic operations
+- **Cert Store** (`target/ast1060-evb/cert-store`): Device certificates and signing
+- **Evidence** (`target/ast1060-evb/evidence`): Device measurements
+- **Hash Service** (`services/spdm/hash`): SHA-384 operations
+- **RNG Service** (`services/spdm/rng`): Random number generation
+
+## Memory Map
+
+```
+0x00000000 - 0x000004A0: Vector table (1184 bytes)
+0x000004A0 - 0x00020000: Kernel (~126KB)
+0x00020000 - 0x00050000: SPDM responder app (192KB)
+0x00050000 - 0x00070000: Crypto server (128KB)
+0x00070000 - 0x00090000: Kernel RAM (128KB)
+0x00090000 - 0x000B0000: App RAM (128KB)
+
+Total: ~704KB / 768KB SRAM available
+```
+
+## License
+
+Licensed under the Apache-2.0 license.
diff --git a/target/ast1060-evb/spdm-responder/spdm_responder_app.rs b/target/ast1060-evb/spdm-responder/spdm_responder_app.rs
new file mode 100644
index 0000000..f09634e
--- /dev/null
+++ b/target/ast1060-evb/spdm-responder/spdm_responder_app.rs
@@ -0,0 +1,170 @@
+// Licensed under the Apache-2.0 license
+
+//! SPDM Responder Application for AST1060-EVB
+//!
+//! This application provides SPDM (Security Protocol and Data Model) responder
+//! functionality for device attestation and secure communication.
+
+#![no_std]
+#![no_main]
+
+use ast1060_cert_store::Ast1060CertStore;
+use ast1060_evidence::Ast1060Evidence;
+use openprot_mctp_client::IpcMctpClient;
+use openprot_spdm_hash::SpdmCryptoHash;
+use openprot_spdm_rng::SpdmCryptoRng;
+use openprot_spdm_transport_mctp::MctpSpdmTransport;
+use pw_log::info;
+use pw_status::Result;
+use spdm_lib::codec::MessageBuf;
+use spdm_lib::context::SpdmContext;
+use spdm_lib::protocol::{
+    AeadCipherSuite, AlgorithmPriorityTable, BaseAsymAlgo, BaseHashAlgo, CapabilityFlags,
+    DeviceAlgorithms, DeviceCapabilities, DheNamedGroup, KeySchedule, LocalDeviceAlgorithms,
+    MeasurementHashAlgo, MeasurementSpecification, MelSpecification, OtherParamSupport,
+    ReqBaseAsymAlg, SpdmVersion,
+};
+use userspace::entry;
+use userspace::syscall;
+
+use app_spdm_responder::handle;
+
+/// Create local device algorithms configuration for SPDM
+fn create_local_algorithms<'a>() -> LocalDeviceAlgorithms<'a> {
+    // Measurement specification (DMTF)
+    let mut measurement_spec = MeasurementSpecification::default();
+    measurement_spec.set_dmtf_measurement_spec(1);
+
+    // Measurement hash algorithm (SHA-384)
+    let mut measurement_hash_algo = MeasurementHashAlgo::default();
+    measurement_hash_algo.set_tpm_alg_sha_384(1);
+
+    // Base asymmetric algorithm (ECDSA P-384)
+    let mut base_asym_algo = BaseAsymAlgo::default();
+    base_asym_algo.set_tpm_alg_ecdsa_ecc_nist_p384(1);
+
+    // Base hash algorithm (SHA-384)
+    let mut base_hash_algo = BaseHashAlgo::default();
+    base_hash_algo.set_tpm_alg_sha_384(1);
+
+    let device_algorithms = DeviceAlgorithms {
+        measurement_spec,
+        other_param_support: OtherParamSupport::default(),
+        measurement_hash_algo,
+        base_asym_algo,
+        base_hash_algo,
+        mel_specification: MelSpecification::default(),
+        dhe_group: DheNamedGroup::default(),
+        aead_cipher_suite: AeadCipherSuite::default(),
+        req_base_asym_algo: ReqBaseAsymAlg::default(),
+        key_schedule: KeySchedule::default(),
+    };
+
+    let algorithm_priority_table = AlgorithmPriorityTable {
+        measurement_specification: None,
+        opaque_data_format: None,
+        base_asym_algo: None,
+        base_hash_algo: None,
+        mel_specification: None,
+        dhe_group: None,
+        aead_cipher_suite: None,
+        req_base_asym_algo: None,
+        key_schedule: None,
+    };
+
+    LocalDeviceAlgorithms {
+        device_algorithms,
+        algorithm_priority_table,
+    }
+}
+
+/// SPDM responder main loop
+fn spdm_responder_loop() -> Result<()> {
+    info!("SPDM Responder starting...");
+
+    // Initialize platform implementations
+    let mut cert_store = Ast1060CertStore::new(handle::CRYPTO);
+    let mut hash = SpdmCryptoHash::new(handle::CRYPTO);
+    let mut m1_hash = SpdmCryptoHash::new(handle::CRYPTO);
+    let mut l1_hash = SpdmCryptoHash::new(handle::CRYPTO);
+    let mut rng = SpdmCryptoRng::new(handle::CRYPTO);
+    let evidence = Ast1060Evidence::new();
+
+    info!("Platform implementations initialized");
+
+    // Initialize MCTP transport
+    let mctp_client = IpcMctpClient::new(handle::MCTP);
+    let mut transport = MctpSpdmTransport::new_responder(mctp_client);
+
+    // Configure device capabilities
+    let mut flags = CapabilityFlags::default();
+    flags.set_cert_cap(1);      // Certificate capability
+    flags.set_chal_cap(1);      // Challenge capability
+    flags.set_meas_cap(2);      // Measurements with signature (2 = with signature)
+    flags.set_meas_fresh_cap(1); // Measurements freshness capability
+    flags.set_chunk_cap(1);     // Chunk capability
+
+    let capabilities = DeviceCapabilities {
+        ct_exponent: 0,
+        flags,
+        data_transfer_size: 1024,
+        max_spdm_msg_size: 4096,
+        include_supported_algorithms: true,
+    };
+
+    // Configure supported algorithms
+    let algorithms = create_local_algorithms();
+
+    // Supported SPDM versions
+    static SUPPORTED_VERSIONS: [SpdmVersion; 2] = [SpdmVersion::V12, SpdmVersion::V11];
+
+    // Create SPDM context directly (no wrapper)
+    let mut context = match SpdmContext::new(
+        &SUPPORTED_VERSIONS,
+        &mut transport,
+        capabilities,
+        algorithms,
+        &mut cert_store,
+        None, // No peer cert store needed for responder
+        &mut hash,
+        &mut m1_hash,
+        &mut l1_hash,
+        &mut rng,
+        &evidence,
+    ) {
+        Ok(ctx) => ctx,
+        Err(_e) => {
+            pw_log::error!("Failed to create SPDM context");
+            return Err(pw_status::Error::Unknown);
+        }
+    };
+
+    info!("SPDM context created, entering message loop");
+
+    // Process SPDM messages
+    // Buffer and MessageBuf must live as long as context due to lifetime constraint
+    let mut buffer = [0u8; 4096];
+    let mut message_buf = MessageBuf::new(&mut buffer);
+
+    loop {
+        if let Err(_e) = context.responder_process_message(&mut message_buf) {
+            // Continue processing - don't exit on errors
+            // Errors are expected during normal operation (e.g., malformed requests)
+        }
+    }
+}
+
+#[entry]
+fn entry() -> ! {
+    if let Err(e) = spdm_responder_loop() {
+        pw_log::error!("SPDM responder error: {:04x}", e as u32);
+        let _ = syscall::debug_shutdown(Err(e));
+    }
+
+    loop {}
+}
+
+#[panic_handler]
+fn panic(_info: &core::panic::PanicInfo) -> ! {
+    loop {}
+}
diff --git a/target/ast1060-evb/spdm-responder/system.json5 b/target/ast1060-evb/spdm-responder/system.json5
new file mode 100644
index 0000000..df1dcdf
--- /dev/null
+++ b/target/ast1060-evb/spdm-responder/system.json5
@@ -0,0 +1,150 @@
+// Licensed under the Apache-2.0 license
+
+// ASPEED AST1060-EVB SPDM Responder Configuration
+// ARM Cortex-M4F with UART console
+//
+// Memory Layout (PMSAv7-aligned for AST1060 MPU):
+//   0x00000000 - 0x00000500: Vector table + kernel annotations (1280 bytes)
+//   0x00000500 - 0x00020000: Kernel code (~127KB)
+//   0x00020000 - 0x00030000: I2C server (64KB flash)
+//   0x00030000 - 0x00040000: MCTP server (64KB flash)
+//   0x00040000 - 0x00060000: SPDM responder (128KB flash)
+//   0x00060000 - 0x00080000: Crypto server (128KB flash, aligned to 128KB boundary)
+//   0x00080000 - 0x00084000: I2C server RAM (16KB)
+//   0x00084000 - 0x00088000: MCTP server RAM (16KB)
+//   0x00088000 - 0x00090000: SPDM responder RAM (32KB)
+//   0x00090000 - 0x00098000: Crypto server RAM (32KB)
+//   0x00098000 - 0x000A8000: Kernel RAM (64KB)
+//
+// Total: 672KB (fits within 768KB SRAM)
+{
+    arch: {
+        type: "armv7m",
+        vector_table_start_address: 0x00000000,
+        vector_table_size_bytes: 1280,  // 0x500 (272 vectors + thread/stack annotations)
+    },
+    kernel: {
+        flash_start_address: 0x00000500,  // After vector table + annotations
+        flash_size_bytes: 129792,         // ~127KB (ends at 0x00020000)
+        ram_start_address: 0x00098000,    // After all app RAM
+        ram_size_bytes: 65536,            // 64KB
+    },
+    apps: [
+        // ──── I2C Server ────
+        {
+            name: "i2c_server",
+            flash_size_bytes: 65536,      // 64KB for I2C server
+            ram_size_bytes: 16384,        // 16KB RAM
+            process: {
+                name: "i2c_server_process",
+                objects: [
+                    {
+                        name: "I2C",
+                        type: "channel_handler",
+                    },
+                ],
+                threads: [
+                    {
+                        name: "i2c_server_thread",
+                        stack_size_bytes: 4096,
+                    },
+                ],
+                memory_mappings: [
+                    {
+                        name: "i2c_regs",
+                        type: "device",
+                        start_address: 0x7e7b0000,
+                        size_bytes: 0x4000,
+                    },
+                    {
+                        name: "scu",
+                        type: "device",
+                        start_address: 0x7e6e2000,
+                        size_bytes: 0x1000,
+                    },
+                ],
+            },
+        },
+        // ──── MCTP Server ────
+        {
+            name: "mctp_server",
+            flash_size_bytes: 65536,      // 64KB for MCTP server
+            ram_size_bytes: 16384,        // 16KB RAM
+            process: {
+                name: "mctp_server_process",
+                objects: [
+                    {
+                        name: "MCTP",
+                        type: "channel_handler",
+                    },
+                    {
+                        name: "I2C",
+                        type: "channel_initiator",
+                        handler_app: "i2c_server",
+                        handler_object_name: "I2C",
+                    },
+                    {
+                        name: "WG",
+                        type: "wait_group",
+                    },
+                ],
+                threads: [
+                    {
+                        name: "mctp_server_thread",
+                        stack_size_bytes: 4096,
+                    },
+                ],
+            },
+        },
+        // ──── SPDM Responder ────
+        {
+            name: "spdm_responder",
+            flash_size_bytes: 131072,     // 128KB for SPDM responder (aligned)
+            ram_size_bytes: 32768,        // 32KB RAM for SPDM contexts and buffers
+            process: {
+                name: "spdm_responder_process",
+                objects: [
+                    {
+                        name: "CRYPTO",
+                        type: "channel_initiator",
+                        handler_app: "crypto_server",
+                        handler_object_name: "CRYPTO",
+                    },
+                    {
+                        name: "MCTP",
+                        type: "channel_initiator",
+                        handler_app: "mctp_server",
+                        handler_object_name: "MCTP",
+                    },
+                ],
+                threads: [
+                    {
+                        name: "spdm_responder_thread",
+                        stack_size_bytes: 16384,  // 16KB stack for SPDM operations
+                    },
+                ],
+            },
+        },
+        // ──── Crypto Server ────
+        {
+            name: "crypto_server",
+            flash_size_bytes: 131072,     // 128KB for crypto server
+            ram_size_bytes: 32768,        // 32KB RAM for crypto contexts
+            process: {
+                name: "crypto_server_process",
+                objects: [
+                    {
+                        name: "CRYPTO",
+                        type: "channel_handler",
+                    },
+                ],
+                threads: [
+                    {
+                        name: "crypto_server_thread",
+                        stack_size_bytes: 8192,  // 8KB stack for crypto ops
+                    },
+                ],
+            },
+        },
+    ],
+}
diff --git a/target/ast1060-evb/spdm-responder/target.rs b/target/ast1060-evb/spdm-responder/target.rs
new file mode 100644
index 0000000..1f43f1f
--- /dev/null
+++ b/target/ast1060-evb/spdm-responder/target.rs
@@ -0,0 +1,37 @@
+// Licensed under the Apache-2.0 license
+
+//! AST1060-EVB SPDM Responder Target
+//!
+//! Target entry point and initialization for the SPDM responder system.
+
+#![no_std]
+#![no_main]
+
+use cortex_m_semihosting::debug::{EXIT_FAILURE, EXIT_SUCCESS, exit};
+use target_common::{TargetInterface, declare_target};
+use {console_backend as _, entry as _};
+
+pub struct Target {}
+
+impl TargetInterface for Target {
+    const NAME: &'static str = "AST1060-EVB SPDM Responder";
+
+    fn main() -> ! {
+        codegen::start();
+        #[expect(clippy::empty_loop)]
+        loop {}
+    }
+
+    fn shutdown(code: u32) -> ! {
+        pw_log::info!("Shutting down with code {:04x}", code as u32);
+        let status = match code {
+            0 => EXIT_SUCCESS,
+            _ => EXIT_FAILURE,
+        };
+        exit(status);
+        #[expect(clippy::empty_loop)]
+        loop {}
+    }
+}
+
+declare_target!(Target);
diff --git a/third_party/crates_io/crates_no_std/Cargo.toml b/third_party/crates_io/crates_no_std/Cargo.toml
index da85f42..6fd952c 100644
--- a/third_party/crates_io/crates_no_std/Cargo.toml
+++ b/third_party/crates_io/crates_no_std/Cargo.toml
@@ -32,7 +32,7 @@
 zerocopy = { version = "0.8", default-features = false, features = ["derive"] }
 rand_chacha = { version = "0.3", default-features = false }
 rand_core = { version = "0.6", default-features = false }
-getrandom = { version = "0.2", default-features = false }
+getrandom = { version = "0.2", default-features = false, features = ["custom"] }
 
 # aspeed-ddk transitive deps needed as explicit Bazel targets
 heapless = "0.8.0"