@@ -36,6 +36,10 @@ int gost_get_max_signature_size(const GOST_KEY_DATA *key_data)
3636 */
3737static OSSL_FUNC_signature_newctx_fn signature_newctx ;
3838static OSSL_FUNC_signature_freectx_fn signature_free ;
39+ static OSSL_FUNC_signature_sign_init_fn signature_sign_init ;
40+ static OSSL_FUNC_signature_sign_fn signature_sign ;
41+ static OSSL_FUNC_signature_verify_init_fn signature_verify_init ;
42+ static OSSL_FUNC_signature_verify_fn signature_verify ;
3943static OSSL_FUNC_signature_digest_sign_init_fn signature_digest_sign_init ;
4044static OSSL_FUNC_signature_digest_sign_update_fn signature_digest_sign_update ;
4145static OSSL_FUNC_signature_digest_sign_final_fn signature_digest_sign_final ;
@@ -44,6 +48,8 @@ static OSSL_FUNC_signature_digest_verify_update_fn signature_digest_verify_updat
4448static OSSL_FUNC_signature_digest_verify_final_fn signature_digest_verify_final ;
4549static OSSL_FUNC_signature_get_ctx_params_fn signature_get_ctx_params ;
4650static OSSL_FUNC_signature_gettable_ctx_params_fn signature_gettable_ctx_params ;
51+ static OSSL_FUNC_signature_set_ctx_params_fn signature_set_ctx_params ;
52+ static OSSL_FUNC_signature_settable_ctx_params_fn signature_settable_ctx_params ;
4753
4854typedef struct {
4955 PROV_CTX * provctx ;
@@ -384,12 +390,128 @@ static int signature_digest_verify_final(void *vctx, const unsigned char *sig,
384390 return internal_pkey_ec_cp_verify (ctx -> key_data -> ec , sig , siglen , digest , dlen );
385391}
386392
393+ /*
394+ * Raw sign/verify (pre-hashed TBS).
395+ *
396+ * Used by OpenSSL when applications hash first and then call EVP_PKEY_sign /
397+ * EVP_PKEY_verify with EVP_PKEY_CTX_set_signature_md() — e.g. Node.js
398+ * createSign()/SignFinal (Node_SignFinal). Without these entry points the
399+ * provider only exposes DIGEST_SIGN/DIGEST_VERIFY and OpenSSL returns
400+ * EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED.
401+ */
402+ static int signature_sign_init (void * vctx , void * provkey ,
403+ const OSSL_PARAM params [])
404+ {
405+ return signature_signverify_init (vctx , provkey , params , SIGN_OPERATION );
406+ }
407+
408+ static int signature_verify_init (void * vctx , void * provkey ,
409+ const OSSL_PARAM params [])
410+ {
411+ return signature_signverify_init (vctx , provkey , params , VERIFY_OPERATION );
412+ }
413+
414+ static int signature_check_tbs_len (GOST_SIGNATURE_CTX * ctx , size_t tbslen )
415+ {
416+ if (ctx -> md != NULL ) {
417+ int mdlen = EVP_MD_get_size (ctx -> md );
418+
419+ if (mdlen <= 0 || tbslen != (size_t )mdlen )
420+ return 0 ;
421+ return 1 ;
422+ }
423+
424+ /*
425+ * If the digest was not set on the context, accept the usual GOST digest
426+ * lengths so callers that only supply the raw hash still work.
427+ */
428+ switch (ctx -> key_data -> type ) {
429+ case NID_id_GostR3410_2001 :
430+ case NID_id_GostR3410_2001DH :
431+ case NID_id_GostR3410_2012_256 :
432+ return tbslen == 32 ;
433+ case NID_id_GostR3410_2012_512 :
434+ return tbslen == 64 ;
435+ default :
436+ return 0 ;
437+ }
438+ }
439+
440+ static int signature_sign (void * vctx , unsigned char * sig , size_t * siglen ,
441+ size_t sigsize , const unsigned char * tbs ,
442+ size_t tbslen )
443+ {
444+ GOST_SIGNATURE_CTX * ctx = vctx ;
445+
446+ if (ctx == NULL
447+ || ctx -> operation != SIGN_OPERATION
448+ || ctx -> key_data == NULL
449+ || ctx -> key_data -> ec == NULL
450+ || siglen == NULL
451+ || tbs == NULL )
452+ return 0 ;
453+
454+ if (!signature_check_tbs_len (ctx , tbslen ))
455+ return 0 ;
456+
457+ /* Size query */
458+ if (sig == NULL ) {
459+ int max_size = gost_get_max_signature_size (ctx -> key_data );
460+
461+ if (max_size <= 0 )
462+ return 0 ;
463+ * siglen = (size_t )max_size ;
464+ return 1 ;
465+ }
466+
467+ * siglen = sigsize ;
468+ return internal_pkey_ec_cp_sign (ctx -> key_data -> ec , ctx -> key_data -> type , sig ,
469+ siglen , tbs , tbslen );
470+ }
471+
472+ static int signature_verify (void * vctx , const unsigned char * sig , size_t siglen ,
473+ const unsigned char * tbs , size_t tbslen )
474+ {
475+ GOST_SIGNATURE_CTX * ctx = vctx ;
476+
477+ if (ctx == NULL
478+ || ctx -> operation != VERIFY_OPERATION
479+ || ctx -> key_data == NULL
480+ || ctx -> key_data -> ec == NULL
481+ || sig == NULL
482+ || tbs == NULL )
483+ return 0 ;
484+
485+ if (!signature_check_tbs_len (ctx , tbslen ))
486+ return 0 ;
487+
488+ return internal_pkey_ec_cp_verify (ctx -> key_data -> ec , sig , siglen , tbs ,
489+ tbslen );
490+ }
491+
492+ static const OSSL_PARAM signature_settable_params [] = {
493+ OSSL_PARAM_utf8_string (OSSL_SIGNATURE_PARAM_DIGEST , NULL , 0 ),
494+ OSSL_PARAM_utf8_string (OSSL_SIGNATURE_PARAM_PROPERTIES , NULL , 0 ),
495+ OSSL_PARAM_END
496+ };
497+
498+ static const OSSL_PARAM * signature_settable_ctx_params (void * vctx , void * provctx )
499+ {
500+ return signature_settable_params ;
501+ }
502+
387503typedef void (* fptr_t )(void );
388504static const OSSL_DISPATCH id_signature_functions [] = {
389505 { OSSL_FUNC_SIGNATURE_NEWCTX , (fptr_t )signature_newctx },
390506 { OSSL_FUNC_SIGNATURE_FREECTX , (fptr_t )signature_free },
507+ { OSSL_FUNC_SIGNATURE_SIGN_INIT , (fptr_t )signature_sign_init },
508+ { OSSL_FUNC_SIGNATURE_SIGN , (fptr_t )signature_sign },
509+ { OSSL_FUNC_SIGNATURE_VERIFY_INIT , (fptr_t )signature_verify_init },
510+ { OSSL_FUNC_SIGNATURE_VERIFY , (fptr_t )signature_verify },
391511 { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS , (fptr_t )signature_get_ctx_params },
392512 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS , (fptr_t )signature_gettable_ctx_params },
513+ { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS , (fptr_t )signature_set_ctx_params },
514+ { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS , (fptr_t )signature_settable_ctx_params },
393515 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT , (fptr_t )signature_digest_sign_init },
394516 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE , (fptr_t )signature_digest_sign_update },
395517 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL , (fptr_t )signature_digest_sign_final },
0 commit comments