1 /* 2 * Copyright (c) 1996, 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.provider; 27 28 import java.io.*; 29 import java.util.*; 30 import java.math.BigInteger; 31 import java.nio.ByteBuffer; 32 33 import java.security.*; 34 import java.security.SecureRandom; 35 import java.security.interfaces.*; 36 import java.security.spec.*; 37 38 import sun.security.util.Debug; 39 import sun.security.util.DerValue; 40 import sun.security.util.DerInputStream; 41 import sun.security.util.DerOutputStream; 42 import sun.security.jca.JCAUtil; 43 44 /** 45 * The Digital Signature Standard (using the Digital Signature 46 * Algorithm), as described in fips186-3 of the National Instute of 47 * Standards and Technology (NIST), using SHA digest algorithms 48 * from FIPS180-3. 49 * 50 * This file contains both the signature implementation for the 51 * commonly used SHA1withDSA (DSS), SHA224withDSA, SHA256withDSA, 52 * as well as RawDSA, used by TLS among others. RawDSA expects 53 * the 20 byte SHA-1 digest as input via update rather than the 54 * original data like other signature implementations. 55 * 56 * @author Benjamin Renaud 57 * 58 * @since 1.1 59 * 60 * @see DSAPublicKey 61 * @see DSAPrivateKey 62 */ 63 abstract class DSA extends SignatureSpi { 64 65 /* Are we debugging? */ 66 private static final boolean debug = false; 67 68 /* The number of bits used in exponent blinding */ 69 private static final int BLINDING_BITS = 7; 70 71 /* The constant component of the exponent blinding value */ 72 private static final BigInteger BLINDING_CONSTANT = 73 BigInteger.valueOf(1 << BLINDING_BITS); 74 75 /* The parameter object */ 76 private DSAParams params; 77 78 /* algorithm parameters */ 79 private BigInteger presetP, presetQ, presetG; 80 81 /* The public key, if any */ 82 private BigInteger presetY; 83 84 /* The private key, if any */ 85 private BigInteger presetX; 86 87 /* The RNG used to output a seed for generating k */ 88 private SecureRandom signingRandom; 89 90 /* The message digest object used */ 91 private final MessageDigest md; 92 93 /* The format. true for the IEEE P1363 format. false (default) for ASN.1 */ 94 private final boolean p1363Format; 95 96 /** 97 * Construct a blank DSA object. It must be 98 * initialized before being usable for signing or verifying. 99 */ DSA(MessageDigest md)100 DSA(MessageDigest md) { 101 this(md, false); 102 } 103 104 /** 105 * Construct a blank DSA object that will use the specified 106 * signature format. {@code p1363Format} should be {@code true} to 107 * use the IEEE P1363 format. If {@code p1363Format} is {@code false}, 108 * the DER-encoded ASN.1 format will be used. The DSA object must be 109 * initialized before being usable for signing or verifying. 110 */ DSA(MessageDigest md, boolean p1363Format)111 DSA(MessageDigest md, boolean p1363Format) { 112 super(); 113 this.md = md; 114 this.p1363Format = p1363Format; 115 } 116 checkKey(DSAParams params, int digestLen, String mdAlgo)117 private static void checkKey(DSAParams params, int digestLen, String mdAlgo) 118 throws InvalidKeyException { 119 // FIPS186-3 states in sec4.2 that a hash function which provides 120 // a lower security strength than the (L, N) pair ordinarily should 121 // not be used. 122 int valueN = params.getQ().bitLength(); 123 if (valueN > digestLen) { 124 throw new InvalidKeyException("The security strength of " + 125 mdAlgo + " digest algorithm is not sufficient for this key size"); 126 } 127 } 128 129 /** 130 * Initialize the DSA object with a DSA private key. 131 * 132 * @param privateKey the DSA private key 133 * 134 * @exception InvalidKeyException if the key is not a valid DSA private 135 * key. 136 */ engineInitSign(PrivateKey privateKey)137 protected void engineInitSign(PrivateKey privateKey) 138 throws InvalidKeyException { 139 if (!(privateKey instanceof java.security.interfaces.DSAPrivateKey)) { 140 throw new InvalidKeyException("not a DSA private key: " + 141 privateKey); 142 } 143 144 java.security.interfaces.DSAPrivateKey priv = 145 (java.security.interfaces.DSAPrivateKey)privateKey; 146 147 // check for algorithm specific constraints before doing initialization 148 DSAParams params = priv.getParams(); 149 if (params == null) { 150 throw new InvalidKeyException("DSA private key lacks parameters"); 151 } 152 153 // check key size against hash output size for signing 154 // skip this check for verification to minimize impact on existing apps 155 if (md.getAlgorithm() != "NullDigest20") { 156 checkKey(params, md.getDigestLength()*8, md.getAlgorithm()); 157 } 158 159 this.params = params; 160 this.presetX = priv.getX(); 161 this.presetY = null; 162 this.presetP = params.getP(); 163 this.presetQ = params.getQ(); 164 this.presetG = params.getG(); 165 this.md.reset(); 166 } 167 /** 168 * Initialize the DSA object with a DSA public key. 169 * 170 * @param publicKey the DSA public key. 171 * 172 * @exception InvalidKeyException if the key is not a valid DSA public 173 * key. 174 */ engineInitVerify(PublicKey publicKey)175 protected void engineInitVerify(PublicKey publicKey) 176 throws InvalidKeyException { 177 if (!(publicKey instanceof java.security.interfaces.DSAPublicKey)) { 178 throw new InvalidKeyException("not a DSA public key: " + 179 publicKey); 180 } 181 java.security.interfaces.DSAPublicKey pub = 182 (java.security.interfaces.DSAPublicKey)publicKey; 183 184 // check for algorithm specific constraints before doing initialization 185 DSAParams params = pub.getParams(); 186 if (params == null) { 187 throw new InvalidKeyException("DSA public key lacks parameters"); 188 } 189 this.params = params; 190 this.presetY = pub.getY(); 191 this.presetX = null; 192 this.presetP = params.getP(); 193 this.presetQ = params.getQ(); 194 this.presetG = params.getG(); 195 this.md.reset(); 196 } 197 198 /** 199 * Update a byte to be signed or verified. 200 */ engineUpdate(byte b)201 protected void engineUpdate(byte b) { 202 md.update(b); 203 } 204 205 /** 206 * Update an array of bytes to be signed or verified. 207 */ engineUpdate(byte[] data, int off, int len)208 protected void engineUpdate(byte[] data, int off, int len) { 209 md.update(data, off, len); 210 } 211 engineUpdate(ByteBuffer b)212 protected void engineUpdate(ByteBuffer b) { 213 md.update(b); 214 } 215 216 217 /** 218 * Sign all the data thus far updated. The signature format is 219 * determined by {@code p1363Format}. If {@code p1363Format} is 220 * {@code false} (the default), then the signature is formatted 221 * according to the Canonical Encoding Rules, returned as a DER 222 * sequence of Integers, r and s. If {@code p1363Format} is 223 * {@code false}, the signature is returned in the IEEE P1363 224 * format, which is the concatenation or r and s. 225 * 226 * @return a signature block formatted according to the format 227 * indicated by {@code p1363Format} 228 * 229 * @exception SignatureException if the signature object was not 230 * properly initialized, or if another exception occurs. 231 * 232 * @see sun.security.DSA#engineUpdate 233 * @see sun.security.DSA#engineVerify 234 */ engineSign()235 protected byte[] engineSign() throws SignatureException { 236 BigInteger k = generateK(presetQ); 237 BigInteger r = generateR(presetP, presetQ, presetG, k); 238 BigInteger s = generateS(presetX, presetQ, r, k); 239 240 if (p1363Format) { 241 // Return the concatenation of r and s 242 byte[] rBytes = r.toByteArray(); 243 byte[] sBytes = s.toByteArray(); 244 245 int size = presetQ.bitLength() / 8; 246 byte[] outseq = new byte[size * 2]; 247 248 int rLength = rBytes.length; 249 int sLength = sBytes.length; 250 int i; 251 for (i = rLength; i > 0 && rBytes[rLength - i] == 0; i--); 252 253 int j; 254 for (j = sLength; 255 j > 0 && sBytes[sLength - j] == 0; j--); 256 257 System.arraycopy(rBytes, rLength - i, outseq, size - i, i); 258 System.arraycopy(sBytes, sLength - j, outseq, size * 2 - j, j); 259 260 return outseq; 261 } else { 262 // Return the DER-encoded ASN.1 form 263 try { 264 DerOutputStream outseq = new DerOutputStream(100); 265 outseq.putInteger(r); 266 outseq.putInteger(s); 267 DerValue result = new DerValue(DerValue.tag_Sequence, 268 outseq.toByteArray()); 269 270 return result.toByteArray(); 271 272 } catch (IOException e) { 273 throw new SignatureException("error encoding signature"); 274 } 275 } 276 } 277 278 /** 279 * Verify all the data thus far updated. 280 * 281 * @param signature the alleged signature, encoded using the 282 * Canonical Encoding Rules, as a sequence of integers, r and s. 283 * 284 * @exception SignatureException if the signature object was not 285 * properly initialized, or if another exception occurs. 286 * 287 * @see sun.security.DSA#engineUpdate 288 * @see sun.security.DSA#engineSign 289 */ engineVerify(byte[] signature)290 protected boolean engineVerify(byte[] signature) 291 throws SignatureException { 292 return engineVerify(signature, 0, signature.length); 293 } 294 295 /** 296 * Verify all the data thus far updated. 297 * 298 * @param signature the alleged signature, encoded using the 299 * format indicated by {@code p1363Format}. If {@code p1363Format} 300 * is {@code false} (the default), then the signature is formatted 301 * according to the Canonical Encoding Rules, as a DER sequence of 302 * Integers, r and s. If {@code p1363Format} is {@code false}, 303 * the signature is in the IEEE P1363 format, which is the 304 * concatenation or r and s. 305 * 306 * @param offset the offset to start from in the array of bytes. 307 * 308 * @param length the number of bytes to use, starting at offset. 309 * 310 * @exception SignatureException if the signature object was not 311 * properly initialized, or if another exception occurs. 312 * 313 * @see sun.security.DSA#engineUpdate 314 * @see sun.security.DSA#engineSign 315 */ engineVerify(byte[] signature, int offset, int length)316 protected boolean engineVerify(byte[] signature, int offset, int length) 317 throws SignatureException { 318 319 BigInteger r = null; 320 BigInteger s = null; 321 322 if (p1363Format) { 323 if ((length & 1) == 1) { 324 // length of signature byte array should be even 325 throw new SignatureException("invalid signature format"); 326 } 327 int mid = length/2; 328 r = new BigInteger(Arrays.copyOfRange(signature, 0, mid)); 329 s = new BigInteger(Arrays.copyOfRange(signature, mid, length)); 330 } else { 331 // first decode the signature. 332 try { 333 // Enforce strict DER checking for signatures 334 DerInputStream in = 335 new DerInputStream(signature, offset, length, false); 336 DerValue[] values = in.getSequence(2); 337 338 // check number of components in the read sequence 339 // and trailing data 340 if ((values.length != 2) || (in.available() != 0)) { 341 throw new IOException("Invalid encoding for signature"); 342 } 343 r = values[0].getBigInteger(); 344 s = values[1].getBigInteger(); 345 } catch (IOException e) { 346 throw new SignatureException("Invalid encoding for signature", e); 347 } 348 } 349 350 // some implementations do not correctly encode values in the ASN.1 351 // 2's complement format. force r and s to be positive in order to 352 // to validate those signatures 353 if (r.signum() < 0) { 354 r = new BigInteger(1, r.toByteArray()); 355 } 356 if (s.signum() < 0) { 357 s = new BigInteger(1, s.toByteArray()); 358 } 359 360 if ((r.compareTo(presetQ) == -1) && (s.compareTo(presetQ) == -1)) { 361 BigInteger w = generateW(presetP, presetQ, presetG, s); 362 BigInteger v = generateV(presetY, presetP, presetQ, presetG, w, r); 363 return v.equals(r); 364 } else { 365 throw new SignatureException("invalid signature: out of range values"); 366 } 367 } 368 369 @Deprecated engineSetParameter(String key, Object param)370 protected void engineSetParameter(String key, Object param) { 371 throw new InvalidParameterException("No parameter accepted"); 372 } 373 374 @Override engineSetParameter(AlgorithmParameterSpec params)375 protected void engineSetParameter(AlgorithmParameterSpec params) 376 throws InvalidAlgorithmParameterException { 377 if (params != null) { 378 throw new InvalidAlgorithmParameterException("No parameter accepted"); 379 } 380 } 381 382 @Deprecated engineGetParameter(String key)383 protected Object engineGetParameter(String key) { 384 return null; 385 } 386 387 @Override engineGetParameters()388 protected AlgorithmParameters engineGetParameters() { 389 return null; 390 } 391 392 generateR(BigInteger p, BigInteger q, BigInteger g, BigInteger k)393 private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g, 394 BigInteger k) { 395 396 // exponent blinding to hide information from timing channel 397 SecureRandom random = getSigningRandom(); 398 // start with a random blinding component 399 BigInteger blindingValue = new BigInteger(BLINDING_BITS, random); 400 // add the fixed blinding component 401 blindingValue = blindingValue.add(BLINDING_CONSTANT); 402 // replace k with a blinded value that is congruent (mod q) 403 k = k.add(q.multiply(blindingValue)); 404 405 BigInteger temp = g.modPow(k, p); 406 return temp.mod(q); 407 } 408 generateS(BigInteger x, BigInteger q, BigInteger r, BigInteger k)409 private BigInteger generateS(BigInteger x, BigInteger q, 410 BigInteger r, BigInteger k) throws SignatureException { 411 412 byte[] s2; 413 try { 414 s2 = md.digest(); 415 } catch (RuntimeException re) { 416 // Only for RawDSA due to its 20-byte length restriction 417 throw new SignatureException(re.getMessage()); 418 } 419 // get the leftmost min(N, outLen) bits of the digest value 420 int nBytes = q.bitLength()/8; 421 if (nBytes < s2.length) { 422 s2 = Arrays.copyOfRange(s2, 0, nBytes); 423 } 424 BigInteger z = new BigInteger(1, s2); 425 BigInteger k1 = k.modInverse(q); 426 427 return x.multiply(r).add(z).multiply(k1).mod(q); 428 } 429 generateW(BigInteger p, BigInteger q, BigInteger g, BigInteger s)430 private BigInteger generateW(BigInteger p, BigInteger q, 431 BigInteger g, BigInteger s) { 432 return s.modInverse(q); 433 } 434 generateV(BigInteger y, BigInteger p, BigInteger q, BigInteger g, BigInteger w, BigInteger r)435 private BigInteger generateV(BigInteger y, BigInteger p, 436 BigInteger q, BigInteger g, BigInteger w, BigInteger r) 437 throws SignatureException { 438 439 byte[] s2; 440 try { 441 s2 = md.digest(); 442 } catch (RuntimeException re) { 443 // Only for RawDSA due to its 20-byte length restriction 444 throw new SignatureException(re.getMessage()); 445 } 446 // get the leftmost min(N, outLen) bits of the digest value 447 int nBytes = q.bitLength()/8; 448 if (nBytes < s2.length) { 449 s2 = Arrays.copyOfRange(s2, 0, nBytes); 450 } 451 BigInteger z = new BigInteger(1, s2); 452 453 BigInteger u1 = z.multiply(w).mod(q); 454 BigInteger u2 = (r.multiply(w)).mod(q); 455 456 BigInteger t1 = g.modPow(u1,p); 457 BigInteger t2 = y.modPow(u2,p); 458 BigInteger t3 = t1.multiply(t2); 459 BigInteger t5 = t3.mod(p); 460 return t5.mod(q); 461 } 462 generateK(BigInteger q)463 protected BigInteger generateK(BigInteger q) { 464 // Implementation defined in FIPS 186-4 AppendixB.2.1. 465 SecureRandom random = getSigningRandom(); 466 byte[] kValue = new byte[(q.bitLength() + 7)/8 + 8]; 467 468 random.nextBytes(kValue); 469 return new BigInteger(1, kValue).mod( 470 q.subtract(BigInteger.ONE)).add(BigInteger.ONE); 471 } 472 473 // Use the application-specified SecureRandom Object if provided. 474 // Otherwise, use our default SecureRandom Object. getSigningRandom()475 protected SecureRandom getSigningRandom() { 476 if (signingRandom == null) { 477 if (appRandom != null) { 478 signingRandom = appRandom; 479 } else { 480 signingRandom = JCAUtil.getSecureRandom(); 481 } 482 } 483 return signingRandom; 484 } 485 486 /** 487 * Return a human readable rendition of the engine. 488 */ toString()489 public String toString() { 490 String printable = "DSA Signature"; 491 if (presetP != null && presetQ != null && presetG != null) { 492 printable += "\n\tp: " + Debug.toHexString(presetP); 493 printable += "\n\tq: " + Debug.toHexString(presetQ); 494 printable += "\n\tg: " + Debug.toHexString(presetG); 495 } else { 496 printable += "\n\t P, Q or G not initialized."; 497 } 498 if (presetY != null) { 499 printable += "\n\ty: " + Debug.toHexString(presetY); 500 } 501 if (presetY == null && presetX == null) { 502 printable += "\n\tUNINIIALIZED"; 503 } 504 return printable; 505 } 506 507 /** 508 * Standard SHA224withDSA implementation as defined in FIPS186-3. 509 */ 510 public static final class SHA224withDSA extends DSA { SHA224withDSA()511 public SHA224withDSA() throws NoSuchAlgorithmException { 512 super(MessageDigest.getInstance("SHA-224")); 513 } 514 } 515 516 /** 517 * SHA224withDSA implementation that uses the IEEE P1363 format. 518 */ 519 public static final class SHA224withDSAinP1363Format extends DSA { SHA224withDSAinP1363Format()520 public SHA224withDSAinP1363Format() throws NoSuchAlgorithmException { 521 super(MessageDigest.getInstance("SHA-224"), true); 522 } 523 } 524 525 /** 526 * Standard SHA256withDSA implementation as defined in FIPS186-3. 527 */ 528 public static final class SHA256withDSA extends DSA { SHA256withDSA()529 public SHA256withDSA() throws NoSuchAlgorithmException { 530 super(MessageDigest.getInstance("SHA-256")); 531 } 532 } 533 534 /** 535 * SHA256withDSA implementation that uses the IEEE P1363 format. 536 */ 537 public static final class SHA256withDSAinP1363Format extends DSA { SHA256withDSAinP1363Format()538 public SHA256withDSAinP1363Format() throws NoSuchAlgorithmException { 539 super(MessageDigest.getInstance("SHA-256"), true); 540 } 541 } 542 543 /** 544 * Standard SHA1withDSA implementation. 545 */ 546 public static final class SHA1withDSA extends DSA { SHA1withDSA()547 public SHA1withDSA() throws NoSuchAlgorithmException { 548 super(MessageDigest.getInstance("SHA-1")); 549 } 550 } 551 552 /** 553 * SHA1withDSA implementation that uses the IEEE P1363 format. 554 */ 555 public static final class SHA1withDSAinP1363Format extends DSA { SHA1withDSAinP1363Format()556 public SHA1withDSAinP1363Format() throws NoSuchAlgorithmException { 557 super(MessageDigest.getInstance("SHA-1"), true); 558 } 559 } 560 561 /** 562 * Raw DSA. 563 * 564 * Raw DSA requires the data to be exactly 20 bytes long. If it is 565 * not, a SignatureException is thrown when sign()/verify() is called 566 * per JCA spec. 567 */ 568 static class Raw extends DSA { 569 // Internal special-purpose MessageDigest impl for RawDSA 570 // Only override whatever methods used 571 // NOTE: no clone support 572 public static final class NullDigest20 extends MessageDigest { 573 // 20 byte digest buffer 574 private final byte[] digestBuffer = new byte[20]; 575 576 // offset into the buffer; use Integer.MAX_VALUE to indicate 577 // out-of-bound condition 578 private int ofs = 0; 579 NullDigest20()580 protected NullDigest20() { 581 super("NullDigest20"); 582 } engineUpdate(byte input)583 protected void engineUpdate(byte input) { 584 if (ofs == digestBuffer.length) { 585 ofs = Integer.MAX_VALUE; 586 } else { 587 digestBuffer[ofs++] = input; 588 } 589 } engineUpdate(byte[] input, int offset, int len)590 protected void engineUpdate(byte[] input, int offset, int len) { 591 if (len > (digestBuffer.length - ofs)) { 592 ofs = Integer.MAX_VALUE; 593 } else { 594 System.arraycopy(input, offset, digestBuffer, ofs, len); 595 ofs += len; 596 } 597 } engineUpdate(ByteBuffer input)598 protected final void engineUpdate(ByteBuffer input) { 599 int inputLen = input.remaining(); 600 if (inputLen > (digestBuffer.length - ofs)) { 601 ofs = Integer.MAX_VALUE; 602 } else { 603 input.get(digestBuffer, ofs, inputLen); 604 ofs += inputLen; 605 } 606 } engineDigest()607 protected byte[] engineDigest() throws RuntimeException { 608 if (ofs != digestBuffer.length) { 609 throw new RuntimeException 610 ("Data for RawDSA must be exactly 20 bytes long"); 611 } 612 reset(); 613 return digestBuffer; 614 } engineDigest(byte[] buf, int offset, int len)615 protected int engineDigest(byte[] buf, int offset, int len) 616 throws DigestException { 617 if (ofs != digestBuffer.length) { 618 throw new DigestException 619 ("Data for RawDSA must be exactly 20 bytes long"); 620 } 621 if (len < digestBuffer.length) { 622 throw new DigestException 623 ("Output buffer too small; must be at least 20 bytes"); 624 } 625 System.arraycopy(digestBuffer, 0, buf, offset, digestBuffer.length); 626 reset(); 627 return digestBuffer.length; 628 } 629 engineReset()630 protected void engineReset() { 631 ofs = 0; 632 } engineGetDigestLength()633 protected final int engineGetDigestLength() { 634 return digestBuffer.length; 635 } 636 } 637 Raw(boolean p1363Format)638 private Raw(boolean p1363Format) throws NoSuchAlgorithmException { 639 super(new NullDigest20(), p1363Format); 640 } 641 642 } 643 644 /** 645 * Standard Raw DSA implementation. 646 */ 647 public static final class RawDSA extends Raw { RawDSA()648 public RawDSA() throws NoSuchAlgorithmException { 649 super(false); 650 } 651 } 652 653 /** 654 * Raw DSA implementation that uses the IEEE P1363 format. 655 */ 656 public static final class RawDSAinP1363Format extends Raw { RawDSAinP1363Format()657 public RawDSAinP1363Format() throws NoSuchAlgorithmException { 658 super(true); 659 } 660 } 661 } 662