diff --git a/Cargo.lock b/Cargo.lock index 2b0fb5d..694d199 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -439,7 +439,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -850,7 +850,7 @@ checksum = "e19b23d53f35ce9f56aebc7d1bb4e6ac1e9c0db7ac85c8d1760c04379edced37" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1407,7 +1407,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1527,9 +1527,9 @@ dependencies = [ [[package]] name = "sev" -version = "6.2.1" +version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1750ba11a6a6bba3c220da714caa0226aa34e417dce3975d2953062240717dea" +checksum = "d295a3e215c5c2a7d16bebd55c29e6e379599287846c5f9c6e7ef7e334383ced" dependencies = [ "base64 0.22.1", "bincode", @@ -1697,7 +1697,7 @@ dependencies = [ "getrandom 0.3.1", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2059,7 +2059,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index be79605..6d94da7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ hyperv = ["tss-esapi"] clap = { version = "4.5", features = [ "derive" ] } env_logger = "0.10.0" anyhow = "1.0.69" -sev = { version = "6.2.1", default-features = false, features = ['openssl','snp']} +sev = { version = "6.3.0", default-features = false, features = ['openssl','snp']} nix = "^0.23" serde = { version = "1.0", features = ["derive"] } bincode = "^1.2.1" diff --git a/README.md b/README.md index 13d04ea..5ed0138 100644 --- a/README.md +++ b/README.md @@ -163,8 +163,7 @@ snpguest fetch ### 5. `key` -Creates the derived key based on input parameters and stores it. `$KEY_PATH` is the path to store the derived key. `$ROOT_KEY_SELECT` is the root key from which to derive the key (either "vcek" or "vmrk"). The `--guest_field_select` option specifies which Guest Field Select bits to enable as a 6-digit binary string. Each of the 6 bits from *right to left* correspond to Guest Policy, Image ID, Family ID, Measurement, SVN and TCB Version respectively. For each bit, 0 denotes off, and 1 denotes on. The `--guest_svn` option specifies the guest SVN to mix into the key, and the `--tcb_version` option specifies the TCB version to mix into the derived key. The `--vmpl` option specifies the VMPL level the Guest is running on and defaults to 1. - +Creates the derived key based on input parameters and stores it. `$KEY_PATH` is the path to store the derived key. `$ROOT_KEY_SELECT` is the root key from which to derive the key (either "vcek" or "vmrk"). The `--guest_field_select` option specifies which Guest Field Select bits to enable as a binary string of length 6 or 7. Each of the bits from *right to left* correspond to Guest Policy, Image ID, Family ID, Measurement, SVN and TCB Version, Launch Mitigation Vector, respectively. For each bit, 0 denotes off, and 1 denotes on. The `--guest_svn` option specifies the guest SVN to mix into the key, the `--tcb_version` option specifies the TCB version to mix into the derived key, and the `--launch_mit_vector` option specifies the launch mitigation vector value to mix into the derived key. The `--vmpl` option specifies the VMPL level the Guest is running on and defaults to 1. **Usage** ```bash @@ -177,20 +176,23 @@ snpguest key $KEY_PATH $ROOT_KEY_SELECT [-v, --vmpl] [-g, --guest_field_select] | `$KEY_PATH` | The path to store the derived key. | required | | `$ROOT_KEY_SELECT` | is the root key from which to derive the key (either "vcek" or "vmrk"). | required | | `-v, --vmpl $VMPL` | option specifies the VMPL level the Guest is running on. | 1 | -| `-g, --guest_field_select $GFS` | option specifies which Guest Field Select bits to enable as a 6-digit binary string. For each bit, 0 denotes off, and 1 denotes on. | — | +| `-g, --guest_field_select $GFS` | option specifies which Guest Field Select bits to enable as a binary string (length 6 or 7). For each bit, 0 denotes off, and 1 denotes on. | all 0s | | `-s, --guest_svn $GSVN` | option specifies the guest SVN to mix into the key. | — | | `-t, --tcb_version $TCBV` | option specifies the TCB version to mix into the derived key. | — | +| `-l, --launch_mit_vector $LMV` | option specifies the launch mitigation vector value to mix into the derived key (only available for `MSG_KEY_REQ` version ≥ 2 ). | — | **Guest Field Select** -| Bit | Description | -| :-- | :-- | -| 0 (LSB) | Guest Policy | -| 1 | Image ID | -| 2 | Family ID | -| 3 | Measurement | -| 4 | SVN | -| 5 (MSB) | TCB Version | +| Bit | Field | Note | +| :-- | :-- | :-- | +| 0 (LSB) | Guest Policy | | +| 1 | Image ID | | +| 2 | Family ID | | +| 3 | Measurement | | +| 4 | SVN | | +| 5 | TCB Version | | +| 6 (MSB) | Launch MIT Vector | Set to 0 if not specified; supported for `MSG_KEY_REQ` version ≥ 2. | +| (7–63) | (Reserved) | Currently not supported. | For example, `--guest_field_select 110001` denotes ``` @@ -199,7 +201,8 @@ Image ID:Off (0), Family ID: Off (0), Measurement: Off (0), SVN:On (1), -TCB Version:On (1). +TCB Version:On (1), +Launch MIT Vector: Off (none). ``` **Example** diff --git a/src/key.rs b/src/key.rs index 5f49528..29d14ec 100644 --- a/src/key.rs +++ b/src/key.rs @@ -20,9 +20,9 @@ pub struct KeyArgs { #[arg(short, long, value_name = "vmpl", default_value = "1")] pub vmpl: Option, - /// Specify which Guest Field Select bits to enable. It is a 6 digit binary string. For each bit, 0 denotes off and 1 denotes on. - /// The least significant (rightmost) bit is Guest Policy followed by Image ID, Family ID, Measurement, SVN, TCB Version which is the most significant (leftmost) bit. - #[arg(short, long = "guest_field_select", value_name = "######")] + /// Specify which Guest Field Select bits to enable. It is a 6 or 7 digit binary string. For each bit, 0 denotes off and 1 denotes on. + /// The least significant (rightmost) bit is Guest Policy followed by Image ID, Family ID, Measurement, SVN, TCB Version, and Launch Mitigation Vector which is the most significant (leftmost) bit. + #[arg(short, long = "guest_field_select", value_name = "#######")] pub gfs: Option, /// Specify the guest SVN to mix into the key. Must not exceed the guest SVN provided at launch in the ID block. @@ -32,6 +32,10 @@ pub struct KeyArgs { /// Specify the TCB version to mix into the derived key. Must not exceed CommittedTcb. #[arg(short, long = "tcb_version")] pub tcbv: Option, + + /// Specify the launch mitigation vector to mix into the derived key. + #[arg(short, long = "launch_mit_vector")] + pub lmv: Option, } pub fn get_derived_key(args: KeyArgs) -> Result<()> { @@ -54,12 +58,18 @@ pub fn get_derived_key(args: KeyArgs) -> Result<()> { let gfs = match args.gfs { Some(gfs) => { - let value: u64 = u64::from_str_radix(gfs.as_str(), 2).unwrap(); - if value <= 63 { - value - } else { - return Err(anyhow::anyhow!("Invalid Guest Field Select option.")); + if gfs.len() != 6 && gfs.len() != 7 { + return Err(anyhow::anyhow!( + "Invalid Guest Field Select option. Must be 6 or 7 digits." + )); + } + if gfs.chars().any(|c| c != '0' && c != '1') { + return Err(anyhow::anyhow!( + "Invalid Guest Field Select option. Must be a binary string." + )); } + let value: u64 = u64::from_str_radix(gfs.as_str(), 2).unwrap(); + value } None => 0, }; @@ -68,10 +78,20 @@ pub fn get_derived_key(args: KeyArgs) -> Result<()> { let tcbv: u64 = args.tcbv.unwrap_or(0); - let request = DerivedKey::new(root_key_select, GuestFieldSelect(gfs), vmpl, gsvn, tcbv); + let request = DerivedKey::new( + root_key_select, + GuestFieldSelect(gfs), + vmpl, + gsvn, + tcbv, + args.lmv, + ); + + let msg_ver = if args.lmv.is_some() { 2 } else { 1 }; + let mut sev_fw = Firmware::open().context("failed to open SEV firmware device.")?; let derived_key: [u8; 32] = sev_fw - .get_derived_key(None, request) + .get_derived_key(Some(msg_ver), request) .context("Failed to request derived key")?; // Create derived key path