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
26package javax.crypto;
27
28import java.util.StringTokenizer;
29import java.util.NoSuchElementException;
30import java.security.AlgorithmParameters;
31import java.security.Provider;
32import java.security.Key;
33import java.security.SecureRandom;
34import java.security.NoSuchAlgorithmException;
35import java.security.NoSuchProviderException;
36import java.security.InvalidKeyException;
37import java.security.InvalidAlgorithmParameterException;
38import java.security.ProviderException;
39import java.security.spec.AlgorithmParameterSpec;
40
41import 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
230public 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}
1012