diff options
author | Niels Möller <nisse@lysator.liu.se> | 2022-09-14 16:17:52 +0200 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2022-09-14 16:17:52 +0200 |
commit | 4eb5868ce8963827aa6e00a01ed90df488b288fe (patch) | |
tree | 88ab45104879a65fe6ade2986b7f3f10d1a6536c /ecc-ecdsa-verify.c | |
parent | daabcc72a87a61f69188c26cf8ddabfc98ef64f0 (diff) | |
download | nettle-4eb5868ce8963827aa6e00a01ed90df488b288fe.tar.gz |
Fix ECDSA verify corner case
* ecc-ecdsa-verify.c (ecc_ecdsa_verify): Use ecc_nonsec_add_jjj,
to produce correct result in a corner case where point addition
needs to use point duplication. Also use ecc_j_to_a rather than
ecc->h_to_a, since ecdsa supports only weierstrass curves.
* ecc-gostdsa-verify.c (ecc_gostdsa_verify): Analogous change.
* testsuite/ecdsa-verify-test.c (test_main): Add corresponding test.
* testsuite/ecdsa-sign-test.c (test_main): And a test producing
the problematic signature.
Diffstat (limited to 'ecc-ecdsa-verify.c')
-rw-r--r-- | ecc-ecdsa-verify.c | 22 |
1 files changed, 5 insertions, 17 deletions
diff --git a/ecc-ecdsa-verify.c b/ecc-ecdsa-verify.c index f3b112b0..bd6491a1 100644 --- a/ecc-ecdsa-verify.c +++ b/ecc-ecdsa-verify.c @@ -117,25 +117,13 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc, /* Total storage: 7*ecc->p.size + ecc->mul_g_itch (ecc->p.size) */ ecc->mul_g (ecc, P1, u1, P1 + 3*ecc->p.size); - /* NOTE: ecc_add_jjj and/or ecc_j_to_a will produce garbage in - case u1 G = +/- u2 V. However, anyone who gets his or her - hands on a signature where this happens during verification, - can also get the private key as z = +/- u1 / u_2 (mod q). And - then it doesn't matter very much if verification of - signatures with that key succeeds or fails. - - u1 G = - u2 V can never happen for a correctly generated - signature, since it implies k = 0. - - u1 G = u2 V is possible, if we are unlucky enough to get h / - s_1 = z. Hitting that is about as unlikely as finding the - private key by guessing. - */ - /* Total storage: 6*ecc->p.size + ecc->add_hhh_itch */ - ecc->add_hhh (ecc, P2, P2, P1, P1 + 3*ecc->p.size); + /* Total storage: 6*ecc->p.size + ECC_ADD_JJA_ITCH(size) */ + if (!ecc_nonsec_add_jjj (ecc, P2, P2, P1, P1 + 3*ecc->p.size)) + /* Infinity point, not a valid signature. */ + return 0; } /* x coordinate only, modulo q */ - ecc->h_to_a (ecc, 2, P1, P2, P1 + 3*ecc->p.size); + ecc_j_to_a (ecc, 2, P1, P2, P1 + 3*ecc->p.size); return (mpn_cmp (rp, P1, ecc->p.size) == 0); #undef P2 |