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