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