1 /* 2 * Copyright 2020-2024 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 implementation 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 determine 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 computation 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 size_t aid_len; 81 82 /* main digest */ 83 EVP_MD *md; 84 EVP_MD_CTX *mdctx; 85 size_t mdsize; 86 87 /* SM2 ID used for calculating the Z value */ 88 unsigned char *id; 89 size_t id_len; 90 } PROV_SM2_CTX; 91 92 static int sm2sig_set_mdname(PROV_SM2_CTX *psm2ctx, const char *mdname) 93 { 94 if (psm2ctx->md == NULL) /* We need an SM3 md to compare with */ 95 psm2ctx->md = EVP_MD_fetch(psm2ctx->libctx, psm2ctx->mdname, 96 psm2ctx->propq); 97 if (psm2ctx->md == NULL) 98 return 0; 99 100 /* XOF digests don't work */ 101 if (EVP_MD_xof(psm2ctx->md)) { 102 ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED); 103 return 0; 104 } 105 106 if (mdname == NULL) 107 return 1; 108 109 if (strlen(mdname) >= sizeof(psm2ctx->mdname) 110 || !EVP_MD_is_a(psm2ctx->md, mdname)) { 111 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "digest=%s", 112 mdname); 113 return 0; 114 } 115 116 OPENSSL_strlcpy(psm2ctx->mdname, mdname, sizeof(psm2ctx->mdname)); 117 return 1; 118 } 119 120 static void *sm2sig_newctx(void *provctx, const char *propq) 121 { 122 PROV_SM2_CTX *ctx = OPENSSL_zalloc(sizeof(PROV_SM2_CTX)); 123 124 if (ctx == NULL) 125 return NULL; 126 127 ctx->libctx = PROV_LIBCTX_OF(provctx); 128 if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) { 129 OPENSSL_free(ctx); 130 return NULL; 131 } 132 ctx->mdsize = SM3_DIGEST_LENGTH; 133 strcpy(ctx->mdname, OSSL_DIGEST_NAME_SM3); 134 return ctx; 135 } 136 137 static int sm2sig_signature_init(void *vpsm2ctx, void *ec, 138 const OSSL_PARAM params[]) 139 { 140 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; 141 142 if (!ossl_prov_is_running() 143 || psm2ctx == NULL) 144 return 0; 145 146 if (ec == NULL && psm2ctx->ec == NULL) { 147 ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); 148 return 0; 149 } 150 151 if (ec != NULL) { 152 if (!EC_KEY_up_ref(ec)) 153 return 0; 154 EC_KEY_free(psm2ctx->ec); 155 psm2ctx->ec = ec; 156 } 157 158 return sm2sig_set_ctx_params(psm2ctx, params); 159 } 160 161 static int sm2sig_sign(void *vpsm2ctx, unsigned char *sig, size_t *siglen, 162 size_t sigsize, const unsigned char *tbs, size_t tbslen) 163 { 164 PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx; 165 int ret; 166 unsigned int sltmp; 167 /* SM2 uses ECDSA_size as well */ 168 size_t ecsize = ECDSA_size(ctx->ec); 169 170 if (sig == NULL) { 171 *siglen = ecsize; 172 return 1; 173 } 174 175 if (sigsize < (size_t)ecsize) 176 return 0; 177 178 if (ctx->mdsize != 0 && tbslen != ctx->mdsize) 179 return 0; 180 181 ret = ossl_sm2_internal_sign(tbs, tbslen, sig, &sltmp, ctx->ec); 182 if (ret <= 0) 183 return 0; 184 185 *siglen = sltmp; 186 return 1; 187 } 188 189 static int sm2sig_verify(void *vpsm2ctx, const unsigned char *sig, size_t siglen, 190 const unsigned char *tbs, size_t tbslen) 191 { 192 PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx; 193 194 if (ctx->mdsize != 0 && tbslen != ctx->mdsize) 195 return 0; 196 197 return ossl_sm2_internal_verify(tbs, tbslen, sig, siglen, ctx->ec); 198 } 199 200 static void free_md(PROV_SM2_CTX *ctx) 201 { 202 EVP_MD_CTX_free(ctx->mdctx); 203 EVP_MD_free(ctx->md); 204 ctx->mdctx = NULL; 205 ctx->md = NULL; 206 } 207 208 static int sm2sig_digest_signverify_init(void *vpsm2ctx, const char *mdname, 209 void *ec, const OSSL_PARAM params[]) 210 { 211 PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx; 212 int md_nid; 213 WPACKET pkt; 214 int ret = 0; 215 unsigned char *aid = NULL; 216 217 if (!sm2sig_signature_init(vpsm2ctx, ec, params) 218 || !sm2sig_set_mdname(ctx, mdname)) 219 return ret; 220 221 if (ctx->mdctx == NULL) { 222 ctx->mdctx = EVP_MD_CTX_new(); 223 if (ctx->mdctx == NULL) 224 goto error; 225 } 226 227 md_nid = EVP_MD_get_type(ctx->md); 228 229 /* 230 * We do not care about DER writing errors. 231 * All it really means is that for some reason, there's no 232 * AlgorithmIdentifier to be had, but the operation itself is 233 * still valid, just as long as it's not used to construct 234 * anything that needs an AlgorithmIdentifier. 235 */ 236 ctx->aid_len = 0; 237 if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) 238 && ossl_DER_w_algorithmIdentifier_SM2_with_MD(&pkt, -1, ctx->ec, md_nid) 239 && WPACKET_finish(&pkt)) { 240 WPACKET_get_total_written(&pkt, &ctx->aid_len); 241 aid = WPACKET_get_curr(&pkt); 242 } 243 WPACKET_cleanup(&pkt); 244 if (aid != NULL && ctx->aid_len != 0) 245 memmove(ctx->aid_buf, aid, ctx->aid_len); 246 247 if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params)) 248 goto error; 249 250 ctx->flag_compute_z_digest = 1; 251 252 ret = 1; 253 254 error: 255 return ret; 256 } 257 258 static int sm2sig_compute_z_digest(PROV_SM2_CTX *ctx) 259 { 260 uint8_t *z = NULL; 261 int ret = 1; 262 263 if (ctx->flag_compute_z_digest) { 264 /* Only do this once */ 265 ctx->flag_compute_z_digest = 0; 266 267 if ((z = OPENSSL_zalloc(ctx->mdsize)) == NULL 268 /* get hashed prefix 'z' of tbs message */ 269 || !ossl_sm2_compute_z_digest(z, ctx->md, ctx->id, ctx->id_len, 270 ctx->ec) 271 || !EVP_DigestUpdate(ctx->mdctx, z, ctx->mdsize)) 272 ret = 0; 273 OPENSSL_free(z); 274 } 275 276 return ret; 277 } 278 279 int sm2sig_digest_signverify_update(void *vpsm2ctx, const unsigned char *data, 280 size_t datalen) 281 { 282 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; 283 284 if (psm2ctx == NULL || psm2ctx->mdctx == NULL) 285 return 0; 286 287 return sm2sig_compute_z_digest(psm2ctx) 288 && EVP_DigestUpdate(psm2ctx->mdctx, data, datalen); 289 } 290 291 int sm2sig_digest_sign_final(void *vpsm2ctx, unsigned char *sig, size_t *siglen, 292 size_t sigsize) 293 { 294 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; 295 unsigned char digest[EVP_MAX_MD_SIZE]; 296 unsigned int dlen = 0; 297 298 if (psm2ctx == NULL || psm2ctx->mdctx == NULL) 299 return 0; 300 301 /* 302 * If sig is NULL then we're just finding out the sig size. Other fields 303 * are ignored. Defer to sm2sig_sign. 304 */ 305 if (sig != NULL) { 306 if (!(sm2sig_compute_z_digest(psm2ctx) 307 && EVP_DigestFinal_ex(psm2ctx->mdctx, digest, &dlen))) 308 return 0; 309 } 310 311 return sm2sig_sign(vpsm2ctx, sig, siglen, sigsize, digest, (size_t)dlen); 312 } 313 314 315 int sm2sig_digest_verify_final(void *vpsm2ctx, const unsigned char *sig, 316 size_t siglen) 317 { 318 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; 319 unsigned char digest[EVP_MAX_MD_SIZE]; 320 unsigned int dlen = 0; 321 int md_size; 322 323 if (psm2ctx == NULL || psm2ctx->mdctx == NULL) 324 return 0; 325 326 md_size = EVP_MD_get_size(psm2ctx->md); 327 if (md_size <= 0 || md_size > (int)sizeof(digest)) 328 return 0; 329 330 if (!(sm2sig_compute_z_digest(psm2ctx) 331 && EVP_DigestFinal_ex(psm2ctx->mdctx, digest, &dlen))) 332 return 0; 333 334 return sm2sig_verify(vpsm2ctx, sig, siglen, digest, (size_t)dlen); 335 } 336 337 static void sm2sig_freectx(void *vpsm2ctx) 338 { 339 PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx; 340 341 free_md(ctx); 342 EC_KEY_free(ctx->ec); 343 OPENSSL_free(ctx->propq); 344 OPENSSL_free(ctx->id); 345 OPENSSL_free(ctx); 346 } 347 348 static void *sm2sig_dupctx(void *vpsm2ctx) 349 { 350 PROV_SM2_CTX *srcctx = (PROV_SM2_CTX *)vpsm2ctx; 351 PROV_SM2_CTX *dstctx; 352 353 dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 354 if (dstctx == NULL) 355 return NULL; 356 357 *dstctx = *srcctx; 358 dstctx->ec = NULL; 359 dstctx->propq = NULL; 360 dstctx->md = NULL; 361 dstctx->mdctx = NULL; 362 dstctx->id = NULL; 363 364 if (srcctx->ec != NULL && !EC_KEY_up_ref(srcctx->ec)) 365 goto err; 366 dstctx->ec = srcctx->ec; 367 368 if (srcctx->propq != NULL) { 369 dstctx->propq = OPENSSL_strdup(srcctx->propq); 370 if (dstctx->propq == NULL) 371 goto err; 372 } 373 374 if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md)) 375 goto err; 376 dstctx->md = srcctx->md; 377 378 if (srcctx->mdctx != NULL) { 379 dstctx->mdctx = EVP_MD_CTX_new(); 380 if (dstctx->mdctx == NULL 381 || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx)) 382 goto err; 383 } 384 385 if (srcctx->id != NULL) { 386 dstctx->id = OPENSSL_malloc(srcctx->id_len); 387 if (dstctx->id == NULL) 388 goto err; 389 dstctx->id_len = srcctx->id_len; 390 memcpy(dstctx->id, srcctx->id, srcctx->id_len); 391 } 392 393 return dstctx; 394 err: 395 sm2sig_freectx(dstctx); 396 return NULL; 397 } 398 399 static int sm2sig_get_ctx_params(void *vpsm2ctx, OSSL_PARAM *params) 400 { 401 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; 402 OSSL_PARAM *p; 403 404 if (psm2ctx == NULL) 405 return 0; 406 407 p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); 408 if (p != NULL 409 && !OSSL_PARAM_set_octet_string(p, 410 psm2ctx->aid_len == 0 ? NULL : psm2ctx->aid_buf, 411 psm2ctx->aid_len)) 412 return 0; 413 414 p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE); 415 if (p != NULL && !OSSL_PARAM_set_size_t(p, psm2ctx->mdsize)) 416 return 0; 417 418 p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST); 419 if (p != NULL && !OSSL_PARAM_set_utf8_string(p, psm2ctx->md == NULL 420 ? psm2ctx->mdname 421 : EVP_MD_get0_name(psm2ctx->md))) 422 return 0; 423 424 return 1; 425 } 426 427 static const OSSL_PARAM known_gettable_ctx_params[] = { 428 OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), 429 OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), 430 OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), 431 OSSL_PARAM_END 432 }; 433 434 static const OSSL_PARAM *sm2sig_gettable_ctx_params(ossl_unused void *vpsm2ctx, 435 ossl_unused void *provctx) 436 { 437 return known_gettable_ctx_params; 438 } 439 440 static int sm2sig_set_ctx_params(void *vpsm2ctx, const OSSL_PARAM params[]) 441 { 442 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; 443 const OSSL_PARAM *p; 444 size_t mdsize; 445 446 if (psm2ctx == NULL) 447 return 0; 448 if (ossl_param_is_empty(params)) 449 return 1; 450 451 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DIST_ID); 452 if (p != NULL) { 453 void *tmp_id = NULL; 454 size_t tmp_idlen = 0; 455 456 /* 457 * If the 'z' digest has already been computed, the ID is set too late 458 */ 459 if (!psm2ctx->flag_compute_z_digest) 460 return 0; 461 462 if (p->data_size != 0 463 && !OSSL_PARAM_get_octet_string(p, &tmp_id, 0, &tmp_idlen)) 464 return 0; 465 OPENSSL_free(psm2ctx->id); 466 psm2ctx->id = tmp_id; 467 psm2ctx->id_len = tmp_idlen; 468 } 469 470 /* 471 * The following code checks that the size is the same as the SM3 digest 472 * size returning an error otherwise. 473 * If there is ever any different digest algorithm allowed with SM2 474 * this needs to be adjusted accordingly. 475 */ 476 p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE); 477 if (p != NULL && (!OSSL_PARAM_get_size_t(p, &mdsize) 478 || mdsize != psm2ctx->mdsize)) 479 return 0; 480 481 p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); 482 if (p != NULL) { 483 char *mdname = NULL; 484 485 if (!OSSL_PARAM_get_utf8_string(p, &mdname, 0)) 486 return 0; 487 if (!sm2sig_set_mdname(psm2ctx, mdname)) { 488 OPENSSL_free(mdname); 489 return 0; 490 } 491 OPENSSL_free(mdname); 492 } 493 494 return 1; 495 } 496 497 static const OSSL_PARAM known_settable_ctx_params[] = { 498 OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), 499 OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), 500 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DIST_ID, NULL, 0), 501 OSSL_PARAM_END 502 }; 503 504 static const OSSL_PARAM *sm2sig_settable_ctx_params(ossl_unused void *vpsm2ctx, 505 ossl_unused void *provctx) 506 { 507 return known_settable_ctx_params; 508 } 509 510 static int sm2sig_get_ctx_md_params(void *vpsm2ctx, OSSL_PARAM *params) 511 { 512 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; 513 514 if (psm2ctx->mdctx == NULL) 515 return 0; 516 517 return EVP_MD_CTX_get_params(psm2ctx->mdctx, params); 518 } 519 520 static const OSSL_PARAM *sm2sig_gettable_ctx_md_params(void *vpsm2ctx) 521 { 522 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; 523 524 if (psm2ctx->md == NULL) 525 return 0; 526 527 return EVP_MD_gettable_ctx_params(psm2ctx->md); 528 } 529 530 static int sm2sig_set_ctx_md_params(void *vpsm2ctx, const OSSL_PARAM params[]) 531 { 532 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; 533 534 if (psm2ctx->mdctx == NULL) 535 return 0; 536 537 return EVP_MD_CTX_set_params(psm2ctx->mdctx, params); 538 } 539 540 static const OSSL_PARAM *sm2sig_settable_ctx_md_params(void *vpsm2ctx) 541 { 542 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; 543 544 if (psm2ctx->md == NULL) 545 return 0; 546 547 return EVP_MD_settable_ctx_params(psm2ctx->md); 548 } 549 550 const OSSL_DISPATCH ossl_sm2_signature_functions[] = { 551 { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))sm2sig_newctx }, 552 { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))sm2sig_signature_init }, 553 { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))sm2sig_sign }, 554 { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))sm2sig_signature_init }, 555 { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))sm2sig_verify }, 556 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, 557 (void (*)(void))sm2sig_digest_signverify_init }, 558 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, 559 (void (*)(void))sm2sig_digest_signverify_update }, 560 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, 561 (void (*)(void))sm2sig_digest_sign_final }, 562 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, 563 (void (*)(void))sm2sig_digest_signverify_init }, 564 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, 565 (void (*)(void))sm2sig_digest_signverify_update }, 566 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, 567 (void (*)(void))sm2sig_digest_verify_final }, 568 { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))sm2sig_freectx }, 569 { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))sm2sig_dupctx }, 570 { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))sm2sig_get_ctx_params }, 571 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, 572 (void (*)(void))sm2sig_gettable_ctx_params }, 573 { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))sm2sig_set_ctx_params }, 574 { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, 575 (void (*)(void))sm2sig_settable_ctx_params }, 576 { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, 577 (void (*)(void))sm2sig_get_ctx_md_params }, 578 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, 579 (void (*)(void))sm2sig_gettable_ctx_md_params }, 580 { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, 581 (void (*)(void))sm2sig_set_ctx_md_params }, 582 { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, 583 (void (*)(void))sm2sig_settable_ctx_md_params }, 584 OSSL_DISPATCH_END 585 }; 586