1 /* 2 * Copyright 2019-2021 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 * DSA low level APIs are deprecated for public use, but still ok for 12 * internal use. 13 */ 14 #include "internal/deprecated.h" 15 16 #include <string.h> 17 18 #include <openssl/crypto.h> 19 #include <openssl/core_dispatch.h> 20 #include <openssl/core_names.h> 21 #include <openssl/err.h> 22 #include <openssl/dsa.h> 23 #include <openssl/params.h> 24 #include <openssl/evp.h> 25 #include <openssl/err.h> 26 #include <openssl/proverr.h> 27 #include "internal/nelem.h" 28 #include "internal/sizes.h" 29 #include "internal/cryptlib.h" 30 #include "prov/providercommon.h" 31 #include "prov/implementations.h" 32 #include "prov/provider_ctx.h" 33 #include "prov/securitycheck.h" 34 #include "crypto/dsa.h" 35 #include "prov/der_dsa.h" 36 37 static OSSL_FUNC_signature_newctx_fn dsa_newctx; 38 static OSSL_FUNC_signature_sign_init_fn dsa_sign_init; 39 static OSSL_FUNC_signature_verify_init_fn dsa_verify_init; 40 static OSSL_FUNC_signature_sign_fn dsa_sign; 41 static OSSL_FUNC_signature_verify_fn dsa_verify; 42 static OSSL_FUNC_signature_digest_sign_init_fn dsa_digest_sign_init; 43 static OSSL_FUNC_signature_digest_sign_update_fn dsa_digest_signverify_update; 44 static OSSL_FUNC_signature_digest_sign_final_fn dsa_digest_sign_final; 45 static OSSL_FUNC_signature_digest_verify_init_fn dsa_digest_verify_init; 46 static OSSL_FUNC_signature_digest_verify_update_fn dsa_digest_signverify_update; 47 static OSSL_FUNC_signature_digest_verify_final_fn dsa_digest_verify_final; 48 static OSSL_FUNC_signature_freectx_fn dsa_freectx; 49 static OSSL_FUNC_signature_dupctx_fn dsa_dupctx; 50 static OSSL_FUNC_signature_get_ctx_params_fn dsa_get_ctx_params; 51 static OSSL_FUNC_signature_gettable_ctx_params_fn dsa_gettable_ctx_params; 52 static OSSL_FUNC_signature_set_ctx_params_fn dsa_set_ctx_params; 53 static OSSL_FUNC_signature_settable_ctx_params_fn dsa_settable_ctx_params; 54 static OSSL_FUNC_signature_get_ctx_md_params_fn dsa_get_ctx_md_params; 55 static OSSL_FUNC_signature_gettable_ctx_md_params_fn dsa_gettable_ctx_md_params; 56 static OSSL_FUNC_signature_set_ctx_md_params_fn dsa_set_ctx_md_params; 57 static OSSL_FUNC_signature_settable_ctx_md_params_fn dsa_settable_ctx_md_params; 58 59 /* 60 * What's passed as an actual key is defined by the KEYMGMT interface. 61 * We happen to know that our KEYMGMT simply passes DSA structures, so 62 * we use that here too. 63 */ 64 65 typedef struct { 66 OSSL_LIB_CTX *libctx; 67 char *propq; 68 DSA *dsa; 69 70 /* 71 * Flag to determine if the hash function can be changed (1) or not (0) 72 * Because it's dangerous to change during a DigestSign or DigestVerify 73 * operation, this flag is cleared by their Init function, and set again 74 * by their Final function. 75 */ 76 unsigned int flag_allow_md : 1; 77 78 char mdname[OSSL_MAX_NAME_SIZE]; 79 80 /* The Algorithm Identifier of the combined signature algorithm */ 81 unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; 82 unsigned char *aid; 83 size_t aid_len; 84 85 /* main digest */ 86 EVP_MD *md; 87 EVP_MD_CTX *mdctx; 88 int operation; 89 } PROV_DSA_CTX; 90 91 92 static size_t dsa_get_md_size(const PROV_DSA_CTX *pdsactx) 93 { 94 if (pdsactx->md != NULL) 95 return EVP_MD_get_size(pdsactx->md); 96 return 0; 97 } 98 99 static void *dsa_newctx(void *provctx, const char *propq) 100 { 101 PROV_DSA_CTX *pdsactx; 102 103 if (!ossl_prov_is_running()) 104 return NULL; 105 106 pdsactx = OPENSSL_zalloc(sizeof(PROV_DSA_CTX)); 107 if (pdsactx == NULL) 108 return NULL; 109 110 pdsactx->libctx = PROV_LIBCTX_OF(provctx); 111 pdsactx->flag_allow_md = 1; 112 if (propq != NULL && (pdsactx->propq = OPENSSL_strdup(propq)) == NULL) { 113 OPENSSL_free(pdsactx); 114 pdsactx = NULL; 115 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 116 } 117 return pdsactx; 118 } 119 120 static int dsa_setup_md(PROV_DSA_CTX *ctx, 121 const char *mdname, const char *mdprops) 122 { 123 if (mdprops == NULL) 124 mdprops = ctx->propq; 125 126 if (mdname != NULL) { 127 int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN); 128 WPACKET pkt; 129 EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); 130 int md_nid = ossl_digest_get_approved_nid_with_sha1(ctx->libctx, md, 131 sha1_allowed); 132 size_t mdname_len = strlen(mdname); 133 134 if (md == NULL || md_nid < 0) { 135 if (md == NULL) 136 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 137 "%s could not be fetched", mdname); 138 if (md_nid < 0) 139 ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, 140 "digest=%s", mdname); 141 if (mdname_len >= sizeof(ctx->mdname)) 142 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 143 "%s exceeds name buffer length", mdname); 144 EVP_MD_free(md); 145 return 0; 146 } 147 148 if (!ctx->flag_allow_md) { 149 if (ctx->mdname[0] != '\0' && !EVP_MD_is_a(md, ctx->mdname)) { 150 ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, 151 "digest %s != %s", mdname, ctx->mdname); 152 EVP_MD_free(md); 153 return 0; 154 } 155 EVP_MD_free(md); 156 return 1; 157 } 158 159 EVP_MD_CTX_free(ctx->mdctx); 160 EVP_MD_free(ctx->md); 161 162 /* 163 * We do not care about DER writing errors. 164 * All it really means is that for some reason, there's no 165 * AlgorithmIdentifier to be had, but the operation itself is 166 * still valid, just as long as it's not used to construct 167 * anything that needs an AlgorithmIdentifier. 168 */ 169 ctx->aid_len = 0; 170 if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) 171 && ossl_DER_w_algorithmIdentifier_DSA_with_MD(&pkt, -1, ctx->dsa, 172 md_nid) 173 && WPACKET_finish(&pkt)) { 174 WPACKET_get_total_written(&pkt, &ctx->aid_len); 175 ctx->aid = WPACKET_get_curr(&pkt); 176 } 177 WPACKET_cleanup(&pkt); 178 179 ctx->mdctx = NULL; 180 ctx->md = md; 181 OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname)); 182 } 183 return 1; 184 } 185 186 static int dsa_signverify_init(void *vpdsactx, void *vdsa, 187 const OSSL_PARAM params[], int operation) 188 { 189 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 190 191 if (!ossl_prov_is_running() 192 || pdsactx == NULL) 193 return 0; 194 195 if (vdsa == NULL && pdsactx->dsa == NULL) { 196 ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); 197 return 0; 198 } 199 200 if (vdsa != NULL) { 201 if (!ossl_dsa_check_key(pdsactx->libctx, vdsa, 202 operation == EVP_PKEY_OP_SIGN)) { 203 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); 204 return 0; 205 } 206 if (!DSA_up_ref(vdsa)) 207 return 0; 208 DSA_free(pdsactx->dsa); 209 pdsactx->dsa = vdsa; 210 } 211 212 pdsactx->operation = operation; 213 214 if (!dsa_set_ctx_params(pdsactx, params)) 215 return 0; 216 217 return 1; 218 } 219 220 static int dsa_sign_init(void *vpdsactx, void *vdsa, const OSSL_PARAM params[]) 221 { 222 return dsa_signverify_init(vpdsactx, vdsa, params, EVP_PKEY_OP_SIGN); 223 } 224 225 static int dsa_verify_init(void *vpdsactx, void *vdsa, 226 const OSSL_PARAM params[]) 227 { 228 return dsa_signverify_init(vpdsactx, vdsa, params, EVP_PKEY_OP_VERIFY); 229 } 230 231 static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen, 232 size_t sigsize, const unsigned char *tbs, size_t tbslen) 233 { 234 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 235 int ret; 236 unsigned int sltmp; 237 size_t dsasize = DSA_size(pdsactx->dsa); 238 size_t mdsize = dsa_get_md_size(pdsactx); 239 240 if (!ossl_prov_is_running()) 241 return 0; 242 243 if (sig == NULL) { 244 *siglen = dsasize; 245 return 1; 246 } 247 248 if (sigsize < (size_t)dsasize) 249 return 0; 250 251 if (mdsize != 0 && tbslen != mdsize) 252 return 0; 253 254 ret = ossl_dsa_sign_int(0, tbs, tbslen, sig, &sltmp, pdsactx->dsa); 255 if (ret <= 0) 256 return 0; 257 258 *siglen = sltmp; 259 return 1; 260 } 261 262 static int dsa_verify(void *vpdsactx, const unsigned char *sig, size_t siglen, 263 const unsigned char *tbs, size_t tbslen) 264 { 265 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 266 size_t mdsize = dsa_get_md_size(pdsactx); 267 268 if (!ossl_prov_is_running() || (mdsize != 0 && tbslen != mdsize)) 269 return 0; 270 271 return DSA_verify(0, tbs, tbslen, sig, siglen, pdsactx->dsa); 272 } 273 274 static int dsa_digest_signverify_init(void *vpdsactx, const char *mdname, 275 void *vdsa, const OSSL_PARAM params[], 276 int operation) 277 { 278 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 279 280 if (!ossl_prov_is_running()) 281 return 0; 282 283 if (!dsa_signverify_init(vpdsactx, vdsa, params, operation)) 284 return 0; 285 286 if (!dsa_setup_md(pdsactx, mdname, NULL)) 287 return 0; 288 289 pdsactx->flag_allow_md = 0; 290 291 if (pdsactx->mdctx == NULL) { 292 pdsactx->mdctx = EVP_MD_CTX_new(); 293 if (pdsactx->mdctx == NULL) 294 goto error; 295 } 296 297 if (!EVP_DigestInit_ex2(pdsactx->mdctx, pdsactx->md, params)) 298 goto error; 299 300 return 1; 301 302 error: 303 EVP_MD_CTX_free(pdsactx->mdctx); 304 pdsactx->mdctx = NULL; 305 return 0; 306 } 307 308 static int dsa_digest_sign_init(void *vpdsactx, const char *mdname, 309 void *vdsa, const OSSL_PARAM params[]) 310 { 311 return dsa_digest_signverify_init(vpdsactx, mdname, vdsa, params, 312 EVP_PKEY_OP_SIGN); 313 } 314 315 static int dsa_digest_verify_init(void *vpdsactx, const char *mdname, 316 void *vdsa, const OSSL_PARAM params[]) 317 { 318 return dsa_digest_signverify_init(vpdsactx, mdname, vdsa, params, 319 EVP_PKEY_OP_VERIFY); 320 } 321 322 int dsa_digest_signverify_update(void *vpdsactx, const unsigned char *data, 323 size_t datalen) 324 { 325 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 326 327 if (pdsactx == NULL || pdsactx->mdctx == NULL) 328 return 0; 329 330 return EVP_DigestUpdate(pdsactx->mdctx, data, datalen); 331 } 332 333 int dsa_digest_sign_final(void *vpdsactx, unsigned char *sig, size_t *siglen, 334 size_t sigsize) 335 { 336 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 337 unsigned char digest[EVP_MAX_MD_SIZE]; 338 unsigned int dlen = 0; 339 340 if (!ossl_prov_is_running() || pdsactx == NULL || pdsactx->mdctx == NULL) 341 return 0; 342 343 /* 344 * If sig is NULL then we're just finding out the sig size. Other fields 345 * are ignored. Defer to dsa_sign. 346 */ 347 if (sig != NULL) { 348 /* 349 * There is the possibility that some externally provided 350 * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow - 351 * but that problem is much larger than just in DSA. 352 */ 353 if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen)) 354 return 0; 355 } 356 357 pdsactx->flag_allow_md = 1; 358 359 return dsa_sign(vpdsactx, sig, siglen, sigsize, digest, (size_t)dlen); 360 } 361 362 363 int dsa_digest_verify_final(void *vpdsactx, const unsigned char *sig, 364 size_t siglen) 365 { 366 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 367 unsigned char digest[EVP_MAX_MD_SIZE]; 368 unsigned int dlen = 0; 369 370 if (!ossl_prov_is_running() || pdsactx == NULL || pdsactx->mdctx == NULL) 371 return 0; 372 373 /* 374 * There is the possibility that some externally provided 375 * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow - 376 * but that problem is much larger than just in DSA. 377 */ 378 if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen)) 379 return 0; 380 381 pdsactx->flag_allow_md = 1; 382 383 return dsa_verify(vpdsactx, sig, siglen, digest, (size_t)dlen); 384 } 385 386 static void dsa_freectx(void *vpdsactx) 387 { 388 PROV_DSA_CTX *ctx = (PROV_DSA_CTX *)vpdsactx; 389 390 OPENSSL_free(ctx->propq); 391 EVP_MD_CTX_free(ctx->mdctx); 392 EVP_MD_free(ctx->md); 393 ctx->propq = NULL; 394 ctx->mdctx = NULL; 395 ctx->md = NULL; 396 DSA_free(ctx->dsa); 397 OPENSSL_free(ctx); 398 } 399 400 static void *dsa_dupctx(void *vpdsactx) 401 { 402 PROV_DSA_CTX *srcctx = (PROV_DSA_CTX *)vpdsactx; 403 PROV_DSA_CTX *dstctx; 404 405 if (!ossl_prov_is_running()) 406 return NULL; 407 408 dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 409 if (dstctx == NULL) 410 return NULL; 411 412 *dstctx = *srcctx; 413 dstctx->dsa = NULL; 414 dstctx->md = NULL; 415 dstctx->mdctx = NULL; 416 dstctx->propq = NULL; 417 418 if (srcctx->dsa != NULL && !DSA_up_ref(srcctx->dsa)) 419 goto err; 420 dstctx->dsa = srcctx->dsa; 421 422 if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md)) 423 goto err; 424 dstctx->md = srcctx->md; 425 426 if (srcctx->mdctx != NULL) { 427 dstctx->mdctx = EVP_MD_CTX_new(); 428 if (dstctx->mdctx == NULL 429 || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx)) 430 goto err; 431 } 432 if (srcctx->propq != NULL) { 433 dstctx->propq = OPENSSL_strdup(srcctx->propq); 434 if (dstctx->propq == NULL) 435 goto err; 436 } 437 438 return dstctx; 439 err: 440 dsa_freectx(dstctx); 441 return NULL; 442 } 443 444 static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params) 445 { 446 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 447 OSSL_PARAM *p; 448 449 if (pdsactx == NULL) 450 return 0; 451 452 p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); 453 if (p != NULL 454 && !OSSL_PARAM_set_octet_string(p, pdsactx->aid, pdsactx->aid_len)) 455 return 0; 456 457 p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST); 458 if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdsactx->mdname)) 459 return 0; 460 461 return 1; 462 } 463 464 static const OSSL_PARAM known_gettable_ctx_params[] = { 465 OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), 466 OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), 467 OSSL_PARAM_END 468 }; 469 470 static const OSSL_PARAM *dsa_gettable_ctx_params(ossl_unused void *ctx, 471 ossl_unused void *provctx) 472 { 473 return known_gettable_ctx_params; 474 } 475 476 static int dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[]) 477 { 478 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 479 const OSSL_PARAM *p; 480 481 if (pdsactx == NULL) 482 return 0; 483 if (params == NULL) 484 return 1; 485 486 p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); 487 if (p != NULL) { 488 char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname; 489 char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops; 490 const OSSL_PARAM *propsp = 491 OSSL_PARAM_locate_const(params, 492 OSSL_SIGNATURE_PARAM_PROPERTIES); 493 494 if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) 495 return 0; 496 if (propsp != NULL 497 && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops))) 498 return 0; 499 if (!dsa_setup_md(pdsactx, mdname, mdprops)) 500 return 0; 501 } 502 503 return 1; 504 } 505 506 static const OSSL_PARAM settable_ctx_params[] = { 507 OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), 508 OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), 509 OSSL_PARAM_END 510 }; 511 512 static const OSSL_PARAM settable_ctx_params_no_digest[] = { 513 OSSL_PARAM_END 514 }; 515 516 static const OSSL_PARAM *dsa_settable_ctx_params(void *vpdsactx, 517 ossl_unused void *provctx) 518 { 519 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 520 521 if (pdsactx != NULL && !pdsactx->flag_allow_md) 522 return settable_ctx_params_no_digest; 523 return settable_ctx_params; 524 } 525 526 static int dsa_get_ctx_md_params(void *vpdsactx, OSSL_PARAM *params) 527 { 528 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 529 530 if (pdsactx->mdctx == NULL) 531 return 0; 532 533 return EVP_MD_CTX_get_params(pdsactx->mdctx, params); 534 } 535 536 static const OSSL_PARAM *dsa_gettable_ctx_md_params(void *vpdsactx) 537 { 538 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 539 540 if (pdsactx->md == NULL) 541 return 0; 542 543 return EVP_MD_gettable_ctx_params(pdsactx->md); 544 } 545 546 static int dsa_set_ctx_md_params(void *vpdsactx, const OSSL_PARAM params[]) 547 { 548 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 549 550 if (pdsactx->mdctx == NULL) 551 return 0; 552 553 return EVP_MD_CTX_set_params(pdsactx->mdctx, params); 554 } 555 556 static const OSSL_PARAM *dsa_settable_ctx_md_params(void *vpdsactx) 557 { 558 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; 559 560 if (pdsactx->md == NULL) 561 return 0; 562 563 return EVP_MD_settable_ctx_params(pdsactx->md); 564 } 565 566 const OSSL_DISPATCH ossl_dsa_signature_functions[] = { 567 { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx }, 568 { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_sign_init }, 569 { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))dsa_sign }, 570 { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))dsa_verify_init }, 571 { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))dsa_verify }, 572 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, 573 (void (*)(void))dsa_digest_sign_init }, 574 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, 575 (void (*)(void))dsa_digest_signverify_update }, 576 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, 577 (void (*)(void))dsa_digest_sign_final }, 578 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, 579 (void (*)(void))dsa_digest_verify_init }, 580 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, 581 (void (*)(void))dsa_digest_signverify_update }, 582 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, 583 (void (*)(void))dsa_digest_verify_final }, 584 { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx }, 585 { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx }, 586 { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))dsa_get_ctx_params }, 587 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, 588 (void (*)(void))dsa_gettable_ctx_params }, 589 { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))dsa_set_ctx_params }, 590 { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, 591 (void (*)(void))dsa_settable_ctx_params }, 592 { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, 593 (void (*)(void))dsa_get_ctx_md_params }, 594 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, 595 (void (*)(void))dsa_gettable_ctx_md_params }, 596 { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, 597 (void (*)(void))dsa_set_ctx_md_params }, 598 { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, 599 (void (*)(void))dsa_settable_ctx_md_params }, 600 { 0, NULL } 601 }; 602