JNI/JCE: reduce extra WolfCryptRng object creation between Signature and KeyPairGenerator classes

pull/73/head
Chris Conlon 2024-04-11 17:39:47 -06:00
parent 5f094107a0
commit 947db4345a
3 changed files with 84 additions and 35 deletions

View File

@ -80,6 +80,9 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
private Rng rng = null; private Rng rng = null;
/* Lock around Rng access */
private final Object rngLock = new Object();
/* for debug logging */ /* for debug logging */
private WolfCryptDebug debug; private WolfCryptDebug debug;
private String algString; private String algString;
@ -88,8 +91,8 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
this.type = type; this.type = type;
rng = new Rng(); this.rng = new Rng();
rng.init(); this.rng.init();
if (debug.DEBUG) if (debug.DEBUG)
algString = typeToString(type); algString = typeToString(type);
@ -232,7 +235,10 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
Rsa rsa = new Rsa(); Rsa rsa = new Rsa();
try { try {
rsa.makeKey(this.keysize, this.publicExponent, rng); synchronized (rngLock) {
rsa.makeKey(this.keysize, this.publicExponent,
this.rng);
}
/* private key */ /* private key */
privDer = rsa.privateKeyEncodePKCS8(); privDer = rsa.privateKeyEncodePKCS8();
@ -280,13 +286,16 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
ECPrivateKey eccPriv = null; ECPrivateKey eccPriv = null;
ECPublicKey eccPub = null; ECPublicKey eccPub = null;
Ecc ecc = null;
Ecc ecc = new Ecc(); synchronized (rngLock) {
ecc = new Ecc(this.rng);
if (this.curve == null) { if (this.curve == null) {
ecc.makeKey(rng, this.keysize); ecc.makeKey(this.rng, this.keysize);
} else { } else {
ecc.makeKeyOnCurve(rng, this.keysize, this.curve); ecc.makeKeyOnCurve(this.rng, this.keysize, this.curve);
}
} }
/* private key */ /* private key */
@ -343,7 +352,9 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
dh.setParams(dhP, dhG); dh.setParams(dhP, dhG);
/* make key */ /* make key */
dh.makeKey(rng); synchronized (rngLock) {
dh.makeKey(this.rng);
}
privSpec = new DHPrivateKeySpec( privSpec = new DHPrivateKeySpec(
new BigInteger(dh.getPrivateKey()), new BigInteger(dh.getPrivateKey()),
@ -403,9 +414,11 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
@Override @Override
protected synchronized void finalize() throws Throwable { protected synchronized void finalize() throws Throwable {
try { try {
if (this.rng != null) { synchronized (rngLock) {
rng.free(); if (this.rng != null) {
rng.releaseNativeStruct(); this.rng.free();
this.rng.releaseNativeStruct();
}
} }
} finally { } finally {
super.finalize(); super.finalize();

View File

@ -111,15 +111,20 @@ public class WolfCryptSignature extends SignatureSpi {
this.keyType = ktype; this.keyType = ktype;
this.digestType = dtype; this.digestType = dtype;
/* init asn object */
asn = new Asn();
if ((ktype != KeyType.WC_RSA) && if ((ktype != KeyType.WC_RSA) &&
(ktype != KeyType.WC_ECDSA)) { (ktype != KeyType.WC_ECDSA)) {
throw new NoSuchAlgorithmException( throw new NoSuchAlgorithmException(
"Signature algorithm key type must be RSA or ECC"); "Signature algorithm key type must be RSA or ECC");
} }
synchronized (rngLock) {
this.rng = new Rng();
this.rng.init();
}
/* init asn object */
asn = new Asn();
/* init hash type */ /* init hash type */
switch (dtype) { switch (dtype) {
case WC_MD5: case WC_MD5:
@ -157,11 +162,6 @@ public class WolfCryptSignature extends SignatureSpi {
"Unsupported signature algorithm digest type"); "Unsupported signature algorithm digest type");
} }
synchronized (rngLock) {
this.rng = new Rng();
this.rng.init();
}
if (debug.DEBUG) { if (debug.DEBUG) {
keyString = typeToString(ktype); keyString = typeToString(ktype);
digestString = digestToString(dtype); digestString = digestToString(dtype);
@ -247,14 +247,18 @@ public class WolfCryptSignature extends SignatureSpi {
/* initialize native struct */ /* initialize native struct */
switch (keyType) { switch (keyType) {
case WC_RSA: case WC_RSA:
if (this.rsa != null) if (this.rsa != null) {
this.rsa.releaseNativeStruct(); this.rsa.releaseNativeStruct();
}
this.rsa = new Rsa(); this.rsa = new Rsa();
break; break;
case WC_ECDSA: case WC_ECDSA:
if (this.ecc != null) if (this.ecc != null) {
this.ecc.releaseNativeStruct(); this.ecc.releaseNativeStruct();
this.ecc = new Ecc(); }
synchronized (this.rngLock) {
this.ecc = new Ecc(this.rng);
}
break; break;
} }
@ -312,14 +316,18 @@ public class WolfCryptSignature extends SignatureSpi {
/* initialize native struct */ /* initialize native struct */
switch (keyType) { switch (keyType) {
case WC_RSA: case WC_RSA:
if (this.rsa != null) if (this.rsa != null) {
this.rsa.releaseNativeStruct(); this.rsa.releaseNativeStruct();
}
this.rsa = new Rsa(); this.rsa = new Rsa();
break; break;
case WC_ECDSA: case WC_ECDSA:
if (this.ecc != null) if (this.ecc != null) {
this.ecc.releaseNativeStruct(); this.ecc.releaseNativeStruct();
this.ecc = new Ecc(); }
synchronized (this.rngLock) {
this.ecc = new Ecc(this.rng);
}
break; break;
} }
@ -415,7 +423,7 @@ public class WolfCryptSignature extends SignatureSpi {
byte[] tmp = new byte[encodedSz]; byte[] tmp = new byte[encodedSz];
System.arraycopy(encDigest, 0, tmp, 0, encodedSz); System.arraycopy(encDigest, 0, tmp, 0, encodedSz);
synchronized (rngLock) { synchronized (rngLock) {
signature = this.rsa.sign(tmp, rng); signature = this.rsa.sign(tmp, this.rng);
} }
zeroArray(tmp); zeroArray(tmp);
@ -425,7 +433,7 @@ public class WolfCryptSignature extends SignatureSpi {
/* ECC sign */ /* ECC sign */
synchronized (rngLock) { synchronized (rngLock) {
signature = this.ecc.sign(digest, rng); signature = this.ecc.sign(digest, this.rng);
} }
break; break;
@ -652,6 +660,7 @@ public class WolfCryptSignature extends SignatureSpi {
/* release RNG */ /* release RNG */
this.rng.free(); this.rng.free();
this.rng.releaseNativeStruct(); this.rng.releaseNativeStruct();
this.rng = null;
} }
} }

View File

@ -38,9 +38,17 @@ public class Ecc extends NativeStruct {
/* used with native wc_ecc_set_rng() */ /* used with native wc_ecc_set_rng() */
private Rng rng = null; private Rng rng = null;
/* Do we own the Rng struct, or has that been passed in? Used
* during Rng cleanup. */
private boolean weOwnRng = true;
/** Lock around Rng object access */
private final Object rngLock = new Object();
/** Lock around object state */ /** Lock around object state */
protected final Object stateLock = new Object(); protected final Object stateLock = new Object();
/** /**
* Create new Ecc object * Create new Ecc object
*/ */
@ -48,6 +56,18 @@ public class Ecc extends NativeStruct {
init(); init();
} }
/**
* Create new Ecc object with existing Rng object.
*
* @param rng initialized com.wolfssl.wolfcrypt.Rng object
*/
public Ecc(Rng rng) {
this.rng = rng;
weOwnRng = false;
init();
}
@Override @Override
public synchronized void releaseNativeStruct() { public synchronized void releaseNativeStruct() {
free(); free();
@ -100,9 +120,12 @@ public class Ecc extends NativeStruct {
} }
/* used with native wc_ecc_set_rng() */ /* used with native wc_ecc_set_rng() */
if (rng == null) { synchronized (rngLock) {
rng = new Rng(); if (rng == null) {
rng.init(); rng = new Rng();
rng.init();
weOwnRng = true;
}
} }
state = WolfCryptState.INITIALIZED; state = WolfCryptState.INITIALIZED;
@ -124,9 +147,11 @@ public class Ecc extends NativeStruct {
wc_ecc_free(); wc_ecc_free();
} }
if (this.rng != null) { synchronized (rngLock) {
rng.free(); if (this.weOwnRng && this.rng != null) {
rng.releaseNativeStruct(); rng.free();
rng.releaseNativeStruct();
}
} }
state = WolfCryptState.UNINITIALIZED; state = WolfCryptState.UNINITIALIZED;
@ -445,7 +470,9 @@ public class Ecc extends NativeStruct {
if (state == WolfCryptState.READY) { if (state == WolfCryptState.READY) {
synchronized (pointerLock) { synchronized (pointerLock) {
return wc_ecc_shared_secret(pubKey, this.rng); synchronized (rngLock) {
return wc_ecc_shared_secret(pubKey, this.rng);
}
} }
} else { } else {
throw new IllegalStateException( throw new IllegalStateException(