1 /* 2 * Copyright (c) 2009, 2018, 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.io.IOException; 29 import java.nio.ByteBuffer; 30 import java.math.BigInteger; 31 32 import java.security.*; 33 import java.security.interfaces.*; 34 import java.security.spec.*; 35 36 import sun.security.jca.JCAUtil; 37 import sun.security.util.*; 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 // The format. true for the IEEE P1363 format. false (default) for ASN.1 76 private final boolean p1363Format; 77 78 /** 79 * Constructs a new ECDSASignature. 80 * 81 * @exception ProviderException if the native ECC library is unavailable. 82 */ 83 ECDSASignature() { 84 this(false); 85 } 86 87 /** 88 * Constructs a new ECDSASignature that will use the specified 89 * signature format. {@code p1363Format} should be {@code true} to 90 * use the IEEE P1363 format. If {@code p1363Format} is {@code false}, 91 * the DER-encoded ASN.1 format will be used. This constructor is 92 * used by the RawECDSA subclasses. 93 */ 94 ECDSASignature(boolean p1363Format) { 95 this.messageDigest = null; 96 this.p1363Format = p1363Format; 97 } 98 99 /** 100 * Constructs a new ECDSASignature. Used by subclasses. 101 */ 102 ECDSASignature(String digestName) { 103 this(digestName, false); 104 } 105 106 /** 107 * Constructs a new ECDSASignature that will use the specified 108 * digest and signature format. {@code p1363Format} should be 109 * {@code true} to use the IEEE P1363 format. If {@code p1363Format} 110 * is {@code false}, the DER-encoded ASN.1 format will be used. This 111 * constructor is used by subclasses. 112 */ 113 ECDSASignature(String digestName, boolean p1363Format) { 114 try { 115 messageDigest = MessageDigest.getInstance(digestName); 116 } catch (NoSuchAlgorithmException e) { 117 throw new ProviderException(e); 118 } 119 this.needsReset = false; 120 this.p1363Format = p1363Format; 121 } 122 123 // Class for Raw ECDSA signatures. 124 static class RawECDSA extends ECDSASignature { 125 126 // the longest supported digest is 512 bits (SHA-512) 127 private static final int RAW_ECDSA_MAX = 64; 128 129 private final byte[] precomputedDigest; 130 private int offset = 0; 131 132 RawECDSA(boolean p1363Format) { 133 super(p1363Format); 134 precomputedDigest = new byte[RAW_ECDSA_MAX]; 135 } 136 137 // Stores the precomputed message digest value. 138 @Override 139 protected void engineUpdate(byte b) throws SignatureException { 140 if (offset >= precomputedDigest.length) { 141 offset = RAW_ECDSA_MAX + 1; 142 return; 143 } 144 precomputedDigest[offset++] = b; 145 } 146 147 // Stores the precomputed message digest value. 148 @Override 149 protected void engineUpdate(byte[] b, int off, int len) 150 throws SignatureException { 151 if (offset >= precomputedDigest.length) { 152 offset = RAW_ECDSA_MAX + 1; 153 return; 154 } 155 System.arraycopy(b, off, precomputedDigest, offset, len); 156 offset += len; 157 } 158 159 // Stores the precomputed message digest value. 160 @Override 161 protected void engineUpdate(ByteBuffer byteBuffer) { 162 int len = byteBuffer.remaining(); 163 if (len <= 0) { 164 return; 165 } 166 if (offset + len >= precomputedDigest.length) { 167 offset = RAW_ECDSA_MAX + 1; 168 return; 169 } 170 byteBuffer.get(precomputedDigest, offset, len); 171 offset += len; 172 } 173 174 @Override 175 protected void resetDigest(){ 176 offset = 0; 177 } 178 179 // Returns the precomputed message digest value. 180 @Override 181 protected byte[] getDigestValue() throws SignatureException { 182 if (offset > RAW_ECDSA_MAX) { 183 throw new SignatureException("Message digest is too long"); 184 185 } 186 byte[] result = new byte[offset]; 187 System.arraycopy(precomputedDigest, 0, result, 0, offset); 188 offset = 0; 189 190 return result; 191 } 192 } 193 194 // Nested class for NONEwithECDSA signatures 195 public static final class Raw extends RawECDSA { 196 public Raw() { 197 super(false); 198 } 199 } 200 201 // Nested class for NONEwithECDSAinP1363Format signatures 202 public static final class RawinP1363Format extends RawECDSA { 203 public RawinP1363Format() { 204 super(true); 205 } 206 } 207 208 // Nested class for SHA1withECDSA signatures 209 public static final class SHA1 extends ECDSASignature { 210 public SHA1() { 211 super("SHA1"); 212 } 213 } 214 215 // Nested class for SHA1withECDSAinP1363Format signatures 216 public static final class SHA1inP1363Format extends ECDSASignature { 217 public SHA1inP1363Format() { 218 super("SHA1", true); 219 } 220 } 221 222 // Nested class for SHA224withECDSA signatures 223 public static final class SHA224 extends ECDSASignature { 224 public SHA224() { 225 super("SHA-224"); 226 } 227 } 228 229 // Nested class for SHA224withECDSAinP1363Format signatures 230 public static final class SHA224inP1363Format extends ECDSASignature { 231 public SHA224inP1363Format() { 232 super("SHA-224", true); 233 } 234 } 235 236 // Nested class for SHA256withECDSA signatures 237 public static final class SHA256 extends ECDSASignature { 238 public SHA256() { 239 super("SHA-256"); 240 } 241 } 242 243 // Nested class for SHA256withECDSAinP1363Format signatures 244 public static final class SHA256inP1363Format extends ECDSASignature { 245 public SHA256inP1363Format() { 246 super("SHA-256", true); 247 } 248 } 249 250 // Nested class for SHA384withECDSA signatures 251 public static final class SHA384 extends ECDSASignature { 252 public SHA384() { 253 super("SHA-384"); 254 } 255 } 256 257 // Nested class for SHA384withECDSAinP1363Format signatures 258 public static final class SHA384inP1363Format extends ECDSASignature { 259 public SHA384inP1363Format() { 260 super("SHA-384", true); 261 } 262 } 263 264 // Nested class for SHA512withECDSA signatures 265 public static final class SHA512 extends ECDSASignature { 266 public SHA512() { 267 super("SHA-512"); 268 } 269 } 270 271 // Nested class for SHA512withECDSAinP1363Format signatures 272 public static final class SHA512inP1363Format extends ECDSASignature { 273 public SHA512inP1363Format() { 274 super("SHA-512", true); 275 } 276 } 277 278 // initialize for verification. See JCA doc 279 @Override 280 protected void engineInitVerify(PublicKey publicKey) 281 throws InvalidKeyException { 282 this.publicKey = (ECPublicKey) ECKeyFactory.toECKey(publicKey); 283 284 // Should check that the supplied key is appropriate for signature 285 // algorithm (e.g. P-256 for SHA256withECDSA) 286 this.privateKey = null; 287 resetDigest(); 288 } 289 290 // initialize for signing. See JCA doc 291 @Override 292 protected void engineInitSign(PrivateKey privateKey) 293 throws InvalidKeyException { 294 engineInitSign(privateKey, null); 295 } 296 297 // initialize for signing. See JCA doc 298 @Override 299 protected void engineInitSign(PrivateKey privateKey, SecureRandom random) 300 throws InvalidKeyException { 301 this.privateKey = (ECPrivateKey) ECKeyFactory.toECKey(privateKey); 302 303 // Should check that the supplied key is appropriate for signature 304 // algorithm (e.g. P-256 for SHA256withECDSA) 305 this.publicKey = null; 306 this.random = random; 307 resetDigest(); 308 } 309 310 /** 311 * Resets the message digest if needed. 312 */ 313 protected void resetDigest() { 314 if (needsReset) { 315 if (messageDigest != null) { 316 messageDigest.reset(); 317 } 318 needsReset = false; 319 } 320 } 321 322 /** 323 * Returns the message digest value. 324 */ 325 protected byte[] getDigestValue() throws SignatureException { 326 needsReset = false; 327 return messageDigest.digest(); 328 } 329 330 // update the signature with the plaintext data. See JCA doc 331 @Override 332 protected void engineUpdate(byte b) throws SignatureException { 333 messageDigest.update(b); 334 needsReset = true; 335 } 336 337 // update the signature with the plaintext data. See JCA doc 338 @Override 339 protected void engineUpdate(byte[] b, int off, int len) 340 throws SignatureException { 341 messageDigest.update(b, off, len); 342 needsReset = true; 343 } 344 345 // update the signature with the plaintext data. See JCA doc 346 @Override 347 protected void engineUpdate(ByteBuffer byteBuffer) { 348 int len = byteBuffer.remaining(); 349 if (len <= 0) { 350 return; 351 } 352 353 messageDigest.update(byteBuffer); 354 needsReset = true; 355 } 356 357 // sign the data and return the signature. See JCA doc 358 @Override 359 protected byte[] engineSign() throws SignatureException { 360 byte[] s = privateKey.getS().toByteArray(); 361 ECParameterSpec params = privateKey.getParams(); 362 // DER OID 363 byte[] encodedParams = ECUtil.encodeECParameterSpec(null, params); 364 int keySize = params.getCurve().getField().getFieldSize(); 365 366 // seed is twice the key size (in bytes) plus 1 367 byte[] seed = new byte[(((keySize + 7) >> 3) + 1) * 2]; 368 if (random == null) { 369 random = JCAUtil.getSecureRandom(); 370 } 371 random.nextBytes(seed); 372 373 // random bits needed for timing countermeasures 374 int timingArgument = random.nextInt(); 375 // values must be non-zero to enable countermeasures 376 timingArgument |= 1; 377 378 byte[] sig; 379 try { 380 sig = signDigest(getDigestValue(), s, encodedParams, seed, 381 timingArgument); 382 } catch (GeneralSecurityException e) { 383 throw new SignatureException("Could not sign data", e); 384 } 385 386 if (p1363Format) { 387 return sig; 388 } else { 389 return encodeSignature(sig); 390 } 391 } 392 393 // verify the data and return the result. See JCA doc 394 @Override 395 protected boolean engineVerify(byte[] signature) throws SignatureException { 396 397 byte[] w; 398 ECParameterSpec params = publicKey.getParams(); 399 // DER OID 400 byte[] encodedParams = ECUtil.encodeECParameterSpec(null, params); 401 402 if (publicKey instanceof ECPublicKeyImpl) { 403 w = ((ECPublicKeyImpl)publicKey).getEncodedPublicValue(); 404 } else { // instanceof ECPublicKey 405 w = ECUtil.encodePoint(publicKey.getW(), params.getCurve()); 406 } 407 408 byte[] sig; 409 if (p1363Format) { 410 sig = signature; 411 } else { 412 sig = decodeSignature(signature); 413 } 414 415 try { 416 return verifySignedDigest(sig, getDigestValue(), w, encodedParams); 417 } catch (GeneralSecurityException e) { 418 throw new SignatureException("Could not verify signature", e); 419 } 420 } 421 422 // set parameter, not supported. See JCA doc 423 @Override 424 @Deprecated 425 protected void engineSetParameter(String param, Object value) 426 throws InvalidParameterException { 427 throw new UnsupportedOperationException("setParameter() not supported"); 428 } 429 430 @Override 431 protected void engineSetParameter(AlgorithmParameterSpec params) 432 throws InvalidAlgorithmParameterException { 433 if (params != null) { 434 throw new InvalidAlgorithmParameterException("No parameter accepted"); 435 } 436 } 437 438 // get parameter, not supported. See JCA doc 439 @Override 440 @Deprecated 441 protected Object engineGetParameter(String param) 442 throws InvalidParameterException { 443 throw new UnsupportedOperationException("getParameter() not supported"); 444 } 445 446 @Override 447 protected AlgorithmParameters engineGetParameters() { 448 return null; 449 } 450 451 // Convert the concatenation of R and S into their DER encoding 452 private byte[] encodeSignature(byte[] signature) throws SignatureException { 453 454 try { 455 456 int n = signature.length >> 1; 457 byte[] bytes = new byte[n]; 458 System.arraycopy(signature, 0, bytes, 0, n); 459 BigInteger r = new BigInteger(1, bytes); 460 System.arraycopy(signature, n, bytes, 0, n); 461 BigInteger s = new BigInteger(1, bytes); 462 463 DerOutputStream out = new DerOutputStream(signature.length + 10); 464 out.putInteger(r); 465 out.putInteger(s); 466 DerValue result = 467 new DerValue(DerValue.tag_Sequence, out.toByteArray()); 468 469 return result.toByteArray(); 470 471 } catch (Exception e) { 472 throw new SignatureException("Could not encode signature", e); 473 } 474 } 475 476 // Convert the DER encoding of R and S into a concatenation of R and S 477 private byte[] decodeSignature(byte[] sig) throws SignatureException { 478 479 try { 480 // Enforce strict DER checking for signatures 481 DerInputStream in = new DerInputStream(sig, 0, sig.length, false); 482 DerValue[] values = in.getSequence(2); 483 484 // check number of components in the read sequence 485 // and trailing data 486 if ((values.length != 2) || (in.available() != 0)) { 487 throw new IOException("Invalid encoding for signature"); 488 } 489 490 BigInteger r = values[0].getPositiveBigInteger(); 491 BigInteger s = values[1].getPositiveBigInteger(); 492 493 // trim leading zeroes 494 byte[] rBytes = trimZeroes(r.toByteArray()); 495 byte[] sBytes = trimZeroes(s.toByteArray()); 496 int k = Math.max(rBytes.length, sBytes.length); 497 // r and s each occupy half the array 498 byte[] result = new byte[k << 1]; 499 System.arraycopy(rBytes, 0, result, k - rBytes.length, 500 rBytes.length); 501 System.arraycopy(sBytes, 0, result, result.length - sBytes.length, 502 sBytes.length); 503 return result; 504 505 } catch (Exception e) { 506 throw new SignatureException("Invalid encoding for signature", e); 507 } 508 } 509 510 // trim leading (most significant) zeroes from the result 511 private static byte[] trimZeroes(byte[] b) { 512 int i = 0; 513 while ((i < b.length - 1) && (b[i] == 0)) { 514 i++; 515 } 516 if (i == 0) { 517 return b; 518 } 519 byte[] t = new byte[b.length - i]; 520 System.arraycopy(b, i, t, 0, t.length); 521 return t; 522 } 523 524 /** 525 * Signs the digest using the private key. 526 * 527 * @param digest the digest to be signed. 528 * @param s the private key's S value. 529 * @param encodedParams the curve's DER encoded object identifier. 530 * @param seed the random seed. 531 * @param timing When non-zero, the implmentation will use timing 532 * countermeasures to hide secrets from timing channels. The EC 533 * implementation will disable the countermeasures when this value is 534 * zero, because the underlying EC functions are shared by several 535 * crypto operations, some of which do not use the countermeasures. 536 * The high-order 31 bits must be uniformly random. The entropy from 537 * these bits is used by the countermeasures. 538 * 539 * @return byte[] the signature. 540 */ 541 private static native byte[] signDigest(byte[] digest, byte[] s, 542 byte[] encodedParams, byte[] seed, int timing) 543 throws GeneralSecurityException; 544 545 /** 546 * Verifies the signed digest using the public key. 547 * 548 * @param signedDigest the signature to be verified. It is encoded 549 * as a concatenation of the key's R and S values. 550 * @param digest the digest to be used. 551 * @param w the public key's W point (in uncompressed form). 552 * @param encodedParams the curve's DER encoded object identifier. 553 * 554 * @return boolean true if the signature is successfully verified. 555 */ 556 private static native boolean verifySignedDigest(byte[] signature, 557 byte[] digest, byte[] w, byte[] encodedParams) 558 throws GeneralSecurityException; 559 }