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