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