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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
1006     protected void engineUpdateAAD(ByteBuffer src) {
1007         throw new UnsupportedOperationException(
1008             "The underlying Cipher implementation "
1009             +  "does not support this method");
1010     }
1011 }