1
0
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:
Pavol Rusnak 2013-09-27 15:55:55 +02:00
parent f4f246f3d7
commit 71ff1c5124
3 changed files with 55 additions and 46 deletions

93
ecdsa.c
View File

@ -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);

View File

@ -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

View File

@ -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