introduce confidential macro, mark confidential items

pull/25/head
Jochen Hoenicke 7 years ago committed by Pavol Rusnak
parent e223861848
commit 9dfc6a4477
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -122,7 +122,7 @@ int hdnode_from_xprv(uint32_t depth, uint32_t child_num, const uint8_t *chain_co
int hdnode_from_seed(const uint8_t *seed, int seed_len, const char* curve, HDNode *out)
{
uint8_t I[32 + 32];
static CONFIDENTIAL uint8_t I[32 + 32];
memset(out, 0, sizeof(HDNode));
out->depth = 0;
out->child_num = 0;
@ -130,8 +130,10 @@ int hdnode_from_seed(const uint8_t *seed, int seed_len, const char* curve, HDNod
if (out->curve == 0) {
return 0;
}
hmac_sha512((const uint8_t*) out->curve->bip32_name,
strlen(out->curve->bip32_name), seed, seed_len, I);
static CONFIDENTIAL HMAC_SHA512_CTX ctx;
hmac_sha512_Init(&ctx, (const uint8_t*) out->curve->bip32_name, strlen(out->curve->bip32_name));
hmac_sha512_Update(&ctx, seed, seed_len);
hmac_sha512_Final(&ctx, I);
if (out->curve->params) {
bignum256 a;
@ -141,8 +143,9 @@ int hdnode_from_seed(const uint8_t *seed, int seed_len, const char* curve, HDNod
&& bn_is_less(&a, &out->curve->params->order)) { // < order
break;
}
hmac_sha512((const uint8_t*) out->curve->bip32_name,
strlen(out->curve->bip32_name), I, sizeof(I), I);
hmac_sha512_Init(&ctx, (const uint8_t*) out->curve->bip32_name, strlen(out->curve->bip32_name));
hmac_sha512_Update(&ctx, I, sizeof(I));
hmac_sha512_Final(&ctx, I);
}
MEMSET_BZERO(&a, sizeof(a));
}
@ -168,9 +171,9 @@ uint32_t hdnode_fingerprint(HDNode *node)
int hdnode_private_ckd(HDNode *inout, uint32_t i)
{
uint8_t data[1 + 32 + 4];
uint8_t I[32 + 32];
bignum256 a, b;
static CONFIDENTIAL uint8_t data[1 + 32 + 4];
static CONFIDENTIAL uint8_t I[32 + 32];
static CONFIDENTIAL bignum256 a, b;
if (i & 0x80000000) { // private derivation
data[0] = 0;
@ -186,7 +189,11 @@ int hdnode_private_ckd(HDNode *inout, uint32_t i)
bn_read_be(inout->private_key, &a);
hmac_sha512(inout->chain_code, 32, data, sizeof(data), I);
static CONFIDENTIAL HMAC_SHA512_CTX ctx;
hmac_sha512_Init(&ctx, inout->chain_code, 32);
hmac_sha512_Update(&ctx, data, sizeof(data));
hmac_sha512_Final(&ctx, I);
if (inout->curve->params) {
while (true) {
bool failed = false;
@ -208,7 +215,9 @@ int hdnode_private_ckd(HDNode *inout, uint32_t i)
data[0] = 1;
memcpy(data + 1, I + 32, 32);
hmac_sha512(inout->chain_code, 32, data, sizeof(data), I);
hmac_sha512_Init(&ctx, inout->chain_code, 32);
hmac_sha512_Update(&ctx, data, sizeof(data));
hmac_sha512_Final(&ctx, I);
}
} else {
memcpy(inout->private_key, I, 32);
@ -308,10 +317,10 @@ void hdnode_public_ckd_address_optimized(const curve_point *pub, const uint8_t *
#if USE_BIP32_CACHE
static bool private_ckd_cache_root_set = false;
static HDNode private_ckd_cache_root;
static CONFIDENTIAL HDNode private_ckd_cache_root;
static int private_ckd_cache_index = 0;
static struct {
static CONFIDENTIAL struct {
bool set;
size_t depth;
uint32_t i[BIP32_CACHE_MAXDEPTH];

@ -31,12 +31,13 @@
#include "pbkdf2.h"
#include "bip39_english.h"
#include "options.h"
#include "macros.h"
#if USE_BIP39_CACHE
static int bip39_cache_index = 0;
static struct {
static CONFIDENTIAL struct {
bool set;
char mnemonic[256];
char passphrase[64];
@ -52,7 +53,9 @@ const char *mnemonic_generate(int strength)
}
uint8_t data[32];
random_buffer(data, 32);
return mnemonic_from_data(data, strength / 8);
const char *r = mnemonic_from_data(data, strength / 8);
MEMSET_BZERO(data, sizeof(data));
return r;
}
const uint16_t *mnemonic_generate_indexes(int strength)
@ -62,7 +65,9 @@ const uint16_t *mnemonic_generate_indexes(int strength)
}
uint8_t data[32];
random_buffer(data, 32);
return mnemonic_from_data_indexes(data, strength / 8);
const uint16_t *r = mnemonic_from_data_indexes(data, strength / 8);
MEMSET_BZERO(data, sizeof(data));
return r;
}
const char *mnemonic_from_data(const uint8_t *data, int len)
@ -80,7 +85,7 @@ const char *mnemonic_from_data(const uint8_t *data, int len)
memcpy(bits, data, len);
int mlen = len * 3 / 4;
static char mnemo[24 * 10];
static CONFIDENTIAL char mnemo[24 * 10];
int i, j, idx;
char *p = mnemo;
@ -95,6 +100,7 @@ const char *mnemonic_from_data(const uint8_t *data, int len)
*p = (i < mlen - 1) ? ' ' : 0;
p++;
}
MEMSET_BZERO(bits, sizeof(bits));
return mnemo;
}
@ -114,7 +120,7 @@ const uint16_t *mnemonic_from_data_indexes(const uint8_t *data, int len)
memcpy(bits, data, len);
int mlen = len * 3 / 4;
static uint16_t mnemo[24];
static CONFIDENTIAL uint16_t mnemo[24];
int i, j, idx;
for (i = 0; i < mlen; i++) {
@ -125,6 +131,7 @@ const uint16_t *mnemonic_from_data_indexes(const uint8_t *data, int len)
}
mnemo[i] = idx;
}
MEMSET_BZERO(bits, sizeof(bits));
return mnemo;
}
@ -153,7 +160,8 @@ int mnemonic_check(const char *mnemonic)
char current_word[10];
uint32_t j, k, ki, bi;
uint8_t bits[32 + 1];
memset(bits, 0, sizeof(bits));
MEMSET_BZERO(bits, sizeof(bits));
i = 0; bi = 0;
while (mnemonic[i]) {
j = 0;
@ -221,7 +229,7 @@ void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed
uint8_t salt[8 + 256];
memcpy(salt, "mnemonic", 8);
memcpy(salt + 8, passphrase, passphraselen);
PBKDF2_HMAC_SHA512_CTX pctx;
static CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx;
pbkdf2_hmac_sha512_Init(&pctx, (const uint8_t *)mnemonic, strlen(mnemonic), salt, passphraselen + 8);
if (progress_callback) {
progress_callback(0, BIP39_PBKDF2_ROUNDS);
@ -233,6 +241,7 @@ void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed
}
}
pbkdf2_hmac_sha512_Final(&pctx, seed);
MEMSET_BZERO(salt, sizeof(salt));
#if USE_BIP39_CACHE
// store to cache
if (mnemoniclen < 256 && passphraselen < 64) {

@ -434,13 +434,13 @@ void point_multiply(const ecdsa_curve *curve, const bignum256 *k, const curve_po
assert (bn_is_less(k, &curve->order));
int i, j;
bignum256 a;
static CONFIDENTIAL bignum256 a;
uint32_t *aptr;
uint32_t abits;
int ashift;
uint32_t is_even = (k->val[0] & 1) - 1;
uint32_t bits, sign, nsign;
jacobian_curve_point jres;
static CONFIDENTIAL jacobian_curve_point jres;
curve_point pmult[8];
const bignum256 *prime = &curve->prime;
@ -542,6 +542,8 @@ void point_multiply(const ecdsa_curve *curve, const bignum256 *k, const curve_po
}
conditional_negate(sign, &jres.z, prime);
jacobian_to_curve(&jres, res, prime);
MEMSET_BZERO(&a, sizeof(a));
MEMSET_BZERO(&jres, sizeof(jres));
}
#if USE_PRECOMPUTED_CP
@ -553,10 +555,10 @@ void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, curve_point *
assert (bn_is_less(k, &curve->order));
int i, j;
bignum256 a;
static CONFIDENTIAL bignum256 a;
uint32_t is_even = (k->val[0] & 1) - 1;
uint32_t lowbits;
jacobian_curve_point jres;
static CONFIDENTIAL jacobian_curve_point jres;
const bignum256 *prime = &curve->prime;
// is_even = 0xffffffff if k is even, 0 otherwise.
@ -628,6 +630,8 @@ void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, curve_point *
}
conditional_negate(((a.val[0] >> 4) & 1) - 1, &jres.y, prime);
jacobian_to_curve(&jres, res, prime);
MEMSET_BZERO(&a, sizeof(a));
MEMSET_BZERO(&jres, sizeof(jres));
}
#else

@ -24,11 +24,12 @@
#include <string.h>
#include "hmac.h"
#include "options.h"
#include "macros.h"
void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, const uint32_t keylen)
{
uint8_t i_key_pad[SHA256_BLOCK_LENGTH];
static CONFIDENTIAL uint8_t i_key_pad[SHA256_BLOCK_LENGTH];
memset(i_key_pad, 0, SHA256_BLOCK_LENGTH);
if (keylen > SHA256_BLOCK_LENGTH) {
sha256_Raw(key, keylen, i_key_pad);
@ -51,19 +52,17 @@ void hmac_sha256_Update(HMAC_SHA256_CTX *hctx, const uint8_t *msg, const uint32_
void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac)
{
uint8_t hash[SHA256_DIGEST_LENGTH];
sha256_Final(&(hctx->ctx), hash);
sha256_Final(&(hctx->ctx), hmac);
sha256_Init(&(hctx->ctx));
sha256_Update(&(hctx->ctx), hctx->o_key_pad, SHA256_BLOCK_LENGTH);
sha256_Update(&(hctx->ctx), hash, SHA256_DIGEST_LENGTH);
sha256_Update(&(hctx->ctx), hmac, SHA256_DIGEST_LENGTH);
sha256_Final(&(hctx->ctx), hmac);
MEMSET_BZERO(hash, sizeof(hash));
MEMSET_BZERO(hctx, sizeof(HMAC_SHA256_CTX));
}
void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac)
{
HMAC_SHA256_CTX hctx;
static CONFIDENTIAL HMAC_SHA256_CTX hctx;
hmac_sha256_Init(&hctx, key, keylen);
hmac_sha256_Update(&hctx, msg, msglen);
hmac_sha256_Final(&hctx, hmac);
@ -71,35 +70,41 @@ void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg,
void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen, uint32_t *opad_digest, uint32_t *ipad_digest)
{
int i;
uint32_t buf[SHA256_BLOCK_LENGTH/sizeof(uint32_t)];
uint32_t o_key_pad[16], i_key_pad[16];
static CONFIDENTIAL uint32_t key_pad[SHA256_BLOCK_LENGTH/sizeof(uint32_t)];
memset(buf, 0, SHA256_BLOCK_LENGTH);
MEMSET_BZERO(key_pad, sizeof(key_pad));
if (keylen > SHA256_BLOCK_LENGTH) {
sha256_Raw(key, keylen, (uint8_t*) buf);
static CONFIDENTIAL SHA256_CTX context;
sha256_Init(&context);
sha256_Update(&context, key, keylen);
sha256_Final(&context, (uint8_t*)key_pad);
} else {
memcpy(buf, key, keylen);
memcpy(key_pad, key, keylen);
}
for (i = 0; i < 16; i++) {
/* compute o_key_pad and its digest */
for (int i = 0; i < SHA256_BLOCK_LENGTH/(int)sizeof(uint32_t); i++) {
uint32_t data;
#if BYTE_ORDER == LITTLE_ENDIAN
REVERSE32(buf[i], data);
REVERSE32(key_pad[i], data);
#else
data = buf[i];
data = key_pad[i];
#endif
o_key_pad[i] = data ^ 0x5c5c5c5c;
i_key_pad[i] = data ^ 0x36363636;
key_pad[i] = data ^ 0x5c5c5c5c;
}
sha256_Transform(sha256_initial_hash_value, key_pad, opad_digest);
sha256_Transform(sha256_initial_hash_value, o_key_pad, opad_digest);
sha256_Transform(sha256_initial_hash_value, i_key_pad, ipad_digest);
/* convert o_key_pad to i_key_pad and compute its digest */
for (int i = 0; i < SHA256_BLOCK_LENGTH/(int)sizeof(uint32_t); i++) {
key_pad[i] = key_pad[i] ^ 0x5c5c5c5c ^ 0x36363636;
}
sha256_Transform(sha256_initial_hash_value, key_pad, ipad_digest);
MEMSET_BZERO(key_pad, sizeof(key_pad));
}
void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key, const uint32_t keylen)
{
uint8_t i_key_pad[SHA512_BLOCK_LENGTH];
static CONFIDENTIAL uint8_t i_key_pad[SHA512_BLOCK_LENGTH];
memset(i_key_pad, 0, SHA512_BLOCK_LENGTH);
if (keylen > SHA512_BLOCK_LENGTH) {
sha512_Raw(key, keylen, i_key_pad);
@ -122,13 +127,11 @@ void hmac_sha512_Update(HMAC_SHA512_CTX *hctx, const uint8_t *msg, const uint32_
void hmac_sha512_Final(HMAC_SHA512_CTX *hctx, uint8_t *hmac)
{
uint8_t hash[SHA512_DIGEST_LENGTH];
sha512_Final(&(hctx->ctx), hash);
sha512_Final(&(hctx->ctx), hmac);
sha512_Init(&(hctx->ctx));
sha512_Update(&(hctx->ctx), hctx->o_key_pad, SHA512_BLOCK_LENGTH);
sha512_Update(&(hctx->ctx), hash, SHA512_DIGEST_LENGTH);
sha512_Update(&(hctx->ctx), hmac, SHA512_DIGEST_LENGTH);
sha512_Final(&(hctx->ctx), hmac);
MEMSET_BZERO(hash, sizeof(hash));
MEMSET_BZERO(hctx, sizeof(HMAC_SHA512_CTX));
}
@ -142,28 +145,34 @@ void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg,
void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen, uint64_t *opad_digest, uint64_t *ipad_digest)
{
int i;
uint64_t buf[SHA512_BLOCK_LENGTH/sizeof(uint64_t)];
uint64_t o_key_pad[16], i_key_pad[16];
static CONFIDENTIAL uint64_t key_pad[SHA512_BLOCK_LENGTH/sizeof(uint64_t)];
memset(buf, 0, SHA512_BLOCK_LENGTH);
MEMSET_BZERO(key_pad, sizeof(key_pad));
if (keylen > SHA512_BLOCK_LENGTH) {
sha512_Raw(key, keylen, (uint8_t*)buf);
static CONFIDENTIAL SHA512_CTX context;
sha512_Init(&context);
sha512_Update(&context, key, keylen);
sha512_Final(&context, (uint8_t*)key_pad);
} else {
memcpy(buf, key, keylen);
memcpy(key_pad, key, keylen);
}
for (i = 0; i < 16; i++) {
/* compute o_key_pad and its digest */
for (int i = 0; i < SHA512_BLOCK_LENGTH/(int)sizeof(uint64_t); i++) {
uint64_t data;
#if BYTE_ORDER == LITTLE_ENDIAN
REVERSE64(buf[i], data);
REVERSE64(key_pad[i], data);
#else
data = buf[i];
data = key_pad[i];
#endif
o_key_pad[i] = data ^ 0x5c5c5c5c5c5c5c5c;
i_key_pad[i] = data ^ 0x3636363636363636;
key_pad[i] = data ^ 0x5c5c5c5c5c5c5c5c;
}
sha512_Transform(sha512_initial_hash_value, key_pad, opad_digest);
sha512_Transform(sha512_initial_hash_value, o_key_pad, opad_digest);
sha512_Transform(sha512_initial_hash_value, i_key_pad, ipad_digest);
/* convert o_key_pad to i_key_pad and compute its digest */
for (int i = 0; i < SHA512_BLOCK_LENGTH/(int)sizeof(uint64_t); i++) {
key_pad[i] = key_pad[i] ^ 0x5c5c5c5c5c5c5c5c ^ 0x3636363636363636;
}
sha512_Transform(sha512_initial_hash_value, key_pad, ipad_digest);
MEMSET_BZERO(key_pad, sizeof(key_pad));
}

@ -71,4 +71,9 @@
#define USE_KECCAK 1
#endif
// add way how to mark confidential data
#ifndef CONFIDENTIAL
#define CONFIDENTIAL
#endif
#endif

Loading…
Cancel
Save