1 /*
2  * Copyright (c) 2002, 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 com.sun.crypto.provider;
27 
28 import java.util.Arrays;
29 import java.util.Locale;
30 
31 import java.security.*;
32 import java.security.spec.*;
33 import javax.crypto.*;
34 import javax.crypto.spec.*;
35 import javax.crypto.BadPaddingException;
36 
37 /**
38  * This class represents the symmetric algorithms in its various modes
39  * (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>,
40  * <code>PCBC</code>, <code>CTR</code>, and <code>CTS</code>) and
41  * padding schemes (<code>PKCS5Padding</code>, <code>NoPadding</code>,
42  * <code>ISO10126Padding</code>).
43  *
44  * @author Gigi Ankeny
45  * @author Jan Luehe
46  * @see ElectronicCodeBook
47  * @see CipherFeedback
48  * @see OutputFeedback
49  * @see CipherBlockChaining
50  * @see PCBC
51  * @see CounterMode
52  * @see CipherTextStealing
53  */
54 
55 final class CipherCore {
56 
57     /*
58      * internal buffer
59      */
60     private byte[] buffer = null;
61 
62     /*
63      * block size of cipher in bytes
64      */
65     private int blockSize = 0;
66 
67     /*
68      * unit size (number of input bytes that can be processed at a time)
69      */
70     private int unitBytes = 0;
71 
72     /*
73      * index of the content size left in the buffer
74      */
75     private int buffered = 0;
76 
77     /*
78      * minimum number of bytes in the buffer required for
79      * FeedbackCipher.encryptFinal()/decryptFinal() call.
80      * update() must buffer this many bytes before starting
81      * to encrypt/decrypt data.
82      * currently, only the following cases have non-zero values:
83      * 1) CTS mode - due to its special handling on the last two blocks
84      * (the last one may be incomplete).
85      * 2) GCM mode + decryption - due to its trailing tag bytes
86      */
87     private int minBytes = 0;
88 
89     /*
90      * number of bytes needed to make the total input length a multiple
91      * of the blocksize (this is used in feedback mode, when the number of
92      * input bytes that are processed at a time is different from the block
93      * size)
94      */
95     private int diffBlocksize = 0;
96 
97     /*
98      * padding class
99      */
100     private Padding padding = null;
101 
102     /*
103      * internal cipher engine
104      */
105     private FeedbackCipher cipher = null;
106 
107     /*
108      * the cipher mode
109      */
110     private int cipherMode = ECB_MODE;
111 
112     /*
113      * are we encrypting or decrypting?
114      */
115     private boolean decrypting = false;
116 
117     /*
118      * Block Mode constants
119      */
120     private static final int ECB_MODE = 0;
121     private static final int CBC_MODE = 1;
122     private static final int CFB_MODE = 2;
123     private static final int OFB_MODE = 3;
124     private static final int PCBC_MODE = 4;
125     private static final int CTR_MODE = 5;
126     private static final int CTS_MODE = 6;
127     static final int GCM_MODE = 7;
128 
129     /*
130      * variables used for performing the GCM (key+iv) uniqueness check.
131      * To use GCM mode safely, the cipher object must be re-initialized
132      * with a different combination of key + iv values for each
133      * encryption operation. However, checking all past key + iv values
134      * isn't feasible. Thus, we only do a per-instance check of the
135      * key + iv values used in previous encryption.
136      * For decryption operations, no checking is necessary.
137      * NOTE: this key+iv check have to be done inside CipherCore class
138      * since CipherCore class buffers potential tag bytes in GCM mode
139      * and may not call GaloisCounterMode when there isn't sufficient
140      * input to process.
141      */
142     private boolean requireReinit = false;
143     private byte[] lastEncKey = null;
144     private byte[] lastEncIv = null;
145 
146     /**
147      * Creates an instance of CipherCore with default ECB mode and
148      * PKCS5Padding.
149      */
CipherCore(SymmetricCipher impl, int blkSize)150     CipherCore(SymmetricCipher impl, int blkSize) {
151         blockSize = blkSize;
152         unitBytes = blkSize;
153         diffBlocksize = blkSize;
154 
155         /*
156          * The buffer should be usable for all cipher mode and padding
157          * schemes. Thus, it has to be at least (blockSize+1) for CTS.
158          * In decryption mode, it also hold the possible padding block.
159          */
160         buffer = new byte[blockSize*2];
161 
162         // set mode and padding
163         cipher = new ElectronicCodeBook(impl);
164         padding = new PKCS5Padding(blockSize);
165     }
166 
167     /**
168      * Sets the mode of this cipher.
169      *
170      * @param mode the cipher mode
171      *
172      * @exception NoSuchAlgorithmException if the requested cipher mode does
173      * not exist for this cipher
174      */
setMode(String mode)175     void setMode(String mode) throws NoSuchAlgorithmException {
176         if (mode == null)
177             throw new NoSuchAlgorithmException("null mode");
178 
179         String modeUpperCase = mode.toUpperCase(Locale.ENGLISH);
180 
181         if (modeUpperCase.equals("ECB")) {
182             return;
183         }
184 
185         SymmetricCipher rawImpl = cipher.getEmbeddedCipher();
186         if (modeUpperCase.equals("CBC")) {
187             cipherMode = CBC_MODE;
188             cipher = new CipherBlockChaining(rawImpl);
189         } else if (modeUpperCase.equals("CTS")) {
190             cipherMode = CTS_MODE;
191             cipher = new CipherTextStealing(rawImpl);
192             minBytes = blockSize+1;
193             padding = null;
194         } else if (modeUpperCase.equals("CTR")) {
195             cipherMode = CTR_MODE;
196             cipher = new CounterMode(rawImpl);
197             unitBytes = 1;
198             padding = null;
199         }  else if (modeUpperCase.equals("GCM")) {
200             // can only be used for block ciphers w/ 128-bit block size
201             if (blockSize != 16) {
202                 throw new NoSuchAlgorithmException
203                     ("GCM mode can only be used for AES cipher");
204             }
205             cipherMode = GCM_MODE;
206             cipher = new GaloisCounterMode(rawImpl);
207             padding = null;
208         } else if (modeUpperCase.startsWith("CFB")) {
209             cipherMode = CFB_MODE;
210             unitBytes = getNumOfUnit(mode, "CFB".length(), blockSize);
211             cipher = new CipherFeedback(rawImpl, unitBytes);
212         } else if (modeUpperCase.startsWith("OFB")) {
213             cipherMode = OFB_MODE;
214             unitBytes = getNumOfUnit(mode, "OFB".length(), blockSize);
215             cipher = new OutputFeedback(rawImpl, unitBytes);
216         } else if (modeUpperCase.equals("PCBC")) {
217             cipherMode = PCBC_MODE;
218             cipher = new PCBC(rawImpl);
219         }
220         else {
221             throw new NoSuchAlgorithmException("Cipher mode: " + mode
222                                                + " not found");
223         }
224     }
225 
226     /**
227      * Returns the mode of this cipher.
228      *
229      * @return the parsed cipher mode
230      */
getMode()231     int getMode() {
232         return cipherMode;
233     }
234 
getNumOfUnit(String mode, int offset, int blockSize)235     private static int getNumOfUnit(String mode, int offset, int blockSize)
236         throws NoSuchAlgorithmException {
237         int result = blockSize; // use blockSize as default value
238         if (mode.length() > offset) {
239             int numInt;
240             try {
241                 Integer num = Integer.valueOf(mode.substring(offset));
242                 numInt = num.intValue();
243                 result = numInt >> 3;
244             } catch (NumberFormatException e) {
245                 throw new NoSuchAlgorithmException
246                     ("Algorithm mode: " + mode + " not implemented");
247             }
248             if ((numInt % 8 != 0) || (result > blockSize)) {
249                 throw new NoSuchAlgorithmException
250                     ("Invalid algorithm mode: " + mode);
251             }
252         }
253         return result;
254     }
255 
256     /**
257      * Sets the padding mechanism of this cipher.
258      *
259      * @param paddingScheme the padding mechanism
260      *
261      * @exception NoSuchPaddingException if the requested padding mechanism
262      * does not exist
263      */
setPadding(String paddingScheme)264     void setPadding(String paddingScheme)
265         throws NoSuchPaddingException
266     {
267         if (paddingScheme == null) {
268             throw new NoSuchPaddingException("null padding");
269         }
270         if (paddingScheme.equalsIgnoreCase("NoPadding")) {
271             padding = null;
272         } else if (paddingScheme.equalsIgnoreCase("ISO10126Padding")) {
273             padding = new ISO10126Padding(blockSize);
274         } else if (!paddingScheme.equalsIgnoreCase("PKCS5Padding")) {
275             throw new NoSuchPaddingException("Padding: " + paddingScheme
276                                              + " not implemented");
277         }
278         if ((padding != null) &&
279             ((cipherMode == CTR_MODE) || (cipherMode == CTS_MODE)
280              || (cipherMode == GCM_MODE))) {
281             padding = null;
282             String modeStr = null;
283             switch (cipherMode) {
284             case CTR_MODE:
285                 modeStr = "CTR";
286                 break;
287             case GCM_MODE:
288                 modeStr = "GCM";
289                 break;
290             case CTS_MODE:
291                 modeStr = "CTS";
292                 break;
293             default:
294                 // should never happen
295             }
296             if (modeStr != null) {
297                 throw new NoSuchPaddingException
298                     (modeStr + " mode must be used with NoPadding");
299             }
300         }
301     }
302 
303     /**
304      * Returns the length in bytes that an output buffer would need to be in
305      * order to hold the result of the next <code>update</code> or
306      * <code>doFinal</code> operation, given the input length
307      * <code>inputLen</code> (in bytes).
308      *
309      * <p>This call takes into account any unprocessed (buffered) data from a
310      * previous <code>update</code> call, padding, and AEAD tagging.
311      *
312      * <p>The actual output length of the next <code>update</code> or
313      * <code>doFinal</code> call may be smaller than the length returned by
314      * this method.
315      *
316      * @param inputLen the input length (in bytes)
317      *
318      * @return the required output buffer size (in bytes)
319      */
getOutputSize(int inputLen)320     int getOutputSize(int inputLen) {
321         // estimate based on the maximum
322         return getOutputSizeByOperation(inputLen, true);
323     }
324 
getOutputSizeByOperation(int inputLen, boolean isDoFinal)325     private int getOutputSizeByOperation(int inputLen, boolean isDoFinal) {
326         int totalLen = Math.addExact(buffered, cipher.getBufferedLength());
327         totalLen = Math.addExact(totalLen, inputLen);
328         switch (cipherMode) {
329         case GCM_MODE:
330             if (isDoFinal) {
331                 int tagLen = ((GaloisCounterMode) cipher).getTagLen();
332                 if (!decrypting) {
333                     totalLen = Math.addExact(totalLen, tagLen);
334                 } else {
335                     totalLen -= tagLen;
336                 }
337             }
338             if (totalLen < 0) {
339                 totalLen = 0;
340             }
341             break;
342         default:
343             if (padding != null && !decrypting) {
344                 if (unitBytes != blockSize) {
345                     if (totalLen < diffBlocksize) {
346                         totalLen = diffBlocksize;
347                     } else {
348                         int residue = (totalLen - diffBlocksize) % blockSize;
349                         totalLen = Math.addExact(totalLen, (blockSize - residue));
350                     }
351                 } else {
352                     totalLen = Math.addExact(totalLen, padding.padLength(totalLen));
353                 }
354             }
355             break;
356         }
357         return totalLen;
358     }
359 
360     /**
361      * Returns the initialization vector (IV) in a new buffer.
362      *
363      * <p>This is useful in the case where a random IV has been created
364      * (see <a href = "#init">init</a>),
365      * or in the context of password-based encryption or
366      * decryption, where the IV is derived from a user-provided password.
367      *
368      * @return the initialization vector in a new buffer, or null if the
369      * underlying algorithm does not use an IV, or if the IV has not yet
370      * been set.
371      */
getIV()372     byte[] getIV() {
373         byte[] iv = cipher.getIV();
374         return (iv == null) ? null : iv.clone();
375     }
376 
377     /**
378      * Returns the parameters used with this cipher.
379      *
380      * <p>The returned parameters may be the same that were used to initialize
381      * this cipher, or may contain the default set of parameters or a set of
382      * randomly generated parameters used by the underlying cipher
383      * implementation (provided that the underlying cipher implementation
384      * uses a default set of parameters or creates new parameters if it needs
385      * parameters but was not initialized with any).
386      *
387      * @return the parameters used with this cipher, or null if this cipher
388      * does not use any parameters.
389      */
getParameters(String algName)390     AlgorithmParameters getParameters(String algName) {
391         if (cipherMode == ECB_MODE) {
392             return null;
393         }
394         AlgorithmParameters params = null;
395         AlgorithmParameterSpec spec;
396         byte[] iv = getIV();
397         if (iv == null) {
398             // generate spec using default value
399             if (cipherMode == GCM_MODE) {
400                 iv = new byte[GaloisCounterMode.DEFAULT_IV_LEN];
401             } else {
402                 iv = new byte[blockSize];
403             }
404             SunJCE.getRandom().nextBytes(iv);
405         }
406         if (cipherMode == GCM_MODE) {
407             algName = "GCM";
408             spec = new GCMParameterSpec
409                 (((GaloisCounterMode) cipher).getTagLen()*8, iv);
410         } else {
411            if (algName.equals("RC2")) {
412                RC2Crypt rawImpl = (RC2Crypt) cipher.getEmbeddedCipher();
413                spec = new RC2ParameterSpec
414                    (rawImpl.getEffectiveKeyBits(), iv);
415            } else {
416                spec = new IvParameterSpec(iv);
417            }
418         }
419         try {
420             params = AlgorithmParameters.getInstance(algName,
421                     SunJCE.getInstance());
422             params.init(spec);
423         } catch (NoSuchAlgorithmException nsae) {
424             // should never happen
425             throw new RuntimeException("Cannot find " + algName +
426                 " AlgorithmParameters implementation in SunJCE provider");
427         } catch (InvalidParameterSpecException ipse) {
428             // should never happen
429             throw new RuntimeException(spec.getClass() + " not supported");
430         }
431         return params;
432     }
433 
434     /**
435      * Initializes this cipher with a key and a source of randomness.
436      *
437      * <p>The cipher is initialized for one of the following four operations:
438      * encryption, decryption, key wrapping or key unwrapping, depending on
439      * the value of <code>opmode</code>.
440      *
441      * <p>If this cipher requires an initialization vector (IV), it will get
442      * it from <code>random</code>.
443      * This behaviour should only be used in encryption or key wrapping
444      * mode, however.
445      * When initializing a cipher that requires an IV for decryption or
446      * key unwrapping, the IV
447      * (same IV that was used for encryption or key wrapping) must be provided
448      * explicitly as a
449      * parameter, in order to get the correct result.
450      *
451      * <p>This method also cleans existing buffer and other related state
452      * information.
453      *
454      * @param opmode the operation mode of this cipher (this is one of
455      * the following:
456      * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
457      * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
458      * @param key the secret key
459      * @param random the source of randomness
460      *
461      * @exception InvalidKeyException if the given key is inappropriate for
462      * initializing this cipher
463      */
init(int opmode, Key key, SecureRandom random)464     void init(int opmode, Key key, SecureRandom random)
465             throws InvalidKeyException {
466         try {
467             init(opmode, key, (AlgorithmParameterSpec)null, random);
468         } catch (InvalidAlgorithmParameterException e) {
469             throw new InvalidKeyException(e.getMessage());
470         }
471     }
472 
473     /**
474      * Initializes this cipher with a key, a set of
475      * algorithm parameters, and a source of randomness.
476      *
477      * <p>The cipher is initialized for one of the following four operations:
478      * encryption, decryption, key wrapping or key unwrapping, depending on
479      * the value of <code>opmode</code>.
480      *
481      * <p>If this cipher (including its underlying feedback or padding scheme)
482      * requires any random bytes, it will get them from <code>random</code>.
483      *
484      * @param opmode the operation mode of this cipher (this is one of
485      * the following:
486      * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
487      * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
488      * @param key the encryption key
489      * @param params the algorithm parameters
490      * @param random the source of randomness
491      *
492      * @exception InvalidKeyException if the given key is inappropriate for
493      * initializing this cipher
494      * @exception InvalidAlgorithmParameterException if the given algorithm
495      * parameters are inappropriate for this cipher
496      */
init(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random)497     void init(int opmode, Key key, AlgorithmParameterSpec params,
498             SecureRandom random)
499             throws InvalidKeyException, InvalidAlgorithmParameterException {
500         decrypting = (opmode == Cipher.DECRYPT_MODE)
501                   || (opmode == Cipher.UNWRAP_MODE);
502 
503         byte[] keyBytes = getKeyBytes(key);
504         int tagLen = -1;
505         byte[] ivBytes = null;
506         if (params != null) {
507             if (cipherMode == GCM_MODE) {
508                 if (params instanceof GCMParameterSpec) {
509                     tagLen = ((GCMParameterSpec)params).getTLen();
510                     if (tagLen < 96 || tagLen > 128 || ((tagLen & 0x07) != 0)) {
511                         throw new InvalidAlgorithmParameterException
512                             ("Unsupported TLen value; must be one of " +
513                              "{128, 120, 112, 104, 96}");
514                     }
515                     tagLen = tagLen >> 3;
516                     ivBytes = ((GCMParameterSpec)params).getIV();
517                 } else {
518                     throw new InvalidAlgorithmParameterException
519                         ("Unsupported parameter: " + params);
520                }
521             } else {
522                 if (params instanceof IvParameterSpec) {
523                     ivBytes = ((IvParameterSpec)params).getIV();
524                     if ((ivBytes == null) || (ivBytes.length != blockSize)) {
525                         throw new InvalidAlgorithmParameterException
526                             ("Wrong IV length: must be " + blockSize +
527                              " bytes long");
528                     }
529                 } else if (params instanceof RC2ParameterSpec) {
530                     ivBytes = ((RC2ParameterSpec)params).getIV();
531                     if ((ivBytes != null) && (ivBytes.length != blockSize)) {
532                         throw new InvalidAlgorithmParameterException
533                             ("Wrong IV length: must be " + blockSize +
534                              " bytes long");
535                     }
536                 } else {
537                     throw new InvalidAlgorithmParameterException
538                         ("Unsupported parameter: " + params);
539                 }
540             }
541         }
542         if (cipherMode == ECB_MODE) {
543             if (ivBytes != null) {
544                 throw new InvalidAlgorithmParameterException
545                                                 ("ECB mode cannot use IV");
546             }
547         } else if (ivBytes == null)  {
548             if (decrypting) {
549                 throw new InvalidAlgorithmParameterException("Parameters "
550                                                              + "missing");
551             }
552 
553             if (random == null) {
554                 random = SunJCE.getRandom();
555             }
556             if (cipherMode == GCM_MODE) {
557                 ivBytes = new byte[GaloisCounterMode.DEFAULT_IV_LEN];
558             } else {
559                 ivBytes = new byte[blockSize];
560             }
561             random.nextBytes(ivBytes);
562         }
563 
564         buffered = 0;
565         diffBlocksize = blockSize;
566 
567         String algorithm = key.getAlgorithm();
568 
569         // GCM mode needs additional handling
570         if (cipherMode == GCM_MODE) {
571             if(tagLen == -1) {
572                 tagLen = GaloisCounterMode.DEFAULT_TAG_LEN;
573             }
574             if (decrypting) {
575                 minBytes = tagLen;
576             } else {
577                 // check key+iv for encryption in GCM mode
578                 requireReinit =
579                     Arrays.equals(ivBytes, lastEncIv) &&
580                     MessageDigest.isEqual(keyBytes, lastEncKey);
581                 if (requireReinit) {
582                     throw new InvalidAlgorithmParameterException
583                         ("Cannot reuse iv for GCM encryption");
584                 }
585                 lastEncIv = ivBytes;
586                 lastEncKey = keyBytes;
587             }
588             ((GaloisCounterMode) cipher).init
589                 (decrypting, algorithm, keyBytes, ivBytes, tagLen);
590         } else {
591             cipher.init(decrypting, algorithm, keyBytes, ivBytes);
592         }
593         // skip checking key+iv from now on until after doFinal()
594         requireReinit = false;
595     }
596 
init(int opmode, Key key, AlgorithmParameters params, SecureRandom random)597     void init(int opmode, Key key, AlgorithmParameters params,
598               SecureRandom random)
599         throws InvalidKeyException, InvalidAlgorithmParameterException {
600         AlgorithmParameterSpec spec = null;
601         String paramType = null;
602         if (params != null) {
603             try {
604                 if (cipherMode == GCM_MODE) {
605                     paramType = "GCM";
606                     spec = params.getParameterSpec(GCMParameterSpec.class);
607                 } else {
608                     // NOTE: RC2 parameters are always handled through
609                     // init(..., AlgorithmParameterSpec,...) method, so
610                     // we can assume IvParameterSpec type here.
611                     paramType = "IV";
612                     spec = params.getParameterSpec(IvParameterSpec.class);
613                 }
614             } catch (InvalidParameterSpecException ipse) {
615                 throw new InvalidAlgorithmParameterException
616                     ("Wrong parameter type: " + paramType + " expected");
617             }
618         }
619         init(opmode, key, spec, random);
620     }
621 
622     /**
623      * Return the key bytes of the specified key. Throw an InvalidKeyException
624      * if the key is not usable.
625      */
getKeyBytes(Key key)626     static byte[] getKeyBytes(Key key) throws InvalidKeyException {
627         if (key == null) {
628             throw new InvalidKeyException("No key given");
629         }
630         // note: key.getFormat() may return null
631         if (!"RAW".equalsIgnoreCase(key.getFormat())) {
632             throw new InvalidKeyException("Wrong format: RAW bytes needed");
633         }
634         byte[] keyBytes = key.getEncoded();
635         if (keyBytes == null) {
636             throw new InvalidKeyException("RAW key bytes missing");
637         }
638         return keyBytes;
639     }
640 
641 
642     /**
643      * Continues a multiple-part encryption or decryption operation
644      * (depending on how this cipher was initialized), processing another data
645      * part.
646      *
647      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
648      * buffer, starting at <code>inputOffset</code>, are processed, and the
649      * result is stored in a new buffer.
650      *
651      * @param input the input buffer
652      * @param inputOffset the offset in <code>input</code> where the input
653      * starts
654      * @param inputLen the input length
655      *
656      * @return the new buffer with the result
657      *
658      * @exception IllegalStateException if this cipher is in a wrong state
659      * (e.g., has not been initialized)
660      */
update(byte[] input, int inputOffset, int inputLen)661     byte[] update(byte[] input, int inputOffset, int inputLen) {
662         checkReinit();
663 
664         byte[] output = null;
665         try {
666             output = new byte[getOutputSizeByOperation(inputLen, false)];
667             int len = update(input, inputOffset, inputLen, output,
668                              0);
669             if (len == output.length) {
670                 return output;
671             } else {
672                 byte[] copy = Arrays.copyOf(output, len);
673                 if (decrypting) {
674                     // Zero out internal buffer which is no longer required
675                     Arrays.fill(output, (byte) 0x00);
676                 }
677                 return copy;
678             }
679         } catch (ShortBufferException e) {
680             // should never happen
681             throw new ProviderException("Unexpected exception", e);
682         }
683     }
684 
685     /**
686      * Continues a multiple-part encryption or decryption operation
687      * (depending on how this cipher was initialized), processing another data
688      * part.
689      *
690      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
691      * buffer, starting at <code>inputOffset</code>, are processed, and the
692      * result is stored in the <code>output</code> buffer, starting at
693      * <code>outputOffset</code>.
694      *
695      * @param input the input buffer
696      * @param inputOffset the offset in <code>input</code> where the input
697      * starts
698      * @param inputLen the input length
699      * @param output the buffer for the result
700      * @param outputOffset the offset in <code>output</code> where the result
701      * is stored
702      *
703      * @return the number of bytes stored in <code>output</code>
704      *
705      * @exception ShortBufferException if the given output buffer is too small
706      * to hold the result
707      */
update(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)708     int update(byte[] input, int inputOffset, int inputLen, byte[] output,
709                int outputOffset) throws ShortBufferException {
710         checkReinit();
711 
712         // figure out how much can be sent to crypto function
713         int len = Math.addExact(buffered, inputLen);
714         len -= minBytes;
715         if (padding != null && decrypting) {
716             // do not include the padding bytes when decrypting
717             len -= blockSize;
718         }
719         // do not count the trailing bytes which do not make up a unit
720         len = (len > 0 ? (len - (len % unitBytes)) : 0);
721 
722         // check output buffer capacity
723         if ((output == null) ||
724             ((output.length - outputOffset) < len)) {
725             throw new ShortBufferException("Output buffer must be "
726                                            + "(at least) " + len
727                                            + " bytes long");
728         }
729 
730         int outLen = 0;
731         if (len != 0) { // there is some work to do
732             if ((input == output)
733                  && (outputOffset - inputOffset < inputLen)
734                  && (inputOffset - outputOffset < buffer.length)) {
735                 // copy 'input' out to avoid its content being
736                 // overwritten prematurely.
737                 input = Arrays.copyOfRange(input, inputOffset,
738                     Math.addExact(inputOffset, inputLen));
739                 inputOffset = 0;
740             }
741             if (len <= buffered) {
742                 // all to-be-processed data are from 'buffer'
743                 if (decrypting) {
744                     outLen = cipher.decrypt(buffer, 0, len, output, outputOffset);
745                 } else {
746                     outLen = cipher.encrypt(buffer, 0, len, output, outputOffset);
747                 }
748                 buffered -= len;
749                 if (buffered != 0) {
750                     System.arraycopy(buffer, len, buffer, 0, buffered);
751                 }
752             } else { // len > buffered
753                 int inputConsumed = len - buffered;
754                 int temp;
755                 if (buffered > 0) {
756                     int bufferCapacity = buffer.length - buffered;
757                     if (bufferCapacity != 0) {
758                         temp = Math.min(bufferCapacity, inputConsumed);
759                         if (unitBytes != blockSize) {
760                             temp -= (Math.addExact(buffered, temp) % unitBytes);
761                         }
762                         System.arraycopy(input, inputOffset, buffer, buffered, temp);
763                         inputOffset = Math.addExact(inputOffset, temp);
764                         inputConsumed -= temp;
765                         inputLen -= temp;
766                         buffered = Math.addExact(buffered, temp);
767                     }
768                     // process 'buffer'. When finished we can null out 'buffer'
769                     // Only necessary to null out if buffer holds data for encryption
770                     if (decrypting) {
771                          outLen = cipher.decrypt(buffer, 0, buffered, output, outputOffset);
772                     } else {
773                          outLen = cipher.encrypt(buffer, 0, buffered, output, outputOffset);
774                          //encrypt mode. Zero out internal (input) buffer
775                          Arrays.fill(buffer, (byte) 0x00);
776                     }
777                     outputOffset = Math.addExact(outputOffset, outLen);
778                     buffered = 0;
779                 }
780                 if (inputConsumed > 0) { // still has input to process
781                     if (decrypting) {
782                         outLen += cipher.decrypt(input, inputOffset, inputConsumed,
783                             output, outputOffset);
784                     } else {
785                         outLen += cipher.encrypt(input, inputOffset, inputConsumed,
786                             output, outputOffset);
787                     }
788                     inputOffset += inputConsumed;
789                     inputLen -= inputConsumed;
790                 }
791             }
792             // Let's keep track of how many bytes are needed to make
793             // the total input length a multiple of blocksize when
794             // padding is applied
795             if (unitBytes != blockSize) {
796                 if (len < diffBlocksize) {
797                     diffBlocksize -= len;
798                 } else {
799                     diffBlocksize = blockSize -
800                         ((len - diffBlocksize) % blockSize);
801                 }
802             }
803         }
804         // Store remaining input into 'buffer' again
805         if (inputLen > 0) {
806             System.arraycopy(input, inputOffset, buffer, buffered,
807                              inputLen);
808             buffered = Math.addExact(buffered, inputLen);
809         }
810         return outLen;
811     }
812 
813     /**
814      * Encrypts or decrypts data in a single-part operation,
815      * or finishes a multiple-part operation.
816      * The data is encrypted or decrypted, depending on how this cipher was
817      * initialized.
818      *
819      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
820      * buffer, starting at <code>inputOffset</code>, and any input bytes that
821      * may have been buffered during a previous <code>update</code> operation,
822      * are processed, with padding (if requested) being applied.
823      * The result is stored in a new buffer.
824      *
825      * <p>The cipher is reset to its initial state (uninitialized) after this
826      * call.
827      *
828      * @param input the input buffer
829      * @param inputOffset the offset in <code>input</code> where the input
830      * starts
831      * @param inputLen the input length
832      *
833      * @return the new buffer with the result
834      *
835      * @exception IllegalBlockSizeException if this cipher is a block cipher,
836      * no padding has been requested (only in encryption mode), and the total
837      * input length of the data processed by this cipher is not a multiple of
838      * block size
839      * @exception BadPaddingException if this cipher is in decryption mode,
840      * and (un)padding has been requested, but the decrypted data is not
841      * bounded by the appropriate padding bytes
842      */
doFinal(byte[] input, int inputOffset, int inputLen)843     byte[] doFinal(byte[] input, int inputOffset, int inputLen)
844         throws IllegalBlockSizeException, BadPaddingException {
845         try {
846             checkReinit();
847             byte[] output = new byte[getOutputSizeByOperation(inputLen, true)];
848             byte[] finalBuf = prepareInputBuffer(input, inputOffset,
849                     inputLen, output, 0);
850             int finalOffset = (finalBuf == input) ? inputOffset : 0;
851             int finalBufLen = (finalBuf == input) ? inputLen : finalBuf.length;
852 
853             int outLen = fillOutputBuffer(finalBuf, finalOffset, output, 0,
854                     finalBufLen, input);
855 
856             endDoFinal();
857             if (outLen < output.length) {
858                 byte[] copy = Arrays.copyOf(output, outLen);
859                 if (decrypting) {
860                     // Zero out internal (ouput) array
861                     Arrays.fill(output, (byte) 0x00);
862                 }
863                 return copy;
864             } else {
865                 return output;
866             }
867         } catch (ShortBufferException e) {
868             // never thrown
869             throw new ProviderException("Unexpected exception", e);
870         }
871     }
872 
873     /**
874      * Encrypts or decrypts data in a single-part operation,
875      * or finishes a multiple-part operation.
876      * The data is encrypted or decrypted, depending on how this cipher was
877      * initialized.
878      *
879      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
880      * buffer, starting at <code>inputOffset</code>, and any input bytes that
881      * may have been buffered during a previous <code>update</code> operation,
882      * are processed, with padding (if requested) being applied.
883      * The result is stored in the <code>output</code> buffer, starting at
884      * <code>outputOffset</code>.
885      *
886      * <p>The cipher is reset to its initial state (uninitialized) after this
887      * call.
888      *
889      * @param input the input buffer
890      * @param inputOffset the offset in <code>input</code> where the input
891      * starts
892      * @param inputLen the input length
893      * @param output the buffer for the result
894      * @param outputOffset the offset in <code>output</code> where the result
895      * is stored
896      *
897      * @return the number of bytes stored in <code>output</code>
898      *
899      * @exception IllegalBlockSizeException if this cipher is a block cipher,
900      * no padding has been requested (only in encryption mode), and the total
901      * input length of the data processed by this cipher is not a multiple of
902      * block size
903      * @exception ShortBufferException if the given output buffer is too small
904      * to hold the result
905      * @exception BadPaddingException if this cipher is in decryption mode,
906      * and (un)padding has been requested, but the decrypted data is not
907      * bounded by the appropriate padding bytes
908      */
doFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)909     int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
910                 int outputOffset)
911         throws IllegalBlockSizeException, ShortBufferException,
912                BadPaddingException {
913         checkReinit();
914 
915         int estOutSize = getOutputSizeByOperation(inputLen, true);
916         int outputCapacity = checkOutputCapacity(output, outputOffset,
917                 estOutSize);
918         int offset = decrypting ? 0 : outputOffset; // 0 for decrypting
919         byte[] finalBuf = prepareInputBuffer(input, inputOffset,
920                 inputLen, output, outputOffset);
921         byte[] outWithPadding = null; // for decrypting only
922 
923         int finalOffset = (finalBuf == input) ? inputOffset : 0;
924         int finalBufLen = (finalBuf == input) ? inputLen : finalBuf.length;
925 
926         if (decrypting) {
927             // if the size of specified output buffer is less than
928             // the length of the cipher text, then the current
929             // content of cipher has to be preserved in order for
930             // users to retry the call with a larger buffer in the
931             // case of ShortBufferException.
932             if (outputCapacity < estOutSize) {
933                 cipher.save();
934             }
935             // create temporary output buffer so that only "real"
936             // data bytes are passed to user's output buffer.
937             outWithPadding = new byte[estOutSize];
938         }
939         byte[] outBuffer = decrypting ? outWithPadding : output;
940 
941         int outLen = fillOutputBuffer(finalBuf, finalOffset, outBuffer,
942                 offset, finalBufLen, input);
943 
944         if (decrypting) {
945 
946             if (outputCapacity < outLen) {
947                 // restore so users can retry with a larger buffer
948                 cipher.restore();
949                 throw new ShortBufferException("Output buffer too short: "
950                                                + (outputCapacity)
951                                                + " bytes given, " + outLen
952                                                + " bytes needed");
953             }
954             // copy the result into user-supplied output buffer
955             System.arraycopy(outWithPadding, 0, output, outputOffset, outLen);
956             // decrypt mode. Zero out output data that's not required
957             Arrays.fill(outWithPadding, (byte) 0x00);
958         }
959         endDoFinal();
960         return outLen;
961     }
962 
endDoFinal()963     private void endDoFinal() {
964         buffered = 0;
965         diffBlocksize = blockSize;
966         if (cipherMode != ECB_MODE) {
967             cipher.reset();
968         }
969     }
970 
unpad(int outLen, byte[] outWithPadding)971     private int unpad(int outLen, byte[] outWithPadding)
972             throws BadPaddingException {
973         int padStart = padding.unpad(outWithPadding, 0, outLen);
974         if (padStart < 0) {
975             throw new BadPaddingException("Given final block not " +
976             "properly padded. Such issues can arise if a bad key " +
977             "is used during decryption.");
978         }
979         outLen = padStart;
980         return outLen;
981     }
982 
prepareInputBuffer(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)983     private byte[] prepareInputBuffer(byte[] input, int inputOffset,
984                       int inputLen, byte[] output, int outputOffset)
985                       throws IllegalBlockSizeException, ShortBufferException {
986         // calculate total input length
987         int len = Math.addExact(buffered, inputLen);
988         // calculate padding length
989         int totalLen = Math.addExact(len, cipher.getBufferedLength());
990         int paddingLen = 0;
991         // will the total input length be a multiple of blockSize?
992         if (unitBytes != blockSize) {
993             if (totalLen < diffBlocksize) {
994                 paddingLen = diffBlocksize - totalLen;
995             } else {
996                 paddingLen = blockSize -
997                     ((totalLen - diffBlocksize) % blockSize);
998             }
999         } else if (padding != null) {
1000             paddingLen = padding.padLength(totalLen);
1001         }
1002 
1003         if (decrypting && (padding != null) &&
1004             (paddingLen > 0) && (paddingLen != blockSize)) {
1005             throw new IllegalBlockSizeException
1006                 ("Input length must be multiple of " + blockSize +
1007                  " when decrypting with padded cipher");
1008         }
1009 
1010         /*
1011          * prepare the final input, assemble a new buffer if any
1012          * of the following is true:
1013          *  - 'input' and 'output' are the same buffer
1014          *  - there are internally buffered bytes
1015          *  - doing encryption and padding is needed
1016          */
1017         if ((buffered != 0) || (!decrypting && padding != null) ||
1018             ((input == output)
1019               && (outputOffset - inputOffset < inputLen)
1020               && (inputOffset - outputOffset < buffer.length))) {
1021             byte[] finalBuf;
1022             if (decrypting || padding == null) {
1023                 paddingLen = 0;
1024             }
1025             finalBuf = new byte[Math.addExact(len, paddingLen)];
1026             if (buffered != 0) {
1027                 System.arraycopy(buffer, 0, finalBuf, 0, buffered);
1028                 if (!decrypting) {
1029                     // done with input buffer. We should zero out the
1030                     // data if we're in encrypt mode.
1031                     Arrays.fill(buffer, (byte) 0x00);
1032                 }
1033             }
1034             if (inputLen != 0) {
1035                 System.arraycopy(input, inputOffset, finalBuf,
1036                         buffered, inputLen);
1037             }
1038             if (paddingLen != 0) {
1039                 padding.padWithLen(finalBuf, Math.addExact(buffered, inputLen), paddingLen);
1040             }
1041             return finalBuf;
1042         }
1043         return input;
1044     }
1045 
fillOutputBuffer(byte[] finalBuf, int finalOffset, byte[] output, int outOfs, int finalBufLen, byte[] input)1046     private int fillOutputBuffer(byte[] finalBuf, int finalOffset,
1047                                  byte[] output, int outOfs, int finalBufLen,
1048                                  byte[] input)
1049             throws ShortBufferException, BadPaddingException,
1050             IllegalBlockSizeException {
1051         int len;
1052         try {
1053             len = finalNoPadding(finalBuf, finalOffset, output,
1054                     outOfs, finalBufLen);
1055             if (decrypting && padding != null) {
1056                 len = unpad(len, output);
1057             }
1058             return len;
1059         } finally {
1060             if (!decrypting) {
1061                 // reset after doFinal() for GCM encryption
1062                 requireReinit = (cipherMode == GCM_MODE);
1063                 if (finalBuf != input) {
1064                     // done with internal finalBuf array. Copied to output
1065                     Arrays.fill(finalBuf, (byte) 0x00);
1066                 }
1067             }
1068         }
1069     }
1070 
checkOutputCapacity(byte[] output, int outputOffset, int estOutSize)1071     private int checkOutputCapacity(byte[] output, int outputOffset,
1072                             int estOutSize) throws ShortBufferException {
1073         // check output buffer capacity.
1074         // if we are decrypting with padding applied, we can perform this
1075         // check only after we have determined how many padding bytes there
1076         // are.
1077         int outputCapacity = output.length - outputOffset;
1078         int minOutSize = decrypting ? (estOutSize - blockSize) : estOutSize;
1079         if ((output == null) || (outputCapacity < minOutSize)) {
1080             throw new ShortBufferException("Output buffer must be "
1081                 + "(at least) " + minOutSize + " bytes long");
1082         }
1083         return outputCapacity;
1084     }
1085 
checkReinit()1086     private void checkReinit() {
1087         if (requireReinit) {
1088             throw new IllegalStateException
1089                 ("Must use either different key or iv for GCM encryption");
1090         }
1091     }
1092 
finalNoPadding(byte[] in, int inOfs, byte[] out, int outOfs, int len)1093     private int finalNoPadding(byte[] in, int inOfs, byte[] out, int outOfs,
1094                                int len)
1095         throws IllegalBlockSizeException, AEADBadTagException,
1096         ShortBufferException {
1097 
1098         if ((cipherMode != GCM_MODE) && (in == null || len == 0)) {
1099             return 0;
1100         }
1101         if ((cipherMode != CFB_MODE) && (cipherMode != OFB_MODE) &&
1102             (cipherMode != GCM_MODE) &&
1103             ((len % unitBytes) != 0) && (cipherMode != CTS_MODE)) {
1104                 if (padding != null) {
1105                     throw new IllegalBlockSizeException
1106                         ("Input length (with padding) not multiple of " +
1107                          unitBytes + " bytes");
1108                 } else {
1109                     throw new IllegalBlockSizeException
1110                         ("Input length not multiple of " + unitBytes
1111                          + " bytes");
1112                 }
1113         }
1114         int outLen = 0;
1115         if (decrypting) {
1116             outLen = cipher.decryptFinal(in, inOfs, len, out, outOfs);
1117         } else {
1118             outLen = cipher.encryptFinal(in, inOfs, len, out, outOfs);
1119         }
1120         return outLen;
1121     }
1122 
1123     // Note: Wrap() and Unwrap() are the same in
1124     // each of SunJCE CipherSpi implementation classes.
1125     // They are duplicated due to export control requirements:
1126     // All CipherSpi implementation must be final.
1127     /**
1128      * Wrap a key.
1129      *
1130      * @param key the key to be wrapped.
1131      *
1132      * @return the wrapped key.
1133      *
1134      * @exception IllegalBlockSizeException if this cipher is a block
1135      * cipher, no padding has been requested, and the length of the
1136      * encoding of the key to be wrapped is not a
1137      * multiple of the block size.
1138      *
1139      * @exception InvalidKeyException if it is impossible or unsafe to
1140      * wrap the key with this cipher (e.g., a hardware protected key is
1141      * being passed to a software only cipher).
1142      */
wrap(Key key)1143     byte[] wrap(Key key)
1144         throws IllegalBlockSizeException, InvalidKeyException {
1145         byte[] result = null;
1146 
1147         try {
1148             byte[] encodedKey = key.getEncoded();
1149             if ((encodedKey == null) || (encodedKey.length == 0)) {
1150                 throw new InvalidKeyException("Cannot get an encoding of " +
1151                                               "the key to be wrapped");
1152             }
1153             result = doFinal(encodedKey, 0, encodedKey.length);
1154         } catch (BadPaddingException e) {
1155             // Should never happen
1156         }
1157         return result;
1158     }
1159 
1160     /**
1161      * Unwrap a previously wrapped key.
1162      *
1163      * @param wrappedKey the key to be unwrapped.
1164      *
1165      * @param wrappedKeyAlgorithm the algorithm the wrapped key is for.
1166      *
1167      * @param wrappedKeyType the type of the wrapped key.
1168      * This is one of <code>Cipher.SECRET_KEY</code>,
1169      * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.
1170      *
1171      * @return the unwrapped key.
1172      *
1173      * @exception NoSuchAlgorithmException if no installed providers
1174      * can create keys of type <code>wrappedKeyType</code> for the
1175      * <code>wrappedKeyAlgorithm</code>.
1176      *
1177      * @exception InvalidKeyException if <code>wrappedKey</code> does not
1178      * represent a wrapped key of type <code>wrappedKeyType</code> for
1179      * the <code>wrappedKeyAlgorithm</code>.
1180      */
unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)1181     Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
1182                int wrappedKeyType)
1183         throws InvalidKeyException, NoSuchAlgorithmException {
1184         byte[] encodedKey;
1185         try {
1186             encodedKey = doFinal(wrappedKey, 0, wrappedKey.length);
1187         } catch (BadPaddingException ePadding) {
1188             throw new InvalidKeyException("The wrapped key is not padded " +
1189                                           "correctly");
1190         } catch (IllegalBlockSizeException eBlockSize) {
1191             throw new InvalidKeyException("The wrapped key does not have " +
1192                                           "the correct length");
1193         }
1194         return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
1195                                           wrappedKeyType);
1196     }
1197 
1198     /**
1199      * Continues a multi-part update of the Additional Authentication
1200      * Data (AAD), using a subset of the provided buffer.
1201      * <p>
1202      * Calls to this method provide AAD to the cipher when operating in
1203      * modes such as AEAD (GCM/CCM).  If this cipher is operating in
1204      * either GCM or CCM mode, all AAD must be supplied before beginning
1205      * operations on the ciphertext (via the {@code update} and {@code
1206      * doFinal} methods).
1207      *
1208      * @param src the buffer containing the AAD
1209      * @param offset the offset in {@code src} where the AAD input starts
1210      * @param len the number of AAD bytes
1211      *
1212      * @throws IllegalStateException if this cipher is in a wrong state
1213      * (e.g., has not been initialized), does not accept AAD, or if
1214      * operating in either GCM or CCM mode and one of the {@code update}
1215      * methods has already been called for the active
1216      * encryption/decryption operation
1217      * @throws UnsupportedOperationException if this method
1218      * has not been overridden by an implementation
1219      *
1220      * @since 1.8
1221      */
updateAAD(byte[] src, int offset, int len)1222     void updateAAD(byte[] src, int offset, int len) {
1223         checkReinit();
1224         cipher.updateAAD(src, offset, len);
1225     }
1226 }
1227