mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-27 21:45:43 +00:00
fix(crypto,core,legacy): Check private key validity when deriving public key.
[no changelog]
This commit is contained in:
parent
5d03110a42
commit
34621a6b6d
core/embed/extmod/modtrezorcrypto
crypto
legacy/firmware
@ -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…
Reference in New Issue
Block a user