796117
From fa98a26f68c6cb27a3feea0b10475e7ff2ade74a Mon Sep 17 00:00:00 2001
796117
From: Daiki Ueno <dueno@redhat.com>
796117
Date: Tue, 30 Mar 2021 09:22:47 +0200
796117
Subject: [PATCH] Port upstream hardening of EC scaler multiplication
796117
796117
Some internal functions used in point multiplications are known to
796117
misbehave if the scaler is out-of-range.  This performs canonical
796117
reduction on scalers, before point multiplication.
796117
796117
Signed-off-by: Daiki Ueno <dueno@redhat.com>
796117
---
796117
 ecc-ecdsa-sign.c   |  5 +++--
796117
 ecc-ecdsa-verify.c | 14 ++++++++++++--
796117
 2 files changed, 15 insertions(+), 4 deletions(-)
796117
796117
diff --git a/ecc-ecdsa-sign.c b/ecc-ecdsa-sign.c
796117
index cdf37746..acfb2a2e 100644
796117
--- a/ecc-ecdsa-sign.c
796117
+++ b/ecc-ecdsa-sign.c
796117
@@ -88,8 +88,9 @@ ecc_ecdsa_sign (const struct ecc_curve *ecc,
796117
   ecc_modq_mul (ecc, tp, zp, rp);
796117
   ecc_modq_add (ecc, hp, hp, tp);
796117
   ecc_modq_mul (ecc, tp, hp, kinv);
796117
-
796117
-  mpn_copyi (sp, tp, ecc->size);
796117
+  /* Ensure canonical reduction. */
796117
+  cy = mpn_sub_n (sp, tp, ecc->q, ecc->size);
796117
+  cnd_copy (cy, sp, tp, ecc->size);
796117
 #undef P
796117
 #undef hp
796117
 #undef kinv
796117
diff --git a/ecc-ecdsa-verify.c b/ecc-ecdsa-verify.c
796117
index f24eff37..5015271c 100644
796117
--- a/ecc-ecdsa-verify.c
796117
+++ b/ecc-ecdsa-verify.c
796117
@@ -66,6 +66,8 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc,
796117
 		  const mp_limb_t *rp, const mp_limb_t *sp,
796117
 		  mp_limb_t *scratch)
796117
 {
796117
+  mp_limb_t cy;
796117
+
796117
   /* Procedure, according to RFC 6090, "KT-I". q denotes the group
796117
      order.
796117
 
796117
@@ -88,6 +90,7 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc,
796117
 #define u2 (scratch + 4*ecc->size)
796117
 #define hp (scratch + 4*ecc->size)
796117
 #define u1 (scratch + 6*ecc->size)
796117
+#define tp (scratch + 7*ecc->size)
796117
 
796117
   if (! (ecdsa_in_range (ecc, rp)
796117
 	 && ecdsa_in_range (ecc, sp)))
796117
@@ -102,14 +105,20 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc,
796117
   ecc_modq_inv (ecc, sinv, sinv + ecc->size, P2);
796117
 
796117
   /* u2 = r / s, P2 = u2 * Y */
796117
-  ecc_modq_mul (ecc, u2, rp, sinv);
796117
+  ecc_modq_mul (ecc, tp, rp, sinv);
796117
+  /* Ensure canonical reduction. */
796117
+  cy = mpn_sub_n (u2, tp, ecc->q, ecc->size);
796117
+  cnd_copy (cy, u2, tp, ecc->size);
796117
 
796117
    /* Total storage: 5*ecc->size + ECC_MUL_A_ITCH (ecc->size) */
796117
   ecc_mul_a (ecc, 1, P2, u2, pp, u2 + ecc->size);
796117
 
796117
   /* u1 = h / s, P1 = u1 * G */
796117
   ecc_hash (ecc, hp, length, digest);
796117
-  ecc_modq_mul (ecc, u1, hp, sinv);
796117
+  ecc_modq_mul (ecc, tp, hp, sinv);
796117
+  /* Ensure canonical reduction. */
796117
+  cy = mpn_sub_n (u1, tp, ecc->q, ecc->size);
796117
+  cnd_copy (cy, u1, tp, ecc->size);
796117
 
796117
   /* u = 0 can happen only if h = 0 or h = q, which is extremely
796117
      unlikely. */
796117
@@ -147,4 +156,5 @@ ecc_ecdsa_verify (const struct ecc_curve *ecc,
796117
 #undef u2
796117
 #undef hp
796117
 #undef u1
796117
+#undef tp
796117
 }
796117
-- 
796117
2.30.2
796117