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