1 /*
   2  * Copyright (c) 2002, 2013, 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     private 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      */
 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      */
 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.startsWith("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     private static int getNumOfUnit(String mode, int offset, int blockSize)
 227         throws NoSuchAlgorithmException {
 228         int result = blockSize; // use blockSize as default value
 229         if (mode.length() > offset) {
 230             int numInt;
 231             try {
 232                 Integer num = Integer.valueOf(mode.substring(offset));
 233                 numInt = num.intValue();
 234                 result = numInt >> 3;
 235             } catch (NumberFormatException e) {
 236                 throw new NoSuchAlgorithmException
 237                     ("Algorithm mode: " + mode + " not implemented");
 238             }
 239             if ((numInt % 8 != 0) || (result > blockSize)) {
 240                 throw new NoSuchAlgorithmException
 241                     ("Invalid algorithm mode: " + mode);
 242             }
 243         }
 244         return result;
 245     }
 246 
 247 
 248     /**
 249      * Sets the padding mechanism of this cipher.
 250      *
 251      * @param padding the padding mechanism
 252      *
 253      * @exception NoSuchPaddingException if the requested padding mechanism
 254      * does not exist
 255      */
 256     void setPadding(String paddingScheme)
 257         throws NoSuchPaddingException
 258     {
 259         if (paddingScheme == null) {
 260             throw new NoSuchPaddingException("null padding");
 261         }
 262         if (paddingScheme.equalsIgnoreCase("NoPadding")) {
 263             padding = null;
 264         } else if (paddingScheme.equalsIgnoreCase("ISO10126Padding")) {
 265             padding = new ISO10126Padding(blockSize);
 266         } else if (!paddingScheme.equalsIgnoreCase("PKCS5Padding")) {
 267             throw new NoSuchPaddingException("Padding: " + paddingScheme
 268                                              + " not implemented");
 269         }
 270         if ((padding != null) &&
 271             ((cipherMode == CTR_MODE) || (cipherMode == CTS_MODE)
 272              || (cipherMode == GCM_MODE))) {
 273             padding = null;
 274             String modeStr = null;
 275             switch (cipherMode) {
 276             case CTR_MODE:
 277                 modeStr = "CTR";
 278                 break;
 279             case GCM_MODE:
 280                 modeStr = "GCM";
 281                 break;
 282             case CTS_MODE:
 283                 modeStr = "CTS";
 284                 break;
 285             default:
 286                 // should never happen
 287             }
 288             if (modeStr != null) {
 289                 throw new NoSuchPaddingException
 290                     (modeStr + " mode must be used with NoPadding");
 291             }
 292         }
 293     }
 294 
 295     /**
 296      * Returns the length in bytes that an output buffer would need to be in
 297      * order to hold the result of the next <code>update</code> or
 298      * <code>doFinal</code> operation, given the input length
 299      * <code>inputLen</code> (in bytes).
 300      *
 301      * <p>This call takes into account any unprocessed (buffered) data from a
 302      * previous <code>update</code> call, padding, and AEAD tagging.
 303      *
 304      * <p>The actual output length of the next <code>update</code> or
 305      * <code>doFinal</code> call may be smaller than the length returned by
 306      * this method.
 307      *
 308      * @param inputLen the input length (in bytes)
 309      *
 310      * @return the required output buffer size (in bytes)
 311      */
 312     int getOutputSize(int inputLen) {
 313         // estimate based on the maximum
 314         return getOutputSizeByOperation(inputLen, true);
 315     }
 316 
 317     private int getOutputSizeByOperation(int inputLen, boolean isDoFinal) {
 318         int totalLen = buffered + inputLen + cipher.getBufferedLength();
 319         switch (cipherMode) {
 320         case GCM_MODE:
 321             if (isDoFinal) {
 322                 int tagLen = ((GaloisCounterMode) cipher).getTagLen();
 323                 if (!decrypting) {
 324                     totalLen += tagLen;
 325                 } else {
 326                     totalLen -= tagLen;
 327                 }
 328             }
 329             if (totalLen < 0) {
 330                 totalLen = 0;
 331             }
 332             break;
 333         default:
 334             if (padding != null && !decrypting) {
 335                 if (unitBytes != blockSize) {
 336                     if (totalLen < diffBlocksize) {
 337                         totalLen = diffBlocksize;
 338                     } else {
 339                         int residue = (totalLen - diffBlocksize) % blockSize;
 340                         totalLen += (blockSize - residue);
 341                     }
 342                 } else {
 343                     totalLen += padding.padLength(totalLen);
 344                 }
 345             }
 346             break;
 347         }
 348         return totalLen;
 349     }
 350 
 351     /**
 352      * Returns the initialization vector (IV) in a new buffer.
 353      *
 354      * <p>This is useful in the case where a random IV has been created
 355      * (see <a href = "#init">init</a>),
 356      * or in the context of password-based encryption or
 357      * decryption, where the IV is derived from a user-provided password.
 358      *
 359      * @return the initialization vector in a new buffer, or null if the
 360      * underlying algorithm does not use an IV, or if the IV has not yet
 361      * been set.
 362      */
 363     byte[] getIV() {
 364         byte[] iv = cipher.getIV();
 365         return (iv == null) ? null : iv.clone();
 366     }
 367 
 368     /**
 369      * Returns the parameters used with this cipher.
 370      *
 371      * <p>The returned parameters may be the same that were used to initialize
 372      * this cipher, or may contain the default set of parameters or a set of
 373      * randomly generated parameters used by the underlying cipher
 374      * implementation (provided that the underlying cipher implementation
 375      * uses a default set of parameters or creates new parameters if it needs
 376      * parameters but was not initialized with any).
 377      *
 378      * @return the parameters used with this cipher, or null if this cipher
 379      * does not use any parameters.
 380      */
 381     AlgorithmParameters getParameters(String algName) {
 382         if (cipherMode == ECB_MODE) {
 383             return null;
 384         }
 385         AlgorithmParameters params = null;
 386         AlgorithmParameterSpec spec;
 387         byte[] iv = getIV();
 388         if (iv == null) {
 389             // generate spec using default value
 390             if (cipherMode == GCM_MODE) {
 391                 iv = new byte[GaloisCounterMode.DEFAULT_IV_LEN];
 392             } else {
 393                 iv = new byte[blockSize];
 394             }
 395             SunJCE.getRandom().nextBytes(iv);
 396         }
 397         if (cipherMode == GCM_MODE) {
 398             algName = "GCM";
 399             spec = new GCMParameterSpec
 400                 (((GaloisCounterMode) cipher).getTagLen()*8, iv);
 401         } else {
 402            if (algName.equals("RC2")) {
 403                RC2Crypt rawImpl = (RC2Crypt) cipher.getEmbeddedCipher();
 404                spec = new RC2ParameterSpec
 405                    (rawImpl.getEffectiveKeyBits(), iv);
 406            } else {
 407                spec = new IvParameterSpec(iv);
 408            }
 409         }
 410         try {
 411             params = AlgorithmParameters.getInstance(algName,
 412                     SunJCE.getInstance());
 413             params.init(spec);
 414         } catch (NoSuchAlgorithmException nsae) {
 415             // should never happen
 416             throw new RuntimeException("Cannot find " + algName +
 417                 " AlgorithmParameters implementation in SunJCE provider");
 418         } catch (InvalidParameterSpecException ipse) {
 419             // should never happen
 420             throw new RuntimeException(spec.getClass() + " not supported");
 421         }
 422         return params;
 423     }
 424 
 425     /**
 426      * Initializes this cipher with a key and a source of randomness.
 427      *
 428      * <p>The cipher is initialized for one of the following four operations:
 429      * encryption, decryption, key wrapping or key unwrapping, depending on
 430      * the value of <code>opmode</code>.
 431      *
 432      * <p>If this cipher requires an initialization vector (IV), it will get
 433      * it from <code>random</code>.
 434      * This behaviour should only be used in encryption or key wrapping
 435      * mode, however.
 436      * When initializing a cipher that requires an IV for decryption or
 437      * key unwrapping, the IV
 438      * (same IV that was used for encryption or key wrapping) must be provided
 439      * explicitly as a
 440      * parameter, in order to get the correct result.
 441      *
 442      * <p>This method also cleans existing buffer and other related state
 443      * information.
 444      *
 445      * @param opmode the operation mode of this cipher (this is one of
 446      * the following:
 447      * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
 448      * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
 449      * @param key the secret key
 450      * @param random the source of randomness
 451      *
 452      * @exception InvalidKeyException if the given key is inappropriate for
 453      * initializing this cipher
 454      */
 455     void init(int opmode, Key key, SecureRandom random)
 456             throws InvalidKeyException {
 457         try {
 458             init(opmode, key, (AlgorithmParameterSpec)null, random);
 459         } catch (InvalidAlgorithmParameterException e) {
 460             throw new InvalidKeyException(e.getMessage());
 461         }
 462     }
 463 
 464     /**
 465      * Initializes this cipher with a key, a set of
 466      * algorithm parameters, and a source of randomness.
 467      *
 468      * <p>The cipher is initialized for one of the following four operations:
 469      * encryption, decryption, key wrapping or key unwrapping, depending on
 470      * the value of <code>opmode</code>.
 471      *
 472      * <p>If this cipher (including its underlying feedback or padding scheme)
 473      * requires any random bytes, it will get them from <code>random</code>.
 474      *
 475      * @param opmode the operation mode of this cipher (this is one of
 476      * the following:
 477      * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
 478      * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
 479      * @param key the encryption key
 480      * @param params the algorithm parameters
 481      * @param random the source of randomness
 482      *
 483      * @exception InvalidKeyException if the given key is inappropriate for
 484      * initializing this cipher
 485      * @exception InvalidAlgorithmParameterException if the given algorithm
 486      * parameters are inappropriate for this cipher
 487      */
 488     void init(int opmode, Key key, AlgorithmParameterSpec params,
 489             SecureRandom random)
 490             throws InvalidKeyException, InvalidAlgorithmParameterException {
 491         decrypting = (opmode == Cipher.DECRYPT_MODE)
 492                   || (opmode == Cipher.UNWRAP_MODE);
 493 
 494         byte[] keyBytes = getKeyBytes(key);
 495         int tagLen = -1;
 496         byte[] ivBytes = null;
 497         if (params != null) {
 498             if (cipherMode == GCM_MODE) {
 499                 if (params instanceof GCMParameterSpec) {
 500                     tagLen = ((GCMParameterSpec)params).getTLen();
 501                     if (tagLen < 96 || tagLen > 128 || ((tagLen & 0x07) != 0)) {
 502                         throw new InvalidAlgorithmParameterException
 503                             ("Unsupported TLen value; must be one of " +
 504                              "{128, 120, 112, 104, 96}");
 505                     }
 506                     tagLen = tagLen >> 3;
 507                     ivBytes = ((GCMParameterSpec)params).getIV();
 508                 } else {
 509                     throw new InvalidAlgorithmParameterException
 510                         ("Unsupported parameter: " + params);
 511                }
 512             } else {
 513                 if (params instanceof IvParameterSpec) {
 514                     ivBytes = ((IvParameterSpec)params).getIV();
 515                     if ((ivBytes == null) || (ivBytes.length != blockSize)) {
 516                         throw new InvalidAlgorithmParameterException
 517                             ("Wrong IV length: must be " + blockSize +
 518                              " bytes long");
 519                     }
 520                 } else if (params instanceof RC2ParameterSpec) {
 521                     ivBytes = ((RC2ParameterSpec)params).getIV();
 522                     if ((ivBytes != null) && (ivBytes.length != blockSize)) {
 523                         throw new InvalidAlgorithmParameterException
 524                             ("Wrong IV length: must be " + blockSize +
 525                              " bytes long");
 526                     }
 527                 } else {
 528                     throw new InvalidAlgorithmParameterException
 529                         ("Unsupported parameter: " + params);
 530                 }
 531             }
 532         }
 533         if (cipherMode == ECB_MODE) {
 534             if (ivBytes != null) {
 535                 throw new InvalidAlgorithmParameterException
 536                                                 ("ECB mode cannot use IV");
 537             }
 538         } else if (ivBytes == null)  {
 539             if (decrypting) {
 540                 throw new InvalidAlgorithmParameterException("Parameters "
 541                                                              + "missing");
 542             }
 543 
 544             if (random == null) {
 545                 random = SunJCE.getRandom();
 546             }
 547             if (cipherMode == GCM_MODE) {
 548                 ivBytes = new byte[GaloisCounterMode.DEFAULT_IV_LEN];
 549             } else {
 550                 ivBytes = new byte[blockSize];
 551             }
 552             random.nextBytes(ivBytes);
 553         }
 554 
 555         buffered = 0;
 556         diffBlocksize = blockSize;
 557 
 558         String algorithm = key.getAlgorithm();
 559 
 560         // GCM mode needs additional handling
 561         if (cipherMode == GCM_MODE) {
 562             if(tagLen == -1) {
 563                 tagLen = GaloisCounterMode.DEFAULT_TAG_LEN;
 564             }
 565             if (decrypting) {
 566                 minBytes = tagLen;
 567             } else {
 568                 // check key+iv for encryption in GCM mode
 569                 requireReinit =
 570                     Arrays.equals(ivBytes, lastEncIv) &&
 571                     Arrays.equals(keyBytes, lastEncKey);
 572                 if (requireReinit) {
 573                     throw new InvalidAlgorithmParameterException
 574                         ("Cannot reuse iv for GCM encryption");
 575                 }
 576                 lastEncIv = ivBytes;
 577                 lastEncKey = keyBytes;
 578             }
 579             ((GaloisCounterMode) cipher).init
 580                 (decrypting, algorithm, keyBytes, ivBytes, tagLen);
 581         } else {
 582             cipher.init(decrypting, algorithm, keyBytes, ivBytes);
 583         }
 584         // skip checking key+iv from now on until after doFinal()
 585         requireReinit = false;
 586     }
 587 
 588     void init(int opmode, Key key, AlgorithmParameters params,
 589               SecureRandom random)
 590         throws InvalidKeyException, InvalidAlgorithmParameterException {
 591         AlgorithmParameterSpec spec = null;
 592         String paramType = null;
 593         if (params != null) {
 594             try {
 595                 if (cipherMode == GCM_MODE) {
 596                     paramType = "GCM";
 597                     spec = params.getParameterSpec(GCMParameterSpec.class);
 598                 } else {
 599                     // NOTE: RC2 parameters are always handled through
 600                     // init(..., AlgorithmParameterSpec,...) method, so
 601                     // we can assume IvParameterSpec type here.
 602                     paramType = "IV";
 603                     spec = params.getParameterSpec(IvParameterSpec.class);
 604                 }
 605             } catch (InvalidParameterSpecException ipse) {
 606                 throw new InvalidAlgorithmParameterException
 607                     ("Wrong parameter type: " + paramType + " expected");
 608             }
 609         }
 610         init(opmode, key, spec, random);
 611     }
 612 
 613     /**
 614      * Return the key bytes of the specified key. Throw an InvalidKeyException
 615      * if the key is not usable.
 616      */
 617     static byte[] getKeyBytes(Key key) throws InvalidKeyException {
 618         if (key == null) {
 619             throw new InvalidKeyException("No key given");
 620         }
 621         // note: key.getFormat() may return null
 622         if (!"RAW".equalsIgnoreCase(key.getFormat())) {
 623             throw new InvalidKeyException("Wrong format: RAW bytes needed");
 624         }
 625         byte[] keyBytes = key.getEncoded();
 626         if (keyBytes == null) {
 627             throw new InvalidKeyException("RAW key bytes missing");
 628         }
 629         return keyBytes;
 630     }
 631 
 632 
 633     /**
 634      * Continues a multiple-part encryption or decryption operation
 635      * (depending on how this cipher was initialized), processing another data
 636      * part.
 637      *
 638      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
 639      * buffer, starting at <code>inputOffset</code>, are processed, and the
 640      * result is stored in a new buffer.
 641      *
 642      * @param input the input buffer
 643      * @param inputOffset the offset in <code>input</code> where the input
 644      * starts
 645      * @param inputLen the input length
 646      *
 647      * @return the new buffer with the result
 648      *
 649      * @exception IllegalStateException if this cipher is in a wrong state
 650      * (e.g., has not been initialized)
 651      */
 652     byte[] update(byte[] input, int inputOffset, int inputLen) {
 653         if (requireReinit) {
 654             throw new IllegalStateException
 655                 ("Must use either different key or iv for GCM encryption");
 656         }
 657 
 658         byte[] output = null;
 659         try {
 660             output = new byte[getOutputSizeByOperation(inputLen, false)];
 661             int len = update(input, inputOffset, inputLen, output,
 662                              0);
 663             if (len == output.length) {
 664                 return output;
 665             } else {
 666                 return Arrays.copyOf(output, len);
 667             }
 668         } catch (ShortBufferException e) {
 669             // should never happen
 670             throw new ProviderException("Unexpected exception", e);
 671         }
 672     }
 673 
 674     /**
 675      * Continues a multiple-part encryption or decryption operation
 676      * (depending on how this cipher was initialized), processing another data
 677      * part.
 678      *
 679      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
 680      * buffer, starting at <code>inputOffset</code>, are processed, and the
 681      * result is stored in the <code>output</code> buffer, starting at
 682      * <code>outputOffset</code>.
 683      *
 684      * @param input the input buffer
 685      * @param inputOffset the offset in <code>input</code> where the input
 686      * starts
 687      * @param inputLen the input length
 688      * @param output the buffer for the result
 689      * @param outputOffset the offset in <code>output</code> where the result
 690      * is stored
 691      *
 692      * @return the number of bytes stored in <code>output</code>
 693      *
 694      * @exception ShortBufferException if the given output buffer is too small
 695      * to hold the result
 696      */
 697     int update(byte[] input, int inputOffset, int inputLen, byte[] output,
 698                int outputOffset) throws ShortBufferException {
 699         if (requireReinit) {
 700             throw new IllegalStateException
 701                 ("Must use either different key or iv for GCM encryption");
 702         }
 703 
 704         // figure out how much can be sent to crypto function
 705         int len = buffered + inputLen - minBytes;
 706         if (padding != null && decrypting) {
 707             // do not include the padding bytes when decrypting
 708             len -= blockSize;
 709         }
 710         // do not count the trailing bytes which do not make up a unit
 711         len = (len > 0 ? (len - (len%unitBytes)) : 0);
 712 
 713         // check output buffer capacity
 714         if ((output == null) ||
 715             ((output.length - outputOffset) < len)) {
 716             throw new ShortBufferException("Output buffer must be "
 717                                            + "(at least) " + len
 718                                            + " bytes long");
 719         }
 720 
 721         int outLen = 0;
 722         if (len != 0) { // there is some work to do
 723             if (len <= buffered) {
 724                 // all to-be-processed data are from 'buffer'
 725                 if (decrypting) {
 726                     outLen = cipher.decrypt(buffer, 0, len, output, outputOffset);
 727                 } else {
 728                     outLen = cipher.encrypt(buffer, 0, len, output, outputOffset);
 729                 }
 730                 buffered -= len;
 731                 if (buffered != 0) {
 732                     System.arraycopy(buffer, len, buffer, 0, buffered);
 733                 }
 734             } else { // len > buffered
 735                 if ((input != output) && (buffered == 0)) {
 736                     // all to-be-processed data are from 'input'
 737                     // however, note that if 'input' and 'output' are the same,
 738                     // then they can't be passed directly to the underlying cipher
 739                     // engine operations as data may be overwritten before they
 740                     // are read.
 741                     if (decrypting) {
 742                         outLen = cipher.decrypt(input, inputOffset, len, output, outputOffset);
 743                     } else {
 744                         outLen = cipher.encrypt(input, inputOffset, len, output, outputOffset);
 745                     }
 746                     inputOffset += len;
 747                     inputLen -= len;
 748                 } else {
 749                     // assemble the data using both 'buffer' and 'input'
 750                     byte[] in = new byte[len];
 751                     int inConsumed = len - buffered;
 752                     if (buffered != 0) {
 753                         System.arraycopy(buffer, 0, in, 0, buffered);
 754                         buffered = 0;
 755                     }
 756                     if (inConsumed != 0) {
 757                         System.arraycopy(input, inputOffset, in, len - inConsumed, inConsumed);
 758                         inputOffset += inConsumed;
 759                         inputLen -= inConsumed;
 760                     }
 761                     if (decrypting) {
 762                         outLen = cipher.decrypt(in, 0, len, output, outputOffset);
 763                     } else {
 764                         outLen = cipher.encrypt(in, 0, len, output, outputOffset);
 765                     }
 766                 }
 767             }
 768             // Let's keep track of how many bytes are needed to make
 769             // the total input length a multiple of blocksize when
 770             // padding is applied
 771             if (unitBytes != blockSize) {
 772                 if (len < diffBlocksize) {
 773                     diffBlocksize -= len;
 774                 } else {
 775                     diffBlocksize = blockSize -
 776                         ((len - diffBlocksize) % blockSize);
 777                 }
 778             }
 779         }
 780         // Store remaining input into 'buffer' again
 781         if (inputLen > 0) {
 782             System.arraycopy(input, inputOffset, buffer, buffered,
 783                              inputLen);
 784             buffered += inputLen;
 785         }
 786         return outLen;
 787     }
 788 
 789     /**
 790      * Encrypts or decrypts data in a single-part operation,
 791      * or finishes a multiple-part operation.
 792      * The data is encrypted or decrypted, depending on how this cipher was
 793      * initialized.
 794      *
 795      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
 796      * buffer, starting at <code>inputOffset</code>, and any input bytes that
 797      * may have been buffered during a previous <code>update</code> operation,
 798      * are processed, with padding (if requested) being applied.
 799      * The result is stored in a new buffer.
 800      *
 801      * <p>The cipher is reset to its initial state (uninitialized) after this
 802      * call.
 803      *
 804      * @param input the input buffer
 805      * @param inputOffset the offset in <code>input</code> where the input
 806      * starts
 807      * @param inputLen the input length
 808      *
 809      * @return the new buffer with the result
 810      *
 811      * @exception IllegalBlockSizeException if this cipher is a block cipher,
 812      * no padding has been requested (only in encryption mode), and the total
 813      * input length of the data processed by this cipher is not a multiple of
 814      * block size
 815      * @exception BadPaddingException if this cipher is in decryption mode,
 816      * and (un)padding has been requested, but the decrypted data is not
 817      * bounded by the appropriate padding bytes
 818      */
 819     byte[] doFinal(byte[] input, int inputOffset, int inputLen)
 820         throws IllegalBlockSizeException, BadPaddingException {
 821         byte[] output = null;
 822         try {
 823             output = new byte[getOutputSizeByOperation(inputLen, true)];
 824             int len = doFinal(input, inputOffset, inputLen, output, 0);
 825             if (len < output.length) {
 826                 return Arrays.copyOf(output, len);
 827             } else {
 828                 return output;
 829             }
 830         } catch (ShortBufferException e) {
 831             // never thrown
 832             throw new ProviderException("Unexpected exception", e);
 833         }
 834     }
 835 
 836     /**
 837      * Encrypts or decrypts data in a single-part operation,
 838      * or finishes a multiple-part operation.
 839      * The data is encrypted or decrypted, depending on how this cipher was
 840      * initialized.
 841      *
 842      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
 843      * buffer, starting at <code>inputOffset</code>, and any input bytes that
 844      * may have been buffered during a previous <code>update</code> operation,
 845      * are processed, with padding (if requested) being applied.
 846      * The result is stored in the <code>output</code> buffer, starting at
 847      * <code>outputOffset</code>.
 848      *
 849      * <p>The cipher is reset to its initial state (uninitialized) after this
 850      * call.
 851      *
 852      * @param input the input buffer
 853      * @param inputOffset the offset in <code>input</code> where the input
 854      * starts
 855      * @param inputLen the input length
 856      * @param output the buffer for the result
 857      * @param outputOffset the offset in <code>output</code> where the result
 858      * is stored
 859      *
 860      * @return the number of bytes stored in <code>output</code>
 861      *
 862      * @exception IllegalBlockSizeException if this cipher is a block cipher,
 863      * no padding has been requested (only in encryption mode), and the total
 864      * input length of the data processed by this cipher is not a multiple of
 865      * block size
 866      * @exception ShortBufferException if the given output buffer is too small
 867      * to hold the result
 868      * @exception BadPaddingException if this cipher is in decryption mode,
 869      * and (un)padding has been requested, but the decrypted data is not
 870      * bounded by the appropriate padding bytes
 871      */
 872     int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
 873                 int outputOffset)
 874         throws IllegalBlockSizeException, ShortBufferException,
 875                BadPaddingException {
 876         if (requireReinit) {
 877             throw new IllegalStateException
 878                 ("Must use either different key or iv for GCM encryption");
 879         }
 880 
 881         int estOutSize = getOutputSizeByOperation(inputLen, true);
 882         // check output buffer capacity.
 883         // if we are decrypting with padding applied, we can perform this
 884         // check only after we have determined how many padding bytes there
 885         // are.
 886         int outputCapacity = output.length - outputOffset;
 887         int minOutSize = (decrypting? (estOutSize - blockSize):estOutSize);
 888         if ((output == null) || (outputCapacity < minOutSize)) {
 889             throw new ShortBufferException("Output buffer must be "
 890                 + "(at least) " + minOutSize + " bytes long");
 891         }
 892 
 893         // calculate total input length
 894         int len = buffered + inputLen;
 895 
 896         // calculate padding length
 897         int totalLen = len + cipher.getBufferedLength();
 898         int paddingLen = 0;
 899         // will the total input length be a multiple of blockSize?
 900         if (unitBytes != blockSize) {
 901             if (totalLen < diffBlocksize) {
 902                 paddingLen = diffBlocksize - totalLen;
 903             } else {
 904                 paddingLen = blockSize -
 905                     ((totalLen - diffBlocksize) % blockSize);
 906             }
 907         } else if (padding != null) {
 908             paddingLen = padding.padLength(totalLen);
 909         }
 910 
 911         if (decrypting && (padding != null) &&
 912             (paddingLen > 0) && (paddingLen != blockSize)) {
 913             throw new IllegalBlockSizeException
 914                 ("Input length must be multiple of " + blockSize +
 915                  " when decrypting with padded cipher");
 916         }
 917 
 918         /*
 919          * prepare the final input, assemble a new buffer if any
 920          * of the following is true:
 921          *  - 'input' and 'output' are the same buffer
 922          *  - there are internally buffered bytes
 923          *  - doing encryption and padding is needed
 924          */
 925         byte[] finalBuf = input;
 926         int finalOffset = inputOffset;
 927         int finalBufLen = inputLen;
 928         if ((input == output) || (buffered != 0) ||
 929             (!decrypting && padding != null)) {
 930             if (decrypting || padding == null) {
 931                 paddingLen = 0;
 932             }
 933             finalBuf = new byte[len + paddingLen];
 934             finalOffset = 0;
 935             if (buffered != 0) {
 936                 System.arraycopy(buffer, 0, finalBuf, 0, buffered);
 937             }
 938             if (inputLen != 0) {
 939                 System.arraycopy(input, inputOffset, finalBuf,
 940                                  buffered, inputLen);
 941             }
 942             if (paddingLen != 0) {
 943                 padding.padWithLen(finalBuf, (buffered+inputLen), paddingLen);
 944             }
 945             finalBufLen = finalBuf.length;
 946         }
 947         int outLen = 0;
 948         if (decrypting) {
 949             // if the size of specified output buffer is less than
 950             // the length of the cipher text, then the current
 951             // content of cipher has to be preserved in order for
 952             // users to retry the call with a larger buffer in the
 953             // case of ShortBufferException.
 954             if (outputCapacity < estOutSize) {
 955                 cipher.save();
 956             }
 957             // create temporary output buffer so that only "real"
 958             // data bytes are passed to user's output buffer.
 959             byte[] outWithPadding = new byte[estOutSize];
 960             outLen = finalNoPadding(finalBuf, finalOffset, outWithPadding,
 961                                     0, finalBufLen);
 962 
 963             if (padding != null) {
 964                 int padStart = padding.unpad(outWithPadding, 0, outLen);
 965                 if (padStart < 0) {
 966                     throw new BadPaddingException("Given final block not "
 967                                                   + "properly padded");
 968                 }
 969                 outLen = padStart;
 970             }
 971 
 972             if (outputCapacity < outLen) {
 973                 // restore so users can retry with a larger buffer
 974                 cipher.restore();
 975                 throw new ShortBufferException("Output buffer too short: "
 976                                                + (outputCapacity)
 977                                                + " bytes given, " + outLen
 978                                                + " bytes needed");
 979             }
 980             // copy the result into user-supplied output buffer
 981             System.arraycopy(outWithPadding, 0, output, outputOffset, outLen);
 982         } else { // encrypting
 983             try {
 984                 outLen = finalNoPadding(finalBuf, finalOffset, output,
 985                                         outputOffset, finalBufLen);
 986             } finally {
 987                 // reset after doFinal() for GCM encryption
 988                 requireReinit = (cipherMode == GCM_MODE);
 989             }
 990         }
 991 
 992         buffered = 0;
 993         diffBlocksize = blockSize;
 994         if (cipherMode != ECB_MODE) {
 995             cipher.reset();
 996         }
 997         return outLen;
 998     }
 999 
1000     private int finalNoPadding(byte[] in, int inOfs, byte[] out, int outOfs,
1001                                int len)
1002         throws IllegalBlockSizeException, AEADBadTagException,
1003         ShortBufferException {
1004 
1005         if ((cipherMode != GCM_MODE) && (in == null || len == 0)) {
1006             return 0;
1007         }
1008         if ((cipherMode != CFB_MODE) && (cipherMode != OFB_MODE) &&
1009             (cipherMode != GCM_MODE) &&
1010             ((len % unitBytes) != 0) && (cipherMode != CTS_MODE)) {
1011                 if (padding != null) {
1012                     throw new IllegalBlockSizeException
1013                         ("Input length (with padding) not multiple of " +
1014                          unitBytes + " bytes");
1015                 } else {
1016                     throw new IllegalBlockSizeException
1017                         ("Input length not multiple of " + unitBytes
1018                          + " bytes");
1019                 }
1020         }
1021         int outLen = 0;
1022         if (decrypting) {
1023             outLen = cipher.decryptFinal(in, inOfs, len, out, outOfs);
1024         } else {
1025             outLen = cipher.encryptFinal(in, inOfs, len, out, outOfs);
1026         }
1027         return outLen;
1028     }
1029 
1030     // Note: Wrap() and Unwrap() are the same in
1031     // each of SunJCE CipherSpi implementation classes.
1032     // They are duplicated due to export control requirements:
1033     // All CipherSpi implementation must be final.
1034     /**
1035      * Wrap a key.
1036      *
1037      * @param key the key to be wrapped.
1038      *
1039      * @return the wrapped key.
1040      *
1041      * @exception IllegalBlockSizeException if this cipher is a block
1042      * cipher, no padding has been requested, and the length of the
1043      * encoding of the key to be wrapped is not a
1044      * multiple of the block size.
1045      *
1046      * @exception InvalidKeyException if it is impossible or unsafe to
1047      * wrap the key with this cipher (e.g., a hardware protected key is
1048      * being passed to a software only cipher).
1049      */
1050     byte[] wrap(Key key)
1051         throws IllegalBlockSizeException, InvalidKeyException {
1052         byte[] result = null;
1053 
1054         try {
1055             byte[] encodedKey = key.getEncoded();
1056             if ((encodedKey == null) || (encodedKey.length == 0)) {
1057                 throw new InvalidKeyException("Cannot get an encoding of " +
1058                                               "the key to be wrapped");
1059             }
1060             result = doFinal(encodedKey, 0, encodedKey.length);
1061         } catch (BadPaddingException e) {
1062             // Should never happen
1063         }
1064         return result;
1065     }
1066 
1067     /**
1068      * Unwrap a previously wrapped key.
1069      *
1070      * @param wrappedKey the key to be unwrapped.
1071      *
1072      * @param wrappedKeyAlgorithm the algorithm the wrapped key is for.
1073      *
1074      * @param wrappedKeyType the type of the wrapped key.
1075      * This is one of <code>Cipher.SECRET_KEY</code>,
1076      * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.
1077      *
1078      * @return the unwrapped key.
1079      *
1080      * @exception NoSuchAlgorithmException if no installed providers
1081      * can create keys of type <code>wrappedKeyType</code> for the
1082      * <code>wrappedKeyAlgorithm</code>.
1083      *
1084      * @exception InvalidKeyException if <code>wrappedKey</code> does not
1085      * represent a wrapped key of type <code>wrappedKeyType</code> for
1086      * the <code>wrappedKeyAlgorithm</code>.
1087      */
1088     Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
1089                int wrappedKeyType)
1090         throws InvalidKeyException, NoSuchAlgorithmException {
1091         byte[] encodedKey;
1092         try {
1093             encodedKey = doFinal(wrappedKey, 0, wrappedKey.length);
1094         } catch (BadPaddingException ePadding) {
1095             throw new InvalidKeyException("The wrapped key is not padded " +
1096                                           "correctly");
1097         } catch (IllegalBlockSizeException eBlockSize) {
1098             throw new InvalidKeyException("The wrapped key does not have " +
1099                                           "the correct length");
1100         }
1101         return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
1102                                           wrappedKeyType);
1103     }
1104 
1105     /**
1106      * Continues a multi-part update of the Additional Authentication
1107      * Data (AAD), using a subset of the provided buffer.
1108      * <p>
1109      * Calls to this method provide AAD to the cipher when operating in
1110      * modes such as AEAD (GCM/CCM).  If this cipher is operating in
1111      * either GCM or CCM mode, all AAD must be supplied before beginning
1112      * operations on the ciphertext (via the {@code update} and {@code
1113      * doFinal} methods).
1114      *
1115      * @param src the buffer containing the AAD
1116      * @param offset the offset in {@code src} where the AAD input starts
1117      * @param len the number of AAD bytes
1118      *
1119      * @throws IllegalStateException if this cipher is in a wrong state
1120      * (e.g., has not been initialized), does not accept AAD, or if
1121      * operating in either GCM or CCM mode and one of the {@code update}
1122      * methods has already been called for the active
1123      * encryption/decryption operation
1124      * @throws UnsupportedOperationException if this method
1125      * has not been overridden by an implementation
1126      *
1127      * @since 1.8
1128      */
1129     void updateAAD(byte[] src, int offset, int len) {
1130         if (requireReinit) {
1131             throw new IllegalStateException
1132                 ("Must use either different key or iv for GCM encryption");
1133         }
1134         cipher.updateAAD(src, offset, len);
1135     }
1136 }