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 */ 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 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 */ 320 int getOutputSize(int inputLen) { 321 // estimate based on the maximum 322 return getOutputSizeByOperation(inputLen, true); 323 } 324 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 963 private void endDoFinal() { 964 buffered = 0; 965 diffBlocksize = blockSize; 966 if (cipherMode != ECB_MODE) { 967 cipher.reset(); 968 } 969 } 970 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 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 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 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 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 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 */ 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 */ 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 */ 1222 void updateAAD(byte[] src, int offset, int len) { 1223 checkReinit(); 1224 cipher.updateAAD(src, offset, len); 1225 } 1226 }