fix(crypto,core,legacy): Check private key validity when deriving public key.

[no changelog]
pull/1884/head
Andrew Kozlik 3 years ago committed by Andrew Kozlik
parent 5d03110a42
commit 34621a6b6d

@ -70,12 +70,16 @@ STATIC mp_obj_t mod_trezorcrypto_nist256p1_publickey(size_t n_args,
bool compressed = n_args < 2 || args[1] == mp_const_true;
if (compressed) {
vstr_init_len(&pk, 33);
ecdsa_get_public_key33(&nist256p1, (const uint8_t *)sk.buf,
(uint8_t *)pk.buf);
if (ecdsa_get_public_key33(&nist256p1, (const uint8_t *)sk.buf,
(uint8_t *)pk.buf) != 0) {
mp_raise_ValueError("Invalid secret key");
}
} else {
vstr_init_len(&pk, 65);
ecdsa_get_public_key65(&nist256p1, (const uint8_t *)sk.buf,
(uint8_t *)pk.buf);
if (ecdsa_get_public_key65(&nist256p1, (const uint8_t *)sk.buf,
(uint8_t *)pk.buf) != 0) {
mp_raise_ValueError("Invalid secret key");
}
}
return mp_obj_new_str_from_vstr(&mp_type_bytes, &pk);
}

@ -641,6 +641,11 @@ int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key,
bignum256 k = {0};
bn_read_be(priv_key, &k);
if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) {
// Invalid private key.
return 2;
}
point_multiply(curve, &k, &point, &point);
memzero(&k, sizeof(k));
@ -721,8 +726,8 @@ int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key,
}
bn_read_be(priv_key, s);
if (bn_is_zero(s)) {
// Using an all-zero private key is most likely an indication of a bug.
if (bn_is_zero(s) || !bn_is_less(s, &curve->order)) {
// Invalid private key.
return 2;
}
@ -783,6 +788,12 @@ int ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key,
bignum256 k = {0};
bn_read_be(priv_key, &k);
if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) {
// Invalid private key.
memzero(pub_key, 33);
return -1;
}
// compute k*G
if (scalar_multiply(curve, &k, &R) != 0) {
memzero(&k, sizeof(k));
@ -802,6 +813,12 @@ int ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key,
bignum256 k = {0};
bn_read_be(priv_key, &k);
if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) {
// Invalid private key.
memzero(pub_key, 65);
return -1;
}
// compute k*G
if (scalar_multiply(curve, &k, &R) != 0) {
memzero(&k, sizeof(k));

@ -135,7 +135,9 @@ int schnorr_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key,
curve_point R = {0};
bignum256 e = {0}, s = {0}, k = {0};
ecdsa_get_public_key33(curve, priv_key, pub_key);
if (ecdsa_get_public_key33(curve, priv_key, pub_key) != 0) {
return 1;
}
// Compute k
if (generate_k_schnorr(curve, priv_key, digest, &k) != 0) {

@ -8959,7 +8959,7 @@ START_TEST(test_schnorr_sign_verify_digest) {
memcpy(priv_key, fromhex(tests[i].priv_key), 32);
memcpy(expected, fromhex(tests[i].sig), SCHNORR_SIG_LENGTH);
ecdsa_get_public_key33(curve, priv_key, pub_key);
ck_assert_int_eq(ecdsa_get_public_key33(curve, priv_key, pub_key), 0);
schnorr_sign_digest(curve, priv_key, digest, result);

@ -79,8 +79,15 @@ void openssl_check(unsigned int iterations, int nid, const ecdsa_curve *curve) {
}
// generate public key from private key
ecdsa_get_public_key33(curve, priv_key, pub_key33);
ecdsa_get_public_key65(curve, priv_key, pub_key65);
if (ecdsa_get_public_key33(curve, priv_key, pub_key33) != 0) {
printf("ecdsa_get_public_key33 failed\n");
return;
}
if (ecdsa_get_public_key65(curve, priv_key, pub_key65) != 0) {
printf("ecdsa_get_public_key65 failed\n");
return;
}
// use our ECDSA verifier to verify the message signature
if (ecdsa_verify(curve, HASHER_SHA2, pub_key65, sig, msg, msg_len) != 0) {

@ -604,8 +604,11 @@ void u2f_register(const APDU *a) {
return;
}
ecdsa_get_public_key65(node->curve->params, node->private_key,
(uint8_t *)&resp->pubKey);
if (ecdsa_get_public_key65(node->curve->params, node->private_key,
(uint8_t *)&resp->pubKey) != 0) {
send_u2f_error(U2F_SW_WRONG_DATA);
return;
}
memcpy(resp->keyHandleCertSig + resp->keyHandleLen, U2F_ATT_CERT,
sizeof(U2F_ATT_CERT));

Loading…
Cancel
Save