@@ -704,6 +704,7 @@ bool SignTraits::DeriveBits(Environment* env,
704704 bool has_context = (params.flags & SignConfiguration::kHasContextString &&
705705 params.context_string .size () > 0 );
706706 bool is_prehashed = params.flags & SignConfiguration::kHasPrehashed ;
707+ bool is_sign = params.mode == SignConfiguration::Mode::Sign;
707708
708709 if (has_context && !is_prehashed && !SupportsContextString (key)) {
709710 if (can_throw) crypto::CheckThrow (env, SignBase::Error::ContextUnsupported);
@@ -713,30 +714,7 @@ bool SignTraits::DeriveBits(Environment* env,
713714 // Prehashed signing: the caller already hashed the data and is providing
714715 // the digest directly. Use the low-level EVP_PKEY_sign/EVP_PKEY_verify path.
715716 if (is_prehashed) {
716- bool is_eddsa = key.id () == EVP_PKEY_ED25519 || key.id () == EVP_PKEY_ED448;
717- #if OPENSSL_WITH_PQC
718- bool is_mldsa = key.id () == EVP_PKEY_ML_DSA_44 ||
719- key.id () == EVP_PKEY_ML_DSA_65 ||
720- key.id () == EVP_PKEY_ML_DSA_87;
721- #else
722- bool is_mldsa = false ;
723- #endif
724-
725- // One-shot-only algorithms that don't have prehash variants
726- // (SLH-DSA) are not supported.
727- if (key.isOneShotVariant () && !is_eddsa && !is_mldsa) {
728- if (can_throw)
729- crypto::CheckThrow (env, SignBase::Error::PrehashUnsupported);
730- return false ;
731- }
732-
733- // For ML-DSA, context must already be part of the externally computed
734- // mu value. Passing a context string separately is not supported.
735- if (has_context && is_mldsa) {
736- if (can_throw)
737- crypto::CheckThrow (env, SignBase::Error::ContextUnsupported);
738- return false ;
739- }
717+ const int key_type = key.id ();
740718
741719 EVPKeyCtxPointer pkctx = key.newCtx ();
742720 if (!pkctx) [[unlikely]] {
@@ -746,101 +724,105 @@ bool SignTraits::DeriveBits(Environment* env,
746724
747725 int init_ret;
748726
749- if (is_eddsa) {
727+ switch (key_type) {
728+ case EVP_PKEY_ED25519:
729+ case EVP_PKEY_ED448: {
750730#ifdef OSSL_SIGNATURE_PARAM_INSTANCE
751- // For Ed25519ph/Ed448ph, use EVP_PKEY_sign_init_ex with INSTANCE param.
752- const char * instance_name =
753- key.id () == EVP_PKEY_ED25519 ? " Ed25519ph" : " Ed448ph" ;
754-
755- // Build OSSL_PARAM array with instance and optional context string.
756- std::vector<OSSL_PARAM> ossl_params;
757- ossl_params.push_back (OSSL_PARAM_construct_utf8_string (
758- OSSL_SIGNATURE_PARAM_INSTANCE, const_cast <char *>(instance_name), 0 ));
759-
760- if (has_context) {
761- ossl_params.push_back (OSSL_PARAM_construct_octet_string (
762- OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
763- const_cast <unsigned char *>(
764- params.context_string .data <unsigned char >()),
765- params.context_string .size ()));
766- }
767- ossl_params.push_back (OSSL_PARAM_END);
768-
769- switch (params.mode ) {
770- case SignConfiguration::Mode::Sign:
771- init_ret = pkctx.initForSignEx (ossl_params.data ());
772- break ;
773- case SignConfiguration::Mode::Verify:
774- init_ret = pkctx.initForVerifyEx (ossl_params.data ());
775- break ;
776- }
731+ const char * instance_name =
732+ key_type == EVP_PKEY_ED25519 ? " Ed25519ph" : " Ed448ph" ;
733+
734+ std::vector<OSSL_PARAM> ossl_params;
735+ ossl_params.push_back (
736+ OSSL_PARAM_construct_utf8_string (OSSL_SIGNATURE_PARAM_INSTANCE,
737+ const_cast <char *>(instance_name),
738+ 0 ));
739+
740+ if (has_context) {
741+ ossl_params.push_back (OSSL_PARAM_construct_octet_string (
742+ OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
743+ const_cast <unsigned char *>(
744+ params.context_string .data <unsigned char >()),
745+ params.context_string .size ()));
746+ }
747+ ossl_params.push_back (OSSL_PARAM_END);
748+
749+ init_ret = is_sign ? pkctx.initForSignEx (ossl_params.data ())
750+ : pkctx.initForVerifyEx (ossl_params.data ());
751+ break ;
777752#else
778- if (can_throw)
779- crypto::CheckThrow (env, SignBase::Error::PrehashUnsupported);
780- return false ;
753+ if (can_throw)
754+ crypto::CheckThrow (env, SignBase::Error::PrehashUnsupported);
755+ return false ;
781756#endif // OSSL_SIGNATURE_PARAM_INSTANCE
782- } else if (is_mldsa) {
783- #ifdef OSSL_SIGNATURE_PARAM_MU
784- // For ML-DSA, use EVP_PKEY_sign_message_init with mu param.
785- // The caller provides the 64-byte mu value directly.
786- // Context string is not passed here — it's already incorporated
787- // into mu by the caller.
788- int mu_flag = 1 ;
789- std::vector<OSSL_PARAM> ossl_params;
790- ossl_params.push_back (
791- OSSL_PARAM_construct_int (OSSL_SIGNATURE_PARAM_MU, &mu_flag));
792- ossl_params.push_back (OSSL_PARAM_END);
793-
794- switch (params.mode ) {
795- case SignConfiguration::Mode::Sign:
796- init_ret = pkctx.initForSignMessage (ossl_params.data ());
797- break ;
798- case SignConfiguration::Mode::Verify:
799- init_ret = pkctx.initForVerifyMessage (ossl_params.data ());
800- break ;
801- }
802- #else
803- if (can_throw)
804- crypto::CheckThrow (env, SignBase::Error::PrehashUnsupported);
805- return false ;
806- #endif // OSSL_SIGNATURE_PARAM_MU
807- } else {
808- // RSA, ECDSA, DSA: use standard EVP_PKEY_sign_init path.
809- switch (params.mode ) {
810- case SignConfiguration::Mode::Sign:
811- init_ret = pkctx.initForSign ();
812- break ;
813- case SignConfiguration::Mode::Verify:
814- init_ret = pkctx.initForVerify ();
815- break ;
816757 }
817758
818- if (init_ret <= 0 ) [[unlikely]] {
819- if (can_throw) crypto::CheckThrow (env, SignBase::Error::Init);
759+ #if OPENSSL_WITH_PQC
760+ case EVP_PKEY_ML_DSA_44:
761+ case EVP_PKEY_ML_DSA_65:
762+ case EVP_PKEY_ML_DSA_87: {
763+ // Context must already be part of the externally computed mu value.
764+ if (has_context) {
765+ if (can_throw)
766+ crypto::CheckThrow (env, SignBase::Error::ContextUnsupported);
767+ return false ;
768+ }
769+
770+ #ifdef OSSL_SIGNATURE_PARAM_MU
771+ int mu_flag = 1 ;
772+ std::vector<OSSL_PARAM> ossl_params;
773+ ossl_params.push_back (
774+ OSSL_PARAM_construct_int (OSSL_SIGNATURE_PARAM_MU, &mu_flag));
775+ ossl_params.push_back (OSSL_PARAM_END);
776+
777+ init_ret = is_sign ? pkctx.initForSignMessage (ossl_params.data ())
778+ : pkctx.initForVerifyMessage (ossl_params.data ());
779+ break ;
780+ #else
781+ if (can_throw)
782+ crypto::CheckThrow (env, SignBase::Error::PrehashUnsupported);
820783 return false ;
784+ #endif // OSSL_SIGNATURE_PARAM_MU
821785 }
786+ #endif // OPENSSL_WITH_PQC
822787
823- int padding = params.flags & SignConfiguration::kHasPadding
824- ? params.padding
825- : key.getDefaultSignPadding ();
788+ default :
789+ if (key.isOneShotVariant ()) {
790+ if (can_throw)
791+ crypto::CheckThrow (env, SignBase::Error::PrehashUnsupported);
792+ return false ;
793+ }
826794
827- std::optional<int > salt_length =
828- params.flags & SignConfiguration::kHasSaltLength
829- ? std::optional<int >(params.salt_length )
830- : std::nullopt ;
795+ init_ret = is_sign ? pkctx.initForSign () : pkctx.initForVerify ();
831796
832- if (! ApplyRSAOptions (key, pkctx. get (), padding, salt_length)) {
833- if (can_throw) crypto::CheckThrow (env, SignBase::Error::PrivateKey );
834- return false ;
835- }
797+ if (init_ret <= 0 ) [[unlikely]] {
798+ if (can_throw) crypto::CheckThrow (env, SignBase::Error::Init );
799+ return false ;
800+ }
836801
837- if (!pkctx.setSignatureMd (params.digest )) {
838- if (can_throw) crypto::CheckThrow (env, SignBase::Error::Init);
839- return false ;
840- }
802+ {
803+ int padding = params.flags & SignConfiguration::kHasPadding
804+ ? params.padding
805+ : key.getDefaultSignPadding ();
806+
807+ std::optional<int > salt_length =
808+ params.flags & SignConfiguration::kHasSaltLength
809+ ? std::optional<int >(params.salt_length )
810+ : std::nullopt ;
811+
812+ if (!ApplyRSAOptions (key, pkctx.get (), padding, salt_length)) {
813+ if (can_throw) crypto::CheckThrow (env, SignBase::Error::PrivateKey);
814+ return false ;
815+ }
816+
817+ if (!pkctx.setSignatureMd (params.digest )) {
818+ if (can_throw) crypto::CheckThrow (env, SignBase::Error::Init);
819+ return false ;
820+ }
821+ }
822+ break ;
841823 }
842824
843- if (is_eddsa && init_ret <= 0 ) [[unlikely]] {
825+ if (init_ret <= 0 ) [[unlikely]] {
844826 if (can_throw) crypto::CheckThrow (env, SignBase::Error::Init);
845827 return false ;
846828 }
@@ -850,36 +832,31 @@ bool SignTraits::DeriveBits(Environment* env,
850832 .len = params.data .size (),
851833 };
852834
853- switch (params.mode ) {
854- case SignConfiguration::Mode::Sign: {
855- auto sig = pkctx.sign (data_buf);
856- if (!sig) [[unlikely]] {
857- if (can_throw) crypto::CheckThrow (env, SignBase::Error::PrivateKey);
858- return false ;
859- }
860- DCHECK (!sig.isSecure ());
861- auto bs = ByteSource::Allocated (sig.release ());
835+ if (is_sign) {
836+ auto sig = pkctx.sign (data_buf);
837+ if (!sig) [[unlikely]] {
838+ if (can_throw) crypto::CheckThrow (env, SignBase::Error::PrivateKey);
839+ return false ;
840+ }
841+ DCHECK (!sig.isSecure ());
842+ auto bs = ByteSource::Allocated (sig.release ());
862843
863- if (UseP1363Encoding (key, params.dsa_encoding )) {
864- *out = ConvertSignatureToP1363 (env, key, std::move (bs));
865- } else {
866- *out = std::move (bs);
867- }
868- break ;
844+ if (UseP1363Encoding (key, params.dsa_encoding )) {
845+ *out = ConvertSignatureToP1363 (env, key, std::move (bs));
846+ } else {
847+ *out = std::move (bs);
869848 }
870- case SignConfiguration::Mode::Verify: {
871- ncrypto::Buffer<const unsigned char > sig_buf{
872- .data = params.signature .data <unsigned char >(),
873- .len = params.signature .size (),
874- };
875- auto buf = DataPointer::Alloc (1 );
876- static_cast <char *>(buf.get ())[0 ] = 0 ;
877- if (pkctx.verify (sig_buf, data_buf)) {
878- static_cast <char *>(buf.get ())[0 ] = 1 ;
879- }
880- *out = ByteSource::Allocated (buf.release ());
881- break ;
849+ } else {
850+ ncrypto::Buffer<const unsigned char > sig_buf{
851+ .data = params.signature .data <unsigned char >(),
852+ .len = params.signature .size (),
853+ };
854+ auto buf = DataPointer::Alloc (1 );
855+ static_cast <char *>(buf.get ())[0 ] = 0 ;
856+ if (pkctx.verify (sig_buf, data_buf)) {
857+ static_cast <char *>(buf.get ())[0 ] = 1 ;
882858 }
859+ *out = ByteSource::Allocated (buf.release ());
883860 }
884861
885862 return true ;
@@ -897,21 +874,13 @@ bool SignTraits::DeriveBits(Environment* env,
897874 .len = params.context_string .size (),
898875 };
899876
900- switch (params.mode ) {
901- case SignConfiguration::Mode::Sign:
902- return context.signInitWithContext (key, params.digest , context_buf);
903- case SignConfiguration::Mode::Verify:
904- return context.verifyInitWithContext (key, params.digest , context_buf);
905- }
906- } else {
907- switch (params.mode ) {
908- case SignConfiguration::Mode::Sign:
909- return context.signInit (key, params.digest );
910- case SignConfiguration::Mode::Verify:
911- return context.verifyInit (key, params.digest );
912- }
877+ return is_sign
878+ ? context.signInitWithContext (key, params.digest , context_buf)
879+ : context.verifyInitWithContext (
880+ key, params.digest , context_buf);
913881 }
914- UNREACHABLE ();
882+ return is_sign ? context.signInit (key, params.digest )
883+ : context.verifyInit (key, params.digest );
915884 })();
916885
917886 if (!ctx.has_value ()) [[unlikely]] {
@@ -933,41 +902,37 @@ bool SignTraits::DeriveBits(Environment* env,
933902 return false ;
934903 }
935904
936- switch (params.mode ) {
937- case SignConfiguration::Mode::Sign: {
938- if (key.isOneShotVariant ()) {
939- auto data = context.signOneShot (params.data );
940- if (!data) [[unlikely]] {
941- if (can_throw) crypto::CheckThrow (env, SignBase::Error::PrivateKey);
942- return false ;
943- }
944- DCHECK (!data.isSecure ());
945- *out = ByteSource::Allocated (data.release ());
946- } else {
947- auto data = context.sign (params.data );
948- if (!data) [[unlikely]] {
949- if (can_throw) crypto::CheckThrow (env, SignBase::Error::PrivateKey);
950- return false ;
951- }
952- DCHECK (!data.isSecure ());
953- auto bs = ByteSource::Allocated (data.release ());
905+ if (is_sign) {
906+ if (key.isOneShotVariant ()) {
907+ auto data = context.signOneShot (params.data );
908+ if (!data) [[unlikely]] {
909+ if (can_throw) crypto::CheckThrow (env, SignBase::Error::PrivateKey);
910+ return false ;
911+ }
912+ DCHECK (!data.isSecure ());
913+ *out = ByteSource::Allocated (data.release ());
914+ } else {
915+ auto data = context.sign (params.data );
916+ if (!data) [[unlikely]] {
917+ if (can_throw) crypto::CheckThrow (env, SignBase::Error::PrivateKey);
918+ return false ;
919+ }
920+ DCHECK (!data.isSecure ());
921+ auto bs = ByteSource::Allocated (data.release ());
954922
955- if (UseP1363Encoding (key, params.dsa_encoding )) {
956- *out = ConvertSignatureToP1363 (env, key, std::move (bs));
957- } else {
958- *out = std::move (bs);
959- }
923+ if (UseP1363Encoding (key, params.dsa_encoding )) {
924+ *out = ConvertSignatureToP1363 (env, key, std::move (bs));
925+ } else {
926+ *out = std::move (bs);
960927 }
961- break ;
962928 }
963- case SignConfiguration::Mode::Verify: {
964- auto buf = DataPointer::Alloc (1 );
965- static_cast <char *>(buf.get ())[0 ] = 0 ;
966- if (context.verify (params.data , params.signature )) {
967- static_cast <char *>(buf.get ())[0 ] = 1 ;
968- }
969- *out = ByteSource::Allocated (buf.release ());
929+ } else {
930+ auto buf = DataPointer::Alloc (1 );
931+ static_cast <char *>(buf.get ())[0 ] = 0 ;
932+ if (context.verify (params.data , params.signature )) {
933+ static_cast <char *>(buf.get ())[0 ] = 1 ;
970934 }
935+ *out = ByteSource::Allocated (buf.release ());
971936 }
972937
973938 return true ;
0 commit comments