diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java index 97a836cf36..7ab89ed1e4 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java @@ -378,9 +378,6 @@ final class P11AEADCipher extends CipherSpi { long p11KeyID = p11Key.getKeyID(); try { - if (session == null) { - session = token.getOpSession(); - } CK_MECHANISM mechWithParams; switch (blockMode) { case MODE_GCM: @@ -390,6 +387,9 @@ final class P11AEADCipher extends CipherSpi { 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 @@ final class P11AEADCipher extends CipherSpi { p11KeyID); } } catch (PKCS11Exception e) { - //e.printStackTrace(); p11Key.releaseKeyID(); session = token.releaseSession(session); throw e; @@ -718,7 +717,9 @@ final class P11AEADCipher extends CipherSpi { 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)); } diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java index 924376d31c..41fe61b8a1 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java @@ -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 @@ final class P11Digest extends MessageDigestSpi implements Cloneable, 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: diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java index 56d0b1c70c..338cb215d5 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java @@ -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 @@ final class P11Mac extends MacSpi { 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: diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c index af1d877875..5990121047 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c @@ -721,7 +721,7 @@ jTlsMacParamsToCKTlsMacParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) } // populate using java values - ckParamPtr->prfMechanism = jLongToCKULong(jPrfMechanism); + ckParamPtr->prfHashMechanism = jLongToCKULong(jPrfMechanism); ckParamPtr->ulMacLength = jLongToCKULong(jUlMacLength); ckParamPtr->ulServerOrClient = jLongToCKULong(jUlServerOrClient); @@ -1014,17 +1014,18 @@ cleanup: } /* - * 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 @@ jGCMParamsToCKGCMParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) 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 @@ jGCMParamsToCKGCMParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) 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 @@ CK_MECHANISM_PTR jMechanismToCKMechanismPtr(JNIEnv *env, jobject jMech) 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); diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c index bc424e7640..1a94d3c4dc 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c @@ -72,6 +72,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptInit { CK_SESSION_HANDLE ckSessionHandle; CK_MECHANISM_PTR ckpMechanism = NULL; + CK_MECHANISM_PTR ckpTemp; CK_OBJECT_HANDLE ckKeyHandle; CK_RV rv; @@ -81,15 +82,32 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptInit 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 - freeCKMechanismPtr(ckpMechanism); + 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; } + + TRACE0("FINISHED\n"); } #endif @@ -292,6 +310,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptInit { CK_SESSION_HANDLE ckSessionHandle; CK_MECHANISM_PTR ckpMechanism = NULL; + CK_MECHANISM_PTR ckpTemp; CK_OBJECT_HANDLE ckKeyHandle; CK_RV rv; @@ -301,15 +320,32 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptInit 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 - freeCKMechanismPtr(ckpMechanism); + 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; } + + TRACE0("FINISHED\n"); } #endif diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c index 81329b879b..cba1bf309b 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c @@ -302,29 +302,30 @@ void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) { 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 @@ void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) { 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 @@ void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) { 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 @@ void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) { 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 @@ void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) { 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 @@ void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) { // 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 diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h new file mode 100644 index 0000000000..447a95973d --- /dev/null +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h @@ -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_ */ diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h index c3c6b96f28..d0531cc1c7 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h @@ -1833,6 +1833,7 @@ typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR; 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 struct CK_TLS_KDF_PARAMS { 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 @@ typedef CK_SEED_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ #endif /* _PKCS11T_H_ */ + diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h index 273f734fc9..8dd964b866 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h @@ -159,7 +159,6 @@ /* include the platform dependent part of the header */ #include "p11_md.h" -#include "pkcs11.h" #include #include #include @@ -296,6 +295,10 @@ void printDebug(const char *format, ...); #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 diff --git a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h index 49379f18db..0d8cb36337 100644 --- a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h +++ b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h @@ -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" diff --git a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h index 6f296e9079..7cff0c7c24 100644 --- a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h +++ b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h @@ -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) diff --git a/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java b/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java index f14e3facc1..2e3a83d46f 100644 --- a/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java +++ b/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java @@ -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 @@ public class TestGCMKeyAndIvCheck extends PKCS11Test { ", 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 @@ public class TestGCMKeyAndIvCheck extends PKCS11Test { 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 @@ public class TestGCMKeyAndIvCheck extends PKCS11Test { 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 @@ public class TestGCMKeyAndIvCheck extends PKCS11Test { } // 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 @@ public class TestGCMKeyAndIvCheck extends PKCS11Test { 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