2 * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
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
10 #include "internal/deprecated.h"
12 #include <openssl/crypto.h>
13 #include <openssl/evp.h>
14 #include <openssl/core_dispatch.h>
15 #include <openssl/core_names.h>
16 #include <openssl/params.h>
17 #include <openssl/err.h>
18 #include <openssl/proverr.h>
19 #include "crypto/sm2.h"
20 #include "prov/provider_ctx.h"
21 #include "prov/implementations.h"
22 #include "prov/provider_util.h"
24 static OSSL_FUNC_asym_cipher_newctx_fn sm2_newctx
;
25 static OSSL_FUNC_asym_cipher_encrypt_init_fn sm2_init
;
26 static OSSL_FUNC_asym_cipher_encrypt_fn sm2_asym_encrypt
;
27 static OSSL_FUNC_asym_cipher_decrypt_init_fn sm2_init
;
28 static OSSL_FUNC_asym_cipher_decrypt_fn sm2_asym_decrypt
;
29 static OSSL_FUNC_asym_cipher_freectx_fn sm2_freectx
;
30 static OSSL_FUNC_asym_cipher_dupctx_fn sm2_dupctx
;
31 static OSSL_FUNC_asym_cipher_get_ctx_params_fn sm2_get_ctx_params
;
32 static OSSL_FUNC_asym_cipher_gettable_ctx_params_fn sm2_gettable_ctx_params
;
33 static OSSL_FUNC_asym_cipher_set_ctx_params_fn sm2_set_ctx_params
;
34 static OSSL_FUNC_asym_cipher_settable_ctx_params_fn sm2_settable_ctx_params
;
37 * What's passed as an actual key is defined by the KEYMGMT interface.
38 * We happen to know that our KEYMGMT simply passes EC_KEY structures, so
39 * we use that here too.
48 static void *sm2_newctx(void *provctx
)
50 PROV_SM2_CTX
*psm2ctx
= OPENSSL_zalloc(sizeof(PROV_SM2_CTX
));
54 psm2ctx
->libctx
= PROV_LIBCTX_OF(provctx
);
59 static int sm2_init(void *vpsm2ctx
, void *vkey
, const OSSL_PARAM params
[])
61 PROV_SM2_CTX
*psm2ctx
= (PROV_SM2_CTX
*)vpsm2ctx
;
63 if (psm2ctx
== NULL
|| vkey
== NULL
|| !EC_KEY_up_ref(vkey
))
65 EC_KEY_free(psm2ctx
->key
);
68 return sm2_set_ctx_params(psm2ctx
, params
);
71 static const EVP_MD
*sm2_get_md(PROV_SM2_CTX
*psm2ctx
)
73 const EVP_MD
*md
= ossl_prov_digest_md(&psm2ctx
->md
);
76 md
= ossl_prov_digest_fetch(&psm2ctx
->md
, psm2ctx
->libctx
, "SM3", NULL
);
81 static int sm2_asym_encrypt(void *vpsm2ctx
, unsigned char *out
, size_t *outlen
,
82 size_t outsize
, const unsigned char *in
,
85 PROV_SM2_CTX
*psm2ctx
= (PROV_SM2_CTX
*)vpsm2ctx
;
86 const EVP_MD
*md
= sm2_get_md(psm2ctx
);
92 if (!ossl_sm2_ciphertext_size(psm2ctx
->key
, md
, inlen
, outlen
)) {
93 ERR_raise(ERR_LIB_PROV
, PROV_R_INVALID_KEY
);
99 return ossl_sm2_encrypt(psm2ctx
->key
, md
, in
, inlen
, out
, outlen
);
102 static int sm2_asym_decrypt(void *vpsm2ctx
, unsigned char *out
, size_t *outlen
,
103 size_t outsize
, const unsigned char *in
,
106 PROV_SM2_CTX
*psm2ctx
= (PROV_SM2_CTX
*)vpsm2ctx
;
107 const EVP_MD
*md
= sm2_get_md(psm2ctx
);
113 if (!ossl_sm2_plaintext_size(in
, inlen
, outlen
))
118 return ossl_sm2_decrypt(psm2ctx
->key
, md
, in
, inlen
, out
, outlen
);
121 static void sm2_freectx(void *vpsm2ctx
)
123 PROV_SM2_CTX
*psm2ctx
= (PROV_SM2_CTX
*)vpsm2ctx
;
125 EC_KEY_free(psm2ctx
->key
);
126 ossl_prov_digest_reset(&psm2ctx
->md
);
128 OPENSSL_free(psm2ctx
);
131 static void *sm2_dupctx(void *vpsm2ctx
)
133 PROV_SM2_CTX
*srcctx
= (PROV_SM2_CTX
*)vpsm2ctx
;
134 PROV_SM2_CTX
*dstctx
;
136 dstctx
= OPENSSL_zalloc(sizeof(*srcctx
));
141 if (dstctx
->key
!= NULL
&& !EC_KEY_up_ref(dstctx
->key
)) {
142 OPENSSL_free(dstctx
);
146 if (!ossl_prov_digest_copy(&dstctx
->md
, &srcctx
->md
)) {
154 static int sm2_get_ctx_params(void *vpsm2ctx
, OSSL_PARAM
*params
)
156 PROV_SM2_CTX
*psm2ctx
= (PROV_SM2_CTX
*)vpsm2ctx
;
159 if (vpsm2ctx
== NULL
)
162 p
= OSSL_PARAM_locate(params
, OSSL_ASYM_CIPHER_PARAM_DIGEST
);
164 const EVP_MD
*md
= ossl_prov_digest_md(&psm2ctx
->md
);
166 if (!OSSL_PARAM_set_utf8_string(p
, md
== NULL
? ""
167 : EVP_MD_get0_name(md
)))
174 static const OSSL_PARAM known_gettable_ctx_params
[] = {
175 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_DIGEST
, NULL
, 0),
179 static const OSSL_PARAM
*sm2_gettable_ctx_params(ossl_unused
void *vpsm2ctx
,
180 ossl_unused
void *provctx
)
182 return known_gettable_ctx_params
;
185 static int sm2_set_ctx_params(void *vpsm2ctx
, const OSSL_PARAM params
[])
187 PROV_SM2_CTX
*psm2ctx
= (PROV_SM2_CTX
*)vpsm2ctx
;
194 if (!ossl_prov_digest_load_from_params(&psm2ctx
->md
, params
,
201 static const OSSL_PARAM known_settable_ctx_params
[] = {
202 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_DIGEST
, NULL
, 0),
203 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PROPERTIES
, NULL
, 0),
204 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_ENGINE
, NULL
, 0),
208 static const OSSL_PARAM
*sm2_settable_ctx_params(ossl_unused
void *vpsm2ctx
,
209 ossl_unused
void *provctx
)
211 return known_settable_ctx_params
;
214 const OSSL_DISPATCH ossl_sm2_asym_cipher_functions
[] = {
215 { OSSL_FUNC_ASYM_CIPHER_NEWCTX
, (void (*)(void))sm2_newctx
},
216 { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT
, (void (*)(void))sm2_init
},
217 { OSSL_FUNC_ASYM_CIPHER_ENCRYPT
, (void (*)(void))sm2_asym_encrypt
},
218 { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT
, (void (*)(void))sm2_init
},
219 { OSSL_FUNC_ASYM_CIPHER_DECRYPT
, (void (*)(void))sm2_asym_decrypt
},
220 { OSSL_FUNC_ASYM_CIPHER_FREECTX
, (void (*)(void))sm2_freectx
},
221 { OSSL_FUNC_ASYM_CIPHER_DUPCTX
, (void (*)(void))sm2_dupctx
},
222 { OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS
,
223 (void (*)(void))sm2_get_ctx_params
},
224 { OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS
,
225 (void (*)(void))sm2_gettable_ctx_params
},
226 { OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS
,
227 (void (*)(void))sm2_set_ctx_params
},
228 { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS
,
229 (void (*)(void))sm2_settable_ctx_params
},