[dice] Accept different hash sizes for VM DICE chain
Bug: 395551194
Bug: 400346224
Test: atest libservice_vm_requests.test
Change-Id: Ic2747aeb05008ff66b5ed03844e56c1be1b91ad6
diff --git a/libs/libservice_vm_requests/src/client_vm.rs b/libs/libservice_vm_requests/src/client_vm.rs
index 4e54510..8ad10fd 100644
--- a/libs/libservice_vm_requests/src/client_vm.rs
+++ b/libs/libservice_vm_requests/src/client_vm.rs
@@ -25,7 +25,7 @@
use core::result;
use coset::{AsCborValue, CborSerializable, CoseSign, CoseSign1};
use der::{Decode, Encode};
-use diced_open_dice::{DiceArtifacts, HASH_SIZE};
+use diced_open_dice::DiceArtifacts;
use log::{debug, error, info};
use microdroid_kernel_hashes::{HASH_SIZE as KERNEL_HASH_SIZE, OS_HASHES};
use service_vm_comm::{ClientVmAttestationParams, Csr, CsrPayload, RequestProcessingError};
@@ -252,7 +252,7 @@
Ok(false)
}
-fn expected_kernel_authority_hash(service_vm_entry: &Value) -> Result<[u8; HASH_SIZE]> {
+fn expected_kernel_authority_hash(service_vm_entry: &Value) -> Result<Vec<u8>> {
let cose_sign1 = CoseSign1::from_cbor_value(service_vm_entry.clone())?;
let payload = cose_sign1.payload.ok_or_else(|| {
error!("No payload found in the service VM DICE chain entry");
diff --git a/libs/libservice_vm_requests/src/dice.rs b/libs/libservice_vm_requests/src/dice.rs
index ef9d894..ba67450 100644
--- a/libs/libservice_vm_requests/src/dice.rs
+++ b/libs/libservice_vm_requests/src/dice.rs
@@ -19,8 +19,8 @@
use alloc::vec::Vec;
use bssl_avf::{ed25519_verify, Digester, EcKey};
use cbor_util::{
- cbor_value_type, get_label_value, get_label_value_as_bytes, value_to_array,
- value_to_byte_array, value_to_bytes, value_to_map, value_to_num, value_to_text,
+ cbor_value_type, get_label_value, get_label_value_as_bytes, value_to_array, value_to_bytes,
+ value_to_map, value_to_num, value_to_text,
};
use ciborium::value::Value;
use core::cell::OnceCell;
@@ -31,7 +31,7 @@
Algorithm, AsCborValue, CborSerializable, CoseError, CoseKey, CoseSign1, KeyOperation, KeyType,
Label,
};
-use diced_open_dice::{DiceMode, HASH_SIZE};
+use diced_open_dice::DiceMode;
use log::{debug, error, info};
use service_vm_comm::RequestProcessingError;
@@ -288,8 +288,8 @@
pub(crate) struct DiceChainEntryPayload {
pub(crate) subject_public_key: PublicKey,
mode: DiceMode,
- pub(crate) code_hash: [u8; HASH_SIZE],
- pub(crate) authority_hash: [u8; HASH_SIZE],
+ pub(crate) code_hash: Vec<u8>,
+ pub(crate) authority_hash: Vec<u8>,
config_descriptor: ConfigDescriptor,
}
@@ -327,12 +327,12 @@
}
MODE => builder.mode(to_mode(value)?)?,
CODE_HASH => {
- let code_hash = value_to_byte_array(value, "DiceChainEntryPayload code_hash")?;
+ let code_hash = value_to_bytes(value, "DiceChainEntryPayload code_hash")?;
builder.code_hash(code_hash)?;
}
AUTHORITY_HASH => {
let authority_hash =
- value_to_byte_array(value, "DiceChainEntryPayload authority_hash")?;
+ value_to_bytes(value, "DiceChainEntryPayload authority_hash")?;
builder.authority_hash(authority_hash)?;
}
CONFIG_DESC => {
@@ -524,8 +524,8 @@
struct PayloadBuilder {
subject_public_key: OnceCell<PublicKey>,
mode: OnceCell<DiceMode>,
- code_hash: OnceCell<[u8; HASH_SIZE]>,
- authority_hash: OnceCell<[u8; HASH_SIZE]>,
+ code_hash: OnceCell<Vec<u8>>,
+ authority_hash: OnceCell<Vec<u8>>,
config_descriptor: OnceCell<ConfigDescriptor>,
}
@@ -552,11 +552,11 @@
set_once(&self.mode, mode, "mode")
}
- fn code_hash(&mut self, code_hash: [u8; HASH_SIZE]) -> Result<()> {
+ fn code_hash(&mut self, code_hash: Vec<u8>) -> Result<()> {
set_once(&self.code_hash, code_hash, "code_hash")
}
- fn authority_hash(&mut self, authority_hash: [u8; HASH_SIZE]) -> Result<()> {
+ fn authority_hash(&mut self, authority_hash: Vec<u8>) -> Result<()> {
set_once(&self.authority_hash, authority_hash, "authority_hash")
}
@@ -570,7 +570,9 @@
// the Open Profile for DICE spec.
let mode = self.mode.take().unwrap_or(DiceMode::kDiceModeNotInitialized);
let code_hash = take_value(&mut self.code_hash, "code_hash")?;
+ validate_hash_size(code_hash.len(), "code_hash")?;
let authority_hash = take_value(&mut self.authority_hash, "authority_hash")?;
+ validate_hash_size(authority_hash.len(), "authority_hash")?;
let config_descriptor = take_value(&mut self.config_descriptor, "config_descriptor")?;
Ok(DiceChainEntryPayload {
subject_public_key,
@@ -581,3 +583,18 @@
})
}
}
+
+fn validate_hash_size(len: usize, name: &str) -> Result<()> {
+ // According to the Android Profile for DICE specification, SHA-256, SHA-384, and SHA-512
+ // are all acceptable hash algorithms.
+ const ACCEPTABLE_HASH_SIZES: [usize; 3] = [32, 48, 64];
+ if ACCEPTABLE_HASH_SIZES.contains(&len) {
+ Ok(())
+ } else {
+ error!(
+ "Invalid hash size for {}: {}. Acceptable hash sizes are: {:?}",
+ name, len, ACCEPTABLE_HASH_SIZES
+ );
+ Err(RequestProcessingError::InvalidDiceChain)
+ }
+}