mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-22 22:38:08 +00:00
replace infinite loops with loops with counters
This commit is contained in:
parent
f4f246f3d7
commit
71ff1c5124
93
ecdsa.c
93
ecdsa.c
@ -136,9 +136,9 @@ void scalar_multiply(bignum256 *k, curve_point *res)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generate random K for signing
|
// generate random K for signing
|
||||||
void generate_k_random(bignum256 *k) {
|
int generate_k_random(bignum256 *k) {
|
||||||
int i;
|
int i, j;
|
||||||
for (;;) {
|
for (j = 0; j < 10000; j++) {
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
k->val[i] = random32() & 0x3FFFFFFF;
|
k->val[i] = random32() & 0x3FFFFFFF;
|
||||||
}
|
}
|
||||||
@ -146,14 +146,17 @@ void generate_k_random(bignum256 *k) {
|
|||||||
// if k is too big or too small, we don't like it
|
// if k is too big or too small, we don't like it
|
||||||
if (k->val[5] == 0x3FFFFFFF && k->val[6] == 0x3FFFFFFF && k->val[7] == 0x3FFFFFFF && k->val[8] == 0xFFFF) continue;
|
if (k->val[5] == 0x3FFFFFFF && k->val[6] == 0x3FFFFFFF && k->val[7] == 0x3FFFFFFF && k->val[8] == 0xFFFF) continue;
|
||||||
if (k->val[5] == 0x0 && k->val[6] == 0x0 && k->val[7] == 0x0 && k->val[8] == 0x0) continue;
|
if (k->val[5] == 0x0 && k->val[6] == 0x0 && k->val[7] == 0x0 && k->val[8] == 0x0) continue;
|
||||||
return;
|
return 0; // good number - no error
|
||||||
}
|
}
|
||||||
|
// we generated 10000 numbers, none of them is good -> fail
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate K in a deterministic way, according to RFC6979
|
// generate K in a deterministic way, according to RFC6979
|
||||||
// http://tools.ietf.org/html/rfc6979
|
// http://tools.ietf.org/html/rfc6979
|
||||||
void generate_k_rfc6979(bignum256 *secret, const uint8_t *priv_key, const uint8_t *hash)
|
int generate_k_rfc6979(bignum256 *secret, const uint8_t *priv_key, const uint8_t *hash)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
uint8_t v[32], k[32], bx[2*32], buf[32 + 1 + sizeof(bx)], t[32];
|
uint8_t v[32], k[32], bx[2*32], buf[32 + 1 + sizeof(bx)], t[32];
|
||||||
bignum256 z1;
|
bignum256 z1;
|
||||||
|
|
||||||
@ -177,17 +180,19 @@ void generate_k_rfc6979(bignum256 *secret, const uint8_t *priv_key, const uint8_
|
|||||||
hmac_sha256(k, sizeof(k), buf, sizeof(buf), k);
|
hmac_sha256(k, sizeof(k), buf, sizeof(buf), k);
|
||||||
hmac_sha256(k, sizeof(k), v, sizeof(k), v);
|
hmac_sha256(k, sizeof(k), v, sizeof(k), v);
|
||||||
|
|
||||||
for (;;) {
|
for (i = 0; i < 10000; i++) {
|
||||||
hmac_sha256(k, sizeof(k), v, sizeof(v), t);
|
hmac_sha256(k, sizeof(k), v, sizeof(v), t);
|
||||||
bn_read_be(t, secret);
|
bn_read_be(t, secret);
|
||||||
if ( !bn_is_zero(secret) && bn_is_less(secret, &order256k1) ) {
|
if ( !bn_is_zero(secret) && bn_is_less(secret, &order256k1) ) {
|
||||||
return;
|
return 0; // good number -> no error
|
||||||
}
|
}
|
||||||
memcpy(buf, v, sizeof(v));
|
memcpy(buf, v, sizeof(v));
|
||||||
buf[sizeof(v)] = 0x00;
|
buf[sizeof(v)] = 0x00;
|
||||||
hmac_sha256(k, sizeof(k), buf, sizeof(v) + 1, k);
|
hmac_sha256(k, sizeof(k), buf, sizeof(v) + 1, k);
|
||||||
hmac_sha256(k, sizeof(k), v, sizeof(v), v);
|
hmac_sha256(k, sizeof(k), v, sizeof(v), v);
|
||||||
}
|
}
|
||||||
|
// we generated 10000 numbers, none of them is good -> fail
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// uses secp256k1 curve
|
// uses secp256k1 curve
|
||||||
@ -208,46 +213,48 @@ int ecdsa_sign(const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, ui
|
|||||||
// SHA256_Raw(hash, 32, hash);
|
// SHA256_Raw(hash, 32, hash);
|
||||||
|
|
||||||
bn_read_be(hash, &z);
|
bn_read_be(hash, &z);
|
||||||
for (;;) {
|
|
||||||
|
|
||||||
// generate random number k
|
// generate random number k
|
||||||
//generate_k_random(&k);
|
//if (generate_k_random(&k) != 0) {
|
||||||
|
// return 1;
|
||||||
|
//}
|
||||||
|
|
||||||
// generate K deterministically
|
// generate K deterministically
|
||||||
generate_k_rfc6979(&k, priv_key, hash);
|
if (generate_k_rfc6979(&k, priv_key, hash) != 0) {
|
||||||
|
return 1;
|
||||||
// compute k*G
|
|
||||||
scalar_multiply(&k, &R);
|
|
||||||
// r = (rx mod n)
|
|
||||||
bn_mod(&R.x, &order256k1);
|
|
||||||
// if r is zero, we try different k
|
|
||||||
for (i = 0; i < 9; i++) {
|
|
||||||
if (R.x.val[i] != 0) break;
|
|
||||||
}
|
|
||||||
if (i == 9) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
bn_inverse(&k, &order256k1);
|
|
||||||
bn_read_be(priv_key, da);
|
|
||||||
bn_multiply(&R.x, da, &order256k1);
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
da->val[i] += z.val[i];
|
|
||||||
da->val[i + 1] += (da->val[i] >> 30);
|
|
||||||
da->val[i] &= 0x3FFFFFFF;
|
|
||||||
}
|
|
||||||
da->val[8] += z.val[8];
|
|
||||||
bn_multiply(da, &k, &order256k1);
|
|
||||||
bn_mod(&k, &order256k1);
|
|
||||||
for (i = 0; i < 9; i++) {
|
|
||||||
if (k.val[i] != 0) break;
|
|
||||||
}
|
|
||||||
if (i == 9) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
// we are done, R.x and k is the result signature
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute k*G
|
||||||
|
scalar_multiply(&k, &R);
|
||||||
|
// r = (rx mod n)
|
||||||
|
bn_mod(&R.x, &order256k1);
|
||||||
|
// if r is zero, we fail
|
||||||
|
for (i = 0; i < 9; i++) {
|
||||||
|
if (R.x.val[i] != 0) break;
|
||||||
|
}
|
||||||
|
if (i == 9) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
bn_inverse(&k, &order256k1);
|
||||||
|
bn_read_be(priv_key, da);
|
||||||
|
bn_multiply(&R.x, da, &order256k1);
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
da->val[i] += z.val[i];
|
||||||
|
da->val[i + 1] += (da->val[i] >> 30);
|
||||||
|
da->val[i] &= 0x3FFFFFFF;
|
||||||
|
}
|
||||||
|
da->val[8] += z.val[8];
|
||||||
|
bn_multiply(da, &k, &order256k1);
|
||||||
|
bn_mod(&k, &order256k1);
|
||||||
|
for (i = 0; i < 9; i++) {
|
||||||
|
if (k.val[i] != 0) break;
|
||||||
|
}
|
||||||
|
// if k is zero, we fail
|
||||||
|
if (i == 9) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we are done, R.x and k is the result signature
|
||||||
bn_write_be(&R.x, sig);
|
bn_write_be(&R.x, sig);
|
||||||
bn_write_be(&k, sig + 32);
|
bn_write_be(&k, sig + 32);
|
||||||
|
|
||||||
|
2
ecdsa.h
2
ecdsa.h
@ -35,6 +35,6 @@ void ecdsa_get_public_key65(const uint8_t *priv_key, uint8_t *pub_key);
|
|||||||
void ecdsa_get_address(const uint8_t *pub_key, char version, char *addr);
|
void ecdsa_get_address(const uint8_t *pub_key, char version, char *addr);
|
||||||
int ecdsa_verify(const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len);
|
int ecdsa_verify(const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len);
|
||||||
|
|
||||||
void generate_k_rfc6979(bignum256 *secret, const uint8_t *priv_key, const uint8_t *hash);
|
int generate_k_rfc6979(bignum256 *secret, const uint8_t *priv_key, const uint8_t *hash);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
6
tests.c
6
tests.c
@ -174,13 +174,15 @@ END_TEST
|
|||||||
|
|
||||||
START_TEST(test_rfc6979)
|
START_TEST(test_rfc6979)
|
||||||
{
|
{
|
||||||
|
int res;
|
||||||
bignum256 k;
|
bignum256 k;
|
||||||
uint8_t buf[32];
|
uint8_t buf[32];
|
||||||
|
|
||||||
SHA256_Raw((uint8_t *)"sample", 6, buf);
|
SHA256_Raw((uint8_t *)"sample", 6, buf);
|
||||||
generate_k_rfc6979(&k, fromhex("cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50"), buf);
|
res = generate_k_rfc6979(&k, fromhex("cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50"), buf);
|
||||||
bn_write_be(&k, buf);
|
ck_assert_int_eq(res, 0);
|
||||||
|
|
||||||
|
bn_write_be(&k, buf);
|
||||||
ck_assert_mem_eq(buf, fromhex("2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3"), 32);
|
ck_assert_mem_eq(buf, fromhex("2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3"), 32);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
Loading…
Reference in New Issue
Block a user