Path: blob/master/src/java.base/share/classes/javax/crypto/Cipher.java
41152 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.crypto;2627import java.util.*;28import java.util.concurrent.ConcurrentHashMap;29import java.util.concurrent.ConcurrentMap;30import java.util.regex.*;313233import java.security.*;34import java.security.Provider.Service;35import java.security.spec.AlgorithmParameterSpec;36import java.security.spec.InvalidParameterSpecException;37import java.security.cert.Certificate;38import java.security.cert.X509Certificate;3940import javax.crypto.spec.*;4142import java.nio.ByteBuffer;43import java.nio.ReadOnlyBufferException;4445import sun.security.util.Debug;46import sun.security.jca.*;47import sun.security.util.KnownOIDs;4849/**50* This class provides the functionality of a cryptographic cipher for51* encryption and decryption. It forms the core of the Java Cryptographic52* Extension (JCE) framework.53*54* <p>In order to create a Cipher object, the application calls the55* Cipher's {@code getInstance} method, and passes the name of the56* requested <i>transformation</i> to it. Optionally, the name of a provider57* may be specified.58*59* <p>A <i>transformation</i> is a string that describes the operation (or60* set of operations) to be performed on the given input, to produce some61* output. A transformation always includes the name of a cryptographic62* algorithm (e.g., <i>AES</i>), and may be followed by a feedback mode and63* padding scheme.64*65* <p> A transformation is of the form:66*67* <ul>68* <li>"<i>algorithm/mode/padding</i>" or69*70* <li>"<i>algorithm</i>"71* </ul>72*73* <P> (in the latter case,74* provider-specific default values for the mode and padding scheme are used).75* For example, the following is a valid transformation:76*77* <pre>78* Cipher c = Cipher.getInstance("<i>AES/CBC/PKCS5Padding</i>");79* </pre>80*81* Using modes such as {@code CFB} and {@code OFB}, block82* ciphers can encrypt data in units smaller than the cipher's actual83* block size. When requesting such a mode, you may optionally specify84* the number of bits to be processed at a time by appending this number85* to the mode name as shown in the "{@code AES/CFB8/NoPadding}" and86* "{@code AES/OFB32/PKCS5Padding}" transformations. If no such87* number is specified, a provider-specific default is used.88* (See the89* {@extLink security_guide_jdk_providers JDK Providers Documentation}90* for the JDK Providers default values.)91* Thus, block ciphers can be turned into byte-oriented stream ciphers by92* 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 and96* Additional Associated Data (AAD) that is not encrypted. (Please see97* <a href="http://www.ietf.org/rfc/rfc5116.txt"> RFC 5116 </a> for more98* information on AEAD and AAD algorithms such as GCM/CCM.) Both99* confidential and AAD data can be used when calculating the100* authentication tag (similar to a {@link Mac}). This tag is appended101* to the ciphertext during encryption, and is verified on decryption.102* <p>103* AEAD modes such as GCM/CCM perform all AAD authenticity calculations104* before starting the ciphertext authenticity calculations. To avoid105* implementations having to internally buffer ciphertext, all AAD data106* must be supplied to GCM/CCM implementations (via the {@code updateAAD}107* methods) <b>before</b> the ciphertext is processed (via108* the {@code update} and {@code doFinal} methods).109* <p>110* Note that GCM mode has a uniqueness requirement on IVs used in111* encryption with a given key. When IVs are repeated for GCM112* encryption, such usages are subject to forgery attacks. Thus, after113* each encryption operation using GCM mode, callers should re-initialize114* the cipher objects with GCM parameters which have a different IV value.115* <pre>116* GCMParameterSpec s = ...;117* cipher.init(..., s);118*119* // If the GCM parameters were generated by the provider, it can120* // be retrieved by:121* // cipher.getParameters().getParameterSpec(GCMParameterSpec.class);122*123* cipher.updateAAD(...); // AAD124* cipher.update(...); // Multi-part update125* cipher.doFinal(...); // conclusion of operation126*127* // Use a different IV value for every encryption128* byte[] newIv = ...;129* s = new GCMParameterSpec(s.getTLen(), newIv);130* cipher.init(..., s);131* ...132*133* </pre>134* The ChaCha20 and ChaCha20-Poly1305 algorithms have a similar requirement135* for unique nonces with a given key. After each encryption or decryption136* operation, callers should re-initialize their ChaCha20 or ChaCha20-Poly1305137* ciphers with parameters that specify a different nonce value. Please138* see <a href="https://tools.ietf.org/html/rfc7539">RFC 7539</a> for more139* information on the ChaCha20 and ChaCha20-Poly1305 algorithms.140* <p>141* Every implementation of the Java platform is required to support142* the following standard {@code Cipher} transformations with the keysizes143* in parentheses:144* <ul>145* <li>{@code AES/CBC/NoPadding} (128)</li>146* <li>{@code AES/CBC/PKCS5Padding} (128)</li>147* <li>{@code AES/ECB/NoPadding} (128)</li>148* <li>{@code AES/ECB/PKCS5Padding} (128)</li>149* <li>{@code AES/GCM/NoPadding} (128)</li>150* <li>{@code DESede/CBC/NoPadding} (168)</li>151* <li>{@code DESede/CBC/PKCS5Padding} (168)</li>152* <li>{@code DESede/ECB/NoPadding} (168)</li>153* <li>{@code DESede/ECB/PKCS5Padding} (168)</li>154* <li>{@code RSA/ECB/PKCS1Padding} (1024, 2048)</li>155* <li>{@code RSA/ECB/OAEPWithSHA-1AndMGF1Padding} (1024, 2048)</li>156* <li>{@code RSA/ECB/OAEPWithSHA-256AndMGF1Padding} (1024, 2048)</li>157* </ul>158* These transformations are described in the159* <a href="{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">160* Cipher section</a> of the161* Java Security Standard Algorithm Names Specification.162* Consult the release documentation for your implementation to see if any163* other transformations are supported.164*165* @author Jan Luehe166* @see KeyGenerator167* @see SecretKey168* @since 1.4169*/170171public class Cipher {172173private static final Debug debug =174Debug.getInstance("jca", "Cipher");175176private static final Debug pdebug =177Debug.getInstance("provider", "Provider");178private static final boolean skipDebug =179Debug.isOn("engine=") && !Debug.isOn("cipher");180181/**182* Constant used to initialize cipher to encryption mode.183*/184public static final int ENCRYPT_MODE = 1;185186/**187* Constant used to initialize cipher to decryption mode.188*/189public static final int DECRYPT_MODE = 2;190191/**192* Constant used to initialize cipher to key-wrapping mode.193*/194public static final int WRAP_MODE = 3;195196/**197* Constant used to initialize cipher to key-unwrapping mode.198*/199public static final int UNWRAP_MODE = 4;200201/**202* Constant used to indicate the to-be-unwrapped key is a "public key".203*/204public static final int PUBLIC_KEY = 1;205206/**207* Constant used to indicate the to-be-unwrapped key is a "private key".208*/209public static final int PRIVATE_KEY = 2;210211/**212* Constant used to indicate the to-be-unwrapped key is a "secret key".213*/214public static final int SECRET_KEY = 3;215216// The provider217private Provider provider;218219// The provider implementation (delegate)220private CipherSpi spi;221222// The transformation223private String transformation;224225// Crypto permission representing the maximum allowable cryptographic226// strength that this Cipher object can be used for. (The cryptographic227// strength is a function of the keysize and algorithm parameters encoded228// in the crypto permission.)229private CryptoPermission cryptoPerm;230231// The exemption mechanism that needs to be enforced232private ExemptionMechanism exmech;233234// Flag which indicates whether or not this cipher has been initialized235private boolean initialized = false;236237// The operation mode - store the operation mode after the238// cipher has been initialized.239private int opmode = 0;240241// next SPI to try in provider selection242// null once provider is selected243private CipherSpi firstSpi;244245// next service to try in provider selection246// null once provider is selected247private Service firstService;248249// remaining services to try in provider selection250// null once provider is selected251private Iterator<Service> serviceIterator;252253// list of transform Strings to lookup in the provider254private List<Transform> transforms;255256private final Object lock;257258/**259* Creates a Cipher object.260*261* @param cipherSpi the delegate262* @param provider the provider263* @param transformation the transformation264* @throws NullPointerException if {@code provider} is {@code null}265* @throws IllegalArgumentException if the supplied arguments266* are deemed invalid for constructing the Cipher object267*/268protected Cipher(CipherSpi cipherSpi,269Provider provider,270String transformation) {271// See bug 4341369 & 4334690 for more info.272// If the caller is trusted, then okay.273// Otherwise throw an IllegalArgumentException.274if (!JceSecurityManager.INSTANCE.isCallerTrusted(provider)) {275throw new IllegalArgumentException("Cannot construct cipher");276}277this.spi = cipherSpi;278this.provider = provider;279this.transformation = transformation;280this.cryptoPerm = CryptoAllPermission.INSTANCE;281this.lock = null;282}283284/**285* Creates a Cipher object. Called internally and by NullCipher.286*287* @param cipherSpi the delegate288* @param transformation the transformation289*/290Cipher(CipherSpi cipherSpi, String transformation) {291this.spi = cipherSpi;292this.transformation = transformation;293this.cryptoPerm = CryptoAllPermission.INSTANCE;294this.lock = null;295}296297private Cipher(CipherSpi firstSpi, Service firstService,298Iterator<Service> serviceIterator, String transformation,299List<Transform> transforms) {300this.firstSpi = firstSpi;301this.firstService = firstService;302this.serviceIterator = serviceIterator;303this.transforms = transforms;304this.transformation = transformation;305this.lock = new Object();306}307308private static String[] tokenizeTransformation(String transformation)309throws NoSuchAlgorithmException {310if (transformation == null) {311throw new NoSuchAlgorithmException("No transformation given");312}313/*314* array containing the components of a Cipher transformation:315*316* index 0: algorithm component (e.g., AES)317* index 1: feedback component (e.g., CFB)318* index 2: padding component (e.g., PKCS5Padding)319*/320String[] parts = new String[3];321int count = 0;322StringTokenizer parser = new StringTokenizer(transformation, "/");323try {324while (parser.hasMoreTokens() && count < 3) {325parts[count++] = parser.nextToken().trim();326}327if (count == 0 || count == 2) {328throw new NoSuchAlgorithmException("Invalid transformation"329+ " format:" +330transformation);331}332// treats all subsequent tokens as part of padding333if (count == 3 && parser.hasMoreTokens()) {334parts[2] = parts[2] + parser.nextToken("\r\n");335}336} catch (NoSuchElementException e) {337throw new NoSuchAlgorithmException("Invalid transformation " +338"format:" + transformation);339}340if ((parts[0] == null) || (parts[0].isEmpty())) {341throw new NoSuchAlgorithmException("Invalid transformation:" +342"algorithm not specified-"343+ transformation);344}345return parts;346}347348// Provider attribute name for supported chaining mode349private static final String ATTR_MODE = "SupportedModes";350// Provider attribute name for supported padding names351private static final String ATTR_PAD = "SupportedPaddings";352353// constants indicating whether the provider supports354// a given mode or padding355private static final int S_NO = 0; // does not support356private static final int S_MAYBE = 1; // unable to determine357private static final int S_YES = 2; // does support358359/**360* Nested class to deal with modes and paddings.361*/362private static class Transform {363// transform string to lookup in the provider364final String transform;365// the mode/padding suffix in upper case. for example, if the algorithm366// to lookup is "AES/CBC/PKCS5Padding" suffix is "/CBC/PKCS5PADDING"367// if lookup is "AES", suffix is the empty string368// needed because aliases prevent straight transform.equals()369final String suffix;370// value to pass to setMode() or null if no such call required371final String mode;372// value to pass to setPadding() or null if no such call required373final String pad;374Transform(String alg, String suffix, String mode, String pad) {375this.transform = alg + suffix;376this.suffix = suffix.toUpperCase(Locale.ENGLISH);377this.mode = mode;378this.pad = pad;379}380// set mode and padding for the given SPI381void setModePadding(CipherSpi spi) throws NoSuchAlgorithmException,382NoSuchPaddingException {383if (mode != null) {384spi.engineSetMode(mode);385}386if (pad != null) {387spi.engineSetPadding(pad);388}389}390// check whether the given services supports the mode and391// padding described by this Transform392int supportsModePadding(Service s) {393int smode = supportsMode(s);394if (smode == S_NO) {395return smode;396}397int spad = supportsPadding(s);398// our constants are defined so that Math.min() is a tri-valued AND399return Math.min(smode, spad);400}401402// separate methods for mode and padding403// called directly by Cipher only to throw the correct exception404int supportsMode(Service s) {405return supports(s, ATTR_MODE, mode);406}407int supportsPadding(Service s) {408return supports(s, ATTR_PAD, pad);409}410411private static int supports(Service s, String attrName, String value) {412if (value == null) {413return S_YES;414}415String regexp = s.getAttribute(attrName);416if (regexp == null) {417return S_MAYBE;418}419return matches(regexp, value) ? S_YES : S_NO;420}421422// ConcurrentMap<String,Pattern> for previously compiled patterns423private static final ConcurrentMap<String, Pattern> patternCache =424new ConcurrentHashMap<String, Pattern>();425426private static boolean matches(String regexp, String str) {427Pattern pattern = patternCache.get(regexp);428if (pattern == null) {429pattern = Pattern.compile(regexp);430patternCache.putIfAbsent(regexp, pattern);431}432return pattern.matcher(str.toUpperCase(Locale.ENGLISH)).matches();433}434435}436437private static List<Transform> getTransforms(String transformation)438throws NoSuchAlgorithmException {439String[] parts = tokenizeTransformation(transformation);440441String alg = parts[0];442String mode = parts[1];443String pad = parts[2];444if ((mode != null) && (mode.isEmpty())) {445mode = null;446}447if ((pad != null) && (pad.isEmpty())) {448pad = null;449}450451if ((mode == null) && (pad == null)) {452// AES453Transform tr = new Transform(alg, "", null, null);454return Collections.singletonList(tr);455} else { // if ((mode != null) && (pad != null)) {456// AES/CBC/PKCS5Padding457List<Transform> list = new ArrayList<>(4);458list.add(new Transform(alg, "/" + mode + "/" + pad, null, null));459list.add(new Transform(alg, "/" + mode, null, pad));460list.add(new Transform(alg, "//" + pad, mode, null));461list.add(new Transform(alg, "", mode, pad));462return list;463}464}465466// get the transform matching the specified service467private static Transform getTransform(Service s,468List<Transform> transforms) {469String alg = s.getAlgorithm().toUpperCase(Locale.ENGLISH);470for (Transform tr : transforms) {471if (alg.endsWith(tr.suffix)) {472return tr;473}474}475return null;476}477478/**479* Returns a {@code Cipher} object that implements the specified480* transformation.481*482* <p> This method traverses the list of registered security Providers,483* starting with the most preferred Provider.484* A new Cipher object encapsulating the485* CipherSpi implementation from the first486* Provider that supports the specified algorithm is returned.487*488* <p> Note that the list of registered providers may be retrieved via489* the {@link Security#getProviders() Security.getProviders()} method.490*491* @apiNote492* It is recommended to use a transformation that fully specifies the493* algorithm, mode, and padding. By not doing so, the provider will494* use a default for the mode and padding which may not meet the security495* requirements of your application.496*497* @implNote498* The JDK Reference Implementation additionally uses the499* {@code jdk.security.provider.preferred}500* {@link Security#getProperty(String) Security} property to determine501* the preferred provider order for the specified algorithm. This502* may be different than the order of providers returned by503* {@link Security#getProviders() Security.getProviders()}.504* See also the Cipher Transformations section of the {@extLink505* security_guide_jdk_providers JDK Providers} document for information506* on the transformation defaults used by JDK providers.507*508* @param transformation the name of the transformation, e.g.,509* <i>AES/CBC/PKCS5Padding</i>.510* See the Cipher section in the <a href=511* "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">512* Java Security Standard Algorithm Names Specification</a>513* for information about standard transformation names.514*515* @return a cipher that implements the requested transformation516*517* @throws NoSuchAlgorithmException if {@code transformation}518* is {@code null}, empty, in an invalid format,519* or if no {@code Provider} supports a {@code CipherSpi}520* implementation for the specified algorithm521*522* @throws NoSuchPaddingException if {@code transformation}523* contains a padding scheme that is not available524*525* @see java.security.Provider526*/527public static final Cipher getInstance(String transformation)528throws NoSuchAlgorithmException, NoSuchPaddingException529{530if ((transformation == null) || transformation.isEmpty()) {531throw new NoSuchAlgorithmException("Null or empty transformation");532}533List<Transform> transforms = getTransforms(transformation);534List<ServiceId> cipherServices = new ArrayList<>(transforms.size());535for (Transform transform : transforms) {536cipherServices.add(new ServiceId("Cipher", transform.transform));537}538List<Service> services = GetInstance.getServices(cipherServices);539// make sure there is at least one service from a signed provider540// and that it can use the specified mode and padding541Iterator<Service> t = services.iterator();542Exception failure = null;543while (t.hasNext()) {544Service s = t.next();545if (JceSecurity.canUseProvider(s.getProvider()) == false) {546continue;547}548Transform tr = getTransform(s, transforms);549if (tr == null) {550// should never happen551continue;552}553int canuse = tr.supportsModePadding(s);554if (canuse == S_NO) {555// does not support mode or padding we need, ignore556continue;557}558// S_YES, S_MAYBE559// even when mode and padding are both supported, they560// may not be used together, try out and see if it works561try {562CipherSpi spi = (CipherSpi)s.newInstance(null);563tr.setModePadding(spi);564// specify null instead of spi for delayed provider selection565return new Cipher(null, s, t, transformation, transforms);566} catch (Exception e) {567failure = e;568}569}570throw new NoSuchAlgorithmException571("Cannot find any provider supporting " + transformation, failure);572}573574/**575* Returns a {@code Cipher} object that implements the specified576* transformation.577*578* <p> A new Cipher object encapsulating the579* CipherSpi implementation from the specified provider580* is returned. The specified provider must be registered581* in the security provider list.582*583* <p> Note that the list of registered providers may be retrieved via584* the {@link Security#getProviders() Security.getProviders()} method.585*586* @apiNote587* It is recommended to use a transformation that fully specifies the588* algorithm, mode, and padding. By not doing so, the provider will589* use a default for the mode and padding which may not meet the security590* requirements of your application.591*592* @implNote593* See the Cipher Transformations section of the {@extLink594* security_guide_jdk_providers JDK Providers} document for information595* on the transformation defaults used by JDK providers.596*597* @param transformation the name of the transformation,598* e.g., <i>AES/CBC/PKCS5Padding</i>.599* See the Cipher section in the <a href=600* "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">601* Java Security Standard Algorithm Names Specification</a>602* for information about standard transformation names.603*604* @param provider the name of the provider.605*606* @return a cipher that implements the requested transformation607*608* @throws IllegalArgumentException if the {@code provider}609* is {@code null} or empty610*611* @throws NoSuchAlgorithmException if {@code transformation}612* is {@code null}, empty, in an invalid format,613* or if a {@code CipherSpi} implementation for the614* specified algorithm is not available from the specified615* provider616*617* @throws NoSuchPaddingException if {@code transformation}618* contains a padding scheme that is not available619*620* @throws NoSuchProviderException if the specified provider is not621* registered in the security provider list622*623* @see java.security.Provider624*/625public static final Cipher getInstance(String transformation,626String provider)627throws NoSuchAlgorithmException, NoSuchProviderException,628NoSuchPaddingException629{630if ((transformation == null) || transformation.isEmpty()) {631throw new NoSuchAlgorithmException("Null or empty transformation");632}633if ((provider == null) || (provider.isEmpty())) {634throw new IllegalArgumentException("Missing provider");635}636Provider p = Security.getProvider(provider);637if (p == null) {638throw new NoSuchProviderException("No such provider: " +639provider);640}641return getInstance(transformation, p);642}643644private String getProviderName() {645return (provider == null) ? "(no provider)" : provider.getName();646}647648/**649* Returns a {@code Cipher} object that implements the specified650* transformation.651*652* <p> A new Cipher object encapsulating the653* CipherSpi implementation from the specified Provider654* object is returned. Note that the specified Provider object655* does not have to be registered in the provider list.656*657* @apiNote658* It is recommended to use a transformation that fully specifies the659* algorithm, mode, and padding. By not doing so, the provider will660* use a default for the mode and padding which may not meet the security661* requirements of your application.662*663* @implNote664* See the Cipher Transformations section of the {@extLink665* security_guide_jdk_providers JDK Providers} document for information666* on the transformation defaults used by JDK providers.667*668* @param transformation the name of the transformation,669* e.g., <i>AES/CBC/PKCS5Padding</i>.670* See the Cipher section in the <a href=671* "{@docRoot}/../specs/security/standard-names.html#cipher-algorithm-names">672* Java Security Standard Algorithm Names Specification</a>673* for information about standard transformation names.674*675* @param provider the provider.676*677* @return a cipher that implements the requested transformation678*679* @throws IllegalArgumentException if the {@code provider}680* is {@code null}681*682* @throws NoSuchAlgorithmException if {@code transformation}683* is {@code null}, empty, in an invalid format,684* or if a {@code CipherSpi} implementation for the685* specified algorithm is not available from the specified686* {@code Provider} object687*688* @throws NoSuchPaddingException if {@code transformation}689* contains a padding scheme that is not available690*691* @see java.security.Provider692*/693public static final Cipher getInstance(String transformation,694Provider provider)695throws NoSuchAlgorithmException, NoSuchPaddingException696{697if ((transformation == null) || transformation.isEmpty()) {698throw new NoSuchAlgorithmException("Null or empty transformation");699}700if (provider == null) {701throw new IllegalArgumentException("Missing provider");702}703Exception failure = null;704List<Transform> transforms = getTransforms(transformation);705boolean providerChecked = false;706String paddingError = null;707for (Transform tr : transforms) {708Service s = provider.getService("Cipher", tr.transform);709if (s == null) {710continue;711}712if (providerChecked == false) {713// for compatibility, first do the lookup and then verify714// the provider. this makes the difference between a NSAE715// and a SecurityException if the716// provider does not support the algorithm.717Exception ve = JceSecurity.getVerificationResult(provider);718if (ve != null) {719String msg = "JCE cannot authenticate the provider "720+ provider.getName();721throw new SecurityException(msg, ve);722}723providerChecked = true;724}725if (tr.supportsMode(s) == S_NO) {726continue;727}728if (tr.supportsPadding(s) == S_NO) {729paddingError = tr.pad;730continue;731}732try {733CipherSpi spi = (CipherSpi)s.newInstance(null);734tr.setModePadding(spi);735Cipher cipher = new Cipher(spi, transformation);736cipher.provider = s.getProvider();737cipher.initCryptoPermission();738return cipher;739} catch (Exception e) {740failure = e;741}742}743744// throw NoSuchPaddingException if the problem is with padding745if (failure instanceof NoSuchPaddingException) {746throw (NoSuchPaddingException)failure;747}748if (paddingError != null) {749throw new NoSuchPaddingException750("Padding not supported: " + paddingError);751}752throw new NoSuchAlgorithmException753("No such algorithm: " + transformation, failure);754}755756// If the requested crypto service is export-controlled,757// determine the maximum allowable keysize.758private void initCryptoPermission() throws NoSuchAlgorithmException {759if (JceSecurity.isRestricted() == false) {760cryptoPerm = CryptoAllPermission.INSTANCE;761exmech = null;762return;763}764cryptoPerm = getConfiguredPermission(transformation);765// Instantiate the exemption mechanism (if required)766String exmechName = cryptoPerm.getExemptionMechanism();767if (exmechName != null) {768exmech = ExemptionMechanism.getInstance(exmechName);769}770}771772// max number of debug warnings to print from chooseFirstProvider()773private static int warnCount = 10;774775/**776* Choose the Spi from the first provider available. Used if777* delayed provider selection is not possible because init()778* is not the first method called.779*/780void chooseFirstProvider() {781if (spi != null) {782return;783}784synchronized (lock) {785if (spi != null) {786return;787}788if (debug != null) {789int w = --warnCount;790if (w >= 0) {791debug.println("Cipher.init() not first method "792+ "called, disabling delayed provider selection");793if (w == 0) {794debug.println("Further warnings of this type will "795+ "be suppressed");796}797new Exception("Call trace").printStackTrace();798}799}800Exception lastException = null;801while ((firstService != null) || serviceIterator.hasNext()) {802Service s;803CipherSpi thisSpi;804if (firstService != null) {805s = firstService;806thisSpi = firstSpi;807firstService = null;808firstSpi = null;809} else {810s = serviceIterator.next();811thisSpi = null;812}813if (JceSecurity.canUseProvider(s.getProvider()) == false) {814continue;815}816Transform tr = getTransform(s, transforms);817if (tr == null) {818// should never happen819continue;820}821if (tr.supportsModePadding(s) == S_NO) {822continue;823}824try {825if (thisSpi == null) {826Object obj = s.newInstance(null);827if (obj instanceof CipherSpi == false) {828continue;829}830thisSpi = (CipherSpi)obj;831}832tr.setModePadding(thisSpi);833initCryptoPermission();834spi = thisSpi;835provider = s.getProvider();836// not needed any more837firstService = null;838serviceIterator = null;839transforms = null;840return;841} catch (Exception e) {842lastException = e;843}844}845ProviderException e = new ProviderException846("Could not construct CipherSpi instance");847if (lastException != null) {848e.initCause(lastException);849}850throw e;851}852}853854private static final int I_KEY = 1;855private static final int I_PARAMSPEC = 2;856private static final int I_PARAMS = 3;857private static final int I_CERT = 4;858859private void implInit(CipherSpi thisSpi, int type, int opmode, Key key,860AlgorithmParameterSpec paramSpec, AlgorithmParameters params,861SecureRandom random) throws InvalidKeyException,862InvalidAlgorithmParameterException {863switch (type) {864case I_KEY:865checkCryptoPerm(thisSpi, key);866thisSpi.engineInit(opmode, key, random);867break;868case I_PARAMSPEC:869checkCryptoPerm(thisSpi, key, paramSpec);870thisSpi.engineInit(opmode, key, paramSpec, random);871break;872case I_PARAMS:873checkCryptoPerm(thisSpi, key, params);874thisSpi.engineInit(opmode, key, params, random);875break;876case I_CERT:877checkCryptoPerm(thisSpi, key);878thisSpi.engineInit(opmode, key, random);879break;880default:881throw new AssertionError("Internal Cipher error: " + type);882}883}884885private void chooseProvider(int initType, int opmode, Key key,886AlgorithmParameterSpec paramSpec,887AlgorithmParameters params, SecureRandom random)888throws InvalidKeyException, InvalidAlgorithmParameterException {889synchronized (lock) {890if (spi != null) {891implInit(spi, initType, opmode, key, paramSpec, params, random);892return;893}894Exception lastException = null;895while ((firstService != null) || serviceIterator.hasNext()) {896Service s;897CipherSpi thisSpi;898if (firstService != null) {899s = firstService;900thisSpi = firstSpi;901firstService = null;902firstSpi = null;903} else {904s = serviceIterator.next();905thisSpi = null;906}907// if provider says it does not support this key, ignore it908if (s.supportsParameter(key) == false) {909continue;910}911if (JceSecurity.canUseProvider(s.getProvider()) == false) {912continue;913}914Transform tr = getTransform(s, transforms);915if (tr == null) {916// should never happen917continue;918}919if (tr.supportsModePadding(s) == S_NO) {920continue;921}922try {923if (thisSpi == null) {924thisSpi = (CipherSpi)s.newInstance(null);925}926tr.setModePadding(thisSpi);927initCryptoPermission();928implInit(thisSpi, initType, opmode, key, paramSpec,929params, random);930provider = s.getProvider();931this.spi = thisSpi;932firstService = null;933serviceIterator = null;934transforms = null;935return;936} catch (Exception e) {937// NoSuchAlgorithmException from newInstance()938// InvalidKeyException from init()939// RuntimeException (ProviderException) from init()940// SecurityException from crypto permission check941if (lastException == null) {942lastException = e;943}944}945}946// no working provider found, fail947if (lastException instanceof InvalidKeyException) {948throw (InvalidKeyException)lastException;949}950if (lastException instanceof InvalidAlgorithmParameterException) {951throw (InvalidAlgorithmParameterException)lastException;952}953if (lastException instanceof RuntimeException) {954throw (RuntimeException)lastException;955}956String kName = (key != null) ? key.getClass().getName() : "(null)";957throw new InvalidKeyException958("No installed provider supports this key: "959+ kName, lastException);960}961}962963/**964* Returns the provider of this {@code Cipher} object.965*966* @return the provider of this {@code Cipher} object967*/968public final Provider getProvider() {969chooseFirstProvider();970return this.provider;971}972973/**974* Returns the algorithm name of this {@code Cipher} object.975*976* <p>This is the same name that was specified in one of the977* {@code getInstance} calls that created this {@code Cipher}978* object..979*980* @return the algorithm name of this {@code Cipher} object.981*/982public final String getAlgorithm() {983return this.transformation;984}985986/**987* Returns the block size (in bytes).988*989* @return the block size (in bytes), or 0 if the underlying algorithm is990* not a block cipher991*/992public final int getBlockSize() {993chooseFirstProvider();994return spi.engineGetBlockSize();995}996997/**998* Returns the length in bytes that an output buffer would need to be in999* order to hold the result of the next {@code update} or1000* {@code doFinal} operation, given the input length1001* {@code inputLen} (in bytes).1002*1003* <p>This call takes into account any unprocessed (buffered) data from a1004* previous {@code update} call, padding, and AEAD tagging.1005*1006* <p>The actual output length of the next {@code update} or1007* {@code doFinal} call may be smaller than the length returned by1008* this method.1009*1010* @param inputLen the input length (in bytes)1011*1012* @return the required output buffer size (in bytes)1013*1014* @exception IllegalStateException if this cipher is in a wrong state1015* (e.g., has not yet been initialized)1016*/1017public final int getOutputSize(int inputLen) {10181019if (!initialized && !(this instanceof NullCipher)) {1020throw new IllegalStateException("Cipher not initialized");1021}1022if (inputLen < 0) {1023throw new IllegalArgumentException("Input size must be equal " +1024"to or greater than zero");1025}1026chooseFirstProvider();1027return spi.engineGetOutputSize(inputLen);1028}10291030/**1031* Returns the initialization vector (IV) in a new buffer.1032*1033* <p>This is useful in the case where a random IV was created,1034* or in the context of password-based encryption or1035* decryption, where the IV is derived from a user-supplied password.1036*1037* @return the initialization vector in a new buffer, or null if the1038* underlying algorithm does not use an IV, or if the IV has not yet1039* been set.1040*/1041public final byte[] getIV() {1042chooseFirstProvider();1043return spi.engineGetIV();1044}10451046/**1047* Returns the parameters used with this cipher.1048*1049* <p>The returned parameters may be the same that were used to initialize1050* this cipher, or may contain a combination of default and random1051* parameter values used by the underlying cipher implementation if this1052* cipher requires algorithm parameters but was not initialized with any.1053*1054* @return the parameters used with this cipher, or null if this cipher1055* does not use any parameters.1056*/1057public final AlgorithmParameters getParameters() {1058chooseFirstProvider();1059return spi.engineGetParameters();1060}10611062/**1063* Returns the exemption mechanism object used with this cipher.1064*1065* @return the exemption mechanism object used with this cipher, or1066* null if this cipher does not use any exemption mechanism.1067*/1068public final ExemptionMechanism getExemptionMechanism() {1069chooseFirstProvider();1070return exmech;1071}10721073//1074// Crypto permission check code below1075//1076private void checkCryptoPerm(CipherSpi checkSpi, Key key)1077throws InvalidKeyException {1078if (cryptoPerm == CryptoAllPermission.INSTANCE) {1079return;1080}1081// Check if key size and default parameters are within legal limits1082AlgorithmParameterSpec params;1083try {1084params = getAlgorithmParameterSpec(checkSpi.engineGetParameters());1085} catch (InvalidParameterSpecException ipse) {1086throw new InvalidKeyException1087("Unsupported default algorithm parameters");1088}1089if (!passCryptoPermCheck(checkSpi, key, params)) {1090throw new InvalidKeyException(1091"Illegal key size or default parameters");1092}1093}10941095private void checkCryptoPerm(CipherSpi checkSpi, Key key,1096AlgorithmParameterSpec params) throws InvalidKeyException,1097InvalidAlgorithmParameterException {1098if (cryptoPerm == CryptoAllPermission.INSTANCE) {1099return;1100}1101// Determine keysize and check if it is within legal limits1102if (!passCryptoPermCheck(checkSpi, key, null)) {1103throw new InvalidKeyException("Illegal key size");1104}1105if ((params != null) && (!passCryptoPermCheck(checkSpi, key, params))) {1106throw new InvalidAlgorithmParameterException("Illegal parameters");1107}1108}11091110private void checkCryptoPerm(CipherSpi checkSpi, Key key,1111AlgorithmParameters params)1112throws InvalidKeyException, InvalidAlgorithmParameterException {1113if (cryptoPerm == CryptoAllPermission.INSTANCE) {1114return;1115}1116// Convert the specified parameters into specs and then delegate.1117AlgorithmParameterSpec pSpec;1118try {1119pSpec = getAlgorithmParameterSpec(params);1120} catch (InvalidParameterSpecException ipse) {1121throw new InvalidAlgorithmParameterException1122("Failed to retrieve algorithm parameter specification");1123}1124checkCryptoPerm(checkSpi, key, pSpec);1125}11261127private boolean passCryptoPermCheck(CipherSpi checkSpi, Key key,1128AlgorithmParameterSpec params)1129throws InvalidKeyException {1130String em = cryptoPerm.getExemptionMechanism();1131int keySize = checkSpi.engineGetKeySize(key);1132// Use the "algorithm" component of the cipher1133// transformation so that the perm check would1134// work when the key has the "aliased" algo.1135String algComponent;1136int index = transformation.indexOf('/');1137if (index != -1) {1138algComponent = transformation.substring(0, index);1139} else {1140algComponent = transformation;1141}1142CryptoPermission checkPerm =1143new CryptoPermission(algComponent, keySize, params, em);11441145if (!cryptoPerm.implies(checkPerm)) {1146if (debug != null) {1147debug.println("Crypto Permission check failed");1148debug.println("granted: " + cryptoPerm);1149debug.println("requesting: " + checkPerm);1150}1151return false;1152}1153if (exmech == null) {1154return true;1155}1156try {1157if (!exmech.isCryptoAllowed(key)) {1158if (debug != null) {1159debug.println(exmech.getName() + " isn't enforced");1160}1161return false;1162}1163} catch (ExemptionMechanismException eme) {1164if (debug != null) {1165debug.println("Cannot determine whether "+1166exmech.getName() + " has been enforced");1167eme.printStackTrace();1168}1169return false;1170}1171return true;1172}11731174// check if opmode is one of the defined constants1175// throw InvalidParameterExeption if not1176private static void checkOpmode(int opmode) {1177if ((opmode < ENCRYPT_MODE) || (opmode > UNWRAP_MODE)) {1178throw new InvalidParameterException("Invalid operation mode");1179}1180}11811182/**1183* Initializes this cipher with a key.1184*1185* <p>The cipher is initialized for one of the following four operations:1186* encryption, decryption, key wrapping or key unwrapping, depending1187* on the value of {@code opmode}.1188*1189* <p>If this cipher requires any algorithm parameters that cannot be1190* derived from the given {@code key}, the underlying cipher1191* implementation is supposed to generate the required parameters itself1192* (using provider-specific default or random values) if it is being1193* initialized for encryption or key wrapping, and raise an1194* {@code InvalidKeyException} if it is being1195* initialized for decryption or key unwrapping.1196* The generated parameters can be retrieved using1197* {@link #getParameters() getParameters} or1198* {@link #getIV() getIV} (if the parameter is an IV).1199*1200* <p>If this cipher requires algorithm parameters that cannot be1201* derived from the input parameters, and there are no reasonable1202* provider-specific default values, initialization will1203* necessarily fail.1204*1205* <p>If this cipher (including its underlying feedback or padding scheme)1206* requires any random bytes (e.g., for parameter generation), it will get1207* them using the {@link java.security.SecureRandom}1208* implementation of the highest-priority1209* installed provider as the source of randomness.1210* (If none of the installed providers supply an implementation of1211* SecureRandom, a system-provided source of randomness will be used.)1212*1213* <p>Note that when a Cipher object is initialized, it loses all1214* previously-acquired state. In other words, initializing a Cipher is1215* equivalent to creating a new instance of that Cipher and initializing1216* it.1217*1218* @param opmode the operation mode of this cipher (this is one of1219* the following:1220* {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},1221* {@code WRAP_MODE} or {@code UNWRAP_MODE})1222* @param key the key1223*1224* @exception InvalidKeyException if the given key is inappropriate for1225* initializing this cipher, or requires1226* algorithm parameters that cannot be1227* determined from the given key, or if the given key has a keysize that1228* exceeds the maximum allowable keysize (as determined from the1229* configured jurisdiction policy files).1230* @throws UnsupportedOperationException if {@code opmode} is1231* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented1232* by the underlying {@code CipherSpi}.1233*/1234public final void init(int opmode, Key key) throws InvalidKeyException {1235init(opmode, key, JCAUtil.getDefSecureRandom());1236}12371238/**1239* Initializes this cipher with a key and a source of randomness.1240*1241* <p>The cipher is initialized for one of the following four operations:1242* encryption, decryption, key wrapping or key unwrapping, depending1243* on the value of {@code opmode}.1244*1245* <p>If this cipher requires any algorithm parameters that cannot be1246* derived from the given {@code key}, the underlying cipher1247* implementation is supposed to generate the required parameters itself1248* (using provider-specific default or random values) if it is being1249* initialized for encryption or key wrapping, and raise an1250* {@code InvalidKeyException} if it is being1251* initialized for decryption or key unwrapping.1252* The generated parameters can be retrieved using1253* {@link #getParameters() getParameters} or1254* {@link #getIV() getIV} (if the parameter is an IV).1255*1256* <p>If this cipher requires algorithm parameters that cannot be1257* derived from the input parameters, and there are no reasonable1258* provider-specific default values, initialization will1259* necessarily fail.1260*1261* <p>If this cipher (including its underlying feedback or padding scheme)1262* requires any random bytes (e.g., for parameter generation), it will get1263* them from {@code random}.1264*1265* <p>Note that when a Cipher object is initialized, it loses all1266* previously-acquired state. In other words, initializing a Cipher is1267* equivalent to creating a new instance of that Cipher and initializing1268* it.1269*1270* @param opmode the operation mode of this cipher (this is one of the1271* following:1272* {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},1273* {@code WRAP_MODE} or {@code UNWRAP_MODE})1274* @param key the encryption key1275* @param random the source of randomness1276*1277* @exception InvalidKeyException if the given key is inappropriate for1278* initializing this cipher, or requires1279* algorithm parameters that cannot be1280* determined from the given key, or if the given key has a keysize that1281* exceeds the maximum allowable keysize (as determined from the1282* configured jurisdiction policy files).1283* @throws UnsupportedOperationException if {@code opmode} is1284* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented1285* by the underlying {@code CipherSpi}.1286*/1287public final void init(int opmode, Key key, SecureRandom random)1288throws InvalidKeyException1289{1290initialized = false;1291checkOpmode(opmode);12921293if (spi != null) {1294checkCryptoPerm(spi, key);1295spi.engineInit(opmode, key, random);1296} else {1297try {1298chooseProvider(I_KEY, opmode, key, null, null, random);1299} catch (InvalidAlgorithmParameterException e) {1300// should never occur1301throw new InvalidKeyException(e);1302}1303}13041305initialized = true;1306this.opmode = opmode;13071308if (!skipDebug && pdebug != null) {1309pdebug.println(this.toString());1310}1311}13121313/**1314* Initializes this cipher with a key and a set of algorithm1315* parameters.1316*1317* <p>The cipher is initialized for one of the following four operations:1318* encryption, decryption, key wrapping or key unwrapping, depending1319* on the value of {@code opmode}.1320*1321* <p>If this cipher requires any algorithm parameters and1322* {@code params} is null, the underlying cipher implementation is1323* supposed to generate the required parameters itself (using1324* provider-specific default or random values) if it is being1325* initialized for encryption or key wrapping, and raise an1326* {@code InvalidAlgorithmParameterException} if it is being1327* initialized for decryption or key unwrapping.1328* The generated parameters can be retrieved using1329* {@link #getParameters() getParameters} or1330* {@link #getIV() getIV} (if the parameter is an IV).1331*1332* <p>If this cipher requires algorithm parameters that cannot be1333* derived from the input parameters, and there are no reasonable1334* provider-specific default values, initialization will1335* necessarily fail.1336*1337* <p>If this cipher (including its underlying feedback or padding scheme)1338* requires any random bytes (e.g., for parameter generation), it will get1339* them using the {@link java.security.SecureRandom}1340* implementation of the highest-priority1341* installed provider as the source of randomness.1342* (If none of the installed providers supply an implementation of1343* SecureRandom, a system-provided source of randomness will be used.)1344*1345* <p>Note that when a Cipher object is initialized, it loses all1346* previously-acquired state. In other words, initializing a Cipher is1347* equivalent to creating a new instance of that Cipher and initializing1348* it.1349*1350* @param opmode the operation mode of this cipher (this is one of the1351* following:1352* {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},1353* {@code WRAP_MODE} or {@code UNWRAP_MODE})1354* @param key the encryption key1355* @param params the algorithm parameters1356*1357* @exception InvalidKeyException if the given key is inappropriate for1358* initializing this cipher, or its keysize exceeds the maximum allowable1359* keysize (as determined from the configured jurisdiction policy files).1360* @exception InvalidAlgorithmParameterException if the given algorithm1361* parameters are inappropriate for this cipher,1362* or this cipher requires1363* algorithm parameters and {@code params} is null, or the given1364* algorithm parameters imply a cryptographic strength that would exceed1365* the legal limits (as determined from the configured jurisdiction1366* policy files).1367* @throws UnsupportedOperationException if {@code opmode} is1368* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented1369* by the underlying {@code CipherSpi}.1370*/1371public final void init(int opmode, Key key, AlgorithmParameterSpec params)1372throws InvalidKeyException, InvalidAlgorithmParameterException1373{1374init(opmode, key, params, JCAUtil.getDefSecureRandom());1375}13761377/**1378* Initializes this cipher with a key, a set of algorithm1379* parameters, and a source of randomness.1380*1381* <p>The cipher is initialized for one of the following four operations:1382* encryption, decryption, key wrapping or key unwrapping, depending1383* on the value of {@code opmode}.1384*1385* <p>If this cipher requires any algorithm parameters and1386* {@code params} is null, the underlying cipher implementation is1387* supposed to generate the required parameters itself (using1388* provider-specific default or random values) if it is being1389* initialized for encryption or key wrapping, and raise an1390* {@code InvalidAlgorithmParameterException} if it is being1391* initialized for decryption or key unwrapping.1392* The generated parameters can be retrieved using1393* {@link #getParameters() getParameters} or1394* {@link #getIV() getIV} (if the parameter is an IV).1395*1396* <p>If this cipher requires algorithm parameters that cannot be1397* derived from the input parameters, and there are no reasonable1398* provider-specific default values, initialization will1399* necessarily fail.1400*1401* <p>If this cipher (including its underlying feedback or padding scheme)1402* requires any random bytes (e.g., for parameter generation), it will get1403* them from {@code random}.1404*1405* <p>Note that when a Cipher object is initialized, it loses all1406* previously-acquired state. In other words, initializing a Cipher is1407* equivalent to creating a new instance of that Cipher and initializing1408* it.1409*1410* @param opmode the operation mode of this cipher (this is one of the1411* following:1412* {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},1413* {@code WRAP_MODE} or {@code UNWRAP_MODE})1414* @param key the encryption key1415* @param params the algorithm parameters1416* @param random the source of randomness1417*1418* @exception InvalidKeyException if the given key is inappropriate for1419* initializing this cipher, or its keysize exceeds the maximum allowable1420* keysize (as determined from the configured jurisdiction policy files).1421* @exception InvalidAlgorithmParameterException if the given algorithm1422* parameters are inappropriate for this cipher,1423* or this cipher requires1424* algorithm parameters and {@code params} is null, or the given1425* algorithm parameters imply a cryptographic strength that would exceed1426* the legal limits (as determined from the configured jurisdiction1427* policy files).1428* @throws UnsupportedOperationException if {@code opmode} is1429* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented1430* by the underlying {@code CipherSpi}.1431*/1432public final void init(int opmode, Key key, AlgorithmParameterSpec params,1433SecureRandom random)1434throws InvalidKeyException, InvalidAlgorithmParameterException1435{1436initialized = false;1437checkOpmode(opmode);14381439if (spi != null) {1440checkCryptoPerm(spi, key, params);1441spi.engineInit(opmode, key, params, random);1442} else {1443chooseProvider(I_PARAMSPEC, opmode, key, params, null, random);1444}14451446initialized = true;1447this.opmode = opmode;14481449if (!skipDebug && pdebug != null) {1450pdebug.println(this.toString());1451}1452}14531454/**1455* Initializes this cipher with a key and a set of algorithm1456* parameters.1457*1458* <p>The cipher is initialized for one of the following four operations:1459* encryption, decryption, key wrapping or key unwrapping, depending1460* on the value of {@code opmode}.1461*1462* <p>If this cipher requires any algorithm parameters and1463* {@code params} is null, the underlying cipher implementation is1464* supposed to generate the required parameters itself (using1465* provider-specific default or random values) if it is being1466* initialized for encryption or key wrapping, and raise an1467* {@code InvalidAlgorithmParameterException} if it is being1468* initialized for decryption or key unwrapping.1469* The generated parameters can be retrieved using1470* {@link #getParameters() getParameters} or1471* {@link #getIV() getIV} (if the parameter is an IV).1472*1473* <p>If this cipher requires algorithm parameters that cannot be1474* derived from the input parameters, and there are no reasonable1475* provider-specific default values, initialization will1476* necessarily fail.1477*1478* <p>If this cipher (including its underlying feedback or padding scheme)1479* requires any random bytes (e.g., for parameter generation), it will get1480* them using the {@link java.security.SecureRandom}1481* implementation of the highest-priority1482* installed provider as the source of randomness.1483* (If none of the installed providers supply an implementation of1484* SecureRandom, a system-provided source of randomness will be used.)1485*1486* <p>Note that when a Cipher object is initialized, it loses all1487* previously-acquired state. In other words, initializing a Cipher is1488* equivalent to creating a new instance of that Cipher and initializing1489* it.1490*1491* @param opmode the operation mode of this cipher (this is one of the1492* following: {@code ENCRYPT_MODE},1493* {@code DECRYPT_MODE}, {@code WRAP_MODE}1494* or {@code UNWRAP_MODE})1495* @param key the encryption key1496* @param params the algorithm parameters1497*1498* @exception InvalidKeyException if the given key is inappropriate for1499* initializing this cipher, or its keysize exceeds the maximum allowable1500* keysize (as determined from the configured jurisdiction policy files).1501* @exception InvalidAlgorithmParameterException if the given algorithm1502* parameters are inappropriate for this cipher,1503* or this cipher requires1504* algorithm parameters and {@code params} is null, or the given1505* algorithm parameters imply a cryptographic strength that would exceed1506* the legal limits (as determined from the configured jurisdiction1507* policy files).1508* @throws UnsupportedOperationException if {@code opmode} is1509* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented1510* by the underlying {@code CipherSpi}.1511*/1512public final void init(int opmode, Key key, AlgorithmParameters params)1513throws InvalidKeyException, InvalidAlgorithmParameterException1514{1515init(opmode, key, params, JCAUtil.getDefSecureRandom());1516}15171518/**1519* Initializes this cipher with a key, a set of algorithm1520* parameters, and a source of randomness.1521*1522* <p>The cipher is initialized for one of the following four operations:1523* encryption, decryption, key wrapping or key unwrapping, depending1524* on the value of {@code opmode}.1525*1526* <p>If this cipher requires any algorithm parameters and1527* {@code params} is null, the underlying cipher implementation is1528* supposed to generate the required parameters itself (using1529* provider-specific default or random values) if it is being1530* initialized for encryption or key wrapping, and raise an1531* {@code InvalidAlgorithmParameterException} if it is being1532* initialized for decryption or key unwrapping.1533* The generated parameters can be retrieved using1534* {@link #getParameters() getParameters} or1535* {@link #getIV() getIV} (if the parameter is an IV).1536*1537* <p>If this cipher requires algorithm parameters that cannot be1538* derived from the input parameters, and there are no reasonable1539* provider-specific default values, initialization will1540* necessarily fail.1541*1542* <p>If this cipher (including its underlying feedback or padding scheme)1543* requires any random bytes (e.g., for parameter generation), it will get1544* them from {@code random}.1545*1546* <p>Note that when a Cipher object is initialized, it loses all1547* previously-acquired state. In other words, initializing a Cipher is1548* equivalent to creating a new instance of that Cipher and initializing1549* it.1550*1551* @param opmode the operation mode of this cipher (this is one of the1552* following: {@code ENCRYPT_MODE},1553* {@code DECRYPT_MODE}, {@code WRAP_MODE}1554* or {@code UNWRAP_MODE})1555* @param key the encryption key1556* @param params the algorithm parameters1557* @param random the source of randomness1558*1559* @exception InvalidKeyException if the given key is inappropriate for1560* initializing this cipher, or its keysize exceeds the maximum allowable1561* keysize (as determined from the configured jurisdiction policy files).1562* @exception InvalidAlgorithmParameterException if the given algorithm1563* parameters are inappropriate for this cipher,1564* or this cipher requires1565* algorithm parameters and {@code params} is null, or the given1566* algorithm parameters imply a cryptographic strength that would exceed1567* the legal limits (as determined from the configured jurisdiction1568* policy files).1569* @throws UnsupportedOperationException if {@code opmode} is1570* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented1571* by the underlying {@code CipherSpi}.1572*/1573public final void init(int opmode, Key key, AlgorithmParameters params,1574SecureRandom random)1575throws InvalidKeyException, InvalidAlgorithmParameterException1576{1577initialized = false;1578checkOpmode(opmode);15791580if (spi != null) {1581checkCryptoPerm(spi, key, params);1582spi.engineInit(opmode, key, params, random);1583} else {1584chooseProvider(I_PARAMS, opmode, key, null, params, random);1585}15861587initialized = true;1588this.opmode = opmode;15891590if (!skipDebug && pdebug != null) {1591pdebug.println(this.toString());1592}1593}15941595/**1596* Initializes this cipher with the public key from the given certificate.1597* <p> The cipher is initialized for one of the following four operations:1598* encryption, decryption, key wrapping or key unwrapping, depending1599* on the value of {@code opmode}.1600*1601* <p>If the certificate is of type X.509 and has a <i>key usage</i>1602* extension field marked as critical, and the value of the <i>key usage</i>1603* extension field implies that the public key in1604* the certificate and its corresponding private key are not1605* supposed to be used for the operation represented by the value1606* of {@code opmode},1607* an {@code InvalidKeyException}1608* is thrown.1609*1610* <p> If this cipher requires any algorithm parameters that cannot be1611* derived from the public key in the given certificate, the underlying1612* cipher1613* implementation is supposed to generate the required parameters itself1614* (using provider-specific default or random values) if it is being1615* initialized for encryption or key wrapping, and raise an1616* {@code InvalidKeyException} if it is being initialized for decryption or1617* key unwrapping.1618* The generated parameters can be retrieved using1619* {@link #getParameters() getParameters} or1620* {@link #getIV() getIV} (if the parameter is an IV).1621*1622* <p>If this cipher requires algorithm parameters that cannot be1623* derived from the input parameters, and there are no reasonable1624* provider-specific default values, initialization will1625* necessarily fail.1626*1627* <p>If this cipher (including its underlying feedback or padding scheme)1628* requires any random bytes (e.g., for parameter generation), it will get1629* them using the1630* {@code SecureRandom}1631* implementation of the highest-priority1632* installed provider as the source of randomness.1633* (If none of the installed providers supply an implementation of1634* SecureRandom, a system-provided source of randomness will be used.)1635*1636* <p>Note that when a Cipher object is initialized, it loses all1637* previously-acquired state. In other words, initializing a Cipher is1638* equivalent to creating a new instance of that Cipher and initializing1639* it.1640*1641* @param opmode the operation mode of this cipher (this is one of the1642* following:1643* {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},1644* {@code WRAP_MODE} or {@code UNWRAP_MODE})1645* @param certificate the certificate1646*1647* @exception InvalidKeyException if the public key in the given1648* certificate is inappropriate for initializing this cipher, or this1649* cipher requires algorithm parameters that cannot be determined from the1650* public key in the given certificate, or the keysize of the public key1651* in the given certificate has a keysize that exceeds the maximum1652* allowable keysize (as determined by the configured jurisdiction policy1653* files).1654* @throws UnsupportedOperationException if {@code opmode} is1655* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented1656* by the underlying {@code CipherSpi}.1657*/1658public final void init(int opmode, Certificate certificate)1659throws InvalidKeyException1660{1661init(opmode, certificate, JCAUtil.getDefSecureRandom());1662}16631664/**1665* Initializes this cipher with the public key from the given certificate1666* and a source of randomness.1667*1668* <p>The cipher is initialized for one of the following four operations:1669* encryption, decryption, key wrapping1670* or key unwrapping, depending on1671* the value of {@code opmode}.1672*1673* <p>If the certificate is of type X.509 and has a <i>key usage</i>1674* extension field marked as critical, and the value of the <i>key usage</i>1675* extension field implies that the public key in1676* the certificate and its corresponding private key are not1677* supposed to be used for the operation represented by the value of1678* {@code opmode},1679* an {@code InvalidKeyException}1680* is thrown.1681*1682* <p>If this cipher requires any algorithm parameters that cannot be1683* derived from the public key in the given {@code certificate},1684* the underlying cipher1685* implementation is supposed to generate the required parameters itself1686* (using provider-specific default or random values) if it is being1687* initialized for encryption or key wrapping, and raise an1688* {@code InvalidKeyException} if it is being1689* initialized for decryption or key unwrapping.1690* The generated parameters can be retrieved using1691* {@link #getParameters() getParameters} or1692* {@link #getIV() getIV} (if the parameter is an IV).1693*1694* <p>If this cipher requires algorithm parameters that cannot be1695* derived from the input parameters, and there are no reasonable1696* provider-specific default values, initialization will1697* necessarily fail.1698*1699* <p>If this cipher (including its underlying feedback or padding scheme)1700* requires any random bytes (e.g., for parameter generation), it will get1701* them from {@code random}.1702*1703* <p>Note that when a Cipher object is initialized, it loses all1704* previously-acquired state. In other words, initializing a Cipher is1705* equivalent to creating a new instance of that Cipher and initializing1706* it.1707*1708* @param opmode the operation mode of this cipher (this is one of the1709* following:1710* {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},1711* {@code WRAP_MODE} or {@code UNWRAP_MODE})1712* @param certificate the certificate1713* @param random the source of randomness1714*1715* @exception InvalidKeyException if the public key in the given1716* certificate is inappropriate for initializing this cipher, or this1717* cipher1718* requires algorithm parameters that cannot be determined from the1719* public key in the given certificate, or the keysize of the public key1720* in the given certificate has a keysize that exceeds the maximum1721* allowable keysize (as determined by the configured jurisdiction policy1722* files).1723* @throws UnsupportedOperationException if {@code opmode} is1724* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented1725* by the underlying {@code CipherSpi}.1726*/1727public final void init(int opmode, Certificate certificate,1728SecureRandom random)1729throws InvalidKeyException1730{1731initialized = false;1732checkOpmode(opmode);17331734// Check key usage if the certificate is of type X.509.1735if (certificate instanceof java.security.cert.X509Certificate) {1736// Check whether the cert has a key usage extension1737// marked as a critical extension.1738X509Certificate cert = (X509Certificate)certificate;1739Set<String> critSet = cert.getCriticalExtensionOIDs();17401741if (critSet != null && !critSet.isEmpty()1742&& critSet.contains(KnownOIDs.KeyUsage.value())) {1743boolean[] keyUsageInfo = cert.getKeyUsage();1744// keyUsageInfo[2] is for keyEncipherment;1745// keyUsageInfo[3] is for dataEncipherment.1746if ((keyUsageInfo != null) &&1747(((opmode == Cipher.ENCRYPT_MODE) &&1748(keyUsageInfo.length > 3) &&1749(keyUsageInfo[3] == false)) ||1750((opmode == Cipher.WRAP_MODE) &&1751(keyUsageInfo.length > 2) &&1752(keyUsageInfo[2] == false)))) {1753throw new InvalidKeyException("Wrong key usage");1754}1755}1756}17571758PublicKey publicKey =1759(certificate==null? null:certificate.getPublicKey());17601761if (spi != null) {1762checkCryptoPerm(spi, publicKey);1763spi.engineInit(opmode, publicKey, random);1764} else {1765try {1766chooseProvider(I_CERT, opmode, publicKey, null, null, random);1767} catch (InvalidAlgorithmParameterException e) {1768// should never occur1769throw new InvalidKeyException(e);1770}1771}17721773initialized = true;1774this.opmode = opmode;17751776if (!skipDebug && pdebug != null) {1777pdebug.println(this.toString());1778}1779}17801781/**1782* Ensures that Cipher is in a valid state for update() and doFinal()1783* calls - should be initialized and in ENCRYPT_MODE or DECRYPT_MODE.1784* @throws IllegalStateException if Cipher object is not in valid state.1785*/1786private void checkCipherState() {1787if (!(this instanceof NullCipher)) {1788if (!initialized) {1789throw new IllegalStateException("Cipher not initialized");1790}1791if ((opmode != Cipher.ENCRYPT_MODE) &&1792(opmode != Cipher.DECRYPT_MODE)) {1793throw new IllegalStateException("Cipher not initialized " +1794"for encryption/decryption");1795}1796}1797}17981799/**1800* Continues a multiple-part encryption or decryption operation1801* (depending on how this cipher was initialized), processing another data1802* part.1803*1804* <p>The bytes in the {@code input} buffer are processed, and the1805* result is stored in a new buffer.1806*1807* <p>If {@code input} has a length of zero, this method returns1808* {@code null}.1809*1810* @param input the input buffer1811*1812* @return the new buffer with the result, or null if the underlying1813* cipher is a block cipher and the input data is too short to result in a1814* new block.1815*1816* @exception IllegalStateException if this cipher is in a wrong state1817* (e.g., has not been initialized)1818*/1819public final byte[] update(byte[] input) {1820checkCipherState();18211822// Input sanity check1823if (input == null) {1824throw new IllegalArgumentException("Null input buffer");1825}18261827chooseFirstProvider();1828if (input.length == 0) {1829return null;1830}1831return spi.engineUpdate(input, 0, input.length);1832}18331834/**1835* Continues a multiple-part encryption or decryption operation1836* (depending on how this cipher was initialized), processing another data1837* part.1838*1839* <p>The first {@code inputLen} bytes in the {@code input}1840* buffer, starting at {@code inputOffset} inclusive, are processed,1841* and the result is stored in a new buffer.1842*1843* <p>If {@code inputLen} is zero, this method returns1844* {@code null}.1845*1846* @param input the input buffer1847* @param inputOffset the offset in {@code input} where the input1848* starts1849* @param inputLen the input length1850*1851* @return the new buffer with the result, or null if the underlying1852* cipher is a block cipher and the input data is too short to result in a1853* new block.1854*1855* @exception IllegalStateException if this cipher is in a wrong state1856* (e.g., has not been initialized)1857*/1858public final byte[] update(byte[] input, int inputOffset, int inputLen) {1859checkCipherState();18601861// Input sanity check1862if (input == null || inputOffset < 01863|| inputLen > (input.length - inputOffset) || inputLen < 0) {1864throw new IllegalArgumentException("Bad arguments");1865}18661867chooseFirstProvider();1868if (inputLen == 0) {1869return null;1870}1871return spi.engineUpdate(input, inputOffset, inputLen);1872}18731874/**1875* Continues a multiple-part encryption or decryption operation1876* (depending on how this cipher was initialized), processing another data1877* part.1878*1879* <p>The first {@code inputLen} bytes in the {@code input}1880* buffer, starting at {@code inputOffset} inclusive, are processed,1881* and the result is stored in the {@code output} buffer.1882*1883* <p>If the {@code output} buffer is too small to hold the result,1884* a {@code ShortBufferException} is thrown. In this case, repeat this1885* call with a larger output buffer. Use1886* {@link #getOutputSize(int) getOutputSize} to determine how big1887* the output buffer should be.1888*1889* <p>If {@code inputLen} is zero, this method returns1890* a length of zero.1891*1892* <p>Note: this method should be copy-safe, which means the1893* {@code input} and {@code output} buffers can reference1894* the same byte array and no unprocessed input data is overwritten1895* when the result is copied into the output buffer.1896*1897* @param input the input buffer1898* @param inputOffset the offset in {@code input} where the input1899* starts1900* @param inputLen the input length1901* @param output the buffer for the result1902*1903* @return the number of bytes stored in {@code output}1904*1905* @exception IllegalStateException if this cipher is in a wrong state1906* (e.g., has not been initialized)1907* @exception ShortBufferException if the given output buffer is too small1908* to hold the result1909*/1910public final int update(byte[] input, int inputOffset, int inputLen,1911byte[] output)1912throws ShortBufferException {1913checkCipherState();19141915// Input sanity check1916if (input == null || inputOffset < 01917|| inputLen > (input.length - inputOffset) || inputLen < 0) {1918throw new IllegalArgumentException("Bad arguments");1919}19201921chooseFirstProvider();1922if (inputLen == 0) {1923return 0;1924}1925return spi.engineUpdate(input, inputOffset, inputLen,1926output, 0);1927}19281929/**1930* Continues a multiple-part encryption or decryption operation1931* (depending on how this cipher was initialized), processing another data1932* part.1933*1934* <p>The first {@code inputLen} bytes in the {@code input}1935* buffer, starting at {@code inputOffset} inclusive, are processed,1936* and the result is stored in the {@code output} buffer, starting at1937* {@code outputOffset} inclusive.1938*1939* <p>If the {@code output} buffer is too small to hold the result,1940* a {@code ShortBufferException} is thrown. In this case, repeat this1941* call with a larger output buffer. Use1942* {@link #getOutputSize(int) getOutputSize} to determine how big1943* the output buffer should be.1944*1945* <p>If {@code inputLen} is zero, this method returns1946* a length of zero.1947*1948* <p>Note: this method should be copy-safe, which means the1949* {@code input} and {@code output} buffers can reference1950* the same byte array and no unprocessed input data is overwritten1951* when the result is copied into the output buffer.1952*1953* @param input the input buffer1954* @param inputOffset the offset in {@code input} where the input1955* starts1956* @param inputLen the input length1957* @param output the buffer for the result1958* @param outputOffset the offset in {@code output} where the result1959* is stored1960*1961* @return the number of bytes stored in {@code output}1962*1963* @exception IllegalStateException if this cipher is in a wrong state1964* (e.g., has not been initialized)1965* @exception ShortBufferException if the given output buffer is too small1966* to hold the result1967*/1968public final int update(byte[] input, int inputOffset, int inputLen,1969byte[] output, int outputOffset)1970throws ShortBufferException {1971checkCipherState();19721973// Input sanity check1974if (input == null || inputOffset < 01975|| inputLen > (input.length - inputOffset) || inputLen < 01976|| outputOffset < 0) {1977throw new IllegalArgumentException("Bad arguments");1978}19791980chooseFirstProvider();1981if (inputLen == 0) {1982return 0;1983}1984return spi.engineUpdate(input, inputOffset, inputLen,1985output, outputOffset);1986}19871988/**1989* Continues a multiple-part encryption or decryption operation1990* (depending on how this cipher was initialized), processing another data1991* part.1992*1993* <p>All {@code input.remaining()} bytes starting at1994* {@code input.position()} are processed. The result is stored1995* in the output buffer.1996* Upon return, the input buffer's position will be equal1997* to its limit; its limit will not have changed. The output buffer's1998* position will have advanced by n, where n is the value returned1999* by this method; the output buffer's limit will not have changed.2000*2001* <p>If {@code output.remaining()} bytes are insufficient to2002* hold the result, a {@code ShortBufferException} is thrown.2003* In this case, repeat this call with a larger output buffer. Use2004* {@link #getOutputSize(int) getOutputSize} to determine how big2005* the output buffer should be.2006*2007* <p>Note: this method should be copy-safe, which means the2008* {@code input} and {@code output} buffers can reference2009* the same block of memory and no unprocessed input data is overwritten2010* when the result is copied into the output buffer.2011*2012* @param input the input ByteBuffer2013* @param output the output ByteByffer2014*2015* @return the number of bytes stored in {@code output}2016*2017* @exception IllegalStateException if this cipher is in a wrong state2018* (e.g., has not been initialized)2019* @exception IllegalArgumentException if input and output are the2020* same object2021* @exception ReadOnlyBufferException if the output buffer is read-only2022* @exception ShortBufferException if there is insufficient space in the2023* output buffer2024* @since 1.52025*/2026public final int update(ByteBuffer input, ByteBuffer output)2027throws ShortBufferException {2028checkCipherState();20292030if ((input == null) || (output == null)) {2031throw new IllegalArgumentException("Buffers must not be null");2032}2033if (input == output) {2034throw new IllegalArgumentException("Input and output buffers must "2035+ "not be the same object, consider using buffer.duplicate()");2036}2037if (output.isReadOnly()) {2038throw new ReadOnlyBufferException();2039}20402041chooseFirstProvider();2042return spi.engineUpdate(input, output);2043}20442045/**2046* Finishes a multiple-part encryption or decryption operation, depending2047* on how this cipher was initialized.2048*2049* <p>Input data that may have been buffered during a previous2050* {@code update} operation is processed, with padding (if requested)2051* being applied.2052* If an AEAD mode such as GCM/CCM is being used, the authentication2053* tag is appended in the case of encryption, or verified in the2054* case of decryption.2055* The result is stored in a new buffer.2056*2057* <p>Upon finishing, this method resets this cipher object to the state2058* it was in when previously initialized via a call to {@code init}.2059* That is, the object is reset and available to encrypt or decrypt2060* (depending on the operation mode that was specified in the call to2061* {@code init}) more data.2062*2063* <p>Note: if any exception is thrown, this cipher object may need to2064* be reset before it can be used again.2065*2066* @return the new buffer with the result2067*2068* @exception IllegalStateException if this cipher is in a wrong state2069* (e.g., has not been initialized)2070* @exception IllegalBlockSizeException if this cipher is a block cipher,2071* no padding has been requested (only in encryption mode), and the total2072* input length of the data processed by this cipher is not a multiple of2073* block size; or if this encryption algorithm is unable to2074* process the input data provided.2075* @exception BadPaddingException if this cipher is in decryption mode,2076* and (un)padding has been requested, but the decrypted data is not2077* bounded by the appropriate padding bytes2078* @exception AEADBadTagException if this cipher is decrypting in an2079* AEAD mode (such as GCM/CCM), and the received authentication tag2080* does not match the calculated value2081*/2082public final byte[] doFinal()2083throws IllegalBlockSizeException, BadPaddingException {2084checkCipherState();20852086chooseFirstProvider();2087return spi.engineDoFinal(null, 0, 0);2088}20892090/**2091* Finishes a multiple-part encryption or decryption operation, depending2092* on how this cipher was initialized.2093*2094* <p>Input data that may have been buffered during a previous2095* {@code update} operation is processed, with padding (if requested)2096* being applied.2097* If an AEAD mode such as GCM/CCM is being used, the authentication2098* tag is appended in the case of encryption, or verified in the2099* case of decryption.2100* The result is stored in the {@code output} buffer, starting at2101* {@code outputOffset} inclusive.2102*2103* <p>If the {@code output} buffer is too small to hold the result,2104* a {@code ShortBufferException} is thrown. In this case, repeat this2105* call with a larger output buffer. Use2106* {@link #getOutputSize(int) getOutputSize} to determine how big2107* the output buffer should be.2108*2109* <p>Upon finishing, this method resets this cipher object to the state2110* it was in when previously initialized via a call to {@code init}.2111* That is, the object is reset and available to encrypt or decrypt2112* (depending on the operation mode that was specified in the call to2113* {@code init}) more data.2114*2115* <p>Note: if any exception is thrown, this cipher object may need to2116* be reset before it can be used again.2117*2118* @param output the buffer for the result2119* @param outputOffset the offset in {@code output} where the result2120* is stored2121*2122* @return the number of bytes stored in {@code output}2123*2124* @exception IllegalStateException if this cipher is in a wrong state2125* (e.g., has not been initialized)2126* @exception IllegalBlockSizeException if this cipher is a block cipher,2127* no padding has been requested (only in encryption mode), and the total2128* input length of the data processed by this cipher is not a multiple of2129* block size; or if this encryption algorithm is unable to2130* process the input data provided.2131* @exception ShortBufferException if the given output buffer is too small2132* to hold the result2133* @exception BadPaddingException if this cipher is in decryption mode,2134* and (un)padding has been requested, but the decrypted data is not2135* bounded by the appropriate padding bytes2136* @exception AEADBadTagException if this cipher is decrypting in an2137* AEAD mode (such as GCM/CCM), and the received authentication tag2138* does not match the calculated value2139*/2140public final int doFinal(byte[] output, int outputOffset)2141throws IllegalBlockSizeException, ShortBufferException,2142BadPaddingException {2143checkCipherState();21442145// Input sanity check2146if ((output == null) || (outputOffset < 0)) {2147throw new IllegalArgumentException("Bad arguments");2148}21492150chooseFirstProvider();2151return spi.engineDoFinal(null, 0, 0, output, outputOffset);2152}21532154/**2155* Encrypts or decrypts data in a single-part operation, or finishes a2156* multiple-part operation. The data is encrypted or decrypted,2157* depending on how this cipher was initialized.2158*2159* <p>The bytes in the {@code input} buffer, and any input bytes that2160* may have been buffered during a previous {@code update} operation,2161* are processed, with padding (if requested) being applied.2162* If an AEAD mode such as GCM/CCM is being used, the authentication2163* tag is appended in the case of encryption, or verified in the2164* case of decryption.2165* The result is stored in a new buffer.2166*2167* <p>Upon finishing, this method resets this cipher object to the state2168* it was in when previously initialized via a call to {@code init}.2169* That is, the object is reset and available to encrypt or decrypt2170* (depending on the operation mode that was specified in the call to2171* {@code init}) more data.2172*2173* <p>Note: if any exception is thrown, this cipher object may need to2174* be reset before it can be used again.2175*2176* @param input the input buffer2177*2178* @return the new buffer with the result2179*2180* @exception IllegalStateException if this cipher is in a wrong state2181* (e.g., has not been initialized)2182* @exception IllegalBlockSizeException if this cipher is a block cipher,2183* no padding has been requested (only in encryption mode), and the total2184* input length of the data processed by this cipher is not a multiple of2185* block size; or if this encryption algorithm is unable to2186* process the input data provided.2187* @exception BadPaddingException if this cipher is in decryption mode,2188* and (un)padding has been requested, but the decrypted data is not2189* bounded by the appropriate padding bytes2190* @exception AEADBadTagException if this cipher is decrypting in an2191* AEAD mode (such as GCM/CCM), and the received authentication tag2192* does not match the calculated value2193*/2194public final byte[] doFinal(byte[] input)2195throws IllegalBlockSizeException, BadPaddingException {2196checkCipherState();21972198// Input sanity check2199if (input == null) {2200throw new IllegalArgumentException("Null input buffer");2201}22022203chooseFirstProvider();2204return spi.engineDoFinal(input, 0, input.length);2205}22062207/**2208* Encrypts or decrypts data in a single-part operation, or finishes a2209* multiple-part operation. The data is encrypted or decrypted,2210* depending on how this cipher was initialized.2211*2212* <p>The first {@code inputLen} bytes in the {@code input}2213* buffer, starting at {@code inputOffset} inclusive, and any input2214* bytes that may have been buffered during a previous {@code update}2215* operation, are processed, with padding (if requested) being applied.2216* If an AEAD mode such as GCM/CCM is being used, the authentication2217* tag is appended in the case of encryption, or verified in the2218* case of decryption.2219* The result is stored in a new buffer.2220*2221* <p>Upon finishing, this method resets this cipher object to the state2222* it was in when previously initialized via a call to {@code init}.2223* That is, the object is reset and available to encrypt or decrypt2224* (depending on the operation mode that was specified in the call to2225* {@code init}) more data.2226*2227* <p>Note: if any exception is thrown, this cipher object may need to2228* be reset before it can be used again.2229*2230* @param input the input buffer2231* @param inputOffset the offset in {@code input} where the input2232* starts2233* @param inputLen the input length2234*2235* @return the new buffer with the result2236*2237* @exception IllegalStateException if this cipher is in a wrong state2238* (e.g., has not been initialized)2239* @exception IllegalBlockSizeException if this cipher is a block cipher,2240* no padding has been requested (only in encryption mode), and the total2241* input length of the data processed by this cipher is not a multiple of2242* block size; or if this encryption algorithm is unable to2243* process the input data provided.2244* @exception BadPaddingException if this cipher is in decryption mode,2245* and (un)padding has been requested, but the decrypted data is not2246* bounded by the appropriate padding bytes2247* @exception AEADBadTagException if this cipher is decrypting in an2248* AEAD mode (such as GCM/CCM), and the received authentication tag2249* does not match the calculated value2250*/2251public final byte[] doFinal(byte[] input, int inputOffset, int inputLen)2252throws IllegalBlockSizeException, BadPaddingException {2253checkCipherState();22542255// Input sanity check2256if (input == null || inputOffset < 02257|| inputLen > (input.length - inputOffset) || inputLen < 0) {2258throw new IllegalArgumentException("Bad arguments");2259}22602261chooseFirstProvider();2262return spi.engineDoFinal(input, inputOffset, inputLen);2263}22642265/**2266* Encrypts or decrypts data in a single-part operation, or finishes a2267* multiple-part operation. The data is encrypted or decrypted,2268* depending on how this cipher was initialized.2269*2270* <p>The first {@code inputLen} bytes in the {@code input}2271* buffer, starting at {@code inputOffset} inclusive, and any input2272* bytes that may have been buffered during a previous {@code update}2273* operation, are processed, with padding (if requested) being applied.2274* If an AEAD mode such as GCM/CCM is being used, the authentication2275* tag is appended in the case of encryption, or verified in the2276* case of decryption.2277* The result is stored in the {@code output} buffer.2278*2279* <p>If the {@code output} buffer is too small to hold the result,2280* a {@code ShortBufferException} is thrown. In this case, repeat this2281* call with a larger output buffer. Use2282* {@link #getOutputSize(int) getOutputSize} to determine how big2283* the output buffer should be.2284*2285* <p>Upon finishing, this method resets this cipher object to the state2286* it was in when previously initialized via a call to {@code init}.2287* That is, the object is reset and available to encrypt or decrypt2288* (depending on the operation mode that was specified in the call to2289* {@code init}) more data.2290*2291* <p>Note: if any exception is thrown, this cipher object may need to2292* be reset before it can be used again.2293*2294* <p>Note: this method should be copy-safe, which means the2295* {@code input} and {@code output} buffers can reference2296* the same byte array and no unprocessed input data is overwritten2297* when the result is copied into the output buffer.2298*2299* @param input the input buffer2300* @param inputOffset the offset in {@code input} where the input2301* starts2302* @param inputLen the input length2303* @param output the buffer for the result2304*2305* @return the number of bytes stored in {@code output}2306*2307* @exception IllegalStateException if this cipher is in a wrong state2308* (e.g., has not been initialized)2309* @exception IllegalBlockSizeException if this cipher is a block cipher,2310* no padding has been requested (only in encryption mode), and the total2311* input length of the data processed by this cipher is not a multiple of2312* block size; or if this encryption algorithm is unable to2313* process the input data provided.2314* @exception ShortBufferException if the given output buffer is too small2315* to hold the result2316* @exception BadPaddingException if this cipher is in decryption mode,2317* and (un)padding has been requested, but the decrypted data is not2318* bounded by the appropriate padding bytes2319* @exception AEADBadTagException if this cipher is decrypting in an2320* AEAD mode (such as GCM/CCM), and the received authentication tag2321* does not match the calculated value2322*/2323public final int doFinal(byte[] input, int inputOffset, int inputLen,2324byte[] output)2325throws ShortBufferException, IllegalBlockSizeException,2326BadPaddingException {2327checkCipherState();23282329// Input sanity check2330if (input == null || inputOffset < 02331|| inputLen > (input.length - inputOffset) || inputLen < 0) {2332throw new IllegalArgumentException("Bad arguments");2333}23342335chooseFirstProvider();2336return spi.engineDoFinal(input, inputOffset, inputLen,2337output, 0);2338}23392340/**2341* Encrypts or decrypts data in a single-part operation, or finishes a2342* multiple-part operation. The data is encrypted or decrypted,2343* depending on how this cipher was initialized.2344*2345* <p>The first {@code inputLen} bytes in the {@code input}2346* buffer, starting at {@code inputOffset} inclusive, and any input2347* bytes that may have been buffered during a previous2348* {@code update} operation, are processed, with padding2349* (if requested) being applied.2350* If an AEAD mode such as GCM/CCM is being used, the authentication2351* tag is appended in the case of encryption, or verified in the2352* case of decryption.2353* The result is stored in the {@code output} buffer, starting at2354* {@code outputOffset} inclusive.2355*2356* <p>If the {@code output} buffer is too small to hold the result,2357* a {@code ShortBufferException} is thrown. In this case, repeat this2358* call with a larger output buffer. Use2359* {@link #getOutputSize(int) getOutputSize} to determine how big2360* the output buffer should be.2361*2362* <p>Upon finishing, this method resets this cipher object to the state2363* it was in when previously initialized via a call to {@code init}.2364* That is, the object is reset and available to encrypt or decrypt2365* (depending on the operation mode that was specified in the call to2366* {@code init}) more data.2367*2368* <p>Note: if any exception is thrown, this cipher object may need to2369* be reset before it can be used again.2370*2371* <p>Note: this method should be copy-safe, which means the2372* {@code input} and {@code output} buffers can reference2373* the same byte array and no unprocessed input data is overwritten2374* when the result is copied into the output buffer.2375*2376* @param input the input buffer2377* @param inputOffset the offset in {@code input} where the input2378* starts2379* @param inputLen the input length2380* @param output the buffer for the result2381* @param outputOffset the offset in {@code output} where the result2382* is stored2383*2384* @return the number of bytes stored in {@code output}2385*2386* @exception IllegalStateException if this cipher is in a wrong state2387* (e.g., has not been initialized)2388* @exception IllegalBlockSizeException if this cipher is a block cipher,2389* no padding has been requested (only in encryption mode), and the total2390* input length of the data processed by this cipher is not a multiple of2391* block size; or if this encryption algorithm is unable to2392* process the input data provided.2393* @exception ShortBufferException if the given output buffer is too small2394* to hold the result2395* @exception BadPaddingException if this cipher is in decryption mode,2396* and (un)padding has been requested, but the decrypted data is not2397* bounded by the appropriate padding bytes2398* @exception AEADBadTagException if this cipher is decrypting in an2399* AEAD mode (such as GCM/CCM), and the received authentication tag2400* does not match the calculated value2401*/2402public final int doFinal(byte[] input, int inputOffset, int inputLen,2403byte[] output, int outputOffset)2404throws ShortBufferException, IllegalBlockSizeException,2405BadPaddingException {2406checkCipherState();24072408// Input sanity check2409if (input == null || inputOffset < 02410|| inputLen > (input.length - inputOffset) || inputLen < 02411|| outputOffset < 0) {2412throw new IllegalArgumentException("Bad arguments");2413}24142415chooseFirstProvider();2416return spi.engineDoFinal(input, inputOffset, inputLen,2417output, outputOffset);2418}24192420/**2421* Encrypts or decrypts data in a single-part operation, or finishes a2422* multiple-part operation. The data is encrypted or decrypted,2423* depending on how this cipher was initialized.2424*2425* <p>All {@code input.remaining()} bytes starting at2426* {@code input.position()} are processed.2427* If an AEAD mode such as GCM/CCM is being used, the authentication2428* tag is appended in the case of encryption, or verified in the2429* case of decryption.2430* The result is stored in the output buffer.2431* Upon return, the input buffer's position will be equal2432* to its limit; its limit will not have changed. The output buffer's2433* position will have advanced by n, where n is the value returned2434* by this method; the output buffer's limit will not have changed.2435*2436* <p>If {@code output.remaining()} bytes are insufficient to2437* hold the result, a {@code ShortBufferException} is thrown.2438* In this case, repeat this call with a larger output buffer. Use2439* {@link #getOutputSize(int) getOutputSize} to determine how big2440* the output buffer should be.2441*2442* <p>Upon finishing, this method resets this cipher object to the state2443* it was in when previously initialized via a call to {@code init}.2444* That is, the object is reset and available to encrypt or decrypt2445* (depending on the operation mode that was specified in the call to2446* {@code init}) more data.2447*2448* <p>Note: if any exception is thrown, this cipher object may need to2449* be reset before it can be used again.2450*2451* <p>Note: this method should be copy-safe, which means the2452* {@code input} and {@code output} buffers can reference2453* the same byte array and no unprocessed input data is overwritten2454* when the result is copied into the output buffer.2455*2456* @param input the input ByteBuffer2457* @param output the output ByteBuffer2458*2459* @return the number of bytes stored in {@code output}2460*2461* @exception IllegalStateException if this cipher is in a wrong state2462* (e.g., has not been initialized)2463* @exception IllegalArgumentException if input and output are the2464* same object2465* @exception ReadOnlyBufferException if the output buffer is read-only2466* @exception IllegalBlockSizeException if this cipher is a block cipher,2467* no padding has been requested (only in encryption mode), and the total2468* input length of the data processed by this cipher is not a multiple of2469* block size; or if this encryption algorithm is unable to2470* process the input data provided.2471* @exception ShortBufferException if there is insufficient space in the2472* output buffer2473* @exception BadPaddingException if this cipher is in decryption mode,2474* and (un)padding has been requested, but the decrypted data is not2475* bounded by the appropriate padding bytes2476* @exception AEADBadTagException if this cipher is decrypting in an2477* AEAD mode (such as GCM/CCM), and the received authentication tag2478* does not match the calculated value2479*2480* @since 1.52481*/2482public final int doFinal(ByteBuffer input, ByteBuffer output)2483throws ShortBufferException, IllegalBlockSizeException,2484BadPaddingException {2485checkCipherState();24862487if ((input == null) || (output == null)) {2488throw new IllegalArgumentException("Buffers must not be null");2489}2490if (input == output) {2491throw new IllegalArgumentException("Input and output buffers must "2492+ "not be the same object, consider using buffer.duplicate()");2493}2494if (output.isReadOnly()) {2495throw new ReadOnlyBufferException();2496}24972498chooseFirstProvider();2499return spi.engineDoFinal(input, output);2500}25012502/**2503* Wrap a key.2504*2505* @param key the key to be wrapped.2506*2507* @return the wrapped key.2508*2509* @exception IllegalStateException if this cipher is in a wrong2510* state (e.g., has not been initialized).2511*2512* @exception IllegalBlockSizeException if this cipher is a block2513* cipher, no padding has been requested, and the length of the2514* encoding of the key to be wrapped is not a2515* multiple of the block size.2516*2517* @exception InvalidKeyException if it is impossible or unsafe to2518* wrap the key with this cipher (e.g., a hardware protected key is2519* being passed to a software-only cipher).2520*2521* @throws UnsupportedOperationException if the corresponding method in the2522* {@code CipherSpi} is not supported.2523*/2524public final byte[] wrap(Key key)2525throws IllegalBlockSizeException, InvalidKeyException {2526if (!(this instanceof NullCipher)) {2527if (!initialized) {2528throw new IllegalStateException("Cipher not initialized");2529}2530if (opmode != Cipher.WRAP_MODE) {2531throw new IllegalStateException("Cipher not initialized " +2532"for wrapping keys");2533}2534}25352536chooseFirstProvider();2537return spi.engineWrap(key);2538}25392540/**2541* Unwrap a previously wrapped key.2542*2543* @param wrappedKey the key to be unwrapped.2544*2545* @param wrappedKeyAlgorithm the algorithm associated with the wrapped2546* key.2547*2548* @param wrappedKeyType the type of the wrapped key. This must be one of2549* {@code SECRET_KEY}, {@code PRIVATE_KEY}, or2550* {@code PUBLIC_KEY}.2551*2552* @return the unwrapped key.2553*2554* @exception IllegalStateException if this cipher is in a wrong state2555* (e.g., has not been initialized).2556*2557* @exception NoSuchAlgorithmException if no installed providers2558* can create keys of type {@code wrappedKeyType} for the2559* {@code wrappedKeyAlgorithm}.2560*2561* @exception InvalidKeyException if {@code wrappedKey} does not2562* represent a wrapped key of type {@code wrappedKeyType} for2563* the {@code wrappedKeyAlgorithm}.2564*2565* @throws UnsupportedOperationException if the corresponding method in the2566* {@code CipherSpi} is not supported.2567*/2568public final Key unwrap(byte[] wrappedKey,2569String wrappedKeyAlgorithm,2570int wrappedKeyType)2571throws InvalidKeyException, NoSuchAlgorithmException {25722573if (!(this instanceof NullCipher)) {2574if (!initialized) {2575throw new IllegalStateException("Cipher not initialized");2576}2577if (opmode != Cipher.UNWRAP_MODE) {2578throw new IllegalStateException("Cipher not initialized " +2579"for unwrapping keys");2580}2581}2582if ((wrappedKeyType != SECRET_KEY) &&2583(wrappedKeyType != PRIVATE_KEY) &&2584(wrappedKeyType != PUBLIC_KEY)) {2585throw new InvalidParameterException("Invalid key type");2586}25872588chooseFirstProvider();2589return spi.engineUnwrap(wrappedKey,2590wrappedKeyAlgorithm,2591wrappedKeyType);2592}25932594private AlgorithmParameterSpec getAlgorithmParameterSpec(2595AlgorithmParameters params)2596throws InvalidParameterSpecException {2597if (params == null) {2598return null;2599}26002601String alg = params.getAlgorithm().toUpperCase(Locale.ENGLISH);26022603if (alg.equalsIgnoreCase("RC2")) {2604return params.getParameterSpec(RC2ParameterSpec.class);2605}26062607if (alg.equalsIgnoreCase("RC5")) {2608return params.getParameterSpec(RC5ParameterSpec.class);2609}26102611if (alg.startsWith("PBE")) {2612return params.getParameterSpec(PBEParameterSpec.class);2613}26142615if (alg.startsWith("DES")) {2616return params.getParameterSpec(IvParameterSpec.class);2617}2618return null;2619}26202621private static CryptoPermission getConfiguredPermission(2622String transformation) throws NullPointerException,2623NoSuchAlgorithmException {2624if (transformation == null) throw new NullPointerException();2625String[] parts = tokenizeTransformation(transformation);2626return JceSecurityManager.INSTANCE.getCryptoPermission(parts[0]);2627}26282629/**2630* Returns the maximum key length for the specified transformation2631* according to the installed JCE jurisdiction policy files. If2632* JCE unlimited strength jurisdiction policy files are installed,2633* Integer.MAX_VALUE will be returned.2634* For more information on the default key sizes and the JCE jurisdiction2635* policy files, please see the Cryptographic defaults and limitations in2636* the {@extLink security_guide_jdk_providers JDK Providers Documentation}.2637*2638* @param transformation the cipher transformation.2639* @return the maximum key length in bits or Integer.MAX_VALUE.2640* @exception NullPointerException if {@code transformation} is null.2641* @exception NoSuchAlgorithmException if {@code transformation}2642* is not a valid transformation, i.e. in the form of "algorithm" or2643* "algorithm/mode/padding".2644* @since 1.52645*/2646public static final int getMaxAllowedKeyLength(String transformation)2647throws NoSuchAlgorithmException {2648CryptoPermission cp = getConfiguredPermission(transformation);2649return cp.getMaxKeySize();2650}26512652/**2653* Returns an AlgorithmParameterSpec object which contains2654* the maximum cipher parameter value according to the2655* jurisdiction policy file. If JCE unlimited strength jurisdiction2656* policy files are installed or there is no maximum limit on the2657* parameters for the specified transformation in the policy file,2658* null will be returned.2659*2660* @param transformation the cipher transformation.2661* @return an AlgorithmParameterSpec which holds the maximum2662* value or null.2663* @exception NullPointerException if {@code transformation}2664* is null.2665* @exception NoSuchAlgorithmException if {@code transformation}2666* is not a valid transformation, i.e. in the form of "algorithm" or2667* "algorithm/mode/padding".2668* @since 1.52669*/2670public static final AlgorithmParameterSpec getMaxAllowedParameterSpec(2671String transformation) throws NoSuchAlgorithmException {2672CryptoPermission cp = getConfiguredPermission(transformation);2673return cp.getAlgorithmParameterSpec();2674}26752676/**2677* Continues a multi-part update of the Additional Authentication2678* Data (AAD).2679* <p>2680* Calls to this method provide AAD to the cipher when operating in2681* modes such as AEAD (GCM/CCM). If this cipher is operating in2682* either GCM or CCM mode, all AAD must be supplied before beginning2683* operations on the ciphertext (via the {@code update} and2684* {@code doFinal} methods).2685*2686* @param src the buffer containing the Additional Authentication Data2687*2688* @throws IllegalArgumentException if the {@code src}2689* byte array is null2690* @throws IllegalStateException if this cipher is in a wrong state2691* (e.g., has not been initialized), does not accept AAD, or if2692* operating in either GCM or CCM mode and one of the {@code update}2693* methods has already been called for the active2694* encryption/decryption operation2695* @throws UnsupportedOperationException if the corresponding method2696* in the {@code CipherSpi} has not been overridden by an2697* implementation2698*2699* @since 1.72700*/2701public final void updateAAD(byte[] src) {2702if (src == null) {2703throw new IllegalArgumentException("src buffer is null");2704}27052706updateAAD(src, 0, src.length);2707}27082709/**2710* Continues a multi-part update of the Additional Authentication2711* Data (AAD), using a subset of the provided buffer.2712* <p>2713* Calls to this method provide AAD to the cipher when operating in2714* modes such as AEAD (GCM/CCM). If this cipher is operating in2715* either GCM or CCM mode, all AAD must be supplied before beginning2716* operations on the ciphertext (via the {@code update}2717* and {@code doFinal} methods).2718*2719* @param src the buffer containing the AAD2720* @param offset the offset in {@code src} where the AAD input starts2721* @param len the number of AAD bytes2722*2723* @throws IllegalArgumentException if the {@code src}2724* byte array is null, or the {@code offset} or {@code length}2725* is less than 0, or the sum of the {@code offset} and2726* {@code len} is greater than the length of the2727* {@code src} byte array2728* @throws IllegalStateException if this cipher is in a wrong state2729* (e.g., has not been initialized), does not accept AAD, or if2730* operating in either GCM or CCM mode and one of the {@code update}2731* methods has already been called for the active2732* encryption/decryption operation2733* @throws UnsupportedOperationException if the corresponding method2734* in the {@code CipherSpi} has not been overridden by an2735* implementation2736*2737* @since 1.72738*/2739public final void updateAAD(byte[] src, int offset, int len) {2740checkCipherState();27412742// Input sanity check2743if ((src == null) || (offset < 0) || (len < 0)2744|| len > (src.length - offset)) {2745throw new IllegalArgumentException("Bad arguments");2746}27472748chooseFirstProvider();2749if (len == 0) {2750return;2751}2752spi.engineUpdateAAD(src, offset, len);2753}27542755/**2756* Continues a multi-part update of the Additional Authentication2757* Data (AAD).2758* <p>2759* Calls to this method provide AAD to the cipher when operating in2760* modes such as AEAD (GCM/CCM). If this cipher is operating in2761* either GCM or CCM mode, all AAD must be supplied before beginning2762* operations on the ciphertext (via the {@code update}2763* and {@code doFinal} methods).2764* <p>2765* All {@code src.remaining()} bytes starting at2766* {@code src.position()} are processed.2767* Upon return, the input buffer's position will be equal2768* to its limit; its limit will not have changed.2769*2770* @param src the buffer containing the AAD2771*2772* @throws IllegalArgumentException if the {@code src ByteBuffer}2773* is null2774* @throws IllegalStateException if this cipher is in a wrong state2775* (e.g., has not been initialized), does not accept AAD, or if2776* operating in either GCM or CCM mode and one of the {@code update}2777* methods has already been called for the active2778* encryption/decryption operation2779* @throws UnsupportedOperationException if the corresponding method2780* in the {@code CipherSpi} has not been overridden by an2781* implementation2782*2783* @since 1.72784*/2785public final void updateAAD(ByteBuffer src) {2786checkCipherState();27872788// Input sanity check2789if (src == null) {2790throw new IllegalArgumentException("src ByteBuffer is null");2791}27922793chooseFirstProvider();2794if (src.remaining() == 0) {2795return;2796}2797spi.engineUpdateAAD(src);2798}27992800/**2801* Returns a String representation of this Cipher.2802*2803* @implNote2804* This implementation returns a String containing the transformation,2805* mode, and provider of this Cipher.2806* The exact format of the String is unspecified and is subject to change.2807*2808* @return a String describing this Cipher2809*/2810@Override2811public String toString() {2812final StringBuilder sb = new StringBuilder();2813sb.append("Cipher.")2814.append(transformation)2815.append(", mode: ");2816switch (opmode) {2817case 0:2818sb.append("not initialized");2819break;2820case ENCRYPT_MODE:2821sb.append("encryption");2822break;2823case DECRYPT_MODE:2824sb.append("decryption");2825break;2826case WRAP_MODE:2827sb.append("key wrapping");2828break;2829case UNWRAP_MODE:2830sb.append("key unwrapping");2831break;2832default:2833// should never happen2834sb.append("error:").append(Integer.toString(opmode));2835}2836sb.append(", algorithm from: ").append(getProviderName());2837return sb.toString();2838}2839}284028412842