This is an automated email from the ASF dual-hosted git repository.

rduan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-sgx-sdk.git

commit ff8f3dbf6901aba070a6e844bc43180edadd0b60
Author: Fanghao Yang <[email protected]>
AuthorDate: Mon Sep 25 16:54:20 2023 -0400

    Example for microsoft azure attestation
---
 samplecode/microsoft_azure_attestation/Makefile    | 159 ++++++++
 .../microsoft_azure_attestation/app/Cargo.toml     |  23 ++
 .../microsoft_azure_attestation/app/build.rs       |  41 ++
 .../microsoft_azure_attestation/app/src/main.rs    | 412 +++++++++++++++++++++
 .../microsoft_azure_attestation/bin/.gitkeep       |   0
 .../microsoft_azure_attestation/enclave/Cargo.toml |  42 +++
 .../enclave/Enclave.config.xml                     |  10 +
 .../enclave/Enclave.edl                            |  31 ++
 .../enclave/Enclave.lds                            |   9 +
 .../enclave/Enclave_private.pem                    |  39 ++
 .../microsoft_azure_attestation/enclave/Makefile   |  38 ++
 .../microsoft_azure_attestation/enclave/Xargo.toml |  95 +++++
 .../microsoft_azure_attestation/enclave/src/lib.rs |  48 +++
 .../enclave/x86_64-unknown-linux-sgx.json          |  45 +++
 .../microsoft_azure_attestation/lib/readme.txt     |   1 +
 15 files changed, 993 insertions(+)

diff --git a/samplecode/microsoft_azure_attestation/Makefile 
b/samplecode/microsoft_azure_attestation/Makefile
new file mode 100644
index 00000000..d1fce912
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/Makefile
@@ -0,0 +1,159 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+######## SGX SDK Settings ########
+
+SGX_SDK ?= /opt/sgxsdk
+SGX_MODE ?= HW
+SGX_ARCH ?= x64
+
+TOP_DIR := ../..
+include $(TOP_DIR)/buildenv.mk
+
+ifeq ($(shell getconf LONG_BIT), 32)
+       SGX_ARCH := x86
+else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
+       SGX_ARCH := x86
+endif
+
+ifeq ($(SGX_ARCH), x86)
+       SGX_COMMON_CFLAGS := -m32
+       SGX_LIBRARY_PATH := $(SGX_SDK)/lib
+       SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
+       SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
+else
+       SGX_COMMON_CFLAGS := -m64
+       SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
+       SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
+       SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
+endif
+
+ifeq ($(SGX_DEBUG), 1)
+ifeq ($(SGX_PRERELEASE), 1)
+$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
+endif
+endif
+
+ifeq ($(SGX_DEBUG), 1)
+       SGX_COMMON_CFLAGS += -O0 -g
+else
+       SGX_COMMON_CFLAGS += -O2
+endif
+
+SGX_COMMON_CFLAGS += -fstack-protector
+
+######## CUSTOM Settings ########
+
+CUSTOM_LIBRARY_PATH := ./lib
+CUSTOM_BIN_PATH := ./bin
+CUSTOM_EDL_PATH := ../../edl
+CUSTOM_COMMON_PATH := ../../common
+
+######## EDL Settings ########
+
+Enclave_EDL_Files := enclave/Enclave_t.c enclave/Enclave_t.h app/Enclave_u.c 
app/Enclave_u.h
+
+######## APP Settings ########
+
+App_Rust_Flags := --release
+App_SRC_Files := $(shell find app/ -type f -name '*.rs') $(shell find app/ 
-type f -name 'Cargo.toml')
+App_Include_Paths := -I ./app -I./include -I$(SGX_SDK)/include 
-I$(CUSTOM_EDL_PATH)
+App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
+
+App_Rust_Path := ./app/target/release
+App_Enclave_u_Object :=app/libEnclave_u.a
+App_Name := bin/maa
+
+######## Enclave Settings ########
+
+ifneq ($(SGX_MODE), HW)
+       Trts_Library_Name := sgx_trts_sim
+       Service_Library_Name := sgx_tservice_sim
+else
+       Trts_Library_Name := sgx_trts
+       Service_Library_Name := sgx_tservice
+endif
+Crypto_Library_Name := sgx_tcrypto
+KeyExchange_Library_Name := sgx_tkey_exchange
+ProtectedFs_Library_Name := sgx_tprotected_fs
+
+RustEnclave_C_Files := $(wildcard ./enclave/*.c)
+RustEnclave_C_Objects := $(RustEnclave_C_Files:.c=.o)
+RustEnclave_Include_Paths := -I$(CUSTOM_COMMON_PATH)/inc -I$(CUSTOM_EDL_PATH) 
-I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport 
-I$(SGX_SDK)/include/epid -I ./enclave -I./include
+
+RustEnclave_Link_Libs := -L$(CUSTOM_LIBRARY_PATH) -lenclave
+RustEnclave_Compile_Flags := $(SGX_COMMON_CFLAGS) $(ENCLAVE_CFLAGS) 
$(RustEnclave_Include_Paths)
+RustEnclave_Link_Flags := -Wl,--no-undefined -nostdlib -nodefaultlibs 
-nostartfiles -L$(SGX_LIBRARY_PATH) \
+       -Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
+       -Wl,--start-group -lsgx_tstdc -l$(Service_Library_Name) 
-l$(Crypto_Library_Name) $(RustEnclave_Link_Libs) -Wl,--end-group \
+       -Wl,--version-script=enclave/Enclave.lds \
+       $(ENCLAVE_LDFLAGS)
+
+RustEnclave_Name := enclave/enclave.so
+Signed_RustEnclave_Name := bin/enclave.signed.so
+
+.PHONY: all
+all: $(App_Name) $(Signed_RustEnclave_Name)
+
+######## EDL Objects ########
+
+$(Enclave_EDL_Files): $(SGX_EDGER8R) enclave/Enclave.edl
+       $(SGX_EDGER8R) --trusted enclave/Enclave.edl --search-path 
$(SGX_SDK)/include --search-path $(CUSTOM_EDL_PATH) --trusted-dir enclave
+       $(SGX_EDGER8R) --untrusted enclave/Enclave.edl --search-path 
$(SGX_SDK)/include --search-path $(CUSTOM_EDL_PATH) --untrusted-dir app
+       @echo "GEN  =>  $(Enclave_EDL_Files)"
+
+######## App Objects ########
+
+app/Enclave_u.o: $(Enclave_EDL_Files)
+       @$(CC) $(App_C_Flags) -c app/Enclave_u.c -o $@
+       @echo "CC   <=  $<"
+
+$(App_Enclave_u_Object): app/Enclave_u.o
+       $(AR) rcsD $@ $^
+       cp $(App_Enclave_u_Object) ./lib
+
+$(App_Name): $(App_Enclave_u_Object) $(App_SRC_Files) $(Qpl_Name)
+       @cd app && SGX_SDK=$(SGX_SDK) cargo build $(App_Rust_Flags)
+       @echo "Cargo  =>  $@"
+       mkdir -p bin
+       cp $(App_Rust_Path)/maa ./bin
+
+######## Enclave Objects ########
+
+enclave/Enclave_t.o: $(Enclave_EDL_Files)
+       @$(CC) $(RustEnclave_Compile_Flags) -c enclave/Enclave_t.c -o $@
+       @echo "CC   <=  $<"
+
+$(RustEnclave_Name): enclave enclave/Enclave_t.o
+       @$(CXX) enclave/Enclave_t.o -o $@ $(RustEnclave_Link_Flags)
+       @echo "LINK =>  $@"
+
+$(Signed_RustEnclave_Name): $(RustEnclave_Name)
+       mkdir -p bin
+       @$(SGX_ENCLAVE_SIGNER) sign -key enclave/Enclave_private.pem -enclave 
$(RustEnclave_Name) -out $@ -config enclave/Enclave.config.xml
+       @echo "SIGN =>  $@"
+
+.PHONY: enclave
+enclave:
+       $(MAKE) -C ./enclave/
+
+
+.PHONY: clean
+clean:
+       @rm -f $(App_Name) $(RustEnclave_Name) $(Signed_RustEnclave_Name) 
$(Qpl_Name) enclave/*_t.* app/*_u.* lib/*.a
+       @cd enclave && cargo clean && rm -f Cargo.lock
+       @cd app && cargo clean && rm -f Cargo.lock
diff --git a/samplecode/microsoft_azure_attestation/app/Cargo.toml 
b/samplecode/microsoft_azure_attestation/app/Cargo.toml
new file mode 100644
index 00000000..76d4bcac
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/app/Cargo.toml
@@ -0,0 +1,23 @@
+[package]
+name = "maa"
+version = "1.0.0"
+authors = ["Fanghao Yang"]
+build = "build.rs"
+
+[dependencies]
+sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git"; }
+sgx_urts = { git = "https://github.com/apache/teaclave-sgx-sdk.git"; }
+sha2 = "*"
+base64 = "*"
+base64-url = "2.0.0"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1"
+libloading = "*"
+reqwest = { version = "0.11.20", features = ["blocking", "json"] }
+jsonwebtoken = "7.0"
+jsonwebkey = { version = "0.3", features = ["pkcs-convert"] }
+x509-certificate = "0.21.0"
+
+[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_types = { path = "../../../sgx_types" }
+sgx_urts = { path = "../../../sgx_urts" }
diff --git a/samplecode/microsoft_azure_attestation/app/build.rs 
b/samplecode/microsoft_azure_attestation/app/build.rs
new file mode 100644
index 00000000..915e700b
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/app/build.rs
@@ -0,0 +1,41 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License..
+
+use std::env;
+
+fn main() {
+    let sdk_dir = env::var("SGX_SDK").unwrap_or_else(|_| 
"/opt/sgxsdk".to_string());
+    let is_sim = env::var("SGX_MODE").unwrap_or_else(|_| "HW".to_string());
+
+    println!("cargo:rustc-link-search=native=../lib");
+    println!("cargo:rustc-link-lib=static=Enclave_u");
+
+    println!("cargo:rustc-link-search=native={}/lib64", sdk_dir);
+
+    // if the linker failed to find libsgx_dcap_ql.so, please make sure that
+    // (1) libsgx-dcap-ql is installed
+    // (2) libsgx_dcap_ql.so exists. typicall at /usr/lib/x86_64-linux-gnu
+    // if libsgx_dcap_ql.so.1 is there, but no libsgx-dcap_ql,
+    // just create a symlink by
+    // ln -s libsgx_dcap_ql.so.1 libsgx_dcap_ql.so
+    println!("cargo:rustc-link-lib=dylib=sgx_dcap_ql");
+    match is_sim.as_ref() {
+        "SW" => println!("cargo:rustc-link-lib=dylib=sgx_urts_sim"),
+        "HW" => println!("cargo:rustc-link-lib=dylib=sgx_urts"),
+        _ => println!("cargo:rustc-link-lib=dylib=sgx_urts"), // Treat 
undefined as HW
+    }
+}
diff --git a/samplecode/microsoft_azure_attestation/app/src/main.rs 
b/samplecode/microsoft_azure_attestation/app/src/main.rs
new file mode 100644
index 00000000..98cdcba9
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/app/src/main.rs
@@ -0,0 +1,412 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License..
+
+#![allow(non_snake_case)]
+
+extern crate base64;
+extern crate base64_url;
+extern crate jsonwebkey;
+extern crate jsonwebtoken;
+extern crate libloading;
+extern crate serde;
+extern crate serde_json;
+extern crate sgx_types;
+extern crate sgx_urts;
+extern crate sha2;
+extern crate x509_certificate;
+
+use std::convert::{TryFrom, TryInto};
+
+use base64::{engine::general_purpose, Engine as _};
+use jsonwebkey::{JsonWebKey, Key, PublicExponent, RsaPublic};
+use jsonwebtoken as jwt;
+use serde::{Deserialize, Serialize};
+use sgx_types::*;
+use sgx_urts::SgxEnclave;
+use sha2::{Digest, Sha256};
+use x509_certificate::{X509Certificate, X509CertificateError};
+
+static ENCLAVE_FILE: &'static str = "enclave.signed.so";
+const ATTESTATION_PROVIDER_URL: &'static str = 
"https://sharedeus.eus.attest.azure.net";;
+const SGX_ATTESTATION_URI: &'static str = 
"/attest/SgxEnclave?api-version=2022-08-01";
+
+extern "C" {
+    fn enclave_create_report(
+        eid: sgx_enclave_id_t,
+        retval: *mut i32,
+        p_qe3_target: &sgx_target_info_t,
+        p_report_data: &sgx_report_data_t,
+        p_report: *mut sgx_report_t,
+    ) -> sgx_status_t;
+}
+
+fn init_enclave() -> SgxResult<SgxEnclave> {
+    let mut launch_token: sgx_launch_token_t = [0; 1024];
+    let mut launch_token_updated: i32 = 0;
+    // call sgx_create_enclave to initialize an enclave instance
+    // Debug Support: set 2nd parameter to 1
+    let debug = 0;
+    let mut misc_attr = sgx_misc_attribute_t {
+        secs_attr: sgx_attributes_t { flags: 0, xfrm: 0 },
+        misc_select: 0,
+    };
+    SgxEnclave::create(
+        ENCLAVE_FILE,
+        debug,
+        &mut launch_token,
+        &mut launch_token_updated,
+        &mut misc_attr,
+    )
+}
+
+// Re-invent App/utility.cpp
+// int generate_quote(uint8_t **quote_buffer, uint32_t& quote_size)
+fn generate_quote(runtime_data: &[u8]) -> Option<Vec<u8>> {
+    let mut ti: sgx_target_info_t = sgx_target_info_t::default();
+
+    println!("Step1: Call sgx_qe_get_target_info:");
+    //println!("sgx_qe_get_target_info = {:p}", sgx_qe_get_target_info as * 
const _);
+
+    let qe3_ret = unsafe { sgx_qe_get_target_info(&mut ti as *mut _) };
+
+    if qe3_ret != sgx_quote3_error_t::SGX_QL_SUCCESS {
+        println!("Error in sgx_qe_get_target_info. {:?}\n", qe3_ret);
+        return None;
+    }
+
+    //println!("target_info.mr_enclave = {:?}", ti.mr_enclave.m);
+    //println!("target_info.config_id = {:02x}", ti.config_id.iter().format(" 
"));
+
+    println!("succeed!\nStep2: Call create_app_report:");
+    let app_report: sgx_report_t = if let Some(r) = 
create_app_enclave_report(&ti, &runtime_data) {
+        println!("succeed! \nStep3: Call sgx_qe_get_quote_size:");
+        r
+    } else {
+        println!("\nCall to create_app_report() failed\n");
+        return None;
+    };
+
+    println!(
+        "app_report.body.mr_enclave = {:x?}",
+        app_report.body.mr_enclave.m
+    );
+    println!(
+        "app_report.body.mr_signer = {:x?}",
+        app_report.body.mr_signer.m
+    );
+    // println!(
+    //     "app_report.body.misc_select = {:08x}",
+    //     app_report.body.misc_select
+    // );
+
+    let mut quote_size: u32 = 0;
+    let qe3_ret = unsafe { sgx_qe_get_quote_size(&mut quote_size as _) };
+
+    if qe3_ret != sgx_quote3_error_t::SGX_QL_SUCCESS {
+        println!("Error in sgx_qe_get_quote_size . {:?}\n", qe3_ret);
+        return None;
+    }
+
+    println!("succeed!");
+
+    let mut quote_vec: Vec<u8> = vec![0; quote_size as usize];
+
+    println!("\nStep4: Call sgx_qe_get_quote:");
+
+    let qe3_ret =
+        unsafe { sgx_qe_get_quote(&app_report as _, quote_size, 
quote_vec.as_mut_ptr() as _) };
+
+    if qe3_ret != sgx_quote3_error_t::SGX_QL_SUCCESS {
+        println!("Error in sgx_qe_get_quote. {:?}\n", qe3_ret);
+        return None;
+    }
+    println!("succeed!");
+    Some(quote_vec)
+}
+
+fn create_app_enclave_report(
+    qe_ti: &sgx_target_info_t,
+    runtime_data: &[u8],
+) -> Option<sgx_report_t> {
+    let enclave = if let Ok(r) = init_enclave() {
+        r
+    } else {
+        return None;
+    };
+
+    let mut retval = 0;
+    let mut ret_report: sgx_report_t = sgx_report_t::default();
+    let mut report_data = sgx_report_data_t::default();
+    let mut hasher = Sha256::new();
+    hasher.update(runtime_data);
+    let res = hasher.finalize();
+    report_data.d[..32].copy_from_slice(&res);
+
+    let result = unsafe {
+        enclave_create_report(
+            enclave.geteid(),
+            &mut retval,
+            qe_ti,
+            &report_data,
+            &mut ret_report as *mut sgx_report_t,
+        )
+    };
+    match result {
+        sgx_status_t::SGX_SUCCESS => {}
+        _ => {
+            println!("[-] ECALL Enclave Failed {}!", result.as_str());
+            return None;
+        }
+    }
+    enclave.destroy();
+    Some(ret_report)
+}
+
+#[derive(Serialize)]
+#[serde(rename_all = "camelCase")]
+struct AzureSgxAttestationRequest {
+    quote: String,
+    runtime_data: SgxRuntimeData,
+}
+
+#[derive(Serialize)]
+#[serde(rename_all = "camelCase")]
+struct SgxRuntimeData {
+    data: String,
+    data_type: String,
+}
+
+impl SgxRuntimeData {
+    fn new_binary(data: &[u8]) -> Self {
+        Self {
+            data: base64_url::encode(data),
+            data_type: "Binary".to_string(),
+        }
+    }
+}
+
+#[derive(Deserialize)]
+struct JwtResponse {
+    pub token: String,
+}
+#[derive(Deserialize)]
+struct RawJsonWebKey {
+    pub x5c: Vec<String>,
+    pub kid: String,
+    pub kty: String,
+    // pub alg: String,
+}
+#[derive(Deserialize)]
+struct RawJsonWebKeySet {
+    pub keys: Vec<RawJsonWebKey>,
+}
+
+#[derive(Debug)]
+struct JsonWebKeySet {
+    pub keys: Vec<JsonWebKey>,
+}
+
+impl TryFrom<RawJsonWebKeySet> for JsonWebKeySet {
+    type Error = X509CertificateError;
+    // This method only works for RS256 algorithm using by Azure Attestation
+    fn try_from(raw_set: RawJsonWebKeySet) -> Result<Self, 
X509CertificateError> {
+        let mut keys = Vec::new();
+        for key in raw_set.keys {
+            if key.kty != "RSA" {
+                return Err(X509CertificateError::UnknownKeyAlgorithm(key.kty));
+            }
+            let raw_cert = general_purpose::STANDARD
+                .decode(key.x5c[0].clone())
+                .unwrap();
+            let x509 = X509Certificate::from_der(&raw_cert)?;
+            let pubkey = x509.rsa_public_key_data()?;
+            let rsa_pub = RsaPublic {
+                e: PublicExponent,
+                n: pubkey.modulus.as_slice().into(),
+            };
+            let rsa_key = Key::RSA {
+                public: rsa_pub,
+                private: None,
+            };
+            let mut jwk = JsonWebKey::new(rsa_key);
+            jwk.key_id = Some(key.kid);
+            keys.push(jwk);
+        }
+        Ok(JsonWebKeySet { keys })
+    }
+}
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "kebab-case")]
+struct TokenClaims {
+    pub x_ms_sgx_is_debuggable: bool,
+    pub x_ms_sgx_mrenclave: String,
+    pub x_ms_sgx_mrsigner: String,
+    // pub x_ms_sgx_product_id: u64,
+    pub x_ms_sgx_svn: u64,
+    pub x_ms_sgx_ehd: String,
+}
+
+/// Validate JsonWebToken with JsonWebKeySet,
+/// only works for RS256 algorithm and token from default attestation provider.
+fn validate_json_web_token(jwt: String, jwks: JsonWebKeySet) -> 
jwt::errors::Result<TokenClaims> {
+    let header = jwt::decode_header(&jwt)?;
+    if header.kid.is_none() {
+        return Err(jwt::errors::Error::from(
+            jwt::errors::ErrorKind::InvalidToken,
+        ));
+    }
+    // find the corresponding key
+    let mut idx: Option<usize> = None;
+    for (i, key) in jwks.keys.iter().enumerate() {
+        if key.key_id.is_some() {
+            if key.key_id == header.kid {
+                idx = Some(i);
+            }
+        }
+    }
+    if idx.is_none() {
+        // cannot find corresponding pubkey
+        return Err(jwt::errors::Error::from(
+            jwt::errors::ErrorKind::InvalidRsaKey,
+        ));
+    }
+    let pem = jwks.keys[idx.unwrap()].key.try_to_pem().unwrap();
+    // println!("\n{pem}");
+    let key = jwt::DecodingKey::from_rsa_pem(pem.as_bytes())?;
+    // prepare validation
+    let algo = jwt::Algorithm::RS256;
+    let mut validation = jwt::Validation::new(algo);
+    validation.validate_exp = false;
+    validation.iss = Some(ATTESTATION_PROVIDER_URL.to_string());
+    // decode JWT with the public key
+    Ok(jwt::decode::<TokenClaims>(&jwt, &key, &validation)?.claims)
+}
+
+fn main() {
+    let runtime_data = b"This is some runtime data";
+    // generate a quote using runtime data
+    let quote = generate_quote(runtime_data).unwrap();
+    let attest_request = AzureSgxAttestationRequest {
+        quote: base64_url::encode(&quote),
+        runtime_data: SgxRuntimeData::new_binary(runtime_data),
+    };
+    // request for azure attestation
+    let client = reqwest::blocking::Client::new();
+    let res = client
+        .post(format!(
+            "{}{}",
+            ATTESTATION_PROVIDER_URL, SGX_ATTESTATION_URI
+        ))
+        .json(&attest_request)
+        .send()
+        .unwrap();
+    let jwt = res.json::<JwtResponse>().unwrap().token;
+    // println!("{:?}", jwt);
+    // get public key from azure attestation
+    let res = client
+        .get(format!("{}/certs", ATTESTATION_PROVIDER_URL))
+        .send()
+        .unwrap();
+    let resp_text = res.text().unwrap();
+    // println!("{resp_text}");
+    let raw_key_set: RawJsonWebKeySet = 
serde_json::from_str(&resp_text).unwrap();
+    let jwk_set: JsonWebKeySet = raw_key_set.try_into().unwrap();
+    let claims = validate_json_web_token(jwt, jwk_set).unwrap();
+    println!(
+        "Verified SGX debuggable status: {}",
+        claims.x_ms_sgx_is_debuggable
+    );
+    println!(
+        "Verified SGX enclave measurement: {}",
+        claims.x_ms_sgx_mrenclave
+    );
+    println!(
+        "Verified SGX signer measurement: {}",
+        claims.x_ms_sgx_mrsigner
+    );
+    println!("Verified SGX SGX SVN: {}", claims.x_ms_sgx_svn);
+    println!(
+        "Verified SGX runtime data: {}",
+        
std::str::from_utf8(&base64_url::decode(&claims.x_ms_sgx_ehd).unwrap()).unwrap()
+    );
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    const RAW_KEY_SET: &str = r#"{
+        "keys": [
+          {
+            "x5c": [
+              
"MIIVTTCCFDWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAxMS8wLQYDVQQDDCZodHRwczovL3NoYXJlZGV1cy5ldXMuYXR0ZXN0LmF6dXJlLm5ldDAiGA8yMDE5MDUwMTAwMDAwMFoYDzIwNTAxMjMxMjM1OTU5WjAxMS8wLQYDVQQDDCZodHRwczovL3NoYXJlZGV1cy5ldXMuYXR0ZXN0LmF6dXJlLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKfQDlZ09kKuVXiUBEImso/kOXUU7qP5rvuesKcITCYOkz1W9er/1uLBxjaTTzpK3G588QtLzOtcrjM86r7+TqGEzSvdLLzDnyr5GCo09kMHMCpuFp12ySL4m8ZqZKgPvOorAeJqsfvrPjsSIojW1q85Lrl3/YPgeTVF5o0izYxarqobEQOLqJer0ZWLVQZshk/kPtTeQcp/Tlgxh
 [...]
+            ],
+            "kid": "rFl9xM+g7TvX63y0iseZtIn20MD5SYAnGblKFasau8I=",
+            "kty": "RSA"
+          },
+          {
+            "x5c": [
+              
"MIIF5jCCA86gAwIBAgITMwAAAAtkicH3HZ7g0AAAAAAACzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UEAxMkTWljcm9zb2Z0IEF6dXJlIEF0dGVzdGF0aW9uIFBDQSAyMDE5MB4XDTIzMDQwNDE4NTc0NVoXDTI0MDcwNDE4NTc0NVowfzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UEAxMgTWljcm9zb2Z0IEF6dXJlIEF0dGVzdGF0aW9uIDIwMjAwggEiMA0GCSqGSIb3D
 [...]
+              
"MIIHQDCCBSigAwIBAgITMwAAADd1bHkqKXnfPQAAAAAANzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTkwNTMwMjI0ODUyWhcNMzQwNTMwMjI1ODUyWjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UEAxMkTWljcm9zb2Z0IEF6dXJlIEF0dGVzdGF0aW9uIFBDQSAyMDE5MIICI
 [...]
+              
"MIIF7TCCA9WgAwIBAgIQP4vItfyfspZDtWnWbELhRDANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwMzIyMjIwNTI4WhcNMzYwMzIyMjIxMzA0WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTEwg
 [...]
+            ],
+            "kid": "dSsaF5uUxZO_LRycmQ4KJu3ctMc",
+            "kty": "RSA"
+          },
+          {
+            "x5c": [
+              
"MIIUSDCCE7GgAwIBAgIBATANBgkqhkiG9w0BAQsFADAxMS8wLQYDVQQDDCZodHRwczovL3NoYXJlZGV1cy5ldXMuYXR0ZXN0LmF6dXJlLm5ldDAiGA8yMDE5MDUwMTAwMDAwMFoYDzIwNTAxMjMxMjM1OTU5WjAxMS8wLQYDVQQDDCZodHRwczovL3NoYXJlZGV1cy5ldXMuYXR0ZXN0LmF6dXJlLm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxrDxU/OhXpoey4D/EeWeArxghOZZWxThSuuK5bIMiVpfKq5sG36WEYFBK//6yK0h1SzocPm9L0u92HvqcB9dtO76aRo4kPqZVAFPRxnhxTCSO6tkHPmA7yZ4RbWROPrgnkUv8R2kGOTeke7NKv9dLKaYQVtGv/K0UA3GhyiWTgECAwEAAaOCEmowghJmMAkGA1UdEwQCMAAwHQYDVR0OB
 [...]
+            ],
+            "kid": "lH/VQ9TL53cXpeFt3Vf9tiOv+rkWwV+5PbiNzgWcySQ=",
+            "kty": "RSA"
+          }
+        ]
+      }"#;
+
+    // The sample JWT from the Azure attestation server.
+    // Format: ${header}.${body}.${signature}
+    const RAW_TOKEN: &str = 
"eyJhbGciOiJSUzI1NiIsImprdSI6Imh0dHBzOi8vc2hhcmVkZXVzLmV1cy5hdHRlc3QuYXp1cmUubmV0L2NlcnRzIiwia2lkIjoickZsOXhNK2c3VHZYNjN5MGlzZVp0SW4yME1ENVNZQW5HYmxLRmFzYXU4ST0iLCJ0eXAiOiJKV1QifQ\
+    
.eyJhYXMtZWhkIjoiVkdocGN5QnBjeUJ6YjIxbElISjFiblJwYldVZ1pHRjBZUSIsImV4cCI6MTY5NTc2NjU0NywiaWF0IjoxNjk1NzM3NzQ3LCJpcy1kZWJ1Z2dhYmxlIjpmYWxzZSwiaXNzIjoiaHR0cHM6Ly9zaGFyZWRldXMuZXVzLmF0dGVzdC5henVyZS5uZXQiLCJqdGkiOiJmM2Q3NDU2ZjIwOGVhNzc5MTkxY2U0ZGVkMDY2YWI3ZmUyY2I3NTVhY2Y1MDYzOThiMzIzOGVmMjY3ZjgzZDlmIiwibWFhLWF0dGVzdGF0aW9uY29sbGF0ZXJhbCI6eyJxZWlkY2VydHNoYXNoIjoiYTY0ZDY0OTE5ODUwN2Q4YjU3ZTMzZjYzYWIyNjY4MzhmNDNmMzI3YmQ0YWFjYzc4NTEwYjY5NzZlZDA0NmUxMCIsInFlaWRjcmxoYXNoIjoiMTMxMTNlZWQ1NTEyZTB
 [...]
+    
.QJyc2Ka98fiy6r_FDbfzjgV3TCTFmODe-32FiGSiAyCz_ZO5Bmw9XnQI2Rzs-Yrq6b4bDV4WlMRmJePRXzI1i2cR3xtWhnJKQjTz_EYp63OfH8SsiWci_BQpTnzoiAbUi5EdrbYz3CXQtThTy_XHyYmJVEY8qLZ0dzSO4QmBxz6q8BfcEp7fhwuKzibetQlJ3zdz-TwIK0l0WbZ1jBG93oXPnQy9KhDAyDX533DvYjDjAE3FPnjV5cMZfjmcLVxTL6DROEIlZtm_yn5zJSWlQBrFRDxoYxoYtQlEeaOn-klKZj4ECJF498mACo5fYW20UhXv5ZZNdEMYVNb4dEVf-w";
+
+    #[test]
+    fn raw_key_conversion() {
+        let raw_set: RawJsonWebKeySet = 
serde_json::from_str(&RAW_KEY_SET).unwrap();
+        let jwk_set: JsonWebKeySet = raw_set.try_into().unwrap();
+        assert_eq!(jwk_set.keys.len(), 3);
+    }
+
+    #[test]
+    fn token_validation() {
+        let raw_set: RawJsonWebKeySet = 
serde_json::from_str(&RAW_KEY_SET).unwrap();
+        let jwks: JsonWebKeySet = raw_set.try_into().unwrap();
+        let claims = validate_json_web_token(RAW_TOKEN.to_string(), 
jwks).unwrap();
+        assert!(!claims.x_ms_sgx_is_debuggable);
+        assert_eq!(
+            claims.x_ms_sgx_mrenclave,
+            "f56735aa42563627a832e0c7ba9911382eb68afed75830b3f97266f3e67bdc99"
+        );
+        assert_eq!(
+            claims.x_ms_sgx_mrsigner,
+            "a595c6c5805da0c9c4cb920334d354aeaee2207e479dff679d5f360375f557dd"
+        );
+        assert_eq!(
+            base64_url::decode(&claims.x_ms_sgx_ehd).unwrap(),
+            b"This is some runtime data",
+        )
+    }
+}
diff --git a/samplecode/microsoft_azure_attestation/bin/.gitkeep 
b/samplecode/microsoft_azure_attestation/bin/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/samplecode/microsoft_azure_attestation/enclave/Cargo.toml 
b/samplecode/microsoft_azure_attestation/enclave/Cargo.toml
new file mode 100644
index 00000000..c860f344
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/enclave/Cargo.toml
@@ -0,0 +1,42 @@
+[package]
+name = "MicrosoftAzureAttestation"
+version = "1.0.0"
+authors = ["The Teaclave Authors"]
+
+[lib]
+name = "maa"
+crate-type = ["staticlib"]
+
+[features]
+default = []
+
+[target.'cfg(not(target_env = "sgx"))'.dependencies]
+sgx_types = { git = "https://github.com/apache/teaclave-sgx-sdk.git"; }
+sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git"; }
+sgx_trts = { git = "https://github.com/apache/teaclave-sgx-sdk.git"; }
+sgx_tse = { git = "https://github.com/apache/teaclave-sgx-sdk.git"; }
+[patch.'https://github.com/apache/teaclave-sgx-sdk.git']
+sgx_alloc = { path = "../../../sgx_alloc" }
+sgx_build_helper = { path = "../../../sgx_build_helper" }
+sgx_cov = { path = "../../../sgx_cov" }
+sgx_crypto_helper = { path = "../../../sgx_crypto_helper" }
+sgx_libc = { path = "../../../sgx_libc" }
+sgx_rand = { path = "../../../sgx_rand" }
+sgx_rand_derive = { path = "../../../sgx_rand_derive" }
+sgx_serialize = { path = "../../../sgx_serialize" }
+sgx_serialize_derive = { path = "../../../sgx_serialize_derive" }
+sgx_serialize_derive_internals = { path = 
"../../../sgx_serialize_derive_internals" }
+sgx_tcrypto = { path = "../../../sgx_tcrypto" }
+sgx_tcrypto_helper = { path = "../../../sgx_tcrypto_helper" }
+sgx_tdh = { path = "../../../sgx_tdh" }
+sgx_tkey_exchange = { path = "../../../sgx_tkey_exchange" }
+sgx_tprotected_fs = { path = "../../../sgx_tprotected_fs" }
+sgx_trts = { path = "../../../sgx_trts" }
+sgx_tse = { path = "../../../sgx_tse" }
+sgx_tseal = { path = "../../../sgx_tseal" }
+sgx_tstd = { path = "../../../sgx_tstd" }
+sgx_tunittest = { path = "../../../sgx_tunittest" }
+sgx_types = { path = "../../../sgx_types" }
+sgx_ucrypto = { path = "../../../sgx_ucrypto" }
+sgx_unwind = { path = "../../../sgx_unwind" }
+sgx_urts = { path = "../../../sgx_urts" }
diff --git a/samplecode/microsoft_azure_attestation/enclave/Enclave.config.xml 
b/samplecode/microsoft_azure_attestation/enclave/Enclave.config.xml
new file mode 100644
index 00000000..5b97ad8d
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/enclave/Enclave.config.xml
@@ -0,0 +1,10 @@
+<EnclaveConfiguration>
+  <ProdID>0x1</ProdID>
+  <ISVSVN>1</ISVSVN>
+  <TCSNum>1</TCSNum>
+  <TCSPolicy>1</TCSPolicy>
+  <HW>0</HW>
+  <StackMaxSize>0x2000</StackMaxSize>
+  <HeapMaxSize>0x4000</HeapMaxSize>
+  <DisableDebug>1</DisableDebug>
+</EnclaveConfiguration>
diff --git a/samplecode/microsoft_azure_attestation/enclave/Enclave.edl 
b/samplecode/microsoft_azure_attestation/enclave/Enclave.edl
new file mode 100644
index 00000000..cfcf80f6
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/enclave/Enclave.edl
@@ -0,0 +1,31 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+enclave {
+    from "sgx_tstd.edl" import *;
+    from "sgx_stdio.edl" import *;
+    from "sgx_file.edl" import *;
+    include "sgx_report.h"
+
+    trusted {
+        /* define ECALLs here. */
+        public uint32_t enclave_create_report([in]const sgx_target_info_t* 
p_qe3_target,
+                                              [in]const sgx_report_data_t* 
p_report_data,
+                                              [out]sgx_report_t* p_report);
+
+    };
+};
diff --git a/samplecode/microsoft_azure_attestation/enclave/Enclave.lds 
b/samplecode/microsoft_azure_attestation/enclave/Enclave.lds
new file mode 100644
index 00000000..e3d9d0ee
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/enclave/Enclave.lds
@@ -0,0 +1,9 @@
+enclave.so
+{
+    global:
+        g_global_data_sim;
+        g_global_data;
+        enclave_entry;
+    local:
+        *;
+};
diff --git a/samplecode/microsoft_azure_attestation/enclave/Enclave_private.pem 
b/samplecode/microsoft_azure_attestation/enclave/Enclave_private.pem
new file mode 100644
index 00000000..314705b4
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/enclave/Enclave_private.pem
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4QIBAAKCAYEAkfZLXB3p7SYhqBmRbiBlTaCQ1dWWsVCGkgrcN/IAKxsh2XRJ
+CtEEGoY3gOeZynZOAGx+eT3TskLF2/WDeQp3PKYsLlflcPwJY1ICaUBYzVtFKM/w
+19uNXA5njiXdkZmOpXvsl97P0T24+ll+uL55BayuLHitshY5CD9ITkzcckn5q1cv
+QsEXud/Q1l/jxE/+gghqFkSjCoxC4272XPfM177bPk0MIsIBWp/IQJWOykdk0Xlb
+KMkjWhk9pTThbdqHxwcXeY6FhiBAO1QcofWzHDuSrhKA5A7zBosbVUAs7D1iyZKK
+E9n+R8F4yOrGZ4lN8pJ/+WyJRcuxdoAmaYbIM99tYHos3pY/+9F9/llTSQj0K5G1
+m/9rMzS+uT58bX2yIQXLSRaikITNz78GNDH1E33rC1hK3iYjr5Cec9gjtaZPHq3H
+qnv01IRt6n7pcmSWR04FFLahOMCCt1/Zk4U9IOvy+teJU/qibsIxxoLdgZzi4vY4
+WafHaR8b0qp8XhC7AgEDAoIBgGFO3OgT8UjEFnARC57AQ4kVtePjucuLBGFcks/2
+qsdna+ZNhgc2ArxZelXvu9xO3qry/vt+jSGB2T1OV6YG+ihuyB7lQ6CoBkI2rEYq
+5d482MXf9eU9COgJml7D6Qu7tG5SnbqUiot+e1GQ/yXUUK5zHshQc8wO0LAqMDQz
+PaGGpnI6H4HWD9E/4I7ql9g1VFawRrmDF1xdgez0pD36iI/UkimIssHWq5G/2tW5
+CdwvmIumPMXbbOa7fm4jQPPnBCpP9BQ3LKKNjIW5TKU4RNIChFzLOEUhhl6PRvwk
+8SQcRJsEx/ixsziWKm3x8iVK4UQZjom2HEIGVeF/ZUQ7fMbuLJnhZWwoSFonM/G/
+EOTfccnp+ZvVgtDq2iMZCFrSp3bZGUxC3+T/iFQpEC93FnhhnGyCD7ulo01o8xpH
+qrNIuLeXjWUGOoFXLyq0WyaHnTwnHDQPK4EsVyqiX4YC6ppMPfdutYolBzFOm5a9
+TbyIVvfI64cgUhj6frOgYyVM2wKBwQDi0VQglAobzmPY8iJ/5di446xcmt764bZ8
+slBwYqJfG8hRWWZrXuyT42BaN58hvGFIvLro2msMRjpMYjWBZIOXhgPQ5ss7hK5G
+Ik9Xf9JGfXKbn1rdLl4g7swVGWHioZVtniN4S6ICPBaRJ60ytRhxABgDARVw/XyO
+bnSAFc7nvIrNrdFAo3Q3M1XArWvho28RKZF8oT9sGJ4vK8X/3NMvda30D9uswt/8
+btL41u2BSr13ZvcVMyyBh4RDdFUZnycCgcEApL3VOqe4dn2JmcwHKjtzKFQfxkbN
+gXry/AHgaqYg1vczj7H3s3CE3vzYycg8Ddyaw69vQgDz1nv2V97ZAckJcfQmqMFJ
+gNUlLnRgvDrnqzxW4RNkVRDI2OWrb3+OAqAhgSIB3mawtslqwFnAuko67etoZZQd
+07AyLQS9TFbUwPyvPZyiUk8o205RacL01vW7W+nJSf6giuVhyECESqQKCgPoE6Gd
+WAA3qF11a4/7ZYWi9+Hf+cQfwh/ZgcWSjH5NAoHBAJc2OBW4Br00QpChbFVD5dCX
+yD28lKdBJFMhivWXFuoShYuQ7vI/SGKXlZF6ahZ9ljB90fCRnLLZfDLsI6uYV7pZ
+V+CZ3NJYdC7BijpVNtmo9xJqPJN0PsCfMri7lpcWY55pbPrdFqwoDwtvyMx4uvYA
+EAIAuPX+Uwme+FVj30UoXIkei4Bs+CTM49XI8pZs9LYbtlMWKkgQaXTH2VU94h+j
+yU1f58iB6qhJ4fs586uHKPpEpLjMyFZaWCz4OLu/bwKBwG3T43xv0E7+W7vdWhwn
+ohriv9mEiQD8of1WlZxuwI9Pd7UhT8z1ren95dva0rPoZy0fn4FV9+RSpDqUkKvb
+W6FNbxsrhlXjbh74QH18mnIoOetiQuNgheXuckpVCVcVa6tsAT7vIHnbnIA71dGG
+0fPyRZkNaTfKzB4DKN2POICodNO9wYw0xeeJi5vXTeSj0j1GhjFUawdDloWAWDHC
+sVwCmrfBE5AAJRro+PJf/O5ZF0/r6qaCv9a/5laDtwhUMwKBwDp16J55+fy6S7BZ
+/LdMSim1XGxHdk+eT/ViBjXk+Ltr8IGDp72sI+nA3NK0u1vRNUYkdH3qj6zocusu
+t1+NH0mah1BNvqU/lWkGZe5kJ6FDFYnL8OB+ChNXNKZaT09GOcG2DxSFN9g5u3EK
+doIX5Qku7Ra3LElgTcINoNb2JJ9go8Tl9AwdUICX9FAuA1k6GxrdIcbhtOA+tI2G
+2jSl4qqd3uTTDdkzw0eW08pJxtAPxwTi2BENfOSbsA1c4TVExA==
+-----END RSA PRIVATE KEY-----
diff --git a/samplecode/microsoft_azure_attestation/enclave/Makefile 
b/samplecode/microsoft_azure_attestation/enclave/Makefile
new file mode 100644
index 00000000..fe3a7079
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/enclave/Makefile
@@ -0,0 +1,38 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+Rust_Enclave_Name := libenclave.a
+Rust_Enclave_Files := $(wildcard src/*.rs)
+Rust_Target_Path := $(CURDIR)/../../../xargo
+
+ifeq ($(MITIGATION-CVE-2020-0551), LOAD)
+export MITIGATION_CVE_2020_0551=LOAD
+else ifeq ($(MITIGATION-CVE-2020-0551), CF)
+export MITIGATION_CVE_2020_0551=CF
+endif
+
+.PHONY: all
+
+all: $(Rust_Enclave_Name)
+
+$(Rust_Enclave_Name): $(Rust_Enclave_Files)
+ifeq ($(XARGO_SGX), 1)
+       RUST_TARGET_PATH=$(Rust_Target_Path) xargo build --target 
x86_64-unknown-linux-sgx --release
+       cp ./target/x86_64-unknown-linux-sgx/release/libmaa.a 
../lib/libenclave.a
+else
+       cargo build --release
+       cp ./target/release/libmaa.a ../lib/libenclave.a
+endif
diff --git a/samplecode/microsoft_azure_attestation/enclave/Xargo.toml 
b/samplecode/microsoft_azure_attestation/enclave/Xargo.toml
new file mode 100644
index 00000000..ffb42729
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/enclave/Xargo.toml
@@ -0,0 +1,95 @@
+[dependencies]
+alloc = {}
+
+[dependencies.sgx_types]
+path = "../../../sgx_types"
+stage = 1
+
+[dependencies.sgx_alloc]
+path = "../../../sgx_alloc"
+stage = 1
+
+[dependencies.sgx_unwind]
+path = "../../../sgx_unwind"
+stage = 1
+
+[dependencies.sgx_demangle]
+path = "../../../sgx_demangle"
+stage = 1
+
+[dependencies.panic_abort]
+path = "../../../sgx_panic_abort"
+stage = 1
+
+[dependencies.sgx_libc]
+path = "../../../sgx_libc"
+stage = 2
+
+[dependencies.sgx_tkey_exchange]
+path = "../../../sgx_tkey_exchange"
+stage = 2
+
+[dependencies.sgx_tse]
+path = "../../../sgx_tse"
+stage = 2
+
+[dependencies.sgx_tcrypto]
+path = "../../../sgx_tcrypto"
+stage = 2
+
+[dependencies.sgx_trts]
+path = "../../../sgx_trts"
+stage = 3
+
+[dependencies.sgx_backtrace_sys]
+path = "../../../sgx_backtrace_sys"
+stage = 3
+
+[dependencies.panic_unwind]
+path = "../../../sgx_panic_unwind"
+stage = 3
+
+[dependencies.sgx_tdh]
+path = "../../../sgx_tdh"
+stage = 4
+
+[dependencies.sgx_tseal]
+path = "../../../sgx_tseal"
+stage = 4
+
+[dependencies.sgx_tprotected_fs]
+path = "../../../sgx_tprotected_fs"
+stage = 4
+
+[dependencies.std]
+path = "../../../xargo/sgx_tstd"
+stage = 5
+features = ["backtrace"]
+
+[dependencies.sgx_no_tstd]
+path = "../../../sgx_no_tstd"
+stage = 5
+
+[dependencies.sgx_rand]
+path = "../../../sgx_rand"
+stage = 6
+
+[dependencies.sgx_serialize]
+path = "../../../sgx_serialize"
+stage = 6
+
+[dependencies.sgx_tunittest]
+path = "../../../sgx_tunittest"
+stage = 6
+
+[dependencies.sgx_backtrace]
+path = "../../../sgx_backtrace"
+stage = 7
+
+[dependencies.sgx_cov]
+path = "../../../sgx_cov"
+stage = 7
+
+[dependencies.sgx_signal]
+path = "../../../sgx_signal"
+stage = 7
diff --git a/samplecode/microsoft_azure_attestation/enclave/src/lib.rs 
b/samplecode/microsoft_azure_attestation/enclave/src/lib.rs
new file mode 100644
index 00000000..9feacd3e
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/enclave/src/lib.rs
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License..
+
+#![crate_name = "maa"]
+#![crate_type = "staticlib"]
+#![cfg_attr(not(target_env = "sgx"), no_std)]
+#![cfg_attr(target_env = "sgx", feature(rustc_private))]
+
+extern crate sgx_tse;
+extern crate sgx_types;
+#[cfg(not(target_env = "sgx"))]
+#[macro_use]
+extern crate sgx_tstd as std;
+
+use sgx_tse::rsgx_create_report;
+use sgx_types::*;
+
+#[no_mangle]
+pub extern "C" fn enclave_create_report(
+    p_qe3_target: &sgx_target_info_t,
+    p_report_data: &sgx_report_data_t,
+    p_report: &mut sgx_report_t,
+) -> u32 {
+    match rsgx_create_report(p_qe3_target, p_report_data) {
+        Ok(report) => {
+            *p_report = report;
+            0
+        }
+        Err(x) => {
+            println!("rsgx_create_report failed! {:?}", x);
+            x as u32
+        }
+    }
+}
diff --git 
a/samplecode/microsoft_azure_attestation/enclave/x86_64-unknown-linux-sgx.json 
b/samplecode/microsoft_azure_attestation/enclave/x86_64-unknown-linux-sgx.json
new file mode 100644
index 00000000..53f104e2
--- /dev/null
+++ 
b/samplecode/microsoft_azure_attestation/enclave/x86_64-unknown-linux-sgx.json
@@ -0,0 +1,45 @@
+{
+  "arch": "x86_64",
+  "cpu": "x86-64",
+  "crt-static-respected": true,
+  "data-layout": 
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
+  "dynamic-linking": true,
+  "env": "sgx",
+  "executables": true,
+  "has-rpath": true,
+  "has-thread-local": true,
+  "linker-flavor": "gcc",
+  "linker-is-gnu": true,
+  "llvm-target": "x86_64-unknown-linux-gnu",
+  "max-atomic-width": 64,
+  "os": "linux",
+  "position-independent-executables": true,
+  "pre-link-args": {
+    "gcc": [
+      "-Wl,--as-needed",
+      "-Wl,-z,noexecstack",
+      "-m64"
+    ]
+  },
+  "relro-level": "full",
+  "stack-probes": {
+    "kind": "inline-or-call",
+    "min-llvm-version-for-inline": [
+      11,
+      0,
+      1
+    ]
+  },
+  "supported-sanitizers": [
+    "address",
+    "cfi",
+    "leak",
+    "memory",
+    "thread"
+  ],
+  "target-c-int-width": "32",
+  "target-endian": "little",
+  "target-family": "unix",
+  "target-pointer-width": "64",
+  "vendor": "mesalock"
+}
diff --git a/samplecode/microsoft_azure_attestation/lib/readme.txt 
b/samplecode/microsoft_azure_attestation/lib/readme.txt
new file mode 100644
index 00000000..7951405f
--- /dev/null
+++ b/samplecode/microsoft_azure_attestation/lib/readme.txt
@@ -0,0 +1 @@
+lib
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to