changeset 56515:6bbb4af131e3

8228835: Memory leak in PKCS11 provider when using AES GCM Summary: updated freeCKMechanismPtr to free mechanism-specific memories Reviewed-by: jnimeh
author valeriep
date Wed, 14 Aug 2019 01:40:29 +0000
parents 7f75db20c209
children 807d192fb7dd
files src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h
diffstat 4 files changed, 985 insertions(+), 772 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c	Wed Aug 14 00:57:15 2019 +0000
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c	Wed Aug 14 01:40:29 2019 +0000
@@ -73,7 +73,7 @@
 
 
 /*
- * converts a pointer to a CK_DATE structure into a Java CK_DATE Object.
+ * converts a CK_DATE pointer into a Java CK_DATE Object.
  *
  * @param env - used to call JNI funktions to create the new Java object
  * @param ckpValue - the pointer to the CK_DATE structure
@@ -119,11 +119,11 @@
 }
 
 /*
- * converts a pointer to a CK_VERSION structure into a Java CK_VERSION Object.
+ * converts a CK_VERSION pointer into a Java CK_VERSION Object.
  *
  * @param env - used to call JNI funktions to create the new Java object
  * @param ckpVersion - the pointer to the CK_VERSION structure
- * @return - the new Java CK_VERSION object
+ * @return the new Java CK_VERSION object
  */
 jobject ckVersionPtrToJVersion(JNIEnv *env, const CK_VERSION_PTR ckpVersion)
 {
@@ -157,11 +157,11 @@
 }
 
 /*
- * converts a pointer to a CK_SESSION_INFO structure into a Java CK_SESSION_INFO Object.
+ * converts a CK_SESSION_INFO pointer into a Java CK_SESSION_INFO Object.
  *
  * @param env - used to call JNI funktions to create the new Java object
  * @param ckpSessionInfo - the pointer to the CK_SESSION_INFO structure
- * @return - the new Java CK_SESSION_INFO object
+ * @return the new Java CK_SESSION_INFO object
  */
 jobject ckSessionInfoPtrToJSessionInfo(JNIEnv *env, const CK_SESSION_INFO_PTR ckpSessionInfo)
 {
@@ -200,11 +200,11 @@
 }
 
 /*
- * converts a pointer to a CK_ATTRIBUTE structure into a Java CK_ATTRIBUTE Object.
+ * converts a CK_ATTRIBUTE pointer into a Java CK_ATTRIBUTE Object.
  *
  * @param env - used to call JNI funktions to create the new Java object
  * @param ckpAttribute - the pointer to the CK_ATTRIBUTE structure
- * @return - the new Java CK_ATTRIBUTE object
+ * @return the new Java CK_ATTRIBUTE object
  */
 jobject ckAttributePtrToJAttribute(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute)
 {
@@ -240,13 +240,14 @@
 
 
 /*
- * converts a Java CK_VERSION object into a pointer to a CK_VERSION structure
+ * converts a Java CK_VERSION object into a CK_VERSION pointer
  *
  * @param env - used to call JNI funktions to get the values out of the Java object
  * @param jVersion - the Java CK_VERSION object to convert
- * @return - the pointer to the new CK_VERSION structure
+ * @return pointer to the new CK_VERSION structure
  */
-CK_VERSION_PTR jVersionToCKVersionPtr(JNIEnv *env, jobject jVersion)
+CK_VERSION_PTR
+jVersionToCKVersionPtr(JNIEnv *env, jobject jVersion)
 {
     CK_VERSION_PTR ckpVersion;
     jclass jVersionClass;
@@ -257,80 +258,73 @@
         return NULL;
     }
 
-    /* get CK_VERSION class */
+    // retrieve java values
     jVersionClass = (*env)->GetObjectClass(env, jVersion);
     if (jVersionClass == NULL) { return NULL; }
-
-    /* get Major */
     jFieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B");
     if (jFieldID == NULL) { return NULL; }
     jMajor = (*env)->GetByteField(env, jVersion, jFieldID);
-
-    /* get Minor */
     jFieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B");
     if (jFieldID == NULL) { return NULL; }
     jMinor = (*env)->GetByteField(env, jVersion, jFieldID);
 
-    /* allocate memory for CK_VERSION pointer */
-    ckpVersion = (CK_VERSION_PTR) malloc(sizeof(CK_VERSION));
+    // allocate memory for CK_VERSION pointer
+    ckpVersion = (CK_VERSION_PTR) calloc(1, sizeof(CK_VERSION));
     if (ckpVersion == NULL) {
         throwOutOfMemoryError(env, 0);
         return NULL;
     }
+
+    // populate using java values
     ckpVersion->major = jByteToCKByte(jMajor);
     ckpVersion->minor = jByteToCKByte(jMinor);
 
-    return ckpVersion ;
+    return ckpVersion;
 }
 
 
 /*
- * converts a Java CK_DATE object into a pointer to a CK_DATE structure
+ * converts a Java CK_DATE object into a CK_DATE pointer
  *
- * @param env - used to call JNI funktions to get the values out of the Java object
- * @param jVersion - the Java CK_DATE object to convert
- * @return - the pointer to the new CK_DATE structure
+ * @param env - used to call JNI functions to get the values out of the Java object
+ * @param jDate - the Java CK_DATE object to convert
+ * @return pointer to the new CK_DATE structure
  */
-CK_DATE * jDateObjectPtrToCKDatePtr(JNIEnv *env, jobject jDate)
+CK_DATE * jDateObjectToCKDatePtr(JNIEnv *env, jobject jDate)
 {
-    CK_DATE * ckpDate;
+    CK_DATE * ckpDate = NULL;
     CK_ULONG ckLength;
     jclass jDateClass;
     jfieldID jFieldID;
     jobject jYear, jMonth, jDay;
-    jchar *jTempChars;
+    jchar *jTempChars = NULL;
     CK_ULONG i;
 
     if (jDate == NULL) {
         return NULL;
     }
 
-    /* get CK_DATE class */
+    // retrieve java values
     jDateClass = (*env)->FindClass(env, CLASS_DATE);
     if (jDateClass == NULL) { return NULL; }
-
-    /* get Year */
     jFieldID = (*env)->GetFieldID(env, jDateClass, "year", "[C");
     if (jFieldID == NULL) { return NULL; }
     jYear = (*env)->GetObjectField(env, jDate, jFieldID);
-
-    /* get Month */
     jFieldID = (*env)->GetFieldID(env, jDateClass, "month", "[C");
     if (jFieldID == NULL) { return NULL; }
     jMonth = (*env)->GetObjectField(env, jDate, jFieldID);
-
-    /* get Day */
     jFieldID = (*env)->GetFieldID(env, jDateClass, "day", "[C");
     if (jFieldID == NULL) { return NULL; }
     jDay = (*env)->GetObjectField(env, jDate, jFieldID);
 
-    /* allocate memory for CK_DATE pointer */
-    ckpDate = (CK_DATE *) malloc(sizeof(CK_DATE));
+    // allocate memory for CK_DATE pointer
+    ckpDate = (CK_DATE *) calloc(1, sizeof(CK_DATE));
     if (ckpDate == NULL) {
         throwOutOfMemoryError(env, 0);
         return NULL;
     }
 
+    // populate using java values
     if (jYear == NULL) {
         ckpDate->year[0] = 0;
         ckpDate->year[1] = 0;
@@ -338,17 +332,14 @@
         ckpDate->year[3] = 0;
     } else {
         ckLength = (*env)->GetArrayLength(env, jYear);
-        jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
+        jTempChars = (jchar*) calloc(ckLength, sizeof(jchar));
         if (jTempChars == NULL) {
-            free(ckpDate);
             throwOutOfMemoryError(env, 0);
-            return NULL;
+            goto cleanup;
         }
         (*env)->GetCharArrayRegion(env, jYear, 0, ckLength, jTempChars);
         if ((*env)->ExceptionCheck(env)) {
-            free(ckpDate);
-            free(jTempChars);
-            return NULL;
+            goto cleanup;
         }
 
         for (i = 0; (i < ckLength) && (i < 4) ; i++) {
@@ -362,17 +353,14 @@
         ckpDate->month[1] = 0;
     } else {
         ckLength = (*env)->GetArrayLength(env, jMonth);
-        jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
+        jTempChars = (jchar*) calloc(ckLength, sizeof(jchar));
         if (jTempChars == NULL) {
-            free(ckpDate);
             throwOutOfMemoryError(env, 0);
-            return NULL;
+            goto cleanup;
         }
         (*env)->GetCharArrayRegion(env, jMonth, 0, ckLength, jTempChars);
         if ((*env)->ExceptionCheck(env)) {
-            free(ckpDate);
-            free(jTempChars);
-            return NULL;
+            goto cleanup;
         }
 
         for (i = 0; (i < ckLength) && (i < 2) ; i++) {
@@ -386,17 +374,14 @@
         ckpDate->day[1] = 0;
     } else {
         ckLength = (*env)->GetArrayLength(env, jDay);
-        jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
+        jTempChars = (jchar*) calloc(ckLength, sizeof(jchar));
         if (jTempChars == NULL) {
-            free(ckpDate);
             throwOutOfMemoryError(env, 0);
-            return NULL;
+            goto cleanup;
         }
         (*env)->GetCharArrayRegion(env, jDay, 0, ckLength, jTempChars);
         if ((*env)->ExceptionCheck(env)) {
-            free(ckpDate);
-            free(jTempChars);
-            return NULL;
+            goto cleanup;
         }
 
         for (i = 0; (i < ckLength) && (i < 2) ; i++) {
@@ -405,7 +390,11 @@
         free(jTempChars);
     }
 
-    return ckpDate ;
+    return ckpDate;
+cleanup:
+    free(jTempChars);
+    free(ckpDate);
+    return NULL;
 }
 
 
@@ -414,7 +403,7 @@
  *
  * @param env - used to call JNI funktions to get the values out of the Java object
  * @param jAttribute - the Java CK_ATTRIBUTE object to convert
- * @return - the new CK_ATTRIBUTE structure
+ * @return the new CK_ATTRIBUTE structure
  */
 CK_ATTRIBUTE jAttributeToCKAttribute(JNIEnv *env, jobject jAttribute)
 {
@@ -423,6 +412,7 @@
     jfieldID jFieldID;
     jlong jType;
     jobject jPValue;
+
     memset(&ckAttribute, 0, sizeof(CK_ATTRIBUTE));
 
     // TBD: what if jAttribute == NULL?!
@@ -466,187 +456,279 @@
     jclass jSsl3RandomDataClass;
     jobject jRandomInfo, jRIClientRandom, jRIServerRandom, jVersion;
 
-    /* get RandomInfo */
+    // retrieve java values
     fieldID = (*env)->GetFieldID(env, masterKeyDeriveParamClass, "RandomInfo",
             "Lsun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA;");
     if (fieldID == NULL) { return; }
     jRandomInfo = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pClientRandom and ulClientRandomLength out of RandomInfo */
     jSsl3RandomDataClass = (*env)->FindClass(env, CLASS_SSL3_RANDOM_DATA);
     if (jSsl3RandomDataClass == NULL) { return; }
     fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pClientRandom", "[B");
     if (fieldID == NULL) { return; }
     jRIClientRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
-
-    /* get pServerRandom and ulServerRandomLength out of RandomInfo */
     fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pServerRandom", "[B");
     if (fieldID == NULL) { return; }
     jRIServerRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
-
-    /* get pVersion */
     fieldID = (*env)->GetFieldID(env, masterKeyDeriveParamClass, "pVersion",
             "Lsun/security/pkcs11/wrapper/CK_VERSION;");
     if (fieldID == NULL) { return; }
     jVersion = (*env)->GetObjectField(env, jParam, fieldID);
 
-    /* populate java values */
+    // populate using java values
     *cKMasterKeyDeriveParamVersion = jVersionToCKVersionPtr(env, jVersion);
     if ((*env)->ExceptionCheck(env)) { return; }
     jByteArrayToCKByteArray(env, jRIClientRandom,
             &(cKMasterKeyDeriveParamRandomInfo->pClientRandom),
             &(cKMasterKeyDeriveParamRandomInfo->ulClientRandomLen));
     if ((*env)->ExceptionCheck(env)) {
-        free(*cKMasterKeyDeriveParamVersion);
-        return;
+        goto cleanup;
     }
     jByteArrayToCKByteArray(env, jRIServerRandom,
             &(cKMasterKeyDeriveParamRandomInfo->pServerRandom),
             &(cKMasterKeyDeriveParamRandomInfo->ulServerRandomLen));
     if ((*env)->ExceptionCheck(env)) {
-        free(*cKMasterKeyDeriveParamVersion);
-        free(cKMasterKeyDeriveParamRandomInfo->pClientRandom);
-        return;
+        goto cleanup;
     }
+    return;
+cleanup:
+    free(*cKMasterKeyDeriveParamVersion);
+    free(cKMasterKeyDeriveParamRandomInfo->pClientRandom);
+    cKMasterKeyDeriveParamRandomInfo->ulClientRandomLen = 0L;
+    free(cKMasterKeyDeriveParamRandomInfo->pServerRandom);
+    cKMasterKeyDeriveParamRandomInfo->ulServerRandomLen = 0L;
+    // explicitly set to NULL to ensure no double free possible
+    *cKMasterKeyDeriveParamVersion = NULL;
+    cKMasterKeyDeriveParamRandomInfo->pClientRandom = NULL;
+    cKMasterKeyDeriveParamRandomInfo->pServerRandom = NULL;
 }
 
 /*
  * converts the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to a
- * CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure
+ * CK_SSL3_MASTER_KEY_DERIVE_PARAMS pointer
  *
  * @param env - used to call JNI functions to get the Java classes and objects
  * @param jParam - the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to convert
- * @param ckParamPtr - pointer to the new CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure
  */
-void jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv *env,
-        jobject jParam, CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR ckParamPtr)
+CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR
+jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParamPtr(JNIEnv *env,
+        jobject jParam, CK_ULONG *pLength)
 {
+    CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR ckParamPtr;
     jclass jSsl3MasterKeyDeriveParamsClass;
-    memset(ckParamPtr, 0, sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS));
+
+    if (pLength != NULL) {
+        *pLength = 0L;
+    }
+
+    // allocate memory for CK_SSL3_MASTER_KEY_DERIVE_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // retrieve and populate using java values
     jSsl3MasterKeyDeriveParamsClass =
             (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
-    if (jSsl3MasterKeyDeriveParamsClass == NULL) { return; }
+    if (jSsl3MasterKeyDeriveParamsClass == NULL) {
+        goto cleanup;
+    }
     masterKeyDeriveParamToCKMasterKeyDeriveParam(env, jParam,
             jSsl3MasterKeyDeriveParamsClass,
             &(ckParamPtr->pVersion), &(ckParamPtr->RandomInfo));
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
+    }
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr);
+    return NULL;
 }
 
 /*
  * converts the Java CK_TLS12_MASTER_KEY_DERIVE_PARAMS object to a
- * CK_TLS12_MASTER_KEY_DERIVE_PARAMS structure
+ * CK_TLS12_MASTER_KEY_DERIVE_PARAMS pointer
  *
  * @param env - used to call JNI functions to get the Java classes and objects
  * @param jParam - the Java CK_TLS12_MASTER_KEY_DERIVE_PARAMS object to convert
- * @param ckParamPtr - pointer to the new CK_TLS12_MASTER_KEY_DERIVE_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_TLS12_MASTER_KEY_DERIVE_PARAMS structure
  */
-void jTls12MasterKeyDeriveParamToCKTls12MasterKeyDeriveParam(JNIEnv *env,
-        jobject jParam, CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR ckParamPtr)
+CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR
+jTls12MasterKeyDeriveParamToCKTls12MasterKeyDeriveParamPtr(JNIEnv *env,
+        jobject jParam, CK_ULONG *pLength)
 {
+    CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR ckParamPtr;
     jclass jTls12MasterKeyDeriveParamsClass;
     jfieldID fieldID;
-    memset(ckParamPtr, 0, sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS));
+    jlong prfHashMechanism;
+
+    if (pLength != NULL) {
+        *pLength = 0L;
+    }
+
+    // retrieve java values
     jTls12MasterKeyDeriveParamsClass =
-            (*env)->FindClass(env, CLASS_TLS12_MASTER_KEY_DERIVE_PARAMS);
-    if (jTls12MasterKeyDeriveParamsClass == NULL) { return; }
+        (*env)->FindClass(env, CLASS_TLS12_MASTER_KEY_DERIVE_PARAMS);
+    if (jTls12MasterKeyDeriveParamsClass == NULL) { return NULL; }
+    fieldID = (*env)->GetFieldID(env,
+            jTls12MasterKeyDeriveParamsClass, "prfHashMechanism", "J");
+    if (fieldID == NULL) { return NULL; }
+    prfHashMechanism = (*env)->GetLongField(env, jParam, fieldID);
+
+    // allocate memory for CK_TLS12_MASTER_KEY_DERIVE_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     masterKeyDeriveParamToCKMasterKeyDeriveParam(env, jParam,
             jTls12MasterKeyDeriveParamsClass, &ckParamPtr->pVersion,
             &ckParamPtr->RandomInfo);
-    fieldID = (*env)->GetFieldID(env,
-            jTls12MasterKeyDeriveParamsClass, "prfHashMechanism", "J");
-    if (fieldID != NULL) {
-        jlong prfHashMechanism =
-                (*env)->GetLongField(env, jParam, fieldID);
-        ckParamPtr->prfHashMechanism = (CK_MECHANISM_TYPE)prfHashMechanism;
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
     }
+
+    ckParamPtr->prfHashMechanism = (CK_MECHANISM_TYPE) prfHashMechanism;
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr);
+    return NULL;
 }
 
 /*
- * converts the Java CK_TLS_PRF_PARAMS object to a CK_TLS_PRF_PARAMS structure
+ * converts the Java CK_TLS_PRF_PARAMS object to a CK_TLS_PRF_PARAMS pointer
+ *
+ * @param env - used to call JNI functions to get the Java classes and objects
+ * @param jParam - the Java CK_TLS_PRF_PARAMS object to convert
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_TLS_PRF_PARAMS structure
  */
-void jTlsPrfParamsToCKTlsPrfParam(JNIEnv *env, jobject jParam,
-CK_TLS_PRF_PARAMS_PTR ckParamPtr)
+CK_TLS_PRF_PARAMS_PTR
+jTlsPrfParamsToCKTlsPrfParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
+    CK_TLS_PRF_PARAMS_PTR ckParamPtr;
     jclass jTlsPrfParamsClass;
     jfieldID fieldID;
     jobject jSeed, jLabel, jOutput;
-    memset(ckParamPtr, 0, sizeof(CK_TLS_PRF_PARAMS));
 
-    // TBD: what if jParam == NULL?!
+    if (pLength != NULL) {
+        *pLength = 0;
+    }
 
-    /* get pSeed */
+    // retrieve java values
     jTlsPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS);
-    if (jTlsPrfParamsClass == NULL) { return; }
+    if (jTlsPrfParamsClass == NULL) { return NULL; }
     fieldID = (*env)->GetFieldID(env, jTlsPrfParamsClass, "pSeed", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jSeed = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pLabel */
     fieldID = (*env)->GetFieldID(env, jTlsPrfParamsClass, "pLabel", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jLabel = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pOutput */
     fieldID = (*env)->GetFieldID(env, jTlsPrfParamsClass, "pOutput", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jOutput = (*env)->GetObjectField(env, jParam, fieldID);
 
-    /* populate java values */
+    // allocate memory for CK_TLS_PRF_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_TLS_PRF_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     jByteArrayToCKByteArray(env, jSeed, &(ckParamPtr->pSeed), &(ckParamPtr->ulSeedLen));
-    if ((*env)->ExceptionCheck(env)) { return; }
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
+    }
     jByteArrayToCKByteArray(env, jLabel, &(ckParamPtr->pLabel), &(ckParamPtr->ulLabelLen));
     if ((*env)->ExceptionCheck(env)) {
-        free(ckParamPtr->pSeed);
-        return;
+        goto cleanup;
     }
-    ckParamPtr->pulOutputLen = malloc(sizeof(CK_ULONG));
+    ckParamPtr->pulOutputLen = calloc(1, sizeof(CK_ULONG));
     if (ckParamPtr->pulOutputLen == NULL) {
-        free(ckParamPtr->pSeed);
-        free(ckParamPtr->pLabel);
-        throwOutOfMemoryError(env, 0);
-        return;
+        goto cleanup;
     }
     jByteArrayToCKByteArray(env, jOutput, &(ckParamPtr->pOutput), ckParamPtr->pulOutputLen);
     if ((*env)->ExceptionCheck(env)) {
-        free(ckParamPtr->pSeed);
-        free(ckParamPtr->pLabel);
-        free(ckParamPtr->pOutput);
-        return;
+        goto cleanup;
     }
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_TLS_PRF_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr->pSeed);
+    free(ckParamPtr->pLabel);
+    free(ckParamPtr->pOutput);
+    free(ckParamPtr->pulOutputLen);
+    free(ckParamPtr);
+    return NULL;
 }
 
 /*
- * converts the Java CK_TLS_MAC_PARAMS object to a CK_TLS_MAC_PARAMS structure
+ * converts the Java CK_TLS_MAC_PARAMS object to a CK_TLS_MAC_PARAMS pointer
+ *
+ * @param env - used to call JNI functions to get the Java classes and objects
+ * @param jParam - the Java CK_TLS_MAC_PARAMS object to convert
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_TLS_MAC_PARAMS structure
  */
-void jTlsMacParamsToCKTlsMacParam(JNIEnv *env, jobject jParam,
-        CK_TLS_MAC_PARAMS_PTR ckParamPtr)
+
+CK_TLS_MAC_PARAMS_PTR
+jTlsMacParamsToCKTlsMacParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
+    CK_TLS_MAC_PARAMS_PTR ckParamPtr;
     jclass jTlsMacParamsClass;
     jfieldID fieldID;
     jlong jPrfMechanism, jUlMacLength, jUlServerOrClient;
-    memset(ckParamPtr, 0, sizeof(CK_TLS_MAC_PARAMS));
 
+    if (pLength != NULL) {
+        *pLength = 0L;
+    }
+
+    // retrieve java values
     jTlsMacParamsClass = (*env)->FindClass(env, CLASS_TLS_MAC_PARAMS);
-    if (jTlsMacParamsClass == NULL) { return; }
-
-    /* get prfMechanism */
+    if (jTlsMacParamsClass == NULL) { return NULL; }
     fieldID = (*env)->GetFieldID(env, jTlsMacParamsClass, "prfMechanism", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPrfMechanism = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get ulMacLength */
     fieldID = (*env)->GetFieldID(env, jTlsMacParamsClass, "ulMacLength", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jUlMacLength = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get ulServerOrClient */
     fieldID = (*env)->GetFieldID(env, jTlsMacParamsClass, "ulServerOrClient", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jUlServerOrClient = (*env)->GetLongField(env, jParam, fieldID);
 
-    /* populate java values */
+    // allocate memory for CK_TLS_MAC_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_TLS_MAC_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     ckParamPtr->prfMechanism = jLongToCKULong(jPrfMechanism);
     ckParamPtr->ulMacLength = jLongToCKULong(jUlMacLength);
     ckParamPtr->ulServerOrClient = jLongToCKULong(jUlServerOrClient);
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_TLS_MAC_PARAMS);
+    }
+    return ckParamPtr;
 }
 
 void keyMatParamToCKKeyMatParam(JNIEnv *env, jobject jParam,
@@ -666,63 +748,47 @@
     jobject jReturnedKeyMaterial, jRMIvClient, jRMIvServer;
     CK_ULONG ckTemp;
 
-    /* get ulMacSizeInBits */
+    // the pointer arguments should already be initialized by caller
+
+    // retrieve java values
     fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "ulMacSizeInBits", "J");
     if (fieldID == NULL) { return; }
     jMacSizeInBits = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get ulKeySizeInBits */
     fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "ulKeySizeInBits", "J");
     if (fieldID == NULL) { return; }
     jKeySizeInBits = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get ulIVSizeInBits */
     fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "ulIVSizeInBits", "J");
     if (fieldID == NULL) { return; }
     jIVSizeInBits = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get bIsExport */
     fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "bIsExport", "Z");
     if (fieldID == NULL) { return; }
     jIsExport = (*env)->GetBooleanField(env, jParam, fieldID);
-
-    /* get RandomInfo */
     jSsl3RandomDataClass = (*env)->FindClass(env, CLASS_SSL3_RANDOM_DATA);
     if (jSsl3RandomDataClass == NULL) { return; }
     fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "RandomInfo",
             "Lsun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA;");
     if (fieldID == NULL) { return; }
     jRandomInfo = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pClientRandom and ulClientRandomLength out of RandomInfo */
     fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pClientRandom", "[B");
     if (fieldID == NULL) { return; }
     jRIClientRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
-
-    /* get pServerRandom and ulServerRandomLength out of RandomInfo */
     fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pServerRandom", "[B");
     if (fieldID == NULL) { return; }
     jRIServerRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
-
-    /* get pReturnedKeyMaterial */
     jSsl3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT);
     if (jSsl3KeyMatOutClass == NULL) { return; }
     fieldID = (*env)->GetFieldID(env, jKeyMatParamClass, "pReturnedKeyMaterial",
             "Lsun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT;");
     if (fieldID == NULL) { return; }
     jReturnedKeyMaterial = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pIVClient out of pReturnedKeyMaterial */
     fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "pIVClient", "[B");
     if (fieldID == NULL) { return; }
     jRMIvClient = (*env)->GetObjectField(env, jReturnedKeyMaterial, fieldID);
-
-    /* get pIVServer out of pReturnedKeyMaterial */
     fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "pIVServer", "[B");
     if (fieldID == NULL) { return; }
     jRMIvServer = (*env)->GetObjectField(env, jReturnedKeyMaterial, fieldID);
 
-    /* populate java values */
+    // populate the specified pointers using java values
     *cKKeyMatParamUlMacSizeInBits = jLongToCKULong(jMacSizeInBits);
     *cKKeyMatParamUlKeySizeInBits = jLongToCKULong(jKeySizeInBits);
     *cKKeyMatParamUlIVSizeInBits = jLongToCKULong(jIVSizeInBits);
@@ -730,22 +796,22 @@
     jByteArrayToCKByteArray(env, jRIClientRandom,
             &(cKKeyMatParamRandomInfo->pClientRandom),
             &(cKKeyMatParamRandomInfo->ulClientRandomLen));
-    if ((*env)->ExceptionCheck(env)) { return; }
+    if ((*env)->ExceptionCheck(env)) {
+        // just return as no memory allocation yet
+        return;
+    }
     jByteArrayToCKByteArray(env, jRIServerRandom,
             &(cKKeyMatParamRandomInfo->pServerRandom),
             &(cKKeyMatParamRandomInfo->ulServerRandomLen));
     if ((*env)->ExceptionCheck(env)) {
-        free(cKKeyMatParamRandomInfo->pClientRandom);
-        return;
+        goto cleanup;
     }
     /* allocate memory for pReturnedKeyMaterial */
     *cKKeyMatParamPReturnedKeyMaterial =
-            (CK_SSL3_KEY_MAT_OUT_PTR)malloc(sizeof(CK_SSL3_KEY_MAT_OUT));
+            (CK_SSL3_KEY_MAT_OUT_PTR) calloc(1, sizeof(CK_SSL3_KEY_MAT_OUT));
     if (*cKKeyMatParamPReturnedKeyMaterial == NULL) {
-        free(cKKeyMatParamRandomInfo->pClientRandom);
-        free(cKKeyMatParamRandomInfo->pServerRandom);
         throwOutOfMemoryError(env, 0);
-        return;
+        goto cleanup;
     }
 
     // the handles are output params only, no need to fetch them from Java
@@ -757,219 +823,349 @@
     jByteArrayToCKByteArray(env, jRMIvClient,
             &((*cKKeyMatParamPReturnedKeyMaterial)->pIVClient), &ckTemp);
     if ((*env)->ExceptionCheck(env)) {
-        free(cKKeyMatParamRandomInfo->pClientRandom);
-        free(cKKeyMatParamRandomInfo->pServerRandom);
-        free((*cKKeyMatParamPReturnedKeyMaterial));
-        return;
+        goto cleanup;
     }
     jByteArrayToCKByteArray(env, jRMIvServer,
             &((*cKKeyMatParamPReturnedKeyMaterial)->pIVServer), &ckTemp);
     if ((*env)->ExceptionCheck(env)) {
-        free(cKKeyMatParamRandomInfo->pClientRandom);
-        free(cKKeyMatParamRandomInfo->pServerRandom);
-        free((*cKKeyMatParamPReturnedKeyMaterial)->pIVClient);
-        free((*cKKeyMatParamPReturnedKeyMaterial));
-        return;
+        goto cleanup;
     }
 
     return;
+cleanup:
+    free(cKKeyMatParamRandomInfo->pClientRandom);
+    free(cKKeyMatParamRandomInfo->pServerRandom);
+    if ((*cKKeyMatParamPReturnedKeyMaterial) != NULL) {
+        free((*cKKeyMatParamPReturnedKeyMaterial)->pIVClient);
+        free(*cKKeyMatParamPReturnedKeyMaterial);
+    }
+    // explicitly set to NULL to ensure no double free possible
+    cKKeyMatParamRandomInfo->pClientRandom = NULL;
+    cKKeyMatParamRandomInfo->pServerRandom = NULL;
+    *cKKeyMatParamPReturnedKeyMaterial = NULL;
+    return;
 }
 /*
  * converts the Java CK_SSL3_KEY_MAT_PARAMS object to a
- * CK_SSL3_KEY_MAT_PARAMS structure
+ * CK_SSL3_KEY_MAT_PARAMS pointer
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_SSL3_KEY_MAT_PARAMS object to convert
- * @param ckParamPtr - pointer to the new CK_SSL3_KEY_MAT_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_SSL3_KEY_MAT_PARAMS structure
  */
-void jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject jParam,
-        CK_SSL3_KEY_MAT_PARAMS_PTR ckParamPtr)
+CK_SSL3_KEY_MAT_PARAMS_PTR
+jSsl3KeyMatParamToCKSsl3KeyMatParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
+    CK_SSL3_KEY_MAT_PARAMS_PTR ckParamPtr;
     jclass jSsl3KeyMatParamsClass;
-    memset(ckParamPtr, 0, sizeof(CK_SSL3_KEY_MAT_PARAMS));
+
+    if (pLength != NULL) {
+        *pLength = 0;
+    }
+
+    // allocate memory for CK_SSL3_KEY_MAT_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_SSL3_KEY_MAT_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // retrieve and  populate using java values
     jSsl3KeyMatParamsClass = (*env)->FindClass(env,
             CLASS_SSL3_KEY_MAT_PARAMS);
-    if (jSsl3KeyMatParamsClass == NULL) { return; }
+    if (jSsl3KeyMatParamsClass == NULL) {
+        goto cleanup;
+    }
     keyMatParamToCKKeyMatParam(env, jParam, jSsl3KeyMatParamsClass,
             &(ckParamPtr->ulMacSizeInBits), &(ckParamPtr->ulKeySizeInBits),
             &(ckParamPtr->ulIVSizeInBits), &(ckParamPtr->bIsExport),
             &(ckParamPtr->RandomInfo), &(ckParamPtr->pReturnedKeyMaterial));
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
+    }
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_SSL3_KEY_MAT_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr);
+    return NULL;
 }
 
 /*
  * converts the Java CK_TLS12_KEY_MAT_PARAMS object to a
- * CK_TLS12_KEY_MAT_PARAMS structure
+ * CK_TLS12_KEY_MAT_PARAMS pointer
  *
  * @param env - used to call JNI functions to get the Java classes and objects
  * @param jParam - the Java CK_TLS12_KEY_MAT_PARAMS object to convert
- * @param ckParamPtr - pointer to the new CK_TLS12_KEY_MAT_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_TLS12_KEY_MAT_PARAMS structure
  */
-void jTls12KeyMatParamToCKTls12KeyMatParam(JNIEnv *env,
-        jobject jParam, CK_TLS12_KEY_MAT_PARAMS_PTR ckParamPtr)
+CK_TLS12_KEY_MAT_PARAMS_PTR jTls12KeyMatParamToCKTls12KeyMatParamPtr(JNIEnv *env,
+        jobject jParam, CK_ULONG *pLength)
 {
+    CK_TLS12_KEY_MAT_PARAMS_PTR ckParamPtr;
     jclass jTls12KeyMatParamsClass;
     jfieldID fieldID;
-    memset(ckParamPtr, 0, sizeof(CK_TLS12_KEY_MAT_PARAMS));
+    jlong prfHashMechanism;
+
+    if (pLength != NULL) {
+        *pLength = 0;
+    }
+
+    // retrieve java values
     jTls12KeyMatParamsClass = (*env)->FindClass(env,
             CLASS_TLS12_KEY_MAT_PARAMS);
-    if (jTls12KeyMatParamsClass == NULL) { return; }
+    if (jTls12KeyMatParamsClass == NULL) { return NULL; }
+    fieldID = (*env)->GetFieldID(env, jTls12KeyMatParamsClass,
+            "prfHashMechanism", "J");
+    if (fieldID == NULL) { return NULL; }
+    prfHashMechanism = (*env)->GetLongField(env, jParam, fieldID);
+
+    // allocate memory for CK_TLS12_KEY_MAT_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_TLS12_KEY_MAT_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     keyMatParamToCKKeyMatParam(env, jParam, jTls12KeyMatParamsClass,
             &(ckParamPtr->ulMacSizeInBits), &(ckParamPtr->ulKeySizeInBits),
             &(ckParamPtr->ulIVSizeInBits), &(ckParamPtr->bIsExport),
             &(ckParamPtr->RandomInfo), &(ckParamPtr->pReturnedKeyMaterial));
-    fieldID = (*env)->GetFieldID(env, jTls12KeyMatParamsClass,
-            "prfHashMechanism", "J");
-    if (fieldID != NULL) {
-        jlong prfHashMechanism = (*env)->GetLongField(env, jParam, fieldID);
-        ckParamPtr->prfHashMechanism = (CK_MECHANISM_TYPE)prfHashMechanism;
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
     }
+    ckParamPtr->prfHashMechanism = (CK_MECHANISM_TYPE)prfHashMechanism;
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_TLS12_KEY_MAT_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr);
+    return NULL;
 }
 
 /*
- * converts the Java CK_AES_CTR_PARAMS object to a CK_AES_CTR_PARAMS structure
+ * converts the Java CK_AES_CTR_PARAMS object to a CK_AES_CTR_PARAMS pointer
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_AES_CTR_PARAMS object to convert
- * @param ckParamPtr - pointer to the new CK_AES_CTR_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_AES_CTR_PARAMS structure
  */
-void jAesCtrParamsToCKAesCtrParam(JNIEnv *env, jobject jParam,
-                                  CK_AES_CTR_PARAMS_PTR ckParamPtr) {
+CK_AES_CTR_PARAMS_PTR
+jAesCtrParamsToCKAesCtrParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
+{
+    CK_AES_CTR_PARAMS_PTR ckParamPtr;
     jclass jAesCtrParamsClass;
     jfieldID fieldID;
     jlong jCounterBits;
     jobject jCb;
-    CK_BYTE_PTR ckBytes;
+    CK_BYTE_PTR ckBytes = NULL;
     CK_ULONG ckTemp;
 
-    /* get ulCounterBits */
+    if (pLength != NULL) {
+        *pLength = 0L;
+    }
+
+    // retrieve java values
     jAesCtrParamsClass = (*env)->FindClass(env, CLASS_AES_CTR_PARAMS);
-    if (jAesCtrParamsClass == NULL) { return; }
+    if (jAesCtrParamsClass == NULL) { return NULL; }
     if (!(*env)->IsInstanceOf(env, jParam, jAesCtrParamsClass)) {
-        return;
+        return NULL;
     }
     fieldID = (*env)->GetFieldID(env, jAesCtrParamsClass, "ulCounterBits", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jCounterBits = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get cb */
     fieldID = (*env)->GetFieldID(env, jAesCtrParamsClass, "cb", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jCb = (*env)->GetObjectField(env, jParam, fieldID);
 
-    /* populate java values */
+    // allocate memory for CK_AES_CTR_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_AES_CTR_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
+    jByteArrayToCKByteArray(env, jCb, &ckBytes, &ckTemp);
+    if ((*env)->ExceptionCheck(env) || ckTemp != 16) {
+        goto cleanup;
+    }
+    memcpy(ckParamPtr->cb, ckBytes, ckTemp);
+    free(ckBytes);
+
     ckParamPtr->ulCounterBits = jLongToCKULong(jCounterBits);
-    jByteArrayToCKByteArray(env, jCb, &ckBytes, &ckTemp);
-    if ((*env)->ExceptionCheck(env)) { return; }
-    if (ckTemp != 16) {
-        TRACE1("\nERROR: WRONG CTR IV LENGTH %lu", ckTemp);
-    } else {
-        memcpy(ckParamPtr->cb, ckBytes, ckTemp);
-        free(ckBytes);
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_AES_CTR_PARAMS);
     }
+    return ckParamPtr;
+cleanup:
+    free(ckBytes);
+    free(ckParamPtr);
+    return NULL;
 }
 
 /*
- * converts the Java CK_GCM_PARAMS object to a CK_GCM_PARAMS structure
+ * converts the Java CK_GCM_PARAMS object to a CK_GCM_PARAMS pointer
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_GCM_PARAMS object to convert
- * @param ckpParam - pointer to the new CK_GCM_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_GCM_PARAMS structure
  */
-void jGCMParamsToCKGCMParam(JNIEnv *env, jobject jParam,
-                            CK_GCM_PARAMS_PTR ckpParam) {
+CK_GCM_PARAMS_PTR
+jGCMParamsToCKGCMParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
+{
+    CK_GCM_PARAMS_PTR ckParamPtr;
     jclass jGcmParamsClass;
     jfieldID fieldID;
     jobject jIv, jAad;
     jlong jTagLen;
 
-    /* get iv */
-    jGcmParamsClass = (*env)->FindClass(env, CLASS_GCM_PARAMS);
-    if (jGcmParamsClass == NULL) { return; }
-    if (!(*env)->IsInstanceOf(env, jParam, jGcmParamsClass)) {
-        return;
+    TRACE0("DEBUG jGCMParamsToCKGCMParam is called\n");
+
+    if (pLength != NULL) {
+        *pLength = 0L;
     }
 
+    // retrieve java values
+    jGcmParamsClass = (*env)->FindClass(env, CLASS_GCM_PARAMS);
+    if (jGcmParamsClass == NULL) { return NULL; }
+    if (!(*env)->IsInstanceOf(env, jParam, jGcmParamsClass)) {
+        return NULL;
+    }
     fieldID = (*env)->GetFieldID(env, jGcmParamsClass, "iv", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jIv = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get aad */
     fieldID = (*env)->GetFieldID(env, jGcmParamsClass, "aad", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jAad = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get tagLength */
     fieldID = (*env)->GetFieldID(env, jGcmParamsClass, "tagBits", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jTagLen = (*env)->GetLongField(env, jParam, fieldID);
 
+    // allocate memory for CK_GCM_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_GCM_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
 
-    /* populate java values */
-    jByteArrayToCKByteArray(env, jIv, &(ckpParam->pIv), &(ckpParam->ulIvLen));
-    if ((*env)->ExceptionCheck(env)) { return; }
+    // populate using java values
+    jByteArrayToCKByteArray(env, jIv, &(ckParamPtr->pIv), &(ckParamPtr->ulIvLen));
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
+    }
 
-    jByteArrayToCKByteArray(env, jAad, &(ckpParam->pAAD), &(ckpParam->ulAADLen));
-    if ((*env)->ExceptionCheck(env)) { return; }
+    jByteArrayToCKByteArray(env, jAad, &(ckParamPtr->pAAD), &(ckParamPtr->ulAADLen));
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
+    }
 
-    ckpParam->ulTagBits = jLongToCKULong(jTagLen);
+    ckParamPtr->ulTagBits = jLongToCKULong(jTagLen);
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_GCM_PARAMS);
+    }
+    TRACE1("Created inner GCM_PARAMS PTR %lX\n", ptr_to_jlong(ckParamPtr));
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr->pIv);
+    free(ckParamPtr->pAAD);
+    free(ckParamPtr);
+    return NULL;
+
 }
 
 /*
- * converts the Java CK_CCM_PARAMS object to a CK_CCM_PARAMS structure
+ * converts the Java CK_CCM_PARAMS object to a CK_CCM_PARAMS pointer
  *
  * @param env - used to call JNI functions to get the Java classes and objects
  * @param jParam - the Java CK_CCM_PARAMS object to convert
- * @param ckpParam - pointer to the new CK_CCM_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_CCM_PARAMS structure
  */
-void jCCMParamsToCKCCMParam(JNIEnv *env, jobject jParam,
-                            CK_CCM_PARAMS_PTR ckpParam) {
+CK_CCM_PARAMS_PTR
+jCCMParamsToCKCCMParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
+{
+    CK_CCM_PARAMS_PTR ckParamPtr;
     jclass jCcmParamsClass;
     jfieldID fieldID;
     jobject jNonce, jAad;
     jlong jDataLen, jMacLen;
 
-    /* get iv */
+    if (pLength != NULL) {
+        *pLength = 0;
+    }
+
+    // retrieve java values
     jCcmParamsClass = (*env)->FindClass(env, CLASS_CCM_PARAMS);
-    if (jCcmParamsClass == NULL) { return; }
-
+    if (jCcmParamsClass == NULL) { return NULL; }
     if (!(*env)->IsInstanceOf(env, jParam, jCcmParamsClass)) {
-        return;
+        return NULL;
     }
     fieldID = (*env)->GetFieldID(env, jCcmParamsClass, "dataLen", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jDataLen = (*env)->GetLongField(env, jParam, fieldID);
-
     fieldID = (*env)->GetFieldID(env, jCcmParamsClass, "nonce", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jNonce = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get aad */
     fieldID = (*env)->GetFieldID(env, jCcmParamsClass, "aad", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jAad = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get macLen */
     fieldID = (*env)->GetFieldID(env, jCcmParamsClass, "macLen", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jMacLen = (*env)->GetLongField(env, jParam, fieldID);
 
-    /* populate java values */
-    ckpParam->ulDataLen = jLongToCKULong(jDataLen);
-    jByteArrayToCKByteArray(env, jNonce, &(ckpParam->pNonce),
-            &(ckpParam->ulNonceLen));
-    jByteArrayToCKByteArray(env, jAad, &(ckpParam->pAAD),
-            &(ckpParam->ulAADLen));
-    ckpParam->ulMACLen = jLongToCKULong(jMacLen);
-    if ((*env)->ExceptionCheck(env)) { return; }
+    // allocate memory for CK_CCM_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_CCM_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
+    ckParamPtr->ulDataLen = jLongToCKULong(jDataLen);
+    jByteArrayToCKByteArray(env, jNonce, &(ckParamPtr->pNonce),
+            &(ckParamPtr->ulNonceLen));
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
+    }
+
+    jByteArrayToCKByteArray(env, jAad, &(ckParamPtr->pAAD),
+            &(ckParamPtr->ulAADLen));
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
+    }
+
+    ckParamPtr->ulMACLen = jLongToCKULong(jMacLen);
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_CCM_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr->pNonce);
+    free(ckParamPtr->pAAD);
+    free(ckParamPtr);
+    return NULL;
 }
 
 /*
- * converts a Java CK_MECHANISM object into a pointer to a CK_MECHANISM
- * structure. NOTE: CALLER IS RESPONSIBLE FOR FREEING THE RETURNED POINTER
+ * converts a Java CK_MECHANISM object into a CK_MECHANISM pointer
+ * pointer.
  *
  * @param env - used to call JNI funktions to get the values out of the Java object
- * @param jMechanism - the Java CK_MECHANISM object to convert
- * @return - pointer to the new CK_MECHANISM structure
+ * @param jMech - the Java CK_MECHANISM object to convert
+ * @return pointer to the new CK_MECHANISM structure
  */
 CK_MECHANISM_PTR jMechanismToCKMechanismPtr(JNIEnv *env, jobject jMech)
 {
@@ -978,7 +1174,7 @@
     jobject jParam = (*env)->GetObjectField(env, jMech, mech_pParameterID);
 
     /* allocate memory for CK_MECHANISM_PTR */
-    ckpMech =  (CK_MECHANISM_PTR) malloc(sizeof(CK_MECHANISM));
+    ckpMech =  (CK_MECHANISM_PTR) calloc(1, sizeof(CK_MECHANISM));
     if (ckpMech == NULL) {
         throwOutOfMemoryError(env, 0);
         return NULL;
@@ -1001,48 +1197,15 @@
 }
 
 /*
- * the following functions convert Attribute and Mechanism value pointers
- *
- * jobject ckAttributeValueToJObject(JNIEnv *env,
- *                                   const CK_ATTRIBUTE_PTR ckpAttribute);
- *
- * CK_VOID_PTR jObjectToPrimitiveCKObjectPtr(JNIEnv *env,
- *                                       jobject jObject,
- *                                       CK_ULONG *pLength);
- *
- * CK_VOID_PTR jMechParamToCKMechParamPtr(JNIEnv *env,
- *                              jobject jParam,
- *                              CK_MECHANISM_TYPE ckMech,
- *                              CK_ULONG *ckpLength);
- *
- * These functions are used if a PKCS#11 mechanism or attribute structure gets
- * convertet to a Java attribute or mechanism object or vice versa.
- *
- * ckAttributeValueToJObject converts a PKCS#11 attribute value pointer to a Java
- * object depending on the type of the Attribute. A PKCS#11 attribute value can
+ * converts the pValue of a CK_ATTRIBUTE structure into a Java Object by
+ * checking the type of the attribute. A PKCS#11 attribute value can
  * be a CK_ULONG, CK_BYTE[], CK_CHAR[], big integer, CK_BBOOL, CK_UTF8CHAR[],
  * CK_DATE or CK_FLAGS that gets converted to a corresponding Java object.
  *
- * jObjectToPrimitiveCKObjectPtr is used by jAttributeToCKAttributePtr for
- * converting the Java attribute value to a PKCS#11 attribute value pointer.
- * For now only primitive datatypes and arrays of primitive datatypes can get
- * converted. Otherwise this function throws a PKCS#11Exception with the
- * errorcode CKR_VENDOR_DEFINED.
- *
- * jMechParamToCKMechParamPtr converts a Java mechanism parameter to a PKCS#11
- * mechanism parameter. Based on the specified PKCS#11 mechanism type, this
- * function will allocate memory for a PKCS#11 parameter structure and
- * populate its field using the Java object.
- */
-
-/*
- * converts the pValue of a CK_ATTRIBUTE structure into a Java Object by
- * checking the type of the attribute.
- *
- * @param env - used to call JNI funktions to create the new Java object
+ * @param env - used to call JNI functions to create the new Java object
  * @param ckpAttribute - the pointer to the CK_ATTRIBUTE structure that contains the type
  *                       and the pValue to convert
- * @return - the new Java object of the CK-type pValue
+ * @return the new Java object of the CK-type pValue
  */
 jobject ckAttributeValueToJObject(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute)
 {
@@ -1185,9 +1348,8 @@
  */
 
 /*
- * converts the given Java mechanism parameter to a CK mechanism parameter structure
- * and store the length in bytes in the length variable.
- * The memory of *ckpParamPtr has to be freed after use!
+ * converts the given Java mechanism parameter to a CK mechanism parameter
+ * pointer and store the length in bytes in the length variable.
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java mechanism parameter object to convert
@@ -1223,156 +1385,68 @@
      * Most common cases, i.e. NULL/byte[]/long, are already handled by
      * jMechParamToCKMechParam before calling this method.
      */
-    TRACE1("\nDEBUG: jMechParamToCKMechParamPtrSlow, mech=0x%lX", ckMech);
+    TRACE1("\nDEBUG: jMechParamToCKMechParamPtrSlow, mech=0x%lX\n", ckMech);
 
     switch (ckMech) {
         case CKM_SSL3_PRE_MASTER_KEY_GEN:
         case CKM_TLS_PRE_MASTER_KEY_GEN:
-            *ckpLength = sizeof(CK_VERSION);
             ckpParamPtr = jVersionToCKVersionPtr(env, jParam);
+            if (ckpParamPtr != NULL) {
+                *ckpLength = sizeof(CK_VERSION);
+            } else {
+                *ckpLength = 0;
+            }
             break;
         case CKM_SSL3_MASTER_KEY_DERIVE:
         case CKM_TLS_MASTER_KEY_DERIVE:
         case CKM_SSL3_MASTER_KEY_DERIVE_DH:
         case CKM_TLS_MASTER_KEY_DERIVE_DH:
-            ckpParamPtr =
-                    malloc(sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
-
-            jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(env, jParam,
-                    (CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParamPtr(env, jParam,
+                    ckpLength);
             break;
         case CKM_SSL3_KEY_AND_MAC_DERIVE:
         case CKM_TLS_KEY_AND_MAC_DERIVE:
-            ckpParamPtr =
-                    malloc(sizeof(CK_SSL3_KEY_MAT_PARAMS));
-            if (ckpParamPtr == NULL) {
-                 throwOutOfMemoryError(env, 0);
-                 return NULL;
-            }
-            *ckpLength = sizeof(CK_SSL3_KEY_MAT_PARAMS);
-
-            jSsl3KeyMatParamToCKSsl3KeyMatParam(env, jParam,
-                    (CK_SSL3_KEY_MAT_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jSsl3KeyMatParamToCKSsl3KeyMatParamPtr(env, jParam,
+                    ckpLength);
             break;
         case CKM_TLS12_KEY_AND_MAC_DERIVE:
-            ckpParamPtr =
-                    malloc(sizeof(CK_TLS12_KEY_MAT_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_TLS12_KEY_MAT_PARAMS);
-
-            jTls12KeyMatParamToCKTls12KeyMatParam(env, jParam,
-                    (CK_TLS12_KEY_MAT_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jTls12KeyMatParamToCKTls12KeyMatParamPtr(env, jParam,
+                    ckpLength);
             break;
         case CKM_TLS12_MASTER_KEY_DERIVE:
         case CKM_TLS12_MASTER_KEY_DERIVE_DH:
-            ckpParamPtr =
-                    malloc(sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS);
-
-            jTls12MasterKeyDeriveParamToCKTls12MasterKeyDeriveParam(env, jParam,
-                    (CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jTls12MasterKeyDeriveParamToCKTls12MasterKeyDeriveParamPtr(env, jParam,
+                    ckpLength);
             break;
         case CKM_TLS_PRF:
         case CKM_NSS_TLS_PRF_GENERAL:
-            ckpParamPtr = malloc(sizeof(CK_TLS_PRF_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_TLS_PRF_PARAMS);
-
-            jTlsPrfParamsToCKTlsPrfParam(env, jParam,
-                    (CK_TLS_PRF_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jTlsPrfParamsToCKTlsPrfParamPtr(env, jParam,
+                    ckpLength);
             break;
         case CKM_TLS_MAC:
-            ckpParamPtr = malloc(sizeof(CK_TLS_MAC_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_TLS_MAC_PARAMS);
-
-            jTlsMacParamsToCKTlsMacParam(env, jParam,
-                    (CK_TLS_MAC_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jTlsMacParamsToCKTlsMacParamPtr(env, jParam,
+                    ckpLength);
             break;
         case CKM_AES_CTR:
-            ckpParamPtr = malloc(sizeof(CK_AES_CTR_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_AES_CTR_PARAMS);
-
-            jAesCtrParamsToCKAesCtrParam(env, jParam,
-                    (CK_AES_CTR_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jAesCtrParamsToCKAesCtrParamPtr(env, jParam,
+                    ckpLength);
             break;
         case CKM_AES_GCM:
-            ckpParamPtr = malloc(sizeof(CK_GCM_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_GCM_PARAMS);
-
-            jGCMParamsToCKGCMParam(env, jParam, (CK_GCM_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jGCMParamsToCKGCMParamPtr(env, jParam, ckpLength);
             break;
         case CKM_AES_CCM:
-            ckpParamPtr = malloc(sizeof(CK_CCM_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_CCM_PARAMS);
-
-            jCCMParamsToCKCCMParam(env, jParam,
-                    (CK_CCM_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jCCMParamsToCKCCMParamPtr(env, jParam, ckpLength);
             break;
         case CKM_RSA_PKCS_OAEP:
-            ckpParamPtr = malloc(sizeof(CK_RSA_PKCS_OAEP_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_RSA_PKCS_OAEP_PARAMS);
-
-            jRsaPkcsOaepParamToCKRsaPkcsOaepParam(env, jParam,
-                    (CK_RSA_PKCS_OAEP_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jRsaPkcsOaepParamToCKRsaPkcsOaepParamPtr(env, jParam, ckpLength);
             break;
         case CKM_PBE_SHA1_DES3_EDE_CBC:
         case CKM_PBE_SHA1_DES2_EDE_CBC:
         case CKM_PBA_SHA1_WITH_SHA1_HMAC:
-            ckpParamPtr = malloc(sizeof(CK_PBE_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-
-            *ckpLength = sizeof(CK_PBE_PARAMS);
-
-            jPbeParamToCKPbeParam(env, jParam, (CK_PBE_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jPbeParamToCKPbeParamPtr(env, jParam, ckpLength);
             break;
         case CKM_PKCS5_PBKD2:
-            ckpParamPtr = malloc(sizeof(CK_PKCS5_PBKD2_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_PKCS5_PBKD2_PARAMS);
-
-            jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(env, jParam,
-                     (CK_PKCS5_PBKD2_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(env, jParam, ckpLength);
             break;
         case CKM_RSA_PKCS_PSS:
         case CKM_SHA1_RSA_PKCS_PSS:
@@ -1380,62 +1454,21 @@
         case CKM_SHA384_RSA_PKCS_PSS:
         case CKM_SHA512_RSA_PKCS_PSS:
         case CKM_SHA224_RSA_PKCS_PSS:
-            ckpParamPtr = malloc(sizeof(CK_RSA_PKCS_PSS_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_RSA_PKCS_PSS_PARAMS);
-
-            jRsaPkcsPssParamToCKRsaPkcsPssParam(env, jParam,
-                    (CK_RSA_PKCS_PSS_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jRsaPkcsPssParamToCKRsaPkcsPssParamPtr(env, jParam, ckpLength);
             break;
         case CKM_ECDH1_DERIVE:
         case CKM_ECDH1_COFACTOR_DERIVE:
-            ckpParamPtr = malloc(sizeof(CK_ECDH1_DERIVE_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_ECDH1_DERIVE_PARAMS);
-
-            jEcdh1DeriveParamToCKEcdh1DeriveParam(env, jParam,
-                    (CK_ECDH1_DERIVE_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jEcdh1DeriveParamToCKEcdh1DeriveParamPtr(env, jParam, ckpLength);
             break;
         case CKM_ECMQV_DERIVE:
-            ckpParamPtr = malloc(sizeof(CK_ECDH2_DERIVE_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_ECDH2_DERIVE_PARAMS);
-
-            jEcdh2DeriveParamToCKEcdh2DeriveParam(env, jParam,
-                    (CK_ECDH2_DERIVE_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jEcdh2DeriveParamToCKEcdh2DeriveParamPtr(env, jParam, ckpLength);
             break;
         case CKM_X9_42_DH_DERIVE:
-            ckpParamPtr = malloc(sizeof(CK_X9_42_DH1_DERIVE_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_X9_42_DH1_DERIVE_PARAMS);
-
-            /* convert jParameter to CKParameter */
-            jX942Dh1DeriveParamToCKX942Dh1DeriveParam(env, jParam,
-                (CK_X9_42_DH1_DERIVE_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jX942Dh1DeriveParamToCKX942Dh1DeriveParamPtr(env, jParam, ckpLength);
             break;
         case CKM_X9_42_DH_HYBRID_DERIVE:
         case CKM_X9_42_MQV_DERIVE:
-            ckpParamPtr = malloc(sizeof(CK_X9_42_DH2_DERIVE_PARAMS));
-            if (ckpParamPtr == NULL) {
-                throwOutOfMemoryError(env, 0);
-                return NULL;
-            }
-            *ckpLength = sizeof(CK_X9_42_DH2_DERIVE_PARAMS);
-
-            jX942Dh2DeriveParamToCKX942Dh2DeriveParam(env, jParam,
-                    (CK_X9_42_DH2_DERIVE_PARAMS_PTR) ckpParamPtr);
+            ckpParamPtr = jX942Dh2DeriveParamToCKX942Dh2DeriveParamPtr(env, jParam, ckpLength);
             break;
         // defined by pkcs11.h but we don't support
         case CKM_KEA_DERIVE: // CK_KEA_DERIVE_PARAMS
@@ -1460,118 +1493,144 @@
     TRACE0("\nDEBUG: jMechParamToCKMechParamPtrSlow FINISHED\n");
 
     if ((*env)->ExceptionCheck(env)) {
-        free(ckpParamPtr);
-        *ckpLength = 0;
         return NULL;
     }
 
     return ckpParamPtr;
 }
 
-/* the mechanism parameter convertion functions: */
-
 /*
- * converts the Java CK_RSA_PKCS_OAEP_PARAMS object to a CK_RSA_PKCS_OAEP_PARAMS structure
+ * converts the Java CK_RSA_PKCS_OAEP_PARAMS object to a
+ * CK_RSA_PKCS_OAEP_PARAMS pointer
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_RSA_PKCS_OAEP_PARAMS object to convert
- * @return - the new CK_RSA_PKCS_OAEP_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_RSA_PKCS_OAEP_PARAMS structure
  */
-void jRsaPkcsOaepParamToCKRsaPkcsOaepParam(JNIEnv *env, jobject jParam,
-CK_RSA_PKCS_OAEP_PARAMS_PTR ckParamPtr)
+CK_RSA_PKCS_OAEP_PARAMS_PTR
+jRsaPkcsOaepParamToCKRsaPkcsOaepParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
+    CK_RSA_PKCS_OAEP_PARAMS_PTR ckParamPtr;
     jclass jRsaPkcsOaepParamsClass;
     jfieldID fieldID;
     jlong jHashAlg, jMgf, jSource;
     jobject jSourceData;
-    CK_BYTE_PTR ckpByte;
-    memset(ckParamPtr, 0, sizeof(CK_RSA_PKCS_OAEP_PARAMS));
 
-    /* get hashAlg */
+    if (pLength!= NULL) {
+        *pLength = 0L;
+    }
+
+    // retrieve java values
     jRsaPkcsOaepParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_OAEP_PARAMS);
-    if (jRsaPkcsOaepParamsClass == NULL) { return; }
+    if (jRsaPkcsOaepParamsClass == NULL) { return NULL; }
     fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "hashAlg", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jHashAlg = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get mgf */
     fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "mgf", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jMgf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get source */
     fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "source", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jSource = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get sourceData and sourceDataLength */
     fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "pSourceData", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jSourceData = (*env)->GetObjectField(env, jParam, fieldID);
 
-    /* populate java values */
+    // allocate memory for CK_RSA_PKCS_OAEP_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_RSA_PKCS_OAEP_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     ckParamPtr->hashAlg = jLongToCKULong(jHashAlg);
     ckParamPtr->mgf = jLongToCKULong(jMgf);
     ckParamPtr->source = jLongToCKULong(jSource);
-    jByteArrayToCKByteArray(env, jSourceData, & ckpByte, &(ckParamPtr->ulSourceDataLen));
-    if ((*env)->ExceptionCheck(env)) { return; }
-    ckParamPtr->pSourceData = (CK_VOID_PTR) ckpByte;
+    jByteArrayToCKByteArray(env, jSourceData, (CK_BYTE_PTR*) &(ckParamPtr->pSourceData),
+            &(ckParamPtr->ulSourceDataLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParamPtr);
+        return NULL;
+    }
+
+    if (pLength!= NULL) {
+        *pLength = sizeof(CK_RSA_PKCS_OAEP_PARAMS);
+    }
+    return ckParamPtr;
 }
 
 /*
- * converts the Java CK_PBE_PARAMS object to a CK_PBE_PARAMS structure
+ * converts the Java CK_PBE_PARAMS object to a CK_PBE_PARAMS pointer
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_PBE_PARAMS object to convert
- * @param ckParamPtr pointer to the new CK_PBE_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_PBE_PARAMS structure
  */
-void jPbeParamToCKPbeParam(JNIEnv *env, jobject jParam,
-CK_PBE_PARAMS_PTR ckParamPtr)
+CK_PBE_PARAMS_PTR
+jPbeParamToCKPbeParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
+    CK_PBE_PARAMS_PTR ckParamPtr;
     jclass jPbeParamsClass;
     jfieldID fieldID;
     jlong jIteration;
     jobject jInitVector, jPassword, jSalt;
     CK_ULONG ckTemp;
-    memset(ckParamPtr, 0, sizeof(CK_PBE_PARAMS));
 
-    /* get pInitVector */
+    if (pLength != NULL) {
+        *pLength = 0;
+    }
+
+    // retrieve java values
     jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS);
-    if (jPbeParamsClass == NULL) { return; }
+    if (jPbeParamsClass == NULL) { return NULL; }
     fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pInitVector", "[C");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jInitVector = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pPassword and ulPasswordLength */
     fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pPassword", "[C");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPassword = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pSalt and ulSaltLength */
     fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pSalt", "[C");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jSalt = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get ulIteration */
     fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "ulIteration", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jIteration = (*env)->GetLongField(env, jParam, fieldID);
 
-    /* populate java values */
+    // allocate memory for CK_PBE_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_PBE_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     ckParamPtr->ulIteration = jLongToCKULong(jIteration);
     jCharArrayToCKCharArray(env, jInitVector, &(ckParamPtr->pInitVector), &ckTemp);
-    if ((*env)->ExceptionCheck(env)) { return; }
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
+    }
     jCharArrayToCKCharArray(env, jPassword, &(ckParamPtr->pPassword), &(ckParamPtr->ulPasswordLen));
     if ((*env)->ExceptionCheck(env)) {
-        free(ckParamPtr->pInitVector);
-        return;
+        goto cleanup;
     }
     jCharArrayToCKCharArray(env, jSalt, &(ckParamPtr->pSalt), &(ckParamPtr->ulSaltLen));
     if ((*env)->ExceptionCheck(env)) {
-        free(ckParamPtr->pInitVector);
-        free(ckParamPtr->pPassword);
-        return;
+        goto cleanup;
     }
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_PBE_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr->pInitVector);
+    free(ckParamPtr->pPassword);
+    free(ckParamPtr->pSalt);
+    free(ckParamPtr);
+    return NULL;
 }
 
 /*
@@ -1602,7 +1661,7 @@
     jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
     ckMechanismType = jLongToCKULong(jMechanismType);
     if (ckMechanismType != ckMechanism->mechanism) {
-        /* we do not have maching types, this should not occur */
+        /* we do not have matching types, this should not occur */
         return;
     }
 
@@ -1637,321 +1696,426 @@
 }
 
 /*
- * converts the Java CK_PKCS5_PBKD2_PARAMS object to a CK_PKCS5_PBKD2_PARAMS structure
+ * converts the Java CK_PKCS5_PBKD2_PARAMS object to a CK_PKCS5_PBKD2_PARAMS
+ * pointer
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_PKCS5_PBKD2_PARAMS object to convert
- * @param ckParamPtr - pointer to the new CK_PKCS5_PBKD2_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_PKCS5_PBKD2_PARAMS structure
  */
-void jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(JNIEnv *env, jobject jParam,
-CK_PKCS5_PBKD2_PARAMS_PTR ckParamPtr)
+CK_PKCS5_PBKD2_PARAMS_PTR
+jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
+    CK_PKCS5_PBKD2_PARAMS_PTR ckParamPtr;
     jclass jPkcs5Pbkd2ParamsClass;
     jfieldID fieldID;
     jlong jSaltSource, jIteration, jPrf;
     jobject jSaltSourceData, jPrfData;
-    memset(ckParamPtr, 0, sizeof(CK_PKCS5_PBKD2_PARAMS));
 
-    /* get saltSource */
+    if (pLength != NULL) {
+        *pLength = 0L;
+    }
+
+    // retrieve java values
     jPkcs5Pbkd2ParamsClass = (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS);
-    if (jPkcs5Pbkd2ParamsClass == NULL) { return; }
+    if (jPkcs5Pbkd2ParamsClass == NULL) { return NULL; }
     fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "saltSource", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jSaltSource = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pSaltSourceData */
     fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pSaltSourceData", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jSaltSourceData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get iterations */
     fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "iterations", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jIteration = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get prf */
     fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "prf", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPrf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pPrfData and ulPrfDataLength in byte */
     fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pPrfData", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPrfData = (*env)->GetObjectField(env, jParam, fieldID);
 
-    /* populate java values */
+    // allocate memory for CK_PKCS5_PBKD2_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_PKCS5_PBKD2_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     ckParamPtr->saltSource = jLongToCKULong(jSaltSource);
-    jByteArrayToCKByteArray(env, jSaltSourceData, (CK_BYTE_PTR *) &(ckParamPtr->pSaltSourceData), &(ckParamPtr->ulSaltSourceDataLen));
-    if ((*env)->ExceptionCheck(env)) { return; }
+    jByteArrayToCKByteArray(env, jSaltSourceData, (CK_BYTE_PTR *)
+            &(ckParamPtr->pSaltSourceData), &(ckParamPtr->ulSaltSourceDataLen));
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
+    }
     ckParamPtr->iterations = jLongToCKULong(jIteration);
     ckParamPtr->prf = jLongToCKULong(jPrf);
-    jByteArrayToCKByteArray(env, jPrfData, (CK_BYTE_PTR *) &(ckParamPtr->pPrfData), &(ckParamPtr->ulPrfDataLen));
+    jByteArrayToCKByteArray(env, jPrfData, (CK_BYTE_PTR *)
+            &(ckParamPtr->pPrfData), &(ckParamPtr->ulPrfDataLen));
     if ((*env)->ExceptionCheck(env)) {
-        free(ckParamPtr->pSaltSourceData);
-        return;
+        goto cleanup;
     }
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_PKCS5_PBKD2_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr->pSaltSourceData);
+    free(ckParamPtr->pPrfData);
+    free(ckParamPtr);
+    return NULL;
+
 }
 
 /*
- * converts the Java CK_RSA_PKCS_PSS_PARAMS object to a CK_RSA_PKCS_PSS_PARAMS structure
+ * converts the Java CK_RSA_PKCS_PSS_PARAMS object to a CK_RSA_PKCS_PSS_PARAMS
+ * pointer
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_RSA_PKCS_PSS_PARAMS object to convert
- * @param ckParamPtr - pointer to the new CK_RSA_PKCS_PSS_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_RSA_PKCS_PSS_PARAMS structure
  */
-void jRsaPkcsPssParamToCKRsaPkcsPssParam(JNIEnv *env, jobject jParam,
-CK_RSA_PKCS_PSS_PARAMS_PTR ckParamPtr)
+CK_RSA_PKCS_PSS_PARAMS_PTR
+jRsaPkcsPssParamToCKRsaPkcsPssParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
+    CK_RSA_PKCS_PSS_PARAMS_PTR ckParamPtr;
     jclass jRsaPkcsPssParamsClass;
     jfieldID fieldID;
     jlong jHashAlg, jMgf, jSLen;
-    memset(ckParamPtr, 0, sizeof(CK_RSA_PKCS_PSS_PARAMS));
 
-    /* get hashAlg */
+    if (pLength != NULL) {
+        *pLength = 0;
+    }
+
+    // retrieve java values
     jRsaPkcsPssParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_PSS_PARAMS);
-    if (jRsaPkcsPssParamsClass == NULL) { return; }
+    if (jRsaPkcsPssParamsClass == NULL) { return NULL; }
     fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "hashAlg", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jHashAlg = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get mgf */
     fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "mgf", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jMgf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get sLen */
     fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "sLen", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jSLen = (*env)->GetLongField(env, jParam, fieldID);
 
-    /* populate java values */
+    // allocate memory for CK_RSA_PKCS_PSS_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_RSA_PKCS_PSS_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     ckParamPtr->hashAlg = jLongToCKULong(jHashAlg);
     ckParamPtr->mgf = jLongToCKULong(jMgf);
     ckParamPtr->sLen = jLongToCKULong(jSLen);
     TRACE1("DEBUG: jRsaPkcsPssParamToCKRsaPkcsPssParam, hashAlg=0x%lX\n", ckParamPtr->hashAlg);
     TRACE1("DEBUG: jRsaPkcsPssParamToCKRsaPkcsPssParam, mgf=0x%lX\n", ckParamPtr->mgf);
     TRACE1("DEBUG: jRsaPkcsPssParamToCKRsaPkcsPssParam, sLen=%lu\n", ckParamPtr->sLen);
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_RSA_PKCS_PSS_PARAMS);
+    }
+    return ckParamPtr;
+
 }
 
 /*
- * converts the Java CK_ECDH1_DERIVE_PARAMS object to a CK_ECDH1_DERIVE_PARAMS structure
+ * converts the Java CK_ECDH1_DERIVE_PARAMS object to a CK_ECDH1_DERIVE_PARAMS
+ * pointer
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_ECDH1_DERIVE_PARAMS object to convert
- * @param ckParamPtr - the new CK_ECDH1_DERIVE_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @retur pointer to nthe new CK_ECDH1_DERIVE_PARAMS structure
  */
-void jEcdh1DeriveParamToCKEcdh1DeriveParam(JNIEnv *env, jobject jParam,
-CK_ECDH1_DERIVE_PARAMS_PTR ckParamPtr)
+CK_ECDH1_DERIVE_PARAMS_PTR
+jEcdh1DeriveParamToCKEcdh1DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
+    CK_ECDH1_DERIVE_PARAMS_PTR ckParamPtr;
     jclass jEcdh1DeriveParamsClass;
     jfieldID fieldID;
     jlong jLong;
     jobject jSharedData, jPublicData;
-    memset(ckParamPtr, 0, sizeof(CK_ECDH1_DERIVE_PARAMS));
 
-    /* get kdf */
+    if (pLength != NULL) {
+        *pLength = 0;
+    }
+
+    // retrieve java values
     jEcdh1DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH1_DERIVE_PARAMS);
-    if (jEcdh1DeriveParamsClass == NULL) { return; }
+    if (jEcdh1DeriveParamsClass == NULL) { return NULL; }
     fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "kdf", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jLong = (*env)->GetLongField(env, jParam, fieldID);
-    ckParamPtr->kdf = jLongToCKULong(jLong);
-
-    /* get pSharedData and ulSharedDataLen */
     fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "pSharedData", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jSharedData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pPublicData and ulPublicDataLen */
     fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "pPublicData", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
 
-    /* populate java values */
+    // allocate memory for CK_ECDH1_DERIVE_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_ECDH1_DERIVE_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     ckParamPtr->kdf = jLongToCKULong(jLong);
-    jByteArrayToCKByteArray(env, jSharedData, &(ckParamPtr->pSharedData), &(ckParamPtr->ulSharedDataLen));
-    if ((*env)->ExceptionCheck(env)) { return; }
-    jByteArrayToCKByteArray(env, jPublicData, &(ckParamPtr->pPublicData), &(ckParamPtr->ulPublicDataLen));
+    jByteArrayToCKByteArray(env, jSharedData, &(ckParamPtr->pSharedData),
+            &(ckParamPtr->ulSharedDataLen));
     if ((*env)->ExceptionCheck(env)) {
-        free(ckParamPtr->pSharedData);
-        return;
+        goto cleanup;
     }
+    jByteArrayToCKByteArray(env, jPublicData, &(ckParamPtr->pPublicData),
+            &(ckParamPtr->ulPublicDataLen));
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
+    }
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_ECDH1_DERIVE_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr->pSharedData);
+    free(ckParamPtr->pPublicData);
+    free(ckParamPtr);
+    return NULL;
 }
 
 /*
- * converts the Java CK_ECDH2_DERIVE_PARAMS object to a CK_ECDH2_DERIVE_PARAMS structure
+ * converts the Java CK_ECDH2_DERIVE_PARAMS object to a CK_ECDH2_DERIVE_PARAMS
+ * pointer
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_ECDH2_DERIVE_PARAMS object to convert
- * @param ckParamPtr - pointer to the new CK_ECDH2_DERIVE_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_ECDH2_DERIVE_PARAMS structure
  */
-void jEcdh2DeriveParamToCKEcdh2DeriveParam(JNIEnv *env, jobject jParam,
-CK_ECDH2_DERIVE_PARAMS_PTR ckParamPtr)
+CK_ECDH2_DERIVE_PARAMS_PTR
+jEcdh2DeriveParamToCKEcdh2DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
+    CK_ECDH2_DERIVE_PARAMS_PTR ckParamPtr;
     jclass jEcdh2DeriveParamsClass;
     jfieldID fieldID;
     jlong jKdf, jPrivateDataLen, jPrivateData;
     jobject jSharedData, jPublicData, jPublicData2;
-    memset(ckParamPtr, 0, sizeof(CK_ECDH2_DERIVE_PARAMS));
 
-    /* get kdf */
+    // retrieve java values
     jEcdh2DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH2_DERIVE_PARAMS);
-    if (jEcdh2DeriveParamsClass == NULL) { return; }
+    if (jEcdh2DeriveParamsClass == NULL) { return NULL; }
     fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "kdf", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jKdf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pSharedData and ulSharedDataLen */
     fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pSharedData", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jSharedData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pPublicData and ulPublicDataLen */
     fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pPublicData", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get ulPrivateDataLen */
     fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "ulPrivateDataLen", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPrivateDataLen = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get hPrivateData */
     fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "hPrivateData", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPrivateData = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pPublicData2 and ulPublicDataLen2 */
     fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pPublicData2", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPublicData2 = (*env)->GetObjectField(env, jParam, fieldID);
 
-    /* populate java values */
+    // allocate memory for CK_ECDH2_DERIVE_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_ECDH2_DERIVE_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     ckParamPtr->kdf = jLongToCKULong(jKdf);
-    jByteArrayToCKByteArray(env, jSharedData, &(ckParamPtr->pSharedData), &(ckParamPtr->ulSharedDataLen));
-    if ((*env)->ExceptionCheck(env)) { return; }
-    jByteArrayToCKByteArray(env, jPublicData, &(ckParamPtr->pPublicData), &(ckParamPtr->ulPublicDataLen));
+    jByteArrayToCKByteArray(env, jSharedData, &(ckParamPtr->pSharedData),
+            &(ckParamPtr->ulSharedDataLen));
     if ((*env)->ExceptionCheck(env)) {
-        free(ckParamPtr->pSharedData);
-        return;
+        goto cleanup;
+    }
+    jByteArrayToCKByteArray(env, jPublicData, &(ckParamPtr->pPublicData),
+            &(ckParamPtr->ulPublicDataLen));
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
     }
     ckParamPtr->ulPrivateDataLen = jLongToCKULong(jPrivateDataLen);
     ckParamPtr->hPrivateData = jLongToCKULong(jPrivateData);
-    jByteArrayToCKByteArray(env, jPublicData2, &(ckParamPtr->pPublicData2), &(ckParamPtr->ulPublicDataLen2));
+    jByteArrayToCKByteArray(env, jPublicData2, &(ckParamPtr->pPublicData2),
+            &(ckParamPtr->ulPublicDataLen2));
     if ((*env)->ExceptionCheck(env)) {
-        free(ckParamPtr->pSharedData);
-        free(ckParamPtr->pPublicData);
-        return;
+        goto cleanup;
     }
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_ECDH2_DERIVE_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr->pSharedData);
+    free(ckParamPtr->pPublicData);
+    free(ckParamPtr->pPublicData2);
+    free(ckParamPtr);
+    return NULL;
 }
 
 /*
- * converts the Java CK_X9_42_DH1_DERIVE_PARAMS object to a CK_X9_42_DH1_DERIVE_PARAMS structure
+ * converts the Java CK_X9_42_DH1_DERIVE_PARAMS object to a
+ * CK_X9_42_DH1_DERIVE_PARAMS pointer
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_X9_42_DH1_DERIVE_PARAMS object to convert
- * @param ckParamPtr - pointer to the new CK_X9_42_DH1_DERIVE_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_X9_42_DH1_DERIVE_PARAMS structure
  */
-void jX942Dh1DeriveParamToCKX942Dh1DeriveParam(JNIEnv *env, jobject jParam,
-        CK_X9_42_DH1_DERIVE_PARAMS_PTR ckParamPtr)
+CK_X9_42_DH1_DERIVE_PARAMS_PTR
+jX942Dh1DeriveParamToCKX942Dh1DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
+    CK_X9_42_DH1_DERIVE_PARAMS_PTR ckParamPtr;
     jclass jX942Dh1DeriveParamsClass;
     jfieldID fieldID;
     jlong jKdf;
     jobject jOtherInfo, jPublicData;
-    memset(ckParamPtr, 0, sizeof(CK_X9_42_DH1_DERIVE_PARAMS));
 
-    /* get kdf */
+    if (pLength != NULL) {
+        *pLength = 0;
+    }
+
+    // retrieve java values
     jX942Dh1DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH1_DERIVE_PARAMS);
-    if (jX942Dh1DeriveParamsClass == NULL) { return; }
+    if (jX942Dh1DeriveParamsClass == NULL) { return NULL; }
     fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "kdf", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jKdf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pOtherInfo and ulOtherInfoLen */
     fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "pOtherInfo", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jOtherInfo = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pPublicData and ulPublicDataLen */
     fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "pPublicData", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
 
-    /* populate java values */
+    // allocate memory for CK_X9_42_DH1_DERIVE_PARAMS pointer
+    ckParamPtr = calloc(1, sizeof(CK_X9_42_DH1_DERIVE_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     ckParamPtr->kdf = jLongToCKULong(jKdf);
-    jByteArrayToCKByteArray(env, jOtherInfo, &(ckParamPtr->pOtherInfo), &(ckParamPtr->ulOtherInfoLen));
-    if ((*env)->ExceptionCheck(env)) { return; }
-    jByteArrayToCKByteArray(env, jPublicData, &(ckParamPtr->pPublicData), &(ckParamPtr->ulPublicDataLen));
+    jByteArrayToCKByteArray(env, jOtherInfo, &(ckParamPtr->pOtherInfo),
+            &(ckParamPtr->ulOtherInfoLen));
     if ((*env)->ExceptionCheck(env)) {
-        free(ckParamPtr->pOtherInfo);
-        return;
+        goto cleanup;
     }
+    jByteArrayToCKByteArray(env, jPublicData, &(ckParamPtr->pPublicData),
+            &(ckParamPtr->ulPublicDataLen));
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
+    }
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_X9_42_DH1_DERIVE_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr->pOtherInfo);
+    free(ckParamPtr->pPublicData);
+    free(ckParamPtr);
+    return NULL;
 }
 
 /*
- * converts the Java CK_X9_42_DH2_DERIVE_PARAMS object to a CK_X9_42_DH2_DERIVE_PARAMS structure
+ * converts the Java CK_X9_42_DH2_DERIVE_PARAMS object to a
+ * CK_X9_42_DH2_DERIVE_PARAMS pointer
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_X9_42_DH2_DERIVE_PARAMS object to convert
- * @param ckParamPtr - pointer to the new CK_X9_42_DH2_DERIVE_PARAMS structure
+ * @param pLength - length of the allocated memory of the returned pointer
+ * @return pointer to the new CK_X9_42_DH2_DERIVE_PARAMS structure
  */
-void jX942Dh2DeriveParamToCKX942Dh2DeriveParam(JNIEnv *env, jobject jParam,
-        CK_X9_42_DH2_DERIVE_PARAMS_PTR ckParamPtr)
+CK_X9_42_DH2_DERIVE_PARAMS_PTR
+jX942Dh2DeriveParamToCKX942Dh2DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
+    CK_X9_42_DH2_DERIVE_PARAMS_PTR ckParamPtr;
     jclass jX942Dh2DeriveParamsClass;
     jfieldID fieldID;
     jlong jKdf, jPrivateDataLen, jPrivateData;
     jobject jOtherInfo, jPublicData, jPublicData2;
-    memset(ckParamPtr, 0, sizeof(CK_X9_42_DH2_DERIVE_PARAMS));
 
-    /* get kdf */
+    if (pLength != NULL) {
+        *pLength = 0L;
+    }
+
+    // retrieve java values
     jX942Dh2DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH2_DERIVE_PARAMS);
-    if (jX942Dh2DeriveParamsClass == NULL) { return; }
+    if (jX942Dh2DeriveParamsClass == NULL) { return NULL; }
     fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "kdf", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jKdf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pOtherInfo and ulOtherInfoLen */
     fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pOtherInfo", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jOtherInfo = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pPublicData and ulPublicDataLen */
     fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pPublicData", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get ulPrivateDataLen */
     fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "ulPrivateDataLen", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPrivateDataLen = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get hPrivateData */
     fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "hPrivateData", "J");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPrivateData = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pPublicData2 and ulPublicDataLen2 */
     fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pPublicData2", "[B");
-    if (fieldID == NULL) { return; }
+    if (fieldID == NULL) { return NULL; }
     jPublicData2 = (*env)->GetObjectField(env, jParam, fieldID);
 
-    /* populate java values */
+    // allocate memory for CK_DATE pointer
+    ckParamPtr = calloc(1, sizeof(CK_X9_42_DH2_DERIVE_PARAMS));
+    if (ckParamPtr == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    // populate using java values
     ckParamPtr->kdf = jLongToCKULong(jKdf);
-    jByteArrayToCKByteArray(env, jOtherInfo, &(ckParamPtr->pOtherInfo), &(ckParamPtr->ulOtherInfoLen));
-    if ((*env)->ExceptionCheck(env)) { return; }
-    jByteArrayToCKByteArray(env, jPublicData, &(ckParamPtr->pPublicData), &(ckParamPtr->ulPublicDataLen));
+    jByteArrayToCKByteArray(env, jOtherInfo, &(ckParamPtr->pOtherInfo),
+            &(ckParamPtr->ulOtherInfoLen));
     if ((*env)->ExceptionCheck(env)) {
-        free(ckParamPtr->pOtherInfo);
-        return;
+        goto cleanup;
+    }
+    jByteArrayToCKByteArray(env, jPublicData, &(ckParamPtr->pPublicData),
+            &(ckParamPtr->ulPublicDataLen));
+    if ((*env)->ExceptionCheck(env)) {
+        goto cleanup;
     }
     ckParamPtr->ulPrivateDataLen = jLongToCKULong(jPrivateDataLen);
     ckParamPtr->hPrivateData = jLongToCKULong(jPrivateData);
-    jByteArrayToCKByteArray(env, jPublicData2, &(ckParamPtr->pPublicData2), &(ckParamPtr->ulPublicDataLen2));
+    jByteArrayToCKByteArray(env, jPublicData2, &(ckParamPtr->pPublicData2),
+            &(ckParamPtr->ulPublicDataLen2));
     if ((*env)->ExceptionCheck(env)) {
-        free(ckParamPtr->pOtherInfo);
-        free(ckParamPtr->pPublicData);
-        return;
+        goto cleanup;
     }
+
+    if (pLength != NULL) {
+        *pLength = sizeof(CK_X9_42_DH2_DERIVE_PARAMS);
+    }
+    return ckParamPtr;
+cleanup:
+    free(ckParamPtr->pOtherInfo);
+    free(ckParamPtr->pPublicData);
+    free(ckParamPtr->pPublicData2);
+    free(ckParamPtr);
+    return NULL;
 }
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c	Wed Aug 14 00:57:15 2019 +0000
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c	Wed Aug 14 01:40:29 2019 +0000
@@ -198,8 +198,8 @@
         TRACE0("DEBUG: override CKA_NETSCAPE_DB attr value to TRUE\n");
     }
 
-    ckpAttributes = (CK_ATTRIBUTE_PTR)malloc(
-            CK_ATTRIBUTES_TEMPLATE_LENGTH * sizeof(CK_ATTRIBUTE));
+    ckpAttributes = (CK_ATTRIBUTE_PTR) calloc(
+            CK_ATTRIBUTES_TEMPLATE_LENGTH, sizeof(CK_ATTRIBUTE));
     if (ckpAttributes == NULL) {
         throwOutOfMemoryError(env, 0);
         goto cleanup;
@@ -599,7 +599,7 @@
     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
     if ((*env)->ExceptionCheck(env)) { return NULL; }
 
-    ckpKeyHandles = (CK_OBJECT_HANDLE_PTR) malloc(2 * sizeof(CK_OBJECT_HANDLE));
+    ckpKeyHandles = (CK_OBJECT_HANDLE_PTR) calloc(2, sizeof(CK_OBJECT_HANDLE));
     if (ckpKeyHandles == NULL) {
         throwOutOfMemoryError(env, 0);
         goto cleanup;
@@ -698,7 +698,8 @@
 
     rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, ckpMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
     if (rv == CKR_BUFFER_TOO_SMALL) {
-        ckpWrappedKey = (CK_BYTE_PTR) malloc(ckWrappedKeyLength);
+        ckpWrappedKey = (CK_BYTE_PTR)
+                calloc(ckWrappedKeyLength, sizeof(CK_BYTE));
         if (ckpWrappedKey == NULL) {
             throwOutOfMemoryError(env, 0);
             goto cleanup;
@@ -793,51 +794,6 @@
 
 #ifdef P11_ENABLE_C_DERIVEKEY
 
-static void freeMasterKeyDeriveParams(CK_SSL3_RANDOM_DATA *RandomInfo, CK_VERSION_PTR pVersion) {
-    if (RandomInfo->pClientRandom != NULL) {
-        free(RandomInfo->pClientRandom);
-    }
-    if (RandomInfo->pServerRandom != NULL) {
-        free(RandomInfo->pServerRandom);
-    }
-    if (pVersion != NULL) {
-        free(pVersion);
-    }
-}
-
-void ssl3FreeMasterKeyDeriveParams(CK_MECHANISM_PTR ckpMechanism) {
-    CK_SSL3_MASTER_KEY_DERIVE_PARAMS *params =
-            (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckpMechanism->pParameter;
-    if (params == NULL) {
-        return;
-    }
-    freeMasterKeyDeriveParams(&(params->RandomInfo), params->pVersion);
-}
-
-void tls12FreeMasterKeyDeriveParams(CK_MECHANISM_PTR ckpMechanism) {
-    CK_TLS12_MASTER_KEY_DERIVE_PARAMS *params =
-            (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)ckpMechanism->pParameter;
-    if (params == NULL) {
-        return;
-    }
-    freeMasterKeyDeriveParams(&(params->RandomInfo), params->pVersion);
-}
-
-void freeEcdh1DeriveParams(CK_MECHANISM_PTR ckpMechanism) {
-    CK_ECDH1_DERIVE_PARAMS *params =
-            (CK_ECDH1_DERIVE_PARAMS *)ckpMechanism->pParameter;
-    if (params == NULL) {
-        return;
-    }
-
-    if (params->pSharedData != NULL) {
-        free(params->pSharedData);
-    }
-    if (params->pPublicData != NULL) {
-        free(params->pPublicData);
-    }
-}
-
 /*
  * Copy back the PRF output to Java.
  */
@@ -897,12 +853,6 @@
             /* copy back the Java buffer to the object */
             (*env)->ReleaseByteArrayElements(env, jOutput, jBytes, 0);
         }
-
-        // free malloc'd data
-        free(ckTLSPrfParams->pSeed);
-        free(ckTLSPrfParams->pLabel);
-        free(ckTLSPrfParams->pulOutputLen);
-        free(ckTLSPrfParams->pOutput);
     }
 }
 
@@ -968,18 +918,9 @@
     case CKM_TLS_MASTER_KEY_DERIVE:
         /* we must copy back the client version */
         ssl3CopyBackClientVersion(env, ckpMechanism, jMechanism);
-        ssl3FreeMasterKeyDeriveParams(ckpMechanism);
         break;
     case CKM_TLS12_MASTER_KEY_DERIVE:
         tls12CopyBackClientVersion(env, ckpMechanism, jMechanism);
-        tls12FreeMasterKeyDeriveParams(ckpMechanism);
-        break;
-    case CKM_SSL3_MASTER_KEY_DERIVE_DH:
-    case CKM_TLS_MASTER_KEY_DERIVE_DH:
-        ssl3FreeMasterKeyDeriveParams(ckpMechanism);
-        break;
-    case CKM_TLS12_MASTER_KEY_DERIVE_DH:
-        tls12FreeMasterKeyDeriveParams(ckpMechanism);
         break;
     case CKM_SSL3_KEY_AND_MAC_DERIVE:
     case CKM_TLS_KEY_AND_MAC_DERIVE:
@@ -993,9 +934,6 @@
     case CKM_TLS_PRF:
         copyBackTLSPrfParams(env, ckpMechanism, jMechanism);
         break;
-    case CKM_ECDH1_DERIVE:
-        freeEcdh1DeriveParams(ckpMechanism);
-        break;
     default:
         // empty
         break;
@@ -1131,14 +1069,6 @@
         return;
     }
 
-    // free malloc'd data
-    if (RandomInfo->pClientRandom != NULL) {
-        free(RandomInfo->pClientRandom);
-    }
-    if (RandomInfo->pServerRandom != NULL) {
-        free(RandomInfo->pServerRandom);
-    }
-
     if (ckSSL3KeyMatOut != NULL_PTR) {
       /* get the Java params object (pParameter) */
       fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter",
@@ -1200,8 +1130,6 @@
         /* copy back the Java buffer to the object */
         (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
       }
-      // free malloc'd data
-      free(ckSSL3KeyMatOut->pIVClient);
 
       /* copy back the server IV */
       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVServer", "[B");
@@ -1220,9 +1148,6 @@
         /* copy back the Java buffer to the object */
         (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
       }
-      // free malloc'd data
-      free(ckSSL3KeyMatOut->pIVServer);
-      free(ckSSL3KeyMatOut);
     }
 }
 
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c	Wed Aug 14 00:57:15 2019 +0000
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c	Wed Aug 14 01:40:29 2019 +0000
@@ -290,17 +290,122 @@
 }
 
 /* This function frees the specified CK_MECHANISM_PTR pointer and its
- * pParameter. NOTE: mechanism-specific memory allocations have to be
- * freed before this call as this method only frees the generic
- * memory associated with CK_MECHANISM structure.
+ * pParameter including mechanism-specific memory allocations.
  *
  * @param mechPtr pointer to the to-be-freed CK_MECHANISM structure.
  */
+void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) {
+     void *tmp;
+     CK_SSL3_MASTER_KEY_DERIVE_PARAMS *sslMkdTmp;
+     CK_SSL3_KEY_MAT_PARAMS* sslKmTmp;
+     CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tlsMkdTmp;
+     CK_TLS12_KEY_MAT_PARAMS* tlsKmTmp;
 
-void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) {
      if (mechPtr != NULL) {
-         TRACE1("DEBUG: free CK_MECHANISM %x", mechPtr);
-         free(mechPtr->pParameter);
+         TRACE2("DEBUG: free mech %lX (mech id = 0x%lX)\n",
+                 ptr_to_jlong(mechPtr),  mechPtr->mechanism);
+         if (mechPtr->pParameter != NULL) {
+             switch (mechPtr->mechanism) {
+                 case CKM_AES_GCM:
+                     tmp = mechPtr->pParameter;
+                     TRACE1("\t=> free GCM_PARAMS %lX\n",
+                             ptr_to_jlong(tmp));
+                     free(((CK_GCM_PARAMS*)tmp)->pIv);
+                     free(((CK_GCM_PARAMS*)tmp)->pAAD);
+                     break;
+                 case CKM_AES_CCM:
+                     tmp = mechPtr->pParameter;
+                     TRACE1("\t=> free CK_CCM_PARAMS %lX\n",
+                             ptr_to_jlong(tmp));
+                     free(((CK_CCM_PARAMS*)tmp)->pNonce);
+                     free(((CK_CCM_PARAMS*)tmp)->pAAD);
+                     break;
+                 case CKM_TLS_PRF:
+                 case CKM_NSS_TLS_PRF_GENERAL:
+                     tmp = mechPtr->pParameter;
+                     TRACE1("\t=> free CK_TLS_PRF_PARAMS %lX\n",
+                         ptr_to_jlong(tmp));
+                     free(((CK_TLS_PRF_PARAMS*)tmp)->pSeed);
+                     free(((CK_TLS_PRF_PARAMS*)tmp)->pLabel);
+                     free(((CK_TLS_PRF_PARAMS*)tmp)->pulOutputLen);
+                     free(((CK_TLS_PRF_PARAMS*)tmp)->pOutput);
+                     break;
+                 case CKM_SSL3_MASTER_KEY_DERIVE:
+                 case CKM_TLS_MASTER_KEY_DERIVE:
+                 case CKM_SSL3_MASTER_KEY_DERIVE_DH:
+                 case CKM_TLS_MASTER_KEY_DERIVE_DH:
+                     sslMkdTmp = mechPtr->pParameter;
+                     TRACE1("\t=> free CK_SSL3_MASTER_KEY_DERIVE_PARAMS %lX\n",
+                         ptr_to_jlong(sslMkdTmp));
+                     free(sslMkdTmp->RandomInfo.pClientRandom);
+                     free(sslMkdTmp->RandomInfo.pServerRandom);
+                     free(sslMkdTmp->pVersion);
+                     break;
+                 case CKM_SSL3_KEY_AND_MAC_DERIVE:
+                 case CKM_TLS_KEY_AND_MAC_DERIVE:
+                     sslKmTmp = mechPtr->pParameter;
+                     TRACE1("\t=> free CK_SSL3_KEY_MAT_PARAMS %lX\n",
+                         ptr_to_jlong(sslKmTmp));
+                     free(sslKmTmp->RandomInfo.pClientRandom);
+                     free(sslKmTmp->RandomInfo.pServerRandom);
+                     if (sslKmTmp->pReturnedKeyMaterial != NULL) {
+                         free(sslKmTmp->pReturnedKeyMaterial->pIVClient);
+                         free(sslKmTmp->pReturnedKeyMaterial->pIVServer);
+                         free(sslKmTmp->pReturnedKeyMaterial);
+                     }
+                     break;
+                 case CKM_TLS12_MASTER_KEY_DERIVE:
+                 case CKM_TLS12_MASTER_KEY_DERIVE_DH:
+                     tlsMkdTmp = mechPtr->pParameter;
+                     TRACE1("\t=> CK_TLS12_MASTER_KEY_DERIVE_PARAMS %lX\n",
+                         ptr_to_jlong(tlsMkdTmp));
+                     free(tlsMkdTmp->RandomInfo.pClientRandom);
+                     free(tlsMkdTmp->RandomInfo.pServerRandom);
+                     free(tlsMkdTmp->pVersion);
+                     break;
+                 case CKM_TLS12_KEY_AND_MAC_DERIVE:
+                     tlsKmTmp = mechPtr->pParameter;
+                     TRACE1("\t=> free CK_TLS12_KEY_MAT_PARAMS %lX\n",
+                         ptr_to_jlong(tlsKmTmp));
+                     free(tlsKmTmp->RandomInfo.pClientRandom);
+                     free(tlsKmTmp->RandomInfo.pServerRandom);
+                     if (tlsKmTmp->pReturnedKeyMaterial != NULL) {
+                         free(tlsKmTmp->pReturnedKeyMaterial->pIVClient);
+                         free(tlsKmTmp->pReturnedKeyMaterial->pIVServer);
+                         free(tlsKmTmp->pReturnedKeyMaterial);
+                     }
+                     break;
+                 case CKM_ECDH1_DERIVE:
+                 case CKM_ECDH1_COFACTOR_DERIVE:
+                     tmp = mechPtr->pParameter;
+                     TRACE1("\t=> free CK_ECDH1_DERIVE_PARAMS %lX\n",
+                         ptr_to_jlong(tmp));
+                     free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pSharedData);
+                     free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pPublicData);
+                     break;
+                 case CKM_TLS_MAC:
+                 case CKM_AES_CTR:
+                 case CKM_RSA_PKCS_PSS:
+                 case CKM_CAMELLIA_CTR:
+                     TRACE0("\t=> NO OP\n");
+                     // params do not contain pointers
+                     break;
+                 default:
+                     // currently unsupported mechs by SunPKCS11 provider
+                     // CKM_RSA_PKCS_OAEP, CKM_ECMQV_DERIVE,
+                     // CKM_X9_42_*, CKM_KEA_DERIVE, CKM_RC2_*, CKM_RC5_*,
+                     // CKM_SKIPJACK_*, CKM_KEY_WRAP_SET_OAEP, CKM_PKCS5_PBKD2,
+                     // PBE mechs, WTLS mechs, CMS mechs,
+                     // CKM_EXTRACT_KEY_FROM_KEY, CKM_OTP, CKM_KIP,
+                     // CKM_DSA_PARAMETER_GEN?, CKM_GOSTR3410_*
+                     // CK_any_CBC_ENCRYPT_DATA?
+                     TRACE0("\t=> ERROR UNSUPPORTED CK PARAMS\n");
+                     break;
+             }
+             free(mechPtr->pParameter);
+         } else {
+             TRACE0("DEBUG => Parameter NULL\n");
+         }
          free(mechPtr);
      }
 }
@@ -356,7 +461,7 @@
         return;
     }
     *ckpLength = (*env)->GetArrayLength(env, jArray);
-    jpTemp = (jboolean*) malloc((*ckpLength) * sizeof(jboolean));
+    jpTemp = (jboolean*) calloc(*ckpLength, sizeof(jboolean));
     if (jpTemp == NULL) {
         throwOutOfMemoryError(env, 0);
         return;
@@ -367,7 +472,7 @@
         return;
     }
 
-    *ckpArray = (CK_BBOOL*) malloc ((*ckpLength) * sizeof(CK_BBOOL));
+    *ckpArray = (CK_BBOOL*) calloc (*ckpLength, sizeof(CK_BBOOL));
     if (*ckpArray == NULL) {
         free(jpTemp);
         throwOutOfMemoryError(env, 0);
@@ -398,7 +503,7 @@
         return;
     }
     *ckpLength = (*env)->GetArrayLength(env, jArray);
-    jpTemp = (jbyte*) malloc((*ckpLength) * sizeof(jbyte));
+    jpTemp = (jbyte*) calloc(*ckpLength, sizeof(jbyte));
     if (jpTemp == NULL) {
         throwOutOfMemoryError(env, 0);
         return;
@@ -413,7 +518,7 @@
     if (sizeof(CK_BYTE) == sizeof(jbyte)) {
         *ckpArray = (CK_BYTE_PTR) jpTemp;
     } else {
-        *ckpArray = (CK_BYTE_PTR) malloc ((*ckpLength) * sizeof(CK_BYTE));
+        *ckpArray = (CK_BYTE_PTR) calloc (*ckpLength, sizeof(CK_BYTE));
         if (*ckpArray == NULL) {
             free(jpTemp);
             throwOutOfMemoryError(env, 0);
@@ -445,7 +550,7 @@
         return;
     }
     *ckpLength = (*env)->GetArrayLength(env, jArray);
-    jTemp = (jlong*) malloc((*ckpLength) * sizeof(jlong));
+    jTemp = (jlong*) calloc(*ckpLength, sizeof(jlong));
     if (jTemp == NULL) {
         throwOutOfMemoryError(env, 0);
         return;
@@ -456,7 +561,7 @@
         return;
     }
 
-    *ckpArray = (CK_ULONG_PTR) malloc (*ckpLength * sizeof(CK_ULONG));
+    *ckpArray = (CK_ULONG_PTR) calloc(*ckpLength, sizeof(CK_ULONG));
     if (*ckpArray == NULL) {
         free(jTemp);
         throwOutOfMemoryError(env, 0);
@@ -487,7 +592,7 @@
         return;
     }
     *ckpLength = (*env)->GetArrayLength(env, jArray);
-    jpTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar));
+    jpTemp = (jchar*) calloc(*ckpLength, sizeof(jchar));
     if (jpTemp == NULL) {
         throwOutOfMemoryError(env, 0);
         return;
@@ -498,7 +603,7 @@
         return;
     }
 
-    *ckpArray = (CK_CHAR_PTR) malloc (*ckpLength * sizeof(CK_CHAR));
+    *ckpArray = (CK_CHAR_PTR) calloc (*ckpLength, sizeof(CK_CHAR));
     if (*ckpArray == NULL) {
         free(jpTemp);
         throwOutOfMemoryError(env, 0);
@@ -529,7 +634,7 @@
         return;
     }
     *ckpLength = (*env)->GetArrayLength(env, jArray);
-    jTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar));
+    jTemp = (jchar*) calloc(*ckpLength, sizeof(jchar));
     if (jTemp == NULL) {
         throwOutOfMemoryError(env, 0);
         return;
@@ -540,7 +645,7 @@
         return;
     }
 
-    *ckpArray = (CK_UTF8CHAR_PTR) malloc (*ckpLength * sizeof(CK_UTF8CHAR));
+    *ckpArray = (CK_UTF8CHAR_PTR) calloc(*ckpLength, sizeof(CK_UTF8CHAR));
     if (*ckpArray == NULL) {
         free(jTemp);
         throwOutOfMemoryError(env, 0);
@@ -575,7 +680,7 @@
     if (pCharArray == NULL) { return; }
 
     *ckpLength = (CK_ULONG) strlen(pCharArray);
-    *ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR));
+    *ckpArray = (CK_UTF8CHAR_PTR) calloc(*ckpLength + 1, sizeof(CK_UTF8CHAR));
     if (*ckpArray == NULL) {
         (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
         throwOutOfMemoryError(env, 0);
@@ -609,7 +714,7 @@
     }
     jLength = (*env)->GetArrayLength(env, jArray);
     *ckpLength = jLongToCKULong(jLength);
-    *ckpArray = (CK_ATTRIBUTE_PTR) malloc(*ckpLength * sizeof(CK_ATTRIBUTE));
+    *ckpArray = (CK_ATTRIBUTE_PTR) calloc(*ckpLength, sizeof(CK_ATTRIBUTE));
     if (*ckpArray == NULL) {
         throwOutOfMemoryError(env, 0);
         return;
@@ -651,7 +756,7 @@
     if (sizeof(CK_BYTE) == sizeof(jbyte)) {
         jpTemp = (jbyte*) ckpArray;
     } else {
-        jpTemp = (jbyte*) malloc((ckLength) * sizeof(jbyte));
+        jpTemp = (jbyte*) calloc(ckLength, sizeof(jbyte));
         if (jpTemp == NULL) {
             throwOutOfMemoryError(env, 0);
             return NULL;
@@ -685,7 +790,7 @@
     jlong* jpTemp;
     jlongArray jArray;
 
-    jpTemp = (jlong*) malloc((ckLength) * sizeof(jlong));
+    jpTemp = (jlong*) calloc(ckLength, sizeof(jlong));
     if (jpTemp == NULL) {
         throwOutOfMemoryError(env, 0);
         return NULL;
@@ -716,7 +821,7 @@
     jchar* jpTemp;
     jcharArray jArray;
 
-    jpTemp = (jchar*) malloc(ckLength * sizeof(jchar));
+    jpTemp = (jchar*) calloc(ckLength, sizeof(jchar));
     if (jpTemp == NULL) {
         throwOutOfMemoryError(env, 0);
         return NULL;
@@ -747,7 +852,7 @@
     jchar* jpTemp;
     jcharArray jArray;
 
-    jpTemp = (jchar*) malloc(ckLength * sizeof(jchar));
+    jpTemp = (jchar*) calloc(ckLength, sizeof(jchar));
     if (jpTemp == NULL) {
         throwOutOfMemoryError(env, 0);
         return NULL;
@@ -1051,7 +1156,7 @@
     jDateClass = (*env)->FindClass(env, CLASS_DATE);
     if (jDateClass == NULL) { return NULL; }
     if ((*env)->IsInstanceOf(env, jObject, jDateClass)) {
-        ckpObject = jDateObjectPtrToCKDatePtr(env, jObject);
+        ckpObject = jDateObjectToCKDatePtr(env, jObject);
         *ckpLength = sizeof(CK_DATE);
         TRACE3("<converted date value %.4s-%.2s-%.2s>", ((CK_DATE *) ckpObject)->year,
                 ((CK_DATE *) ckpObject)->month, ((CK_DATE *) ckpObject)->day);
@@ -1123,7 +1228,7 @@
     if (classNameString == NULL) { return NULL; }
     exceptionMsgPrefix = "Java object of this class cannot be converted to native PKCS#11 type: ";
     exceptionMsg = (char *)
-        malloc((strlen(exceptionMsgPrefix) + strlen(classNameString) + 1));
+        malloc(strlen(exceptionMsgPrefix) + strlen(classNameString) + 1);
     if (exceptionMsg == NULL) {
         (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);
         throwOutOfMemoryError(env, 0);
@@ -1143,16 +1248,26 @@
 #ifdef P11_MEMORYDEBUG
 
 #undef malloc
+#undef calloc
 #undef free
 
 void *p11malloc(size_t c, char *file, int line) {
     void *p = malloc(c);
-    printf("malloc\t%08x\t%d\t%s:%d\n", p, c, file, line); fflush(stdout);
+    fprintf(stdout, "malloc\t%08lX\t%lX\t%s:%d\n", ptr_to_jlong(p), c, file, line);
+    fflush(stdout);
+    return p;
+}
+
+void *p11calloc(size_t c, size_t s, char *file, int line) {
+    void *p = calloc(c, s);
+    fprintf(stdout, "calloc\t%08lX\t%lX\t%lX\t%s:%d\n", ptr_to_jlong(p), c, s, file, line);
+    fflush(stdout);
     return p;
 }
 
 void p11free(void *p, char *file, int line) {
-    printf("free\t%08x\t\t%s:%d\n", p, file, line); fflush(stdout);
+    fprintf(stdout, "free\t%08lX\t\t%s:%d\n", ptr_to_jlong(p), file, line);
+    fflush(stdout);
     free(p);
 }
 
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h	Wed Aug 14 00:57:15 2019 +0000
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h	Wed Aug 14 01:40:29 2019 +0000
@@ -207,6 +207,10 @@
 #define ckULongToJSize(x)       ((jsize) x)
 #define unsignedIntToCKULong(x) ((CK_ULONG) x)
 
+//#define TRACE0d(s) { printf(s); fflush(stdout); }
+//#define TRACE1d(s, p1) { printf(s, p1); fflush(stdout); }
+//#define TRACE2d(s, p1, p2) { printf(s, p1, p2); fflush(stdout); }
+
 #ifdef P11_DEBUG
 #define TRACE0(s) { printf(s); fflush(stdout); }
 #define TRACE1(s, p1) { printf(s, p1); fflush(stdout); }
@@ -352,7 +356,7 @@
 CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject);
 CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject);
 CK_VERSION_PTR jVersionToCKVersionPtr(JNIEnv *env, jobject jVersion);
-CK_DATE * jDateObjectPtrToCKDatePtr(JNIEnv *env, jobject jDate);
+CK_DATE * jDateObjectToCKDatePtr(JNIEnv *env, jobject jDate);
 CK_ATTRIBUTE jAttributeToCKAttribute(JNIEnv *env, jobject jAttribute);
 CK_MECHANISM_PTR jMechanismToCKMechanismPtr(JNIEnv *env, jobject jMechanism);
 
@@ -363,26 +367,29 @@
 *ckpLength);
 
 
-/* functions to convert a specific Java mechanism parameter object to a CK-mechanism parameter structure */
+/* functions to convert a specific Java mechanism parameter object to a CK-mechanism parameter pointer */
 
-void jRsaPkcsOaepParamToCKRsaPkcsOaepParam(JNIEnv *env, jobject jParam, CK_RSA_PKCS_OAEP_PARAMS_PTR ckParamPtr);
-void jPbeParamToCKPbeParam(JNIEnv *env, jobject jParam, CK_PBE_PARAMS_PTR ckParamPtr);
+CK_RSA_PKCS_OAEP_PARAMS_PTR jRsaPkcsOaepParamToCKRsaPkcsOaepParamPtr(JNIEnv *env,
+    jobject jParam, CK_ULONG* pLength);
+CK_PBE_PARAMS_PTR jPbeParamToCKPbeParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength);
+CK_PKCS5_PBKD2_PARAMS_PTR jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength);
+CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength);
+CK_SSL3_KEY_MAT_PARAMS_PTR jSsl3KeyMatParamToCKSsl3KeyMatParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength);
+CK_KEY_DERIVATION_STRING_DATA jKeyDerivationStringDataToCKKeyDerivationStringData(JNIEnv *env, jobject jParam);
+CK_RSA_PKCS_PSS_PARAMS_PTR jRsaPkcsPssParamToCKRsaPkcsPssParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength);
+CK_ECDH1_DERIVE_PARAMS_PTR jEcdh1DeriveParamToCKEcdh1DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength);
+CK_ECDH2_DERIVE_PARAMS_PTR jEcdh2DeriveParamToCKEcdh2DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength);
+CK_X9_42_DH1_DERIVE_PARAMS_PTR jX942Dh1DeriveParamToCKX942Dh1DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength);
+CK_X9_42_DH2_DERIVE_PARAMS_PTR jX942Dh2DeriveParamToCKX942Dh2DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength);
+
+/* functions to copy the returned values inside CK-mechanism back to Java object */
+
 void copyBackPBEInitializationVector(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
-void jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(JNIEnv *env, jobject jParam, CK_PKCS5_PBKD2_PARAMS_PTR ckParamPtr);
 void copyBackSetUnwrappedKey(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
-void jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv *env, jobject jParam, CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR ckParamPtr);
 void ssl3CopyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
 void tls12CopyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
-void jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject jParam, CK_SSL3_KEY_MAT_PARAMS_PTR ckParamPtr);
 void ssl3CopyBackKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
 void tls12CopyBackKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
-CK_KEY_DERIVATION_STRING_DATA jKeyDerivationStringDataToCKKeyDerivationStringData(JNIEnv *env, jobject jParam);
-void jRsaPkcsPssParamToCKRsaPkcsPssParam(JNIEnv *env, jobject jParam, CK_RSA_PKCS_PSS_PARAMS_PTR ckParamPtr);
-void jEcdh1DeriveParamToCKEcdh1DeriveParam(JNIEnv *env, jobject jParam, CK_ECDH1_DERIVE_PARAMS_PTR ckParamPtr);
-void jEcdh2DeriveParamToCKEcdh2DeriveParam(JNIEnv *env, jobject jParam,
-CK_ECDH2_DERIVE_PARAMS_PTR ckParamPtr);
-void jX942Dh1DeriveParamToCKX942Dh1DeriveParam(JNIEnv *env, jobject jParam, CK_X9_42_DH1_DERIVE_PARAMS_PTR ckParamPtr);
-void jX942Dh2DeriveParamToCKX942Dh2DeriveParam(JNIEnv *env, jobject jParam, CK_X9_42_DH2_DERIVE_PARAMS_PTR ckParamPtr);
 
 
 /* functions to convert the InitArgs object for calling the right Java mutex functions */
@@ -462,8 +469,9 @@
 #ifdef P11_MEMORYDEBUG
 #include <stdlib.h>
 
-/* Simple malloc/free dumper */
+/* Simple malloc/calloc/free dumper */
 void *p11malloc(size_t c, char *file, int line);
+void *p11calloc(size_t c, size_t s, char *file, int line);
 void p11free(void *p, char *file, int line);
 
 /* Use THIS_FILE when it is available. */
@@ -472,6 +480,7 @@
 #endif
 
 #define malloc(c)       (p11malloc((c), THIS_FILE, __LINE__))
+#define calloc(c, s)    (p11calloc((c), (s), THIS_FILE, __LINE__))
 #define free(c)         (p11free((c), THIS_FILE, __LINE__))
 
 #endif