@@ -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/*
0 commit comments