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