sev.rs0.00%
1
// Copyright 2026 Google LLC2
//3
// Licensed under the Apache License, Version 2.0 (the "License");4
// you may not use this file except in compliance with the License.5
// You may obtain a copy of the License at6
//7
// https://www.apache.org/licenses/LICENSE-2.08
//9
// Unless required by applicable law or agreed to in writing, software10
// distributed under the License is distributed on an "AS IS" BASIS,11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12
// See the License for the specific language governing permissions and13
// limitations under the License.14
15
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};16
17
use crate::consts;18
use crate::firmware::ovmf::x86_64::{GUID_SIZE, parse_data};19
use crate::firmware::{Result, error};20
21
pub const GUID_SEV_ES_RESET_BLOCK: [u8; GUID_SIZE] = [22
0xde, 0x71, 0xf7, 0x00, 0x7e, 0x1a, 0xcb, 0x4f, 0x89, 0x0e, 0x68, 0xc7, 0x7e, 0x2f, 0xb4, 0x4e,23
];24
25
pub const GUID_SEV_METADATA: [u8; GUID_SIZE] = [26
0x66, 0x65, 0x88, 0xdc, 0x4a, 0x98, 0x98, 0x47, 0xA7, 0x5e, 0x55, 0x85, 0xa7, 0xbf, 0x67, 0xcc,27
];28
pub const SEV_SIGNATURE: u32 = u32::from_le_bytes(*b"ASEV");29
30
#[derive(Debug, KnownLayout, Immutable, FromBytes, IntoBytes)]31
#[repr(C)]32
pub struct SevMetaData {33
pub signature: u32,34
pub len: u32,35
pub version: u32,36
pub num_desc: u32,37
}38
39
consts! {40
#[derive(KnownLayout, Immutable, FromBytes, IntoBytes)]41
pub struct SevDescType(u32) {42
SNP_DESC_MEM = 1;43
SNP_SECRETS = 2;44
CPUID = 3;45
}46
}47
48
#[derive(Debug, KnownLayout, Immutable, FromBytes, IntoBytes)]49
#[repr(C)]50
pub struct SevMetadataDesc {51
pub base: u32,52
pub len: u32,53
pub type_: SevDescType,54
}55
56
#[repr(C)]57
#[derive(Debug, Clone, PartialEq, Eq, KnownLayout, Immutable, FromBytes, IntoBytes)]58
pub struct SnpCpuidFunc {59
pub eax_in: u32,60
pub ecx_in: u32,61
pub xcr0_in: u64,62
pub xss_in: u64,63
pub eax: u32,64
pub ebx: u32,65
pub ecx: u32,66
pub edx: u32,67
pub reserved: u64,68
}69
70
#[repr(C)]71
#[derive(Debug, Clone, KnownLayout, Immutable, FromBytes, IntoBytes)]72
pub struct SnpCpuidInfo {73
pub count: u32,74
pub _reserved1: u32,75
pub _reserved2: u64,76
pub entries: [SnpCpuidFunc; 64],77
}78
79
pub fn parse_sev_ap_eip(data: &[u8]) -> Result<u32> {80
let Some(ap_eip) = parse_data(data, &GUID_SEV_ES_RESET_BLOCK) else {81
return error::MissingMetadata {82
name: "SevEsResetBlock",83
}84
.fail();85
};86
let Ok(ap_eip) = u32::read_from_bytes(ap_eip) else {87
return error::InvalidLayout.fail();88
};89
Ok(ap_eip)90
}91
92
pub fn parse_desc(data: &[u8]) -> Result<&[SevMetadataDesc]> {93
let Some(offset_r) = parse_data(data, &GUID_SEV_METADATA) else {94
return error::MissingMetadata {95
name: "SevMetadata",96
}97
.fail();98
};99
let Ok(offset_r) = u32::read_from_bytes(offset_r) else {100
return error::InvalidLayout.fail();101
};102
let offset = data.len() - offset_r as usize;103
let Ok((metadata, remain)) = SevMetaData::ref_from_prefix(&data[offset..]) else {104
return error::InvalidLayout.fail();105
};106
if metadata.signature != SEV_SIGNATURE {107
return error::MissingAmdSevSignature {108
got: metadata.signature,109
}110
.fail();111
};112
let Ok((entries, _)) =113
<[SevMetadataDesc]>::ref_from_prefix_with_elems(remain, metadata.num_desc as usize)114
else {115
return error::InvalidLayout.fail();116
};117
Ok(entries)118
}119