summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2022-09-14 16:17:52 +0200
committerNiels Möller <nisse@lysator.liu.se>2022-09-14 16:17:52 +0200
commit4eb5868ce8963827aa6e00a01ed90df488b288fe (patch)
tree88ab45104879a65fe6ade2986b7f3f10d1a6536c
parentdaabcc72a87a61f69188c26cf8ddabfc98ef64f0 (diff)
downloadnettle-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.
-rw-r--r--ChangeLog10
-rw-r--r--ecc-ecdsa-verify.c22
-rw-r--r--ecc-gostdsa-verify.c5
-rw-r--r--testsuite/ecdsa-sign-test.c12
-rw-r--r--testsuite/ecdsa-verify-test.c15
5 files changed, 45 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 41863a07..0f497b52 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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"