From 1cfffa1a88901ece1ef247c08f2fd1d178e1bcab Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Tue, 18 Jul 2023 08:22:13 -0700 Subject: [PATCH] Add Serialize/Deserialize to `TargetInfo` The `TargetInfo` type is used to go to/from an enclave from the untrusted application, so it needs to support serialization. --- Cargo.lock | 93 +++++++++++++++++++++++++++++++++++ core/sys/types/Cargo.toml | 3 +- core/sys/types/build.rs | 4 +- core/sys/types/src/lib.rs | 21 ++++++++ core/types/Cargo.toml | 1 + core/types/src/target_info.rs | 45 ++++++++++++++++- deny.toml | 9 +++- 7 files changed, 169 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a622ee4..905e7d49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,6 +165,41 @@ dependencies = [ "typenum", ] +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.25", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.25", +] + [[package]] name = "dashmap" version = "5.5.0" @@ -309,6 +344,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda653ca797810c02f7ca4b804b40b8b95ae046eb989d356bce17919a8c25499" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "generic-array" version = "0.14.7" @@ -348,6 +389,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "hashbrown" version = "0.12.3" @@ -384,6 +431,12 @@ dependencies = [ "digest", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "instant" version = "0.1.12" @@ -514,6 +567,7 @@ dependencies = [ "cargo-emit", "mc-sgx-core-build", "serde", + "serde_with", ] [[package]] @@ -530,6 +584,7 @@ dependencies = [ "rand", "rand_core", "serde", + "serde_cbor", "textwrap", "yare", ] @@ -1103,6 +1158,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.171" @@ -1114,6 +1179,28 @@ dependencies = [ "syn 2.0.25", ] +[[package]] +name = "serde_with" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e47d95bc83ed33b2ecf84f4187ad1ab9685d18ff28db000c99deac8ce180e3" +dependencies = [ + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.25", +] + [[package]] name = "serial_test" version = "2.0.0" @@ -1192,6 +1279,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "subtle" version = "2.5.0" diff --git a/core/sys/types/Cargo.toml b/core/sys/types/Cargo.toml index 188beac5..76035d1a 100644 --- a/core/sys/types/Cargo.toml +++ b/core/sys/types/Cargo.toml @@ -15,7 +15,8 @@ rust-version = "1.62.1" doctest = false [dependencies] -serde = { version = "1.0.152", default-features = false, features = ["derive"] } +serde = { version = "1.0", default-features = false, features = ["derive"] } +serde_with = { version = "3.1", default-features = false, features = ["macros"] } [build-dependencies] bindgen = "0.66.1" diff --git a/core/sys/types/build.rs b/core/sys/types/build.rs index 87853727..39cdc8bc 100644 --- a/core/sys/types/build.rs +++ b/core/sys/types/build.rs @@ -27,7 +27,6 @@ const CORE_TYPES: &[&str] = &[ "_sgx_report_data_t", "_sgx_misc_attribute_t", "_status_t", - "_target_info_t", "sgx_config_id_t", "sgx_config_svn_t", "sgx_isv_svn_t", @@ -105,7 +104,6 @@ fn main() { "sgx_att_key_id_ext_t", "sgx_qe_report_info_t", "sgx_quote_nonce_t", - "sgx_target_info_t", "sgx_report_t", "sgx_report_body_t", "sgx_key_id_t", @@ -115,7 +113,7 @@ fn main() { "sgx_attributes_t", ]) .dynamically_sized_types(["sgx_quote_t"]) - .serialize_types(["sgx_measurement_t"]) + .serialize_types(["sgx_measurement_t", "sgx_attributes_t"]) .derive_default([ "sgx_report_t", "sgx_attributes_t", diff --git a/core/sys/types/src/lib.rs b/core/sys/types/src/lib.rs index c478da27..7e48b174 100644 --- a/core/sys/types/src/lib.rs +++ b/core/sys/types/src/lib.rs @@ -11,6 +11,7 @@ )] use serde::{Deserialize, Serialize}; +use serde_with::{serde_as, Bytes}; include!(concat!(env!("OUT_DIR"), "/bindings.rs")); @@ -88,6 +89,26 @@ impl Default for sgx_report_body_t { } } +// Manually creating the bindings for `sgx_target_info_t` because of the need to derive serde for +// the `config_id` and `reserved3` fields. This structure is unlikely to change in size as the +// `reserved3` field is 384 bytes, appearing to be padding to make this structure 512 bytes. It is +// likely that any new fields will be taken from the `reserved3` space. +#[serde_as] +#[repr(C)] +#[derive(Eq, Hash, PartialEq, Clone, Debug, Copy, Serialize, Deserialize)] +pub struct sgx_target_info_t { + pub mr_enclave: sgx_measurement_t, + pub attributes: sgx_attributes_t, + pub reserved1: [u8; SGX_TARGET_INFO_RESERVED1_BYTES], + pub config_svn: sgx_config_svn_t, + pub misc_select: sgx_misc_select_t, + pub reserved2: [u8; SGX_TARGET_INFO_RESERVED2_BYTES], + #[serde_as(as = "Bytes")] + pub config_id: sgx_config_id_t, + #[serde_as(as = "Bytes")] + pub reserved3: [u8; SGX_TARGET_INFO_RESERVED3_BYTES], +} + impl Default for sgx_target_info_t { fn default() -> Self { Self { diff --git a/core/types/Cargo.toml b/core/types/Cargo.toml index f40e2283..77353bb2 100644 --- a/core/types/Cargo.toml +++ b/core/types/Cargo.toml @@ -32,5 +32,6 @@ getrandom = { version = "0.2", default-features = false, features = ["custom"] } [dev-dependencies] rand = "0.8.5" +serde_cbor = "0.11.1" textwrap = "0.16.0" yare = "1.0.1" diff --git a/core/types/src/target_info.rs b/core/types/src/target_info.rs index 94195998..7da60ad4 100644 --- a/core/types/src/target_info.rs +++ b/core/types/src/target_info.rs @@ -5,10 +5,11 @@ use crate::{ config_id::ConfigId, impl_newtype, Attributes, ConfigSvn, MiscellaneousSelect, MrEnclave, }; use mc_sgx_core_sys_types::sgx_target_info_t; +use serde::{Deserialize, Serialize}; /// The target info #[repr(transparent)] -#[derive(Default, Debug, Clone, Hash, PartialEq, Eq)] +#[derive(Default, Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)] pub struct TargetInfo(sgx_target_info_t); impl TargetInfo { @@ -90,4 +91,46 @@ mod test { assert_eq!(info.miscellaneous_select(), MiscellaneousSelect::from(6)); assert_eq!(info.config_id(), ConfigId::from([8; SGX_CONFIGID_SIZE])); } + + #[test] + fn serialize_from_target_info_t() { + let info = sgx_target_info_t { + mr_enclave: MrEnclave::from([3u8; MrEnclave::SIZE]).into(), + attributes: Attributes::default() + .set_flags(AttributeFlags::MODE_64BIT) + .set_extended_features_mask(ExtendedFeatureRequestMask::AVX) + .into(), + reserved1: [5u8; SGX_TARGET_INFO_RESERVED1_BYTES], + config_svn: 6, + misc_select: 7, + reserved2: [8u8; SGX_TARGET_INFO_RESERVED2_BYTES], + config_id: [9u8; SGX_CONFIGID_SIZE], + reserved3: [10u8; SGX_TARGET_INFO_RESERVED3_BYTES], + }; + + // cbor is the format to go to/from an enclave in the main MobileCoin repo + let bytes = serde_cbor::to_vec(&info).expect("failed to serialize"); + let target_info: TargetInfo = + serde_cbor::from_slice(bytes.as_slice()).expect("failed to deserialize"); + + assert_eq!( + target_info.mr_enclave(), + MrEnclave::from([3u8; SGX_HASH_SIZE]) + ); + assert_eq!( + target_info.attributes(), + Attributes::default() + .set_flags(AttributeFlags::MODE_64BIT) + .set_extended_features_mask(ExtendedFeatureRequestMask::AVX) + ); + assert_eq!(target_info.config_svn(), ConfigSvn::from(6)); + assert_eq!( + target_info.miscellaneous_select(), + MiscellaneousSelect::from(7) + ); + assert_eq!( + target_info.config_id(), + ConfigId::from([9; SGX_CONFIGID_SIZE]) + ); + } } diff --git a/deny.toml b/deny.toml index 0ba14b32..6edb6ac0 100644 --- a/deny.toml +++ b/deny.toml @@ -8,7 +8,11 @@ unmaintained = "deny" unsound = "deny" yanked = "deny" notice = "warn" -ignore = [] +ignore = [ + # serde_cbor is only used in dev, it's to maintain parity with the serialization in + # + "RUSTSEC-2021-0127", +] [licenses] unlicensed = "deny" @@ -32,7 +36,8 @@ multiple-versions = "warn" # Lint level for when a crate version requirement is `*` wildcards = "deny" highlight = "all" -allow = [] +allow = [ +] deny = [ # https://github.com/briansmith/ring/issues/774 { name = "ring" },