Coverage Report

Created: 2026-10-28 06:28

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