Skip to content

Commit c96ad43

Browse files
authored
Merge pull request #536 from GauriSpears/master
provider hash-then-sign support
2 parents c13eea2 + 5c7be9c commit c96ad43

1 file changed

Lines changed: 122 additions & 0 deletions

File tree

‎gost_prov_signature.c‎

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ int gost_get_max_signature_size(const GOST_KEY_DATA *key_data)
3636
*/
3737
static OSSL_FUNC_signature_newctx_fn signature_newctx;
3838
static 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;
3943
static OSSL_FUNC_signature_digest_sign_init_fn signature_digest_sign_init;
4044
static OSSL_FUNC_signature_digest_sign_update_fn signature_digest_sign_update;
4145
static 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
4448
static OSSL_FUNC_signature_digest_verify_final_fn signature_digest_verify_final;
4549
static OSSL_FUNC_signature_get_ctx_params_fn signature_get_ctx_params;
4650
static 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

4854
typedef 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+
387503
typedef void (*fptr_t)(void);
388504
static 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

Comments
 (0)