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