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/sun/security/pkcs11/P11AEADCipher.java
38919 views
1
/*
2
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
package sun.security.pkcs11;
26
27
import java.io.ByteArrayOutputStream;
28
import java.nio.ByteBuffer;
29
import java.util.Arrays;
30
import java.util.Locale;
31
32
import java.security.*;
33
import java.security.spec.*;
34
35
import javax.crypto.*;
36
import javax.crypto.spec.*;
37
38
import sun.nio.ch.DirectBuffer;
39
import sun.security.jca.JCAUtil;
40
import sun.security.pkcs11.wrapper.*;
41
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
42
43
/**
44
* P11 AEAD Cipher implementation class. This class currently supports
45
* AES with GCM mode.
46
*
47
* Note that AEAD modes do not use padding, so this class does not have
48
* its own padding impl. In addition, NSS CKM_AES_GCM only supports single-part
49
* encryption/decryption, thus the current impl uses PKCS#11 C_Encrypt/C_Decrypt
50
* calls and buffers data until doFinal is called.
51
*
52
* Note that PKCS#11 standard currently only supports GCM and CCM AEAD modes.
53
* There are no provisions for other AEAD modes yet.
54
*
55
* @since 13
56
*/
57
final class P11AEADCipher extends CipherSpi {
58
59
// mode constant for GCM mode
60
private static final int MODE_GCM = 10;
61
62
// default constants for GCM
63
private static final int GCM_DEFAULT_TAG_LEN = 16;
64
private static final int GCM_DEFAULT_IV_LEN = 16;
65
66
private static final String ALGO = "AES";
67
68
// token instance
69
private final Token token;
70
71
// mechanism id
72
private final long mechanism;
73
74
// mode, one of MODE_* above
75
private final int blockMode;
76
77
// acceptable key size, -1 if more than 1 key sizes are accepted
78
private final int fixedKeySize;
79
80
// associated session, if any
81
private Session session = null;
82
83
// key, if init() was called
84
private P11Key p11Key = null;
85
86
// flag indicating whether an operation is initialized
87
private boolean initialized = false;
88
89
// falg indicating encrypt or decrypt mode
90
private boolean encrypt = true;
91
92
// parameters
93
private byte[] iv = null;
94
private int tagLen = -1;
95
private SecureRandom random = JCAUtil.getSecureRandom();
96
97
// dataBuffer is cleared upon doFinal calls
98
private ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream();
99
// aadBuffer is cleared upon successful init calls
100
private ByteArrayOutputStream aadBuffer = new ByteArrayOutputStream();
101
private boolean updateCalled = false;
102
103
private boolean requireReinit = false;
104
private P11Key lastEncKey = null;
105
private byte[] lastEncIv = null;
106
107
P11AEADCipher(Token token, String algorithm, long mechanism)
108
throws PKCS11Exception, NoSuchAlgorithmException {
109
super();
110
this.token = token;
111
this.mechanism = mechanism;
112
113
String[] algoParts = algorithm.split("/");
114
if (algoParts.length != 3) {
115
throw new ProviderException("Unsupported Transformation format: " +
116
algorithm);
117
}
118
if (!algoParts[0].startsWith("AES")) {
119
throw new ProviderException("Only support AES for AEAD cipher mode");
120
}
121
int index = algoParts[0].indexOf('_');
122
if (index != -1) {
123
// should be well-formed since we specify what we support
124
fixedKeySize = Integer.parseInt(algoParts[0].substring(index+1)) >> 3;
125
} else {
126
fixedKeySize = -1;
127
}
128
this.blockMode = parseMode(algoParts[1]);
129
if (!algoParts[2].equals("NoPadding")) {
130
throw new ProviderException("Only NoPadding is supported for AEAD cipher mode");
131
}
132
}
133
134
protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
135
// Disallow change of mode for now since currently it's explicitly
136
// defined in transformation strings
137
throw new NoSuchAlgorithmException("Unsupported mode " + mode);
138
}
139
140
private int parseMode(String mode) throws NoSuchAlgorithmException {
141
mode = mode.toUpperCase(Locale.ENGLISH);
142
int result;
143
if (mode.equals("GCM")) {
144
result = MODE_GCM;
145
} else {
146
throw new NoSuchAlgorithmException("Unsupported mode " + mode);
147
}
148
return result;
149
}
150
151
// see JCE spec
152
protected void engineSetPadding(String padding)
153
throws NoSuchPaddingException {
154
// Disallow change of padding for now since currently it's explicitly
155
// defined in transformation strings
156
throw new NoSuchPaddingException("Unsupported padding " + padding);
157
}
158
159
// see JCE spec
160
protected int engineGetBlockSize() {
161
return 16; // constant; only AES is supported
162
}
163
164
// see JCE spec
165
protected int engineGetOutputSize(int inputLen) {
166
return doFinalLength(inputLen);
167
}
168
169
// see JCE spec
170
protected byte[] engineGetIV() {
171
return (iv == null) ? null : iv.clone();
172
}
173
174
// see JCE spec
175
protected AlgorithmParameters engineGetParameters() {
176
if (encrypt && iv == null && tagLen == -1) {
177
switch (blockMode) {
178
case MODE_GCM:
179
iv = new byte[GCM_DEFAULT_IV_LEN];
180
tagLen = GCM_DEFAULT_TAG_LEN;
181
break;
182
default:
183
throw new ProviderException("Unsupported mode");
184
}
185
random.nextBytes(iv);
186
}
187
try {
188
AlgorithmParameterSpec spec;
189
String apAlgo;
190
switch (blockMode) {
191
case MODE_GCM:
192
apAlgo = "GCM";
193
spec = new GCMParameterSpec(tagLen << 3, iv);
194
break;
195
default:
196
throw new ProviderException("Unsupported mode");
197
}
198
AlgorithmParameters params =
199
AlgorithmParameters.getInstance(apAlgo);
200
params.init(spec);
201
return params;
202
} catch (GeneralSecurityException e) {
203
// NoSuchAlgorithmException, NoSuchProviderException
204
// InvalidParameterSpecException
205
throw new ProviderException("Could not encode parameters", e);
206
}
207
}
208
209
// see JCE spec
210
protected void engineInit(int opmode, Key key, SecureRandom sr)
211
throws InvalidKeyException {
212
if (opmode == Cipher.DECRYPT_MODE) {
213
throw new InvalidKeyException("Parameters required for decryption");
214
}
215
updateCalled = false;
216
try {
217
implInit(opmode, key, null, -1, sr);
218
} catch (InvalidAlgorithmParameterException e) {
219
throw new InvalidKeyException("init() failed", e);
220
}
221
}
222
223
// see JCE spec
224
protected void engineInit(int opmode, Key key,
225
AlgorithmParameterSpec params, SecureRandom sr)
226
throws InvalidKeyException, InvalidAlgorithmParameterException {
227
if (opmode == Cipher.DECRYPT_MODE && params == null) {
228
throw new InvalidAlgorithmParameterException
229
("Parameters required for decryption");
230
}
231
updateCalled = false;
232
byte[] ivValue = null;
233
int tagLen = -1;
234
if (params != null) {
235
switch (blockMode) {
236
case MODE_GCM:
237
if (!(params instanceof GCMParameterSpec)) {
238
throw new InvalidAlgorithmParameterException
239
("Only GCMParameterSpec is supported");
240
}
241
ivValue = ((GCMParameterSpec) params).getIV();
242
tagLen = ((GCMParameterSpec) params).getTLen() >> 3;
243
break;
244
default:
245
throw new ProviderException("Unsupported mode");
246
}
247
}
248
implInit(opmode, key, ivValue, tagLen, sr);
249
}
250
251
// see JCE spec
252
protected void engineInit(int opmode, Key key, AlgorithmParameters params,
253
SecureRandom sr)
254
throws InvalidKeyException, InvalidAlgorithmParameterException {
255
if (opmode == Cipher.DECRYPT_MODE && params == null) {
256
throw new InvalidAlgorithmParameterException
257
("Parameters required for decryption");
258
}
259
updateCalled = false;
260
try {
261
AlgorithmParameterSpec paramSpec = null;
262
if (params != null) {
263
switch (blockMode) {
264
case MODE_GCM:
265
paramSpec =
266
params.getParameterSpec(GCMParameterSpec.class);
267
break;
268
default:
269
throw new ProviderException("Unsupported mode");
270
}
271
}
272
engineInit(opmode, key, paramSpec, sr);
273
} catch (InvalidParameterSpecException ex) {
274
throw new InvalidAlgorithmParameterException(ex);
275
}
276
}
277
278
// actual init() implementation
279
private void implInit(int opmode, Key key, byte[] iv, int tagLen,
280
SecureRandom sr)
281
throws InvalidKeyException, InvalidAlgorithmParameterException {
282
reset(true);
283
if (fixedKeySize != -1 &&
284
((key instanceof P11Key) ? ((P11Key) key).length() >> 3 :
285
key.getEncoded().length) != fixedKeySize) {
286
throw new InvalidKeyException("Key size is invalid");
287
}
288
P11Key newKey = P11SecretKeyFactory.convertKey(token, key, ALGO);
289
switch (opmode) {
290
case Cipher.ENCRYPT_MODE:
291
encrypt = true;
292
requireReinit = Arrays.equals(iv, lastEncIv) &&
293
(newKey == lastEncKey);
294
if (requireReinit) {
295
throw new InvalidAlgorithmParameterException
296
("Cannot reuse iv for GCM encryption");
297
}
298
break;
299
case Cipher.DECRYPT_MODE:
300
encrypt = false;
301
requireReinit = false;
302
break;
303
default:
304
throw new InvalidAlgorithmParameterException
305
("Unsupported mode: " + opmode);
306
}
307
308
// decryption without parameters is checked in all engineInit() calls
309
if (sr != null) {
310
this.random = sr;
311
}
312
if (iv == null && tagLen == -1) {
313
// generate default values
314
switch (blockMode) {
315
case MODE_GCM:
316
iv = new byte[GCM_DEFAULT_IV_LEN];
317
this.random.nextBytes(iv);
318
tagLen = GCM_DEFAULT_TAG_LEN;
319
break;
320
default:
321
throw new ProviderException("Unsupported mode");
322
}
323
}
324
this.iv = iv;
325
this.tagLen = tagLen;
326
this.p11Key = newKey;
327
try {
328
initialize();
329
} catch (PKCS11Exception e) {
330
throw new InvalidKeyException("Could not initialize cipher", e);
331
}
332
}
333
334
private void cancelOperation() {
335
// cancel operation by finishing it; avoid killSession as some
336
// hardware vendors may require re-login
337
int bufLen = doFinalLength(0);
338
byte[] buffer = new byte[bufLen];
339
byte[] in = dataBuffer.toByteArray();
340
int inLen = in.length;
341
try {
342
if (encrypt) {
343
token.p11.C_Encrypt(session.id(), 0, in, 0, inLen,
344
0, buffer, 0, bufLen);
345
} else {
346
token.p11.C_Decrypt(session.id(), 0, in, 0, inLen,
347
0, buffer, 0, bufLen);
348
}
349
} catch (PKCS11Exception e) {
350
if (e.getErrorCode() == CKR_OPERATION_NOT_INITIALIZED) {
351
// Cancel Operation may be invoked after an error on a PKCS#11
352
// call. If the operation inside the token was already cancelled,
353
// do not fail here. This is part of a defensive mechanism for
354
// PKCS#11 libraries that do not strictly follow the standard.
355
return;
356
}
357
if (encrypt) {
358
throw new ProviderException("Cancel failed", e);
359
}
360
// ignore failure for decryption
361
}
362
}
363
364
private void ensureInitialized() throws PKCS11Exception {
365
if (initialized && aadBuffer.size() > 0) {
366
// need to cancel first to avoid CKR_OPERATION_ACTIVE
367
reset(true);
368
}
369
if (!initialized) {
370
initialize();
371
}
372
}
373
374
private void initialize() throws PKCS11Exception {
375
if (p11Key == null) {
376
throw new ProviderException(
377
"Operation cannot be performed without"
378
+ " calling engineInit first");
379
}
380
if (requireReinit) {
381
throw new IllegalStateException
382
("Must use either different key or iv for GCM encryption");
383
}
384
385
token.ensureValid();
386
387
byte[] aad = (aadBuffer.size() > 0? aadBuffer.toByteArray() : null);
388
389
long p11KeyID = p11Key.getKeyID();
390
try {
391
if (session == null) {
392
session = token.getOpSession();
393
}
394
CK_MECHANISM mechWithParams;
395
switch (blockMode) {
396
case MODE_GCM:
397
mechWithParams = new CK_MECHANISM(mechanism,
398
new CK_GCM_PARAMS(tagLen << 3, iv, aad));
399
break;
400
default:
401
throw new ProviderException("Unsupported mode: " + blockMode);
402
}
403
if (encrypt) {
404
token.p11.C_EncryptInit(session.id(), mechWithParams,
405
p11KeyID);
406
} else {
407
token.p11.C_DecryptInit(session.id(), mechWithParams,
408
p11KeyID);
409
}
410
} catch (PKCS11Exception e) {
411
//e.printStackTrace();
412
p11Key.releaseKeyID();
413
session = token.releaseSession(session);
414
throw e;
415
} finally {
416
dataBuffer.reset();
417
aadBuffer.reset();
418
}
419
initialized = true;
420
}
421
422
// if doFinal(inLen) is called, how big does the output buffer have to be?
423
private int doFinalLength(int inLen) {
424
if (inLen < 0) {
425
throw new ProviderException("Invalid negative input length");
426
}
427
428
int result = inLen + dataBuffer.size();
429
if (encrypt) {
430
result += tagLen;
431
} else {
432
// PKCS11Exception: CKR_BUFFER_TOO_SMALL
433
//result -= tagLen;
434
}
435
return result;
436
}
437
438
// reset the states to the pre-initialized values
439
private void reset(boolean doCancel) {
440
if (!initialized) {
441
return;
442
}
443
initialized = false;
444
445
try {
446
if (session == null) {
447
return;
448
}
449
450
if (doCancel && token.explicitCancel) {
451
cancelOperation();
452
}
453
} finally {
454
p11Key.releaseKeyID();
455
session = token.releaseSession(session);
456
dataBuffer.reset();
457
}
458
}
459
460
// see JCE spec
461
protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
462
updateCalled = true;
463
int n = implUpdate(in, inOfs, inLen);
464
return new byte[0];
465
}
466
467
// see JCE spec
468
protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out,
469
int outOfs) throws ShortBufferException {
470
updateCalled = true;
471
implUpdate(in, inOfs, inLen);
472
return 0;
473
}
474
475
// see JCE spec
476
@Override
477
protected int engineUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
478
throws ShortBufferException {
479
updateCalled = true;
480
implUpdate(inBuffer);
481
return 0;
482
}
483
484
// see JCE spec
485
@Override
486
protected synchronized void engineUpdateAAD(byte[] src, int srcOfs, int srcLen)
487
throws IllegalStateException {
488
if ((src == null) || (srcOfs < 0) || (srcOfs + srcLen > src.length)) {
489
throw new IllegalArgumentException("Invalid AAD");
490
}
491
if (requireReinit) {
492
throw new IllegalStateException
493
("Must use either different key or iv for GCM encryption");
494
}
495
if (p11Key == null) {
496
throw new IllegalStateException("Need to initialize Cipher first");
497
}
498
if (updateCalled) {
499
throw new IllegalStateException
500
("Update has been called; no more AAD data");
501
}
502
aadBuffer.write(src, srcOfs, srcLen);
503
}
504
505
// see JCE spec
506
@Override
507
protected void engineUpdateAAD(ByteBuffer src)
508
throws IllegalStateException {
509
if (src == null) {
510
throw new IllegalArgumentException("Invalid AAD");
511
}
512
byte[] srcBytes = new byte[src.remaining()];
513
src.get(srcBytes);
514
engineUpdateAAD(srcBytes, 0, srcBytes.length);
515
}
516
517
// see JCE spec
518
protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
519
throws IllegalBlockSizeException, BadPaddingException {
520
int minOutLen = doFinalLength(inLen);
521
try {
522
byte[] out = new byte[minOutLen];
523
int n = engineDoFinal(in, inOfs, inLen, out, 0);
524
return P11Util.convert(out, 0, n);
525
} catch (ShortBufferException e) {
526
// convert since the output length is calculated by doFinalLength()
527
throw new ProviderException(e);
528
} finally {
529
updateCalled = false;
530
}
531
}
532
// see JCE spec
533
protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
534
int outOfs) throws ShortBufferException, IllegalBlockSizeException,
535
BadPaddingException {
536
try {
537
return implDoFinal(in, inOfs, inLen, out, outOfs, out.length - outOfs);
538
} finally {
539
updateCalled = false;
540
}
541
}
542
543
// see JCE spec
544
@Override
545
protected int engineDoFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
546
throws ShortBufferException, IllegalBlockSizeException,
547
BadPaddingException {
548
try {
549
return implDoFinal(inBuffer, outBuffer);
550
} finally {
551
updateCalled = false;
552
}
553
}
554
555
private int implUpdate(byte[] in, int inOfs, int inLen) {
556
if (inLen > 0) {
557
updateCalled = true;
558
try {
559
ensureInitialized();
560
} catch (PKCS11Exception e) {
561
//e.printStackTrace();
562
reset(false);
563
throw new ProviderException("update() failed", e);
564
}
565
dataBuffer.write(in, inOfs, inLen);
566
}
567
// always 0 as NSS only supports single-part encryption/decryption
568
return 0;
569
}
570
571
private int implUpdate(ByteBuffer inBuf) {
572
int inLen = inBuf.remaining();
573
if (inLen > 0) {
574
try {
575
ensureInitialized();
576
} catch (PKCS11Exception e) {
577
reset(false);
578
throw new ProviderException("update() failed", e);
579
}
580
byte[] data = new byte[inLen];
581
inBuf.get(data);
582
dataBuffer.write(data, 0, data.length);
583
}
584
// always 0 as NSS only supports single-part encryption/decryption
585
return 0;
586
}
587
588
private int implDoFinal(byte[] in, int inOfs, int inLen,
589
byte[] out, int outOfs, int outLen)
590
throws ShortBufferException, IllegalBlockSizeException,
591
BadPaddingException {
592
int requiredOutLen = doFinalLength(inLen);
593
if (outLen < requiredOutLen) {
594
throw new ShortBufferException();
595
}
596
boolean doCancel = true;
597
try {
598
ensureInitialized();
599
if (dataBuffer.size() > 0) {
600
if (in != null && inOfs > 0 && inLen > 0 &&
601
inOfs < (in.length - inLen)) {
602
dataBuffer.write(in, inOfs, inLen);
603
}
604
in = dataBuffer.toByteArray();
605
inOfs = 0;
606
inLen = in.length;
607
}
608
int k = 0;
609
if (encrypt) {
610
k = token.p11.C_Encrypt(session.id(), 0, in, inOfs, inLen,
611
0, out, outOfs, outLen);
612
doCancel = false;
613
} else {
614
// Special handling to match SunJCE provider behavior
615
if (inLen == 0) {
616
return 0;
617
}
618
k = token.p11.C_Decrypt(session.id(), 0, in, inOfs, inLen,
619
0, out, outOfs, outLen);
620
doCancel = false;
621
}
622
return k;
623
} catch (PKCS11Exception e) {
624
// As per the PKCS#11 standard, C_Encrypt and C_Decrypt may only
625
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
626
// successful calls to determine the output length. However,
627
// these cases are not expected here because the output length
628
// is checked in the OpenJDK side before making the PKCS#11 call.
629
// Thus, doCancel can safely be 'false'.
630
doCancel = false;
631
handleException(e);
632
throw new ProviderException("doFinal() failed", e);
633
} finally {
634
if (encrypt) {
635
lastEncKey = this.p11Key;
636
lastEncIv = this.iv;
637
requireReinit = true;
638
}
639
reset(doCancel);
640
}
641
}
642
643
private int implDoFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
644
throws ShortBufferException, IllegalBlockSizeException,
645
BadPaddingException {
646
int outLen = outBuffer.remaining();
647
int inLen = inBuffer.remaining();
648
649
int requiredOutLen = doFinalLength(inLen);
650
if (outLen < requiredOutLen) {
651
throw new ShortBufferException();
652
}
653
654
boolean doCancel = true;
655
try {
656
ensureInitialized();
657
658
long inAddr = 0;
659
byte[] in = null;
660
int inOfs = 0;
661
if (dataBuffer.size() > 0) {
662
if (inLen > 0) {
663
byte[] temp = new byte[inLen];
664
inBuffer.get(temp);
665
dataBuffer.write(temp, 0, temp.length);
666
}
667
in = dataBuffer.toByteArray();
668
inOfs = 0;
669
inLen = in.length;
670
} else {
671
if (inBuffer instanceof DirectBuffer) {
672
inAddr = ((DirectBuffer) inBuffer).address();
673
inOfs = inBuffer.position();
674
} else {
675
if (inBuffer.hasArray()) {
676
in = inBuffer.array();
677
inOfs = inBuffer.position() + inBuffer.arrayOffset();
678
} else {
679
in = new byte[inLen];
680
inBuffer.get(in);
681
}
682
}
683
}
684
long outAddr = 0;
685
byte[] outArray = null;
686
int outOfs = 0;
687
if (outBuffer instanceof DirectBuffer) {
688
outAddr = ((DirectBuffer) outBuffer).address();
689
outOfs = outBuffer.position();
690
} else {
691
if (outBuffer.hasArray()) {
692
outArray = outBuffer.array();
693
outOfs = outBuffer.position() + outBuffer.arrayOffset();
694
} else {
695
outArray = new byte[outLen];
696
}
697
}
698
699
int k = 0;
700
if (encrypt) {
701
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
702
outAddr, outArray, outOfs, outLen);
703
doCancel = false;
704
} else {
705
// Special handling to match SunJCE provider behavior
706
if (inLen == 0) {
707
return 0;
708
}
709
k = token.p11.C_Decrypt(session.id(), inAddr, in, inOfs, inLen,
710
outAddr, outArray, outOfs, outLen);
711
doCancel = false;
712
}
713
outBuffer.position(outBuffer.position() + k);
714
return k;
715
} catch (PKCS11Exception e) {
716
// As per the PKCS#11 standard, C_Encrypt and C_Decrypt may only
717
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
718
// successful calls to determine the output length. However,
719
// these cases are not expected here because the output length
720
// is checked in the OpenJDK side before making the PKCS#11 call.
721
// Thus, doCancel can safely be 'false'.
722
doCancel = false;
723
handleException(e);
724
throw new ProviderException("doFinal() failed", e);
725
} finally {
726
if (encrypt) {
727
lastEncKey = this.p11Key;
728
lastEncIv = this.iv;
729
requireReinit = true;
730
}
731
reset(doCancel);
732
}
733
}
734
735
private void handleException(PKCS11Exception e)
736
throws ShortBufferException, IllegalBlockSizeException,
737
BadPaddingException {
738
long errorCode = e.getErrorCode();
739
if (errorCode == CKR_BUFFER_TOO_SMALL) {
740
throw (ShortBufferException)
741
(new ShortBufferException().initCause(e));
742
} else if (errorCode == CKR_DATA_LEN_RANGE ||
743
errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
744
throw (IllegalBlockSizeException)
745
(new IllegalBlockSizeException(e.toString()).initCause(e));
746
} else if (errorCode == CKR_ENCRYPTED_DATA_INVALID) {
747
throw (BadPaddingException)
748
(new BadPaddingException(e.toString()).initCause(e));
749
}
750
}
751
752
// see JCE spec
753
protected byte[] engineWrap(Key key) throws IllegalBlockSizeException,
754
InvalidKeyException {
755
// XXX key wrapping
756
throw new UnsupportedOperationException("engineWrap()");
757
}
758
759
// see JCE spec
760
protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
761
int wrappedKeyType)
762
throws InvalidKeyException, NoSuchAlgorithmException {
763
// XXX key unwrapping
764
throw new UnsupportedOperationException("engineUnwrap()");
765
}
766
767
// see JCE spec
768
@Override
769
protected int engineGetKeySize(Key key) throws InvalidKeyException {
770
int n = P11SecretKeyFactory.convertKey
771
(token, key, ALGO).length();
772
return n;
773
}
774
}
775
776
777