src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c
changeset 55332 f492567244ab
parent 47216 71c04702a3d5
child 58489 2faeaa5933a6
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c	Tue Jun 11 13:04:36 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c	Tue Jun 11 21:30:28 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 
 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
@@ -71,7 +71,7 @@
  jobject jMechanism, jlong jKeyHandle)
 {
     CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
+    CK_MECHANISM_PTR ckpMechanism = NULL;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
@@ -80,15 +80,14 @@
 
     ckSessionHandle = jLongToCKULong(jSessionHandle);
     ckKeyHandle = jLongToCKULong(jKeyHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
     if ((*env)->ExceptionCheck(env)) { return; }
 
-    rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, &ckMechanism,
+    rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, ckpMechanism,
                                         ckKeyHandle);
 
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
+    // if OAEP, then cannot free here
+    freeCKMechanismPtr(ckpMechanism);
 
     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 }
@@ -98,54 +97,67 @@
 /*
  * Class:     sun_security_pkcs11_wrapper_PKCS11
  * Method:    C_Encrypt
- * Signature: (J[BII[BII)I
+ * Signature: (JJ[BIIJ[BII)I
  * Parametermapping:                    *PKCS11*
  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jlong directIn              CK_BYTE_PTR pData
  * @param   jbyteArray jData            CK_BYTE_PTR pData
  *                                      CK_ULONG ulDataLen
- * @return  jbyteArray jEncryptedData   CK_BYTE_PTR pEncryptedData
+ * @param   jlong directOut             CK_BYTE_PTR pEncryptedData
+ * @return  jint encryptedDataLen       CK_BYTE_PTR pEncryptedData
  *                                      CK_ULONG_PTR pulEncryptedDataLen
  */
 JNIEXPORT jint JNICALL
 Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt
 (JNIEnv *env, jobject obj, jlong jSessionHandle,
- jbyteArray jIn, jint jInOfs, jint jInLen,
- jbyteArray jOut, jint jOutOfs, jint jOutLen)
+ jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
+ jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
 {
     CK_SESSION_HANDLE ckSessionHandle;
     CK_RV rv;
 
     CK_BYTE_PTR inBufP;
     CK_BYTE_PTR outBufP;
-    CK_ULONG ckEncryptedPartLen;
+    CK_ULONG ckEncryptedLen = 0;
 
     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
     if (ckpFunctions == NULL) { return 0; }
 
     ckSessionHandle = jLongToCKULong(jSessionHandle);
 
-    inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
-    if (inBufP == NULL) { return 0; }
-
-    outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
-    if (outBufP == NULL) {
-        // Make sure to release inBufP
-        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-        return 0;
+    if (directIn != 0) {
+      inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
+    } else {
+      inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
+      if (inBufP == NULL) { return 0; }
     }
 
-    ckEncryptedPartLen = jOutLen;
+    if (directOut != 0) {
+      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
+    } else {
+      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
+      if (outBufP == NULL) {
+          goto cleanup;
+      }
+    }
+
+    ckEncryptedLen = jOutLen;
 
     rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle,
                                     (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
                                     (CK_BYTE_PTR)(outBufP + jOutOfs),
-                                    &ckEncryptedPartLen);
-
-    (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-    (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+                                    &ckEncryptedLen);
 
     ckAssertReturnValueOK(env, rv);
-    return ckEncryptedPartLen;
+
+cleanup:
+    if (directIn == 0 && inBufP != NULL) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+    }
+    if (directOut == 0 && outBufP != NULL) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+    }
+    return ckEncryptedLen;
 }
 #endif
 
@@ -172,7 +184,7 @@
 
     CK_BYTE_PTR inBufP;
     CK_BYTE_PTR outBufP;
-    CK_ULONG ckEncryptedPartLen;
+    CK_ULONG ckEncryptedPartLen = 0;
 
     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
     if (ckpFunctions == NULL) { return 0; }
@@ -191,34 +203,26 @@
     } else {
       outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
       if (outBufP == NULL) {
-          // Make sure to release inBufP
-          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-          return 0;
+          goto cleanup;
       }
     }
 
     ckEncryptedPartLen = jOutLen;
 
-    //printf("EU: inBufP=%i, jInOfs=%i, jInLen=%i, outBufP=%i\n",
-    //       inBufP, jInOfs, jInLen, outBufP);
-
     rv = (*ckpFunctions->C_EncryptUpdate)(ckSessionHandle,
                                           (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
                                           (CK_BYTE_PTR)(outBufP + jOutOfs),
                                           &ckEncryptedPartLen);
 
-    //printf("EU: ckEncryptedPartLen=%i\n", ckEncryptedPartLen);
+    ckAssertReturnValueOK(env, rv);
 
-    if (directIn == 0) {
+cleanup:
+    if (directIn == 0 && inBufP != NULL) {
         (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
     }
-
-    if (directOut == 0) {
+    if (directOut == 0 && outBufP != NULL) {
         (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
     }
-
-    ckAssertReturnValueOK(env, rv);
-
     return ckEncryptedPartLen;
 }
 #endif
@@ -257,14 +261,10 @@
 
     ckLastEncryptedPartLen = jOutLen;
 
-    //printf("EF: outBufP=%i\n", outBufP);
-
     rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle,
                                          (CK_BYTE_PTR)(outBufP + jOutOfs),
                                          &ckLastEncryptedPartLen);
 
-    //printf("EF: ckLastEncryptedPartLen=%i", ckLastEncryptedPartLen);
-
     if (directOut == 0) {
         (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
     }
@@ -291,7 +291,7 @@
  jobject jMechanism, jlong jKeyHandle)
 {
     CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
+    CK_MECHANISM_PTR ckpMechanism = NULL;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
@@ -300,15 +300,14 @@
 
     ckSessionHandle = jLongToCKULong(jSessionHandle);
     ckKeyHandle = jLongToCKULong(jKeyHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
     if ((*env)->ExceptionCheck(env)) { return; }
 
-    rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, &ckMechanism,
+    rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, ckpMechanism,
                                         ckKeyHandle);
 
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
+    // if OAEP, then cannot free here
+    freeCKMechanismPtr(ckpMechanism);
 
     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 }
@@ -318,7 +317,7 @@
 /*
  * Class:     sun_security_pkcs11_wrapper_PKCS11
  * Method:    C_Decrypt
- * Signature: (J[BII[BII)I
+ * Signature: (JJ[BIIJ[BII)I
  * Parametermapping:                    *PKCS11*
  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
  * @param   jbyteArray jEncryptedData   CK_BYTE_PTR pEncryptedData
@@ -329,44 +328,53 @@
 JNIEXPORT jint JNICALL
 Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt
 (JNIEnv *env, jobject obj, jlong jSessionHandle,
- jbyteArray jIn, jint jInOfs, jint jInLen,
- jbyteArray jOut, jint jOutOfs, jint jOutLen)
+ jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
+ jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
 {
     CK_SESSION_HANDLE ckSessionHandle;
     CK_RV rv;
 
     CK_BYTE_PTR inBufP;
     CK_BYTE_PTR outBufP;
-    CK_ULONG ckPartLen;
+    CK_ULONG ckOutLen = 0;
 
     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
     if (ckpFunctions == NULL) { return 0; }
 
     ckSessionHandle = jLongToCKULong(jSessionHandle);
 
-    inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
-    if (inBufP == NULL) { return 0; }
-
-    outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
-    if (outBufP == NULL) {
-        // Make sure to release inBufP
-        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-        return 0;
+    if (directIn != 0) {
+      inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
+    } else {
+      inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
+      if (inBufP == NULL) { return 0; }
     }
 
-    ckPartLen = jOutLen;
+    if (directOut != 0) {
+      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
+    } else {
+      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
+      if (outBufP == NULL) {
+          goto cleanup;
+      }
+    }
+    ckOutLen = jOutLen;
 
     rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle,
                                     (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
                                     (CK_BYTE_PTR)(outBufP + jOutOfs),
-                                    &ckPartLen);
-
-    (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-    (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+                                    &ckOutLen);
 
     ckAssertReturnValueOK(env, rv);
 
-    return ckPartLen;
+cleanup:
+    if (directIn == 0 && inBufP != NULL) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+    }
+    if (directOut == 0 && outBufP != NULL) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+    }
+    return ckOutLen;
 }
 #endif
 
@@ -393,7 +401,7 @@
 
     CK_BYTE_PTR inBufP;
     CK_BYTE_PTR outBufP;
-    CK_ULONG ckDecryptedPartLen;
+    CK_ULONG ckDecryptedPartLen = 0;
 
     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
     if (ckpFunctions == NULL) { return 0; }
@@ -412,28 +420,24 @@
     } else {
       outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
       if (outBufP == NULL) {
-          // Make sure to release inBufP
-          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-          return 0;
+          goto cleanup;
       }
     }
 
     ckDecryptedPartLen = jOutLen;
-
     rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle,
                                           (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
                                           (CK_BYTE_PTR)(outBufP + jOutOfs),
                                           &ckDecryptedPartLen);
-    if (directIn == 0) {
+    ckAssertReturnValueOK(env, rv);
+
+cleanup:
+    if (directIn == 0 && inBufP != NULL) {
         (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
     }
-
-    if (directOut == 0) {
+    if (directOut == 0 && outBufP != NULL) {
         (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
     }
-
-    ckAssertReturnValueOK(env, rv);
-
     return ckDecryptedPartLen;
 }