Skip to content

Commit 6376e36

Browse files
committed
attest: add unit tests for pre-boot attestation
Add unit tests for the hash() function used during pre-boot attestation negotiation. hash() feeds NegotiationParams into SHA-512 in the order dictated by the server's NegotiationResponse. Because the server controls which params contribute and in what sequence, ordering sensitivity is a security property: different orderings must produce different digests. Tests cover: - Challenge-first and EcPublicKeyBytes-first orderings, verified against a manually computed SHA-512 reference. - That swapping the param order produces a distinct digest. Signed-off-by: Nihal <nihalxkumar@protonmail.com>
1 parent 558b7c2 commit 6376e36

1 file changed

Lines changed: 107 additions & 0 deletions

File tree

kernel/src/attest.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,110 @@ fn hash(
355355

356356
try_to_vec(&sha.finalize()).or(Err(AttestationError::VecAlloc))
357357
}
358+
359+
#[cfg(test)]
360+
mod tests {
361+
use super::*;
362+
use alloc::vec;
363+
use cocoon_tpm_tpm2_interface::{Tpm2bEccParameter, TpmBuffer};
364+
365+
fn make_ecc_point(x: &[u8], y: &[u8]) -> TpmsEccPoint<'static> {
366+
TpmsEccPoint {
367+
x: Tpm2bEccParameter {
368+
buffer: TpmBuffer::Owned(x.to_vec()),
369+
},
370+
y: Tpm2bEccParameter {
371+
buffer: TpmBuffer::Owned(y.to_vec()),
372+
},
373+
}
374+
}
375+
376+
mod negotiation_hash {
377+
use super::*;
378+
379+
/// hash() feeds NegotiationParams into SHA-512 in the order they
380+
/// appear in `response.params`. The ordering matters because
381+
/// the server dictates which fields contribute to the attestation
382+
/// hash and in what order. These two tests verify that
383+
/// [Challenge, EcPublicKeyBytes] and [EcPublicKeyBytes, Challenge]
384+
/// produce different digests, therefore confirming the function
385+
/// respects the param ordering from the negotiation response.
386+
#[test]
387+
fn challenge_then_ec_key() {
388+
let challenge = vec![0xdd; 48];
389+
let x = vec![0x10; 66];
390+
let y = vec![0x20; 66];
391+
let response = NegotiationResponse {
392+
challenge: challenge.clone(),
393+
params: vec![
394+
NegotiationParam::Challenge,
395+
NegotiationParam::EcPublicKeyBytes,
396+
],
397+
};
398+
let pub_key = make_ecc_point(&x, &y);
399+
400+
let result = hash(&response, &pub_key).unwrap();
401+
402+
let mut sha = Sha512::new();
403+
sha.update(&challenge);
404+
sha.update(&x);
405+
sha.update(&y);
406+
let expected = sha.finalize();
407+
assert_eq!(result, expected.as_slice());
408+
}
409+
410+
#[test]
411+
fn ec_key_then_challenge() {
412+
let challenge = vec![0xee; 24];
413+
let x = vec![0x30; 10];
414+
let y = vec![0x40; 10];
415+
let response = NegotiationResponse {
416+
challenge: challenge.clone(),
417+
params: vec![
418+
NegotiationParam::EcPublicKeyBytes,
419+
NegotiationParam::Challenge,
420+
],
421+
};
422+
let pub_key = make_ecc_point(&x, &y);
423+
424+
let result = hash(&response, &pub_key).unwrap();
425+
426+
let mut sha = Sha512::new();
427+
sha.update(&x);
428+
sha.update(&y);
429+
sha.update(&challenge);
430+
let expected = sha.finalize();
431+
assert_eq!(result, expected.as_slice());
432+
}
433+
434+
/// Changing the param order must change the hash. This is a
435+
/// security property: if the server negotiates a different param
436+
/// list, the resulting attestation evidence must differ.
437+
#[test]
438+
fn different_order_produces_different_hash() {
439+
let challenge = vec![0x42; 32];
440+
let x = vec![0x01; 10];
441+
let y = vec![0x02; 10];
442+
let pub_key = make_ecc_point(&x, &y);
443+
444+
let response_chal_first = NegotiationResponse {
445+
challenge: challenge.clone(),
446+
params: vec![
447+
NegotiationParam::Challenge,
448+
NegotiationParam::EcPublicKeyBytes,
449+
],
450+
};
451+
let response_key_first = NegotiationResponse {
452+
challenge: challenge.clone(),
453+
params: vec![
454+
NegotiationParam::EcPublicKeyBytes,
455+
NegotiationParam::Challenge,
456+
],
457+
};
458+
459+
let hash1 = hash(&response_chal_first, &pub_key).unwrap();
460+
let hash2 = hash(&response_key_first, &pub_key).unwrap();
461+
assert_ne!(hash1, hash2);
462+
}
463+
}
464+
}

0 commit comments

Comments
 (0)