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