From cf080a46a0cd99c0fd0baede9033a8958fe44767 Mon Sep 17 00:00:00 2001 From: "Zheng, Qi" Date: Wed, 27 Apr 2022 16:20:26 +0800 Subject: [PATCH] Add SGX KSS config_svn verification support in grpc_ratls --- demos/ra_tls/build_occlum_instance.sh | 2 ++ .../src/cpp/sgx/sgx_ra_tls_backends.cc | 20 +++++++++++++++---- .../v1.38.1/src/cpp/sgx/sgx_ra_tls_backends.h | 4 +++- .../v1.38.1/src/cpp/sgx/sgx_ra_tls_occlum.cc | 1 + demos/ra_tls/ra_config_template.json | 6 ++++-- .../remote_attestation/init_ra_flow/README.md | 8 ++++++-- .../init_ra_flow/build_content.sh | 8 +++++++- .../init_ra_flow/ra_config_template.json | 6 ++++-- demos/remote_attestation/init_ra_flow/run.sh | 2 +- .../init_ra_flow/run_till_ready.sh | 2 +- example/build_content.sh | 2 ++ example/ra_config_template.json | 6 ++++-- 12 files changed, 51 insertions(+), 16 deletions(-) diff --git a/demos/ra_tls/build_occlum_instance.sh b/demos/ra_tls/build_occlum_instance.sh index e379b627..dde415be 100755 --- a/demos/ra_tls/build_occlum_instance.sh +++ b/demos/ra_tls/build_occlum_instance.sh @@ -26,6 +26,7 @@ function build_instance() { .verify_mr_signer = "on" | .verify_isv_prod_id = "off" | .verify_isv_svn = "off" | + .verify_config_svn = "off" | .verify_enclave_debuggable = "on" | .sgx_mrs[0].mr_enclave = ''"'`get_mr client mr_enclave`'" | .sgx_mrs[0].mr_signer = ''"'`get_mr client mr_signer`'" | @@ -43,6 +44,7 @@ function build_instance() { .verify_mr_signer = "off" | .verify_isv_prod_id = "off" | .verify_isv_svn = "off" | + .verify_config_svn = "off" | .verify_enclave_debuggable = "on" | .sgx_mrs[0].debuggable = false ' ../ra_config_template.json > dynamic_config.json diff --git a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backends.cc b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backends.cc index 8d57637d..2ac4bff0 100644 --- a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backends.cc +++ b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backends.cc @@ -65,6 +65,7 @@ static sgx_config parse_sgx_config_json(const char* file) { sgx_cfg.verify_mr_signer = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_mr_signer"), "on"); sgx_cfg.verify_isv_prod_id = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_isv_prod_id"), "on"); sgx_cfg.verify_isv_svn = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_isv_svn"), "on"); + sgx_cfg.verify_config_svn = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_config_svn"), "on"); sgx_cfg.verify_enclave_debuggable = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_enclave_debuggable"), "on"); @@ -89,6 +90,9 @@ static sgx_config parse_sgx_config_json(const char* file) { auto isv_svn = sgx_json.print_item(sgx_json.get_item(obj, "isv_svn")); sgx_cfg.sgx_mrs[i].isv_svn = strtoul(isv_svn, nullptr, 10); + auto config_svn = sgx_json.print_item(sgx_json.get_item(obj, "config_svn")); + sgx_cfg.sgx_mrs[i].config_svn = strtoul(config_svn, nullptr, 10); + if (cJSON_IsTrue(sgx_json.get_item(obj, "debuggable")) == 0) sgx_cfg.sgx_mrs[i].debuggable = false; else @@ -112,7 +116,7 @@ void ra_tls_verify_init() { static bool verify_measurement_internal(const char* mr_enclave, const char* mr_signer, const char* isv_prod_id, const char* isv_svn, - bool debuggable) { + const char* config_svn, bool debuggable) { bool status = false; auto & sgx_cfg = _ctx_.sgx_cfg; for (auto & obj : sgx_cfg.sgx_mrs) { @@ -138,6 +142,11 @@ static bool verify_measurement_internal(const char* mr_enclave, const char* mr_s status = false; } + if (status && sgx_cfg.verify_config_svn && \ + (obj.config_svn != *(uint16_t*)config_svn)) { + status = false; + } + if (status && sgx_cfg.verify_enclave_debuggable && \ (obj.debuggable != debuggable)) { status = false; @@ -152,12 +161,14 @@ static bool verify_measurement_internal(const char* mr_enclave, const char* mr_s int verify_measurement(const char* mr_enclave, const char* mr_signer, const char* isv_prod_id, const char* isv_svn, - bool debuggable) { + const char* config_svn, bool debuggable) { std::lock_guard lock(_ctx_.mtx); bool status = false; try { - assert(mr_enclave && mr_signer && isv_prod_id && isv_svn); - status = verify_measurement_internal(mr_enclave, mr_signer, isv_prod_id, isv_svn, debuggable); + assert(mr_enclave && mr_signer && isv_prod_id && isv_svn && config_svn); + status = verify_measurement_internal( + mr_enclave, mr_signer, isv_prod_id, isv_svn, config_svn, debuggable + ); if (status) { grpc_printf(" |- verify result : success\n"); } else { @@ -166,6 +177,7 @@ int verify_measurement(const char* mr_enclave, const char* mr_signer, grpc_printf(" |- mr_signer : %s\n", byte_to_hex(mr_signer, 32).c_str()); grpc_printf(" |- isv_prod_id : %hu\n", *((uint16_t*)isv_prod_id)); grpc_printf(" |- isv_svn : %hu\n", *((uint16_t*)isv_svn)); + grpc_printf(" |- config_svn : %hu\n", *((uint16_t*)config_svn)); grpc_printf(" |- debuggable : %s\n", debuggable?"true":"false"); grpc_printf(" |- verify result : failed\n"); } diff --git a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backends.h b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backends.h index 3285d384..0c28518e 100644 --- a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backends.h +++ b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backends.h @@ -50,6 +50,7 @@ struct sgx_measurement { char mr_signer[32]; uint16_t isv_prod_id; uint16_t isv_svn; + uint16_t config_svn; bool debuggable; }; @@ -58,6 +59,7 @@ struct sgx_config { bool verify_mr_signer = true; bool verify_isv_prod_id = true; bool verify_isv_svn = true; + bool verify_config_svn = true; bool verify_enclave_debuggable = true; std::vector sgx_mrs; }; @@ -100,7 +102,7 @@ void ra_tls_verify_init(); int verify_measurement(const char* mr_enclave, const char* mr_signer, const char* isv_prod_id, const char* isv_svn, - bool debuggable); + const char* config_svn, bool debuggable); void credential_option_set_certificate_provider(grpc::sgx::CredentialsOptions& options); diff --git a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_occlum.cc b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_occlum.cc index 7ffc304e..ef0086ae 100644 --- a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_occlum.cc +++ b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_occlum.cc @@ -308,6 +308,7 @@ int occlum_verify_cert(const unsigned char * der_crt, size_t len) { (const char *)&p_rep_body->mr_signer, (const char *)&p_rep_body->isv_prod_id, (const char *)&p_rep_body->isv_svn, + (const char *)&p_rep_body->config_svn, debuggable); if (ret != 0) { grpc_printf("verify the measurement failed!\n"); diff --git a/demos/ra_tls/ra_config_template.json b/demos/ra_tls/ra_config_template.json index 573c86ff..11d35ca7 100644 --- a/demos/ra_tls/ra_config_template.json +++ b/demos/ra_tls/ra_config_template.json @@ -3,13 +3,15 @@ "verify_mr_signer" : "on", "verify_isv_prod_id" : "on", "verify_isv_svn" : "on", + "verify_config_svn" : "on", "verify_enclave_debuggable" : "on", "sgx_mrs": [ { "mr_enclave" : "", "mr_signer" : "", - "isv_prod_id" : "0", - "isv_svn" : "0", + "isv_prod_id" : 0, + "isv_svn" : 0, + "config_svn" : 0, "debuggable" : false } ] diff --git a/demos/remote_attestation/init_ra_flow/README.md b/demos/remote_attestation/init_ra_flow/README.md index 28190670..c443d431 100644 --- a/demos/remote_attestation/init_ra_flow/README.md +++ b/demos/remote_attestation/init_ra_flow/README.md @@ -21,13 +21,15 @@ The GRPC-RATLS server holds some sensitive data thus it is usually deploed on se "verify_mr_signer" : "on", "verify_isv_prod_id" : "on", "verify_isv_svn" : "on", + "verify_config_svn" : "on", "verify_enclave_debuggable" : "on", "sgx_mrs": [ { "mr_enclave" : "", "mr_signer" : "", - "isv_prod_id" : "0", - "isv_svn" : "0", + "isv_prod_id" : 0, + "isv_svn" : 0, + "config_svn" : 0, "debuggable" : false } ], @@ -38,6 +40,8 @@ Users need decide which `verify_xxx` are taking effect. 1. if yes, fill in the measures data under `sgx_mrs`. 2. if no, set `verify_xxx` to `off`. +* **config_svn** is a 16 bits information brought by [`SGX KSS feature`](https://github.com/occlum/occlum/blob/master/docs/remote_attestation.md#sgx-kss-key-separation-and-sharing-feature-support), which provides a benefit that the enclave SGX quote (config_svn part) could be modified in running stage instead of signing stage. + Details could refer to the `build_server_instance` in script [`build_content.sh`](./build_content.sh). The `RA Verify Config` JSON records the secrets. Each secret has a name and its base64 encoded string value, such as diff --git a/demos/remote_attestation/init_ra_flow/build_content.sh b/demos/remote_attestation/init_ra_flow/build_content.sh index 142579b9..6a73abcb 100755 --- a/demos/remote_attestation/init_ra_flow/build_content.sh +++ b/demos/remote_attestation/init_ra_flow/build_content.sh @@ -53,6 +53,8 @@ function build_client_instance() .resource_limits.kernel_space_heap_size = "128MB" | .resource_limits.max_num_of_threads = 32 | .metadata.debuggable = false | + .metadata.enable_kss = true | + .metadata.version_number = 88 | .env.default += ["PYTHONHOME=/opt/python-occlum"]' Occlum.json)" && \ echo "${new_json}" > Occlum.json @@ -64,6 +66,7 @@ function build_client_instance() .verify_mr_signer = "on" | .verify_isv_prod_id = "off" | .verify_isv_svn = "off" | + .verify_config_svn = "off" | .verify_enclave_debuggable = "on" | .sgx_mrs[0].mr_signer = ''"'`get_mr client mr_signer`'" | .sgx_mrs[0].debuggable = false ' ../ra_config_template.json > dynamic_config.json @@ -109,10 +112,13 @@ function build_server_instance() jq '.verify_mr_enclave = "on" | .verify_mr_signer = "on" | .verify_isv_prod_id = "off" | - .verify_isv_svn = "off" | + .verify_isv_svn = "on" | + .verify_config_svn = "on" | .verify_enclave_debuggable = "on" | .sgx_mrs[0].mr_enclave = ''"'`get_mr client mr_enclave`'" | .sgx_mrs[0].mr_signer = ''"'`get_mr client mr_signer`'" | + .sgx_mrs[0].isv_svn = 88 | + .sgx_mrs[0].config_svn = 1234 | .sgx_mrs[0].debuggable = false ' ../ra_config_template.json > dynamic_config.json new_json="$(jq '.resource_limits.user_space_size = "500MB" | diff --git a/demos/remote_attestation/init_ra_flow/ra_config_template.json b/demos/remote_attestation/init_ra_flow/ra_config_template.json index 573c86ff..11d35ca7 100644 --- a/demos/remote_attestation/init_ra_flow/ra_config_template.json +++ b/demos/remote_attestation/init_ra_flow/ra_config_template.json @@ -3,13 +3,15 @@ "verify_mr_signer" : "on", "verify_isv_prod_id" : "on", "verify_isv_svn" : "on", + "verify_config_svn" : "on", "verify_enclave_debuggable" : "on", "sgx_mrs": [ { "mr_enclave" : "", "mr_signer" : "", - "isv_prod_id" : "0", - "isv_svn" : "0", + "isv_prod_id" : 0, + "isv_svn" : 0, + "config_svn" : 0, "debuggable" : false } ] diff --git a/demos/remote_attestation/init_ra_flow/run.sh b/demos/remote_attestation/init_ra_flow/run.sh index c6e8789b..b627897d 100755 --- a/demos/remote_attestation/init_ra_flow/run.sh +++ b/demos/remote_attestation/init_ra_flow/run.sh @@ -14,5 +14,5 @@ sleep 3 echo "Start Flask-TLS restful web portal on backgound ..." pushd occlum_client -occlum run /bin/rest_api.py & +occlum run --config-svn 1234 /bin/rest_api.py & popd \ No newline at end of file diff --git a/demos/remote_attestation/init_ra_flow/run_till_ready.sh b/demos/remote_attestation/init_ra_flow/run_till_ready.sh index 043d3a6c..c3ec4dde 100755 --- a/demos/remote_attestation/init_ra_flow/run_till_ready.sh +++ b/demos/remote_attestation/init_ra_flow/run_till_ready.sh @@ -19,7 +19,7 @@ done echo "Start Flask-TLS restful web portal on backgound ..." pushd occlum_client -occlum run /bin/rest_api.py & +occlum run --config-svn 1234 /bin/rest_api.py & popd while ! nc -z $FLASK_SERVER_IP $FLASK_SERVER_PORT; do diff --git a/example/build_content.sh b/example/build_content.sh index 5f368fda..eec3a482 100755 --- a/example/build_content.sh +++ b/example/build_content.sh @@ -77,6 +77,7 @@ function build_tf_instance() .verify_mr_signer = "on" | .verify_isv_prod_id = "off" | .verify_isv_svn = "off" | + .verify_config_svn = "off" | .verify_enclave_debuggable = "on" | .sgx_mrs[0].mr_signer = ''"'`get_mr tf mr_signer`'" | .sgx_mrs[0].debuggable = false ' ../ra_config_template.json > dynamic_config.json @@ -126,6 +127,7 @@ function build_server_instance() .verify_mr_signer = "on" | .verify_isv_prod_id = "off" | .verify_isv_svn = "off" | + .verify_config_svn = "off" | .verify_enclave_debuggable = "on" | .sgx_mrs[0].mr_enclave = ''"'`get_mr tf mr_enclave`'" | .sgx_mrs[0].mr_signer = ''"'`get_mr tf mr_signer`'" | diff --git a/example/ra_config_template.json b/example/ra_config_template.json index 573c86ff..5bb0f4da 100644 --- a/example/ra_config_template.json +++ b/example/ra_config_template.json @@ -3,13 +3,15 @@ "verify_mr_signer" : "on", "verify_isv_prod_id" : "on", "verify_isv_svn" : "on", + "verify_config_svn" : "off", "verify_enclave_debuggable" : "on", "sgx_mrs": [ { "mr_enclave" : "", "mr_signer" : "", - "isv_prod_id" : "0", - "isv_svn" : "0", + "isv_prod_id" : 0, + "isv_svn" : 0, + "config_svn" : 0, "debuggable" : false } ]