Home | History | Annotate | Line # | Download | only in signature
      1 /*
      2  * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 /*
     11  * ECDSA low level APIs are deprecated for public use, but still ok for
     12  * internal use - SM2 implemetation uses ECDSA_size() function.
     13  */
     14 #include "internal/deprecated.h"
     15 
     16 #include <string.h> /* memcpy */
     17 #include <openssl/crypto.h>
     18 #include <openssl/core_dispatch.h>
     19 #include <openssl/core_names.h>
     20 #include <openssl/dsa.h>
     21 #include <openssl/params.h>
     22 #include <openssl/evp.h>
     23 #include <openssl/err.h>
     24 #include <openssl/proverr.h>
     25 #include "internal/nelem.h"
     26 #include "internal/sizes.h"
     27 #include "internal/cryptlib.h"
     28 #include "internal/sm3.h"
     29 #include "prov/implementations.h"
     30 #include "prov/providercommon.h"
     31 #include "prov/provider_ctx.h"
     32 #include "crypto/ec.h"
     33 #include "crypto/sm2.h"
     34 #include "prov/der_sm2.h"
     35 
     36 static OSSL_FUNC_signature_newctx_fn sm2sig_newctx;
     37 static OSSL_FUNC_signature_sign_init_fn sm2sig_signature_init;
     38 static OSSL_FUNC_signature_verify_init_fn sm2sig_signature_init;
     39 static OSSL_FUNC_signature_sign_fn sm2sig_sign;
     40 static OSSL_FUNC_signature_verify_fn sm2sig_verify;
     41 static OSSL_FUNC_signature_digest_sign_init_fn sm2sig_digest_signverify_init;
     42 static OSSL_FUNC_signature_digest_sign_update_fn sm2sig_digest_signverify_update;
     43 static OSSL_FUNC_signature_digest_sign_final_fn sm2sig_digest_sign_final;
     44 static OSSL_FUNC_signature_digest_verify_init_fn sm2sig_digest_signverify_init;
     45 static OSSL_FUNC_signature_digest_verify_update_fn sm2sig_digest_signverify_update;
     46 static OSSL_FUNC_signature_digest_verify_final_fn sm2sig_digest_verify_final;
     47 static OSSL_FUNC_signature_freectx_fn sm2sig_freectx;
     48 static OSSL_FUNC_signature_dupctx_fn sm2sig_dupctx;
     49 static OSSL_FUNC_signature_get_ctx_params_fn sm2sig_get_ctx_params;
     50 static OSSL_FUNC_signature_gettable_ctx_params_fn sm2sig_gettable_ctx_params;
     51 static OSSL_FUNC_signature_set_ctx_params_fn sm2sig_set_ctx_params;
     52 static OSSL_FUNC_signature_settable_ctx_params_fn sm2sig_settable_ctx_params;
     53 static OSSL_FUNC_signature_get_ctx_md_params_fn sm2sig_get_ctx_md_params;
     54 static OSSL_FUNC_signature_gettable_ctx_md_params_fn sm2sig_gettable_ctx_md_params;
     55 static OSSL_FUNC_signature_set_ctx_md_params_fn sm2sig_set_ctx_md_params;
     56 static OSSL_FUNC_signature_settable_ctx_md_params_fn sm2sig_settable_ctx_md_params;
     57 
     58 /*
     59  * What's passed as an actual key is defined by the KEYMGMT interface.
     60  * We happen to know that our KEYMGMT simply passes EC structures, so
     61  * we use that here too.
     62  */
     63 typedef struct {
     64     OSSL_LIB_CTX *libctx;
     65     char *propq;
     66     EC_KEY *ec;
     67 
     68     /*
     69      * Flag to termine if the 'z' digest needs to be computed and fed to the
     70      * hash function.
     71      * This flag should be set on initialization and the compuation should
     72      * be performed only once, on first update.
     73      */
     74     unsigned int flag_compute_z_digest : 1;
     75 
     76     char mdname[OSSL_MAX_NAME_SIZE];
     77 
     78     /* The Algorithm Identifier of the combined signature algorithm */
     79     unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];
     80     unsigned char *aid;
     81     size_t  aid_len;
     82 
     83     /* main digest */
     84     EVP_MD *md;
     85     EVP_MD_CTX *mdctx;
     86     size_t mdsize;
     87 
     88     /* SM2 ID used for calculating the Z value */
     89     unsigned char *id;
     90     size_t id_len;
     91 } PROV_SM2_CTX;
     92 
     93 static int sm2sig_set_mdname(PROV_SM2_CTX *psm2ctx, const char *mdname)
     94 {
     95     if (psm2ctx->md == NULL) /* We need an SM3 md to compare with */
     96         psm2ctx->md = EVP_MD_fetch(psm2ctx->libctx, psm2ctx->mdname,
     97                                    psm2ctx->propq);
     98     if (psm2ctx->md == NULL)
     99         return 0;
    100 
    101     if (mdname == NULL)
    102         return 1;
    103 
    104     if (strlen(mdname) >= sizeof(psm2ctx->mdname)
    105         || !EVP_MD_is_a(psm2ctx->md, mdname)) {
    106         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "digest=%s",
    107                        mdname);
    108         return 0;
    109     }
    110 
    111     OPENSSL_strlcpy(psm2ctx->mdname, mdname, sizeof(psm2ctx->mdname));
    112     return 1;
    113 }
    114 
    115 static void *sm2sig_newctx(void *provctx, const char *propq)
    116 {
    117     PROV_SM2_CTX *ctx = OPENSSL_zalloc(sizeof(PROV_SM2_CTX));
    118 
    119     if (ctx == NULL)
    120         return NULL;
    121 
    122     ctx->libctx = PROV_LIBCTX_OF(provctx);
    123     if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) {
    124         OPENSSL_free(ctx);
    125         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
    126         return NULL;
    127     }
    128     ctx->mdsize = SM3_DIGEST_LENGTH;
    129     strcpy(ctx->mdname, OSSL_DIGEST_NAME_SM3);
    130     return ctx;
    131 }
    132 
    133 static int sm2sig_signature_init(void *vpsm2ctx, void *ec,
    134                                  const OSSL_PARAM params[])
    135 {
    136     PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
    137 
    138     if (!ossl_prov_is_running()
    139             || psm2ctx == NULL)
    140         return 0;
    141 
    142     if (ec == NULL && psm2ctx->ec == NULL) {
    143         ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
    144         return 0;
    145     }
    146 
    147     if (ec != NULL) {
    148         if (!EC_KEY_up_ref(ec))
    149             return 0;
    150         EC_KEY_free(psm2ctx->ec);
    151         psm2ctx->ec = ec;
    152     }
    153 
    154     return sm2sig_set_ctx_params(psm2ctx, params);
    155 }
    156 
    157 static int sm2sig_sign(void *vpsm2ctx, unsigned char *sig, size_t *siglen,
    158                        size_t sigsize, const unsigned char *tbs, size_t tbslen)
    159 {
    160     PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx;
    161     int ret;
    162     unsigned int sltmp;
    163     /* SM2 uses ECDSA_size as well */
    164     size_t ecsize = ECDSA_size(ctx->ec);
    165 
    166     if (sig == NULL) {
    167         *siglen = ecsize;
    168         return 1;
    169     }
    170 
    171     if (sigsize < (size_t)ecsize)
    172         return 0;
    173 
    174     if (ctx->mdsize != 0 && tbslen != ctx->mdsize)
    175         return 0;
    176 
    177     ret = ossl_sm2_internal_sign(tbs, tbslen, sig, &sltmp, ctx->ec);
    178     if (ret <= 0)
    179         return 0;
    180 
    181     *siglen = sltmp;
    182     return 1;
    183 }
    184 
    185 static int sm2sig_verify(void *vpsm2ctx, const unsigned char *sig, size_t siglen,
    186                          const unsigned char *tbs, size_t tbslen)
    187 {
    188     PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx;
    189 
    190     if (ctx->mdsize != 0 && tbslen != ctx->mdsize)
    191         return 0;
    192 
    193     return ossl_sm2_internal_verify(tbs, tbslen, sig, siglen, ctx->ec);
    194 }
    195 
    196 static void free_md(PROV_SM2_CTX *ctx)
    197 {
    198     EVP_MD_CTX_free(ctx->mdctx);
    199     EVP_MD_free(ctx->md);
    200     ctx->mdctx = NULL;
    201     ctx->md = NULL;
    202 }
    203 
    204 static int sm2sig_digest_signverify_init(void *vpsm2ctx, const char *mdname,
    205                                          void *ec, const OSSL_PARAM params[])
    206 {
    207     PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx;
    208     int md_nid;
    209     WPACKET pkt;
    210     int ret = 0;
    211 
    212     if (!sm2sig_signature_init(vpsm2ctx, ec, params)
    213         || !sm2sig_set_mdname(ctx, mdname))
    214         return ret;
    215 
    216     if (ctx->mdctx == NULL) {
    217         ctx->mdctx = EVP_MD_CTX_new();
    218         if (ctx->mdctx == NULL)
    219             goto error;
    220     }
    221 
    222     md_nid = EVP_MD_get_type(ctx->md);
    223 
    224     /*
    225      * We do not care about DER writing errors.
    226      * All it really means is that for some reason, there's no
    227      * AlgorithmIdentifier to be had, but the operation itself is
    228      * still valid, just as long as it's not used to construct
    229      * anything that needs an AlgorithmIdentifier.
    230      */
    231     ctx->aid_len = 0;
    232     if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf))
    233         && ossl_DER_w_algorithmIdentifier_SM2_with_MD(&pkt, -1, ctx->ec, md_nid)
    234         && WPACKET_finish(&pkt)) {
    235         WPACKET_get_total_written(&pkt, &ctx->aid_len);
    236         ctx->aid = WPACKET_get_curr(&pkt);
    237     }
    238     WPACKET_cleanup(&pkt);
    239 
    240     if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params))
    241         goto error;
    242 
    243     ctx->flag_compute_z_digest = 1;
    244 
    245     ret = 1;
    246 
    247  error:
    248     return ret;
    249 }
    250 
    251 static int sm2sig_compute_z_digest(PROV_SM2_CTX *ctx)
    252 {
    253     uint8_t *z = NULL;
    254     int ret = 1;
    255 
    256     if (ctx->flag_compute_z_digest) {
    257         /* Only do this once */
    258         ctx->flag_compute_z_digest = 0;
    259 
    260         if ((z = OPENSSL_zalloc(ctx->mdsize)) == NULL
    261             /* get hashed prefix 'z' of tbs message */
    262             || !ossl_sm2_compute_z_digest(z, ctx->md, ctx->id, ctx->id_len,
    263                                           ctx->ec)
    264             || !EVP_DigestUpdate(ctx->mdctx, z, ctx->mdsize))
    265             ret = 0;
    266         OPENSSL_free(z);
    267     }
    268 
    269     return ret;
    270 }
    271 
    272 int sm2sig_digest_signverify_update(void *vpsm2ctx, const unsigned char *data,
    273                                     size_t datalen)
    274 {
    275     PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
    276 
    277     if (psm2ctx == NULL || psm2ctx->mdctx == NULL)
    278         return 0;
    279 
    280     return sm2sig_compute_z_digest(psm2ctx)
    281         && EVP_DigestUpdate(psm2ctx->mdctx, data, datalen);
    282 }
    283 
    284 int sm2sig_digest_sign_final(void *vpsm2ctx, unsigned char *sig, size_t *siglen,
    285                              size_t sigsize)
    286 {
    287     PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
    288     unsigned char digest[EVP_MAX_MD_SIZE];
    289     unsigned int dlen = 0;
    290 
    291     if (psm2ctx == NULL || psm2ctx->mdctx == NULL)
    292         return 0;
    293 
    294     /*
    295      * If sig is NULL then we're just finding out the sig size. Other fields
    296      * are ignored. Defer to sm2sig_sign.
    297      */
    298     if (sig != NULL) {
    299         if (!(sm2sig_compute_z_digest(psm2ctx)
    300               && EVP_DigestFinal_ex(psm2ctx->mdctx, digest, &dlen)))
    301             return 0;
    302     }
    303 
    304     return sm2sig_sign(vpsm2ctx, sig, siglen, sigsize, digest, (size_t)dlen);
    305 }
    306 
    307 
    308 int sm2sig_digest_verify_final(void *vpsm2ctx, const unsigned char *sig,
    309                                size_t siglen)
    310 {
    311     PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
    312     unsigned char digest[EVP_MAX_MD_SIZE];
    313     unsigned int dlen = 0;
    314 
    315     if (psm2ctx == NULL
    316         || psm2ctx->mdctx == NULL
    317         || EVP_MD_get_size(psm2ctx->md) > (int)sizeof(digest))
    318         return 0;
    319 
    320     if (!(sm2sig_compute_z_digest(psm2ctx)
    321           && EVP_DigestFinal_ex(psm2ctx->mdctx, digest, &dlen)))
    322         return 0;
    323 
    324     return sm2sig_verify(vpsm2ctx, sig, siglen, digest, (size_t)dlen);
    325 }
    326 
    327 static void sm2sig_freectx(void *vpsm2ctx)
    328 {
    329     PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx;
    330 
    331     free_md(ctx);
    332     EC_KEY_free(ctx->ec);
    333     OPENSSL_free(ctx->propq);
    334     OPENSSL_free(ctx->id);
    335     OPENSSL_free(ctx);
    336 }
    337 
    338 static void *sm2sig_dupctx(void *vpsm2ctx)
    339 {
    340     PROV_SM2_CTX *srcctx = (PROV_SM2_CTX *)vpsm2ctx;
    341     PROV_SM2_CTX *dstctx;
    342 
    343     dstctx = OPENSSL_zalloc(sizeof(*srcctx));
    344     if (dstctx == NULL)
    345         return NULL;
    346 
    347     *dstctx = *srcctx;
    348     dstctx->ec = NULL;
    349     dstctx->propq = NULL;
    350     dstctx->md = NULL;
    351     dstctx->mdctx = NULL;
    352     dstctx->id = NULL;
    353 
    354     if (srcctx->ec != NULL && !EC_KEY_up_ref(srcctx->ec))
    355         goto err;
    356     dstctx->ec = srcctx->ec;
    357 
    358     if (srcctx->propq != NULL) {
    359         dstctx->propq = OPENSSL_strdup(srcctx->propq);
    360         if (dstctx->propq == NULL)
    361             goto err;
    362     }
    363 
    364     if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md))
    365         goto err;
    366     dstctx->md = srcctx->md;
    367 
    368     if (srcctx->mdctx != NULL) {
    369         dstctx->mdctx = EVP_MD_CTX_new();
    370         if (dstctx->mdctx == NULL
    371                 || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx))
    372             goto err;
    373     }
    374 
    375     if (srcctx->id != NULL) {
    376         dstctx->id = OPENSSL_malloc(srcctx->id_len);
    377         if (dstctx->id == NULL)
    378             goto err;
    379         dstctx->id_len = srcctx->id_len;
    380         memcpy(dstctx->id, srcctx->id, srcctx->id_len);
    381     }
    382 
    383     return dstctx;
    384  err:
    385     sm2sig_freectx(dstctx);
    386     return NULL;
    387 }
    388 
    389 static int sm2sig_get_ctx_params(void *vpsm2ctx, OSSL_PARAM *params)
    390 {
    391     PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
    392     OSSL_PARAM *p;
    393 
    394     if (psm2ctx == NULL)
    395         return 0;
    396 
    397     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
    398     if (p != NULL
    399         && !OSSL_PARAM_set_octet_string(p, psm2ctx->aid, psm2ctx->aid_len))
    400         return 0;
    401 
    402     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
    403     if (p != NULL && !OSSL_PARAM_set_size_t(p, psm2ctx->mdsize))
    404         return 0;
    405 
    406     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);
    407     if (p != NULL && !OSSL_PARAM_set_utf8_string(p, psm2ctx->md == NULL
    408                                                     ? psm2ctx->mdname
    409                                                     : EVP_MD_get0_name(psm2ctx->md)))
    410         return 0;
    411 
    412     return 1;
    413 }
    414 
    415 static const OSSL_PARAM known_gettable_ctx_params[] = {
    416     OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
    417     OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
    418     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
    419     OSSL_PARAM_END
    420 };
    421 
    422 static const OSSL_PARAM *sm2sig_gettable_ctx_params(ossl_unused void *vpsm2ctx,
    423                                                     ossl_unused void *provctx)
    424 {
    425     return known_gettable_ctx_params;
    426 }
    427 
    428 static int sm2sig_set_ctx_params(void *vpsm2ctx, const OSSL_PARAM params[])
    429 {
    430     PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
    431     const OSSL_PARAM *p;
    432     size_t mdsize;
    433 
    434     if (psm2ctx == NULL)
    435         return 0;
    436     if (params == NULL)
    437         return 1;
    438 
    439     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DIST_ID);
    440     if (p != NULL) {
    441         void *tmp_id = NULL;
    442         size_t tmp_idlen = 0;
    443 
    444         /*
    445          * If the 'z' digest has already been computed, the ID is set too late
    446          */
    447         if (!psm2ctx->flag_compute_z_digest)
    448             return 0;
    449 
    450         if (p->data_size != 0
    451             && !OSSL_PARAM_get_octet_string(p, &tmp_id, 0, &tmp_idlen))
    452             return 0;
    453         OPENSSL_free(psm2ctx->id);
    454         psm2ctx->id = tmp_id;
    455         psm2ctx->id_len = tmp_idlen;
    456     }
    457 
    458     /*
    459      * The following code checks that the size is the same as the SM3 digest
    460      * size returning an error otherwise.
    461      * If there is ever any different digest algorithm allowed with SM2
    462      * this needs to be adjusted accordingly.
    463      */
    464     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
    465     if (p != NULL && (!OSSL_PARAM_get_size_t(p, &mdsize)
    466                       || mdsize != psm2ctx->mdsize))
    467         return 0;
    468 
    469     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
    470     if (p != NULL) {
    471         char *mdname = NULL;
    472 
    473         if (!OSSL_PARAM_get_utf8_string(p, &mdname, 0))
    474             return 0;
    475         if (!sm2sig_set_mdname(psm2ctx, mdname)) {
    476             OPENSSL_free(mdname);
    477             return 0;
    478         }
    479         OPENSSL_free(mdname);
    480     }
    481 
    482     return 1;
    483 }
    484 
    485 static const OSSL_PARAM known_settable_ctx_params[] = {
    486     OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
    487     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
    488     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DIST_ID, NULL, 0),
    489     OSSL_PARAM_END
    490 };
    491 
    492 static const OSSL_PARAM *sm2sig_settable_ctx_params(ossl_unused void *vpsm2ctx,
    493                                                     ossl_unused void *provctx)
    494 {
    495     return known_settable_ctx_params;
    496 }
    497 
    498 static int sm2sig_get_ctx_md_params(void *vpsm2ctx, OSSL_PARAM *params)
    499 {
    500     PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
    501 
    502     if (psm2ctx->mdctx == NULL)
    503         return 0;
    504 
    505     return EVP_MD_CTX_get_params(psm2ctx->mdctx, params);
    506 }
    507 
    508 static const OSSL_PARAM *sm2sig_gettable_ctx_md_params(void *vpsm2ctx)
    509 {
    510     PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
    511 
    512     if (psm2ctx->md == NULL)
    513         return 0;
    514 
    515     return EVP_MD_gettable_ctx_params(psm2ctx->md);
    516 }
    517 
    518 static int sm2sig_set_ctx_md_params(void *vpsm2ctx, const OSSL_PARAM params[])
    519 {
    520     PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
    521 
    522     if (psm2ctx->mdctx == NULL)
    523         return 0;
    524 
    525     return EVP_MD_CTX_set_params(psm2ctx->mdctx, params);
    526 }
    527 
    528 static const OSSL_PARAM *sm2sig_settable_ctx_md_params(void *vpsm2ctx)
    529 {
    530     PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
    531 
    532     if (psm2ctx->md == NULL)
    533         return 0;
    534 
    535     return EVP_MD_settable_ctx_params(psm2ctx->md);
    536 }
    537 
    538 const OSSL_DISPATCH ossl_sm2_signature_functions[] = {
    539     { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))sm2sig_newctx },
    540     { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))sm2sig_signature_init },
    541     { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))sm2sig_sign },
    542     { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))sm2sig_signature_init },
    543     { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))sm2sig_verify },
    544     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
    545       (void (*)(void))sm2sig_digest_signverify_init },
    546     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,
    547       (void (*)(void))sm2sig_digest_signverify_update },
    548     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,
    549       (void (*)(void))sm2sig_digest_sign_final },
    550     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
    551       (void (*)(void))sm2sig_digest_signverify_init },
    552     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE,
    553       (void (*)(void))sm2sig_digest_signverify_update },
    554     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL,
    555       (void (*)(void))sm2sig_digest_verify_final },
    556     { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))sm2sig_freectx },
    557     { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))sm2sig_dupctx },
    558     { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))sm2sig_get_ctx_params },
    559     { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
    560       (void (*)(void))sm2sig_gettable_ctx_params },
    561     { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))sm2sig_set_ctx_params },
    562     { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
    563       (void (*)(void))sm2sig_settable_ctx_params },
    564     { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS,
    565       (void (*)(void))sm2sig_get_ctx_md_params },
    566     { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS,
    567       (void (*)(void))sm2sig_gettable_ctx_md_params },
    568     { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS,
    569       (void (*)(void))sm2sig_set_ctx_md_params },
    570     { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS,
    571       (void (*)(void))sm2sig_settable_ctx_md_params },
    572     { 0, NULL }
    573 };
    574