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