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