From 47835ef07eeb2098369ab422796d86c61dc0e5f4 Mon Sep 17 00:00:00 2001 From: Sangho Lee Date: Mon, 4 May 2026 18:48:40 +0000 Subject: [PATCH 1/3] generate identity signing key pair --- Cargo.lock | 136 ++++++++++++++++++++ dev_tests/src/ratchet.rs | 2 +- litebox_platform_lvbs/Cargo.toml | 2 + litebox_platform_lvbs/src/host/lvbs_impl.rs | 20 +++ litebox_platform_lvbs/src/mshv/error.rs | 14 +- litebox_platform_lvbs/src/mshv/mod.rs | 4 + litebox_platform_lvbs/src/mshv/vsm.rs | 133 +++++++++++++++++++ 7 files changed, 308 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e43cffa1c..019d7cb0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,6 +145,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.22.1" @@ -487,6 +493,18 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -668,6 +686,7 @@ dependencies = [ "block-buffer", "const-oid", "crypto-common", + "subtle", ] [[package]] @@ -681,6 +700,19 @@ dependencies = [ "syn", ] +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", +] + [[package]] name = "either" version = "1.15.0" @@ -693,6 +725,24 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55dd888a213fc57e957abf2aa305ee3e8a28dbe05687a251f33b637cd46b0070" +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "encode_unicode" version = "1.0.0" @@ -775,6 +825,16 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "filetime" version = "0.2.27" @@ -927,6 +987,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -983,6 +1044,17 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + [[package]] name = "hash32" version = "0.3.1" @@ -1019,6 +1091,24 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "http" version = "1.4.0" @@ -1555,6 +1645,7 @@ dependencies = [ "digest", "elf", "hashbrown", + "hkdf", "libc", "litebox", "litebox_common_linux", @@ -1563,6 +1654,7 @@ dependencies = [ "num_enum", "object", "once_cell", + "p384", "rangemap", "raw-cpuid", "rsa", @@ -2099,6 +2191,18 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "paste" version = "1.0.15" @@ -2222,6 +2326,15 @@ dependencies = [ "syn", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -2428,6 +2541,16 @@ dependencies = [ "web-sys", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ringbuf" version = "0.4.8" @@ -2522,6 +2645,19 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + [[package]] name = "security-framework" version = "2.11.1" diff --git a/dev_tests/src/ratchet.rs b/dev_tests/src/ratchet.rs index d5b76f069..71190b32d 100644 --- a/dev_tests/src/ratchet.rs +++ b/dev_tests/src/ratchet.rs @@ -37,7 +37,7 @@ fn ratchet_globals() -> Result<()> { ("litebox/", 9), ("litebox_platform_linux_kernel/", 6), ("litebox_platform_linux_userland/", 5), - ("litebox_platform_lvbs/", 24), + ("litebox_platform_lvbs/", 25), ("litebox_platform_multiplex/", 1), ("litebox_platform_windows_userland/", 8), ("litebox_runner_lvbs/", 6), diff --git a/litebox_platform_lvbs/Cargo.toml b/litebox_platform_lvbs/Cargo.toml index 0c628a346..b64e4441d 100644 --- a/litebox_platform_lvbs/Cargo.toml +++ b/litebox_platform_lvbs/Cargo.toml @@ -33,6 +33,8 @@ aligned-vec = { version = "0.6.4", default-features = false } raw-cpuid = "11.6.0" zerocopy = { version = "0.8", default-features = false, features = ["derive"] } zeroize = { version = "1.8", default-features = false } +hkdf = { version = "0.12.4", default-features = false } +p384 = { version = "0.13.1", default-features = false, features = ["arithmetic", "ecdsa"] } [target.'cfg(target_arch = "x86_64")'.dependencies] x86_64 = { version = "0.15.2", default-features = false, features = ["instructions"] } diff --git a/litebox_platform_lvbs/src/host/lvbs_impl.rs b/litebox_platform_lvbs/src/host/lvbs_impl.rs index 977461a69..c0ca94861 100644 --- a/litebox_platform_lvbs/src/host/lvbs_impl.rs +++ b/litebox_platform_lvbs/src/host/lvbs_impl.rs @@ -120,6 +120,10 @@ pub(crate) const PRK_LEN: usize = 32; static PRK_ONCE: spin::Once<[u8; PRK_LEN]> = spin::Once::new(); +// Do not expose a raw PRK getter (i.e., no `get_platform_root_key`). +// Consumers should request derived key material through +// `DerivedKeyProvider` so PRK access stays centralized in this module. + /// Sets the Platform Root Key (PRK) for this platform. /// /// This should be called once during platform initialization with a key derived @@ -136,6 +140,22 @@ pub(crate) fn set_platform_root_key(key: &[u8]) { }); } +impl litebox::platform::DerivedKeyProvider for LvbsLinuxKernel { + fn derive_key( + &self, + kdf: Option Result<(), E>>, + params: litebox::platform::KDFParams, + ) -> Result<(), litebox::platform::DerivedKeyError> { + let Some(prk) = PRK_ONCE.get() else { + return Err(litebox::platform::DerivedKeyError::UnsupportedRebootPersistentKey); + }; + match kdf { + None => Err(litebox::platform::DerivedKeyError::ShimKDFRequired), + Some(kdf) => Ok(kdf(prk, params)?), + } + } +} + pub struct HostLvbsInterface; impl HostLvbsInterface {} diff --git a/litebox_platform_lvbs/src/mshv/error.rs b/litebox_platform_lvbs/src/mshv/error.rs index aa767b78f..b19382c71 100644 --- a/litebox_platform_lvbs/src/mshv/error.rs +++ b/litebox_platform_lvbs/src/mshv/error.rs @@ -105,6 +105,13 @@ pub enum VsmError { #[error("{0} is not supported")] OperationNotSupported(&'static str), + // Key Management Errors + #[error("platform root key is not set")] + PlatformRootKeyNotSet, + + #[error("failed to generate identity signing key")] + IdentitySigningKeyGenerationFailed, + // VTL0 Memory Copy Errors #[error("failed to copy data from/to VTL0")] Vtl0CopyFailed, @@ -177,7 +184,8 @@ impl From for Errno { // Not found errors VsmError::SystemCertificatesNotFound | VsmError::KernelSymbolTableNotFound - | VsmError::PrecomputedPatchNotFound => Errno::ENOENT, + | VsmError::PrecomputedPatchNotFound + | VsmError::PlatformRootKeyNotSet => Errno::ENOENT, // Operation not permitted after end of boot VsmError::OperationAfterEndOfBoot(_) => Errno::EPERM, @@ -199,7 +207,9 @@ impl From for Errno { | VsmError::SymbolTableOutOfRange => Errno::ERANGE, // Init/hardware failures - I/O error - VsmError::ApInitFailed(_) | VsmError::HypercallFailed(_) => Errno::EIO, + VsmError::ApInitFailed(_) + | VsmError::HypercallFailed(_) + | VsmError::IdentitySigningKeyGenerationFailed => Errno::EIO, // True format/validation errors - invalid argument VsmError::AddressNotPageAligned diff --git a/litebox_platform_lvbs/src/mshv/mod.rs b/litebox_platform_lvbs/src/mshv/mod.rs index 826daaa39..ea96c20ad 100644 --- a/litebox_platform_lvbs/src/mshv/mod.rs +++ b/litebox_platform_lvbs/src/mshv/mod.rs @@ -131,6 +131,9 @@ pub const VSM_VTL_CALL_FUNC_ID_ALLOCATE_RINGBUFFER_MEMORY: u32 = 0x1_ffec; // This VSM function ID for setting the platform root key is subject to change pub const VSM_VTL_CALL_FUNC_ID_SET_PLATFORM_ROOT_KEY: u32 = 0x1_ffed; +// This VSM function ID for generating the identity signing key is subject to change +pub const VSM_VTL_CALL_FUNC_ID_GENERATE_IDENTITY_SIGNING_KEY: u32 = 0x1_ffee; + // This VSM function ID for OP-TEE messages is subject to change pub const VSM_VTL_CALL_FUNC_ID_OPTEE_MESSAGE: u32 = 0x1_fff0; @@ -154,6 +157,7 @@ pub enum VsmFunction { OpteeMessage = VSM_VTL_CALL_FUNC_ID_OPTEE_MESSAGE, AllocateRingbufferMemory = VSM_VTL_CALL_FUNC_ID_ALLOCATE_RINGBUFFER_MEMORY, SetPlatformRootKey = VSM_VTL_CALL_FUNC_ID_SET_PLATFORM_ROOT_KEY, + GenerateIdentitySigningKey = VSM_VTL_CALL_FUNC_ID_GENERATE_IDENTITY_SIGNING_KEY, } pub const MSR_EFER: u32 = 0xc000_0080; diff --git a/litebox_platform_lvbs/src/mshv/vsm.rs b/litebox_platform_lvbs/src/mshv/vsm.rs index 9470d0add..1ed711a38 100644 --- a/litebox_platform_lvbs/src/mshv/vsm.rs +++ b/litebox_platform_lvbs/src/mshv/vsm.rs @@ -48,8 +48,12 @@ use core::{ sync::atomic::{AtomicBool, AtomicI64, Ordering}, }; use hashbrown::HashMap; +use hkdf::Hkdf; +use litebox::platform::{DerivedKeyError, DerivedKeyProvider, KDFParams}; use litebox::utils::TruncateExt; use litebox_common_linux::errno::Errno; +use p384::elliptic_curve::sec1::ToEncodedPoint; +use sha2::Sha384; use spin::Once; use thiserror::Error; use x86_64::{ @@ -67,8 +71,21 @@ struct AlignedPage([u8; PAGE_SIZE]); // For now, we do not validate large kernel modules due to the VTL1's memory size limitation. const MODULE_VALIDATION_MAX_SIZE: usize = 64 * 1024 * 1024; +const IDENTITY_SIGNING_KEY_DERIVATION_INFO: &[u8] = b"litebox-lvbs-identity-signing-key-p384-v1"; +const IDENTITY_SIGNING_PRIVATE_KEY_LEN: usize = 48; +const IDENTITY_SIGNING_PUBLIC_KEY_LEN: usize = 97; + static CPU_ONLINE_MASK: Once> = Once::new(); +struct IdentitySigningKeyPair { + // Kept in VTL1 for future IDK_S signing operations; this VSM call only exports the public key. + #[allow(dead_code)] + secret_key: p384::SecretKey, + public_key: [u8; IDENTITY_SIGNING_PUBLIC_KEY_LEN], +} + +static IDENTITY_SIGNING_KEY_PAIR: Once = Once::new(); + pub(crate) fn init(is_bsp: bool) { assert!( !(is_bsp && mshv_vsm_configure_partition().is_err()), @@ -919,6 +936,94 @@ fn mshv_vsm_set_platform_root_key(key_pa: u64) -> Result { } } +/// VSM function for generating the identity signing key pair (IDK_S). +/// +/// - `public_key_pa`: Physical address (VTL0) where the uncompressed SEC1 P-384 +/// public key will be written. The corresponding private key is derived from the PRK +/// and never leaves VTL1. +/// +/// This function assumes that the caller prepares a buffer at the given physical +/// address (in a single or contiguous physical memory page(s)) whose length is equal to +/// or greater than `IDENTITY_SIGNING_PUBLIC_KEY_LEN`. +pub fn mshv_vsm_gen_identity_signing_key(public_key_pa: u64) -> Result { + if crate::platform_low().vtl0_kernel_info.check_end_of_boot() { + return Err(VsmError::OperationAfterEndOfBoot( + "generate identity signing key", + )); + } + + debug_serial_println!("VSM: Generate identity signing key"); + + let public_key_pa = + PhysAddr::try_new(public_key_pa).map_err(|_| VsmError::InvalidPhysicalAddress)?; + if public_key_pa.is_null() { + return Err(VsmError::InvalidInputAddress); + } + + let key_pair = IDENTITY_SIGNING_KEY_PAIR.try_call_once(derive_identity_signing_key_pair)?; + if unsafe { crate::platform_low().copy_slice_to_vtl0_phys(public_key_pa, &key_pair.public_key) } + { + Ok(0) + } else { + Err(VsmError::Vtl0CopyFailed) + } +} + +fn derive_identity_signing_key_pair() -> Result { + derive_identity_signing_key_pair_with(|context, output| { + crate::platform_low() + .derive_key( + Some(identity_signing_key_kdf), + KDFParams { context, output }, + ) + .map_err(|err| match err { + DerivedKeyError::ShimKDFRequired + | DerivedKeyError::UnsupportedRebootPersistentKey => { + VsmError::PlatformRootKeyNotSet + } + DerivedKeyError::ShimKDFError(err) => err, + }) + }) +} + +fn derive_identity_signing_key_pair_with( + derive_private_key: impl Fn(&[u8], &mut [u8]) -> Result<(), VsmError>, +) -> Result { + let mut derivation_info = [0u8; IDENTITY_SIGNING_KEY_DERIVATION_INFO.len() + 1]; + derivation_info[..IDENTITY_SIGNING_KEY_DERIVATION_INFO.len()] + .copy_from_slice(IDENTITY_SIGNING_KEY_DERIVATION_INFO); + let mut private_key_bytes = Zeroizing::new([0u8; IDENTITY_SIGNING_PRIVATE_KEY_LEN]); + + // HKDF output is uniformly random bytes, but P-384 private keys must be + // valid non-zero scalars smaller than the curve order. Retry with a new + // derivation label until the candidate is accepted. + for counter in u8::MIN..=u8::MAX { + derivation_info[IDENTITY_SIGNING_KEY_DERIVATION_INFO.len()] = counter; + derive_private_key(&derivation_info, &mut *private_key_bytes)?; + + let Ok(secret_key) = p384::SecretKey::from_slice(&*private_key_bytes) else { + continue; + }; + + let public_key = secret_key.public_key(); + let encoded_point = public_key.to_encoded_point(false); + let mut public_key_bytes = [0u8; IDENTITY_SIGNING_PUBLIC_KEY_LEN]; + public_key_bytes.copy_from_slice(encoded_point.as_bytes()); + return Ok(IdentitySigningKeyPair { + secret_key, + public_key: public_key_bytes, + }); + } + + Err(VsmError::IdentitySigningKeyGenerationFailed) +} + +fn identity_signing_key_kdf(root_key: &[u8], params: KDFParams<'_>) -> Result<(), VsmError> { + Hkdf::::new(None, root_key) + .expand(params.context, params.output) + .map_err(|_| VsmError::IdentitySigningKeyGenerationFailed) +} + /// VSM function dispatcher pub fn vsm_dispatch(func_id: VsmFunction, params: &[u64]) -> i64 { let result: Result = match func_id { @@ -943,6 +1048,7 @@ pub fn vsm_dispatch(func_id: VsmFunction, params: &[u64]) -> i64 { mshv_vsm_allocate_ringbuffer_memory(params[0], size) } VsmFunction::SetPlatformRootKey => mshv_vsm_set_platform_root_key(params[0]), + VsmFunction::GenerateIdentitySigningKey => mshv_vsm_gen_identity_signing_key(params[0]), VsmFunction::OpteeMessage => Err(VsmError::OperationNotSupported("OP-TEE communication")), }; match result { @@ -1883,3 +1989,30 @@ impl SymbolTable { Ok(0) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn identity_signing_key_pair_signs_and_verifies_message() { + use p384::ecdsa::{ + Signature, SigningKey, VerifyingKey, + signature::{Signer, Verifier}, + }; + + let prk = [0x5a; PRK_LEN]; + let message = b"IDK_S signing test message"; + + let key_pair = derive_identity_signing_key_pair_with(|context, output| { + identity_signing_key_kdf(&prk, KDFParams { context, output }) + }) + .unwrap(); + let signing_key = SigningKey::from(&key_pair.secret_key); + let verifying_key = VerifyingKey::from_sec1_bytes(&key_pair.public_key).unwrap(); + + let signature: Signature = signing_key.sign(message); + + verifying_key.verify(message, &signature).unwrap(); + } +} From 294c6cb0a351f420e9697c69adeac24974d54763 Mon Sep 17 00:00:00 2001 From: Sangho Lee Date: Tue, 5 May 2026 03:37:04 +0000 Subject: [PATCH 2/3] drop hkdf --- Cargo.lock | 10 ---------- litebox_platform_lvbs/Cargo.toml | 1 - litebox_platform_lvbs/src/mshv/vsm.rs | 15 ++++++++++----- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 019d7cb0f..efca04697 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1091,15 +1091,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - [[package]] name = "hmac" version = "0.12.1" @@ -1645,7 +1636,6 @@ dependencies = [ "digest", "elf", "hashbrown", - "hkdf", "libc", "litebox", "litebox_common_linux", diff --git a/litebox_platform_lvbs/Cargo.toml b/litebox_platform_lvbs/Cargo.toml index b64e4441d..afd7ee0e3 100644 --- a/litebox_platform_lvbs/Cargo.toml +++ b/litebox_platform_lvbs/Cargo.toml @@ -33,7 +33,6 @@ aligned-vec = { version = "0.6.4", default-features = false } raw-cpuid = "11.6.0" zerocopy = { version = "0.8", default-features = false, features = ["derive"] } zeroize = { version = "1.8", default-features = false } -hkdf = { version = "0.12.4", default-features = false } p384 = { version = "0.13.1", default-features = false, features = ["arithmetic", "ecdsa"] } [target.'cfg(target_arch = "x86_64")'.dependencies] diff --git a/litebox_platform_lvbs/src/mshv/vsm.rs b/litebox_platform_lvbs/src/mshv/vsm.rs index 1ed711a38..6fcc455b6 100644 --- a/litebox_platform_lvbs/src/mshv/vsm.rs +++ b/litebox_platform_lvbs/src/mshv/vsm.rs @@ -48,12 +48,11 @@ use core::{ sync::atomic::{AtomicBool, AtomicI64, Ordering}, }; use hashbrown::HashMap; -use hkdf::Hkdf; use litebox::platform::{DerivedKeyError, DerivedKeyProvider, KDFParams}; use litebox::utils::TruncateExt; use litebox_common_linux::errno::Errno; use p384::elliptic_curve::sec1::ToEncodedPoint; -use sha2::Sha384; +use sha2::{Digest, Sha384}; use spin::Once; use thiserror::Error; use x86_64::{ @@ -1019,9 +1018,15 @@ fn derive_identity_signing_key_pair_with( } fn identity_signing_key_kdf(root_key: &[u8], params: KDFParams<'_>) -> Result<(), VsmError> { - Hkdf::::new(None, root_key) - .expand(params.context, params.output) - .map_err(|_| VsmError::IdentitySigningKeyGenerationFailed) + let digest = Sha384::new() + .chain_update(root_key) + .chain_update(params.context) + .finalize(); + if params.output.len() != digest.len() { + return Err(VsmError::IdentitySigningKeyGenerationFailed); + } + params.output.copy_from_slice(&digest); + Ok(()) } /// VSM function dispatcher From 8cabb643cbb22e4ba5456d07b960fdaed130129d Mon Sep 17 00:00:00 2001 From: Sangho Lee Date: Tue, 5 May 2026 15:29:44 +0000 Subject: [PATCH 3/3] fix comments --- litebox_platform_lvbs/src/host/lvbs_impl.rs | 4 ++-- litebox_platform_lvbs/src/mshv/vsm.rs | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/litebox_platform_lvbs/src/host/lvbs_impl.rs b/litebox_platform_lvbs/src/host/lvbs_impl.rs index c0ca94861..3f859a59b 100644 --- a/litebox_platform_lvbs/src/host/lvbs_impl.rs +++ b/litebox_platform_lvbs/src/host/lvbs_impl.rs @@ -121,8 +121,8 @@ pub(crate) const PRK_LEN: usize = 32; static PRK_ONCE: spin::Once<[u8; PRK_LEN]> = spin::Once::new(); // Do not expose a raw PRK getter (i.e., no `get_platform_root_key`). -// Consumers should request derived key material through -// `DerivedKeyProvider` so PRK access stays centralized in this module. +// Consumers should provide key derivation function and context +// through `DerivedKeyProvider` so PRK access stays in this module. /// Sets the Platform Root Key (PRK) for this platform. /// diff --git a/litebox_platform_lvbs/src/mshv/vsm.rs b/litebox_platform_lvbs/src/mshv/vsm.rs index 6fcc455b6..dbb6640ed 100644 --- a/litebox_platform_lvbs/src/mshv/vsm.rs +++ b/litebox_platform_lvbs/src/mshv/vsm.rs @@ -935,9 +935,10 @@ fn mshv_vsm_set_platform_root_key(key_pa: u64) -> Result { } } -/// VSM function for generating the identity signing key pair (IDK_S). +/// This function generates an identity signing key pair (IDK_S) and returns the public +/// portion of it. /// -/// - `public_key_pa`: Physical address (VTL0) where the uncompressed SEC1 P-384 +/// - `public_key_pa`: Physical address (VTL0) where an uncompressed SEC1 P-384 /// public key will be written. The corresponding private key is derived from the PRK /// and never leaves VTL1. ///