[11u] RFR: 8208698: Improved ECC Implementation
Langer, Christoph
christoph.langer at sap.com
Tue May 28 07:21:21 UTC 2019
Hi,
please review this backport of JDK-8208698: Improved ECC Implementation.
Bug: https://bugs.openjdk.java.net/browse/JDK-8208698
Original Change: http://hg.openjdk.java.net/jdk/jdk/rev/752e57845ad2
Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8208698.11u/
The patch did not apply cleanly because there were conflicts in src/jdk.crypto.ec/share/classes/sun/security/ec/ECDHKeyAgreement.java due to JDK-8205476 which is part of jdk/jdk but not of jdk11u-dev. Unfortunately, JDK-8205476 can not be downported as prerequisite because it brings a behavioral change and is associated with a CSR. So I resolved the rejects manually. I add the rejects below.
Thanks
Christoph
--- ECDHKeyAgreement.java
+++ ECDHKeyAgreement.java
@@ -99,42 +104,74 @@
("Key must be a PublicKey with algorithm EC");
}
- ECPublicKey ecKey = (ECPublicKey)key;
- ECParameterSpec params = ecKey.getParams();
+ this.publicKey = (ECPublicKey) key;
- if (ecKey instanceof ECPublicKeyImpl) {
- publicValue = ((ECPublicKeyImpl)ecKey).getEncodedPublicValue();
- } else { // instanceof ECPublicKey
- publicValue =
- ECUtil.encodePoint(ecKey.getW(), params.getCurve());
- }
+ ECParameterSpec params = publicKey.getParams();
int keyLenBits = params.getCurve().getField().getFieldSize();
secretLen = (keyLenBits + 7) >> 3;
return null;
}
+ private static void validateCoordinate(BigInteger c, BigInteger mod) {
+ if (c.compareTo(BigInteger.ZERO) < 0) {
+ throw new ProviderException("invalid coordinate");
+ }
+
+ if (c.compareTo(mod) >= 0) {
+ throw new ProviderException("invalid coordinate");
+ }
+ }
+
+ /*
+ * Check whether a public key is valid. Throw ProviderException
+ * if it is not valid or could not be validated.
+ */
+ private static void validate(ECOperations ops, ECPublicKey key) {
+
+ // ensure that integers are in proper range
+ BigInteger x = key.getW().getAffineX();
+ BigInteger y = key.getW().getAffineY();
+
+ BigInteger p = ops.getField().getSize();
+ validateCoordinate(x, p);
+ validateCoordinate(y, p);
+
+ // ensure the point is on the curve
+ EllipticCurve curve = key.getParams().getCurve();
+ BigInteger rhs = x.modPow(BigInteger.valueOf(3), p).add(curve.getA()
+ .multiply(x)).add(curve.getB()).mod(p);
+ BigInteger lhs = y.modPow(BigInteger.valueOf(2), p).mod(p);
+ if (!rhs.equals(lhs)) {
+ throw new ProviderException("point is not on curve");
+ }
+
+ // check the order of the point
+ ImmutableIntegerModuloP xElem = ops.getField().getElement(x);
+ ImmutableIntegerModuloP yElem = ops.getField().getElement(y);
+ AffinePoint affP = new AffinePoint(xElem, yElem);
+ byte[] order = key.getParams().getOrder().toByteArray();
+ ArrayUtil.reverse(order);
+ Point product = ops.multiply(affP, order);
+ if (!ops.isNeutral(product)) {
+ throw new ProviderException("point has incorrect order");
+ }
+
+ }
+
// see JCE spec
@Override
protected byte[] engineGenerateSecret() throws IllegalStateException {
- if ((privateKey == null) || (publicValue == null)) {
+ if ((privateKey == null) || (publicKey == null)) {
throw new IllegalStateException("Not initialized correctly");
}
- byte[] s = privateKey.getS().toByteArray();
- byte[] encodedParams = // DER OID
- ECUtil.encodeECParameterSpec(null, privateKey.getParams());
-
- try {
-
- byte[] result = deriveKey(s, publicValue, encodedParams);
- publicValue = null;
- return result;
-
- } catch (GeneralSecurityException e) {
- throw new ProviderException("Could not derive key", e);
- }
-
+ Optional<byte[]> resultOpt = deriveKeyImpl(privateKey, publicKey);
+ byte[] result = resultOpt.orElseGet(
+ () -> deriveKeyNative(privateKey, publicKey)
+ );
+ publicKey = null;
+ return result;
}
// see JCE spec
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/security-dev/attachments/20190528/a0980809/attachment.htm>
More information about the security-dev
mailing list