2 * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
11 /* We need to use some engine deprecated APIs */
12 #define OPENSSL_SUPPRESS_DEPRECATED
15 * RC4 and SHA-1 low level APIs and EVP _meth_ APISs are deprecated for public
16 * use, but still ok for internal use.
18 #include "internal/deprecated.h"
21 #include <openssl/crypto.h>
22 #include "internal/cryptlib.h"
23 #include "crypto/engine.h"
24 #include <openssl/pem.h>
25 #include <openssl/evp.h>
26 #include <openssl/rand.h>
27 #include <openssl/rsa.h>
28 #include <openssl/dsa.h>
29 #include <openssl/dh.h>
31 #include <openssl/hmac.h>
32 #include <openssl/x509v3.h>
35 * This testing gunk is implemented (and explained) lower down. It also
36 * assumes the application explicitly calls "ENGINE_load_openssl()" because
37 * this is no longer automatic in ENGINE_load_builtin_engines().
39 #define TEST_ENG_OPENSSL_RC4
40 #ifndef OPENSSL_NO_STDIO
41 # define TEST_ENG_OPENSSL_PKEY
43 /* #define TEST_ENG_OPENSSL_HMAC */
44 /* #define TEST_ENG_OPENSSL_HMAC_INIT */
45 /* #define TEST_ENG_OPENSSL_RC4_OTHERS */
46 #ifndef OPENSSL_NO_STDIO
47 # define TEST_ENG_OPENSSL_RC4_P_INIT
49 /* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
50 #define TEST_ENG_OPENSSL_SHA
51 /* #define TEST_ENG_OPENSSL_SHA_OTHERS */
52 /* #define TEST_ENG_OPENSSL_SHA_P_INIT */
53 /* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
54 /* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
56 /* Now check what of those algorithms are actually enabled */
58 # undef TEST_ENG_OPENSSL_RC4
59 # undef TEST_ENG_OPENSSL_RC4_OTHERS
60 # undef TEST_ENG_OPENSSL_RC4_P_INIT
61 # undef TEST_ENG_OPENSSL_RC4_P_CIPHER
64 static int openssl_destroy(ENGINE
*e
);
66 #ifdef TEST_ENG_OPENSSL_RC4
67 static int openssl_ciphers(ENGINE
*e
, const EVP_CIPHER
**cipher
,
68 const int **nids
, int nid
);
70 #ifdef TEST_ENG_OPENSSL_SHA
71 static int openssl_digests(ENGINE
*e
, const EVP_MD
**digest
,
72 const int **nids
, int nid
);
75 #ifdef TEST_ENG_OPENSSL_PKEY
76 static EVP_PKEY
*openssl_load_privkey(ENGINE
*eng
, const char *key_id
,
81 #ifdef TEST_ENG_OPENSSL_HMAC
82 static int ossl_register_hmac_meth(void);
83 static int ossl_pkey_meths(ENGINE
*e
, EVP_PKEY_METHOD
**pmeth
,
84 const int **nids
, int nid
);
87 /* The constants used when creating the ENGINE */
88 static const char *engine_openssl_id
= "openssl";
89 static const char *engine_openssl_name
= "Software engine support";
92 * This internal function is used by ENGINE_openssl() and possibly by the
93 * "dynamic" ENGINE support too
95 static int bind_helper(ENGINE
*e
)
97 if (!ENGINE_set_id(e
, engine_openssl_id
)
98 || !ENGINE_set_name(e
, engine_openssl_name
)
99 || !ENGINE_set_destroy_function(e
, openssl_destroy
)
100 #ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
101 || !ENGINE_set_RSA(e
, RSA_get_default_method())
102 # ifndef OPENSSL_NO_DSA
103 || !ENGINE_set_DSA(e
, DSA_get_default_method())
105 # ifndef OPENSSL_NO_EC
106 || !ENGINE_set_EC(e
, EC_KEY_OpenSSL())
108 # ifndef OPENSSL_NO_DH
109 || !ENGINE_set_DH(e
, DH_get_default_method())
111 || !ENGINE_set_RAND(e
, RAND_OpenSSL())
112 # ifdef TEST_ENG_OPENSSL_RC4
113 || !ENGINE_set_ciphers(e
, openssl_ciphers
)
115 # ifdef TEST_ENG_OPENSSL_SHA
116 || !ENGINE_set_digests(e
, openssl_digests
)
119 #ifdef TEST_ENG_OPENSSL_PKEY
120 || !ENGINE_set_load_privkey_function(e
, openssl_load_privkey
)
122 #ifdef TEST_ENG_OPENSSL_HMAC
123 || !ossl_register_hmac_meth()
124 || !ENGINE_set_pkey_meths(e
, ossl_pkey_meths
)
129 * If we add errors to this ENGINE, ensure the error handling is setup
132 /* openssl_load_error_strings(); */
136 static ENGINE
*engine_openssl(void)
138 ENGINE
*ret
= ENGINE_new();
141 if (!bind_helper(ret
)) {
148 void engine_load_openssl_int(void)
150 ENGINE
*toadd
= engine_openssl();
157 * If the "add" worked, it gets a structural reference. So either way, we
158 * release our just-created reference.
162 * If the "add" didn't work, it was probably a conflict because it was
163 * already added (eg. someone calling ENGINE_load_blah then calling
164 * ENGINE_load_builtin_engines() perhaps).
170 * This stuff is needed if this ENGINE is being compiled into a
171 * self-contained shared-library.
173 #ifdef ENGINE_DYNAMIC_SUPPORT
174 static int bind_fn(ENGINE
*e
, const char *id
)
176 if (id
&& (strcmp(id
, engine_openssl_id
) != 0))
183 IMPLEMENT_DYNAMIC_CHECK_FN()
184 IMPLEMENT_DYNAMIC_BIND_FN(bind_fn
)
185 #endif /* ENGINE_DYNAMIC_SUPPORT */
186 #ifdef TEST_ENG_OPENSSL_RC4
188 * This section of code compiles an "alternative implementation" of two modes of
189 * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
190 * should under normal circumstances go via this support rather than the default
191 * EVP support. There are other symbols to tweak the testing;
192 * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
193 * we're asked for a cipher we don't support (should not happen).
194 * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
195 * the "init_key" handler is called.
196 * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
198 # include <openssl/rc4.h>
199 # define TEST_RC4_KEY_SIZE 16
201 unsigned char key
[TEST_RC4_KEY_SIZE
];
204 # define test(ctx) ((TEST_RC4_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx))
205 static int test_rc4_init_key(EVP_CIPHER_CTX
*ctx
, const unsigned char *key
,
206 const unsigned char *iv
, int enc
)
208 const int n
= EVP_CIPHER_CTX_key_length(ctx
);
210 # ifdef TEST_ENG_OPENSSL_RC4_P_INIT
211 fprintf(stderr
, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
215 memcpy(&test(ctx
)->key
[0], key
, n
);
216 RC4_set_key(&test(ctx
)->ks
, n
, test(ctx
)->key
);
220 static int test_rc4_cipher(EVP_CIPHER_CTX
*ctx
, unsigned char *out
,
221 const unsigned char *in
, size_t inl
)
223 # ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
224 fprintf(stderr
, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
226 RC4(&test(ctx
)->ks
, inl
, in
, out
);
230 static EVP_CIPHER
*r4_cipher
= NULL
;
231 static const EVP_CIPHER
*test_r4_cipher(void)
233 if (r4_cipher
== NULL
) {
236 if ((cipher
= EVP_CIPHER_meth_new(NID_rc4
, 1, TEST_RC4_KEY_SIZE
)) == NULL
237 || !EVP_CIPHER_meth_set_iv_length(cipher
, 0)
238 || !EVP_CIPHER_meth_set_flags(cipher
, EVP_CIPH_VARIABLE_LENGTH
)
239 || !EVP_CIPHER_meth_set_init(cipher
, test_rc4_init_key
)
240 || !EVP_CIPHER_meth_set_do_cipher(cipher
, test_rc4_cipher
)
241 || !EVP_CIPHER_meth_set_impl_ctx_size(cipher
, sizeof(TEST_RC4_KEY
))) {
242 EVP_CIPHER_meth_free(cipher
);
249 static void test_r4_cipher_destroy(void)
251 EVP_CIPHER_meth_free(r4_cipher
);
255 static EVP_CIPHER
*r4_40_cipher
= NULL
;
256 static const EVP_CIPHER
*test_r4_40_cipher(void)
258 if (r4_40_cipher
== NULL
) {
261 if ((cipher
= EVP_CIPHER_meth_new(NID_rc4
, 1, 5 /* 40 bits */)) == NULL
262 || !EVP_CIPHER_meth_set_iv_length(cipher
, 0)
263 || !EVP_CIPHER_meth_set_flags(cipher
, EVP_CIPH_VARIABLE_LENGTH
)
264 || !EVP_CIPHER_meth_set_init(cipher
, test_rc4_init_key
)
265 || !EVP_CIPHER_meth_set_do_cipher(cipher
, test_rc4_cipher
)
266 || !EVP_CIPHER_meth_set_impl_ctx_size(cipher
, sizeof(TEST_RC4_KEY
))) {
267 EVP_CIPHER_meth_free(cipher
);
270 r4_40_cipher
= cipher
;
274 static void test_r4_40_cipher_destroy(void)
276 EVP_CIPHER_meth_free(r4_40_cipher
);
279 static int test_cipher_nids(const int **nids
)
281 static int cipher_nids
[4] = { 0, 0, 0, 0 };
286 const EVP_CIPHER
*cipher
;
287 if ((cipher
= test_r4_cipher()) != NULL
)
288 cipher_nids
[pos
++] = EVP_CIPHER_nid(cipher
);
289 if ((cipher
= test_r4_40_cipher()) != NULL
)
290 cipher_nids
[pos
++] = EVP_CIPHER_nid(cipher
);
291 cipher_nids
[pos
] = 0;
298 static int openssl_ciphers(ENGINE
*e
, const EVP_CIPHER
**cipher
,
299 const int **nids
, int nid
)
302 /* We are returning a list of supported nids */
303 return test_cipher_nids(nids
);
305 /* We are being asked for a specific cipher */
307 *cipher
= test_r4_cipher();
308 else if (nid
== NID_rc4_40
)
309 *cipher
= test_r4_40_cipher();
311 # ifdef TEST_ENG_OPENSSL_RC4_OTHERS
312 fprintf(stderr
, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
322 #ifdef TEST_ENG_OPENSSL_SHA
323 /* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
324 # include <openssl/sha.h>
326 static int test_sha1_init(EVP_MD_CTX
*ctx
)
328 # ifdef TEST_ENG_OPENSSL_SHA_P_INIT
329 fprintf(stderr
, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
331 return SHA1_Init(EVP_MD_CTX_md_data(ctx
));
334 static int test_sha1_update(EVP_MD_CTX
*ctx
, const void *data
, size_t count
)
336 # ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
337 fprintf(stderr
, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
339 return SHA1_Update(EVP_MD_CTX_md_data(ctx
), data
, count
);
342 static int test_sha1_final(EVP_MD_CTX
*ctx
, unsigned char *md
)
344 # ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
345 fprintf(stderr
, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
347 return SHA1_Final(md
, EVP_MD_CTX_md_data(ctx
));
350 static EVP_MD
*sha1_md
= NULL
;
351 static const EVP_MD
*test_sha_md(void)
353 if (sha1_md
== NULL
) {
356 if ((md
= EVP_MD_meth_new(NID_sha1
, NID_sha1WithRSAEncryption
)) == NULL
357 || !EVP_MD_meth_set_result_size(md
, SHA_DIGEST_LENGTH
)
358 || !EVP_MD_meth_set_input_blocksize(md
, SHA_CBLOCK
)
359 || !EVP_MD_meth_set_app_datasize(md
,
360 sizeof(EVP_MD
*) + sizeof(SHA_CTX
))
361 || !EVP_MD_meth_set_flags(md
, 0)
362 || !EVP_MD_meth_set_init(md
, test_sha1_init
)
363 || !EVP_MD_meth_set_update(md
, test_sha1_update
)
364 || !EVP_MD_meth_set_final(md
, test_sha1_final
)) {
365 EVP_MD_meth_free(md
);
372 static void test_sha_md_destroy(void)
374 EVP_MD_meth_free(sha1_md
);
377 static int test_digest_nids(const int **nids
)
379 static int digest_nids
[2] = { 0, 0 };
385 if ((md
= test_sha_md()) != NULL
)
386 digest_nids
[pos
++] = EVP_MD_type(md
);
387 digest_nids
[pos
] = 0;
394 static int openssl_digests(ENGINE
*e
, const EVP_MD
**digest
,
395 const int **nids
, int nid
)
398 /* We are returning a list of supported nids */
399 return test_digest_nids(nids
);
401 /* We are being asked for a specific digest */
403 *digest
= test_sha_md();
405 # ifdef TEST_ENG_OPENSSL_SHA_OTHERS
406 fprintf(stderr
, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
416 #ifdef TEST_ENG_OPENSSL_PKEY
417 static EVP_PKEY
*openssl_load_privkey(ENGINE
*eng
, const char *key_id
,
418 UI_METHOD
*ui_method
,
423 fprintf(stderr
, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n",
425 in
= BIO_new_file(key_id
, "r");
428 key
= PEM_read_bio_PrivateKey(in
, NULL
, 0, NULL
);
434 #ifdef TEST_ENG_OPENSSL_HMAC
437 * Experimental HMAC redirection implementation: mainly copied from
441 /* HMAC pkey context structure */
444 const EVP_MD
*md
; /* MD for HMAC use */
445 ASN1_OCTET_STRING ktmp
; /* Temp storage for key */
447 } OSSL_HMAC_PKEY_CTX
;
449 static int ossl_hmac_init(EVP_PKEY_CTX
*ctx
)
451 OSSL_HMAC_PKEY_CTX
*hctx
;
453 if ((hctx
= OPENSSL_zalloc(sizeof(*hctx
))) == NULL
) {
454 ERR_raise(ERR_LIB_ENGINE
, ERR_R_MALLOC_FAILURE
);
457 hctx
->ktmp
.type
= V_ASN1_OCTET_STRING
;
458 hctx
->ctx
= HMAC_CTX_new();
459 if (hctx
->ctx
== NULL
) {
463 EVP_PKEY_CTX_set_data(ctx
, hctx
);
464 EVP_PKEY_CTX_set0_keygen_info(ctx
, NULL
, 0);
465 # ifdef TEST_ENG_OPENSSL_HMAC_INIT
466 fprintf(stderr
, "(TEST_ENG_OPENSSL_HMAC) ossl_hmac_init() called\n");
471 static void ossl_hmac_cleanup(EVP_PKEY_CTX
*ctx
);
473 static int ossl_hmac_copy(EVP_PKEY_CTX
*dst
, EVP_PKEY_CTX
*src
)
475 OSSL_HMAC_PKEY_CTX
*sctx
, *dctx
;
477 /* allocate memory for dst->data and a new HMAC_CTX in dst->data->ctx */
478 if (!ossl_hmac_init(dst
))
480 sctx
= EVP_PKEY_CTX_get_data(src
);
481 dctx
= EVP_PKEY_CTX_get_data(dst
);
483 if (!HMAC_CTX_copy(dctx
->ctx
, sctx
->ctx
))
485 if (sctx
->ktmp
.data
) {
486 if (!ASN1_OCTET_STRING_set(&dctx
->ktmp
,
487 sctx
->ktmp
.data
, sctx
->ktmp
.length
))
492 /* release HMAC_CTX in dst->data->ctx and memory allocated for dst->data */
493 ossl_hmac_cleanup(dst
);
497 static void ossl_hmac_cleanup(EVP_PKEY_CTX
*ctx
)
499 OSSL_HMAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
502 HMAC_CTX_free(hctx
->ctx
);
503 OPENSSL_clear_free(hctx
->ktmp
.data
, hctx
->ktmp
.length
);
505 EVP_PKEY_CTX_set_data(ctx
, NULL
);
509 static int ossl_hmac_keygen(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*pkey
)
511 ASN1_OCTET_STRING
*hkey
= NULL
;
512 OSSL_HMAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
513 if (!hctx
->ktmp
.data
)
515 hkey
= ASN1_OCTET_STRING_dup(&hctx
->ktmp
);
518 EVP_PKEY_assign(pkey
, EVP_PKEY_HMAC
, hkey
);
523 static int ossl_int_update(EVP_MD_CTX
*ctx
, const void *data
, size_t count
)
525 OSSL_HMAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx
));
526 if (!HMAC_Update(hctx
->ctx
, data
, count
))
531 static int ossl_hmac_signctx_init(EVP_PKEY_CTX
*ctx
, EVP_MD_CTX
*mctx
)
533 EVP_MD_CTX_set_flags(mctx
, EVP_MD_CTX_FLAG_NO_INIT
);
534 EVP_MD_CTX_set_update_fn(mctx
, ossl_int_update
);
538 static int ossl_hmac_signctx(EVP_PKEY_CTX
*ctx
, unsigned char *sig
,
539 size_t *siglen
, EVP_MD_CTX
*mctx
)
542 OSSL_HMAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
543 int l
= EVP_MD_CTX_size(mctx
);
551 if (!HMAC_Final(hctx
->ctx
, sig
, &hlen
))
553 *siglen
= (size_t)hlen
;
557 static int ossl_hmac_ctrl(EVP_PKEY_CTX
*ctx
, int type
, int p1
, void *p2
)
559 OSSL_HMAC_PKEY_CTX
*hctx
= EVP_PKEY_CTX_get_data(ctx
);
561 ASN1_OCTET_STRING
*key
;
564 case EVP_PKEY_CTRL_SET_MAC_KEY
:
565 if ((!p2
&& p1
> 0) || (p1
< -1))
567 if (!ASN1_OCTET_STRING_set(&hctx
->ktmp
, p2
, p1
))
571 case EVP_PKEY_CTRL_MD
:
575 case EVP_PKEY_CTRL_DIGESTINIT
:
576 pk
= EVP_PKEY_CTX_get0_pkey(ctx
);
577 key
= EVP_PKEY_get0(pk
);
578 if (!HMAC_Init_ex(hctx
->ctx
, key
->data
, key
->length
, hctx
->md
, NULL
))
589 static int ossl_hmac_ctrl_str(EVP_PKEY_CTX
*ctx
,
590 const char *type
, const char *value
)
595 if (strcmp(type
, "key") == 0) {
596 void *p
= (void *)value
;
597 return ossl_hmac_ctrl(ctx
, EVP_PKEY_CTRL_SET_MAC_KEY
, -1, p
);
599 if (strcmp(type
, "hexkey") == 0) {
603 key
= OPENSSL_hexstr2buf(value
, &keylen
);
606 r
= ossl_hmac_ctrl(ctx
, EVP_PKEY_CTRL_SET_MAC_KEY
, keylen
, key
);
613 static EVP_PKEY_METHOD
*ossl_hmac_meth
;
615 static int ossl_register_hmac_meth(void)
617 EVP_PKEY_METHOD
*meth
;
618 meth
= EVP_PKEY_meth_new(EVP_PKEY_HMAC
, 0);
621 EVP_PKEY_meth_set_init(meth
, ossl_hmac_init
);
622 EVP_PKEY_meth_set_copy(meth
, ossl_hmac_copy
);
623 EVP_PKEY_meth_set_cleanup(meth
, ossl_hmac_cleanup
);
625 EVP_PKEY_meth_set_keygen(meth
, 0, ossl_hmac_keygen
);
627 EVP_PKEY_meth_set_signctx(meth
, ossl_hmac_signctx_init
,
630 EVP_PKEY_meth_set_ctrl(meth
, ossl_hmac_ctrl
, ossl_hmac_ctrl_str
);
631 ossl_hmac_meth
= meth
;
635 static int ossl_pkey_meths(ENGINE
*e
, EVP_PKEY_METHOD
**pmeth
,
636 const int **nids
, int nid
)
638 static int ossl_pkey_nids
[] = {
644 *nids
= ossl_pkey_nids
;
648 if (nid
== EVP_PKEY_HMAC
) {
649 *pmeth
= ossl_hmac_meth
;
659 int openssl_destroy(ENGINE
*e
)
661 test_sha_md_destroy();
662 #ifdef TEST_ENG_OPENSSL_RC4
663 test_r4_cipher_destroy();
664 test_r4_40_cipher_destroy();