File libnettle-CVE-2021-20305.patch of Package libnettle.19992
libnettle: multiply function being called with out-of-range scalars [CVE-2021-20305, bsc#1184401]
Back-port the effect of ecc_mod_mul_canonical() to ecc-ecdsa-sign(), ecc_ecdsa_verify() and _eddsa_hash().
Cherry-picked from upstream commits:
* New functions ecc_mod_mul_canonical and ecc_mod_sqr_canonical.
https://git.lysator.liu.se/nettle/nettle/-/commit/a63893791280d441c713293491da97c79c0950fe
* Fix bug in ecc_ecdsa_verify.
https://git.lysator.liu.se/nettle/nettle/-/commit/74ee0e82b6891e090f20723750faeb19064e31b2
* Ensure ecdsa_sign output is canonically reduced.
https://git.lysator.liu.se/nettle/nettle/-/commit/51f643eee00e2caa65c8a2f5857f49acdf3ef1ce
* Similar fix for eddsa.
https://git.lysator.liu.se/nettle/nettle/-/commit/ae3801a0e5cce276c270973214385c86048d5f7b
Index: nettle-3.4.1/ecc-ecdsa-sign.c
===================================================================
--- nettle-3.4.1.orig/ecc-ecdsa-sign.c
+++ nettle-3.4.1/ecc-ecdsa-sign.c
@@ -78,6 +78,8 @@ ecc_ecdsa_sign (const struct ecc_curve *
4. s2 <-- (h + z*s1)/k mod q.
*/
+ mp_limb_t cy;
+
ecc->mul_g (ecc, P, kp, P + 3*ecc->p.size);
/* x coordinate only, modulo q */
ecc->h_to_a (ecc, 2, rp, P, P + 3*ecc->p.size);
@@ -92,7 +94,13 @@ ecc_ecdsa_sign (const struct ecc_curve *
ecc_modq_add (ecc, hp, hp, tp);
ecc_modq_mul (ecc, tp, hp, kinv);
- mpn_copyi (sp, tp, ecc->p.size);
+ /* Back-port the effect of ecc_mod_mul_canonical() here
+ * to produce canonical results
+ */
+ cy = mpn_sub_n (sp, tp, ecc->q.m, ecc->q.size);
+ cnd_copy (cy, sp, tp, ecc->q.size);
+ // mpn_copyi (sp, tp, ecc->p.size);
+
#undef P
#undef hp
#undef kinv
Index: nettle-3.4.1/ecc-ecdsa-verify.c
===================================================================
--- nettle-3.4.1.orig/ecc-ecdsa-verify.c
+++ nettle-3.4.1/ecc-ecdsa-verify.c
@@ -77,28 +77,23 @@ ecc_ecdsa_verify (const struct ecc_curve
{
/* Procedure, according to RFC 6090, "KT-I". q denotes the group
order.
-
1. Check 0 < r, s < q.
-
2. s' <-- s^{-1} (mod q)
-
3. u1 <-- h * s' (mod q)
-
4. u2 <-- r * s' (mod q)
-
5. R = u1 G + u2 Y
-
6. Signature is valid if R_x = r (mod q).
*/
#define P2 scratch
#define u1 (scratch + 3*ecc->p.size)
#define u2 (scratch + 4*ecc->p.size)
-
#define P1 (scratch + 4*ecc->p.size)
#define sinv (scratch)
#define hp (scratch + ecc->p.size)
+ mp_limb_t cy;
+
if (! (ecdsa_in_range (ecc, rp)
&& ecdsa_in_range (ecc, sp)))
return 0;
@@ -110,12 +105,20 @@ ecc_ecdsa_verify (const struct ecc_curve
/* Compute sinv */
ecc->q.invert (&ecc->q, sinv, sp, sinv + 2*ecc->p.size);
+ /* Back-port the effect of ecc_mod_mul_canonical() here
+ * to produce canonical results
+ */
+
/* u1 = h / s, P1 = u1 * G */
ecc_hash (&ecc->q, hp, length, digest);
- ecc_modq_mul (ecc, u1, hp, sinv);
+ ecc_modq_mul (ecc, u2, hp, sinv);
+ cy = mpn_sub_n (u1, u2, ecc->q.m, ecc->q.size);
+ cnd_copy (cy, u1, u2, ecc->q.size);
/* u2 = r / s, P2 = u2 * Y */
- ecc_modq_mul (ecc, u2, rp, sinv);
+ ecc_modq_mul (ecc, hp, rp, sinv);
+ cy = mpn_sub_n (u2, hp, ecc->q.m, ecc->q.size);
+ cnd_copy (cy, u2, hp, ecc->q.size);
/* Total storage: 5*ecc->p.size + ecc->mul_itch */
ecc->mul (ecc, P2, u2, pp, u2 + ecc->p.size);
Index: nettle-3.4.1/eddsa-hash.c
===================================================================
--- nettle-3.4.1.orig/eddsa-hash.c
+++ nettle-3.4.1/eddsa-hash.c
@@ -41,11 +41,20 @@
#include "ecc-internal.h"
#include "nettle-internal.h"
+/* Convert hash digest to integer, and reduce canonically modulo q.
+ Needs space for 2*m->size + 1 at rp. */
+
void
_eddsa_hash (const struct ecc_modulo *m,
mp_limb_t *rp, const uint8_t *digest)
{
+ mp_limb_t cy;
size_t nbytes = 1 + m->bit_size / 8;
- mpn_set_base256_le (rp, 2*m->size, digest, 2*nbytes);
- m->mod (m, rp);
+
+ mpn_set_base256_le (rp + m->size, 2*m->size, digest, 2*nbytes);
+ m->mod (m, rp + m->size);
+
+ /* Ensure canonical reduction. */
+ cy = mpn_sub_n (rp, rp + m->size, m->m, m->size);
+ cnd_copy (cy, rp, rp + m->size, m->size);
}
Index: nettle-3.4.1/testsuite/ecdsa-sign-test.c
===================================================================
--- nettle-3.4.1.orig/testsuite/ecdsa-sign-test.c
+++ nettle-3.4.1/testsuite/ecdsa-sign-test.c
@@ -58,6 +58,19 @@ test_ecdsa (const struct ecc_curve *ecc,
void
test_main (void)
{
+ /* Producing the signature for corresponding test in
+ ecdsa-verify-test.c, with special u1 and u2. */
+ test_ecdsa (&nettle_secp_224r1,
+ "99b5b787484def12894ca507058b3bf5"
+ "43d72d82fa7721d2e805e5e6",
+ "2",
+ SHEX("cdb887ac805a3b42e22d224c85482053"
+ "16c755d4a736bb2032c92553"),
+ "706a46dc76dcb76798e60e6d89474788"
+ "d16dc18032d268fd1a704fa6", /* r */
+ "3a41e1423b1853e8aa89747b1f987364"
+ "44705d6d6d8371ea1f578f2e"); /* s */
+
/* Test cases for the smaller groups, verified with a
proof-of-concept implementation done for Yubico AB. */
test_ecdsa (&nettle_secp_192r1,
Index: nettle-3.4.1/testsuite/ecdsa-verify-test.c
===================================================================
--- nettle-3.4.1.orig/testsuite/ecdsa-verify-test.c
+++ nettle-3.4.1/testsuite/ecdsa-verify-test.c
@@ -81,6 +81,26 @@ test_ecdsa (const struct ecc_curve *ecc,
void
test_main (void)
{
+ /* Corresponds to nonce k = 2 and private key z =
+ 0x99b5b787484def12894ca507058b3bf543d72d82fa7721d2e805e5e6. z and
+ hash are chosen so that intermediate scalars in the verify
+ equations are u1 = 0x6b245680e700, u2 =
+ 259da6542d4ba7d21ad916c3bd57f811. These values require canonical
+ reduction of the scalars. Bug caused by missing canonical
+ reduction reported by Guido Vranken. */
+ test_ecdsa (&nettle_secp_224r1,
+ "9e7e6cc6b1bdfa8ee039b66ad85e5490"
+ "7be706a900a3cba1c8fdd014", /* x */
+ "74855db3f7c1b4097ae095745fc915e3"
+ "8a79d2a1de28f282eafb22ba", /* y */
+
+ SHEX("cdb887ac805a3b42e22d224c85482053"
+ "16c755d4a736bb2032c92553"),
+ "706a46dc76dcb76798e60e6d89474788"
+ "d16dc18032d268fd1a704fa6", /* r */
+ "3a41e1423b1853e8aa89747b1f987364"
+ "44705d6d6d8371ea1f578f2e"); /* s */
+
/* From RFC 4754 */
test_ecdsa (&nettle_secp_256r1,
"2442A5CC 0ECD015F A3CA31DC 8E2BBC70"