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