1 /*
2 * Copyright (c) 1997, 2018, 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.*;
29 import java.util.concurrent.ConcurrentHashMap;
30 import java.util.concurrent.ConcurrentMap;
31 import java.util.regex.*;
32
33
34 import java.security.*;
35 import java.security.Provider.Service;
36 import java.security.spec.AlgorithmParameterSpec;
37 import java.security.spec.InvalidParameterSpecException;
38 import java.security.cert.Certificate;
39 import java.security.cert.X509Certificate;
40
41 import javax.crypto.spec.*;
42
43 import java.nio.ByteBuffer;
44 import java.nio.ReadOnlyBufferException;
45
46 import sun.security.util.Debug;
47 import sun.security.jca.*;
48
49 /**
50 * This class provides the functionality of a cryptographic cipher for
51 * encryption and decryption. It forms the core of the Java Cryptographic
52 * Extension (JCE) framework.
53 *
54 * <p>In order to create a Cipher object, the application calls the
55 * Cipher's {@code getInstance} method, and passes the name of the
56 * requested <i>transformation</i> to it. Optionally, the name of a provider
57 * may be specified.
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>AES</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>AES/CBC/PKCS5Padding</i>");
79 * </pre>
80 *
81 * Using modes such as {@code CFB} and {@code OFB}, block
82 * ciphers can encrypt data in units smaller than the cipher's actual
83 * block size. When requesting such a mode, you may optionally specify
84 * the number of bits to be processed at a time by appending this number
85 * to the mode name as shown in the "{@code AES/CFB8/NoPadding}" and
86 * "{@code AES/OFB32/PKCS5Padding}" transformations. If no such
87 * number is specified, a provider-specific default is used.
88 * (See the
89 * {@extLink security_guide_jdk_providers JDK Providers Documentation}
90 * for the JDK Providers default values.)
91 * Thus, block ciphers can be turned into byte-oriented stream ciphers by
92 * using an 8 bit mode such as CFB8 or OFB8.
93 * <p>
94 * Modes such as Authenticated Encryption with Associated Data (AEAD)
95 * provide authenticity assurances for both confidential data and
96 * Additional Associated Data (AAD) that is not encrypted. (Please see
97 * <a href="http://www.ietf.org/rfc/rfc5116.txt"> RFC 5116 </a> for more
98 * information on AEAD and AAD algorithms such as GCM/CCM.) Both
99 * confidential and AAD data can be used when calculating the
100 * authentication tag (similar to a {@link Mac}). This tag is appended
101 * to the ciphertext during encryption, and is verified on decryption.
102 * <p>
103 * AEAD modes such as GCM/CCM perform all AAD authenticity calculations
104 * before starting the ciphertext authenticity calculations. To avoid
105 * implementations having to internally buffer ciphertext, all AAD data
106 * must be supplied to GCM/CCM implementations (via the {@code updateAAD}
107 * methods) <b>before</b> the ciphertext is processed (via
108 * the {@code update} and {@code doFinal} methods).
109 * <p>
110 * Note that GCM mode has a uniqueness requirement on IVs used in
111 * encryption with a given key. When IVs are repeated for GCM
112 * encryption, such usages are subject to forgery attacks. Thus, after
113 * each encryption operation using GCM mode, callers should re-initialize
114 * the cipher objects with GCM parameters which have a different IV value.
115 * <pre>
116 * GCMParameterSpec s = ...;
117 * cipher.init(..., s);
118 *
119 * // If the GCM parameters were generated by the provider, it can
120 * // be retrieved by:
121 * // cipher.getParameters().getParameterSpec(GCMParameterSpec.class);
122 *
123 * cipher.updateAAD(...); // AAD
124 * cipher.update(...); // Multi-part update
125 * cipher.doFinal(...); // conclusion of operation
126 *
127 * // Use a different IV value for every encryption
128 * byte[] newIv = ...;
129 * s = new GCMParameterSpec(s.getTLen(), newIv);
130 * cipher.init(..., s);
131 * ...
132 *
133 * </pre>
134 * The ChaCha20 and ChaCha20-Poly1305 algorithms have a similar requirement
135 * for unique nonces with a given key. After each encryption or decryption
136 * operation, callers should re-initialize their ChaCha20 or ChaCha20-Poly1305
137 * ciphers with parameters that specify a different nonce value. Please
138 * see <a href="https://tools.ietf.org/html/rfc7539">RFC 7539</a> for more
139 * information on the ChaCha20 and ChaCha20-Poly1305 algorithms.
140 * <p>
141 * Every implementation of the Java platform is required to support
142 * the following standard {@code Cipher} transformations with the keysizes
143 * in parentheses:
144 * <ul>
145 * <li>{@code AES/CBC/NoPadding} (128)</li>
146 * <li>{@code AES/CBC/PKCS5Padding} (128)</li>
147 * <li>{@code AES/ECB/NoPadding} (128)</li>
148 * <li>{@code AES/ECB/PKCS5Padding} (128)</li>
149 * <li>{@code AES/GCM/NoPadding} (128)</li>
150 * <li>{@code DES/CBC/NoPadding} (56)</li>
151 * <li>{@code DES/CBC/PKCS5Padding} (56)</li>
152 * <li>{@code DES/ECB/NoPadding} (56)</li>
153 * <li>{@code DES/ECB/PKCS5Padding} (56)</li>
154 * <li>{@code DESede/CBC/NoPadding} (168)</li>
155 * <li>{@code DESede/CBC/PKCS5Padding} (168)</li>
156 * <li>{@code DESede/ECB/NoPadding} (168)</li>
157 * <li>{@code DESede/ECB/PKCS5Padding} (168)</li>
158 * <li>{@code RSA/ECB/PKCS1Padding} (1024, 2048)</li>
159 * <li>{@code RSA/ECB/OAEPWithSHA-1AndMGF1Padding} (1024, 2048)</li>
160 * <li>{@code RSA/ECB/OAEPWithSHA-256AndMGF1Padding} (1024, 2048)</li>
161 * </ul>
162 * These transformations are described in the
163 * <a href="{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
164 * Cipher section</a> of the
165 * Java Security Standard Algorithm Names Specification.
166 * Consult the release documentation for your implementation to see if any
167 * other transformations are supported.
168 *
169 * @author Jan Luehe
170 * @see KeyGenerator
171 * @see SecretKey
172 * @since 1.4
173 */
174
175 public class Cipher {
176
177 private static final Debug debug =
178 Debug.getInstance("jca", "Cipher");
179
180 private static final Debug pdebug =
181 Debug.getInstance("provider", "Provider");
182 private static final boolean skipDebug =
183 Debug.isOn("engine=") && !Debug.isOn("cipher");
184
185 /**
186 * Constant used to initialize cipher to encryption mode.
187 */
188 public static final int ENCRYPT_MODE = 1;
189
190 /**
191 * Constant used to initialize cipher to decryption mode.
192 */
193 public static final int DECRYPT_MODE = 2;
194
195 /**
196 * Constant used to initialize cipher to key-wrapping mode.
197 */
198 public static final int WRAP_MODE = 3;
199
200 /**
201 * Constant used to initialize cipher to key-unwrapping mode.
202 */
203 public static final int UNWRAP_MODE = 4;
204
205 /**
206 * Constant used to indicate the to-be-unwrapped key is a "public key".
207 */
208 public static final int PUBLIC_KEY = 1;
209
210 /**
211 * Constant used to indicate the to-be-unwrapped key is a "private key".
212 */
213 public static final int PRIVATE_KEY = 2;
214
215 /**
216 * Constant used to indicate the to-be-unwrapped key is a "secret key".
217 */
218 public static final int SECRET_KEY = 3;
219
220 // The provider
221 private Provider provider;
222
223 // The provider implementation (delegate)
224 private CipherSpi spi;
225
226 // The transformation
227 private String transformation;
228
229 // Crypto permission representing the maximum allowable cryptographic
230 // strength that this Cipher object can be used for. (The cryptographic
231 // strength is a function of the keysize and algorithm parameters encoded
232 // in the crypto permission.)
233 private CryptoPermission cryptoPerm;
234
235 // The exemption mechanism that needs to be enforced
236 private ExemptionMechanism exmech;
237
238 // Flag which indicates whether or not this cipher has been initialized
239 private boolean initialized = false;
240
241 // The operation mode - store the operation mode after the
242 // cipher has been initialized.
243 private int opmode = 0;
244
245 // The OID for the KeyUsage extension in an X.509 v3 certificate
246 private static final String KEY_USAGE_EXTENSION_OID = "2.5.29.15";
247
248 // next SPI to try in provider selection
249 // null once provider is selected
250 private CipherSpi firstSpi;
251
252 // next service to try in provider selection
253 // null once provider is selected
254 private Service firstService;
255
256 // remaining services to try in provider selection
257 // null once provider is selected
258 private Iterator<Service> serviceIterator;
259
260 // list of transform Strings to lookup in the provider
261 private List<Transform> transforms;
262
263 private final Object lock;
264
265 /**
266 * Creates a Cipher object.
267 *
268 * @param cipherSpi the delegate
269 * @param provider the provider
270 * @param transformation the transformation
271 */
272 protected Cipher(CipherSpi cipherSpi,
273 Provider provider,
274 String transformation) {
275 // See bug 4341369 & 4334690 for more info.
276 // If the caller is trusted, then okay.
277 // Otherwise throw a NullPointerException.
278 if (!JceSecurityManager.INSTANCE.isCallerTrusted(provider)) {
279 throw new NullPointerException();
280 }
281 this.spi = cipherSpi;
282 this.provider = provider;
283 this.transformation = transformation;
284 this.cryptoPerm = CryptoAllPermission.INSTANCE;
285 this.lock = null;
286 }
287
288 /**
289 * Creates a Cipher object. Called internally and by NullCipher.
290 *
291 * @param cipherSpi the delegate
292 * @param transformation the transformation
293 */
294 Cipher(CipherSpi cipherSpi, String transformation) {
295 this.spi = cipherSpi;
296 this.transformation = transformation;
297 this.cryptoPerm = CryptoAllPermission.INSTANCE;
298 this.lock = null;
299 }
300
301 private Cipher(CipherSpi firstSpi, Service firstService,
302 Iterator<Service> serviceIterator, String transformation,
303 List<Transform> transforms) {
304 this.firstSpi = firstSpi;
305 this.firstService = firstService;
306 this.serviceIterator = serviceIterator;
307 this.transforms = transforms;
308 this.transformation = transformation;
309 this.lock = new Object();
310 }
311
312 private static String[] tokenizeTransformation(String transformation)
313 throws NoSuchAlgorithmException {
314 if (transformation == null) {
315 throw new NoSuchAlgorithmException("No transformation given");
316 }
317 /*
318 * array containing the components of a Cipher transformation:
319 *
320 * index 0: algorithm component (e.g., AES)
321 * index 1: feedback component (e.g., CFB)
322 * index 2: padding component (e.g., PKCS5Padding)
323 */
324 String[] parts = new String[3];
325 int count = 0;
326 StringTokenizer parser = new StringTokenizer(transformation, "/");
327 try {
328 while (parser.hasMoreTokens() && count < 3) {
329 parts[count++] = parser.nextToken().trim();
330 }
331 if (count == 0 || count == 2) {
332 throw new NoSuchAlgorithmException("Invalid transformation"
333 + " format:" +
334 transformation);
335 }
336 // treats all subsequent tokens as part of padding
337 if (count == 3 && parser.hasMoreTokens()) {
338 parts[2] = parts[2] + parser.nextToken("\r\n");
339 }
340 } catch (NoSuchElementException e) {
341 throw new NoSuchAlgorithmException("Invalid transformation " +
342 "format:" + transformation);
343 }
344 if ((parts[0] == null) || (parts[0].isEmpty())) {
345 throw new NoSuchAlgorithmException("Invalid transformation:" +
346 "algorithm not specified-"
347 + transformation);
348 }
349 return parts;
350 }
351
352 // Provider attribute name for supported chaining mode
353 private static final String ATTR_MODE = "SupportedModes";
354 // Provider attribute name for supported padding names
355 private static final String ATTR_PAD = "SupportedPaddings";
356
357 // constants indicating whether the provider supports
358 // a given mode or padding
359 private static final int S_NO = 0; // does not support
360 private static final int S_MAYBE = 1; // unable to determine
361 private static final int S_YES = 2; // does support
362
363 /**
364 * Nested class to deal with modes and paddings.
365 */
366 private static class Transform {
367 // transform string to lookup in the provider
368 final String transform;
369 // the mode/padding suffix in upper case. for example, if the algorithm
370 // to lookup is "AES/CBC/PKCS5Padding" suffix is "/CBC/PKCS5PADDING"
371 // if lookup is "AES", suffix is the empty string
372 // needed because aliases prevent straight transform.equals()
373 final String suffix;
374 // value to pass to setMode() or null if no such call required
375 final String mode;
376 // value to pass to setPadding() or null if no such call required
377 final String pad;
378 Transform(String alg, String suffix, String mode, String pad) {
379 this.transform = alg + suffix;
380 this.suffix = suffix.toUpperCase(Locale.ENGLISH);
381 this.mode = mode;
382 this.pad = pad;
383 }
384 // set mode and padding for the given SPI
385 void setModePadding(CipherSpi spi) throws NoSuchAlgorithmException,
386 NoSuchPaddingException {
387 if (mode != null) {
388 spi.engineSetMode(mode);
389 }
390 if (pad != null) {
391 spi.engineSetPadding(pad);
392 }
393 }
394 // check whether the given services supports the mode and
395 // padding described by this Transform
396 int supportsModePadding(Service s) {
397 int smode = supportsMode(s);
398 if (smode == S_NO) {
399 return smode;
400 }
401 int spad = supportsPadding(s);
402 // our constants are defined so that Math.min() is a tri-valued AND
403 return Math.min(smode, spad);
404 }
405
406 // separate methods for mode and padding
407 // called directly by Cipher only to throw the correct exception
408 int supportsMode(Service s) {
409 return supports(s, ATTR_MODE, mode);
410 }
411 int supportsPadding(Service s) {
412 return supports(s, ATTR_PAD, pad);
413 }
414
415 private static int supports(Service s, String attrName, String value) {
416 if (value == null) {
417 return S_YES;
418 }
419 String regexp = s.getAttribute(attrName);
420 if (regexp == null) {
421 return S_MAYBE;
422 }
423 return matches(regexp, value) ? S_YES : S_NO;
424 }
425
426 // ConcurrentMap<String,Pattern> for previously compiled patterns
427 private static final ConcurrentMap<String, Pattern> patternCache =
428 new ConcurrentHashMap<String, Pattern>();
429
430 private static boolean matches(String regexp, String str) {
431 Pattern pattern = patternCache.get(regexp);
432 if (pattern == null) {
433 pattern = Pattern.compile(regexp);
434 patternCache.putIfAbsent(regexp, pattern);
435 }
436 return pattern.matcher(str.toUpperCase(Locale.ENGLISH)).matches();
437 }
438
439 }
440
441 private static List<Transform> getTransforms(String transformation)
442 throws NoSuchAlgorithmException {
443 String[] parts = tokenizeTransformation(transformation);
444
445 String alg = parts[0];
446 String mode = parts[1];
447 String pad = parts[2];
448 if ((mode != null) && (mode.isEmpty())) {
449 mode = null;
450 }
451 if ((pad != null) && (pad.isEmpty())) {
452 pad = null;
453 }
454
455 if ((mode == null) && (pad == null)) {
456 // AES
457 Transform tr = new Transform(alg, "", null, null);
458 return Collections.singletonList(tr);
459 } else { // if ((mode != null) && (pad != null)) {
460 // AES/CBC/PKCS5Padding
461 List<Transform> list = new ArrayList<>(4);
462 list.add(new Transform(alg, "/" + mode + "/" + pad, null, null));
463 list.add(new Transform(alg, "/" + mode, null, pad));
464 list.add(new Transform(alg, "//" + pad, mode, null));
465 list.add(new Transform(alg, "", mode, pad));
466 return list;
467 }
468 }
469
470 // get the transform matching the specified service
471 private static Transform getTransform(Service s,
472 List<Transform> transforms) {
473 String alg = s.getAlgorithm().toUpperCase(Locale.ENGLISH);
474 for (Transform tr : transforms) {
475 if (alg.endsWith(tr.suffix)) {
476 return tr;
477 }
478 }
479 return null;
480 }
481
482 /**
483 * Returns a {@code Cipher} object that implements the specified
484 * transformation.
485 *
486 * <p> This method traverses the list of registered security Providers,
487 * starting with the most preferred Provider.
488 * A new Cipher object encapsulating the
489 * CipherSpi implementation from the first
490 * Provider that supports the specified algorithm is returned.
491 *
492 * <p> Note that the list of registered providers may be retrieved via
493 * the {@link Security#getProviders() Security.getProviders()} method.
494 *
495 * @implNote
496 * The JDK Reference Implementation additionally uses the
497 * {@code jdk.security.provider.preferred}
498 * {@link Security#getProperty(String) Security} property to determine
499 * the preferred provider order for the specified algorithm. This
500 * may be different than the order of providers returned by
501 * {@link Security#getProviders() Security.getProviders()}.
502 *
503 * @param transformation the name of the transformation, e.g.,
504 * <i>AES/CBC/PKCS5Padding</i>.
505 * See the Cipher section in the <a href=
506 * "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
507 * Java Security Standard Algorithm Names Specification</a>
508 * for information about standard transformation names.
509 *
510 * @return a cipher that implements the requested transformation
511 *
512 * @throws NoSuchAlgorithmException if {@code transformation}
513 * is {@code null}, empty, in an invalid format,
514 * or if no {@code Provider} supports a {@code CipherSpi}
515 * implementation for the specified algorithm
516 *
517 * @throws NoSuchPaddingException if {@code transformation}
518 * contains a padding scheme that is not available
519 *
520 * @see java.security.Provider
521 */
522 public static final Cipher getInstance(String transformation)
523 throws NoSuchAlgorithmException, NoSuchPaddingException
524 {
525 if ((transformation == null) || transformation.equals("")) {
526 throw new NoSuchAlgorithmException("Null or empty transformation");
527 }
528 List<Transform> transforms = getTransforms(transformation);
529 List<ServiceId> cipherServices = new ArrayList<>(transforms.size());
530 for (Transform transform : transforms) {
531 cipherServices.add(new ServiceId("Cipher", transform.transform));
532 }
533 List<Service> services = GetInstance.getServices(cipherServices);
534 // make sure there is at least one service from a signed provider
535 // and that it can use the specified mode and padding
536 Iterator<Service> t = services.iterator();
537 Exception failure = null;
538 while (t.hasNext()) {
539 Service s = t.next();
540 if (JceSecurity.canUseProvider(s.getProvider()) == false) {
541 continue;
542 }
543 Transform tr = getTransform(s, transforms);
544 if (tr == null) {
545 // should never happen
546 continue;
547 }
548 int canuse = tr.supportsModePadding(s);
549 if (canuse == S_NO) {
550 // does not support mode or padding we need, ignore
551 continue;
552 }
553 if (canuse == S_YES) {
554 return new Cipher(null, s, t, transformation, transforms);
555 } else { // S_MAYBE, try out if it works
556 try {
557 CipherSpi spi = (CipherSpi)s.newInstance(null);
558 tr.setModePadding(spi);
559 return new Cipher(spi, s, t, transformation, transforms);
560 } catch (Exception e) {
561 failure = e;
562 }
563 }
564 }
565 throw new NoSuchAlgorithmException
566 ("Cannot find any provider supporting " + transformation, failure);
567 }
568
569 /**
570 * Returns a {@code Cipher} object that implements the specified
571 * transformation.
572 *
573 * <p> A new Cipher object encapsulating the
574 * CipherSpi implementation from the specified provider
575 * is returned. The specified provider must be registered
576 * in the security provider list.
577 *
578 * <p> Note that the list of registered providers may be retrieved via
579 * the {@link Security#getProviders() Security.getProviders()} method.
580 *
581 * @param transformation the name of the transformation,
582 * e.g., <i>AES/CBC/PKCS5Padding</i>.
583 * See the Cipher section in the <a href=
584 * "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
585 * Java Security Standard Algorithm Names Specification</a>
586 * for information about standard transformation names.
587 *
588 * @param provider the name of the provider.
589 *
590 * @return a cipher that implements the requested transformation
591 *
592 * @throws IllegalArgumentException if the {@code provider}
593 * is {@code null} or empty
594 *
595 * @throws NoSuchAlgorithmException if {@code transformation}
596 * is {@code null}, empty, in an invalid format,
597 * or if a {@code CipherSpi} implementation for the
598 * specified algorithm is not available from the specified
599 * provider
600 *
601 * @throws NoSuchPaddingException if {@code transformation}
602 * contains a padding scheme that is not available
603 *
604 * @throws NoSuchProviderException if the specified provider is not
605 * registered in the security provider list
606 *
607 * @see java.security.Provider
608 */
609 public static final Cipher getInstance(String transformation,
610 String provider)
611 throws NoSuchAlgorithmException, NoSuchProviderException,
612 NoSuchPaddingException
613 {
614 if ((transformation == null) || transformation.equals("")) {
615 throw new NoSuchAlgorithmException("Null or empty transformation");
616 }
617 if ((provider == null) || (provider.isEmpty())) {
618 throw new IllegalArgumentException("Missing provider");
619 }
620 Provider p = Security.getProvider(provider);
621 if (p == null) {
622 throw new NoSuchProviderException("No such provider: " +
623 provider);
624 }
625 return getInstance(transformation, p);
626 }
627
628 private String getProviderName() {
629 return (provider == null) ? "(no provider)" : provider.getName();
630 }
631
632 /**
633 * Returns a {@code Cipher} object that implements the specified
634 * transformation.
635 *
636 * <p> A new Cipher object encapsulating the
637 * CipherSpi implementation from the specified Provider
638 * object is returned. Note that the specified Provider object
639 * does not have to be registered in the provider list.
640 *
641 * @param transformation the name of the transformation,
642 * e.g., <i>AES/CBC/PKCS5Padding</i>.
643 * See the Cipher section in the <a href=
644 * "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">
645 * Java Security Standard Algorithm Names Specification</a>
646 * for information about standard transformation names.
647 *
648 * @param provider the provider.
649 *
650 * @return a cipher that implements the requested transformation
651 *
652 * @throws IllegalArgumentException if the {@code provider}
653 * is {@code null}
654 *
655 * @throws NoSuchAlgorithmException if {@code transformation}
656 * is {@code null}, empty, in an invalid format,
657 * or if a {@code CipherSpi} implementation for the
658 * specified algorithm is not available from the specified
659 * {@code Provider} object
660 *
661 * @throws NoSuchPaddingException if {@code transformation}
662 * contains a padding scheme that is not available
663 *
664 * @see java.security.Provider
665 */
666 public static final Cipher getInstance(String transformation,
667 Provider provider)
668 throws NoSuchAlgorithmException, NoSuchPaddingException
669 {
670 if ((transformation == null) || transformation.equals("")) {
671 throw new NoSuchAlgorithmException("Null or empty transformation");
672 }
673 if (provider == null) {
674 throw new IllegalArgumentException("Missing provider");
675 }
676 Exception failure = null;
677 List<Transform> transforms = getTransforms(transformation);
678 boolean providerChecked = false;
679 String paddingError = null;
680 for (Transform tr : transforms) {
681 Service s = provider.getService("Cipher", tr.transform);
682 if (s == null) {
683 continue;
684 }
685 if (providerChecked == false) {
686 // for compatibility, first do the lookup and then verify
687 // the provider. this makes the difference between a NSAE
688 // and a SecurityException if the
689 // provider does not support the algorithm.
690 Exception ve = JceSecurity.getVerificationResult(provider);
691 if (ve != null) {
692 String msg = "JCE cannot authenticate the provider "
693 + provider.getName();
694 throw new SecurityException(msg, ve);
695 }
696 providerChecked = true;
697 }
698 if (tr.supportsMode(s) == S_NO) {
699 continue;
700 }
701 if (tr.supportsPadding(s) == S_NO) {
702 paddingError = tr.pad;
703 continue;
704 }
705 try {
706 CipherSpi spi = (CipherSpi)s.newInstance(null);
707 tr.setModePadding(spi);
708 Cipher cipher = new Cipher(spi, transformation);
709 cipher.provider = s.getProvider();
710 cipher.initCryptoPermission();
711 return cipher;
712 } catch (Exception e) {
713 failure = e;
714 }
715 }
716
717 // throw NoSuchPaddingException if the problem is with padding
718 if (failure instanceof NoSuchPaddingException) {
719 throw (NoSuchPaddingException)failure;
720 }
721 if (paddingError != null) {
722 throw new NoSuchPaddingException
723 ("Padding not supported: " + paddingError);
724 }
725 throw new NoSuchAlgorithmException
726 ("No such algorithm: " + transformation, failure);
727 }
728
729 // If the requested crypto service is export-controlled,
730 // determine the maximum allowable keysize.
731 private void initCryptoPermission() throws NoSuchAlgorithmException {
732 if (JceSecurity.isRestricted() == false) {
733 cryptoPerm = CryptoAllPermission.INSTANCE;
734 exmech = null;
735 return;
736 }
737 cryptoPerm = getConfiguredPermission(transformation);
738 // Instantiate the exemption mechanism (if required)
739 String exmechName = cryptoPerm.getExemptionMechanism();
740 if (exmechName != null) {
741 exmech = ExemptionMechanism.getInstance(exmechName);
742 }
743 }
744
745 // max number of debug warnings to print from chooseFirstProvider()
746 private static int warnCount = 10;
747
748 /**
749 * Choose the Spi from the first provider available. Used if
750 * delayed provider selection is not possible because init()
751 * is not the first method called.
752 */
753 void chooseFirstProvider() {
754 if (spi != null) {
755 return;
756 }
757 synchronized (lock) {
758 if (spi != null) {
759 return;
760 }
761 if (debug != null) {
762 int w = --warnCount;
763 if (w >= 0) {
764 debug.println("Cipher.init() not first method "
765 + "called, disabling delayed provider selection");
766 if (w == 0) {
767 debug.println("Further warnings of this type will "
768 + "be suppressed");
769 }
770 new Exception("Call trace").printStackTrace();
771 }
772 }
773 Exception lastException = null;
774 while ((firstService != null) || serviceIterator.hasNext()) {
775 Service s;
776 CipherSpi thisSpi;
777 if (firstService != null) {
778 s = firstService;
779 thisSpi = firstSpi;
780 firstService = null;
781 firstSpi = null;
782 } else {
783 s = serviceIterator.next();
784 thisSpi = null;
785 }
786 if (JceSecurity.canUseProvider(s.getProvider()) == false) {
787 continue;
788 }
789 Transform tr = getTransform(s, transforms);
790 if (tr == null) {
791 // should never happen
792 continue;
793 }
794 if (tr.supportsModePadding(s) == S_NO) {
795 continue;
796 }
797 try {
798 if (thisSpi == null) {
799 Object obj = s.newInstance(null);
800 if (obj instanceof CipherSpi == false) {
801 continue;
802 }
803 thisSpi = (CipherSpi)obj;
804 }
805 tr.setModePadding(thisSpi);
806 initCryptoPermission();
807 spi = thisSpi;
808 provider = s.getProvider();
809 // not needed any more
810 firstService = null;
811 serviceIterator = null;
812 transforms = null;
813 return;
814 } catch (Exception e) {
815 lastException = e;
816 }
817 }
818 ProviderException e = new ProviderException
819 ("Could not construct CipherSpi instance");
820 if (lastException != null) {
821 e.initCause(lastException);
822 }
823 throw e;
824 }
825 }
826
827 private static final int I_KEY = 1;
828 private static final int I_PARAMSPEC = 2;
829 private static final int I_PARAMS = 3;
830 private static final int I_CERT = 4;
831
832 private void implInit(CipherSpi thisSpi, int type, int opmode, Key key,
833 AlgorithmParameterSpec paramSpec, AlgorithmParameters params,
834 SecureRandom random) throws InvalidKeyException,
835 InvalidAlgorithmParameterException {
836 switch (type) {
837 case I_KEY:
838 checkCryptoPerm(thisSpi, key);
839 thisSpi.engineInit(opmode, key, random);
840 break;
841 case I_PARAMSPEC:
842 checkCryptoPerm(thisSpi, key, paramSpec);
843 thisSpi.engineInit(opmode, key, paramSpec, random);
844 break;
845 case I_PARAMS:
846 checkCryptoPerm(thisSpi, key, params);
847 thisSpi.engineInit(opmode, key, params, random);
848 break;
849 case I_CERT:
850 checkCryptoPerm(thisSpi, key);
851 thisSpi.engineInit(opmode, key, random);
852 break;
853 default:
854 throw new AssertionError("Internal Cipher error: " + type);
855 }
856 }
857
858 private void chooseProvider(int initType, int opmode, Key key,
859 AlgorithmParameterSpec paramSpec,
860 AlgorithmParameters params, SecureRandom random)
861 throws InvalidKeyException, InvalidAlgorithmParameterException {
862 synchronized (lock) {
863 if (spi != null) {
864 implInit(spi, initType, opmode, key, paramSpec, params, random);
865 return;
866 }
867 Exception lastException = null;
868 while ((firstService != null) || serviceIterator.hasNext()) {
869 Service s;
870 CipherSpi thisSpi;
871 if (firstService != null) {
872 s = firstService;
873 thisSpi = firstSpi;
874 firstService = null;
875 firstSpi = null;
876 } else {
877 s = serviceIterator.next();
878 thisSpi = null;
879 }
880 // if provider says it does not support this key, ignore it
881 if (s.supportsParameter(key) == false) {
882 continue;
883 }
884 if (JceSecurity.canUseProvider(s.getProvider()) == false) {
885 continue;
886 }
887 Transform tr = getTransform(s, transforms);
888 if (tr == null) {
889 // should never happen
890 continue;
891 }
892 if (tr.supportsModePadding(s) == S_NO) {
893 continue;
894 }
895 try {
896 if (thisSpi == null) {
897 thisSpi = (CipherSpi)s.newInstance(null);
898 }
899 tr.setModePadding(thisSpi);
900 initCryptoPermission();
901 implInit(thisSpi, initType, opmode, key, paramSpec,
902 params, random);
903 provider = s.getProvider();
904 this.spi = thisSpi;
905 firstService = null;
906 serviceIterator = null;
907 transforms = null;
908 return;
909 } catch (Exception e) {
910 // NoSuchAlgorithmException from newInstance()
911 // InvalidKeyException from init()
912 // RuntimeException (ProviderException) from init()
913 // SecurityException from crypto permission check
914 if (lastException == null) {
915 lastException = e;
916 }
917 }
918 }
919 // no working provider found, fail
920 if (lastException instanceof InvalidKeyException) {
921 throw (InvalidKeyException)lastException;
922 }
923 if (lastException instanceof InvalidAlgorithmParameterException) {
924 throw (InvalidAlgorithmParameterException)lastException;
925 }
926 if (lastException instanceof RuntimeException) {
927 throw (RuntimeException)lastException;
928 }
929 String kName = (key != null) ? key.getClass().getName() : "(null)";
930 throw new InvalidKeyException
931 ("No installed provider supports this key: "
932 + kName, lastException);
933 }
934 }
935
936 /**
937 * Returns the provider of this {@code Cipher} object.
938 *
939 * @return the provider of this {@code Cipher} object
940 */
941 public final Provider getProvider() {
942 chooseFirstProvider();
943 return this.provider;
944 }
945
946 /**
947 * Returns the algorithm name of this {@code Cipher} object.
948 *
949 * <p>This is the same name that was specified in one of the
950 * {@code getInstance} calls that created this {@code Cipher}
951 * object..
952 *
953 * @return the algorithm name of this {@code Cipher} object.
954 */
955 public final String getAlgorithm() {
956 return this.transformation;
957 }
958
959 /**
960 * Returns the block size (in bytes).
961 *
962 * @return the block size (in bytes), or 0 if the underlying algorithm is
963 * not a block cipher
964 */
965 public final int getBlockSize() {
966 chooseFirstProvider();
967 return spi.engineGetBlockSize();
968 }
969
970 /**
971 * Returns the length in bytes that an output buffer would need to be in
972 * order to hold the result of the next {@code update} or
973 * {@code doFinal} operation, given the input length
974 * {@code inputLen} (in bytes).
975 *
976 * <p>This call takes into account any unprocessed (buffered) data from a
977 * previous {@code update} call, padding, and AEAD tagging.
978 *
979 * <p>The actual output length of the next {@code update} or
980 * {@code doFinal} call may be smaller than the length returned by
981 * this method.
982 *
983 * @param inputLen the input length (in bytes)
984 *
985 * @return the required output buffer size (in bytes)
986 *
987 * @exception IllegalStateException if this cipher is in a wrong state
988 * (e.g., has not yet been initialized)
989 */
990 public final int getOutputSize(int inputLen) {
991
992 if (!initialized && !(this instanceof NullCipher)) {
993 throw new IllegalStateException("Cipher not initialized");
994 }
995 if (inputLen < 0) {
996 throw new IllegalArgumentException("Input size must be equal " +
997 "to or greater than zero");
998 }
999 chooseFirstProvider();
1000 return spi.engineGetOutputSize(inputLen);
1001 }
1002
1003 /**
1004 * Returns the initialization vector (IV) in a new buffer.
1005 *
1006 * <p>This is useful in the case where a random IV was created,
1007 * or in the context of password-based encryption or
1008 * decryption, where the IV is derived from a user-supplied password.
1009 *
1010 * @return the initialization vector in a new buffer, or null if the
1011 * underlying algorithm does not use an IV, or if the IV has not yet
1012 * been set.
1013 */
1014 public final byte[] getIV() {
1015 chooseFirstProvider();
1016 return spi.engineGetIV();
1017 }
1018
1019 /**
1020 * Returns the parameters used with this cipher.
1021 *
1022 * <p>The returned parameters may be the same that were used to initialize
1023 * this cipher, or may contain a combination of default and random
1024 * parameter values used by the underlying cipher implementation if this
1025 * cipher requires algorithm parameters but was not initialized with any.
1026 *
1027 * @return the parameters used with this cipher, or null if this cipher
1028 * does not use any parameters.
1029 */
1030 public final AlgorithmParameters getParameters() {
1031 chooseFirstProvider();
1032 return spi.engineGetParameters();
1033 }
1034
1035 /**
1036 * Returns the exemption mechanism object used with this cipher.
1037 *
1038 * @return the exemption mechanism object used with this cipher, or
1039 * null if this cipher does not use any exemption mechanism.
1040 */
1041 public final ExemptionMechanism getExemptionMechanism() {
1042 chooseFirstProvider();
1043 return exmech;
1044 }
1045
1046 //
1047 // Crypto permission check code below
1048 //
1049 private void checkCryptoPerm(CipherSpi checkSpi, Key key)
1050 throws InvalidKeyException {
1051 if (cryptoPerm == CryptoAllPermission.INSTANCE) {
1052 return;
1053 }
1054 // Check if key size and default parameters are within legal limits
1055 AlgorithmParameterSpec params;
1056 try {
1057 params = getAlgorithmParameterSpec(checkSpi.engineGetParameters());
1058 } catch (InvalidParameterSpecException ipse) {
1059 throw new InvalidKeyException
1060 ("Unsupported default algorithm parameters");
1061 }
1062 if (!passCryptoPermCheck(checkSpi, key, params)) {
1063 throw new InvalidKeyException(
1064 "Illegal key size or default parameters");
1065 }
1066 }
1067
1068 private void checkCryptoPerm(CipherSpi checkSpi, Key key,
1069 AlgorithmParameterSpec params) throws InvalidKeyException,
1070 InvalidAlgorithmParameterException {
1071 if (cryptoPerm == CryptoAllPermission.INSTANCE) {
1072 return;
1073 }
1074 // Determine keysize and check if it is within legal limits
1075 if (!passCryptoPermCheck(checkSpi, key, null)) {
1076 throw new InvalidKeyException("Illegal key size");
1077 }
1078 if ((params != null) && (!passCryptoPermCheck(checkSpi, key, params))) {
1079 throw new InvalidAlgorithmParameterException("Illegal parameters");
1080 }
1081 }
1082
1083 private void checkCryptoPerm(CipherSpi checkSpi, Key key,
1084 AlgorithmParameters params)
1085 throws InvalidKeyException, InvalidAlgorithmParameterException {
1086 if (cryptoPerm == CryptoAllPermission.INSTANCE) {
1087 return;
1088 }
1089 // Convert the specified parameters into specs and then delegate.
1090 AlgorithmParameterSpec pSpec;
1091 try {
1092 pSpec = getAlgorithmParameterSpec(params);
1093 } catch (InvalidParameterSpecException ipse) {
1094 throw new InvalidAlgorithmParameterException
1095 ("Failed to retrieve algorithm parameter specification");
1096 }
1097 checkCryptoPerm(checkSpi, key, pSpec);
1098 }
1099
1100 private boolean passCryptoPermCheck(CipherSpi checkSpi, Key key,
1101 AlgorithmParameterSpec params)
1102 throws InvalidKeyException {
1103 String em = cryptoPerm.getExemptionMechanism();
1104 int keySize = checkSpi.engineGetKeySize(key);
1105 // Use the "algorithm" component of the cipher
1106 // transformation so that the perm check would
1107 // work when the key has the "aliased" algo.
1108 String algComponent;
1109 int index = transformation.indexOf('/');
1110 if (index != -1) {
1111 algComponent = transformation.substring(0, index);
1112 } else {
1113 algComponent = transformation;
1114 }
1115 CryptoPermission checkPerm =
1116 new CryptoPermission(algComponent, keySize, params, em);
1117
1118 if (!cryptoPerm.implies(checkPerm)) {
1119 if (debug != null) {
1120 debug.println("Crypto Permission check failed");
1121 debug.println("granted: " + cryptoPerm);
1122 debug.println("requesting: " + checkPerm);
1123 }
1124 return false;
1125 }
1126 if (exmech == null) {
1127 return true;
1128 }
1129 try {
1130 if (!exmech.isCryptoAllowed(key)) {
1131 if (debug != null) {
1132 debug.println(exmech.getName() + " isn't enforced");
1133 }
1134 return false;
1135 }
1136 } catch (ExemptionMechanismException eme) {
1137 if (debug != null) {
1138 debug.println("Cannot determine whether "+
1139 exmech.getName() + " has been enforced");
1140 eme.printStackTrace();
1141 }
1142 return false;
1143 }
1144 return true;
1145 }
1146
1147 // check if opmode is one of the defined constants
1148 // throw InvalidParameterExeption if not
1149 private static void checkOpmode(int opmode) {
1150 if ((opmode < ENCRYPT_MODE) || (opmode > UNWRAP_MODE)) {
1151 throw new InvalidParameterException("Invalid operation mode");
1152 }
1153 }
1154
1155 private static String getOpmodeString(int opmode) {
1156 switch (opmode) {
1157 case ENCRYPT_MODE:
1158 return "encryption";
1159 case DECRYPT_MODE:
1160 return "decryption";
1161 case WRAP_MODE:
1162 return "key wrapping";
1163 case UNWRAP_MODE:
1164 return "key unwrapping";
1165 default:
1166 return "";
1167 }
1168 }
1169
1170 /**
1171 * Initializes this cipher with a key.
1172 *
1173 * <p>The cipher is initialized for one of the following four operations:
1174 * encryption, decryption, key wrapping or key unwrapping, depending
1175 * on the value of {@code opmode}.
1176 *
1177 * <p>If this cipher requires any algorithm parameters that cannot be
1178 * derived from the given {@code key}, the underlying cipher
1179 * implementation is supposed to generate the required parameters itself
1180 * (using provider-specific default or random values) if it is being
1181 * initialized for encryption or key wrapping, and raise an
1182 * {@code InvalidKeyException} if it is being
1183 * initialized for decryption or key unwrapping.
1184 * The generated parameters can be retrieved using
1185 * {@link #getParameters() getParameters} or
1186 * {@link #getIV() getIV} (if the parameter is an IV).
1187 *
1188 * <p>If this cipher requires algorithm parameters that cannot be
1189 * derived from the input parameters, and there are no reasonable
1190 * provider-specific default values, initialization will
1191 * necessarily fail.
1192 *
1193 * <p>If this cipher (including its underlying feedback or padding scheme)
1194 * requires any random bytes (e.g., for parameter generation), it will get
1195 * them using the {@link java.security.SecureRandom}
1196 * implementation of the highest-priority
1197 * installed provider as the source of randomness.
1198 * (If none of the installed providers supply an implementation of
1199 * SecureRandom, a system-provided source of randomness will be used.)
1200 *
1201 * <p>Note that when a Cipher object is initialized, it loses all
1202 * previously-acquired state. In other words, initializing a Cipher is
1203 * equivalent to creating a new instance of that Cipher and initializing
1204 * it.
1205 *
1206 * @param opmode the operation mode of this cipher (this is one of
1207 * the following:
1208 * {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},
1209 * {@code WRAP_MODE} or {@code UNWRAP_MODE})
1210 * @param key the key
1211 *
1212 * @exception InvalidKeyException if the given key is inappropriate for
1213 * initializing this cipher, or requires
1214 * algorithm parameters that cannot be
1215 * determined from the given key, or if the given key has a keysize that
1216 * exceeds the maximum allowable keysize (as determined from the
1217 * configured jurisdiction policy files).
1218 * @throws UnsupportedOperationException if {@code opmode} is
1219 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1220 * by the underlying {@code CipherSpi}.
1221 */
1222 public final void init(int opmode, Key key) throws InvalidKeyException {
1223 init(opmode, key, JceSecurity.RANDOM);
1224 }
1225
1226 /**
1227 * Initializes this cipher with a key and a source of randomness.
1228 *
1229 * <p>The cipher is initialized for one of the following four operations:
1230 * encryption, decryption, key wrapping or key unwrapping, depending
1231 * on the value of {@code opmode}.
1232 *
1233 * <p>If this cipher requires any algorithm parameters that cannot be
1234 * derived from the given {@code key}, the underlying cipher
1235 * implementation is supposed to generate the required parameters itself
1236 * (using provider-specific default or random values) if it is being
1237 * initialized for encryption or key wrapping, and raise an
1238 * {@code InvalidKeyException} if it is being
1239 * initialized for decryption or key unwrapping.
1240 * The generated parameters can be retrieved using
1241 * {@link #getParameters() getParameters} or
1242 * {@link #getIV() getIV} (if the parameter is an IV).
1243 *
1244 * <p>If this cipher requires algorithm parameters that cannot be
1245 * derived from the input parameters, and there are no reasonable
1246 * provider-specific default values, initialization will
1247 * necessarily fail.
1248 *
1249 * <p>If this cipher (including its underlying feedback or padding scheme)
1250 * requires any random bytes (e.g., for parameter generation), it will get
1251 * them from {@code random}.
1252 *
1253 * <p>Note that when a Cipher object is initialized, it loses all
1254 * previously-acquired state. In other words, initializing a Cipher is
1255 * equivalent to creating a new instance of that Cipher and initializing
1256 * it.
1257 *
1258 * @param opmode the operation mode of this cipher (this is one of the
1259 * following:
1260 * {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},
1261 * {@code WRAP_MODE} or {@code UNWRAP_MODE})
1262 * @param key the encryption key
1263 * @param random the source of randomness
1264 *
1265 * @exception InvalidKeyException if the given key is inappropriate for
1266 * initializing this cipher, or requires
1267 * algorithm parameters that cannot be
1268 * determined from the given key, or if the given key has a keysize that
1269 * exceeds the maximum allowable keysize (as determined from the
1270 * configured jurisdiction policy files).
1271 * @throws UnsupportedOperationException if {@code opmode} is
1272 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1273 * by the underlying {@code CipherSpi}.
1274 */
1275 public final void init(int opmode, Key key, SecureRandom random)
1276 throws InvalidKeyException
1277 {
1278 initialized = false;
1279 checkOpmode(opmode);
1280
1281 if (spi != null) {
1282 checkCryptoPerm(spi, key);
1283 spi.engineInit(opmode, key, random);
1284 } else {
1285 try {
1286 chooseProvider(I_KEY, opmode, key, null, null, random);
1287 } catch (InvalidAlgorithmParameterException e) {
1288 // should never occur
1289 throw new InvalidKeyException(e);
1290 }
1291 }
1292
1293 initialized = true;
1294 this.opmode = opmode;
1295
1296 if (!skipDebug && pdebug != null) {
1297 pdebug.println("Cipher." + transformation + " " +
1298 getOpmodeString(opmode) + " algorithm from: " +
1299 getProviderName());
1300 }
1301 }
1302
1303 /**
1304 * Initializes this cipher with a key and a set of algorithm
1305 * parameters.
1306 *
1307 * <p>The cipher is initialized for one of the following four operations:
1308 * encryption, decryption, key wrapping or key unwrapping, depending
1309 * on the value of {@code opmode}.
1310 *
1311 * <p>If this cipher requires any algorithm parameters and
1312 * {@code params} is null, the underlying cipher implementation is
1313 * supposed to generate the required parameters itself (using
1314 * provider-specific default or random values) if it is being
1315 * initialized for encryption or key wrapping, and raise an
1316 * {@code InvalidAlgorithmParameterException} if it is being
1317 * initialized for decryption or key unwrapping.
1318 * The generated parameters can be retrieved using
1319 * {@link #getParameters() getParameters} or
1320 * {@link #getIV() getIV} (if the parameter is an IV).
1321 *
1322 * <p>If this cipher requires algorithm parameters that cannot be
1323 * derived from the input parameters, and there are no reasonable
1324 * provider-specific default values, initialization will
1325 * necessarily fail.
1326 *
1327 * <p>If this cipher (including its underlying feedback or padding scheme)
1328 * requires any random bytes (e.g., for parameter generation), it will get
1329 * them using the {@link java.security.SecureRandom}
1330 * implementation of the highest-priority
1331 * installed provider as the source of randomness.
1332 * (If none of the installed providers supply an implementation of
1333 * SecureRandom, a system-provided source of randomness will be used.)
1334 *
1335 * <p>Note that when a Cipher object is initialized, it loses all
1336 * previously-acquired state. In other words, initializing a Cipher is
1337 * equivalent to creating a new instance of that Cipher and initializing
1338 * it.
1339 *
1340 * @param opmode the operation mode of this cipher (this is one of the
1341 * following:
1342 * {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},
1343 * {@code WRAP_MODE} or {@code UNWRAP_MODE})
1344 * @param key the encryption key
1345 * @param params the algorithm parameters
1346 *
1347 * @exception InvalidKeyException if the given key is inappropriate for
1348 * initializing this cipher, or its keysize exceeds the maximum allowable
1349 * keysize (as determined from the configured jurisdiction policy files).
1350 * @exception InvalidAlgorithmParameterException if the given algorithm
1351 * parameters are inappropriate for this cipher,
1352 * or this cipher requires
1353 * algorithm parameters and {@code params} is null, or the given
1354 * algorithm parameters imply a cryptographic strength that would exceed
1355 * the legal limits (as determined from the configured jurisdiction
1356 * policy files).
1357 * @throws UnsupportedOperationException if {@code opmode} is
1358 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1359 * by the underlying {@code CipherSpi}.
1360 */
1361 public final void init(int opmode, Key key, AlgorithmParameterSpec params)
1362 throws InvalidKeyException, InvalidAlgorithmParameterException
1363 {
1364 init(opmode, key, params, JceSecurity.RANDOM);
1365 }
1366
1367 /**
1368 * Initializes this cipher with a key, a set of algorithm
1369 * parameters, and a source of randomness.
1370 *
1371 * <p>The cipher is initialized for one of the following four operations:
1372 * encryption, decryption, key wrapping or key unwrapping, depending
1373 * on the value of {@code opmode}.
1374 *
1375 * <p>If this cipher requires any algorithm parameters and
1376 * {@code params} is null, the underlying cipher implementation is
1377 * supposed to generate the required parameters itself (using
1378 * provider-specific default or random values) if it is being
1379 * initialized for encryption or key wrapping, and raise an
1380 * {@code InvalidAlgorithmParameterException} if it is being
1381 * initialized for decryption or key unwrapping.
1382 * The generated parameters can be retrieved using
1383 * {@link #getParameters() getParameters} or
1384 * {@link #getIV() getIV} (if the parameter is an IV).
1385 *
1386 * <p>If this cipher requires algorithm parameters that cannot be
1387 * derived from the input parameters, and there are no reasonable
1388 * provider-specific default values, initialization will
1389 * necessarily fail.
1390 *
1391 * <p>If this cipher (including its underlying feedback or padding scheme)
1392 * requires any random bytes (e.g., for parameter generation), it will get
1393 * them from {@code random}.
1394 *
1395 * <p>Note that when a Cipher object is initialized, it loses all
1396 * previously-acquired state. In other words, initializing a Cipher is
1397 * equivalent to creating a new instance of that Cipher and initializing
1398 * it.
1399 *
1400 * @param opmode the operation mode of this cipher (this is one of the
1401 * following:
1402 * {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},
1403 * {@code WRAP_MODE} or {@code UNWRAP_MODE})
1404 * @param key the encryption key
1405 * @param params the algorithm parameters
1406 * @param random the source of randomness
1407 *
1408 * @exception InvalidKeyException if the given key is inappropriate for
1409 * initializing this cipher, or its keysize exceeds the maximum allowable
1410 * keysize (as determined from the configured jurisdiction policy files).
1411 * @exception InvalidAlgorithmParameterException if the given algorithm
1412 * parameters are inappropriate for this cipher,
1413 * or this cipher requires
1414 * algorithm parameters and {@code params} is null, or the given
1415 * algorithm parameters imply a cryptographic strength that would exceed
1416 * the legal limits (as determined from the configured jurisdiction
1417 * policy files).
1418 * @throws UnsupportedOperationException if {@code opmode} is
1419 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1420 * by the underlying {@code CipherSpi}.
1421 */
1422 public final void init(int opmode, Key key, AlgorithmParameterSpec params,
1423 SecureRandom random)
1424 throws InvalidKeyException, InvalidAlgorithmParameterException
1425 {
1426 initialized = false;
1427 checkOpmode(opmode);
1428
1429 if (spi != null) {
1430 checkCryptoPerm(spi, key, params);
1431 spi.engineInit(opmode, key, params, random);
1432 } else {
1433 chooseProvider(I_PARAMSPEC, opmode, key, params, null, random);
1434 }
1435
1436 initialized = true;
1437 this.opmode = opmode;
1438
1439 if (!skipDebug && pdebug != null) {
1440 pdebug.println("Cipher." + transformation + " " +
1441 getOpmodeString(opmode) + " algorithm from: " +
1442 getProviderName());
1443 }
1444 }
1445
1446 /**
1447 * Initializes this cipher with a key and a set of algorithm
1448 * parameters.
1449 *
1450 * <p>The cipher is initialized for one of the following four operations:
1451 * encryption, decryption, key wrapping or key unwrapping, depending
1452 * on the value of {@code opmode}.
1453 *
1454 * <p>If this cipher requires any algorithm parameters and
1455 * {@code params} is null, the underlying cipher implementation is
1456 * supposed to generate the required parameters itself (using
1457 * provider-specific default or random values) if it is being
1458 * initialized for encryption or key wrapping, and raise an
1459 * {@code InvalidAlgorithmParameterException} if it is being
1460 * initialized for decryption or key unwrapping.
1461 * The generated parameters can be retrieved using
1462 * {@link #getParameters() getParameters} or
1463 * {@link #getIV() getIV} (if the parameter is an IV).
1464 *
1465 * <p>If this cipher requires algorithm parameters that cannot be
1466 * derived from the input parameters, and there are no reasonable
1467 * provider-specific default values, initialization will
1468 * necessarily fail.
1469 *
1470 * <p>If this cipher (including its underlying feedback or padding scheme)
1471 * requires any random bytes (e.g., for parameter generation), it will get
1472 * them using the {@link java.security.SecureRandom}
1473 * implementation of the highest-priority
1474 * installed provider as the source of randomness.
1475 * (If none of the installed providers supply an implementation of
1476 * SecureRandom, a system-provided source of randomness will be used.)
1477 *
1478 * <p>Note that when a Cipher object is initialized, it loses all
1479 * previously-acquired state. In other words, initializing a Cipher is
1480 * equivalent to creating a new instance of that Cipher and initializing
1481 * it.
1482 *
1483 * @param opmode the operation mode of this cipher (this is one of the
1484 * following: {@code ENCRYPT_MODE},
1485 * {@code DECRYPT_MODE}, {@code WRAP_MODE}
1486 * or {@code UNWRAP_MODE})
1487 * @param key the encryption key
1488 * @param params the algorithm parameters
1489 *
1490 * @exception InvalidKeyException if the given key is inappropriate for
1491 * initializing this cipher, or its keysize exceeds the maximum allowable
1492 * keysize (as determined from the configured jurisdiction policy files).
1493 * @exception InvalidAlgorithmParameterException if the given algorithm
1494 * parameters are inappropriate for this cipher,
1495 * or this cipher requires
1496 * algorithm parameters and {@code params} is null, or the given
1497 * algorithm parameters imply a cryptographic strength that would exceed
1498 * the legal limits (as determined from the configured jurisdiction
1499 * policy files).
1500 * @throws UnsupportedOperationException if {@code opmode} is
1501 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1502 * by the underlying {@code CipherSpi}.
1503 */
1504 public final void init(int opmode, Key key, AlgorithmParameters params)
1505 throws InvalidKeyException, InvalidAlgorithmParameterException
1506 {
1507 init(opmode, key, params, JceSecurity.RANDOM);
1508 }
1509
1510 /**
1511 * Initializes this cipher with a key, a set of algorithm
1512 * parameters, and a source of randomness.
1513 *
1514 * <p>The cipher is initialized for one of the following four operations:
1515 * encryption, decryption, key wrapping or key unwrapping, depending
1516 * on the value of {@code opmode}.
1517 *
1518 * <p>If this cipher requires any algorithm parameters and
1519 * {@code params} is null, the underlying cipher implementation is
1520 * supposed to generate the required parameters itself (using
1521 * provider-specific default or random values) if it is being
1522 * initialized for encryption or key wrapping, and raise an
1523 * {@code InvalidAlgorithmParameterException} if it is being
1524 * initialized for decryption or key unwrapping.
1525 * The generated parameters can be retrieved using
1526 * {@link #getParameters() getParameters} or
1527 * {@link #getIV() getIV} (if the parameter is an IV).
1528 *
1529 * <p>If this cipher requires algorithm parameters that cannot be
1530 * derived from the input parameters, and there are no reasonable
1531 * provider-specific default values, initialization will
1532 * necessarily fail.
1533 *
1534 * <p>If this cipher (including its underlying feedback or padding scheme)
1535 * requires any random bytes (e.g., for parameter generation), it will get
1536 * them from {@code random}.
1537 *
1538 * <p>Note that when a Cipher object is initialized, it loses all
1539 * previously-acquired state. In other words, initializing a Cipher is
1540 * equivalent to creating a new instance of that Cipher and initializing
1541 * it.
1542 *
1543 * @param opmode the operation mode of this cipher (this is one of the
1544 * following: {@code ENCRYPT_MODE},
1545 * {@code DECRYPT_MODE}, {@code WRAP_MODE}
1546 * or {@code UNWRAP_MODE})
1547 * @param key the encryption key
1548 * @param params the algorithm parameters
1549 * @param random the source of randomness
1550 *
1551 * @exception InvalidKeyException if the given key is inappropriate for
1552 * initializing this cipher, or its keysize exceeds the maximum allowable
1553 * keysize (as determined from the configured jurisdiction policy files).
1554 * @exception InvalidAlgorithmParameterException if the given algorithm
1555 * parameters are inappropriate for this cipher,
1556 * or this cipher requires
1557 * algorithm parameters and {@code params} is null, or the given
1558 * algorithm parameters imply a cryptographic strength that would exceed
1559 * the legal limits (as determined from the configured jurisdiction
1560 * policy files).
1561 * @throws UnsupportedOperationException if {@code opmode} is
1562 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1563 * by the underlying {@code CipherSpi}.
1564 */
1565 public final void init(int opmode, Key key, AlgorithmParameters params,
1566 SecureRandom random)
1567 throws InvalidKeyException, InvalidAlgorithmParameterException
1568 {
1569 initialized = false;
1570 checkOpmode(opmode);
1571
1572 if (spi != null) {
1573 checkCryptoPerm(spi, key, params);
1574 spi.engineInit(opmode, key, params, random);
1575 } else {
1576 chooseProvider(I_PARAMS, opmode, key, null, params, random);
1577 }
1578
1579 initialized = true;
1580 this.opmode = opmode;
1581
1582 if (!skipDebug && pdebug != null) {
1583 pdebug.println("Cipher." + transformation + " " +
1584 getOpmodeString(opmode) + " algorithm from: " +
1585 getProviderName());
1586 }
1587 }
1588
1589 /**
1590 * Initializes this cipher with the public key from the given certificate.
1591 * <p> The cipher is initialized for one of the following four operations:
1592 * encryption, decryption, key wrapping or key unwrapping, depending
1593 * on the value of {@code opmode}.
1594 *
1595 * <p>If the certificate is of type X.509 and has a <i>key usage</i>
1596 * extension field marked as critical, and the value of the <i>key usage</i>
1597 * extension field implies that the public key in
1598 * the certificate and its corresponding private key are not
1599 * supposed to be used for the operation represented by the value
1600 * of {@code opmode},
1601 * an {@code InvalidKeyException}
1602 * is thrown.
1603 *
1604 * <p> If this cipher requires any algorithm parameters that cannot be
1605 * derived from the public key in the given certificate, the underlying
1606 * cipher
1607 * implementation is supposed to generate the required parameters itself
1608 * (using provider-specific default or random values) if it is being
1609 * initialized for encryption or key wrapping, and raise an
1610 * {@code InvalidKeyException} if it is being initialized for decryption or
1611 * key unwrapping.
1612 * The generated parameters can be retrieved using
1613 * {@link #getParameters() getParameters} or
1614 * {@link #getIV() getIV} (if the parameter is an IV).
1615 *
1616 * <p>If this cipher requires algorithm parameters that cannot be
1617 * derived from the input parameters, and there are no reasonable
1618 * provider-specific default values, initialization will
1619 * necessarily fail.
1620 *
1621 * <p>If this cipher (including its underlying feedback or padding scheme)
1622 * requires any random bytes (e.g., for parameter generation), it will get
1623 * them using the
1624 * {@code SecureRandom}
1625 * implementation of the highest-priority
1626 * installed provider as the source of randomness.
1627 * (If none of the installed providers supply an implementation of
1628 * SecureRandom, a system-provided source of randomness will be used.)
1629 *
1630 * <p>Note that when a Cipher object is initialized, it loses all
1631 * previously-acquired state. In other words, initializing a Cipher is
1632 * equivalent to creating a new instance of that Cipher and initializing
1633 * it.
1634 *
1635 * @param opmode the operation mode of this cipher (this is one of the
1636 * following:
1637 * {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},
1638 * {@code WRAP_MODE} or {@code UNWRAP_MODE})
1639 * @param certificate the certificate
1640 *
1641 * @exception InvalidKeyException if the public key in the given
1642 * certificate is inappropriate for initializing this cipher, or this
1643 * cipher requires algorithm parameters that cannot be determined from the
1644 * public key in the given certificate, or the keysize of the public key
1645 * in the given certificate has a keysize that exceeds the maximum
1646 * allowable keysize (as determined by the configured jurisdiction policy
1647 * files).
1648 * @throws UnsupportedOperationException if {@code opmode} is
1649 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1650 * by the underlying {@code CipherSpi}.
1651 */
1652 public final void init(int opmode, Certificate certificate)
1653 throws InvalidKeyException
1654 {
1655 init(opmode, certificate, JceSecurity.RANDOM);
1656 }
1657
1658 /**
1659 * Initializes this cipher with the public key from the given certificate
1660 * and
1661 * a source of randomness.
1662 *
1663 * <p>The cipher is initialized for one of the following four operations:
1664 * encryption, decryption, key wrapping
1665 * or key unwrapping, depending on
1666 * the value of {@code opmode}.
1667 *
1668 * <p>If the certificate is of type X.509 and has a <i>key usage</i>
1669 * extension field marked as critical, and the value of the <i>key usage</i>
1670 * extension field implies that the public key in
1671 * the certificate and its corresponding private key are not
1672 * supposed to be used for the operation represented by the value of
1673 * {@code opmode},
1674 * an {@code InvalidKeyException}
1675 * is thrown.
1676 *
1677 * <p>If this cipher requires any algorithm parameters that cannot be
1678 * derived from the public key in the given {@code certificate},
1679 * the underlying cipher
1680 * implementation is supposed to generate the required parameters itself
1681 * (using provider-specific default or random values) if it is being
1682 * initialized for encryption or key wrapping, and raise an
1683 * {@code InvalidKeyException} if it is being
1684 * initialized for decryption or key unwrapping.
1685 * The generated parameters can be retrieved using
1686 * {@link #getParameters() getParameters} or
1687 * {@link #getIV() getIV} (if the parameter is an IV).
1688 *
1689 * <p>If this cipher requires algorithm parameters that cannot be
1690 * derived from the input parameters, and there are no reasonable
1691 * provider-specific default values, initialization will
1692 * necessarily fail.
1693 *
1694 * <p>If this cipher (including its underlying feedback or padding scheme)
1695 * requires any random bytes (e.g., for parameter generation), it will get
1696 * them from {@code random}.
1697 *
1698 * <p>Note that when a Cipher object is initialized, it loses all
1699 * previously-acquired state. In other words, initializing a Cipher is
1700 * equivalent to creating a new instance of that Cipher and initializing
1701 * it.
1702 *
1703 * @param opmode the operation mode of this cipher (this is one of the
1704 * following:
1705 * {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},
1706 * {@code WRAP_MODE} or {@code UNWRAP_MODE})
1707 * @param certificate the certificate
1708 * @param random the source of randomness
1709 *
1710 * @exception InvalidKeyException if the public key in the given
1711 * certificate is inappropriate for initializing this cipher, or this
1712 * cipher
1713 * requires algorithm parameters that cannot be determined from the
1714 * public key in the given certificate, or the keysize of the public key
1715 * in the given certificate has a keysize that exceeds the maximum
1716 * allowable keysize (as determined by the configured jurisdiction policy
1717 * files).
1718 * @throws UnsupportedOperationException if {@code opmode} is
1719 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1720 * by the underlying {@code CipherSpi}.
1721 */
1722 public final void init(int opmode, Certificate certificate,
1723 SecureRandom random)
1724 throws InvalidKeyException
1725 {
1726 initialized = false;
1727 checkOpmode(opmode);
1728
1729 // Check key usage if the certificate is of
1730 // type X.509.
1731 if (certificate instanceof java.security.cert.X509Certificate) {
1732 // Check whether the cert has a key usage extension
1733 // marked as a critical extension.
1734 X509Certificate cert = (X509Certificate)certificate;
1735 Set<String> critSet = cert.getCriticalExtensionOIDs();
1736
1737 if (critSet != null && !critSet.isEmpty()
1738 && critSet.contains(KEY_USAGE_EXTENSION_OID)) {
1739 boolean[] keyUsageInfo = cert.getKeyUsage();
1740 // keyUsageInfo[2] is for keyEncipherment;
1741 // keyUsageInfo[3] is for dataEncipherment.
1742 if ((keyUsageInfo != null) &&
1743 (((opmode == Cipher.ENCRYPT_MODE) &&
1744 (keyUsageInfo.length > 3) &&
1745 (keyUsageInfo[3] == false)) ||
1746 ((opmode == Cipher.WRAP_MODE) &&
1747 (keyUsageInfo.length > 2) &&
1748 (keyUsageInfo[2] == false)))) {
1749 throw new InvalidKeyException("Wrong key usage");
1750 }
1751 }
1752 }
1753
1754 PublicKey publicKey =
1755 (certificate==null? null:certificate.getPublicKey());
1756
1757 if (spi != null) {
1758 checkCryptoPerm(spi, publicKey);
1759 spi.engineInit(opmode, publicKey, random);
1760 } else {
1761 try {
1762 chooseProvider(I_CERT, opmode, publicKey, null, null, random);
1763 } catch (InvalidAlgorithmParameterException e) {
1764 // should never occur
1765 throw new InvalidKeyException(e);
1766 }
1767 }
1768
1769 initialized = true;
1770 this.opmode = opmode;
1771
1772 if (!skipDebug && pdebug != null) {
1773 pdebug.println("Cipher." + transformation + " " +
1774 getOpmodeString(opmode) + " algorithm from: " +
1775 getProviderName());
1776 }
1777 }
1778
1779 /**
1780 * Ensures that Cipher is in a valid state for update() and doFinal()
1781 * calls - should be initialized and in ENCRYPT_MODE or DECRYPT_MODE.
1782 * @throws IllegalStateException if Cipher object is not in valid state.
1783 */
1784 private void checkCipherState() {
1785 if (!(this instanceof NullCipher)) {
1786 if (!initialized) {
1787 throw new IllegalStateException("Cipher not initialized");
1788 }
1789 if ((opmode != Cipher.ENCRYPT_MODE) &&
1790 (opmode != Cipher.DECRYPT_MODE)) {
1791 throw new IllegalStateException("Cipher not initialized " +
1792 "for encryption/decryption");
1793 }
1794 }
1795 }
1796
1797 /**
1798 * Continues a multiple-part encryption or decryption operation
1799 * (depending on how this cipher was initialized), processing another data
1800 * part.
1801 *
1802 * <p>The bytes in the {@code input} buffer are processed, and the
1803 * result is stored in a new buffer.
1804 *
1805 * <p>If {@code input} has a length of zero, this method returns
1806 * {@code null}.
1807 *
1808 * @param input the input buffer
1809 *
1810 * @return the new buffer with the result, or null if the underlying
1811 * cipher is a block cipher and the input data is too short to result in a
1812 * new block.
1813 *
1814 * @exception IllegalStateException if this cipher is in a wrong state
1815 * (e.g., has not been initialized)
1816 */
1817 public final byte[] update(byte[] input) {
1818 checkCipherState();
1819
1820 // Input sanity check
1821 if (input == null) {
1822 throw new IllegalArgumentException("Null input buffer");
1823 }
1824
1825 chooseFirstProvider();
1826 if (input.length == 0) {
1827 return null;
1828 }
1829 return spi.engineUpdate(input, 0, input.length);
1830 }
1831
1832 /**
1833 * Continues a multiple-part encryption or decryption operation
1834 * (depending on how this cipher was initialized), processing another data
1835 * part.
1836 *
1837 * <p>The first {@code inputLen} bytes in the {@code input}
1838 * buffer, starting at {@code inputOffset} inclusive, are processed,
1839 * and the result is stored in a new buffer.
1840 *
1841 * <p>If {@code inputLen} is zero, this method returns
1842 * {@code null}.
1843 *
1844 * @param input the input buffer
1845 * @param inputOffset the offset in {@code input} where the input
1846 * starts
1847 * @param inputLen the input length
1848 *
1849 * @return the new buffer with the result, or null if the underlying
1850 * cipher is a block cipher and the input data is too short to result in a
1851 * new block.
1852 *
1853 * @exception IllegalStateException if this cipher is in a wrong state
1854 * (e.g., has not been initialized)
1855 */
1856 public final byte[] update(byte[] input, int inputOffset, int inputLen) {
1857 checkCipherState();
1858
1859 // Input sanity check
1860 if (input == null || inputOffset < 0
1861 || inputLen > (input.length - inputOffset) || inputLen < 0) {
1862 throw new IllegalArgumentException("Bad arguments");
1863 }
1864
1865 chooseFirstProvider();
1866 if (inputLen == 0) {
1867 return null;
1868 }
1869 return spi.engineUpdate(input, inputOffset, inputLen);
1870 }
1871
1872 /**
1873 * Continues a multiple-part encryption or decryption operation
1874 * (depending on how this cipher was initialized), processing another data
1875 * part.
1876 *
1877 * <p>The first {@code inputLen} bytes in the {@code input}
1878 * buffer, starting at {@code inputOffset} inclusive, are processed,
1879 * and the result is stored in the {@code output} buffer.
1880 *
1881 * <p>If the {@code output} buffer is too small to hold the result,
1882 * a {@code ShortBufferException} is thrown. In this case, repeat this
1883 * call with a larger output buffer. Use
1884 * {@link #getOutputSize(int) getOutputSize} to determine how big
1885 * the output buffer should be.
1886 *
1887 * <p>If {@code inputLen} is zero, this method returns
1888 * a length of zero.
1889 *
1890 * <p>Note: this method should be copy-safe, which means the
1891 * {@code input} and {@code output} buffers can reference
1892 * the same byte array and no unprocessed input data is overwritten
1893 * when the result is copied into the output buffer.
1894 *
1895 * @param input the input buffer
1896 * @param inputOffset the offset in {@code input} where the input
1897 * starts
1898 * @param inputLen the input length
1899 * @param output the buffer for the result
1900 *
1901 * @return the number of bytes stored in {@code output}
1902 *
1903 * @exception IllegalStateException if this cipher is in a wrong state
1904 * (e.g., has not been initialized)
1905 * @exception ShortBufferException if the given output buffer is too small
1906 * to hold the result
1907 */
1908 public final int update(byte[] input, int inputOffset, int inputLen,
1909 byte[] output)
1910 throws ShortBufferException {
1911 checkCipherState();
1912
1913 // Input sanity check
1914 if (input == null || inputOffset < 0
1915 || inputLen > (input.length - inputOffset) || inputLen < 0) {
1916 throw new IllegalArgumentException("Bad arguments");
1917 }
1918
1919 chooseFirstProvider();
1920 if (inputLen == 0) {
1921 return 0;
1922 }
1923 return spi.engineUpdate(input, inputOffset, inputLen,
1924 output, 0);
1925 }
1926
1927 /**
1928 * Continues a multiple-part encryption or decryption operation
1929 * (depending on how this cipher was initialized), processing another data
1930 * part.
1931 *
1932 * <p>The first {@code inputLen} bytes in the {@code input}
1933 * buffer, starting at {@code inputOffset} inclusive, are processed,
1934 * and the result is stored in the {@code output} buffer, starting at
1935 * {@code outputOffset} inclusive.
1936 *
1937 * <p>If the {@code output} buffer is too small to hold the result,
1938 * a {@code ShortBufferException} is thrown. In this case, repeat this
1939 * call with a larger output buffer. Use
1940 * {@link #getOutputSize(int) getOutputSize} to determine how big
1941 * the output buffer should be.
1942 *
1943 * <p>If {@code inputLen} is zero, this method returns
1944 * a length of zero.
1945 *
1946 * <p>Note: this method should be copy-safe, which means the
1947 * {@code input} and {@code output} buffers can reference
1948 * the same byte array and no unprocessed input data is overwritten
1949 * when the result is copied into the output buffer.
1950 *
1951 * @param input the input buffer
1952 * @param inputOffset the offset in {@code input} where the input
1953 * starts
1954 * @param inputLen the input length
1955 * @param output the buffer for the result
1956 * @param outputOffset the offset in {@code output} where the result
1957 * is stored
1958 *
1959 * @return the number of bytes stored in {@code output}
1960 *
1961 * @exception IllegalStateException if this cipher is in a wrong state
1962 * (e.g., has not been initialized)
1963 * @exception ShortBufferException if the given output buffer is too small
1964 * to hold the result
1965 */
1966 public final int update(byte[] input, int inputOffset, int inputLen,
1967 byte[] output, int outputOffset)
1968 throws ShortBufferException {
1969 checkCipherState();
1970
1971 // Input sanity check
1972 if (input == null || inputOffset < 0
1973 || inputLen > (input.length - inputOffset) || inputLen < 0
1974 || outputOffset < 0) {
1975 throw new IllegalArgumentException("Bad arguments");
1976 }
1977
1978 chooseFirstProvider();
1979 if (inputLen == 0) {
1980 return 0;
1981 }
1982 return spi.engineUpdate(input, inputOffset, inputLen,
1983 output, outputOffset);
1984 }
1985
1986 /**
1987 * Continues a multiple-part encryption or decryption operation
1988 * (depending on how this cipher was initialized), processing another data
1989 * part.
1990 *
1991 * <p>All {@code input.remaining()} bytes starting at
1992 * {@code input.position()} are processed. The result is stored
1993 * in the output buffer.
1994 * Upon return, the input buffer's position will be equal
1995 * to its limit; its limit will not have changed. The output buffer's
1996 * position will have advanced by n, where n is the value returned
1997 * by this method; the output buffer's limit will not have changed.
1998 *
1999 * <p>If {@code output.remaining()} bytes are insufficient to
2000 * hold the result, a {@code ShortBufferException} is thrown.
2001 * In this case, repeat this call with a larger output buffer. Use
2002 * {@link #getOutputSize(int) getOutputSize} to determine how big
2003 * the output buffer should be.
2004 *
2005 * <p>Note: this method should be copy-safe, which means the
2006 * {@code input} and {@code output} buffers can reference
2007 * the same block of memory and no unprocessed input data is overwritten
2008 * when the result is copied into the output buffer.
2009 *
2010 * @param input the input ByteBuffer
2011 * @param output the output ByteByffer
2012 *
2013 * @return the number of bytes stored in {@code output}
2014 *
2015 * @exception IllegalStateException if this cipher is in a wrong state
2016 * (e.g., has not been initialized)
2017 * @exception IllegalArgumentException if input and output are the
2018 * same object
2019 * @exception ReadOnlyBufferException if the output buffer is read-only
2020 * @exception ShortBufferException if there is insufficient space in the
2021 * output buffer
2022 * @since 1.5
2023 */
2024 public final int update(ByteBuffer input, ByteBuffer output)
2025 throws ShortBufferException {
2026 checkCipherState();
2027
2028 if ((input == null) || (output == null)) {
2029 throw new IllegalArgumentException("Buffers must not be null");
2030 }
2031 if (input == output) {
2032 throw new IllegalArgumentException("Input and output buffers must "
2033 + "not be the same object, consider using buffer.duplicate()");
2034 }
2035 if (output.isReadOnly()) {
2036 throw new ReadOnlyBufferException();
2037 }
2038
2039 chooseFirstProvider();
2040 return spi.engineUpdate(input, output);
2041 }
2042
2043 /**
2044 * Finishes a multiple-part encryption or decryption operation, depending
2045 * on how this cipher was initialized.
2046 *
2047 * <p>Input data that may have been buffered during a previous
2048 * {@code update} operation is processed, with padding (if requested)
2049 * being applied.
2050 * If an AEAD mode such as GCM/CCM is being used, the authentication
2051 * tag is appended in the case of encryption, or verified in the
2052 * case of decryption.
2053 * The result is stored in a new buffer.
2054 *
2055 * <p>Upon finishing, this method resets this cipher object to the state
2056 * it was in when previously initialized via a call to {@code init}.
2057 * That is, the object is reset and available to encrypt or decrypt
2058 * (depending on the operation mode that was specified in the call to
2059 * {@code init}) more data.
2060 *
2061 * <p>Note: if any exception is thrown, this cipher object may need to
2062 * be reset before it can be used again.
2063 *
2064 * @return the new buffer with the result
2065 *
2066 * @exception IllegalStateException if this cipher is in a wrong state
2067 * (e.g., has not been initialized)
2068 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2069 * no padding has been requested (only in encryption mode), and the total
2070 * input length of the data processed by this cipher is not a multiple of
2071 * block size; or if this encryption algorithm is unable to
2072 * process the input data provided.
2073 * @exception BadPaddingException if this cipher is in decryption mode,
2074 * and (un)padding has been requested, but the decrypted data is not
2075 * bounded by the appropriate padding bytes
2076 * @exception AEADBadTagException if this cipher is decrypting in an
2077 * AEAD mode (such as GCM/CCM), and the received authentication tag
2078 * does not match the calculated value
2079 */
2080 public final byte[] doFinal()
2081 throws IllegalBlockSizeException, BadPaddingException {
2082 checkCipherState();
2083
2084 chooseFirstProvider();
2085 return spi.engineDoFinal(null, 0, 0);
2086 }
2087
2088 /**
2089 * Finishes a multiple-part encryption or decryption operation, depending
2090 * on how this cipher was initialized.
2091 *
2092 * <p>Input data that may have been buffered during a previous
2093 * {@code update} operation is processed, with padding (if requested)
2094 * being applied.
2095 * If an AEAD mode such as GCM/CCM is being used, the authentication
2096 * tag is appended in the case of encryption, or verified in the
2097 * case of decryption.
2098 * The result is stored in the {@code output} buffer, starting at
2099 * {@code outputOffset} inclusive.
2100 *
2101 * <p>If the {@code output} buffer is too small to hold the result,
2102 * a {@code ShortBufferException} is thrown. In this case, repeat this
2103 * call with a larger output buffer. Use
2104 * {@link #getOutputSize(int) getOutputSize} to determine how big
2105 * the output buffer should be.
2106 *
2107 * <p>Upon finishing, this method resets this cipher object to the state
2108 * it was in when previously initialized via a call to {@code init}.
2109 * That is, the object is reset and available to encrypt or decrypt
2110 * (depending on the operation mode that was specified in the call to
2111 * {@code init}) more data.
2112 *
2113 * <p>Note: if any exception is thrown, this cipher object may need to
2114 * be reset before it can be used again.
2115 *
2116 * @param output the buffer for the result
2117 * @param outputOffset the offset in {@code output} where the result
2118 * is stored
2119 *
2120 * @return the number of bytes stored in {@code output}
2121 *
2122 * @exception IllegalStateException if this cipher is in a wrong state
2123 * (e.g., has not been initialized)
2124 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2125 * no padding has been requested (only in encryption mode), and the total
2126 * input length of the data processed by this cipher is not a multiple of
2127 * block size; or if this encryption algorithm is unable to
2128 * process the input data provided.
2129 * @exception ShortBufferException if the given output buffer is too small
2130 * to hold the result
2131 * @exception BadPaddingException if this cipher is in decryption mode,
2132 * and (un)padding has been requested, but the decrypted data is not
2133 * bounded by the appropriate padding bytes
2134 * @exception AEADBadTagException if this cipher is decrypting in an
2135 * AEAD mode (such as GCM/CCM), and the received authentication tag
2136 * does not match the calculated value
2137 */
2138 public final int doFinal(byte[] output, int outputOffset)
2139 throws IllegalBlockSizeException, ShortBufferException,
2140 BadPaddingException {
2141 checkCipherState();
2142
2143 // Input sanity check
2144 if ((output == null) || (outputOffset < 0)) {
2145 throw new IllegalArgumentException("Bad arguments");
2146 }
2147
2148 chooseFirstProvider();
2149 return spi.engineDoFinal(null, 0, 0, output, outputOffset);
2150 }
2151
2152 /**
2153 * Encrypts or decrypts data in a single-part operation, or finishes a
2154 * multiple-part operation. The data is encrypted or decrypted,
2155 * depending on how this cipher was initialized.
2156 *
2157 * <p>The bytes in the {@code input} buffer, and any input bytes that
2158 * may have been buffered during a previous {@code update} operation,
2159 * are processed, with padding (if requested) being applied.
2160 * If an AEAD mode such as GCM/CCM is being used, the authentication
2161 * tag is appended in the case of encryption, or verified in the
2162 * case of decryption.
2163 * The result is stored in a new buffer.
2164 *
2165 * <p>Upon finishing, this method resets this cipher object to the state
2166 * it was in when previously initialized via a call to {@code init}.
2167 * That is, the object is reset and available to encrypt or decrypt
2168 * (depending on the operation mode that was specified in the call to
2169 * {@code init}) more data.
2170 *
2171 * <p>Note: if any exception is thrown, this cipher object may need to
2172 * be reset before it can be used again.
2173 *
2174 * @param input the input buffer
2175 *
2176 * @return the new buffer with the result
2177 *
2178 * @exception IllegalStateException if this cipher is in a wrong state
2179 * (e.g., has not been initialized)
2180 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2181 * no padding has been requested (only in encryption mode), and the total
2182 * input length of the data processed by this cipher is not a multiple of
2183 * block size; or if this encryption algorithm is unable to
2184 * process the input data provided.
2185 * @exception BadPaddingException if this cipher is in decryption mode,
2186 * and (un)padding has been requested, but the decrypted data is not
2187 * bounded by the appropriate padding bytes
2188 * @exception AEADBadTagException if this cipher is decrypting in an
2189 * AEAD mode (such as GCM/CCM), and the received authentication tag
2190 * does not match the calculated value
2191 */
2192 public final byte[] doFinal(byte[] input)
2193 throws IllegalBlockSizeException, BadPaddingException {
2194 checkCipherState();
2195
2196 // Input sanity check
2197 if (input == null) {
2198 throw new IllegalArgumentException("Null input buffer");
2199 }
2200
2201 chooseFirstProvider();
2202 return spi.engineDoFinal(input, 0, input.length);
2203 }
2204
2205 /**
2206 * Encrypts or decrypts data in a single-part operation, or finishes a
2207 * multiple-part operation. The data is encrypted or decrypted,
2208 * depending on how this cipher was initialized.
2209 *
2210 * <p>The first {@code inputLen} bytes in the {@code input}
2211 * buffer, starting at {@code inputOffset} inclusive, and any input
2212 * bytes that may have been buffered during a previous {@code update}
2213 * operation, are processed, with padding (if requested) being applied.
2214 * If an AEAD mode such as GCM/CCM is being used, the authentication
2215 * tag is appended in the case of encryption, or verified in the
2216 * case of decryption.
2217 * The result is stored in a new buffer.
2218 *
2219 * <p>Upon finishing, this method resets this cipher object to the state
2220 * it was in when previously initialized via a call to {@code init}.
2221 * That is, the object is reset and available to encrypt or decrypt
2222 * (depending on the operation mode that was specified in the call to
2223 * {@code init}) more data.
2224 *
2225 * <p>Note: if any exception is thrown, this cipher object may need to
2226 * be reset before it can be used again.
2227 *
2228 * @param input the input buffer
2229 * @param inputOffset the offset in {@code input} where the input
2230 * starts
2231 * @param inputLen the input length
2232 *
2233 * @return the new buffer with the result
2234 *
2235 * @exception IllegalStateException if this cipher is in a wrong state
2236 * (e.g., has not been initialized)
2237 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2238 * no padding has been requested (only in encryption mode), and the total
2239 * input length of the data processed by this cipher is not a multiple of
2240 * block size; or if this encryption algorithm is unable to
2241 * process the input data provided.
2242 * @exception BadPaddingException if this cipher is in decryption mode,
2243 * and (un)padding has been requested, but the decrypted data is not
2244 * bounded by the appropriate padding bytes
2245 * @exception AEADBadTagException if this cipher is decrypting in an
2246 * AEAD mode (such as GCM/CCM), and the received authentication tag
2247 * does not match the calculated value
2248 */
2249 public final byte[] doFinal(byte[] input, int inputOffset, int inputLen)
2250 throws IllegalBlockSizeException, BadPaddingException {
2251 checkCipherState();
2252
2253 // Input sanity check
2254 if (input == null || inputOffset < 0
2255 || inputLen > (input.length - inputOffset) || inputLen < 0) {
2256 throw new IllegalArgumentException("Bad arguments");
2257 }
2258
2259 chooseFirstProvider();
2260 return spi.engineDoFinal(input, inputOffset, inputLen);
2261 }
2262
2263 /**
2264 * Encrypts or decrypts data in a single-part operation, or finishes a
2265 * multiple-part operation. The data is encrypted or decrypted,
2266 * depending on how this cipher was initialized.
2267 *
2268 * <p>The first {@code inputLen} bytes in the {@code input}
2269 * buffer, starting at {@code inputOffset} inclusive, and any input
2270 * bytes that may have been buffered during a previous {@code update}
2271 * operation, are processed, with padding (if requested) being applied.
2272 * If an AEAD mode such as GCM/CCM is being used, the authentication
2273 * tag is appended in the case of encryption, or verified in the
2274 * case of decryption.
2275 * The result is stored in the {@code output} buffer.
2276 *
2277 * <p>If the {@code output} buffer is too small to hold the result,
2278 * a {@code ShortBufferException} is thrown. In this case, repeat this
2279 * call with a larger output buffer. Use
2280 * {@link #getOutputSize(int) getOutputSize} to determine how big
2281 * the output buffer should be.
2282 *
2283 * <p>Upon finishing, this method resets this cipher object to the state
2284 * it was in when previously initialized via a call to {@code init}.
2285 * That is, the object is reset and available to encrypt or decrypt
2286 * (depending on the operation mode that was specified in the call to
2287 * {@code init}) more data.
2288 *
2289 * <p>Note: if any exception is thrown, this cipher object may need to
2290 * be reset before it can be used again.
2291 *
2292 * <p>Note: this method should be copy-safe, which means the
2293 * {@code input} and {@code output} buffers can reference
2294 * the same byte array and no unprocessed input data is overwritten
2295 * when the result is copied into the output buffer.
2296 *
2297 * @param input the input buffer
2298 * @param inputOffset the offset in {@code input} where the input
2299 * starts
2300 * @param inputLen the input length
2301 * @param output the buffer for the result
2302 *
2303 * @return the number of bytes stored in {@code output}
2304 *
2305 * @exception IllegalStateException if this cipher is in a wrong state
2306 * (e.g., has not been initialized)
2307 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2308 * no padding has been requested (only in encryption mode), and the total
2309 * input length of the data processed by this cipher is not a multiple of
2310 * block size; or if this encryption algorithm is unable to
2311 * process the input data provided.
2312 * @exception ShortBufferException if the given output buffer is too small
2313 * to hold the result
2314 * @exception BadPaddingException if this cipher is in decryption mode,
2315 * and (un)padding has been requested, but the decrypted data is not
2316 * bounded by the appropriate padding bytes
2317 * @exception AEADBadTagException if this cipher is decrypting in an
2318 * AEAD mode (such as GCM/CCM), and the received authentication tag
2319 * does not match the calculated value
2320 */
2321 public final int doFinal(byte[] input, int inputOffset, int inputLen,
2322 byte[] output)
2323 throws ShortBufferException, IllegalBlockSizeException,
2324 BadPaddingException {
2325 checkCipherState();
2326
2327 // Input sanity check
2328 if (input == null || inputOffset < 0
2329 || inputLen > (input.length - inputOffset) || inputLen < 0) {
2330 throw new IllegalArgumentException("Bad arguments");
2331 }
2332
2333 chooseFirstProvider();
2334 return spi.engineDoFinal(input, inputOffset, inputLen,
2335 output, 0);
2336 }
2337
2338 /**
2339 * Encrypts or decrypts data in a single-part operation, or finishes a
2340 * multiple-part operation. The data is encrypted or decrypted,
2341 * depending on how this cipher was initialized.
2342 *
2343 * <p>The first {@code inputLen} bytes in the {@code input}
2344 * buffer, starting at {@code inputOffset} inclusive, and any input
2345 * bytes that may have been buffered during a previous
2346 * {@code update} operation, are processed, with padding
2347 * (if requested) being applied.
2348 * If an AEAD mode such as GCM/CCM is being used, the authentication
2349 * tag is appended in the case of encryption, or verified in the
2350 * case of decryption.
2351 * The result is stored in the {@code output} buffer, starting at
2352 * {@code outputOffset} inclusive.
2353 *
2354 * <p>If the {@code output} buffer is too small to hold the result,
2355 * a {@code ShortBufferException} is thrown. In this case, repeat this
2356 * call with a larger output buffer. Use
2357 * {@link #getOutputSize(int) getOutputSize} to determine how big
2358 * the output buffer should be.
2359 *
2360 * <p>Upon finishing, this method resets this cipher object to the state
2361 * it was in when previously initialized via a call to {@code init}.
2362 * That is, the object is reset and available to encrypt or decrypt
2363 * (depending on the operation mode that was specified in the call to
2364 * {@code init}) more data.
2365 *
2366 * <p>Note: if any exception is thrown, this cipher object may need to
2367 * be reset before it can be used again.
2368 *
2369 * <p>Note: this method should be copy-safe, which means the
2370 * {@code input} and {@code output} buffers can reference
2371 * the same byte array and no unprocessed input data is overwritten
2372 * when the result is copied into the output buffer.
2373 *
2374 * @param input the input buffer
2375 * @param inputOffset the offset in {@code input} where the input
2376 * starts
2377 * @param inputLen the input length
2378 * @param output the buffer for the result
2379 * @param outputOffset the offset in {@code output} where the result
2380 * is stored
2381 *
2382 * @return the number of bytes stored in {@code output}
2383 *
2384 * @exception IllegalStateException if this cipher is in a wrong state
2385 * (e.g., has not been initialized)
2386 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2387 * no padding has been requested (only in encryption mode), and the total
2388 * input length of the data processed by this cipher is not a multiple of
2389 * block size; or if this encryption algorithm is unable to
2390 * process the input data provided.
2391 * @exception ShortBufferException if the given output buffer is too small
2392 * to hold the result
2393 * @exception BadPaddingException if this cipher is in decryption mode,
2394 * and (un)padding has been requested, but the decrypted data is not
2395 * bounded by the appropriate padding bytes
2396 * @exception AEADBadTagException if this cipher is decrypting in an
2397 * AEAD mode (such as GCM/CCM), and the received authentication tag
2398 * does not match the calculated value
2399 */
2400 public final int doFinal(byte[] input, int inputOffset, int inputLen,
2401 byte[] output, int outputOffset)
2402 throws ShortBufferException, IllegalBlockSizeException,
2403 BadPaddingException {
2404 checkCipherState();
2405
2406 // Input sanity check
2407 if (input == null || inputOffset < 0
2408 || inputLen > (input.length - inputOffset) || inputLen < 0
2409 || outputOffset < 0) {
2410 throw new IllegalArgumentException("Bad arguments");
2411 }
2412
2413 chooseFirstProvider();
2414 return spi.engineDoFinal(input, inputOffset, inputLen,
2415 output, outputOffset);
2416 }
2417
2418 /**
2419 * Encrypts or decrypts data in a single-part operation, or finishes a
2420 * multiple-part operation. The data is encrypted or decrypted,
2421 * depending on how this cipher was initialized.
2422 *
2423 * <p>All {@code input.remaining()} bytes starting at
2424 * {@code input.position()} are processed.
2425 * If an AEAD mode such as GCM/CCM is being used, the authentication
2426 * tag is appended in the case of encryption, or verified in the
2427 * case of decryption.
2428 * The result is stored in the output buffer.
2429 * Upon return, the input buffer's position will be equal
2430 * to its limit; its limit will not have changed. The output buffer's
2431 * position will have advanced by n, where n is the value returned
2432 * by this method; the output buffer's limit will not have changed.
2433 *
2434 * <p>If {@code output.remaining()} bytes are insufficient to
2435 * hold the result, a {@code ShortBufferException} is thrown.
2436 * In this case, repeat this call with a larger output buffer. Use
2437 * {@link #getOutputSize(int) getOutputSize} to determine how big
2438 * the output buffer should be.
2439 *
2440 * <p>Upon finishing, this method resets this cipher object to the state
2441 * it was in when previously initialized via a call to {@code init}.
2442 * That is, the object is reset and available to encrypt or decrypt
2443 * (depending on the operation mode that was specified in the call to
2444 * {@code init}) more data.
2445 *
2446 * <p>Note: if any exception is thrown, this cipher object may need to
2447 * be reset before it can be used again.
2448 *
2449 * <p>Note: this method should be copy-safe, which means the
2450 * {@code input} and {@code output} buffers can reference
2451 * the same byte array and no unprocessed input data is overwritten
2452 * when the result is copied into the output buffer.
2453 *
2454 * @param input the input ByteBuffer
2455 * @param output the output ByteBuffer
2456 *
2457 * @return the number of bytes stored in {@code output}
2458 *
2459 * @exception IllegalStateException if this cipher is in a wrong state
2460 * (e.g., has not been initialized)
2461 * @exception IllegalArgumentException if input and output are the
2462 * same object
2463 * @exception ReadOnlyBufferException if the output buffer is read-only
2464 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2465 * no padding has been requested (only in encryption mode), and the total
2466 * input length of the data processed by this cipher is not a multiple of
2467 * block size; or if this encryption algorithm is unable to
2468 * process the input data provided.
2469 * @exception ShortBufferException if there is insufficient space in the
2470 * output buffer
2471 * @exception BadPaddingException if this cipher is in decryption mode,
2472 * and (un)padding has been requested, but the decrypted data is not
2473 * bounded by the appropriate padding bytes
2474 * @exception AEADBadTagException if this cipher is decrypting in an
2475 * AEAD mode (such as GCM/CCM), and the received authentication tag
2476 * does not match the calculated value
2477 *
2478 * @since 1.5
2479 */
2480 public final int doFinal(ByteBuffer input, ByteBuffer output)
2481 throws ShortBufferException, IllegalBlockSizeException,
2482 BadPaddingException {
2483 checkCipherState();
2484
2485 if ((input == null) || (output == null)) {
2486 throw new IllegalArgumentException("Buffers must not be null");
2487 }
2488 if (input == output) {
2489 throw new IllegalArgumentException("Input and output buffers must "
2490 + "not be the same object, consider using buffer.duplicate()");
2491 }
2492 if (output.isReadOnly()) {
2493 throw new ReadOnlyBufferException();
2494 }
2495
2496 chooseFirstProvider();
2497 return spi.engineDoFinal(input, output);
2498 }
2499
2500 /**
2501 * Wrap a key.
2502 *
2503 * @param key the key to be wrapped.
2504 *
2505 * @return the wrapped key.
2506 *
2507 * @exception IllegalStateException if this cipher is in a wrong
2508 * state (e.g., has not been initialized).
2509 *
2510 * @exception IllegalBlockSizeException if this cipher is a block
2511 * cipher, no padding has been requested, and the length of the
2512 * encoding of the key to be wrapped is not a
2513 * multiple of the block size.
2514 *
2515 * @exception InvalidKeyException if it is impossible or unsafe to
2516 * wrap the key with this cipher (e.g., a hardware protected key is
2517 * being passed to a software-only cipher).
2518 *
2519 * @throws UnsupportedOperationException if the corresponding method in the
2520 * {@code CipherSpi} is not supported.
2521 */
2522 public final byte[] wrap(Key key)
2523 throws IllegalBlockSizeException, InvalidKeyException {
2524 if (!(this instanceof NullCipher)) {
2525 if (!initialized) {
2526 throw new IllegalStateException("Cipher not initialized");
2527 }
2528 if (opmode != Cipher.WRAP_MODE) {
2529 throw new IllegalStateException("Cipher not initialized " +
2530 "for wrapping keys");
2531 }
2532 }
2533
2534 chooseFirstProvider();
2535 return spi.engineWrap(key);
2536 }
2537
2538 /**
2539 * Unwrap a previously wrapped key.
2540 *
2541 * @param wrappedKey the key to be unwrapped.
2542 *
2543 * @param wrappedKeyAlgorithm the algorithm associated with the wrapped
2544 * key.
2545 *
2546 * @param wrappedKeyType the type of the wrapped key. This must be one of
2547 * {@code SECRET_KEY}, {@code PRIVATE_KEY}, or
2548 * {@code PUBLIC_KEY}.
2549 *
2550 * @return the unwrapped key.
2551 *
2552 * @exception IllegalStateException if this cipher is in a wrong state
2553 * (e.g., has not been initialized).
2554 *
2555 * @exception NoSuchAlgorithmException if no installed providers
2556 * can create keys of type {@code wrappedKeyType} for the
2557 * {@code wrappedKeyAlgorithm}.
2558 *
2559 * @exception InvalidKeyException if {@code wrappedKey} does not
2560 * represent a wrapped key of type {@code wrappedKeyType} for
2561 * the {@code wrappedKeyAlgorithm}.
2562 *
2563 * @throws UnsupportedOperationException if the corresponding method in the
2564 * {@code CipherSpi} is not supported.
2565 */
2566 public final Key unwrap(byte[] wrappedKey,
2567 String wrappedKeyAlgorithm,
2568 int wrappedKeyType)
2569 throws InvalidKeyException, NoSuchAlgorithmException {
2570
2571 if (!(this instanceof NullCipher)) {
2572 if (!initialized) {
2573 throw new IllegalStateException("Cipher not initialized");
2574 }
2575 if (opmode != Cipher.UNWRAP_MODE) {
2576 throw new IllegalStateException("Cipher not initialized " +
2577 "for unwrapping keys");
2578 }
2579 }
2580 if ((wrappedKeyType != SECRET_KEY) &&
2581 (wrappedKeyType != PRIVATE_KEY) &&
2582 (wrappedKeyType != PUBLIC_KEY)) {
2583 throw new InvalidParameterException("Invalid key type");
2584 }
2585
2586 chooseFirstProvider();
2587 return spi.engineUnwrap(wrappedKey,
2588 wrappedKeyAlgorithm,
2589 wrappedKeyType);
2590 }
2591
2592 private AlgorithmParameterSpec getAlgorithmParameterSpec(
2593 AlgorithmParameters params)
2594 throws InvalidParameterSpecException {
2595 if (params == null) {
2596 return null;
2597 }
2598
2599 String alg = params.getAlgorithm().toUpperCase(Locale.ENGLISH);
2600
2601 if (alg.equalsIgnoreCase("RC2")) {
2602 return params.getParameterSpec(RC2ParameterSpec.class);
2603 }
2604
2605 if (alg.equalsIgnoreCase("RC5")) {
2606 return params.getParameterSpec(RC5ParameterSpec.class);
2607 }
2608
2609 if (alg.startsWith("PBE")) {
2610 return params.getParameterSpec(PBEParameterSpec.class);
2611 }
2612
2613 if (alg.startsWith("DES")) {
2614 return params.getParameterSpec(IvParameterSpec.class);
2615 }
2616 return null;
2617 }
2618
2619 private static CryptoPermission getConfiguredPermission(
2620 String transformation) throws NullPointerException,
2621 NoSuchAlgorithmException {
2622 if (transformation == null) throw new NullPointerException();
2623 String[] parts = tokenizeTransformation(transformation);
2624 return JceSecurityManager.INSTANCE.getCryptoPermission(parts[0]);
2625 }
2626
2627 /**
2628 * Returns the maximum key length for the specified transformation
2629 * according to the installed JCE jurisdiction policy files. If
2630 * JCE unlimited strength jurisdiction policy files are installed,
2631 * Integer.MAX_VALUE will be returned.
2632 * For more information on the default key sizes and the JCE jurisdiction
2633 * policy files, please see the Cryptographic defaults and limitations in
2634 * the {@extLink security_guide_jdk_providers JDK Providers Documentation}.
2635 *
2636 * @param transformation the cipher transformation.
2637 * @return the maximum key length in bits or Integer.MAX_VALUE.
2638 * @exception NullPointerException if {@code transformation} is null.
2639 * @exception NoSuchAlgorithmException if {@code transformation}
2640 * is not a valid transformation, i.e. in the form of "algorithm" or
2641 * "algorithm/mode/padding".
2642 * @since 1.5
2643 */
2644 public static final int getMaxAllowedKeyLength(String transformation)
2645 throws NoSuchAlgorithmException {
2646 CryptoPermission cp = getConfiguredPermission(transformation);
2647 return cp.getMaxKeySize();
2648 }
2649
2650 /**
2651 * Returns an AlgorithmParameterSpec object which contains
2652 * the maximum cipher parameter value according to the
2653 * jurisdiction policy file. If JCE unlimited strength jurisdiction
2654 * policy files are installed or there is no maximum limit on the
2655 * parameters for the specified transformation in the policy file,
2656 * null will be returned.
2657 *
2658 * @param transformation the cipher transformation.
2659 * @return an AlgorithmParameterSpec which holds the maximum
2660 * value or null.
2661 * @exception NullPointerException if {@code transformation}
2662 * is null.
2663 * @exception NoSuchAlgorithmException if {@code transformation}
2664 * is not a valid transformation, i.e. in the form of "algorithm" or
2665 * "algorithm/mode/padding".
2666 * @since 1.5
2667 */
2668 public static final AlgorithmParameterSpec getMaxAllowedParameterSpec(
2669 String transformation) throws NoSuchAlgorithmException {
2670 CryptoPermission cp = getConfiguredPermission(transformation);
2671 return cp.getAlgorithmParameterSpec();
2672 }
2673
2674 /**
2675 * Continues a multi-part update of the Additional Authentication
2676 * Data (AAD).
2677 * <p>
2678 * Calls to this method provide AAD to the cipher when operating in
2679 * modes such as AEAD (GCM/CCM). If this cipher is operating in
2680 * either GCM or CCM mode, all AAD must be supplied before beginning
2681 * operations on the ciphertext (via the {@code update} and
2682 * {@code doFinal} methods).
2683 *
2684 * @param src the buffer containing the Additional Authentication Data
2685 *
2686 * @throws IllegalArgumentException if the {@code src}
2687 * byte array is null
2688 * @throws IllegalStateException if this cipher is in a wrong state
2689 * (e.g., has not been initialized), does not accept AAD, or if
2690 * operating in either GCM or CCM mode and one of the {@code update}
2691 * methods has already been called for the active
2692 * encryption/decryption operation
2693 * @throws UnsupportedOperationException if the corresponding method
2694 * in the {@code CipherSpi} has not been overridden by an
2695 * implementation
2696 *
2697 * @since 1.7
2698 */
2699 public final void updateAAD(byte[] src) {
2700 if (src == null) {
2701 throw new IllegalArgumentException("src buffer is null");
2702 }
2703
2704 updateAAD(src, 0, src.length);
2705 }
2706
2707 /**
2708 * Continues a multi-part update of the Additional Authentication
2709 * Data (AAD), using a subset of the provided buffer.
2710 * <p>
2711 * Calls to this method provide AAD to the cipher when operating in
2712 * modes such as AEAD (GCM/CCM). If this cipher is operating in
2713 * either GCM or CCM mode, all AAD must be supplied before beginning
2714 * operations on the ciphertext (via the {@code update}
2715 * and {@code doFinal} methods).
2716 *
2717 * @param src the buffer containing the AAD
2718 * @param offset the offset in {@code src} where the AAD input starts
2719 * @param len the number of AAD bytes
2720 *
2721 * @throws IllegalArgumentException if the {@code src}
2722 * byte array is null, or the {@code offset} or {@code length}
2723 * is less than 0, or the sum of the {@code offset} and
2724 * {@code len} is greater than the length of the
2725 * {@code src} byte array
2726 * @throws IllegalStateException if this cipher is in a wrong state
2727 * (e.g., has not been initialized), does not accept AAD, or if
2728 * operating in either GCM or CCM mode and one of the {@code update}
2729 * methods has already been called for the active
2730 * encryption/decryption operation
2731 * @throws UnsupportedOperationException if the corresponding method
2732 * in the {@code CipherSpi} has not been overridden by an
2733 * implementation
2734 *
2735 * @since 1.7
2736 */
2737 public final void updateAAD(byte[] src, int offset, int len) {
2738 checkCipherState();
2739
2740 // Input sanity check
2741 if ((src == null) || (offset < 0) || (len < 0)
2742 || len > (src.length - offset)) {
2743 throw new IllegalArgumentException("Bad arguments");
2744 }
2745
2746 chooseFirstProvider();
2747 if (len == 0) {
2748 return;
2749 }
2750 spi.engineUpdateAAD(src, offset, len);
2751 }
2752
2753 /**
2754 * Continues a multi-part update of the Additional Authentication
2755 * Data (AAD).
2756 * <p>
2757 * Calls to this method provide AAD to the cipher when operating in
2758 * modes such as AEAD (GCM/CCM). If this cipher is operating in
2759 * either GCM or CCM mode, all AAD must be supplied before beginning
2760 * operations on the ciphertext (via the {@code update}
2761 * and {@code doFinal} methods).
2762 * <p>
2763 * All {@code src.remaining()} bytes starting at
2764 * {@code src.position()} are processed.
2765 * Upon return, the input buffer's position will be equal
2766 * to its limit; its limit will not have changed.
2767 *
2768 * @param src the buffer containing the AAD
2769 *
2770 * @throws IllegalArgumentException if the {@code src ByteBuffer}
2771 * is null
2772 * @throws IllegalStateException if this cipher is in a wrong state
2773 * (e.g., has not been initialized), does not accept AAD, or if
2774 * operating in either GCM or CCM mode and one of the {@code update}
2775 * methods has already been called for the active
2776 * encryption/decryption operation
2777 * @throws UnsupportedOperationException if the corresponding method
2778 * in the {@code CipherSpi} has not been overridden by an
2779 * implementation
2780 *
2781 * @since 1.7
2782 */
2783 public final void updateAAD(ByteBuffer src) {
2784 checkCipherState();
2785
2786 // Input sanity check
2787 if (src == null) {
2788 throw new IllegalArgumentException("src ByteBuffer is null");
2789 }
2790
2791 chooseFirstProvider();
2792 if (src.remaining() == 0) {
2793 return;
2794 }
2795 spi.engineUpdateAAD(src);
2796 }
2797 }
2798