From e7a5b8687c9b8bfab26c02556c7c3b74a84c10d7 Mon Sep 17 00:00:00 2001 From: "S. Santos" Date: Wed, 3 Apr 2024 09:58:08 -0300 Subject: [PATCH] [WIP] Add Sealing Key --- enclave/App/App.cpp | 537 +----------------- enclave/App/database/db_manager.cpp | 420 +++++++++----- enclave/App/database/db_manager.h | 32 +- .../sealing_key_manager/sealing_key_manager.h | 4 - enclave/App/statechain/deposit.cpp | 49 ++ enclave/App/statechain/deposit.h | 22 + enclave/App/statechain/sign.cpp | 164 ++++++ enclave/App/statechain/sign.h | 31 + enclave/App/statechain/transfer_receiver.cpp | 93 +++ enclave/App/statechain/transfer_receiver.h | 28 + enclave/App/utilities/utilities.cpp | 12 + enclave/App/utilities/utilities.h | 3 + enclave/Enclave/Enclave.cpp | 279 +++------ enclave/Enclave/Enclave.edl | 33 +- enclave/Makefile | 7 +- enclave/utils/include_secp256k1_zkp_lib.cpp | 17 + enclave/utils/include_secp256k1_zkp_lib.h | 12 +- 17 files changed, 854 insertions(+), 889 deletions(-) create mode 100644 enclave/App/statechain/deposit.cpp create mode 100644 enclave/App/statechain/deposit.h create mode 100644 enclave/App/statechain/sign.cpp create mode 100644 enclave/App/statechain/sign.h create mode 100644 enclave/App/statechain/transfer_receiver.cpp create mode 100644 enclave/App/statechain/transfer_receiver.h create mode 100644 enclave/utils/include_secp256k1_zkp_lib.cpp diff --git a/enclave/App/App.cpp b/enclave/App/App.cpp index 191cc1df..d41a060a 100644 --- a/enclave/App/App.cpp +++ b/enclave/App/App.cpp @@ -21,6 +21,9 @@ #include "../utils/strencodings.h" #include "utilities/utilities.h" #include "database/db_manager.h" +#include "statechain/deposit.h" +#include "statechain/sign.h" +#include "statechain/transfer_receiver.h" #include "sealing_key_manager/sealing_key_manager.h" #include "App.h" @@ -30,235 +33,6 @@ # define ENCLAVE_FILENAME "enclave.signed.so" -bool save_generated_public_key( - std::string& database_connection_string, - char* sealed, size_t sealed_size, - unsigned char* server_public_key, size_t server_public_key_size, - std::string& statechain_id, - std::string& error_message) -{ - try - { - pqxx::connection conn(database_connection_string); - if (conn.is_open()) { - - std::string create_table_query = - "CREATE TABLE IF NOT EXISTS generated_public_key ( " - "id SERIAL PRIMARY KEY, " - "statechain_id varchar(50), " - "sealed_keypair BYTEA, " - "sealed_secnonce BYTEA, " - "public_nonce BYTEA, " - "public_key BYTEA UNIQUE, " - "sig_count INTEGER DEFAULT 0);"; - - pqxx::work txn(conn); - txn.exec(create_table_query); - txn.commit(); - - std::basic_string_view sealed_data_view(reinterpret_cast(sealed), sealed_size); - std::basic_string_view public_key_data_view(reinterpret_cast(server_public_key), server_public_key_size); - - std::string insert_query = - "INSERT INTO generated_public_key (sealed_keypair, public_key, statechain_id) VALUES ($1, $2, $3);"; - pqxx::work txn2(conn); - - txn2.exec_params(insert_query, sealed_data_view, public_key_data_view, statechain_id); - txn2.commit(); - - conn.close(); - return true; - } else { - error_message = "Failed to connect to the database!"; - return false; - } - } - catch (std::exception const &e) - { - error_message = e.what(); - return false; - } -} - -bool update_sealed_keypair( - std::string& database_connection_string, - char* sealed, size_t sealed_size, - unsigned char* server_public_key, size_t server_public_key_size, - std::string& statechain_id, - std::string& error_message) -{ - try - { - pqxx::connection conn(database_connection_string); - if (conn.is_open()) { - - std::string insert_query = - "UPDATE generated_public_key " - "SET sealed_keypair = $1, public_key = $2, sealed_secnonce = NULL, public_nonce = NULL " - "WHERE statechain_id = $3;"; - pqxx::work txn2(conn); - - std::basic_string_view sealed_data_view(reinterpret_cast(sealed), sealed_size); - std::basic_string_view public_key_data_view(reinterpret_cast(server_public_key), server_public_key_size); - - txn2.exec_params(insert_query, sealed_data_view, public_key_data_view, statechain_id); - txn2.commit(); - - conn.close(); - return true; - - } else { - error_message = "Failed to connect to the database!"; - return false; - } - } - catch (std::exception const &e) - { - error_message = e.what(); - return false; - } -} - -bool load_generated_key_data( - std::string& database_connection_string, - std::string& statechain_id, - char* sealed_keypair, size_t sealed_keypair_size, - char* sealed_secnonce, size_t sealed_secnonce_size, - unsigned char* public_nonce, const size_t public_nonce_size, - std::string& error_message) -{ - try - { - pqxx::connection conn(database_connection_string); - if (conn.is_open()) { - - std::string sealed_keypair_query = - "SELECT sealed_keypair, sealed_secnonce, public_nonce FROM generated_public_key WHERE statechain_id = $1;"; - - pqxx::nontransaction ntxn(conn); - - conn.prepare("load_generated_key_data_query", sealed_keypair_query); - - pqxx::result result = ntxn.exec_prepared("load_generated_key_data_query", statechain_id); - - if (!result.empty()) { - auto sealed_keypair_field = result[0]["sealed_keypair"]; - auto sealed_secnonce_field = result[0]["sealed_secnonce"]; - auto public_nonce_field = result[0]["public_nonce"]; - - if (!sealed_keypair_field.is_null()) { - auto sealed_keypair_view = sealed_keypair_field.as>(); - - if (sealed_keypair_view.size() != sealed_keypair_size) { - error_message = "Failed to retrieve keypair. Different size than expected !"; - return false; - } - - memcpy(sealed_keypair, sealed_keypair_view.data(), sealed_keypair_size); - } - - if (!sealed_secnonce_field.is_null()) { - auto sealed_secnonce_view = sealed_secnonce_field.as>(); - - if (sealed_secnonce_view.size() != sealed_secnonce_size) { - error_message = "Failed to retrieve secret nonce. Different size than expected !"; - return false; - } - - memcpy(sealed_secnonce, sealed_secnonce_view.data(), sealed_secnonce_size); - } - - if (!public_nonce_field.is_null()) { - auto public_nonce_view = public_nonce_field.as>(); - - if (public_nonce_view.size() != public_nonce_size) { - error_message = "Failed to retrieve public nonce. Different size than expected !"; - return false; - } - - memcpy(public_nonce, public_nonce_view.data(), public_nonce_size); - } - } - else { - error_message = "Failed to retrieve keypair. No data found !"; - return false; - } - - conn.close(); - return true; - } else { - error_message = "Failed to connect to the database!"; - return false; - } - } - catch (std::exception const &e) - { - error_message = e.what(); - return false; - } -} - -bool update_sealed_secnonce( - std::string& database_connection_string, - std::string& statechain_id, - unsigned char* serialized_server_pubnonce, const size_t serialized_server_pubnonce_size, - char* sealed_secnonce, size_t sealed_secnonce_size, - std::string& error_message) -{ - try - { - pqxx::connection conn(database_connection_string); - if (conn.is_open()) { - - std::basic_string_view sealed_secnonce_data_view(reinterpret_cast(sealed_secnonce), sealed_secnonce_size); - std::basic_string_view serialized_server_pubnonce_view(reinterpret_cast(serialized_server_pubnonce), serialized_server_pubnonce_size); - - std::string updated_query = - "UPDATE generated_public_key SET public_nonce = $1, sealed_secnonce = $2 WHERE statechain_id = $3"; - pqxx::work txn(conn); - - txn.exec_params(updated_query, serialized_server_pubnonce_view, sealed_secnonce_data_view, statechain_id); - txn.commit(); - - conn.close(); - return true; - } else { - error_message = "Failed to connect to the database!"; - return false; - } - } - catch (std::exception const &e) - { - error_message = e.what(); - return false; - } -} - -bool update_sig_count(std::string& database_connection_string, std::string& statechain_id) { - try - { - pqxx::connection conn(database_connection_string); - if (conn.is_open()) { - - std::string update_query = - "UPDATE generated_public_key SET sig_count = sig_count + 1 WHERE statechain_id = $1;"; - pqxx::work txn(conn); - - txn.exec_params(update_query, statechain_id); - txn.commit(); - - conn.close(); - return true; - } else { - return false; - } - } - catch (std::exception const &e) - { - return false; - } -} - /* ocall functions (untrusted) */ void ocall_print_string(const char *str) { @@ -275,17 +49,6 @@ void ocall_print_hex(const unsigned char** key, const int *keylen) printf("%s\n", key_to_string(*key, *keylen).c_str()); } -void initialize_encrypted_data(chacha20_poly1305_encrypted_data& encrypted_data, size_t data_len) { - - // initialize encrypted_data - encrypted_data.data_len = data_len; - encrypted_data.data = new unsigned char[encrypted_data.data_len]; - memset(encrypted_data.data, 0, encrypted_data.data_len); - - memset(encrypted_data.mac, 0, sizeof(encrypted_data.mac)); - memset(encrypted_data.nonce, 0, sizeof(encrypted_data.nonce)); -} - int SGX_CDECL main(int argc, char *argv[]) { (void)(argc); @@ -299,8 +62,6 @@ int SGX_CDECL main(int argc, char *argv[]) auto config = toml::parse_file("Settings.toml"); auto database_connection_string = config["intel_sgx"]["database_connection_string"].as_string()->get(); - std::cout << "Database connection string: " << database_connection_string << std::endl; - { const std::lock_guard lock(mutex_enclave_id); @@ -320,7 +81,7 @@ int SGX_CDECL main(int argc, char *argv[]) } CROW_ROUTE(app, "/get_public_key") - .methods("POST"_method)([&enclave_id, &mutex_enclave_id, &database_connection_string, &sealing_key_manager](const crow::request& req) { + .methods("POST"_method)([&enclave_id, &mutex_enclave_id, &sealing_key_manager](const crow::request& req) { if (sealing_key_manager.isSeedEmpty()) { return crow::response(500, "Sealing key is empty."); @@ -331,67 +92,17 @@ int SGX_CDECL main(int argc, char *argv[]) return crow::response(400); if (req_body.count("statechain_id") == 0) - return crow::response(400, "Invalid parameter. It must be 'client_pubkey'."); + return crow::response(400, "Invalid parameter. It must be 'statechain_id'."); std::string statechain_id = req_body["statechain_id"].s(); - // 1. Allocate memory for the aggregated pubkey and sealedprivkey. - size_t server_pubkey_size = 33; // serialized compressed public keys are 33-byte array - unsigned char server_pubkey[server_pubkey_size]; - - size_t sealedprivkey_size = utils::sgx_calc_sealed_data_size(0U, sizeof(secp256k1_keypair)); - char sealedprivkey[sealedprivkey_size]; - const std::lock_guard lock(mutex_enclave_id); - sgx_status_t ecall_ret; - sgx_status_t status = generate_new_keypair( - enclave_id, &ecall_ret, - server_pubkey, server_pubkey_size, - sealedprivkey, sealedprivkey_size); - - if (ecall_ret != SGX_SUCCESS) { - return crow::response(500, "Key aggregation Ecall failed "); - } if (status != SGX_SUCCESS) { - return crow::response(500, "Key aggregation failed "); - } - - // new encryption scheme - /* chacha20_poly1305_encrypted_data encrypted_data; - initialize_encrypted_data(encrypted_data, sizeof(secp256k1_keypair)); - - size_t server_pubkey_size2 = 33; // serialized compressed public keys are 33-byte array - unsigned char server_pubkey2[server_pubkey_size2]; - - sgx_status_t ecall_ret2; - generate_new_keypair2(enclave_id, &ecall_ret2, - server_pubkey2, server_pubkey_size2, - sealing_key_manager.sealed_seed, sealing_key_manager.sealed_seed_size, - &encrypted_data); - - std::string error_message2; - db_manager::save_generated_public_key(encrypted_data, server_pubkey2, server_pubkey_size2, statechain_id, error_message2); - */ - - auto server_seckey_hex = key_to_string(server_pubkey, server_pubkey_size); - - std::string error_message; - bool data_saved = save_generated_public_key( - // sealedprivkey.data(), sealedprivkey.size(), server_pubkey, server_pubkey_size, error_message); - database_connection_string, sealedprivkey, sealedprivkey_size, server_pubkey, server_pubkey_size, statechain_id, error_message); - - if (!data_saved) { - error_message = "Failed to save aggregated key data: " + error_message; - return crow::response(500, error_message); - } - - crow::json::wvalue result({{"server_pubkey", server_seckey_hex}}); - return crow::response{result}; - + return deposit::get_public_key(enclave_id, statechain_id, sealing_key_manager); }); CROW_ROUTE(app, "/get_public_nonce") - .methods("POST"_method)([&enclave_id, &mutex_enclave_id, &database_connection_string](const crow::request& req) { + .methods("POST"_method)([&enclave_id, &mutex_enclave_id, &sealing_key_manager](const crow::request& req) { auto req_body = crow::json::load(req.body); if (!req_body) @@ -403,68 +114,13 @@ int SGX_CDECL main(int argc, char *argv[]) std::string statechain_id = req_body["statechain_id"].s(); - size_t sealed_keypair_size = utils::sgx_calc_sealed_data_size(0U, sizeof(secp256k1_keypair)); - std::vector sealed_keypair(sealed_keypair_size); // Using a vector to manage dynamic-sized array. - - size_t sealed_secnonce_size = utils::sgx_calc_sealed_data_size(0U, sizeof(secp256k1_musig_secnonce)); - std::vector sealed_secnonce(sealed_secnonce_size); // Using a vector to manage dynamic-sized array. - - unsigned char serialized_server_pubnonce[66]; - - memset(sealed_keypair.data(), 0, sealed_keypair_size); - memset(sealed_secnonce.data(), 0, sealed_secnonce_size); - - std::string error_message; - bool data_loaded = load_generated_key_data( - database_connection_string, - statechain_id, - sealed_keypair.data(), sealed_keypair_size, - sealed_secnonce.data(), sealed_secnonce_size, - serialized_server_pubnonce, sizeof(serialized_server_pubnonce), - error_message); - - if (!data_loaded) { - error_message = "Failed to load aggregated key data: " + error_message; - return crow::response(500, error_message); - } - - memset(sealed_secnonce.data(), 0, sealed_secnonce_size); - memset(serialized_server_pubnonce, 0, sizeof(serialized_server_pubnonce)); - - sgx_status_t ecall_ret; - sgx_status_t status = generate_nonce( - enclave_id, &ecall_ret, - sealed_keypair.data(), sealed_keypair_size, - sealed_secnonce.data(), sealed_secnonce_size, - serialized_server_pubnonce, sizeof(serialized_server_pubnonce)); - - if (ecall_ret != SGX_SUCCESS) { - return crow::response(500, "Generate Nonce Ecall failed "); - } if (status != SGX_SUCCESS) { - return crow::response(500, "Generate Nonce failed "); - } - - bool data_saved = update_sealed_secnonce( - database_connection_string, - statechain_id, - serialized_server_pubnonce, sizeof(serialized_server_pubnonce), - sealed_secnonce.data(), sealed_secnonce_size, - error_message - ); - - if (!data_saved) { - error_message = "Failed to save sealed secret nonce: " + error_message; - return crow::response(500, error_message); - } - - auto serialized_server_pubnonce_hex = key_to_string(serialized_server_pubnonce, sizeof(serialized_server_pubnonce)); + const std::lock_guard lock(mutex_enclave_id); - crow::json::wvalue result({{"server_pubnonce", serialized_server_pubnonce_hex}}); - return crow::response{result}; + return signature::get_public_nonce(enclave_id, statechain_id, sealing_key_manager); }); - + CROW_ROUTE(app, "/get_partial_signature") - .methods("POST"_method)([&enclave_id, &mutex_enclave_id, &database_connection_string](const crow::request& req) { + .methods("POST"_method)([&enclave_id, &mutex_enclave_id, &sealing_key_manager](const crow::request& req) { auto req_body = crow::json::load(req.body); if (!req_body) @@ -485,109 +141,26 @@ int SGX_CDECL main(int argc, char *argv[]) session_hex = session_hex.substr(2); } - std::vector serialized_session = ParseHex(session_hex); if (serialized_session.size() != 133) { return crow::response(400, "Invalid session length. Must be 133 bytes!"); } - size_t sealed_keypair_size = utils::sgx_calc_sealed_data_size(0U, sizeof(secp256k1_keypair)); - std::vector sealed_keypair(sealed_keypair_size); // Using a vector to manage dynamic-sized array. - - size_t sealed_secnonce_size = utils::sgx_calc_sealed_data_size(0U, sizeof(secp256k1_musig_secnonce)); - std::vector sealed_secnonce(sealed_secnonce_size); // Using a vector to manage dynamic-sized array. - - unsigned char serialized_server_pubnonce[66]; - - memset(sealed_keypair.data(), 0, sealed_keypair_size); - memset(sealed_secnonce.data(), 0, sealed_secnonce_size); - memset(serialized_server_pubnonce, 0, sizeof(serialized_server_pubnonce)); - - std::string error_message; - bool data_loaded = load_generated_key_data( - database_connection_string, - statechain_id, - sealed_keypair.data(), sealed_keypair_size, - sealed_secnonce.data(), sealed_secnonce_size, - serialized_server_pubnonce, sizeof(serialized_server_pubnonce), - error_message); - - if (!data_loaded) { - error_message = "Failed to load aggregated key data: " + error_message; - return crow::response(500, error_message); - } - - bool is_sealed_keypair_empty = std::all_of(sealed_keypair.begin(), sealed_keypair.end(), [](char elem){ return elem == 0; }); - bool is_sealed_secnonce_empty = std::all_of(sealed_secnonce.begin(), sealed_secnonce.end(), [](char elem){ return elem == 0; }); - - if (is_sealed_keypair_empty || is_sealed_secnonce_empty) { - return crow::response(400, "Empty sealed keypair or sealed secnonce!"); - } - - unsigned char serialized_partial_sig[32]; - - sgx_status_t ecall_ret; - sgx_status_t status = get_partial_signature( - enclave_id, &ecall_ret, - sealed_keypair.data(), sealed_keypair_size, - sealed_secnonce.data(), sealed_secnonce_size, - (int) negate_seckey, - serialized_session.data(), serialized_session.size(), - serialized_server_pubnonce, sizeof(serialized_server_pubnonce), - serialized_partial_sig, sizeof(serialized_partial_sig)); - - if (ecall_ret != SGX_SUCCESS) { - return crow::response(500, "Generate Signature Ecall failed "); - } if (status != SGX_SUCCESS) { - return crow::response(500, "Generate Signature failed "); - } - - bool sig_count_updated = update_sig_count(database_connection_string, statechain_id); - if (!sig_count_updated) { - return crow::response(500, "Failed to update signature count!"); - } - - auto partial_sig_hex = key_to_string(serialized_partial_sig, sizeof(serialized_partial_sig)); - - crow::json::wvalue result({{"partial_sig", partial_sig_hex}}); - return crow::response{result}; + const std::lock_guard lock(mutex_enclave_id); + + return signature::get_partial_signature(enclave_id, statechain_id, negate_seckey, serialized_session, sealing_key_manager); }); CROW_ROUTE(app,"/signature_count/") - ([&database_connection_string](std::string statechain_id){ - - std::string error_message; - pqxx::connection conn(database_connection_string); - if (conn.is_open()) { - - std::string sig_count_query = - "SELECT sig_count FROM generated_public_key WHERE statechain_id = $1;"; - - pqxx::nontransaction ntxn(conn); + ([](std::string statechain_id){ - conn.prepare("sig_count_query", sig_count_query); - - pqxx::result result = ntxn.exec_prepared("sig_count_query", statechain_id); - - if (!result.empty()) { - auto sig_count_field = result[0]["sig_count"]; - if (!sig_count_field.is_null()) { - auto sig_count = sig_count_field.as(); - crow::json::wvalue response({{"sig_count", sig_count}}); - return crow::response{response}; - } - } - conn.close(); - return crow::response(500, "Failed to retrieve signature count!"); - } else { - return crow::response(500, "Failed to connect to the database!"); - } + return signature::signature_count(statechain_id); }); CROW_ROUTE(app, "/keyupdate") - .methods("POST"_method)([&enclave_id, &mutex_enclave_id, &database_connection_string](const crow::request& req) { + .methods("POST"_method)([&enclave_id, &mutex_enclave_id, &sealing_key_manager](const crow::request& req) { auto req_body = crow::json::load(req.body); if (!req_body) @@ -623,73 +196,13 @@ int SGX_CDECL main(int argc, char *argv[]) return crow::response(400, "Invalid x1 length. Must be 32 bytes!"); } - size_t sealed_keypair_size = utils::sgx_calc_sealed_data_size(0U, sizeof(secp256k1_keypair)); - std::vector sealed_keypair(sealed_keypair_size); // Using a vector to manage dynamic-sized array. - - size_t sealed_secnonce_size = utils::sgx_calc_sealed_data_size(0U, sizeof(secp256k1_musig_secnonce)); - std::vector sealed_secnonce(sealed_secnonce_size); // Using a vector to manage dynamic-sized array. - - unsigned char serialized_server_pubnonce[66]; - - memset(sealed_keypair.data(), 0, sealed_keypair_size); - memset(sealed_secnonce.data(), 0, sealed_secnonce_size); - - std::string error_message; - bool data_loaded = load_generated_key_data( - database_connection_string, - statechain_id, - sealed_keypair.data(), sealed_keypair_size, - sealed_secnonce.data(), sealed_secnonce_size, - serialized_server_pubnonce, sizeof(serialized_server_pubnonce), - error_message); - - if (!data_loaded) { - error_message = "Failed to load aggregated key data: " + error_message; - return crow::response(500, error_message); - } - - bool is_sealed_keypair_empty = std::all_of(sealed_keypair.begin(), sealed_keypair.end(), [](char elem){ return elem == 0; }); - - if (is_sealed_keypair_empty) { - return crow::response(400, "Empty sealed keypair!"); - } - - // 1. Allocate memory for the aggregated pubkey and sealedprivkey. - size_t new_server_pubkey_size = 33; // serialized compressed public keys are 33-byte array - unsigned char new_server_pubkey[new_server_pubkey_size]; - - size_t new_sealedkeypair_size = utils::sgx_calc_sealed_data_size(0U, sizeof(secp256k1_keypair)); - char new_sealedkeypair[new_sealedkeypair_size]; - - const std::lock_guard lock(mutex_enclave_id); - - sgx_status_t ecall_ret; - sgx_status_t status = key_update( - enclave_id, &ecall_ret, - sealed_keypair.data(), sealed_keypair_size, - serialized_x1.data(), serialized_x1.size(), - serialized_t2.data(), serialized_t2.size(), - new_server_pubkey, new_server_pubkey_size, - new_sealedkeypair, new_sealedkeypair_size); - - if (ecall_ret != SGX_SUCCESS) { - return crow::response(500, "Key aggregation Ecall failed "); - } if (status != SGX_SUCCESS) { - return crow::response(500, "Key aggregation failed "); - } - - bool data_saved = update_sealed_keypair( - database_connection_string, new_sealedkeypair, new_sealedkeypair_size, new_server_pubkey, new_server_pubkey_size, statechain_id, error_message); - - if (!data_saved) { - error_message = "Failed to update aggregated key data: " + error_message; - return crow::response(500, error_message); - } - - auto new_server_seckey_hex = key_to_string(new_server_pubkey, new_server_pubkey_size); - - crow::json::wvalue result({{"server_pubkey", new_server_seckey_hex}}); - return crow::response{result}; + return transfer_receiver::keyupdate( + enclave_id, + statechain_id, + serialized_t2, + serialized_x1, + sealing_key_manager + ); }); CROW_ROUTE(app,"/delete_statechain/") @@ -746,7 +259,7 @@ int SGX_CDECL main(int argc, char *argv[]) crow::json::wvalue result({{"message", "OK."}}); return crow::response{result}; }); - + app.port(18080).multithreaded().run(); { diff --git a/enclave/App/database/db_manager.cpp b/enclave/App/database/db_manager.cpp index 1725592b..50554dda 100644 --- a/enclave/App/database/db_manager.cpp +++ b/enclave/App/database/db_manager.cpp @@ -1,15 +1,64 @@ #include "db_manager.h" +#include "../../utils/strencodings.h" #include "../Enclave_u.h" #include "../lib/toml.hpp" -#include "../../utils/strencodings.h" +#include "../utilities/utilities.h" #include -#include +#include #include - +#include namespace db_manager { - bool add_sealed_seed(char* sealed_secret, size_t sealed_secret_size, std::string& error_message) { + // Assumes the buffer is large enough. In a real application, ensure buffer safety. + void serialize(const chacha20_poly1305_encrypted_data* src, unsigned char* buffer, size_t* serialized_len) { + // Copy `data_len`, `nonce`, and `mac` directly + size_t offset = 0; + memcpy(buffer + offset, &src->data_len, sizeof(src->data_len)); + offset += sizeof(src->data_len); + + memcpy(buffer + offset, src->nonce, sizeof(src->nonce)); + offset += sizeof(src->nonce); + + memcpy(buffer + offset, src->mac, sizeof(src->mac)); + offset += sizeof(src->mac); + + // Now copy dynamic `data` + memcpy(buffer + offset, src->data, src->data_len); + offset += src->data_len; + + *serialized_len = offset; + } + + // Returns a newly allocated structure that must be freed by the caller. + bool deserialize(const unsigned char* buffer, chacha20_poly1305_encrypted_data* dest) { + + if (!dest) return false; + + size_t offset = 0; + memcpy(&dest->data_len, buffer + offset, sizeof(dest->data_len)); + offset += sizeof(dest->data_len); + + memcpy(dest->nonce, buffer + offset, sizeof(dest->nonce)); + offset += sizeof(dest->nonce); + + memcpy(dest->mac, buffer + offset, sizeof(dest->mac)); + offset += sizeof(dest->mac); + + dest->data = new unsigned char[dest->data_len]; + if (!dest->data) { + return false; // NULL; + } + memcpy(dest->data, buffer + offset, dest->data_len); + + return true; + } + + bool save_generated_public_key( + const chacha20_poly1305_encrypted_data& encrypted_keypair, + unsigned char* server_public_key, size_t server_public_key_size, + const std::string& statechain_id, + std::string& error_message) { auto config = toml::parse_file("Settings.toml"); auto database_connection_string = config["intel_sgx"]["database_connection_string"].as_string()->get(); @@ -20,24 +69,47 @@ namespace db_manager { if (conn.is_open()) { std::string create_table_query = - "CREATE TABLE IF NOT EXISTS seed ( " + "CREATE TABLE IF NOT EXISTS generated_public_key ( " "id SERIAL PRIMARY KEY, " - "sealed_seed BYTEA NOT NULL);"; + "statechain_id varchar(50), " + "sealed_keypair BYTEA, " + "sealed_secnonce BYTEA, " + "public_nonce BYTEA, " + "public_key BYTEA UNIQUE, " + "sig_count INTEGER DEFAULT 0);"; pqxx::work txn(conn); txn.exec(create_table_query); txn.commit(); - std::string insert_command = "INSERT INTO seed (sealed_seed) VALUES ($1);"; - pqxx::work txn2(conn); - std::basic_string_view sealed_data_view(reinterpret_cast(sealed_secret), sealed_secret_size); + size_t serialized_len = 0; + + size_t bufferSize = sizeof(encrypted_keypair.data_len) + sizeof(encrypted_keypair.nonce) + sizeof(encrypted_keypair.mac) + encrypted_keypair.data_len; + unsigned char* buffer = (unsigned char*) malloc(bufferSize); + + if (!buffer) { + error_message = "Failed to allocate memory for serialization!"; + return false; + } + + serialize(&encrypted_keypair, buffer, &serialized_len); + assert(serialized_len == bufferSize); + + std::basic_string_view sealed_data_view(reinterpret_cast(buffer), bufferSize); + std::basic_string_view public_key_data_view(reinterpret_cast(server_public_key), server_public_key_size); - txn2.exec_params(insert_command, sealed_data_view); + std::string insert_query = + "INSERT INTO generated_public_key (sealed_keypair, public_key, statechain_id) VALUES ($1, $2, $3);"; + pqxx::work txn2(conn); + + txn2.exec_params(insert_query, sealed_data_view, public_key_data_view, statechain_id); txn2.commit(); conn.close(); return true; + + return true; } else { error_message = "Failed to connect to the database!"; return false; @@ -50,11 +122,15 @@ namespace db_manager { } return true; + } - } // add_sealed_seed - - bool get_sealed_seed(char* sealed_secret, size_t sealed_secret_size, std::string& error_message) { - + bool load_generated_key_data( + const std::string& statechain_id, + std::unique_ptr& encrypted_keypair, + std::unique_ptr& encrypted_secnonce, + unsigned char* public_nonce, const size_t public_nonce_size, + std::string& error_message) + { auto config = toml::parse_file("Settings.toml"); auto database_connection_string = config["intel_sgx"]["database_connection_string"].as_string()->get(); @@ -63,26 +139,64 @@ namespace db_manager { pqxx::connection conn(database_connection_string); if (conn.is_open()) { - std::string select_command = "SELECT sealed_seed FROM seed ORDER BY id DESC LIMIT 1;"; - pqxx::work txn(conn); + std::string sealed_keypair_query = + "SELECT sealed_keypair, sealed_secnonce, public_nonce FROM generated_public_key WHERE statechain_id = $1;"; - pqxx::result result = txn.exec(select_command); + pqxx::nontransaction ntxn(conn); - if (result.size() == 0) { - error_message = "No sealed seed found!"; - return false; - } + conn.prepare("load_generated_key_data_query", sealed_keypair_query); + + pqxx::result result = ntxn.exec_prepared("load_generated_key_data_query", statechain_id); + + if (!result.empty()) { + auto sealed_keypair_field = result[0]["sealed_keypair"]; + auto sealed_secnonce_field = result[0]["sealed_secnonce"]; + auto public_nonce_field = result[0]["public_nonce"]; + + if (sealed_keypair_field.is_null()) { + encrypted_keypair.reset(); + } else if (encrypted_keypair != nullptr) { + auto sealed_keypair_view = sealed_keypair_field.as>(); + + std::vector sealed_keypair(sealed_keypair_view.size()); + memcpy(sealed_keypair.data(), sealed_keypair_view.data(), sealed_keypair_view.size()); + + if (!deserialize(sealed_keypair.data(), encrypted_keypair.get())) { + error_message = "Failed to deserialize keypair!"; + return false; + } + } + + if (sealed_secnonce_field.is_null()) { + encrypted_secnonce.reset(); + } else if (encrypted_secnonce != nullptr) { + auto sealed_secnonce_view = sealed_secnonce_field.as>(); + + std::vector sealed_secnonce(sealed_secnonce_view.size()); + memcpy(sealed_secnonce.data(), sealed_secnonce_view.data(), sealed_secnonce_view.size()); + + if (!deserialize(sealed_secnonce.data(), encrypted_secnonce.get())) { + error_message = "Failed to deserialize keypair!"; + return false; + } + } - pqxx::binarystring sealed_data = result[0]["sealed_seed"].as(); + if (!public_nonce_field.is_null() && public_nonce != nullptr) { + auto public_nonce_view = public_nonce_field.as>(); - if (sealed_data.size() != sealed_secret_size) { - error_message = "Failed to retrieve keypair. Different size than expected !"; + if (public_nonce_view.size() != public_nonce_size) { + error_message = "Failed to retrieve public nonce. Different size than expected !"; + return false; + } + + memcpy(public_nonce, public_nonce_view.data(), public_nonce_size); + } + } + else { + error_message = "Failed to retrieve keypair. No data found !"; return false; } - std::memcpy(sealed_secret, sealed_data.data(), sealed_data.size()); - - txn.commit(); conn.close(); return true; } else { @@ -95,151 +209,177 @@ namespace db_manager { error_message = e.what(); return false; } + } - return true; - - } // get_sealed_seed + bool update_sealed_secnonce( + const std::string& statechain_id, + unsigned char* serialized_server_pubnonce, const size_t serialized_server_pubnonce_size, + const chacha20_poly1305_encrypted_data& encrypted_secnonce, + std::string& error_message) + { + auto config = toml::parse_file("Settings.toml"); + auto database_connection_string = config["intel_sgx"]["database_connection_string"].as_string()->get(); - // Assumes the buffer is large enough. In a real application, ensure buffer safety. - void serialize(const chacha20_poly1305_encrypted_data* src, unsigned char* buffer, size_t* serialized_len) { - // Copy `data_len`, `nonce`, and `mac` directly - size_t offset = 0; - memcpy(buffer + offset, &src->data_len, sizeof(src->data_len)); - offset += sizeof(src->data_len); + try + { + pqxx::connection conn(database_connection_string); + if (conn.is_open()) { - memcpy(buffer + offset, src->nonce, sizeof(src->nonce)); - offset += sizeof(src->nonce); + size_t serialized_len = 0; - memcpy(buffer + offset, src->mac, sizeof(src->mac)); - offset += sizeof(src->mac); + size_t bufferSize = sizeof(encrypted_secnonce.data_len) + sizeof(encrypted_secnonce.nonce) + sizeof(encrypted_secnonce.mac) + encrypted_secnonce.data_len; + unsigned char* buffer = (unsigned char*) malloc(bufferSize); - // Now copy dynamic `data` - memcpy(buffer + offset, src->data, src->data_len); - offset += src->data_len; + if (!buffer) { + error_message = "Failed to allocate memory for serialization!"; + return false; + } - *serialized_len = offset; - } + serialize(&encrypted_secnonce, buffer, &serialized_len); + assert(serialized_len == bufferSize); - // Returns a newly allocated structure that must be freed by the caller. - bool deserialize(const unsigned char* buffer, size_t serialized_len, chacha20_poly1305_encrypted_data* dest) { + std::basic_string_view sealed_secnonce_view(reinterpret_cast(buffer), bufferSize); + std::basic_string_view serialized_server_pubnonce_view(reinterpret_cast(serialized_server_pubnonce), serialized_server_pubnonce_size); - // chacha20_poly1305_encrypted_data* dest = new chacha20_poly1305_encrypted_data; - // if (!dest) return NULL; + std::string updated_query = + "UPDATE generated_public_key SET public_nonce = $1, sealed_secnonce = $2 WHERE statechain_id = $3"; + pqxx::work txn(conn); - if (!dest) return false; + txn.exec_params(updated_query, serialized_server_pubnonce_view, sealed_secnonce_view, statechain_id); + txn.commit(); - size_t offset = 0; - memcpy(&dest->data_len, buffer + offset, sizeof(dest->data_len)); - offset += sizeof(dest->data_len); + conn.close(); + return true; + } else { + error_message = "Failed to connect to the database!"; + return false; + } + } + catch (std::exception const &e) + { + error_message = e.what(); + return false; + } + } - memcpy(dest->nonce, buffer + offset, sizeof(dest->nonce)); - offset += sizeof(dest->nonce); + bool update_sig_count(const std::string& statechain_id) + { + auto config = toml::parse_file("Settings.toml"); + auto database_connection_string = config["intel_sgx"]["database_connection_string"].as_string()->get(); - memcpy(dest->mac, buffer + offset, sizeof(dest->mac)); - offset += sizeof(dest->mac); + try + { + pqxx::connection conn(database_connection_string); + if (conn.is_open()) { - dest->data = new unsigned char[dest->data_len]; - if (!dest->data) { - return false; // NULL; - } - memcpy(dest->data, buffer + offset, dest->data_len); - // offset += dest->data_len; // Not needed unless you're reading more data after this + std::string update_query = + "UPDATE generated_public_key SET sig_count = sig_count + 1 WHERE statechain_id = $1;"; + pqxx::work txn(conn); - // return dest; - return true; - } + txn.exec_params(update_query, statechain_id); + txn.commit(); - void print_encrypted_data(const chacha20_poly1305_encrypted_data* data) { - std::cout << "data_len: " << data->data_len << std::endl; - std::cout << "nonce: " << key_to_string(data->nonce, sizeof(data->nonce)) << std::endl; - std::cout << "mac: " << key_to_string(data->mac, sizeof(data->mac)) << std::endl; - std::cout << "data: " << key_to_string(data->data, data->data_len) << std::endl; + conn.close(); + return true; + } else { + return false; + } + } + catch (std::exception const &e) + { + return false; + } } - bool save_generated_public_key( - const chacha20_poly1305_encrypted_data& encrypted_keypair, - unsigned char* server_public_key, size_t server_public_key_size, - std::string& statechain_id, - std::string& error_message) { + bool signature_count(const std::string& statechain_id, int& sig_count) { - auto config = toml::parse_file("Settings.toml"); - auto database_connection_string = config["intel_sgx"]["database_connection_string"].as_string()->get(); - - try - { - pqxx::connection conn(database_connection_string); - if (conn.is_open()) { - - std::string create_table_query = - "CREATE TABLE IF NOT EXISTS generated_public_key ( " - "id SERIAL PRIMARY KEY, " - "statechain_id varchar(50), " - "sealed_keypair BYTEA, " - "sealed_secnonce BYTEA, " - "public_nonce BYTEA, " - "public_key BYTEA UNIQUE, " - "sig_count INTEGER DEFAULT 0);"; - - pqxx::work txn(conn); - txn.exec(create_table_query); - txn.commit(); - - - size_t serialized_len = 0; - - size_t bufferSize = sizeof(encrypted_keypair.data_len) + sizeof(encrypted_keypair.nonce) + sizeof(encrypted_keypair.mac) + encrypted_keypair.data_len; - unsigned char* buffer = (unsigned char*) malloc(bufferSize); - - if (!buffer) { - error_message = "Failed to allocate memory for serialization!"; - return false; - } + auto config = toml::parse_file("Settings.toml"); + auto database_connection_string = config["intel_sgx"]["database_connection_string"].as_string()->get(); - serialize(&encrypted_keypair, buffer, &serialized_len); - assert(serialized_len == bufferSize); + try + { + pqxx::connection conn(database_connection_string); + if (conn.is_open()) { - /* auto buffer_hex = key_to_string(buffer, serialized_len); + std::string sig_count_query = + "SELECT sig_count FROM generated_public_key WHERE statechain_id = $1;"; + + pqxx::nontransaction ntxn(conn); - std::cout << "---- " << std::endl; - print_encrypted_data(&encrypted_keypair); - std::cout << "---- " << std::endl; - std::cout << "buffer: " << buffer_hex << std::endl; + conn.prepare("sig_count_query", sig_count_query); - // chacha20_poly1305_encrypted_data* dest = new chacha20_poly1305_encrypted_keypair; - auto dest = std::make_unique(); - bool res = deserialize(buffer, serialized_len, dest.get()); + pqxx::result result = ntxn.exec_prepared("sig_count_query", statechain_id); - std::cout << "---- " << std::endl; - std::cout << "res: " << res << std::endl; - print_encrypted_data(dest.get()); + if (!result.empty()) { + auto sig_count_field = result[0]["sig_count"]; + if (!sig_count_field.is_null()) { + sig_count = sig_count_field.as(); + return true; + } + } + + conn.close(); + return true; + } else { + return false; + } + } + catch (std::exception const &e) + { + return false; + } + } - free(buffer); */ + bool update_sealed_keypair( + const chacha20_poly1305_encrypted_data& encrypted_keypair, + unsigned char* server_public_key, size_t server_public_key_size, + const std::string& statechain_id, + std::string& error_message) + { + auto config = toml::parse_file("Settings.toml"); + auto database_connection_string = config["intel_sgx"]["database_connection_string"].as_string()->get(); - std::basic_string_view sealed_data_view(reinterpret_cast(buffer), bufferSize); - std::basic_string_view public_key_data_view(reinterpret_cast(server_public_key), server_public_key_size); + try + { + pqxx::connection conn(database_connection_string); + if (conn.is_open()) { - std::string insert_query = - "INSERT INTO generated_public_key (sealed_keypair, public_key, statechain_id) VALUES ($1, $2, $3);"; - pqxx::work txn2(conn); + std::string insert_query = + "UPDATE generated_public_key " + "SET sealed_keypair = $1, public_key = $2, sealed_secnonce = NULL, public_nonce = NULL " + "WHERE statechain_id = $3;"; + pqxx::work txn2(conn); - txn2.exec_params(insert_query, sealed_data_view, public_key_data_view, statechain_id); - txn2.commit(); + size_t serialized_len = 0; - conn.close(); - return true; + size_t bufferSize = sizeof(encrypted_keypair.data_len) + sizeof(encrypted_keypair.nonce) + sizeof(encrypted_keypair.mac) + encrypted_keypair.data_len; + unsigned char* buffer = (unsigned char*) malloc(bufferSize); - return true; - } else { - error_message = "Failed to connect to the database!"; + if (!buffer) { + error_message = "Failed to allocate memory for serialization!"; return false; } - } - catch (std::exception const &e) - { - error_message = e.what(); + + serialize(&encrypted_keypair, buffer, &serialized_len); + assert(serialized_len == bufferSize); + + std::basic_string_view sealed_data_view(reinterpret_cast(buffer), bufferSize); + std::basic_string_view public_key_data_view(reinterpret_cast(server_public_key), server_public_key_size); + + txn2.exec_params(insert_query, sealed_data_view, public_key_data_view, statechain_id); + txn2.commit(); + + conn.close(); + return true; + } else { + error_message = "Failed to connect to the database!"; return false; } - - return true; } + catch (std::exception const &e) + { + error_message = e.what(); + return false; + } + } } \ No newline at end of file diff --git a/enclave/App/database/db_manager.h b/enclave/App/database/db_manager.h index 6d1ba7ea..8f7ed7b1 100644 --- a/enclave/App/database/db_manager.h +++ b/enclave/App/database/db_manager.h @@ -4,18 +4,38 @@ #define DB_MANAGER_H #include "../Enclave_u.h" +#include #include namespace db_manager { - // Remove these 2 functions. Sealed seeds should be stored in the file system. - bool add_sealed_seed(char* sealed_secret, size_t sealed_secret_size, std::string& error_message); - bool get_sealed_seed(char* sealed_secret, size_t sealed_secret_size, std::string& error_message); - bool save_generated_public_key( - const chacha20_poly1305_encrypted_data& encrypted_data, + const chacha20_poly1305_encrypted_data& encrypted_keypair, + unsigned char* server_public_key, size_t server_public_key_size, + const std::string& statechain_id, + std::string& error_message); + + bool load_generated_key_data( + const std::string& statechain_id, + std::unique_ptr& encrypted_keypair, + std::unique_ptr& encrypted_secnonce, + unsigned char* public_nonce, const size_t public_nonce_size, + std::string& error_message); + + bool update_sealed_secnonce( + const std::string& statechain_id, + unsigned char* serialized_server_pubnonce, const size_t serialized_server_pubnonce_size, + const chacha20_poly1305_encrypted_data& encrypted_secnonce, + std::string& error_message); + + bool update_sig_count(const std::string& statechain_id); + + bool signature_count(const std::string& statechain_id, int& sig_count); + + bool update_sealed_keypair( + const chacha20_poly1305_encrypted_data& encrypted_keypair, unsigned char* server_public_key, size_t server_public_key_size, - std::string& statechain_id, + const std::string& statechain_id, std::string& error_message); } diff --git a/enclave/App/sealing_key_manager/sealing_key_manager.h b/enclave/App/sealing_key_manager/sealing_key_manager.h index 09711792..5ae2ad40 100644 --- a/enclave/App/sealing_key_manager/sealing_key_manager.h +++ b/enclave/App/sealing_key_manager/sealing_key_manager.h @@ -45,10 +45,6 @@ namespace sealing_key_manager { // bool testSealedSeed(sgx_enclave_id_t& enclave_id); void listKeyShares(); }; - - - - } #endif // SEALING_KEY_MANAGER_H \ No newline at end of file diff --git a/enclave/App/statechain/deposit.cpp b/enclave/App/statechain/deposit.cpp new file mode 100644 index 00000000..c9cfdfa6 --- /dev/null +++ b/enclave/App/statechain/deposit.cpp @@ -0,0 +1,49 @@ +#include "deposit.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wfloat-equal" +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wconversion" +#include +#pragma GCC diagnostic pop + +#include "../../utils/strencodings.h" +#include "../../utils/include_secp256k1_zkp_lib.h" +#include "../database/db_manager.h" +#include "../statechain/deposit.h" +#include "../sealing_key_manager/sealing_key_manager.h" + +#include "../Enclave_u.h" + +namespace deposit { + crow::response get_public_key(sgx_enclave_id_t& enclave_id, const std::string& statechain_id, sealing_key_manager::SealingKeyManager& sealing_key_manager) { + // 1. Allocate memory for the aggregated pubkey and sealedprivkey. + size_t server_pubkey_size = 33; // serialized compressed public keys are 33-byte array + unsigned char server_pubkey[server_pubkey_size]; + + // new encryption scheme + chacha20_poly1305_encrypted_data encrypted_data; + utils::initialize_encrypted_data(encrypted_data, sizeof(secp256k1_keypair)); + + sgx_status_t ecall_ret; + enclave_generate_new_keypair(enclave_id, &ecall_ret, + server_pubkey, server_pubkey_size, + sealing_key_manager.sealed_seed, sealing_key_manager.sealed_seed_size, + &encrypted_data); + + std::string error_message; + bool data_saved = db_manager::save_generated_public_key(encrypted_data, server_pubkey, server_pubkey_size, statechain_id, error_message); + + auto server_seckey_hex = key_to_string(server_pubkey, server_pubkey_size); + + if (!data_saved) { + error_message = "Failed to save aggregated key data: " + error_message; + return crow::response(500, error_message); + } + + crow::json::wvalue result({{"server_pubkey", server_seckey_hex}}); + return crow::response{result}; + } +} \ No newline at end of file diff --git a/enclave/App/statechain/deposit.h b/enclave/App/statechain/deposit.h new file mode 100644 index 00000000..e044fae7 --- /dev/null +++ b/enclave/App/statechain/deposit.h @@ -0,0 +1,22 @@ +#pragma once + +#ifndef STATECHAIN_DEPOSIT_H +#define STATECHAIN_DEPOSIT_H + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wfloat-equal" +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wconversion" +#include +#pragma GCC diagnostic pop + +#include "../Enclave_u.h" +#include "../sealing_key_manager/sealing_key_manager.h" + +namespace deposit { + crow::response get_public_key(sgx_enclave_id_t& enclave_id, const std::string& statechain_id, sealing_key_manager::SealingKeyManager& sealing_key_manager); +} + +#endif // STATECHAIN_DEPOSIT_H \ No newline at end of file diff --git a/enclave/App/statechain/sign.cpp b/enclave/App/statechain/sign.cpp new file mode 100644 index 00000000..b07fec88 --- /dev/null +++ b/enclave/App/statechain/sign.cpp @@ -0,0 +1,164 @@ +#include "sign.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wfloat-equal" +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wconversion" +#include +#pragma GCC diagnostic pop + +#include "../../utils/strencodings.h" +#include "../../utils/include_secp256k1_zkp_lib.h" +#include "../database/db_manager.h" +#include "../Enclave_u.h" +#include "../sealing_key_manager/sealing_key_manager.h" + +namespace signature { + crow::response get_public_nonce(sgx_enclave_id_t& enclave_id, const std::string& statechain_id, sealing_key_manager::SealingKeyManager& sealing_key_manager) { + + auto encrypted_keypair = std::make_unique(); + + // the secret nonce is not defined yet + auto encrypted_secnonce = std::make_unique(); + encrypted_secnonce.reset(); + + std::string error_message; + bool data_loaded = db_manager::load_generated_key_data( + statechain_id, + encrypted_keypair, + encrypted_secnonce, + nullptr, + 0, + error_message + ); + + assert(encrypted_secnonce == nullptr); + + if (!data_loaded) { + error_message = "Failed to load aggregated key data: " + error_message; + return crow::response(500, error_message); + } + + unsigned char serialized_server_pubnonce[66]; + memset(serialized_server_pubnonce, 0, sizeof(serialized_server_pubnonce)); + + encrypted_secnonce = std::make_unique(); + utils::initialize_encrypted_data(*encrypted_secnonce, sizeof(secp256k1_musig_secnonce)); + + sgx_status_t ecall_ret; + sgx_status_t status = enclave_generate_nonce( + enclave_id, &ecall_ret, + sealing_key_manager.sealed_seed, sealing_key_manager.sealed_seed_size, + encrypted_keypair.get(), + encrypted_secnonce.get(), + serialized_server_pubnonce, sizeof(serialized_server_pubnonce)); + + if (ecall_ret != SGX_SUCCESS) { + return crow::response(500, "Generate Nonce Ecall failed "); + } if (status != SGX_SUCCESS) { + return crow::response(500, "Generate Nonce failed "); + } + + bool data_saved = db_manager::update_sealed_secnonce( + statechain_id, + serialized_server_pubnonce, sizeof(serialized_server_pubnonce), + *encrypted_secnonce, + error_message + ); + + if (!data_saved) { + error_message = "Failed to save sealed secret nonce: " + error_message; + return crow::response(500, error_message); + } + + auto serialized_server_pubnonce_hex = key_to_string(serialized_server_pubnonce, sizeof(serialized_server_pubnonce)); + + crow::json::wvalue result({{"server_pubnonce", serialized_server_pubnonce_hex}}); + return crow::response{result}; + } + + crow::response get_partial_signature( + sgx_enclave_id_t& enclave_id, + const std::string& statechain_id, + const int64_t negate_seckey, + std::vector& serialized_session, + const sealing_key_manager::SealingKeyManager& sealing_key_manager) + { + + auto encrypted_keypair = std::make_unique(); + auto encrypted_secnonce = std::make_unique(); + + unsigned char serialized_server_pubnonce[66]; + memset(serialized_server_pubnonce, 0, sizeof(serialized_server_pubnonce)); + + std::string error_message; + bool data_loaded = db_manager::load_generated_key_data( + statechain_id, + encrypted_keypair, + encrypted_secnonce, + serialized_server_pubnonce, + sizeof(serialized_server_pubnonce), + error_message + ); + + if (!data_loaded) { + error_message = "Failed to load aggregated key data: " + error_message; + return crow::response(500, error_message); + } + + bool is_sealed_keypair_empty = encrypted_keypair == nullptr; + bool is_sealed_secnonce_empty = encrypted_secnonce == nullptr; + + if (is_sealed_keypair_empty || is_sealed_secnonce_empty) { + return crow::response(400, "Empty sealed keypair or sealed secnonce!"); + } + + unsigned char serialized_partial_sig[32]; + + sgx_status_t ecall_ret; + sgx_status_t status = enclave_partial_signature( + enclave_id, &ecall_ret, + sealing_key_manager.sealed_seed, sealing_key_manager.sealed_seed_size, + encrypted_keypair.get(), + encrypted_secnonce.get(), + (int) negate_seckey, + serialized_session.data(), serialized_session.size(), + serialized_server_pubnonce, sizeof(serialized_server_pubnonce), + serialized_partial_sig, sizeof(serialized_partial_sig)); + + if (ecall_ret != SGX_SUCCESS) { + return crow::response(500, "Enclave Generate Signature Ecall failed "); + } if (status != SGX_SUCCESS) { + return crow::response(500, "Enclave Generate Signature failed "); + } + + bool sig_count_updated = db_manager::update_sig_count(statechain_id); + if (!sig_count_updated) { + return crow::response(500, "Failed to update signature count!"); + } + + auto partial_sig_hex = key_to_string(serialized_partial_sig, sizeof(serialized_partial_sig)); + + crow::json::wvalue result({{"partial_sig", partial_sig_hex}}); + return crow::response{result}; + + } + + crow::response signature_count(const std::string& statechain_id) { + + int sig_count; + std::string error_message; + bool count_retrieved = db_manager::signature_count(statechain_id, sig_count); + + if (!count_retrieved) { + error_message = "Failed to retrieve signature count: " + error_message; + return crow::response(500, error_message); + } + + crow::json::wvalue result({{"sig_count", sig_count}}); + return crow::response{result}; + + } +} \ No newline at end of file diff --git a/enclave/App/statechain/sign.h b/enclave/App/statechain/sign.h new file mode 100644 index 00000000..fb397fea --- /dev/null +++ b/enclave/App/statechain/sign.h @@ -0,0 +1,31 @@ +#pragma once + +#ifndef STATECHAIN_SIGN_H +#define STATECHAIN_SIGN_H + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wfloat-equal" +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wconversion" +#include +#pragma GCC diagnostic pop + +#include "../Enclave_u.h" +#include "../sealing_key_manager/sealing_key_manager.h" + +namespace signature { + crow::response get_public_nonce(sgx_enclave_id_t& enclave_id, const std::string& statechain_id, sealing_key_manager::SealingKeyManager& sealing_key_manager); + + crow::response get_partial_signature( + sgx_enclave_id_t& enclave_id, + const std::string& statechain_id, + const int64_t negate_seckey, + std::vector& serialized_session, + const sealing_key_manager::SealingKeyManager& sealing_key_manager); + + crow::response signature_count(const std::string& statechain_id); +} + +#endif // STATECHAIN_SIGN_H \ No newline at end of file diff --git a/enclave/App/statechain/transfer_receiver.cpp b/enclave/App/statechain/transfer_receiver.cpp new file mode 100644 index 00000000..84289a2f --- /dev/null +++ b/enclave/App/statechain/transfer_receiver.cpp @@ -0,0 +1,93 @@ +#include "transfer_receiver.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wfloat-equal" +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wconversion" +#include +#pragma GCC diagnostic pop + +#include "../../utils/strencodings.h" +#include "../../utils/include_secp256k1_zkp_lib.h" +#include "../database/db_manager.h" +#include "../Enclave_u.h" +#include "../sealing_key_manager/sealing_key_manager.h" + +namespace transfer_receiver { + crow::response keyupdate( + sgx_enclave_id_t& enclave_id, + const std::string& statechain_id, + std::vector& serialized_t2, + std::vector& serialized_x1, + const sealing_key_manager::SealingKeyManager& sealing_key_manager) + { + auto old_encrypted_keypair = std::make_unique(); + + // the secret nonce is not used here + auto encrypted_secnonce = std::make_unique(); + encrypted_secnonce.reset(); + + unsigned char serialized_server_pubnonce[66]; + memset(serialized_server_pubnonce, 0, sizeof(serialized_server_pubnonce)); + + std::string error_message; + bool data_loaded = db_manager::load_generated_key_data( + statechain_id, + old_encrypted_keypair, + encrypted_secnonce, + nullptr, + 0, + error_message + ); + + if (!data_loaded) { + error_message = "Failed to load aggregated key data: " + error_message; + return crow::response(500, error_message); + } + + if (old_encrypted_keypair == nullptr) { + return crow::response(400, "Empty encrypted keypair!"); + } + + // 1. Allocate memory for the aggregated pubkey and sealedprivkey. + size_t new_server_pubkey_size = 33; // serialized compressed public keys are 33-byte array + unsigned char new_server_pubkey[new_server_pubkey_size]; + + auto new_encrypted_keypair = std::make_unique(); + utils::initialize_encrypted_data(*new_encrypted_keypair, sizeof(secp256k1_keypair)); + + sgx_status_t ecall_ret; + sgx_status_t status = enclave_key_update( + enclave_id, &ecall_ret, + sealing_key_manager.sealed_seed, sealing_key_manager.sealed_seed_size, + old_encrypted_keypair.get(), + serialized_x1.data(), serialized_x1.size(), + serialized_t2.data(), serialized_t2.size(), + new_server_pubkey, new_server_pubkey_size, + new_encrypted_keypair.get()); + + if (ecall_ret != SGX_SUCCESS) { + return crow::response(500, "Enclave key update Ecall failed "); + } if (status != SGX_SUCCESS) { + return crow::response(500, "Enclave key update failed "); + } + + bool data_saved = db_manager::update_sealed_keypair( + *new_encrypted_keypair, + new_server_pubkey, new_server_pubkey_size, + statechain_id, + error_message); + + if (!data_saved) { + error_message = "Failed to update aggregated key data: " + error_message; + return crow::response(500, error_message); + } + + auto new_server_seckey_hex = key_to_string(new_server_pubkey, new_server_pubkey_size); + + crow::json::wvalue result({{"server_pubkey", new_server_seckey_hex}}); + return crow::response{result}; + } +} \ No newline at end of file diff --git a/enclave/App/statechain/transfer_receiver.h b/enclave/App/statechain/transfer_receiver.h new file mode 100644 index 00000000..d64dead5 --- /dev/null +++ b/enclave/App/statechain/transfer_receiver.h @@ -0,0 +1,28 @@ +#pragma once + +#ifndef STATECHAIN_TRANSFER_RECEIVER_H +#define STATECHAIN_TRANSFER_RECEIVER_H + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wfloat-equal" +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wconversion" +#include +#pragma GCC diagnostic pop + +#include "../Enclave_u.h" +#include "../sealing_key_manager/sealing_key_manager.h" + +namespace transfer_receiver { + crow::response keyupdate( + sgx_enclave_id_t& enclave_id, + const std::string& statechain_id, + std::vector& serialized_t2, + std::vector& serialized_x1, + const sealing_key_manager::SealingKeyManager& sealing_key_manager + ); +} + +#endif // STATECHAIN_TRANSFER_RECEIVER_H \ No newline at end of file diff --git a/enclave/App/utilities/utilities.cpp b/enclave/App/utilities/utilities.cpp index e639684a..40db6494 100644 --- a/enclave/App/utilities/utilities.cpp +++ b/enclave/App/utilities/utilities.cpp @@ -1,6 +1,7 @@ #include "utilities.h" #include "sgx_tseal.h" +#include "../Enclave_u.h" namespace utils { @@ -15,5 +16,16 @@ namespace utils { return UINT32_MAX; return (uint32_t)(sizeof(sgx_sealed_data_t) + payload_size); } + + void initialize_encrypted_data(chacha20_poly1305_encrypted_data& encrypted_data, size_t data_len) { + + // initialize encrypted_data + encrypted_data.data_len = data_len; + encrypted_data.data = new unsigned char[encrypted_data.data_len]; + memset(encrypted_data.data, 0, encrypted_data.data_len); + + memset(encrypted_data.mac, 0, sizeof(encrypted_data.mac)); + memset(encrypted_data.nonce, 0, sizeof(encrypted_data.nonce)); + } } // namespace utils \ No newline at end of file diff --git a/enclave/App/utilities/utilities.h b/enclave/App/utilities/utilities.h index 4c7e39cd..917e0243 100644 --- a/enclave/App/utilities/utilities.h +++ b/enclave/App/utilities/utilities.h @@ -4,6 +4,7 @@ #define UTILITIES_H #include +#include "../Enclave_u.h" namespace utils { @@ -15,6 +16,8 @@ namespace utils { uint32_t sgx_calc_sealed_data_size(const uint32_t add_mac_txt_size, const uint32_t txt_encrypt_size); + void initialize_encrypted_data(chacha20_poly1305_encrypted_data& encrypted_data, size_t data_len); + } #endif // UTILS_H \ No newline at end of file diff --git a/enclave/Enclave/Enclave.cpp b/enclave/Enclave/Enclave.cpp index 048097fe..8db77b60 100644 --- a/enclave/Enclave/Enclave.cpp +++ b/enclave/Enclave/Enclave.cpp @@ -65,7 +65,25 @@ void encrypt_data( } -sgx_status_t generate_new_keypair2( +int decrypt_data( + chacha20_poly1305_encrypted_data *encrypted_data, + char* sealed_seed, size_t sealed_seed_len, + uint8_t* decrypted_data, size_t decrypted_data_size) +{ + unsigned char seed[32]; + memset(seed, 0, 32); + + unseal(sealed_seed, sealed_seed_len, seed, sizeof(seed)); + + // Associated data (optional, can be NULL if not used) + uint8_t *ad = NULL; + size_t ad_size = 0; + + int status = crypto_aead_unlock(decrypted_data, encrypted_data->mac, seed, encrypted_data->nonce, ad, ad_size, encrypted_data->data, encrypted_data->data_len); + return status; +} + +sgx_status_t enclave_generate_new_keypair( unsigned char *compressed_server_pubkey, size_t compressed_server_pubkey_size, char* sealed_seed, size_t sealed_seed_len, @@ -112,81 +130,59 @@ sgx_status_t generate_new_keypair2( return ret; } -sgx_status_t generate_new_keypair( - unsigned char *compressed_server_pubkey, - size_t compressed_server_pubkey_size, - - char *sealedkeypair, - size_t sealedkeypair_size) +sgx_status_t enclave_generate_nonce( + char* sealed_seed, size_t sealed_seed_len, + chacha20_poly1305_encrypted_data *encrypted_keypair, + chacha20_poly1305_encrypted_data *encrypted_secnonce, + unsigned char* server_pubnonce_data, size_t server_pubnonce_data_size) { - (void) compressed_server_pubkey_size; + (void) server_pubnonce_data_size; - // Step 1: Open Context. - sgx_status_t ret = SGX_ERROR_UNEXPECTED; - sgx_ecc_state_handle_t p_ecc_handle = NULL; + secp256k1_keypair server_keypair; + memset(server_keypair.data, 0, sizeof(server_keypair.data)); - if ((ret = sgx_ecc256_open_context(&p_ecc_handle)) != SGX_SUCCESS) - { - ocall_print_string("\nTrustedApp: sgx_ecc256_open_context() failed !\n"); - if (p_ecc_handle != NULL) - { - sgx_ecc256_close_context(p_ecc_handle); - } - return ret; + int status = decrypt_data(encrypted_keypair, sealed_seed, sealed_seed_len, server_keypair.data, sizeof(server_keypair.data)); + if (status != 0) { + ocall_print_string("\nDecryption failed\n"); + return SGX_ERROR_UNEXPECTED; } - secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - unsigned char server_privkey[32]; - memset(server_privkey, 0, 32); - - do { - sgx_read_rand(server_privkey, 32); - } while (!secp256k1_ec_seckey_verify(ctx, server_privkey)); + secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - secp256k1_keypair server_keypair; + // step 1 - Extract server secret and public keys from keypair - int return_val = secp256k1_keypair_create(ctx, &server_keypair, server_privkey); + unsigned char server_seckey[32]; + int return_val = secp256k1_keypair_sec(ctx, server_seckey, &server_keypair); assert(return_val); secp256k1_pubkey server_pubkey; return_val = secp256k1_keypair_pub(ctx, &server_pubkey, &server_keypair); assert(return_val); - unsigned char local_compressed_server_pubkey[33]; - memset(local_compressed_server_pubkey, 0, 33); + // step 2 - Generate secret and public nonce - size_t len = sizeof(local_compressed_server_pubkey); - return_val = secp256k1_ec_pubkey_serialize(ctx, local_compressed_server_pubkey, &len, &server_pubkey, SECP256K1_EC_COMPRESSED); + unsigned char session_id[32]; + memset(session_id, 0, 32); + sgx_read_rand(session_id, sizeof(session_id)); + + secp256k1_musig_pubnonce server_pubnonce; + secp256k1_musig_secnonce server_secnonce; + + return_val = secp256k1_musig_nonce_gen(ctx, &server_secnonce, &server_pubnonce, session_id, server_seckey, &server_pubkey, NULL, NULL, NULL); assert(return_val); - // Should be the same size as the size of the output, because we passed a 33 byte array. - assert(len == sizeof(local_compressed_server_pubkey)); - memcpy(compressed_server_pubkey, local_compressed_server_pubkey, 33); + // step 3 - Encrypt secret nonce + encrypt_data(encrypted_secnonce, sealed_seed, sealed_seed_len, server_secnonce.data, sizeof(secp256k1_musig_secnonce::data)); - secp256k1_context_destroy(ctx); + unsigned char serialized_server_pubnonce[66]; + return_val = secp256k1_musig_pubnonce_serialize(ctx, serialized_server_pubnonce, &server_pubnonce); + assert(return_val); - // Step 3: Calculate sealed data size. - if (sealedkeypair_size >= sgx_calc_sealed_data_size(0U, sizeof(server_keypair))) - { - if ((ret = sgx_seal_data(0U, NULL, sizeof(server_keypair.data), server_keypair.data, (uint32_t) sealedkeypair_size, (sgx_sealed_data_t *)sealedkeypair)) != SGX_SUCCESS) - { - ocall_print_string("\nTrustedApp: sgx_seal_data() failed !\n"); - } - } - else - { - ocall_print_string("\nTrustedApp: Size allocated for sealedprivkey by untrusted app is less than the required size !\n"); - ret = SGX_ERROR_INVALID_PARAMETER; - } + memcpy(server_pubnonce_data, serialized_server_pubnonce, sizeof(serialized_server_pubnonce)); - // Step 4: Close Context. - if (p_ecc_handle != NULL) - { - sgx_ecc256_close_context(p_ecc_handle); - } + secp256k1_context_destroy(ctx); - return ret; + return SGX_SUCCESS; } sgx_status_t unseal(char* sealed, size_t sealed_size, unsigned char *raw_data, size_t raw_data_size) @@ -226,75 +222,10 @@ sgx_status_t unseal(char* sealed, size_t sealed_size, unsigned char *raw_data, s return ret; } -sgx_status_t generate_nonce( - char* sealed_keypair, size_t sealed_keypair_size, - char* sealed_secnonce, size_t sealed_secnonce_size, - unsigned char* server_pubnonce_data, size_t server_pubnonce_data_size) -{ - // TODO: replace with assert - (void) sealed_keypair_size; - (void) sealed_secnonce_size; - (void) server_pubnonce_data_size; - - secp256k1_keypair server_keypair; - unseal(sealed_keypair, sealed_keypair_size, server_keypair.data, sizeof(server_keypair.data)); - - secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - - // step 1 - Extract server secret and public keys from keypair - - unsigned char server_seckey[32]; - int return_val = secp256k1_keypair_sec(ctx, server_seckey, &server_keypair); - assert(return_val); - - secp256k1_pubkey server_pubkey; - return_val = secp256k1_keypair_pub(ctx, &server_pubkey, &server_keypair); - assert(return_val); - - // step 2 - Generate secret and public nonce - - unsigned char session_id[32]; - memset(session_id, 0, 32); - sgx_read_rand(session_id, sizeof(session_id)); - - secp256k1_musig_pubnonce server_pubnonce; - secp256k1_musig_secnonce server_secnonce; - - return_val = secp256k1_musig_nonce_gen(ctx, &server_secnonce, &server_pubnonce, session_id, server_seckey, &server_pubkey, NULL, NULL, NULL); - assert(return_val); - - // step 3 - Seal secret nonce - - sgx_status_t ret = SGX_ERROR_UNEXPECTED; - - if (sealed_secnonce_size >= sgx_calc_sealed_data_size(0U, sizeof(server_secnonce.data))) - { - if ((ret = sgx_seal_data(0U, NULL, sizeof(server_secnonce.data), server_secnonce.data, (uint32_t) sealed_secnonce_size, (sgx_sealed_data_t *)sealed_secnonce)) != SGX_SUCCESS) - { - ocall_print_string("\nTrustedApp: sgx_seal_data() failed !\n"); - } - } - else - { - ocall_print_string("\nTrustedApp: Size allocated for sealedprivkey by untrusted app is less than the required size !\n"); - ret = SGX_ERROR_INVALID_PARAMETER; - } - - unsigned char serialized_server_pubnonce[66]; - return_val = secp256k1_musig_pubnonce_serialize(ctx, serialized_server_pubnonce, &server_pubnonce); - assert(return_val); - - memcpy(server_pubnonce_data, serialized_server_pubnonce, sizeof(serialized_server_pubnonce)); - - secp256k1_context_destroy(ctx); - - return ret; - -} - -sgx_status_t get_partial_signature( - char* sealed_keypair, size_t sealed_keypair_size, - char* sealed_secnonce, size_t sealed_secnonce_size, +sgx_status_t enclave_partial_signature( + char* sealed_seed, size_t sealed_seed_len, + chacha20_poly1305_encrypted_data *encrypted_keypair, + chacha20_poly1305_encrypted_data *encrypted_secnonce, int negate_seckey, unsigned char* session_data, size_t session_data_size, unsigned char* serialized_server_pubnonce, size_t serialized_server_pubnonce_size, @@ -303,10 +234,16 @@ sgx_status_t get_partial_signature( (void) partial_sig_data; (void) partial_sig_data_size; (void) serialized_server_pubnonce_size; - // step 0 - Unseal sealed keypair + + // step 0 - Decrypt encrypted_keypair secp256k1_keypair server_keypair; - unseal(sealed_keypair, sealed_keypair_size, server_keypair.data, sizeof(server_keypair.data)); + + int status = decrypt_data(encrypted_keypair, sealed_seed, sealed_seed_len, server_keypair.data, sizeof(server_keypair.data)); + if (status != 0) { + ocall_print_string("\nDecryption failed\n"); + return SGX_ERROR_UNEXPECTED; + } secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); @@ -320,10 +257,15 @@ sgx_status_t get_partial_signature( return_val = secp256k1_keypair_pub(ctx, &server_pubkey, &server_keypair); assert(return_val); - // step 2 - Unseal sealed sealed_secnonce + // step 2 - Decrypt encrypted_secnonce secp256k1_musig_secnonce server_secnonce; - unseal(sealed_secnonce, sealed_secnonce_size, server_secnonce.data, sizeof(server_secnonce.data)); + + status = decrypt_data(encrypted_secnonce, sealed_seed, sealed_seed_len, server_secnonce.data, sizeof(server_secnonce.data)); + if (status != 0) { + ocall_print_string("\nDecryption failed\n"); + return SGX_ERROR_UNEXPECTED; + } secp256k1_musig_session session; memcpy(session.data, session_data, session_data_size); @@ -350,17 +292,15 @@ sgx_status_t get_partial_signature( return SGX_SUCCESS; } -sgx_status_t key_update( - char* sealed_keypair, size_t sealed_keypair_size, +sgx_status_t enclave_key_update( + char* sealed_seed, size_t sealed_seed_len, + chacha20_poly1305_encrypted_data *old_encrypted_keypair, unsigned char* serialized_x1, size_t serialized_x1_size, unsigned char* serialized_t2, size_t serialized_t2_size, unsigned char *compressed_server_pubkey, size_t compressed_server_pubkey_size, - char* sealedkeypair, size_t sealedkeypair_size) + chacha20_poly1305_encrypted_data *new_encrypted_keypair) { - (void) sealed_keypair_size; - (void) compressed_server_pubkey_size; - (void) sealedkeypair_size; assert(serialized_x1_size == 32); assert(serialized_t2_size == 32); @@ -368,7 +308,11 @@ sgx_status_t key_update( // step 0 - Unseal sealed keypair secp256k1_keypair server_keypair; - unseal(sealed_keypair, sealed_keypair_size, server_keypair.data, sizeof(server_keypair.data)); + int status = decrypt_data(old_encrypted_keypair, sealed_seed, sealed_seed_len, server_keypair.data, sizeof(server_keypair.data)); + if (status != 0) { + ocall_print_string("\nDecryption failed\n"); + return SGX_ERROR_UNEXPECTED; + } secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); @@ -426,56 +370,14 @@ sgx_status_t key_update( memcpy(compressed_server_pubkey, local_compressed_server_pubkey, 33); - // Step 1: Open Context. - sgx_status_t ret = SGX_ERROR_UNEXPECTED; - sgx_ecc_state_handle_t p_ecc_handle = NULL; - secp256k1_context_destroy(ctx); - if ((ret = sgx_ecc256_open_context(&p_ecc_handle)) != SGX_SUCCESS) - { - ocall_print_string("\nTrustedApp: sgx_ecc256_open_context() failed !\n"); - if (p_ecc_handle != NULL) - { - sgx_ecc256_close_context(p_ecc_handle); - } - return ret; - } - - // Step 3: Calculate sealed data size. - if (sealedkeypair_size >= sgx_calc_sealed_data_size(0U, sizeof(new_server_keypair))) - { - if ((ret = sgx_seal_data(0U, NULL, sizeof(new_server_keypair.data), new_server_keypair.data, (uint32_t) sealedkeypair_size, (sgx_sealed_data_t *)sealedkeypair)) != SGX_SUCCESS) - { - ocall_print_string("\nTrustedApp: sgx_seal_data() failed !\n"); - } - } - else - { - ocall_print_string("\nTrustedApp: Size allocated for sealedprivkey by untrusted app is less than the required size !\n"); - ret = SGX_ERROR_INVALID_PARAMETER; - } - - // ocall_print_string("--- new sealedkeypair:"); - // ocall_print_hex((const unsigned char**) &sealedkeypair, (int *) &sealedkeypair_size); + // step 3 - Encrypt secret nonce + encrypt_data(new_encrypted_keypair, sealed_seed, sealed_seed_len, new_server_keypair.data, sizeof(secp256k1_keypair::data)); - // Step 4: Close Context. - if (p_ecc_handle != NULL) - { - sgx_ecc256_close_context(p_ecc_handle); - } - - return ret; + return SGX_SUCCESS; } -/* -sgx_status_t status = recover_seed( - - all_key_shares, total_size, - key_share_indexes, num_key_shares, - key_share_data_size, threshold, - sealed_seed, sealed_seed_size);*/ - sgx_status_t recover_seed( char* all_key_shares, size_t total_size, unsigned char* indexes, size_t num_key_shares, @@ -499,25 +401,10 @@ sgx_status_t recover_seed( uint8_t secret_data[unsealed_data_size]; - for (size_t i = 0; i < threshold; ++i) { - ocall_print_int("share ", (const int *) &i); - ocall_print_hex((const unsigned char**) &shares[i], (int *) &key_share_data_size); - } - - for (size_t i = 0; i < threshold; ++i) { - ocall_print_int("index ", (const int *) &i); - ocall_print_int("value ", (const int *) &indexes[i]); - } - int32_t secret_data_len = recover_secret((uint8_t) threshold, (const uint8_t*) indexes, (const uint8_t **)shares, unsealed_data_size, secret_data); - ocall_print_int("secret_data_len ", (const int *) &secret_data_len); assert(secret_data_len == (int32_t) unsealed_data_size); - char* seed = data_to_hex(secret_data, unsealed_data_size); - ocall_print_string("Seed:"); - ocall_print_string(seed); - if (sealed_seed_size >= sgx_calc_sealed_data_size(0U, unsealed_data_size)) { if ((ret = sgx_seal_data(0U, NULL, unsealed_data_size, secret_data, (uint32_t) sealed_seed_size, (sgx_sealed_data_t *)sealed_seed)) != SGX_SUCCESS) diff --git a/enclave/Enclave/Enclave.edl b/enclave/Enclave/Enclave.edl index f0794272..0840bbdf 100644 --- a/enclave/Enclave/Enclave.edl +++ b/enclave/Enclave/Enclave.edl @@ -17,42 +17,39 @@ enclave { trusted { - public sgx_status_t generate_new_keypair2( + public sgx_status_t enclave_generate_new_keypair( [out, size=compressed_server_pubkey_size] unsigned char *compressed_server_pubkey, size_t compressed_server_pubkey_size, [in, size=sealed_seed_len] char* sealed_seed, size_t sealed_seed_len, [in, out] struct chacha20_poly1305_encrypted_data* encrypted_data); - public sgx_status_t generate_new_keypair( - [out, size=compressed_server_pubkey_size] unsigned char *compressed_server_pubkey, - size_t compressed_server_pubkey_size, - [out, size=sealedkeypair_size] char* sealedkeypair, - size_t sealedkeypair_size); + public sgx_status_t enclave_generate_nonce( + [in, size=sealed_seed_len] char* sealed_seed, size_t sealed_seed_len, + [in] struct chacha20_poly1305_encrypted_data *encrypted_keypair, + [in, out] struct chacha20_poly1305_encrypted_data *encrypted_secnonce, + [out, size=server_pubnonce_data_size] unsigned char* server_pubnonce_data, size_t server_pubnonce_data_size); - public sgx_status_t unseal( + sgx_status_t unseal( [in, size=sealed_size] char* sealed, size_t sealed_size, [out, size=raw_data_size] unsigned char *raw_data, size_t raw_data_size); - public sgx_status_t generate_nonce( - [in, size=sealed_keypair_size] char* sealed_keypair, size_t sealed_keypair_size, - [out, size=sealed_secnonce_size] char* sealed_secnonce, size_t sealed_secnonce_size, - [out, size=server_pubnonce_data_size] unsigned char* server_pubnonce_data, size_t server_pubnonce_data_size); - - public sgx_status_t get_partial_signature( - [in, size=sealed_keypair_size] char* sealed_keypair, size_t sealed_keypair_size, - [in, size=sealed_secnonce_size] char* sealed_secnonce, size_t sealed_secnonce_size, + public sgx_status_t enclave_partial_signature( + [in, size=sealed_seed_len] char* sealed_seed, size_t sealed_seed_len, + [in] struct chacha20_poly1305_encrypted_data *encrypted_keypair, + [in] struct chacha20_poly1305_encrypted_data *encrypted_secnonce, int negate_seckey, [in, size=session_data_size] unsigned char* session_data, size_t session_data_size, [in, size=serialized_server_pubnonce_size] unsigned char* serialized_server_pubnonce, size_t serialized_server_pubnonce_size, [out, size=partial_sig_data_size] unsigned char *partial_sig_data, size_t partial_sig_data_size ); - public sgx_status_t key_update( - [in, size=sealed_keypair_size] char* sealed_keypair, size_t sealed_keypair_size, + public sgx_status_t enclave_key_update( + [in, size=sealed_seed_len] char* sealed_seed, size_t sealed_seed_len, + [in] struct chacha20_poly1305_encrypted_data *old_encrypted_keypair, [in, size=serialized_x1_size] unsigned char* serialized_x1, size_t serialized_x1_size, [in, size=serialized_t2_size] unsigned char* serialized_t2, size_t serialized_t2_size, [out, size=compressed_server_pubkey_size] unsigned char *compressed_server_pubkey, size_t compressed_server_pubkey_size, - [out, size=sealedkeypair_size] char* sealedkeypair, size_t sealedkeypair_size + [in, out] struct chacha20_poly1305_encrypted_data* new_encrypted_keypair ); public sgx_status_t recover_seed( diff --git a/enclave/Makefile b/enclave/Makefile index 37c4f102..615f35d3 100644 --- a/enclave/Makefile +++ b/enclave/Makefile @@ -62,10 +62,11 @@ else Urts_Library_Name := sgx_urts endif -App_Cpp_Files := App/App.cpp utils/strencodings.cpp App/utilities/utilities.cpp App/database/db_manager.cpp App/sealing_key_manager/sealing_key_manager.cpp +App_Cpp_Files := App/App.cpp utils/strencodings.cpp utils/include_secp256k1_zkp_lib.cpp App/utilities/utilities.cpp App/database/db_manager.cpp \ + App/sealing_key_manager/sealing_key_manager.cpp App/statechain/deposit.cpp App/statechain/sign.cpp App/statechain/transfer_receiver.cpp App_Include_Paths := -IApp -I$(SGX_SDK)/include -I./secp256k1-zkp/include -App_C_Flags := -fPIC -Wno-attributes $(App_Include_Paths) +App_C_Flags := -fPIC -Wno-attributes $(App_Include_Paths) # Three configuration modes - Debug, prerelease, release # Debug - Macro DEBUG enabled. @@ -103,7 +104,7 @@ else endif Crypto_Library_Name := sgx_tcrypto -Enclave_Cpp_Files := Enclave/Enclave.cpp +Enclave_Cpp_Files := Enclave/Enclave.cpp utils/include_secp256k1_zkp_lib.cpp Enclave_C_Files := Enclave/libs/monocypher.c Enclave_Include_Paths := -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx -I./secp256k1-zkp/include -I/usr/local/include diff --git a/enclave/utils/include_secp256k1_zkp_lib.cpp b/enclave/utils/include_secp256k1_zkp_lib.cpp new file mode 100644 index 00000000..a618c7a7 --- /dev/null +++ b/enclave/utils/include_secp256k1_zkp_lib.cpp @@ -0,0 +1,17 @@ +#include // For abort() + +extern "C" { + #include "include_secp256k1_zkp_lib.h" + + void secp256k1_default_illegal_callback_fn(const char* str, void* data) { + (void)str; + (void)data; + abort(); + } + + void secp256k1_default_error_callback_fn(const char* str, void* data) { + (void)str; + (void)data; + abort(); + } +} \ No newline at end of file diff --git a/enclave/utils/include_secp256k1_zkp_lib.h b/enclave/utils/include_secp256k1_zkp_lib.h index d80254bf..cabf9570 100644 --- a/enclave/utils/include_secp256k1_zkp_lib.h +++ b/enclave/utils/include_secp256k1_zkp_lib.h @@ -8,17 +8,9 @@ extern "C" { #include "../secp256k1-zkp/include/secp256k1_schnorrsig.h" #include "../secp256k1-zkp/include/secp256k1_musig.h" - void secp256k1_default_illegal_callback_fn(const char* str, void* data) { - (void)str; - (void)data; - abort(); - } + void secp256k1_default_illegal_callback_fn(const char* str, void* data); - void secp256k1_default_error_callback_fn(const char* str, void* data) { - (void)str; - (void)data; - abort(); - } + void secp256k1_default_error_callback_fn(const char* str, void* data); } #endif // INCLUDE_SECP256K1_ZPK_H \ No newline at end of file