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