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