1 /** 2 * @license 3 * Copyright 2016 Google Inc. All rights reserved. 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.security.wycheproof; 18 19 import com.google.security.wycheproof.WycheproofRunner.ExcludedTest; 20 import com.google.security.wycheproof.WycheproofRunner.ProviderType; 21 import java.math.BigInteger; 22 import java.security.GeneralSecurityException; 23 import java.security.InvalidKeyException; 24 import java.security.KeyFactory; 25 import java.security.KeyPair; 26 import java.security.KeyPairGenerator; 27 import java.security.NoSuchAlgorithmException; 28 import java.security.interfaces.ECPrivateKey; 29 import java.security.interfaces.ECPublicKey; 30 import java.security.spec.ECFieldFp; 31 import java.security.spec.ECGenParameterSpec; 32 import java.security.spec.ECParameterSpec; 33 import java.security.spec.ECPoint; 34 import java.security.spec.ECPrivateKeySpec; 35 import java.security.spec.ECPublicKeySpec; 36 import java.security.spec.EllipticCurve; 37 import java.security.spec.InvalidKeySpecException; 38 import java.security.spec.X509EncodedKeySpec; 39 import javax.crypto.KeyAgreement; 40 import junit.framework.TestCase; 41 42 /** 43 * Testing ECDH. 44 * 45 * <p><b>Defense in depth</b>: The tests for ECDH assume that a attacker has control over all 46 * aspects of the public key in an exchange. That means that the attacker can potentially send weak 47 * or invalid public keys. For example, invalid public keys can contain points not on the curve, 48 * curves that have been deliberately chosen so that DLs are easy to compute as well as orders or 49 * cofactors that are wrong. It is expected that implementations validate the inputs of a key 50 * agreement and that in no case information about the private key is leaked. 51 * 52 * <p><b>References:</b> Ingrid Biehl, Bernd Meyer, Volker Müller, "Differential Fault Attacks on 53 * Elliptic Curve Cryptosystems", Crypto '00, pp. 131-164 54 * 55 * <p>Adrian Antipa, Daniel Brown, Alfred Menezes, Rene Struik, and Scott Vanstone, "Validation of 56 * Elliptic Curve Public Keys", PKC 2003, https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf 57 * 58 * <p># <b>Bugs:</b> CVE-2015-7940: BouncyCastle before 1.51 does not validate a point is on the 59 * curve. BouncyCastle v.1.52 checks that the public key point is on the public key curve but does 60 * not check whether public key and private key use the same curve. BouncyCastle v.1.53 is still 61 * vulnerable to attacks with modified public keys. An attacker can change the order of the curve 62 * used by the public key. ECDHC would then reduce the private key modulo this order, which can be 63 * used to find the private key. 64 * 65 * <p>SunEC had similar problem. CVE ? 66 * 67 * @author bleichen@google.com (Daniel Bleichenbacher) 68 */ 69 // TODO(bleichen): Stuff we haven't implemented: 70 // - timing attacks 71 // Stuff we are delaying because there are more important bugs: 72 // - testWrongOrder using BouncyCastle with ECDHWithSHA1Kdf throws 73 // java.lang.UnsupportedOperationException: KDF can only be used when algorithm is known 74 // Not sure if that is expected or another bug. 75 // CVEs for ECDH we haven't used anywhere. 76 // - CVE-2014-3470: OpenSSL anonymous ECDH denial of service: triggered by NULL value in 77 // certificate. 78 // - CVE-2014-3572: OpenSSL downgrades ECDHE to ECDH 79 // - CVE-2011-3210: OpenSSL was not thread safe 80 public class EcdhTest extends TestCase { 81 82 static final String[] ECDH_VARIANTS = { 83 // Raw ECDH. The shared secret is the x-coordinate of the ECDH computation. 84 // The tests below assume that this variant is implemenented. 85 "ECDH", 86 // ECDHC is a variant described in P1363 7.2.2 ECSVDP-DHC. 87 // BouncyCastle implements this variant. 88 "ECDHC", 89 // A variant with an explicit key derivation function. 90 // This is implemented by BouncyCastle. 91 "ECDHWITHSHA1KDF", 92 }; 93 94 /** ECDH test vectors */ 95 public static class EcdhTestVector { 96 final String curvename; 97 final String pub; // hexadecimal representation of the X509 encoding 98 final BigInteger s; // private key 99 final String shared; // hexadecimal representation of the shared secret 100 EcdhTestVector(String curvename, String pub, BigInteger s, String shared)101 public EcdhTestVector(String curvename, String pub, BigInteger s, String shared) { 102 this.curvename = curvename; 103 this.pub = pub; 104 this.s = s; 105 this.shared = shared; 106 } 107 getPublicKey()108 public ECPublicKey getPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException { 109 KeyFactory kf = KeyFactory.getInstance("EC"); 110 byte[] encoded = TestUtil.hexToBytes(pub); 111 return (ECPublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded)); 112 } 113 getPrivateKey()114 public ECPrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException { 115 KeyFactory kf = KeyFactory.getInstance("EC"); 116 ECPrivateKeySpec spec = new ECPrivateKeySpec(s, EcUtil.getCurveSpecRef(curvename)); 117 return (ECPrivateKey) kf.generatePrivate(spec); 118 } 119 } 120 121 public static final EcdhTestVector[] ECDH_TEST_VECTORS = { 122 // vectors with normal ECDH values 123 new EcdhTestVector( 124 "secp224r1", 125 "304e301006072a8648ce3d020106052b81040021033a00049c08bb3788a5cb8d" 126 + "22591f2520791cdaf61765a84f0419d28ff8fb2dcb5d51e5714d8740420d0945" 127 + "187f97be42872bae9bf3f5b1857a475f", 128 new BigInteger("8af784fe9cebd363df85f598dcc2ab82b2ca725360dadb77b3708032", 16), 129 "c1921af3d06d813ccb009e363a647836d30b3f9c211c26e64a3bb0b6"), 130 new EcdhTestVector( 131 "secp256r1", 132 "3059301306072a8648ce3d020106082a8648ce3d030107034200044b3b0a5231" 133 + "76309f259498c55e3a9be45c9fb65ad4e60d6064e04b89c1bd0a1835039219c1" 134 + "22b89e2b539bb16d3afced502137f02944c374863137035fd3f1ae", 135 new BigInteger("051a995be2a8499e2c9331b3b5f3c012048bb02a1a6f044ed93d9bd295fcec16", 16), 136 "33befba428b295b9a0123d3a848d91d1e9a5266959e036d1a25e28d83d06421f"), 137 new EcdhTestVector( 138 "secp384r1", 139 "3076301006072a8648ce3d020106052b8104002203620004c1d31b771bb123f4" 140 + "fb2b789a2880c57a68b3bbfa7da3d80b8325b73428bd2a4e79b55b57ac454f52" 141 + "8ac02b62d54dfc315b9ba04363e94b825767951a9338f5d1db4c6d3f0e9a15bc" 142 + "9b834fc11a01e4b310c22aba73766fd769ea684fbad5d9d2", 143 new BigInteger("ff65a2bf5e1347e2286fb29273fb118a76996038bea2fcfd2032e8663f7588e5" 144 + "3130d195b161eba39085abbc3e24bcef", 16), 145 "dbd85b2caaca6d69460c94bd9f99b3bd51404788a58334a18709a882050fe1bf" 146 + "a4dd74de6e4368c1243443e5f64b60c7"), 147 new EcdhTestVector( 148 "secp521r1", 149 "30819b301006072a8648ce3d020106052b81040023038186000401ca6ec5476b" 150 + "ae3cf0f28f370ac3a9a0de2091418a590978bf87a6f1aeadebde98925e8fb42c" 151 + "d03d57ff9aeb9890646067a3095874828a392b80a88880e5f456e4d000493581" 152 + "376d20d711a487e0106a3fc047b91803ed154e274b26d858cf2f55e356b45765" 153 + "2101b925b7d36b542d2a3e33e01404fb4f944c3b8ef276b6f5082e591135", 154 new BigInteger("01f362c182f1eaae2920578a2f30c228e28b996e74d4bd799621300d5f2e6c69" 155 + "30204f00476732c95a79ae527503621edf633dbb87400740f54adc4430706221" 156 + "2f68", 16), 157 "0107b9c99c80e2bc834e10c44afe2d611aafe8aad0eb80384aefbd9bb8196ea3" 158 + "b5797bedac39de3362532c9b04aeb98a3e60034c3d2dcb4a43b8f8b44e9528d3" 159 + "eeb8"), 160 new EcdhTestVector( 161 "brainpoolp256r1", 162 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 163 + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d" 164 + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c" 165 + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7" 166 + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27" 167 + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745" 168 + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71" 169 + "8c397aa3b561a6f7901e0e82974856a7020101034200048178776ff8332108da" 170 + "d4fa59bce3111133a30e33fa7f96d0211ec9fa4904dcca084de67f52fd720ccd" 171 + "ada5c49305200a6028793a83cbe692c08237ecd0572fa2", 172 new BigInteger("143be522a9d0420f6bd19b95ce3a5e19c61970c31f13448276546625e607e7c9", 16), 173 "3658b819481f00f74cfd76b9dcf82867c3c3186f948cbc75bf296c6d332aedf0"), 174 // vectors with extreme values for the shared secret 175 new EcdhTestVector( 176 "secp256r1", 177 "3059301306072a8648ce3d020106082a8648ce3d03010703420004983f80374a" 178 + "4730f9decd7221fa3ebb527d44f459b6c6afcf7de7069481400a748fb8733ba0" 179 + "8e01cd53d54af45975554d0dbd6d5f0acf0fd95692606347cace7e", 180 new BigInteger("56556c546751dee664ae71baa0189a2e69b1e1f8939a49ed7cc35d7ea98fbcc7", 16), 181 "0000000000000000000000000000000000000000000000000000000000000000"), 182 new EcdhTestVector( 183 "secp384r1", 184 "3076301006072a8648ce3d020106052b8104002203620004d64af08419f8a0aa" 185 + "5d830a2b0f42e6a27a3c17e0e98f64a1e7e10c6a41a308832dcd9a493db0cd43" 186 + "7e47063c1db6c967494c8460f03bf95ff619b7c7499e1bc08fd759fc44c4af3d" 187 + "03de541a719baf996b4f91a9af5bf08fa671af0899f91359", 188 new BigInteger("ee383acde7e5b3e6c246833e183c4272a1714a13097b4b57bc2eeecdccbd69b6" 189 + "cff435215a3c92b5d4e0b2c36444a7fa", 16), 190 "0000000000000000000000000000000000000000000000000000000000000000" 191 + "00000000000000000000000000000000"), 192 new EcdhTestVector( 193 "secp384r1", 194 "3076301006072a8648ce3d020106052b81040022036200041c1ed3f66b6ae370" 195 + "411ac30fda63c784c5cbc3951a7cfe567d8bfa3ea535a2eb8c192d349e69ea2a" 196 + "39eb5013a5cf383cf91c82e81eee1a9bc97386e340e65b2b2d8cf2633b919a82" 197 + "10a638b8e2345cda054ce96efcaeee20dcce82d13d40eb6a", 198 new BigInteger("98f230ef0c0ab02c78179ba9ea3e1c8d16c3ec276665c432b9040b803dfff657" 199 + "a6c77512b6a602d416785016c3cd3da7", 16), 200 "0000000000000000000000000000000000000000000000000000000000000000" 201 + "00000000000000000000000000000002"), 202 new EcdhTestVector( 203 "secp384r1", 204 "3076301006072a8648ce3d020106052b8104002203620004d10b0df120b1324d" 205 + "8b76ee43065e4f4be63f68cf5b381ae79046920108a8f21cf8097bf313225b74" 206 + "1125eb5a66105ee445961b28ad1843613775c063a85319f1353d8bf2a217210e" 207 + "309f2c7c27b57d42fdc042abb00b37a0f3118cf74b4174f0", 208 new BigInteger("5b8e9af3c17fa0d683f3bc94f8685f33c0b616281f91b466cac9da0a0e085ba6" 209 + "f48aafcdb4fc13d55f1a33ac436f82bb", 16), 210 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" 211 + "ffffffff0000000000000000fffffffe"), 212 new EcdhTestVector( 213 "secp521r1", 214 "30819b301006072a8648ce3d020106052b810400230381860004008269c7d0ff" 215 + "febadbf5bdfa2adf0f378d0844268e5acb57d0157fe688488cef91256e15939d" 216 + "311aaf6479e29ef14de3981c3a5768c7b66693e956fa515d4a0c847c0054a32b" 217 + "4a8f615ba5550f204ebf1f7f02f7252b5ae564361eec468adf4d59caa4c4b424" 218 + "a30761d805d521c2e1f1dfde385e9146624cb2b84f94888730acbfbf1294", 219 new BigInteger("019ad2de5943f5112021a3215cee84c4e8d40e188641419a5b7958636f1843d0" 220 + "cbda4747aad69fd806b333b82b095d0f10bda8dbeca7ee9f67d09caffb4869e4" 221 + "1172", 16), 222 "0000000000000000000000000000000000000000000000000000000000000000" 223 + "0000000000000000000000000000000000000000000000000000000000000000" 224 + "0000"), 225 new EcdhTestVector( 226 "secp521r1", 227 "30819b301006072a8648ce3d020106052b810400230381860004003b0d698705" 228 + "0fad0f76ac1ac7a1c7e91e24addf821c06ae0844a3f1b6338c111a32a94a5369" 229 + "fdf8fd1cc137314c7d7a99dfabba1cc92f10026e45388714fe453ed50015e59a" 230 + "c4bab161635e0df0f5553ee6112fc60f744ffc607965975c0843f7a893441c4f" 231 + "e5e6e290426dd219ecbc159f39302b52b37b69a890e9fc4cf70eba39bbf6", 232 new BigInteger("0147492d3019808024569dc81b0e6aef9f27bfd43e009e8b4b6b0512b220490e" 233 + "08f98324b16d3ed91a54d391f92973f5376c66b9f8a9cbf893b0900968fd8d6e" 234 + "5e7d", 16), 235 "0000000000000000000000000000000000000000000000000000000000000000" 236 + "0000000000000000000000000000000000000000000000000000000000000000" 237 + "0001"), 238 new EcdhTestVector( 239 "secp521r1", 240 "30819b301006072a8648ce3d020106052b81040023038186000401bb2936bfc5" 241 + "8f1e9819d62ed2a38a0ce618f000546fe8af4983d8dbbda7b7ae914a656ac540" 242 + "7c153f6edacb170fd2129d126d987d5032c7a31540bb6a4e93f8af15015c23ce" 243 + "1263e691903cd2c859d883c980fada91b764aef7e5a20fb22bcf5949e62c8082" 244 + "c8245bcf8686a6a39b7ef2eec49b1a047b73aeb06e3793c1d01fa24fd156", 245 new BigInteger("5a5f98ceb2f856685c51ba714d5e1db06d1e6542a8d02b9c13efeeb1f3e6613d" 246 + "8ef83e49748cb63aad268ba68c9295c507dac125f51ba75c82f6029dcc14d4ab" 247 + "16", 16), 248 "0000000000000000000000000000000000000000000000000000000000000000" 249 + "0000000000000000000000000000000000000000000000000000000000000000" 250 + "0002"), 251 new EcdhTestVector( 252 "secp521r1", 253 "30819b301006072a8648ce3d020106052b81040023038186000401ce7a5356fd" 254 + "002ff3d9a193dd910795b56f8bd2f975367d982d27e04b4e0935425fdef6b3e1" 255 + "6fac26a898a757ddbfb01a45236a8a06ead9db3dff644ed87a7f09310000c862" 256 + "7374a123b1c0fdf7efaaee362fa7fdeb1c56bd787e81484d21a818ff49552704" 257 + "af2d2fe714a1576299ff6d3745349cdb463e8c003641c13c870391cfd360", 258 new BigInteger("c5dd96d1f0aa141f184d0a749809dc0749a0629b9b7d99d1cbe40c14204d70c7" 259 + "f63413756040a4c2a67551df6723c4b784ace44d7e35f46233c78b2c7548594b" 260 + "3d", 16), 261 "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 262 + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 263 + "fffd"), 264 new EcdhTestVector( 265 "secp521r1", 266 "30819b301006072a8648ce3d020106052b81040023038186000400d4574ad46e" 267 + "42824b7738f0ed19f0dbec65e743ed6a1798e8168546713a929c97cb8b2f3c20" 268 + "928bed9fad88319ef216e42c7a82707befead2b21000e06e6ca37709004848c1" 269 + "34a7fa6d0f8cd9aa237b84ffa02cb3bc8d84b8022153a3e01248dfc87403e8f3" 270 + "f1b70b52b7eabffd01fe1b4101fa901494a2067e2321a47e87cce45eecfd", 271 new BigInteger("01ac34343b1814a092e48f1c60de0bacced8c328246f103428ab0ce6611807e6" 272 + "90022dbc6bc558265b917dc513152cd1661b30e3b62a2cc2bf9f909e3fd51918" 273 + "de5b", 16), 274 "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 275 + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 276 + "fffe"), 277 new EcdhTestVector( 278 "brainpoolp256r1", 279 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 280 + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d" 281 + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c" 282 + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7" 283 + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27" 284 + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745" 285 + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71" 286 + "8c397aa3b561a6f7901e0e82974856a70201010342000498703a894131de3f81" 287 + "5836bdb1d5a03e59fbf50ffde6575ee690e9ebf6a32e785ad50d1eb00062a9b8" 288 + "176ba32f06f3908f82a3ddd9da10eafcac61f57a180bcb", 289 new BigInteger("17617237e4ec2629d798a81ca086c1a73494e70619dd7b77cb7360174de82107", 16), 290 "0000000000000000000000000000000000000000000000000000000000000001"), 291 new EcdhTestVector( 292 "brainpoolp256r1", 293 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 294 + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d" 295 + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c" 296 + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7" 297 + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27" 298 + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745" 299 + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71" 300 + "8c397aa3b561a6f7901e0e82974856a702010103420004055f1b89b08c1c4a0f" 301 + "96ff15dd284bdad79b90636ce73c461cb6da001e19638c07490bed6a644e944a" 302 + "c3e8684c4d5cf469a3f5b039690cba52dc0dccb095e61e", 303 new BigInteger("7988ceedd4ce4f516f083261dc0dbb4d59c71b058bf00876135fb1d5e72a1cea", 16), 304 "0000000000000000000000000000000000000000000000000000000000000002"), 305 new EcdhTestVector( 306 "brainpoolp256r1", 307 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 308 + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d" 309 + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c" 310 + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7" 311 + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27" 312 + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745" 313 + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71" 314 + "8c397aa3b561a6f7901e0e82974856a70201010342000424f99dbc3d8f4989f2" 315 + "43662e67de0f8d03d0f84031caa553f4a3ccc1c999de1e43530fcd456a5d83d5" 316 + "11aedc8bda7c2b18cc509cabe47e76d46501fd82ebbfae", 317 new BigInteger("844649c38c375c5f4959b129c6510e54f71a60b91d1b09a7b1a8dd0e954da186", 16), 318 "a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5376"), 319 // vectors with extreme values for the public key 320 new EcdhTestVector( 321 "secp256r1", 322 "3059301306072a8648ce3d020106082a8648ce3d030107034200040000000000" 323 + "00000000000000000000000000000000000000000000000000000066485c780e" 324 + "2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4", 325 new BigInteger("2e0a2c5159af006f28f5b51e55ce9270f17a431ebefee2d95bf2f954c3c460c5", 16), 326 "bb4b8e7b1b5d766d7e6d3de41e0ab0703cadcca4e039f310e3ed0004e2c1ba67"), 327 new EcdhTestVector( 328 "secp384r1", 329 "3076301006072a8648ce3d020106052b81040022036200040000000000000000" 330 + "0000000000000000000000000000000000000000000000000000000000000000" 331 + "00000000000000003cf99ef04f51a5ea630ba3f9f960dd593a14c9be39fd2bd2" 332 + "15d3b4b08aaaf86bbf927f2c46e52ab06fb742b8850e521e", 333 new BigInteger("b0a8c4804a2b9769216a51b51ece43391cf3f66c383a748d54f1c15f27bbf041" 334 + "a3b9470a6d49f8abe9e6b4db6bd7c59f", 16), 335 "6598237fdfd3f38e00c3c58a3045b9d54c510f0f5523293af1966635f2ddf963" 336 + "87b12065ad8e1a5b72618e6441c72841"), 337 new EcdhTestVector( 338 "secp384r1", 339 "3076301006072a8648ce3d020106052b8104002203620004ffffffffffffffff" 340 + "fffffffffffffffffffffffffffffffffffffffffffffffeffffffff00000000" 341 + "00000000fffffffe732152442fb6ee5c3e6ce1d920c059bc623563814d79042b" 342 + "903ce60f1d4487fccd450a86da03f3e6ed525d02017bfdb3", 343 new BigInteger("135b5751b27de8fe0e34d452ad81c4ca90def546275c349f467aabd24e039b75" 344 + "28c473bc5732cb96921d01e6ca11739a", 16), 345 "ef5ceb524843eb0277f574b278b09f82670dbcdacbe51a646441a45ebdfa4976" 346 + "1fb3b534bfccd957edb99e9a4e329467"), 347 new EcdhTestVector( 348 "secp521r1", 349 "30819b301006072a8648ce3d020106052b810400230381860004000000000000" 350 + "0000000000000000000000000000000000000000000000000000000000000000" 351 + "0000000000000000000000000000000000000000000000000000000000d20ec9" 352 + "fea6b577c10d26ca1bb446f40b299e648b1ad508aad068896fee3f8e614bc630" 353 + "54d5772bf01a65d412e0bcaa8e965d2f5d332d7f39f846d440ae001f4f87", 354 new BigInteger("7ca82bb7bdd0ab3805e1d25ce49f71780e93a0314f579a474d0b0f81812c8365" 355 + "bc3917eb00208a1cfdb44cdc53f112930560e86bcad563d0bd4ff951f2c41454" 356 + "f6", 16), 357 "00d6283f6a7b59628920dd3afe97a5021c79e26c71adf5c0774cedaaf5b25b92" 358 + "ed2776cfefbe95e467a15032c221064ff19b1207183f0ca0c594b6a83ca0e3f3" 359 + "2250"), 360 new EcdhTestVector( 361 "secp521r1", 362 "30819b301006072a8648ce3d020106052b810400230381860004000000000000" 363 + "0000000000000000000000000000000000000000000000000000000000000000" 364 + "000000000000000000000000000000000000000000000000000000010010e59b" 365 + "e93c4f269c0269c79e2afd65d6aeaa9b701eacc194fb3ee03df47849bf550ec6" 366 + "36ebee0ddd4a16f1cd9406605af38f584567770e3f272d688c832e843564", 367 new BigInteger("011cf3abed354498f6922af2ddc9d74b2bb829bee79cc272c7b154f16a720c29" 368 + "429bb354bb034549e33be5b84ffb6da99a0c28bb37fa44f78cce5feb871370e1" 369 + "2c93", 16), 370 "00e51b94872c9cb3831bac48e9e4cbc6b4eafdc09ce51f43d0ff118b5d429f20" 371 + "b88261dbfc9636ecf081cdcf1b1336425a39841cf1ff742bc3d5553a709cd0a7" 372 + "3a13"), 373 new EcdhTestVector( 374 "secp521r1", 375 "30819b301006072a8648ce3d020106052b81040023038186000401ffffffffff" 376 + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 377 + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffd0010e59b" 378 + "e93c4f269c0269c79e2afd65d6aeaa9b701eacc194fb3ee03df47849bf550ec6" 379 + "36ebee0ddd4a16f1cd9406605af38f584567770e3f272d688c832e843564", 380 new BigInteger("011c2b1a82cd320924e757b4259e5f7c0455efe3f05d316c9705b5071fdbd59e" 381 + "db59ee938b95a67727ca01ffe5155baf5eff83ae5ec4a56770a50475b017a762" 382 + "30cf", 16), 383 "000adf30396bda59d36fc307a4f43f594806f3a46373f3e4af6516e67f99d981" 384 + "1c0496f49527895fa7738423f6429318f54afa6841cb4692e15016fe49fc7c82" 385 + "509d"), 386 new EcdhTestVector( 387 "secp521r1", 388 "30819b301006072a8648ce3d020106052b81040023038186000401ffffffffff" 389 + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 390 + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffe00d9254f" 391 + "df800496acb33790b103c5ee9fac12832fe546c632225b0f7fce3da4574b1a87" 392 + "9b623d722fa8fc34d5fc2a8731aad691a9a8bb8b554c95a051d6aa505acf", 393 new BigInteger("01e1603fe7e275673aeb8b3f105f4058e073b4c37d2f0ae2bd66b189454e1b41" 394 + "c442c3f35f085eae3aa37eefffe76736440f9b3fd2e3931d468b6d90e560bc0f" 395 + "35f5", 16), 396 "0158694585e55f1289e410fdeeed82940b3029dd8207dcb4de407278a6328d5e" 397 + "b904262419f1ef2ecacb415872f0c9d64df82b1241cd780bd0abc9e26ceebadf" 398 + "44e7"), 399 new EcdhTestVector( 400 "brainpoolp256r1", 401 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 402 + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d" 403 + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c" 404 + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7" 405 + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27" 406 + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745" 407 + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71" 408 + "8c397aa3b561a6f7901e0e82974856a702010103420004000000000000000000" 409 + "000000000000000000000000000000000000000000000109e0e9e8d98fb89da2" 410 + "a32b2c7618b26bb99b920f02a5e831a142e6c8673110cd", 411 new BigInteger("61c2be000b5888035bfde07d532b36d91cc347f556d87c7a01397f4cde29c6e4", 16), 412 "3db56c93e51a0b5b17a8009be010be6eecca6b7e0b587753cb8bc850869a710d"), 413 new EcdhTestVector( 414 "brainpoolp256r1", 415 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 416 + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d" 417 + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c" 418 + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7" 419 + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27" 420 + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745" 421 + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71" 422 + "8c397aa3b561a6f7901e0e82974856a702010103420004a9fb57dba1eea9bc3e" 423 + "660a909d838d726e3bf623d52620282013481d1f6e537613a0346db14d55d1bc" 424 + "c27079b68864ac32885b5bdfc3c9db6f85a35d3df4c39b", 425 new BigInteger("8527b0540fc10b025a6e0892439c59a889a52e57a0f81b4df41442869c524873", 16), 426 "a01ed9d4f5a0884db2a232dd5369d6014bfe1f2f6a6d05a757e7a078b71a1f54"), 427 }; 428 429 /** Test vectors */ 430 public static class EcPublicKeyTestVector { 431 final String comment; 432 final String encoded; // hexadecimal representation of the X509 encoding 433 final BigInteger p; // characteristic of the field 434 final BigInteger n; // order of the subgroup 435 final BigInteger a; // parameter a of the Weierstrass representation 436 final BigInteger b; // parameter b of the Weierstrass represnetation 437 final BigInteger gx; // x-coordinate of the generator 438 final BigInteger gy; // y-coordainat of the generator 439 final Integer h; // cofactor: may be null 440 final BigInteger pubx; // x-coordinate of the public point 441 final BigInteger puby; // y-coordinate of the public point 442 EcPublicKeyTestVector( String comment, String encoded, BigInteger p, BigInteger n, BigInteger a, BigInteger b, BigInteger gx, BigInteger gy, Integer h, BigInteger pubx, BigInteger puby)443 public EcPublicKeyTestVector( 444 String comment, 445 String encoded, 446 BigInteger p, 447 BigInteger n, 448 BigInteger a, 449 BigInteger b, 450 BigInteger gx, 451 BigInteger gy, 452 Integer h, 453 BigInteger pubx, 454 BigInteger puby) { 455 this.comment = comment; 456 this.encoded = encoded; 457 this.p = p; 458 this.n = n; 459 this.a = a; 460 this.b = b; 461 this.gx = gx; 462 this.gy = gy; 463 this.h = h; 464 this.pubx = pubx; 465 this.puby = puby; 466 } 467 468 /** 469 * Returns this key as ECPublicKeySpec or null if the key cannot be represented as 470 * ECPublicKeySpec. The later happens for example if the order of cofactor are not positive. 471 */ getSpec()472 public ECPublicKeySpec getSpec() { 473 try { 474 ECFieldFp fp = new ECFieldFp(p); 475 EllipticCurve curve = new EllipticCurve(fp, a, b); 476 ECPoint g = new ECPoint(gx, gy); 477 // ECParameterSpec requires that the cofactor h is specified. 478 if (h == null) { 479 return null; 480 } 481 ECParameterSpec params = new ECParameterSpec(curve, g, n, h); 482 ECPoint pubPoint = new ECPoint(pubx, puby); 483 ECPublicKeySpec pub = new ECPublicKeySpec(pubPoint, params); 484 return pub; 485 } catch (Exception ex) { 486 System.out.println(comment + " throws " + ex.toString()); 487 return null; 488 } 489 } 490 getX509EncodedKeySpec()491 public X509EncodedKeySpec getX509EncodedKeySpec() { 492 return new X509EncodedKeySpec(TestUtil.hexToBytes(encoded)); 493 } 494 } 495 496 public static final EcPublicKeyTestVector EC_VALID_PUBLIC_KEY = 497 new EcPublicKeyTestVector( 498 "unmodified", 499 "3059301306072a8648ce3d020106082a8648ce3d03010703420004cdeb39edd0" 500 + "3e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b84" 501 + "29598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 502 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 503 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 504 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 505 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 506 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 507 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), 508 1, 509 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 510 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)); 511 512 public static final EcPublicKeyTestVector[] EC_MODIFIED_PUBLIC_KEYS = { 513 // Modified keys 514 new EcPublicKeyTestVector( 515 "public point not on curve", 516 "3059301306072a8648ce3d020106082a8648ce3d03010703420004cdeb39edd0" 517 + "3e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b84" 518 + "29598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebaca", 519 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 520 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 521 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 522 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 523 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 524 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), 525 1, 526 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 527 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebaca", 16)), 528 new EcPublicKeyTestVector( 529 "public point = (0,0)", 530 "3059301306072a8648ce3d020106082a8648ce3d030107034200040000000000" 531 + "0000000000000000000000000000000000000000000000000000000000000000" 532 + "000000000000000000000000000000000000000000000000000000", 533 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 534 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 535 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 536 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 537 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 538 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), 539 1, 540 new BigInteger("0"), 541 new BigInteger("0")), 542 new EcPublicKeyTestVector( 543 "order = 1", 544 "308201133081cc06072a8648ce3d02013081c0020101302c06072a8648ce3d01" 545 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 546 + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff" 547 + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53" 548 + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d" 549 + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33" 550 + "576b315ececbb6406837bf51f502010102010103420004cdeb39edd03e2b1a11" 551 + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b" 552 + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 553 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 554 new BigInteger("01", 16), 555 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 556 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 557 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 558 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), 559 1, 560 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 561 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)), 562 new EcPublicKeyTestVector( 563 "order = 26959946660873538060741835960514744168612397095220107664918121663170", 564 "3082012f3081e806072a8648ce3d02013081dc020101302c06072a8648ce3d01" 565 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 566 + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff" 567 + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53" 568 + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d" 569 + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33" 570 + "576b315ececbb6406837bf51f5021d00ffffffff00000000ffffffffffffffff" 571 + "bce6faada7179e84f3b9cac202010103420004cdeb39edd03e2b1a11a5e134ec" 572 + "99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb85c" 573 + "3303ddb1553c3b761c2caacca71606ba9ebac8", 574 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 575 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2", 16), 576 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 577 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 578 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 579 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), 580 1, 581 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 582 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)), 583 new EcPublicKeyTestVector( 584 "generator = (0,0)", 585 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 586 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 587 + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff" 588 + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53" 589 + "b0f63bce3c3e27d2604b04410400000000000000000000000000000000000000" 590 + "0000000000000000000000000000000000000000000000000000000000000000" 591 + "00000000000000000000000000022100ffffffff00000000ffffffffffffffff" 592 + "bce6faada7179e84f3b9cac2fc63255102010103420004cdeb39edd03e2b1a11" 593 + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b" 594 + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 595 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 596 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 597 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 598 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 599 new BigInteger("0"), 600 new BigInteger("0"), 601 1, 602 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 603 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)), 604 new EcPublicKeyTestVector( 605 "generator not on curve", 606 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 607 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 608 + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff" 609 + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53" 610 + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d" 611 + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33" 612 + "576b315ececbb6406837bf51f7022100ffffffff00000000ffffffffffffffff" 613 + "bce6faada7179e84f3b9cac2fc63255102010103420004cdeb39edd03e2b1a11" 614 + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b" 615 + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 616 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 617 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 618 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 619 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 620 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 621 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f7", 16), 622 1, 623 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 624 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)), 625 new EcPublicKeyTestVector( 626 "cofactor = 2", 627 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 628 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 629 + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff" 630 + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53" 631 + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d" 632 + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33" 633 + "576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffff" 634 + "bce6faada7179e84f3b9cac2fc63255102010203420004cdeb39edd03e2b1a11" 635 + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b" 636 + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 637 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 638 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 639 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 640 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 641 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 642 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), 643 2, 644 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 645 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)), 646 new EcPublicKeyTestVector( 647 "cofactor = None", 648 "308201303081e906072a8648ce3d02013081dd020101302c06072a8648ce3d01" 649 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 650 + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff" 651 + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53" 652 + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d" 653 + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33" 654 + "576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffff" 655 + "bce6faada7179e84f3b9cac2fc63255103420004cdeb39edd03e2b1a11a5e134" 656 + "ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb8" 657 + "5c3303ddb1553c3b761c2caacca71606ba9ebac8", 658 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 659 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 660 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 661 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 662 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 663 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), 664 null, 665 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 666 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)), 667 new EcPublicKeyTestVector( 668 "modified prime", 669 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 670 + "01022100fd091059a6893635f900e9449d63f572b2aebc4cff7b4e5e33f1b200" 671 + "e8bbc1453044042002f6efa55976c9cb06ff16bb629c0a8d4d5143b40084b1a1" 672 + "cc0e4dff17443eb704205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53" 673 + "b0f63bce3c3e27d2604b0441040000000000000000000006597fa94b1fd90000" 674 + "000000000000000000000000021b8c7dd77f9a95627922eceefea73f028f1ec9" 675 + "5ba9b8fa95a3ad24bdf9fff414022100ffffffff00000000ffffffffffffffff" 676 + "bce6faada7179e84f3b9cac2fc63255102010103420004000000000000000000" 677 + "0006597fa94b1fd90000000000000000000000000000021b8c7dd77f9a956279" 678 + "22eceefea73f028f1ec95ba9b8fa95a3ad24bdf9fff414", 679 new BigInteger("fd091059a6893635f900e9449d63f572b2aebc4cff7b4e5e33f1b200e8bbc145", 16), 680 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 681 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 682 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 683 new BigInteger("06597fa94b1fd9000000000000000000000000000002", 16), 684 new BigInteger("1b8c7dd77f9a95627922eceefea73f028f1ec95ba9b8fa95a3ad24bdf9fff414", 16), 685 1, 686 new BigInteger("06597fa94b1fd9000000000000000000000000000002", 16), 687 new BigInteger("1b8c7dd77f9a95627922eceefea73f028f1ec95ba9b8fa95a3ad24bdf9fff414", 16)), 688 new EcPublicKeyTestVector( 689 "using secp224r1", 690 "304e301006072a8648ce3d020106052b81040021033a0004074f56dc2ea648ef" 691 + "89c3b72e23bbd2da36f60243e4d2067b70604af1c2165cec2f86603d60c8a611" 692 + "d5b84ba3d91dfe1a480825bcc4af3bcf", 693 new BigInteger("ffffffffffffffffffffffffffffffff000000000000000000000001", 16), 694 new BigInteger("ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d", 16), 695 new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffffffffffe", 16), 696 new BigInteger("b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", 16), 697 new BigInteger("b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", 16), 698 new BigInteger("bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", 16), 699 1, 700 new BigInteger("074f56dc2ea648ef89c3b72e23bbd2da36f60243e4d2067b70604af1", 16), 701 new BigInteger("c2165cec2f86603d60c8a611d5b84ba3d91dfe1a480825bcc4af3bcf", 16)), 702 new EcPublicKeyTestVector( 703 "a = 0", 704 "308201143081cd06072a8648ce3d02013081c1020101302c06072a8648ce3d01" 705 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 706 + "ffffffff30250401000420f104880c3980129c7efa19b6b0cb04e547b8d0fc0b" 707 + "95f4946496dd4ac4a7c440044104cdeb39edd03e2b1a11a5e134ec99d5f25f21" 708 + "673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb85c3303ddb155" 709 + "3c3b761c2caacca71606ba9ebac8022100ffffffff00000000ffffffffffffff" 710 + "ffbce6faada7179e84f3b9cac2fc63255102010103420004cdeb39edd03e2b1a" 711 + "11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c" 712 + "0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 713 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 714 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 715 new BigInteger("0"), 716 new BigInteger("f104880c3980129c7efa19b6b0cb04e547b8d0fc0b95f4946496dd4ac4a7c440", 16), 717 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 718 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16), 719 1, 720 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 721 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)), 722 new EcPublicKeyTestVector( 723 "new curve with generator of order 3 that is also on secp256r1", 724 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 725 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 726 + "ffffffff3044042046dc879a5c2995d0e6f682468ea95791b7bbd0225cfdb251" 727 + "3fb10a737afece170420bea6c109251bfe4acf2eeda7c24c4ab70a1473335dec" 728 + "28b244d4d823d15935e2044104701c05255026aa4630b78fc6b769e388059ab1" 729 + "443cbdd1f8348bedc3be589dc34cfdab998ad27738ae382aa013986ade0f4859" 730 + "2a9a1ae37ca61d25ec5356f1bd022100ffffffff00000000ffffffffffffffff" 731 + "bce6faada7179e84f3b9cac2fc63255102010103420004701c05255026aa4630" 732 + "b78fc6b769e388059ab1443cbdd1f8348bedc3be589dc3b3025465752d88c851" 733 + "c7d55fec679521f0b7a6d665e51c8359e2da13aca90e42", 734 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 735 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 736 new BigInteger("46dc879a5c2995d0e6f682468ea95791b7bbd0225cfdb2513fb10a737afece17", 16), 737 new BigInteger("bea6c109251bfe4acf2eeda7c24c4ab70a1473335dec28b244d4d823d15935e2", 16), 738 new BigInteger("701c05255026aa4630b78fc6b769e388059ab1443cbdd1f8348bedc3be589dc3", 16), 739 new BigInteger("4cfdab998ad27738ae382aa013986ade0f48592a9a1ae37ca61d25ec5356f1bd", 16), 740 1, 741 new BigInteger("701c05255026aa4630b78fc6b769e388059ab1443cbdd1f8348bedc3be589dc3", 16), 742 new BigInteger("b3025465752d88c851c7d55fec679521f0b7a6d665e51c8359e2da13aca90e42", 16)), 743 // Invalid keys 744 new EcPublicKeyTestVector( 745 "order = -1157920892103562487626974469494075735299969552241357603" 746 + "42422259061068512044369", 747 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 748 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 749 + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff" 750 + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53" 751 + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d" 752 + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33" 753 + "576b315ececbb6406837bf51f50221ff00000000ffffffff0000000000000000" 754 + "4319055258e8617b0c46353d039cdaaf02010103420004cdeb39edd03e2b1a11" 755 + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b" 756 + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 757 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 758 new BigInteger( 759 "-115792089210356248762697446949407573529996955224135760342422259061068512044369"), 760 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 761 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 762 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 763 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), 764 1, 765 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 766 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)), 767 new EcPublicKeyTestVector( 768 "order = 0", 769 "308201133081cc06072a8648ce3d02013081c0020101302c06072a8648ce3d01" 770 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 771 + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff" 772 + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53" 773 + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d" 774 + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33" 775 + "576b315ececbb6406837bf51f502010002010103420004cdeb39edd03e2b1a11" 776 + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b" 777 + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 778 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 779 new BigInteger("0"), 780 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 781 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 782 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 783 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), 784 1, 785 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 786 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)), 787 new EcPublicKeyTestVector( 788 "cofactor = -1", 789 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 790 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 791 + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff" 792 + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53" 793 + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d" 794 + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33" 795 + "576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffff" 796 + "bce6faada7179e84f3b9cac2fc6325510201ff03420004cdeb39edd03e2b1a11" 797 + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b" 798 + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 799 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 800 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 801 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 802 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 803 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 804 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), 805 -1, 806 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 807 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)), 808 new EcPublicKeyTestVector( 809 "cofactor = 0", 810 "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01" 811 + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff" 812 + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff" 813 + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53" 814 + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d" 815 + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33" 816 + "576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffff" 817 + "bce6faada7179e84f3b9cac2fc63255102010003420004cdeb39edd03e2b1a11" 818 + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b" 819 + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 820 new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16), 821 new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16), 822 new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), 823 new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), 824 new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16), 825 new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16), 826 0, 827 new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16), 828 new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)), 829 }; 830 831 /** Checks that key agreement using ECDH works. */ 832 @ExcludedTest( 833 providers = {ProviderType.BOUNCY_CASTLE}, 834 comment = "KeyPairGenerator.EC is removed") testBasic()835 public void testBasic() throws Exception { 836 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); 837 ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1"); 838 keyGen.initialize(ecSpec); 839 KeyPair keyPairA = keyGen.generateKeyPair(); 840 KeyPair keyPairB = keyGen.generateKeyPair(); 841 842 KeyAgreement kaA = KeyAgreement.getInstance("ECDH"); 843 KeyAgreement kaB = KeyAgreement.getInstance("ECDH"); 844 kaA.init(keyPairA.getPrivate()); 845 kaB.init(keyPairB.getPrivate()); 846 kaA.doPhase(keyPairB.getPublic(), true); 847 kaB.doPhase(keyPairA.getPublic(), true); 848 byte[] kAB = kaA.generateSecret(); 849 byte[] kBA = kaB.generateSecret(); 850 assertEquals(TestUtil.bytesToHex(kAB), TestUtil.bytesToHex(kBA)); 851 } 852 853 @ExcludedTest( 854 providers = {ProviderType.BOUNCY_CASTLE}, 855 comment = "KeyAgreement.ECDH is removed") testVectors()856 public void testVectors() throws Exception { 857 KeyAgreement ka = KeyAgreement.getInstance("ECDH"); 858 for (EcdhTestVector t : ECDH_TEST_VECTORS) { 859 try { 860 ka.init(t.getPrivateKey()); 861 ka.doPhase(t.getPublicKey(), true); 862 byte[] shared = ka.generateSecret(); 863 assertEquals("Curve:" + t.curvename, TestUtil.bytesToHex(shared), t.shared); 864 } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) { 865 // Skipped, because the provider does not support the curve. 866 } 867 } 868 } 869 870 @ExcludedTest( 871 providers = {ProviderType.BOUNCY_CASTLE}, 872 comment = "KeyFactory.EC is removed") testDecode()873 public void testDecode() throws Exception { 874 KeyFactory kf = KeyFactory.getInstance("EC"); 875 ECPublicKey key1 = (ECPublicKey) kf.generatePublic(EC_VALID_PUBLIC_KEY.getSpec()); 876 ECPublicKey key2 = (ECPublicKey) kf.generatePublic(EC_VALID_PUBLIC_KEY.getX509EncodedKeySpec()); 877 ECParameterSpec params1 = key1.getParams(); 878 ECParameterSpec params2 = key2.getParams(); 879 assertEquals(params1.getCofactor(), params2.getCofactor()); 880 assertEquals(params1.getCurve(), params2.getCurve()); 881 assertEquals(params1.getGenerator(), params2.getGenerator()); 882 assertEquals(params1.getOrder(), params2.getOrder()); 883 assertEquals(key1.getW(), key2.getW()); 884 } 885 886 /** 887 * This test modifies the order of group in the public key. A severe bug would be an 888 * implementation that leaks information whether the private key is larger than the order given in 889 * the public key. Also a severe bug would be to reduce the private key modulo the order given in 890 * the public key parameters. 891 */ 892 @SuppressWarnings("InsecureCryptoUsage") testModifiedPublic(String algorithm)893 public void testModifiedPublic(String algorithm) throws Exception { 894 KeyAgreement ka; 895 try { 896 ka = KeyAgreement.getInstance(algorithm); 897 } catch (NoSuchAlgorithmException ex) { 898 System.out.println("testWrongOrder: " + algorithm + " not supported"); 899 return; 900 } 901 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); 902 keyGen.initialize(EcUtil.getNistP256Params()); 903 ECPrivateKey priv = (ECPrivateKey) keyGen.generateKeyPair().getPrivate(); 904 KeyFactory kf = KeyFactory.getInstance("EC"); 905 ECPublicKey validKey = (ECPublicKey) kf.generatePublic(EC_VALID_PUBLIC_KEY.getSpec()); 906 ka.init(priv); 907 ka.doPhase(validKey, true); 908 String expected = TestUtil.bytesToHex(ka.generateSecret()); 909 for (EcPublicKeyTestVector test : EC_MODIFIED_PUBLIC_KEYS) { 910 try { 911 X509EncodedKeySpec spec = test.getX509EncodedKeySpec(); 912 ECPublicKey modifiedKey = (ECPublicKey) kf.generatePublic(spec); 913 ka.init(priv); 914 ka.doPhase(modifiedKey, true); 915 String shared = TestUtil.bytesToHex(ka.generateSecret()); 916 // The implementation did not notice that the public key was modified. 917 // This is not nice, but at the moment we only fail the test if the 918 // modification was essential for computing the shared secret. 919 // 920 // BouncyCastle v.1.53 fails this test, for ECDHC with modified order. 921 // This implementation reduces the product s*h modulo the order given 922 // in the public key. An attacker who can modify the order of the public key 923 // and who can learn whether such a modification changes the shared secret is 924 // able to learn the private key with a simple binary search. 925 assertEquals("algorithm:" + algorithm + " test:" + test.comment, expected, shared); 926 } catch (GeneralSecurityException ex) { 927 // OK, since the public keys have been modified. 928 System.out.println("testModifiedPublic:" + test.comment + " throws " + ex.toString()); 929 } 930 } 931 } 932 933 /** 934 * This is a similar test as testModifiedPublic. However, this test uses test vectors 935 * ECPublicKeySpec 936 */ 937 @SuppressWarnings("InsecureCryptoUsage") testModifiedPublicSpec(String algorithm)938 public void testModifiedPublicSpec(String algorithm) throws Exception { 939 KeyAgreement ka; 940 try { 941 ka = KeyAgreement.getInstance(algorithm); 942 } catch (NoSuchAlgorithmException ex) { 943 System.out.println("testWrongOrder: " + algorithm + " not supported"); 944 return; 945 } 946 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); 947 keyGen.initialize(EcUtil.getNistP256Params()); 948 ECPrivateKey priv = (ECPrivateKey) keyGen.generateKeyPair().getPrivate(); 949 KeyFactory kf = KeyFactory.getInstance("EC"); 950 ECPublicKey validKey = (ECPublicKey) kf.generatePublic(EC_VALID_PUBLIC_KEY.getSpec()); 951 ka.init(priv); 952 ka.doPhase(validKey, true); 953 String expected = TestUtil.bytesToHex(ka.generateSecret()); 954 for (EcPublicKeyTestVector test : EC_MODIFIED_PUBLIC_KEYS) { 955 ECPublicKeySpec spec = test.getSpec(); 956 if (spec == null) { 957 // The constructor of EcPublicKeySpec performs some very minor validity checks. 958 // spec == null if one of these validity checks fails. Of course such a failure is OK. 959 continue; 960 } 961 try { 962 ECPublicKey modifiedKey = (ECPublicKey) kf.generatePublic(spec); 963 ka.init(priv); 964 ka.doPhase(modifiedKey, true); 965 String shared = TestUtil.bytesToHex(ka.generateSecret()); 966 // The implementation did not notice that the public key was modified. 967 // This is not nice, but at the moment we only fail the test if the 968 // modification was essential for computing the shared secret. 969 // 970 // BouncyCastle v.1.53 fails this test, for ECDHC with modified order. 971 // This implementation reduces the product s*h modulo the order given 972 // in the public key. An attacker who can modify the order of the public key 973 // and who can learn whether such a modification changes the shared secret is 974 // able to learn the private key with a simple binary search. 975 assertEquals("algorithm:" + algorithm + " test:" + test.comment, expected, shared); 976 } catch (GeneralSecurityException ex) { 977 // OK, since the public keys have been modified. 978 System.out.println("testModifiedPublic:" + test.comment + " throws " + ex.toString()); 979 } 980 } 981 } 982 testModifiedPublic()983 public void testModifiedPublic() throws Exception { 984 testModifiedPublic("ECDH"); 985 testModifiedPublic("ECDHC"); 986 } 987 testModifiedPublicSpec()988 public void testModifiedPublicSpec() throws Exception { 989 testModifiedPublicSpec("ECDH"); 990 testModifiedPublicSpec("ECDHC"); 991 } 992 993 @SuppressWarnings("InsecureCryptoUsage") testDistinctCurves(String algorithm, ECPrivateKey priv, ECPublicKey pub)994 public void testDistinctCurves(String algorithm, ECPrivateKey priv, ECPublicKey pub) 995 throws Exception { 996 KeyAgreement kaA; 997 try { 998 kaA = KeyAgreement.getInstance(algorithm); 999 } catch (NoSuchAlgorithmException ex) { 1000 System.out.println("Algorithm not supported: " + algorithm); 1001 return; 1002 } 1003 byte[] shared; 1004 try { 1005 kaA.init(priv); 1006 kaA.doPhase(pub, true); 1007 shared = kaA.generateSecret(); 1008 } catch (InvalidKeyException ex) { 1009 // This is expected. 1010 return; 1011 } 1012 // Printing some information to determine what might have gone wrong: 1013 // E.g., if the generated secret is the same as the x-coordinate of the public key 1014 // then it is likely that the ECDH computation was using a fake group with small order. 1015 // Such a situation is probably exploitable. 1016 // This probably is exploitable. If the curve of the private key was used for the ECDH 1017 // then the generated secret and the x-coordinate of the public key are likely 1018 // distinct. 1019 EllipticCurve pubCurve = pub.getParams().getCurve(); 1020 EllipticCurve privCurve = priv.getParams().getCurve(); 1021 ECPoint pubW = pub.getW(); 1022 System.out.println("testDistinctCurves: algorithm=" + algorithm); 1023 System.out.println( 1024 "Private key: a=" 1025 + privCurve.getA() 1026 + " b=" 1027 + privCurve.getB() 1028 + " p" 1029 + EcUtil.getModulus(privCurve)); 1030 System.out.println(" s =" + priv.getS()); 1031 System.out.println( 1032 "Public key: a=" 1033 + pubCurve.getA() 1034 + " b=" 1035 + pubCurve.getB() 1036 + " p" 1037 + EcUtil.getModulus(pubCurve)); 1038 System.out.println(" w = (" + pubW.getAffineX() + ", " + pubW.getAffineY() + ")"); 1039 System.out.println( 1040 " = (" 1041 + pubW.getAffineX().toString(16) 1042 + ", " 1043 + pubW.getAffineY().toString(16) 1044 + ")"); 1045 System.out.println("generated shared secret:" + TestUtil.bytesToHex(shared)); 1046 fail("Generated secret with distinct Curves using " + algorithm); 1047 } 1048 1049 /** 1050 * This test modifies the order of group in the public key. A severe bug would be an 1051 * implementation that leaks information whether the private key is larger than the order given in 1052 * the public key. Also a severe bug would be to reduce the private key modulo the order given in 1053 * the public key parameters. 1054 */ 1055 // TODO(bleichen): This can be merged with testModifiedPublic once this is fixed. 1056 @SuppressWarnings("InsecureCryptoUsage") testWrongOrder(String algorithm, ECParameterSpec spec)1057 public void testWrongOrder(String algorithm, ECParameterSpec spec) throws Exception { 1058 KeyAgreement ka; 1059 try { 1060 ka = KeyAgreement.getInstance(algorithm); 1061 } catch (NoSuchAlgorithmException ex) { 1062 System.out.println("testWrongOrder: " + algorithm + " not supported"); 1063 return; 1064 } 1065 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); 1066 ECPrivateKey priv; 1067 ECPublicKey pub; 1068 try { 1069 keyGen.initialize(spec); 1070 priv = (ECPrivateKey) keyGen.generateKeyPair().getPrivate(); 1071 pub = (ECPublicKey) keyGen.generateKeyPair().getPublic(); 1072 } catch (GeneralSecurityException ex) { 1073 // This is OK, since not all provider support Brainpool curves 1074 System.out.println("testWrongOrder: could not generate keys for curve"); 1075 return; 1076 } 1077 // Get the shared secret for the unmodified keys. 1078 ka.init(priv); 1079 ka.doPhase(pub, true); 1080 byte[] shared = ka.generateSecret(); 1081 // Generate a modified public key. 1082 ECParameterSpec modifiedParams = 1083 new ECParameterSpec( 1084 spec.getCurve(), spec.getGenerator(), spec.getOrder().shiftRight(16), 1); 1085 ECPublicKeySpec modifiedPubSpec = new ECPublicKeySpec(pub.getW(), modifiedParams); 1086 KeyFactory kf = KeyFactory.getInstance("EC"); 1087 ECPublicKey modifiedPub; 1088 try { 1089 modifiedPub = (ECPublicKey) kf.generatePublic(modifiedPubSpec); 1090 } catch (GeneralSecurityException ex) { 1091 // The provider does not support non-standard curves or did a validity check. 1092 // Both would be correct. 1093 System.out.println("testWrongOrder: can't modify order."); 1094 return; 1095 } 1096 byte[] shared2; 1097 try { 1098 ka.init(priv); 1099 ka.doPhase(modifiedPub, true); 1100 shared2 = ka.generateSecret(); 1101 } catch (GeneralSecurityException ex) { 1102 // This is the expected behavior 1103 System.out.println("testWrongOrder:" + ex.toString()); 1104 return; 1105 } 1106 // TODO(bleichen): Getting here is already a bug and we might flag this later. 1107 // At the moment we are only interested in really bad behavior of a library, that potentially 1108 // leaks the secret key. This is the case when the shared secrets are different, since this 1109 // suggests that the implementation reduces the multiplier modulo the given order of the curve 1110 // or some other behaviour that is dependent on the private key. 1111 // An attacker who can check whether a DH computation was done correctly or incorrectly because 1112 // of modular reduction, can determine the private key, either by a binary search or by trying 1113 // to guess the private key modulo some small "order". 1114 // BouncyCastle v.1.53 fails this test, and leaks the private key. 1115 System.out.println( 1116 "Generated shared secret with a modified order:" 1117 + algorithm 1118 + "\n" 1119 + "expected:" 1120 + TestUtil.bytesToHex(shared) 1121 + " computed:" 1122 + TestUtil.bytesToHex(shared2)); 1123 assertEquals( 1124 "Algorithm:" + algorithm, TestUtil.bytesToHex(shared), TestUtil.bytesToHex(shared2)); 1125 } 1126 testWrongOrderEcdh()1127 public void testWrongOrderEcdh() throws Exception { 1128 testWrongOrder("ECDH", EcUtil.getNistP256Params()); 1129 testWrongOrder("ECDH", EcUtil.getBrainpoolP256r1Params()); 1130 } 1131 testWrongOrderEcdhc()1132 public void testWrongOrderEcdhc() throws Exception { 1133 testWrongOrder("ECDHC", EcUtil.getNistP256Params()); 1134 testWrongOrder("ECDHC", EcUtil.getBrainpoolP256r1Params()); 1135 } 1136 } 1137