Skip to content

Commit 0e86ed5

Browse files
sabrinajleeSabrina Lee
andauthored
Implement cleaner in remaining algorithms (#944)
Removes the deprecated finalize() method from the non key algorithms and implements a runnable function to handle native memory cleanup in their places. Signed-off-by: Sabrina Lee <[email protected]> Co-authored-by: Sabrina Lee <[email protected]>
1 parent e37012b commit 0e86ed5

22 files changed

+398
-281
lines changed

src/main/java/com/ibm/crypto/plus/provider/AESCCMCipher.java

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ public AESCCMCipher(OpenJCEPlusProvider provider) {
106106
throw provider.providerException("Failed to initialize cipher context", e);
107107
}
108108
buffer = new byte[AES_BLOCK_SIZE * 2];
109+
110+
this.provider.registerCleanable(this, cleanOCKResources(Key, ockContext));
109111
}
110112

111113

@@ -732,25 +734,6 @@ int getMode() {
732734
return (encrypting) ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
733735
}
734736

735-
736-
@Override
737-
protected synchronized void finalize() throws Throwable {
738-
//final String methodName = "finalize";
739-
// OCKDebug.Msg (debPrefix, methodName, "finalize called");
740-
try {
741-
if (ockContext != null) {
742-
CCMCipher.doCCM_cleanup(ockContext);
743-
}
744-
if (Key != null) {
745-
Arrays.fill(Key, (byte) 0x00);
746-
Key = null;
747-
}
748-
} finally {
749-
super.finalize();
750-
}
751-
}
752-
753-
754737
private void checkReinit() {
755738
if (requireReinit) {
756739
throw new IllegalStateException(
@@ -790,4 +773,22 @@ protected int engineUpdate(ByteBuffer input, ByteBuffer output) throws ShortBuff
790773
"engineUpdate is not supported for AESCCM. Only engineDoFinal is supported.");
791774
}
792775

776+
private Runnable cleanOCKResources(byte[] Key, OCKContext ockContext) {
777+
return() -> {
778+
try {
779+
if (ockContext != null) {
780+
CCMCipher.doCCM_cleanup(ockContext);
781+
}
782+
if (Key != null) {
783+
Arrays.fill(Key, (byte) 0x00);
784+
}
785+
} catch (Exception e) {
786+
if (OpenJCEPlusProvider.getDebug() != null) {
787+
OpenJCEPlusProvider.getDebug().println("An error occurred while cleaning : " + e.getMessage());
788+
e.printStackTrace();
789+
}
790+
}
791+
};
792+
}
793+
793794
} // End of class

src/main/java/com/ibm/crypto/plus/provider/AESCipher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ private void internalInit(int opmode, Key key, byte[] iv) throws InvalidKeyExcep
296296
try {
297297
if ((symmetricCipher == null) || (symmetricCipher.getKeyLength() != rawKey.length)) {
298298
symmetricCipher = SymmetricCipher.getInstanceAES(provider.getOCKContext(), mode,
299-
padding, rawKey.length);
299+
padding, rawKey.length, provider);
300300
// Check whether used algorithm is CBC and whether hardware supports is available
301301
use_z_fast_command = symmetricCipher.getHardwareSupportStatus();
302302
}

src/main/java/com/ibm/crypto/plus/provider/AESGCMCipher.java

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ public AESGCMCipher(OpenJCEPlusProvider provider) {
144144
throw provider.providerException("Failed to initialize cipher context", e);
145145
}
146146
buffer = new byte[AES_BLOCK_SIZE * 2];
147+
148+
this.provider.registerCleanable(this, cleanOCKResources(Key));
147149
}
148150

149151

@@ -333,7 +335,7 @@ protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[]
333335
}
334336

335337
int ret = GCMCipher.doGCMFinal_Encrypt(ockContext, Key, IV, tagLenInBytes, input,
336-
inputOffset, inputLen, output, outputOffset, authData);
338+
inputOffset, inputLen, output, outputOffset, authData, provider);
337339
authData = null; // Before returning from doFinal(), restore AAD to uninitialized state
338340

339341
if (generateIV) {
@@ -356,7 +358,7 @@ protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[]
356358
}
357359

358360
int ret = GCMCipher.doGCMFinal_Decrypt(ockContext, Key, IV, tagLenInBytes, input,
359-
inputOffset, inputLen, output, outputOffset, authData);
361+
inputOffset, inputLen, output, outputOffset, authData, provider);
360362
authData = null; // Before returning from doFinal(), restore AAD to uninitialized state
361363
return ret;
362364
}
@@ -989,7 +991,7 @@ protected int doUpdate(byte[] input, int inputOffset, int inputLen, byte[] outpu
989991
if (!encrypting) {
990992
// OCKDebug.Msg(debPrefix, methodName, "Calling do_GCM_InitForUpdateDecrypt");
991993
outLen = GCMCipher.do_GCM_InitForUpdateDecrypt(ockContext, Key, IV,
992-
tagLenInBytes, buffer, 0, len, output, outputOffset, authData);
994+
tagLenInBytes, buffer, 0, len, output, outputOffset, authData, provider);
993995
// OCKDebug.Msg(debPrefix, methodName, "returning ret from
994996
// InitForUpdateDecrypt=" + outLen);
995997
} else {
@@ -1007,7 +1009,7 @@ protected int doUpdate(byte[] input, int inputOffset, int inputLen, byte[] outpu
10071009
}
10081010
// OCKDebug.Msg(debPrefix, methodName, "Calling do_GCM_InitForUpdateEncrypt");
10091011
outLen = GCMCipher.do_GCM_InitForUpdateEncrypt(ockContext, Key, IV,
1010-
tagLenInBytes, buffer, 0, len, output, outputOffset, authData);
1012+
tagLenInBytes, buffer, 0, len, output, outputOffset, authData, provider);
10111013
// OCKDebug.Msg(debPrefix, methodName, "returning ret from
10121014
// InitForUpdateEncrypt=" + outLen);
10131015
}
@@ -1043,7 +1045,7 @@ protected int doUpdate(byte[] input, int inputOffset, int inputLen, byte[] outpu
10431045
// GCMCipher.do_GCM_UpdateDecrypt");
10441046

10451047
outLen = GCMCipher.do_GCM_UpdForUpdateDecrypt(ockContext, Key, IV,
1046-
tagLenInBytes, buffer, 0, len, output, outputOffset, authData);
1048+
tagLenInBytes, buffer, 0, len, output, outputOffset, authData, provider);
10471049

10481050
// OCKDebug.Msg(debPrefix, methodName, "returning ret from
10491051
// GCMCipher.do_GCM_UpdForUpdateDecrypt=" + outLen);
@@ -1055,7 +1057,7 @@ protected int doUpdate(byte[] input, int inputOffset, int inputLen, byte[] outpu
10551057
// OCKDebug.Msg(debPrefix, methodName, "FirstUpdate generateIV");
10561058

10571059
outLen = GCMCipher.do_GCM_UpdForUpdateEncrypt(ockContext, Key, IV,
1058-
tagLenInBytes, buffer, 0, len, output, outputOffset, authData);
1060+
tagLenInBytes, buffer, 0, len, output, outputOffset, authData, provider);
10591061
// OCKDebug.Msg(debPrefix, methodName, "returning ret from
10601062
// GCMCipher.do_GCM_UpdForUpdateEncrypt=" + outLen);
10611063
// outLen = cipher.encrypt(buffer, 0, len, output, outputOffset);
@@ -1089,13 +1091,13 @@ protected int doUpdate(byte[] input, int inputOffset, int inputLen, byte[] outpu
10891091
if (!encrypting) {
10901092
outLen = GCMCipher.do_GCM_UpdForUpdateDecrypt(ockContext, Key, IV,
10911093
tagLenInBytes, buffer, 0, buffered, output, outputOffset,
1092-
authData);
1094+
authData, provider);
10931095
// outLen = cipher.decrypt(buffer, 0, buffered, output, outputOffset);
10941096
} // decrypting
10951097
else {
10961098
outLen = GCMCipher.do_GCM_UpdForUpdateEncrypt(ockContext, Key, IV,
10971099
tagLenInBytes, buffer, 0, buffered, output, outputOffset,
1098-
authData);
1100+
authData, provider);
10991101
// outLen = cipher.encrypt(buffer, 0, buffered, output, outputOffset);
11001102
// encrypt mode. Zero out internal (input) buffer
11011103
Arrays.fill(buffer, (byte) 0x00);
@@ -1110,15 +1112,15 @@ protected int doUpdate(byte[] input, int inputOffset, int inputLen, byte[] outpu
11101112

11111113
outLen += GCMCipher.do_GCM_UpdForUpdateDecrypt(ockContext, Key, IV,
11121114
tagLenInBytes, input, inputOffset, inputConsumed, output,
1113-
outputOffset, authData);
1115+
outputOffset, authData, provider);
11141116
// outLen += cipher.decrypt(input, inputOffset, inputConsumed,
11151117
// output, outputOffset);
11161118
} else {
11171119

11181120

11191121
outLen += GCMCipher.do_GCM_UpdForUpdateEncrypt(ockContext, Key, IV,
11201122
tagLenInBytes, input, inputOffset, inputConsumed, output,
1121-
outputOffset, authData);
1123+
outputOffset, authData, provider);
11221124

11231125
}
11241126
inputOffset += inputConsumed;
@@ -1272,13 +1274,13 @@ private int finalNoPadding(byte[] in, int inOfs, byte[] out, int outOfs, int len
12721274

12731275
if (!encrypting) {
12741276
outLen = GCMCipher.do_GCM_FinalForUpdateDecrypt(ockContext, Key, IV, tagLenInBytes, in,
1275-
inOfs, len, out, outOfs, authData);
1277+
inOfs, len, out, outOfs, authData, provider);
12761278
// OCKDebug.Msg(debPrefix, methodName, "outLen from
12771279
// GCMCipher.do_GCM_FinalForUpdateDecrypt=" + outLen);
12781280

12791281
} else {
12801282
outLen = GCMCipher.do_GCM_FinalForUpdateEncrypt(ockContext, Key, IV, tagLenInBytes, in,
1281-
inOfs, len, out, outOfs, authData);
1283+
inOfs, len, out, outOfs, authData, provider);
12821284
// OCKDebug.Msg(debPrefix, methodName, "outLen from
12831285
// GCMCipher.do_GCM_FinalForUpdateEncrypt=" + outLen);
12841286

@@ -1413,22 +1415,6 @@ private void endDoFinal() {
14131415
diffBlocksize = blockSize;
14141416
}
14151417

1416-
@Override
1417-
protected synchronized void finalize() throws Throwable {
1418-
//final String methodName = "finalize";
1419-
// OCKDebug.Msg (debPrefix, methodName, "finalize called");
1420-
try {
1421-
1422-
//JS00684 - Leave cleanup of internal variables to GCMCipher that caches them
1423-
if (Key != null) {
1424-
Arrays.fill(Key, (byte) 0x00);
1425-
Key = null;
1426-
}
1427-
} finally {
1428-
super.finalize();
1429-
}
1430-
}
1431-
14321418
private void checkReinit() {
14331419
if (requireReinit) {
14341420
throw new IllegalStateException(
@@ -1467,4 +1453,20 @@ private void resetVars(boolean afterFailure) {
14671453
this.buffered = 0;
14681454
Arrays.fill(buffer, (byte) 0x0);
14691455
}
1456+
1457+
private Runnable cleanOCKResources(byte[] Key) {
1458+
return() -> {
1459+
try {
1460+
//JS00684 - Leave cleanup of internal variables to GCMCipher that caches them
1461+
if (Key != null) {
1462+
Arrays.fill(Key, (byte) 0x00);
1463+
}
1464+
} catch (Exception e) {
1465+
if (OpenJCEPlusProvider.getDebug() != null) {
1466+
OpenJCEPlusProvider.getDebug().println("An error occurred while cleaning : " + e.getMessage());
1467+
e.printStackTrace();
1468+
}
1469+
}
1470+
};
1471+
}
14701472
}

src/main/java/com/ibm/crypto/plus/provider/ChaCha20Cipher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ private void internalInit(int opmode, Key newKey, byte[] newNonceBytes, int newC
232232
try {
233233
if (symmetricCipher == null) {
234234
symmetricCipher = SymmetricCipher.getInstanceChaCha20(provider.getOCKContext(),
235-
padding);
235+
padding, provider);
236236
}
237237

238238
if (isEncrypt) {

src/main/java/com/ibm/crypto/plus/provider/ChaCha20Poly1305Cipher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ private void internalInit(int opmode, Key newKey, byte[] newNonceBytes)
328328
try {
329329
if (poly1305Cipher == null) {
330330
poly1305Cipher = Poly1305Cipher.getInstance(provider.getOCKContext(),
331-
OCK_CHACHA20_POLY1305, padding);
331+
OCK_CHACHA20_POLY1305, padding, provider);
332332
}
333333

334334
if (this.encrypting) {

src/main/java/com/ibm/crypto/plus/provider/DESedeCipher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ private void internalInit(int opmode, Key key, byte[] iv) throws InvalidKeyExcep
240240
try {
241241
if (symmetricCipher == null) {
242242
symmetricCipher = SymmetricCipher.getInstanceDESede(provider.getOCKContext(), mode,
243-
padding);
243+
padding, provider);
244244
}
245245

246246
if (isEncrypt) {

src/main/java/com/ibm/crypto/plus/provider/HASHDRBG.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright IBM Corp. 2023
2+
* Copyright IBM Corp. 2023, 2025
33
*
44
* This code is free software; you can redistribute it and/or modify it
55
* under the terms provided by IBM in the LICENSE file that accompanied
@@ -33,7 +33,7 @@ protected HASHDRBG(OpenJCEPlusProvider provider, String ockRandomAlgo) {
3333
this.randomAlgo = ockRandomAlgo;
3434
basicRandom = BasicRandom.getInstance(provider.getOCKContext());
3535
try {
36-
extendedRandom = ExtendedRandom.getInstance(provider.getOCKContext(), ockRandomAlgo);
36+
extendedRandom = ExtendedRandom.getInstance(provider.getOCKContext(), ockRandomAlgo, provider);
3737
} catch (Exception e) {
3838
throw provider.providerException("Failed to get HASHDRBG algorithm", e);
3939
}
@@ -89,7 +89,7 @@ private void readObject(java.io.ObjectInputStream s)
8989
basicRandom = BasicRandom.getInstance(provider.getOCKContext());
9090
try {
9191
// Recreate OCK object per tag [SERIALIZATION] in DesignNotes.txt
92-
extendedRandom = ExtendedRandom.getInstance(provider.getOCKContext(), randomAlgo);
92+
extendedRandom = ExtendedRandom.getInstance(provider.getOCKContext(), randomAlgo, provider);
9393
} catch (Exception e) {
9494
throw provider.providerException("Failed to get HASHDRBG algorithm", e);
9595
}

src/main/java/com/ibm/crypto/plus/provider/HKDFGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public HKDFGenerator(OpenJCEPlusProvider provider, String digestAlgorithm)
4949
this.provider = provider;
5050
this.digestAlgorithm = digestAlgorithm;
5151
try {
52-
hkdfObj = HKDF.getInstance(this.provider.getOCKContext(), this.digestAlgorithm);
52+
hkdfObj = HKDF.getInstance(this.provider.getOCKContext(), this.digestAlgorithm, provider);
5353
hkdfLen = hkdfObj.getMacLength();
5454
} catch (Exception ex) {
5555
throw new NoSuchAlgorithmException("cannot initialize hkdf");

src/main/java/com/ibm/crypto/plus/provider/HKDFKeyDerivation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ private HKDFKeyDerivation(OpenJCEPlusProvider provider, SupportedHmac supportedH
7676
this.digestAlgName = supportedHmac.digestAlg;
7777
this.hmacLen = supportedHmac.hmacLen;
7878
try {
79-
hkdfObj = HKDF.getInstance(this.provider.getOCKContext(), this.digestAlgName);
79+
hkdfObj = HKDF.getInstance(this.provider.getOCKContext(), this.digestAlgName, provider);
8080
if (hkdfObj.getMacLength() != this.hmacLen) {
8181
throw new ProviderException("Mismatch between expected and OCK provided HMAC length");
8282
}

src/main/java/com/ibm/crypto/plus/provider/HmacCore.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ abstract class HmacCore extends MacSpi {
2525
HmacCore(OpenJCEPlusProvider provider, String ockDigestAlgo, int blockLength) {
2626
try {
2727
this.provider = provider;
28-
this.hmac = HMAC.getInstance(provider.getOCKContext(), ockDigestAlgo);
28+
this.hmac = HMAC.getInstance(provider.getOCKContext(), ockDigestAlgo, provider);
2929
} catch (Exception e) {
3030
throw provider.providerException("Failure in HmacCore", e);
3131
}

0 commit comments

Comments
 (0)