@@ -298,6 +298,7 @@ OSSL_PKCS12_key_gen_t* OSSL_PKCS12_key_gen;
298298typedef struct OpenSSLMDContext {
299299 EVP_MD_CTX * ctx ;
300300 const EVP_MD * digestAlg ;
301+ EVP_MD_CTX * cachedInitializedDigestContext ;
301302} OpenSSLMDContext ;
302303
303304/* Handle errors from OpenSSL calls. */
@@ -901,22 +902,38 @@ JNIEXPORT jlong JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_DigestCreateCon
901902 context -> ctx = ctx ;
902903 context -> digestAlg = digestAlg ;
903904
905+ /*
906+ * Create a second initialized openssl digest context. This is being done for performance reasons since
907+ * creating and or re-initializing digest contexts later during processing is found to be expensive.
908+ * This second context, context->cachedInitializedDigestContext, will be copied over the working context,
909+ * context->ctx, using the EVP_MD_CTX_copy_ex API whenever we wish to re-initalize this cipher. This occurs
910+ * during an explicit reset of the cipher or whenever a final digest is computed.
911+ */
912+ context -> cachedInitializedDigestContext = (* OSSL_MD_CTX_new )();
913+ if (NULL == context -> cachedInitializedDigestContext ) {
914+ goto releaseContexts ;
915+ }
916+
917+ if (1 != (* OSSL_MD_CTX_copy_ex )(context -> cachedInitializedDigestContext , context -> ctx )) {
918+ goto releaseContexts ;
919+ }
920+
904921 if (0 != copyContext ) {
905922 EVP_MD_CTX * contextToCopy = ((OpenSSLMDContext * )(intptr_t )copyContext )-> ctx ;
906923 if (NULL == contextToCopy ) {
907- (* OSSL_MD_CTX_free )(ctx );
908- free (context );
909- return -1 ;
924+ goto releaseContexts ;
910925 }
911926 if (0 == (* OSSL_MD_CTX_copy_ex )(ctx , contextToCopy )) {
912- printErrors ();
913- (* OSSL_MD_CTX_free )(ctx );
914- free (context );
915- return -1 ;
927+ goto releaseContexts ;
916928 }
917929 }
918930
919931 return (jlong )(intptr_t )context ;
932+
933+ releaseContexts :
934+ printErrors ();
935+ Java_jdk_crypto_jniprovider_NativeCrypto_DigestDestroyContext (env , thisObj , (jlong )(intptr_t )context );
936+ return -1 ;
920937}
921938
922939/*
@@ -928,11 +945,20 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_DigestDestroyCon
928945 (JNIEnv * env , jclass thisObj , jlong c )
929946{
930947 OpenSSLMDContext * context = (OpenSSLMDContext * )(intptr_t ) c ;
931- if (( NULL == context ) || ( NULL == context -> ctx ) ) {
948+ if (NULL == context ) {
932949 return -1 ;
933950 }
934951
935- (* OSSL_MD_CTX_free )(context -> ctx );
952+ if (NULL != context -> ctx ) {
953+ (* OSSL_MD_CTX_free )(context -> ctx );
954+ context -> ctx = NULL ;
955+ }
956+
957+ if (NULL != context -> cachedInitializedDigestContext ) {
958+ (* OSSL_MD_CTX_free )(context -> cachedInitializedDigestContext );
959+ context -> cachedInitializedDigestContext = NULL ;
960+ }
961+
936962 free (context );
937963 return 0 ;
938964}
@@ -989,7 +1015,7 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_DigestComputeAnd
9891015 unsigned char * messageNative = NULL ;
9901016 unsigned char * digestNative = NULL ;
9911017
992- if ((NULL == context ) || (NULL == context -> ctx )) {
1018+ if ((NULL == context ) || (NULL == context -> ctx ) || ( NULL == context -> cachedInitializedDigestContext ) ) {
9931019 return -1 ;
9941020 }
9951021
@@ -1021,10 +1047,23 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_DigestComputeAnd
10211047
10221048 (* env )-> ReleasePrimitiveArrayCritical (env , digest , digestNative , 0 );
10231049
1024- (* OSSL_MD_CTX_reset )(context -> ctx );
1025-
1026- if (1 != (* OSSL_DigestInit_ex )(context -> ctx , context -> digestAlg , NULL )) {
1050+ /*
1051+ * Reset the message digest context to the original context. We are then ready to perform
1052+ * digest operations again using a copy of this cached context.
1053+ */
1054+ if (1 != (* OSSL_MD_CTX_copy_ex )(context -> ctx , context -> cachedInitializedDigestContext )) {
10271055 printErrors ();
1056+
1057+ if (NULL != context -> ctx ) {
1058+ (* OSSL_MD_CTX_free )(context -> ctx );
1059+ context -> ctx = NULL ;
1060+ }
1061+
1062+ if (NULL != context -> cachedInitializedDigestContext ) {
1063+ (* OSSL_MD_CTX_free )(context -> cachedInitializedDigestContext );
1064+ context -> cachedInitializedDigestContext = NULL ;
1065+ }
1066+
10281067 return -1 ;
10291068 }
10301069
@@ -1035,22 +1074,38 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_DigestComputeAnd
10351074 *
10361075 * Class: jdk_crypto_jniprovider_NativeCrypto
10371076 * Method: DigestReset
1038- * Signature: (J)V
1077+ * Signature: (J)I
10391078 */
1040- JNIEXPORT void JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_DigestReset
1079+ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_DigestReset
10411080 (JNIEnv * env , jclass thisObj , jlong c )
10421081{
10431082 OpenSSLMDContext * context = (OpenSSLMDContext * )(intptr_t ) c ;
10441083
1045- if ((NULL == context ) || (NULL == context -> ctx )) {
1046- return ;
1084+ if ((NULL == context ) || (NULL == context -> ctx ) || ( NULL == context -> cachedInitializedDigestContext ) ) {
1085+ return -1 ;
10471086 }
10481087
1049- (* OSSL_MD_CTX_reset )(context -> ctx );
1050-
1051- if (1 != (* OSSL_DigestInit_ex )(context -> ctx , context -> digestAlg , NULL )) {
1088+ /*
1089+ * Reset the message digest context to the original context. We are then ready to perform
1090+ * digest operations again using a copy of this cached context.
1091+ */
1092+ if (1 != (* OSSL_MD_CTX_copy_ex )(context -> ctx , context -> cachedInitializedDigestContext )) {
10521093 printErrors ();
1094+
1095+ if (NULL != context -> ctx ) {
1096+ (* OSSL_MD_CTX_free )(context -> ctx );
1097+ context -> ctx = NULL ;
1098+ }
1099+
1100+ if (NULL != context -> cachedInitializedDigestContext ) {
1101+ (* OSSL_MD_CTX_free )(context -> cachedInitializedDigestContext );
1102+ context -> cachedInitializedDigestContext = NULL ;
1103+ }
1104+
1105+ return -1 ;
10531106 }
1107+
1108+ return 0 ;
10541109}
10551110
10561111/*
@@ -1097,7 +1152,7 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_DestroyContext
10971152 */
10981153JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_CBCInit
10991154 (JNIEnv * env , jclass thisObj , jlong c , jint mode , jbyteArray iv , jint iv_len ,
1100- jbyteArray key , jint key_len )
1155+ jbyteArray key , jint key_len , jboolean doReset )
11011156{
11021157 EVP_CIPHER_CTX * ctx = (EVP_CIPHER_CTX * )(intptr_t ) c ;
11031158 unsigned char * ivNative = NULL ;
@@ -1108,18 +1163,20 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_CBCInit
11081163 return -1 ;
11091164 }
11101165
1111- switch (key_len ) {
1112- case 16 :
1113- evp_cipher1 = (* OSSL_aes_128_cbc )();
1114- break ;
1115- case 24 :
1116- evp_cipher1 = (* OSSL_aes_192_cbc )();
1117- break ;
1118- case 32 :
1119- evp_cipher1 = (* OSSL_aes_256_cbc )();
1120- break ;
1121- default :
1122- break ;
1166+ if (JNI_FALSE == doReset ) {
1167+ switch (key_len ) {
1168+ case 16 :
1169+ evp_cipher1 = (* OSSL_aes_128_cbc )();
1170+ break ;
1171+ case 24 :
1172+ evp_cipher1 = (* OSSL_aes_192_cbc )();
1173+ break ;
1174+ case 32 :
1175+ evp_cipher1 = (* OSSL_aes_256_cbc )();
1176+ break ;
1177+ default :
1178+ break ;
1179+ }
11231180 }
11241181
11251182 ivNative = (unsigned char * )((* env )-> GetByteArrayElements (env , iv , 0 ));
@@ -1140,7 +1197,9 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_CBCInit
11401197 return -1 ;
11411198 }
11421199
1143- (* OSSL_CIPHER_CTX_set_padding )(ctx , 0 );
1200+ if (JNI_FALSE == doReset ) {
1201+ (* OSSL_CIPHER_CTX_set_padding )(ctx , 0 );
1202+ }
11441203
11451204 (* env )-> ReleaseByteArrayElements (env , iv , (jbyte * )ivNative , JNI_ABORT );
11461205 (* env )-> ReleaseByteArrayElements (env , key , (jbyte * )keyNative , JNI_ABORT );
0 commit comments