-
Notifications
You must be signed in to change notification settings - Fork 138
Combine PRK and IDK_S generation VTL calls #1130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,7 +13,7 @@ use litebox::{ | |
| utils::{ReinterpretSignedExt, TruncateExt}, | ||
| }; | ||
| use litebox_common_linux::errno::Errno; | ||
| use litebox_common_lvbs::{NUM_VTLCALL_PARAMS, VsmError, VsmFunction}; | ||
| use litebox_common_lvbs::{NUM_VTLCALL_PARAMS, PRK_LEN, VsmError, VsmFunction}; | ||
| use litebox_common_optee::{ | ||
| OpteeMessageCommand, OpteeMsgArgs, OpteeRpcArgs, OpteeSmcArgs, OpteeSmcResult, | ||
| OpteeSmcReturnCode, TeeOrigin, TeeResult, UteeEntryFunc, UteeParams, optee_msg_args_total_size, | ||
|
|
@@ -256,10 +256,24 @@ fn vtlcall_dispatch(params: &[u64; NUM_VTLCALL_PARAMS]) -> i64 { | |
| let smc_args_pfn = params[1]; | ||
| optee_smc_handler_entry(smc_args_pfn) | ||
| } | ||
| VsmFunction::GenerateIdentitySigningKey => { | ||
| let public_key_pa = params[1]; | ||
| let key_alg = params[2]; | ||
| litebox_shim_optee::idk::generate_identity_signing_key(public_key_pa, key_alg) | ||
| VsmFunction::SetPlatformRootKeyAndGenerateIdentitySigningKey => { | ||
| let tpm_random_pa = params[1]; | ||
| let public_key_pa = params[2]; | ||
| let key_alg = params[3]; | ||
|
|
||
| let return_code = vsm_dispatch( | ||
| VsmFunction::SetPlatformRootKeyAndGenerateIdentitySigningKey, | ||
| ¶ms[1..2], | ||
| ); | ||
| if return_code < 0 { | ||
| return return_code; | ||
| } | ||
|
|
||
| litebox_shim_optee::idk::generate_identity_signing_key( | ||
| tpm_random_pa + PRK_LEN as u64, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looks like this is a concatenation of two data: PRK || seed ? then, something like prk_and_seed might be better. |
||
| public_key_pa, | ||
| key_alg, | ||
| ) | ||
| } | ||
| _ => vsm_dispatch(func_id, ¶ms[1..]), | ||
| } | ||
|
|
@@ -310,9 +324,8 @@ fn vsm_dispatch(func_id: VsmFunction, params: &[u64]) -> i64 { | |
| VsmFunction::AllocateRingbufferMemory => { | ||
| heki.allocate_ringbuffer_memory(params[0], params[1]) | ||
| } | ||
| VsmFunction::SetPlatformRootKey => vtl1.set_platform_root_key(params[0]).map(|()| 0), | ||
| VsmFunction::GenerateIdentitySigningKey => { | ||
| Err(VsmError::OperationNotSupported("Identity key generation")) | ||
| VsmFunction::SetPlatformRootKeyAndGenerateIdentitySigningKey => { | ||
| vtl1.set_platform_root_key(params[0]).map(|()| 0) | ||
| } | ||
| VsmFunction::OpteeMessage => Err(VsmError::OperationNotSupported("OP-TEE communication")), | ||
| }; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT license. | ||
|
|
||
| use crate::NormalWorldMutPtr; | ||
| use crate::{NormalWorldConstPtr, NormalWorldMutPtr}; | ||
| use litebox::{mm::linux::PAGE_SIZE, platform::CrngProvider, utils::TruncateExt}; | ||
| use litebox_common_linux::errno::Errno; | ||
| use num_enum::TryFromPrimitive; | ||
|
|
@@ -11,6 +11,7 @@ use zeroize::Zeroizing; | |
|
|
||
| const IDENTITY_SIGNING_PRIVATE_KEY_LEN: usize = 48; | ||
| const IDENTITY_SIGNING_PUBLIC_KEY_LEN: usize = 97; | ||
| const TPM_IDKS_RANDOM_LEN: usize = 32; | ||
| const KEY_ALGORITHM_MASK: u64 = 0xff00; | ||
| const KEY_VARIANT_MASK: u64 = 0xff; | ||
| const KEY_ALGORITHM_VALUE_MASK: u64 = KEY_ALGORITHM_MASK | KEY_VARIANT_MASK; | ||
|
|
@@ -40,8 +41,8 @@ enum EcdsaCurve { | |
| P521 = 0x03, | ||
| } | ||
|
|
||
| pub fn generate_identity_signing_key(public_key_pa: u64, key_alg: u64) -> i64 { | ||
| match generate_identity_signing_key_inner(public_key_pa, key_alg) { | ||
| pub fn generate_identity_signing_key(tpm_random_pa: u64, public_key_pa: u64, key_alg: u64) -> i64 { | ||
| match generate_identity_signing_key_inner(tpm_random_pa, public_key_pa, key_alg) { | ||
| Ok(res) => res, | ||
| Err(e) => e.as_neg().into(), | ||
| } | ||
|
|
@@ -61,16 +62,30 @@ pub fn generate_identity_signing_key(public_key_pa: u64, key_alg: u64) -> i64 { | |
| /// 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`. | ||
| fn generate_identity_signing_key_inner(public_key_pa: u64, key_alg: u64) -> Result<i64, Errno> { | ||
| fn generate_identity_signing_key_inner( | ||
| tpm_random_pa: u64, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I got confused here because it looks like |
||
| public_key_pa: u64, | ||
| key_alg: u64, | ||
| ) -> Result<i64, Errno> { | ||
| validate_key_algorithm(key_alg)?; | ||
|
|
||
| let tpm_random_ptr = NormalWorldConstPtr::<u8, PAGE_SIZE>::with_contiguous_pages( | ||
| tpm_random_pa.trunc(), | ||
| TPM_IDKS_RANDOM_LEN, | ||
| ) | ||
| .map_err(|_| Errno::EINVAL)?; | ||
| let mut tpm_random = [0u8; TPM_IDKS_RANDOM_LEN]; | ||
| tpm_random_ptr | ||
| .read_slice_at_offset(0, &mut tpm_random) | ||
| .map_err(|_| Errno::EFAULT)?; | ||
|
|
||
| let pubkey_ptr = | ||
| NormalWorldMutPtr::<[u8; IDENTITY_SIGNING_PUBLIC_KEY_LEN], PAGE_SIZE>::with_usize( | ||
| public_key_pa.trunc(), | ||
| ) | ||
| .map_err(|_| Errno::EINVAL)?; | ||
|
|
||
| let key_pair = get_identity_signing_key_pair()?; | ||
| let key_pair = get_identity_signing_key_pair(Some(&tpm_random))?; | ||
| pubkey_ptr | ||
| .write_at_offset(0, key_pair.public_key) | ||
| .map_err(|_| Errno::EFAULT)?; | ||
|
|
@@ -100,9 +115,11 @@ fn validate_key_algorithm(key_alg: u64) -> Result<(), Errno> { | |
| } | ||
| } | ||
|
|
||
| fn get_identity_signing_key_pair() -> Result<&'static IdentitySigningKeyPair, Errno> { | ||
| fn get_identity_signing_key_pair( | ||
| tpm_random: Option<&[u8; TPM_IDKS_RANDOM_LEN]>, | ||
| ) -> Result<&'static IdentitySigningKeyPair, Errno> { | ||
| IDENTITY_SIGNING_KEY_PAIR.try_call_once(|| { | ||
| let private_key = generate_identity_signing_private_key()?; | ||
| let private_key = generate_identity_signing_private_key(tpm_random)?; | ||
| let public_key = identity_signing_public_key_from_private_key(&private_key)?; | ||
| Ok(IdentitySigningKeyPair { | ||
| private_key, | ||
|
|
@@ -111,12 +128,14 @@ fn get_identity_signing_key_pair() -> Result<&'static IdentitySigningKeyPair, Er | |
| }) | ||
| } | ||
|
|
||
| fn generate_identity_signing_private_key() | ||
| -> Result<Zeroizing<[u8; IDENTITY_SIGNING_PRIVATE_KEY_LEN]>, Errno> { | ||
| fn generate_identity_signing_private_key( | ||
| tpm_random: Option<&[u8; TPM_IDKS_RANDOM_LEN]>, | ||
| ) -> Result<Zeroizing<[u8; IDENTITY_SIGNING_PRIVATE_KEY_LEN]>, Errno> { | ||
| let mut private_key_bytes = Zeroizing::new([0u8; IDENTITY_SIGNING_PRIVATE_KEY_LEN]); | ||
|
|
||
| for _ in 0..MAX_KEYGEN_ATTEMPT { | ||
| litebox_platform_multiplex::platform().fill_bytes_crng(&mut *private_key_bytes); | ||
| litebox_platform_multiplex::platform() | ||
| .fill_bytes_crng(&mut *private_key_bytes, tpm_random.map(|r| &r[..])); | ||
| if is_valid_identity_signing_private_key(&private_key_bytes) { | ||
| return Ok(private_key_bytes); | ||
| } | ||
|
|
@@ -160,7 +179,7 @@ mod tests { | |
| let message = b"IDK_S signing test message"; | ||
|
|
||
| let _task = init_platform(); | ||
| let private_key = generate_identity_signing_private_key().unwrap(); | ||
| let private_key = generate_identity_signing_private_key(None).unwrap(); | ||
| assert!(is_valid_identity_signing_private_key(&private_key)); | ||
| let signing_key = SigningKey::from_slice(&private_key[..]).unwrap(); | ||
| let public_key = identity_signing_public_key_from_private_key(&private_key).unwrap(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nits: Is this the address of an RNG seed? Technically, LiteBox doesn't know or doesn't care whether this is from TPM or not (e.g., could be from Pluton, HSM, ...). A generic name might be better (e.g., trusted seed, ...)