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