From 9e4440ef0bfb9e7cc084a9060ed245fd31cbc0c9 Mon Sep 17 00:00:00 2001 From: Rajeev Ranjan Date: Wed, 17 Feb 2021 08:33:27 +0530 Subject: [PATCH] KME Replication at trusted layer Implementation of workorder targetted for KME (primary/replica) - state-uid - state-request - get-state - set-state Signed-off-by: Rajeev Ranjan --- .../enclave/enclave_data.cpp | 4 +- .../enclave/enclave_data.h | 27 +- .../enclave/kme/ext_work_order_info_kme.h | 8 + .../kme/workload/kme_workload_plug-in.cpp | 378 +++++++++++++++++- .../kme/workload/kme_workload_plug-in.h | 54 +++ .../enclave_untrusted/enclave_bridge/base.cpp | 7 + .../enclave_bridge/enclave.cpp | 3 +- .../enclave_bridge/enclave_queue.cpp | 2 + .../base_enclave_info.cpp | 10 + .../base_enclave_info.h | 1 + 10 files changed, 486 insertions(+), 8 deletions(-) diff --git a/tc/sgx/trusted_worker_manager/enclave/enclave_data.cpp b/tc/sgx/trusted_worker_manager/enclave/enclave_data.cpp index f6a012e4f..d8fdb5cc7 100644 --- a/tc/sgx/trusted_worker_manager/enclave/enclave_data.cpp +++ b/tc/sgx/trusted_worker_manager/enclave/enclave_data.cpp @@ -79,7 +79,7 @@ EnclaveData::EnclaveData(const uint8_t* inSealedData) { nullptr, 0, &decrypted_data[0], &decrypted_size); tcf::error::ThrowSgxError(ret, "Failed to unseal data"); std::string decrypted_data_string(reinterpret_cast(&decrypted_data[0])); - DeserializeSealedData(decrypted_data_string); + DeserializePrivateData(decrypted_data_string); // Clear local variable storing secret(s) decrypted_data.clear(); decrypted_data_string.clear(); @@ -92,7 +92,7 @@ EnclaveData::EnclaveData(const uint8_t* inSealedData) { } // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -void EnclaveData::DeserializeSealedData(const std::string& inSerializedEnclaveData) { +void EnclaveData::DeserializePrivateData(const std::string& inSerializedEnclaveData) { std::string svalue; const char* pvalue = nullptr; size_t pvalue_len = 0; diff --git a/tc/sgx/trusted_worker_manager/enclave/enclave_data.h b/tc/sgx/trusted_worker_manager/enclave/enclave_data.h index d8f7c0ef6..4a66b395a 100644 --- a/tc/sgx/trusted_worker_manager/enclave/enclave_data.h +++ b/tc/sgx/trusted_worker_manager/enclave/enclave_data.h @@ -64,7 +64,7 @@ class EnclaveData { protected: void SerializePrivateData(void); void SerializePublicData(void); - void DeserializeSealedData(const std::string& inSerializedEnclaveData); + void DeserializePrivateData(const std::string& inSerializedEnclaveData); tcf::crypto::sig::PublicKey public_signing_key_; tcf::crypto::sig::PrivateKey private_signing_key_; @@ -79,7 +79,18 @@ class EnclaveData { std::string serialized_public_data_; public: - static EnclaveData* getInstance(const uint8_t* inSealedData=nullptr) { + void updateEnclaveData(std::string decrypted_private_data) { + DeserializePrivateData(decrypted_private_data); + // Clear local variable storing secret(s) + decrypted_private_data.clear(); + + // Create encryption key signature + generate_encryption_key_signature(); + + SerializePrivateData(); + SerializePublicData(); + } + static EnclaveData* getInstance(const uint8_t* inSealedData=nullptr) { if(!instance) { if(inSealedData != nullptr) instance = new EnclaveData(inSealedData); @@ -150,4 +161,16 @@ class EnclaveData { size_t sdsize = sgx_calc_sealed_data_size(0, get_private_data_size()); return sdsize; } + + void get_sealed_data(uint8_t* outSealedEnclaveData) const { + sgx_attributes_t attribute_mask = {0xfffffffffffffff3, 0}; + sgx_seal_data_ex(SGX_KEYPOLICY_MRENCLAVE, attribute_mask, + 0, // misc_mask + 0, // additional mac text length + nullptr, // additional mac text + get_private_data_size(), + reinterpret_cast(get_private_data().c_str()), + static_cast(get_sealed_data_size()), + reinterpret_cast(outSealedEnclaveData)); + } }; diff --git a/tc/sgx/trusted_worker_manager/enclave/kme/ext_work_order_info_kme.h b/tc/sgx/trusted_worker_manager/enclave/kme/ext_work_order_info_kme.h index 9418b42e1..8bf5ebc18 100644 --- a/tc/sgx/trusted_worker_manager/enclave/kme/ext_work_order_info_kme.h +++ b/tc/sgx/trusted_worker_manager/enclave/kme/ext_work_order_info_kme.h @@ -32,6 +32,14 @@ enum KmeRegistrationStatus { ERR_UNIQUE_ID_NOT_MATCH = 7 /// WPE unique id didn't match }; +enum KmeReplicationReturnCode { /// KME Replication operation(state-uid, state-request, get-state, set-state) status + KME_REPL_OP_SUCCESS = 0, /// Operation successful + KME_REPL_OP_FAILED = 1, /// Operation failure + ERR_KME_REPL_UID_MISMATCH = 2, /// State UID did not match for requesting Replica KME + ERR_KME_REPL_NONCE_MISMATCH = 3, /// Nonce did not match for requesting Replica KME + ERR_KME_REPL_SIG_VERIF_FAILED = 4 /// State UID+Nonce signature mismatch +}; + enum KmePreProcessStatus { ERR_WPE_MAX_WO_COUNT_REACHED = 1 }; diff --git a/tc/sgx/trusted_worker_manager/enclave/kme/workload/kme_workload_plug-in.cpp b/tc/sgx/trusted_worker_manager/enclave/kme/workload/kme_workload_plug-in.cpp index 67366023a..48ee009fd 100644 --- a/tc/sgx/trusted_worker_manager/enclave/kme/workload/kme_workload_plug-in.cpp +++ b/tc/sgx/trusted_worker_manager/enclave/kme/workload/kme_workload_plug-in.cpp @@ -22,8 +22,12 @@ #include "json_utils.h" #include "signup_enclave_util.h" #include "enclave_utils.h" +#include "crypto.h" +#include "hex_string.h" +#include using namespace tcf::error; +#define KME_STATE_UPDATE_UID_SIZE_BYTES 16 REGISTER_WORKLOAD_PROCESSOR_KME("kme",KMEWorkloadProcessor); @@ -45,6 +49,21 @@ std::map KMEWorkloadProcessor::sig_key_map; */ std::map KMEWorkloadProcessor::wpe_enc_key_map; +/* +* State_uid persisted from last call to state_uid from a replica KME. +* @TODO - Might need to be converted to a map for handling multiple +* replica KME spawning/syncing simultaneously +*/ +std::string state_uid_hex; + +/* +* State request nonce persisted from last call to state_request from +* a replica KME. Used to check freshness when set-state call arrives. +* @TODO - Might need to be converted to a map for handling multiple +* replica KME spawning/syncing simultaneously +*/ +std::string state_req_nonce_hex; + WPEInfo::WPEInfo() { workorder_count = 0; signing_key = {}; @@ -57,6 +76,289 @@ WPEInfo::WPEInfo(const ByteArray& _sk) { signing_key = _sk; } +WPEInfo::WPEInfo(const uint64_t _wo_c, const ByteArray& _sk) { + workorder_count = _wo_c; + /* signing key corresponds to the private key of + * unique ID verification key */ + signing_key = _sk; +} + +/* + * Get Unique ID for the KME State Update. + * + * @param in_work_order_data - vector of work order indata + * @param out_work_order_data - vector of work order outdata + * + * Outdata contains the following - + * uid_ba - Unique id for replication as ByteArray +*/ +void KMEWorkloadProcessor::GetStateReplicationId( + const std::vector& in_work_order_data, + std::vector& out_work_order_data) { + + // Generate random bytes of size 16, + ByteArray uid_bytes = tcf::crypto::RandomBitString(KME_STATE_UPDATE_UID_SIZE_BYTES); + // Convert nonce to hex string + std::string uid_hex = ByteArrayToHexEncodedString(uid_bytes); + + // Persist the state_uid in-memory + state_uid_hex = uid_hex; + + ByteArray uid_ba = StrToByteArray(uid_hex); + + SetStatus(KME_REPL_OP_SUCCESS, out_work_order_data); + AddOutput(1, uid_ba, out_work_order_data); +} + +/* + * Create KME State Update Request. + * + * @param in_work_order_data - vector of work order indata. + * It consists of the unique_id and signing key + * @param out_work_order_data - vector of work order outdata + * + * Outdata contains the following - + * uid_ba - Unique id for replication as ByteArray + * nonce_ba - A random nonce as ByteArray + * uid_nonce_signed - Signatue (using private signing key of Replica KME) + * of the concatenation of uid & nonce +*/ +void KMEWorkloadProcessor::CreateStateReplicatonRequest( + const std::vector& in_work_order_data, + std::vector& out_work_order_data) { + + // Extract uid from in_data that comes in the request from + // replica KME + ByteArray uid_ba = in_work_order_data[0].decrypted_data; + // Generate random bytes of size 16, + ByteArray nonce_bytes = tcf::crypto::RandomBitString(16); + // Convert nonce to hex string + std::string nonce_hex = ByteArrayToHexEncodedString(nonce_bytes); + // Persist the state_req_nonce_hex in-memory to later verify freshness + // of set-state request in a replica KME + state_req_nonce_hex = nonce_hex; + + ByteArray nonce_ba = StrToByteArray(state_req_nonce_hex); + SetStatus(KME_REPL_OP_SUCCESS, out_work_order_data); + AddOutput(1, uid_ba, out_work_order_data); // unique_id_hex_str + AddOutput(2, nonce_ba, out_work_order_data); // generated_nonce_hex_str + ByteArray concat_ba = StrToByteArray( ByteArrayToStr(uid_ba) + + ByteArrayToStr(nonce_ba)); + uint8_t concat_str_hash[SGX_HASH_SIZE] = {0}; + ComputeSHA256Hash(ByteArrayToString(concat_ba), concat_str_hash); + EnclaveData* enclave_data = EnclaveData::getInstance(); + ByteArray uid_nonce_signed = enclave_data->sign_message( + ByteArray(std::begin(concat_str_hash), std::end(concat_str_hash))); + uid_nonce_signed = StrToByteArray(ByteArrayToHexEncodedString(uid_nonce_signed)); + AddOutput(3, uid_nonce_signed, out_work_order_data); // uid_nonce_signed +} + +/* + * Get Primary KME State API. + * + * @param in_work_order_data - vector of work order indata + * @param out_work_order_data - vector of work order outdata + * + * Outdata contains the following - + * unique_id_hex - Unique id for replication as ByteArray + * generated_nonce_hex - Generated nonce + * enc_sym_key - Encrypted (using pub encryption key of replica KME) + * symmetric key + * enc_state_data - Encrypted (using symmetric key) state data + * hash_signed - Hash of state data, symmetric key, unique id, nonce + * is hashed and then signed using the private signing + * key of the primary KME +*/ +void KMEWorkloadProcessor::GetStateReplica( + const std::vector& in_work_order_data, + std::vector& out_work_order_data) { + + // Extract attestation_info from in_data at index 0 + ByteArray attestation_info = in_work_order_data[0].decrypted_data; + // Extract unique_id_hex from in_data at index 1 + ByteArray unique_id_hex = in_work_order_data[1].decrypted_data; + // Extract generated_nonce_hex from in_data at index 2 + ByteArray generated_nonce_hex = in_work_order_data[2].decrypted_data; + // Extract uid_nonce_sig from in_data at index 3 + ByteArray uid_nonce_sig = in_work_order_data[3].decrypted_data; + // Extract replica KME pub signing key from in_data that comes in + // the request + ByteArray pub_sig_key_ba = in_work_order_data[4].decrypted_data; + // Extract replica KME pub enc key from in_data that comes in + // the request + ByteArray pub_enc_key_ba = in_work_order_data[5].decrypted_data; + + //@TODO - Verify attestation_info; MRSIGNER & MRENCLAVE should match for the + //requesting & primary KME. + + //Verify that the unique_id matches the one in-memory + if (memcmp(unique_id_hex.data(), + StrToByteArray(state_uid_hex).data(), 16) != 0) { + this->SetStatus((int)ERR_KME_REPL_UID_MISMATCH, out_work_order_data); + ThrowIf(true, "State uid did not match"); + } + + //Verfiy signature + tcf::crypto::sig::PublicKey pub_sk = tcf::crypto::sig::PublicKey(ByteArrayToStr(pub_sig_key_ba)); + + ByteArray concat_ba = StrToByteArray( ByteArrayToStr(unique_id_hex) + + ByteArrayToStr(generated_nonce_hex)); + uint8_t concat_str_hash[SGX_HASH_SIZE] = {0}; + ComputeSHA256Hash(ByteArrayToString(concat_ba), concat_str_hash); + uid_nonce_sig = HexEncodedStringToByteArray(ByteArrayToStr(uid_nonce_sig)); + if (pub_sk.VerifySignature(ByteArray(std::begin(concat_str_hash), + std::end(concat_str_hash)), + uid_nonce_sig) != 1) { + this->SetStatus((int)ERR_KME_REPL_SIG_VERIF_FAILED, out_work_order_data); + ThrowIf(true, "Signature verification failed while getting state."); + } + //Generate Symmetric enc key + ByteArray sym_key = tcf::crypto::skenc::GenerateKey(); + + EnclaveData* enclave_data = EnclaveData::getInstance(); + //Obtain state data. String concatenation of pvt_data, enc_key_map, sig_key_map + //delimited by semicolon (;) + std::string state_data = enclave_data->get_private_data(); + state_data += ";"; + state_data += KMEWorkloadProcessor::serializeEncKeyMap(); + state_data += ";"; + state_data += KMEWorkloadProcessor::serializeSigKeyMap(); + + ByteArray state_data_ba = StrToByteArray(state_data); + //Encrypt state data with sym enc key + ByteArray enc_state_data = tcf::crypto::skenc::EncryptMessage( + sym_key, state_data_ba); + //Encrypt sym enc key with requester pub enc key + tcf::crypto::pkenc::PublicKey pub_ek = tcf::crypto::pkenc::PublicKey(ByteArrayToStr(pub_enc_key_ba)); + ByteArray enc_sym_key = pub_ek.EncryptMessage(sym_key); + + //Generate signature of the output + + //SHA256 of state data(JSON as byte array) is calculated + ComputeSHA256Hash(ByteArrayToString(state_data_ba), concat_str_hash); + + //Concatenate hash, sym enc key, unique id, nonce + concat_ba = StrToByteArray( ByteArrayToStr(ByteArray(std::begin(concat_str_hash), + std::end(concat_str_hash))) + + ByteArrayToStr(sym_key) + + ByteArrayToStr(unique_id_hex) + + ByteArrayToStr(generated_nonce_hex)); + + //SHA256 of concatenated byte array is calculated + ComputeSHA256Hash(ByteArrayToString(concat_ba), concat_str_hash); + + //Sign hash with signing key + ByteArray hash_signed = enclave_data->sign_message( + ByteArray(std::begin(concat_str_hash), std::end(concat_str_hash))); + + //Cleanup in-memory state-uid + state_uid_hex = ""; + + SetStatus(KME_REPL_OP_SUCCESS, out_work_order_data); + //@TODO - Output at index 1 to be Attestation info of this(primary) KME + AddOutput(1, unique_id_hex, out_work_order_data); // unique_id_hex_str + AddOutput(2, generated_nonce_hex, out_work_order_data); // generated_nonce_hex_str + AddOutput(3, enc_sym_key, out_work_order_data); // Encrypted symmetric key + AddOutput(4, enc_state_data, out_work_order_data); // Encrypted state data + AddOutput(5, hash_signed, out_work_order_data); // Signed hash +} + +/* + * Set Backup KME State. + * + * @param in_work_order_data - vector of work order indata + * @param out_work_order_data - vector of work order outdata + * + * Outdata contains the following - + * sealed_ba - Sealed data as ByteArray +*/ +void KMEWorkloadProcessor::UpdateState( + const std::vector& in_work_order_data, + std::vector& out_work_order_data) { + + + // Extract attestation_info from in_data at index 0 + ByteArray attestation_info = in_work_order_data[0].decrypted_data; + // Extract unique_id_hex from in_data at index 1 + ByteArray unique_id_hex = in_work_order_data[1].decrypted_data; + // Extract generated_nonce_hex from in_data at index 2 + ByteArray generated_nonce_hex = in_work_order_data[2].decrypted_data; + // Extract enc_sym_key from in_data at index 3 + ByteArray enc_sym_key = in_work_order_data[3].decrypted_data; + // Extract enc_state_data from in_data at index 4 + ByteArray enc_state_data = in_work_order_data[4].decrypted_data; + // Extract output_sig from in_data at index 5 + ByteArray output_sig = in_work_order_data[5].decrypted_data; + + EnclaveData* enclave_data = EnclaveData::getInstance(); + + //@TODO - Verify that attestation attributes match with primary KME + //Verify that input nonce matches with that in-memory + if (memcmp(generated_nonce_hex.data(), + StrToByteArray(state_req_nonce_hex).data(), 16) != 0) { + this->SetStatus((int)ERR_KME_REPL_NONCE_MISMATCH, out_work_order_data); + ThrowIf(true, "Generated nonce did not match"); + } + //Verify signature + + //Decrypt state that was encrypted using sym key + ByteArray sym_key = enclave_data->decrypt_message(enc_sym_key); + ByteArray dec_state_data = tcf::crypto::skenc::DecryptMessage( + sym_key, enc_state_data); + uint8_t concat_str_hash[SGX_HASH_SIZE] = {0}; + + ComputeSHA256Hash(ByteArrayToString(dec_state_data), concat_str_hash); + + //Concatenate hash, sym enc key, unique id, nonce + ByteArray concat_ba = StrToByteArray( ByteArrayToStr(ByteArray(std::begin(concat_str_hash), + std::end(concat_str_hash))) + + ByteArrayToStr(sym_key) + + ByteArrayToStr(unique_id_hex) + + ByteArrayToStr(generated_nonce_hex)); + + //SHA256 of concatenated byte array is calculated + ComputeSHA256Hash(ByteArrayToString(concat_ba), concat_str_hash); + + if (enclave_data->verify_signature( + ByteArray(std::begin(concat_str_hash), + std::end(concat_str_hash)), output_sig) != 0) { + this->SetStatus((int)ERR_KME_REPL_SIG_VERIF_FAILED, out_work_order_data); + ThrowIf(true, "Signature verification failed while setting state."); + } + + //Delete sym key + sym_key.clear(); + + //Update internal private state. Split string concatenation of pvt_data, + //enc_key_map, sig_key_map delimited by semicolon (;) + std::string str = ByteArrayToStr(dec_state_data); + std::string::size_type pos = str.find_first_of(';'); + std::string pvt_state_data = str.substr(0, pos); + + str = str.substr(pos+1); + pos = str.find_first_of(';'); + std::string enc_key_map_ser = str.substr(0, pos); + + std::string sig_key_map_ser = str.substr(pos+1); + + sig_key_map = derializeSigKeyMap(sig_key_map_ser); + + wpe_enc_key_map = derializeEncKeyMap(enc_key_map_ser); + + enclave_data->updateEnclaveData(ByteArrayToStr(dec_state_data)); + + //Add output + SetStatus(KME_REPL_OP_SUCCESS, out_work_order_data); + //@TODO + //AddOutput(1, unique_id_hex, out_work_order_data); // updated KME attestation data + + uint8_t* out_sealed_enclave_data; + out_sealed_enclave_data = (uint8_t*) malloc(enclave_data->get_sealed_data_size()); + enclave_data->get_sealed_data(out_sealed_enclave_data); + ByteArray sealed_ba = ByteArray(out_sealed_enclave_data, out_sealed_enclave_data+(enclave_data->get_sealed_data_size())); + AddOutput(1, sealed_ba, out_work_order_data); // encrypted sealed data as base64 +} + void KMEWorkloadProcessor::GetUniqueId( const std::vector& in_work_order_data, std::vector& out_work_order_data) { @@ -200,8 +502,8 @@ void KMEWorkloadProcessor::Register( mr_enclave_bytes = HexEncodedStringToByteArray(mr_enclave); // Compare MRENCLAVE value - EnclaveData* enclaveData = EnclaveData::getInstance(); - ByteArray ext_data = enclaveData->get_extended_data(); + EnclaveData* enclave_data = EnclaveData::getInstance(); + ByteArray ext_data = enclave_data->get_extended_data(); if (memcmp(ext_data.data(), mr_enclave_bytes.data(), SGX_HASH_SIZE) != 0) { this->SetStatus((int)ERR_MRENCLAVE_NOT_MATCH, out_work_order_data); @@ -367,7 +669,15 @@ void KMEWorkloadProcessor::ProcessWorkOrder( const std::vector& in_work_order_data, std::vector& out_work_order_data) { - if (workload_id == "kme-uid") { + if (workload_id == "state-uid") { + GetStateReplicationId(in_work_order_data, out_work_order_data); + } if (workload_id == "state-request") { + CreateStateReplicatonRequest(in_work_order_data, out_work_order_data); + } else if (workload_id == "get-state") { + GetStateReplica(in_work_order_data, out_work_order_data); + } else if (workload_id == "set-state") { + UpdateState(in_work_order_data, out_work_order_data); + } else if (workload_id == "kme-uid") { GetUniqueId(in_work_order_data, out_work_order_data); } else if (workload_id == "kme-reg") { Register(in_work_order_data, out_work_order_data); @@ -389,3 +699,65 @@ int KMEWorkloadProcessor::isSgxSimulator() { #endif // defined(SGX_SIMULATOR) } +std::string KMEWorkloadProcessor::serializeSigKeyMap(){ + std::string serialized_str; + std::map::iterator it; + + for (it = sig_key_map.begin(); it != sig_key_map.end(); it++){ + serialized_str += ByteArrayToStr(it->first); + serialized_str += ","; + serialized_str += ByteArrayToStr(it->second); + serialized_str += " "; + } + if (serialized_str.length() > 1) + serialized_str = serialized_str.substr(0, serialized_str.length()-2); + return serialized_str; +} +std::map KMEWorkloadProcessor::derializeSigKeyMap(std::string serialized){ + std::map _sig_key_map; + + while(serialized.length() != 0){ + std::string::size_type pos = serialized.find_first_of(' '); + std::string map_entry = serialized.substr(0, pos); + + std::string::size_type pos_entry = serialized.find_first_of(','); + std::string key = map_entry.substr(0, pos_entry); + std::string value = map_entry.substr(pos_entry+1); + _sig_key_map[StrToByteArray(key)] = StrToByteArray(value); + + serialized = serialized.substr(pos+1); + } + + return _sig_key_map; +} +std::string KMEWorkloadProcessor::serializeEncKeyMap(){ + std::string serialized_str; + std::map::iterator it; + + for (it = wpe_enc_key_map.begin(); it != wpe_enc_key_map.end(); it++){ + serialized_str += ByteArrayToStr(it->first); + serialized_str += ":"; + serialized_str += ByteArrayToStr((it->second).serialize()); + serialized_str += "|"; + } + + return serialized_str; +} +std::map KMEWorkloadProcessor::derializeEncKeyMap(std::string serialized){ + std::map _enc_key_map; + + while(serialized.length() != 0){ + std::string::size_type pos = serialized.find_first_of('|'); + std::string map_entry = serialized.substr(0, pos); + + std::string::size_type pos_entry = map_entry.find_first_of(':'); + std::string key = map_entry.substr(0, pos_entry); + std::string value = map_entry.substr(pos_entry+1); + WPEInfo w_info = WPEInfo(); + w_info.deserialize(StrToByteArray(value)); + _enc_key_map[StrToByteArray(key)] = w_info; + serialized = serialized.substr(pos+1); + } + + return _enc_key_map; +} diff --git a/tc/sgx/trusted_worker_manager/enclave/kme/workload/kme_workload_plug-in.h b/tc/sgx/trusted_worker_manager/enclave/kme/workload/kme_workload_plug-in.h index c3fb9477f..26c53c563 100644 --- a/tc/sgx/trusted_worker_manager/enclave/kme/workload/kme_workload_plug-in.h +++ b/tc/sgx/trusted_worker_manager/enclave/kme/workload/kme_workload_plug-in.h @@ -33,6 +33,40 @@ typedef struct WPEInfo { WPEInfo(); WPEInfo(const ByteArray& _sk); + WPEInfo(const uint64_t _wo_c, const ByteArray& _sk); + + /* + * Serialize WPEInfo into a ByteArray, the member variables + * delimited by a comma (,). + * + * @returns Serialized WPEInfo as bytearray + * + */ + ByteArray serialize(){ + std::string serialized = std::to_string(workorder_count); + serialized += ","; + serialized += ByteArrayToStr(signing_key); + + return StrToByteArray(serialized); + } + + /* + * Deserialize ByteArray to WPEInfo instance. + * + * @param ba - Serialized WPEInfo instance as a ByteArray + * + */ + void deserialize(ByteArray ba){ + std::string str = ByteArrayToStr(ba); + + std::string::size_type pos = str.find_first_of(','); + + std::string count = str.substr(0, pos); + workorder_count = std::stoul(count.c_str()); + + std::string key = str.substr(pos+1); + signing_key = StrToByteArray(key); + } } WPEInfo; class KMEWorkloadProcessor: public WorkloadProcessorKME { @@ -47,6 +81,22 @@ class KMEWorkloadProcessor: public WorkloadProcessorKME { IMPL_WORKLOAD_PROCESSOR_CLONE(KMEWorkloadProcessor); + void GetStateReplicationId( + const std::vector& in_work_order_data, + std::vector& out_work_order_data); + + void CreateStateReplicatonRequest( + const std::vector& in_work_order_data, + std::vector& out_work_order_data); + + void GetStateReplica( + const std::vector& in_work_order_data, + std::vector& out_work_order_data); + + void UpdateState( + const std::vector& in_work_order_data, + std::vector& out_work_order_data); + void GetUniqueId( const std::vector& in_work_order_data, std::vector& out_work_order_data); @@ -66,6 +116,10 @@ class KMEWorkloadProcessor: public WorkloadProcessorKME { const ByteArray& work_order_id, const std::vector& in_work_order_data, std::vector& out_work_order_data) override; + std::string serializeSigKeyMap(); + std::map derializeSigKeyMap(std::string serialized); + std::string serializeEncKeyMap(); + std::map derializeEncKeyMap(std::string serialized); private: int isSgxSimulator(); diff --git a/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/base.cpp b/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/base.cpp index 063d238b5..8d32dbd60 100644 --- a/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/base.cpp +++ b/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/base.cpp @@ -115,6 +115,13 @@ tcf_err_t tcf::enclave_api::base::Terminate() { for (tcf::enclave_api::Enclave& enc : g_Enclave) { enc.Unload(); } + // Empty out the vector of enclaves maintained + int q_size = g_Enclave.size(); + for (int i=0; i< q_size; i++){ + g_Enclave.pop_back(); + g_EnclaveReadyQueue->pop(); + } + //g_Enclave.clear(); g_IsInitialized = false; } } catch (tcf::error::Error& e) { diff --git a/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/enclave.cpp b/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/enclave.cpp index 817eb29e9..0c7e33229 100644 --- a/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/enclave.cpp +++ b/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/enclave.cpp @@ -86,7 +86,8 @@ namespace tcf { if (this->enclaveId) { // No power or busy retries here.... // We don't want to reinitialize just to shutdown. - sgx_destroy_enclave(this->enclaveId); + if (SGX_SUCCESS != sgx_destroy_enclave(this->enclaveId)) + tcf::Log(TCF_LOG_ERROR,"Enclave destroy failed.\n"); this->enclaveId = 0; } } // Enclave::Unload diff --git a/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/enclave_queue.cpp b/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/enclave_queue.cpp index e7d6cd67a..b87bacf41 100644 --- a/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/enclave_queue.cpp +++ b/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge/enclave_queue.cpp @@ -22,6 +22,8 @@ #include "tcf_error.h" #include "types.h" +#include "log.h" + #include "enclave_queue.h" diff --git a/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge_wrapper/base_enclave_info.cpp b/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge_wrapper/base_enclave_info.cpp index a22c578f7..6b5f44a31 100644 --- a/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge_wrapper/base_enclave_info.cpp +++ b/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge_wrapper/base_enclave_info.cpp @@ -66,3 +66,13 @@ BaseEnclaveInfo::~BaseEnclaveInfo() { } catch (...) {} } // BaseEnclaveInfo::~BaseEnclaveInfo + +// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +void BaseEnclaveInfo::TerminateEnclave() { + try { + tcf::Log(TCF_LOG_INFO, "Will terminate currently running enclave\n"); + tcf::enclave_api::base::Terminate(); + } catch (...) { + tcf::Log(TCF_LOG_ERROR, "Error terminating Avalon Intel SGX Enclave\n"); + } +} // BaseEnclaveInfo::TerminateEnclave diff --git a/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge_wrapper/base_enclave_info.h b/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge_wrapper/base_enclave_info.h index 35a0febe6..7bbefff1c 100644 --- a/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge_wrapper/base_enclave_info.h +++ b/tc/sgx/trusted_worker_manager/enclave_untrusted/enclave_bridge_wrapper/base_enclave_info.h @@ -27,6 +27,7 @@ class BaseEnclaveInfo { const std::string& persisted_sealed_data, const int num_of_enclaves); virtual ~BaseEnclaveInfo(); + void TerminateEnclave(); std::string mr_enclave; // hex encoding of the enclave measurement std::string basename; // hex encoding of the basename