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