8229243: SunPKCS11-Solaris provider tests failing on Solaris 11.4
authorvaleriep
Tue, 08 Oct 2019 00:01:20 +0000
changeset 58489 2faeaa5933a6
parent 58488 165b193b30dd
child 58490 5b5de2618756
8229243: SunPKCS11-Solaris provider tests failing on Solaris 11.4 Summary: For CK_GCM_PARAMS, try the spec definition first before falling back to the header file definition Reviewed-by: xuelei
src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java
src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java
src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java
src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c
src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c
src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c
src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h
src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h
src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h
src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h
src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h
test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java	Mon Oct 07 18:44:53 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java	Tue Oct 08 00:01:20 2019 +0000
@@ -378,9 +378,6 @@
 
         long p11KeyID = p11Key.getKeyID();
         try {
-            if (session == null) {
-                session = token.getOpSession();
-            }
             CK_MECHANISM mechWithParams;
             switch (blockMode) {
                 case MODE_GCM:
@@ -390,6 +387,9 @@
                 default:
                     throw new ProviderException("Unsupported mode: " + blockMode);
             }
+            if (session == null) {
+                session = token.getOpSession();
+            }
             if (encrypt) {
                 token.p11.C_EncryptInit(session.id(), mechWithParams,
                     p11KeyID);
@@ -398,7 +398,6 @@
                     p11KeyID);
             }
         } catch (PKCS11Exception e) {
-            //e.printStackTrace();
             p11Key.releaseKeyID();
             session = token.releaseSession(session);
             throw e;
@@ -718,7 +717,9 @@
                    errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
             throw (IllegalBlockSizeException)
                     (new IllegalBlockSizeException(e.toString()).initCause(e));
-        } else if (errorCode == CKR_ENCRYPTED_DATA_INVALID) {
+        } else if (errorCode == CKR_ENCRYPTED_DATA_INVALID ||
+                // Solaris-specific
+                errorCode == CKR_GENERAL_ERROR) {
             throw (BadPaddingException)
                     (new BadPaddingException(e.toString()).initCause(e));
         }
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java	Mon Oct 07 18:44:53 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java	Tue Oct 08 00:01:20 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -103,9 +103,11 @@
             digestLength = 20;
             break;
         case (int)CKM_SHA224:
+        case (int)CKM_SHA512_224:
             digestLength = 28;
             break;
         case (int)CKM_SHA256:
+        case (int)CKM_SHA512_256:
             digestLength = 32;
             break;
         case (int)CKM_SHA384:
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java	Mon Oct 07 18:44:53 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java	Tue Oct 08 00:01:20 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -91,9 +91,11 @@
             macLength = 20;
             break;
         case (int)CKM_SHA224_HMAC:
+        case (int)CKM_SHA512_224_HMAC:
             macLength = 28;
             break;
         case (int)CKM_SHA256_HMAC:
+        case (int)CKM_SHA512_256_HMAC:
             macLength = 32;
             break;
         case (int)CKM_SHA384_HMAC:
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c	Mon Oct 07 18:44:53 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c	Tue Oct 08 00:01:20 2019 +0000
@@ -721,7 +721,7 @@
     }
 
     // populate using java values
-    ckParamPtr->prfMechanism = jLongToCKULong(jPrfMechanism);
+    ckParamPtr->prfHashMechanism = jLongToCKULong(jPrfMechanism);
     ckParamPtr->ulMacLength = jLongToCKULong(jUlMacLength);
     ckParamPtr->ulServerOrClient = jLongToCKULong(jUlServerOrClient);
 
@@ -1014,17 +1014,18 @@
 }
 
 /*
- * converts the Java CK_GCM_PARAMS object to a CK_GCM_PARAMS pointer
+ * converts the Java CK_GCM_PARAMS object to a CK_GCM_PARAMS_NO_IVBITS pointer
+ * Note: Need to try NSS definition first to avoid SIGSEGV.
  *
  * @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 pLength - length of the allocated memory of the returned pointer
- * @return pointer to the new CK_GCM_PARAMS structure
+ * @return pointer to the new CK_GCM_PARAMS_NO_IVBITS structure
  */
-CK_GCM_PARAMS_PTR
+CK_GCM_PARAMS_NO_IVBITS_PTR
 jGCMParamsToCKGCMParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
-    CK_GCM_PARAMS_PTR ckParamPtr;
+    CK_GCM_PARAMS_NO_IVBITS_PTR ckParamPtr;
     jclass jGcmParamsClass;
     jfieldID fieldID;
     jobject jIv, jAad;
@@ -1052,8 +1053,8 @@
     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));
+    // allocate memory for CK_GCM_PARAMS_NO_IVBITS pointer
+    ckParamPtr = calloc(1, sizeof(CK_GCM_PARAMS_NO_IVBITS));
     if (ckParamPtr == NULL) {
         throwOutOfMemoryError(env, 0);
         return NULL;
@@ -1073,16 +1074,15 @@
     ckParamPtr->ulTagBits = jLongToCKULong(jTagLen);
 
     if (pLength != NULL) {
-        *pLength = sizeof(CK_GCM_PARAMS);
+        *pLength = sizeof(CK_GCM_PARAMS_NO_IVBITS);
     }
-    TRACE1("Created inner GCM_PARAMS PTR %lX\n", ptr_to_jlong(ckParamPtr));
+    TRACE1("Created inner GCM_PARAMS PTR w/o ulIvBits %p\n", ckParamPtr);
     return ckParamPtr;
 cleanup:
     free(ckParamPtr->pIv);
     free(ckParamPtr->pAAD);
     free(ckParamPtr);
     return NULL;
-
 }
 
 /*
@@ -1179,7 +1179,7 @@
         throwOutOfMemoryError(env, 0);
         return NULL;
     }
-    TRACE1("DEBUG jMechanismToCKMechanismPtr: allocated mech %p \n", ckpMech);
+    TRACE1("DEBUG jMechanismToCKMechanismPtr: allocated mech %p\n", ckpMech);
 
     ckpMech->mechanism = jLongToCKULong(jMechType);
 
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c	Mon Oct 07 18:44:53 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c	Tue Oct 08 00:01:20 2019 +0000
@@ -72,6 +72,7 @@
 {
     CK_SESSION_HANDLE ckSessionHandle;
     CK_MECHANISM_PTR ckpMechanism = NULL;
+    CK_MECHANISM_PTR ckpTemp;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
@@ -81,15 +82,32 @@
     ckSessionHandle = jLongToCKULong(jSessionHandle);
     ckKeyHandle = jLongToCKULong(jKeyHandle);
     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
+    TRACE1("DEBUG C_EncryptInit: created pMech = %p\n",
+            ckpMechanism);
+
     if ((*env)->ExceptionCheck(env)) { return; }
 
     rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, ckpMechanism,
                                         ckKeyHandle);
 
-    // if OAEP, then cannot free here
+    if (ckpMechanism->mechanism == CKM_AES_GCM) {
+        if (rv == CKR_ARGUMENTS_BAD || rv == CKR_MECHANISM_PARAM_INVALID) {
+            // retry with CKM_GCM_PARAMS structure in pkcs11t.h
+            TRACE0("DEBUG C_EncryptInit: retry with CK_GCM_PARAMS\n");
+            ckpTemp = updateGCMParams(env, ckpMechanism);
+            if (ckpTemp != NULL) { // only re-call if conversion succeeds
+                ckpMechanism = ckpTemp;
+                rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, ckpMechanism,
+                        ckKeyHandle);
+            }
+        }
+    }
+
+    TRACE1("DEBUG C_EncryptInit: freed pMech = %p\n", ckpMechanism);
     freeCKMechanismPtr(ckpMechanism);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+    TRACE0("FINISHED\n");
 }
 #endif
 
@@ -292,6 +310,7 @@
 {
     CK_SESSION_HANDLE ckSessionHandle;
     CK_MECHANISM_PTR ckpMechanism = NULL;
+    CK_MECHANISM_PTR ckpTemp;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
@@ -301,15 +320,32 @@
     ckSessionHandle = jLongToCKULong(jSessionHandle);
     ckKeyHandle = jLongToCKULong(jKeyHandle);
     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
+    TRACE1("DEBUG C_DecryptInit: created pMech = %p\n",
+            ckpMechanism);
+
     if ((*env)->ExceptionCheck(env)) { return; }
 
     rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, ckpMechanism,
                                         ckKeyHandle);
 
-    // if OAEP, then cannot free here
+    if (ckpMechanism->mechanism == CKM_AES_GCM) {
+        if (rv == CKR_ARGUMENTS_BAD || rv == CKR_MECHANISM_PARAM_INVALID) {
+            // retry with CKM_GCM_PARAMS structure in pkcs11t.h
+            TRACE0("DEBUG C_DecryptInit: retry with CK_GCM_PARAMS\n");
+            ckpTemp = updateGCMParams(env, ckpMechanism);
+            if (ckpTemp != NULL) { // only re-call if conversion succeeds
+                ckpMechanism = ckpTemp;
+                rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, ckpMechanism,
+                        ckKeyHandle);
+            }
+        }
+    }
+
+    TRACE1("DEBUG C_DecryptInit: freed pMech = %p\n", ckpMechanism);
     freeCKMechanismPtr(ckpMechanism);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+    TRACE0("FINISHED\n");
 }
 #endif
 
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c	Mon Oct 07 18:44:53 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c	Tue Oct 08 00:01:20 2019 +0000
@@ -302,29 +302,30 @@
      CK_TLS12_KEY_MAT_PARAMS* tlsKmTmp;
 
      if (mechPtr != NULL) {
-         TRACE2("DEBUG: free mech %lX (mech id = 0x%lX)\n",
-                 ptr_to_jlong(mechPtr),  mechPtr->mechanism);
+         TRACE2("DEBUG freeCKMechanismPtr: free pMech %p (mech 0x%lX)\n",
+                 mechPtr,  mechPtr->mechanism);
          if (mechPtr->pParameter != NULL) {
+             tmp = mechPtr->pParameter;
              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);
+                     if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS)) {
+                         TRACE0("[ GCM_PARAMS w/o ulIvBits ]\n");
+                         free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pIv);
+                         free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pAAD);
+                     } else if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS)) {
+                         TRACE0("[ GCM_PARAMS ]\n");
+                         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));
+                     TRACE0("[ CK_CCM_PARAMS ]\n");
                      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));
+                     TRACE0("[ CK_TLS_PRF_PARAMS ]\n");
                      free(((CK_TLS_PRF_PARAMS*)tmp)->pSeed);
                      free(((CK_TLS_PRF_PARAMS*)tmp)->pLabel);
                      free(((CK_TLS_PRF_PARAMS*)tmp)->pulOutputLen);
@@ -334,18 +335,16 @@
                  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));
+                     sslMkdTmp = tmp;
+                     TRACE0("[ CK_SSL3_MASTER_KEY_DERIVE_PARAMS ]\n");
                      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));
+                     sslKmTmp = tmp;
+                     TRACE0("[ CK_SSL3_KEY_MAT_PARAMS ]\n");
                      free(sslKmTmp->RandomInfo.pClientRandom);
                      free(sslKmTmp->RandomInfo.pServerRandom);
                      if (sslKmTmp->pReturnedKeyMaterial != NULL) {
@@ -356,17 +355,15 @@
                      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));
+                     tlsMkdTmp = tmp;
+                     TRACE0("[ CK_TLS12_MASTER_KEY_DERIVE_PARAMS ]\n");
                      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));
+                     tlsKmTmp = tmp;
+                     TRACE0("[ CK_TLS12_KEY_MAT_PARAMS ]\n");
                      free(tlsKmTmp->RandomInfo.pClientRandom);
                      free(tlsKmTmp->RandomInfo.pServerRandom);
                      if (tlsKmTmp->pReturnedKeyMaterial != NULL) {
@@ -377,9 +374,7 @@
                      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));
+                     TRACE0("[ CK_ECDH1_DERIVE_PARAMS ]\n");
                      free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pSharedData);
                      free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pPublicData);
                      break;
@@ -387,7 +382,6 @@
                  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:
@@ -399,17 +393,59 @@
                      // 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");
+                     TRACE0("ERROR: UNSUPPORTED CK_MECHANISM\n");
                      break;
              }
-             free(mechPtr->pParameter);
+             TRACE1("\t=> freed param %p\n", tmp);
+             free(tmp);
          } else {
-             TRACE0("DEBUG => Parameter NULL\n");
+             TRACE0("\t=> param NULL\n");
          }
          free(mechPtr);
+         TRACE0("FINISHED\n");
      }
 }
 
+/* This function replaces the CK_GCM_PARAMS_NO_IVBITS structure associated
+ * with the specified CK_MECHANISM structure with CK_GCM_PARAMS
+ * structure.
+ *
+ * @param mechPtr pointer to the CK_MECHANISM structure containing
+ * the to-be-converted CK_GCM_PARAMS_NO_IVBITS structure.
+ * @return pointer to the CK_MECHANISM structure containing the
+ * converted CK_GCM_PARAMS structure or NULL if no conversion took place.
+ */
+CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr) {
+    CK_GCM_PARAMS* pGcmParams2 = NULL;
+    CK_GCM_PARAMS_NO_IVBITS* pParams = NULL;
+    if ((mechPtr->mechanism == CKM_AES_GCM) &&
+            (mechPtr->pParameter != NULL_PTR) &&
+            (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS))) {
+        pGcmParams2 = calloc(1, sizeof(CK_GCM_PARAMS));
+        if (pGcmParams2 == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return NULL;
+        }
+        pParams = (CK_GCM_PARAMS_NO_IVBITS*) mechPtr->pParameter;
+        pGcmParams2->pIv = pParams->pIv;
+        pGcmParams2->ulIvLen = pParams->ulIvLen;
+        pGcmParams2->ulIvBits = (pGcmParams2->ulIvLen << 3);
+        pGcmParams2->pAAD = pParams->pAAD;
+        pGcmParams2->ulAADLen = pParams->ulAADLen;
+        pGcmParams2->ulTagBits = pParams->ulTagBits;
+        TRACE1("DEBUG updateGCMParams: pMech %p\n", mechPtr);
+        TRACE2("\t=> GCM param w/o ulIvBits %p => GCM param %p\n", pParams,
+                pGcmParams2);
+        free(pParams);
+        mechPtr->pParameter = pGcmParams2;
+        mechPtr->ulParameterLen = sizeof(CK_GCM_PARAMS);
+        return mechPtr;
+    } else {
+        TRACE0("DEBUG updateGCMParams: no conversion done\n");
+    }
+    return NULL;
+}
+
 /*
  * the following functions convert Java arrays to PKCS#11 array pointers and
  * their array length and vice versa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h	Tue Oct 08 00:01:20 2019 +0000
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* There is a known incompatibility for CK_GCM_PARAMS structure.
+ * PKCS#11 v2.40 standard mechanisms specification specifies
+ * CK_GCM_PARAMS as
+ *     typedef struct CK_GCM_PARAMS {
+ *         CK_BYTE_PTR       pIv;
+ *         CK_ULONG          ulIvLen;
+ *         CK_BYTE_PTR       pAAD;
+ *         CK_ULONG          ulAADLen;
+ *         CK_ULONG          ulTagBits;
+ *     } CK_GCM_PARAMS;
+ * However, the official header file of PKCS#11 v2.40 defines the
+ * CK_GCM_PARAMS with an extra "ulIvBits" field (type CK_ULONG).
+ * NSS uses the spec version while Solaris and SoftHSM2 use the header
+ * version. In order to work with both sides, SunPKCS11 provider defines
+ * the spec version of CK_GCM_PARAMS as CK_GCM_PARAMS_NO_IVBITS (as in this
+ * file) and uses it first before failing over to the header version.
+ */
+#ifndef _PKCS11GCM2_H_
+#define _PKCS11GCM2_H_ 1
+
+/* include the platform dependent part of the header */
+typedef struct CK_GCM_PARAMS_NO_IVBITS {
+    CK_BYTE_PTR       pIv;
+    CK_ULONG          ulIvLen;
+    CK_BYTE_PTR       pAAD;
+    CK_ULONG          ulAADLen;
+    CK_ULONG          ulTagBits;
+} CK_GCM_PARAMS_NO_IVBITS;
+
+typedef CK_GCM_PARAMS_NO_IVBITS CK_PTR CK_GCM_PARAMS_NO_IVBITS_PTR;
+
+#endif /* _PKCS11GCM2_H_ */
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h	Mon Oct 07 18:44:53 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h	Tue Oct 08 00:01:20 2019 +0000
@@ -1833,6 +1833,7 @@
 typedef struct CK_GCM_PARAMS {
     CK_BYTE_PTR       pIv;
     CK_ULONG          ulIvLen;
+    CK_ULONG          ulIvBits;
     CK_BYTE_PTR       pAAD;
     CK_ULONG          ulAADLen;
     CK_ULONG          ulTagBits;
@@ -1962,7 +1963,7 @@
 typedef CK_TLS_KDF_PARAMS CK_PTR CK_TLS_KDF_PARAMS_PTR;
 
 typedef struct CK_TLS_MAC_PARAMS {
-    CK_MECHANISM_TYPE         prfMechanism;
+    CK_MECHANISM_TYPE         prfHashMechanism;
     CK_ULONG                  ulMacLength;
     CK_ULONG                  ulServerOrClient;
 } CK_TLS_MAC_PARAMS;
@@ -2000,3 +2001,4 @@
 
 #endif /* _PKCS11T_H_ */
 
+
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h	Mon Oct 07 18:44:53 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h	Tue Oct 08 00:01:20 2019 +0000
@@ -159,7 +159,6 @@
 /* include the platform dependent part of the header */
 #include "p11_md.h"
 
-#include "pkcs11.h"
 #include <jni.h>
 #include <jni_util.h>
 #include <stdarg.h>
@@ -296,6 +295,10 @@
 #define CLASS_TLS_PRF_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS"
 #define CLASS_TLS_MAC_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_MAC_PARAMS"
 
+/* function to update the CK_NSS_GCM_PARAMS in mechanism pointer with
+ * CK_GCM_PARAMS
+ */
+CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr);
 
 /* function to convert a PKCS#11 return value other than CK_OK into a Java Exception
  * or to throw a PKCS11RuntimeException
--- a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h	Mon Oct 07 18:44:53 2019 -0400
+++ b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h	Tue Oct 08 00:01:20 2019 +0000
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ */
+
 /*
  * reserved comment block
  * DO NOT REMOVE OR ALTER!
@@ -69,6 +73,7 @@
 #endif
 
 #include "pkcs11.h"
+#include "pkcs11gcm2.h"
 
 #include "jni.h"
 
--- a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h	Mon Oct 07 18:44:53 2019 -0400
+++ b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h	Tue Oct 08 00:01:20 2019 +0000
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ */
+
 /*
  * reserved comment block
  * DO NOT REMOVE OR ALTER!
@@ -77,6 +81,7 @@
 #endif /* CreateMutex */
 
 #include "pkcs11.h"
+#include "pkcs11gcm2.h"
 
 /* statement according to PKCS11 docu */
 #pragma pack(pop, cryptoki)
--- a/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java	Mon Oct 07 18:44:53 2019 -0400
+++ b/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java	Tue Oct 08 00:01:20 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8080462
+ * @bug 8080462 8229243
  * @library /test/lib ..
  * @modules jdk.crypto.cryptoki
  * @run main TestGCMKeyAndIvCheck
@@ -81,6 +81,7 @@
                     ", no support for " + mode);
             return;
         }
+        System.out.println("Testing against " + p.getName());
         SecretKey key = new SecretKeySpec(new byte[16], "AES");
         // First try parameter-less init.
         c.init(Cipher.ENCRYPT_MODE, key);
@@ -111,12 +112,11 @@
             throw new Exception("Parameters contains incorrect IV value");
         }
 
-        // Should be ok to use the same key+iv for decryption
         c.init(Cipher.DECRYPT_MODE, key, params);
         c.updateAAD(AAD);
         byte[] recovered = c.doFinal(ctPlusTag);
         if (!Arrays.equals(recovered, PT)) {
-            throw new Exception("decryption result mismatch");
+            throw new Exception("Decryption result mismatch");
         }
 
         // Now try to encrypt again using the same key+iv; should fail also
@@ -125,6 +125,7 @@
             throw new Exception("Should throw exception when same key+iv is used");
         } catch (InvalidAlgorithmParameterException iape) {
             // expected
+            System.out.println("Expected IAPE thrown");
         }
 
         // Now try to encrypt again using parameter-less init; should work
@@ -138,7 +139,8 @@
         }
 
         // Now try to encrypt again using a different parameter; should work
-        AlgorithmParameterSpec spec2 = new GCMParameterSpec(128, new byte[30]);
+        AlgorithmParameterSpec spec2 = new GCMParameterSpec(128,
+            "Solaris PKCS11 lib does not allow all-zero IV".getBytes());
         c.init(Cipher.ENCRYPT_MODE, key, spec2);
         c.updateAAD(AAD);
         c.doFinal(PT);
@@ -154,7 +156,7 @@
         c.updateAAD(AAD);
         recovered = c.doFinal(ctPlusTag);
         if (!Arrays.equals(recovered, PT)) {
-            throw new Exception("decryption result mismatch");
+            throw new Exception("Decryption result mismatch");
         }
 
         // Now try decryption again and re-init using the same parameters