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 (!"NullDigest20".equals(md.getAlgorithm())) {
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