1 /* 2 * Copyright (c) 1997, 2012, 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 javax.crypto; 27 28 import java.util.StringTokenizer; 29 import java.util.NoSuchElementException; 30 import java.security.AlgorithmParameters; 31 import java.security.Provider; 32 import java.security.Key; 33 import java.security.SecureRandom; 34 import java.security.NoSuchAlgorithmException; 35 import java.security.NoSuchProviderException; 36 import java.security.InvalidKeyException; 37 import java.security.InvalidAlgorithmParameterException; 38 import java.security.ProviderException; 39 import java.security.spec.AlgorithmParameterSpec; 40 41 import java.nio.ByteBuffer; 42 43 /** 44 * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) 45 * for the <code>Cipher</code> class. 46 * All the abstract methods in this class must be implemented by each 47 * cryptographic service provider who wishes to supply the implementation 48 * of a particular cipher algorithm. 49 * 50 * <p>In order to create an instance of <code>Cipher</code>, which 51 * encapsulates an instance of this <code>CipherSpi</code> class, an 52 * application calls one of the 53 * {@link Cipher#getInstance(java.lang.String) getInstance} 54 * factory methods of the 55 * {@link Cipher Cipher} engine class and specifies the requested 56 * <i>transformation</i>. 57 * Optionally, the application may also specify the name of a provider. 58 * 59 * <p>A <i>transformation</i> is a string that describes the operation (or 60 * set of operations) to be performed on the given input, to produce some 61 * output. A transformation always includes the name of a cryptographic 62 * algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and 63 * padding scheme. 64 * 65 * <p> A transformation is of the form:<p> 66 * 67 * <ul> 68 * <li>"<i>algorithm/mode/padding</i>" or 69 * <p> 70 * <li>"<i>algorithm</i>" 71 * </ul> 72 * 73 * <P> (in the latter case, 74 * provider-specific default values for the mode and padding scheme are used). 75 * For example, the following is a valid transformation:<p> 76 * 77 * <pre> 78 * Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>"); 79 * </pre> 80 * 81 * <p>A provider may supply a separate class for each combination 82 * of <i>algorithm/mode/padding</i>, or may decide to provide more generic 83 * classes representing sub-transformations corresponding to 84 * <i>algorithm</i> or <i>algorithm/mode</i> or <i>algorithm//padding</i> 85 * (note the double slashes), 86 * in which case the requested mode and/or padding are set automatically by 87 * the <code>getInstance</code> methods of <code>Cipher</code>, which invoke 88 * the {@link #engineSetMode(java.lang.String) engineSetMode} and 89 * {@link #engineSetPadding(java.lang.String) engineSetPadding} 90 * methods of the provider's subclass of <code>CipherSpi</code>. 91 * 92 * <p>A <code>Cipher</code> property in a provider master class may have one of 93 * the following formats: 94 * 95 * <ul> 96 * 97 * <li> 98 * <pre> 99 * // provider's subclass of "CipherSpi" implements "algName" with 100 * // pluggable mode and padding 101 * <code>Cipher.</code><i>algName</i> 102 * </pre> 103 * 104 * <li> 105 * <pre> 106 * // provider's subclass of "CipherSpi" implements "algName" in the 107 * // specified "mode", with pluggable padding 108 * <code>Cipher.</code><i>algName/mode</i> 109 * </pre> 110 * 111 * <li> 112 * <pre> 113 * // provider's subclass of "CipherSpi" implements "algName" with the 114 * // specified "padding", with pluggable mode 115 * <code>Cipher.</code><i>algName//padding</i> 116 * </pre> 117 * 118 * <li> 119 * <pre> 120 * // provider's subclass of "CipherSpi" implements "algName" with the 121 * // specified "mode" and "padding" 122 * <code>Cipher.</code><i>algName/mode/padding</i> 123 * </pre> 124 * 125 * </ul> 126 * 127 * <p>For example, a provider may supply a subclass of <code>CipherSpi</code> 128 * that implements <i>DES/ECB/PKCS5Padding</i>, one that implements 129 * <i>DES/CBC/PKCS5Padding</i>, one that implements 130 * <i>DES/CFB/PKCS5Padding</i>, and yet another one that implements 131 * <i>DES/OFB/PKCS5Padding</i>. That provider would have the following 132 * <code>Cipher</code> properties in its master class:<p> 133 * 134 * <ul> 135 * 136 * <li> 137 * <pre> 138 * <code>Cipher.</code><i>DES/ECB/PKCS5Padding</i> 139 * </pre> 140 * 141 * <li> 142 * <pre> 143 * <code>Cipher.</code><i>DES/CBC/PKCS5Padding</i> 144 * </pre> 145 * 146 * <li> 147 * <pre> 148 * <code>Cipher.</code><i>DES/CFB/PKCS5Padding</i> 149 * </pre> 150 * 151 * <li> 152 * <pre> 153 * <code>Cipher.</code><i>DES/OFB/PKCS5Padding</i> 154 * </pre> 155 * 156 * </ul> 157 * 158 * <p>Another provider may implement a class for each of the above modes 159 * (i.e., one class for <i>ECB</i>, one for <i>CBC</i>, one for <i>CFB</i>, 160 * and one for <i>OFB</i>), one class for <i>PKCS5Padding</i>, 161 * and a generic <i>DES</i> class that subclasses from <code>CipherSpi</code>. 162 * That provider would have the following 163 * <code>Cipher</code> properties in its master class:<p> 164 * 165 * <ul> 166 * 167 * <li> 168 * <pre> 169 * <code>Cipher.</code><i>DES</i> 170 * </pre> 171 * 172 * </ul> 173 * 174 * <p>The <code>getInstance</code> factory method of the <code>Cipher</code> 175 * engine class follows these rules in order to instantiate a provider's 176 * implementation of <code>CipherSpi</code> for a 177 * transformation of the form "<i>algorithm</i>": 178 * 179 * <ol> 180 * <li> 181 * Check if the provider has registered a subclass of <code>CipherSpi</code> 182 * for the specified "<i>algorithm</i>". 183 * <p>If the answer is YES, instantiate this 184 * class, for whose mode and padding scheme default values (as supplied by 185 * the provider) are used. 186 * <p>If the answer is NO, throw a <code>NoSuchAlgorithmException</code> 187 * exception. 188 * </ol> 189 * 190 * <p>The <code>getInstance</code> factory method of the <code>Cipher</code> 191 * engine class follows these rules in order to instantiate a provider's 192 * implementation of <code>CipherSpi</code> for a 193 * transformation of the form "<i>algorithm/mode/padding</i>": 194 * 195 * <ol> 196 * <li> 197 * Check if the provider has registered a subclass of <code>CipherSpi</code> 198 * for the specified "<i>algorithm/mode/padding</i>" transformation. 199 * <p>If the answer is YES, instantiate it. 200 * <p>If the answer is NO, go to the next step.<p> 201 * <li> 202 * Check if the provider has registered a subclass of <code>CipherSpi</code> 203 * for the sub-transformation "<i>algorithm/mode</i>". 204 * <p>If the answer is YES, instantiate it, and call 205 * <code>engineSetPadding(<i>padding</i>)</code> on the new instance. 206 * <p>If the answer is NO, go to the next step.<p> 207 * <li> 208 * Check if the provider has registered a subclass of <code>CipherSpi</code> 209 * for the sub-transformation "<i>algorithm//padding</i>" (note the double 210 * slashes). 211 * <p>If the answer is YES, instantiate it, and call 212 * <code>engineSetMode(<i>mode</i>)</code> on the new instance. 213 * <p>If the answer is NO, go to the next step.<p> 214 * <li> 215 * Check if the provider has registered a subclass of <code>CipherSpi</code> 216 * for the sub-transformation "<i>algorithm</i>". 217 * <p>If the answer is YES, instantiate it, and call 218 * <code>engineSetMode(<i>mode</i>)</code> and 219 * <code>engineSetPadding(<i>padding</i>)</code> on the new instance. 220 * <p>If the answer is NO, throw a <code>NoSuchAlgorithmException</code> 221 * exception. 222 * </ol> 223 * 224 * @author Jan Luehe 225 * @see KeyGenerator 226 * @see SecretKey 227 * @since 1.4 228 */ 229 230 public abstract class CipherSpi { 231 232 /** 233 * Sets the mode of this cipher. 234 * 235 * @param mode the cipher mode 236 * 237 * @exception NoSuchAlgorithmException if the requested cipher mode does 238 * not exist 239 */ engineSetMode(String mode)240 protected abstract void engineSetMode(String mode) 241 throws NoSuchAlgorithmException; 242 243 /** 244 * Sets the padding mechanism of this cipher. 245 * 246 * @param padding the padding mechanism 247 * 248 * @exception NoSuchPaddingException if the requested padding mechanism 249 * does not exist 250 */ engineSetPadding(String padding)251 protected abstract void engineSetPadding(String padding) 252 throws NoSuchPaddingException; 253 254 /** 255 * Returns the block size (in bytes). 256 * 257 * @return the block size (in bytes), or 0 if the underlying algorithm is 258 * not a block cipher 259 */ engineGetBlockSize()260 protected abstract int engineGetBlockSize(); 261 262 /** 263 * Returns the length in bytes that an output buffer would 264 * need to be in order to hold the result of the next <code>update</code> 265 * or <code>doFinal</code> operation, given the input length 266 * <code>inputLen</code> (in bytes). 267 * 268 * <p>This call takes into account any unprocessed (buffered) data from a 269 * previous <code>update</code> call, padding, and AEAD tagging. 270 * 271 * <p>The actual output length of the next <code>update</code> or 272 * <code>doFinal</code> call may be smaller than the length returned by 273 * this method. 274 * 275 * @param inputLen the input length (in bytes) 276 * 277 * @return the required output buffer size (in bytes) 278 */ engineGetOutputSize(int inputLen)279 protected abstract int engineGetOutputSize(int inputLen); 280 281 /** 282 * Returns the initialization vector (IV) in a new buffer. 283 * 284 * <p> This is useful in the context of password-based encryption or 285 * decryption, where the IV is derived from a user-provided passphrase. 286 * 287 * @return the initialization vector in a new buffer, or null if the 288 * underlying algorithm does not use an IV, or if the IV has not yet 289 * been set. 290 */ engineGetIV()291 protected abstract byte[] engineGetIV(); 292 293 /** 294 * Returns the parameters used with this cipher. 295 * 296 * <p>The returned parameters may be the same that were used to initialize 297 * this cipher, or may contain a combination of default and random 298 * parameter values used by the underlying cipher implementation if this 299 * cipher requires algorithm parameters but was not initialized with any. 300 * 301 * @return the parameters used with this cipher, or null if this cipher 302 * does not use any parameters. 303 */ engineGetParameters()304 protected abstract AlgorithmParameters engineGetParameters(); 305 306 /** 307 * Initializes this cipher with a key and a source 308 * of randomness. 309 * 310 * <p>The cipher is initialized for one of the following four operations: 311 * encryption, decryption, key wrapping or key unwrapping, depending on 312 * the value of <code>opmode</code>. 313 * 314 * <p>If this cipher requires any algorithm parameters that cannot be 315 * derived from the given <code>key</code>, the underlying cipher 316 * implementation is supposed to generate the required parameters itself 317 * (using provider-specific default or random values) if it is being 318 * initialized for encryption or key wrapping, and raise an 319 * <code>InvalidKeyException</code> if it is being 320 * initialized for decryption or key unwrapping. 321 * The generated parameters can be retrieved using 322 * {@link #engineGetParameters() engineGetParameters} or 323 * {@link #engineGetIV() engineGetIV} (if the parameter is an IV). 324 * 325 * <p>If this cipher requires algorithm parameters that cannot be 326 * derived from the input parameters, and there are no reasonable 327 * provider-specific default values, initialization will 328 * necessarily fail. 329 * 330 * <p>If this cipher (including its underlying feedback or padding scheme) 331 * requires any random bytes (e.g., for parameter generation), it will get 332 * them from <code>random</code>. 333 * 334 * <p>Note that when a Cipher object is initialized, it loses all 335 * previously-acquired state. In other words, initializing a Cipher is 336 * equivalent to creating a new instance of that Cipher and initializing 337 * it. 338 * 339 * @param opmode the operation mode of this cipher (this is one of 340 * the following: 341 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, 342 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) 343 * @param key the encryption key 344 * @param random the source of randomness 345 * 346 * @exception InvalidKeyException if the given key is inappropriate for 347 * initializing this cipher, or requires 348 * algorithm parameters that cannot be 349 * determined from the given key. 350 */ engineInit(int opmode, Key key, SecureRandom random)351 protected abstract void engineInit(int opmode, Key key, 352 SecureRandom random) 353 throws InvalidKeyException; 354 355 /** 356 * Initializes this cipher with a key, a set of 357 * algorithm parameters, and a source of randomness. 358 * 359 * <p>The cipher is initialized for one of the following four operations: 360 * encryption, decryption, key wrapping or key unwrapping, depending on 361 * the value of <code>opmode</code>. 362 * 363 * <p>If this cipher requires any algorithm parameters and 364 * <code>params</code> is null, the underlying cipher implementation is 365 * supposed to generate the required parameters itself (using 366 * provider-specific default or random values) if it is being 367 * initialized for encryption or key wrapping, and raise an 368 * <code>InvalidAlgorithmParameterException</code> if it is being 369 * initialized for decryption or key unwrapping. 370 * The generated parameters can be retrieved using 371 * {@link #engineGetParameters() engineGetParameters} or 372 * {@link #engineGetIV() engineGetIV} (if the parameter is an IV). 373 * 374 * <p>If this cipher requires algorithm parameters that cannot be 375 * derived from the input parameters, and there are no reasonable 376 * provider-specific default values, initialization will 377 * necessarily fail. 378 * 379 * <p>If this cipher (including its underlying feedback or padding scheme) 380 * requires any random bytes (e.g., for parameter generation), it will get 381 * them from <code>random</code>. 382 * 383 * <p>Note that when a Cipher object is initialized, it loses all 384 * previously-acquired state. In other words, initializing a Cipher is 385 * equivalent to creating a new instance of that Cipher and initializing 386 * it. 387 * 388 * @param opmode the operation mode of this cipher (this is one of 389 * the following: 390 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, 391 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) 392 * @param key the encryption key 393 * @param params the algorithm parameters 394 * @param random the source of randomness 395 * 396 * @exception InvalidKeyException if the given key is inappropriate for 397 * initializing this cipher 398 * @exception InvalidAlgorithmParameterException if the given algorithm 399 * parameters are inappropriate for this cipher, 400 * or if this cipher requires 401 * algorithm parameters and <code>params</code> is null. 402 */ engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random)403 protected abstract void engineInit(int opmode, Key key, 404 AlgorithmParameterSpec params, 405 SecureRandom random) 406 throws InvalidKeyException, InvalidAlgorithmParameterException; 407 408 /** 409 * Initializes this cipher with a key, a set of 410 * algorithm parameters, and a source of randomness. 411 * 412 * <p>The cipher is initialized for one of the following four operations: 413 * encryption, decryption, key wrapping or key unwrapping, depending on 414 * the value of <code>opmode</code>. 415 * 416 * <p>If this cipher requires any algorithm parameters and 417 * <code>params</code> is null, the underlying cipher implementation is 418 * supposed to generate the required parameters itself (using 419 * provider-specific default or random values) if it is being 420 * initialized for encryption or key wrapping, and raise an 421 * <code>InvalidAlgorithmParameterException</code> if it is being 422 * initialized for decryption or key unwrapping. 423 * The generated parameters can be retrieved using 424 * {@link #engineGetParameters() engineGetParameters} or 425 * {@link #engineGetIV() engineGetIV} (if the parameter is an IV). 426 * 427 * <p>If this cipher requires algorithm parameters that cannot be 428 * derived from the input parameters, and there are no reasonable 429 * provider-specific default values, initialization will 430 * necessarily fail. 431 * 432 * <p>If this cipher (including its underlying feedback or padding scheme) 433 * requires any random bytes (e.g., for parameter generation), it will get 434 * them from <code>random</code>. 435 * 436 * <p>Note that when a Cipher object is initialized, it loses all 437 * previously-acquired state. In other words, initializing a Cipher is 438 * equivalent to creating a new instance of that Cipher and initializing 439 * it. 440 * 441 * @param opmode the operation mode of this cipher (this is one of 442 * the following: 443 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, 444 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) 445 * @param key the encryption key 446 * @param params the algorithm parameters 447 * @param random the source of randomness 448 * 449 * @exception InvalidKeyException if the given key is inappropriate for 450 * initializing this cipher 451 * @exception InvalidAlgorithmParameterException if the given algorithm 452 * parameters are inappropriate for this cipher, 453 * or if this cipher requires 454 * algorithm parameters and <code>params</code> is null. 455 */ engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)456 protected abstract void engineInit(int opmode, Key key, 457 AlgorithmParameters params, 458 SecureRandom random) 459 throws InvalidKeyException, InvalidAlgorithmParameterException; 460 461 /** 462 * Continues a multiple-part encryption or decryption operation 463 * (depending on how this cipher was initialized), processing another data 464 * part. 465 * 466 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 467 * buffer, starting at <code>inputOffset</code> inclusive, are processed, 468 * and the result is stored in a new buffer. 469 * 470 * @param input the input buffer 471 * @param inputOffset the offset in <code>input</code> where the input 472 * starts 473 * @param inputLen the input length 474 * 475 * @return the new buffer with the result, or null if the underlying 476 * cipher is a block cipher and the input data is too short to result in a 477 * new block. 478 */ engineUpdate(byte[] input, int inputOffset, int inputLen)479 protected abstract byte[] engineUpdate(byte[] input, int inputOffset, 480 int inputLen); 481 482 /** 483 * Continues a multiple-part encryption or decryption operation 484 * (depending on how this cipher was initialized), processing another data 485 * part. 486 * 487 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 488 * buffer, starting at <code>inputOffset</code> inclusive, are processed, 489 * and the result is stored in the <code>output</code> buffer, starting at 490 * <code>outputOffset</code> inclusive. 491 * 492 * <p>If the <code>output</code> buffer is too small to hold the result, 493 * a <code>ShortBufferException</code> is thrown. 494 * 495 * @param input the input buffer 496 * @param inputOffset the offset in <code>input</code> where the input 497 * starts 498 * @param inputLen the input length 499 * @param output the buffer for the result 500 * @param outputOffset the offset in <code>output</code> where the result 501 * is stored 502 * 503 * @return the number of bytes stored in <code>output</code> 504 * 505 * @exception ShortBufferException if the given output buffer is too small 506 * to hold the result 507 */ engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)508 protected abstract int engineUpdate(byte[] input, int inputOffset, 509 int inputLen, byte[] output, 510 int outputOffset) 511 throws ShortBufferException; 512 513 /** 514 * Continues a multiple-part encryption or decryption operation 515 * (depending on how this cipher was initialized), processing another data 516 * part. 517 * 518 * <p>All <code>input.remaining()</code> bytes starting at 519 * <code>input.position()</code> are processed. The result is stored 520 * in the output buffer. 521 * Upon return, the input buffer's position will be equal 522 * to its limit; its limit will not have changed. The output buffer's 523 * position will have advanced by n, where n is the value returned 524 * by this method; the output buffer's limit will not have changed. 525 * 526 * <p>If <code>output.remaining()</code> bytes are insufficient to 527 * hold the result, a <code>ShortBufferException</code> is thrown. 528 * 529 * <p>Subclasses should consider overriding this method if they can 530 * process ByteBuffers more efficiently than byte arrays. 531 * 532 * @param input the input ByteBuffer 533 * @param output the output ByteByffer 534 * 535 * @return the number of bytes stored in <code>output</code> 536 * 537 * @exception ShortBufferException if there is insufficient space in the 538 * output buffer 539 * 540 * @throws NullPointerException if either parameter is <CODE>null</CODE> 541 * @since 1.5 542 */ engineUpdate(ByteBuffer input, ByteBuffer output)543 protected int engineUpdate(ByteBuffer input, ByteBuffer output) 544 throws ShortBufferException { 545 try { 546 return bufferCrypt(input, output, true); 547 } catch (IllegalBlockSizeException e) { 548 // never thrown for engineUpdate() 549 throw new ProviderException("Internal error in update()"); 550 } catch (BadPaddingException e) { 551 // never thrown for engineUpdate() 552 throw new ProviderException("Internal error in update()"); 553 } 554 } 555 556 /** 557 * Encrypts or decrypts data in a single-part operation, 558 * or finishes a multiple-part operation. 559 * The data is encrypted or decrypted, depending on how this cipher was 560 * initialized. 561 * 562 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 563 * buffer, starting at <code>inputOffset</code> inclusive, and any input 564 * bytes that may have been buffered during a previous <code>update</code> 565 * operation, are processed, with padding (if requested) being applied. 566 * If an AEAD mode such as GCM/CCM is being used, the authentication 567 * tag is appended in the case of encryption, or verified in the 568 * case of decryption. 569 * The result is stored in a new buffer. 570 * 571 * <p>Upon finishing, this method resets this cipher object to the state 572 * it was in when previously initialized via a call to 573 * <code>engineInit</code>. 574 * That is, the object is reset and available to encrypt or decrypt 575 * (depending on the operation mode that was specified in the call to 576 * <code>engineInit</code>) more data. 577 * 578 * <p>Note: if any exception is thrown, this cipher object may need to 579 * be reset before it can be used again. 580 * 581 * @param input the input buffer 582 * @param inputOffset the offset in <code>input</code> where the input 583 * starts 584 * @param inputLen the input length 585 * 586 * @return the new buffer with the result 587 * 588 * @exception IllegalBlockSizeException if this cipher is a block cipher, 589 * no padding has been requested (only in encryption mode), and the total 590 * input length of the data processed by this cipher is not a multiple of 591 * block size; or if this encryption algorithm is unable to 592 * process the input data provided. 593 * @exception BadPaddingException if this cipher is in decryption mode, 594 * and (un)padding has been requested, but the decrypted data is not 595 * bounded by the appropriate padding bytes 596 * @exception AEADBadTagException if this cipher is decrypting in an 597 * AEAD mode (such as GCM/CCM), and the received authentication tag 598 * does not match the calculated value 599 */ engineDoFinal(byte[] input, int inputOffset, int inputLen)600 protected abstract byte[] engineDoFinal(byte[] input, int inputOffset, 601 int inputLen) 602 throws IllegalBlockSizeException, BadPaddingException; 603 604 /** 605 * Encrypts or decrypts data in a single-part operation, 606 * or finishes a multiple-part operation. 607 * The data is encrypted or decrypted, depending on how this cipher was 608 * initialized. 609 * 610 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 611 * buffer, starting at <code>inputOffset</code> inclusive, and any input 612 * bytes that may have been buffered during a previous <code>update</code> 613 * operation, are processed, with padding (if requested) being applied. 614 * If an AEAD mode such as GCM/CCM is being used, the authentication 615 * tag is appended in the case of encryption, or verified in the 616 * case of decryption. 617 * The result is stored in the <code>output</code> buffer, starting at 618 * <code>outputOffset</code> inclusive. 619 * 620 * <p>If the <code>output</code> buffer is too small to hold the result, 621 * a <code>ShortBufferException</code> is thrown. 622 * 623 * <p>Upon finishing, this method resets this cipher object to the state 624 * it was in when previously initialized via a call to 625 * <code>engineInit</code>. 626 * That is, the object is reset and available to encrypt or decrypt 627 * (depending on the operation mode that was specified in the call to 628 * <code>engineInit</code>) more data. 629 * 630 * <p>Note: if any exception is thrown, this cipher object may need to 631 * be reset before it can be used again. 632 * 633 * @param input the input buffer 634 * @param inputOffset the offset in <code>input</code> where the input 635 * starts 636 * @param inputLen the input length 637 * @param output the buffer for the result 638 * @param outputOffset the offset in <code>output</code> where the result 639 * is stored 640 * 641 * @return the number of bytes stored in <code>output</code> 642 * 643 * @exception IllegalBlockSizeException if this cipher is a block cipher, 644 * no padding has been requested (only in encryption mode), and the total 645 * input length of the data processed by this cipher is not a multiple of 646 * block size; or if this encryption algorithm is unable to 647 * process the input data provided. 648 * @exception ShortBufferException if the given output buffer is too small 649 * to hold the result 650 * @exception BadPaddingException if this cipher is in decryption mode, 651 * and (un)padding has been requested, but the decrypted data is not 652 * bounded by the appropriate padding bytes 653 * @exception AEADBadTagException if this cipher is decrypting in an 654 * AEAD mode (such as GCM/CCM), and the received authentication tag 655 * does not match the calculated value 656 */ engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)657 protected abstract int engineDoFinal(byte[] input, int inputOffset, 658 int inputLen, byte[] output, 659 int outputOffset) 660 throws ShortBufferException, IllegalBlockSizeException, 661 BadPaddingException; 662 663 /** 664 * Encrypts or decrypts data in a single-part operation, 665 * or finishes a multiple-part operation. 666 * The data is encrypted or decrypted, depending on how this cipher was 667 * initialized. 668 * 669 * <p>All <code>input.remaining()</code> bytes starting at 670 * <code>input.position()</code> are processed. 671 * If an AEAD mode such as GCM/CCM is being used, the authentication 672 * tag is appended in the case of encryption, or verified in the 673 * case of decryption. 674 * The result is stored in the output buffer. 675 * Upon return, the input buffer's position will be equal 676 * to its limit; its limit will not have changed. The output buffer's 677 * position will have advanced by n, where n is the value returned 678 * by this method; the output buffer's limit will not have changed. 679 * 680 * <p>If <code>output.remaining()</code> bytes are insufficient to 681 * hold the result, a <code>ShortBufferException</code> is thrown. 682 * 683 * <p>Upon finishing, this method resets this cipher object to the state 684 * it was in when previously initialized via a call to 685 * <code>engineInit</code>. 686 * That is, the object is reset and available to encrypt or decrypt 687 * (depending on the operation mode that was specified in the call to 688 * <code>engineInit</code>) more data. 689 * 690 * <p>Note: if any exception is thrown, this cipher object may need to 691 * be reset before it can be used again. 692 * 693 * <p>Subclasses should consider overriding this method if they can 694 * process ByteBuffers more efficiently than byte arrays. 695 * 696 * @param input the input ByteBuffer 697 * @param output the output ByteByffer 698 * 699 * @return the number of bytes stored in <code>output</code> 700 * 701 * @exception IllegalBlockSizeException if this cipher is a block cipher, 702 * no padding has been requested (only in encryption mode), and the total 703 * input length of the data processed by this cipher is not a multiple of 704 * block size; or if this encryption algorithm is unable to 705 * process the input data provided. 706 * @exception ShortBufferException if there is insufficient space in the 707 * output buffer 708 * @exception BadPaddingException if this cipher is in decryption mode, 709 * and (un)padding has been requested, but the decrypted data is not 710 * bounded by the appropriate padding bytes 711 * @exception AEADBadTagException if this cipher is decrypting in an 712 * AEAD mode (such as GCM/CCM), and the received authentication tag 713 * does not match the calculated value 714 * 715 * @throws NullPointerException if either parameter is <CODE>null</CODE> 716 * @since 1.5 717 */ engineDoFinal(ByteBuffer input, ByteBuffer output)718 protected int engineDoFinal(ByteBuffer input, ByteBuffer output) 719 throws ShortBufferException, IllegalBlockSizeException, 720 BadPaddingException { 721 return bufferCrypt(input, output, false); 722 } 723 724 // copied from sun.security.jca.JCAUtil 725 // will be changed to reference that method once that code has been 726 // integrated and promoted getTempArraySize(int totalSize)727 static int getTempArraySize(int totalSize) { 728 return Math.min(4096, totalSize); 729 } 730 731 /** 732 * Implementation for encryption using ByteBuffers. Used for both 733 * engineUpdate() and engineDoFinal(). 734 */ bufferCrypt(ByteBuffer input, ByteBuffer output, boolean isUpdate)735 private int bufferCrypt(ByteBuffer input, ByteBuffer output, 736 boolean isUpdate) throws ShortBufferException, 737 IllegalBlockSizeException, BadPaddingException { 738 if ((input == null) || (output == null)) { 739 throw new NullPointerException 740 ("Input and output buffers must not be null"); 741 } 742 int inPos = input.position(); 743 int inLimit = input.limit(); 744 int inLen = inLimit - inPos; 745 if (isUpdate && (inLen == 0)) { 746 return 0; 747 } 748 int outLenNeeded = engineGetOutputSize(inLen); 749 if (output.remaining() < outLenNeeded) { 750 throw new ShortBufferException("Need at least " + outLenNeeded 751 + " bytes of space in output buffer"); 752 } 753 754 boolean a1 = input.hasArray(); 755 boolean a2 = output.hasArray(); 756 757 if (a1 && a2) { 758 byte[] inArray = input.array(); 759 int inOfs = input.arrayOffset() + inPos; 760 byte[] outArray = output.array(); 761 int outPos = output.position(); 762 int outOfs = output.arrayOffset() + outPos; 763 int n; 764 if (isUpdate) { 765 n = engineUpdate(inArray, inOfs, inLen, outArray, outOfs); 766 } else { 767 n = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs); 768 } 769 input.position(inLimit); 770 output.position(outPos + n); 771 return n; 772 } else if (!a1 && a2) { 773 int outPos = output.position(); 774 byte[] outArray = output.array(); 775 int outOfs = output.arrayOffset() + outPos; 776 byte[] inArray = new byte[getTempArraySize(inLen)]; 777 int total = 0; 778 do { 779 int chunk = Math.min(inLen, inArray.length); 780 input.get(inArray, 0, chunk); 781 int n; 782 if (isUpdate || (inLen != chunk)) { 783 n = engineUpdate(inArray, 0, chunk, outArray, outOfs); 784 } else { 785 n = engineDoFinal(inArray, 0, chunk, outArray, outOfs); 786 } 787 total += n; 788 outOfs += n; 789 inLen -= chunk; 790 } while (inLen > 0); 791 output.position(outPos + total); 792 return total; 793 } else { // output is not backed by an accessible byte[] 794 byte[] inArray; 795 int inOfs; 796 if (a1) { 797 inArray = input.array(); 798 inOfs = input.arrayOffset() + inPos; 799 } else { 800 inArray = new byte[getTempArraySize(inLen)]; 801 inOfs = 0; 802 } 803 byte[] outArray = new byte[getTempArraySize(outLenNeeded)]; 804 int outSize = outArray.length; 805 int total = 0; 806 boolean resized = false; 807 do { 808 int chunk = Math.min(inLen, outSize); 809 if ((a1 == false) && (resized == false)) { 810 input.get(inArray, 0, chunk); 811 inOfs = 0; 812 } 813 try { 814 int n; 815 if (isUpdate || (inLen != chunk)) { 816 n = engineUpdate(inArray, inOfs, chunk, outArray, 0); 817 } else { 818 n = engineDoFinal(inArray, inOfs, chunk, outArray, 0); 819 } 820 resized = false; 821 inOfs += chunk; 822 inLen -= chunk; 823 output.put(outArray, 0, n); 824 total += n; 825 } catch (ShortBufferException e) { 826 if (resized) { 827 // we just resized the output buffer, but it still 828 // did not work. Bug in the provider, abort 829 throw (ProviderException)new ProviderException 830 ("Could not determine buffer size").initCause(e); 831 } 832 // output buffer is too small, realloc and try again 833 resized = true; 834 int newOut = engineGetOutputSize(chunk); 835 outArray = new byte[newOut]; 836 } 837 } while (inLen > 0); 838 input.position(inLimit); 839 return total; 840 } 841 } 842 843 /** 844 * Wrap a key. 845 * 846 * <p>This concrete method has been added to this previously-defined 847 * abstract class. (For backwards compatibility, it cannot be abstract.) 848 * It may be overridden by a provider to wrap a key. 849 * Such an override is expected to throw an IllegalBlockSizeException or 850 * InvalidKeyException (under the specified circumstances), 851 * if the given key cannot be wrapped. 852 * If this method is not overridden, it always throws an 853 * UnsupportedOperationException. 854 * 855 * @param key the key to be wrapped. 856 * 857 * @return the wrapped key. 858 * 859 * @exception IllegalBlockSizeException if this cipher is a block cipher, 860 * no padding has been requested, and the length of the encoding of the 861 * key to be wrapped is not a multiple of the block size. 862 * 863 * @exception InvalidKeyException if it is impossible or unsafe to 864 * wrap the key with this cipher (e.g., a hardware protected key is 865 * being passed to a software-only cipher). 866 */ engineWrap(Key key)867 protected byte[] engineWrap(Key key) 868 throws IllegalBlockSizeException, InvalidKeyException 869 { 870 throw new UnsupportedOperationException(); 871 } 872 873 /** 874 * Unwrap a previously wrapped key. 875 * 876 * <p>This concrete method has been added to this previously-defined 877 * abstract class. (For backwards compatibility, it cannot be abstract.) 878 * It may be overridden by a provider to unwrap a previously wrapped key. 879 * Such an override is expected to throw an InvalidKeyException if 880 * the given wrapped key cannot be unwrapped. 881 * If this method is not overridden, it always throws an 882 * UnsupportedOperationException. 883 * 884 * @param wrappedKey the key to be unwrapped. 885 * 886 * @param wrappedKeyAlgorithm the algorithm associated with the wrapped 887 * key. 888 * 889 * @param wrappedKeyType the type of the wrapped key. This is one of 890 * <code>SECRET_KEY</code>, <code>PRIVATE_KEY</code>, or 891 * <code>PUBLIC_KEY</code>. 892 * 893 * @return the unwrapped key. 894 * 895 * @exception NoSuchAlgorithmException if no installed providers 896 * can create keys of type <code>wrappedKeyType</code> for the 897 * <code>wrappedKeyAlgorithm</code>. 898 * 899 * @exception InvalidKeyException if <code>wrappedKey</code> does not 900 * represent a wrapped key of type <code>wrappedKeyType</code> for 901 * the <code>wrappedKeyAlgorithm</code>. 902 */ engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)903 protected Key engineUnwrap(byte[] wrappedKey, 904 String wrappedKeyAlgorithm, 905 int wrappedKeyType) 906 throws InvalidKeyException, NoSuchAlgorithmException 907 { 908 throw new UnsupportedOperationException(); 909 } 910 911 /** 912 * Returns the key size of the given key object in bits. 913 * <p>This concrete method has been added to this previously-defined 914 * abstract class. It throws an <code>UnsupportedOperationException</code> 915 * if it is not overridden by the provider. 916 * 917 * @param key the key object. 918 * 919 * @return the key size of the given key object. 920 * 921 * @exception InvalidKeyException if <code>key</code> is invalid. 922 */ engineGetKeySize(Key key)923 protected int engineGetKeySize(Key key) 924 throws InvalidKeyException 925 { 926 throw new UnsupportedOperationException(); 927 } 928 929 /** 930 * Continues a multi-part update of the Additional Authentication 931 * Data (AAD), using a subset of the provided buffer. 932 * <p> 933 * Calls to this method provide AAD to the cipher when operating in 934 * modes such as AEAD (GCM/CCM). If this cipher is operating in 935 * either GCM or CCM mode, all AAD must be supplied before beginning 936 * operations on the ciphertext (via the {@code update} and {@code 937 * doFinal} methods). 938 * 939 * @param src the buffer containing the AAD 940 * @param offset the offset in {@code src} where the AAD input starts 941 * @param len the number of AAD bytes 942 * 943 * @throws IllegalStateException if this cipher is in a wrong state 944 * (e.g., has not been initialized), does not accept AAD, or if 945 * operating in either GCM or CCM mode and one of the {@code update} 946 * methods has already been called for the active 947 * encryption/decryption operation 948 * @throws UnsupportedOperationException if this method 949 * has not been overridden by an implementation 950 * 951 * @since 1.7 952 */ engineUpdateAAD(byte[] src, int offset, int len)953 protected void engineUpdateAAD(byte[] src, int offset, int len) { 954 throw new UnsupportedOperationException( 955 "The underlying Cipher implementation " 956 + "does not support this method"); 957 } 958 959 /** 960 * Continues a multi-part update of the Additional Authentication 961 * Data (AAD). 962 * <p> 963 * Calls to this method provide AAD to the cipher when operating in 964 * modes such as AEAD (GCM/CCM). If this cipher is operating in 965 * either GCM or CCM mode, all AAD must be supplied before beginning 966 * operations on the ciphertext (via the {@code update} and {@code 967 * doFinal} methods). 968 * <p> 969 * All {@code src.remaining()} bytes starting at 970 * {@code src.position()} are processed. 971 * Upon return, the input buffer's position will be equal 972 * to its limit; its limit will not have changed. 973 * 974 * @param src the buffer containing the AAD 975 * 976 * @throws IllegalStateException if this cipher is in a wrong state 977 * (e.g., has not been initialized), does not accept AAD, or if 978 * operating in either GCM or CCM mode and one of the {@code update} 979 * methods has already been called for the active 980 * encryption/decryption operation 981 * @throws UnsupportedOperationException if this method 982 * has not been overridden by an implementation 983 * 984 * @since 1.7 985 */ engineUpdateAAD(ByteBuffer src)986 protected void engineUpdateAAD(ByteBuffer src) { 987 throw new UnsupportedOperationException( 988 "The underlying Cipher implementation " 989 + "does not support this method"); 990 } 991 } 992