]> git.ipfire.org Git - thirdparty/openssl.git/blob - providers/common/provider_util.c
a409d717f96bc86d54c8b8ad74affe6c6c6e8ad8
[thirdparty/openssl.git] / providers / common / provider_util.c
1 /*
2 * Copyright 2019-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/evp.h>
11 #include <openssl/core_names.h>
12 #include <openssl/err.h>
13 #include "prov/provider_util.h"
14
15 void ossl_prov_cipher_reset(PROV_CIPHER *pc)
16 {
17 EVP_CIPHER_free(pc->alloc_cipher);
18 pc->alloc_cipher = NULL;
19 pc->cipher = NULL;
20 pc->engine = NULL;
21 }
22
23 int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src)
24 {
25 if (src->alloc_cipher != NULL && !EVP_CIPHER_up_ref(src->alloc_cipher))
26 return 0;
27 dst->engine = src->engine;
28 dst->cipher = src->cipher;
29 dst->alloc_cipher = src->alloc_cipher;
30 return 1;
31 }
32
33 static int load_common(const OSSL_PARAM params[], const char **propquery,
34 ENGINE **engine)
35 {
36 const OSSL_PARAM *p;
37
38 *propquery = NULL;
39 p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_PROPERTIES);
40 if (p != NULL) {
41 if (p->data_type != OSSL_PARAM_UTF8_STRING)
42 return 0;
43 *propquery = p->data;
44 }
45
46 *engine = NULL;
47 /* TODO legacy stuff, to be removed */
48 /* Inside the FIPS module, we don't support legacy ciphers */
49 #if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
50 p = OSSL_PARAM_locate_const(params, "engine");
51 if (p != NULL) {
52 if (p->data_type != OSSL_PARAM_UTF8_STRING)
53 return 0;
54 ENGINE_finish(*engine);
55 *engine = ENGINE_by_id(p->data);
56 if (*engine == NULL)
57 return 0;
58 }
59 #endif
60 return 1;
61 }
62
63 int ossl_prov_cipher_load_from_params(PROV_CIPHER *pc,
64 const OSSL_PARAM params[],
65 OPENSSL_CTX *ctx)
66 {
67 const OSSL_PARAM *p;
68 const char *propquery;
69
70 if (!load_common(params, &propquery, &pc->engine))
71 return 0;
72
73 p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_CIPHER);
74 if (p == NULL)
75 return 1;
76 if (p->data_type != OSSL_PARAM_UTF8_STRING)
77 return 0;
78
79 EVP_CIPHER_free(pc->alloc_cipher);
80 ERR_set_mark();
81 pc->cipher = pc->alloc_cipher = EVP_CIPHER_fetch(ctx, p->data, propquery);
82 /* TODO legacy stuff, to be removed */
83 #ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy ciphers */
84 if (pc->cipher == NULL)
85 pc->cipher = EVP_get_cipherbyname(p->data);
86 #endif
87 if (pc->cipher != NULL)
88 ERR_pop_to_mark();
89 else
90 ERR_clear_last_mark();
91 return pc->cipher != NULL;
92 }
93
94 const EVP_CIPHER *ossl_prov_cipher_cipher(const PROV_CIPHER *pc)
95 {
96 return pc->cipher;
97 }
98
99 ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc)
100 {
101 return pc->engine;
102 }
103
104 void ossl_prov_digest_reset(PROV_DIGEST *pd)
105 {
106 EVP_MD_free(pd->alloc_md);
107 pd->alloc_md = NULL;
108 pd->md = NULL;
109 pd->engine = NULL;
110 }
111
112 int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src)
113 {
114 if (src->alloc_md != NULL && !EVP_MD_up_ref(src->alloc_md))
115 return 0;
116 dst->engine = src->engine;
117 dst->md = src->md;
118 dst->alloc_md = src->alloc_md;
119 return 1;
120 }
121
122 int ossl_prov_digest_load_from_params(PROV_DIGEST *pd,
123 const OSSL_PARAM params[],
124 OPENSSL_CTX *ctx)
125 {
126 const OSSL_PARAM *p;
127 const char *propquery;
128
129 if (!load_common(params, &propquery, &pd->engine))
130 return 0;
131
132
133 p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST);
134 if (p == NULL)
135 return 1;
136 if (p->data_type != OSSL_PARAM_UTF8_STRING)
137 return 0;
138
139 EVP_MD_free(pd->alloc_md);
140 ERR_set_mark();
141 pd->md = pd->alloc_md = EVP_MD_fetch(ctx, p->data, propquery);
142 /* TODO legacy stuff, to be removed */
143 #ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy digests */
144 if (pd->md == NULL)
145 pd->md = EVP_get_digestbyname(p->data);
146 #endif
147 if (pd->md != NULL)
148 ERR_pop_to_mark();
149 else
150 ERR_clear_last_mark();
151 return pd->md != NULL;
152 }
153
154 const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd)
155 {
156 return pd->md;
157 }
158
159 ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd)
160 {
161 return pd->engine;
162 }
163
164 int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
165 const OSSL_PARAM params[],
166 const char *macname,
167 const char *ciphername,
168 const char *mdname,
169 OPENSSL_CTX *libctx)
170 {
171 const OSSL_PARAM *p;
172 OSSL_PARAM mac_params[5], *mp = mac_params;
173 const char *properties = NULL;
174
175 if (macname == NULL
176 && (p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_MAC)) != NULL) {
177 if (p->data_type != OSSL_PARAM_UTF8_STRING)
178 return 0;
179 macname = p->data;
180 }
181 if ((p = OSSL_PARAM_locate_const(params,
182 OSSL_ALG_PARAM_PROPERTIES)) != NULL) {
183 if (p->data_type != OSSL_PARAM_UTF8_STRING)
184 return 0;
185 properties = p->data;
186 }
187
188 /* If we got a new mac name, we make a new EVP_MAC_CTX */
189 if (macname != NULL) {
190 EVP_MAC *mac = EVP_MAC_fetch(libctx, macname, properties);
191
192 EVP_MAC_CTX_free(*macctx);
193 *macctx = mac == NULL ? NULL : EVP_MAC_CTX_new(mac);
194 /* The context holds on to the MAC */
195 EVP_MAC_free(mac);
196 if (*macctx == NULL)
197 return 0;
198 }
199
200 /*
201 * If there is no MAC yet (and therefore, no MAC context), we ignore
202 * all other parameters.
203 */
204 if (*macctx == NULL)
205 return 1;
206
207 if (mdname == NULL) {
208 if ((p = OSSL_PARAM_locate_const(params,
209 OSSL_ALG_PARAM_DIGEST)) != NULL) {
210 if (p->data_type != OSSL_PARAM_UTF8_STRING)
211 return 0;
212 mdname = p->data;
213 }
214 }
215 if (ciphername == NULL) {
216 if ((p = OSSL_PARAM_locate_const(params,
217 OSSL_ALG_PARAM_CIPHER)) != NULL) {
218 if (p->data_type != OSSL_PARAM_UTF8_STRING)
219 return 0;
220 ciphername = p->data;
221 }
222 }
223
224 if (mdname != NULL)
225 *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
226 (char *)mdname, 0);
227 if (ciphername != NULL)
228 *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
229 (char *)ciphername, 0);
230 if (properties != NULL)
231 *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES,
232 (char *)properties, 0);
233
234 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
235 if ((p = OSSL_PARAM_locate_const(params, "engine")) != NULL) {
236 if (p->data_type != OSSL_PARAM_UTF8_STRING)
237 return 0;
238 *mp++ = OSSL_PARAM_construct_utf8_string("engine",
239 p->data, p->data_size);
240 }
241 #endif
242 *mp = OSSL_PARAM_construct_end();
243
244 if (EVP_MAC_CTX_set_params(*macctx, mac_params))
245 return 1;
246
247 EVP_MAC_CTX_free(*macctx);
248 *macctx = NULL;
249 return 0;
250 }
251
252 void ossl_prov_cache_exported_algorithms(const OSSL_ALGORITHM_CAPABLE *in,
253 OSSL_ALGORITHM *out)
254 {
255 int i, j;
256
257 if (out[0].algorithm_names == NULL) {
258 for (i = j = 0; in[i].alg.algorithm_names != NULL; ++i) {
259 if (in[i].capable == NULL || in[i].capable())
260 out[j++] = in[i].alg;
261 }
262 out[j++] = in[i].alg;
263 }
264 }