fix: defensively copy secret and encapsulation before destroy()
SecretWithEncapsulation may zeroize internal buffers on destroy(). Create defensive copies of the shared secret and ciphertext using Arrays.copyOf() before destroying the result object to ensure stable output. No cryptographic behavior changes; fixes a potential lifecycle bug. Signed-off-by: Leo Galambos <lg@hq.egothor.org>
This commit is contained in:
@@ -39,6 +39,7 @@ import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
@@ -158,8 +159,8 @@ public final class BikeKemContext implements KemContext {
|
||||
.createKey(key.getEncoded());
|
||||
BIKEKEMGenerator gen = new BIKEKEMGenerator(new SecureRandom());
|
||||
SecretWithEncapsulation res = gen.generateEncapsulated(keyParam);
|
||||
byte[] secret = res.getSecret();
|
||||
byte[] ct = res.getEncapsulation();
|
||||
byte[] secret = Arrays.copyOf(res.getSecret(), res.getSecret().length);
|
||||
byte[] ct = Arrays.copyOf(res.getEncapsulation(), res.getEncapsulation().length);
|
||||
res.destroy();
|
||||
return new KemResult(ct, secret);
|
||||
} catch (DestroyFailedException e) {
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
@@ -190,8 +191,8 @@ public final class CmceKemContext implements KemContext {
|
||||
.createKey(key.getEncoded());
|
||||
CMCEKEMGenerator gen = new CMCEKEMGenerator(new SecureRandom());
|
||||
SecretWithEncapsulation res = gen.generateEncapsulated(keyParam);
|
||||
byte[] secret = res.getSecret();
|
||||
byte[] ct = res.getEncapsulation();
|
||||
byte[] secret = Arrays.copyOf(res.getSecret(), res.getSecret().length);
|
||||
byte[] ct = Arrays.copyOf(res.getEncapsulation(), res.getEncapsulation().length);
|
||||
res.destroy();
|
||||
return new KemResult(ct, secret);
|
||||
} catch (DestroyFailedException e) {
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
@@ -179,8 +180,8 @@ public final class FrodoKemContext implements KemContext {
|
||||
.createKey(key.getEncoded());
|
||||
FrodoKEMGenerator gen = new FrodoKEMGenerator(new SecureRandom());
|
||||
SecretWithEncapsulation res = gen.generateEncapsulated(keyParam);
|
||||
byte[] secret = res.getSecret();
|
||||
byte[] ct = res.getEncapsulation();
|
||||
byte[] secret = Arrays.copyOf(res.getSecret(), res.getSecret().length);
|
||||
byte[] ct = Arrays.copyOf(res.getEncapsulation(), res.getEncapsulation().length);
|
||||
res.destroy();
|
||||
return new KemResult(ct, secret);
|
||||
} catch (DestroyFailedException e) {
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
@@ -179,8 +180,8 @@ public final class HqcKemContext implements KemContext {
|
||||
.createKey(key.getEncoded());
|
||||
HQCKEMGenerator gen = new HQCKEMGenerator(new SecureRandom());
|
||||
SecretWithEncapsulation res = gen.generateEncapsulated(keyParam);
|
||||
byte[] secret = res.getSecret();
|
||||
byte[] ct = res.getEncapsulation();
|
||||
byte[] secret = Arrays.copyOf(res.getSecret(), res.getSecret().length);
|
||||
byte[] ct = Arrays.copyOf(res.getEncapsulation(), res.getEncapsulation().length);
|
||||
res.destroy();
|
||||
return new KemResult(ct, secret);
|
||||
} catch (DestroyFailedException e) {
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
@@ -182,8 +183,8 @@ public final class KyberKemContext implements KemContext {
|
||||
.createKey(key.getEncoded());
|
||||
MLKEMGenerator gen = new MLKEMGenerator(new SecureRandom());
|
||||
SecretWithEncapsulation res = gen.generateEncapsulated(keyParam);
|
||||
byte[] secret = res.getSecret();
|
||||
byte[] ct = res.getEncapsulation();
|
||||
byte[] secret = Arrays.copyOf(res.getSecret(), res.getSecret().length);
|
||||
byte[] ct = Arrays.copyOf(res.getEncapsulation(), res.getEncapsulation().length);
|
||||
res.destroy();
|
||||
return new KemResult(ct, secret);
|
||||
} catch (DestroyFailedException e) {
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
@@ -213,8 +214,8 @@ public final class NtruKemContext implements KemContext {
|
||||
.createKey(key.getEncoded());
|
||||
NTRUKEMGenerator gen = new NTRUKEMGenerator(new SecureRandom());
|
||||
SecretWithEncapsulation res = gen.generateEncapsulated(keyParam);
|
||||
byte[] secret = res.getSecret();
|
||||
byte[] ct = res.getEncapsulation();
|
||||
byte[] secret = Arrays.copyOf(res.getSecret(), res.getSecret().length);
|
||||
byte[] ct = Arrays.copyOf(res.getEncapsulation(), res.getEncapsulation().length);
|
||||
res.destroy();
|
||||
return new KemResult(ct, secret);
|
||||
} catch (DestroyFailedException e) {
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
@@ -175,8 +176,8 @@ public final class NtrulPrimeKemContext implements KemContext {
|
||||
.createKey(key.getEncoded());
|
||||
NTRULPRimeKEMGenerator gen = new NTRULPRimeKEMGenerator(new SecureRandom());
|
||||
SecretWithEncapsulation res = gen.generateEncapsulated(keyParam);
|
||||
byte[] secret = res.getSecret();
|
||||
byte[] ct = res.getEncapsulation();
|
||||
byte[] secret = Arrays.copyOf(res.getSecret(), res.getSecret().length);
|
||||
byte[] ct = Arrays.copyOf(res.getEncapsulation(), res.getEncapsulation().length);
|
||||
res.destroy();
|
||||
return new KemResult(ct, secret);
|
||||
} catch (DestroyFailedException e) {
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
@@ -181,8 +182,8 @@ public final class SntruPrimeKemContext implements KemContext {
|
||||
.createKey(key.getEncoded());
|
||||
SNTRUPrimeKEMGenerator gen = new SNTRUPrimeKEMGenerator(new SecureRandom());
|
||||
SecretWithEncapsulation res = gen.generateEncapsulated(keyParam);
|
||||
byte[] secret = res.getSecret();
|
||||
byte[] ct = res.getEncapsulation();
|
||||
byte[] secret = Arrays.copyOf(res.getSecret(), res.getSecret().length);
|
||||
byte[] ct = Arrays.copyOf(res.getEncapsulation(), res.getEncapsulation().length);
|
||||
res.destroy();
|
||||
return new KemResult(ct, secret);
|
||||
} catch (DestroyFailedException e) {
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
@@ -182,8 +183,8 @@ public final class SaberKemContext implements KemContext {
|
||||
.createKey(key.getEncoded());
|
||||
SABERKEMGenerator gen = new SABERKEMGenerator(new SecureRandom());
|
||||
SecretWithEncapsulation res = gen.generateEncapsulated(keyParam);
|
||||
byte[] secret = res.getSecret();
|
||||
byte[] ct = res.getEncapsulation();
|
||||
byte[] secret = Arrays.copyOf(res.getSecret(), res.getSecret().length);
|
||||
byte[] ct = Arrays.copyOf(res.getEncapsulation(), res.getEncapsulation().length);
|
||||
res.destroy();
|
||||
return new KemResult(ct, secret);
|
||||
} catch (DestroyFailedException e) {
|
||||
|
||||
Reference in New Issue
Block a user