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