refactor
This commit is contained in:
		
							parent
							
								
									966819d0e6
								
							
						
					
					
						commit
						2cd8fc0e56
					
				
							
								
								
									
										35
									
								
								Cargo.toml
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										35
									
								
								Cargo.toml
									
									
									
									
									
								
							| @ -2,11 +2,11 @@ | |||||||
| # All rights reserved. | # All rights reserved. | ||||||
| 
 | 
 | ||||||
| [package] | [package] | ||||||
| name = "occlum-ratls" | name = "occlum-sgx" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| edition = "2021" | edition = "2021" | ||||||
| authors = ["Valentyn Faychuk <faitchouk.valentyn@gmail.com>", "Ivan Chirkin <chirkin.ivan@gmail.com>"] | authors = ["Valentyn Faychuk <faitchouk.valentyn@gmail.com>"] | ||||||
| description = "Remote attestation for Intel SGX" | description = "Intel SGX Occlum interface" | ||||||
| license = "MIT OR Apache-2.0" | license = "MIT OR Apache-2.0" | ||||||
| keywords = ["occlum", "rustls", "ratls"] | keywords = ["occlum", "rustls", "ratls"] | ||||||
| # Inspired by https://github.com/aggregion/occlum-ratls | # Inspired by https://github.com/aggregion/occlum-ratls | ||||||
| @ -14,7 +14,6 @@ keywords = ["occlum", "rustls", "ratls"] | |||||||
| [dependencies] | [dependencies] | ||||||
| rustls = "0.23" | rustls = "0.23" | ||||||
| x509-parser = "0.16" | x509-parser = "0.16" | ||||||
| #occlum-sgx = "0.1" # get/verify quote |  | ||||||
| ring = "0.17" # hash256 | ring = "0.17" # hash256 | ||||||
| rcgen = "0.13" | rcgen = "0.13" | ||||||
| log = "0.4" | log = "0.4" | ||||||
| @ -28,10 +27,6 @@ hyper-rustls = { version = "0.27", features = ["http2"] } | |||||||
| prost = "0.13" | prost = "0.13" | ||||||
| base64 = "0.22" | base64 = "0.22" | ||||||
| lazy_static = "1.5" | lazy_static = "1.5" | ||||||
| #sgx_tse = { version = "1.1", features = ["capi"] } |  | ||||||
| #sgx_tse = "1.1" |  | ||||||
| #sgx_types = "1.1" |  | ||||||
| #sgx_tseal = "1.1" |  | ||||||
| 
 | 
 | ||||||
| [dependencies.tonic] | [dependencies.tonic] | ||||||
| version = "0.12" | version = "0.12" | ||||||
| @ -57,6 +52,19 @@ default-features = false | |||||||
| features = ["__rustls"] | features = ["__rustls"] | ||||||
| optional = true | optional = true | ||||||
| 
 | 
 | ||||||
|  | [dependencies.pbkdf2] | ||||||
|  | version = "0.12.2" | ||||||
|  | optional = true | ||||||
|  | features = ["hmac"] | ||||||
|  | 
 | ||||||
|  | [dependencies.sha2] | ||||||
|  | version = "0.10.8" | ||||||
|  | optional = true | ||||||
|  | 
 | ||||||
|  | [dependencies.aes-gcm] | ||||||
|  | version = "0.10.3" | ||||||
|  | optional = true | ||||||
|  | 
 | ||||||
| [dev-dependencies.env_logger] | [dev-dependencies.env_logger] | ||||||
| version = "0.11" | version = "0.11" | ||||||
| 
 | 
 | ||||||
| @ -76,26 +84,29 @@ tonic-build = "0.12" | |||||||
| default = [] | default = [] | ||||||
| # TOOD: rename to testing and reverse uses in the code | # TOOD: rename to testing and reverse uses in the code | ||||||
| occlum = [] | occlum = [] | ||||||
|  | sealing = ["occlum", "dep:pbkdf2", "dep:sha2", "dep:aes-gcm"] | ||||||
| reqwest = ["dep:reqwest"] | reqwest = ["dep:reqwest"] | ||||||
| actix-web = ["dep:actix-web", "actix-service", "actix-http"] | actix-web = ["dep:actix-web", "actix-service", "actix-http"] | ||||||
| tonic = ["dep:tonic"] | tonic = ["dep:tonic"] | ||||||
|  | full = ["occlum", "sealing", "reqwest", "actix-web", "tonic"] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| [[example]] | [[example]] | ||||||
| name = "mratls_https_server" | name = "mratls_https_server" | ||||||
| required-features = ["actix-web"] | required-features = ["actix-web", "occlum"] | ||||||
| 
 | 
 | ||||||
| [[example]] | [[example]] | ||||||
| name = "mratls_https_client" | name = "mratls_https_client" | ||||||
| required-features = ["reqwest"] | required-features = ["reqwest", "occlum"] | ||||||
| 
 | 
 | ||||||
| [[example]] | [[example]] | ||||||
| name = "mratls_grpcs_server" | name = "mratls_grpcs_server" | ||||||
| required-features = ["tonic"] | required-features = ["tonic", "occlum"] | ||||||
| 
 | 
 | ||||||
| [[example]] | [[example]] | ||||||
| name = "mratls_grpcs_client" | name = "mratls_grpcs_client" | ||||||
| required-features = ["tonic"] | required-features = ["tonic", "occlum"] | ||||||
| 
 | 
 | ||||||
| [[example]] | [[example]] | ||||||
| name = "sealing" | name = "sealing" | ||||||
|  | required-features = ["sealing"] | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| # Occlum SGX Remote Attestation integrated in TLS connection | # Occlum SGX Remote Attestation integrated in TLS connection and many more | ||||||
| 
 | 
 | ||||||
| The MRSIGNER of the `example/signing_key.pem` is hardcoded in the enclave code: | The MRSIGNER of the `example/signing_key.pem` is hardcoded in the enclave code: | ||||||
| 
 | 
 | ||||||
| @ -60,14 +60,14 @@ Run the occlum image in the docker environment: | |||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| # Notice that there is no SGX device mounted | # Notice that there is no SGX device mounted | ||||||
| docker run --rm -it -v /path/to/occlum-ratls:/root/occlum-ratls occlum/occlum:latest-ubuntu20.04 | docker run --rm -it -v /path/to/occlum-sgx:/root/occlum-sgx occlum/occlum:latest-ubuntu20.04 | ||||||
| # Inside the docker container do env preparation to build the image | # Inside the docker container do env preparation to build the image | ||||||
| rustup install stable-x86_64-unknown-linux-gnu | rustup install stable-x86_64-unknown-linux-gnu | ||||||
| rustup default stable | rustup default stable | ||||||
| rustup target add x86_64-unknown-linux-musl | rustup target add x86_64-unknown-linux-musl | ||||||
| 
 | 
 | ||||||
| # Build the server and the client | # Build the server and the client | ||||||
| cd occlum-ratls | cd occlum-sgx | ||||||
| ./build_server.sh grpcs | ./build_server.sh grpcs | ||||||
| ./build_client.sh grpcs | ./build_client.sh grpcs | ||||||
| ``` | ``` | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								build.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										11
									
								
								build.rs
									
									
									
									
									
								
							| @ -4,6 +4,7 @@ fn main() { | |||||||
|     #[cfg(feature = "occlum")] |     #[cfg(feature = "occlum")] | ||||||
|     { |     { | ||||||
|         let target = std::env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default(); |         let target = std::env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default(); | ||||||
|  | 
 | ||||||
|         let dcap_lib_path = match target.as_str() { |         let dcap_lib_path = match target.as_str() { | ||||||
|             "musl" => "/opt/occlum/toolchains/dcap_lib/musl", |             "musl" => "/opt/occlum/toolchains/dcap_lib/musl", | ||||||
|             _ => "/opt/occlum/toolchains/dcap_lib/glibc", // gnu, msvc, sgx...
 |             _ => "/opt/occlum/toolchains/dcap_lib/glibc", // gnu, msvc, sgx...
 | ||||||
| @ -21,6 +22,16 @@ fn main() { | |||||||
|         println!("cargo:rustc-link-search={}", dcap_lib_path); |         println!("cargo:rustc-link-search={}", dcap_lib_path); | ||||||
|         println!("cargo:rustc-link-lib=occlum_dcap"); |         println!("cargo:rustc-link-lib=occlum_dcap"); | ||||||
|         // println!("cargo:rustc-link-lib=static:+whole-archive=occlum_dcap");
 |         // println!("cargo:rustc-link-lib=static:+whole-archive=occlum_dcap");
 | ||||||
|  | 
 | ||||||
|  |         /* ---occlum_utils--- */ | ||||||
|  | 
 | ||||||
|  |         let util_lib_path = match target.as_str() { | ||||||
|  |             "musl" => "/opt/occlum/toolchains/utils_lib/musl", | ||||||
|  |             _ => "/opt/occlum/toolchains/utils_lib/glibc", // gnu, msvc, sgx...
 | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         println!("cargo:rustc-link-search={}", util_lib_path); | ||||||
|  |         println!("cargo:rustc-link-lib=occlum_utils"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[cfg(feature = "tonic")] |     #[cfg(feature = "tonic")] | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ set -e | |||||||
| SCRIPT=$0 | SCRIPT=$0 | ||||||
| EXEC=$1 | EXEC=$1 | ||||||
| 
 | 
 | ||||||
| occlum-cargo build --release --example sealing --features="occlum" | occlum-cargo build --release --example sealing --features="sealing" | ||||||
| strip target/x86_64-unknown-linux-musl/release/examples/sealing | strip target/x86_64-unknown-linux-musl/release/examples/sealing | ||||||
| 
 | 
 | ||||||
| cat > sealing.yaml <<EOF | cat > sealing.yaml <<EOF | ||||||
| @ -19,6 +19,7 @@ targets: | |||||||
|     copy: |     copy: | ||||||
|       - files: |       - files: | ||||||
|         - /opt/occlum/toolchains/dcap_lib/musl/libocclum_dcap.so.0.1.0 |         - /opt/occlum/toolchains/dcap_lib/musl/libocclum_dcap.so.0.1.0 | ||||||
|  |         - /opt/occlum/toolchains/utils_lib/musl/libocclum_utils.so.0.1.0 | ||||||
| EOF | EOF | ||||||
| 
 | 
 | ||||||
| rm -rf sealing_instance && mkdir sealing_instance && cd sealing_instance | rm -rf sealing_instance && mkdir sealing_instance && cd sealing_instance | ||||||
|  | |||||||
| @ -1,7 +1,51 @@ | |||||||
| use occlum_ratls::prelude::*; | use occlum_ratls::prelude::*; | ||||||
|  | use std::{ | ||||||
|  |     fs, | ||||||
|  |     path::Path, | ||||||
|  |     time::{SystemTime, UNIX_EPOCH}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const DATA_PATH: &str = "/host/sealed_data"; | ||||||
| 
 | 
 | ||||||
| fn main() { | fn main() { | ||||||
|     println!("Example of sealing"); |     println!("Example of sealing"); | ||||||
|     let config = SealingConfig::new().unwrap(); |     let sgx_sealing = SgxSealing::new().unwrap(); | ||||||
|     config.print_sealing_key(); |     println!("sealing : {:?}", sgx_sealing); | ||||||
|  | 
 | ||||||
|  |     let timestamp = SystemTime::now() | ||||||
|  |         .duration_since(UNIX_EPOCH) | ||||||
|  |         .unwrap_or_default() | ||||||
|  |         .as_secs(); | ||||||
|  | 
 | ||||||
|  |     println!("timestamp: {:?}", ×tamp); | ||||||
|  | 
 | ||||||
|  |     if !Path::new(DATA_PATH).exists() { | ||||||
|  |         // seal data
 | ||||||
|  | 
 | ||||||
|  |         let payload = format!("this is sealing paylod; timestamp {}", timestamp) | ||||||
|  |             .as_bytes() | ||||||
|  |             .to_vec(); | ||||||
|  | 
 | ||||||
|  |         seal_and_write_data(sgx_sealing, payload); | ||||||
|  |     } else { | ||||||
|  |         // unseal data
 | ||||||
|  | 
 | ||||||
|  |         let sealed_data = std::fs::read(DATA_PATH).unwrap(); | ||||||
|  |         unseal_data(sgx_sealing, sealed_data); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn seal_and_write_data(sgx_sealing: SgxSealing, payload: Vec<u8>) { | ||||||
|  |     let sealed_data = sgx_sealing.seal_data(payload).unwrap(); | ||||||
|  |     println!("sealed_data: {:?}", &sealed_data); | ||||||
|  |     fs::write(DATA_PATH, &sealed_data).expect("Failed to write file {DATA_PATH}"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn unseal_data(sgx_sealing: SgxSealing, sealed_data: Vec<u8>) { | ||||||
|  |     println!("sealed_data: {:?}", &sealed_data); | ||||||
|  |     let unsealed_data = sgx_sealing.un_seal_data(sealed_data).unwrap(); | ||||||
|  |     println!("unsealed_data: {:?}", &unsealed_data); | ||||||
|  | 
 | ||||||
|  |     let unsealed_utf8_string = String::from_utf8_lossy(&unsealed_data); | ||||||
|  |     println!("unsealed data utf8: \"{unsealed_utf8_string}\""); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1978,13 +1978,20 @@ extern "C" { | |||||||
|         supplemental_data_size: u32, |         supplemental_data_size: u32, | ||||||
|         supplemental_data: *mut u8, |         supplemental_data: *mut u8, | ||||||
|     ) -> i32; |     ) -> i32; | ||||||
|     pub fn dcap_generate_key( |     pub fn dcap_quote_close(handle: *mut ::std::os::raw::c_void); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // occlum_utils  occlum-detee/tools/toolchains/utils_lib
 | ||||||
|  | extern "C" { | ||||||
|  |     pub fn utils_ioctl_open() -> *mut ::std::os::raw::c_void; | ||||||
|  |     pub fn utils_gen_key( | ||||||
|         handle: *mut ::std::os::raw::c_void, |         handle: *mut ::std::os::raw::c_void, | ||||||
|         key: *mut sgx_key_128bit_t, |         key: *mut sgx_key_128bit_t, | ||||||
|         key_request: *const sgx_key_request_t, |         key_request: *const sgx_key_request_t, | ||||||
|     ) -> i32; |     ) -> i32; | ||||||
|     pub fn dcap_quote_close(handle: *mut ::std::os::raw::c_void); |     pub fn utils_ioctl_close(handle: *mut ::std::os::raw::c_void); | ||||||
| } | } | ||||||
|  | 
 | ||||||
| #[repr(C)] | #[repr(C)] | ||||||
| #[derive(Debug, Copy, Clone)] | #[derive(Debug, Copy, Clone)] | ||||||
| pub struct __locale_data { | pub struct __locale_data { | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ use std::sync::Arc; | |||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     racert::{CertificateBuilder, RaTlsCertificate, RaTlsCertificateBuilder}, |     racert::{CertificateBuilder, RaTlsCertificate, RaTlsCertificateBuilder}, | ||||||
|     RaTlsConfig, RaTlsConfigBuilder, RaTlsError, |     RaTlsConfig, RaTlsConfigBuilder, SgxError, | ||||||
| }; | }; | ||||||
| use rustls::client::danger::HandshakeSignatureValid; | use rustls::client::danger::HandshakeSignatureValid; | ||||||
| use rustls::crypto::{aws_lc_rs, verify_tls12_signature, verify_tls13_signature, CryptoProvider}; | use rustls::crypto::{aws_lc_rs, verify_tls12_signature, verify_tls13_signature, CryptoProvider}; | ||||||
| @ -79,7 +79,7 @@ pub struct RaTlsClientCertResolver { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl RaTlsClientCertResolver { | impl RaTlsClientCertResolver { | ||||||
|     pub fn new() -> Result<Self, RaTlsError> { |     pub fn new() -> Result<Self, SgxError> { | ||||||
|         let builder = RaTlsCertificateBuilder::new().with_common_name("Client".to_string()); |         let builder = RaTlsCertificateBuilder::new().with_common_name("Client".to_string()); | ||||||
|         let cert = builder.build().map(Arc::new)?; |         let cert = builder.build().map(Arc::new)?; | ||||||
|         Ok(Self { cert }) |         Ok(Self { cert }) | ||||||
| @ -101,7 +101,7 @@ impl ResolvesClientCert for RaTlsClientCertResolver { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl RaTlsConfigBuilder<ClientConfig> for ClientConfig { | impl RaTlsConfigBuilder<ClientConfig> for ClientConfig { | ||||||
|     fn from_ratls_config(config: RaTlsConfig) -> Result<Self, RaTlsError> { |     fn from_ratls_config(config: RaTlsConfig) -> Result<Self, SgxError> { | ||||||
|         Ok(Self::builder() |         Ok(Self::builder() | ||||||
|             .dangerous() |             .dangerous() | ||||||
|             .with_custom_certificate_verifier(Arc::new(RaTlsServerCertVerifier::new(config))) |             .with_custom_certificate_verifier(Arc::new(RaTlsServerCertVerifier::new(config))) | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| use crate::{RaTlsConfigBuilder, RaTlsError}; | use crate::{RaTlsConfigBuilder, SgxError}; | ||||||
| 
 | 
 | ||||||
| #[cfg(feature = "occlum")] | #[cfg(feature = "occlum")] | ||||||
| use crate::quote::{Quote, STATIC_QUOTE}; | use crate::quote::{Quote, STATIC_QUOTE}; | ||||||
| 
 | 
 | ||||||
| use crate::quote::{SealingKeyPolicy, Sgx128BitKey, IOCTL_CLIENT}; |  | ||||||
| use rustls::{ClientConfig, ServerConfig}; | use rustls::{ClientConfig, ServerConfig}; | ||||||
| 
 | 
 | ||||||
|  | #[cfg(feature = "occlum")] | ||||||
| pub type Measurement = [u8; 32]; | pub type Measurement = [u8; 32]; | ||||||
| 
 | 
 | ||||||
| #[derive(Default, Debug)] | #[derive(Default, Debug)] | ||||||
| @ -57,7 +57,7 @@ impl InstanceMeasurement { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn with_current_mrsigner(self) -> Result<Self, RaTlsError> { |     pub fn with_current_mrsigner(self) -> Result<Self, SgxError> { | ||||||
|         let quote = Self::generate_static_empty_quote()?; |         let quote = Self::generate_static_empty_quote()?; | ||||||
|         let mrsigner_from_quote = quote.mrsigner().into(); |         let mrsigner_from_quote = quote.mrsigner().into(); | ||||||
| 
 | 
 | ||||||
| @ -78,7 +78,7 @@ impl InstanceMeasurement { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn with_current_mrenclave(self) -> Result<Self, RaTlsError> { |     pub fn with_current_mrenclave(self) -> Result<Self, SgxError> { | ||||||
|         let quote = Self::generate_static_empty_quote()?; |         let quote = Self::generate_static_empty_quote()?; | ||||||
|         let mrenclave_from_quote = quote.mrenclave().into(); |         let mrenclave_from_quote = quote.mrenclave().into(); | ||||||
| 
 | 
 | ||||||
| @ -99,7 +99,7 @@ impl InstanceMeasurement { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn with_current_measurements() -> Result<Self, RaTlsError> { |     pub fn with_current_measurements() -> Result<Self, SgxError> { | ||||||
|         let quote = Self::generate_static_empty_quote()?; |         let quote = Self::generate_static_empty_quote()?; | ||||||
| 
 | 
 | ||||||
|         Ok(Self { |         Ok(Self { | ||||||
| @ -110,7 +110,7 @@ impl InstanceMeasurement { | |||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn generate_static_empty_quote() -> Result<&'static Quote, RaTlsError> { |     fn generate_static_empty_quote() -> Result<&'static Quote, SgxError> { | ||||||
|         Ok(STATIC_QUOTE.as_ref().map_err(|e| e.clone())?) |         Ok(STATIC_QUOTE.as_ref().map_err(|e| e.clone())?) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -163,60 +163,22 @@ impl RaTlsConfig { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[cfg(feature = "occlum")] |     #[cfg(feature = "occlum")] | ||||||
|     pub(crate) fn is_allowed_quote(&self, quote: &Quote) -> Result<(), RaTlsError> { |     pub(crate) fn is_allowed_quote(&self, quote: &Quote) -> Result<(), SgxError> { | ||||||
|         match self |         match self | ||||||
|             .allowed_instances |             .allowed_instances | ||||||
|             .iter() |             .iter() | ||||||
|             .any(|im| im.check_quote_measurements(quote)) |             .any(|im| im.check_quote_measurements(quote)) | ||||||
|         { |         { | ||||||
|             true => Ok(()), |             true => Ok(()), | ||||||
|             false => Err(RaTlsError::QuoteError(format!( |             false => Err(SgxError::QuoteError(format!("{:?} is not allowed", quote))), | ||||||
|                 "{:?} is not allowed", |  | ||||||
|                 quote |  | ||||||
|             ))), |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn into_server_config(self) -> Result<ServerConfig, RaTlsError> { |     pub fn into_server_config(self) -> Result<ServerConfig, SgxError> { | ||||||
|         ServerConfig::from_ratls_config(self) |         ServerConfig::from_ratls_config(self) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn into_client_config(self) -> Result<ClientConfig, RaTlsError> { |     pub fn into_client_config(self) -> Result<ClientConfig, SgxError> { | ||||||
|         ClientConfig::from_ratls_config(self) |         ClientConfig::from_ratls_config(self) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 |  | ||||||
| pub struct SealingConfig { |  | ||||||
|     #[cfg(feature = "occlum")] |  | ||||||
|     pub sealing_key: Sgx128BitKey, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl SealingConfig { |  | ||||||
|     #[cfg(feature = "occlum")] |  | ||||||
|     fn generate_static_empty_quote() -> Result<&'static Quote, RaTlsError> { |  | ||||||
|         Ok(STATIC_QUOTE.as_ref().map_err(|e| e.clone())?) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     #[cfg(feature = "occlum")] |  | ||||||
|     pub fn new() -> Result<Self, RaTlsError> { |  | ||||||
|         let quote = Self::generate_static_empty_quote()?; |  | ||||||
|         let policy = SealingKeyPolicy::MrEnclave; |  | ||||||
|         let sealing_key = IOCTL_CLIENT |  | ||||||
|             .lock() |  | ||||||
|             .unwrap() |  | ||||||
|             .generate_sealing_key(quote, policy)?; |  | ||||||
|         Ok(Self { sealing_key }) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn print_sealing_key(&self) { |  | ||||||
|         #[cfg(feature = "occlum")] |  | ||||||
|         println!("Sealing key: {:?}", self.sealing_key); |  | ||||||
|         #[cfg(not(feature = "occlum"))] |  | ||||||
|         println!("Enable occlum feature"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     #[cfg(not(feature = "occlum"))] |  | ||||||
|     pub fn new() -> Result<Self, RaTlsError> { |  | ||||||
|         Ok(Self {}) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								src/error.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										18
									
								
								src/error.rs
									
									
									
									
									
								
							| @ -1,22 +1,28 @@ | |||||||
| use std::{error::Error, fmt::Display}; | use std::{error::Error, fmt::Display}; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone)] | #[derive(Debug, Clone)] | ||||||
| pub enum RaTlsError { | pub enum SgxError { | ||||||
|     CertificateBuildError(String), |     CertificateBuildError(String), | ||||||
|     QuoteError(String), |     QuoteError(String), | ||||||
|     DcapError(String), |     DcapError(String), | ||||||
|  |     SealingError(String), | ||||||
|  |     UnSealingError(String), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Display for RaTlsError { | impl Display for SgxError { | ||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|         match *self { |         match *self { | ||||||
|             RaTlsError::CertificateBuildError(ref message) => { |             SgxError::CertificateBuildError(ref message) => { | ||||||
|                 write!(f, "CertificateBuildError: {}", message) |                 write!(f, "CertificateBuildError: {}", message) | ||||||
|             } |             } | ||||||
|             RaTlsError::QuoteError(ref message) => write!(f, "QuoteVerifyError: {}", message), |             SgxError::QuoteError(ref message) => write!(f, "QuoteVerifyError: {}", message), | ||||||
|             RaTlsError::DcapError(ref message) => write!(f, "DcapError: {}", message), |             SgxError::DcapError(ref message) => write!(f, "DcapError: {}", message), | ||||||
|  |             SgxError::SealingError(ref message) => write!(f, "SealingError: {}", message), | ||||||
|  |             SgxError::UnSealingError(ref message) => { | ||||||
|  |                 write!(f, "UnSealingError: {}", message) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Error for RaTlsError {} | impl Error for SgxError {} | ||||||
|  | |||||||
							
								
								
									
										142
									
								
								src/ioctl.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										142
									
								
								src/ioctl.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,142 @@ | |||||||
|  | use crate::bindings::*; | ||||||
|  | use crate::error::SgxError; | ||||||
|  | use crate::quote::{ReportData, VerifyResult}; | ||||||
|  | use log::{trace, warn}; | ||||||
|  | use std::time::Instant; | ||||||
|  | 
 | ||||||
|  | type HandleType = *mut ::std::os::raw::c_void; | ||||||
|  | 
 | ||||||
|  | // TODO: it should be refactored. makes it abstract and hide quote_size and supplemental_size
 | ||||||
|  | pub struct SgxIoctlClient { | ||||||
|  |     fd: HandleType, | ||||||
|  |     quote_size: Option<u32>, | ||||||
|  |     supplemental_size: Option<u32>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Needed to numb the compiler
 | ||||||
|  | unsafe impl Send for SgxIoctlClient {} | ||||||
|  | 
 | ||||||
|  | impl SgxIoctlClient { | ||||||
|  |     pub(crate) fn new() -> Self { | ||||||
|  |         Self { | ||||||
|  |             fd: std::ptr::null_mut(), | ||||||
|  |             quote_size: None, | ||||||
|  |             supplemental_size: None, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub(crate) fn handle(&mut self) -> Result<HandleType, SgxError> { | ||||||
|  |         if self.fd.is_null() { | ||||||
|  |             let handle = unsafe { dcap_quote_open() }; | ||||||
|  |             if handle.is_null() { | ||||||
|  |                 return Err(SgxError::DcapError( | ||||||
|  |                     "Failed to open DCAP quote device".to_string(), | ||||||
|  |                 )); | ||||||
|  |             } | ||||||
|  |             self.fd = handle; | ||||||
|  |         } | ||||||
|  |         Ok(self.fd) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_quote_size(&mut self) -> Result<u32, SgxError> { | ||||||
|  |         if self.quote_size.is_none() { | ||||||
|  |             let size = unsafe { dcap_get_quote_size(self.handle()?) }; | ||||||
|  |             trace!("DCAP quote size is {}", size); | ||||||
|  |             self.quote_size = Some(size); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Ok(*self.quote_size.as_ref().unwrap()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_supplemental_data_size(&mut self) -> Result<u32, SgxError> { | ||||||
|  |         if self.supplemental_size.is_none() { | ||||||
|  |             let size = unsafe { dcap_get_supplemental_data_size(self.handle()?) }; | ||||||
|  |             trace!("DCAP supplemental data size is {}", size); | ||||||
|  |             self.supplemental_size = Some(size); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Ok(*self.supplemental_size.as_ref().unwrap()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn generate_quote(&mut self, report_data: ReportData) -> Result<Vec<u8>, SgxError> { | ||||||
|  |         let instant = Instant::now(); | ||||||
|  |         let quote_buf = self.generate_quote_inner(report_data)?; | ||||||
|  |         trace!("Generated quote in {:?}ms", instant.elapsed().as_millis()); | ||||||
|  |         Ok(quote_buf) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn generate_quote_inner(&mut self, report_data: ReportData) -> Result<Vec<u8>, SgxError> { | ||||||
|  |         let quote_size = self.get_quote_size()?; | ||||||
|  |         let mut quote_buf: Vec<u8> = vec![0; quote_size as usize]; | ||||||
|  | 
 | ||||||
|  |         let instant = Instant::now(); | ||||||
|  |         let ret_code = unsafe { | ||||||
|  |             dcap_generate_quote(self.handle()?, quote_buf.as_mut_ptr(), &report_data.into()) | ||||||
|  |         }; | ||||||
|  |         trace!("Generated quote in {:?}ms", instant.elapsed().as_millis()); | ||||||
|  | 
 | ||||||
|  |         if ret_code < 0 { | ||||||
|  |             return Err(SgxError::DcapError( | ||||||
|  |                 "Failed to generate DCAP quote".to_string(), | ||||||
|  |             )); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Ok(quote_buf) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn verify_quote(&mut self, quote_buf: &[u8]) -> Result<VerifyResult, SgxError> { | ||||||
|  |         let instant = Instant::now(); | ||||||
|  |         let result = self.verify_quote_inner(quote_buf)?; | ||||||
|  |         trace!("Verified quote in {:?}ms", instant.elapsed().as_millis()); | ||||||
|  | 
 | ||||||
|  |         if result.is_negligible() { | ||||||
|  |             if !result.is_ok() { | ||||||
|  |                 warn!("DCAP quote verification returned: {:?}", result); | ||||||
|  |             } | ||||||
|  |             return Ok(result); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Err(SgxError::QuoteError(format!( | ||||||
|  |             "DCAP quote verification returned: {:?}", | ||||||
|  |             result | ||||||
|  |         ))) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn verify_quote_inner(&mut self, quote_buf: &[u8]) -> Result<VerifyResult, SgxError> { | ||||||
|  |         let supplemental_data_size = self.get_supplemental_data_size()?; | ||||||
|  | 
 | ||||||
|  |         let mut status = 1; | ||||||
|  |         let mut result = SGX_QL_QV_RESULT_UNSPECIFIED; | ||||||
|  |         let mut suppl_buf: Vec<u8> = vec![0; supplemental_data_size as usize]; | ||||||
|  | 
 | ||||||
|  |         let ret_code = unsafe { | ||||||
|  |             dcap_verify_quote( | ||||||
|  |                 self.handle()?, | ||||||
|  |                 quote_buf.as_ptr(), | ||||||
|  |                 quote_buf.len() as u32, | ||||||
|  |                 &mut status, | ||||||
|  |                 &mut result, | ||||||
|  |                 supplemental_data_size, | ||||||
|  |                 suppl_buf.as_mut_ptr(), | ||||||
|  |             ) | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         if ret_code < 0 { | ||||||
|  |             return Err(SgxError::DcapError( | ||||||
|  |                 "Failed to verify DCAP quote".to_string(), | ||||||
|  |             )); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Ok(result.into()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Drop for SgxIoctlClient { | ||||||
|  |     fn drop(&mut self) { | ||||||
|  |         unsafe { | ||||||
|  |             if !self.fd.is_null() { | ||||||
|  |                 dcap_quote_close(self.fd); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										18
									
								
								src/lib.rs
									
									
									
									
									
								
							| @ -7,20 +7,30 @@ mod server; | |||||||
| #[cfg(feature = "occlum")] | #[cfg(feature = "occlum")] | ||||||
| mod utils; | mod utils; | ||||||
| 
 | 
 | ||||||
|  | #[cfg(feature = "occlum")] | ||||||
|  | mod ioctl; | ||||||
|  | 
 | ||||||
| #[cfg(feature = "occlum")] | #[cfg(feature = "occlum")] | ||||||
| mod bindings; | mod bindings; | ||||||
| pub mod prelude; | pub mod prelude; | ||||||
| #[cfg(feature = "occlum")] | #[cfg(feature = "occlum")] | ||||||
| mod quote; | mod quote; | ||||||
| //mod sscert;
 | 
 | ||||||
|  | #[allow(dead_code)] | ||||||
|  | #[cfg(feature = "occlum")] | ||||||
|  | mod sgx_consts; | ||||||
|  | 
 | ||||||
|  | #[cfg(feature = "sealing")] | ||||||
|  | mod sealing; | ||||||
| 
 | 
 | ||||||
| pub use crate::config::RaTlsConfig; | pub use crate::config::RaTlsConfig; | ||||||
| pub use crate::config::SealingConfig; | #[cfg(feature = "sealing")] | ||||||
|  | pub use crate::sealing::SgxSealing; | ||||||
| 
 | 
 | ||||||
| #[cfg(feature = "occlum")] | #[cfg(feature = "occlum")] | ||||||
| pub use crate::config::InstanceMeasurement; | pub use crate::config::InstanceMeasurement; | ||||||
| 
 | 
 | ||||||
| pub use crate::error::RaTlsError; | pub use crate::error::SgxError; | ||||||
| 
 | 
 | ||||||
| #[cfg(feature = "actix-web")] | #[cfg(feature = "actix-web")] | ||||||
| pub use crate::http::actix_web; | pub use crate::http::actix_web; | ||||||
| @ -29,5 +39,5 @@ pub use crate::http::actix_web; | |||||||
| pub use crate::http::reqwest; | pub use crate::http::reqwest; | ||||||
| 
 | 
 | ||||||
| pub trait RaTlsConfigBuilder<T> { | pub trait RaTlsConfigBuilder<T> { | ||||||
|     fn from_ratls_config(config: RaTlsConfig) -> Result<T, RaTlsError>; |     fn from_ratls_config(config: RaTlsConfig) -> Result<T, SgxError>; | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| pub use crate::RaTlsConfig; | pub use crate::RaTlsConfig; | ||||||
| pub use crate::SealingConfig; | #[cfg(feature = "sealing")] | ||||||
|  | pub use crate::SgxSealing; | ||||||
| 
 | 
 | ||||||
| #[cfg(feature = "occlum")] | #[cfg(feature = "occlum")] | ||||||
| pub use crate::config::InstanceMeasurement; | pub use crate::config::InstanceMeasurement; | ||||||
|  | |||||||
							
								
								
									
										260
									
								
								src/quote.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										260
									
								
								src/quote.rs
									
									
									
									
									
								
							| @ -1,63 +1,18 @@ | |||||||
| use crate::bindings::*; | use crate::bindings::*; | ||||||
| use crate::error::RaTlsError; | use crate::error::SgxError; | ||||||
|  | use crate::ioctl::SgxIoctlClient; | ||||||
| use lazy_static::lazy_static; | use lazy_static::lazy_static; | ||||||
| use log::{trace, warn}; |  | ||||||
| use std::fmt::Debug; | use std::fmt::Debug; | ||||||
| use std::ops::Deref; | use std::ops::Deref; | ||||||
| use std::sync::Mutex; | use std::sync::Mutex; | ||||||
| use std::time::Instant; |  | ||||||
| 
 |  | ||||||
| pub const SGX_FLAGS_INITTED: uint64_t = 0x0000_0000_0000_0001; //If set, then the enclave is initialized
 |  | ||||||
| pub const SGX_FLAGS_DEBUG: uint64_t = 0x0000_0000_0000_0002; //If set, then the enclave is debug
 |  | ||||||
| pub const SGX_FLAGS_MODE64BIT: uint64_t = 0x0000_0000_0000_0004; //If set, then the enclave is 64 bit
 |  | ||||||
| pub const SGX_FLAGS_PROVISION_KEY: uint64_t = 0x0000_0000_0000_0010; //If set, then the enclave has access to provision key
 |  | ||||||
| pub const SGX_FLAGS_EINITTOKEN_KEY: uint64_t = 0x0000_0000_0000_0020; //If set, then the enclave has access to EINITTOKEN key
 |  | ||||||
| pub const SGX_FLAGS_KSS: uint64_t = 0x0000_0000_0000_0080; //If set enclave uses KSS
 |  | ||||||
| pub const SGX_FLAGS_AEX_NOTIFY: uint64_t = 0x0000_0000_0000_0400; //If set, then the enclave enables AEX Notify
 |  | ||||||
| pub const FLAGS_NON_SECURITY_BITS: uint64_t = 0x00FF_FFFF_FFFF_FFC0 |  | ||||||
|     | SGX_FLAGS_MODE64BIT |  | ||||||
|     | SGX_FLAGS_PROVISION_KEY |  | ||||||
|     | SGX_FLAGS_EINITTOKEN_KEY; |  | ||||||
| pub const TSEAL_DEFAULT_FLAGSMASK: uint64_t = !FLAGS_NON_SECURITY_BITS; |  | ||||||
| pub const FLAGS_SECURITY_BITS_RESERVED: uint64_t = |  | ||||||
|     !(FLAGS_NON_SECURITY_BITS | SGX_FLAGS_INITTED | SGX_FLAGS_DEBUG | SGX_FLAGS_KSS); |  | ||||||
| pub const MISC_NON_SECURITY_BITS: uint32_t = 0x0FFF_FFFF; |  | ||||||
| pub const TSEAL_DEFAULT_MISCMASK: uint32_t = !MISC_NON_SECURITY_BITS; |  | ||||||
| 
 |  | ||||||
| // TODO Intel sgx sdk 2.4
 |  | ||||||
| pub const SGX_KEYSELECT_LICENSE: uint16_t = 0x0000; |  | ||||||
| pub const SGX_KEYSELECT_PROVISION: uint16_t = 0x0001; |  | ||||||
| pub const SGX_KEYSELECT_PROVISION_SEAL: uint16_t = 0x0002; |  | ||||||
| pub const SGX_KEYSELECT_REPORT: uint16_t = 0x0003; |  | ||||||
| pub const SGX_KEYSELECT_SEAL: uint16_t = 0x0004; |  | ||||||
| 
 |  | ||||||
| // Key Policy
 |  | ||||||
| pub const SGX_KEYPOLICY_MRENCLAVE: uint16_t = 0x0001; /* Derive key using the enclave's ENCLAVE measurement register */ |  | ||||||
| pub const SGX_KEYPOLICY_MRSIGNER: uint16_t = 0x0002; /* Derive key using the enclave's SINGER measurement register */ |  | ||||||
| pub const SGX_KEYPOLICY_NOISVPRODID: uint16_t = 0x0004; /* Derive key without the enclave's ISVPRODID */ |  | ||||||
| pub const SGX_KEYPOLICY_CONFIGID: uint16_t = 0x0008; /* Derive key with the enclave's CONFIGID */ |  | ||||||
| pub const SGX_KEYPOLICY_ISVFAMILYID: uint16_t = 0x0010; /* Derive key with the enclave's ISVFAMILYID */ |  | ||||||
| pub const SGX_KEYPOLICY_ISVEXTPRODID: uint16_t = 0x0020; /* Derive key with the enclave's ISVEXTPRODID */ |  | ||||||
| 
 |  | ||||||
| pub const SGX_KEYID_SIZE: size_t = 32; |  | ||||||
| pub const SGX_CPUSVN_SIZE: size_t = 16; |  | ||||||
| pub const SGX_CONFIGID_SIZE: size_t = 64; |  | ||||||
| pub const SGX_KEY_REQUEST_RESERVED2_BYTES: size_t = 434; |  | ||||||
| 
 |  | ||||||
| pub enum SealingKeyPolicy { |  | ||||||
|     MrSigner, |  | ||||||
|     MrEnclave, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub type Sgx128BitKey = sgx_key_128bit_t; |  | ||||||
| 
 | 
 | ||||||
| pub struct Quote { | pub struct Quote { | ||||||
|     buf: Vec<u8>, |     buf: Vec<u8>, | ||||||
|     report_body: *const sgx_report_body_t, |     pub(crate) report_body: *const sgx_report_body_t, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl TryFrom<Vec<u8>> for Quote { | impl TryFrom<Vec<u8>> for Quote { | ||||||
|     type Error = RaTlsError; |     type Error = SgxError; | ||||||
|     fn try_from(buf: Vec<u8>) -> Result<Self, Self::Error> { |     fn try_from(buf: Vec<u8>) -> Result<Self, Self::Error> { | ||||||
|         let report_body_offset = size_of::<QuoteHeader>(); |         let report_body_offset = size_of::<QuoteHeader>(); | ||||||
|         let report_body_size = size_of::<sgx_report_body_t>(); |         let report_body_size = size_of::<sgx_report_body_t>(); | ||||||
| @ -65,7 +20,7 @@ impl TryFrom<Vec<u8>> for Quote { | |||||||
|         if buf.len() < report_body_offset + report_body_size { |         if buf.len() < report_body_offset + report_body_size { | ||||||
|             let minimal = report_body_offset + report_body_size; |             let minimal = report_body_offset + report_body_size; | ||||||
|             let actual = buf.len(); |             let actual = buf.len(); | ||||||
|             return Err(RaTlsError::QuoteError(format!( |             return Err(SgxError::QuoteError(format!( | ||||||
|                 "Failed to parse DCAP quote, min {minimal}, act {actual}" |                 "Failed to parse DCAP quote, min {minimal}, act {actual}" | ||||||
|             ))); |             ))); | ||||||
|         } |         } | ||||||
| @ -88,7 +43,7 @@ struct QuoteHeader { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl TryFrom<&[u8]> for Quote { | impl TryFrom<&[u8]> for Quote { | ||||||
|     type Error = RaTlsError; |     type Error = SgxError; | ||||||
| 
 | 
 | ||||||
|     fn try_from(buf: &[u8]) -> Result<Self, Self::Error> { |     fn try_from(buf: &[u8]) -> Result<Self, Self::Error> { | ||||||
|         buf.to_vec().try_into() |         buf.to_vec().try_into() | ||||||
| @ -96,7 +51,7 @@ impl TryFrom<&[u8]> for Quote { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl TryFrom<ReportData> for Quote { | impl TryFrom<ReportData> for Quote { | ||||||
|     type Error = RaTlsError; |     type Error = SgxError; | ||||||
| 
 | 
 | ||||||
|     fn try_from(value: ReportData) -> Result<Self, Self::Error> { |     fn try_from(value: ReportData) -> Result<Self, Self::Error> { | ||||||
|         Self::from_report_data(value) |         Self::from_report_data(value) | ||||||
| @ -112,7 +67,7 @@ impl Deref for Quote { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Quote { | impl Quote { | ||||||
|     pub fn from_report_data(data: ReportData) -> Result<Self, RaTlsError> { |     pub fn from_report_data(data: ReportData) -> Result<Self, SgxError> { | ||||||
|         IOCTL_CLIENT |         IOCTL_CLIENT | ||||||
|             .lock() |             .lock() | ||||||
|             .unwrap() |             .unwrap() | ||||||
| @ -120,7 +75,7 @@ impl Quote { | |||||||
|             .try_into() |             .try_into() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn from_slice(slice: &[u8]) -> Result<Self, RaTlsError> { |     pub fn from_slice(slice: &[u8]) -> Result<Self, SgxError> { | ||||||
|         slice.try_into() |         slice.try_into() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -128,7 +83,7 @@ impl Quote { | |||||||
|         self |         self | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn verify(&self) -> Result<VerifyResult, RaTlsError> { |     pub fn verify(&self) -> Result<VerifyResult, SgxError> { | ||||||
|         IOCTL_CLIENT.lock().unwrap().verify_quote(self.buf.as_ref()) |         IOCTL_CLIENT.lock().unwrap().verify_quote(self.buf.as_ref()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -181,8 +136,8 @@ impl Debug for Quote { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| lazy_static! { | lazy_static! { | ||||||
|     pub static ref IOCTL_CLIENT: Mutex<IoctlClient> = { |     pub static ref IOCTL_CLIENT: Mutex<SgxIoctlClient> = { | ||||||
|         let client = IoctlClient::new(); |         let client = SgxIoctlClient::new(); | ||||||
|         Mutex::new(client) |         Mutex::new(client) | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| @ -194,200 +149,11 @@ lazy_static! { | |||||||
| // unsafe impl Send for Quote {}
 | // unsafe impl Send for Quote {}
 | ||||||
| 
 | 
 | ||||||
| lazy_static! { | lazy_static! { | ||||||
|     pub static ref STATIC_QUOTE: Result<Quote, RaTlsError> = Quote::from_report_data([0u8; 64]); |     pub static ref STATIC_QUOTE: Result<Quote, SgxError> = Quote::from_report_data([0u8; 64]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unsafe impl Sync for Quote {} | unsafe impl Sync for Quote {} | ||||||
| 
 | 
 | ||||||
| pub struct IoctlClient { |  | ||||||
|     fd: HandleType, |  | ||||||
|     quote_size: Option<u32>, |  | ||||||
|     supplemental_size: Option<u32>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Needed to numb the compiler
 |  | ||||||
| unsafe impl Send for IoctlClient {} |  | ||||||
| 
 |  | ||||||
| impl IoctlClient { |  | ||||||
|     fn new() -> Self { |  | ||||||
|         Self { |  | ||||||
|             fd: std::ptr::null_mut(), |  | ||||||
|             quote_size: None, |  | ||||||
|             supplemental_size: None, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn handle(&mut self) -> Result<HandleType, RaTlsError> { |  | ||||||
|         if self.fd.is_null() { |  | ||||||
|             let handle = unsafe { dcap_quote_open() }; |  | ||||||
|             if handle.is_null() { |  | ||||||
|                 return Err(RaTlsError::DcapError( |  | ||||||
|                     "Failed to open DCAP quote device".to_string(), |  | ||||||
|                 )); |  | ||||||
|             } |  | ||||||
|             self.fd = handle; |  | ||||||
|         } |  | ||||||
|         Ok(self.fd) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn get_quote_size(&mut self) -> Result<u32, RaTlsError> { |  | ||||||
|         if self.quote_size.is_none() { |  | ||||||
|             let size = unsafe { dcap_get_quote_size(self.handle()?) }; |  | ||||||
|             trace!("DCAP quote size is {}", size); |  | ||||||
|             self.quote_size = Some(size); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Ok(*self.quote_size.as_ref().unwrap()) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn get_supplemental_data_size(&mut self) -> Result<u32, RaTlsError> { |  | ||||||
|         if self.supplemental_size.is_none() { |  | ||||||
|             let size = unsafe { dcap_get_supplemental_data_size(self.handle()?) }; |  | ||||||
|             trace!("DCAP supplemental data size is {}", size); |  | ||||||
|             self.supplemental_size = Some(size); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Ok(*self.supplemental_size.as_ref().unwrap()) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn generate_quote(&mut self, report_data: ReportData) -> Result<Vec<u8>, RaTlsError> { |  | ||||||
|         let instant = Instant::now(); |  | ||||||
|         let quote_buf = self.generate_quote_inner(report_data)?; |  | ||||||
|         trace!("Generated quote in {:?}ms", instant.elapsed().as_millis()); |  | ||||||
|         Ok(quote_buf) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn generate_quote_inner(&mut self, report_data: ReportData) -> Result<Vec<u8>, RaTlsError> { |  | ||||||
|         let quote_size = self.get_quote_size()?; |  | ||||||
|         let mut quote_buf: Vec<u8> = vec![0; quote_size as usize]; |  | ||||||
| 
 |  | ||||||
|         let instant = Instant::now(); |  | ||||||
|         let ret_code = unsafe { |  | ||||||
|             dcap_generate_quote(self.handle()?, quote_buf.as_mut_ptr(), &report_data.into()) |  | ||||||
|         }; |  | ||||||
|         trace!("Generated quote in {:?}ms", instant.elapsed().as_millis()); |  | ||||||
| 
 |  | ||||||
|         if ret_code < 0 { |  | ||||||
|             return Err(RaTlsError::DcapError( |  | ||||||
|                 "Failed to generate DCAP quote".to_string(), |  | ||||||
|             )); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Ok(quote_buf) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn verify_quote(&mut self, quote_buf: &[u8]) -> Result<VerifyResult, RaTlsError> { |  | ||||||
|         let instant = Instant::now(); |  | ||||||
|         let result = self.verify_quote_inner(quote_buf)?; |  | ||||||
|         trace!("Verified quote in {:?}ms", instant.elapsed().as_millis()); |  | ||||||
| 
 |  | ||||||
|         if result.is_negligible() { |  | ||||||
|             if !result.is_ok() { |  | ||||||
|                 warn!("DCAP quote verification returned: {:?}", result); |  | ||||||
|             } |  | ||||||
|             return Ok(result); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Err(RaTlsError::QuoteError(format!( |  | ||||||
|             "DCAP quote verification returned: {:?}", |  | ||||||
|             result |  | ||||||
|         ))) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn verify_quote_inner(&mut self, quote_buf: &[u8]) -> Result<VerifyResult, RaTlsError> { |  | ||||||
|         let supplemental_data_size = self.get_supplemental_data_size()?; |  | ||||||
| 
 |  | ||||||
|         let mut status = 1; |  | ||||||
|         let mut result = SGX_QL_QV_RESULT_UNSPECIFIED; |  | ||||||
|         let mut suppl_buf: Vec<u8> = vec![0; supplemental_data_size as usize]; |  | ||||||
| 
 |  | ||||||
|         let ret_code = unsafe { |  | ||||||
|             dcap_verify_quote( |  | ||||||
|                 self.handle()?, |  | ||||||
|                 quote_buf.as_ptr(), |  | ||||||
|                 quote_buf.len() as u32, |  | ||||||
|                 &mut status, |  | ||||||
|                 &mut result, |  | ||||||
|                 supplemental_data_size, |  | ||||||
|                 suppl_buf.as_mut_ptr(), |  | ||||||
|             ) |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         if ret_code < 0 { |  | ||||||
|             return Err(RaTlsError::DcapError( |  | ||||||
|                 "Failed to verify DCAP quote".to_string(), |  | ||||||
|             )); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Ok(result.into()) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /// Generate a sealing key for the given policy and SGX report
 |  | ||||||
|     /// The sealing key is used to encrypt/decrypt data in the enclave
 |  | ||||||
|     /// The quote must be previously generated using the `generate_quote`
 |  | ||||||
|     pub fn generate_sealing_key( |  | ||||||
|         &mut self, |  | ||||||
|         quote: &Quote, |  | ||||||
|         policy: SealingKeyPolicy, |  | ||||||
|     ) -> Result<Sgx128BitKey, RaTlsError> { |  | ||||||
|         let report_body = unsafe { *quote.report_body }; |  | ||||||
|         let mut key_policy = match policy { |  | ||||||
|             SealingKeyPolicy::MrSigner => SGX_KEYPOLICY_MRSIGNER, |  | ||||||
|             SealingKeyPolicy::MrEnclave => SGX_KEYPOLICY_MRENCLAVE, |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         if (report_body.attributes.flags & SGX_FLAGS_KSS) != 0 { |  | ||||||
|             const KEY_POLICY_KSS: uint16_t = |  | ||||||
|                 SGX_KEYPOLICY_CONFIGID | SGX_KEYPOLICY_ISVFAMILYID | SGX_KEYPOLICY_ISVEXTPRODID; |  | ||||||
|             key_policy = key_policy | KEY_POLICY_KSS; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Intel sgx sdk 1.8
 |  | ||||||
|         let attribute_mask = sgx_attributes_t { |  | ||||||
|             flags: TSEAL_DEFAULT_FLAGSMASK, |  | ||||||
|             xfrm: 0, |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         let mut key_id = sgx_key_id_t::default(); |  | ||||||
| 
 |  | ||||||
|         let misc_mask: sgx_misc_select_t = TSEAL_DEFAULT_MISCMASK; |  | ||||||
| 
 |  | ||||||
|         let mut key = sgx_key_128bit_t::default(); |  | ||||||
|         let key_request = sgx_key_request_t { |  | ||||||
|             key_name: SGX_KEYSELECT_SEAL, |  | ||||||
|             key_policy, |  | ||||||
|             isv_svn: report_body.isv_svn, |  | ||||||
|             reserved1: 0_u16, |  | ||||||
|             cpu_svn: report_body.cpu_svn, |  | ||||||
|             attribute_mask, |  | ||||||
|             key_id, |  | ||||||
|             misc_mask, |  | ||||||
|             config_svn: report_body.config_svn, |  | ||||||
|             reserved2: [0_u8; SGX_KEY_REQUEST_RESERVED2_BYTES], |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         let ret_code = unsafe { dcap_generate_key(self.handle()?, &mut key, &key_request) }; |  | ||||||
|         if ret_code < 0 { |  | ||||||
|             return Err(RaTlsError::DcapError( |  | ||||||
|                 "Failed to generate DCAP sealing key".to_string(), |  | ||||||
|             )); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Ok(key) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Drop for IoctlClient { |  | ||||||
|     fn drop(&mut self) { |  | ||||||
|         unsafe { |  | ||||||
|             if !self.fd.is_null() { |  | ||||||
|                 dcap_quote_close(self.fd); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type HandleType = *mut ::std::os::raw::c_void; |  | ||||||
| pub type ReportData = [u8; 64]; | pub type ReportData = [u8; 64]; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ use std::error::Error; | |||||||
| 
 | 
 | ||||||
| #[cfg(feature = "occlum")] | #[cfg(feature = "occlum")] | ||||||
| use crate::utils::hash_sha512; | use crate::utils::hash_sha512; | ||||||
| use crate::{error::RaTlsError, RaTlsConfig}; | use crate::{error::SgxError, RaTlsConfig}; | ||||||
| use log::error; | use log::error; | ||||||
| 
 | 
 | ||||||
| #[cfg(feature = "occlum")] | #[cfg(feature = "occlum")] | ||||||
| @ -18,7 +18,7 @@ use rustls::{pki_types::CertificateDer, sign::CertifiedKey}; | |||||||
| use x509_parser::{nom::Parser, oid_registry::Oid, prelude::X509CertificateParser, public_key}; | use x509_parser::{nom::Parser, oid_registry::Oid, prelude::X509CertificateParser, public_key}; | ||||||
| 
 | 
 | ||||||
| pub trait CertificateBuilder: Send + Sync { | pub trait CertificateBuilder: Send + Sync { | ||||||
|     fn build(&self) -> Result<CertifiedKey, RaTlsError>; |     fn build(&self) -> Result<CertifiedKey, SgxError>; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct RaTlsCertifiedKey { | struct RaTlsCertifiedKey { | ||||||
| @ -86,16 +86,16 @@ impl RaTlsCertificateBuilder { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl CertificateBuilder for RaTlsCertificateBuilder { | impl CertificateBuilder for RaTlsCertificateBuilder { | ||||||
|     fn build(&self) -> Result<CertifiedKey, RaTlsError> { |     fn build(&self) -> Result<CertifiedKey, SgxError> { | ||||||
|         let cert_key = self.build_internal().map_err(|e| { |         let cert_key = self.build_internal().map_err(|e| { | ||||||
|             let err = RaTlsError::CertificateBuildError(e.to_string()); |             let err = SgxError::CertificateBuildError(e.to_string()); | ||||||
|             error!("{}", err); |             error!("{}", err); | ||||||
|             err |             err | ||||||
|         })?; |         })?; | ||||||
| 
 | 
 | ||||||
|         let private_key_der = PrivateKeyDer::from(PrivatePkcs8KeyDer::from(cert_key.key_der)); |         let private_key_der = PrivateKeyDer::from(PrivatePkcs8KeyDer::from(cert_key.key_der)); | ||||||
|         let signing_key = any_supported_type(&private_key_der).map_err(|e| { |         let signing_key = any_supported_type(&private_key_der).map_err(|e| { | ||||||
|             let err = RaTlsError::CertificateBuildError(e.to_string()); |             let err = SgxError::CertificateBuildError(e.to_string()); | ||||||
|             error!("{}", err); |             error!("{}", err); | ||||||
|             err |             err | ||||||
|         })?; |         })?; | ||||||
|  | |||||||
| @ -1,2 +0,0 @@ | |||||||
| #[cfg(feature = "occlum")] |  | ||||||
| use crate::quote::{Quote, STATIC_QUOTE}; |  | ||||||
							
								
								
									
										21
									
								
								src/sealing/decrypt.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										21
									
								
								src/sealing/decrypt.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | use aes_gcm::{aead::Aead, Aes256Gcm, Key, KeyInit, Nonce}; | ||||||
|  | 
 | ||||||
|  | use super::SgxSealing; | ||||||
|  | use crate::SgxError; | ||||||
|  | 
 | ||||||
|  | impl SgxSealing { | ||||||
|  |     pub fn un_seal_data(self, payload_encrypted_packet: Vec<u8>) -> Result<Vec<u8>, SgxError> { | ||||||
|  |         let sealing_key = self.get_aes256_sealing_key()?; | ||||||
|  | 
 | ||||||
|  |         let aes_encryption_256bit_key = Key::<Aes256Gcm>::from_slice(&sealing_key); | ||||||
|  |         let nonce = Nonce::from_slice(&payload_encrypted_packet[..12]); // nonce (IV) 96-bits (12); is prepending while encryping
 | ||||||
|  |         let raw_cipher_text = &payload_encrypted_packet[12..]; | ||||||
|  | 
 | ||||||
|  |         let cipher = Aes256Gcm::new(aes_encryption_256bit_key); | ||||||
|  |         let clear_text = cipher | ||||||
|  |             .decrypt(nonce, raw_cipher_text.as_ref()) | ||||||
|  |             .map_err(|e| SgxError::UnSealingError(e.to_string()))?; | ||||||
|  | 
 | ||||||
|  |         Ok(clear_text) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								src/sealing/encrypt.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										26
									
								
								src/sealing/encrypt.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | use aes_gcm::{ | ||||||
|  |     aead::{Aead, AeadCore, OsRng}, | ||||||
|  |     Aes256Gcm, Key, KeyInit, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | use super::SgxSealing; | ||||||
|  | use crate::SgxError; | ||||||
|  | 
 | ||||||
|  | impl SgxSealing { | ||||||
|  |     pub fn seal_data(self, payload_plain_text: Vec<u8>) -> Result<Vec<u8>, SgxError> { | ||||||
|  |         let sealing_key = self.get_aes256_sealing_key()?; | ||||||
|  | 
 | ||||||
|  |         let aes_encryption_256bit_key = Key::<Aes256Gcm>::from_slice(&sealing_key); | ||||||
|  |         let nonce = Aes256Gcm::generate_nonce(&mut OsRng); // 96-bits (12); unique per message
 | ||||||
|  | 
 | ||||||
|  |         let cipher = Aes256Gcm::new(aes_encryption_256bit_key); | ||||||
|  |         let mut ciphertext = cipher | ||||||
|  |             .encrypt(&nonce, payload_plain_text.as_ref()) | ||||||
|  |             .map_err(|e| SgxError::SealingError(e.to_string()))?; | ||||||
|  | 
 | ||||||
|  |         let mut encrypted_packet = nonce.to_vec(); | ||||||
|  |         encrypted_packet.append(&mut ciphertext); | ||||||
|  | 
 | ||||||
|  |         Ok(encrypted_packet) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								src/sealing/key_derivation.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										19
									
								
								src/sealing/key_derivation.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | use pbkdf2::pbkdf2_hmac_array; | ||||||
|  | use sha2::Sha256; | ||||||
|  | 
 | ||||||
|  | use super::SgxSealing; | ||||||
|  | use crate::SgxError; | ||||||
|  | 
 | ||||||
|  | pub type SealingKey256BitDerived = [u8; 32]; | ||||||
|  | 
 | ||||||
|  | impl SgxSealing { | ||||||
|  |     pub fn get_aes256_sealing_key(self) -> Result<SealingKey256BitDerived, SgxError> { | ||||||
|  |         let mrsigner_for_salt = Self::get_current_sgx_quote()?.mrsigner().m; | ||||||
|  | 
 | ||||||
|  |         Ok(pbkdf2_hmac_array::<Sha256, 32>( | ||||||
|  |             &self.sealing_key, | ||||||
|  |             &mrsigner_for_salt, | ||||||
|  |             25519, | ||||||
|  |         )) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								src/sealing/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										8
									
								
								src/sealing/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | mod decrypt; | ||||||
|  | mod encrypt; | ||||||
|  | pub mod key_derivation; | ||||||
|  | pub mod sealing_config; | ||||||
|  | pub mod sealing_error; | ||||||
|  | 
 | ||||||
|  | pub use sealing_config::SealingConfig; | ||||||
|  | pub use sealing_error::SealingError; | ||||||
							
								
								
									
										107
									
								
								src/sealing/sgx_sealing.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										107
									
								
								src/sealing/sgx_sealing.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,107 @@ | |||||||
|  | use crate::bindings::*; | ||||||
|  | use crate::error::SgxError; | ||||||
|  | use crate::ioctl::SgxIoctlClient; | ||||||
|  | #[cfg(feature = "occlum")] | ||||||
|  | use crate::quote::{Quote, IOCTL_CLIENT, STATIC_QUOTE}; | ||||||
|  | use crate::sgx_consts::{ | ||||||
|  |     SGX_FLAGS_KSS, SGX_KEYPOLICY_CONFIGID, SGX_KEYPOLICY_ISVEXTPRODID, SGX_KEYPOLICY_ISVFAMILYID, | ||||||
|  |     SGX_KEYPOLICY_MRENCLAVE, SGX_KEYPOLICY_MRSIGNER, SGX_KEYSELECT_SEAL, | ||||||
|  |     SGX_KEY_REQUEST_RESERVED2_BYTES, TSEAL_DEFAULT_FLAGSMASK, TSEAL_DEFAULT_MISCMASK, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #[allow(dead_code)] | ||||||
|  | pub enum SealingKeyPolicy { | ||||||
|  |     MrSigner, | ||||||
|  |     MrEnclave, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub type Sgx128BitKey = sgx_key_128bit_t; | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct SgxSealing { | ||||||
|  |     #[cfg(feature = "occlum")] | ||||||
|  |     pub sealing_key: Sgx128BitKey, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl SgxSealing { | ||||||
|  |     #[cfg(feature = "occlum")] | ||||||
|  |     pub(crate) fn get_current_sgx_quote() -> Result<&'static Quote, SgxError> { | ||||||
|  |         Ok(STATIC_QUOTE.as_ref().map_err(|e| e.clone())?) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[cfg(feature = "occlum")] | ||||||
|  |     pub fn new() -> Result<Self, SgxError> { | ||||||
|  |         // by default, use MrEnclave key policy
 | ||||||
|  |         Self::with_policy(SealingKeyPolicy::MrEnclave) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_policy(policy: SealingKeyPolicy) -> Result<Self, SgxError> { | ||||||
|  |         let quote = Self::get_current_sgx_quote()?; | ||||||
|  |         let sealing_key = IOCTL_CLIENT | ||||||
|  |             .lock() | ||||||
|  |             .unwrap() | ||||||
|  |             .generate_sealing_key(quote, policy)?; | ||||||
|  |         Ok(Self { sealing_key }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[cfg(not(feature = "occlum"))] | ||||||
|  |     pub fn new() -> Result<Self, SgxError> { | ||||||
|  |         Ok(Self {}) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl SgxIoctlClient { | ||||||
|  |     /// Generate a sealing key for the given policy and SGX report
 | ||||||
|  |     /// The sealing key is used to encrypt/decrypt data in the enclave
 | ||||||
|  |     /// The quote must be previously generated using the `generate_quote`
 | ||||||
|  |     fn generate_sealing_key( | ||||||
|  |         &mut self, | ||||||
|  |         quote: &Quote, | ||||||
|  |         policy: SealingKeyPolicy, | ||||||
|  |     ) -> Result<Sgx128BitKey, SgxError> { | ||||||
|  |         let report_body = unsafe { *quote.report_body }; | ||||||
|  |         let mut key_policy = match policy { | ||||||
|  |             SealingKeyPolicy::MrSigner => SGX_KEYPOLICY_MRSIGNER, | ||||||
|  |             SealingKeyPolicy::MrEnclave => SGX_KEYPOLICY_MRENCLAVE, | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         if (report_body.attributes.flags & SGX_FLAGS_KSS) != 0 { | ||||||
|  |             const KEY_POLICY_KSS: uint16_t = | ||||||
|  |                 SGX_KEYPOLICY_CONFIGID | SGX_KEYPOLICY_ISVFAMILYID | SGX_KEYPOLICY_ISVEXTPRODID; | ||||||
|  |             key_policy = key_policy | KEY_POLICY_KSS; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Intel sgx sdk 1.8
 | ||||||
|  |         let attribute_mask = sgx_attributes_t { | ||||||
|  |             flags: TSEAL_DEFAULT_FLAGSMASK, | ||||||
|  |             xfrm: 0, | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         let key_id = sgx_key_id_t::default(); | ||||||
|  | 
 | ||||||
|  |         let misc_mask: sgx_misc_select_t = TSEAL_DEFAULT_MISCMASK; | ||||||
|  | 
 | ||||||
|  |         let mut key = sgx_key_128bit_t::default(); | ||||||
|  |         let key_request = sgx_key_request_t { | ||||||
|  |             key_name: SGX_KEYSELECT_SEAL, | ||||||
|  |             key_policy, | ||||||
|  |             isv_svn: report_body.isv_svn, | ||||||
|  |             reserved1: 0_u16, | ||||||
|  |             cpu_svn: report_body.cpu_svn, | ||||||
|  |             attribute_mask, | ||||||
|  |             key_id, | ||||||
|  |             misc_mask, | ||||||
|  |             config_svn: report_body.config_svn, | ||||||
|  |             reserved2: [0_u8; SGX_KEY_REQUEST_RESERVED2_BYTES], | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         let ret_code = unsafe { utils_gen_key(self.handle()?, &mut key, &key_request) }; | ||||||
|  |         if ret_code < 0 { | ||||||
|  |             return Err(SgxError::DcapError( | ||||||
|  |                 "Failed to generate DCAP sealing key".to_string(), | ||||||
|  |             )); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Ok(key) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,6 +1,6 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     racert::{CertificateBuilder, RaTlsCertificate, RaTlsCertificateBuilder}, |     racert::{CertificateBuilder, RaTlsCertificate, RaTlsCertificateBuilder}, | ||||||
|     RaTlsConfig, RaTlsConfigBuilder, RaTlsError, |     RaTlsConfig, RaTlsConfigBuilder, SgxError, | ||||||
| }; | }; | ||||||
| use rustls::client::danger::HandshakeSignatureValid; | use rustls::client::danger::HandshakeSignatureValid; | ||||||
| use rustls::crypto::{aws_lc_rs, verify_tls12_signature, verify_tls13_signature, CryptoProvider}; | use rustls::crypto::{aws_lc_rs, verify_tls12_signature, verify_tls13_signature, CryptoProvider}; | ||||||
| @ -81,7 +81,7 @@ pub struct RaTlsServerCertResolver { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl RaTlsServerCertResolver { | impl RaTlsServerCertResolver { | ||||||
|     pub fn new() -> Result<Self, RaTlsError> { |     pub fn new() -> Result<Self, SgxError> { | ||||||
|         let builder = RaTlsCertificateBuilder::new().with_common_name("Client".to_string()); |         let builder = RaTlsCertificateBuilder::new().with_common_name("Client".to_string()); | ||||||
|         let cert = builder.build().map(Arc::new)?; |         let cert = builder.build().map(Arc::new)?; | ||||||
|         Ok(Self { cert }) |         Ok(Self { cert }) | ||||||
| @ -95,7 +95,7 @@ impl ResolvesServerCert for RaTlsServerCertResolver { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl RaTlsConfigBuilder<ServerConfig> for ServerConfig { | impl RaTlsConfigBuilder<ServerConfig> for ServerConfig { | ||||||
|     fn from_ratls_config(config: RaTlsConfig) -> Result<Self, RaTlsError> { |     fn from_ratls_config(config: RaTlsConfig) -> Result<Self, SgxError> { | ||||||
|         Ok(Self::builder() |         Ok(Self::builder() | ||||||
|             .with_client_cert_verifier(Arc::new(RaTlsClientCertVerifier::new(config))) |             .with_client_cert_verifier(Arc::new(RaTlsClientCertVerifier::new(config))) | ||||||
|             .with_cert_resolver(Arc::new(RaTlsServerCertResolver::new()?))) |             .with_cert_resolver(Arc::new(RaTlsServerCertResolver::new()?))) | ||||||
|  | |||||||
							
								
								
									
										38
									
								
								src/sgx_consts.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										38
									
								
								src/sgx_consts.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | use crate::bindings::*; | ||||||
|  | 
 | ||||||
|  | pub const SGX_FLAGS_INITTED: uint64_t = 0x0000_0000_0000_0001; //If set, then the enclave is initialized
 | ||||||
|  | pub const SGX_FLAGS_DEBUG: uint64_t = 0x0000_0000_0000_0002; //If set, then the enclave is debug
 | ||||||
|  | pub const SGX_FLAGS_MODE64BIT: uint64_t = 0x0000_0000_0000_0004; //If set, then the enclave is 64 bit
 | ||||||
|  | pub const SGX_FLAGS_PROVISION_KEY: uint64_t = 0x0000_0000_0000_0010; //If set, then the enclave has access to provision key
 | ||||||
|  | pub const SGX_FLAGS_EINITTOKEN_KEY: uint64_t = 0x0000_0000_0000_0020; //If set, then the enclave has access to EINITTOKEN key
 | ||||||
|  | pub const SGX_FLAGS_KSS: uint64_t = 0x0000_0000_0000_0080; //If set enclave uses KSS
 | ||||||
|  | pub const SGX_FLAGS_AEX_NOTIFY: uint64_t = 0x0000_0000_0000_0400; //If set, then the enclave enables AEX Notify
 | ||||||
|  | pub const FLAGS_NON_SECURITY_BITS: uint64_t = 0x00FF_FFFF_FFFF_FFC0 | ||||||
|  |     | SGX_FLAGS_MODE64BIT | ||||||
|  |     | SGX_FLAGS_PROVISION_KEY | ||||||
|  |     | SGX_FLAGS_EINITTOKEN_KEY; | ||||||
|  | pub const TSEAL_DEFAULT_FLAGSMASK: uint64_t = !FLAGS_NON_SECURITY_BITS; | ||||||
|  | pub const FLAGS_SECURITY_BITS_RESERVED: uint64_t = | ||||||
|  |     !(FLAGS_NON_SECURITY_BITS | SGX_FLAGS_INITTED | SGX_FLAGS_DEBUG | SGX_FLAGS_KSS); | ||||||
|  | pub const MISC_NON_SECURITY_BITS: uint32_t = 0x0FFF_FFFF; | ||||||
|  | pub const TSEAL_DEFAULT_MISCMASK: uint32_t = !MISC_NON_SECURITY_BITS; | ||||||
|  | 
 | ||||||
|  | // TODO Intel sgx sdk 2.4
 | ||||||
|  | pub const SGX_KEYSELECT_LICENSE: uint16_t = 0x0000; | ||||||
|  | pub const SGX_KEYSELECT_PROVISION: uint16_t = 0x0001; | ||||||
|  | pub const SGX_KEYSELECT_PROVISION_SEAL: uint16_t = 0x0002; | ||||||
|  | pub const SGX_KEYSELECT_REPORT: uint16_t = 0x0003; | ||||||
|  | pub const SGX_KEYSELECT_SEAL: uint16_t = 0x0004; | ||||||
|  | 
 | ||||||
|  | // Key Policy
 | ||||||
|  | pub const SGX_KEYPOLICY_MRENCLAVE: uint16_t = 0x0001; /* Derive key using the enclave's ENCLAVE measurement register */ | ||||||
|  | pub const SGX_KEYPOLICY_MRSIGNER: uint16_t = 0x0002; /* Derive key using the enclave's SINGER measurement register */ | ||||||
|  | pub const SGX_KEYPOLICY_NOISVPRODID: uint16_t = 0x0004; /* Derive key without the enclave's ISVPRODID */ | ||||||
|  | pub const SGX_KEYPOLICY_CONFIGID: uint16_t = 0x0008; /* Derive key with the enclave's CONFIGID */ | ||||||
|  | pub const SGX_KEYPOLICY_ISVFAMILYID: uint16_t = 0x0010; /* Derive key with the enclave's ISVFAMILYID */ | ||||||
|  | pub const SGX_KEYPOLICY_ISVEXTPRODID: uint16_t = 0x0020; /* Derive key with the enclave's ISVEXTPRODID */ | ||||||
|  | 
 | ||||||
|  | pub const SGX_KEYID_SIZE: size_t = 32; | ||||||
|  | pub const SGX_CPUSVN_SIZE: size_t = 16; | ||||||
|  | pub const SGX_CONFIGID_SIZE: size_t = 64; | ||||||
|  | pub const SGX_KEY_REQUEST_RESERVED2_BYTES: size_t = 434; | ||||||
| @ -1,67 +0,0 @@ | |||||||
| // use rustls::{server::{ClientCertVerified, ClientCertVerifier, ResolvesServerCert}, sign::CertifiedKey, Certificate, Error, ServerConfig, DistinguishedNames};
 |  | ||||||
| // use std::{sync::Arc, time::SystemTime};
 |  | ||||||
| //
 |  | ||||||
| // use crate::{
 |  | ||||||
| //     racert::{CertificateBuilder, RaTlsCertificate, RaTlsCertificateBuilder},
 |  | ||||||
| //     RaTlsConfig, RaTlsConfigBuilder, RaTlsError,
 |  | ||||||
| // };
 |  | ||||||
| //
 |  | ||||||
| // pub struct RaTlsClientCertVerifier {
 |  | ||||||
| //     config: RaTlsConfig,
 |  | ||||||
| // }
 |  | ||||||
| //
 |  | ||||||
| // impl RaTlsClientCertVerifier {
 |  | ||||||
| //     pub fn new(config: RaTlsConfig) -> Self {
 |  | ||||||
| //         Self { config }
 |  | ||||||
| //     }
 |  | ||||||
| // }
 |  | ||||||
| //
 |  | ||||||
| // impl ClientCertVerifier for RaTlsClientCertVerifier {
 |  | ||||||
| //     fn verify_client_cert(
 |  | ||||||
| //         &self,
 |  | ||||||
| //         end_entity: &Certificate,
 |  | ||||||
| //         _intermediates: &[Certificate],
 |  | ||||||
| //         _now: SystemTime,
 |  | ||||||
| //     ) -> Result<ClientCertVerified, Error> {
 |  | ||||||
| //         end_entity.verify_quote(&self.config).map_err(|e| {
 |  | ||||||
| //             println!("{:?}", e);
 |  | ||||||
| //             rustls::Error::General(e.to_string())
 |  | ||||||
| //         })?;
 |  | ||||||
| //
 |  | ||||||
| //         Ok(ClientCertVerified::assertion())
 |  | ||||||
| //     }
 |  | ||||||
| //
 |  | ||||||
| //     fn client_auth_root_subjects(&self) -> Option<DistinguishedNames> {
 |  | ||||||
| //         Some(DistinguishedNames::new())
 |  | ||||||
| //     }
 |  | ||||||
| // }
 |  | ||||||
| //
 |  | ||||||
| // pub struct RaTlsServerCertResolver {
 |  | ||||||
| //     cert: Arc<CertifiedKey>,
 |  | ||||||
| // }
 |  | ||||||
| //
 |  | ||||||
| // impl RaTlsServerCertResolver {
 |  | ||||||
| //     pub fn new() -> Result<Self, RaTlsError> {
 |  | ||||||
| //         let builder = RaTlsCertificateBuilder::new().with_common_name("Client".to_string());
 |  | ||||||
| //         let cert = builder.build().map(Arc::new)?;
 |  | ||||||
| //         Ok(Self { cert })
 |  | ||||||
| //     }
 |  | ||||||
| // }
 |  | ||||||
| //
 |  | ||||||
| // impl ResolvesServerCert for RaTlsServerCertResolver {
 |  | ||||||
| //     fn resolve(
 |  | ||||||
| //         &self,
 |  | ||||||
| //         _client_hello: rustls::server::ClientHello,
 |  | ||||||
| //     ) -> Option<std::sync::Arc<CertifiedKey>> {
 |  | ||||||
| //         Some(self.cert.clone())
 |  | ||||||
| //     }
 |  | ||||||
| // }
 |  | ||||||
| //
 |  | ||||||
| // impl RaTlsConfigBuilder<ServerConfig> for ServerConfig {
 |  | ||||||
| //     fn from_ratls_config(config: RaTlsConfig) -> Result<Self, RaTlsError> {
 |  | ||||||
| //         Ok(Self::builder()
 |  | ||||||
| //             .with_safe_defaults()
 |  | ||||||
| //             .with_client_cert_verifier(Arc::new(RaTlsClientCertVerifier::new(config)))
 |  | ||||||
| //             .with_cert_resolver(Arc::new(RaTlsServerCertResolver::new()?)))
 |  | ||||||
| //     }
 |  | ||||||
| // }
 |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user