From 4a1fcadddc5ff5b1965cf79e31aad4ad0718ba37 Mon Sep 17 00:00:00 2001 From: Pi Delport Date: Mon, 21 Jun 2021 23:42:47 +0200 Subject: [PATCH 01/14] docs(HACKING): add section: "Cargo patch limitation workaround" --- HACKING.md | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/HACKING.md b/HACKING.md index da92dd4b..c938c044 100644 --- a/HACKING.md +++ b/HACKING.md @@ -23,12 +23,37 @@ so these references must be patched like this: sgx_tstd = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda" } ``` -However, also note that Cargo currently has this limitation: +### Cargo patch limitation workaround + +Ideally, we want to explicitly specify the tag or revision of the SGX-forked packages we use, +like this: + +```toml +serde = { git = "https://github.com/mesalock-linux/serde-sgx", tag = "sgx_1.1.3" } +``` + +However, this fails for packages that are also listed as dependencies of other SGX-forked packages +_without_ the explicit tag: Cargo will resolve these as different crates, which causes problems +(such as different crates referring to different versions of `serde`'s traits). + +We cannot use `[patch]` to override these dependencies to use the same specifiers, +because of this Cargo limitation: * [Cannot patch underspecified git dependency #7670](https://github.com/rust-lang/cargo/issues/7670) + * Comment: + +To work around this problem, our specifiers must exactly match the specifiers used by our dependencies' +dependency declarations. (That is, the `rev` / `tag` / `branch` values (or lack of them) must match.) + +Currently, at least these transitively-used dependencies must be specified exactly: -This prevents patching a repository reference to a different revision in the same repository, -which makes some SGX-patched packages (such as `serde-sgx` and `serde-json-sgx`) tricky to deal with. +```toml +once_cell = { git = "https://github.com/mesalock-linux/once_cell-sgx" } +serde = { git = "https://github.com/mesalock-linux/serde-sgx" } +serde-big-array = { git = "https://github.com/mesalock-linux/serde-big-array-sgx" } +serde_derive = { git = "https://github.com/mesalock-linux/serde-sgx" } +serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } +``` ## Aligned memory allocation for secret values From a17e368ff722a40f53a6761937581e9b4fe32d4e Mon Sep 17 00:00:00 2001 From: Pi Delport Date: Mon, 21 Jun 2021 23:51:47 +0200 Subject: [PATCH 02/14] deps(rtc_tenclave,rtc_data_enclave): use exact specifiers for once_cell-sgx and serde-json-sgx Link to the relevant HACKING.md section. --- rtc_auth_enclave/Cargo.lock | 4 ++-- rtc_data_enclave/Cargo.lock | 4 ++-- rtc_data_enclave/Cargo.toml | 7 ++++--- rtc_exec_enclave/Cargo.lock | 4 ++-- rtc_tenclave/Cargo.lock | 4 ++-- rtc_tenclave/Cargo.toml | 29 +++-------------------------- 6 files changed, 15 insertions(+), 37 deletions(-) diff --git a/rtc_auth_enclave/Cargo.lock b/rtc_auth_enclave/Cargo.lock index 5dbfb236..3df12897 100644 --- a/rtc_auth_enclave/Cargo.lock +++ b/rtc_auth_enclave/Cargo.lock @@ -221,7 +221,7 @@ dependencies = [ [[package]] name = "once_cell" version = "1.4.0" -source = "git+https://github.com/mesalock-linux/once_cell-sgx.git?tag=sgx_1.1.3#cefcaa03fed4d85276b3235d875f1b45d399cc3c" +source = "git+https://github.com/mesalock-linux/once_cell-sgx.git#cefcaa03fed4d85276b3235d875f1b45d399cc3c" dependencies = [ "sgx_tstd", ] @@ -499,7 +499,7 @@ dependencies = [ [[package]] name = "serde_json" version = "1.0.60" -source = "git+https://github.com/mesalock-linux/serde-json-sgx?tag=sgx_1.1.3#380893814ad2a057758d825bab798aa117f7362a" +source = "git+https://github.com/mesalock-linux/serde-json-sgx#380893814ad2a057758d825bab798aa117f7362a" dependencies = [ "itoa 0.4.5", "ryu", diff --git a/rtc_data_enclave/Cargo.lock b/rtc_data_enclave/Cargo.lock index 20e6e981..392ea11e 100644 --- a/rtc_data_enclave/Cargo.lock +++ b/rtc_data_enclave/Cargo.lock @@ -300,7 +300,7 @@ dependencies = [ [[package]] name = "once_cell" version = "1.4.0" -source = "git+https://github.com/mesalock-linux/once_cell-sgx.git?tag=sgx_1.1.3#cefcaa03fed4d85276b3235d875f1b45d399cc3c" +source = "git+https://github.com/mesalock-linux/once_cell-sgx.git#cefcaa03fed4d85276b3235d875f1b45d399cc3c" dependencies = [ "sgx_tstd", ] @@ -616,7 +616,7 @@ dependencies = [ [[package]] name = "serde_json" version = "1.0.60" -source = "git+https://github.com/mesalock-linux/serde-json-sgx?tag=sgx_1.1.3#380893814ad2a057758d825bab798aa117f7362a" +source = "git+https://github.com/mesalock-linux/serde-json-sgx#380893814ad2a057758d825bab798aa117f7362a" dependencies = [ "itoa 0.4.5", "ryu", diff --git a/rtc_data_enclave/Cargo.toml b/rtc_data_enclave/Cargo.toml index bea352c5..125aca25 100644 --- a/rtc_data_enclave/Cargo.toml +++ b/rtc_data_enclave/Cargo.toml @@ -31,11 +31,12 @@ rtc_types = { path = "../rtc_types", features = ["teaclave_sgx"] } rtc_tenclave = { path = "../rtc_tenclave" } [dependencies] -# XXX: See comment about serde-sgx dependency versioning in rtc_tenclave/Cargo.toml -serde_derive = { git = "https://github.com/mesalock-linux/serde-sgx" } +# See "Cargo patch limitation workaround" in HACKING.md: serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = ["derive"]} -bincode = { git = "https://github.com/mesalock-linux/bincode-sgx.git" } serde-big-array = { git = "https://github.com/mesalock-linux/serde-big-array-sgx" } +serde_derive = { git = "https://github.com/mesalock-linux/serde-sgx" } + +bincode = { git = "https://github.com/mesalock-linux/bincode-sgx.git" } simple_asn1 = { git = "https://github.com/mesalock-linux/simple_asn1-sgx.git" } thiserror = { git = "https://github.com/mesalock-linux/thiserror-sgx.git", tag = "sgx_1.1.3" } uuid = { git = "https://github.com/mesalock-linux/uuid-sgx", features = ["v4"] } diff --git a/rtc_exec_enclave/Cargo.lock b/rtc_exec_enclave/Cargo.lock index 934d8b41..8007a7b8 100644 --- a/rtc_exec_enclave/Cargo.lock +++ b/rtc_exec_enclave/Cargo.lock @@ -221,7 +221,7 @@ dependencies = [ [[package]] name = "once_cell" version = "1.4.0" -source = "git+https://github.com/mesalock-linux/once_cell-sgx.git?tag=sgx_1.1.3#cefcaa03fed4d85276b3235d875f1b45d399cc3c" +source = "git+https://github.com/mesalock-linux/once_cell-sgx.git#cefcaa03fed4d85276b3235d875f1b45d399cc3c" dependencies = [ "sgx_tstd", ] @@ -500,7 +500,7 @@ dependencies = [ [[package]] name = "serde_json" version = "1.0.60" -source = "git+https://github.com/mesalock-linux/serde-json-sgx?tag=sgx_1.1.3#380893814ad2a057758d825bab798aa117f7362a" +source = "git+https://github.com/mesalock-linux/serde-json-sgx#380893814ad2a057758d825bab798aa117f7362a" dependencies = [ "itoa 0.4.5", "ryu", diff --git a/rtc_tenclave/Cargo.lock b/rtc_tenclave/Cargo.lock index 2e467a1c..4153263a 100644 --- a/rtc_tenclave/Cargo.lock +++ b/rtc_tenclave/Cargo.lock @@ -255,7 +255,7 @@ dependencies = [ [[package]] name = "once_cell" version = "1.4.0" -source = "git+https://github.com/mesalock-linux/once_cell-sgx.git?tag=sgx_1.1.3#cefcaa03fed4d85276b3235d875f1b45d399cc3c" +source = "git+https://github.com/mesalock-linux/once_cell-sgx.git#cefcaa03fed4d85276b3235d875f1b45d399cc3c" dependencies = [ "sgx_tstd", ] @@ -710,7 +710,7 @@ checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" [[package]] name = "serde_json" version = "1.0.60" -source = "git+https://github.com/mesalock-linux/serde-json-sgx?tag=sgx_1.1.3#380893814ad2a057758d825bab798aa117f7362a" +source = "git+https://github.com/mesalock-linux/serde-json-sgx#380893814ad2a057758d825bab798aa117f7362a" dependencies = [ "itoa 0.4.5", "ryu", diff --git a/rtc_tenclave/Cargo.toml b/rtc_tenclave/Cargo.toml index faa2c0cb..e0914a69 100644 --- a/rtc_tenclave/Cargo.toml +++ b/rtc_tenclave/Cargo.toml @@ -24,34 +24,11 @@ rand = { git = "https://github.com/mesalock-linux/rand-sgx", tag = "v0.7.3_sgx1. thiserror = { git = "https://github.com/mesalock-linux/thiserror-sgx.git", tag = "sgx_1.1.3", optional = true } sgx_tcrypto = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda", optional = true } sgx_tdh = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda", features = ["use_lav2"], optional = true } -once_cell = { git = "https://github.com/mesalock-linux/once_cell-sgx.git", tag = "sgx_1.1.3", optional = true } -# XXX: Work around serde-json-sgx / Cargo version handling issue -# -# We want to specify tag = "sgx_1.1.3" for the serde dependency here, -# but this makes Cargo resolve the dependency to a different crate -# version identity than what serde-json-sgx's dependency resolves to, -# even though both "master" and "sgx_1.1.3" point to same git revision. -# -# This causes build failures due to serde_json referring to a different -# versions of the Serialize / Deserialize traits than this project's code. -# -# We cannot use [patch] to override serde-json-sgx's dependency to use -# the same tag for serde-sgx as here, because of this Cargo limitation: -# -# * "Cannot patch underspecified git dependency" -# https://github.com/rust-lang/cargo/issues/7670 -# -# Comment: https://github.com/rust-lang/cargo/issues/7670#issuecomment-841722488 -# -# To work around this problem, the git reference here must match -# the upstream dependency line exactly: -# -# * https://github.com/mesalock-linux/serde-json-sgx/blob/sgx_1.1.3/Cargo.toml#L17 -# +# See "Cargo patch limitation workaround" in HACKING.md: +once_cell = { git = "https://github.com/mesalock-linux/once_cell-sgx.git", optional = true } serde = { git = "https://github.com/mesalock-linux/serde-sgx", optional = true } - -serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx", tag = "sgx_1.1.3", optional = true } +serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx", optional = true } rtc_types = { path = "../rtc_types" } sgx_types = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda", features = ["extra_traits"] } From 8823abbb23dc5a43178834ce4ea1a5c31ba9446f Mon Sep 17 00:00:00 2001 From: Herman Date: Thu, 17 Jun 2021 15:12:09 +0200 Subject: [PATCH 03/14] feat(auth_enclave): add token issuance and persistence --- codegen/auth_enclave/bindings.h | 37 +++++++ rtc_auth_enclave/Cargo.lock | 156 +++++++++++++++++++++++++++- rtc_auth_enclave/Cargo.toml | 13 +++ rtc_auth_enclave/src/jwt.rs | 87 ++++++++++++++++ rtc_auth_enclave/src/lib.rs | 107 +++++++++++++++++++ rtc_auth_enclave/src/token_store.rs | 82 +++++++++++++++ rtc_tenclave/src/kv_store/fs/mod.rs | 3 + rtc_tenclave/src/kv_store/mod.rs | 2 +- rtc_types/src/exec_token.rs | 24 +++++ rtc_types/src/lib.rs | 2 + 10 files changed, 508 insertions(+), 5 deletions(-) create mode 100644 rtc_auth_enclave/src/jwt.rs create mode 100644 rtc_auth_enclave/src/token_store.rs diff --git a/codegen/auth_enclave/bindings.h b/codegen/auth_enclave/bindings.h index 949ef402..114708cc 100644 --- a/codegen/auth_enclave/bindings.h +++ b/codegen/auth_enclave/bindings.h @@ -18,6 +18,43 @@ #define SET_ACCESS_KEY_RESPONSE_SIZE 1 +typedef enum ExecTokenError { + EXEC_TOKEN_ERROR_GENERATE, + EXEC_TOKEN_ERROR_VALIDATION, + EXEC_TOKEN_ERROR_OUTPUT_BUFFER_SIZE, + EXEC_TOKEN_ERROR_CRYPTO, + EXEC_TOKEN_ERROR_IO, +} ExecTokenError; + +typedef uint8_t Nonce[24]; + +/** + * FFI safe result type that can be converted to and from a rust result. + */ +typedef enum EcallResult_Nonce__ExecTokenError_Tag { + ECALL_RESULT_NONCE_EXEC_TOKEN_ERROR_OK_NONCE_EXEC_TOKEN_ERROR, + ECALL_RESULT_NONCE_EXEC_TOKEN_ERROR_ERR_NONCE_EXEC_TOKEN_ERROR, +} EcallResult_Nonce__ExecTokenError_Tag; + +typedef struct EcallResult_Nonce__ExecTokenError { + EcallResult_Nonce__ExecTokenError_Tag tag; + union { + struct { + Nonce ok; + }; + struct { + enum ExecTokenError err; + }; + }; +} EcallResult_Nonce__ExecTokenError; + +typedef struct EcallResult_Nonce__ExecTokenError IssueTokenResult; + +typedef struct ExecReqMetadata { + uint8_t uploader_pub_key[32]; + uint8_t nonce[24]; +} ExecReqMetadata; + /** * FFI safe result type that can be converted to and from a rust result. */ diff --git a/rtc_auth_enclave/Cargo.lock b/rtc_auth_enclave/Cargo.lock index 3df12897..4514a368 100644 --- a/rtc_auth_enclave/Cargo.lock +++ b/rtc_auth_enclave/Cargo.lock @@ -22,12 +22,26 @@ dependencies = [ "winapi", ] +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "base64" +version = "0.13.0" +source = "git+https://github.com/mesalock-linux/rust-base64-sgx#dc7389e10817b078f289386b3b6a852ab6c4c021" +dependencies = [ + "sgx_tstd", +] + [[package]] name = "bitflags" version = "1.2.1" @@ -77,6 +91,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.11" +source = "git+https://github.com/mesalock-linux/chrono-sgx#f964ae7f5f65bd2c9cd6f44a067e7980afc08ca0" +dependencies = [ + "num-integer", + "num-traits", + "sgx_tstd", +] + [[package]] name = "clap" version = "2.33.3" @@ -161,7 +185,7 @@ version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" dependencies = [ - "autocfg", + "autocfg 1.0.1", "hashbrown", ] @@ -188,6 +212,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonwebtoken" +version = "7.2.0" +source = "git+https://github.com/mesalock-linux/jsonwebtoken-sgx#a110ccf3a7ee5c1e9ca8ba776c2f37fc960a4b5f" +dependencies = [ + "base64", + "pem", + "ring 0.16.19", + "serde 1.0.118", + "serde_json 1.0.60", + "sgx_tstd", + "simple_asn1", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -215,7 +253,37 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" dependencies = [ - "autocfg", + "autocfg 1.0.1", +] + +[[package]] +name = "num-bigint" +version = "0.2.5" +source = "git+https://github.com/mesalock-linux/num-bigint-sgx#76a5bed94dc31c32bd1670dbf72877abcf9bbc09" +dependencies = [ + "autocfg 1.0.1", + "num-integer", + "num-traits", + "sgx_tstd", +] + +[[package]] +name = "num-integer" +version = "0.1.41" +source = "git+https://github.com/mesalock-linux/num-integer-sgx#404c50e5378ca635261688b080dee328ff42b6bd" +dependencies = [ + "autocfg 0.1.7", + "num-traits", + "sgx_tstd", +] + +[[package]] +name = "num-traits" +version = "0.2.10" +source = "git+https://github.com/mesalock-linux/num-traits-sgx#af046e0b15c594c960007418097dd4ff37ec3f7a" +dependencies = [ + "autocfg 0.1.7", + "sgx_tstd", ] [[package]] @@ -232,6 +300,17 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +[[package]] +name = "pem" +version = "0.8.2" +source = "git+https://github.com/mesalock-linux/pem-rs-sgx#fdfef4f24a9fb3fa72e8a71bb28bd8ff15feff2f" +dependencies = [ + "base64", + "once_cell 1.4.0", + "regex", + "sgx_tstd", +] + [[package]] name = "ppv-lite86" version = "0.2.6" @@ -360,6 +439,23 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.3.1" +source = "git+https://github.com/mesalock-linux/regex-sgx#76aef86f9836532d17764523d0fa23bb7d2e31cf" +dependencies = [ + "regex-syntax", + "sgx_tstd", +] + +[[package]] +name = "regex-syntax" +version = "0.6.12" +source = "git+https://github.com/mesalock-linux/regex-sgx#76aef86f9836532d17764523d0fa23bb7d2e31cf" +dependencies = [ + "sgx_tstd", +] + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -369,6 +465,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "ring" +version = "0.16.19" +source = "git+https://github.com/mesalock-linux/ring-sgx?tag=v0.16.5#844efe271ed78a399d803b2579f5f2424d543c9f" +dependencies = [ + "cc", + "sgx_tstd", + "spin", + "untrusted", +] + [[package]] name = "ring" version = "0.17.0-alpha.10" @@ -410,12 +517,21 @@ dependencies = [ name = "rtc_auth_enclave" version = "0.1.0" dependencies = [ + "base64", "cbindgen", "cc", + "jsonwebtoken", + "once_cell 1.4.0", + "rand 0.7.3", "rtc_tenclave", "rtc_types", + "secrecy", + "serde 1.0.118", + "serde_json 1.0.60", + "sgx_tcrypto", "sgx_tstd", "sgx_types", + "uuid", ] [[package]] @@ -426,7 +542,7 @@ dependencies = [ "hex", "once_cell 1.4.0", "rand 0.7.3", - "ring", + "ring 0.17.0-alpha.10", "rkyv", "rtc_types", "secrecy", @@ -473,6 +589,7 @@ name = "serde" version = "1.0.118" source = "git+https://github.com/mesalock-linux/serde-sgx#db0226f1d5d70fca6b96af2c285851502204e21c" dependencies = [ + "serde_derive 1.0.118", "sgx_tstd", ] @@ -482,7 +599,17 @@ version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" dependencies = [ - "serde_derive", + "serde_derive 1.0.125", +] + +[[package]] +name = "serde_derive" +version = "1.0.118" +source = "git+https://github.com/mesalock-linux/serde-sgx#db0226f1d5d70fca6b96af2c285851502204e21c" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -625,6 +752,17 @@ dependencies = [ "sgx_build_helper", ] +[[package]] +name = "simple_asn1" +version = "0.5.0" +source = "git+https://github.com/mesalock-linux/simple_asn1-sgx#ba48e2390f14094e5a210ab7dc0421a9a86725d0" +dependencies = [ + "chrono", + "num-bigint", + "num-traits", + "sgx_tstd", +] + [[package]] name = "sodalite" version = "0.4.0" @@ -752,6 +890,16 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "uuid" +version = "0.8.1" +source = "git+https://github.com/mesalock-linux/uuid-sgx#9b425a8f07d5bb6e50b9a24414d11a59ec86617a" +dependencies = [ + "rand 0.7.3", + "serde 1.0.118", + "sgx_tstd", +] + [[package]] name = "vec_map" version = "0.8.2" diff --git a/rtc_auth_enclave/Cargo.toml b/rtc_auth_enclave/Cargo.toml index 3e702170..999bc7bf 100644 --- a/rtc_auth_enclave/Cargo.toml +++ b/rtc_auth_enclave/Cargo.toml @@ -15,8 +15,21 @@ cbindgen = "0.19.0" # See "Pinning SGX dependencies" in HACKING.md [target.'cfg(not(target_env = "sgx"))'.dependencies] +sgx_tcrypto = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda" } sgx_types = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda", features = ["extra_traits"] } sgx_tstd = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda", features = ["backtrace"] } +rand = { git = "https://github.com/mesalock-linux/rand-sgx", tag = "v0.7.3_sgx1.1.3" } +jsonwebtoken = { git = "https://github.com/mesalock-linux/jsonwebtoken-sgx" } +# TODO: confirm that we have to use a forked crate here +uuid = { git = "https://github.com/mesalock-linux/uuid-sgx", features = ["v4", "serde"] } +base64 = { git = "https://github.com/mesalock-linux/rust-base64-sgx" } + +# See "Cargo patch limitation workaround" in HACKING.md: +once_cell = { git = "https://github.com/mesalock-linux/once_cell-sgx.git" } +serde = { git = "https://github.com/mesalock-linux/serde-sgx", feature = ["derive"] } +serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } + +secrecy = { version = "0.7.0", default-features = false } rtc_types = { path = "../rtc_types", features = ["teaclave_sgx"] } diff --git a/rtc_auth_enclave/src/jwt.rs b/rtc_auth_enclave/src/jwt.rs new file mode 100644 index 00000000..8cb86637 --- /dev/null +++ b/rtc_auth_enclave/src/jwt.rs @@ -0,0 +1,87 @@ +use std::string::{String, ToString}; +use std::time::{SystemTime, UNIX_EPOCH}; + +use jsonwebtoken::{encode, EncodingKey, Header}; +use serde::{Deserialize, Serialize}; +use sgx_tstd::untrusted::time::SystemTimeEx; +use uuid::Uuid; + +use crate::uuid_to_string; + +/// Claims body of the JWT token +/// +/// Example output: +/// ``` +/// { +/// "iss": "registree_auth_enclave", +/// "nbf": 1623762799, +/// "iat": 1623762799, +/// "jti": "b300fe149d144e05aa9a9600816b42ca", +/// "exec_module_hash": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", +/// "dataset_uuid": "dd12012195c04ae8990ebd2512ae03ab" +/// } +/// ``` +#[derive(Debug, Serialize, Deserialize)] +struct Claims { + // TODO: serialize to hex string? This can be mrenclave or mrsigner + iss: String, + nbf: u64, + iat: u64, + jti: String, + // TODO: Better names. use `x-ntls-mod-hash` etc? + exec_module_hash: String, + dataset_uuid: String, +} + +impl Claims { + fn new(exec_module_hash: String, dataset_uuid: String, token_id: String) -> Self { + // TODO: Look at the attack vectors opened up by using untrusted system time + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("System time before UNIX Epoch") + .as_secs(); + + Self { + iss: "registree_auth_enclave".to_string(), + nbf: now, + iat: now, + jti: token_id, + exec_module_hash, + dataset_uuid, + } + } +} + +pub(crate) struct EncodedExecutionToken { + pub token: String, + pub token_id: Uuid, +} + +impl EncodedExecutionToken { + pub(crate) fn new(exec_module_hash: [u8; 32], dataset_uuid: Uuid) -> Self { + let token_id = Uuid::new_v4(); + + let claims = Claims::new( + base64::encode(exec_module_hash), + uuid_to_string(dataset_uuid), + uuid_to_string(token_id), + ); + + // TODO: Use a signing key that corresponds to the public key + // in the attestation enclave held data and move to crypto module in tenclave. + let encoding_key = EncodingKey::from_secret("secret".as_ref()); + // Header size 48 characters base64 + let header = Header { + // Explicit typing for the token type + // SEE: https://datatracker.ietf.org/doc/html/draft-ietf-secevent-token-02#section-2.2 + typ: Some("ntlexec+jwt".to_string()), + ..Header::default() + }; + + // Signature length: 44 + let token = encode(&header, &claims, &encoding_key) + .expect("encoding and signing execution token failed"); + + Self { token, token_id } + } +} diff --git a/rtc_auth_enclave/src/lib.rs b/rtc_auth_enclave/src/lib.rs index c1773a45..2319cbf9 100644 --- a/rtc_auth_enclave/src/lib.rs +++ b/rtc_auth_enclave/src/lib.rs @@ -3,9 +3,116 @@ #![deny(unsafe_op_in_unsafe_fn)] #![deny(clippy::mem_forget)] +mod jwt; +mod token_store; + #[cfg(not(target_env = "sgx"))] extern crate sgx_tstd as std; +use core::slice; +use std::ptr; +use std::string::{String, ToString}; + +use rtc_tenclave::crypto::{RtcCrypto, SodaBoxCrypto as Crypto}; pub use rtc_tenclave::dh::*; #[allow(unused_imports)] // for ECALL linking use rtc_tenclave::enclave::enclave_create_report; +use rtc_types::{EcallResult, EncryptedMessage, ExecReqMetadata, ExecTokenError, IssueTokenResult}; +use secrecy::{ExposeSecret, Secret}; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +#[derive(Serialize, Deserialize)] +pub struct ExecReqData { + dataset_uuid: [u8; 16], + dataset_access_key: [u8; 24], + exec_module_hash: [u8; 32], + number_of_uses: u32, +} + +pub type Nonce = [u8; 24]; + +/// Issue an execution token using the parameters defined in the payload. +/// +/// # Safety +/// This function expects +/// 1. `payload_ptr` to be valid for a slice of len `payload_len` +/// 2. `metadata_ptr` should be a valid pointer. +/// 3. An allocated buffer of size `out_token_len` that starts at `out_token_ptr` +/// The edge code from sgx must uphold the above. +#[no_mangle] +pub unsafe extern "C" fn issue_execution_token( + payload_ptr: *const u8, + payload_len: usize, + metadata_ptr: *const ExecReqMetadata, + out_token_ptr: *mut u8, + out_token_len: usize, +) -> IssueTokenResult { + let payload = unsafe { slice::from_raw_parts(payload_ptr, payload_len) }; + let metadata = unsafe { &*metadata_ptr }; + + match issue_execution_token_impl(payload, metadata, out_token_len) { + Ok(message) => { + assert_eq!(message.ciphertext.len(), out_token_len); + unsafe { + ptr::copy_nonoverlapping(message.ciphertext.as_ptr(), out_token_ptr, out_token_len); + } + EcallResult::Ok(message.nonce) + } + Err(err) => EcallResult::Err(err), + } +} + +fn issue_execution_token_impl( + payload: &[u8], + metadata: &ExecReqMetadata, + max_ciphertext_len: usize, +) -> Result { + // Ensure that the out token len is reasonable before proceeding + if max_ciphertext_len < 416 && max_ciphertext_len > 1000 { + return Err(ExecTokenError::OutputBufferSize); + } + + let mut crypto = Crypto::new(); + let message_bytes = + crypto.decrypt_message(payload, &metadata.uploader_pub_key, &metadata.nonce)?; + + let message: ExecReqData = serde_json::from_slice(message_bytes.expose_secret()) + .map_err(|_| ExecTokenError::Validation)?; + + if valid_dataset_access_key(message.dataset_uuid, message.dataset_access_key) { + let token = token_store::issue_token( + Uuid::from_bytes(message.dataset_uuid), + message.exec_module_hash, + message.number_of_uses, + )?; + + let mut token_vec = token.into_bytes(); + + if max_ciphertext_len < token_vec.len() - 16 { + return Err(ExecTokenError::OutputBufferSize); + } + + // TODO: Comment on how message size will be upheld + token_vec.resize(max_ciphertext_len - 16, 0); + + Ok(crypto.encrypt_message( + Secret::new(token_vec.into_boxed_slice()), + &metadata.uploader_pub_key, + )?) + + // TODO: Move this check before persistence + } else { + Err(ExecTokenError::Validation) + } +} + +fn valid_dataset_access_key(_dataset_uuid: [u8; 16], _access_key: [u8; 24]) -> bool { + // TODO: Check access key store to see if the request is valid + true +} + +pub(crate) fn uuid_to_string(uuid: Uuid) -> String { + let mut uuid_buf = Uuid::encode_buffer(); + uuid.to_simple().encode_lower(&mut uuid_buf).to_string() +} diff --git a/rtc_auth_enclave/src/token_store.rs b/rtc_auth_enclave/src/token_store.rs new file mode 100644 index 00000000..26c6874e --- /dev/null +++ b/rtc_auth_enclave/src/token_store.rs @@ -0,0 +1,82 @@ +use std::collections::HashMap; +use std::io; +use std::path::Path; +use std::string::String; + +use jwt::EncodedExecutionToken; +use once_cell::sync::OnceCell; +use rtc_tenclave::kv_store::fs::{FsStore, SgxFiler}; +use rtc_tenclave::kv_store::KvStore; +use serde::{Deserialize, Serialize}; +use sgx_tstd::sync::{SgxMutex as Mutex, SgxMutexGuard as MutexGuard}; +use sgx_tstd::untrusted::{fs as untrusted_fs, path as untrusted_path}; +use uuid::Uuid; + +use crate::{jwt, uuid_to_string}; + +#[derive(Serialize, Deserialize)] +struct ExecutionTokenRecord { + exec_module_hash: [u8; 32], + dataset_uuid: Uuid, + allowed_uses: u32, + current_uses: u32, +} + +fn kv_store<'a>( +) -> MutexGuard<'a, impl KvStore, Error = io::Error>> { + static TOKEN_FS_STORE: OnceCell>> = OnceCell::new(); + let store = TOKEN_FS_STORE.get_or_init(|| { + // TODO: Evaluate if this make sense, and what the possible attack vectors can be from relying on the + // untrusted fs and path functions. + let path = Path::new("./token_kv_store"); + if !untrusted_path::PathEx::exists(path) { + untrusted_fs::create_dir_all(path).expect("Failed to create token kv store directory"); + } + + Mutex::new(FsStore::new(path, SgxFiler)) + }); + store.lock().expect("FS store mutex poisoned") +} + +// Returns exec token hash +pub(crate) fn issue_token( + dataset_uuid: Uuid, + exec_module_hash: [u8; 32], + number_of_allowed_uses: u32, +) -> Result { + let EncodedExecutionToken { token, token_id } = + EncodedExecutionToken::new(exec_module_hash, dataset_uuid); + + save_token( + dataset_uuid, + token_id, + exec_module_hash, + number_of_allowed_uses, + )?; + + Ok(token) +} + +fn save_token( + dataset_uuid: Uuid, + token_uuid: Uuid, + exec_module_hash: [u8; 32], + number_of_allowed_uses: u32, +) -> Result<(), io::Error> { + let mut store = kv_store(); + let dataset_uuid_string = uuid_to_string(dataset_uuid); + let new_record = ExecutionTokenRecord { + dataset_uuid, + exec_module_hash, + allowed_uses: number_of_allowed_uses, + current_uses: 0u32, + }; + + store + .alter(&dataset_uuid_string, |records| { + let mut records = records.map_or(HashMap::new(), |r| r); + records.insert(token_uuid, new_record); + Some(records) + }) + .and(Ok(())) +} diff --git a/rtc_tenclave/src/kv_store/fs/mod.rs b/rtc_tenclave/src/kv_store/fs/mod.rs index c199a6f6..18968e1f 100644 --- a/rtc_tenclave/src/kv_store/fs/mod.rs +++ b/rtc_tenclave/src/kv_store/fs/mod.rs @@ -5,6 +5,9 @@ pub mod std_filer; #[cfg(not(test))] pub mod sgx_filer; +#[cfg(not(test))] +pub use sgx_filer::SgxFiler; + // sgx_tstd (v1.1.3) does not support `fs::read_dir`, so limit the following to tests, for now. // // See: https://github.com/apache/incubator-teaclave-sgx-sdk/blob/v1.1.3/release_notes.md#partially-supported-modstraits-in-sgx_tstd diff --git a/rtc_tenclave/src/kv_store/mod.rs b/rtc_tenclave/src/kv_store/mod.rs index 6985944e..2edd5901 100644 --- a/rtc_tenclave/src/kv_store/mod.rs +++ b/rtc_tenclave/src/kv_store/mod.rs @@ -1,6 +1,6 @@ //! Simple key-value store abstraction -mod fs; +pub mod fs; mod in_memory; /// A key-value store. diff --git a/rtc_types/src/exec_token.rs b/rtc_types/src/exec_token.rs index 494f46b9..9692c5dc 100644 --- a/rtc_types/src/exec_token.rs +++ b/rtc_types/src/exec_token.rs @@ -1,6 +1,10 @@ +use std::io; use std::vec::Vec; + use thiserror::Error; +use crate::{CryptoError, EcallResult, Nonce}; + #[repr(C)] #[derive(Debug)] pub struct ExecReqMetadata { @@ -15,6 +19,8 @@ pub struct ExecTokenResponse { pub nonce: [u8; 24], } +pub type IssueTokenResult = EcallResult; + #[repr(C)] #[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Debug, Error)] pub enum ExecTokenError { @@ -22,4 +28,22 @@ pub enum ExecTokenError { Generate, #[error("Data validation failed")] Validation, + #[error("Output token buffer is either to small or too large")] + OutputBufferSize, + #[error("Encryption/Decryption failed")] + Crypto, + #[error("IO operation failed")] + IO, +} + +impl From for ExecTokenError { + fn from(_: CryptoError) -> Self { + ExecTokenError::Crypto + } +} + +impl From for ExecTokenError { + fn from(_: io::Error) -> Self { + ExecTokenError::IO + } } diff --git a/rtc_types/src/lib.rs b/rtc_types/src/lib.rs index 9af98c19..e3c46650 100644 --- a/rtc_types/src/lib.rs +++ b/rtc_types/src/lib.rs @@ -32,6 +32,8 @@ pub use ecall_result::*; pub mod byte_formats; pub mod enclave_messages; +pub type Nonce = [u8; 24]; + #[repr(C)] #[derive(Clone, Debug)] pub struct EncryptedMessage { From 870764cc0a287eae352e56107162cace9a9e5064 Mon Sep 17 00:00:00 2001 From: Herman Date: Thu, 17 Jun 2021 16:30:23 +0200 Subject: [PATCH 04/14] feat(auth_enclave): generate bindings for token issuance --- codegen/auth_enclave/rtc_auth_t.c | 850 +++++++++++++++++++++++++++--- codegen/auth_enclave/rtc_auth_t.h | 11 + codegen/auth_enclave/rtc_auth_u.c | 190 ++++++- codegen/auth_enclave/rtc_auth_u.h | 41 ++ rtc_auth_enclave/rtc_auth.edl | 6 + 5 files changed, 1024 insertions(+), 74 deletions(-) diff --git a/codegen/auth_enclave/rtc_auth_t.c b/codegen/auth_enclave/rtc_auth_t.c index 81ff0a4b..aded6226 100644 --- a/codegen/auth_enclave/rtc_auth_t.c +++ b/codegen/auth_enclave/rtc_auth_t.c @@ -34,6 +34,15 @@ typedef struct ms_enclave_create_report_t { sgx_report_t* ms_p_report; } ms_enclave_create_report_t; +typedef struct ms_issue_execution_token_t { + IssueTokenResult ms_retval; + const uint8_t* ms_payload_ptr; + size_t ms_payload_len; + const ExecReqMetadata* ms_metadata; + uint8_t* ms_out_token_ptr; + size_t ms_out_token_len; +} ms_issue_execution_token_t; + typedef struct ms_t_global_init_ecall_t { uint64_t ms_id; const uint8_t* ms_path; @@ -501,6 +510,69 @@ typedef struct ms_sgx_thread_set_multiple_untrusted_events_ocall_t { size_t ms_total; } ms_sgx_thread_set_multiple_untrusted_events_ocall_t; +typedef struct ms_u_sgxprotectedfs_exclusive_file_open_t { + void* ms_retval; + const char* ms_filename; + uint8_t ms_read_only; + int64_t* ms_file_size; + int32_t* ms_error_code; +} ms_u_sgxprotectedfs_exclusive_file_open_t; + +typedef struct ms_u_sgxprotectedfs_check_if_file_exists_t { + uint8_t ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_check_if_file_exists_t; + +typedef struct ms_u_sgxprotectedfs_fread_node_t { + int32_t ms_retval; + void* ms_f; + uint64_t ms_node_number; + uint8_t* ms_buffer; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_fread_node_t; + +typedef struct ms_u_sgxprotectedfs_fwrite_node_t { + int32_t ms_retval; + void* ms_f; + uint64_t ms_node_number; + uint8_t* ms_buffer; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_fwrite_node_t; + +typedef struct ms_u_sgxprotectedfs_fclose_t { + int32_t ms_retval; + void* ms_f; +} ms_u_sgxprotectedfs_fclose_t; + +typedef struct ms_u_sgxprotectedfs_fflush_t { + uint8_t ms_retval; + void* ms_f; +} ms_u_sgxprotectedfs_fflush_t; + +typedef struct ms_u_sgxprotectedfs_remove_t { + int32_t ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_remove_t; + +typedef struct ms_u_sgxprotectedfs_recovery_file_open_t { + void* ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_recovery_file_open_t; + +typedef struct ms_u_sgxprotectedfs_fwrite_recovery_node_t { + uint8_t ms_retval; + void* ms_f; + uint8_t* ms_data; + uint32_t ms_data_length; +} ms_u_sgxprotectedfs_fwrite_recovery_node_t; + +typedef struct ms_u_sgxprotectedfs_do_file_recovery_t { + int32_t ms_retval; + const char* ms_filename; + const char* ms_recovery_filename; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_do_file_recovery_t; + static sgx_status_t SGX_CDECL sgx_enclave_create_report(void* pms) { CHECK_REF_POINTER(pms, sizeof(ms_enclave_create_report_t)); @@ -580,6 +652,106 @@ static sgx_status_t SGX_CDECL sgx_enclave_create_report(void* pms) return status; } +static sgx_status_t SGX_CDECL sgx_issue_execution_token(void* pms) +{ + CHECK_REF_POINTER(pms, sizeof(ms_issue_execution_token_t)); + // + // fence after pointer checks + // + sgx_lfence(); + ms_issue_execution_token_t* ms = SGX_CAST(ms_issue_execution_token_t*, pms); + sgx_status_t status = SGX_SUCCESS; + const uint8_t* _tmp_payload_ptr = ms->ms_payload_ptr; + size_t _tmp_payload_len = ms->ms_payload_len; + size_t _len_payload_ptr = _tmp_payload_len * sizeof(uint8_t); + uint8_t* _in_payload_ptr = NULL; + const ExecReqMetadata* _tmp_metadata = ms->ms_metadata; + size_t _len_metadata = sizeof(ExecReqMetadata); + ExecReqMetadata* _in_metadata = NULL; + uint8_t* _tmp_out_token_ptr = ms->ms_out_token_ptr; + size_t _tmp_out_token_len = ms->ms_out_token_len; + size_t _len_out_token_ptr = _tmp_out_token_len * sizeof(uint8_t); + uint8_t* _in_out_token_ptr = NULL; + + if (sizeof(*_tmp_payload_ptr) != 0 && + (size_t)_tmp_payload_len > (SIZE_MAX / sizeof(*_tmp_payload_ptr))) { + return SGX_ERROR_INVALID_PARAMETER; + } + + if (sizeof(*_tmp_out_token_ptr) != 0 && + (size_t)_tmp_out_token_len > (SIZE_MAX / sizeof(*_tmp_out_token_ptr))) { + return SGX_ERROR_INVALID_PARAMETER; + } + + CHECK_UNIQUE_POINTER(_tmp_payload_ptr, _len_payload_ptr); + CHECK_UNIQUE_POINTER(_tmp_metadata, _len_metadata); + CHECK_UNIQUE_POINTER(_tmp_out_token_ptr, _len_out_token_ptr); + + // + // fence after pointer checks + // + sgx_lfence(); + + if (_tmp_payload_ptr != NULL && _len_payload_ptr != 0) { + if ( _len_payload_ptr % sizeof(*_tmp_payload_ptr) != 0) + { + status = SGX_ERROR_INVALID_PARAMETER; + goto err; + } + _in_payload_ptr = (uint8_t*)malloc(_len_payload_ptr); + if (_in_payload_ptr == NULL) { + status = SGX_ERROR_OUT_OF_MEMORY; + goto err; + } + + if (memcpy_s(_in_payload_ptr, _len_payload_ptr, _tmp_payload_ptr, _len_payload_ptr)) { + status = SGX_ERROR_UNEXPECTED; + goto err; + } + + } + if (_tmp_metadata != NULL && _len_metadata != 0) { + _in_metadata = (ExecReqMetadata*)malloc(_len_metadata); + if (_in_metadata == NULL) { + status = SGX_ERROR_OUT_OF_MEMORY; + goto err; + } + + if (memcpy_s(_in_metadata, _len_metadata, _tmp_metadata, _len_metadata)) { + status = SGX_ERROR_UNEXPECTED; + goto err; + } + + } + if (_tmp_out_token_ptr != NULL && _len_out_token_ptr != 0) { + if ( _len_out_token_ptr % sizeof(*_tmp_out_token_ptr) != 0) + { + status = SGX_ERROR_INVALID_PARAMETER; + goto err; + } + if ((_in_out_token_ptr = (uint8_t*)malloc(_len_out_token_ptr)) == NULL) { + status = SGX_ERROR_OUT_OF_MEMORY; + goto err; + } + + memset((void*)_in_out_token_ptr, 0, _len_out_token_ptr); + } + + ms->ms_retval = issue_execution_token((const uint8_t*)_in_payload_ptr, _tmp_payload_len, (const ExecReqMetadata*)_in_metadata, _in_out_token_ptr, _tmp_out_token_len); + if (_in_out_token_ptr) { + if (memcpy_s(_tmp_out_token_ptr, _len_out_token_ptr, _in_out_token_ptr, _len_out_token_ptr)) { + status = SGX_ERROR_UNEXPECTED; + goto err; + } + } + +err: + if (_in_payload_ptr) free(_in_payload_ptr); + if (_in_metadata) free(_in_metadata); + if (_in_out_token_ptr) free(_in_out_token_ptr); + return status; +} + static sgx_status_t SGX_CDECL sgx_t_global_init_ecall(void* pms) { CHECK_REF_POINTER(pms, sizeof(ms_t_global_init_ecall_t)); @@ -714,11 +886,12 @@ static sgx_status_t SGX_CDECL sgx_end_session(void* pms) SGX_EXTERNC const struct { size_t nr_ecall; - struct {void* ecall_addr; uint8_t is_priv; uint8_t is_switchless;} ecall_table[6]; + struct {void* ecall_addr; uint8_t is_priv; uint8_t is_switchless;} ecall_table[7]; } g_ecall_table = { - 6, + 7, { {(void*)(uintptr_t)sgx_enclave_create_report, 0, 0}, + {(void*)(uintptr_t)sgx_issue_execution_token, 0, 0}, {(void*)(uintptr_t)sgx_t_global_init_ecall, 0, 0}, {(void*)(uintptr_t)sgx_t_global_exit_ecall, 0, 0}, {(void*)(uintptr_t)sgx_session_request, 0, 0}, @@ -729,73 +902,83 @@ SGX_EXTERNC const struct { SGX_EXTERNC const struct { size_t nr_ocall; - uint8_t entry_table[63][6]; + uint8_t entry_table[73][7]; } g_dyn_entry_table = { - 63, + 73, { - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, - {0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, + {0, 0, 0, 0, 0, 0, 0, }, } }; @@ -4923,3 +5106,536 @@ sgx_status_t SGX_CDECL sgx_thread_set_multiple_untrusted_events_ocall(int* retva return status; } +sgx_status_t SGX_CDECL u_sgxprotectedfs_exclusive_file_open(void** retval, const char* filename, uint8_t read_only, int64_t* file_size, int32_t* error_code) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_filename = filename ? strlen(filename) + 1 : 0; + size_t _len_file_size = sizeof(int64_t); + size_t _len_error_code = sizeof(int32_t); + + ms_u_sgxprotectedfs_exclusive_file_open_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_exclusive_file_open_t); + void *__tmp = NULL; + + void *__tmp_file_size = NULL; + void *__tmp_error_code = NULL; + + CHECK_ENCLAVE_POINTER(filename, _len_filename); + CHECK_ENCLAVE_POINTER(file_size, _len_file_size); + CHECK_ENCLAVE_POINTER(error_code, _len_error_code); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (filename != NULL) ? _len_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (file_size != NULL) ? _len_file_size : 0)) + return SGX_ERROR_INVALID_PARAMETER; + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (error_code != NULL) ? _len_error_code : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_exclusive_file_open_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_exclusive_file_open_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_exclusive_file_open_t); + + if (filename != NULL) { + ms->ms_filename = (const char*)__tmp; + if (_len_filename % sizeof(*filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, filename, _len_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_filename); + ocalloc_size -= _len_filename; + } else { + ms->ms_filename = NULL; + } + + ms->ms_read_only = read_only; + if (file_size != NULL) { + ms->ms_file_size = (int64_t*)__tmp; + __tmp_file_size = __tmp; + if (_len_file_size % sizeof(*file_size) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + memset(__tmp_file_size, 0, _len_file_size); + __tmp = (void *)((size_t)__tmp + _len_file_size); + ocalloc_size -= _len_file_size; + } else { + ms->ms_file_size = NULL; + } + + if (error_code != NULL) { + ms->ms_error_code = (int32_t*)__tmp; + __tmp_error_code = __tmp; + if (_len_error_code % sizeof(*error_code) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + memset(__tmp_error_code, 0, _len_error_code); + __tmp = (void *)((size_t)__tmp + _len_error_code); + ocalloc_size -= _len_error_code; + } else { + ms->ms_error_code = NULL; + } + + status = sgx_ocall(63, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + if (file_size) { + if (memcpy_s((void*)file_size, _len_file_size, __tmp_file_size, _len_file_size)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + } + if (error_code) { + if (memcpy_s((void*)error_code, _len_error_code, __tmp_error_code, _len_error_code)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + } + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_check_if_file_exists(uint8_t* retval, const char* filename) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_filename = filename ? strlen(filename) + 1 : 0; + + ms_u_sgxprotectedfs_check_if_file_exists_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_check_if_file_exists_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(filename, _len_filename); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (filename != NULL) ? _len_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_check_if_file_exists_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_check_if_file_exists_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_check_if_file_exists_t); + + if (filename != NULL) { + ms->ms_filename = (const char*)__tmp; + if (_len_filename % sizeof(*filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, filename, _len_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_filename); + ocalloc_size -= _len_filename; + } else { + ms->ms_filename = NULL; + } + + status = sgx_ocall(64, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_fread_node(int32_t* retval, void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_buffer = node_size; + + ms_u_sgxprotectedfs_fread_node_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_fread_node_t); + void *__tmp = NULL; + + void *__tmp_buffer = NULL; + + CHECK_ENCLAVE_POINTER(buffer, _len_buffer); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (buffer != NULL) ? _len_buffer : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_fread_node_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_fread_node_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_fread_node_t); + + ms->ms_f = f; + ms->ms_node_number = node_number; + if (buffer != NULL) { + ms->ms_buffer = (uint8_t*)__tmp; + __tmp_buffer = __tmp; + if (_len_buffer % sizeof(*buffer) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + memset(__tmp_buffer, 0, _len_buffer); + __tmp = (void *)((size_t)__tmp + _len_buffer); + ocalloc_size -= _len_buffer; + } else { + ms->ms_buffer = NULL; + } + + ms->ms_node_size = node_size; + status = sgx_ocall(65, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + if (buffer) { + if (memcpy_s((void*)buffer, _len_buffer, __tmp_buffer, _len_buffer)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + } + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_fwrite_node(int32_t* retval, void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_buffer = node_size; + + ms_u_sgxprotectedfs_fwrite_node_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_fwrite_node_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(buffer, _len_buffer); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (buffer != NULL) ? _len_buffer : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_fwrite_node_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_fwrite_node_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_fwrite_node_t); + + ms->ms_f = f; + ms->ms_node_number = node_number; + if (buffer != NULL) { + ms->ms_buffer = (uint8_t*)__tmp; + if (_len_buffer % sizeof(*buffer) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, buffer, _len_buffer)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_buffer); + ocalloc_size -= _len_buffer; + } else { + ms->ms_buffer = NULL; + } + + ms->ms_node_size = node_size; + status = sgx_ocall(66, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_fclose(int32_t* retval, void* f) +{ + sgx_status_t status = SGX_SUCCESS; + + ms_u_sgxprotectedfs_fclose_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_fclose_t); + void *__tmp = NULL; + + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_fclose_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_fclose_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_fclose_t); + + ms->ms_f = f; + status = sgx_ocall(67, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_fflush(uint8_t* retval, void* f) +{ + sgx_status_t status = SGX_SUCCESS; + + ms_u_sgxprotectedfs_fflush_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_fflush_t); + void *__tmp = NULL; + + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_fflush_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_fflush_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_fflush_t); + + ms->ms_f = f; + status = sgx_ocall(68, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_remove(int32_t* retval, const char* filename) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_filename = filename ? strlen(filename) + 1 : 0; + + ms_u_sgxprotectedfs_remove_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_remove_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(filename, _len_filename); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (filename != NULL) ? _len_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_remove_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_remove_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_remove_t); + + if (filename != NULL) { + ms->ms_filename = (const char*)__tmp; + if (_len_filename % sizeof(*filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, filename, _len_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_filename); + ocalloc_size -= _len_filename; + } else { + ms->ms_filename = NULL; + } + + status = sgx_ocall(69, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_recovery_file_open(void** retval, const char* filename) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_filename = filename ? strlen(filename) + 1 : 0; + + ms_u_sgxprotectedfs_recovery_file_open_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_recovery_file_open_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(filename, _len_filename); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (filename != NULL) ? _len_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_recovery_file_open_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_recovery_file_open_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_recovery_file_open_t); + + if (filename != NULL) { + ms->ms_filename = (const char*)__tmp; + if (_len_filename % sizeof(*filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, filename, _len_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_filename); + ocalloc_size -= _len_filename; + } else { + ms->ms_filename = NULL; + } + + status = sgx_ocall(70, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_fwrite_recovery_node(uint8_t* retval, void* f, uint8_t* data, uint32_t data_length) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_data = data_length * sizeof(uint8_t); + + ms_u_sgxprotectedfs_fwrite_recovery_node_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_fwrite_recovery_node_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(data, _len_data); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (data != NULL) ? _len_data : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_fwrite_recovery_node_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_fwrite_recovery_node_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_fwrite_recovery_node_t); + + ms->ms_f = f; + if (data != NULL) { + ms->ms_data = (uint8_t*)__tmp; + if (_len_data % sizeof(*data) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, data, _len_data)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_data); + ocalloc_size -= _len_data; + } else { + ms->ms_data = NULL; + } + + ms->ms_data_length = data_length; + status = sgx_ocall(71, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + +sgx_status_t SGX_CDECL u_sgxprotectedfs_do_file_recovery(int32_t* retval, const char* filename, const char* recovery_filename, uint32_t node_size) +{ + sgx_status_t status = SGX_SUCCESS; + size_t _len_filename = filename ? strlen(filename) + 1 : 0; + size_t _len_recovery_filename = recovery_filename ? strlen(recovery_filename) + 1 : 0; + + ms_u_sgxprotectedfs_do_file_recovery_t* ms = NULL; + size_t ocalloc_size = sizeof(ms_u_sgxprotectedfs_do_file_recovery_t); + void *__tmp = NULL; + + + CHECK_ENCLAVE_POINTER(filename, _len_filename); + CHECK_ENCLAVE_POINTER(recovery_filename, _len_recovery_filename); + + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (filename != NULL) ? _len_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + if (ADD_ASSIGN_OVERFLOW(ocalloc_size, (recovery_filename != NULL) ? _len_recovery_filename : 0)) + return SGX_ERROR_INVALID_PARAMETER; + + __tmp = sgx_ocalloc(ocalloc_size); + if (__tmp == NULL) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + ms = (ms_u_sgxprotectedfs_do_file_recovery_t*)__tmp; + __tmp = (void *)((size_t)__tmp + sizeof(ms_u_sgxprotectedfs_do_file_recovery_t)); + ocalloc_size -= sizeof(ms_u_sgxprotectedfs_do_file_recovery_t); + + if (filename != NULL) { + ms->ms_filename = (const char*)__tmp; + if (_len_filename % sizeof(*filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, filename, _len_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_filename); + ocalloc_size -= _len_filename; + } else { + ms->ms_filename = NULL; + } + + if (recovery_filename != NULL) { + ms->ms_recovery_filename = (const char*)__tmp; + if (_len_recovery_filename % sizeof(*recovery_filename) != 0) { + sgx_ocfree(); + return SGX_ERROR_INVALID_PARAMETER; + } + if (memcpy_s(__tmp, ocalloc_size, recovery_filename, _len_recovery_filename)) { + sgx_ocfree(); + return SGX_ERROR_UNEXPECTED; + } + __tmp = (void *)((size_t)__tmp + _len_recovery_filename); + ocalloc_size -= _len_recovery_filename; + } else { + ms->ms_recovery_filename = NULL; + } + + ms->ms_node_size = node_size; + status = sgx_ocall(72, ms); + + if (status == SGX_SUCCESS) { + if (retval) *retval = ms->ms_retval; + } + sgx_ocfree(); + return status; +} + diff --git a/codegen/auth_enclave/rtc_auth_t.h b/codegen/auth_enclave/rtc_auth_t.h index d69a044b..0a35d1fd 100644 --- a/codegen/auth_enclave/rtc_auth_t.h +++ b/codegen/auth_enclave/rtc_auth_t.h @@ -26,6 +26,7 @@ extern "C" { #endif CreateReportResult enclave_create_report(const sgx_target_info_t* p_qe3_target, EnclaveHeldData enclave_data, sgx_report_t* p_report); +IssueTokenResult issue_execution_token(const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_len); void t_global_init_ecall(uint64_t id, const uint8_t* path, size_t len); void t_global_exit_ecall(void); SessionRequestResult session_request(sgx_enclave_id_t src_enclave_id); @@ -95,6 +96,16 @@ sgx_status_t SGX_CDECL sgx_thread_wait_untrusted_event_ocall(int* retval, const sgx_status_t SGX_CDECL sgx_thread_set_untrusted_event_ocall(int* retval, const void* waiter); sgx_status_t SGX_CDECL sgx_thread_setwait_untrusted_events_ocall(int* retval, const void* waiter, const void* self); sgx_status_t SGX_CDECL sgx_thread_set_multiple_untrusted_events_ocall(int* retval, const void** waiters, size_t total); +sgx_status_t SGX_CDECL u_sgxprotectedfs_exclusive_file_open(void** retval, const char* filename, uint8_t read_only, int64_t* file_size, int32_t* error_code); +sgx_status_t SGX_CDECL u_sgxprotectedfs_check_if_file_exists(uint8_t* retval, const char* filename); +sgx_status_t SGX_CDECL u_sgxprotectedfs_fread_node(int32_t* retval, void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size); +sgx_status_t SGX_CDECL u_sgxprotectedfs_fwrite_node(int32_t* retval, void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size); +sgx_status_t SGX_CDECL u_sgxprotectedfs_fclose(int32_t* retval, void* f); +sgx_status_t SGX_CDECL u_sgxprotectedfs_fflush(uint8_t* retval, void* f); +sgx_status_t SGX_CDECL u_sgxprotectedfs_remove(int32_t* retval, const char* filename); +sgx_status_t SGX_CDECL u_sgxprotectedfs_recovery_file_open(void** retval, const char* filename); +sgx_status_t SGX_CDECL u_sgxprotectedfs_fwrite_recovery_node(uint8_t* retval, void* f, uint8_t* data, uint32_t data_length); +sgx_status_t SGX_CDECL u_sgxprotectedfs_do_file_recovery(int32_t* retval, const char* filename, const char* recovery_filename, uint32_t node_size); #ifdef __cplusplus } diff --git a/codegen/auth_enclave/rtc_auth_u.c b/codegen/auth_enclave/rtc_auth_u.c index 35caa9bf..9e68ae1a 100644 --- a/codegen/auth_enclave/rtc_auth_u.c +++ b/codegen/auth_enclave/rtc_auth_u.c @@ -8,6 +8,15 @@ typedef struct ms_enclave_create_report_t { sgx_report_t* ms_p_report; } ms_enclave_create_report_t; +typedef struct ms_issue_execution_token_t { + IssueTokenResult ms_retval; + const uint8_t* ms_payload_ptr; + size_t ms_payload_len; + const ExecReqMetadata* ms_metadata; + uint8_t* ms_out_token_ptr; + size_t ms_out_token_len; +} ms_issue_execution_token_t; + typedef struct ms_t_global_init_ecall_t { uint64_t ms_id; const uint8_t* ms_path; @@ -475,6 +484,69 @@ typedef struct ms_sgx_thread_set_multiple_untrusted_events_ocall_t { size_t ms_total; } ms_sgx_thread_set_multiple_untrusted_events_ocall_t; +typedef struct ms_u_sgxprotectedfs_exclusive_file_open_t { + void* ms_retval; + const char* ms_filename; + uint8_t ms_read_only; + int64_t* ms_file_size; + int32_t* ms_error_code; +} ms_u_sgxprotectedfs_exclusive_file_open_t; + +typedef struct ms_u_sgxprotectedfs_check_if_file_exists_t { + uint8_t ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_check_if_file_exists_t; + +typedef struct ms_u_sgxprotectedfs_fread_node_t { + int32_t ms_retval; + void* ms_f; + uint64_t ms_node_number; + uint8_t* ms_buffer; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_fread_node_t; + +typedef struct ms_u_sgxprotectedfs_fwrite_node_t { + int32_t ms_retval; + void* ms_f; + uint64_t ms_node_number; + uint8_t* ms_buffer; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_fwrite_node_t; + +typedef struct ms_u_sgxprotectedfs_fclose_t { + int32_t ms_retval; + void* ms_f; +} ms_u_sgxprotectedfs_fclose_t; + +typedef struct ms_u_sgxprotectedfs_fflush_t { + uint8_t ms_retval; + void* ms_f; +} ms_u_sgxprotectedfs_fflush_t; + +typedef struct ms_u_sgxprotectedfs_remove_t { + int32_t ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_remove_t; + +typedef struct ms_u_sgxprotectedfs_recovery_file_open_t { + void* ms_retval; + const char* ms_filename; +} ms_u_sgxprotectedfs_recovery_file_open_t; + +typedef struct ms_u_sgxprotectedfs_fwrite_recovery_node_t { + uint8_t ms_retval; + void* ms_f; + uint8_t* ms_data; + uint32_t ms_data_length; +} ms_u_sgxprotectedfs_fwrite_recovery_node_t; + +typedef struct ms_u_sgxprotectedfs_do_file_recovery_t { + int32_t ms_retval; + const char* ms_filename; + const char* ms_recovery_filename; + uint32_t ms_node_size; +} ms_u_sgxprotectedfs_do_file_recovery_t; + static sgx_status_t SGX_CDECL rtc_auth_u_thread_set_event_ocall(void* pms) { ms_u_thread_set_event_ocall_t* ms = SGX_CAST(ms_u_thread_set_event_ocall_t*, pms); @@ -979,11 +1051,91 @@ static sgx_status_t SGX_CDECL rtc_auth_sgx_thread_set_multiple_untrusted_events_ return SGX_SUCCESS; } +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_exclusive_file_open(void* pms) +{ + ms_u_sgxprotectedfs_exclusive_file_open_t* ms = SGX_CAST(ms_u_sgxprotectedfs_exclusive_file_open_t*, pms); + ms->ms_retval = u_sgxprotectedfs_exclusive_file_open(ms->ms_filename, ms->ms_read_only, ms->ms_file_size, ms->ms_error_code); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_check_if_file_exists(void* pms) +{ + ms_u_sgxprotectedfs_check_if_file_exists_t* ms = SGX_CAST(ms_u_sgxprotectedfs_check_if_file_exists_t*, pms); + ms->ms_retval = u_sgxprotectedfs_check_if_file_exists(ms->ms_filename); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_fread_node(void* pms) +{ + ms_u_sgxprotectedfs_fread_node_t* ms = SGX_CAST(ms_u_sgxprotectedfs_fread_node_t*, pms); + ms->ms_retval = u_sgxprotectedfs_fread_node(ms->ms_f, ms->ms_node_number, ms->ms_buffer, ms->ms_node_size); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_fwrite_node(void* pms) +{ + ms_u_sgxprotectedfs_fwrite_node_t* ms = SGX_CAST(ms_u_sgxprotectedfs_fwrite_node_t*, pms); + ms->ms_retval = u_sgxprotectedfs_fwrite_node(ms->ms_f, ms->ms_node_number, ms->ms_buffer, ms->ms_node_size); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_fclose(void* pms) +{ + ms_u_sgxprotectedfs_fclose_t* ms = SGX_CAST(ms_u_sgxprotectedfs_fclose_t*, pms); + ms->ms_retval = u_sgxprotectedfs_fclose(ms->ms_f); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_fflush(void* pms) +{ + ms_u_sgxprotectedfs_fflush_t* ms = SGX_CAST(ms_u_sgxprotectedfs_fflush_t*, pms); + ms->ms_retval = u_sgxprotectedfs_fflush(ms->ms_f); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_remove(void* pms) +{ + ms_u_sgxprotectedfs_remove_t* ms = SGX_CAST(ms_u_sgxprotectedfs_remove_t*, pms); + ms->ms_retval = u_sgxprotectedfs_remove(ms->ms_filename); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_recovery_file_open(void* pms) +{ + ms_u_sgxprotectedfs_recovery_file_open_t* ms = SGX_CAST(ms_u_sgxprotectedfs_recovery_file_open_t*, pms); + ms->ms_retval = u_sgxprotectedfs_recovery_file_open(ms->ms_filename); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_fwrite_recovery_node(void* pms) +{ + ms_u_sgxprotectedfs_fwrite_recovery_node_t* ms = SGX_CAST(ms_u_sgxprotectedfs_fwrite_recovery_node_t*, pms); + ms->ms_retval = u_sgxprotectedfs_fwrite_recovery_node(ms->ms_f, ms->ms_data, ms->ms_data_length); + + return SGX_SUCCESS; +} + +static sgx_status_t SGX_CDECL rtc_auth_u_sgxprotectedfs_do_file_recovery(void* pms) +{ + ms_u_sgxprotectedfs_do_file_recovery_t* ms = SGX_CAST(ms_u_sgxprotectedfs_do_file_recovery_t*, pms); + ms->ms_retval = u_sgxprotectedfs_do_file_recovery(ms->ms_filename, ms->ms_recovery_filename, ms->ms_node_size); + + return SGX_SUCCESS; +} + static const struct { size_t nr_ocall; - void * table[63]; + void * table[73]; } ocall_table_rtc_auth = { - 63, + 73, { (void*)rtc_auth_u_thread_set_event_ocall, (void*)rtc_auth_u_thread_wait_event_ocall, @@ -1048,6 +1200,16 @@ static const struct { (void*)rtc_auth_sgx_thread_set_untrusted_event_ocall, (void*)rtc_auth_sgx_thread_setwait_untrusted_events_ocall, (void*)rtc_auth_sgx_thread_set_multiple_untrusted_events_ocall, + (void*)rtc_auth_u_sgxprotectedfs_exclusive_file_open, + (void*)rtc_auth_u_sgxprotectedfs_check_if_file_exists, + (void*)rtc_auth_u_sgxprotectedfs_fread_node, + (void*)rtc_auth_u_sgxprotectedfs_fwrite_node, + (void*)rtc_auth_u_sgxprotectedfs_fclose, + (void*)rtc_auth_u_sgxprotectedfs_fflush, + (void*)rtc_auth_u_sgxprotectedfs_remove, + (void*)rtc_auth_u_sgxprotectedfs_recovery_file_open, + (void*)rtc_auth_u_sgxprotectedfs_fwrite_recovery_node, + (void*)rtc_auth_u_sgxprotectedfs_do_file_recovery, } }; sgx_status_t rtc_auth_enclave_create_report(sgx_enclave_id_t eid, CreateReportResult* retval, const sgx_target_info_t* p_qe3_target, EnclaveHeldData enclave_data, sgx_report_t* p_report) @@ -1062,6 +1224,20 @@ sgx_status_t rtc_auth_enclave_create_report(sgx_enclave_id_t eid, CreateReportRe return status; } +sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_len) +{ + sgx_status_t status; + ms_issue_execution_token_t ms; + ms.ms_payload_ptr = payload_ptr; + ms.ms_payload_len = payload_len; + ms.ms_metadata = metadata; + ms.ms_out_token_ptr = out_token_ptr; + ms.ms_out_token_len = out_token_len; + status = sgx_ecall(eid, 1, &ocall_table_rtc_auth, &ms); + if (status == SGX_SUCCESS && retval) *retval = ms.ms_retval; + return status; +} + sgx_status_t rtc_auth_t_global_init_ecall(sgx_enclave_id_t eid, uint64_t id, const uint8_t* path, size_t len) { sgx_status_t status; @@ -1069,14 +1245,14 @@ sgx_status_t rtc_auth_t_global_init_ecall(sgx_enclave_id_t eid, uint64_t id, con ms.ms_id = id; ms.ms_path = path; ms.ms_len = len; - status = sgx_ecall(eid, 1, &ocall_table_rtc_auth, &ms); + status = sgx_ecall(eid, 2, &ocall_table_rtc_auth, &ms); return status; } sgx_status_t rtc_auth_t_global_exit_ecall(sgx_enclave_id_t eid) { sgx_status_t status; - status = sgx_ecall(eid, 2, &ocall_table_rtc_auth, NULL); + status = sgx_ecall(eid, 3, &ocall_table_rtc_auth, NULL); return status; } @@ -1085,7 +1261,7 @@ sgx_status_t rtc_auth_session_request(sgx_enclave_id_t eid, SessionRequestResult sgx_status_t status; ms_session_request_t ms; ms.ms_src_enclave_id = src_enclave_id; - status = sgx_ecall(eid, 3, &ocall_table_rtc_auth, &ms); + status = sgx_ecall(eid, 4, &ocall_table_rtc_auth, &ms); if (status == SGX_SUCCESS && retval) *retval = ms.ms_retval; return status; } @@ -1096,7 +1272,7 @@ sgx_status_t rtc_auth_exchange_report(sgx_enclave_id_t eid, ExchangeReportResult ms_exchange_report_t ms; ms.ms_src_enclave_id = src_enclave_id; ms.ms_dh_msg2 = dh_msg2; - status = sgx_ecall(eid, 4, &ocall_table_rtc_auth, &ms); + status = sgx_ecall(eid, 5, &ocall_table_rtc_auth, &ms); if (status == SGX_SUCCESS && retval) *retval = ms.ms_retval; return status; } @@ -1106,7 +1282,7 @@ sgx_status_t rtc_auth_end_session(sgx_enclave_id_t eid, sgx_status_t* retval, sg sgx_status_t status; ms_end_session_t ms; ms.ms_src_enclave_id = src_enclave_id; - status = sgx_ecall(eid, 5, &ocall_table_rtc_auth, &ms); + status = sgx_ecall(eid, 6, &ocall_table_rtc_auth, &ms); if (status == SGX_SUCCESS && retval) *retval = ms.ms_retval; return status; } diff --git a/codegen/auth_enclave/rtc_auth_u.h b/codegen/auth_enclave/rtc_auth_u.h index c3a5bcec..cb3723d2 100644 --- a/codegen/auth_enclave/rtc_auth_u.h +++ b/codegen/auth_enclave/rtc_auth_u.h @@ -278,8 +278,49 @@ int SGX_UBRIDGE(SGX_CDECL, sgx_thread_setwait_untrusted_events_ocall, (const voi #define SGX_THREAD_SET_MULTIPLE_UNTRUSTED_EVENTS_OCALL_DEFINED__ int SGX_UBRIDGE(SGX_CDECL, sgx_thread_set_multiple_untrusted_events_ocall, (const void** waiters, size_t total)); #endif +#ifndef U_SGXPROTECTEDFS_EXCLUSIVE_FILE_OPEN_DEFINED__ +#define U_SGXPROTECTEDFS_EXCLUSIVE_FILE_OPEN_DEFINED__ +void* SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_exclusive_file_open, (const char* filename, uint8_t read_only, int64_t* file_size, int32_t* error_code)); +#endif +#ifndef U_SGXPROTECTEDFS_CHECK_IF_FILE_EXISTS_DEFINED__ +#define U_SGXPROTECTEDFS_CHECK_IF_FILE_EXISTS_DEFINED__ +uint8_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_check_if_file_exists, (const char* filename)); +#endif +#ifndef U_SGXPROTECTEDFS_FREAD_NODE_DEFINED__ +#define U_SGXPROTECTEDFS_FREAD_NODE_DEFINED__ +int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_fread_node, (void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size)); +#endif +#ifndef U_SGXPROTECTEDFS_FWRITE_NODE_DEFINED__ +#define U_SGXPROTECTEDFS_FWRITE_NODE_DEFINED__ +int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_fwrite_node, (void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size)); +#endif +#ifndef U_SGXPROTECTEDFS_FCLOSE_DEFINED__ +#define U_SGXPROTECTEDFS_FCLOSE_DEFINED__ +int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_fclose, (void* f)); +#endif +#ifndef U_SGXPROTECTEDFS_FFLUSH_DEFINED__ +#define U_SGXPROTECTEDFS_FFLUSH_DEFINED__ +uint8_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_fflush, (void* f)); +#endif +#ifndef U_SGXPROTECTEDFS_REMOVE_DEFINED__ +#define U_SGXPROTECTEDFS_REMOVE_DEFINED__ +int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_remove, (const char* filename)); +#endif +#ifndef U_SGXPROTECTEDFS_RECOVERY_FILE_OPEN_DEFINED__ +#define U_SGXPROTECTEDFS_RECOVERY_FILE_OPEN_DEFINED__ +void* SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_recovery_file_open, (const char* filename)); +#endif +#ifndef U_SGXPROTECTEDFS_FWRITE_RECOVERY_NODE_DEFINED__ +#define U_SGXPROTECTEDFS_FWRITE_RECOVERY_NODE_DEFINED__ +uint8_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_fwrite_recovery_node, (void* f, uint8_t* data, uint32_t data_length)); +#endif +#ifndef U_SGXPROTECTEDFS_DO_FILE_RECOVERY_DEFINED__ +#define U_SGXPROTECTEDFS_DO_FILE_RECOVERY_DEFINED__ +int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_do_file_recovery, (const char* filename, const char* recovery_filename, uint32_t node_size)); +#endif sgx_status_t rtc_auth_enclave_create_report(sgx_enclave_id_t eid, CreateReportResult* retval, const sgx_target_info_t* p_qe3_target, EnclaveHeldData enclave_data, sgx_report_t* p_report); +sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_len); sgx_status_t rtc_auth_t_global_init_ecall(sgx_enclave_id_t eid, uint64_t id, const uint8_t* path, size_t len); sgx_status_t rtc_auth_t_global_exit_ecall(sgx_enclave_id_t eid); sgx_status_t rtc_auth_session_request(sgx_enclave_id_t eid, SessionRequestResult* retval, sgx_enclave_id_t src_enclave_id); diff --git a/rtc_auth_enclave/rtc_auth.edl b/rtc_auth_enclave/rtc_auth.edl index 7a84afc0..f046e905 100644 --- a/rtc_auth_enclave/rtc_auth.edl +++ b/rtc_auth_enclave/rtc_auth.edl @@ -2,6 +2,7 @@ enclave { from "sgx_tstd.edl" import *; from "sgx_backtrace.edl" import *; from "rtc_tenclave.edl" import *; + from "sgx_tprotected_fs.edl" import *; include "sgx_report.h" include "sgx_dh.h" @@ -12,5 +13,10 @@ enclave { public CreateReportResult enclave_create_report([in]const sgx_target_info_t* p_qe3_target, [out, isary]EnclaveHeldData enclave_data, [out]sgx_report_t* p_report); + public IssueTokenResult issue_execution_token([in, count=payload_len]const uint8_t* payload_ptr, + size_t payload_len, + [in]const ExecReqMetadata* metadata, + [out, count=out_token_len]uint8_t* out_token_ptr, + size_t out_token_len); }; }; From 38659590d8de10b7633b9fd96a4e1805a32de088 Mon Sep 17 00:00:00 2001 From: Herman Date: Thu, 17 Jun 2021 16:14:51 +0200 Subject: [PATCH 05/14] feat(uenclave): add token issuance functions for auth enclave --- rtc_uenclave/src/enclaves/rtc_auth.rs | 46 +++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/rtc_uenclave/src/enclaves/rtc_auth.rs b/rtc_uenclave/src/enclaves/rtc_auth.rs index 8a65ee3d..2b47bf54 100644 --- a/rtc_uenclave/src/enclaves/rtc_auth.rs +++ b/rtc_uenclave/src/enclaves/rtc_auth.rs @@ -2,6 +2,7 @@ use std::borrow::Borrow; use crate::{AttestationError, EnclaveConfig, EnclaveReportResult, RtcEnclave}; use auth_sys::AuthSys; +use rtc_types::{EcallError, EncryptedMessage, ExecReqMetadata, ExecTokenError}; use sgx_types::*; /// Wraps all the functionality for interacting with the auth enclave @@ -47,4 +48,49 @@ where pub fn geteid(&self) -> sgx_enclave_id_t { self.0.geteid() } + + /// Issues an execution token using the provided payload + pub fn issue_execution_token( + &self, + payload: &[u8], + metadata: ExecReqMetadata, + ) -> Result> { + ecalls::issue_execution_token(self.geteid(), payload, metadata) + } +} + +pub mod ecalls { + use auth_sys::ffi; + use rtc_types::*; + use sgx_types::*; + + pub fn issue_execution_token( + eid: sgx_enclave_id_t, + payload: &[u8], + metadata: ExecReqMetadata, + ) -> Result> { + let mut out_token_buffer = vec![0u8; 416].into_boxed_slice(); + let mut retval = IssueTokenResult::Ok([0u8; 24]); + + // Safety: Since the payload, and out buffer is allocated and valid this will be + // correctly handled by the SGX edge code + let res = unsafe { + ffi::rtc_auth_issue_execution_token( + eid, + &mut retval, + payload.as_ptr(), + payload.len(), + &metadata, + out_token_buffer.as_mut_ptr(), + out_token_buffer.len(), + ) + }; + + let x: Result> = retval.to_ecall_err(res).into(); + + x.map(|r| EncryptedMessage { + ciphertext: out_token_buffer, + nonce: r, + }) + } } From 66151a8d4cb2e8a1eb654d37f8a5c31ef10550b2 Mon Sep 17 00:00:00 2001 From: Herman Date: Thu, 17 Jun 2021 16:22:42 +0200 Subject: [PATCH 06/14] feat(data_service): add test for auth_enclave token issuance --- .../tests/ecalls/issue_execution_token.rs | 91 +++++++++++++++++++ rtc_data_service/tests/ecalls/mod.rs | 1 + rtc_data_service/tests/main.rs | 4 + rtc_data_service/tests/web_api/data_upload.rs | 4 +- 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 rtc_data_service/tests/ecalls/issue_execution_token.rs diff --git a/rtc_data_service/tests/ecalls/issue_execution_token.rs b/rtc_data_service/tests/ecalls/issue_execution_token.rs new file mode 100644 index 00000000..4e015ec6 --- /dev/null +++ b/rtc_data_service/tests/ecalls/issue_execution_token.rs @@ -0,0 +1,91 @@ +use std::convert::TryInto; +use std::str::FromStr; + +use rtc_types::ExecReqMetadata; +use serde::{Deserialize, Serialize}; +use sgx_types::sgx_target_info_t; + +use crate::{helpers, CRYPTO_BOX_BOXZEROBYTES, CRYPTO_BOX_ZEROBYTES}; + +#[derive(Serialize, Deserialize)] +pub struct ExecReqData { + dataset_uuid: [u8; 16], + dataset_access_key: [u8; 24], + exec_module_hash: [u8; 32], + number_of_uses: u32, +} + +#[test] +fn test_issue_execution_token_success() { + let enclave = helpers::init_auth_enclave(); + + let enclave_pubkey = enclave + .create_report(&sgx_target_info_t::default()) + .unwrap() + .enclave_held_data; + + let mut pubkey = [0_u8; 32]; + let mut privkey = [0_u8; 32]; + + sodalite::box_keypair_seed(&mut pubkey, &mut privkey, &[2_u8; 32]); + + let uuid = uuid::Uuid::from_str("dd12012195c04ae8990ebd2512ae03ab").unwrap(); + let exec_module_hash: Vec = (0u8..32).collect(); + + let req_json = serde_json::to_vec(&ExecReqData { + dataset_uuid: *uuid.as_bytes(), + dataset_access_key: [1; 24], + exec_module_hash: exec_module_hash.try_into().unwrap(), + number_of_uses: 10, + }) + .unwrap(); + + let plaintext = [vec![0_u8; 32], req_json].concat(); + let mut ciphertext = vec![0_u8; plaintext.len()]; + let nonce = [8_u8; 24]; + + sodalite::box_( + &mut ciphertext, + &plaintext, + &nonce, + &enclave_pubkey, + &privkey, + ) + .unwrap(); + + let result = enclave + .issue_execution_token( + &ciphertext[CRYPTO_BOX_BOXZEROBYTES..], + ExecReqMetadata { + uploader_pub_key: pubkey, + nonce, + }, + ) + .unwrap(); + + let mut m = vec![0_u8; result.ciphertext.len() + CRYPTO_BOX_BOXZEROBYTES]; + + let padded_c = [ + vec![0u8; CRYPTO_BOX_BOXZEROBYTES], + result.ciphertext.to_vec(), + ] + .concat(); + + // TODO: Test bad privkey, nonce etc and ensure failure + + let open_result = + sodalite::box_open(&mut m, &padded_c, &result.nonce, &enclave_pubkey, &privkey); + + assert!(open_result.is_ok()); + + // Skip over the padding + let padding: &[u8; CRYPTO_BOX_ZEROBYTES] = + m[..CRYPTO_BOX_ZEROBYTES].try_into().expect("bad padding"); + + assert_eq!( + padding, &[0_u8; CRYPTO_BOX_ZEROBYTES], + "padding should be zero" + ); + + // TODO: Assert that decrypted value is a valid JWT +} diff --git a/rtc_data_service/tests/ecalls/mod.rs b/rtc_data_service/tests/ecalls/mod.rs index 422adaf7..4948a04c 100644 --- a/rtc_data_service/tests/ecalls/mod.rs +++ b/rtc_data_service/tests/ecalls/mod.rs @@ -1,3 +1,4 @@ //! ECALL tests +mod issue_execution_token; mod local_attestation; diff --git a/rtc_data_service/tests/main.rs b/rtc_data_service/tests/main.rs index 5b4f4d1b..6df53372 100644 --- a/rtc_data_service/tests/main.rs +++ b/rtc_data_service/tests/main.rs @@ -1,5 +1,9 @@ //! Top-level test module +// See rtc_tenclave/src/crypto.rs +pub const CRYPTO_BOX_ZEROBYTES: usize = 32; +pub const CRYPTO_BOX_BOXZEROBYTES: usize = 16; + mod helpers; mod ecalls; diff --git a/rtc_data_service/tests/web_api/data_upload.rs b/rtc_data_service/tests/web_api/data_upload.rs index f348b4b2..00cd8bef 100644 --- a/rtc_data_service/tests/web_api/data_upload.rs +++ b/rtc_data_service/tests/web_api/data_upload.rs @@ -13,8 +13,8 @@ use rtc_data_service::data_upload::models; use crate::helpers; // See rtc_tenclave/src/crypto.rs -const CRYPTO_BOX_ZEROBYTES: usize = 32; -const CRYPTO_BOX_BOXZEROBYTES: usize = 16; +use crate::CRYPTO_BOX_BOXZEROBYTES; +use crate::CRYPTO_BOX_ZEROBYTES; /// Upload some data, decrypt and check the result. #[actix_rt::test] From 52d78086b65a5b413d69e0d1649ade33940275a2 Mon Sep 17 00:00:00 2001 From: Herman Date: Tue, 22 Jun 2021 15:03:59 +0200 Subject: [PATCH 07/14] fix(auth_enclave): use correct key for serde crate features --- rtc_auth_enclave/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtc_auth_enclave/Cargo.toml b/rtc_auth_enclave/Cargo.toml index 999bc7bf..6304c29b 100644 --- a/rtc_auth_enclave/Cargo.toml +++ b/rtc_auth_enclave/Cargo.toml @@ -26,7 +26,7 @@ base64 = { git = "https://github.com/mesalock-linux/rust-base64-sgx" } # See "Cargo patch limitation workaround" in HACKING.md: once_cell = { git = "https://github.com/mesalock-linux/once_cell-sgx.git" } -serde = { git = "https://github.com/mesalock-linux/serde-sgx", feature = ["derive"] } +serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = ["derive"] } serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } secrecy = { version = "0.7.0", default-features = false } From 728e4345407b54d32f611f59566ae938cf927817 Mon Sep 17 00:00:00 2001 From: Herman Date: Tue, 22 Jun 2021 15:04:47 +0200 Subject: [PATCH 08/14] refactor(auth_enclave): Use nonce type from rtc_types --- codegen/auth_enclave/bindings.h | 2 +- rtc_auth_enclave/src/lib.rs | 2 -- rtc_types/src/exec_token.rs | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/codegen/auth_enclave/bindings.h b/codegen/auth_enclave/bindings.h index 114708cc..7b1b2bb4 100644 --- a/codegen/auth_enclave/bindings.h +++ b/codegen/auth_enclave/bindings.h @@ -52,7 +52,7 @@ typedef struct EcallResult_Nonce__ExecTokenError IssueTokenResult; typedef struct ExecReqMetadata { uint8_t uploader_pub_key[32]; - uint8_t nonce[24]; + Nonce nonce; } ExecReqMetadata; /** diff --git a/rtc_auth_enclave/src/lib.rs b/rtc_auth_enclave/src/lib.rs index 2319cbf9..f7596d30 100644 --- a/rtc_auth_enclave/src/lib.rs +++ b/rtc_auth_enclave/src/lib.rs @@ -30,8 +30,6 @@ pub struct ExecReqData { number_of_uses: u32, } -pub type Nonce = [u8; 24]; - /// Issue an execution token using the parameters defined in the payload. /// /// # Safety diff --git a/rtc_types/src/exec_token.rs b/rtc_types/src/exec_token.rs index 9692c5dc..fb84c415 100644 --- a/rtc_types/src/exec_token.rs +++ b/rtc_types/src/exec_token.rs @@ -9,14 +9,14 @@ use crate::{CryptoError, EcallResult, Nonce}; #[derive(Debug)] pub struct ExecReqMetadata { pub uploader_pub_key: [u8; 32], - pub nonce: [u8; 24], + pub nonce: Nonce, } #[repr(C)] #[derive(Debug)] pub struct ExecTokenResponse { pub execution_token: Vec, - pub nonce: [u8; 24], + pub nonce: Nonce, } pub type IssueTokenResult = EcallResult; From 9c151d0b1feac171eedf836ba665f97b1190cc70 Mon Sep 17 00:00:00 2001 From: Herman Date: Tue, 22 Jun 2021 15:05:30 +0200 Subject: [PATCH 09/14] refactor(auth_enclave): use unwrap_or_else instead of map_or --- rtc_auth_enclave/src/token_store.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/rtc_auth_enclave/src/token_store.rs b/rtc_auth_enclave/src/token_store.rs index 26c6874e..5ac6942c 100644 --- a/rtc_auth_enclave/src/token_store.rs +++ b/rtc_auth_enclave/src/token_store.rs @@ -72,11 +72,10 @@ fn save_token( current_uses: 0u32, }; - store - .alter(&dataset_uuid_string, |records| { - let mut records = records.map_or(HashMap::new(), |r| r); - records.insert(token_uuid, new_record); - Some(records) - }) - .and(Ok(())) + store.alter(&dataset_uuid_string, |records| { + let mut records = records.unwrap_or_else(HashMap::new); + records.insert(token_uuid, new_record); + Some(records) + })?; + Ok(()) } From fa9a39275b67753b311689fd4bb1955b4685ac69 Mon Sep 17 00:00:00 2001 From: Herman Date: Tue, 22 Jun 2021 15:07:10 +0200 Subject: [PATCH 10/14] docs(auth_enclave): add link for claim key definitions Co-authored-by: Pi Delport --- rtc_auth_enclave/src/jwt.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rtc_auth_enclave/src/jwt.rs b/rtc_auth_enclave/src/jwt.rs index 8cb86637..3907bbcb 100644 --- a/rtc_auth_enclave/src/jwt.rs +++ b/rtc_auth_enclave/src/jwt.rs @@ -23,6 +23,7 @@ use crate::uuid_to_string; /// ``` #[derive(Debug, Serialize, Deserialize)] struct Claims { + // Registered Claim Names: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1 // TODO: serialize to hex string? This can be mrenclave or mrsigner iss: String, nbf: u64, From a672a5ccb2342bb7f8cb54dbfc1ce9cc44b817c5 Mon Sep 17 00:00:00 2001 From: Herman Date: Tue, 22 Jun 2021 15:23:07 +0200 Subject: [PATCH 11/14] refactor(auth_enclave): pull out token length bounds into consts --- rtc_auth_enclave/src/lib.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/rtc_auth_enclave/src/lib.rs b/rtc_auth_enclave/src/lib.rs index f7596d30..fce0fc9a 100644 --- a/rtc_auth_enclave/src/lib.rs +++ b/rtc_auth_enclave/src/lib.rs @@ -22,6 +22,15 @@ use secrecy::{ExposeSecret, Secret}; use serde::{Deserialize, Serialize}; use uuid::Uuid; +/// Minimum size for the out_token parameter's buffer. +/// +/// From my testing, the token size were never bigger than 400. +/// So this value refers to: 400 (for the token) + 16 (Authentication bytes from NaCl) +const MIN_OUT_TOKEN_LEN: usize = 416; + +/// Maximum size for the out_token parameter's buffer. +const MAX_OUT_TOKEN_LEN: usize = 1000; + #[derive(Serialize, Deserialize)] pub struct ExecReqData { dataset_uuid: [u8; 16], @@ -67,7 +76,7 @@ fn issue_execution_token_impl( max_ciphertext_len: usize, ) -> Result { // Ensure that the out token len is reasonable before proceeding - if max_ciphertext_len < 416 && max_ciphertext_len > 1000 { + if max_ciphertext_len < MIN_OUT_TOKEN_LEN || max_ciphertext_len > MAX_OUT_TOKEN_LEN { return Err(ExecTokenError::OutputBufferSize); } @@ -87,19 +96,19 @@ fn issue_execution_token_impl( let mut token_vec = token.into_bytes(); + // TODO: Move this check before persistence if max_ciphertext_len < token_vec.len() - 16 { return Err(ExecTokenError::OutputBufferSize); } - // TODO: Comment on how message size will be upheld + // Grow the plaintext vector to the max ciphertext size - 16 + // The 16 refers to the authentication bytes that gets added by NaCl token_vec.resize(max_ciphertext_len - 16, 0); Ok(crypto.encrypt_message( Secret::new(token_vec.into_boxed_slice()), &metadata.uploader_pub_key, )?) - - // TODO: Move this check before persistence } else { Err(ExecTokenError::Validation) } From 591975e69a3b43b6126caffcfed35cfc6c04eaf5 Mon Sep 17 00:00:00 2001 From: Herman Date: Tue, 22 Jun 2021 15:33:27 +0200 Subject: [PATCH 12/14] feat(auth_enclave): add dataset size to exec token claims --- rtc_auth_enclave/src/jwt.rs | 12 ++++++++++-- rtc_auth_enclave/src/lib.rs | 17 +++++++++++++---- rtc_auth_enclave/src/token_store.rs | 3 ++- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/rtc_auth_enclave/src/jwt.rs b/rtc_auth_enclave/src/jwt.rs index 3907bbcb..3ae3a246 100644 --- a/rtc_auth_enclave/src/jwt.rs +++ b/rtc_auth_enclave/src/jwt.rs @@ -32,10 +32,16 @@ struct Claims { // TODO: Better names. use `x-ntls-mod-hash` etc? exec_module_hash: String, dataset_uuid: String, + dataset_size: u64, } impl Claims { - fn new(exec_module_hash: String, dataset_uuid: String, token_id: String) -> Self { + fn new( + exec_module_hash: String, + dataset_uuid: String, + token_id: String, + dataset_size: u64, + ) -> Self { // TODO: Look at the attack vectors opened up by using untrusted system time let now = SystemTime::now() .duration_since(UNIX_EPOCH) @@ -49,6 +55,7 @@ impl Claims { jti: token_id, exec_module_hash, dataset_uuid, + dataset_size, } } } @@ -59,13 +66,14 @@ pub(crate) struct EncodedExecutionToken { } impl EncodedExecutionToken { - pub(crate) fn new(exec_module_hash: [u8; 32], dataset_uuid: Uuid) -> Self { + pub(crate) fn new(exec_module_hash: [u8; 32], dataset_uuid: Uuid, dataset_size: u64) -> Self { let token_id = Uuid::new_v4(); let claims = Claims::new( base64::encode(exec_module_hash), uuid_to_string(dataset_uuid), uuid_to_string(token_id), + dataset_size, ); // TODO: Use a signing key that corresponds to the public key diff --git a/rtc_auth_enclave/src/lib.rs b/rtc_auth_enclave/src/lib.rs index fce0fc9a..8ca95da4 100644 --- a/rtc_auth_enclave/src/lib.rs +++ b/rtc_auth_enclave/src/lib.rs @@ -87,11 +87,14 @@ fn issue_execution_token_impl( let message: ExecReqData = serde_json::from_slice(message_bytes.expose_secret()) .map_err(|_| ExecTokenError::Validation)?; - if valid_dataset_access_key(message.dataset_uuid, message.dataset_access_key) { + if let Some(dataset_size) = + validate_dataset_access_key(message.dataset_uuid, message.dataset_access_key) + { let token = token_store::issue_token( Uuid::from_bytes(message.dataset_uuid), message.exec_module_hash, message.number_of_uses, + dataset_size, )?; let mut token_vec = token.into_bytes(); @@ -114,9 +117,15 @@ fn issue_execution_token_impl( } } -fn valid_dataset_access_key(_dataset_uuid: [u8; 16], _access_key: [u8; 24]) -> bool { - // TODO: Check access key store to see if the request is valid - true +/// The size of the dataset in bytes +type DatasetSize = u64; + +// This is a placeholder and the signature might change when the dataset and access key store gets implemented. +fn validate_dataset_access_key( + _dataset_uuid: [u8; 16], + _access_key: [u8; 24], +) -> Option { + Some(20) } pub(crate) fn uuid_to_string(uuid: Uuid) -> String { diff --git a/rtc_auth_enclave/src/token_store.rs b/rtc_auth_enclave/src/token_store.rs index 5ac6942c..6c5e83ed 100644 --- a/rtc_auth_enclave/src/token_store.rs +++ b/rtc_auth_enclave/src/token_store.rs @@ -43,9 +43,10 @@ pub(crate) fn issue_token( dataset_uuid: Uuid, exec_module_hash: [u8; 32], number_of_allowed_uses: u32, + dataset_size: u64, ) -> Result { let EncodedExecutionToken { token, token_id } = - EncodedExecutionToken::new(exec_module_hash, dataset_uuid); + EncodedExecutionToken::new(exec_module_hash, dataset_uuid, dataset_size); save_token( dataset_uuid, From ea6f6e97ccd637e627258996d05e2e69f9dd4e66 Mon Sep 17 00:00:00 2001 From: Herman Date: Tue, 22 Jun 2021 15:38:17 +0200 Subject: [PATCH 13/14] docs(uenclave): mention MAX / MIN_OUT_TOKEN_LEN at buffer creation --- rtc_uenclave/src/enclaves/rtc_auth.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rtc_uenclave/src/enclaves/rtc_auth.rs b/rtc_uenclave/src/enclaves/rtc_auth.rs index 2b47bf54..52421019 100644 --- a/rtc_uenclave/src/enclaves/rtc_auth.rs +++ b/rtc_uenclave/src/enclaves/rtc_auth.rs @@ -69,6 +69,7 @@ pub mod ecalls { payload: &[u8], metadata: ExecReqMetadata, ) -> Result> { + // See MAX / MIN_OUT_TOKEN_LEN in rtc_auth_enclave let mut out_token_buffer = vec![0u8; 416].into_boxed_slice(); let mut retval = IssueTokenResult::Ok([0u8; 24]); From bd035878b96af5bba53e658db79a9c53269c3937 Mon Sep 17 00:00:00 2001 From: Herman Date: Thu, 24 Jun 2021 15:35:48 +0200 Subject: [PATCH 14/14] feat(auth_enclave): return actual token size to avoid null trailer issues Co-authored-by: Pi Delport --- codegen/auth_enclave/rtc_auth_t.c | 35 ++++++++++++++++++++---- codegen/auth_enclave/rtc_auth_t.h | 2 +- codegen/auth_enclave/rtc_auth_u.c | 8 +++--- codegen/auth_enclave/rtc_auth_u.h | 2 +- rtc_auth_enclave/rtc_auth.edl | 5 ++-- rtc_auth_enclave/src/lib.rs | 38 +++++++++++---------------- rtc_uenclave/src/enclaves/rtc_auth.rs | 11 +++++--- 7 files changed, 62 insertions(+), 39 deletions(-) diff --git a/codegen/auth_enclave/rtc_auth_t.c b/codegen/auth_enclave/rtc_auth_t.c index aded6226..fdab0226 100644 --- a/codegen/auth_enclave/rtc_auth_t.c +++ b/codegen/auth_enclave/rtc_auth_t.c @@ -40,7 +40,8 @@ typedef struct ms_issue_execution_token_t { size_t ms_payload_len; const ExecReqMetadata* ms_metadata; uint8_t* ms_out_token_ptr; - size_t ms_out_token_len; + size_t ms_out_token_capacity; + size_t* ms_out_token_used; } ms_issue_execution_token_t; typedef struct ms_t_global_init_ecall_t { @@ -669,9 +670,12 @@ static sgx_status_t SGX_CDECL sgx_issue_execution_token(void* pms) size_t _len_metadata = sizeof(ExecReqMetadata); ExecReqMetadata* _in_metadata = NULL; uint8_t* _tmp_out_token_ptr = ms->ms_out_token_ptr; - size_t _tmp_out_token_len = ms->ms_out_token_len; - size_t _len_out_token_ptr = _tmp_out_token_len * sizeof(uint8_t); + size_t _tmp_out_token_capacity = ms->ms_out_token_capacity; + size_t _len_out_token_ptr = _tmp_out_token_capacity * sizeof(uint8_t); uint8_t* _in_out_token_ptr = NULL; + size_t* _tmp_out_token_used = ms->ms_out_token_used; + size_t _len_out_token_used = sizeof(size_t); + size_t* _in_out_token_used = NULL; if (sizeof(*_tmp_payload_ptr) != 0 && (size_t)_tmp_payload_len > (SIZE_MAX / sizeof(*_tmp_payload_ptr))) { @@ -679,13 +683,14 @@ static sgx_status_t SGX_CDECL sgx_issue_execution_token(void* pms) } if (sizeof(*_tmp_out_token_ptr) != 0 && - (size_t)_tmp_out_token_len > (SIZE_MAX / sizeof(*_tmp_out_token_ptr))) { + (size_t)_tmp_out_token_capacity > (SIZE_MAX / sizeof(*_tmp_out_token_ptr))) { return SGX_ERROR_INVALID_PARAMETER; } CHECK_UNIQUE_POINTER(_tmp_payload_ptr, _len_payload_ptr); CHECK_UNIQUE_POINTER(_tmp_metadata, _len_metadata); CHECK_UNIQUE_POINTER(_tmp_out_token_ptr, _len_out_token_ptr); + CHECK_UNIQUE_POINTER(_tmp_out_token_used, _len_out_token_used); // // fence after pointer checks @@ -736,19 +741,39 @@ static sgx_status_t SGX_CDECL sgx_issue_execution_token(void* pms) memset((void*)_in_out_token_ptr, 0, _len_out_token_ptr); } + if (_tmp_out_token_used != NULL && _len_out_token_used != 0) { + if ( _len_out_token_used % sizeof(*_tmp_out_token_used) != 0) + { + status = SGX_ERROR_INVALID_PARAMETER; + goto err; + } + if ((_in_out_token_used = (size_t*)malloc(_len_out_token_used)) == NULL) { + status = SGX_ERROR_OUT_OF_MEMORY; + goto err; + } - ms->ms_retval = issue_execution_token((const uint8_t*)_in_payload_ptr, _tmp_payload_len, (const ExecReqMetadata*)_in_metadata, _in_out_token_ptr, _tmp_out_token_len); + memset((void*)_in_out_token_used, 0, _len_out_token_used); + } + + ms->ms_retval = issue_execution_token((const uint8_t*)_in_payload_ptr, _tmp_payload_len, (const ExecReqMetadata*)_in_metadata, _in_out_token_ptr, _tmp_out_token_capacity, _in_out_token_used); if (_in_out_token_ptr) { if (memcpy_s(_tmp_out_token_ptr, _len_out_token_ptr, _in_out_token_ptr, _len_out_token_ptr)) { status = SGX_ERROR_UNEXPECTED; goto err; } } + if (_in_out_token_used) { + if (memcpy_s(_tmp_out_token_used, _len_out_token_used, _in_out_token_used, _len_out_token_used)) { + status = SGX_ERROR_UNEXPECTED; + goto err; + } + } err: if (_in_payload_ptr) free(_in_payload_ptr); if (_in_metadata) free(_in_metadata); if (_in_out_token_ptr) free(_in_out_token_ptr); + if (_in_out_token_used) free(_in_out_token_used); return status; } diff --git a/codegen/auth_enclave/rtc_auth_t.h b/codegen/auth_enclave/rtc_auth_t.h index 0a35d1fd..73083339 100644 --- a/codegen/auth_enclave/rtc_auth_t.h +++ b/codegen/auth_enclave/rtc_auth_t.h @@ -26,7 +26,7 @@ extern "C" { #endif CreateReportResult enclave_create_report(const sgx_target_info_t* p_qe3_target, EnclaveHeldData enclave_data, sgx_report_t* p_report); -IssueTokenResult issue_execution_token(const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_len); +IssueTokenResult issue_execution_token(const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_capacity, size_t* out_token_used); void t_global_init_ecall(uint64_t id, const uint8_t* path, size_t len); void t_global_exit_ecall(void); SessionRequestResult session_request(sgx_enclave_id_t src_enclave_id); diff --git a/codegen/auth_enclave/rtc_auth_u.c b/codegen/auth_enclave/rtc_auth_u.c index 9e68ae1a..8c77d079 100644 --- a/codegen/auth_enclave/rtc_auth_u.c +++ b/codegen/auth_enclave/rtc_auth_u.c @@ -14,7 +14,8 @@ typedef struct ms_issue_execution_token_t { size_t ms_payload_len; const ExecReqMetadata* ms_metadata; uint8_t* ms_out_token_ptr; - size_t ms_out_token_len; + size_t ms_out_token_capacity; + size_t* ms_out_token_used; } ms_issue_execution_token_t; typedef struct ms_t_global_init_ecall_t { @@ -1224,7 +1225,7 @@ sgx_status_t rtc_auth_enclave_create_report(sgx_enclave_id_t eid, CreateReportRe return status; } -sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_len) +sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_capacity, size_t* out_token_used) { sgx_status_t status; ms_issue_execution_token_t ms; @@ -1232,7 +1233,8 @@ sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResu ms.ms_payload_len = payload_len; ms.ms_metadata = metadata; ms.ms_out_token_ptr = out_token_ptr; - ms.ms_out_token_len = out_token_len; + ms.ms_out_token_capacity = out_token_capacity; + ms.ms_out_token_used = out_token_used; status = sgx_ecall(eid, 1, &ocall_table_rtc_auth, &ms); if (status == SGX_SUCCESS && retval) *retval = ms.ms_retval; return status; diff --git a/codegen/auth_enclave/rtc_auth_u.h b/codegen/auth_enclave/rtc_auth_u.h index cb3723d2..38074d3c 100644 --- a/codegen/auth_enclave/rtc_auth_u.h +++ b/codegen/auth_enclave/rtc_auth_u.h @@ -320,7 +320,7 @@ int32_t SGX_UBRIDGE(SGX_NOCONVENTION, u_sgxprotectedfs_do_file_recovery, (const #endif sgx_status_t rtc_auth_enclave_create_report(sgx_enclave_id_t eid, CreateReportResult* retval, const sgx_target_info_t* p_qe3_target, EnclaveHeldData enclave_data, sgx_report_t* p_report); -sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_len); +sgx_status_t rtc_auth_issue_execution_token(sgx_enclave_id_t eid, IssueTokenResult* retval, const uint8_t* payload_ptr, size_t payload_len, const ExecReqMetadata* metadata, uint8_t* out_token_ptr, size_t out_token_capacity, size_t* out_token_used); sgx_status_t rtc_auth_t_global_init_ecall(sgx_enclave_id_t eid, uint64_t id, const uint8_t* path, size_t len); sgx_status_t rtc_auth_t_global_exit_ecall(sgx_enclave_id_t eid); sgx_status_t rtc_auth_session_request(sgx_enclave_id_t eid, SessionRequestResult* retval, sgx_enclave_id_t src_enclave_id); diff --git a/rtc_auth_enclave/rtc_auth.edl b/rtc_auth_enclave/rtc_auth.edl index f046e905..f10f7c83 100644 --- a/rtc_auth_enclave/rtc_auth.edl +++ b/rtc_auth_enclave/rtc_auth.edl @@ -16,7 +16,8 @@ enclave { public IssueTokenResult issue_execution_token([in, count=payload_len]const uint8_t* payload_ptr, size_t payload_len, [in]const ExecReqMetadata* metadata, - [out, count=out_token_len]uint8_t* out_token_ptr, - size_t out_token_len); + [out, count=out_token_capacity]uint8_t* out_token_ptr, + size_t out_token_capacity, + [out] size_t* out_token_used); }; }; diff --git a/rtc_auth_enclave/src/lib.rs b/rtc_auth_enclave/src/lib.rs index 8ca95da4..a036e0e2 100644 --- a/rtc_auth_enclave/src/lib.rs +++ b/rtc_auth_enclave/src/lib.rs @@ -24,9 +24,8 @@ use uuid::Uuid; /// Minimum size for the out_token parameter's buffer. /// -/// From my testing, the token size were never bigger than 400. -/// So this value refers to: 400 (for the token) + 16 (Authentication bytes from NaCl) -const MIN_OUT_TOKEN_LEN: usize = 416; +/// From my testing, the total token size (including auth bytes) were never bigger than 500. +const MIN_OUT_TOKEN_LEN: usize = 500; /// Maximum size for the out_token parameter's buffer. const MAX_OUT_TOKEN_LEN: usize = 1000; @@ -53,19 +52,27 @@ pub unsafe extern "C" fn issue_execution_token( payload_len: usize, metadata_ptr: *const ExecReqMetadata, out_token_ptr: *mut u8, - out_token_len: usize, + out_token_capacity: usize, + out_token_used: *mut usize, ) -> IssueTokenResult { + // Ensure that the out token len is reasonable before proceeding + if out_token_capacity < MIN_OUT_TOKEN_LEN || out_token_capacity > MAX_OUT_TOKEN_LEN { + return EcallResult::Err(ExecTokenError::OutputBufferSize); + } + let payload = unsafe { slice::from_raw_parts(payload_ptr, payload_len) }; let metadata = unsafe { &*metadata_ptr }; - match issue_execution_token_impl(payload, metadata, out_token_len) { - Ok(message) => { - assert_eq!(message.ciphertext.len(), out_token_len); + match issue_execution_token_impl(payload, metadata) { + Ok(message) if message.ciphertext.len() <= out_token_capacity => { + let out_token_len = message.ciphertext.len(); unsafe { + *out_token_used = out_token_len; ptr::copy_nonoverlapping(message.ciphertext.as_ptr(), out_token_ptr, out_token_len); } EcallResult::Ok(message.nonce) } + Ok(_) => EcallResult::Err(ExecTokenError::OutputBufferSize), Err(err) => EcallResult::Err(err), } } @@ -73,13 +80,7 @@ pub unsafe extern "C" fn issue_execution_token( fn issue_execution_token_impl( payload: &[u8], metadata: &ExecReqMetadata, - max_ciphertext_len: usize, ) -> Result { - // Ensure that the out token len is reasonable before proceeding - if max_ciphertext_len < MIN_OUT_TOKEN_LEN || max_ciphertext_len > MAX_OUT_TOKEN_LEN { - return Err(ExecTokenError::OutputBufferSize); - } - let mut crypto = Crypto::new(); let message_bytes = crypto.decrypt_message(payload, &metadata.uploader_pub_key, &metadata.nonce)?; @@ -97,16 +98,7 @@ fn issue_execution_token_impl( dataset_size, )?; - let mut token_vec = token.into_bytes(); - - // TODO: Move this check before persistence - if max_ciphertext_len < token_vec.len() - 16 { - return Err(ExecTokenError::OutputBufferSize); - } - - // Grow the plaintext vector to the max ciphertext size - 16 - // The 16 refers to the authentication bytes that gets added by NaCl - token_vec.resize(max_ciphertext_len - 16, 0); + let token_vec = token.into_bytes(); Ok(crypto.encrypt_message( Secret::new(token_vec.into_boxed_slice()), diff --git a/rtc_uenclave/src/enclaves/rtc_auth.rs b/rtc_uenclave/src/enclaves/rtc_auth.rs index 52421019..579a706c 100644 --- a/rtc_uenclave/src/enclaves/rtc_auth.rs +++ b/rtc_uenclave/src/enclaves/rtc_auth.rs @@ -70,7 +70,8 @@ pub mod ecalls { metadata: ExecReqMetadata, ) -> Result> { // See MAX / MIN_OUT_TOKEN_LEN in rtc_auth_enclave - let mut out_token_buffer = vec![0u8; 416].into_boxed_slice(); + let mut out_token_buffer = vec![0u8; 500]; + let mut out_token_used = 0; let mut retval = IssueTokenResult::Ok([0u8; 24]); // Safety: Since the payload, and out buffer is allocated and valid this will be @@ -84,14 +85,16 @@ pub mod ecalls { &metadata, out_token_buffer.as_mut_ptr(), out_token_buffer.len(), + &mut out_token_used, ) }; let x: Result> = retval.to_ecall_err(res).into(); - x.map(|r| EncryptedMessage { - ciphertext: out_token_buffer, - nonce: r, + x.map(|nonce| { + out_token_buffer.truncate(out_token_used); + let ciphertext = out_token_buffer.into_boxed_slice(); + EncryptedMessage { ciphertext, nonce } }) } }