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