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 /** 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: 66 * 67 * <ul> 68 * <li>"<i>algorithm/mode/padding</i>" or 69 * 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: 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: 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: 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. 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. 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. 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 * @throws UnsupportedOperationException if {@code opmode} is 351 * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented 352 * by the cipher. 353 */ engineInit(int opmode, Key key, SecureRandom random)354 protected abstract void engineInit(int opmode, Key key, 355 SecureRandom random) 356 throws InvalidKeyException; 357 358 /** 359 * Initializes this cipher with a key, a set of 360 * algorithm parameters, and a source of randomness. 361 * 362 * <p>The cipher is initialized for one of the following four operations: 363 * encryption, decryption, key wrapping or key unwrapping, depending on 364 * the value of <code>opmode</code>. 365 * 366 * <p>If this cipher requires any algorithm parameters and 367 * <code>params</code> is null, the underlying cipher implementation is 368 * supposed to generate the required parameters itself (using 369 * provider-specific default or random values) if it is being 370 * initialized for encryption or key wrapping, and raise an 371 * <code>InvalidAlgorithmParameterException</code> if it is being 372 * initialized for decryption or key unwrapping. 373 * The generated parameters can be retrieved using 374 * {@link #engineGetParameters() engineGetParameters} or 375 * {@link #engineGetIV() engineGetIV} (if the parameter is an IV). 376 * 377 * <p>If this cipher requires algorithm parameters that cannot be 378 * derived from the input parameters, and there are no reasonable 379 * provider-specific default values, initialization will 380 * necessarily fail. 381 * 382 * <p>If this cipher (including its underlying feedback or padding scheme) 383 * requires any random bytes (e.g., for parameter generation), it will get 384 * them from <code>random</code>. 385 * 386 * <p>Note that when a Cipher object is initialized, it loses all 387 * previously-acquired state. In other words, initializing a Cipher is 388 * equivalent to creating a new instance of that Cipher and initializing 389 * it. 390 * 391 * @param opmode the operation mode of this cipher (this is one of 392 * the following: 393 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, 394 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) 395 * @param key the encryption key 396 * @param params the algorithm parameters 397 * @param random the source of randomness 398 * 399 * @exception InvalidKeyException if the given key is inappropriate for 400 * initializing this cipher 401 * @exception InvalidAlgorithmParameterException if the given algorithm 402 * parameters are inappropriate for this cipher, 403 * or if this cipher requires 404 * algorithm parameters and <code>params</code> is null. 405 * @throws UnsupportedOperationException if {@code opmode} is 406 * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented 407 * by the cipher. 408 */ engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random)409 protected abstract void engineInit(int opmode, Key key, 410 AlgorithmParameterSpec params, 411 SecureRandom random) 412 throws InvalidKeyException, InvalidAlgorithmParameterException; 413 414 /** 415 * Initializes this cipher with a key, a set of 416 * algorithm parameters, and a source of randomness. 417 * 418 * <p>The cipher is initialized for one of the following four operations: 419 * encryption, decryption, key wrapping or key unwrapping, depending on 420 * the value of <code>opmode</code>. 421 * 422 * <p>If this cipher requires any algorithm parameters and 423 * <code>params</code> is null, the underlying cipher implementation is 424 * supposed to generate the required parameters itself (using 425 * provider-specific default or random values) if it is being 426 * initialized for encryption or key wrapping, and raise an 427 * <code>InvalidAlgorithmParameterException</code> if it is being 428 * initialized for decryption or key unwrapping. 429 * The generated parameters can be retrieved using 430 * {@link #engineGetParameters() engineGetParameters} or 431 * {@link #engineGetIV() engineGetIV} (if the parameter is an IV). 432 * 433 * <p>If this cipher requires algorithm parameters that cannot be 434 * derived from the input parameters, and there are no reasonable 435 * provider-specific default values, initialization will 436 * necessarily fail. 437 * 438 * <p>If this cipher (including its underlying feedback or padding scheme) 439 * requires any random bytes (e.g., for parameter generation), it will get 440 * them from <code>random</code>. 441 * 442 * <p>Note that when a Cipher object is initialized, it loses all 443 * previously-acquired state. In other words, initializing a Cipher is 444 * equivalent to creating a new instance of that Cipher and initializing 445 * it. 446 * 447 * @param opmode the operation mode of this cipher (this is one of 448 * the following: 449 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, 450 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) 451 * @param key the encryption key 452 * @param params the algorithm parameters 453 * @param random the source of randomness 454 * 455 * @exception InvalidKeyException if the given key is inappropriate for 456 * initializing this cipher 457 * @exception InvalidAlgorithmParameterException if the given algorithm 458 * parameters are inappropriate for this cipher, 459 * or if this cipher requires 460 * algorithm parameters and <code>params</code> is null. 461 * @throws UnsupportedOperationException if {@code opmode} is 462 * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented 463 * by the cipher. 464 */ engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)465 protected abstract void engineInit(int opmode, Key key, 466 AlgorithmParameters params, 467 SecureRandom random) 468 throws InvalidKeyException, InvalidAlgorithmParameterException; 469 470 /** 471 * Continues a multiple-part encryption or decryption operation 472 * (depending on how this cipher was initialized), processing another data 473 * part. 474 * 475 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 476 * buffer, starting at <code>inputOffset</code> inclusive, are processed, 477 * and the result is stored in a new buffer. 478 * 479 * @param input the input buffer 480 * @param inputOffset the offset in <code>input</code> where the input 481 * starts 482 * @param inputLen the input length 483 * 484 * @return the new buffer with the result, or null if the underlying 485 * cipher is a block cipher and the input data is too short to result in a 486 * new block. 487 */ engineUpdate(byte[] input, int inputOffset, int inputLen)488 protected abstract byte[] engineUpdate(byte[] input, int inputOffset, 489 int inputLen); 490 491 /** 492 * Continues a multiple-part encryption or decryption operation 493 * (depending on how this cipher was initialized), processing another data 494 * part. 495 * 496 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 497 * buffer, starting at <code>inputOffset</code> inclusive, are processed, 498 * and the result is stored in the <code>output</code> buffer, starting at 499 * <code>outputOffset</code> inclusive. 500 * 501 * <p>If the <code>output</code> buffer is too small to hold the result, 502 * a <code>ShortBufferException</code> is thrown. 503 * 504 * @param input the input buffer 505 * @param inputOffset the offset in <code>input</code> where the input 506 * starts 507 * @param inputLen the input length 508 * @param output the buffer for the result 509 * @param outputOffset the offset in <code>output</code> where the result 510 * is stored 511 * 512 * @return the number of bytes stored in <code>output</code> 513 * 514 * @exception ShortBufferException if the given output buffer is too small 515 * to hold the result 516 */ engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)517 protected abstract int engineUpdate(byte[] input, int inputOffset, 518 int inputLen, byte[] output, 519 int outputOffset) 520 throws ShortBufferException; 521 522 /** 523 * Continues a multiple-part encryption or decryption operation 524 * (depending on how this cipher was initialized), processing another data 525 * part. 526 * 527 * <p>All <code>input.remaining()</code> bytes starting at 528 * <code>input.position()</code> are processed. The result is stored 529 * in the output buffer. 530 * Upon return, the input buffer's position will be equal 531 * to its limit; its limit will not have changed. The output buffer's 532 * position will have advanced by n, where n is the value returned 533 * by this method; the output buffer's limit will not have changed. 534 * 535 * <p>If <code>output.remaining()</code> bytes are insufficient to 536 * hold the result, a <code>ShortBufferException</code> is thrown. 537 * 538 * <p>Subclasses should consider overriding this method if they can 539 * process ByteBuffers more efficiently than byte arrays. 540 * 541 * @param input the input ByteBuffer 542 * @param output the output ByteByffer 543 * 544 * @return the number of bytes stored in <code>output</code> 545 * 546 * @exception ShortBufferException if there is insufficient space in the 547 * output buffer 548 * 549 * @throws NullPointerException if either parameter is <CODE>null</CODE> 550 * @since 1.5 551 */ engineUpdate(ByteBuffer input, ByteBuffer output)552 protected int engineUpdate(ByteBuffer input, ByteBuffer output) 553 throws ShortBufferException { 554 try { 555 return bufferCrypt(input, output, true); 556 } catch (IllegalBlockSizeException e) { 557 // never thrown for engineUpdate() 558 throw new ProviderException("Internal error in update()"); 559 } catch (BadPaddingException e) { 560 // never thrown for engineUpdate() 561 throw new ProviderException("Internal error in update()"); 562 } 563 } 564 565 /** 566 * Encrypts or decrypts data in a single-part operation, 567 * or finishes a multiple-part operation. 568 * The data is encrypted or decrypted, depending on how this cipher was 569 * initialized. 570 * 571 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 572 * buffer, starting at <code>inputOffset</code> inclusive, and any input 573 * bytes that may have been buffered during a previous <code>update</code> 574 * operation, are processed, with padding (if requested) being applied. 575 * If an AEAD mode such as GCM/CCM is being used, the authentication 576 * tag is appended in the case of encryption, or verified in the 577 * case of decryption. 578 * The result is stored in a new buffer. 579 * 580 * <p>Upon finishing, this method resets this cipher object to the state 581 * it was in when previously initialized via a call to 582 * <code>engineInit</code>. 583 * That is, the object is reset and available to encrypt or decrypt 584 * (depending on the operation mode that was specified in the call to 585 * <code>engineInit</code>) more data. 586 * 587 * <p>Note: if any exception is thrown, this cipher object may need to 588 * be reset before it can be used again. 589 * 590 * @param input the input buffer 591 * @param inputOffset the offset in <code>input</code> where the input 592 * starts 593 * @param inputLen the input length 594 * 595 * @return the new buffer with the result 596 * 597 * @exception IllegalBlockSizeException if this cipher is a block cipher, 598 * no padding has been requested (only in encryption mode), and the total 599 * input length of the data processed by this cipher is not a multiple of 600 * block size; or if this encryption algorithm is unable to 601 * process the input data provided. 602 * @exception BadPaddingException if this cipher is in decryption mode, 603 * and (un)padding has been requested, but the decrypted data is not 604 * bounded by the appropriate padding bytes 605 * @exception AEADBadTagException if this cipher is decrypting in an 606 * AEAD mode (such as GCM/CCM), and the received authentication tag 607 * does not match the calculated value 608 */ engineDoFinal(byte[] input, int inputOffset, int inputLen)609 protected abstract byte[] engineDoFinal(byte[] input, int inputOffset, 610 int inputLen) 611 throws IllegalBlockSizeException, BadPaddingException; 612 613 /** 614 * Encrypts or decrypts data in a single-part operation, 615 * or finishes a multiple-part operation. 616 * The data is encrypted or decrypted, depending on how this cipher was 617 * initialized. 618 * 619 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 620 * buffer, starting at <code>inputOffset</code> inclusive, and any input 621 * bytes that may have been buffered during a previous <code>update</code> 622 * operation, are processed, with padding (if requested) being applied. 623 * If an AEAD mode such as GCM/CCM is being used, the authentication 624 * tag is appended in the case of encryption, or verified in the 625 * case of decryption. 626 * The result is stored in the <code>output</code> buffer, starting at 627 * <code>outputOffset</code> inclusive. 628 * 629 * <p>If the <code>output</code> buffer is too small to hold the result, 630 * a <code>ShortBufferException</code> is thrown. 631 * 632 * <p>Upon finishing, this method resets this cipher object to the state 633 * it was in when previously initialized via a call to 634 * <code>engineInit</code>. 635 * That is, the object is reset and available to encrypt or decrypt 636 * (depending on the operation mode that was specified in the call to 637 * <code>engineInit</code>) more data. 638 * 639 * <p>Note: if any exception is thrown, this cipher object may need to 640 * be reset before it can be used again. 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 * @param output the buffer for the result 647 * @param outputOffset the offset in <code>output</code> where the result 648 * is stored 649 * 650 * @return the number of bytes stored in <code>output</code> 651 * 652 * @exception IllegalBlockSizeException if this cipher is a block cipher, 653 * no padding has been requested (only in encryption mode), and the total 654 * input length of the data processed by this cipher is not a multiple of 655 * block size; or if this encryption algorithm is unable to 656 * process the input data provided. 657 * @exception ShortBufferException if the given output buffer is too small 658 * to hold the result 659 * @exception BadPaddingException if this cipher is in decryption mode, 660 * and (un)padding has been requested, but the decrypted data is not 661 * bounded by the appropriate padding bytes 662 * @exception AEADBadTagException if this cipher is decrypting in an 663 * AEAD mode (such as GCM/CCM), and the received authentication tag 664 * does not match the calculated value 665 */ engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)666 protected abstract int engineDoFinal(byte[] input, int inputOffset, 667 int inputLen, byte[] output, 668 int outputOffset) 669 throws ShortBufferException, IllegalBlockSizeException, 670 BadPaddingException; 671 672 /** 673 * Encrypts or decrypts data in a single-part operation, 674 * or finishes a multiple-part operation. 675 * The data is encrypted or decrypted, depending on how this cipher was 676 * initialized. 677 * 678 * <p>All <code>input.remaining()</code> bytes starting at 679 * <code>input.position()</code> are processed. 680 * If an AEAD mode such as GCM/CCM is being used, the authentication 681 * tag is appended in the case of encryption, or verified in the 682 * case of decryption. 683 * The result is stored in the output buffer. 684 * Upon return, the input buffer's position will be equal 685 * to its limit; its limit will not have changed. The output buffer's 686 * position will have advanced by n, where n is the value returned 687 * by this method; the output buffer's limit will not have changed. 688 * 689 * <p>If <code>output.remaining()</code> bytes are insufficient to 690 * hold the result, a <code>ShortBufferException</code> is thrown. 691 * 692 * <p>Upon finishing, this method resets this cipher object to the state 693 * it was in when previously initialized via a call to 694 * <code>engineInit</code>. 695 * That is, the object is reset and available to encrypt or decrypt 696 * (depending on the operation mode that was specified in the call to 697 * <code>engineInit</code>) more data. 698 * 699 * <p>Note: if any exception is thrown, this cipher object may need to 700 * be reset before it can be used again. 701 * 702 * <p>Subclasses should consider overriding this method if they can 703 * process ByteBuffers more efficiently than byte arrays. 704 * 705 * @param input the input ByteBuffer 706 * @param output the output ByteByffer 707 * 708 * @return the number of bytes stored in <code>output</code> 709 * 710 * @exception IllegalBlockSizeException if this cipher is a block cipher, 711 * no padding has been requested (only in encryption mode), and the total 712 * input length of the data processed by this cipher is not a multiple of 713 * block size; or if this encryption algorithm is unable to 714 * process the input data provided. 715 * @exception ShortBufferException if there is insufficient space in the 716 * output buffer 717 * @exception BadPaddingException if this cipher is in decryption mode, 718 * and (un)padding has been requested, but the decrypted data is not 719 * bounded by the appropriate padding bytes 720 * @exception AEADBadTagException if this cipher is decrypting in an 721 * AEAD mode (such as GCM/CCM), and the received authentication tag 722 * does not match the calculated value 723 * 724 * @throws NullPointerException if either parameter is <CODE>null</CODE> 725 * @since 1.5 726 */ engineDoFinal(ByteBuffer input, ByteBuffer output)727 protected int engineDoFinal(ByteBuffer input, ByteBuffer output) 728 throws ShortBufferException, IllegalBlockSizeException, 729 BadPaddingException { 730 return bufferCrypt(input, output, false); 731 } 732 733 // copied from sun.security.jca.JCAUtil 734 // will be changed to reference that method once that code has been 735 // integrated and promoted getTempArraySize(int totalSize)736 static int getTempArraySize(int totalSize) { 737 return Math.min(4096, totalSize); 738 } 739 740 /** 741 * Implementation for encryption using ByteBuffers. Used for both 742 * engineUpdate() and engineDoFinal(). 743 */ bufferCrypt(ByteBuffer input, ByteBuffer output, boolean isUpdate)744 private int bufferCrypt(ByteBuffer input, ByteBuffer output, 745 boolean isUpdate) throws ShortBufferException, 746 IllegalBlockSizeException, BadPaddingException { 747 if ((input == null) || (output == null)) { 748 throw new NullPointerException 749 ("Input and output buffers must not be null"); 750 } 751 int inPos = input.position(); 752 int inLimit = input.limit(); 753 int inLen = inLimit - inPos; 754 if (isUpdate && (inLen == 0)) { 755 return 0; 756 } 757 int outLenNeeded = engineGetOutputSize(inLen); 758 if (output.remaining() < outLenNeeded) { 759 throw new ShortBufferException("Need at least " + outLenNeeded 760 + " bytes of space in output buffer"); 761 } 762 763 boolean a1 = input.hasArray(); 764 boolean a2 = output.hasArray(); 765 766 if (a1 && a2) { 767 byte[] inArray = input.array(); 768 int inOfs = input.arrayOffset() + inPos; 769 byte[] outArray = output.array(); 770 int outPos = output.position(); 771 int outOfs = output.arrayOffset() + outPos; 772 int n; 773 if (isUpdate) { 774 n = engineUpdate(inArray, inOfs, inLen, outArray, outOfs); 775 } else { 776 n = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs); 777 } 778 input.position(inLimit); 779 output.position(outPos + n); 780 return n; 781 } else if (!a1 && a2) { 782 int outPos = output.position(); 783 byte[] outArray = output.array(); 784 int outOfs = output.arrayOffset() + outPos; 785 byte[] inArray = new byte[getTempArraySize(inLen)]; 786 int total = 0; 787 do { 788 int chunk = Math.min(inLen, inArray.length); 789 if (chunk > 0) { 790 input.get(inArray, 0, chunk); 791 } 792 int n; 793 if (isUpdate || (inLen != chunk)) { 794 n = engineUpdate(inArray, 0, chunk, outArray, outOfs); 795 } else { 796 n = engineDoFinal(inArray, 0, chunk, outArray, outOfs); 797 } 798 total += n; 799 outOfs += n; 800 inLen -= chunk; 801 } while (inLen > 0); 802 output.position(outPos + total); 803 return total; 804 } else { // output is not backed by an accessible byte[] 805 byte[] inArray; 806 int inOfs; 807 if (a1) { 808 inArray = input.array(); 809 inOfs = input.arrayOffset() + inPos; 810 } else { 811 inArray = new byte[getTempArraySize(inLen)]; 812 inOfs = 0; 813 } 814 byte[] outArray = new byte[getTempArraySize(outLenNeeded)]; 815 int outSize = outArray.length; 816 int total = 0; 817 boolean resized = false; 818 do { 819 int chunk = 820 Math.min(inLen, (outSize == 0? inArray.length : outSize)); 821 if (!a1 && !resized && chunk > 0) { 822 input.get(inArray, 0, chunk); 823 inOfs = 0; 824 } 825 try { 826 int n; 827 if (isUpdate || (inLen != chunk)) { 828 n = engineUpdate(inArray, inOfs, chunk, outArray, 0); 829 } else { 830 n = engineDoFinal(inArray, inOfs, chunk, outArray, 0); 831 } 832 resized = false; 833 inOfs += chunk; 834 inLen -= chunk; 835 if (n > 0) { 836 output.put(outArray, 0, n); 837 total += n; 838 } 839 } catch (ShortBufferException e) { 840 if (resized) { 841 // we just resized the output buffer, but it still 842 // did not work. Bug in the provider, abort 843 throw (ProviderException)new ProviderException 844 ("Could not determine buffer size").initCause(e); 845 } 846 // output buffer is too small, realloc and try again 847 resized = true; 848 outSize = engineGetOutputSize(chunk); 849 outArray = new byte[outSize]; 850 } 851 } while (inLen > 0); 852 if (a1) { 853 input.position(inLimit); 854 } 855 return total; 856 } 857 } 858 859 /** 860 * Wrap a key. 861 * 862 * <p>This concrete method has been added to this previously-defined 863 * abstract class. (For backwards compatibility, it cannot be abstract.) 864 * It may be overridden by a provider to wrap a key. 865 * Such an override is expected to throw an IllegalBlockSizeException or 866 * InvalidKeyException (under the specified circumstances), 867 * if the given key cannot be wrapped. 868 * If this method is not overridden, it always throws an 869 * UnsupportedOperationException. 870 * 871 * @param key the key to be wrapped. 872 * 873 * @return the wrapped key. 874 * 875 * @exception IllegalBlockSizeException if this cipher is a block cipher, 876 * no padding has been requested, and the length of the encoding of the 877 * key to be wrapped is not a multiple of the block size. 878 * 879 * @exception InvalidKeyException if it is impossible or unsafe to 880 * wrap the key with this cipher (e.g., a hardware protected key is 881 * being passed to a software-only cipher). 882 * 883 * @throws UnsupportedOperationException if this method is not supported. 884 */ engineWrap(Key key)885 protected byte[] engineWrap(Key key) 886 throws IllegalBlockSizeException, InvalidKeyException 887 { 888 throw new UnsupportedOperationException(); 889 } 890 891 /** 892 * Unwrap a previously wrapped key. 893 * 894 * <p>This concrete method has been added to this previously-defined 895 * abstract class. (For backwards compatibility, it cannot be abstract.) 896 * It may be overridden by a provider to unwrap a previously wrapped key. 897 * Such an override is expected to throw an InvalidKeyException if 898 * the given wrapped key cannot be unwrapped. 899 * If this method is not overridden, it always throws an 900 * UnsupportedOperationException. 901 * 902 * @param wrappedKey the key to be unwrapped. 903 * 904 * @param wrappedKeyAlgorithm the algorithm associated with the wrapped 905 * key. 906 * 907 * @param wrappedKeyType the type of the wrapped key. This is one of 908 * <code>SECRET_KEY</code>, <code>PRIVATE_KEY</code>, or 909 * <code>PUBLIC_KEY</code>. 910 * 911 * @return the unwrapped key. 912 * 913 * @exception NoSuchAlgorithmException if no installed providers 914 * can create keys of type <code>wrappedKeyType</code> for the 915 * <code>wrappedKeyAlgorithm</code>. 916 * 917 * @exception InvalidKeyException if <code>wrappedKey</code> does not 918 * represent a wrapped key of type <code>wrappedKeyType</code> for 919 * the <code>wrappedKeyAlgorithm</code>. 920 * 921 * @throws UnsupportedOperationException if this method is not supported. 922 */ engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)923 protected Key engineUnwrap(byte[] wrappedKey, 924 String wrappedKeyAlgorithm, 925 int wrappedKeyType) 926 throws InvalidKeyException, NoSuchAlgorithmException 927 { 928 throw new UnsupportedOperationException(); 929 } 930 931 /** 932 * Returns the key size of the given key object in bits. 933 * <p>This concrete method has been added to this previously-defined 934 * abstract class. It throws an <code>UnsupportedOperationException</code> 935 * if it is not overridden by the provider. 936 * 937 * @param key the key object. 938 * 939 * @return the key size of the given key object. 940 * 941 * @exception InvalidKeyException if <code>key</code> is invalid. 942 */ engineGetKeySize(Key key)943 protected int engineGetKeySize(Key key) 944 throws InvalidKeyException 945 { 946 throw new UnsupportedOperationException(); 947 } 948 949 /** 950 * Continues a multi-part update of the Additional Authentication 951 * Data (AAD), using a subset of the provided buffer. 952 * <p> 953 * Calls to this method provide AAD to the cipher when operating in 954 * modes such as AEAD (GCM/CCM). If this cipher is operating in 955 * either GCM or CCM mode, all AAD must be supplied before beginning 956 * operations on the ciphertext (via the {@code update} and {@code 957 * doFinal} methods). 958 * 959 * @param src the buffer containing the AAD 960 * @param offset the offset in {@code src} where the AAD input starts 961 * @param len the number of AAD bytes 962 * 963 * @throws IllegalStateException if this cipher is in a wrong state 964 * (e.g., has not been initialized), does not accept AAD, or if 965 * operating in either GCM or CCM mode and one of the {@code update} 966 * methods has already been called for the active 967 * encryption/decryption operation 968 * @throws UnsupportedOperationException if this method 969 * has not been overridden by an implementation 970 * 971 * @since 1.7 972 */ engineUpdateAAD(byte[] src, int offset, int len)973 protected void engineUpdateAAD(byte[] src, int offset, int len) { 974 throw new UnsupportedOperationException( 975 "The underlying Cipher implementation " 976 + "does not support this method"); 977 } 978 979 /** 980 * Continues a multi-part update of the Additional Authentication 981 * Data (AAD). 982 * <p> 983 * Calls to this method provide AAD to the cipher when operating in 984 * modes such as AEAD (GCM/CCM). If this cipher is operating in 985 * either GCM or CCM mode, all AAD must be supplied before beginning 986 * operations on the ciphertext (via the {@code update} and {@code 987 * doFinal} methods). 988 * <p> 989 * All {@code src.remaining()} bytes starting at 990 * {@code src.position()} are processed. 991 * Upon return, the input buffer's position will be equal 992 * to its limit; its limit will not have changed. 993 * 994 * @param src the buffer containing the AAD 995 * 996 * @throws IllegalStateException if this cipher is in a wrong state 997 * (e.g., has not been initialized), does not accept AAD, or if 998 * operating in either GCM or CCM mode and one of the {@code update} 999 * methods has already been called for the active 1000 * encryption/decryption operation 1001 * @throws UnsupportedOperationException if this method 1002 * has not been overridden by an implementation 1003 * 1004 * @since 1.7 1005 */ engineUpdateAAD(ByteBuffer src)1006 protected void engineUpdateAAD(ByteBuffer src) { 1007 throw new UnsupportedOperationException( 1008 "The underlying Cipher implementation " 1009 + "does not support this method"); 1010 } 1011 } 1012