CVE-2020-15522

This commit is contained in:
programmer12 2021-07-31 17:10:50 +08:00
parent b123366209
commit 4a00c56d5c
3 changed files with 223 additions and 2 deletions

155
0001-cve-pre.patch Normal file
View File

@ -0,0 +1,155 @@
From 744c0dc2958870899d8b604bc3cclalef04db5 Mon Sep 17 00:00:00 2001
From: Peter Dettman <peter.dettman@bouncycastle.org>
Date: Fri, 3 Jul 2020 23:18:22 +0700
Subject: [PATCH] Methods for generating random FEs
---
.../org/bouncycastle/math/ec/ECCurve.java | 90 ++++++++++++++++++-
1 file changed, 86 insertions(+), 4 deletions(-)
diff --git a/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java b/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java
index 7c10c78..19cbd92 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java
@@ -1,6 +1,7 @@
package org.bouncycastle.math.ec;
import java.math.BigInteger;
+import java.security.SecureRandom;
import java.util.Hashtable;
import java.util.Random;
@@ -107,6 +108,10 @@ protected ECCurve(FiniteField field)
public abstract boolean isValidFieldElement(BigInteger x);
+ public abstract ECFieldElement randomFieldElement(SecureRandom r);
+
+ public abstract ECFieldElement randomFieldElementMult(SecureRandom r);
+
public synchronized Config configure()
{
return new Config(this.coord, this.endomorphism, this.multiplier);
@@ -589,6 +594,30 @@ public boolean isValidFieldElement(BigInteger x)
return x != null && x.signum() >= 0 && x.compareTo(this.getField().getCharacteristic()) < 0;
}
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ BigInteger p = getField().getCharacteristic();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElement(r, p));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElement(r, p));
+ return fe1.multiply(fe2);
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ BigInteger p = getField().getCharacteristic();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElementMult(r, p));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElementMult(r, p));
+ return fe1.multiply(fe2);
+ }
+
protected ECPoint decompressPoint(int yTilde, BigInteger X1)
{
ECFieldElement x = this.fromBigInteger(X1);
@@ -611,6 +640,28 @@ protected ECPoint decompressPoint(int yTilde, BigInteger X1)
return this.createRawPoint(x, y, true);
}
+
+ private static BigInteger implRandomFieldElement(SecureRandom r, BigInteger p)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(p.bitLength(), r);
+ }
+ while (x.compareTo(p) >= 0);
+ return x;
+ }
+
+ private static BigInteger implRandomFieldElementMult(SecureRandom r, BigInteger p)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(p.bitLength(), r);
+ }
+ while (x.signum() <= 0 || x.compareTo(p) >= 0);
+ return x;
+ }
}
/**
@@ -790,10 +841,6 @@ protected AbstractF2m(int m, int k1, int k2, int k3)
super(buildField(m, k1, k2, k3));
}
- public boolean isValidFieldElement(BigInteger x)
- {
- return x != null && x.signum() >= 0 && x.bitLength() <= this.getFieldSize();
- }
public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression)
{
@@ -840,6 +887,30 @@ public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression)
return this.createRawPoint(X, Y, withCompression);
}
+ public boolean isValidFieldElement(BigInteger x)
+ {
+ return x != null && x.signum() >= 0 && x.bitLength() <= this.getFieldSize();
+ }
+
+ public ECFieldElement randomFieldElement(SecureRandom r)
+ {
+ int m = getFieldSize();
+ return fromBigInteger(BigIntegers.createRandomBigInteger(m, r));
+ }
+
+ public ECFieldElement randomFieldElementMult(SecureRandom r)
+ {
+ /*
+ * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we
+ * use the product of two independent elements to mitigate side-channels.
+ */
+ int m = getFieldSize();
+ ECFieldElement fe1 = fromBigInteger(implRandomFieldElementMult(r, m));
+ ECFieldElement fe2 = fromBigInteger(implRandomFieldElementMult(r, m));
+ return fe1.multiply(fe2);
+ }
+
+
/**
* Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2).
*
@@ -956,6 +1027,17 @@ public boolean isKoblitz()
{
return this.order != null && this.cofactor != null && this.b.isOne() && (this.a.isZero() || this.a.isOne());
}
+
+ private static BigInteger implRandomFieldElementMult(SecureRandom r, int m)
+ {
+ BigInteger x;
+ do
+ {
+ x = BigIntegers.createRandomBigInteger(m, r);
+ }
+ while (x.signum() <= 0);
+ return x;
+ }
}
/**
--
2.23.0

62
CVE-2020-15522.patch Normal file
View File

@ -0,0 +1,62 @@
From 87ab5d8470829879219e50213912bab6b1ab8fe8 Mon Sep 17 00:00:00 2001
From: Peter Dettman <peter.dettman@bouncycastle.org>
Date: Sat, 4 Jul 2020 00:09:03 +0700
Subject: [PATCH] Blind the inversion when normalizing
- see the paper "Yet another GCD based inversion side-channel affecting
ECC implementations" by Nir Drucker and Shay Gueron.
---
.../org/bouncycastle/math/ec/ECPoint.java | 27 ++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java b/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java
index 20882dacc9..575ddb851e 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java
@@ -1,8 +1,11 @@
package org.bouncycastle.math.ec;
import java.math.BigInteger;
+import java.security.SecureRandom;
import java.util.Hashtable;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
+
/**
* base class for points on elliptic curves.
*/
@@ -222,13 +225,31 @@ public ECPoint normalize()
}
default:
{
- ECFieldElement Z1 = getZCoord(0);
- if (Z1.isOne())
+ ECFieldElement z = getZCoord(0);
+ if (z.isOne())
{
return this;
}
- return normalize(Z1.invert());
+ if (null == curve)
+ {
+ throw new IllegalStateException("Detached points must be in affine coordinates");
+ }
+
+ /*
+ * Use blinding to avoid the side-channel leak identified and analyzed in the paper
+ * "Yet another GCD based inversion side-channel affecting ECC implementations" by Nir
+ * Drucker and Shay Gueron.
+ *
+ * To blind the calculation of z^-1, choose a multiplicative (i.e. non-zero) field
+ * element 'b' uniformly at random, then calculate the result instead as (z * b)^-1 * b.
+ * Any side-channel in the implementation of 'inverse' now only leaks information about
+ * the value (z * b), and no longer reveals information about 'z' itself.
+ */
+ SecureRandom r = CryptoServicesRegistrar.getSecureRandom();
+ ECFieldElement b = curve.randomFieldElementMult(r);
+ ECFieldElement zInv = z.multiply(b).invert().multiply(b);
+ return normalize(zInv);
}
}
}

View File

@ -6,7 +6,7 @@
Name: bouncycastle
Version: 1.61
Release: 4
Release: 5
Summary: A Java implementation of cryptographic algorithms
License: MIT
URL: http://www.bouncycastle.org
@ -17,7 +17,8 @@ Source3: http://repo1.maven.org/maven2/org/bouncycastle/bcpkix-jdk15on/
Source4: http://repo1.maven.org/maven2/org/bouncycastle/bcprov-jdk15on/%{version}/bcprov-jdk15on-%{version}.pom
Source5: http://repo1.maven.org/maven2/org/bouncycastle/bctls-jdk15on/%{version}/bctls-jdk15on-%{version}.pom
Patch6000: CVE-2019-17359.patch
Patch6001: 0001-cve-pre.patch
Patch6002: CVE-2020-15522.patch
BuildRequires: ant ant-junit aqute-bnd javamail javapackages-local
Requires(post): javapackages-tools
Requires(postun): javapackages-tools
@ -147,6 +148,9 @@ fi
%{java_sec_dir}/2000-%{class_name}
%changelog
* Sat Jul 31 2021 liwu <liwu13@huawei.com> - 1.61-5
- fix CVE-2020-15522
* Wed Feb 12 2020 Shuaishuai Song <songshuaishuai2@huawei.com> - 1.61-4
- remove script