Commit fd7454df authored by 董子豪's avatar 董子豪

add remote attestation and password

parent 7c732274
......@@ -39,6 +39,7 @@
/autom4te.cache
/sgxwallet
/testw
/client
/configure
/secure_enclave/.deps
/test-driver
......
{
"files.associations": {
"sgxwallet.h": "c",
"iostream": "cpp",
"*.ipp": "cpp",
"ostream": "cpp",
"array": "cpp",
"string_view": "cpp",
"initializer_list": "cpp",
"utility": "cpp",
"string": "cpp",
"secure_enclave_t.h": "c",
"__locale": "cpp",
"functional": "cpp",
"filesystem": "cpp",
"iosfwd": "cpp",
"stdexcept": "cpp",
"fstream": "cpp",
"ios": "cpp",
"sstream": "cpp",
"strstream": "cpp",
"istream": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"map": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"limits": "cpp",
"memory": "cpp",
"new": "cpp",
"optional": "cpp",
"streambuf": "cpp",
"system_error": "cpp",
"type_traits": "cpp",
"tuple": "cpp",
"typeinfo": "cpp"
}
}
\ No newline at end of file
......@@ -67,20 +67,59 @@ vector <string> genECDSAKey() {
HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus,errMsg.data());
vector <string> keys(3);
vector <string> keys(4);
vector<char> hexEncrKey = carray2Hex(encr_pr_key.data(), enc_len);
keys.at(0) = hexEncrKey.data();
keys.at(1) = string(pub_key_x.data()) + string(pub_key_y.data());
keys.at(1) = string(pub_key_x.data());
keys.at(2) = string(pub_key_y.data());
vector<unsigned char> randBuffer(32, 0);
fillRandomBuffer(randBuffer);
vector<char> rand_str = carray2Hex(randBuffer.data(), 32);
keys.at(2) = rand_str.data();
keys.at(3) = rand_str.data();
CHECK_STATE(keys.at(2).size() == 64);
CHECK_STATE(keys.at(3).size() == 64);
return keys;
}
vector <string> genECDSAKeyWithPassword(const uint32_t context, const char* password) {
vector<char> errMsg(BUF_LEN, 0);
int errStatus = 0;
vector <uint8_t> encr_pr_key(BUF_LEN, 0);
vector<char> pub_key_x(BUF_LEN, 0);
vector<char> pub_key_y(BUF_LEN, 0);
uint64_t enc_len = 0;
sgx_status_t status = SGX_SUCCESS;
int exportable = 0;
status = trustedGenerateEcdsaKeyWithPassword(eid, &errStatus, errMsg.data(), context, password,
&exportable, encr_pr_key.data(), &enc_len,
pub_key_x.data(), pub_key_y.data());
HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus,errMsg.data());
vector <string> keys(4);
vector<char> hexEncrKey = carray2Hex(encr_pr_key.data(), enc_len);
keys.at(0) = hexEncrKey.data();
keys.at(1) = string(pub_key_x.data());
keys.at(2) = string(pub_key_y.data());
vector<unsigned char> randBuffer(32, 0);
fillRandomBuffer(randBuffer);
vector<char> rand_str = carray2Hex(randBuffer.data(), 32);
keys.at(3) = rand_str.data();
CHECK_STATE(keys.at(3).size() == 64);
return keys;
}
......@@ -116,6 +155,37 @@ string getECDSAPubKey(const std::string& _encryptedKeyHex) {
return pubKey;
}
string getECDSAPubKeyWithPassword(const uint32_t context, const char* password, const std::string& _encryptedKeyHex) {
vector<char> errMsg(BUF_LEN, 0);
vector<char> pubKeyX(BUF_LEN, 0);
vector<char> pubKeyY(BUF_LEN, 0);
vector<uint8_t> encrPrKey(BUF_LEN, 0);
int errStatus = 0;
uint64_t enc_len = 0;
if (!hex2carray(_encryptedKeyHex.c_str(), &enc_len, encrPrKey.data(),
BUF_LEN)) {
throw SGXException(GET_ECDSA_PUB_KEY_INVALID_KEY_HEX, "Invalid encryptedKeyHex");
}
sgx_status_t status = SGX_SUCCESS;
status = trustedGetPublicEcdsaKeyWithPassword(eid, &errStatus, errMsg.data(), context, password,
encrPrKey.data(), enc_len, pubKeyX.data(), pubKeyY.data());
HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus, errMsg.data())
string pubKey = string(pubKeyX.data()) + string(pubKeyY.data());
if (pubKey.size() != 128) {
spdlog::error("Incorrect pub key size", status);
throw SGXException(666, "Incorrect pub key size");
}
return pubKey;
}
bool verifyECDSASig(string& pubKeyStr, const char *hashHex, const char *signatureR,
const char *signatureS, int base) {
......@@ -208,7 +278,7 @@ vector <string> ecdsaSignHash(const std::string& encryptedKeyHex, const char *ha
/* Now verify signature */
pubKeyStr = getECDSAPubKey(encryptedKeyHex);
// pubKeyStr = getECDSAPubKey(encryptedKeyHex);
static uint64_t i = 0;
......@@ -216,6 +286,8 @@ vector <string> ecdsaSignHash(const std::string& encryptedKeyHex, const char *ha
if (i % 1000 == 0) {
pubKeyStr = getECDSAPubKey(encryptedKeyHex);
if (!verifyECDSASig(pubKeyStr, hashHex, signatureR.data(), signatureS.data(), base)) {
spdlog::error("failed to verify ecdsa signature");
throw SGXException(667, "ECDSA did not verify");
......@@ -225,6 +297,66 @@ vector <string> ecdsaSignHash(const std::string& encryptedKeyHex, const char *ha
return signatureVector;
}
vector <string> ecdsaSignHashWithPassword(const uint32_t context, const char *password, const std::string& encryptedKeyHex, const char *hashHex, int base) {
CHECK_STATE(hashHex);
vector <string> signatureVector(3);
vector<char> errMsg(BUF_LEN, 0);
int errStatus = 0;
vector<char> signatureR(BUF_LEN, 0);
vector<char> signatureS(BUF_LEN, 0);
vector<uint8_t> encryptedKey(BUF_LEN, 0);
uint8_t signatureV = 0;
uint64_t decLen = 0;
string pubKeyStr = "";
if (!hex2carray(encryptedKeyHex.c_str(), &decLen, encryptedKey.data(),
BUF_LEN)) {
throw SGXException(ECDSA_SIGN_INVALID_KEY_HEX, "Invalid encryptedKeyHex");
}
sgx_status_t status = SGX_SUCCESS;
status = trustedEcdsaSignWithPassword(eid, &errStatus, errMsg.data(), context, password,
encryptedKey.data(), decLen, hashHex,
signatureR.data(),
signatureS.data(), &signatureV, base);
HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus, errMsg.data());
signatureVector.at(0) = to_string(signatureV);
if (base == 16) {
signatureVector.at(1) = "0x" + string(signatureR.data());
signatureVector.at(2) = "0x" + string(signatureS.data());
} else {
signatureVector.at(1) = string(signatureR.data());
signatureVector.at(2) = string(signatureS.data());
}
/* Now verify signature */
// pubKeyStr = getECDSAPubKeyWithPassword(context, password, encryptedKeyHex);
// static uint64_t i = 0;
// i++;
// if (i % 1000 == 0) {
// if (!verifyECDSASig(pubKeyStr, hashHex, signatureR.data(), signatureS.data(), base)) {
// spdlog::error("failed to verify ecdsa signature");
// throw SGXException(667, "ECDSA did not verify");
// }
// }
return signatureVector;
}
string encryptECDSAKey(const string& _key) {
vector<char> key(BUF_LEN, 0);
for (size_t i = 0; i < _key.size(); ++i) {
......@@ -248,3 +380,27 @@ string encryptECDSAKey(const string& _key) {
return string(hexEncrKey.begin(), hexEncrKey.end());
}
string encryptECDSAKeyWithPassword(const uint32_t context, const char* password, const string& _key) {
vector<char> key(BUF_LEN, 0);
for (size_t i = 0; i < _key.size(); ++i) {
key[i] = _key[i];
}
vector<uint8_t> encryptedKey(BUF_LEN, 0);
int errStatus = 0;
vector<char> errString(BUF_LEN, 0);
uint64_t enc_len = 0;
sgx_status_t status = SGX_SUCCESS;
status = trustedEncryptKeyWithPassword(eid, &errStatus, errString.data(), context, password, key.data(),
encryptedKey.data(), &enc_len);
HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus, errString.data());
vector<char> hexEncrKey = carray2Hex(encryptedKey.data(), enc_len);
return string(hexEncrKey.begin(), hexEncrKey.end());
}
\ No newline at end of file
......@@ -30,12 +30,15 @@
using namespace std;
vector<string> genECDSAKey();
vector<string> genECDSAKeyWithPassword(const uint32_t context, const char* password);
string getECDSAPubKey(const std::string& _encryptedKeyHex);
string getECDSAPubKeyWithPassword(const uint32_t context, const char* password, const std::string& _encryptedKeyHex);
vector<string> ecdsaSignHash(const std::string& encryptedKeyHex, const char* hashHex, int base);
vector<string> ecdsaSignHashWithPassword(const uint32_t context, const char* password, const std::string& encryptedKeyHex, const char* hashHex, int base);
string encryptECDSAKey(const string& key);
string encryptECDSAKeyWithPassword(const uint32_t context, const char* password, const string& key);
#endif //SGXD_ECDSACRYPTO_H
......@@ -62,7 +62,7 @@ CLEANFILES = $(COMMON_ENCLAVE_SRC) secure_enclave.edl secure_enclave.signed.so
## The build target
bin_PROGRAMS = sgxwallet testw sgx_util
bin_PROGRAMS = sgxwallet testw sgx_util client
## You can't use $(wildcard ...) with automake so all source files
......@@ -76,7 +76,7 @@ COMMON_SRC = SGXException.cpp ExitHandler.cpp zmq_src/ZMQClient.cpp zmq_src/RspM
SGXWalletServer.cpp SGXRegistrationServer.cpp CSRManagerServer.cpp BLSCrypto.cpp CryptoTools.cpp \
DKGCrypto.cpp ServerInit.cpp BLSPrivateKeyShareSGX.cpp LevelDB.cpp ServerDataChecker.cpp SEKManager.cpp \
third_party/intel/sgx_stub.c third_party/intel/sgx_detect_linux.c third_party/intel/create_enclave.c \
third_party/intel/oc_alloc.c ECDSAImpl.c TestUtils.cpp sgxwallet.c SGXInfoServer.cpp ECDSACrypto.cpp
third_party/intel/oc_alloc.c ECDSAImpl.c TestUtils.cpp sgxwallet.c SGXInfoServer.cpp ECDSACrypto.cpp SGXRemoteAttestationServer.cpp
COMMON_ENCLAVE_SRC = secure_enclave_u.c secure_enclave_u.h
sgxwallet_SOURCES = sgxwall.cpp $(COMMON_SRC)
......@@ -110,7 +110,7 @@ sgxwallet_LDADD=-l$(SGX_URTS_LIB) -l$(SGX_UAE_SERVICE_LIB) -LlibBLS/deps/deps_in
-l:libff.a -lgmp -ldl -l:libsgx_capable.a -l:libsgx_tprotected_fs.a \
-l:libzmq.a \
-ljsonrpccpp-stub -ljsonrpccpp-server -ljsonrpccpp-client -ljsonrpccpp-common -ljsoncpp -lmicrohttpd \
-lboost_system -lboost_thread -lgnutls -lgcrypt -lidn2 -lcurl -lssl -lcrypto -lz -lpthread -lstdc++fs
-lboost_system -lboost_thread -lgnutls -lgcrypt -lidn2 -lcurl -lssl -lcrypto -lz -lpthread -lstdc++fs -lsgx_ukey_exchange
testw_SOURCES=testw.cpp $(COMMON_SRC)
nodist_testw_SOURCES=${nodist_sgxwallet_SOURCES}
......@@ -129,3 +129,13 @@ sgx_util_LDADD=-LlibBLS/deps/deps_inst/x86_or_x64/lib -Lleveldb/build -LlibBLS/b
-l:libff.a -lgmp -ljsonrpccpp-stub -ljsonrpccpp-server -ljsonrpccpp-client -ljsonrpccpp-common \
-ljsoncpp -lmicrohttpd -lgnutls -lgcrypt -lidn2 -lcurl -lssl -lcrypto -lz -lpthread -ldl
client_SOURCES = SGXException.cpp ExitHandler.cpp Log.cpp client.cpp InvalidArgumentException.cpp \
cmac128.cpp aes_gcm.cpp ecc256.cpp sha256.cpp ra_ecp.cpp ra_ias.cpp CryptoTools.cpp remoteAttestation.cpp
client_LDADD = -LlibBLS/deps/deps_inst/x86_or_x64/lib -LlibBLS/build \
-LlibBLS/build/libff/libff \
-Llibzmq/build/lib/ \
-l:libff.a -lgmp -ljsonrpccpp-stub -ljsonrpccpp-client -ljsonrpccpp-common \
-ljsoncpp -lmicrohttpd -lgnutls -lgcrypt -lidn2 -lcurl -lssl -lcrypto -lz -lpthread -ldl
#include "SGXRemoteAttestationServer.h"
#include <jsonrpccpp/server/connectors/httpserver.h>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include "third_party/spdlog/spdlog.h"
#include "sgxwallet_common.h"
#include "sgxwallet.h"
#include "CryptoTools.h"
#include "ra_result.h"
#include "Log.h"
#include <sgx_ukey_exchange.h>
#include <sgx_uae_epid.h>
shared_ptr <SGXRemoteAttestationServer> SGXRemoteAttestationServer::server = nullptr;
shared_ptr <HttpServer> SGXRemoteAttestationServer::httpServer = nullptr;
sgx_att_key_id_t SGXRemoteAttestationServer::selected_key_id = {0};
SGXRemoteAttestationServer::SGXRemoteAttestationServer(AbstractServerConnector &connector, serverVersion_t type)
:AbstractRAServer(connector, type) {
// logLevel_ = _logLevel;
}
void SGXRemoteAttestationServer::initRemoteAttestationServer() {
httpServer = make_shared<HttpServer>(BASE_PORT - 1);
server = make_shared<SGXRemoteAttestationServer>(*httpServer, JSONRPC_SERVER_V2); // hybrid server (json-rpc 1.0 & 2.0)
spdlog::info("Starting remote attestation server on port {} ...", BASE_PORT - 1);
if (!server->StartListening()) {
spdlog::error("Remote attestation server could not start listening on port {}", BASE_PORT - 1);
throw SGXException(REMOTE_ATTESTATION_SERVER_FAILED_TO_START, string(__FUNCTION__) + ":Remote attestation server could not start listening.");
} else {
spdlog::info("Remote attestation server started on port {}", BASE_PORT - 1);
}
if (SGX_SUCCESS != selectAttestationKey(g_ecdsa_p256_att_key_id_list, sizeof(g_ecdsa_p256_att_key_id_list))) {
spdlog::error("Remote attestation server could not select attestation key", BASE_PORT - 1);
throw SGXException(REMOTE_ATTESTATION_SERVER_FAILED_TO_START, string(__FUNCTION__) + ":Remote attestation server could not select attestation key.");
}
}
int SGXRemoteAttestationServer::exitServer() {
spdlog::info("Stoping Remote attestation server");
if (server && !server->StopListening()) {
spdlog::error("Remote attestation server could not be stopped. Will forcefully terminate the app");
} else {
spdlog::info("Remote attestation server stopped");
}
return 0;
}
shared_ptr<SGXRemoteAttestationServer> SGXRemoteAttestationServer::getServer() {
CHECK_STATE(server);
return server;
}
int SGXRemoteAttestationServer::selectAttestationKey(const uint8_t* keyList, uint32_t keyListSize) {
return sgx_select_att_key_id(keyList, keyListSize, &selected_key_id);
}
Json::Value SGXRemoteAttestationServer::initRA(const string &pubKey) {
sgx_ec256_public_t publicKey;
uint64_t publicKeySize;
uint32_t extended_epid;
sgx_status_t status, ra_status;
sgx_ra_context_t context;
Json::Value result;
try {
hex2carray(pubKey.c_str(), &publicKeySize, (uint8_t*)&publicKey, pubKey.size());
if (sizeof(sgx_ec256_public_t) != publicKeySize) {
printf("Invalid public key size; need(%ld), but got(%ld)\n", sizeof(sgx_ec256_public_t), publicKeySize);
throw SGXException(RA_INVALID_PUBLIC_KEY, string(__FUNCTION__) + ":Invalid public key size");
}
status = trustedInitRA(eid, &ra_status, publicKey, false, &context);
if (SGX_SUCCESS != status || SGX_SUCCESS != ra_status) {
result["errorCode"] = status;
result["errorRACode"] = ra_status;
throw SGXException(FAIL_INIT_RA, string(__FUNCTION__) + ":Failed Init Remote Attestation");
}
// this->setContext(context);
status = sgx_get_extended_epid_group_id(&extended_epid);
if (SGX_SUCCESS != status) {
result["errorCode"] = status;
throw SGXException(FAIL_GET_EPID, string(__FUNCTION__) + ":Failed Get extended epid");
}
result["context"] = context;
result["EPID"] = extended_epid;
} HANDLE_SGX_EXCEPTION(result)
RETURN_SUCCESS(result);
}
Json::Value SGXRemoteAttestationServer::generateMSG1(uint32_t context) {
vector<char> msg1Carray;
sgx_ra_msg1_t msg1;
sgx_status_t status;
Json::Value result;
try {
status = sgx_ra_get_msg1_ex(&selected_key_id, context, eid, sgx_ra_get_ga, &msg1);
if (SGX_SUCCESS != status) {
result["errorCode"] = status;
throw SGXException(FAIL_GENERATE_MESSAGE1, string(__FUNCTION__) + ":Failed Generate Message1");
}
msg1Carray = carray2Hex((const unsigned char*)&msg1, sizeof(sgx_ra_msg1_t));
result["message1"] = string(msg1Carray.data(), msg1Carray.size());
} HANDLE_SGX_EXCEPTION(result)
RETURN_SUCCESS(result);
}
Json::Value SGXRemoteAttestationServer::generateMSG3(uint32_t context, const string &message) {
sgx_ra_msg2_t* msg2;
uint32_t msg2_size;
vector<char> msg3Carray;
sgx_ra_msg3_t* msg3;
uint32_t msg3_size;
sgx_status_t status;
Json::Value result;
uint64_t message_size;
try {
if (sizeof(sgx_ra_msg2_t) > message.size() / 2) {
throw SGXException(RA_INVALID_MESSAGE2_SIZE, string(__FUNCTION__) + ":Invalid message2 size, lower than sgx_ra_msg2_t");
}
msg2 = (sgx_ra_msg2_t*)malloc(message.size() / 2);
if (!hex2carray(message.c_str(), &message_size, (uint8_t*)msg2, message.size())) {
throw SGXException(FALIED_COVERT_HEX, string(__FUNCTION__) + ":Falied to covert message2 hex to carray");
}
msg2_size = sizeof(sgx_ra_msg2_t) + msg2 -> sig_rl_size;
if ((uint32_t)message_size != msg2_size) {
throw SGXException(RA_INVALID_MESSAGE2_SIZE, string(__FUNCTION__) + ":Invalid message2 size, msg2 size didn't match");
}
status = sgx_ra_proc_msg2_ex(&selected_key_id,
context,
eid,
sgx_ra_proc_msg2_trusted,
sgx_ra_get_msg3_trusted,
msg2,
msg2_size,
&msg3,
&msg3_size);
if (SGX_SUCCESS != status) {
result["errorCode"] = status;
throw SGXException(FAIL_GENERATE_MESSAGE3, string(__FUNCTION__) + ":Failed Generate Message3");
}
msg3Carray = carray2Hex((const unsigned char*)msg3, msg3_size);
result["message3"] = string(msg3Carray.data(), msg3Carray.size());
} HANDLE_SGX_EXCEPTION(result)
SAFE_FREE(msg2);
SAFE_FREE(msg3);
RETURN_SUCCESS(result);
}
Json::Value SGXRemoteAttestationServer::verifyResult(uint32_t context, const string &resultStr) {
Json::Value result;
sgx_status_t status, ra_status;
ra_msg_t* ra_result;
uint32_t result_size;
uint64_t message_size;
try {
if (sizeof(ra_msg_t) > resultStr.size() / 2) {
throw SGXException(RA_INVALID_RESULT_SIZE, string(__FUNCTION__) + ":Invalid result size, lower than ra_msg_t");
}
ra_result = (ra_msg_t*)malloc(resultStr.size() / 2);
if (!hex2carray(resultStr.c_str(), &message_size, (uint8_t*)ra_result, resultStr.size())) {
throw SGXException(FALIED_COVERT_HEX, string(__FUNCTION__) + ":Falied to covert result hex to carray");
}
result_size = sizeof(ra_msg_t) + ra_result->payload_size;
if (result_size != (uint32_t)message_size) {
throw SGXException(RA_INVALID_MESSAGE2_SIZE, string(__FUNCTION__) + ":Invalid result size, result size didn't match");
}
// CHECK MK
// status = trustedVerifyMac(eid,
// &ra_status,
// context,
// ra_result->payload,
// ra_result->payload_size,
// ra_result->payload_mac,
// MAC_SIZE);
// if(SGX_SUCCESS != status || SGX_SUCCESS != ra_status) {
// result["errorCode"] = status;
// result["errorRACode"] = ra_status;
// throw SGXException(FAIL_VERIFY_MAC, string(__FUNCTION__) + ":Failed Verify Remote Attestation Result[Mac]");
// }
// CHECK SK
status = trustedVerifySecret(eid,
&ra_status,
context,
ra_result->payload,
ra_result->payload_size,
ra_result->payload_iv,
ra_result->payload_mac);
if(SGX_SUCCESS != status || SGX_SUCCESS != ra_status) {
result["errorCode"] = status;
result["errorRACode"] = ra_status;
throw SGXException(FAIL_VERIFY_SECRET, string(__FUNCTION__) + ":Failed Verify Remote Attestation Result[Secret]");
}
} HANDLE_SGX_EXCEPTION(result)
SAFE_FREE(ra_result);
RETURN_SUCCESS(result);
}
\ No newline at end of file
#ifndef _SGX_REMOTE_ATTESTATION_SERVER_H_
#define _SGX_REMOTE_ATTESTATION_SERVER_H_
#include <memory>
#include "abstractraserver.h"
#include <jsonrpccpp/server/connectors/httpserver.h>
#include <sgx_uae_quote_ex.h>
using namespace jsonrpc;
using namespace std;
class SGXRemoteAttestationServer: AbstractRAServer {
// Uint32_t logLevel_;
static shared_ptr <HttpServer> httpServer;
static shared_ptr <SGXRemoteAttestationServer> server;
static sgx_att_key_id_t selected_key_id;
static int selectAttestationKey(const uint8_t* keyList, uint32_t keyListSize);
public:
static shared_ptr <SGXRemoteAttestationServer> getServer();
SGXRemoteAttestationServer(AbstractServerConnector &connector, serverVersion_t type);
virtual Json::Value initRA(const string &pubkey);
virtual Json::Value generateMSG1(uint32_t context);
virtual Json::Value generateMSG3(uint32_t context, const string &msg2);
virtual Json::Value verifyResult(uint32_t context, const string &result);
static void closeRA(uint32_t context);
static void initRemoteAttestationServer();
static int exitServer();
};
// This is a hardcode sgx_ql_att_key_id_list_t with one sgx_att_key_id_ext_t in
// it. The sgx_att_key_id_ext_t consists of the intel QE3's measurements.
// Using this hardcode sgx_ql_att_key_id_list_t ensures the AESM will only use
// Intel QE3 to generate the ECDSA quote.
const uint8_t g_ecdsa_p256_att_key_id_list[] = {
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x8c, 0x4f,
0x57, 0x75, 0xd7, 0x96, 0x50, 0x3e, 0x96, 0x13,
0x7f, 0x77, 0xc6, 0x8a, 0x82, 0x9a, 0x00, 0x56,
0xac, 0x8d, 0xed, 0x70, 0x14, 0x0b, 0x08, 0x1b,
0x09, 0x44, 0x90, 0xc5, 0x7b, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
// This is a hardcode sgx_ql_att_key_id_list_t with one sgx_att_key_id_ext_t in
// it. The sgx_att_key_id_ext_t consists of the intel EPID QE's measurements.
// Using this hardcode sgx_ql_att_key_id_list_t ensures the AESM will only use
// Intel EPID QE to generate the EPID quote. It also set att_key_type to
// SGX_UNLINKABLE_SIGNATURE(0), so Intel EPID QE will generate an unlinkable
// EPID quote.
const uint8_t g_epid_unlinkable_att_key_id_list[] = {
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xec, 0x15,
0xb1, 0x07, 0x87, 0xd2, 0xf8, 0x46, 0x67, 0xce,
0xb0, 0xb5, 0x98, 0xff, 0xc4, 0x4a, 0x1f, 0x1c,
0xb8, 0x0f, 0x67, 0x0a, 0xae, 0x5d, 0xf9, 0xe8,
0xfa, 0x9f, 0x63, 0x76, 0xe1, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
#endif
\ No newline at end of file
......@@ -384,13 +384,45 @@ Json::Value SGXWalletServer::generateECDSAKeyImpl() {
throw SGXException(ECDSA_GEN_EMPTY_KEY, string(__FUNCTION__) + ":key was not generated");
}
string keyName = "NEK:" + keys.at(2);
string keyName = "NEK:" + keys.at(3);
writeDataToDB(keyName, keys.at(0));
result["encryptedKey"] = keys.at(0);
result["publicKey"] = keys.at(1);
result["PublicKey"] = keys.at(1);
result["publicKeyX"] = keys.at(1);
result["publicKeyY"] = keys.at(2);
result["PublicKey"] = keys.at(1) + keys.at(2);
result["keyName"] = keyName;
} HANDLE_SGX_EXCEPTION(result)
RETURN_SUCCESS(result);
}
Json::Value SGXWalletServer::generateECDSAKeyWithPasswordImpl(const uint32_t context, const string &password) {
COUNT_STATISTICS
spdlog::info("Entering {}", __FUNCTION__);
INIT_RESULT(result)
result["encryptedKey"] = "";
vector <string> keys;
try {
string passwordTmp = password;
keys = genECDSAKeyWithPassword(context, passwordTmp.c_str());
if (keys.size() == 0) {
throw SGXException(ECDSA_GEN_EMPTY_KEY, string(__FUNCTION__) + ":key was not generated");
}
string keyName = "NEK:" + keys.at(3);
writeDataToDB(keyName, keys.at(0));
result["encryptedKey"] = keys.at(0);
result["publicKeyX"] = keys.at(1);
result["publicKeyY"] = keys.at(2);
result["publicKey"] = keys.at(1) + keys.at(2);
result["keyName"] = keyName;
} HANDLE_SGX_EXCEPTION(result)
......@@ -444,6 +476,54 @@ Json::Value SGXWalletServer::ecdsaSignMessageHashImpl(int _base, const string &_
RETURN_SUCCESS(result)
}
Json::Value SGXWalletServer::ecdsaSignMessageHashWithPasswordImpl(const uint32_t context, const string &password, int _base, const string &_keyName, const string &_messageHash) {
COUNT_STATISTICS
spdlog::trace("Entering {}", __FUNCTION__);
INIT_RESULT(result)
result["signature_v"] = "";
result["signature_r"] = "";
result["signature_s"] = "";
vector <string> signatureVector(3);
checkForDuplicate(ecdsaRequests, ecdsaRequestsLock, _keyName, _messageHash);
try {
string passwordTmp = password;
string hashTmp = _messageHash;
if (hashTmp[0] == '0' && (hashTmp[1] == 'x' || hashTmp[1] == 'X')) {
hashTmp.erase(hashTmp.begin(), hashTmp.begin() + 2);
}
while (hashTmp[0] == '0') {
hashTmp.erase(hashTmp.begin(), hashTmp.begin() + 1);
}
if (!checkECDSAKeyName(_keyName)) {
throw SGXException(INVALID_ECDSA_SIGN_KEY_NAME, string(__FUNCTION__) + ":Invalid ECDSA sign key name");
}
if (!checkHex(hashTmp)) {
throw SGXException(INVALID_ECDSA_SIGN_HASH, ":Invalid ECDSA sign hash");
}
if (_base <= 0 || _base > 32) {
throw SGXException(INVALID_ECDSA_SIGN_BASE, ":Invalid ECDSA sign base");
}
shared_ptr <string> encryptedKey = readFromDb(_keyName, "");
signatureVector = ecdsaSignHashWithPassword(context, passwordTmp.c_str(), encryptedKey->c_str(), hashTmp.c_str(), _base);
if (signatureVector.size() != 3) {
throw SGXException(INVALID_ECSDA_SIGN_SIGNATURE, string(__FUNCTION__) + ":Invalid ecdsa signature");
}
result["signature_v"] = signatureVector.at(0);
result["signature_r"] = signatureVector.at(1);
result["signature_s"] = signatureVector.at(2);
} HANDLE_SGX_EXCEPTION(result)
RETURN_SUCCESS(result)
}
Json::Value SGXWalletServer::getPublicECDSAKeyImpl(const string &_keyName) {
COUNT_STATISTICS
spdlog::debug("Entering {}", __FUNCTION__);
......@@ -468,6 +548,31 @@ Json::Value SGXWalletServer::getPublicECDSAKeyImpl(const string &_keyName) {
RETURN_SUCCESS(result)
}
Json::Value SGXWalletServer::getPublicECDSAKeyWithPasswordImpl(const uint32_t context, const string &password, const string &_keyName) {
COUNT_STATISTICS
spdlog::debug("Entering {}", __FUNCTION__);
INIT_RESULT(result)
result["publicKey"] = "";
result["PublicKey"] = "";
string publicKey;
try {
string passwordTmp = password;
if (!checkECDSAKeyName(_keyName)) {
throw SGXException(INVALID_ECDSA_GETPKEY_KEY_NAME, string(__FUNCTION__) +
":Invalid ECDSA import key name");
}
shared_ptr <string> keyStr = readFromDb(_keyName);
publicKey = getECDSAPubKeyWithPassword(context, passwordTmp.c_str(), keyStr->c_str());
result["PublicKey"] = publicKey;
result["publicKey"] = publicKey;
} HANDLE_SGX_EXCEPTION(result)
RETURN_SUCCESS(result)
}
Json::Value SGXWalletServer::generateDKGPolyImpl(const string &_polyName, int _t) {
COUNT_STATISTICS
spdlog::info("Entering {}", __FUNCTION__);
......@@ -1055,14 +1160,26 @@ Json::Value SGXWalletServer::generateECDSAKey() {
return generateECDSAKeyImpl();
}
Json::Value SGXWalletServer::generateECDSAKeyWithPassword(const uint32_t context, const string &password) {
return generateECDSAKeyWithPasswordImpl(context, password);
}
Json::Value SGXWalletServer::getPublicECDSAKey(const string &_keyName) {
return getPublicECDSAKeyImpl(_keyName);
}
Json::Value SGXWalletServer::getPublicECDSAKeyWithPassword(const uint32_t context, const string &password, const string &_keyName) {
return getPublicECDSAKeyWithPasswordImpl(context, password, _keyName);
}
Json::Value SGXWalletServer::ecdsaSignMessageHash(int _base, const string &_keyShareName, const string &_messageHash) {
return ecdsaSignMessageHashImpl(_base, _keyShareName, _messageHash);
}
Json::Value SGXWalletServer::ecdsaSignMessageHashWithPassword(const uint32_t context, const string &password, int _base, const string &_keyShareName, const string &_messageHash) {
return ecdsaSignMessageHashWithPasswordImpl(context, password, _base, _keyShareName, _messageHash);
}
Json::Value
SGXWalletServer::importBLSKeyShare(const string &_keyShare, const string &_keyShareName) {
return importBLSKeyShareImpl(_keyShare, _keyShareName);
......
......@@ -71,11 +71,15 @@ public:
const std::string& keyShareName);
virtual Json::Value generateECDSAKey();
virtual Json::Value generateECDSAKeyWithPassword(const uint32_t context, const string &password);
virtual Json::Value
ecdsaSignMessageHash(int _base, const string &_keyShareName, const string &_messageHash);
virtual Json::Value
ecdsaSignMessageHashWithPassword(const uint32_t context, const string &password, int _base, const string &_keyShareName, const string &_messageHash);
virtual Json::Value getPublicECDSAKey(const string &_keyName);
virtual Json::Value getPublicECDSAKeyWithPassword(const uint32_t context, const string &password, const string &_keyName);
virtual Json::Value generateDKGPoly(const string &_polyName, int _t);
......@@ -132,10 +136,13 @@ public:
static Json::Value importECDSAKeyImpl(const string &_keyShare, const string &_keyShareName);
static Json::Value generateECDSAKeyImpl();
static Json::Value generateECDSAKeyWithPasswordImpl(const uint32_t context, const string &password);
static Json::Value ecdsaSignMessageHashImpl(int _base, const string &keyName, const string &_messageHash);
static Json::Value ecdsaSignMessageHashWithPasswordImpl(const uint32_t context, const string &password, int _base, const string &keyName, const string &_messageHash);
static Json::Value getPublicECDSAKeyImpl(const string &_keyName);
static Json::Value getPublicECDSAKeyWithPasswordImpl(const uint32_t context, const string &password, const string &_keyName);
static Json::Value generateDKGPolyImpl(const string &_polyName, int _t);
......
......@@ -50,6 +50,7 @@
#include "third_party/intel/sgx_detect.h"
#include "sgxwallet.h"
#include "LevelDB.h"
#include "SGXRemoteAttestationServer.h"
#include "SGXWalletServer.h"
#include "SGXRegistrationServer.h"
#include "SGXInfoServer.h"
......@@ -206,6 +207,7 @@ void initAll(uint32_t _logLevel, bool _checkCert,
spdlog::info("Inited JSON-RPC server over HTTP");
}
SGXRemoteAttestationServer::initRemoteAttestationServer();
SGXRegistrationServer::initRegistrationServer(_autoSign);
CSRManagerServer::initCSRManagerServer();
SGXInfoServer::initInfoServer(_logLevel, _checkCert, _autoSign, _generateTestKeys);
......@@ -228,6 +230,7 @@ void initAll(uint32_t _logLevel, bool _checkCert,
};
void exitAll() {
SGXRemoteAttestationServer::exitServer();
SGXWalletServer::exitServer();
SGXRegistrationServer::exitServer();
CSRManagerServer::exitServer();
......
#ifndef _ABSTRACT_RA_SERVER_H
#define _ABSTRACT_RA_SERVER_H
#include <jsonrpccpp/server.h>
#include <iostream>
using namespace std;
class AbstractRAServer : public jsonrpc::AbstractServer<AbstractRAServer>
{
public:
AbstractRAServer(jsonrpc::AbstractServerConnector &conn, jsonrpc::serverVersion_t type = jsonrpc::JSONRPC_SERVER_V2) : jsonrpc::AbstractServer<AbstractRAServer>(conn, type)
{
this->bindAndAddMethod(jsonrpc::Procedure("initRA", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "publicKey", jsonrpc::JSON_STRING, NULL), &AbstractRAServer::initRAI);
this->bindAndAddMethod(jsonrpc::Procedure("generateMSG1", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "context", jsonrpc::JSON_INTEGER, NULL), &AbstractRAServer::generateMSG1I);
this->bindAndAddMethod(jsonrpc::Procedure("generateMSG3", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "context", jsonrpc::JSON_INTEGER, "message", jsonrpc::JSON_STRING, NULL), &AbstractRAServer::generateMSG3I);
this->bindAndAddMethod(jsonrpc::Procedure("verifyResult", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "context", jsonrpc::JSON_INTEGER, "result",jsonrpc::JSON_STRING, NULL), &AbstractRAServer::verifyResultI);
}
inline virtual void initRAI(const Json::Value &request, Json::Value &response)
{
response = this->initRA(request["publicKey"].asString());
}
inline virtual void generateMSG1I(const Json::Value &request, Json::Value &response)
{
response = this->generateMSG1(request["context"].asUInt());
}
inline virtual void generateMSG3I(const Json::Value &request, Json::Value &response)
{
response = this->generateMSG3(request["context"].asUInt(), request["message"].asString());
}
inline virtual void verifyResultI(const Json::Value &request, Json::Value &response)
{
response = this->verifyResult(request["context"].asUInt(), request["result"].asString());
}
virtual Json::Value initRA(const string& pubKey) = 0;
virtual Json::Value generateMSG1(uint32_t context) = 0;
virtual Json::Value generateMSG3(uint32_t context, const string& message2) = 0;
virtual Json::Value verifyResult(uint32_t context, const string& result) = 0;
};
#endif
......@@ -31,6 +31,8 @@
#include <jsonrpccpp/server.h>
using namespace std;
class AbstractStubServer : public jsonrpc::AbstractServer<AbstractStubServer>
{
public:
......@@ -44,6 +46,10 @@ class AbstractStubServer : public jsonrpc::AbstractServer<AbstractStubServer>
this->bindAndAddMethod(jsonrpc::Procedure("getPublicECDSAKey", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "keyName",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::getPublicECDSAKeyI);
this->bindAndAddMethod(jsonrpc::Procedure("ecdsaSignMessageHash", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "base",jsonrpc::JSON_INTEGER,"keyName",jsonrpc::JSON_STRING,"messageHash",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::ecdsaSignMessageHashI);
this->bindAndAddMethod(jsonrpc::Procedure("generateECDSAKeyWithPassword", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "context",jsonrpc::JSON_INTEGER,"password",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::generateECDSAKeyWithPasswordI);
this->bindAndAddMethod(jsonrpc::Procedure("getPublicECDSAKeyWithPassword", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "context",jsonrpc::JSON_INTEGER,"password",jsonrpc::JSON_STRING,"keyName",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::getPublicECDSAKeyWithPasswordI);
this->bindAndAddMethod(jsonrpc::Procedure("ecdsaSignMessageHashWithPassword", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "context",jsonrpc::JSON_INTEGER,"password",jsonrpc::JSON_STRING,"base",jsonrpc::JSON_INTEGER,"keyName",jsonrpc::JSON_STRING,"messageHash",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::ecdsaSignMessageHashWithPasswordI);
this->bindAndAddMethod(jsonrpc::Procedure("generateDKGPoly", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "polyName",jsonrpc::JSON_STRING,"t",jsonrpc::JSON_INTEGER, NULL), &AbstractStubServer::generateDKGPolyI);
this->bindAndAddMethod(jsonrpc::Procedure("getVerificationVector", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "polyName", jsonrpc::JSON_STRING, "t", jsonrpc::JSON_INTEGER, NULL), &AbstractStubServer::getVerificationVectorI);
this->bindAndAddMethod(jsonrpc::Procedure("getSecretShare", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "polyName",jsonrpc::JSON_STRING,"publicKeys",jsonrpc::JSON_ARRAY, "n",jsonrpc::JSON_INTEGER,"t",jsonrpc::JSON_INTEGER, NULL), &AbstractStubServer::getSecretShareI);
......@@ -93,6 +99,19 @@ class AbstractStubServer : public jsonrpc::AbstractServer<AbstractStubServer>
response = this->ecdsaSignMessageHash(request["base"].asInt(), request["keyName"].asString(), request["messageHash"].asString());
}
inline virtual void generateECDSAKeyWithPasswordI(const Json::Value &request, Json::Value &response)
{
response = this->generateECDSAKeyWithPassword(request["context"].asUInt(), request["password"].asString());
}
inline virtual void getPublicECDSAKeyWithPasswordI(const Json::Value &request, Json::Value &response)
{
response = this->getPublicECDSAKeyWithPassword(request["context"].asUInt(), request["password"].asString(), request["keyName"].asString());
}
inline virtual void ecdsaSignMessageHashWithPasswordI(const Json::Value &request, Json::Value &response)
{
response = this->ecdsaSignMessageHashWithPassword(request["context"].asUInt(), request["password"].asString(), request["base"].asInt(), request["keyName"].asString(), request["messageHash"].asString());
}
inline virtual void generateDKGPolyI(const Json::Value &request, Json::Value &response)
{
response = this->generateDKGPoly(request["polyName"].asString(), request["t"].asInt());
......@@ -175,6 +194,10 @@ class AbstractStubServer : public jsonrpc::AbstractServer<AbstractStubServer>
virtual Json::Value getPublicECDSAKey(const std::string& keyName) = 0;
virtual Json::Value ecdsaSignMessageHash(int base, const std::string& keyName, const std::string& messageHash) = 0;
virtual Json::Value generateECDSAKeyWithPassword(const uint32_t context, const string &password) = 0;
virtual Json::Value getPublicECDSAKeyWithPassword(const uint32_t context, const string &password, const std::string& keyName) = 0;
virtual Json::Value ecdsaSignMessageHashWithPassword(const uint32_t context, const string &password, int base, const std::string& keyName, const std::string& messageHash) = 0;
virtual Json::Value generateDKGPoly(const std::string& polyName, int t) = 0;
virtual Json::Value getVerificationVector(const std::string& polyName, int t) = 0;
virtual Json::Value getSecretShare(const std::string& polyName, const Json::Value& publicKeys, int t, int n) = 0;
......
#include <string.h>
#include <openssl/evp.h>
#include "crypto.h"
using namespace std;
int aes_gcm_encrypt(const sgx_aes_gcm_128bit_key_t *p_key, const uint8_t *p_src, uint32_t src_len,
uint8_t *p_dst, const uint8_t *p_iv, uint32_t iv_len, const uint8_t *p_aad, uint32_t aad_len,
sgx_aes_gcm_128bit_tag_t *p_out_mac) {
if ((src_len >= INT_MAX) || (aad_len >= INT_MAX) || (p_key == NULL) || ((src_len > 0) && (p_dst == NULL)) || ((src_len > 0) && (p_src == NULL))
|| (p_out_mac == NULL) || (iv_len != SGX_AESGCM_IV_SIZE) || ((aad_len > 0) && (p_aad == NULL))
|| (p_iv == NULL) || ((p_src == NULL) && (p_aad == NULL)))
{
return -1;
}
int ret = -1;
int len = 0;
EVP_CIPHER_CTX * pState = NULL;
do {
// Create and init ctx
//
if (!(pState = EVP_CIPHER_CTX_new())) {
break;
}
// Initialise encrypt, key and IV
//
if (1 != EVP_EncryptInit_ex(pState, EVP_aes_128_gcm(), NULL, (unsigned char*)p_key, p_iv)) {
break;
}
// Provide AAD data if exist
//
if (NULL != p_aad) {
if (1 != EVP_EncryptUpdate(pState, NULL, &len, p_aad, aad_len)) {
break;
}
}
if (src_len > 0) {
// Provide the message to be encrypted, and obtain the encrypted output.
//
if (1 != EVP_EncryptUpdate(pState, p_dst, &len, p_src, src_len)) {
break;
}
}
// Finalise the encryption
//
if (1 != EVP_EncryptFinal_ex(pState, p_dst + len, &len)) {
break;
}
// Get tag
//
if (1 != EVP_CIPHER_CTX_ctrl(pState, EVP_CTRL_GCM_GET_TAG, SGX_AESGCM_MAC_SIZE, p_out_mac)) {
break;
}
ret = 0;
} while (0);
// Clean up and return
//
if (pState) {
EVP_CIPHER_CTX_free(pState);
}
return ret;
}
int aes_gcm_decrypt(const sgx_aes_gcm_128bit_key_t *p_key, const uint8_t *p_src, uint32_t src_len,
uint8_t *p_dst, const uint8_t *p_iv, uint32_t iv_len, const uint8_t *p_aad, uint32_t aad_len,
const sgx_aes_gcm_128bit_tag_t *p_in_mac) {
uint8_t l_tag[SGX_AESGCM_MAC_SIZE];
if ((src_len >= INT_MAX) || (aad_len >= INT_MAX) || (p_key == NULL) || ((src_len > 0) && (p_dst == NULL)) || ((src_len > 0) && (p_src == NULL))
|| (p_in_mac == NULL) || (iv_len != SGX_AESGCM_IV_SIZE) || ((aad_len > 0) && (p_aad == NULL))
|| (p_iv == NULL) || ((p_src == NULL) && (p_aad == NULL))) {
return -1;
}
int len = 0;
int ret = -1;
EVP_CIPHER_CTX * pState = NULL;
// Autenthication Tag returned by Decrypt to be compared with Tag created during seal
//
memset(&l_tag, SGX_AESGCM_MAC_SIZE, 0);
memcpy(l_tag, p_in_mac, SGX_AESGCM_MAC_SIZE);
do {
// Create and initialise the context
//
if (!(pState = EVP_CIPHER_CTX_new())) {
break;
}
// Initialise decrypt, key and IV
//
if (!EVP_DecryptInit_ex(pState, EVP_aes_128_gcm(), NULL, (unsigned char*)p_key, p_iv)) {
break;
}
// Provide AAD data if exist
//
if (NULL != p_aad) {
if (!EVP_DecryptUpdate(pState, NULL, &len, p_aad, aad_len)) {
break;
}
}
// Decrypt message, obtain the plaintext output
//
if (!EVP_DecryptUpdate(pState, p_dst, &len, p_src, src_len)) {
break;
}
// Update expected tag value
//
if (!EVP_CIPHER_CTX_ctrl(pState, EVP_CTRL_GCM_SET_TAG, SGX_AESGCM_MAC_SIZE, l_tag)) {
break;
}
// Finalise the decryption. A positive return value indicates success,
// anything else is a failure - the plaintext is not trustworthy.
//
if (EVP_DecryptFinal_ex(pState, p_dst + len, &len) <= 0) {
break;
}
ret = 0;
} while (0);
// Clean up and return
//
if (pState != NULL) {
EVP_CIPHER_CTX_free(pState);
}
memset(&l_tag, SGX_AESGCM_MAC_SIZE, 0);
return ret;
}
\ No newline at end of file
#include <iostream>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "client.h"
#include <jsonrpccpp/client/connectors/httpclient.h>
using namespace jsonrpc;
using namespace std;
bool is_session_exits = false;
int main(int argc, char *argv[]) {
int opt;
if (argc > 1 && strlen(argv[1]) == 1) {
fprintf(stderr, "option is too short %s\n", argv[1]);
exit(1);
}
if (argc == 1) {
std::cout << "You may use following flags:" << std::endl;
std::cout << " -p print all unsigned csr hashes " << std::endl;
std::cout << " -s [hash] sign csr by hash" << std::endl;
std::cout << " -r [hash] reject csr by hash" << std::endl;
std::cout << " -a print all keys" << std::endl;
std::cout << " -l print latest created key" << std::endl;
std::cout << " -n print number of keys stored in database" << std::endl;
std::cout << " -c print server's config" << std::endl;
std::cout << " -i [name] check if key with such name presents in database" << std::endl;
exit(0);
}
while ((opt = getopt(argc, argv, "gprst")) != -1) {
switch (opt) {
case 'r': getSession();
break;
case 'g': getSession();
secureGenerateECDSAKey();
break;
case 'p': getSession();
secureGetPublicKey();
break;
case 's': getSession();
secureEcdsaSign();
break;
case 't': testDecode();
break;
default: fprintf(stderr, "unknown flag\n");
exit(1);
}
}
}
int getSession() {
int fd;
struct stat fileStat;
if(-1 == stat(session_file, &fileStat)) {
cout << "Seesion is not existed" << endl << "Doing Remote Attestation" << endl;
if(0 != doRemoteAttestation()) {
return -1;
}
return writeBackSession();
}
if(fileStat.st_size != sizeof(uint32_t) + sizeof(ra_session_t)) {
cout << "Session file is damaged" << endl << "Doing Remote Attestation" << endl;
if(0 != doRemoteAttestation()) {
return -1;
}
return writeBackSession();
}
if(-1 == (fd = open(session_file, O_RDONLY))) {
fprintf(stderr, "\nopen %s failed\n", session_file);
return -1;
}
if(sizeof(uint32_t) != read(fd, &context, sizeof(uint32_t))) {
fprintf(stderr, "\nread context failed\n");
close(fd);
return -1;
}
if(sizeof(ra_session_t) != read(fd, &session, sizeof(ra_session_t))) {
fprintf(stderr, "\nread session failed\n");
close(fd);
return -1;
}
close(fd);
return -1;
}
int writeBackSession() {
int fd;
if(-1 == (fd = open(session_file, O_WRONLY | O_CREAT, 0644))) {
fprintf(stderr, "\nopen %s failed\n", session_file);
return -1;
}
if(sizeof(uint32_t) != write(fd, &context, sizeof(uint32_t))) {
fprintf(stderr, "\nwrite context failed\n");
return -1;
}
if(sizeof(ra_session_t) != write(fd, &session, sizeof(ra_session_t))) {
fprintf(stderr, "\nwrite session failed\n");
return -1;
}
close(fd);
return 0;
}
int encryptData(const string& plain, string& cipher) {
ra_msg_t* secret;
uint32_t secret_size = sizeof(ra_msg_t) + plain.size();
secret = (ra_msg_t*)malloc(secret_size);
int ret = aes_gcm_encrypt(&session.sk_key,
(const uint8_t*)plain.data(),
plain.size(),
secret->payload,
secret->payload_iv,
12,
NULL,
0,
(sgx_aes_gcm_128bit_key_t*)
secret->payload_mac);
secret->payload_size = plain.size();
if(ret != 0) {
return ret;
}
vector<char> secret_hex = carray2Hex((const uint8_t*)secret, secret_size);
cipher = string(secret_hex.data(), secret_hex.size());
return 0;
}
int decryptData(const string& cipher, string& plain) {
ra_msg_t* secret;
uint64_t secret_size;
secret = (ra_msg_t*)malloc(cipher.size() / 2);
if(!hex2carray(cipher.c_str(), &secret_size, (uint8_t*)secret, cipher.size())) {
fprintf(stderr, "Error, can't covert hex to carray in [%s].\n", __FUNCTION__);
return -1;
}
// secret->payload_size = (uint32_t)secret_size;
uint8_t *decrypted = (uint8_t*) malloc(secret_size);
int ret = aes_gcm_decrypt(&session.sk_key,
(const uint8_t*)secret->payload,
secret->payload_size,
decrypted,
secret->payload_iv,
12,
NULL,
0,
(sgx_aes_gcm_128bit_key_t*)
secret->payload_mac);
plain = string((char*)decrypted, secret_size);
return ret;
}
int secureGenerateECDSAKey() {
HttpClient client("http://localhost:1029");
StubClient c(client, JSONRPC_CLIENT_V2);
Json::Value result;
string password;
string passwordSecret;
string encryptedKey, publicKey, keyName;
cout << "Please Enter Your Password: ";
cin >> password;
cout << password << " " << password.size() << endl;
if(0 != encryptData(password, passwordSecret)) {
fprintf(stderr, "encrypt password failed [%s]\n", __FUNCTION__);
return -1;
}
result = c.generateECDSAKeyWithPassword(context, passwordSecret);
if(0 != result["status"].asInt()) {
printf("%s errorCode:0x%x 0x%x\n",
result["errorMessage"].asString().c_str(),
result["errorCode"].asInt(), result["errorRACode"].asInt());
return -1;
}
// if(decryptData(result["encryptedKey"].asString(), encryptedKey) || decryptData(result["publicKey"].asString(), publicKey)) {
// fprintf(stderr, "decrypt result failed [%s]\n", __FUNCTION__);
// return -1;
// };
// keyName = result["keyName"].asString();
cout << result["encryptedKey"].asString() << endl;
cout << result["publicKey"].asString() << endl;
cout << result["keyName"].asString() << endl;
return 0;
}
int secureGetPublicKey() {
HttpClient client("http://localhost:1029");
StubClient c(client, JSONRPC_CLIENT_V2);
Json::Value result;
string password, keyName;
string passwordSecret;
cout << "Please Enter Your Password: ";
cin >> password;
cout << "Please Enter Private Key Name: ";
cin >> keyName;
if(0 != encryptData(password, passwordSecret)) {
fprintf(stderr, "encrypt password failed [%s]\n", __FUNCTION__);
return -1;
}
result = c.getPublicECDSAKeyWithPassword(context, passwordSecret, keyName);
if(0 != result["status"].asInt()) {
printf("%s errorCode:0x%x 0x%x\n",
result["errorMessage"].asString().c_str(),
result["errorCode"].asInt(), result["errorRACode"].asInt());
return -1;
}
cout << result["publicKey"].asString() << endl;
return 0;
}
int secureEcdsaSign() {
HttpClient client("http://localhost:1029");
StubClient c(client, JSONRPC_CLIENT_V2);
Json::Value result;
string password, keyName;
string passwordSecret;
string messageHash;
cout << "Please Enter Your Password: ";
cin >> password;
cout << "Please Enter Private Key Name: ";
cin >> keyName;
cout << "Please Enter Message: ";
cin >> messageHash;
if(0 != encryptData(password, passwordSecret)) {
fprintf(stderr, "encrypt password failed [%s]\n", __FUNCTION__);
return -1;
}
result = c.ecdsaSignMessageHashWithPassword(context, 16, passwordSecret, keyName, messageHash);
if(0 != result["status"].asInt()) {
printf("%s errorCode:0x%x 0x%x\n",
result["errorMessage"].asString().c_str(),
result["errorCode"].asInt(), result["errorRACode"].asInt());
return -1;
}
cout << result << endl;
return 0;
}
int testDecode() {
string password, password_secret, password_decrypt;
cout << "Please Enter Your Password: ";
cin >> password;
cout << password << " " << password.size() << endl;
if(0 != encryptData(password, password_secret)) {
fprintf(stderr, "encrypt password failed [%s]\n", __FUNCTION__);
return -1;
}
if(0 != decryptData(password_secret, password_decrypt)) {
fprintf(stderr, "decrypt password failed [%s]\n", __FUNCTION__);
return -1;
}
cout << password << " " << password_decrypt << endl;
return 0;
}
\ No newline at end of file
#ifndef _CLIENT_H_
#define _CLIENT_H_
#include "common.h"
#include "crypto.h"
#include "CryptoTools.h"
#include "stubclient.h"
#include "remoteAttestation.h"
int getSession();
int writeBackSession();
int secureGenerateECDSAKey();
int secureGetPublicKey();
int secureEcdsaSign();
int testDecode();
const char session_file[] = "./session.dat";
#endif
\ No newline at end of file
#include <openssl/cmac.h>
#include "crypto.h"
int cmac128(
const sgx_cmac_128bit_key_t *p_key,
const uint8_t *p_src,
uint32_t src_len,
sgx_cmac_128bit_tag_t *p_mac
) {
void* pState = NULL;
if ((p_key == NULL) || (p_src == NULL) || (p_mac == NULL)) {
return -1;
}
size_t mactlen;
int ret = -1;
do {
//create a new ctx of CMAC
//
pState = CMAC_CTX_new();
if (pState == NULL) {
break;
}
// init CMAC ctx with the corresponding size, key and AES alg.
//
if (!CMAC_Init((CMAC_CTX*)pState, (const void *)p_key, SGX_CMAC_KEY_SIZE, EVP_aes_128_cbc(), NULL)) {
break;
}
// perform CMAC hash on p_src
//
if (!CMAC_Update((CMAC_CTX *)pState, p_src, src_len)) {
break;
}
// finalize CMAC hashing
//
if (!CMAC_Final((CMAC_CTX*)pState, (unsigned char*)p_mac, &mactlen)) {
break;
}
//validate mac size
//
if (mactlen != SGX_CMAC_MAC_SIZE) {
break;
}
ret = 0;
} while (0);
// we're done, clear and free CMAC ctx
//
if (pState) {
CMAC_CTX_free((CMAC_CTX*)pState);
}
return ret;
}
\ No newline at end of file
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Enable debugging */
#define DEBUG 1
/* Flag set for prerelease builds */
/* #undef EDEBUG */
/* Flag set for prerelease and release builds */
/* #undef NDEBUG */
/* Name of package */
#define PACKAGE "sgx-gmp-test"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "john.p.mechalas@intel.com"
/* Define to the full name of this package. */
#define PACKAGE_NAME "SGX GMP Test"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "SGX GMP Test 1.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "sgx-gmp-test"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.0"
/* Enable hardware simulation mode */
/* #undef SGX_HW_SIM */
/* Version number of package */
#define VERSION "1.0"
/* config.h.in. Generated from configure.ac by autoheader. */
/* Enable debugging */
#undef DEBUG
/* Flag set for prerelease builds */
#undef EDEBUG
/* Flag set for prerelease and release builds */
#undef NDEBUG
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Enable hardware simulation mode */
#undef SGX_HW_SIM
/* Version number of package */
#undef VERSION
......@@ -2,7 +2,8 @@
AC_INIT([SGX GMP Test], 1.0, [john.p.mechalas@intel.com])
AC_CONFIG_MACRO_DIRS([m4])
AM_INIT_AUTOMAKE([foreign])
AM_INIT_AUTOMAKE([foreign subdir-objects])
AC_CONFIG_HEADERS([config.h])
AC_PROG_CC
AC_PROG_CXX
......
#ifndef _ECC256_H_
#define _ECC256_H_
#include "sgx_tcrypto.h"
typedef void* ecc_state_handle_t;
typedef void* sha_state_handle_t;
#ifdef __cplusplus
extern "C" {
#endif
int ecc256_open_context(ecc_state_handle_t* p_ecc_handle);
void ecc256_close_context(ecc_state_handle_t ecc_handle);
int ecc256_create_key_pair(sgx_ec256_private_t *p_private, sgx_ec256_public_t *p_public, ecc_state_handle_t ecc_handle);
int ecc256_compute_shared_dhkey(const sgx_ec256_private_t *p_private_b, const sgx_ec256_public_t *p_public_ga, sgx_ec256_dh_shared_t *p_shared_key, ecc_state_handle_t ecc_handle);
int cmac128(const sgx_cmac_128bit_key_t *p_key, const uint8_t *p_src, uint32_t src_len, sgx_cmac_128bit_tag_t *p_mac);
int sha256_digest(const uint8_t *p_src, uint32_t src_len, sgx_sha256_hash_t *p_hash);
int sha256_init(sha_state_handle_t* p_sha_handle);
int sha256_update(const uint8_t *p_src, uint32_t src_len, sha_state_handle_t sha_handle);
int sha256_finish(sha_state_handle_t sha_handle, sgx_sha256_hash_t *p_hash);
void sha256_close(sha_state_handle_t sha_handle);
int aes_gcm_encrypt(const sgx_aes_gcm_128bit_key_t *p_key, const uint8_t *p_src, uint32_t src_len,
uint8_t *p_dst, const uint8_t *p_iv, uint32_t iv_len, const uint8_t *p_aad, uint32_t aad_len,
sgx_aes_gcm_128bit_tag_t *p_out_mac);
int aes_gcm_decrypt(const sgx_aes_gcm_128bit_key_t *p_key, const uint8_t *p_src, uint32_t src_len,
uint8_t *p_dst, const uint8_t *p_iv, uint32_t iv_len, const uint8_t *p_aad, uint32_t aad_len,
const sgx_aes_gcm_128bit_tag_t *p_in_mac);
int ecdsa_sign(const uint8_t *p_data,
uint32_t data_size,
const sgx_ec256_private_t *p_private,
sgx_ec256_signature_t *p_signature,
ecc_state_handle_t ecc_handle);
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
#include <string.h>
#include <openssl/evp.h>
#include "crypto.h"
using namespace std;
int aes_gcm_encrypt(const sgx_aes_gcm_128bit_key_t *p_key, const uint8_t *p_src, uint32_t src_len,
uint8_t *p_dst, const uint8_t *p_iv, uint32_t iv_len, const uint8_t *p_aad, uint32_t aad_len,
sgx_aes_gcm_128bit_tag_t *p_out_mac) {
if ((src_len >= INT_MAX) || (aad_len >= INT_MAX) || (p_key == NULL) || ((src_len > 0) && (p_dst == NULL)) || ((src_len > 0) && (p_src == NULL))
|| (p_out_mac == NULL) || (iv_len != SGX_AESGCM_IV_SIZE) || ((aad_len > 0) && (p_aad == NULL))
|| (p_iv == NULL) || ((p_src == NULL) && (p_aad == NULL)))
{
return -1;
}
int ret = -1;
int len = 0;
EVP_CIPHER_CTX * pState = NULL;
do {
// Create and init ctx
//
if (!(pState = EVP_CIPHER_CTX_new())) {
break;
}
// Initialise encrypt, key and IV
//
if (1 != EVP_EncryptInit_ex(pState, EVP_aes_128_gcm(), NULL, (unsigned char*)p_key, p_iv)) {
break;
}
// Provide AAD data if exist
//
if (NULL != p_aad) {
if (1 != EVP_EncryptUpdate(pState, NULL, &len, p_aad, aad_len)) {
break;
}
}
if (src_len > 0) {
// Provide the message to be encrypted, and obtain the encrypted output.
//
if (1 != EVP_EncryptUpdate(pState, p_dst, &len, p_src, src_len)) {
break;
}
}
// Finalise the encryption
//
if (1 != EVP_EncryptFinal_ex(pState, p_dst + len, &len)) {
break;
}
// Get tag
//
if (1 != EVP_CIPHER_CTX_ctrl(pState, EVP_CTRL_GCM_GET_TAG, SGX_AESGCM_MAC_SIZE, p_out_mac)) {
break;
}
ret = 0;
} while (0);
// Clean up and return
//
if (pState) {
EVP_CIPHER_CTX_free(pState);
}
return ret;
}
int aes_gcm_decrypt(const sgx_aes_gcm_128bit_key_t *p_key, const uint8_t *p_src, uint32_t src_len,
uint8_t *p_dst, const uint8_t *p_iv, uint32_t iv_len, const uint8_t *p_aad, uint32_t aad_len,
const sgx_aes_gcm_128bit_tag_t *p_in_mac) {
uint8_t l_tag[SGX_AESGCM_MAC_SIZE];
if ((src_len >= INT_MAX) || (aad_len >= INT_MAX) || (p_key == NULL) || ((src_len > 0) && (p_dst == NULL)) || ((src_len > 0) && (p_src == NULL))
|| (p_in_mac == NULL) || (iv_len != SGX_AESGCM_IV_SIZE) || ((aad_len > 0) && (p_aad == NULL))
|| (p_iv == NULL) || ((p_src == NULL) && (p_aad == NULL))) {
return -1;
}
int len = 0;
int ret = -1;
EVP_CIPHER_CTX * pState = NULL;
// Autenthication Tag returned by Decrypt to be compared with Tag created during seal
//
memset(&l_tag, SGX_AESGCM_MAC_SIZE, 0);
memcpy(l_tag, p_in_mac, SGX_AESGCM_MAC_SIZE);
do {
// Create and initialise the context
//
if (!(pState = EVP_CIPHER_CTX_new())) {
break;
}
// Initialise decrypt, key and IV
//
if (!EVP_DecryptInit_ex(pState, EVP_aes_128_gcm(), NULL, (unsigned char*)p_key, p_iv)) {
break;
}
// Provide AAD data if exist
//
if (NULL != p_aad) {
if (!EVP_DecryptUpdate(pState, NULL, &len, p_aad, aad_len)) {
break;
}
}
// Decrypt message, obtain the plaintext output
//
if (!EVP_DecryptUpdate(pState, p_dst, &len, p_src, src_len)) {
break;
}
// Update expected tag value
//
if (!EVP_CIPHER_CTX_ctrl(pState, EVP_CTRL_GCM_SET_TAG, SGX_AESGCM_MAC_SIZE, l_tag)) {
break;
}
// Finalise the decryption. A positive return value indicates success,
// anything else is a failure - the plaintext is not trustworthy.
//
if (EVP_DecryptFinal_ex(pState, p_dst + len, &len) <= 0) {
break;
}
ret = 0;
} while (0);
// Clean up and return
//
if (pState != NULL) {
EVP_CIPHER_CTX_free(pState);
}
memset(&l_tag, SGX_AESGCM_MAC_SIZE, 0);
return ret;
}
\ No newline at end of file
#include <openssl/cmac.h>
#include "crypto.h"
int cmac128(
const sgx_cmac_128bit_key_t *p_key,
const uint8_t *p_src,
uint32_t src_len,
sgx_cmac_128bit_tag_t *p_mac
) {
void* pState = NULL;
if ((p_key == NULL) || (p_src == NULL) || (p_mac == NULL)) {
return -1;
}
size_t mactlen;
int ret = -1;
do {
//create a new ctx of CMAC
//
pState = CMAC_CTX_new();
if (pState == NULL) {
break;
}
// init CMAC ctx with the corresponding size, key and AES alg.
//
if (!CMAC_Init((CMAC_CTX*)pState, (const void *)p_key, SGX_CMAC_KEY_SIZE, EVP_aes_128_cbc(), NULL)) {
break;
}
// perform CMAC hash on p_src
//
if (!CMAC_Update((CMAC_CTX *)pState, p_src, src_len)) {
break;
}
// finalize CMAC hashing
//
if (!CMAC_Final((CMAC_CTX*)pState, (unsigned char*)p_mac, &mactlen)) {
break;
}
//validate mac size
//
if (mactlen != SGX_CMAC_MAC_SIZE) {
break;
}
ret = 0;
} while (0);
// we're done, clear and free CMAC ctx
//
if (pState) {
CMAC_CTX_free((CMAC_CTX*)pState);
}
return ret;
}
\ No newline at end of file
#ifndef _ECC256_H_
#define _ECC256_H_
#include "sgx_tcrypto.h"
typedef void* ecc_state_handle_t;
typedef void* sha_state_handle_t;
#ifdef __cplusplus
extern "C" {
#endif
int ecc256_open_context(ecc_state_handle_t* p_ecc_handle);
void ecc256_close_context(ecc_state_handle_t ecc_handle);
int ecc256_create_key_pair(sgx_ec256_private_t *p_private, sgx_ec256_public_t *p_public, ecc_state_handle_t ecc_handle);
int ecc256_compute_shared_dhkey(const sgx_ec256_private_t *p_private_b, const sgx_ec256_public_t *p_public_ga, sgx_ec256_dh_shared_t *p_shared_key, ecc_state_handle_t ecc_handle);
int cmac128(const sgx_cmac_128bit_key_t *p_key, const uint8_t *p_src, uint32_t src_len, sgx_cmac_128bit_tag_t *p_mac);
int sha256_digest(const uint8_t *p_src, uint32_t src_len, sgx_sha256_hash_t *p_hash);
int sha256_init(sha_state_handle_t* p_sha_handle);
int sha256_update(const uint8_t *p_src, uint32_t src_len, sha_state_handle_t sha_handle);
int sha256_finish(sha_state_handle_t sha_handle, sgx_sha256_hash_t *p_hash);
void sha256_close(sha_state_handle_t sha_handle);
int aes_gcm_encrypt(const sgx_aes_gcm_128bit_key_t *p_key, const uint8_t *p_src, uint32_t src_len,
uint8_t *p_dst, const uint8_t *p_iv, uint32_t iv_len, const uint8_t *p_aad, uint32_t aad_len,
sgx_aes_gcm_128bit_tag_t *p_out_mac);
int aes_gcm_decrypt(const sgx_aes_gcm_128bit_key_t *p_key, const uint8_t *p_src, uint32_t src_len,
uint8_t *p_dst, const uint8_t *p_iv, uint32_t iv_len, const uint8_t *p_aad, uint32_t aad_len,
const sgx_aes_gcm_128bit_tag_t *p_in_mac);
int ecdsa_sign(const uint8_t *p_data,
uint32_t data_size,
const sgx_ec256_private_t *p_private,
sgx_ec256_signature_t *p_signature,
ecc_state_handle_t ecc_handle);
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
This diff is collapsed.
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <stdlib.h>
#include "crypto.h"
int sha256_digest(const uint8_t *p_src, uint32_t src_len, sgx_sha256_hash_t *p_hash) {
if ((p_src == NULL) || (p_hash == NULL)) {
return -1;
}
if (SHA256((const unsigned char *)p_src, src_len, (unsigned char *)p_hash) == NULL) {
return -1;
}
return 0;
}
int sha256_init(sha_state_handle_t* p_sha_handle) {
if (p_sha_handle == NULL) {
return -1;
}
EVP_MD_CTX* evp_ctx = NULL;
const EVP_MD* sha256_md = NULL;
sgx_status_t retval = SGX_ERROR_UNEXPECTED;
do {
/* allocates, initializes and returns a digest context */
evp_ctx = EVP_MD_CTX_new();
if (evp_ctx == NULL) {
break;
}
/* return EVP_MD structures for SHA256 digest algorithm */
sha256_md = EVP_sha256();
if (sha256_md == NULL) {
break;
}
/* sets up digest context ctx to use a digest type, if impl is NULL then the default implementation of digest type is used */
if (EVP_DigestInit_ex(evp_ctx, sha256_md, NULL) != 1) {
break;
}
*p_sha_handle = evp_ctx;
retval = SGX_SUCCESS;
} while(0);
if (SGX_SUCCESS != retval) {
if (evp_ctx != NULL) {
EVP_MD_CTX_free(evp_ctx);
}
}
return retval;
}
int sha256_update(const uint8_t *p_src, uint32_t src_len, sha_state_handle_t sha_handle) {
if ((p_src == NULL) || (sha_handle == NULL)) {
return -1;
}
if(EVP_DigestUpdate((EVP_MD_CTX*)sha_handle, p_src, src_len) != 1) {
return -1;
}
return 0;
}
int sha256_finish(sha_state_handle_t sha_handle, sgx_sha256_hash_t *p_hash) {
unsigned int hash_len;
if ((sha_handle == NULL) || (p_hash == NULL)) {
return -1;
}
if (EVP_DigestFinal_ex((EVP_MD_CTX*)sha_handle, (unsigned char *)p_hash, &hash_len) != 1) {
return -1;
}
if (SGX_SHA256_HASH_SIZE != hash_len) {
return -1;
}
return 0;
}
void sha256_close(sha_state_handle_t sha_handle) {
if (sha_handle) {
EVP_MD_CTX_free((EVP_MD_CTX*)sha_handle);
}
}
\ No newline at end of file
This diff is collapsed.
libjson-rpc-cpp @ 840f46d2
Subproject commit 840f46d225d8b1337d43317ce77e221f39fd3421
libmicrohttpd @ 41a27cad
Subproject commit 41a27cad4b697141cb4cedae5cecbfdb4c229213
#include <stdlib.h>
#include <string.h>
#include "ra_ecp.h"
#include "crypto/crypto.h"
#define MAC_KEY_SIZE 16
errno_t memcpy_s(
void *dest,
size_t numberOfElements,
const void *src,
size_t count) {
if(numberOfElements<count)
return -1;
memcpy(dest, src, count);
return 0;
}
bool verify_cmac128(
sgx_ec_key_128bit_t mac_key,
const uint8_t *p_data_buf,
uint32_t buf_size,
const uint8_t *p_mac_buf) {
sgx_cmac_128bit_tag_t data_mac;
if(cmac128((sgx_cmac_128bit_key_t *)&mac_key, p_data_buf, buf_size, &data_mac))
return false;
// In real implementation, should use a time safe version of memcmp here,
// in order to avoid side channel attack.
if(memcmp(p_mac_buf, data_mac, SGX_CMAC_MAC_SIZE))
return false;
return true;
}
#define EC_DERIVATION_BUFFER_SIZE(label_length) ((label_length) +4)
const char str_SMK[] = "SMK";
const char str_SK[] = "SK";
const char str_MK[] = "MK";
const char str_VK[] = "VK";
// Derive key from shared key and key id.
// key id should be sample_derive_key_type_t.
bool derive_key(
const sgx_ec256_dh_shared_t *p_shared_key,
uint8_t key_id,
sgx_ec_key_128bit_t* derived_key
) {
int ret = 0;
uint8_t cmac_key[MAC_KEY_SIZE];
sgx_ec_key_128bit_t key_derive_key;
memset(&cmac_key, 0, MAC_KEY_SIZE);
ret = cmac128(
(const sgx_cmac_128bit_key_t *)&cmac_key,
(const uint8_t*)p_shared_key,
sizeof(sgx_ec256_dh_shared_t),
(sgx_cmac_128bit_tag_t *)&key_derive_key);
if (ret) {
// memset here can be optimized away by compiler, so please use memset_s on
// windows for production code and similar functions on other OSes.
memset(&key_derive_key, 0, sizeof(key_derive_key));
return false;
}
const char *label = NULL;
uint32_t label_length = 0;
switch (key_id) {
case DERIVE_KEY_SMK:
label = str_SMK;
label_length = sizeof(str_SMK) -1;
break;
case DERIVE_KEY_SK:
label = str_SK;
label_length = sizeof(str_SK) -1;
break;
case DERIVE_KEY_MK:
label = str_MK;
label_length = sizeof(str_MK) -1;
break;
case DERIVE_KEY_VK:
label = str_VK;
label_length = sizeof(str_VK) -1;
break;
default:
// memset here can be optimized away by compiler, so please use memset_s on
// windows for production code and similar functions on other OSes.
memset(&key_derive_key, 0, sizeof(key_derive_key));
return false;
break;
}
/* derivation_buffer = counter(0x01) || label || 0x00 || output_key_len(0x0080) */
uint32_t derivation_buffer_length = EC_DERIVATION_BUFFER_SIZE(label_length);
uint8_t *p_derivation_buffer = (uint8_t *)malloc(derivation_buffer_length);
if (p_derivation_buffer == NULL) {
// memset here can be optimized away by compiler, so please use memset_s on
// windows for production code and similar functions on other OSes.
memset(&key_derive_key, 0, sizeof(key_derive_key));
return false;
}
memset(p_derivation_buffer, 0, derivation_buffer_length);
/*counter = 0x01 */
p_derivation_buffer[0] = 0x01;
/*label*/
memcpy_s(&p_derivation_buffer[1], derivation_buffer_length - 1, label, label_length);
/*output_key_len=0x0080*/
uint16_t *key_len = (uint16_t *)(&(p_derivation_buffer[derivation_buffer_length - 2]));
*key_len = 0x0080;
ret = cmac128(
(sgx_cmac_128bit_key_t *)&key_derive_key,
p_derivation_buffer,
derivation_buffer_length,
(sgx_cmac_128bit_tag_t *)derived_key);
free(p_derivation_buffer);
// memset here can be optimized away by compiler, so please use memset_s on
// windows for production code and similar functions on other OSes.
memset(&key_derive_key, 0, sizeof(key_derive_key));
if (ret) {
return false;
}
return true;
}
\ No newline at end of file
#ifndef _ECP_H
#define _ECP_H
#include <stdint.h>
#include <stdlib.h>
#include "sgx_ecp_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ERRNO_T_DEFINED
#define _ERRNO_T_DEFINED
typedef int errno_t;
#endif
errno_t memcpy_s(void *dest, size_t numberOfElements, const void *src,
size_t count);
typedef enum _derive_key_type_t {
DERIVE_KEY_SMK = 0,
DERIVE_KEY_SK,
DERIVE_KEY_MK,
DERIVE_KEY_VK,
} derive_key_type_t;
bool derive_key(
const sgx_ec256_dh_shared_t *p_shared_key,
uint8_t key_id,
sgx_ec_key_128bit_t *derived_key);
bool verify_cmac128(
sgx_ec_key_128bit_t mac_key,
const uint8_t *p_data_buf,
uint32_t buf_size,
const uint8_t *p_mac_buf);
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
#include <stdio.h>
#include "ra_ias.h"
int enroll(int sp_credentials, sgx_spid_t* spid,
int* authentication_token) {
// TODO();
return 0;
}
int getSigrl(const sgx_epid_group_id_t gid, uint32_t* p_sig_rl_size,
uint8_t** p_sig_rl) {
// TODO() Access IAS API:
// GET https://api.trustedservices.intel.com/sgx/attestation/v4/sigrl/00000010
*p_sig_rl_size = 0;
*p_sig_rl = NULL;
return 0;
}
int verifyAttestation(const sgx_quote_t* p_isv_quote,
uint8_t* pse_manifest,
ias_att_report_t* attestation_verification_report) {
// TODO() Access IAS API:
// POST https://api.trustedservices.intel.com/sgx/attestation/v4/report with quote
attestation_verification_report->id = 0;
attestation_verification_report->status = IAS_QUOTE_OK;
attestation_verification_report->pse_status = IAS_PSE_OK;
attestation_verification_report->revoke_reason = IAS_REVOC_REASON_NONE;
return 0;
}
\ No newline at end of file
#ifndef _RA_IAS_H
#define _RA_IAS_H
#include "sgx_quote.h"
typedef enum {
IAS_QUOTE_OK,
IAS_QUOTE_SIGNATURE_INVALID,
IAS_QUOTE_GROUP_REVOKED,
IAS_QUOTE_SIGNATURE_REVOKED,
IAS_QUOTE_KEY_REVOKED,
IAS_QUOTE_SIGRL_VERSION_MISMATCH,
IAS_QUOTE_GROUP_OUT_OF_DATE,
} ias_quote_status_t;
// These status should align with the definition in IAS API spec(rev 0.6)
typedef enum {
IAS_PSE_OK,
IAS_PSE_DESC_TYPE_NOT_SUPPORTED,
IAS_PSE_ISVSVN_OUT_OF_DATE,
IAS_PSE_MISCSELECT_INVALID,
IAS_PSE_ATTRIBUTES_INVALID,
IAS_PSE_MRSIGNER_INVALID,
IAS_PS_HW_GID_REVOKED,
IAS_PS_HW_PRIVKEY_RLVER_MISMATCH,
IAS_PS_HW_SIG_RLVER_MISMATCH,
IAS_PS_HW_CA_ID_INVALID,
IAS_PS_HW_SEC_INFO_INVALID,
IAS_PS_HW_PSDA_SVN_OUT_OF_DATE,
} ias_pse_status_t;
// Revocation Reasons from RFC5280
typedef enum {
IAS_REVOC_REASON_NONE,
IAS_REVOC_REASON_KEY_COMPROMISE,
IAS_REVOC_REASON_CA_COMPROMISED,
IAS_REVOC_REASON_SUPERCEDED,
IAS_REVOC_REASON_CESSATION_OF_OPERATION,
IAS_REVOC_REASON_CERTIFICATE_HOLD,
IAS_REVOC_REASON_PRIVILEGE_WITHDRAWN,
IAS_REVOC_REASON_AA_COMPROMISE,
} ias_revoc_reason_t;
typedef struct ias_att_report_t {
uint32_t id;
ias_quote_status_t status;
ias_pse_status_t pse_status;
uint32_t revoke_reason;
} ias_att_report_t;
#ifdef __cplusplus
extern "C" {
#endif
int enroll(int sp_credentials, sgx_spid_t* spid,
int* authentication_token);
int getSigrl(const sgx_epid_group_id_t gid, uint32_t* p_sig_rl_size,
uint8_t** p_sig_rl);
int verifyAttestation(const sgx_quote_t* p_isv_quote,
uint8_t* pse_manifest,
ias_att_report_t* attestation_verification_report);
#ifdef __cplusplus
}
#endif
#endif
#ifndef _RA_RESULT_H_
#define _RA_RESULT_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define IV_SIZE 12
#define MAC_SIZE 16 /* Message Authentication Code*/
/* - 16 bytes*/
#pragma pack(push,1)
typedef struct ra_msg_t {
uint32_t payload_size; /* 0: Size of the payload which is*/
/* encrypted*/
uint8_t payload_iv[IV_SIZE]; /* 4: Reserved bits*/
uint8_t payload_mac[MAC_SIZE]; /* 16: CMAC(SK) of the plain text*/
uint8_t payload[]; /* 32: Ciphertext of the payload*/
/* followed by the plain text*/
} ra_msg_t;
#pragma pack(pop)
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
This diff is collapsed.
#ifndef _REMOTE_ATTESTATION_H_
#define _REMOTE_ATTESTATION_H_
#include "crypto.h"
#include "ra_result.h"
#include "ra_ecp.h"
#include "ra_ias.h"
#include "sgx_tcrypto.h"
#include "sgx_ukey_exchange.h"
// This is a context data structure used on SP side
typedef struct _ra_session_t {
sgx_ec256_public_t g_a;
sgx_ec256_public_t g_b;
sgx_ec_key_128bit_t vk_key;// Shared secret key for the REPORT_DATA
sgx_ec_key_128bit_t mk_key;// Shared secret key for generating MAC's
sgx_ec_key_128bit_t sk_key;// Shared secret key for encryption
sgx_ec_key_128bit_t smk_key;// Used only for SIGMA protocol
sgx_ec256_private_t b;
// sgx_ps_sec_prop_desc_t ps_sec_prop;
}ra_session_t;
static const sgx_ec256_private_t g_sp_priv_key = {
{
0x90, 0xe7, 0x6c, 0xbb, 0x2d, 0x52, 0xa1, 0xce,
0x3b, 0x66, 0xde, 0x11, 0x43, 0x9c, 0x87, 0xec,
0x1f, 0x86, 0x6a, 0x3b, 0x65, 0xb6, 0xae, 0xea,
0xad, 0x57, 0x34, 0x53, 0xd1, 0x03, 0x8c, 0x01
}
};
// This is the public EC key of SP, this key is hard coded in isv_enclave.
// It is based on NIST P-256 curve. Not used in the SP code.
static const sgx_ec256_public_t g_sp_pub_key = {
{
0x72, 0x12, 0x8a, 0x7a, 0x17, 0x52, 0x6e, 0xbf,
0x85, 0xd0, 0x3a, 0x62, 0x37, 0x30, 0xae, 0xad,
0x3e, 0x3d, 0xaa, 0xee, 0x9c, 0x60, 0x73, 0x1d,
0xb0, 0x5b, 0xe8, 0x62, 0x1c, 0x4b, 0xeb, 0x38
},
{
0xd4, 0x81, 0x40, 0xd9, 0x50, 0xe2, 0x57, 0x7b,
0x26, 0xee, 0xb7, 0x41, 0xe7, 0xc6, 0x14, 0xe2,
0x24, 0xb7, 0xbd, 0xc9, 0x03, 0xf2, 0x9a, 0x28,
0xa8, 0x3c, 0xc8, 0x10, 0x11, 0x14, 0x5e, 0x06
}
};
/*Key Derivation Function ID : 0x0001 AES-CMAC Entropy Extraction and Key Expansion*/
const uint16_t CMAC_KDF_ID = 0x0001;
#define QUOTE_UNLINKABLE_SIGNATURE 0
#define QUOTE_LINKABLE_SIGNATURE 1
int doRemoteAttestation();
int handleMSG0(uint32_t extended_epid_group_id);
int handleMSG1(sgx_ra_msg1_t* msg1, uint32_t msg1_size, sgx_ra_msg2_t** msg2, uint32_t* msg2_size);
int handleMSG3(sgx_ra_msg3_t* msg3, uint32_t msg3_size, ra_msg_t** msg3_resp, uint32_t* msg3_resp_size);
int checkMSG3Basic(sgx_ra_msg3_t* msg3, uint32_t msg3_size);
int caculateSecret(uint8_t* secret, uint32_t secret_size, ra_msg_t** result_msg, uint32_t* result_msg_size);
int caculateDHKey(ecc_state_handle_t* ecc_state, ra_session_t* session, sgx_ra_msg1_t* msg1);
int checkEnclaveIdendty(const sgx_report_body_t& report_data);
extern uint32_t context;
extern ra_session_t session;
#endif
......@@ -33,7 +33,7 @@ print("Top directory is:" + topDir)
makeExecutable = subprocess.check_output(["which", "make"])
SCRIPTS_DIR = topDir + "/scripts"
GMP_DIR = topDir + "/sgx-gmp"
SGX_SDK_DIR_SSL = topDir + "/sgx-sdk-build/sgxsdk"
SGX_SDK_DIR_SSL = "/opt/intel/sgxsdk"
ZMQ_DIR = topDir + "/libzmq"
ZMQ_BUILD_DIR = ZMQ_DIR + "/build"
......@@ -41,7 +41,7 @@ LEVELDB_DIR = topDir + "/leveldb"
LEVELDB_BUILD_DIR = LEVELDB_DIR + "/build"
GMP_BUILD_DIR = topDir + "/gmp-build"
TGMP_BUILD_DIR = topDir + "/tgmp-build"
SDK_DIR = topDir + "/sgx-sdk-build"
SDK_DIR = "/opt/intel"
JSON_LIBS_DIR = topDir + "/jsonrpc"
......@@ -56,11 +56,10 @@ subprocess.call(["rm", "-f", "missing"])
subprocess.call(["rm", "-f", "depcomp"])
subprocess.call(["rm", "-rf", GMP_BUILD_DIR])
subprocess.call(["rm", "-rf", TGMP_BUILD_DIR])
subprocess.call(["rm", "-rf", SDK_DIR])
subprocess.call(["rm", "-rf", GMP_BUILD_DIR])
subprocess.call(["rm", "-rf", TGMP_BUILD_DIR])
subprocess.call(["rm", "-rf", SDK_DIR])
# subprocess.call(["rm", "-rf", SDK_DIR])
assert subprocess.call(["cp", "configure.gmp", GMP_DIR + "/configure"]) == 0
......@@ -88,13 +87,13 @@ assert subprocess.call(["bash", "-c", "cmake -DCMAKE_BUILD_TYPE=Release .. && cm
print("Build JSON");
os.chdir(JSON_LIBS_DIR)
assert subprocess.call(["bash", "-c", "./build.sh"]) == 0
# os.chdir(JSON_LIBS_DIR)
# assert subprocess.call(["bash", "-c", "./build.sh"]) == 0
print("Install Linux SDK");
# print("Install Linux SDK");
os.chdir(SCRIPTS_DIR)
assert subprocess.call(["bash", "-c", "./sgx_linux_x64_sdk_2.13.100.4.bin --prefix=" + topDir + "/sgx-sdk-build"]) == 0
# os.chdir(SCRIPTS_DIR)
# assert subprocess.call(["bash", "-c", "./sgx_linux_x64_sdk_2.13.100.4.bin --prefix=" + topDir + "/sgx-sdk-build"]) == 0
print("Make GMP");
......
......@@ -32,6 +32,11 @@ sgx_aes_gcm_128bit_key_t AES_key[1024];
#define SAFE_CHAR_BUF(__X__, __Y__) ;char __X__ [ __Y__ ]; memset(__X__, 0, __Y__);
#define CHECK_STATE(_EXPRESSION_) \
if (!(_EXPRESSION_)) { \
LOG_ERROR("State check failed::");LOG_ERROR(#_EXPRESSION_); \
return -10;}
int AES_encrypt(char *message, uint8_t *encr_message, uint64_t encrBufLen, unsigned char type,
unsigned char exportable, uint64_t* resultLen) {
if (!type) {
......@@ -84,6 +89,69 @@ int AES_encrypt(char *message, uint8_t *encr_message, uint64_t encrBufLen, unsig
return status;
}
int AES_encrypt_with_password(const char *password, char *message, uint8_t *encr_message, uint64_t encrBufLen, unsigned char type,
unsigned char exportable, uint64_t* resultLen) {
if (!type) {
LOG_ERROR("Null type in AES_encrypt");
return -1;
}
if (!message) {
LOG_ERROR("Null message in AES_encrypt");
return -1;
}
if (!encr_message) {
LOG_ERROR("Null encr message in AES_encrypt");
return -2;
}
if (!resultLen) {
LOG_ERROR("Null resultLen in AES_encrypt");
return -3;
}
uint64_t len = strlen(message) + 1;
if (2 + len + SGX_AESGCM_MAC_SIZE + SGX_AESGCM_IV_SIZE > encrBufLen ) {
LOG_ERROR("Output buffer too small");
return -4;
}
SAFE_CHAR_BUF(fullMessage, len + 2);
fullMessage[0] = type;
fullMessage[1] = exportable;
strncpy(fullMessage + 2, message, len );
len = len + 2;
message = fullMessage;
sgx_read_rand(encr_message + SGX_AESGCM_MAC_SIZE, SGX_AESGCM_IV_SIZE);
// encode AES_Key
uint8_t key[SGX_AESGCM_KEY_SIZE];
unsigned char hash[32];
sgx_sha_state_handle_t shaStateHandle;
CHECK_STATE(sgx_sha256_init(&shaStateHandle) == SGX_SUCCESS);
CHECK_STATE(sgx_sha256_update(password, strlen(password), shaStateHandle) == SGX_SUCCESS);
CHECK_STATE(sgx_sha256_update(&(AES_key[512]), sizeof(sgx_aes_gcm_128bit_key_t), shaStateHandle) == SGX_SUCCESS);
CHECK_STATE(sgx_sha256_get_hash(shaStateHandle, (sgx_sha256_hash_t *)hash) == SGX_SUCCESS);
CHECK_STATE(sgx_sha256_close(shaStateHandle) == SGX_SUCCESS);
memcpy(key, hash, SGX_AESGCM_KEY_SIZE);
sgx_status_t status = sgx_rijndael128GCM_encrypt(&key, (uint8_t*)message, len,
encr_message + SGX_AESGCM_MAC_SIZE + SGX_AESGCM_IV_SIZE,
encr_message + SGX_AESGCM_MAC_SIZE, SGX_AESGCM_IV_SIZE,
NULL, 0,
(sgx_aes_gcm_128bit_tag_t *) encr_message);
*resultLen = len + SGX_AESGCM_MAC_SIZE + SGX_AESGCM_IV_SIZE;
return status;
}
int AES_decrypt(uint8_t *encr_message, uint64_t length, char *message, uint64_t msgLen,
uint8_t *type, uint8_t* exportable){
......@@ -135,3 +203,66 @@ int AES_decrypt(uint8_t *encr_message, uint64_t length, char *message, uint64_t
return status;
}
int AES_decrypt_with_password(const char *password, uint8_t *encr_message, uint64_t length, char *message, uint64_t msgLen,
uint8_t *type, uint8_t* exportable){
if (!message) {
LOG_ERROR("Null message in AES_encrypt");
return -1;
}
if (!encr_message) {
LOG_ERROR("Null encr message in AES_encrypt");
return -2;
}
if (!type) {
LOG_ERROR("Null type in AES_encrypt");
return -3;
}
if (!exportable) {
LOG_ERROR("Null exportable in AES_encrypt");
return -4;
}
if (length < SGX_AESGCM_MAC_SIZE + SGX_AESGCM_IV_SIZE) {
LOG_ERROR("length < SGX_AESGCM_MAC_SIZE - SGX_AESGCM_IV_SIZE");
return -5;
}
uint64_t len = length - SGX_AESGCM_MAC_SIZE - SGX_AESGCM_IV_SIZE;
if (msgLen < len) {
LOG_ERROR("Output buffer not large enough");
return -6;
}
// encode AES_Key
uint8_t key[SGX_AESGCM_KEY_SIZE];
unsigned char hash[32];
sgx_sha_state_handle_t shaStateHandle;
CHECK_STATE(sgx_sha256_init(&shaStateHandle) == SGX_SUCCESS);
CHECK_STATE(sgx_sha256_update(password, strlen(password), shaStateHandle) == SGX_SUCCESS);
CHECK_STATE(sgx_sha256_update(&(AES_key[512]), sizeof(sgx_aes_gcm_128bit_key_t), shaStateHandle) == SGX_SUCCESS);
CHECK_STATE(sgx_sha256_get_hash(shaStateHandle, (sgx_sha256_hash_t *)hash) == SGX_SUCCESS);
CHECK_STATE(sgx_sha256_close(shaStateHandle) == SGX_SUCCESS);
memcpy(key, hash, SGX_AESGCM_KEY_SIZE);
sgx_status_t status = sgx_rijndael128GCM_decrypt(&key,
encr_message + SGX_AESGCM_MAC_SIZE + SGX_AESGCM_IV_SIZE, len,
(unsigned char*) message,
encr_message + SGX_AESGCM_MAC_SIZE, SGX_AESGCM_IV_SIZE,
NULL, 0,
(sgx_aes_gcm_128bit_tag_t *)encr_message);
*type = message[0];
*exportable = message[1];
for (int i = 2; i < strlen(message) + 1; i++) {
message[i - 2 ] = message[i];
}
return status;
}
......@@ -31,6 +31,11 @@ int AES_encrypt(char *message, uint8_t *encr_message, uint64_t encrLen,
int AES_decrypt(uint8_t *encr_message, uint64_t length, char *message, uint64_t msgLen,
uint8_t *type, uint8_t* exportable) ;
int AES_encrypt_with_password(const char* password, char *message, uint8_t *encr_message, uint64_t encrLen,
unsigned char type, unsigned char exportable, uint64_t* resultLen);
int AES_decrypt_with_password(const char* password, uint8_t *encr_message, uint64_t length, char *message, uint64_t msgLen,
uint8_t *type, uint8_t* exportable) ;
#define ECDSA '1'
#define BLS '2'
......
......@@ -33,16 +33,29 @@
#include "EnclaveConstants.h"
#include "EnclaveCommon.h"
#include "sgx_tcrypto.h"
#include "sgx_tkey_exchange.h"
using namespace std;
thread_local uint8_t decryptedDkgPoly[DKG_BUFER_LENGTH];
#define IV_SIZE 12
#define MAC_SIZE 16
typedef struct ra_msg_t {
uint32_t payload_size; /* 0: Size of the payload which is*/
/* encrypted*/
uint8_t payload_iv[IV_SIZE]; /* 4: Reserved bits*/
uint8_t payload_mac[MAC_SIZE]; /* 16: CMAC(SK) of the plain text*/
uint8_t payload[]; /* 32: Ciphertext of the payload*/
/* followed by the plain text*/
} ra_msg_t;
uint8_t *getThreadLocalDecryptedDkgPoly() {
return decryptedDkgPoly;
}
string *stringFromKey(libff::alt_bn128_Fr *_key) {
string *ret = nullptr;
mpz_t t;
......@@ -202,6 +215,7 @@ bool enclave_sign(const char *_keyString, const char *_hashXString, const char *
string * r = nullptr;
if (!_keyString) {
LOG_ERROR("Null key string");
goto clean;
......@@ -331,6 +345,83 @@ bool hex2carray(const char *_hex, uint64_t *_bin_len,
return true;
}
int enceyptData(const uint32_t context, const char* plain, const uint32_t plain_size, char* cipher, uint32_t* cipher_size) {
ra_msg_t* secret;
uint32_t secret_size = sizeof(ra_msg_t) + plain_size;
sgx_ec_key_128bit_t sk_key;
// CHECK_STATE(plain)
// CHECK_STATE(cipher)
// CHECK_STATE(cipher_size)
sgx_status_t ret = sgx_ra_get_keys(context, SGX_RA_KEY_SK, &sk_key);
if(SGX_SUCCESS != ret) {
return ret;
}
secret = (ra_msg_t*)malloc(secret_size);
ret = sgx_rijndael128GCM_encrypt(&sk_key,
(const uint8_t*)plain,
plain_size,
secret->payload,
secret->payload_iv,
IV_SIZE,
NULL,
0,
(sgx_aes_gcm_128bit_key_t*)
secret->payload_mac);
secret->payload_size = plain_size;
if(ret != 0) {
return ret;
}
// SAFE_CHAR_BUF(cipherTmp, 2*secret_size)
carray2Hex((const uint8_t*)&secret, secret_size, (char*)cipher);
*cipher_size = 2*secret_size;
return SGX_SUCCESS;
}
int decryptData(const uint32_t context, const char* cipher, uint32_t cipher_size, char* plain, uint32_t* plain_size) {
ra_msg_t* secret;
uint64_t secret_size;
sgx_ec_key_128bit_t sk_key;
// CHECK_STATE(plain)
// CHECK_STATE(cipher)
// CHECK_STATE(plain_size)
if(cipher_size != strlen(cipher)) {
LOG_ERROR("cipher lenth mismatch");
return SGX_ERROR_UNEXPECTED;
}
secret = (ra_msg_t*)malloc(cipher_size / 2);
if(!hex2carray(cipher, &secret_size, (uint8_t*)secret)) {
LOG_ERROR("can't covert hex to carray");
return SGX_ERROR_UNEXPECTED;
}
*plain_size = (uint32_t)secret_size;
sgx_status_t ret = sgx_ra_get_keys(context, SGX_RA_KEY_SK, &sk_key);
if(SGX_SUCCESS != ret) {
return ret;
}
return sgx_rijndael128GCM_decrypt(&sk_key,
(const uint8_t*)secret->payload,
secret->payload_size,
(uint8_t*)plain,
secret->payload_iv,
12,
NULL,
0,
(sgx_aes_gcm_128bit_key_t*)
secret->payload_mac);
}
enum log_level {
L_TRACE = 0, L_DEBUG = 1, L_INFO = 2, L_WARNING = 3, L_ERROR = 4
};
......
......@@ -48,6 +48,9 @@ EXTERNC bool hex2carray2(const char * _hex, uint64_t *_bin_len,
uint8_t* _bin, const int _max_length );
EXTERNC void enclave_init();
EXTERNC int enceyptData(const uint32_t context, const char* plain, const uint32_t plain_size, char* cipher, uint32_t* cipher_size);
EXTERNC int decryptData(const uint32_t context, const char* cipher, const uint32_t cipher_size, char* plain, uint32_t* plain_size);
void get_global_random(unsigned char* _randBuff, uint64_t size);
EXTERNC uint8_t* getThreadLocalDecryptedDkgPoly();
......
#include <string.h>
#include "secure_enclave_t.h"
#include "sgx_tkey_exchange.h"
#include "sgx_tcrypto.h"
sgx_status_t trustedInitRA(const sgx_ec256_public_t g_sp_pub_key, int b_pse, sgx_ra_context_t *p_context) {
return sgx_ra_init(&g_sp_pub_key, b_pse, p_context);
}
sgx_status_t trustedCloseRA(sgx_ra_context_t context) {
return sgx_ra_close(context);
}
sgx_status_t trustedVerifyMac(
sgx_ra_context_t context,
uint8_t* p_message,
size_t message_size,
uint8_t* p_mac,
size_t mac_size
) {
sgx_status_t ret;
sgx_ec_key_128bit_t mk_key;
if(mac_size != sizeof(sgx_mac_t) || message_size > UINT32_MAX) {
return SGX_ERROR_INVALID_PARAMETER;
}
uint8_t mac[SGX_CMAC_MAC_SIZE] = {0};
ret = sgx_ra_get_keys(context, SGX_RA_KEY_MK, &mk_key);
if(SGX_SUCCESS != ret) {
return ret;
}
ret = sgx_rijndael128_cmac_msg(&mk_key,
p_message,
(uint32_t)message_size,
&mac);
if(SGX_SUCCESS != ret) {
return ret;
}
if(0 == consttime_memequal(p_mac, mac, sizeof(mac))) {
return SGX_ERROR_MAC_MISMATCH;
}
return SGX_SUCCESS;
}
sgx_status_t trustedVerifySecret (
sgx_ra_context_t context,
uint8_t *p_secret,
uint32_t secret_size,
const uint8_t *p_iv,
uint8_t *p_gcm_mac
) {
sgx_status_t ret = SGX_SUCCESS;
sgx_ec_key_128bit_t sk_key;
ret = sgx_ra_get_keys(context, SGX_RA_KEY_SK, &sk_key);
if (SGX_SUCCESS != ret) {
return ret;
}
uint8_t *decrypted = (uint8_t*) malloc(sizeof(uint8_t) * secret_size);
ret = sgx_rijndael128GCM_decrypt(&sk_key,
p_secret,
secret_size,
decrypted,
p_iv,
12,
NULL,
0,
(const sgx_aes_gcm_128bit_tag_t *) (p_gcm_mac));
if (SGX_SUCCESS != ret) {
return ret;
}
for(int i=0; i<secret_size; i++) {
if(decrypted[i] != i) {
return SGX_ERROR_UNEXPECTED;
}
}
return SGX_SUCCESS;
}
// sgx_status_t trustedPutSecret (
// ) {
// sgx_status_t ret;
// }
\ No newline at end of file
......@@ -62,7 +62,7 @@ ENCLAVE_KEY=test_insecure_private_key.pem #$(ENCLAVE)_private.pem
## Additional Automake flags needed to build the enclave.
AM_CPPFLAGS += -O2 -Wall -Wno-implicit-function-declaration $(TGMP_CPPFLAGS) -I./third_party/SCIPR -I../third_party/SCIPR -I../sgx-sdk-build/sgxsdk/include/libcxx
AM_CPPFLAGS += -O2 -Wall -Wno-implicit-function-declaration $(TGMP_CPPFLAGS) -I./third_party/SCIPR -I../third_party/SCIPR -I/opt/intel/sgxsdk/include/libcxx
AM_CXXFLAGS += -fno-builtin -fstack-protector-strong
......@@ -82,7 +82,7 @@ CLEANFILES+= secure_enclave_t.c secure_enclave_t.h
## target name (i.e., $(ENCLAVE)_SOURCES will not work).
secure_enclave_SOURCES = secure_enclave_t.c secure_enclave_t.h \
secure_enclave.c \
secure_enclave.c EnclaveRemoteAttestation.c\
Curves.c NumberTheory.c Point.c Signature.c DHDkg.c AESUtils.c \
DKGUtils.cpp TEUtils.cpp EnclaveCommon.cpp DomainParameters.cpp ../third_party/SCIPR/libff/algebra/curves/alt_bn128/alt_bn128_init.cpp \
../third_party/SCIPR/libff/algebra/curves/alt_bn128/alt_bn128_g2.cpp \
......@@ -113,7 +113,7 @@ secure_enclave_LDADD = @SGX_ENCLAVE_LDADD@
## --startgroup and --endgroup flags. (This would be where you'd add
## SGXSSL libraries, and your trusted c++ library
SGX_EXTRA_TLIBS=-lsgx_tgmp -lsgx_tservice -lsgx_urts -lsgx_tcxx
SGX_EXTRA_TLIBS=-lsgx_tgmp -lsgx_tservice -lsgx_urts -lsgx_tcxx -lsgx_tkey_exchange
......
This diff is collapsed.
This diff is collapsed.
......@@ -7,12 +7,31 @@
#define TINY_BUF_SIZE 256
enclave {
from "sgx_tkey_exchange.edl" import *;
include "sgx_key_exchange.h"
trusted {
include "sgx_tgmp.h"
public void trustedEnclaveInit(uint64_t _logLevel);
public sgx_status_t trustedInitRA(sgx_ec256_public_t g_sp_pub_key, int b_pse, [out] sgx_ra_context_t *p_context);
public sgx_status_t trustedCloseRA(sgx_ra_context_t context);
public sgx_status_t trustedVerifyMac(sgx_ra_context_t context,
[in, size = message_size] uint8_t* p_message,
size_t message_size,
[in, size = mac_size] uint8_t* p_mac,
size_t mac_size);
public sgx_status_t trustedVerifySecret (sgx_ra_context_t context,
[in, size = secret_size] uint8_t *p_secret,
uint32_t secret_size,
[in, size = 12]const uint8_t *p_iv,
[in, count = 16]uint8_t *p_gcm_mac);
public void trustedGenerateSEK(
[out] int *errStatus,
[out, count = SMALL_BUF_SIZE] char *err_string,
......@@ -41,6 +60,17 @@ enclave {
[out, count = SMALL_BUF_SIZE] char * pub_key_x,
[out, count = SMALL_BUF_SIZE] char * pub_key_y);
public void trustedGenerateEcdsaKeyWithPassword (
[out] int *errStatus,
[out, count = SMALL_BUF_SIZE] char* err_string,
sgx_ra_context_t context,
[in, string] const char *password,
[in, count = 1] int *is_exportable,
[out, count = SMALL_BUF_SIZE] uint8_t* encrypted_key,
[out] uint64_t *enc_len,
[out, count = SMALL_BUF_SIZE] char * pub_key_x,
[out, count = SMALL_BUF_SIZE] char * pub_key_y);
public void trustedGetPublicEcdsaKey(
[out] int *errStatus,
[out, count = SMALL_BUF_SIZE] char* err_string,
......@@ -49,6 +79,16 @@ enclave {
[out, count = SMALL_BUF_SIZE] char * pub_key_x,
[out, count = SMALL_BUF_SIZE] char * pub_key_y);
public void trustedGetPublicEcdsaKeyWithPassword(
[out] int *errStatus,
[out, count = SMALL_BUF_SIZE] char* err_string,
sgx_ra_context_t context,
[in, string] const char* password,
[in, count = SMALL_BUF_SIZE] uint8_t* encrypted_key,
uint64_t dec_len,
[out, count = SMALL_BUF_SIZE] char * pub_key_x,
[out, count = SMALL_BUF_SIZE] char * pub_key_y);
public void trustedEcdsaSign(
[out] int *errStatus,
[out, count = SMALL_BUF_SIZE] char* err_string,
......@@ -60,6 +100,19 @@ enclave {
[out] uint8_t* sig_v,
int base);
public void trustedEcdsaSignWithPassword(
[out] int *errStatus,
[out, count = SMALL_BUF_SIZE] char* err_string,
sgx_ra_context_t context,
[in, string] const char *password,
[in, count = SMALL_BUF_SIZE] uint8_t* encrypted_key,
uint64_t enc_len,
[in, string] const char* hash,
[out, count = SMALL_BUF_SIZE] char* sig_r,
[out, count = SMALL_BUF_SIZE] char* sig_s,
[out] uint8_t* sig_v,
int base);
public void trustedEncryptKey (
[out] int *errStatus,
[out, count = SMALL_BUF_SIZE] char* err_string,
......@@ -67,6 +120,15 @@ enclave {
[out, count = SMALL_BUF_SIZE] uint8_t* encrypted_key,
[out] uint64_t *enc_len);
public void trustedEncryptKeyWithPassword (
[out] int *errStatus,
[out, count = SMALL_BUF_SIZE] char* err_string,
sgx_ra_context_t context,
[in, string] const char* password,
[in, count = SMALL_BUF_SIZE] const char* key,
[out, count = SMALL_BUF_SIZE] uint8_t* encrypted_key,
[out] uint64_t *enc_len);
public void trustedDecryptKey (
[out] int *errStatus,
[out, count = SMALL_BUF_SIZE] char* err_string,
......@@ -74,6 +136,15 @@ enclave {
uint64_t enc_len,
[out, count = SMALL_BUF_SIZE] char* key );
public void trustedDecryptKeyWithPassword (
[out] int *errStatus,
[out, count = SMALL_BUF_SIZE] char* err_string,
sgx_ra_context_t context,
[in, string] const char* password,
[in, count = SMALL_BUF_SIZE] uint8_t* encrypted_key,
uint64_t enc_len,
[out, count = SMALL_BUF_SIZE] char* key );
public void trustedGenDkgSecret (
[out] int *errStatus,
[out, count = SMALL_BUF_SIZE] char* err_string,
......
File added
......@@ -188,6 +188,19 @@ extern bool autoconfirm;
#define INVALID_KEY_FORMAT -115
#define KEY_ALREADY_REGISTERED -116
#define REMOTE_ATTESTATION_SERVER_FAILED_TO_START -200
#define RA_INVALID_PUBLIC_KEY -201
#define FAIL_INIT_RA -202
#define FAIL_GET_EPID -203
#define FAIL_GENERATE_MESSAGE1 -204
#define RA_INVALID_MESSAGE2_SIZE -205
#define FAIL_GENERATE_MESSAGE3 -206
#define RA_INVALID_RESULT_SIZE -207
#define FAIL_VERIFY_MAC -208
#define FAIL_VERIFY_SECRET -209
#define FALIED_COVERT_HEX -210
#define SGX_ENCLAVE_ERROR -666
#define MAX_CSR_NUM 1000
......
This diff is collapsed.
timestamp for config.h
This diff is collapsed.
{
"files.associations": {
"iostream": "cpp"
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
enclave.so {
global:
g_global_data_sim;
g_global_data;
enclave_entry;
local:
*;
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment