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/com/sun/crypto/provider/AESCipher.java
38922 views
1
/*
2
* Copyright (c) 2002, 2017, 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 com.sun.crypto.provider;
27
28
import java.security.*;
29
import java.security.spec.*;
30
import javax.crypto.*;
31
import javax.crypto.spec.*;
32
import javax.crypto.BadPaddingException;
33
import java.nio.ByteBuffer;
34
35
/**
36
* This class implements the AES algorithm in its various modes
37
* (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>,
38
* <code>PCBC</code>) and padding schemes (<code>PKCS5Padding</code>,
39
* <code>NoPadding</code>, <code>ISO10126Padding</code>).
40
*
41
* @author Valerie Peng
42
*
43
*
44
* @see AESCrypt
45
* @see CipherBlockChaining
46
* @see ElectronicCodeBook
47
* @see CipherFeedback
48
* @see OutputFeedback
49
*/
50
51
abstract class AESCipher extends CipherSpi {
52
public static final class General extends AESCipher {
53
public General() {
54
super(-1);
55
}
56
}
57
abstract static class OidImpl extends AESCipher {
58
protected OidImpl(int keySize, String mode, String padding) {
59
super(keySize);
60
try {
61
engineSetMode(mode);
62
engineSetPadding(padding);
63
} catch (GeneralSecurityException gse) {
64
// internal error; re-throw as provider exception
65
ProviderException pe =new ProviderException("Internal Error");
66
pe.initCause(gse);
67
throw pe;
68
}
69
}
70
}
71
public static final class AES128_ECB_NoPadding extends OidImpl {
72
public AES128_ECB_NoPadding() {
73
super(16, "ECB", "NOPADDING");
74
}
75
}
76
public static final class AES192_ECB_NoPadding extends OidImpl {
77
public AES192_ECB_NoPadding() {
78
super(24, "ECB", "NOPADDING");
79
}
80
}
81
public static final class AES256_ECB_NoPadding extends OidImpl {
82
public AES256_ECB_NoPadding() {
83
super(32, "ECB", "NOPADDING");
84
}
85
}
86
public static final class AES128_CBC_NoPadding extends OidImpl {
87
public AES128_CBC_NoPadding() {
88
super(16, "CBC", "NOPADDING");
89
}
90
}
91
public static final class AES192_CBC_NoPadding extends OidImpl {
92
public AES192_CBC_NoPadding() {
93
super(24, "CBC", "NOPADDING");
94
}
95
}
96
public static final class AES256_CBC_NoPadding extends OidImpl {
97
public AES256_CBC_NoPadding() {
98
super(32, "CBC", "NOPADDING");
99
}
100
}
101
public static final class AES128_OFB_NoPadding extends OidImpl {
102
public AES128_OFB_NoPadding() {
103
super(16, "OFB", "NOPADDING");
104
}
105
}
106
public static final class AES192_OFB_NoPadding extends OidImpl {
107
public AES192_OFB_NoPadding() {
108
super(24, "OFB", "NOPADDING");
109
}
110
}
111
public static final class AES256_OFB_NoPadding extends OidImpl {
112
public AES256_OFB_NoPadding() {
113
super(32, "OFB", "NOPADDING");
114
}
115
}
116
public static final class AES128_CFB_NoPadding extends OidImpl {
117
public AES128_CFB_NoPadding() {
118
super(16, "CFB", "NOPADDING");
119
}
120
}
121
public static final class AES192_CFB_NoPadding extends OidImpl {
122
public AES192_CFB_NoPadding() {
123
super(24, "CFB", "NOPADDING");
124
}
125
}
126
public static final class AES256_CFB_NoPadding extends OidImpl {
127
public AES256_CFB_NoPadding() {
128
super(32, "CFB", "NOPADDING");
129
}
130
}
131
public static final class AES128_GCM_NoPadding extends OidImpl {
132
public AES128_GCM_NoPadding() {
133
super(16, "GCM", "NOPADDING");
134
}
135
}
136
public static final class AES192_GCM_NoPadding extends OidImpl {
137
public AES192_GCM_NoPadding() {
138
super(24, "GCM", "NOPADDING");
139
}
140
}
141
public static final class AES256_GCM_NoPadding extends OidImpl {
142
public AES256_GCM_NoPadding() {
143
super(32, "GCM", "NOPADDING");
144
}
145
}
146
147
// utility method used by AESCipher and AESWrapCipher
148
static final void checkKeySize(Key key, int fixedKeySize)
149
throws InvalidKeyException {
150
if (fixedKeySize != -1) {
151
if (key == null) {
152
throw new InvalidKeyException("The key must not be null");
153
}
154
byte[] value = key.getEncoded();
155
if (value == null) {
156
throw new InvalidKeyException("Key encoding must not be null");
157
} else if (value.length != fixedKeySize) {
158
throw new InvalidKeyException("The key must be " +
159
fixedKeySize + " bytes");
160
}
161
}
162
}
163
164
/*
165
* internal CipherCore object which does the real work.
166
*/
167
private CipherCore core = null;
168
169
/*
170
* needed to support AES oids which associates a fixed key size
171
* to the cipher object.
172
*/
173
private final int fixedKeySize; // in bytes, -1 if no restriction
174
175
/*
176
* needed to enforce ISE thrown when updateAAD is called after update for GCM mode.
177
*/
178
private boolean updateCalled;
179
180
/**
181
* Creates an instance of AES cipher with default ECB mode and
182
* PKCS5Padding.
183
*/
184
protected AESCipher(int keySize) {
185
core = new CipherCore(new AESCrypt(), AESConstants.AES_BLOCK_SIZE);
186
fixedKeySize = keySize;
187
}
188
189
/**
190
* Sets the mode of this cipher.
191
*
192
* @param mode the cipher mode
193
*
194
* @exception NoSuchAlgorithmException if the requested cipher mode does
195
* not exist
196
*/
197
protected void engineSetMode(String mode)
198
throws NoSuchAlgorithmException {
199
core.setMode(mode);
200
}
201
202
/**
203
* Sets the padding mechanism of this cipher.
204
*
205
* @param padding the padding mechanism
206
*
207
* @exception NoSuchPaddingException if the requested padding mechanism
208
* does not exist
209
*/
210
protected void engineSetPadding(String paddingScheme)
211
throws NoSuchPaddingException {
212
core.setPadding(paddingScheme);
213
}
214
215
/**
216
* Returns the block size (in bytes).
217
*
218
* @return the block size (in bytes), or 0 if the underlying algorithm is
219
* not a block cipher
220
*/
221
protected int engineGetBlockSize() {
222
return AESConstants.AES_BLOCK_SIZE;
223
}
224
225
/**
226
* Returns the length in bytes that an output buffer would need to be in
227
* order to hold the result of the next <code>update</code> or
228
* <code>doFinal</code> operation, given the input length
229
* <code>inputLen</code> (in bytes).
230
*
231
* <p>This call takes into account any unprocessed (buffered) data from a
232
* previous <code>update</code> call, and padding.
233
*
234
* <p>The actual output length of the next <code>update</code> or
235
* <code>doFinal</code> call may be smaller than the length returned by
236
* this method.
237
*
238
* @param inputLen the input length (in bytes)
239
*
240
* @return the required output buffer size (in bytes)
241
*/
242
protected int engineGetOutputSize(int inputLen) {
243
return core.getOutputSize(inputLen);
244
}
245
246
/**
247
* Returns the initialization vector (IV) in a new buffer.
248
*
249
* <p>This is useful in the case where a random IV has been created
250
* (see <a href = "#init">init</a>),
251
* or in the context of password-based encryption or
252
* decryption, where the IV is derived from a user-provided password.
253
*
254
* @return the initialization vector in a new buffer, or null if the
255
* underlying algorithm does not use an IV, or if the IV has not yet
256
* been set.
257
*/
258
protected byte[] engineGetIV() {
259
return core.getIV();
260
}
261
262
/**
263
* Returns the parameters used with this cipher.
264
*
265
* <p>The returned parameters may be the same that were used to initialize
266
* this cipher, or may contain the default set of parameters or a set of
267
* randomly generated parameters used by the underlying cipher
268
* implementation (provided that the underlying cipher implementation
269
* uses a default set of parameters or creates new parameters if it needs
270
* parameters but was not initialized with any).
271
*
272
* @return the parameters used with this cipher, or null if this cipher
273
* does not use any parameters.
274
*/
275
protected AlgorithmParameters engineGetParameters() {
276
return core.getParameters("AES");
277
}
278
279
/**
280
* Initializes this cipher with a key and a source of randomness.
281
*
282
* <p>The cipher is initialized for one of the following four operations:
283
* encryption, decryption, key wrapping or key unwrapping, depending on
284
* the value of <code>opmode</code>.
285
*
286
* <p>If this cipher requires an initialization vector (IV), it will get
287
* it from <code>random</code>.
288
* This behaviour should only be used in encryption or key wrapping
289
* mode, however.
290
* When initializing a cipher that requires an IV for decryption or
291
* key unwrapping, the IV
292
* (same IV that was used for encryption or key wrapping) must be provided
293
* explicitly as a
294
* parameter, in order to get the correct result.
295
*
296
* <p>This method also cleans existing buffer and other related state
297
* information.
298
*
299
* @param opmode the operation mode of this cipher (this is one of
300
* the following:
301
* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
302
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
303
* @param key the secret key
304
* @param random the source of randomness
305
*
306
* @exception InvalidKeyException if the given key is inappropriate for
307
* initializing this cipher
308
*/
309
protected void engineInit(int opmode, Key key, SecureRandom random)
310
throws InvalidKeyException {
311
checkKeySize(key, fixedKeySize);
312
updateCalled = false;
313
core.init(opmode, key, random);
314
}
315
316
/**
317
* Initializes this cipher with a key, a set of
318
* algorithm parameters, and a source of randomness.
319
*
320
* <p>The cipher is initialized for one of the following four operations:
321
* encryption, decryption, key wrapping or key unwrapping, depending on
322
* the value of <code>opmode</code>.
323
*
324
* <p>If this cipher (including its underlying feedback or padding scheme)
325
* requires any random bytes, it will get them from <code>random</code>.
326
*
327
* @param opmode the operation mode of this cipher (this is one of
328
* the following:
329
* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
330
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
331
* @param key the encryption key
332
* @param params the algorithm parameters
333
* @param random the source of randomness
334
*
335
* @exception InvalidKeyException if the given key is inappropriate for
336
* initializing this cipher
337
* @exception InvalidAlgorithmParameterException if the given algorithm
338
* parameters are inappropriate for this cipher
339
*/
340
protected void engineInit(int opmode, Key key,
341
AlgorithmParameterSpec params,
342
SecureRandom random)
343
throws InvalidKeyException, InvalidAlgorithmParameterException {
344
checkKeySize(key, fixedKeySize);
345
updateCalled = false;
346
core.init(opmode, key, params, random);
347
}
348
349
protected void engineInit(int opmode, Key key,
350
AlgorithmParameters params,
351
SecureRandom random)
352
throws InvalidKeyException, InvalidAlgorithmParameterException {
353
checkKeySize(key, fixedKeySize);
354
updateCalled = false;
355
core.init(opmode, key, params, random);
356
}
357
358
/**
359
* Continues a multiple-part encryption or decryption operation
360
* (depending on how this cipher was initialized), processing another data
361
* part.
362
*
363
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
364
* buffer, starting at <code>inputOffset</code>, are processed, and the
365
* result is stored in a new buffer.
366
*
367
* @param input the input buffer
368
* @param inputOffset the offset in <code>input</code> where the input
369
* starts
370
* @param inputLen the input length
371
*
372
* @return the new buffer with the result
373
*
374
* @exception IllegalStateException if this cipher is in a wrong state
375
* (e.g., has not been initialized)
376
*/
377
protected byte[] engineUpdate(byte[] input, int inputOffset,
378
int inputLen) {
379
updateCalled = true;
380
return core.update(input, inputOffset, inputLen);
381
}
382
383
/**
384
* Continues a multiple-part encryption or decryption operation
385
* (depending on how this cipher was initialized), processing another data
386
* part.
387
*
388
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
389
* buffer, starting at <code>inputOffset</code>, are processed, and the
390
* result is stored in the <code>output</code> buffer, starting at
391
* <code>outputOffset</code>.
392
*
393
* @param input the input buffer
394
* @param inputOffset the offset in <code>input</code> where the input
395
* starts
396
* @param inputLen the input length
397
* @param output the buffer for the result
398
* @param outputOffset the offset in <code>output</code> where the result
399
* is stored
400
*
401
* @return the number of bytes stored in <code>output</code>
402
*
403
* @exception ShortBufferException if the given output buffer is too small
404
* to hold the result
405
*/
406
protected int engineUpdate(byte[] input, int inputOffset, int inputLen,
407
byte[] output, int outputOffset)
408
throws ShortBufferException {
409
updateCalled = true;
410
return core.update(input, inputOffset, inputLen, output,
411
outputOffset);
412
}
413
414
/**
415
* Encrypts or decrypts data in a single-part operation,
416
* or finishes a multiple-part operation.
417
* The data is encrypted or decrypted, depending on how this cipher was
418
* initialized.
419
*
420
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
421
* buffer, starting at <code>inputOffset</code>, and any input bytes that
422
* may have been buffered during a previous <code>update</code> operation,
423
* are processed, with padding (if requested) being applied.
424
* The result is stored in a new buffer.
425
*
426
* <p>The cipher is reset to its initial state (uninitialized) after this
427
* call.
428
*
429
* @param input the input buffer
430
* @param inputOffset the offset in <code>input</code> where the input
431
* starts
432
* @param inputLen the input length
433
*
434
* @return the new buffer with the result
435
*
436
* @exception IllegalBlockSizeException if this cipher is a block cipher,
437
* no padding has been requested (only in encryption mode), and the total
438
* input length of the data processed by this cipher is not a multiple of
439
* block size
440
* @exception BadPaddingException if this cipher is in decryption mode,
441
* and (un)padding has been requested, but the decrypted data is not
442
* bounded by the appropriate padding bytes
443
*/
444
protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
445
throws IllegalBlockSizeException, BadPaddingException {
446
byte[] out = core.doFinal(input, inputOffset, inputLen);
447
updateCalled = false;
448
return out;
449
}
450
451
/**
452
* Encrypts or decrypts data in a single-part operation,
453
* or finishes a multiple-part operation.
454
* The data is encrypted or decrypted, depending on how this cipher was
455
* initialized.
456
*
457
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
458
* buffer, starting at <code>inputOffset</code>, and any input bytes that
459
* may have been buffered during a previous <code>update</code> operation,
460
* are processed, with padding (if requested) being applied.
461
* The result is stored in the <code>output</code> buffer, starting at
462
* <code>outputOffset</code>.
463
*
464
* <p>The cipher is reset to its initial state (uninitialized) after this
465
* call.
466
*
467
* @param input the input buffer
468
* @param inputOffset the offset in <code>input</code> where the input
469
* starts
470
* @param inputLen the input length
471
* @param output the buffer for the result
472
* @param outputOffset the offset in <code>output</code> where the result
473
* is stored
474
*
475
* @return the number of bytes stored in <code>output</code>
476
*
477
* @exception IllegalBlockSizeException if this cipher is a block cipher,
478
* no padding has been requested (only in encryption mode), and the total
479
* input length of the data processed by this cipher is not a multiple of
480
* block size
481
* @exception ShortBufferException if the given output buffer is too small
482
* to hold the result
483
* @exception BadPaddingException if this cipher is in decryption mode,
484
* and (un)padding has been requested, but the decrypted data is not
485
* bounded by the appropriate padding bytes
486
*/
487
protected int engineDoFinal(byte[] input, int inputOffset, int inputLen,
488
byte[] output, int outputOffset)
489
throws IllegalBlockSizeException, ShortBufferException,
490
BadPaddingException {
491
int outLen = core.doFinal(input, inputOffset, inputLen, output,
492
outputOffset);
493
updateCalled = false;
494
return outLen;
495
}
496
497
/**
498
* Returns the key size of the given key object.
499
*
500
* @param key the key object.
501
*
502
* @return the key size of the given key object.
503
*
504
* @exception InvalidKeyException if <code>key</code> is invalid.
505
*/
506
protected int engineGetKeySize(Key key) throws InvalidKeyException {
507
byte[] encoded = key.getEncoded();
508
if (!AESCrypt.isKeySizeValid(encoded.length)) {
509
throw new InvalidKeyException("Invalid AES key length: " +
510
encoded.length + " bytes");
511
}
512
return Math.multiplyExact(encoded.length, 8);
513
}
514
515
/**
516
* Wrap a key.
517
*
518
* @param key the key to be wrapped.
519
*
520
* @return the wrapped key.
521
*
522
* @exception IllegalBlockSizeException if this cipher is a block
523
* cipher, no padding has been requested, and the length of the
524
* encoding of the key to be wrapped is not a
525
* multiple of the block size.
526
*
527
* @exception InvalidKeyException if it is impossible or unsafe to
528
* wrap the key with this cipher (e.g., a hardware protected key is
529
* being passed to a software only cipher).
530
*/
531
protected byte[] engineWrap(Key key)
532
throws IllegalBlockSizeException, InvalidKeyException {
533
return core.wrap(key);
534
}
535
536
/**
537
* Unwrap a previously wrapped key.
538
*
539
* @param wrappedKey the key to be unwrapped.
540
*
541
* @param wrappedKeyAlgorithm the algorithm the wrapped key is for.
542
*
543
* @param wrappedKeyType the type of the wrapped key.
544
* This is one of <code>Cipher.SECRET_KEY</code>,
545
* <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.
546
*
547
* @return the unwrapped key.
548
*
549
* @exception NoSuchAlgorithmException if no installed providers
550
* can create keys of type <code>wrappedKeyType</code> for the
551
* <code>wrappedKeyAlgorithm</code>.
552
*
553
* @exception InvalidKeyException if <code>wrappedKey</code> does not
554
* represent a wrapped key of type <code>wrappedKeyType</code> for
555
* the <code>wrappedKeyAlgorithm</code>.
556
*/
557
protected Key engineUnwrap(byte[] wrappedKey,
558
String wrappedKeyAlgorithm,
559
int wrappedKeyType)
560
throws InvalidKeyException, NoSuchAlgorithmException {
561
return core.unwrap(wrappedKey, wrappedKeyAlgorithm,
562
wrappedKeyType);
563
}
564
565
/**
566
* Continues a multi-part update of the Additional Authentication
567
* Data (AAD), using a subset of the provided buffer.
568
* <p>
569
* Calls to this method provide AAD to the cipher when operating in
570
* modes such as AEAD (GCM/CCM). If this cipher is operating in
571
* either GCM or CCM mode, all AAD must be supplied before beginning
572
* operations on the ciphertext (via the {@code update} and {@code
573
* doFinal} methods).
574
*
575
* @param src the buffer containing the AAD
576
* @param offset the offset in {@code src} where the AAD input starts
577
* @param len the number of AAD bytes
578
*
579
* @throws IllegalStateException if this cipher is in a wrong state
580
* (e.g., has not been initialized), does not accept AAD, or if
581
* operating in either GCM or CCM mode and one of the {@code update}
582
* methods has already been called for the active
583
* encryption/decryption operation
584
* @throws UnsupportedOperationException if this method
585
* has not been overridden by an implementation
586
*
587
* @since 1.8
588
*/
589
@Override
590
protected void engineUpdateAAD(byte[] src, int offset, int len) {
591
if (core.getMode() == CipherCore.GCM_MODE && updateCalled) {
592
throw new IllegalStateException("AAD must be supplied before encryption/decryption starts");
593
}
594
core.updateAAD(src, offset, len);
595
}
596
597
/**
598
* Continues a multi-part update of the Additional Authentication
599
* Data (AAD).
600
* <p>
601
* Calls to this method provide AAD to the cipher when operating in
602
* modes such as AEAD (GCM/CCM). If this cipher is operating in
603
* either GCM or CCM mode, all AAD must be supplied before beginning
604
* operations on the ciphertext (via the {@code update} and {@code
605
* doFinal} methods).
606
* <p>
607
* All {@code src.remaining()} bytes starting at
608
* {@code src.position()} are processed.
609
* Upon return, the input buffer's position will be equal
610
* to its limit; its limit will not have changed.
611
*
612
* @param src the buffer containing the AAD
613
*
614
* @throws IllegalStateException if this cipher is in a wrong state
615
* (e.g., has not been initialized), does not accept AAD, or if
616
* operating in either GCM or CCM mode and one of the {@code update}
617
* methods has already been called for the active
618
* encryption/decryption operation
619
* @throws UnsupportedOperationException if this method
620
* has not been overridden by an implementation
621
*
622
* @since 1.8
623
*/
624
@Override
625
protected void engineUpdateAAD(ByteBuffer src) {
626
if (core.getMode() == CipherCore.GCM_MODE && updateCalled) {
627
throw new IllegalStateException("AAD must be supplied before encryption/decryption starts");
628
}
629
if (src != null) {
630
int aadLen = src.limit() - src.position();
631
if (aadLen > 0) {
632
if (src.hasArray()) {
633
int aadOfs = Math.addExact(src.arrayOffset(), src.position());
634
core.updateAAD(src.array(), aadOfs, aadLen);
635
src.position(src.limit());
636
} else {
637
byte[] aad = new byte[aadLen];
638
src.get(aad);
639
core.updateAAD(aad, 0, aadLen);
640
}
641
}
642
}
643
}
644
}
645
646
647