]> git.ipfire.org Git - thirdparty/openssl.git/blame - providers/implementations/asymciphers/sm2_enc.c
Rename OPENSSL_CTX prefix to OSSL_LIB_CTX
[thirdparty/openssl.git] / providers / implementations / asymciphers / sm2_enc.c
CommitLineData
ce64d3ee
MC
1/*
2 * Copyright 2020 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#include <openssl/crypto.h>
11#include <openssl/evp.h>
12#include <openssl/core_dispatch.h>
13#include <openssl/core_names.h>
14#include <openssl/params.h>
15#include <openssl/err.h>
16#include <crypto/sm2.h>
17#include "prov/providercommonerr.h"
18#include "prov/provider_ctx.h"
19#include "prov/implementations.h"
20#include "prov/provider_util.h"
21
22static OSSL_FUNC_asym_cipher_newctx_fn sm2_newctx;
23static OSSL_FUNC_asym_cipher_encrypt_init_fn sm2_init;
24static OSSL_FUNC_asym_cipher_encrypt_fn sm2_asym_encrypt;
25static OSSL_FUNC_asym_cipher_decrypt_init_fn sm2_init;
26static OSSL_FUNC_asym_cipher_decrypt_fn sm2_asym_decrypt;
27static OSSL_FUNC_asym_cipher_freectx_fn sm2_freectx;
28static OSSL_FUNC_asym_cipher_dupctx_fn sm2_dupctx;
29static OSSL_FUNC_asym_cipher_get_ctx_params_fn sm2_get_ctx_params;
30static OSSL_FUNC_asym_cipher_gettable_ctx_params_fn sm2_gettable_ctx_params;
31static OSSL_FUNC_asym_cipher_set_ctx_params_fn sm2_set_ctx_params;
32static OSSL_FUNC_asym_cipher_settable_ctx_params_fn sm2_settable_ctx_params;
33
34/*
35 * What's passed as an actual key is defined by the KEYMGMT interface.
36 * We happen to know that our KEYMGMT simply passes EC_KEY structures, so
37 * we use that here too.
38 */
39
40typedef struct {
b4250010 41 OSSL_LIB_CTX *libctx;
ce64d3ee
MC
42 EC_KEY *key;
43 PROV_DIGEST md;
44} PROV_SM2_CTX;
45
46static void *sm2_newctx(void *provctx)
47{
48 PROV_SM2_CTX *psm2ctx = OPENSSL_zalloc(sizeof(PROV_SM2_CTX));
49
50 if (psm2ctx == NULL)
51 return NULL;
52 psm2ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
53
54 return psm2ctx;
55}
56
57static int sm2_init(void *vpsm2ctx, void *vkey)
58{
59 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
60
61 if (psm2ctx == NULL || vkey == NULL || !EC_KEY_up_ref(vkey))
62 return 0;
63 EC_KEY_free(psm2ctx->key);
64 psm2ctx->key = vkey;
65
66 return 1;
67}
68
69static const EVP_MD *sm2_get_md(PROV_SM2_CTX *psm2ctx)
70{
71 const EVP_MD *md = ossl_prov_digest_md(&psm2ctx->md);
72
73 if (md == NULL)
74 md = ossl_prov_digest_fetch(&psm2ctx->md, psm2ctx->libctx, "SM3", NULL);
75
76 return md;
77}
78
79static int sm2_asym_encrypt(void *vpsm2ctx, unsigned char *out, size_t *outlen,
80 size_t outsize, const unsigned char *in,
81 size_t inlen)
82{
83 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
84 const EVP_MD *md = sm2_get_md(psm2ctx);
85
86 if (md == NULL)
87 return 0;
88
89 if (out == NULL) {
90 if (!sm2_ciphertext_size(psm2ctx->key, md, inlen, outlen)) {
91 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
92 return 0;
93 }
94 return 1;
95 }
96
97 return sm2_encrypt(psm2ctx->key, md, in, inlen, out, outlen);
98}
99
100static int sm2_asym_decrypt(void *vpsm2ctx, unsigned char *out, size_t *outlen,
101 size_t outsize, const unsigned char *in,
102 size_t inlen)
103{
104 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
105 const EVP_MD *md = sm2_get_md(psm2ctx);
106
107 if (md == NULL)
108 return 0;
109
110 if (out == NULL) {
111 if (!sm2_plaintext_size(psm2ctx->key, md, inlen, outlen))
112 return 0;
113 return 1;
114 }
115
116 return sm2_decrypt(psm2ctx->key, md, in, inlen, out, outlen);
117}
118
119static void sm2_freectx(void *vpsm2ctx)
120{
121 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
122
123 EC_KEY_free(psm2ctx->key);
124 ossl_prov_digest_reset(&psm2ctx->md);
125
126 OPENSSL_free(psm2ctx);
127}
128
129static void *sm2_dupctx(void *vpsm2ctx)
130{
131 PROV_SM2_CTX *srcctx = (PROV_SM2_CTX *)vpsm2ctx;
132 PROV_SM2_CTX *dstctx;
133
134 dstctx = OPENSSL_zalloc(sizeof(*srcctx));
135 if (dstctx == NULL)
136 return NULL;
137
138 *dstctx = *srcctx;
139 if (dstctx->key != NULL && !EC_KEY_up_ref(dstctx->key)) {
140 OPENSSL_free(dstctx);
141 return NULL;
142 }
143
144 if (!ossl_prov_digest_copy(&dstctx->md, &srcctx->md)) {
145 sm2_freectx(dstctx);
146 return NULL;
147 }
148
149 return dstctx;
150}
151
152static int sm2_get_ctx_params(void *vpsm2ctx, OSSL_PARAM *params)
153{
154 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
155 OSSL_PARAM *p;
156
157 if (vpsm2ctx == NULL || params == NULL)
158 return 0;
159
160 p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_DIGEST);
161 if (p != NULL) {
162 const EVP_MD *md = ossl_prov_digest_md(&psm2ctx->md);
163
164 if (!OSSL_PARAM_set_utf8_string(p, md == NULL ? ""
165 : EVP_MD_name(md)))
166 return 0;
167 }
168
169 return 1;
170}
171
172static const OSSL_PARAM known_gettable_ctx_params[] = {
173 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_DIGEST, NULL, 0),
174 OSSL_PARAM_END
175};
176
177static const OSSL_PARAM *sm2_gettable_ctx_params(ossl_unused void *provctx)
178{
179 return known_gettable_ctx_params;
180}
181
182static int sm2_set_ctx_params(void *vpsm2ctx, const OSSL_PARAM params[])
183{
184 PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx;
185
186 if (psm2ctx == NULL || params == NULL)
187 return 0;
188
189 if (!ossl_prov_digest_load_from_params(&psm2ctx->md, params,
190 psm2ctx->libctx))
191 return 0;
192
193 return 1;
194}
195
196static const OSSL_PARAM known_settable_ctx_params[] = {
197 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_DIGEST, NULL, 0),
198 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PROPERTIES, NULL, 0),
199 OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_ENGINE, NULL, 0),
200 OSSL_PARAM_END
201};
202
203static const OSSL_PARAM *sm2_settable_ctx_params(ossl_unused void *provctx)
204{
205 return known_settable_ctx_params;
206}
207
208const OSSL_DISPATCH sm2_asym_cipher_functions[] = {
209 { OSSL_FUNC_ASYM_CIPHER_NEWCTX, (void (*)(void))sm2_newctx },
210 { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, (void (*)(void))sm2_init },
211 { OSSL_FUNC_ASYM_CIPHER_ENCRYPT, (void (*)(void))sm2_asym_encrypt },
212 { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, (void (*)(void))sm2_init },
213 { OSSL_FUNC_ASYM_CIPHER_DECRYPT, (void (*)(void))sm2_asym_decrypt },
214 { OSSL_FUNC_ASYM_CIPHER_FREECTX, (void (*)(void))sm2_freectx },
215 { OSSL_FUNC_ASYM_CIPHER_DUPCTX, (void (*)(void))sm2_dupctx },
216 { OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS,
217 (void (*)(void))sm2_get_ctx_params },
218 { OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS,
219 (void (*)(void))sm2_gettable_ctx_params },
220 { OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS,
221 (void (*)(void))sm2_set_ctx_params },
222 { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS,
223 (void (*)(void))sm2_settable_ctx_params },
224 { 0, NULL }
225};