<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri",sans-serif;
mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:#0563C1;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:#954F72;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
mso-fareast-language:EN-US;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="DE" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal">Hi,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span lang="EN-US">please review this backport of JDK-8208698: Improved ECC Implementation.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Bug: <a href="https://bugs.openjdk.java.net/browse/JDK-8208698">
https://bugs.openjdk.java.net/browse/JDK-8208698</a> <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Original Change: <a href="http://hg.openjdk.java.net/jdk/jdk/rev/752e57845ad2">
http://hg.openjdk.java.net/jdk/jdk/rev/752e57845ad2</a> <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Webrev: <a href="http://cr.openjdk.java.net/~clanger/webrevs/8208698.11u/">
http://cr.openjdk.java.net/~clanger/webrevs/8208698.11u/</a><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">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.<o:p></o:p></span></p>
<p class="MsoNormal"><b><span lang="EN-US" style="font-size:8.0pt;font-family:"Arial",sans-serif;color:#666666;mso-fareast-language:DE"><o:p> </o:p></span></b></p>
<p class="MsoNormal"><span lang="EN-US">Thanks<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Christoph<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">--- ECDHKeyAgreement.java<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+++ ECDHKeyAgreement.java<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">@@ -99,42 +104,74 @@<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> ("Key must be a PublicKey with algorithm EC");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- ECPublicKey ecKey = (ECPublicKey)key;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- ECParameterSpec params = ecKey.getParams();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ this.publicKey = (ECPublicKey) key;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- if (ecKey instanceof ECPublicKeyImpl) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- publicValue = ((ECPublicKeyImpl)ecKey).getEncodedPublicValue();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- } else { // instanceof ECPublicKey<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- publicValue =<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- ECUtil.encodePoint(ecKey.getW(), params.getCurve());<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ ECParameterSpec params = publicKey.getParams();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> int keyLenBits = params.getCurve().getField().getFieldSize();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> secretLen = (keyLenBits + 7) >> 3;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> return null;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ private static void validateCoordinate(BigInteger c, BigInteger mod) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ if (c.compareTo(BigInteger.ZERO) < 0) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ throw new ProviderException("invalid coordinate");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ if (c.compareTo(mod) >= 0) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ throw new ProviderException("invalid coordinate");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ /*<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ * Check whether a public key is valid. Throw ProviderException<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ * if it is not valid or could not be validated.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ */<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ private static void validate(ECOperations ops, ECPublicKey key) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ // ensure that integers are in proper range<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ BigInteger x = key.getW().getAffineX();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ BigInteger y = key.getW().getAffineY();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ BigInteger p = ops.getField().getSize();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ validateCoordinate(x, p);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ validateCoordinate(y, p);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ // ensure the point is on the curve<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ EllipticCurve curve = key.getParams().getCurve();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ BigInteger rhs = x.modPow(BigInteger.valueOf(3), p).add(curve.getA()<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ .multiply(x)).add(curve.getB()).mod(p);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ BigInteger lhs = y.modPow(BigInteger.valueOf(2), p).mod(p);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ if (!rhs.equals(lhs)) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ throw new ProviderException("point is not on curve");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ // check the order of the point<o:p></o:p></span></p>
<p class="MsoNormal">+ ImmutableIntegerModuloP xElem = ops.getField().getElement(x);<o:p></o:p></p>
<p class="MsoNormal"><span lang="EN-US">+ ImmutableIntegerModuloP yElem = ops.getField().getElement(y);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ AffinePoint affP = new AffinePoint(xElem, yElem);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ byte[] order = key.getParams().getOrder().toByteArray();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ ArrayUtil.reverse(order);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ Point product = ops.multiply(affP, order);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ if (!ops.isNeutral(product)) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ throw new ProviderException("point has incorrect order");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> // see JCE spec<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> @Override<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> protected byte[] engineGenerateSecret() throws IllegalStateException {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- if ((privateKey == null) || (publicValue == null)) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ if ((privateKey == null) || (publicKey == null)) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> throw new IllegalStateException("Not initialized correctly");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- byte[] s = privateKey.getS().toByteArray();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- byte[] encodedParams = // DER OID<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- ECUtil.encodeECParameterSpec(null, privateKey.getParams());<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">-<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- try {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">-<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- byte[] result = deriveKey(s, publicValue, encodedParams);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- publicValue = null;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- return result;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">-<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- } catch (GeneralSecurityException e) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- throw new ProviderException("Could not derive key", e);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">- }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">-<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ Optional<byte[]> resultOpt = deriveKeyImpl(privateKey, publicKey);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ byte[] result = resultOpt.orElseGet(<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ () -> deriveKeyNative(privateKey, publicKey)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ );<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ publicKey = null;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">+ return result;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> // see JCE spec<o:p></o:p></span></p>
</div>
</body>
</html>