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