2 * Copyright 2019-2020 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 /* We need to use some engine deprecated APIs */
11 #define OPENSSL_SUPPRESS_DEPRECATED
13 #include <openssl/evp.h>
14 #include <openssl/core_names.h>
15 #include <openssl/err.h>
16 #include "prov/provider_util.h"
17 #include "prov/providercommonerr.h"
18 #include "internal/nelem.h"
20 void ossl_prov_cipher_reset(PROV_CIPHER
*pc
)
22 EVP_CIPHER_free(pc
->alloc_cipher
);
23 pc
->alloc_cipher
= NULL
;
28 int ossl_prov_cipher_copy(PROV_CIPHER
*dst
, const PROV_CIPHER
*src
)
30 if (src
->alloc_cipher
!= NULL
&& !EVP_CIPHER_up_ref(src
->alloc_cipher
))
32 dst
->engine
= src
->engine
;
33 dst
->cipher
= src
->cipher
;
34 dst
->alloc_cipher
= src
->alloc_cipher
;
38 static int load_common(const OSSL_PARAM params
[], const char **propquery
,
44 p
= OSSL_PARAM_locate_const(params
, OSSL_ALG_PARAM_PROPERTIES
);
46 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
52 /* TODO legacy stuff, to be removed */
53 /* Inside the FIPS module, we don't support legacy ciphers */
54 #if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
55 p
= OSSL_PARAM_locate_const(params
, OSSL_ALG_PARAM_ENGINE
);
57 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
59 ENGINE_finish(*engine
);
60 *engine
= ENGINE_by_id(p
->data
);
68 int ossl_prov_cipher_load_from_params(PROV_CIPHER
*pc
,
69 const OSSL_PARAM params
[],
73 const char *propquery
;
75 if (!load_common(params
, &propquery
, &pc
->engine
))
78 p
= OSSL_PARAM_locate_const(params
, OSSL_ALG_PARAM_CIPHER
);
81 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
84 EVP_CIPHER_free(pc
->alloc_cipher
);
86 pc
->cipher
= pc
->alloc_cipher
= EVP_CIPHER_fetch(ctx
, p
->data
, propquery
);
87 /* TODO legacy stuff, to be removed */
88 #ifndef FIPS_MODULE /* Inside the FIPS module, we don't support legacy ciphers */
89 if (pc
->cipher
== NULL
)
90 pc
->cipher
= EVP_get_cipherbyname(p
->data
);
92 if (pc
->cipher
!= NULL
)
95 ERR_clear_last_mark();
96 return pc
->cipher
!= NULL
;
99 const EVP_CIPHER
*ossl_prov_cipher_cipher(const PROV_CIPHER
*pc
)
104 ENGINE
*ossl_prov_cipher_engine(const PROV_CIPHER
*pc
)
109 void ossl_prov_digest_reset(PROV_DIGEST
*pd
)
111 EVP_MD_free(pd
->alloc_md
);
117 int ossl_prov_digest_copy(PROV_DIGEST
*dst
, const PROV_DIGEST
*src
)
119 if (src
->alloc_md
!= NULL
&& !EVP_MD_up_ref(src
->alloc_md
))
121 dst
->engine
= src
->engine
;
123 dst
->alloc_md
= src
->alloc_md
;
127 const EVP_MD
*ossl_prov_digest_fetch(PROV_DIGEST
*pd
, OPENSSL_CTX
*libctx
,
128 const char *mdname
, const char *propquery
)
130 EVP_MD_free(pd
->alloc_md
);
131 pd
->md
= pd
->alloc_md
= EVP_MD_fetch(libctx
, mdname
, propquery
);
136 int ossl_prov_digest_load_from_params(PROV_DIGEST
*pd
,
137 const OSSL_PARAM params
[],
141 const char *propquery
;
143 if (!load_common(params
, &propquery
, &pd
->engine
))
147 p
= OSSL_PARAM_locate_const(params
, OSSL_ALG_PARAM_DIGEST
);
150 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
154 ossl_prov_digest_fetch(pd
, ctx
, p
->data
, propquery
);
155 /* TODO legacy stuff, to be removed */
156 #ifndef FIPS_MODULE /* Inside the FIPS module, we don't support legacy digests */
158 pd
->md
= EVP_get_digestbyname(p
->data
);
163 ERR_clear_last_mark();
164 return pd
->md
!= NULL
;
167 const EVP_MD
*ossl_prov_digest_md(const PROV_DIGEST
*pd
)
172 ENGINE
*ossl_prov_digest_engine(const PROV_DIGEST
*pd
)
177 int ossl_prov_set_macctx(EVP_MAC_CTX
*macctx
,
178 const OSSL_PARAM params
[],
179 const char *ciphername
,
182 const char *properties
,
183 const unsigned char *key
,
187 OSSL_PARAM mac_params
[6], *mp
= mac_params
;
189 if (params
!= NULL
) {
190 if (mdname
== NULL
) {
191 if ((p
= OSSL_PARAM_locate_const(params
,
192 OSSL_ALG_PARAM_DIGEST
)) != NULL
) {
193 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
198 if (ciphername
== NULL
) {
199 if ((p
= OSSL_PARAM_locate_const(params
,
200 OSSL_ALG_PARAM_CIPHER
)) != NULL
) {
201 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
203 ciphername
= p
->data
;
206 if (engine
== NULL
) {
207 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_ALG_PARAM_ENGINE
))
209 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
217 *mp
++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST
,
219 if (ciphername
!= NULL
)
220 *mp
++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER
,
221 (char *)ciphername
, 0);
222 if (properties
!= NULL
)
223 *mp
++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES
,
224 (char *)properties
, 0);
226 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
228 *mp
++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_ENGINE
,
233 *mp
++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
234 (unsigned char *)key
,
237 *mp
= OSSL_PARAM_construct_end();
239 return EVP_MAC_CTX_set_params(macctx
, mac_params
);
243 int ossl_prov_macctx_load_from_params(EVP_MAC_CTX
**macctx
,
244 const OSSL_PARAM params
[],
246 const char *ciphername
,
251 const char *properties
= NULL
;
254 && (p
= OSSL_PARAM_locate_const(params
, OSSL_ALG_PARAM_MAC
)) != NULL
) {
255 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
259 if ((p
= OSSL_PARAM_locate_const(params
,
260 OSSL_ALG_PARAM_PROPERTIES
)) != NULL
) {
261 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
263 properties
= p
->data
;
266 /* If we got a new mac name, we make a new EVP_MAC_CTX */
267 if (macname
!= NULL
) {
268 EVP_MAC
*mac
= EVP_MAC_fetch(libctx
, macname
, properties
);
270 EVP_MAC_CTX_free(*macctx
);
271 *macctx
= mac
== NULL
? NULL
: EVP_MAC_CTX_new(mac
);
272 /* The context holds on to the MAC */
279 * If there is no MAC yet (and therefore, no MAC context), we ignore
280 * all other parameters.
285 if (ossl_prov_set_macctx(*macctx
, params
, ciphername
, mdname
, NULL
,
286 properties
, NULL
, 0))
289 EVP_MAC_CTX_free(*macctx
);
294 void ossl_prov_cache_exported_algorithms(const OSSL_ALGORITHM_CAPABLE
*in
,
299 if (out
[0].algorithm_names
== NULL
) {
300 for (i
= j
= 0; in
[i
].alg
.algorithm_names
!= NULL
; ++i
) {
301 if (in
[i
].capable
== NULL
|| in
[i
].capable())
302 out
[j
++] = in
[i
].alg
;
304 out
[j
++] = in
[i
].alg
;