@@ -391,12 +391,12 @@ bool SupportsContextString(const EVPKeyPointer& key) {
391391 return false ;
392392}
393393
394- bool UsePrehashedSignVerify (const EVPKeyPointer& key,
395- const Digest& digest,
396- bool has_context) {
397- // Match streaming sign/verify for digest-based keys: hash locally, then ask
398- // the key implementation to sign or verify the digest. Some providers only
399- // expose token-backed keys through that lower-level operation.
394+ bool CanFallbackToPrehashedSignVerify (const EVPKeyPointer& key,
395+ const Digest& digest,
396+ bool has_context) {
397+ // The primary path is OpenSSL's digest-sign operation. Fall back to hashing
398+ // locally only when that path fails; some providers expose token-backed keys
399+ // through the lower-level prehashed sign/verify operation only .
400400 return digest && !has_context && !key.isOneShotVariant ();
401401}
402402
@@ -901,32 +901,8 @@ bool SignTraits::DeriveBits(Environment* env,
901901 params.flags & SignConfiguration::kHasSaltLength
902902 ? std::optional<int >(params.salt_length )
903903 : std::nullopt ;
904-
905- if (UsePrehashedSignVerify (key, params.digest , has_context)) {
906- switch (params.mode ) {
907- case SignConfiguration::Mode::Sign: {
908- *out = SignPrehashed (env,
909- key,
910- params.digest ,
911- params.data ,
912- padding,
913- salt_length,
914- params.dsa_encoding );
915- return static_cast <bool >(*out);
916- }
917- case SignConfiguration::Mode::Verify: {
918- auto buf = DataPointer::Alloc (1 );
919- static_cast <char *>(buf.get ())[0 ] = VerifyPrehashed (key,
920- params.digest ,
921- params.data ,
922- params.signature ,
923- padding,
924- salt_length);
925- *out = ByteSource::Allocated (buf.release ());
926- return true ;
927- }
928- }
929- }
904+ bool can_fallback_to_prehash =
905+ CanFallbackToPrehashedSignVerify (key, params.digest , has_context);
930906
931907 auto context = EVPMDCtxPointer::New ();
932908 if (!context) [[unlikely]]
@@ -975,6 +951,16 @@ bool SignTraits::DeriveBits(Environment* env,
975951 *out = ByteSource::Allocated (data.release ());
976952 } else {
977953 auto data = context.sign (params.data );
954+ if (!data && can_fallback_to_prehash) {
955+ *out = SignPrehashed (env,
956+ key,
957+ params.digest ,
958+ params.data ,
959+ padding,
960+ salt_length,
961+ params.dsa_encoding );
962+ return static_cast <bool >(*out);
963+ }
978964 if (!data) [[unlikely]] {
979965 return false ;
980966 }
@@ -992,9 +978,18 @@ bool SignTraits::DeriveBits(Environment* env,
992978 case SignConfiguration::Mode::Verify: {
993979 auto buf = DataPointer::Alloc (1 );
994980 static_cast <char *>(buf.get ())[0 ] = 0 ;
995- if (context.verify (params.data , params.signature ) &&
981+ int verify_result = context.verifyOneShot (params.data , params.signature );
982+ if (verify_result == 1 &&
996983 !HasSmallOrderEdDsaPoint (key, params.signature )) {
997984 static_cast <char *>(buf.get ())[0 ] = 1 ;
985+ } else if (verify_result < 0 && can_fallback_to_prehash &&
986+ VerifyPrehashed (key,
987+ params.digest ,
988+ params.data ,
989+ params.signature ,
990+ padding,
991+ salt_length)) {
992+ static_cast <char *>(buf.get ())[0 ] = 1 ;
998993 }
999994 *out = ByteSource::Allocated (buf.release ());
1000995 }
0 commit comments