Skip to content

Commit e14913d

Browse files
Fix memory leak computing ECDH secrets (#411)
The context allocated in the method `XECKEY.computeECDHSecret` was never freed when a key was successfully generated. This update frees memory associated with the context prior to return of the secret key bytes. Whitespace and formatting was also done to make use of brackets for if statements. Fixes #387 Signed-off-by: Jason Katonica <katonica@us.ibm.com>
1 parent c71b70c commit e14913d

File tree

3 files changed

+42
-33
lines changed

3 files changed

+42
-33
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ protected Key engineDoPhase(Key key, boolean lastPhase)
110110
this.secret = XECKey.computeECDHSecret(provider.getOCKContext(), genCtx,
111111
ockXecKeyPub.getPKeyId(), ockXecKeyPriv.getPKeyId(), secrectBufferSize);
112112
} catch (OCKException e) {
113-
throw new IllegalStateException(e.getMessage());
113+
throw new IllegalStateException("Failed to generate secret", e);
114114
} catch (Exception e) {
115115
throw new InvalidKeyException("Failed to generate secret", e);
116116
}

src/main/native/ECKey.c

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,15 +2114,17 @@ JNIEXPORT jbyteArray JNICALL Java_com_ibm_crypto_plus_provider_ock_NativeInterfa
21142114
jbyteArray secretBytes = NULL;
21152115
unsigned char * secretBytesNative = NULL;
21162116
jboolean isCopy = 0;
2117-
jbyteArray retSecretBytes = NULL;
21182117
size_t secret_key_len = 0;
2118+
int rc = 0;
21192119

2120-
2121-
if( debug ) gslogFunctionEntry(functionName);
2120+
if (debug) {
2121+
gslogFunctionEntry(functionName);
2122+
}
21222123

21232124
gen_ctx = ICC_EVP_PKEY_CTX_new(ockCtx,(ICC_EVP_PKEY *) ockPrivXecKey,NULL); /* Set private key */
2124-
if(gen_ctx == NULL) throwOCKException(env, 0, "NULL from ICC_EVP_PKEY_CTX_new");
2125-
else {
2125+
if (NULL == gen_ctx) {
2126+
throwOCKException(env, 0, "NULL from ICC_EVP_PKEY_CTX_new");
2127+
} else {
21262128
ICC_EVP_PKEY_derive_init(ockCtx, gen_ctx);
21272129
ICC_EVP_PKEY_derive_set_peer(ockCtx, gen_ctx, ockPubXecKey); /* Set public key */
21282130
if (secretBufferSize > 0) {
@@ -2131,28 +2133,43 @@ JNIEXPORT jbyteArray JNICALL Java_com_ibm_crypto_plus_provider_ock_NativeInterfa
21312133
ICC_EVP_PKEY_derive(ockCtx, gen_ctx, NULL, &secret_key_len); /* Get secret key size */
21322134
}
21332135
secretBytes = (*env)->NewByteArray(env, secret_key_len); /* Create Java secret bytes array with size */
2134-
if( secretBytes == NULL ) throwOCKException(env, 0, "NewByteArray failed");
2135-
else {
2136+
if (NULL == secretBytes) {
2137+
throwOCKException(env, 0, "NewByteArray failed");
2138+
} else {
21362139
secretBytesNative = (unsigned char*)((*env)->GetPrimitiveArrayCritical(env, secretBytes, &isCopy));
2137-
if( secretBytesNative == NULL ) throwOCKException(env, 0, "NULL from GetPrimitiveArrayCritical");
2138-
else {
2139-
ICC_EVP_PKEY_derive(ockCtx, gen_ctx, secretBytesNative, &secret_key_len);
2140-
retSecretBytes = secretBytes;
2141-
if( secretBytesNative != NULL ) (*env)->ReleasePrimitiveArrayCritical(env, secretBytes, secretBytesNative, 0);
2142-
if((secretBytes != NULL) && (retSecretBytes == NULL)) (*env)->DeleteLocalRef(env, secretBytes);
2143-
if( debug ) gslogFunctionExit(functionName);
2144-
return retSecretBytes;
2140+
if (NULL == secretBytesNative) {
2141+
throwOCKException(env, 0, "NULL from GetPrimitiveArrayCritical");
2142+
} else {
2143+
rc = ICC_EVP_PKEY_derive(ockCtx, gen_ctx, secretBytesNative, &secret_key_len);
2144+
if (ICC_OSSL_SUCCESS != rc ) {
2145+
throwOCKException(env, 0, "ICC_EVP_PKEY_derive failed to derive a key");
2146+
}
2147+
ICC_EVP_PKEY_CTX_free(ockCtx, gen_ctx);
2148+
(*env)->ReleasePrimitiveArrayCritical(env, secretBytes, secretBytesNative, 0);
2149+
if (debug) {
2150+
gslogFunctionExit(functionName);
2151+
}
2152+
return secretBytes;
21452153
}
21462154
}
2147-
if (gen_ctx != NULL) {
2148-
ICC_EVP_PKEY_CTX_free(ockCtx,gen_ctx);
2149-
gen_ctx = NULL;
2150-
}
21512155
}
21522156

2153-
if( secretBytesNative != NULL ) (*env)->ReleasePrimitiveArrayCritical(env, secretBytes, secretBytesNative, 0);
2154-
if((secretBytes != NULL) && (retSecretBytes == NULL)) (*env)->DeleteLocalRef(env, secretBytes);
2155-
if( debug ) gslogFunctionExit(functionName);
2157+
if (NULL != gen_ctx) {
2158+
ICC_EVP_PKEY_CTX_free(ockCtx, gen_ctx);
2159+
}
2160+
2161+
if (NULL != secretBytesNative) {
2162+
(*env)->ReleasePrimitiveArrayCritical(env, secretBytes, secretBytesNative, 0);
2163+
}
2164+
2165+
if (NULL != secretBytes) {
2166+
(*env)->DeleteLocalRef(env, secretBytes);
2167+
}
2168+
2169+
if (debug) {
2170+
gslogFunctionExit(functionName);
2171+
}
2172+
21562173
return NULL;
21572174
}
21582175

src/test/java/ibm/jceplus/junit/base/BaseTestXDH.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import java.util.Arrays;
3232
import javax.crypto.KeyAgreement;
3333
import org.junit.jupiter.api.Test;
34-
import static org.junit.Assert.assertTrue;
34+
import static org.junit.jupiter.api.Assertions.assertTrue;
3535

3636
public class BaseTestXDH extends BaseTestJunit5 {
3737

@@ -337,18 +337,10 @@ private void testSmallOrder(String name, String a_pri, String b_pub, String resu
337337
throws Exception {
338338

339339
try {
340-
//System.out.println("Pub - "+b_pub);
341340
runDiffieHellmanTest(name, a_pri, b_pub, result);
342-
} catch (InvalidKeyException ex) {
343-
assertTrue(true);
344-
return;
345-
} catch (InvalidKeySpecException ex) {
346-
assertTrue(true);
341+
} catch (IllegalStateException ex) {
347342
return;
348-
} catch (Exception e1) {
349-
System.out.println(e1.getMessage());
350343
}
351-
352344
throw new RuntimeException("No exception on small-order point");
353345
}
354346

0 commit comments

Comments
 (0)