1 /* 2 * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.ec; 27 28 import java.nio.ByteBuffer; 29 30 import java.security.*; 31 import java.security.interfaces.*; 32 import java.security.spec.*; 33 import java.util.Optional; 34 35 import sun.security.jca.JCAUtil; 36 import sun.security.util.*; 37 import static sun.security.ec.ECOperations.IntermediateValueException; 38 39 /** 40 * ECDSA signature implementation. This class currently supports the 41 * following algorithm names: 42 * 43 * . "NONEwithECDSA" 44 * . "SHA1withECDSA" 45 * . "SHA224withECDSA" 46 * . "SHA256withECDSA" 47 * . "SHA384withECDSA" 48 * . "SHA512withECDSA" 49 * . "NONEwithECDSAinP1363Format" 50 * . "SHA1withECDSAinP1363Format" 51 * . "SHA224withECDSAinP1363Format" 52 * . "SHA256withECDSAinP1363Format" 53 * . "SHA384withECDSAinP1363Format" 54 * . "SHA512withECDSAinP1363Format" 55 * 56 * @since 1.7 57 */ 58 abstract class ECDSASignature extends SignatureSpi { 59 60 // message digest implementation we use 61 private final MessageDigest messageDigest; 62 63 // supplied entropy 64 private SecureRandom random; 65 66 // flag indicating whether the digest has been reset 67 private boolean needsReset; 68 69 // private key, if initialized for signing 70 private ECPrivateKey privateKey; 71 72 // public key, if initialized for verifying 73 private ECPublicKey publicKey; 74 75 // signature parameters 76 private ECParameterSpec sigParams = null; 77 78 // The format. true for the IEEE P1363 format. false (default) for ASN.1 79 private final boolean p1363Format; 80 81 /** 82 * Constructs a new ECDSASignature. 83 * 84 * @exception ProviderException if the native ECC library is unavailable. 85 */ 86 ECDSASignature() { 87 this(false); 88 } 89 90 /** 91 * Constructs a new ECDSASignature that will use the specified 92 * signature format. {@code p1363Format} should be {@code true} to 93 * use the IEEE P1363 format. If {@code p1363Format} is {@code false}, 94 * the DER-encoded ASN.1 format will be used. This constructor is 95 * used by the RawECDSA subclasses. 96 */ 97 ECDSASignature(boolean p1363Format) { 98 this.messageDigest = null; 99 this.p1363Format = p1363Format; 100 } 101 102 /** 103 * Constructs a new ECDSASignature. Used by subclasses. 104 */ 105 ECDSASignature(String digestName) { 106 this(digestName, false); 107 } 108 109 /** 110 * Constructs a new ECDSASignature that will use the specified 111 * digest and signature format. {@code p1363Format} should be 112 * {@code true} to use the IEEE P1363 format. If {@code p1363Format} 113 * is {@code false}, the DER-encoded ASN.1 format will be used. This 114 * constructor is used by subclasses. 115 */ 116 ECDSASignature(String digestName, boolean p1363Format) { 117 try { 118 messageDigest = MessageDigest.getInstance(digestName); 119 } catch (NoSuchAlgorithmException e) { 120 throw new ProviderException(e); 121 } 122 this.needsReset = false; 123 this.p1363Format = p1363Format; 124 } 125 126 // Class for Raw ECDSA signatures. 127 static class RawECDSA extends ECDSASignature { 128 129 // the longest supported digest is 512 bits (SHA-512) 130 private static final int RAW_ECDSA_MAX = 64; 131 132 private final byte[] precomputedDigest; 133 private int offset = 0; 134 135 RawECDSA(boolean p1363Format) { 136 super(p1363Format); 137 precomputedDigest = new byte[RAW_ECDSA_MAX]; 138 } 139 140 // Stores the precomputed message digest value. 141 @Override 142 protected void engineUpdate(byte b) throws SignatureException { 143 if (offset >= precomputedDigest.length) { 144 offset = RAW_ECDSA_MAX + 1; 145 return; 146 } 147 precomputedDigest[offset++] = b; 148 } 149 150 // Stores the precomputed message digest value. 151 @Override 152 protected void engineUpdate(byte[] b, int off, int len) 153 throws SignatureException { 154 if (offset >= precomputedDigest.length) { 155 offset = RAW_ECDSA_MAX + 1; 156 return; 157 } 158 System.arraycopy(b, off, precomputedDigest, offset, len); 159 offset += len; 160 } 161 162 // Stores the precomputed message digest value. 163 @Override 164 protected void engineUpdate(ByteBuffer byteBuffer) { 165 int len = byteBuffer.remaining(); 166 if (len <= 0) { 167 return; 168 } 169 if (len >= precomputedDigest.length - offset) { 170 offset = RAW_ECDSA_MAX + 1; 171 return; 172 } 173 byteBuffer.get(precomputedDigest, offset, len); 174 offset += len; 175 } 176 177 @Override 178 protected void resetDigest() { 179 offset = 0; 180 } 181 182 // Returns the precomputed message digest value. 183 @Override 184 protected byte[] getDigestValue() throws SignatureException { 185 if (offset > RAW_ECDSA_MAX) { 186 throw new SignatureException("Message digest is too long"); 187 188 } 189 byte[] result = new byte[offset]; 190 System.arraycopy(precomputedDigest, 0, result, 0, offset); 191 offset = 0; 192 193 return result; 194 } 195 } 196 197 // Nested class for NONEwithECDSA signatures 198 public static final class Raw extends RawECDSA { 199 public Raw() { 200 super(false); 201 } 202 } 203 204 // Nested class for NONEwithECDSAinP1363Format signatures 205 public static final class RawinP1363Format extends RawECDSA { 206 public RawinP1363Format() { 207 super(true); 208 } 209 } 210 211 // Nested class for SHA1withECDSA signatures 212 public static final class SHA1 extends ECDSASignature { 213 public SHA1() { 214 super("SHA1"); 215 } 216 } 217 218 // Nested class for SHA1withECDSAinP1363Format signatures 219 public static final class SHA1inP1363Format extends ECDSASignature { 220 public SHA1inP1363Format() { 221 super("SHA1", true); 222 } 223 } 224 225 // Nested class for SHA224withECDSA signatures 226 public static final class SHA224 extends ECDSASignature { 227 public SHA224() { 228 super("SHA-224"); 229 } 230 } 231 232 // Nested class for SHA224withECDSAinP1363Format signatures 233 public static final class SHA224inP1363Format extends ECDSASignature { 234 public SHA224inP1363Format() { 235 super("SHA-224", true); 236 } 237 } 238 239 // Nested class for SHA256withECDSA signatures 240 public static final class SHA256 extends ECDSASignature { 241 public SHA256() { 242 super("SHA-256"); 243 } 244 } 245 246 // Nested class for SHA256withECDSAinP1363Format signatures 247 public static final class SHA256inP1363Format extends ECDSASignature { 248 public SHA256inP1363Format() { 249 super("SHA-256", true); 250 } 251 } 252 253 // Nested class for SHA384withECDSA signatures 254 public static final class SHA384 extends ECDSASignature { 255 public SHA384() { 256 super("SHA-384"); 257 } 258 } 259 260 // Nested class for SHA384withECDSAinP1363Format signatures 261 public static final class SHA384inP1363Format extends ECDSASignature { 262 public SHA384inP1363Format() { 263 super("SHA-384", true); 264 } 265 } 266 267 // Nested class for SHA512withECDSA signatures 268 public static final class SHA512 extends ECDSASignature { 269 public SHA512() { 270 super("SHA-512"); 271 } 272 } 273 274 // Nested class for SHA512withECDSAinP1363Format signatures 275 public static final class SHA512inP1363Format extends ECDSASignature { 276 public SHA512inP1363Format() { 277 super("SHA-512", true); 278 } 279 } 280 281 // initialize for verification. See JCA doc 282 @Override 283 protected void engineInitVerify(PublicKey publicKey) 284 throws InvalidKeyException { 285 ECPublicKey key = (ECPublicKey) ECKeyFactory.toECKey(publicKey); 286 if (!isCompatible(this.sigParams, key.getParams())) { 287 throw new InvalidKeyException("Key params does not match signature params"); 288 } 289 290 // Should check that the supplied key is appropriate for signature 291 // algorithm (e.g. P-256 for SHA256withECDSA) 292 this.publicKey = key; 293 this.privateKey = null; 294 resetDigest(); 295 } 296 297 // initialize for signing. See JCA doc 298 @Override 299 protected void engineInitSign(PrivateKey privateKey) 300 throws InvalidKeyException { 301 engineInitSign(privateKey, null); 302 } 303 304 // initialize for signing. See JCA doc 305 @Override 306 protected void engineInitSign(PrivateKey privateKey, SecureRandom random) 307 throws InvalidKeyException { 308 ECPrivateKey key = (ECPrivateKey) ECKeyFactory.toECKey(privateKey); 309 if (!isCompatible(this.sigParams, key.getParams())) { 310 throw new InvalidKeyException("Key params does not match signature params"); 311 } 312 313 // Should check that the supplied key is appropriate for signature 314 // algorithm (e.g. P-256 for SHA256withECDSA) 315 this.privateKey = key; 316 this.publicKey = null; 317 this.random = random; 318 resetDigest(); 319 } 320 321 /** 322 * Resets the message digest if needed. 323 */ 324 protected void resetDigest() { 325 if (needsReset) { 326 if (messageDigest != null) { 327 messageDigest.reset(); 328 } 329 needsReset = false; 330 } 331 } 332 333 /** 334 * Returns the message digest value. 335 */ 336 protected byte[] getDigestValue() throws SignatureException { 337 needsReset = false; 338 return messageDigest.digest(); 339 } 340 341 // update the signature with the plaintext data. See JCA doc 342 @Override 343 protected void engineUpdate(byte b) throws SignatureException { 344 messageDigest.update(b); 345 needsReset = true; 346 } 347 348 // update the signature with the plaintext data. See JCA doc 349 @Override 350 protected void engineUpdate(byte[] b, int off, int len) 351 throws SignatureException { 352 messageDigest.update(b, off, len); 353 needsReset = true; 354 } 355 356 // update the signature with the plaintext data. See JCA doc 357 @Override 358 protected void engineUpdate(ByteBuffer byteBuffer) { 359 int len = byteBuffer.remaining(); 360 if (len <= 0) { 361 return; 362 } 363 364 messageDigest.update(byteBuffer); 365 needsReset = true; 366 } 367 368 private static boolean isCompatible(ECParameterSpec sigParams, 369 ECParameterSpec keyParams) { 370 if (sigParams == null) { 371 // no restriction on key param 372 return true; 373 } 374 return ECUtil.equals(sigParams, keyParams); 375 } 376 377 private byte[] signDigestImpl(ECDSAOperations ops, int seedBits, 378 byte[] digest, ECPrivateKey priv, SecureRandom random) 379 throws SignatureException { 380 381 byte[] seedBytes = new byte[(seedBits + 7) / 8]; 382 byte[] s = priv instanceof ECPrivateKeyImpl 383 ? ((ECPrivateKeyImpl)priv).getArrayS() 384 : ECUtil.sArray(priv.getS(), priv.getParams()); 385 386 // Attempt to create the signature in a loop that uses new random input 387 // each time. The chance of failure is very small assuming the 388 // implementation derives the nonce using extra bits 389 int numAttempts = 128; 390 for (int i = 0; i < numAttempts; i++) { 391 random.nextBytes(seedBytes); 392 ECDSAOperations.Seed seed = new ECDSAOperations.Seed(seedBytes); 393 try { 394 return ops.signDigest(s, digest, seed); 395 } catch (IntermediateValueException ex) { 396 // try again in the next iteration 397 } 398 } 399 400 throw new SignatureException("Unable to produce signature after " 401 + numAttempts + " attempts"); 402 } 403 404 405 private Optional<byte[]> signDigestAvailable(ECPrivateKey privateKey, 406 byte[] digest, SecureRandom random) throws SignatureException { 407 408 ECParameterSpec params = privateKey.getParams(); 409 410 // seed is the key size + 64 bits 411 int seedBits = params.getOrder().bitLength() + 64; 412 Optional<ECDSAOperations> opsOpt = 413 ECDSAOperations.forParameters(params); 414 if (opsOpt.isEmpty()) { 415 return Optional.empty(); 416 } else { 417 byte[] sig = signDigestImpl(opsOpt.get(), seedBits, digest, 418 privateKey, random); 419 return Optional.of(sig); 420 } 421 } 422 423 private byte[] signDigestNative(ECPrivateKey privateKey, byte[] digest, 424 SecureRandom random) throws SignatureException { 425 426 byte[] s = privateKey.getS().toByteArray(); 427 ECParameterSpec params = privateKey.getParams(); 428 429 // DER OID 430 byte[] encodedParams = ECUtil.encodeECParameterSpec(null, params); 431 int orderLength = params.getOrder().bitLength(); 432 433 // seed is twice the order length (in bytes) plus 1 434 byte[] seed = new byte[(((orderLength + 7) >> 3) + 1) * 2]; 435 436 random.nextBytes(seed); 437 438 // random bits needed for timing countermeasures 439 int timingArgument = random.nextInt(); 440 // values must be non-zero to enable countermeasures 441 timingArgument |= 1; 442 443 try { 444 return signDigest(digest, s, encodedParams, seed, 445 timingArgument); 446 } catch (GeneralSecurityException e) { 447 throw new SignatureException("Could not sign data", e); 448 } 449 450 } 451 452 // sign the data and return the signature. See JCA doc 453 @Override 454 protected byte[] engineSign() throws SignatureException { 455 456 if (random == null) { 457 random = JCAUtil.getSecureRandom(); 458 } 459 460 byte[] digest = getDigestValue(); 461 Optional<byte[]> sigOpt = signDigestAvailable(privateKey, digest, random); 462 byte[] sig; 463 if (sigOpt.isPresent()) { 464 sig = sigOpt.get(); 465 } else { 466 if (SunEC.isNativeDisabled()) { 467 NamedCurve nc = CurveDB.lookup(privateKey.getParams()); 468 throw new SignatureException( 469 new InvalidAlgorithmParameterException( 470 "Legacy SunEC curve disabled: " + 471 (nc != null ? nc.toString() 472 : "unknown"))); 473 } 474 sig = signDigestNative(privateKey, digest, random); 475 } 476 477 if (p1363Format) { 478 return sig; 479 } else { 480 return ECUtil.encodeSignature(sig); 481 } 482 } 483 484 // verify the data and return the result. See JCA doc 485 @Override 486 protected boolean engineVerify(byte[] signature) throws SignatureException { 487 488 byte[] sig; 489 if (p1363Format) { 490 sig = signature; 491 } else { 492 sig = ECUtil.decodeSignature(signature); 493 } 494 495 byte[] digest = getDigestValue(); 496 Optional<Boolean> verifyOpt 497 = verifySignedDigestAvailable(publicKey, sig, digest); 498 499 if (verifyOpt.isPresent()) { 500 return verifyOpt.get(); 501 } else { 502 if (SunEC.isNativeDisabled()) { 503 NamedCurve nc = CurveDB.lookup(publicKey.getParams()); 504 throw new SignatureException( 505 new InvalidAlgorithmParameterException( 506 "Legacy SunEC curve disabled: " + 507 (nc != null ? nc.toString() 508 : "unknown"))); 509 } 510 511 byte[] w; 512 ECParameterSpec params = publicKey.getParams(); 513 // DER OID 514 byte[] encodedParams = ECUtil.encodeECParameterSpec(null, params); 515 516 if (publicKey instanceof ECPublicKeyImpl) { 517 w = ((ECPublicKeyImpl) publicKey).getEncodedPublicValue(); 518 } else { // instanceof ECPublicKey 519 w = ECUtil.encodePoint(publicKey.getW(), params.getCurve()); 520 } 521 522 try { 523 return verifySignedDigest(sig, digest, w, encodedParams); 524 } catch (GeneralSecurityException e) { 525 throw new SignatureException("Could not verify signature", e); 526 } 527 } 528 } 529 530 private Optional<Boolean> verifySignedDigestAvailable( 531 ECPublicKey publicKey, byte[] sig, byte[] digestValue) { 532 533 ECParameterSpec params = publicKey.getParams(); 534 535 Optional<ECDSAOperations> opsOpt = 536 ECDSAOperations.forParameters(params); 537 if (opsOpt.isEmpty()) { 538 return Optional.empty(); 539 } else { 540 boolean result = verifySignedDigestImpl(opsOpt.get(), digestValue, 541 publicKey, sig); 542 return Optional.of(result); 543 } 544 } 545 546 private boolean verifySignedDigestImpl(ECDSAOperations ops, 547 byte[] digest, ECPublicKey pub, byte[] sig) { 548 return ops.verifySignedDigest(digest, sig, pub.getW()); 549 } 550 551 // set parameter, not supported. See JCA doc 552 @Override 553 @Deprecated 554 protected void engineSetParameter(String param, Object value) 555 throws InvalidParameterException { 556 throw new UnsupportedOperationException("setParameter() not supported"); 557 } 558 559 @Override 560 protected void engineSetParameter(AlgorithmParameterSpec params) 561 throws InvalidAlgorithmParameterException { 562 if (params != null && !(params instanceof ECParameterSpec)) { 563 throw new InvalidAlgorithmParameterException("No parameter accepted"); 564 } 565 ECKey key = (this.privateKey == null? this.publicKey : this.privateKey); 566 if ((key != null) && !isCompatible((ECParameterSpec)params, key.getParams())) { 567 throw new InvalidAlgorithmParameterException 568 ("Signature params does not match key params"); 569 } 570 571 sigParams = (ECParameterSpec) params; 572 } 573 574 // get parameter, not supported. See JCA doc 575 @Override 576 @Deprecated 577 protected Object engineGetParameter(String param) 578 throws InvalidParameterException { 579 throw new UnsupportedOperationException("getParameter() not supported"); 580 } 581 582 @Override 583 protected AlgorithmParameters engineGetParameters() { 584 if (sigParams == null) { 585 return null; 586 } 587 try { 588 AlgorithmParameters ap = AlgorithmParameters.getInstance("EC"); 589 ap.init(sigParams); 590 return ap; 591 } catch (Exception e) { 592 // should never happen 593 throw new ProviderException("Error retrieving EC parameters", e); 594 } 595 } 596 597 /** 598 * Signs the digest using the private key. 599 * 600 * @param digest the digest to be signed. 601 * @param s the private key's S value. 602 * @param encodedParams the curve's DER encoded object identifier. 603 * @param seed the random seed. 604 * @param timing When non-zero, the implmentation will use timing 605 * countermeasures to hide secrets from timing channels. The EC 606 * implementation will disable the countermeasures when this value is 607 * zero, because the underlying EC functions are shared by several 608 * crypto operations, some of which do not use the countermeasures. 609 * The high-order 31 bits must be uniformly random. The entropy from 610 * these bits is used by the countermeasures. 611 * 612 * @return byte[] the signature. 613 */ 614 private static native byte[] signDigest(byte[] digest, byte[] s, 615 byte[] encodedParams, byte[] seed, int timing) 616 throws GeneralSecurityException; 617 618 /** 619 * Verifies the signed digest using the public key. 620 * 621 * @param signature the signature to be verified. It is encoded 622 * as a concatenation of the key's R and S values. 623 * @param digest the digest to be used. 624 * @param w the public key's W point (in uncompressed form). 625 * @param encodedParams the curve's DER encoded object identifier. 626 * 627 * @return boolean true if the signature is successfully verified. 628 */ 629 private static native boolean verifySignedDigest(byte[] signature, 630 byte[] digest, byte[] w, byte[] encodedParams) 631 throws GeneralSecurityException; 632 }