Unverified Commit 7bf43a09 authored by kladko's avatar kladko

SKALE-1880-fix-ecdsa

parent ce9530ae
......@@ -32,13 +32,10 @@
#include <random>
#include "spdlog/spdlog.h"
#include "common.h"
#include "secure_enclave/Verify.h"
#include "BLSCrypto.h"
......@@ -46,7 +43,6 @@
#include "ECDSACrypto.h"
string concatPubKeyWith0x(char *pub_key_x, char *pub_key_y) {
string px = pub_key_x;
string py = pub_key_y;
......@@ -55,35 +51,35 @@ string concatPubKeyWith0x(char *pub_key_x, char *pub_key_y) {
}
void fillRandomBuffer(vector<unsigned char>& _buffer) {
ifstream devRandom("/dev/urandom", ios::in|ios::binary);
void fillRandomBuffer(vector<unsigned char> &_buffer) {
ifstream devRandom("/dev/urandom", ios::in | ios::binary);
devRandom.exceptions(ifstream::failbit | ifstream::badbit);
devRandom.read((char*) _buffer.data(), _buffer.size());
devRandom.read((char *) _buffer.data(), _buffer.size());
devRandom.close();
}
vector<string> genECDSAKey() {
vector <string> genECDSAKey() {
vector<char> errMsg(1024, 0);
int errStatus = 0;
vector<uint8_t> encr_pr_key(1024, 0);
vector<char>pub_key_x(1024, 0);
vector<char>pub_key_y(1024, 0);
vector <uint8_t> encr_pr_key(1024, 0);
vector<char> pub_key_x(1024, 0);
vector<char> pub_key_y(1024, 0);
uint32_t enc_len = 0;
if (!encryptKeys)
status = trustedGenerateEcdsaKey(eid, &errStatus, errMsg.data(), encr_pr_key.data(),
&enc_len, pub_key_x.data(), pub_key_y.data());
&enc_len, pub_key_x.data(), pub_key_y.data());
else
status = trustedGenerateEcdsaKeyAES(eid, &errStatus,
errMsg.data(), encr_pr_key.data(), &enc_len,
pub_key_x.data(), pub_key_y.data());
errMsg.data(), encr_pr_key.data(), &enc_len,
pub_key_x.data(), pub_key_y.data());
if (status != SGX_SUCCESS || errStatus != 0) {
spdlog::error("RPCException thrown with status {}", status);
throw SGXException(status, errMsg.data());
}
vector<string> keys(3);
vector <string> keys(3);
vector<char> hexEncrKey(BUF_LEN * 2, 0);
carray2Hex(encr_pr_key.data(), enc_len, hexEncrKey.data());
......@@ -91,10 +87,10 @@ vector<string> genECDSAKey() {
keys.at(1) = string(pub_key_x.data()) + string(pub_key_y.data());
vector<unsigned char> randBuffer(32,0);
vector<unsigned char> randBuffer(32, 0);
fillRandomBuffer(randBuffer);
vector<char> rand_str(64,0);
vector<char> rand_str(64, 0);
carray2Hex(randBuffer.data(), 32, rand_str.data());
......@@ -110,7 +106,7 @@ string getECDSAPubKey(const char *_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);
vector <uint8_t> encrPrKey(BUF_LEN, 0);
int errStatus = 0;
uint64_t enc_len = 0;
......@@ -121,114 +117,126 @@ string getECDSAPubKey(const char *_encryptedKeyHex) {
if (!encryptKeys)
status = trustedGetPublicEcdsaKey(eid, &errStatus, errMsg.data(), encrPrKey.data(), enc_len, pubKeyX.data(),
pubKeyY.data());
else status = trustedGetPublicEcdsaKeyAES(eid, &errStatus,
errMsg.data(), encrPrKey.data(), enc_len, pubKeyX.data(), pubKeyY.data());
pubKeyY.data());
else
status = trustedGetPublicEcdsaKeyAES(eid, &errStatus,
errMsg.data(), encrPrKey.data(), enc_len, pubKeyX.data(), pubKeyY.data());
if (errStatus != 0) {
throw SGXException(-666, errMsg.data());
}
string pubKey = string(pubKeyX.data()) + string(pubKeyY.data());//concatPubKeyWith0x(pub_key_x, pub_key_y);//
if (pubKey.size() != 128) {
spdlog::error("Incorrect pub key size", status);
throw SGXException(666, "Incorrect pub key size");
}
return pubKey;
}
vector<string> ecdsaSignHash(const char *encryptedKeyHex, const char *hashHex, int base) {
vector<string> signature_vect(3);
char *errMsg = (char *) calloc(1024, 1);
int errStatus = 0;
char *signature_r = (char *) calloc(1024, 1);
char *signature_s = (char *) calloc(1024, 1);
uint8_t *encr_key = (uint8_t *) calloc(1024, 1);
uint8_t signature_v = 0;
uint64_t dec_len = 0;
void verifyECDSASig(string& pubKeyStr, const char *hashHex, const char *signatureR,
const char *signatureS) {
signature sig = signature_init();
//uint8_t encr_key[BUF_LEN];
if (!hex2carray(encryptedKeyHex, &dec_len, encr_key)) {
throw SGXException(INVALID_HEX, "Invalid encryptedKeyHex");
}
auto r = pubKeyStr.substr(0, 64);
auto s = pubKeyStr.substr(64, 128);
domain_parameters curve = domain_parameters_init();
domain_parameters_load_curve(curve, secp256k1);
point publicKey = point_init();
if (!encryptKeys) {
status = trustedEcdsaSign(eid, &errStatus, errMsg, encr_key, ECDSA_ENCR_LEN, (unsigned char *) hashHex, signature_r,
signature_s, &signature_v, base);
mpz_t msgMpz;
mpz_init(msgMpz);
if (mpz_set_str(msgMpz, hashHex, 16) == -1) {
spdlog::error("invalid message hash {}", hashHex);
goto clean;
}
signature_set_str(sig, signatureR, signatureS, 16);
point_set_hex(publicKey, r.c_str(), s.c_str());
if (!signature_verify(msgMpz, sig, publicKey, curve)) {
spdlog::error("ECDSA sig not verified");
goto clean;
}
clean:
mpz_clear(msgMpz);
domain_parameters_clear(curve);
point_clear(publicKey);
signature_free(sig);
}
}
else
status = trustedEcdsaSignAES(eid, &errStatus, errMsg, encr_key, dec_len, (unsigned char *) hashHex, signature_r,
signature_s, &signature_v, base);
if (errStatus != 0) {
throw SGXException(-666, errMsg);
}
vector <string> ecdsaSignHash(const char *encryptedKeyHex, const char *hashHex, int base) {
vector <string> signature_vect(3);
vector<char> errMsg(1024, 0);
int errStatus = 0;
vector<char> signatureR(1024, 0);
vector<char> signatureS(1024, 0);
vector<uint8_t> encryptedKey(1024, 0);
uint8_t signatureV = 0;
uint64_t decLen = 0;
string pubKeyStr = "";
shared_ptr<SGXException> exception = NULL;
if (status != SGX_SUCCESS) {
spdlog::error(" failed to sign ");
}
signature_vect.at(0) = to_string(signature_v);
if (base == 16) {
signature_vect.at(1) = "0x" + string(signature_r);
signature_vect.at(2) = "0x" + string(signature_s);
} else {
signature_vect.at(1) = string(signature_r);
signature_vect.at(2) = string(signature_s);
if (!hex2carray(encryptedKeyHex, &decLen, encryptedKey.data())) {
exception = make_shared<SGXException>(INVALID_HEX, "Invalid encryptedKeyHex");
goto clean;
}
pubKeyStr = getECDSAPubKey(encryptedKeyHex);
domain_parameters curve = domain_parameters_init();
domain_parameters_load_curve(curve, secp256k1);
point publicKey = point_init();
mpz_t msgMpz;
mpz_init(msgMpz);
if (!encryptKeys) {
status = trustedEcdsaSign(eid, &errStatus, errMsg.data(),
encryptedKey.data(), ECDSA_ENCR_LEN, (unsigned char *) hashHex,
signatureR.data(),
signatureS.data(), &signatureV, base);
if (mpz_set_str(msgMpz, hashHex, 16) == -1) {
spdlog::error("invalid message hash {}", hashHex);
} else
status = trustedEcdsaSignAES(eid, &errStatus,
errMsg.data(), encryptedKey.data(), decLen, (unsigned char *) hashHex,
signatureR.data(),
signatureS.data(), &signatureV, base);
if (errStatus != 0) {
exception = make_shared<SGXException>(666, errMsg.data());
goto clean;
}
signature_set_str(sig, signature_r, signature_s, 16);
if (!signature_verify(msgMpz, sig, publicKey, curve)) {
spdlog::warn("ECDSA sig not verified");
if (status != SGX_SUCCESS) {
spdlog::error("failed to sign {}", status);
exception = make_shared<SGXException>(666, "failed to sign");
goto clean;
}
signature_vect.at(0) = to_string(signatureV);
if (base == 16) {
signature_vect.at(1) = "0x" + string(signatureR.data());
signature_vect.at(2) = "0x" + string(signatureS.data());
} else {
signature_vect.at(1) = string(signatureR.data());
signature_vect.at(2) = string(signatureS.data());
}
/* Now verify signature */
verifyECDSASig(pubKeyStr, hashHex, signatureR.data(), signatureS.data());
clean:
mpz_clear(msgMpz);
domain_parameters_clear(curve);
point_clear(publicKey);
signature_free(sig);
SAFE_FREE(errMsg);
SAFE_FREE(signature_r);
SAFE_FREE(signature_s);
SAFE_FREE(encr_key);
if (exception)
throw *exception;
return signature_vect;
}
\ No newline at end of file
......@@ -82,14 +82,14 @@ void point_set(point R, point P)
}
/*Set point from strings of a base from 2-62*/
void point_set_str(point p, char *x, char *y, int base)
void point_set_str(point p, const char *x, const char *y, int base)
{
mpz_set_str(p->x, x, base);
mpz_set_str(p->y, y, base);
}
/*Set point from hexadecimal strings*/
void point_set_hex(point p, char *x, char *y)
void point_set_hex(point p, const char *x, const char *y)
{
point_set_str(p,x,y,16);
}
......
......@@ -46,7 +46,7 @@ EXTERNC void point_inverse(point R, point P, domain_parameters curve);
EXTERNC void point_print(point p);
/*Set point from hexadecimal strings*/
EXTERNC void point_set_hex(point p, char *x, char *y);
EXTERNC void point_set_hex(point p, const char *x, const char *y);
/*Set point from decimal unsigned long ints*/
EXTERNC void point_set_ui(point p, unsigned long int x, unsigned long int y);
......@@ -61,7 +61,7 @@ EXTERNC void point_doubling(point R, point P, domain_parameters curve);
EXTERNC void point_multiplication(point R, mpz_t multiplier, point P, domain_parameters curve);
/*Set point from strings of a base from 2-62*/
EXTERNC void point_set_str(point p, char *x, char *y, int base);
EXTERNC void point_set_str(point p, const char *x, const char *y, int base);
/*Compare two points return 1 if not the same, returns 0 if they are the same*/
EXTERNC bool point_cmp(point P, point Q);
......
......@@ -59,13 +59,13 @@ void signature_print(signature sig) {
}
/*Set signature from strings of a base from 2-62*/
void signature_set_str(signature sig, char *r, char *s, int base) {
void signature_set_str(signature sig, const char *r, const char *s, int base) {
mpz_set_str(sig->r, r, base);
mpz_set_str(sig->s, s, base);
}
/*Set signature from hexadecimal strings*/
void signature_set_hex(signature sig, char *r, char *s) {
void signature_set_hex(signature sig, const char *r, const char *s) {
signature_set_str(sig, r, s, 16);
}
......
......@@ -44,10 +44,10 @@ typedef struct signature_s* signature;
EXTERNC signature signature_init();
/*Set signature from strings of a base from 2-62*/
EXTERNC void signature_set_str(signature sig, char *r, char *s, int base);
EXTERNC void signature_set_str(signature sig, const char *r, const char *s, int base);
/*Set signature from hexadecimal strings*/
EXTERNC void signature_set_hex(signature sig, char *r, char *s);
EXTERNC void signature_set_hex(signature sig, const char *r, const char *s);
/*Set signature from decimal unsigned long ints*/
EXTERNC void signature_set_ui(signature sig, unsigned long int r, unsigned long int s);
......
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