Skip to content

Commit 0e1a0d9

Browse files
committed
optimize TAP decoding and verification
Signed-off-by: Wojciech Ozga <woz@zurich.ibm.com>
1 parent 9214ff3 commit 0e1a0d9

5 files changed

Lines changed: 146 additions & 49 deletions

File tree

confidential-vms/linux_vm/hypervisor_rootfs/run_linux_vm_qemu.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ TAP=/root/linux_vm/cove_tap_qemu
1212
HOST_PORT="$((3000 + RANDOM % 3000))"
1313
INTERACTIVE="-nographic"
1414
SMP=2
15-
MEMORY=2G
15+
MEMORY=1G
1616

1717
for i in "$@"; do
1818
case $i in

security-monitor/rust-crates/riscv_cove_tap/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ pub use parser::AttestationPayloadParser;
1717
#[cfg(feature = "serializer")]
1818
pub use serializer::AttestationPayloadSerializer;
1919

20+
#[macro_export]
21+
macro_rules! ensure {
22+
($cond:expr, $error:expr) => {
23+
if !$cond {
24+
Err($error)
25+
} else {
26+
Ok(())
27+
}
28+
};
29+
}
30+
2031
pub use spec::*;
2132
pub use error::*;
2233
pub mod spec;

security-monitor/rust-crates/riscv_cove_tap/src/parser.rs

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub use crate::error::TapError;
55
use alloc::vec::Vec;
66
use crate::spec::*;
77
use alloc::vec;
8+
use crate::ensure;
89

910
pub struct AttestationPayloadParser {
1011
pub pointer: *const u8,
@@ -13,23 +14,17 @@ pub struct AttestationPayloadParser {
1314

1415
impl AttestationPayloadParser {
1516
pub fn from_raw_pointer(pointer: *const u8, size: usize) -> Result<Self, TapError> {
16-
Ok(Self {
17-
pointer, size
18-
})
17+
Ok(Self { pointer, size })
1918
}
2019

21-
pub fn parse_and_verify(&mut self, decapsulation_key: &Vec<u8>) -> Result<AttestationPayload, TapError> {
22-
if self.read_u32()? != ACE_MAGIC_TAP_START {
23-
return Err(TapError::InvalidMagicStart());
24-
}
20+
pub fn parse_and_verify(&mut self, decapsulation_key: &[u8]) -> Result<AttestationPayload, TapError> {
21+
ensure!(self.read_u32()? == ACE_MAGIC_TAP_START, TapError::InvalidMagicStart())?;
2522
self.read_u16()?;
2623
// if self.read_u16()? as usize != self.size {
2724
// return Err(TapError::InvalidSize());
2825
// }
2926
let number_of_lockboxes = self.read_u16()?;
30-
if usize::from(number_of_lockboxes) > MAX_NUMBER_OF_LOCKBOXES {
31-
return Err(TapError::InvalidSize());
32-
}
27+
ensure!(usize::from(number_of_lockboxes) <= MAX_NUMBER_OF_LOCKBOXES, TapError::InvalidSize())?;
3328

3429
let mut symmetric_key = vec![];
3530
for _ in 0..number_of_lockboxes {
@@ -44,20 +39,10 @@ impl AttestationPayloadParser {
4439
let tag_size = self.read_u16()? as usize;
4540
let tag = self.read_exact(tag_size)?;
4641
let tsk_size = self.read_u16()? as usize;
47-
let tsk = self.read_exact(tsk_size)?;
48-
match algorithm.decode(decapsulation_key, esk, nonce, tag, tsk) {
49-
Ok(mut tsk) => {
50-
symmetric_key.append(&mut tsk);
51-
break;
52-
}
53-
Err(e) => {
54-
return Err(e)
55-
}
56-
};
57-
}
58-
if symmetric_key.is_empty() {
59-
return Err(TapError::NoLockboxFound());
42+
symmetric_key = self.read_exact(tsk_size)?;
43+
algorithm.decode(decapsulation_key, &esk, &nonce, &tag, &mut symmetric_key)?;
6044
}
45+
ensure!(!symmetric_key.is_empty(), TapError::NoLockboxFound())?;
6146

6247
let payload_encryption_algorithm = PayloadEncryptionAlgorithm::from_u16(self.read_u16()?)?;
6348
match payload_encryption_algorithm {
@@ -66,9 +51,10 @@ impl AttestationPayloadParser {
6651
}
6752

6853
let number_of_digests = self.read_u16()?;
69-
let mut digests = vec![];
54+
let mut digests = Vec::with_capacity(number_of_digests.into());
7055
for _ in 0..number_of_digests {
7156
let size = self.read_u16()? as usize;
57+
ensure!(size >= 4, TapError::InvalidSize())?;
7258
let pcr_id = self.read_u16()?;
7359
let algorithm = DigestAlgorithm::from_u16(self.read_u16()?)?;
7460
let value = self.read_exact(size-4)?;
@@ -83,18 +69,16 @@ impl AttestationPayloadParser {
8369
let mut secrets = vec![];
8470
for _ in 0..number_of_secrets {
8571
let size = self.read_u16()? as usize;
72+
ensure!(size >= 10, TapError::InvalidSize())?;
8673
let name = self.read_u64()? as u64;
8774
let value = self.read_exact(size-10)?;
8875
secrets.push(Secret { name, value });
8976
}
9077

91-
Ok(AttestationPayload {
92-
digests,
93-
secrets,
94-
})
78+
Ok(AttestationPayload { digests, secrets })
9579
}
9680

97-
fn decrypt_aes_gcm_256(&mut self, symmetric_key: &Vec<u8>) -> Result<(), TapError> {
81+
fn decrypt_aes_gcm_256(&mut self, symmetric_key: &[u8]) -> Result<(), TapError> {
9882
use aes_gcm::{AeadInPlace, Aes256Gcm, Key, KeyInit, Tag, Nonce};
9983

10084
let nonce_size = self.read_u16()? as usize;
@@ -103,10 +87,8 @@ impl AttestationPayloadParser {
10387
let tag = self.read_exact(tag_size)?;
10488
let payload_size = self.read_u16()? as usize;
10589

106-
if symmetric_key.len() != 32 {
107-
return Err(TapError::InvalidTskSize());
108-
}
109-
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(symmetric_key.as_slice()));
90+
ensure!(symmetric_key.len() == 32, TapError::InvalidTskSize())?;
91+
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(symmetric_key));
11092
let nonce = Nonce::from_slice(&nonce);
11193
let tag = Tag::from_slice(&tag);
11294
let mut data_slice = unsafe{ core::slice::from_raw_parts_mut(self.pointer as *mut u8, payload_size) };
@@ -133,7 +115,7 @@ impl AttestationPayloadParser {
133115
}
134116

135117
fn read_exact(&mut self, size: usize) -> Result<Vec<u8>, TapError> {
136-
let mut result = vec![];
118+
let mut result = Vec::with_capacity(size);
137119
for _ in 0..size {
138120
let value = unsafe { self.pointer.read_volatile() };
139121
self.pointer = self.pointer.wrapping_add(1);

security-monitor/rust-crates/riscv_cove_tap/src/spec.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,29 +88,27 @@ impl LockboxAlgorithm {
8888
}
8989

9090
#[cfg(feature = "parser")]
91-
pub fn decode(&self, decapsulation_key: &Vec<u8>, esk: Vec<u8>, nonce: Vec<u8>, tag: Vec<u8>, mut tsk: Vec<u8>) -> Result<Vec<u8>, TapError> {
91+
pub fn decode(&self, decapsulation_key: &[u8], esk: &[u8], nonce: &[u8], tag: &[u8], tsk: &mut Vec<u8>) -> Result<(), TapError> {
9292
match self {
9393
LockboxAlgorithm::Debug => {
94-
Ok(tsk)
94+
Ok(())
9595
},
9696
LockboxAlgorithm::MlKem1024Aes256 => {
9797
use aes_gcm::{AeadInPlace, Aes256Gcm, Key, KeyInit, Tag, Nonce};
9898
use hybrid_array::Array;
9999
use ml_kem::{MlKem1024, KemCore, MlKem1024Params, Encoded, EncodedSizeUser,kem::{Decapsulate, DecapsulationKey}};
100100

101-
let m = Array::try_from(esk.as_slice())?;
102-
let dk_bytes = Encoded::<DecapsulationKey::<MlKem1024Params>>::try_from(decapsulation_key.as_slice())?;
101+
let m = Array::try_from(esk)?;
102+
let dk_bytes = Encoded::<DecapsulationKey::<MlKem1024Params>>::try_from(decapsulation_key)?;
103103
let dk = <MlKem1024 as KemCore>::DecapsulationKey::from_bytes(&dk_bytes);
104104
let sk = match dk.decapsulate(&m) {
105105
Ok(v) => v,
106106
Err(_) => return Err(TapError::KemError())
107107
};
108108

109109
let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(sk.as_slice()));
110-
let nonce = Nonce::from_slice(&nonce);
111-
let tag = Tag::from_slice(&tag);
112-
cipher.decrypt_in_place_detached(nonce, b"", &mut tsk, &tag).unwrap();
113-
Ok(tsk)
110+
cipher.decrypt_in_place_detached(Nonce::from_slice(nonce), b"", tsk, &Tag::from_slice(tag)).unwrap();
111+
Ok(())
114112
}
115113
}
116114
}

0 commit comments

Comments
 (0)