Add SGX KSS config_svn verification support in grpc_ratls

This commit is contained in:
Zheng, Qi 2022-04-27 16:20:26 +08:00 committed by volcano
parent 78450e58f8
commit cf080a46a0
12 changed files with 51 additions and 16 deletions

@ -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

@ -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<std::mutex> 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");
}

@ -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_measurement> 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);

@ -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");

@ -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
}
]

@ -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

@ -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" |

@ -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
}
]

@ -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

@ -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

@ -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`'" |

@ -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
}
]