// SPDX-License-Identifier: Apache-2.0 #![cfg(all(feature = "openssl", feature = "snp", target_os = "linux"))] use std::{ convert::{TryFrom, TryInto}, fs, io::Read, path::PathBuf, }; use base64::{engine::general_purpose, Engine as _}; use hex::{self, FromHex}; use sev::measurement::{ idblock::{load_priv_key, snp_calculate_id}, idblock_types::{IdAuth, SevEcdsaPubKey, SevEcdsaSig}, snp::SnpLaunchDigest, }; // Testing that the appropriate id-block and key digests are being generated. #[test] fn test_id_block_and_key_digests() { // Expected ID-BLOCk, ID-KEY digest and AUTH-KEY digest let expected_id_block = "oU1jg0HlZ0Yo/h4C++3r5eWrT68d1y2JZgaOYVu5nv0T0hSzXCMXFbOOJj3GBZdFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAwAAAAAA".to_string(); let expected_id_key_digest = "WfssaG36T+9J84M5qndckAUcKNVzg93DuvO160sUlt87DbvcuuX+J2d6ZEggdz/i".to_string(); let expected_auth_key_digest = "7tgRafsMteDsNHlPEo/U4MSkb2fGWhrfqB/LJLzAiMJyNpt//D6ytq9qQoShs2xf".to_string(); // Pre-generated launch digest let launch_digest = Vec::from_hex("a14d638341e5674628fe1e02fbedebe5e5ab4faf1dd72d8966068e615bb99efd13d214b35c231715b38e263dc6059745").unwrap(); let id_launch_digest: SnpLaunchDigest = SnpLaunchDigest::new(launch_digest.try_into().unwrap()); // Generating ID-block and key digests let block_calculations = snp_calculate_id( Some(id_launch_digest), None, None, None, None, "./tests/measurement/test_id_key.pem".into(), "./tests/measurement/test_auth_key.pem".into(), ) .unwrap(); // Converting ID-block and key digests into BASE64 let id_block_string = general_purpose::STANDARD.encode(bincode::serialize(&block_calculations.id_block).unwrap()); let id_key_digest_string = general_purpose::STANDARD .encode::>(block_calculations.id_key_digest.try_into().unwrap()); let auth_key_digest_string = general_purpose::STANDARD .encode::>(block_calculations.auth_key_digest.try_into().unwrap()); // Comparing results assert_eq!(id_block_string, expected_id_block); assert_eq!(id_key_digest_string, expected_id_key_digest); assert_eq!(auth_key_digest_string, expected_auth_key_digest); } /// Using private test keys and a pre-generated signatures, the application should always generate the same AUTH-BLOCK. #[test] fn test_auth_block_generation() { // Expected AUTH-BLOCK let expected_auth_block = "AQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAOXTv32b+eBhvU6PfGrK4FkJqcPGnwTzGPATXq5x/30F71yMaxvIwEdhOntvAbc42gAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAANQZTcpn3oOB7G0mfAMrA908H16vpqph6Slk5VSL7zMrGukh8m3hasM7ZCdE0Zel2AAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAB9tPIC4+57yn/fdR+jeP8uV3ZBDh2ixkyxVIzwMR131TMq4yC\ wv8iwbzwkmTT529gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD6+k5w4NQsIzZvaUDyFOA39fGAS9xlmdnsyFMveqDetHW2+C\ hmxUMfBzblH0KjXzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7iHuUVX9Whon/SFXD9+2ZgQw9VOz\ UKWURNNwY3QIOyqdxo0y5dmZ3GqMfDrRi6pkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyYei5XacbKjVCX0iiGad9uw/uJS\ 9k0YzpmIi5+09wsQQBG33+o+A0k3Giv69vkTMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACMhkXa\ 1XNJo8X/xsGl90pWnw+DPAeLsizXlHTw/pLOcWpzmFuimWIz0UyQ1ovHcGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1rId\ x4JERA8nyov5IQ3cZKsyziMw6/bdZtVY+zQiTX6niAoEIEHqnSITJojB5PIYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" .to_string(); // Test keys in pem format let id_path: PathBuf = "./tests/measurement/test_id_key.pem".into(); let auth_path: PathBuf = "./tests/measurement/test_auth_key.pem".into(); // Get id private test key from pem let id_ec_priv_key = load_priv_key(id_path).unwrap(); // Generate id public key, should always be the same let id_ec_pub_key = SevEcdsaPubKey::try_from(&id_ec_priv_key).unwrap(); // Get id signature from file (can't regenerate, different each time) let mut id_sig_file = fs::File::open("./tests/measurement/test_id_sig.bin").unwrap(); let mut id_block_bytes = Vec::new(); id_sig_file.read_to_end(&mut id_block_bytes).unwrap(); let id_block_sig: SevEcdsaSig = bincode::deserialize(&id_block_bytes).unwrap(); // Get author private test key from pem let author_ec_priv_key = load_priv_key(auth_path).unwrap(); // Generate author public key, should always be the same let author_pub_key = SevEcdsaPubKey::try_from(&author_ec_priv_key).unwrap(); // Get auth signature from file (can't regenerate, different each time) let mut auth_sig_file = fs::File::open("./tests/measurement/test_auth_sig.bin").unwrap(); let mut auth_block_bytes = Vec::new(); auth_sig_file.read_to_end(&mut auth_block_bytes).unwrap(); let auth_block_sig: SevEcdsaSig = bincode::deserialize(&auth_block_bytes).unwrap(); let auth_block = IdAuth::new( None, None, id_block_sig, id_ec_pub_key, auth_block_sig, author_pub_key, ); // Generate Generate auth_block string let id_auth_bytes = bincode::serialize(&auth_block).unwrap(); let id_auth_str = general_purpose::STANDARD.encode(id_auth_bytes); // Comparing auth_blocks assert_eq!(id_auth_str, expected_auth_block); }