sev 7.1.0

Library for AMD SEV
Documentation
// SPDX-License-Identifier: Apache-2.0

#![cfg(all(feature = "openssl", feature = "snp", target_os = "linux"))]

use std::{
    convert::{TryFrom, TryInto},
    fs,
    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,
    },
    parser::{ByteParser, Decoder},
};

// 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(block_calculations.id_block.to_bytes().unwrap());
    let id_key_digest_string =
        general_purpose::STANDARD.encode(block_calculations.id_key_digest.to_bytes().unwrap());
    let auth_key_digest_string =
        general_purpose::STANDARD.encode(block_calculations.auth_key_digest.to_bytes().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 id_block_sig = SevEcdsaSig::decode(&mut id_sig_file, ()).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 auth_block_sig = SevEcdsaSig::decode(&mut auth_sig_file, ()).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 = auth_block.to_bytes().unwrap();
    let id_auth_str = general_purpose::STANDARD.encode(id_auth_bytes);

    // Comparing auth_blocks
    assert_eq!(id_auth_str, expected_auth_block);
}