Unverified Commit d92bb2eb authored by svetaro's avatar svetaro

Merge branch 'master' into enhancement/SKALE-1512-add-DKG-to-SGX

parents d5c3daaf 3c31e5a9
......@@ -26,49 +26,10 @@
#include "SGXWalletServer.h"
#include "BLSCrypto.h"
#include "ServerInit.h"
void init_enclave() {
eid = 0;
updated = 0;
unsigned long support;
#ifndef SGX_HW_SIM
support = get_sgx_support();
if (!SGX_OK(support)) {
sgx_support_perror(support);
exit(1);
}
#endif
status = sgx_create_enclave_search(ENCLAVE_NAME, SGX_DEBUG_FLAG, &token,
&updated, &eid, 0);
if (status != SGX_SUCCESS) {
if (status == SGX_ERROR_ENCLAVE_FILE_ACCESS) {
fprintf(stderr, "sgx_create_enclave: %s: file not found\n", ENCLAVE_NAME);
fprintf(stderr, "Did you forget to set LD_LIBRARY_PATH?\n");
} else {
fprintf(stderr, "%s: 0x%04x\n", ENCLAVE_NAME, status);
}
exit(1);
}
fprintf(stderr, "Enclave launched\n");
status = tgmp_init(eid);
if (status != SGX_SUCCESS) {
fprintf(stderr, "ECALL tgmp_init: 0x%04x\n", status);
exit(1);
}
fprintf(stderr, "libtgmp initialized\n");
}
int char2int(char _input) {
if (_input >= '0' && _input <= '9')
return _input - '0';
......@@ -123,22 +84,9 @@ bool hex2carray(const char * _hex, uint64_t *_bin_len,
}
void init_daemon() {
libff::init_alt_bn128_params();
// Set up database connection information and open database
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
leveldb::Status status = leveldb::DB::Open(options, "./keysdb", &db);
}
bool sign(char* _encryptedKeyHex, char* _hashHex, size_t _t, size_t _n, size_t _signerIndex,
bool sign(const char* _encryptedKeyHex, const char* _hashHex, size_t _t, size_t _n, size_t _signerIndex,
char* _sig) {
......@@ -150,19 +98,73 @@ bool sign(char* _encryptedKeyHex, char* _hashHex, size_t _t, size_t _n, size_t _
hex2carray(_hashHex, &binLen, hash->data());
auto keyShare = std::make_shared<BLSPrivateKeyShareSGX>(keyStr, _t, _n);
auto sigShare = keyShare->signWithHelperSGX(hash, _signerIndex);
auto sigShareStr = sigShare->toString();
strncpy(_sig, sigShareStr->c_str(), BUF_LEN);
return true;
}
void init_all() {
init_server();
init_enclave();
init_daemon();
char *encryptBLSKeyShare2Hex(int *errStatus, char *err_string, const char *_key) {
char *keyArray = (char *) calloc(BUF_LEN, 1);
uint8_t *encryptedKey = (uint8_t *) calloc(BUF_LEN, 1);
char *errMsg = (char *) calloc(BUF_LEN, 1);
strncpy((char *) keyArray, (char *) _key, BUF_LEN);
*errStatus = -1;
unsigned int encryptedLen = 0;
status = encrypt_key(eid, errStatus, errMsg, keyArray, encryptedKey, &encryptedLen);
if (status != SGX_SUCCESS) {
*errStatus = -1;
return nullptr;
}
if (*errStatus != 0) {
return nullptr;
}
char *result = (char *) calloc(2 * BUF_LEN, 1);
carray2Hex(encryptedKey, encryptedLen, result);
return result;
}
char *decryptBLSKeyShareFromHex(int *errStatus, char *errMsg, const char *_encryptedKey) {
*errStatus = -1;
uint64_t decodedLen = 0;
uint8_t decoded[BUF_LEN];
if (!(hex2carray(_encryptedKey, &decodedLen, decoded))) {
return nullptr;
}
char *plaintextKey = (char *) calloc(BUF_LEN, 1);
status = decrypt_key(eid, errStatus, errMsg, decoded, decodedLen, plaintextKey);
if (status != SGX_SUCCESS) {
return nullptr;
}
if (*errStatus != 0) {
return nullptr;
}
return plaintextKey;
}
\ No newline at end of file
......@@ -3,8 +3,8 @@
//
#ifndef SGXD_BLSCRYPTO_H
#define SGXD_BLSCRYPTO_H
#ifndef SGXWALLET_BLSCRYPTO_H
#define SGXWALLET_BLSCRYPTO_H
#ifdef __cplusplus
#define EXTERNC extern "C"
......@@ -18,7 +18,7 @@ EXTERNC void init_daemon();
EXTERNC void init_enclave();
EXTERNC bool sign(char* encryptedKeyHex, char* hashHex, size_t t, size_t n, char* _sig);
EXTERNC bool sign(const char* encryptedKeyHex, const char* hashHex, size_t t, size_t n, size_t signerIndex, char* _sig);
EXTERNC int char2int(char _input);
......@@ -28,6 +28,8 @@ EXTERNC bool hex2carray(const char * _hex, uint64_t *_bin_len,
EXTERNC char *encryptBLSKeyShare2Hex(int *errStatus, char *err_string, const char *_key);
EXTERNC char *decryptBLSKeyShareFromHex(int *errStatus, char *errMsg, const char *_encryptedKey);
#endif //SGXD_BLSCRYPTO_H
#endif //SGXWALLET_BLSCRYPTO_H
......@@ -32,6 +32,7 @@ using namespace std;
#include "sgxwallet.h"
#include "BLSCrypto.h"
#include "ServerInit.h"
#include "BLSPrivateKeyShareSGX.h"
......@@ -158,6 +159,8 @@ std::shared_ptr<BLSSigShare> BLSPrivateKeyShareSGX::signWithHelperSGX(
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid hex encrypted key"));
}
cerr << "Key is " + *encryptedKeyHex << endl;
sgx_status_t status =
bls_sign_message(eid, &errStatus, errMsg, encryptedKey,
encryptedKeyHex->size() / 2, xStrArg, yStrArg, signature);
......@@ -170,17 +173,27 @@ std::shared_ptr<BLSSigShare> BLSPrivateKeyShareSGX::signWithHelperSGX(
if (errStatus != 0) {
gmp_printf("Enclave bls_sign_message failed %d\n", errStatus);
BOOST_THROW_EXCEPTION(runtime_error("Enclave bls_sign_message failed"));
BOOST_THROW_EXCEPTION(runtime_error("Enclave bls_sign_message failed:" + to_string(errStatus) + ":" + errMsg ));
return nullptr;
}
int sigLen;
if ((sigLen = strnlen(signature, 10)) < 10) {
BOOST_THROW_EXCEPTION(runtime_error("Signature too short:" + to_string(sigLen)));
}
std::string hint = BLSutils::ConvertToString(hash_with_hint.first.Y) + ":" +
hash_with_hint.second;
auto sig = make_shared<string>(signature);
sig->append(":");
sig->append(hint);
auto s = make_shared<BLSSigShare>(sig, _signerIndex, requiredSigners,
totalSigners);
......
......@@ -21,10 +21,11 @@
@date 2019
*/
#ifndef SGXD_BLSPRIVATEKEYSHARESGX_H
#define SGXD_BLSPRIVATEKEYSHARESGX_H
#define SGXD_BLSPRIVATEKEYSHARESGX_H
#ifndef SGXWALLET_BLSPRIVATEKEYSHARESGX_H
#define SGXWALLET_BLSPRIVATEKEYSHARESGX_H
#define SGXWALLET_BLSPRIVATEKEYSHARESGX_H
#include "BLSSigShare.h"
#include "BLSPrivateKeyShare.h"
class BLSPrivateKeyShareSGX {
......
......@@ -99,8 +99,8 @@ add_custom_target(sgxd COMMAND make all
libff/libff/common/utils.cpp
libff/libff/common/utils.hpp
libff/libff/common/utils.tcc
secure_enclave/BLSUtils.cpp
secure_enclave/BLSUtils.h
secure_enclave/BLSEnclave.cpp
secure_enclave/BLSEnclave.h
secure_enclave/secure_enclave.c
secure_enclave/secure_enclave_t.c
secure_enclave/secure_enclave_t.h
......@@ -116,5 +116,6 @@ add_custom_target(sgxd COMMAND make all
sgx_stub.c
sgx_stub.h
sgx_tgmp.h
sgxd.c
sgxwallet.c
testw.cpp
)
/*
Copyright (C) 2019 SKALE Labs
This file is part of skale-consensus.
skale-consensus is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
skale-consensus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with skale-consensus. If not, see <https://www.gnu.org/licenses/>.
@file LevelDB.cpp
@author Stan Kladko
@date 2019
*/
#include <stdexcept>
#include <memory>
#include <string>
#include "leveldb/db.h"
#include "sgxwallet_common.h"
#include "RPCException.h"
#include "LevelDB.h"
using namespace leveldb;
static WriteOptions writeOptions;
static ReadOptions readOptions;
LevelDB* levelDb = nullptr;
std::shared_ptr<std::string> LevelDB::readString(const std::string &_key) {
std::lock_guard<std::recursive_mutex> lock(mutex);
auto result = std::make_shared<std::string>();
if (db == nullptr) {
throw RPCException(NULL_DATABASE, "Null db");
}
auto status = db->Get(readOptions, _key, &*result);
throwExceptionOnError(status);
if (status.IsNotFound())
return nullptr;
return result;
}
void LevelDB::writeString(const std::string &_key, const std::string &_value) {
std::lock_guard<std::recursive_mutex> lock(mutex);
auto status = db->Put(writeOptions, Slice(_key), Slice(_value));
throwExceptionOnError(status);
}
void LevelDB::writeByteArray(const char *_key, size_t _keyLen, const char *value,
size_t _valueLen) {
std::lock_guard<std::recursive_mutex> lock(mutex);
auto status = db->Put(writeOptions, Slice(_key, _keyLen), Slice(value, _valueLen));
throwExceptionOnError(status);
}
void LevelDB::writeByteArray(std::string &_key, const char *value,
size_t _valueLen) {
std::lock_guard<std::recursive_mutex> lock(mutex);
auto status = db->Put(writeOptions, Slice(_key), Slice(value, _valueLen));
throwExceptionOnError(status);
}
void LevelDB::throwExceptionOnError(Status _status) {
if (_status.IsNotFound())
return;
if (!_status.ok()) {
throw RPCException(COULD_NOT_ACCESS_DATABASE, ("Could not access database database:" + _status.ToString()).c_str());
}
}
uint64_t LevelDB::visitKeys(LevelDB::KeyVisitor *_visitor, uint64_t _maxKeysToVisit) {
std::lock_guard<std::recursive_mutex> lock(mutex);
uint64_t readCounter = 0;
leveldb::Iterator *it = db->NewIterator(readOptions);
for (it->SeekToFirst(); it->Valid(); it->Next()) {
_visitor->visitDBKey(it->key().data());
readCounter++;
if (readCounter >= _maxKeysToVisit) {
break;
}
}
delete it;
return readCounter;
}
LevelDB::LevelDB(std::string &filename) {
leveldb::Options options;
options.create_if_missing = true;
if (!leveldb::DB::Open(options, filename, (leveldb::DB **) &db).ok()) {
throw std::runtime_error("Unable to open levelDB database");
}
if (db == nullptr) {
throw std::runtime_error("Null levelDB object");
}
}
LevelDB::~LevelDB() {
if (db != nullptr)
delete db;
}
/*
Copyright (C) 2019 SKALE Labs
This file is part of skale-consensus.
skale-consensus is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
skale-consensus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with skale-consensus. If not, see <https://www.gnu.org/licenses/>.
@file LevelDB.h
@author Stan Kladko
@date 2019
*/
#ifndef SGXWALLET_LEVELDB_H
#define SGXWALLET_LEVELDB_H
#include <memory>
#include <string>
#include <mutex>
namespace leveldb {
class DB;
class Status;
class Slice;
}
class LevelDB {
std::recursive_mutex mutex;
leveldb::DB* db;
public:
std::shared_ptr<std::string> readString(const std::string& _key);
void writeString(const std::string &key1, const std::string &value1);
void writeByteArray(const char *_key, size_t _keyLen, const char *value,
size_t _valueLen);
void writeByteArray(std::string& _key, const char *value,
size_t _valueLen);
public:
void throwExceptionOnError(leveldb::Status result);
LevelDB(std::string& filename);
class KeyVisitor {
public:
virtual void visitDBKey(const char* _data) = 0;
};
uint64_t visitKeys(KeyVisitor* _visitor, uint64_t _maxKeysToVisit);
virtual ~LevelDB();
};
extern LevelDB* levelDb;
#endif
\ No newline at end of file
......@@ -65,7 +65,7 @@ bin_PROGRAMS = sgxwallet testw
COMMON_SRC = sgx_stub.c sgx_detect_linux.c create_enclave.c oc_alloc.c
COMMON_ENCLAVE_SRC = secure_enclave_u.c secure_enclave_u.h
sgxwallet_SOURCES = sgxwallet.c SGXWalletServer.cpp BLSCrypto.cpp BLSPrivateKeyShareSGX.cpp $(COMMON_SRC)
sgxwallet_SOURCES = sgxwallet.c SGXWalletServer.cpp RPCException.cpp BLSCrypto.cpp ServerInit.cpp BLSPrivateKeyShareSGX.cpp LevelDB.cpp $(COMMON_SRC)
nodist_sgxwallet_SOURCES = $(COMMON_ENCLAVE_SRC)
EXTRA_sgxwallet_DEPENDENCIES = secure_enclave.signed.so
......@@ -90,7 +90,7 @@ secure_enclave.signed.so: secure_enclave/secure_enclave.signed.so
sgxwallet_LDADD=-l$(SGX_URTS_LIB) -Lleveldb/build -LlibBLS/build -LlibBLS/build/libff/libff -l:libbls.a -l:libleveldb.a -l:libff.a -lgmp -ldl -l:libsgx_capable.a -l:libsgx_tprotected_fs.a -ljsonrpccpp-stub -lpthread -ljsonrpccpp-common -ljsonrpccpp-server -ljsoncpp -lprocps
testw_SOURCES=testw.cpp SGXWalletServer.cpp BLSCrypto.cpp BLSPrivateKeyShareSGX.cpp $(COMMON_SRC)
testw_SOURCES=testw.cpp SGXWalletServer.cpp RPCException.cpp BLSCrypto.cpp ServerInit.cpp LevelDB.cpp BLSPrivateKeyShareSGX.cpp $(COMMON_SRC)
nodist_testw_SOURCES=${nodist_sgxwallet_SOURCES}
EXTRA_testw_DEPENDENCIES=${EXTRA_sgxwallet_DEPENDENCIES}
testw_LDADD= ${sgxwallet_LDADD}
\ No newline at end of file
......@@ -4,7 +4,11 @@
sgxwallet is a next generation hardware secure crypto wallet that is based on Intel SGX technology. It currently supports Ethereum and SKALE, and will support Bitcoin in the future.
## Prerequisites
## Clone directory and its submodules
``` git clone --recurse-submodules https://github.com/skalenetwork/sgxwallet.git ```
## Enable SGX on your machine
To build and run sgxd, you'll need Intel SGX capable hardware. Most Intel chips that were produced after 2015 support SGX.
......@@ -22,7 +26,9 @@ To enable SGX using a software utility:
* Run `./sgx-enable`. Verify that it says that SGX is successfully enabled
sgxwallet has been tested on Ubuntu Linux 18.04.
sgxwallet has been tested on Ubuntu Linux 18.04.
## Install SGX driver
......@@ -35,10 +41,6 @@ If you do not see the `isgx` device, you need to troubleshoot your driver instal
```cd scripts; sudo install_packages.sh```
## Clone directory and its submodules
``` git clone --recurse-submodules https://github.com/skalenetwork/sgxwallet.git ```
## Install automake 1.15
Currently the build builds with automake 1.15. You need to install it since Ubuntu 18 comes with automake 1.16 by default.
......
//
// Created by skale on 9/8/19.
//
#include "RPCException.h"
//
// Created by skale on 9/8/19.
//
#ifndef SGXD_RPCEXCEPTION_H
#define SGXD_RPCEXCEPTION_H
#include <string>
#include <exception>
class RPCException : public std::exception {
public:
int32_t status;
std::string errString;
RPCException(int32_t _status, const char* _errString) : status(_status), errString(_errString) {}
};
#endif //SGXD_RPCEXCEPTION_H
......@@ -18,59 +18,221 @@
#include <stdio.h>
#include "sgxwallet_common.h"
#include "RPCException.h"
#include "LevelDB.h"
#include "BLSCrypto.h"
#include "SGXWalletServer.h"
#include "SGXWalletServer.hpp"
using namespace jsonrpc;
using namespace std;
SGXWalletServer::SGXWalletServer(AbstractServerConnector &connector,
serverVersion_t type)
: AbstractStubServer(connector, type) {}
class SGXWalletServer : public AbstractStubServer {
public:
SGXWalletServer(AbstractServerConnector &connector, serverVersion_t type);
int init_server() {
HttpServer httpserver(1025);
SGXWalletServer s(httpserver,
JSONRPC_SERVER_V1V2); // hybrid server (json-rpc 1.0 & 2.0)
s.StartListening();
return 0;
}
virtual void notifyServer();
virtual std::string sayHello(const std::string &name);
virtual int addNumbers(int param1, int param2);
virtual double addNumbers2(double param1, double param2);
virtual bool isEqual(const std::string &str1, const std::string &str2);
virtual Json::Value buildObject(const std::string &name, int age);
virtual std::string methodWithoutParameters();
};
Json::Value
importBLSKeyShareImpl(int index, const std::string &_keyShare, const std::string &_keyShareName, int n, int t) {
Json::Value result;
SGXWalletServer::SGXWalletServer(AbstractServerConnector &connector,
serverVersion_t type)
: AbstractStubServer(connector, type) {}
int errStatus = UNKNOWN_ERROR;
char *errMsg = (char *) calloc(BUF_LEN, 1);
result["status"] = 0;
result["errorMessage"] = "";
result["encryptedKeyShare"] = "";
try {
char *encryptedKeyShareHex = encryptBLSKeyShare2Hex(&errStatus, errMsg, _keyShare.c_str());
if (encryptedKeyShareHex == nullptr) {
throw RPCException(UNKNOWN_ERROR, "");
}
if (errStatus != 0) {
throw RPCException(errStatus, errMsg);
}
result["encryptedKeyShare"] = encryptedKeyShareHex;
void SGXWalletServer::notifyServer() { cout << "Server got notified" << endl; }
writeKeyShare(_keyShareName, encryptedKeyShareHex, index, n , t);
string SGXWalletServer::sayHello(const string &name) {
if (name == "")
throw JsonRpcException(-32100, "Name was empty");
return "Hello " + name;
} catch (RPCException &_e) {
result["status"] = _e.status;
result["errorMessage"] = _e.errString;
}
return result;
}
int SGXWalletServer::addNumbers(int param1, int param2) { return param1 + param2; }
double SGXWalletServer::addNumbers2(double param1, double param2) {
return param1 + param2;
Json::Value blsSignMessageHashImpl(const std::string &keyShareName, const std::string &messageHash) {
Json::Value result;
result["status"] = -1;
result["errorMessage"] = "Unknown server error";
result["signatureShare"] = "";
//int errStatus = UNKNOWN_ERROR;
//char *errMsg = (char *) calloc(BUF_LEN, 1);
char *signature = (char *) calloc(BUF_LEN, 1);
shared_ptr <std::string> value = nullptr;
try {
value = readKeyShare(keyShareName);
} catch (RPCException _e) {
result["status"] = _e.status;
result["errorMessage"] = _e.errString;
return result;
} catch (...) {
std::exception_ptr p = std::current_exception();
printf("Exception %s \n", p.__cxa_exception_type()->name());
result["status"] = -1;
result["errorMessage"] = "Read key share has thrown exception:";
return result;
}
try {
if (!sign(value->c_str(), messageHash.c_str(), 2, 2, 1, signature)) {
result["status"] = -1;
result["errorMessage"] = "Could not sign";
return result;
}
} catch (...) {
result["status"] = -1;
result["errorMessage"] = "Sign has thrown exception";
return result;
}
result["status"] = 0;
result["errorMessage"] = "";
result["signatureShare"] = signature;
return result;
}
bool SGXWalletServer::isEqual(const string &str1, const string &str2) {
return str1 == str2;
Json::Value importECDSAKeyImpl(const std::string &key, const std::string &keyName) {
Json::Value result;
result["status"] = 0;
result["errorMessage"] = "";
result["encryptedKey"] = "";
return result;
}
Json::Value SGXWalletServer::buildObject(const string &name, int age) {
Json::Value generateECDSAKeyImpl(const std::string &_keyName) {
Json::Value result;
result["name"] = name;
result["year"] = age;
result["status"] = 0;
result["errorMessage"] = "";
result["encryptedKey"] = "";
try {
writeECDSAKey(_keyName, "");
} catch (RPCException &_e) {
result["status"] = _e.status;
result["errorMessage"] = _e.errString;
}
return result;
}
string SGXWalletServer::methodWithoutParameters() { return "Test"; }
int init_server() {
HttpServer httpserver(1025);
SGXWalletServer s(httpserver,
JSONRPC_SERVER_V1V2); // hybrid server (json-rpc 1.0 & 2.0)
s.StartListening();
return 0;
Json::Value ecdsaSignMessageHashImpl(const std::string &_keyName, const std::string &messageHash) {
Json::Value result;
result["status"] = 0;
result["errorMessage"] = "";
result["signature"] = "";
try {
readECDSAKey(_keyName);
} catch (RPCException &_e) {
result["status"] = _e.status;
result["errorMessage"] = _e.errString;
}
return result;
}
Json::Value SGXWalletServer::generateECDSAKey(const std::string &_keyName) {
return generateECDSAKeyImpl(_keyName);
}
Json::Value SGXWalletServer::ecdsaSignMessageHash(const std::string &_keyName, const std::string &messageHash) {
return ecdsaSignMessageHashImpl(_keyName, messageHash);
}
Json::Value
SGXWalletServer::importBLSKeyShare(int index, const std::string &_keyShare, const std::string &_keyShareName, int n,
int t) {
return importBLSKeyShareImpl(index, _keyShare, _keyShareName, n, t);
}
Json::Value SGXWalletServer::blsSignMessageHash(const std::string &keyShareName, const std::string &messageHash) {
return blsSignMessageHashImpl(keyShareName, messageHash);
}
Json::Value SGXWalletServer::importECDSAKey(const std::string &key, const std::string &keyName) {
return importECDSAKeyImpl(key, keyName);
}
shared_ptr<string> readKeyShare(const string &_keyShareName) {
auto keyShareStr = levelDb->readString("BLSKEYSHARE:" + _keyShareName);
if (keyShareStr == nullptr) {
throw RPCException(KEY_SHARE_DOES_NOT_EXIST, "Key share with this name does not exists");
}
return keyShareStr;
}
void writeKeyShare(const string &_keyShareName, const string &value, int index, int n, int t) {
Json::Value val;
Json::FastWriter writer;
val["value"] = value;
val["t"] = t;
val["index"] = index;
val["n'"] = n;
std::string json = writer.write(val);
auto key = "BLSKEYSHARE:" + _keyShareName;
if (levelDb->readString(_keyShareName) != nullptr) {
throw new RPCException(KEY_SHARE_DOES_NOT_EXIST, "Key share with this name already exists");
}
levelDb->writeString(key, value);
}
shared_ptr <std::string> readECDSAKey(const string &_keyShare) {
return nullptr;
}
void writeECDSAKey(const string &_keyShare, const string &value) {
}
\ No newline at end of file
......@@ -2,8 +2,8 @@
// Created by kladko on 05.09.19.
//
#ifndef SGXD_SGXWALLETSERVER_H
#define SGXD_SGXWALLETSERVER_H
#ifndef SGXWALLET_SGXWALLETSERVER_H
#define SGXWALLET_SGXWALLETSERVER_H
#ifdef __cplusplus
#define EXTERNC extern "C"
......@@ -15,4 +15,10 @@
EXTERNC int init_server();
#endif //SGXD_SGXWALLETSERVER_H
#endif //SGXWALLET_SGXWALLETSERVER_H
#ifndef SGXWALLET_SGXWALLETSERVER_HPP
#define SGXWALLET_SGXWALLETSERVER_HPP
#include "abstractstubserver.h"
using namespace jsonrpc;
using namespace std;
class SGXWalletServer : public AbstractStubServer {
public:
SGXWalletServer(AbstractServerConnector &connector, serverVersion_t type);
virtual Json::Value importBLSKeyShare(int index, const std::string& keyShare, const std::string& keyShareName, int n, int t);
virtual Json::Value blsSignMessageHash(const std::string& keyShareName, const std::string& messageHash);
virtual Json::Value importECDSAKey(const std::string& key, const std::string& keyName);
virtual Json::Value generateECDSAKey(const std::string& keyName);
virtual Json::Value ecdsaSignMessageHash(const std::string& keyShareName, const std::string& messageHash);
};
void writeKeyShare(const string &_keyShareName, const string &value, int index, int n, int t);
shared_ptr<std::string> readKeyShare(const string& _keyShare);
void writeECDSAKey(const string& _key, const string& value);
shared_ptr<std::string> readECDSAKey(const string& _key);
Json::Value importBLSKeyShareImpl(int index, const std::string& keyShare, const std::string& keyShareName, int n, int t);
Json::Value blsSignMessageHashImpl(const std::string& keyShareName, const std::string& messageHash);
Json::Value importECDSAKeyImpl(const std::string& key, const std::string& keyName);
Json::Value generateECDSAKeyImpl(const std::string& keyName);
Json::Value ecdsaSignMessageHashImpl(const std::string& keyShareName, const std::string& messageHash);
#endif //SGXWALLET_SGXWALLETSERVER_HPP
\ No newline at end of file
//
// Created by kladko on 9/2/19.
//
#include <memory>
#include "libff/algebra/curves/alt_bn128/alt_bn128_init.hpp"
#include "bls.h"
#include "leveldb/db.h"
#include <jsonrpccpp/server/connectors/httpserver.h>
#include "BLSPrivateKeyShareSGX.h"
#include "sgxwallet_common.h"
#include "create_enclave.h"
#include "secure_enclave_u.h"
#include "sgx_detect.h"
#include <gmp.h>
#include <sgx_urts.h>
#include "sgxwallet.h"
#include "LevelDB.h"
#include "SGXWalletServer.h"
#include "BLSCrypto.h"
#include "ServerInit.h"
void init_daemon() {
libff::init_alt_bn128_params();
static std::string dbName("./" WALLETDB_NAME);
levelDb = new LevelDB(dbName);
}
void init_enclave() {
eid = 0;
updated = 0;
unsigned long support;
#ifndef SGX_HW_SIM
support = get_sgx_support();
if (!SGX_OK(support)) {
sgx_support_perror(support);
exit(1);
}
#endif
status = sgx_create_enclave_search(ENCLAVE_NAME, SGX_DEBUG_FLAG, &token,
&updated, &eid, 0);
if (status != SGX_SUCCESS) {
if (status == SGX_ERROR_ENCLAVE_FILE_ACCESS) {
fprintf(stderr, "sgx_create_enclave: %s: file not found\n", ENCLAVE_NAME);
fprintf(stderr, "Did you forget to set LD_LIBRARY_PATH?\n");
} else {
fprintf(stderr, "%s: 0x%04x\n", ENCLAVE_NAME, status);
}
exit(1);
}
fprintf(stderr, "Enclave launched\n");
status = tgmp_init(eid);
if (status != SGX_SUCCESS) {
fprintf(stderr, "ECALL tgmp_init: 0x%04x\n", status);
exit(1);
}
fprintf(stderr, "libtgmp initialized\n");
}
int sgxServerInited = 0;
void init_all() {
if (sgxServerInited == 1)
return;
sgxServerInited = 1;
init_server();
init_enclave();
init_daemon();
}
//
// Created by kladko on 9/2/19.
//
#ifndef SGXWALLET_SERVERINIT_H
#define SGXWALLET_SERVERINIT_H
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
EXTERNC void init_all();
EXTERNC void init_daemon();
EXTERNC void init_enclave();
#endif //SGXWALLET_SERVERINIT_H
......@@ -12,52 +12,38 @@ class AbstractStubServer : public jsonrpc::AbstractServer<AbstractStubServer>
public:
AbstractStubServer(jsonrpc::AbstractServerConnector &conn, jsonrpc::serverVersion_t type = jsonrpc::JSONRPC_SERVER_V2) : jsonrpc::AbstractServer<AbstractStubServer>(conn, type)
{
this->bindAndAddMethod(jsonrpc::Procedure("sayHello", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, "name",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::sayHelloI);
this->bindAndAddNotification(jsonrpc::Procedure("notifyServer", jsonrpc::PARAMS_BY_NAME, NULL), &AbstractStubServer::notifyServerI);
this->bindAndAddMethod(jsonrpc::Procedure("addNumbers", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractStubServer::addNumbersI);
this->bindAndAddMethod(jsonrpc::Procedure("addNumbers2", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_REAL,"param2",jsonrpc::JSON_REAL, NULL), &AbstractStubServer::addNumbers2I);
this->bindAndAddMethod(jsonrpc::Procedure("isEqual", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::isEqualI);
this->bindAndAddMethod(jsonrpc::Procedure("buildObject", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractStubServer::buildObjectI);
this->bindAndAddMethod(jsonrpc::Procedure("methodWithoutParameters", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, NULL), &AbstractStubServer::methodWithoutParametersI);
this->bindAndAddMethod(jsonrpc::Procedure("importBLSKeyShare", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "index",jsonrpc::JSON_INTEGER,"keyShare",jsonrpc::JSON_STRING,"keyShareName",jsonrpc::JSON_STRING,"n",jsonrpc::JSON_INTEGER,"t",jsonrpc::JSON_INTEGER, NULL), &AbstractStubServer::importBLSKeyShareI);
this->bindAndAddMethod(jsonrpc::Procedure("blsSignMessageHash", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "keyShareName",jsonrpc::JSON_STRING,"messageHash",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::blsSignMessageHashI);
this->bindAndAddMethod(jsonrpc::Procedure("importECDSAKey", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "key",jsonrpc::JSON_STRING,"keyName",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::importECDSAKeyI);
this->bindAndAddMethod(jsonrpc::Procedure("generateECDSAKey", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "keyName",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::generateECDSAKeyI);
this->bindAndAddMethod(jsonrpc::Procedure("ecdsaSignMessageHash", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "keyShareName",jsonrpc::JSON_STRING,"messageHash",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::ecdsaSignMessageHashI);
}
inline virtual void sayHelloI(const Json::Value &request, Json::Value &response)
inline virtual void importBLSKeyShareI(const Json::Value &request, Json::Value &response)
{
response = this->sayHello(request["name"].asString());
response = this->importBLSKeyShare(request["index"].asInt(), request["keyShare"].asString(), request["keyShareName"].asString(), request["n"].asInt(), request["t"].asInt());
}
inline virtual void notifyServerI(const Json::Value &request)
inline virtual void blsSignMessageHashI(const Json::Value &request, Json::Value &response)
{
(void)request;
this->notifyServer();
response = this->blsSignMessageHash(request["keyShareName"].asString(), request["messageHash"].asString());
}
inline virtual void addNumbersI(const Json::Value &request, Json::Value &response)
inline virtual void importECDSAKeyI(const Json::Value &request, Json::Value &response)
{
response = this->addNumbers(request[0u].asInt(), request[1u].asInt());
response = this->importECDSAKey(request["key"].asString(), request["keyName"].asString());
}
inline virtual void addNumbers2I(const Json::Value &request, Json::Value &response)
inline virtual void generateECDSAKeyI(const Json::Value &request, Json::Value &response)
{
response = this->addNumbers2(request[0u].asDouble(), request[1u].asDouble());
response = this->generateECDSAKey(request["keyName"].asString());
}
inline virtual void isEqualI(const Json::Value &request, Json::Value &response)
inline virtual void ecdsaSignMessageHashI(const Json::Value &request, Json::Value &response)
{
response = this->isEqual(request[0u].asString(), request[1u].asString());
response = this->ecdsaSignMessageHash(request["keyShareName"].asString(), request["messageHash"].asString());
}
inline virtual void buildObjectI(const Json::Value &request, Json::Value &response)
{
response = this->buildObject(request[0u].asString(), request[1u].asInt());
}
inline virtual void methodWithoutParametersI(const Json::Value &request, Json::Value &response)
{
(void)request;
response = this->methodWithoutParameters();
}
virtual std::string sayHello(const std::string& name) = 0;
virtual void notifyServer() = 0;
virtual int addNumbers(int param1, int param2) = 0;
virtual double addNumbers2(double param1, double param2) = 0;
virtual bool isEqual(const std::string& param1, const std::string& param2) = 0;
virtual Json::Value buildObject(const std::string& param1, int param2) = 0;
virtual std::string methodWithoutParameters() = 0;
virtual Json::Value importBLSKeyShare(int index, const std::string& keyShare, const std::string& keyShareName, int n, int t) = 0;
virtual Json::Value blsSignMessageHash(const std::string& keyShareName, const std::string& messageHash) = 0;
virtual Json::Value importECDSAKey(const std::string& key, const std::string& keyName) = 0;
virtual Json::Value generateECDSAKey(const std::string& keyName) = 0;
virtual Json::Value ecdsaSignMessageHash(const std::string& keyShareName, const std::string& messageHash) = 0;
};
#endif //JSONRPC_CPP_STUB_ABSTRACTSTUBSERVER_H_
#!/bin/bash
jsonrpcstub spec.json --cpp-server=AbstractStubServer --cpp-client=StubClient
......@@ -166,7 +166,7 @@ print "===>>> Making SSL project"
os.chdir(SSL_MAKE_DIR);
assert subprocess.call(["make", "SGX_SDK=" + SGX_SDK_DIR_SSL, "all", "test"]) == 0
assert subprocess.call(["make", "SGX_SDK=" + SGX_SDK_DIR_SSL, "all", "test"]) == 0
os.chdir(topDir)
......
sudo mkdir -p "/lib/modules/"`uname -r`"/kernel/drivers/intel/sgx"
sudo cp ../linux-sgx-driver/isgx.ko "/lib/modules/"`uname -r`"/kernel/drivers/intel/sgx"
sudo sh -c "cat /etc/modules | grep -Fxq isgx || echo isgx >> /etc/modules"
sudo /sbin/depmod
sudo /sbin/modprobe isgx
sudo dpkg -i *.deb
sudo apt install autoconf texinfo libssl-dev libboost-all-dev libjsonrpccpp-dev libjsonrpccpp-tools
sudo apt install cmake flex bison libprocps-dev ccache autoconf texinfo libssl-dev libboost-all-dev libjsonrpccpp-dev libjsonrpccpp-tools
//
// Created by kladko on 8/14/19.
//
#define GMP_WITH_SGX
#include <string.h>
#include <cstdint>
#include "../sgxwallet_common.h"
#include "BLSEnclave.h"
#include "libff/algebra/curves/alt_bn128/alt_bn128_init.hpp"
#include "libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp"
std::string *stringFromKey(libff::alt_bn128_Fr *_key) {
mpz_t t;
mpz_init(t);
_key->as_bigint().to_mpz(t);
char arr[mpz_sizeinbase(t, 10) + 2];
char *tmp = mpz_get_str(arr, 10, t);
mpz_clear(t);
return new std::string(tmp);
}
std::string *stringFromFq(libff::alt_bn128_Fq *_fq) {
mpz_t t;
mpz_init(t);
_fq->as_bigint().to_mpz(t);
char arr[mpz_sizeinbase(t, 10) + 2];
char *tmp = mpz_get_str(arr, 10, t);
mpz_clear(t);
return new std::string(tmp);
}
std::string *stringFromG1(libff::alt_bn128_G1 *_g1) {
_g1->to_affine_coordinates();
auto sX = stringFromFq(&_g1->X);
auto sY = stringFromFq(&_g1->Y);
auto sG1 = new std::string(*sX + ":" + *sY);
delete (sX);
delete (sY);
return sG1;
}
libff::alt_bn128_Fr *keyFromString(const char *_keyString) {
return new libff::alt_bn128_Fr(_keyString);
}
int inited = 0;
void init() {
if (inited == 1)
return;
inited = 1;
libff::init_alt_bn128_params();
}
void checkKey(int *err_status, char *err_string, const char *_keyString) {
uint64_t keyLen = strnlen(_keyString, MAX_KEY_LENGTH);
// check that key is zero terminated string
if (keyLen == MAX_KEY_LENGTH) {
snprintf(err_string, MAX_ERR_LEN, "keyLen != MAX_KEY_LENGTH");
return;
}
*err_status = -2;
if (_keyString == nullptr) {
snprintf(err_string, BUF_LEN, "Null key");
return;
}
*err_status = -3;
// check that key is padded with 0s
for (int i = keyLen; i < MAX_KEY_LENGTH; i++) {
if (_keyString[i] != 0) {
snprintf(err_string, BUF_LEN, "Unpadded key");
}
}
std::string ks(_keyString);
// std::string keyString =
// "4160780231445160889237664391382223604184857153814275770598791864649971919844";
auto key = keyFromString(ks.c_str());
auto s1 = stringFromKey(key);
if (s1->compare(ks) != 0) {
throw std::exception();
}
*err_status = 0;
return;
}
bool enclave_sign(const char *_keyString, const char *_hashXString, const char *_hashYString,
char* sig) {
libff::init_alt_bn128_params();
auto key = keyFromString(_keyString);
if (key == nullptr) {
throw std::exception();
}
libff::alt_bn128_Fq hashX(_hashXString);
libff::alt_bn128_Fq hashY(_hashYString);
libff::alt_bn128_Fq hashZ = 1;
libff::alt_bn128_G1 hash(hashX, hashY, hashZ);
libff::alt_bn128_G1 sign = key->as_bigint() * hash; // sign
sign.to_affine_coordinates();
auto r = stringFromG1(&sign);
memset(sig, 0, BUF_LEN);
strncpy(sig, r->c_str(), BUF_LEN);
delete r;
return true;
}
......@@ -2,8 +2,8 @@
// Created by kladko on 8/14/19.
//
#ifndef SGXD_BLSUTILS_H
#define SGXD_BLSUTILS_H
#ifndef SGXWALLET_BLSUTILS_H
#define SGXWALLET_BLSUTILS_H
......@@ -13,10 +13,13 @@
#define EXTERNC
#endif
EXTERNC bool check_key(const char* _keyString);
EXTERNC void checkKey(int *err_status, char *err_string, const char* _keyString);
EXTERNC bool sign(const char *_keyString, const char* _hashXString, const char* _hashYString,
char* _sig);
EXTERNC void check_key(int *err_status, char *err_string, const char* _keyString);
EXTERNC bool enclave_sign(const char *_keyString, const char* _hashXString, const char* _hashYString, char* _sig);
......@@ -26,5 +29,7 @@ EXTERNC void carray2Hex(const unsigned char *d, int _len, char* _hexArray);
EXTERNC bool hex2carray(const char * _hex, uint64_t *_bin_len,
uint8_t* _bin );
EXTERNC void init();
#endif //SGXD_BLSUTILS_H
#endif //SGXWALLET_BLSUTILS_H
//
// Created by kladko on 8/14/19.
//
#define GMP_WITH_SGX
#include <string.h>
#include <cstdint>
#include "../sgxwallet_common.h"
#include "BLSUtils.h"
#include "libff/algebra/curves/alt_bn128/alt_bn128_init.hpp"
#include "libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp"
std::string *stringFromKey(libff::alt_bn128_Fr *_key) {
mpz_t t;
mpz_init(t);
_key->as_bigint().to_mpz(t);
char arr[mpz_sizeinbase(t, 10) + 2];
char *tmp = mpz_get_str(arr, 10, t);
mpz_clear(t);
return new std::string(tmp);
}
std::string *stringFromFq(libff::alt_bn128_Fq*_fq) {
mpz_t t;
mpz_init(t);
_fq->as_bigint().to_mpz(t);
char arr[mpz_sizeinbase(t, 10) + 2];
char *tmp = mpz_get_str(arr, 10, t);
mpz_clear(t);
return new std::string(tmp);
}
std::string *stringFromG1(libff::alt_bn128_G1 *_g1) {
_g1->to_affine_coordinates();
auto sX = stringFromFq(&_g1->X);
auto sY = stringFromFq(&_g1->Y);
auto sG1 = new std::string(*sX + ":" + *sY);
delete(sX);
delete(sY);
return sG1;
}
libff::alt_bn128_Fr *keyFromString(const char* _keyString) {
return new libff::alt_bn128_Fr(_keyString);
}
bool check_key(const char *_keyString) {
libff::init_alt_bn128_params();
if (_keyString == nullptr)
return false;
std::string ks(_keyString);
// std::string keyString =
// "4160780231445160889237664391382223604184857153814275770598791864649971919844";
auto key = keyFromString(ks.c_str());
auto s1 = stringFromKey(key);
if (s1->compare(ks) != 0)
return false;
if (s1->size() < 10)
return false;
if (s1->size() >= 100)
return false;
return true;
}
bool sign(const char *_keyString, const char* _hashXString, const char* _hashYString,
char sig[BUF_LEN]) {
auto key = keyFromString(_keyString);
libff::alt_bn128_Fq hashX(_hashXString);
libff::alt_bn128_Fq hashY(_hashYString);
libff::alt_bn128_Fq hashZ = 1;
libff::alt_bn128_G1 hash(hashX, hashY, hashZ);
libff::alt_bn128_G1 sign = key->as_bigint() * hash; // sign
sign.to_affine_coordinates();
auto r = stringFromG1(&sign);
memset(sig, 0, BUF_LEN);
strncpy(sig, r->c_str(), BUF_LEN);
delete r;
return true;
}
This diff is collapsed.
......@@ -52,7 +52,7 @@ enclave {
public void ecdsa_sign_message (
[user_check] int *err_status,
[out, count = 1024] char* err_string,
[in, count = 1024] unsigned char* encrypted_key,
[in, count = 1024] uint8_t* encrypted_key,
uint32_t enc_len,
[in, count = 1024] uint8_t* hash,
[out, count = 1024] char* signature);
......
......@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "sgxwallet.h"
#include "BLSCrypto.h"
#include "ServerInit.h"
......
......@@ -2,8 +2,8 @@
// Created by kladko on 9/3/19.
//
#ifndef SGXD_SGXD_H
#define SGXD_SGXD_H
#ifndef SGXWALLET_SGXWALLET_H
#define SGXWALLET_SGXWALLET_H
#include "sgxwallet_common.h"
......@@ -22,4 +22,4 @@ extern sgx_status_t status;
#endif //SGXD_SGXD_H
#endif //SGXWALLET_SGXWALLET_H
......@@ -29,4 +29,25 @@
#define DKG_BUFER_LENGTH 1250
#define DKG_MAX_SEALED_LEN 2000
#endif //SGXD_SGXD_COMMON_H
#define UNKNOWN_ERROR -1
#define PLAINTEXT_KEY_TOO_LONG -2
#define UNPADDED_KEY -3
#define NULL_KEY -4
#define INCORRECT_STRING_CONVERSION -5
#define ENCRYPTED_KEY_TOO_LONG -6
#define SEAL_KEY_FAILED -7
#define KEY_SHARE_DOES_NOT_EXIST -7
#define KEY_SHARE_ALREADY_EXISTS -8
#define COULD_NOT_ACCESS_DATABASE -9
#define NULL_DATABASE -10
#define WALLETDB_NAME "sgxwallet.db"
#define ENCLAVE_NAME "secure_enclave.signed.so"
#endif //SGXWALLET_SGXWALLET_COMMON_H
[
{
"name": "sayHello",
"name": "importBLSKeyShare",
"params": {
"name": "Peter"
"keyShareName": "key1",
"n": 2,
"t": 2,
"index" : 2,
"keyShare": "1122334455"
},
"returns": "Hello Peter"
},
{
"name": "notifyServer"
},
{
"name": "addNumbers",
"params": [
3,
4
],
"returns": 7
"returns": {
"status": 0,
"errorMessage": "12345",
"encryptedKeyShare": "12345"
}
},
{
"name": "addNumbers2",
"params": [
3.2,
4.1
],
"returns": 7.5
"name": "blsSignMessageHash",
"params": {
"keyShareName": "key1",
"messageHash": "1122334455"
},
"returns": {
"status": 0,
"errorMessage": "12345",
"signatureShare": "12345"
}
},
{
"name": "isEqual",
"params": [
"string1",
"string2"
],
"returns": false
"name": "importECDSAKey",
"params": {
"keyName": "key1",
"key": "1122334455"
},
"returns": {
"status": 0,
"errorMessage": "12345",
"encryptedKey": "12345"
}
},
{
"name": "buildObject",
"params": [
"peter",
1990
],
"name": "generateECDSAKey",
"params": {
"keyName": "key1"
},
"returns": {
"name": "peter",
"year": 1990
"status": 0,
"errorMessage": "12345",
"encryptedKey": "12345"
}
},
{
"name" : "methodWithoutParameters",
"returns": "String"
"name": "ecdsaSignMessageHash",
"params": {
"keyShareName": "key1",
"messageHash": "1122334455"
},
"returns": {
"status": 0,
"errorMessage": "12345",
"signature": "12345"
}
}
]
\ No newline at end of file
......@@ -12,73 +12,60 @@ class StubClient : public jsonrpc::Client
public:
StubClient(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {}
std::string sayHello(const std::string& name) throw (jsonrpc::JsonRpcException)
Json::Value importBLSKeyShare(int index, const std::string& keyShare, const std::string& keyShareName, int n, int t) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p["name"] = name;
Json::Value result = this->CallMethod("sayHello",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
void notifyServer() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
this->CallNotification("notifyServer",p);
}
int addNumbers(int param1, int param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("addNumbers",p);
if (result.isIntegral())
return result.asInt();
p["index"] = index;
p["keyShare"] = keyShare;
p["keyShareName"] = keyShareName;
p["n"] = n;
p["t"] = t;
Json::Value result = this->CallMethod("importBLSKeyShare",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
double addNumbers2(double param1, double param2) throw (jsonrpc::JsonRpcException)
Json::Value blsSignMessageHash(const std::string& keyShareName, const std::string& messageHash) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("addNumbers2",p);
if (result.isDouble())
return result.asDouble();
p["keyShareName"] = keyShareName;
p["messageHash"] = messageHash;
Json::Value result = this->CallMethod("blsSignMessageHash",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool isEqual(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
Json::Value importECDSAKey(const std::string& key, const std::string& keyName) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("isEqual",p);
if (result.isBool())
return result.asBool();
p["key"] = key;
p["keyName"] = keyName;
Json::Value result = this->CallMethod("importECDSAKey",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value buildObject(const std::string& param1, int param2) throw (jsonrpc::JsonRpcException)
Json::Value generateECDSAKey(const std::string& keyName) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("buildObject",p);
p["keyName"] = keyName;
Json::Value result = this->CallMethod("generateECDSAKey",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string methodWithoutParameters() throw (jsonrpc::JsonRpcException)
Json::Value ecdsaSignMessageHash(const std::string& keyShareName, const std::string& messageHash) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("methodWithoutParameters",p);
if (result.isString())
return result.asString();
p["keyShareName"] = keyShareName;
p["messageHash"] = messageHash;
Json::Value result = this->CallMethod("ecdsaSignMessageHash",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
......
......@@ -31,10 +31,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "sgx_tcrypto.h"
#include "sgx_tseal.h"
#include <sgx_tgmp.h>
#include <sgx_trts.h>
#include <jsonrpccpp/server/connectors/httpserver.h>
#include "sgxwallet_common.h"
#include "create_enclave.h"
......@@ -42,29 +40,40 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "sgx_detect.h"
#include <gmp.h>
#include <sgx_urts.h>
#include <stdio.h>
#include "BLSCrypto.h"
#include "ServerInit.h"
#include "RPCException.h"
#include "LevelDB.h"
#include "SGXWalletServer.hpp"
#include <libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp>
#include <libff/algebra/exponentiation/exponentiation.hpp>
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
#include <libff/algebra/fields/fp.hpp>
std::string stringFromFr(libff::alt_bn128_Fr& el) {
#include <dkg/dkg.h>
mpz_t t;
mpz_init(t);
#define ENCLAVE_NAME "secure_enclave.signed.so"
el.as_bigint().to_mpz(t);
char arr[mpz_sizeinbase(t, 10) + 2];
char *tmp = mpz_get_str(arr, 10, t);
mpz_clear(t);
return std::string(tmp);
}
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
void usage() {
fprintf(stderr, "usage: sgxwallet\n");
exit(1);
fprintf(stderr, "usage: sgxwallet\n");
exit(1);
}
sgx_launch_token_t token = {0};
......@@ -72,73 +81,173 @@ sgx_enclave_id_t eid;
sgx_status_t status;
int updated;
#define TEST_BLS_KEY_SHARE "4160780231445160889237664391382223604184857153814275770598791864649971919844"
#define TEST_BLS_KEY_NAME "SCHAIN:17:INDEX:5:KEY:1"
std::string stringFromFr(libff::alt_bn128_Fr& el) {
void reset_db() {
REQUIRE(system("rm -rf " WALLETDB_NAME) == 0);
}
mpz_t t;
mpz_init(t);
char* encryptTestKey() {
el.as_bigint().to_mpz(t);
const char *key = TEST_BLS_KEY_SHARE;
char arr[mpz_sizeinbase(t, 10) + 2];
char *tmp = mpz_get_str(arr, 10, t);
mpz_clear(t);
int errStatus = -1;
return std::string(tmp);
char *errMsg = (char *) calloc(BUF_LEN, 1);
char *encryptedKeyHex = encryptBLSKeyShare2Hex(&errStatus, errMsg, key);
REQUIRE(encryptedKeyHex != nullptr);
REQUIRE(errStatus == 0);
printf("Encrypt key completed with status: %d %s \n", errStatus, errMsg);
printf("Encrypted key len %d\n", (int) strlen(encryptedKeyHex));
printf("Encrypted key %s \n", encryptedKeyHex);
return encryptedKeyHex;
}
TEST_CASE( "BLS sign test", "[bls-sign]" ) {
TEST_CASE("BLS key encrypt", "[bls-key-encrypt]") {
init_all();
const char *key = "4160780231445160889237664391382223604184857153814275770598"
"791864649971919844";
init_all();
char* key = encryptTestKey();
REQUIRE(key != nullptr);
char* keyArray = (char*) calloc(128, 1);
}
uint8_t* encryptedKey = (uint8_t*) calloc(1024, 1);
char* errMsg = (char*) calloc(1024,1);
TEST_CASE("BLS key encrypt/decrypt", "[bls-key-encrypt-decrypt]") {
{
strncpy((char *)keyArray, (char*)key, 128);
int err_status = 0;
init_all();
unsigned int enc_len = 0;
int errStatus = -1;
char* errMsg = (char*) calloc(BUF_LEN, 1);
status = encrypt_key(eid, &err_status, errMsg, keyArray, encryptedKey, &enc_len);
REQUIRE(status == SGX_SUCCESS);
printf("Encrypt key completed with status: %d %s \n", err_status, errMsg);
printf(" Encrypted key len %d\n", enc_len);
char* encryptedKey = encryptTestKey();
REQUIRE(encryptedKey != nullptr);
char* plaintextKey = decryptBLSKeyShareFromHex(&errStatus, errMsg, encryptedKey);
REQUIRE(errStatus == 0);
char result[2* BUF_LEN];
REQUIRE(strcmp(plaintextKey, TEST_BLS_KEY_SHARE) == 0);
carray2Hex(encryptedKey, enc_len, result);
printf("Decrypt key completed with status: %d %s \n", errStatus, errMsg);
printf("Decrypted key len %d\n", (int) strlen(plaintextKey));
printf("Decrypted key: %s\n", plaintextKey);
uint64_t dec_len = 0;
uint8_t bin[BUF_LEN];
}
}
REQUIRE(hex2carray(result, &dec_len, bin));
TEST_CASE("BLS key import", "[bls-key-import]") {
reset_db();
init_all();
for (uint64_t i=0; i < dec_len; i++) {
REQUIRE(bin[i] == encryptedKey[i]);
}
REQUIRE(dec_len == enc_len);
printf("Result: %s", result);
auto result = importBLSKeyShareImpl(1, TEST_BLS_KEY_SHARE, TEST_BLS_KEY_NAME, 2, 2);
printf("\n Length: %d \n", enc_len);
REQUIRE(result["status"] == 0);
REQUIRE(result["encryptedKeyShare"] != "");
}
TEST_CASE("BLS sign test", "[bls-sign]") {
init_all();
char* encryptedKeyHex = encryptTestKey();
REQUIRE(encryptedKeyHex != nullptr);
const char *hexHash = "001122334455667788" "001122334455667788" "001122334455667788" "001122334455667788";
char* hexHashBuf = (char*) calloc(BUF_LEN, 1);
strncpy(hexHashBuf, hexHash, BUF_LEN);
char sig[BUF_LEN];
REQUIRE(sign(encryptedKeyHex, hexHashBuf, 2, 2, 1, sig));
printf("Signature is: %s \n", sig );
}
TEST_CASE("Server BLS sign test", "[bls-server-sign]") {
reset_db();
init_all();
auto result = importBLSKeyShareImpl(1, TEST_BLS_KEY_SHARE, TEST_BLS_KEY_NAME, 2, 2);
REQUIRE(result["status"] == 0);
REQUIRE(result["encryptedKeyShare"] != "");
const char *hexHash = "001122334455667788" "001122334455667788" "001122334455667788" "001122334455667788";
REQUIRE_NOTHROW(result = blsSignMessageHashImpl(TEST_BLS_KEY_NAME, hexHash));
if (result["status"] != 0) {
printf("Error message: %s", result["errorMessage"].asString().c_str());
}
REQUIRE(result["status"] == 0);
REQUIRE(result["signatureShare"] != "");
printf("Signature is: %s \n", result["signatureShare"].asString().c_str());
}
TEST_CASE("KeysDB test", "[keys-db]") {
reset_db();
init_all();
string key = TEST_BLS_KEY_SHARE;
string value = TEST_BLS_KEY_SHARE;
REQUIRE_THROWS(readKeyShare(key));
writeKeyShare(key, value, 1, 2, 1);
REQUIRE(readKeyShare(key) != nullptr);
// put your test here
}
TEST_CASE( "DKG gen test", "[dkg-gen]" ) {
init_all();
......@@ -239,4 +348,3 @@ TEST_CASE( "DKG auto secret shares test", "[dkg-s_shares]" ) {
free(secret_shares);
}
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