Skip to content

Commit

Permalink
Merge branch 'kb/att_report' into 'master'
Browse files Browse the repository at this point in the history
feat(NODE-1139): Add chip_id to AddNodePayload during node registration

Chip_id is added to the AddNodePayload to be sent during node registration. This MR does these:
1. sevctl is a wrapper around sev library. It has been renamed to snptool to avoid confusion with virtee/sevctl which does not support SEV-SNP.
2. sev library is bumped to version 1.2.1 which supports the 6.1-snp kernel on ic-os.
3. Orchestrator calls the ic_icos_sev crate which relies on sev library to derive the chip_id.
4. Chip_id is now an optional field in the registry. 

Tested on dev-sev and dev targets. 

See merge request dfinity-lab/public/ic!15449
  • Loading branch information
khushboo-dfn committed Oct 27, 2023
2 parents c7ed3f9 + b99c3bd commit 8d77465
Show file tree
Hide file tree
Showing 41 changed files with 174 additions and 72 deletions.
2 changes: 1 addition & 1 deletion Cargo.Bazel.Fuzzing.json.lock
@@ -1,5 +1,5 @@
{
"checksum": "7576f905197c598c36ac08832711e09df68c426937e036249ed041bb9cab3e7e",
"checksum": "da244b91cf0bcee2fc2e8d01bd6b0a77a191023585c05505d0420e068ef38b9f",
"crates": {
"abnf 0.12.0": {
"name": "abnf",
Expand Down
16 changes: 8 additions & 8 deletions Cargo.Bazel.StaticOpenSSL.json.lock
@@ -1,5 +1,5 @@
{
"checksum": "c76d92d7ad673ee8aadd0c439326793f2143301066e6572adcd5f3643c2e7a44",
"checksum": "f5d289e5eff4cd04d46317c2ae6dbc677770d1a6719abcdf29d8b5b5d103ab75",
"crates": {
"abnf 0.12.0": {
"name": "abnf",
Expand Down Expand Up @@ -13955,7 +13955,7 @@
"target": "serial_test"
},
{
"id": "sev 1.2.0",
"id": "sev 1.2.1",
"target": "sev"
},
{
Expand Down Expand Up @@ -45383,13 +45383,13 @@
},
"license": "MIT/Apache-2.0"
},
"sev 1.2.0": {
"sev 1.2.1": {
"name": "sev",
"version": "1.2.0",
"version": "1.2.1",
"repository": {
"Http": {
"url": "https://crates.io/api/v1/crates/sev/1.2.0/download",
"sha256": "9c77eff933413b557ad3af20f6ddb198471d639d611b4738bcb78d32d7941892"
"url": "https://crates.io/api/v1/crates/sev/1.2.1/download",
"sha256": "7fd749a01c88a51ac718b59fe571177b31e478dfe059267977042477a0531224"
}
},
"targets": [
Expand Down Expand Up @@ -45477,7 +45477,7 @@
"target": "serde_bytes"
},
{
"id": "sev 1.2.0",
"id": "sev 1.2.1",
"target": "build_script_build"
},
{
Expand All @@ -45492,7 +45492,7 @@
"selects": {}
},
"edition": "2018",
"version": "1.2.0"
"version": "1.2.1"
},
"build_script_attrs": {
"data_glob": [
Expand Down
4 changes: 2 additions & 2 deletions Cargo.Bazel.StaticOpenSSL.toml.lock
Expand Up @@ -8786,9 +8786,9 @@ dependencies = [

[[package]]
name = "sev"
version = "1.2.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c77eff933413b557ad3af20f6ddb198471d639d611b4738bcb78d32d7941892"
checksum = "7fd749a01c88a51ac718b59fe571177b31e478dfe059267977042477a0531224"
dependencies = [
"bincode",
"bitfield",
Expand Down
16 changes: 8 additions & 8 deletions Cargo.Bazel.json.lock
@@ -1,5 +1,5 @@
{
"checksum": "c76d92d7ad673ee8aadd0c439326793f2143301066e6572adcd5f3643c2e7a44",
"checksum": "f5d289e5eff4cd04d46317c2ae6dbc677770d1a6719abcdf29d8b5b5d103ab75",
"crates": {
"abnf 0.12.0": {
"name": "abnf",
Expand Down Expand Up @@ -13955,7 +13955,7 @@
"target": "serial_test"
},
{
"id": "sev 1.2.0",
"id": "sev 1.2.1",
"target": "sev"
},
{
Expand Down Expand Up @@ -45383,13 +45383,13 @@
},
"license": "MIT/Apache-2.0"
},
"sev 1.2.0": {
"sev 1.2.1": {
"name": "sev",
"version": "1.2.0",
"version": "1.2.1",
"repository": {
"Http": {
"url": "https://crates.io/api/v1/crates/sev/1.2.0/download",
"sha256": "9c77eff933413b557ad3af20f6ddb198471d639d611b4738bcb78d32d7941892"
"url": "https://crates.io/api/v1/crates/sev/1.2.1/download",
"sha256": "7fd749a01c88a51ac718b59fe571177b31e478dfe059267977042477a0531224"
}
},
"targets": [
Expand Down Expand Up @@ -45477,7 +45477,7 @@
"target": "serde_bytes"
},
{
"id": "sev 1.2.0",
"id": "sev 1.2.1",
"target": "build_script_build"
},
{
Expand All @@ -45492,7 +45492,7 @@
"selects": {}
},
"edition": "2018",
"version": "1.2.0"
"version": "1.2.1"
},
"build_script_attrs": {
"data_glob": [
Expand Down
4 changes: 2 additions & 2 deletions Cargo.Bazel.toml.lock
Expand Up @@ -8786,9 +8786,9 @@ dependencies = [

[[package]]
name = "sev"
version = "1.2.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c77eff933413b557ad3af20f6ddb198471d639d611b4738bcb78d32d7941892"
checksum = "7fd749a01c88a51ac718b59fe571177b31e478dfe059267977042477a0531224"
dependencies = [
"bincode",
"bitfield",
Expand Down
20 changes: 11 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -129,7 +129,7 @@ members = [
"rs/ic_os/setupos-disable-checks",
"rs/ic_os/sev_interfaces",
"rs/ic_os/sev",
"rs/ic_os/sevctl",
"rs/ic_os/snptool",
"rs/ic_os/vsock/guest",
"rs/ic_os/vsock/host",
"rs/ic_os/vsock/vsock_lib",
Expand Down
2 changes: 1 addition & 1 deletion bazel/external_crates.bzl
Expand Up @@ -1006,7 +1006,7 @@ def external_crates_repository(name, static_openssl, cargo_lockfile, lockfile, s
version = "^0.8.0",
),
"sev": crate.spec(
version = "^1.2.0",
version = "^1.2.1",
features = [
"openssl",
],
Expand Down
2 changes: 1 addition & 1 deletion ic-os/guestos/defs.bzl
Expand Up @@ -40,7 +40,7 @@ def image_deps(mode, malicious = False):
"//publish/binaries:orchestrator": "/opt/ic/bin/orchestrator:0755",
("//publish/malicious:replica" if malicious else "//publish/binaries:replica"): "/opt/ic/bin/replica:0755", # Install the malicious replica if set
"//publish/binaries:sandbox_launcher": "/opt/ic/bin/sandbox_launcher:0755",
"//publish/binaries:sevctl": "/opt/ic/bin/sevctl:0755",
"//publish/binaries:snptool": "/opt/ic/bin/snptool:0755",
"@sevtool": "/opt/ic/bin/sevtool:0755",
"//publish/binaries:state-tool": "/opt/ic/bin/state-tool:0755",
"//publish/binaries:vsock_guest": "/opt/ic/bin/vsock_guest:0755",
Expand Down
1 change: 1 addition & 0 deletions ic-os/guestos/rootfs/etc/initramfs-tools/modules
@@ -1,2 +1,3 @@
virtio_blk
dm_verity
sev_guest
5 changes: 4 additions & 1 deletion ic-os/guestos/rootfs/opt/ic/bin/setup-sev-certs.sh
Expand Up @@ -3,6 +3,9 @@
set -e

if [[ -e "/dev/sev-guest" ]]; then
# Set permissions for sev-guest device
# TODO: This should move to guest_launch tool
chmod 777 /dev/sev-guest
if [[ -f "/boot/config/vcek.pem" ]]; then
# For prod we expect that the host will generate the ask and vcek certs and pass in via the config.
if ! cmp -s "/boot/config/ark.pem" "/opt/ic/share/ark.pem"; then
Expand All @@ -18,7 +21,7 @@ if [[ -e "/dev/sev-guest" ]]; then
# config may be generated on a machine other than the host.
(
cd /run/ic-node/config
/opt/ic/bin/sevctl get-certs
/opt/ic/bin/snptool get-certs
)
if [[ -f "/run/ic-node/config/ask.cert" && -f "/run/ic-node/config/vcek.cert" ]]; then
# Always use our hard coded ask.pem as the root of trust.
Expand Down
4 changes: 2 additions & 2 deletions publish/binaries/BUILD.bazel
Expand Up @@ -3,7 +3,7 @@ load("//gitlab-ci/src/artifacts:upload.bzl", "upload_artifacts")
load("//publish:defs.bzl", "release_nostrip_binary", "release_strip_binary")

LINUX_ONLY = [
"sevctl",
"snptool",
"vsock_guest",
"vsock_host",
"guestos_tool",
Expand Down Expand Up @@ -52,7 +52,7 @@ BINARIES = {
"orchestrator": "//rs/orchestrator",
"prometheus-config-updater": "//rs/observability/prometheus_config_updater:prometheus_config_updater",
"sandbox_launcher": "//rs/canister_sandbox/sandbox_launcher",
"sevctl": "//rs/ic_os/sevctl:sevctl",
"snptool": "//rs/ic_os/snptool:snptool",
"sns": "//rs/sns/cli:sns",
"state-tool": "//rs/state_tool:state-tool",
"systemd-journal-gatewayd-shim": "//rs/boundary_node/systemd_journal_gatewayd_shim:systemd-journal-gatewayd-shim",
Expand Down
2 changes: 1 addition & 1 deletion rs/ic_os/launch-single-vm/src/main.rs
Expand Up @@ -128,7 +128,7 @@ fn main() {
p2p_addr: SocketAddr::new(ipv6_addr, 4100),
node_operator_principal_id: None,
secret_key_store: None,
chip_id: vec![],
chip_id: None,
},
)]);

Expand Down
5 changes: 4 additions & 1 deletion rs/ic_os/sev/BUILD.bazel
Expand Up @@ -37,5 +37,8 @@ rust_test(
proc_macro_deps = [
"@crate_index//:async-trait",
],
deps = [":sev"],
deps = [
":sev",
"@crate_index//:assert_matches",
],
)
3 changes: 3 additions & 0 deletions rs/ic_os/sev/Cargo.toml
Expand Up @@ -19,3 +19,6 @@ tokio = { workspace = true }
openssl = "0.10.55"
[target.'cfg(all(target_os = "linux", target_arch = "x86_64"))'.dependencies]
sev = { version = "1.2.0", features = ["openssl"] }

[dev-dependencies]
assert_matches = "1.5.0"
15 changes: 15 additions & 0 deletions rs/ic_os/sev/src/lib.rs
Expand Up @@ -5,5 +5,20 @@ mod linux_amd64;
pub use linux_amd64::*;
#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
mod other;
use core::fmt;
#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
pub use other::*;
use std::fmt::{Display, Formatter};

#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
pub enum SnpError {
SnpNotEnabled { description: String },
FirmwareError { description: String },
ReportError { description: String },
}

impl Display for SnpError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
42 changes: 36 additions & 6 deletions rs/ic_os/sev/src/linux_amd64.rs
Expand Up @@ -2,9 +2,6 @@
References:
https://github.com/virtee/sev
https://github.com/virtee/sevctl
https://github.com/AMDESE/sev-tool
https://github.com/AMDESE/sev-guest
Convert:
openssl::x509::X509::from_pem(pem_bytes)
Expand All @@ -13,6 +10,7 @@ References:
x509.to_pem()
*/

use crate::SnpError;
use async_trait::async_trait;
use ic_base_types::{NodeId, RegistryVersion};
use ic_icos_sev_interfaces::{ValidateAttestationError, ValidateAttestedStream};
Expand All @@ -24,6 +22,7 @@ use serde::{Deserialize, Serialize};
use sev::firmware::guest::AttestationReport;
use sha2::Digest;
use std::fs;
use std::path::Path;
use std::sync::Arc;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};

Expand Down Expand Up @@ -132,7 +131,7 @@ where
});
}
let chip_id = transport_info.chip_id;
if chip_id.is_empty() {
if chip_id.is_none() {
return Err(ValidateAttestationError::HandshakeError {
description: "missing chip_id".into(),
});
Expand Down Expand Up @@ -234,9 +233,10 @@ where
description: "attestation report invalid".to_string(),
});
}
if chip_id != peer_package.report.chip_id {
if chip_id != Some(peer_package.report.chip_id.to_vec()) {
return Err(ValidateAttestationError::HandshakeError {
description: "chip_id mismatch".to_string(),
description: "Peer package chip_id does not match chip_id from registry"
.to_string(),
});
}
let peer_tls_cert_hash = peer_package.report.report_data;
Expand Down Expand Up @@ -337,9 +337,33 @@ async fn read_into_buffer<T: AsyncRead + Unpin>(
}
}

pub fn get_chip_id() -> Result<Vec<u8>, SnpError> {
// Check if /dev/sev-guest exists
let sev_guest_device = Path::new("/dev/sev-guest");
if !sev_guest_device.exists() {
return Err(SnpError::SnpNotEnabled {
description: "/dev/sev-guest does not exist. Snp is not enabled on this Guest".into(),
});
}

let mut guest_firmware =
sev::firmware::guest::Firmware::open().map_err(|error| SnpError::FirmwareError {
description: format!("unable to open sev guest firmware: {}", error),
})?;

let report = guest_firmware
.get_report(None, None, Some(0))
.map_err(|error| SnpError::ReportError {
description: format!("unable to fetch snp report: {}", error),
})?;

Ok(report.chip_id.to_vec())
}

#[cfg(test)]
mod test {
use super::*;
use assert_matches::assert_matches;

static ARK_PEM: &[u8] = include_bytes!("data/ark.pem");
static ASK_PEM: &[u8] = include_bytes!("data/ask_milan.pem");
Expand Down Expand Up @@ -377,4 +401,10 @@ mod test {
let attestation_report = AttestationReport::default();
assert!(!is_report_valid(&attestation_report, &vcek));
}

#[test]
fn test_get_chip_id_snp_not_enabled_fails() {
assert_matches!(get_chip_id(), Err(SnpError::SnpNotEnabled { description })
if description.contains("Snp is not enabled on this Guest"));
}
}

0 comments on commit 8d77465

Please sign in to comment.