Skip to content

Commit

Permalink
Remove exceprions from public and private key code
Browse files Browse the repository at this point in the history
  • Loading branch information
relatko committed Oct 2, 2023
1 parent e167dea commit f6ceb9c
Show file tree
Hide file tree
Showing 12 changed files with 362 additions and 250 deletions.
6 changes: 6 additions & 0 deletions src/assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,10 @@ extern void assert(int cond, const char* msgStr);

#define ASSERT(cond) assert((cond), _SHORTEN_(_FILE_LINE_, _MAX_ASSERT_LENGTH_))

/** In crypto code, instead of asserts we return an error. **/
#define CX_ASSERTION_ERROR 0x8FFFFFFF

/** In crypto code, instead of throwing, we return an error **/
#define CX_REJECTED_BY_POLICY 0x8FFFFFFE

#endif // H_FIO_APP_ASSERT
13 changes: 8 additions & 5 deletions src/diffieHellman.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ __noinline_due_to_stack__ void dh_init_aes_key(dh_aes_key_t* dhKey,
BEGIN_TRY {
TRY {
TRACE_STACK_USAGE();
derivePrivateKey(pathSpec, &privateKey);
CX_THROW(derivePrivateKey(pathSpec, &privateKey));

// this is how it is done...
cx_err_t err = cx_ecdh_no_throw(&privateKey,
Expand All @@ -101,14 +101,17 @@ __noinline_due_to_stack__ void dh_init_aes_key(dh_aes_key_t* dhKey,
publicKey->W_len,
basicSecret,
SIZEOF(basicSecret));
ASSERT(err == CX_OK);
sha_512_hash(basicSecret, SIZEOF(basicSecret), secret, SIZEOF(secret));
sha_512_hash(secret, SIZEOF(secret), K, SIZEOF(K));
CX_THROW(err);
err = sha_512_hash(basicSecret, SIZEOF(basicSecret), secret, SIZEOF(secret));
CX_THROW(err);
err = sha_512_hash(secret, SIZEOF(secret), K, SIZEOF(K));
CX_THROW(err);

// First DH_AES_SECRET_SIZE bytes are used to compute shared secret, then DH_KM_SIZE are
// used as Km for HMAC calculation
STATIC_ASSERT(SIZEOF(K) == DH_AES_SECRET_SIZE + DH_KM_SIZE, "Incompatible types");
cx_aes_init_key_no_throw(K, DH_AES_SECRET_SIZE, &dhKey->aesKey);
err = cx_aes_init_key_no_throw(K, DH_AES_SECRET_SIZE, &dhKey->aesKey);
CX_THROW(err);
STATIC_ASSERT(SIZEOF(dhKey->km) == DH_KM_SIZE, "Incompatible types");
memmove(dhKey->km, K + DH_AES_SECRET_SIZE, DH_KM_SIZE);
dhKey->initialized_magic = DH_AES_KEY_INITIALIZED_MAGIC;
Expand Down
64 changes: 37 additions & 27 deletions src/eos_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
#include "cx.h"
#include "utils.h"

#define FORWARD_CX_ERROR(call) \
{ \
cx_err_t callResult = (call); \
if (callResult != CX_OK) return callResult; \
}

/**
* EOS way to check if a signature is canonical :/
*/
Expand Down Expand Up @@ -80,14 +86,14 @@ int ecdsa_der_to_sig(const uint8_t *der, uint8_t *sig) {
* - V, out
* - K, out
*/
void rng_rfc6979(unsigned char *rnd,
unsigned char *h1,
unsigned char *x,
unsigned int x_len,
const unsigned char *q,
unsigned int q_len,
unsigned char *V,
unsigned char *K) {
cx_err_t rng_rfc6979(unsigned char *rnd,
unsigned char *h1,
unsigned char *x,
unsigned int x_len,
const unsigned char *q,
unsigned int q_len,
unsigned char *V,
unsigned char *K) {
unsigned int h_len, found, i;
cx_hmac_sha256_t hmac;

Expand All @@ -104,32 +110,32 @@ void rng_rfc6979(unsigned char *rnd,
memset(K, 0x00, h_len);
// d. Set: K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1))
V[h_len] = 0;
CX_THROW(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
CX_THROW(cx_hmac_no_throw((cx_hmac_t *) &hmac, 0, V, h_len + 1, K, 32));
CX_THROW(cx_hmac_no_throw((cx_hmac_t *) &hmac, 0, x, x_len, K, 32));
CX_THROW(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, h1, h_len, K, 32));
FORWARD_CX_ERROR(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
FORWARD_CX_ERROR(cx_hmac_no_throw((cx_hmac_t *) &hmac, 0, V, h_len + 1, K, 32));
FORWARD_CX_ERROR(cx_hmac_no_throw((cx_hmac_t *) &hmac, 0, x, x_len, K, 32));
FORWARD_CX_ERROR(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, h1, h_len, K, 32));
// e. Set: V = HMAC_K(V)
CX_THROW(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
CX_THROW(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, V, h_len, V, 32));
FORWARD_CX_ERROR(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
FORWARD_CX_ERROR(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, V, h_len, V, 32));
// f. Set: K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1))
V[h_len] = 1;
CX_THROW(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
CX_THROW(cx_hmac_no_throw((cx_hmac_t *) &hmac, 0, V, h_len + 1, K, 32));
CX_THROW(cx_hmac_no_throw((cx_hmac_t *) &hmac, 0, x, x_len, K, 32));
CX_THROW(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, h1, h_len, K, 32));
FORWARD_CX_ERROR(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
FORWARD_CX_ERROR(cx_hmac_no_throw((cx_hmac_t *) &hmac, 0, V, h_len + 1, K, 32));
FORWARD_CX_ERROR(cx_hmac_no_throw((cx_hmac_t *) &hmac, 0, x, x_len, K, 32));
FORWARD_CX_ERROR(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, h1, h_len, K, 32));
// g. Set: V = HMAC_K(V) --
CX_THROW(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
CX_THROW(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, V, h_len, V, 32));
FORWARD_CX_ERROR(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
FORWARD_CX_ERROR(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, V, h_len, V, 32));
// initial setup only once
x = NULL;
} else {
// h.3 K = HMAC_K(V || 0x00)
V[h_len] = 0;
CX_THROW(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
CX_THROW(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, V, h_len + 1, K, 32));
FORWARD_CX_ERROR(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
FORWARD_CX_ERROR(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, V, h_len + 1, K, 32));
// h.3 V = HMAC_K(V)
CX_THROW(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
CX_THROW(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, V, h_len, V, 32));
FORWARD_CX_ERROR(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
FORWARD_CX_ERROR(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, V, h_len, V, 32));
}

// generate candidate
Expand All @@ -145,8 +151,8 @@ void rng_rfc6979(unsigned char *rnd,
if (x_len < h_len) {
h_len = x_len;
}
CX_THROW(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
CX_THROW(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, V, h_len, V, 32));
FORWARD_CX_ERROR(cx_hmac_sha256_init_no_throw(&hmac, K, 32));
FORWARD_CX_ERROR(cx_hmac_no_throw((cx_hmac_t *) &hmac, CX_LAST, V, h_len, V, 32));
memcpy(rnd, V, h_len);
x_len -= h_len;
}
Expand All @@ -159,6 +165,8 @@ void rng_rfc6979(unsigned char *rnd,
}
}
}

return CX_OK;
}

unsigned char const BASE58ALPHABET[58] = {
Expand Down Expand Up @@ -229,7 +237,9 @@ uint32_t compressed_public_key_to_wif(const uint8_t *publicKey,
uint8_t check[20];
cx_ripemd160_t riprip;
cx_ripemd160_init(&riprip);
CX_THROW(cx_hash_no_throw(&riprip.header, CX_LAST, temp, 33, check, sizeof(check)));
if (cx_hash_no_throw(&riprip.header, CX_LAST, temp, 33, check, sizeof(check)) != CX_OK) {
return 0;
}
memcpy(temp + 33, check, 4);

explicit_bzero(out, outLength);
Expand Down
18 changes: 10 additions & 8 deletions src/eos_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,22 @@

#include <stdbool.h>
#include <stdint.h>
#include "cx.h"

unsigned char check_canonical(uint8_t *rs);

int ecdsa_der_to_sig(const uint8_t *der, uint8_t *sig);

void rng_rfc6979(unsigned char *rnd,
unsigned char *h1,
unsigned char *x,
unsigned int x_len,
const unsigned char *q,
unsigned int q_len,
unsigned char *V,
unsigned char *K);
cx_err_t rng_rfc6979(unsigned char *rnd,
unsigned char *h1,
unsigned char *x,
unsigned int x_len,
const unsigned char *q,
unsigned int q_len,
unsigned char *V,
unsigned char *K);

// returns 0 on error
uint32_t public_key_to_wif(const uint8_t *publicKey,
uint32_t keyLength,
char *out,
Expand Down
5 changes: 4 additions & 1 deletion src/getPublicKey.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ static void getPublicKey_ui_runStep() {
SIZEOF(ctx->pubKey.W),
(char*) G_io_apdu_buffer + SIZEOF(ctx->pubKey.W),
MAX_WIF_PUBKEY_LENGTH);
ASSERT(wifkeylen != 0);
ASSERT(wifkeylen <= BUFFER_SIZE_PARANOIA);
// we do not copy trailing 0
io_send_buf(SUCCESS, G_io_apdu_buffer, SIZEOF(ctx->pubKey.W) + wifkeylen - 1);

Expand All @@ -77,7 +79,8 @@ static void runGetPublicKeyUIFlow() {

{
// Calculation
derivePublicKey(&ctx->pathSpec, &ctx->pubKey);
cx_err_t err = derivePublicKey(&ctx->pathSpec, &ctx->pubKey);
ASSERT(err == CX_OK);
ctx->responseReadyMagic = RESPONSE_READY_MAGIC;
}

Expand Down
Loading

0 comments on commit f6ceb9c

Please sign in to comment.