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