diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | ecc-ecdsa-verify.c | 22 | ||||
-rw-r--r-- | ecc-gostdsa-verify.c | 5 | ||||
-rw-r--r-- | testsuite/ecdsa-sign-test.c | 12 | ||||
-rw-r--r-- | testsuite/ecdsa-verify-test.c | 15 |
5 files changed, 45 insertions, 19 deletions
@@ -6,6 +6,16 @@ * Makefile.in (hogweed_SOURCES): Add ecc-nonsec-add-jjj.c. * testsuite/ecc-add-test.c (test_main): Add tests for ecc_nonsec_add_jjj. + * 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. + 2022-09-08 Niels Möller <nisse@lysator.liu.se> * eccdata.c (string_toupper): New utility function. 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 diff --git a/ecc-gostdsa-verify.c b/ecc-gostdsa-verify.c index fcdd4644..d1b0454f 100644 --- a/ecc-gostdsa-verify.c +++ b/ecc-gostdsa-verify.c @@ -115,10 +115,11 @@ ecc_gostdsa_verify (const struct ecc_curve *ecc, ecc->mul_g (ecc, P1, z1, P1 + 3*ecc->p.size); /* Total storage: 6*ecc->p.size + ecc->add_hhh_itch */ - ecc->add_hhh (ecc, P1, P1, P2, P1 + 3*ecc->p.size); + if (!ecc_nonsec_add_jjj (ecc, P1, P1, P2, P1 + 3*ecc->p.size)) + return 0; /* x coordinate only, modulo q */ - ecc->h_to_a (ecc, 2, P2, P1, P1 + 3*ecc->p.size); + ecc_j_to_a (ecc, 2, P2, P1, P1 + 3*ecc->p.size); return (mpn_cmp (rp, P2, ecc->p.size) == 0); #undef P2 diff --git a/testsuite/ecdsa-sign-test.c b/testsuite/ecdsa-sign-test.c index c79493ae..b8a100b6 100644 --- a/testsuite/ecdsa-sign-test.c +++ b/testsuite/ecdsa-sign-test.c @@ -77,6 +77,18 @@ test_main (void) "3a41e1423b1853e8aa89747b1f987364" "44705d6d6d8371ea1f578f2e"); /* s */ + /* Produce a signature where verify operation results in a point duplication. */ + test_ecdsa (&_nettle_secp_256r1, + "1", /* Private key */ + "01010101010101010101010101010101" + "01010101010101010101010101010101", /* nonce */ + SHEX("6ff03b949241ce1dadd43519e6960e0a" + "85b41a69a05c328103aa2bce1594ca16"), /* hash */ + "6ff03b949241ce1dadd43519e6960e0a" + "85b41a69a05c328103aa2bce1594ca16", /* r */ + "53f097727a0e0dc284a0daa0da0ab77d" + "5792ae67ed075d1f8d5bda0f853fa093"); /* s */ + /* Test cases for the smaller groups, verified with a proof-of-concept implementation done for Yubico AB. */ test_ecdsa (&_nettle_secp_192r1, diff --git a/testsuite/ecdsa-verify-test.c b/testsuite/ecdsa-verify-test.c index 8110c64d..8d527000 100644 --- a/testsuite/ecdsa-verify-test.c +++ b/testsuite/ecdsa-verify-test.c @@ -109,6 +109,21 @@ test_main (void) "952800792ed19341fdeeec047f2514f3b0f150d6066151fb", /* r */ "ec5971222014878b50d7a19d8954bc871e7e65b00b860ffb"); /* s */ + /* Test case provided by Guido Vranken, from oss-fuzz. Triggers + point duplication in the verify operation by using private key = + 1 (public key = generator) and hash = r. */ + test_ecdsa (&_nettle_secp_256r1, + "6B17D1F2E12C4247F8BCE6E563A440F2" + "77037D812DEB33A0F4A13945D898C296", /* x */ + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16" + "2BCE33576B315ECECBB6406837BF51F5", /* y */ + SHEX("6ff03b949241ce1dadd43519e6960e0a" + "85b41a69a05c328103aa2bce1594ca16"), /* hash */ + "6ff03b949241ce1dadd43519e6960e0a" + "85b41a69a05c328103aa2bce1594ca16", /* r */ + "53f097727a0e0dc284a0daa0da0ab77d" + "5792ae67ed075d1f8d5bda0f853fa093"); /* s */ + /* From RFC 4754 */ test_ecdsa (&_nettle_secp_256r1, "2442A5CC 0ECD015F A3CA31DC 8E2BBC70" |