1 // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <openssl/evp.h>
16
17 #include <assert.h>
18 #include <string.h>
19
20 #include <openssl/err.h>
21 #include <openssl/mem.h>
22 #include <openssl/nid.h>
23
24 #include "../internal.h"
25 #include "internal.h"
26
27
28 // Node depends on |EVP_R_NOT_XOF_OR_INVALID_LENGTH|.
29 //
30 // TODO(davidben): Fix Node to not touch the error queue itself and remove this.
OPENSSL_DECLARE_ERROR_REASON(EVP,NOT_XOF_OR_INVALID_LENGTH)31 OPENSSL_DECLARE_ERROR_REASON(EVP, NOT_XOF_OR_INVALID_LENGTH)
32
33 // The HPKE module uses the EVP error namespace, but it lives in another
34 // directory.
35 OPENSSL_DECLARE_ERROR_REASON(EVP, EMPTY_PSK)
36
37 EVP_PKEY *EVP_PKEY_new(void) {
38 EVP_PKEY *ret =
39 reinterpret_cast<EVP_PKEY *>(OPENSSL_zalloc(sizeof(EVP_PKEY)));
40 if (ret == NULL) {
41 return NULL;
42 }
43
44 ret->references = 1;
45 return ret;
46 }
47
free_it(EVP_PKEY * pkey)48 static void free_it(EVP_PKEY *pkey) {
49 if (pkey->ameth && pkey->ameth->pkey_free) {
50 pkey->ameth->pkey_free(pkey);
51 }
52 pkey->pkey = nullptr;
53 pkey->ameth = nullptr;
54 }
55
EVP_PKEY_free(EVP_PKEY * pkey)56 void EVP_PKEY_free(EVP_PKEY *pkey) {
57 if (pkey == NULL) {
58 return;
59 }
60
61 if (!CRYPTO_refcount_dec_and_test_zero(&pkey->references)) {
62 return;
63 }
64
65 free_it(pkey);
66 OPENSSL_free(pkey);
67 }
68
EVP_PKEY_up_ref(EVP_PKEY * pkey)69 int EVP_PKEY_up_ref(EVP_PKEY *pkey) {
70 CRYPTO_refcount_inc(&pkey->references);
71 return 1;
72 }
73
EVP_PKEY_is_opaque(const EVP_PKEY * pkey)74 int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) {
75 if (pkey->ameth && pkey->ameth->pkey_opaque) {
76 return pkey->ameth->pkey_opaque(pkey);
77 }
78 return 0;
79 }
80
EVP_PKEY_cmp(const EVP_PKEY * a,const EVP_PKEY * b)81 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
82 if (EVP_PKEY_id(a) != EVP_PKEY_id(b)) {
83 return -1;
84 }
85
86 if (a->ameth) {
87 int ret;
88 // Compare parameters if the algorithm has them
89 if (a->ameth->param_cmp) {
90 ret = a->ameth->param_cmp(a, b);
91 if (ret <= 0) {
92 return ret;
93 }
94 }
95
96 if (a->ameth->pub_cmp) {
97 return a->ameth->pub_cmp(a, b);
98 }
99 }
100
101 return -2;
102 }
103
EVP_PKEY_copy_parameters(EVP_PKEY * to,const EVP_PKEY * from)104 int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
105 if (EVP_PKEY_id(to) == EVP_PKEY_NONE) {
106 evp_pkey_set_method(to, from->ameth);
107 } else if (EVP_PKEY_id(to) != EVP_PKEY_id(from)) {
108 OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
109 return 0;
110 }
111
112 if (EVP_PKEY_missing_parameters(from)) {
113 OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
114 return 0;
115 }
116
117 // Once set, parameters may not change.
118 if (!EVP_PKEY_missing_parameters(to)) {
119 if (EVP_PKEY_cmp_parameters(to, from) == 1) {
120 return 1;
121 }
122 OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS);
123 return 0;
124 }
125
126 if (from->ameth && from->ameth->param_copy) {
127 return from->ameth->param_copy(to, from);
128 }
129
130 // TODO(https://crbug.com/boringssl/536): If the algorithm takes no
131 // parameters, copying them should vacuously succeed.
132 return 0;
133 }
134
EVP_PKEY_missing_parameters(const EVP_PKEY * pkey)135 int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) {
136 if (pkey->ameth && pkey->ameth->param_missing) {
137 return pkey->ameth->param_missing(pkey);
138 }
139 return 0;
140 }
141
EVP_PKEY_size(const EVP_PKEY * pkey)142 int EVP_PKEY_size(const EVP_PKEY *pkey) {
143 if (pkey && pkey->ameth && pkey->ameth->pkey_size) {
144 return pkey->ameth->pkey_size(pkey);
145 }
146 return 0;
147 }
148
EVP_PKEY_bits(const EVP_PKEY * pkey)149 int EVP_PKEY_bits(const EVP_PKEY *pkey) {
150 if (pkey && pkey->ameth && pkey->ameth->pkey_bits) {
151 return pkey->ameth->pkey_bits(pkey);
152 }
153 return 0;
154 }
155
EVP_PKEY_id(const EVP_PKEY * pkey)156 int EVP_PKEY_id(const EVP_PKEY *pkey) {
157 return pkey->ameth != nullptr ? pkey->ameth->pkey_id : EVP_PKEY_NONE;
158 }
159
160 // evp_pkey_asn1_find returns the ASN.1 method table for the given |nid|, which
161 // should be one of the |EVP_PKEY_*| values. It returns NULL if |nid| is
162 // unknown.
evp_pkey_asn1_find(int nid)163 static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) {
164 switch (nid) {
165 case EVP_PKEY_RSA:
166 return &rsa_asn1_meth;
167 case EVP_PKEY_EC:
168 return &ec_asn1_meth;
169 case EVP_PKEY_DSA:
170 return &dsa_asn1_meth;
171 case EVP_PKEY_ED25519:
172 return &ed25519_asn1_meth;
173 case EVP_PKEY_X25519:
174 return &x25519_asn1_meth;
175 default:
176 return NULL;
177 }
178 }
179
evp_pkey_set_method(EVP_PKEY * pkey,const EVP_PKEY_ASN1_METHOD * method)180 void evp_pkey_set_method(EVP_PKEY *pkey, const EVP_PKEY_ASN1_METHOD *method) {
181 free_it(pkey);
182 pkey->ameth = method;
183 }
184
EVP_PKEY_type(int nid)185 int EVP_PKEY_type(int nid) {
186 // In OpenSSL, this was used to map between type aliases. BoringSSL supports
187 // no type aliases, so this function is just the identity.
188 return nid;
189 }
190
EVP_PKEY_assign(EVP_PKEY * pkey,int type,void * key)191 int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) {
192 // This function can only be used to assign RSA, DSA, EC, and DH keys. Other
193 // key types have internal representations which are not exposed through the
194 // public API.
195 switch (type) {
196 case EVP_PKEY_RSA:
197 return EVP_PKEY_assign_RSA(pkey, reinterpret_cast<RSA *>(key));
198 case EVP_PKEY_DSA:
199 return EVP_PKEY_assign_DSA(pkey, reinterpret_cast<DSA *>(key));
200 case EVP_PKEY_EC:
201 return EVP_PKEY_assign_EC_KEY(pkey, reinterpret_cast<EC_KEY *>(key));
202 case EVP_PKEY_DH:
203 return EVP_PKEY_assign_DH(pkey, reinterpret_cast<DH *>(key));
204 }
205
206 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
207 ERR_add_error_dataf("algorithm %d", type);
208 return 0;
209 }
210
EVP_PKEY_set_type(EVP_PKEY * pkey,int type)211 int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) {
212 if (pkey && pkey->pkey) {
213 // Some callers rely on |pkey| getting cleared even if |type| is
214 // unsupported, usually setting |type| to |EVP_PKEY_NONE|.
215 free_it(pkey);
216 }
217
218 const EVP_PKEY_ASN1_METHOD *ameth = evp_pkey_asn1_find(type);
219 if (ameth == NULL) {
220 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
221 ERR_add_error_dataf("algorithm %d", type);
222 return 0;
223 }
224
225 if (pkey) {
226 evp_pkey_set_method(pkey, ameth);
227 }
228
229 return 1;
230 }
231
EVP_PKEY_new_raw_private_key(int type,ENGINE * unused,const uint8_t * in,size_t len)232 EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused,
233 const uint8_t *in, size_t len) {
234 // To avoid pulling in all key types, look for specifically the key types that
235 // support |set_priv_raw|.
236 const EVP_PKEY_ASN1_METHOD *method;
237 switch (type) {
238 case EVP_PKEY_X25519:
239 method = &x25519_asn1_meth;
240 break;
241 case EVP_PKEY_ED25519:
242 method = &ed25519_asn1_meth;
243 break;
244 default:
245 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
246 return nullptr;
247 }
248
249 bssl::UniquePtr<EVP_PKEY> ret(EVP_PKEY_new());
250 if (ret == nullptr) {
251 return nullptr;
252 }
253 evp_pkey_set_method(ret.get(), method);
254
255 if (!ret->ameth->set_priv_raw(ret.get(), in, len)) {
256 return nullptr;
257 }
258
259 return ret.release();
260 }
261
EVP_PKEY_new_raw_public_key(int type,ENGINE * unused,const uint8_t * in,size_t len)262 EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused,
263 const uint8_t *in, size_t len) {
264 // To avoid pulling in all key types, look for specifically the key types that
265 // support |set_pub_raw|.
266 const EVP_PKEY_ASN1_METHOD *method;
267 switch (type) {
268 case EVP_PKEY_X25519:
269 method = &x25519_asn1_meth;
270 break;
271 case EVP_PKEY_ED25519:
272 method = &ed25519_asn1_meth;
273 break;
274 default:
275 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
276 return nullptr;
277 }
278
279 bssl::UniquePtr<EVP_PKEY> ret(EVP_PKEY_new());
280 if (ret == nullptr) {
281 return nullptr;
282 }
283 evp_pkey_set_method(ret.get(), method);
284
285 if (!ret->ameth->set_pub_raw(ret.get(), in, len)) {
286 return nullptr;
287 }
288
289 return ret.release();
290 }
291
EVP_PKEY_get_raw_private_key(const EVP_PKEY * pkey,uint8_t * out,size_t * out_len)292 int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, uint8_t *out,
293 size_t *out_len) {
294 if (pkey->ameth->get_priv_raw == NULL) {
295 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
296 return 0;
297 }
298
299 return pkey->ameth->get_priv_raw(pkey, out, out_len);
300 }
301
EVP_PKEY_get_raw_public_key(const EVP_PKEY * pkey,uint8_t * out,size_t * out_len)302 int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, uint8_t *out,
303 size_t *out_len) {
304 if (pkey->ameth->get_pub_raw == NULL) {
305 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
306 return 0;
307 }
308
309 return pkey->ameth->get_pub_raw(pkey, out, out_len);
310 }
311
EVP_PKEY_cmp_parameters(const EVP_PKEY * a,const EVP_PKEY * b)312 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
313 if (EVP_PKEY_id(a) != EVP_PKEY_id(b)) {
314 return -1;
315 }
316 if (a->ameth && a->ameth->param_cmp) {
317 return a->ameth->param_cmp(a, b);
318 }
319 // TODO(https://crbug.com/boringssl/536): If the algorithm doesn't use
320 // parameters, they should compare as vacuously equal.
321 return -2;
322 }
323
EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX * ctx,const EVP_MD * md)324 int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
325 return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0,
326 (void *)md);
327 }
328
EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX * ctx,const EVP_MD ** out_md)329 int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
330 return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_GET_MD,
331 0, (void *)out_md);
332 }
333
EVP_PKEY_get0(const EVP_PKEY * pkey)334 void *EVP_PKEY_get0(const EVP_PKEY *pkey) {
335 // Node references, but never calls this function, so for now we return NULL.
336 // If other projects require complete support, call |EVP_PKEY_get0_RSA|, etc.,
337 // rather than reading |pkey->pkey| directly. This avoids problems if our
338 // internal representation does not match the type the caller expects from
339 // OpenSSL.
340 return NULL;
341 }
342
OpenSSL_add_all_algorithms(void)343 void OpenSSL_add_all_algorithms(void) {}
344
OPENSSL_add_all_algorithms_conf(void)345 void OPENSSL_add_all_algorithms_conf(void) {}
346
OpenSSL_add_all_ciphers(void)347 void OpenSSL_add_all_ciphers(void) {}
348
OpenSSL_add_all_digests(void)349 void OpenSSL_add_all_digests(void) {}
350
EVP_cleanup(void)351 void EVP_cleanup(void) {}
352
EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY * pkey,const uint8_t * in,size_t len)353 int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in,
354 size_t len) {
355 if (pkey->ameth->set1_tls_encodedpoint == NULL) {
356 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
357 return 0;
358 }
359
360 return pkey->ameth->set1_tls_encodedpoint(pkey, in, len);
361 }
362
EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY * pkey,uint8_t ** out_ptr)363 size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr) {
364 if (pkey->ameth->get1_tls_encodedpoint == NULL) {
365 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
366 return 0;
367 }
368
369 return pkey->ameth->get1_tls_encodedpoint(pkey, out_ptr);
370 }
371
EVP_PKEY_base_id(const EVP_PKEY * pkey)372 int EVP_PKEY_base_id(const EVP_PKEY *pkey) {
373 // OpenSSL has two notions of key type because it supports multiple OIDs for
374 // the same algorithm: NID_rsa vs NID_rsaEncryption and five distinct spelling
375 // of DSA. We do not support these, so the base ID is simply the ID.
376 return EVP_PKEY_id(pkey);
377 }
378