1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci/* We need to use some engine deprecated APIs */
11e1051a39Sopenharmony_ci#define OPENSSL_SUPPRESS_DEPRECATED
12e1051a39Sopenharmony_ci
13e1051a39Sopenharmony_ci/*
14e1051a39Sopenharmony_ci * SHA-1 low level APIs are deprecated for public use, but still ok for
15e1051a39Sopenharmony_ci * internal use.  Note, that due to symbols not being exported, only the
16e1051a39Sopenharmony_ci * #defines and strucures can be accessed, in this case SHA_CBLOCK and
17e1051a39Sopenharmony_ci * sizeof(SHA_CTX).
18e1051a39Sopenharmony_ci */
19e1051a39Sopenharmony_ci#include "internal/deprecated.h"
20e1051a39Sopenharmony_ci
21e1051a39Sopenharmony_ci#include <openssl/opensslconf.h>
22e1051a39Sopenharmony_ci#if defined(_WIN32)
23e1051a39Sopenharmony_ci# include <windows.h>
24e1051a39Sopenharmony_ci#endif
25e1051a39Sopenharmony_ci
26e1051a39Sopenharmony_ci#include <stdio.h>
27e1051a39Sopenharmony_ci#include <string.h>
28e1051a39Sopenharmony_ci
29e1051a39Sopenharmony_ci#include <openssl/engine.h>
30e1051a39Sopenharmony_ci#include <openssl/sha.h>
31e1051a39Sopenharmony_ci#include <openssl/aes.h>
32e1051a39Sopenharmony_ci#include <openssl/rsa.h>
33e1051a39Sopenharmony_ci#include <openssl/evp.h>
34e1051a39Sopenharmony_ci#include <openssl/async.h>
35e1051a39Sopenharmony_ci#include <openssl/bn.h>
36e1051a39Sopenharmony_ci#include <openssl/crypto.h>
37e1051a39Sopenharmony_ci#include <openssl/ssl.h>
38e1051a39Sopenharmony_ci#include <openssl/modes.h>
39e1051a39Sopenharmony_ci
40e1051a39Sopenharmony_ci#if defined(OPENSSL_SYS_UNIX) && defined(OPENSSL_THREADS)
41e1051a39Sopenharmony_ci# undef ASYNC_POSIX
42e1051a39Sopenharmony_ci# define ASYNC_POSIX
43e1051a39Sopenharmony_ci# include <unistd.h>
44e1051a39Sopenharmony_ci#elif defined(_WIN32)
45e1051a39Sopenharmony_ci# undef ASYNC_WIN
46e1051a39Sopenharmony_ci# define ASYNC_WIN
47e1051a39Sopenharmony_ci#endif
48e1051a39Sopenharmony_ci
49e1051a39Sopenharmony_ci#include "e_dasync_err.c"
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ci/* Engine Id and Name */
52e1051a39Sopenharmony_cistatic const char *engine_dasync_id = "dasync";
53e1051a39Sopenharmony_cistatic const char *engine_dasync_name = "Dummy Async engine support";
54e1051a39Sopenharmony_ci
55e1051a39Sopenharmony_ci
56e1051a39Sopenharmony_ci/* Engine Lifetime functions */
57e1051a39Sopenharmony_cistatic int dasync_destroy(ENGINE *e);
58e1051a39Sopenharmony_cistatic int dasync_init(ENGINE *e);
59e1051a39Sopenharmony_cistatic int dasync_finish(ENGINE *e);
60e1051a39Sopenharmony_civoid engine_load_dasync_int(void);
61e1051a39Sopenharmony_ci
62e1051a39Sopenharmony_ci
63e1051a39Sopenharmony_ci/* Set up digests. Just SHA1 for now */
64e1051a39Sopenharmony_cistatic int dasync_digests(ENGINE *e, const EVP_MD **digest,
65e1051a39Sopenharmony_ci                          const int **nids, int nid);
66e1051a39Sopenharmony_ci
67e1051a39Sopenharmony_cistatic void dummy_pause_job(void);
68e1051a39Sopenharmony_ci
69e1051a39Sopenharmony_ci/* SHA1 */
70e1051a39Sopenharmony_cistatic int dasync_sha1_init(EVP_MD_CTX *ctx);
71e1051a39Sopenharmony_cistatic int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data,
72e1051a39Sopenharmony_ci                             size_t count);
73e1051a39Sopenharmony_cistatic int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md);
74e1051a39Sopenharmony_ci
75e1051a39Sopenharmony_ci/*
76e1051a39Sopenharmony_ci * Holds the EVP_MD object for sha1 in this engine. Set up once only during
77e1051a39Sopenharmony_ci * engine bind and can then be reused many times.
78e1051a39Sopenharmony_ci */
79e1051a39Sopenharmony_cistatic EVP_MD *_hidden_sha1_md = NULL;
80e1051a39Sopenharmony_cistatic const EVP_MD *dasync_sha1(void)
81e1051a39Sopenharmony_ci{
82e1051a39Sopenharmony_ci    return _hidden_sha1_md;
83e1051a39Sopenharmony_ci}
84e1051a39Sopenharmony_cistatic void destroy_digests(void)
85e1051a39Sopenharmony_ci{
86e1051a39Sopenharmony_ci    EVP_MD_meth_free(_hidden_sha1_md);
87e1051a39Sopenharmony_ci    _hidden_sha1_md = NULL;
88e1051a39Sopenharmony_ci}
89e1051a39Sopenharmony_ci
90e1051a39Sopenharmony_cistatic int dasync_digest_nids(const int **nids)
91e1051a39Sopenharmony_ci{
92e1051a39Sopenharmony_ci    static int digest_nids[2] = { 0, 0 };
93e1051a39Sopenharmony_ci    static int pos = 0;
94e1051a39Sopenharmony_ci    static int init = 0;
95e1051a39Sopenharmony_ci
96e1051a39Sopenharmony_ci    if (!init) {
97e1051a39Sopenharmony_ci        const EVP_MD *md;
98e1051a39Sopenharmony_ci        if ((md = dasync_sha1()) != NULL)
99e1051a39Sopenharmony_ci            digest_nids[pos++] = EVP_MD_get_type(md);
100e1051a39Sopenharmony_ci        digest_nids[pos] = 0;
101e1051a39Sopenharmony_ci        init = 1;
102e1051a39Sopenharmony_ci    }
103e1051a39Sopenharmony_ci    *nids = digest_nids;
104e1051a39Sopenharmony_ci    return pos;
105e1051a39Sopenharmony_ci}
106e1051a39Sopenharmony_ci
107e1051a39Sopenharmony_ci/* RSA */
108e1051a39Sopenharmony_cistatic int dasync_pkey(ENGINE *e, EVP_PKEY_METHOD **pmeth,
109e1051a39Sopenharmony_ci                       const int **pnids, int nid);
110e1051a39Sopenharmony_ci
111e1051a39Sopenharmony_cistatic int dasync_rsa_init(EVP_PKEY_CTX *ctx);
112e1051a39Sopenharmony_cistatic void dasync_rsa_cleanup(EVP_PKEY_CTX *ctx);
113e1051a39Sopenharmony_cistatic int dasync_rsa_paramgen_init(EVP_PKEY_CTX *ctx);
114e1051a39Sopenharmony_cistatic int dasync_rsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
115e1051a39Sopenharmony_cistatic int dasync_rsa_keygen_init(EVP_PKEY_CTX *ctx);
116e1051a39Sopenharmony_cistatic int dasync_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
117e1051a39Sopenharmony_cistatic int dasync_rsa_encrypt_init(EVP_PKEY_CTX *ctx);
118e1051a39Sopenharmony_cistatic int dasync_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
119e1051a39Sopenharmony_ci                              size_t *outlen, const unsigned char *in,
120e1051a39Sopenharmony_ci                              size_t inlen);
121e1051a39Sopenharmony_cistatic int dasync_rsa_decrypt_init(EVP_PKEY_CTX *ctx);
122e1051a39Sopenharmony_cistatic int dasync_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
123e1051a39Sopenharmony_ci                              size_t *outlen, const unsigned char *in,
124e1051a39Sopenharmony_ci                              size_t inlen);
125e1051a39Sopenharmony_cistatic int dasync_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
126e1051a39Sopenharmony_cistatic int dasync_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
127e1051a39Sopenharmony_ci                               const char *value);
128e1051a39Sopenharmony_ci
129e1051a39Sopenharmony_cistatic EVP_PKEY_METHOD *dasync_rsa;
130e1051a39Sopenharmony_cistatic const EVP_PKEY_METHOD *dasync_rsa_orig;
131e1051a39Sopenharmony_ci
132e1051a39Sopenharmony_ci/* AES */
133e1051a39Sopenharmony_ci
134e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
135e1051a39Sopenharmony_ci                                  void *ptr);
136e1051a39Sopenharmony_cistatic int dasync_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
137e1051a39Sopenharmony_ci                                  const unsigned char *iv, int enc);
138e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
139e1051a39Sopenharmony_ci                                    const unsigned char *in, size_t inl);
140e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx);
141e1051a39Sopenharmony_ci
142e1051a39Sopenharmony_cistatic int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
143e1051a39Sopenharmony_ci                                  void *ptr);
144e1051a39Sopenharmony_cistatic int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
145e1051a39Sopenharmony_ci                                  const unsigned char *iv, int enc);
146e1051a39Sopenharmony_cistatic int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
147e1051a39Sopenharmony_ci                                    const unsigned char *in, size_t inl);
148e1051a39Sopenharmony_cistatic int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx);
149e1051a39Sopenharmony_ci
150e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
151e1051a39Sopenharmony_ci                                             int arg, void *ptr);
152e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
153e1051a39Sopenharmony_ci                                                 const unsigned char *key,
154e1051a39Sopenharmony_ci                                                 const unsigned char *iv,
155e1051a39Sopenharmony_ci                                                 int enc);
156e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,
157e1051a39Sopenharmony_ci                                               unsigned char *out,
158e1051a39Sopenharmony_ci                                               const unsigned char *in,
159e1051a39Sopenharmony_ci                                               size_t inl);
160e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_hmac_sha1_cleanup(EVP_CIPHER_CTX *ctx);
161e1051a39Sopenharmony_ci
162e1051a39Sopenharmony_cistruct dasync_pipeline_ctx {
163e1051a39Sopenharmony_ci    void *inner_cipher_data;
164e1051a39Sopenharmony_ci    unsigned int numpipes;
165e1051a39Sopenharmony_ci    unsigned char **inbufs;
166e1051a39Sopenharmony_ci    unsigned char **outbufs;
167e1051a39Sopenharmony_ci    size_t *lens;
168e1051a39Sopenharmony_ci    unsigned char tlsaad[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN];
169e1051a39Sopenharmony_ci    unsigned int aadctr;
170e1051a39Sopenharmony_ci};
171e1051a39Sopenharmony_ci
172e1051a39Sopenharmony_ci/*
173e1051a39Sopenharmony_ci * Holds the EVP_CIPHER object for aes_128_cbc in this engine. Set up once only
174e1051a39Sopenharmony_ci * during engine bind and can then be reused many times.
175e1051a39Sopenharmony_ci */
176e1051a39Sopenharmony_cistatic EVP_CIPHER *_hidden_aes_128_cbc = NULL;
177e1051a39Sopenharmony_cistatic const EVP_CIPHER *dasync_aes_128_cbc(void)
178e1051a39Sopenharmony_ci{
179e1051a39Sopenharmony_ci    return _hidden_aes_128_cbc;
180e1051a39Sopenharmony_ci}
181e1051a39Sopenharmony_ci
182e1051a39Sopenharmony_cistatic EVP_CIPHER *_hidden_aes_256_ctr = NULL;
183e1051a39Sopenharmony_cistatic const EVP_CIPHER *dasync_aes_256_ctr(void)
184e1051a39Sopenharmony_ci{
185e1051a39Sopenharmony_ci    return _hidden_aes_256_ctr;
186e1051a39Sopenharmony_ci}
187e1051a39Sopenharmony_ci
188e1051a39Sopenharmony_ci/*
189e1051a39Sopenharmony_ci * Holds the EVP_CIPHER object for aes_128_cbc_hmac_sha1 in this engine. Set up
190e1051a39Sopenharmony_ci * once only during engine bind and can then be reused many times.
191e1051a39Sopenharmony_ci *
192e1051a39Sopenharmony_ci * This 'stitched' cipher depends on the EVP_aes_128_cbc_hmac_sha1() cipher,
193e1051a39Sopenharmony_ci * which is implemented only if the AES-NI instruction set extension is available
194e1051a39Sopenharmony_ci * (see OPENSSL_IA32CAP(3)). If that's not the case, then this cipher will not
195e1051a39Sopenharmony_ci * be available either.
196e1051a39Sopenharmony_ci *
197e1051a39Sopenharmony_ci * Note: Since it is a legacy mac-then-encrypt cipher, modern TLS peers (which
198e1051a39Sopenharmony_ci * negotiate the encrypt-then-mac extension) won't negotiate it anyway.
199e1051a39Sopenharmony_ci */
200e1051a39Sopenharmony_cistatic EVP_CIPHER *_hidden_aes_128_cbc_hmac_sha1 = NULL;
201e1051a39Sopenharmony_cistatic const EVP_CIPHER *dasync_aes_128_cbc_hmac_sha1(void)
202e1051a39Sopenharmony_ci{
203e1051a39Sopenharmony_ci    return _hidden_aes_128_cbc_hmac_sha1;
204e1051a39Sopenharmony_ci}
205e1051a39Sopenharmony_ci
206e1051a39Sopenharmony_cistatic void destroy_ciphers(void)
207e1051a39Sopenharmony_ci{
208e1051a39Sopenharmony_ci    EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
209e1051a39Sopenharmony_ci    EVP_CIPHER_meth_free(_hidden_aes_256_ctr);
210e1051a39Sopenharmony_ci    EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);
211e1051a39Sopenharmony_ci    _hidden_aes_128_cbc = NULL;
212e1051a39Sopenharmony_ci    _hidden_aes_256_ctr = NULL;
213e1051a39Sopenharmony_ci    _hidden_aes_128_cbc_hmac_sha1 = NULL;
214e1051a39Sopenharmony_ci}
215e1051a39Sopenharmony_ci
216e1051a39Sopenharmony_cistatic int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
217e1051a39Sopenharmony_ci                                   const int **nids, int nid);
218e1051a39Sopenharmony_ci
219e1051a39Sopenharmony_cistatic int dasync_cipher_nids[] = {
220e1051a39Sopenharmony_ci    NID_aes_128_cbc,
221e1051a39Sopenharmony_ci    NID_aes_256_ctr,
222e1051a39Sopenharmony_ci    NID_aes_128_cbc_hmac_sha1,
223e1051a39Sopenharmony_ci    0
224e1051a39Sopenharmony_ci};
225e1051a39Sopenharmony_ci
226e1051a39Sopenharmony_cistatic int bind_dasync(ENGINE *e)
227e1051a39Sopenharmony_ci{
228e1051a39Sopenharmony_ci    /* Setup RSA */
229e1051a39Sopenharmony_ci    ;
230e1051a39Sopenharmony_ci    if ((dasync_rsa_orig = EVP_PKEY_meth_find(EVP_PKEY_RSA)) == NULL
231e1051a39Sopenharmony_ci        || (dasync_rsa = EVP_PKEY_meth_new(EVP_PKEY_RSA,
232e1051a39Sopenharmony_ci                                           EVP_PKEY_FLAG_AUTOARGLEN)) == NULL)
233e1051a39Sopenharmony_ci        return 0;
234e1051a39Sopenharmony_ci    EVP_PKEY_meth_set_init(dasync_rsa, dasync_rsa_init);
235e1051a39Sopenharmony_ci    EVP_PKEY_meth_set_cleanup(dasync_rsa, dasync_rsa_cleanup);
236e1051a39Sopenharmony_ci    EVP_PKEY_meth_set_paramgen(dasync_rsa, dasync_rsa_paramgen_init,
237e1051a39Sopenharmony_ci                               dasync_rsa_paramgen);
238e1051a39Sopenharmony_ci    EVP_PKEY_meth_set_keygen(dasync_rsa, dasync_rsa_keygen_init,
239e1051a39Sopenharmony_ci                             dasync_rsa_keygen);
240e1051a39Sopenharmony_ci    EVP_PKEY_meth_set_encrypt(dasync_rsa, dasync_rsa_encrypt_init,
241e1051a39Sopenharmony_ci                              dasync_rsa_encrypt);
242e1051a39Sopenharmony_ci    EVP_PKEY_meth_set_decrypt(dasync_rsa, dasync_rsa_decrypt_init,
243e1051a39Sopenharmony_ci                              dasync_rsa_decrypt);
244e1051a39Sopenharmony_ci    EVP_PKEY_meth_set_ctrl(dasync_rsa, dasync_rsa_ctrl,
245e1051a39Sopenharmony_ci                           dasync_rsa_ctrl_str);
246e1051a39Sopenharmony_ci
247e1051a39Sopenharmony_ci    /* Ensure the dasync error handling is set up */
248e1051a39Sopenharmony_ci    ERR_load_DASYNC_strings();
249e1051a39Sopenharmony_ci
250e1051a39Sopenharmony_ci    if (!ENGINE_set_id(e, engine_dasync_id)
251e1051a39Sopenharmony_ci        || !ENGINE_set_name(e, engine_dasync_name)
252e1051a39Sopenharmony_ci        || !ENGINE_set_pkey_meths(e, dasync_pkey)
253e1051a39Sopenharmony_ci        || !ENGINE_set_digests(e, dasync_digests)
254e1051a39Sopenharmony_ci        || !ENGINE_set_ciphers(e, dasync_ciphers)
255e1051a39Sopenharmony_ci        || !ENGINE_set_destroy_function(e, dasync_destroy)
256e1051a39Sopenharmony_ci        || !ENGINE_set_init_function(e, dasync_init)
257e1051a39Sopenharmony_ci        || !ENGINE_set_finish_function(e, dasync_finish)) {
258e1051a39Sopenharmony_ci        DASYNCerr(DASYNC_F_BIND_DASYNC, DASYNC_R_INIT_FAILED);
259e1051a39Sopenharmony_ci        return 0;
260e1051a39Sopenharmony_ci    }
261e1051a39Sopenharmony_ci
262e1051a39Sopenharmony_ci    /*
263e1051a39Sopenharmony_ci     * Set up the EVP_CIPHER and EVP_MD objects for the ciphers/digests
264e1051a39Sopenharmony_ci     * supplied by this engine
265e1051a39Sopenharmony_ci     */
266e1051a39Sopenharmony_ci    _hidden_sha1_md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption);
267e1051a39Sopenharmony_ci    if (_hidden_sha1_md == NULL
268e1051a39Sopenharmony_ci        || !EVP_MD_meth_set_result_size(_hidden_sha1_md, SHA_DIGEST_LENGTH)
269e1051a39Sopenharmony_ci        || !EVP_MD_meth_set_input_blocksize(_hidden_sha1_md, SHA_CBLOCK)
270e1051a39Sopenharmony_ci        || !EVP_MD_meth_set_app_datasize(_hidden_sha1_md,
271e1051a39Sopenharmony_ci                                         sizeof(EVP_MD *) + sizeof(SHA_CTX))
272e1051a39Sopenharmony_ci        || !EVP_MD_meth_set_flags(_hidden_sha1_md, EVP_MD_FLAG_DIGALGID_ABSENT)
273e1051a39Sopenharmony_ci        || !EVP_MD_meth_set_init(_hidden_sha1_md, dasync_sha1_init)
274e1051a39Sopenharmony_ci        || !EVP_MD_meth_set_update(_hidden_sha1_md, dasync_sha1_update)
275e1051a39Sopenharmony_ci        || !EVP_MD_meth_set_final(_hidden_sha1_md, dasync_sha1_final)) {
276e1051a39Sopenharmony_ci        EVP_MD_meth_free(_hidden_sha1_md);
277e1051a39Sopenharmony_ci        _hidden_sha1_md = NULL;
278e1051a39Sopenharmony_ci    }
279e1051a39Sopenharmony_ci
280e1051a39Sopenharmony_ci    _hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc,
281e1051a39Sopenharmony_ci                                              16 /* block size */,
282e1051a39Sopenharmony_ci                                              16 /* key len */);
283e1051a39Sopenharmony_ci    if (_hidden_aes_128_cbc == NULL
284e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc,16)
285e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc,
286e1051a39Sopenharmony_ci                                          EVP_CIPH_FLAG_DEFAULT_ASN1
287e1051a39Sopenharmony_ci                                          | EVP_CIPH_CBC_MODE
288e1051a39Sopenharmony_ci                                          | EVP_CIPH_FLAG_PIPELINE
289e1051a39Sopenharmony_ci                                          | EVP_CIPH_CUSTOM_COPY)
290e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc,
291e1051a39Sopenharmony_ci                                         dasync_aes128_init_key)
292e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc,
293e1051a39Sopenharmony_ci                                              dasync_aes128_cbc_cipher)
294e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc,
295e1051a39Sopenharmony_ci                                            dasync_aes128_cbc_cleanup)
296e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc,
297e1051a39Sopenharmony_ci                                         dasync_aes128_cbc_ctrl)
298e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc,
299e1051a39Sopenharmony_ci                                sizeof(struct dasync_pipeline_ctx))) {
300e1051a39Sopenharmony_ci        EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
301e1051a39Sopenharmony_ci        _hidden_aes_128_cbc = NULL;
302e1051a39Sopenharmony_ci    }
303e1051a39Sopenharmony_ci
304e1051a39Sopenharmony_ci    _hidden_aes_256_ctr = EVP_CIPHER_meth_new(NID_aes_256_ctr,
305e1051a39Sopenharmony_ci                                              1  /* block size */,
306e1051a39Sopenharmony_ci                                              32 /* key len */);
307e1051a39Sopenharmony_ci    if (_hidden_aes_256_ctr == NULL
308e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_256_ctr,16)
309e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_flags(_hidden_aes_256_ctr,
310e1051a39Sopenharmony_ci                                          EVP_CIPH_FLAG_DEFAULT_ASN1
311e1051a39Sopenharmony_ci                                          | EVP_CIPH_CTR_MODE
312e1051a39Sopenharmony_ci                                          | EVP_CIPH_FLAG_PIPELINE
313e1051a39Sopenharmony_ci                                          | EVP_CIPH_CUSTOM_COPY)
314e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_init(_hidden_aes_256_ctr,
315e1051a39Sopenharmony_ci                                         dasync_aes256_init_key)
316e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_256_ctr,
317e1051a39Sopenharmony_ci                                              dasync_aes256_ctr_cipher)
318e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_256_ctr,
319e1051a39Sopenharmony_ci                                            dasync_aes256_ctr_cleanup)
320e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_256_ctr,
321e1051a39Sopenharmony_ci                                         dasync_aes256_ctr_ctrl)
322e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_256_ctr,
323e1051a39Sopenharmony_ci                                sizeof(struct dasync_pipeline_ctx))) {
324e1051a39Sopenharmony_ci        EVP_CIPHER_meth_free(_hidden_aes_256_ctr);
325e1051a39Sopenharmony_ci        _hidden_aes_256_ctr = NULL;
326e1051a39Sopenharmony_ci    }
327e1051a39Sopenharmony_ci
328e1051a39Sopenharmony_ci    _hidden_aes_128_cbc_hmac_sha1 = EVP_CIPHER_meth_new(
329e1051a39Sopenharmony_ci                                                NID_aes_128_cbc_hmac_sha1,
330e1051a39Sopenharmony_ci                                                16 /* block size */,
331e1051a39Sopenharmony_ci                                                16 /* key len */);
332e1051a39Sopenharmony_ci    if (_hidden_aes_128_cbc_hmac_sha1 == NULL
333e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc_hmac_sha1,16)
334e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc_hmac_sha1,
335e1051a39Sopenharmony_ci                                            EVP_CIPH_CBC_MODE
336e1051a39Sopenharmony_ci                                          | EVP_CIPH_FLAG_DEFAULT_ASN1
337e1051a39Sopenharmony_ci                                          | EVP_CIPH_FLAG_AEAD_CIPHER
338e1051a39Sopenharmony_ci                                          | EVP_CIPH_FLAG_PIPELINE
339e1051a39Sopenharmony_ci                                          | EVP_CIPH_CUSTOM_COPY)
340e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc_hmac_sha1,
341e1051a39Sopenharmony_ci                                         dasync_aes128_cbc_hmac_sha1_init_key)
342e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc_hmac_sha1,
343e1051a39Sopenharmony_ci                                            dasync_aes128_cbc_hmac_sha1_cipher)
344e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc_hmac_sha1,
345e1051a39Sopenharmony_ci                                            dasync_aes128_cbc_hmac_sha1_cleanup)
346e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc_hmac_sha1,
347e1051a39Sopenharmony_ci                                         dasync_aes128_cbc_hmac_sha1_ctrl)
348e1051a39Sopenharmony_ci            || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc_hmac_sha1,
349e1051a39Sopenharmony_ci                                sizeof(struct dasync_pipeline_ctx))) {
350e1051a39Sopenharmony_ci        EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);
351e1051a39Sopenharmony_ci        _hidden_aes_128_cbc_hmac_sha1 = NULL;
352e1051a39Sopenharmony_ci    }
353e1051a39Sopenharmony_ci
354e1051a39Sopenharmony_ci    return 1;
355e1051a39Sopenharmony_ci}
356e1051a39Sopenharmony_ci
357e1051a39Sopenharmony_cistatic void destroy_pkey(void)
358e1051a39Sopenharmony_ci{
359e1051a39Sopenharmony_ci    /*
360e1051a39Sopenharmony_ci     * We don't actually need to free the dasync_rsa method since this is
361e1051a39Sopenharmony_ci     * automatically freed for us by libcrypto.
362e1051a39Sopenharmony_ci     */
363e1051a39Sopenharmony_ci    dasync_rsa_orig = NULL;
364e1051a39Sopenharmony_ci    dasync_rsa = NULL;
365e1051a39Sopenharmony_ci}
366e1051a39Sopenharmony_ci
367e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_DYNAMIC_ENGINE
368e1051a39Sopenharmony_cistatic int bind_helper(ENGINE *e, const char *id)
369e1051a39Sopenharmony_ci{
370e1051a39Sopenharmony_ci    if (id && (strcmp(id, engine_dasync_id) != 0))
371e1051a39Sopenharmony_ci        return 0;
372e1051a39Sopenharmony_ci    if (!bind_dasync(e))
373e1051a39Sopenharmony_ci        return 0;
374e1051a39Sopenharmony_ci    return 1;
375e1051a39Sopenharmony_ci}
376e1051a39Sopenharmony_ci
377e1051a39Sopenharmony_ciIMPLEMENT_DYNAMIC_CHECK_FN()
378e1051a39Sopenharmony_ci    IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
379e1051a39Sopenharmony_ci# endif
380e1051a39Sopenharmony_ci
381e1051a39Sopenharmony_cistatic ENGINE *engine_dasync(void)
382e1051a39Sopenharmony_ci{
383e1051a39Sopenharmony_ci    ENGINE *ret = ENGINE_new();
384e1051a39Sopenharmony_ci    if (!ret)
385e1051a39Sopenharmony_ci        return NULL;
386e1051a39Sopenharmony_ci    if (!bind_dasync(ret)) {
387e1051a39Sopenharmony_ci        ENGINE_free(ret);
388e1051a39Sopenharmony_ci        return NULL;
389e1051a39Sopenharmony_ci    }
390e1051a39Sopenharmony_ci    return ret;
391e1051a39Sopenharmony_ci}
392e1051a39Sopenharmony_ci
393e1051a39Sopenharmony_civoid engine_load_dasync_int(void)
394e1051a39Sopenharmony_ci{
395e1051a39Sopenharmony_ci    ENGINE *toadd = engine_dasync();
396e1051a39Sopenharmony_ci    if (!toadd)
397e1051a39Sopenharmony_ci        return;
398e1051a39Sopenharmony_ci    ERR_set_mark();
399e1051a39Sopenharmony_ci    ENGINE_add(toadd);
400e1051a39Sopenharmony_ci    /*
401e1051a39Sopenharmony_ci     * If the "add" worked, it gets a structural reference. So either way, we
402e1051a39Sopenharmony_ci     * release our just-created reference.
403e1051a39Sopenharmony_ci     */
404e1051a39Sopenharmony_ci    ENGINE_free(toadd);
405e1051a39Sopenharmony_ci    /*
406e1051a39Sopenharmony_ci     * If the "add" didn't work, it was probably a conflict because it was
407e1051a39Sopenharmony_ci     * already added (eg. someone calling ENGINE_load_blah then calling
408e1051a39Sopenharmony_ci     * ENGINE_load_builtin_engines() perhaps).
409e1051a39Sopenharmony_ci     */
410e1051a39Sopenharmony_ci    ERR_pop_to_mark();
411e1051a39Sopenharmony_ci}
412e1051a39Sopenharmony_ci
413e1051a39Sopenharmony_cistatic int dasync_init(ENGINE *e)
414e1051a39Sopenharmony_ci{
415e1051a39Sopenharmony_ci    return 1;
416e1051a39Sopenharmony_ci}
417e1051a39Sopenharmony_ci
418e1051a39Sopenharmony_ci
419e1051a39Sopenharmony_cistatic int dasync_finish(ENGINE *e)
420e1051a39Sopenharmony_ci{
421e1051a39Sopenharmony_ci    return 1;
422e1051a39Sopenharmony_ci}
423e1051a39Sopenharmony_ci
424e1051a39Sopenharmony_ci
425e1051a39Sopenharmony_cistatic int dasync_destroy(ENGINE *e)
426e1051a39Sopenharmony_ci{
427e1051a39Sopenharmony_ci    destroy_digests();
428e1051a39Sopenharmony_ci    destroy_ciphers();
429e1051a39Sopenharmony_ci    destroy_pkey();
430e1051a39Sopenharmony_ci    ERR_unload_DASYNC_strings();
431e1051a39Sopenharmony_ci    return 1;
432e1051a39Sopenharmony_ci}
433e1051a39Sopenharmony_ci
434e1051a39Sopenharmony_cistatic int dasync_pkey(ENGINE *e, EVP_PKEY_METHOD **pmeth,
435e1051a39Sopenharmony_ci                       const int **pnids, int nid)
436e1051a39Sopenharmony_ci{
437e1051a39Sopenharmony_ci    static const int rnid = EVP_PKEY_RSA;
438e1051a39Sopenharmony_ci
439e1051a39Sopenharmony_ci    if (pmeth == NULL) {
440e1051a39Sopenharmony_ci        *pnids = &rnid;
441e1051a39Sopenharmony_ci        return 1;
442e1051a39Sopenharmony_ci    }
443e1051a39Sopenharmony_ci
444e1051a39Sopenharmony_ci    if (nid == EVP_PKEY_RSA) {
445e1051a39Sopenharmony_ci        *pmeth = dasync_rsa;
446e1051a39Sopenharmony_ci        return 1;
447e1051a39Sopenharmony_ci    }
448e1051a39Sopenharmony_ci
449e1051a39Sopenharmony_ci    *pmeth = NULL;
450e1051a39Sopenharmony_ci    return 0;
451e1051a39Sopenharmony_ci}
452e1051a39Sopenharmony_ci
453e1051a39Sopenharmony_cistatic int dasync_digests(ENGINE *e, const EVP_MD **digest,
454e1051a39Sopenharmony_ci                          const int **nids, int nid)
455e1051a39Sopenharmony_ci{
456e1051a39Sopenharmony_ci    int ok = 1;
457e1051a39Sopenharmony_ci    if (!digest) {
458e1051a39Sopenharmony_ci        /* We are returning a list of supported nids */
459e1051a39Sopenharmony_ci        return dasync_digest_nids(nids);
460e1051a39Sopenharmony_ci    }
461e1051a39Sopenharmony_ci    /* We are being asked for a specific digest */
462e1051a39Sopenharmony_ci    switch (nid) {
463e1051a39Sopenharmony_ci    case NID_sha1:
464e1051a39Sopenharmony_ci        *digest = dasync_sha1();
465e1051a39Sopenharmony_ci        break;
466e1051a39Sopenharmony_ci    default:
467e1051a39Sopenharmony_ci        ok = 0;
468e1051a39Sopenharmony_ci        *digest = NULL;
469e1051a39Sopenharmony_ci        break;
470e1051a39Sopenharmony_ci    }
471e1051a39Sopenharmony_ci    return ok;
472e1051a39Sopenharmony_ci}
473e1051a39Sopenharmony_ci
474e1051a39Sopenharmony_cistatic int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
475e1051a39Sopenharmony_ci                                   const int **nids, int nid)
476e1051a39Sopenharmony_ci{
477e1051a39Sopenharmony_ci    int ok = 1;
478e1051a39Sopenharmony_ci    if (cipher == NULL) {
479e1051a39Sopenharmony_ci        /* We are returning a list of supported nids */
480e1051a39Sopenharmony_ci        *nids = dasync_cipher_nids;
481e1051a39Sopenharmony_ci        return (sizeof(dasync_cipher_nids) -
482e1051a39Sopenharmony_ci                1) / sizeof(dasync_cipher_nids[0]);
483e1051a39Sopenharmony_ci    }
484e1051a39Sopenharmony_ci    /* We are being asked for a specific cipher */
485e1051a39Sopenharmony_ci    switch (nid) {
486e1051a39Sopenharmony_ci    case NID_aes_128_cbc:
487e1051a39Sopenharmony_ci        *cipher = dasync_aes_128_cbc();
488e1051a39Sopenharmony_ci        break;
489e1051a39Sopenharmony_ci    case NID_aes_256_ctr:
490e1051a39Sopenharmony_ci        *cipher = dasync_aes_256_ctr();
491e1051a39Sopenharmony_ci        break;
492e1051a39Sopenharmony_ci    case NID_aes_128_cbc_hmac_sha1:
493e1051a39Sopenharmony_ci        *cipher = dasync_aes_128_cbc_hmac_sha1();
494e1051a39Sopenharmony_ci        break;
495e1051a39Sopenharmony_ci    default:
496e1051a39Sopenharmony_ci        ok = 0;
497e1051a39Sopenharmony_ci        *cipher = NULL;
498e1051a39Sopenharmony_ci        break;
499e1051a39Sopenharmony_ci    }
500e1051a39Sopenharmony_ci    return ok;
501e1051a39Sopenharmony_ci}
502e1051a39Sopenharmony_ci
503e1051a39Sopenharmony_cistatic void wait_cleanup(ASYNC_WAIT_CTX *ctx, const void *key,
504e1051a39Sopenharmony_ci                         OSSL_ASYNC_FD readfd, void *pvwritefd)
505e1051a39Sopenharmony_ci{
506e1051a39Sopenharmony_ci    OSSL_ASYNC_FD *pwritefd = (OSSL_ASYNC_FD *)pvwritefd;
507e1051a39Sopenharmony_ci#if defined(ASYNC_WIN)
508e1051a39Sopenharmony_ci    CloseHandle(readfd);
509e1051a39Sopenharmony_ci    CloseHandle(*pwritefd);
510e1051a39Sopenharmony_ci#elif defined(ASYNC_POSIX)
511e1051a39Sopenharmony_ci    close(readfd);
512e1051a39Sopenharmony_ci    close(*pwritefd);
513e1051a39Sopenharmony_ci#endif
514e1051a39Sopenharmony_ci    OPENSSL_free(pwritefd);
515e1051a39Sopenharmony_ci}
516e1051a39Sopenharmony_ci
517e1051a39Sopenharmony_ci#define DUMMY_CHAR 'X'
518e1051a39Sopenharmony_ci
519e1051a39Sopenharmony_cistatic void dummy_pause_job(void) {
520e1051a39Sopenharmony_ci    ASYNC_JOB *job;
521e1051a39Sopenharmony_ci    ASYNC_WAIT_CTX *waitctx;
522e1051a39Sopenharmony_ci    ASYNC_callback_fn callback;
523e1051a39Sopenharmony_ci    void * callback_arg;
524e1051a39Sopenharmony_ci    OSSL_ASYNC_FD pipefds[2] = {0, 0};
525e1051a39Sopenharmony_ci    OSSL_ASYNC_FD *writefd;
526e1051a39Sopenharmony_ci#if defined(ASYNC_WIN)
527e1051a39Sopenharmony_ci    DWORD numwritten, numread;
528e1051a39Sopenharmony_ci    char buf = DUMMY_CHAR;
529e1051a39Sopenharmony_ci#elif defined(ASYNC_POSIX)
530e1051a39Sopenharmony_ci    char buf = DUMMY_CHAR;
531e1051a39Sopenharmony_ci#endif
532e1051a39Sopenharmony_ci
533e1051a39Sopenharmony_ci    if ((job = ASYNC_get_current_job()) == NULL)
534e1051a39Sopenharmony_ci        return;
535e1051a39Sopenharmony_ci
536e1051a39Sopenharmony_ci    waitctx = ASYNC_get_wait_ctx(job);
537e1051a39Sopenharmony_ci
538e1051a39Sopenharmony_ci    if (ASYNC_WAIT_CTX_get_callback(waitctx, &callback, &callback_arg) && callback != NULL) {
539e1051a39Sopenharmony_ci        /*
540e1051a39Sopenharmony_ci         * In the Dummy async engine we are cheating. We call the callback that the job
541e1051a39Sopenharmony_ci         * is complete before the call to ASYNC_pause_job(). A real
542e1051a39Sopenharmony_ci         * async engine would only call the callback when the job was actually complete
543e1051a39Sopenharmony_ci         */
544e1051a39Sopenharmony_ci        (*callback)(callback_arg);
545e1051a39Sopenharmony_ci        ASYNC_pause_job();
546e1051a39Sopenharmony_ci        return;
547e1051a39Sopenharmony_ci    }
548e1051a39Sopenharmony_ci
549e1051a39Sopenharmony_ci
550e1051a39Sopenharmony_ci    if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_dasync_id, &pipefds[0],
551e1051a39Sopenharmony_ci                              (void **)&writefd)) {
552e1051a39Sopenharmony_ci        pipefds[1] = *writefd;
553e1051a39Sopenharmony_ci    } else {
554e1051a39Sopenharmony_ci        writefd = OPENSSL_malloc(sizeof(*writefd));
555e1051a39Sopenharmony_ci        if (writefd == NULL)
556e1051a39Sopenharmony_ci            return;
557e1051a39Sopenharmony_ci#if defined(ASYNC_WIN)
558e1051a39Sopenharmony_ci        if (CreatePipe(&pipefds[0], &pipefds[1], NULL, 256) == 0) {
559e1051a39Sopenharmony_ci            OPENSSL_free(writefd);
560e1051a39Sopenharmony_ci            return;
561e1051a39Sopenharmony_ci        }
562e1051a39Sopenharmony_ci#elif defined(ASYNC_POSIX)
563e1051a39Sopenharmony_ci        if (pipe(pipefds) != 0) {
564e1051a39Sopenharmony_ci            OPENSSL_free(writefd);
565e1051a39Sopenharmony_ci            return;
566e1051a39Sopenharmony_ci        }
567e1051a39Sopenharmony_ci#endif
568e1051a39Sopenharmony_ci        *writefd = pipefds[1];
569e1051a39Sopenharmony_ci
570e1051a39Sopenharmony_ci        if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_dasync_id, pipefds[0],
571e1051a39Sopenharmony_ci                                        writefd, wait_cleanup)) {
572e1051a39Sopenharmony_ci            wait_cleanup(waitctx, engine_dasync_id, pipefds[0], writefd);
573e1051a39Sopenharmony_ci            return;
574e1051a39Sopenharmony_ci        }
575e1051a39Sopenharmony_ci    }
576e1051a39Sopenharmony_ci    /*
577e1051a39Sopenharmony_ci     * In the Dummy async engine we are cheating. We signal that the job
578e1051a39Sopenharmony_ci     * is complete by waking it before the call to ASYNC_pause_job(). A real
579e1051a39Sopenharmony_ci     * async engine would only wake when the job was actually complete
580e1051a39Sopenharmony_ci     */
581e1051a39Sopenharmony_ci#if defined(ASYNC_WIN)
582e1051a39Sopenharmony_ci    WriteFile(pipefds[1], &buf, 1, &numwritten, NULL);
583e1051a39Sopenharmony_ci#elif defined(ASYNC_POSIX)
584e1051a39Sopenharmony_ci    if (write(pipefds[1], &buf, 1) < 0)
585e1051a39Sopenharmony_ci        return;
586e1051a39Sopenharmony_ci#endif
587e1051a39Sopenharmony_ci
588e1051a39Sopenharmony_ci    /* Ignore errors - we carry on anyway */
589e1051a39Sopenharmony_ci    ASYNC_pause_job();
590e1051a39Sopenharmony_ci
591e1051a39Sopenharmony_ci    /* Clear the wake signal */
592e1051a39Sopenharmony_ci#if defined(ASYNC_WIN)
593e1051a39Sopenharmony_ci    ReadFile(pipefds[0], &buf, 1, &numread, NULL);
594e1051a39Sopenharmony_ci#elif defined(ASYNC_POSIX)
595e1051a39Sopenharmony_ci    if (read(pipefds[0], &buf, 1) < 0)
596e1051a39Sopenharmony_ci        return;
597e1051a39Sopenharmony_ci#endif
598e1051a39Sopenharmony_ci}
599e1051a39Sopenharmony_ci
600e1051a39Sopenharmony_ci/*
601e1051a39Sopenharmony_ci * SHA1 implementation. At the moment we just defer to the standard
602e1051a39Sopenharmony_ci * implementation
603e1051a39Sopenharmony_ci */
604e1051a39Sopenharmony_cistatic int dasync_sha1_init(EVP_MD_CTX *ctx)
605e1051a39Sopenharmony_ci{
606e1051a39Sopenharmony_ci    dummy_pause_job();
607e1051a39Sopenharmony_ci
608e1051a39Sopenharmony_ci    return EVP_MD_meth_get_init(EVP_sha1())(ctx);
609e1051a39Sopenharmony_ci}
610e1051a39Sopenharmony_ci
611e1051a39Sopenharmony_cistatic int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data,
612e1051a39Sopenharmony_ci                             size_t count)
613e1051a39Sopenharmony_ci{
614e1051a39Sopenharmony_ci    dummy_pause_job();
615e1051a39Sopenharmony_ci
616e1051a39Sopenharmony_ci    return EVP_MD_meth_get_update(EVP_sha1())(ctx, data, count);
617e1051a39Sopenharmony_ci}
618e1051a39Sopenharmony_ci
619e1051a39Sopenharmony_cistatic int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
620e1051a39Sopenharmony_ci{
621e1051a39Sopenharmony_ci    dummy_pause_job();
622e1051a39Sopenharmony_ci
623e1051a39Sopenharmony_ci    return EVP_MD_meth_get_final(EVP_sha1())(ctx, md);
624e1051a39Sopenharmony_ci}
625e1051a39Sopenharmony_ci
626e1051a39Sopenharmony_ci/* Cipher helper functions */
627e1051a39Sopenharmony_ci
628e1051a39Sopenharmony_cistatic int dasync_cipher_ctrl_helper(EVP_CIPHER_CTX *ctx, int type, int arg,
629e1051a39Sopenharmony_ci                                     void *ptr, int aeadcapable,
630e1051a39Sopenharmony_ci                                     const EVP_CIPHER *ciph)
631e1051a39Sopenharmony_ci{
632e1051a39Sopenharmony_ci    int ret;
633e1051a39Sopenharmony_ci    struct dasync_pipeline_ctx *pipe_ctx =
634e1051a39Sopenharmony_ci        (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
635e1051a39Sopenharmony_ci
636e1051a39Sopenharmony_ci    if (pipe_ctx == NULL)
637e1051a39Sopenharmony_ci        return 0;
638e1051a39Sopenharmony_ci
639e1051a39Sopenharmony_ci    switch (type) {
640e1051a39Sopenharmony_ci        case EVP_CTRL_COPY:
641e1051a39Sopenharmony_ci            {
642e1051a39Sopenharmony_ci                size_t sz = EVP_CIPHER_impl_ctx_size(ciph);
643e1051a39Sopenharmony_ci                void *inner_cipher_data = OPENSSL_malloc(sz);
644e1051a39Sopenharmony_ci
645e1051a39Sopenharmony_ci                if (inner_cipher_data == NULL)
646e1051a39Sopenharmony_ci                    return -1;
647e1051a39Sopenharmony_ci                memcpy(inner_cipher_data, pipe_ctx->inner_cipher_data, sz);
648e1051a39Sopenharmony_ci                pipe_ctx->inner_cipher_data = inner_cipher_data;
649e1051a39Sopenharmony_ci            }
650e1051a39Sopenharmony_ci            break;
651e1051a39Sopenharmony_ci
652e1051a39Sopenharmony_ci        case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS:
653e1051a39Sopenharmony_ci            pipe_ctx->numpipes = arg;
654e1051a39Sopenharmony_ci            pipe_ctx->outbufs = (unsigned char **)ptr;
655e1051a39Sopenharmony_ci            break;
656e1051a39Sopenharmony_ci
657e1051a39Sopenharmony_ci        case EVP_CTRL_SET_PIPELINE_INPUT_BUFS:
658e1051a39Sopenharmony_ci            pipe_ctx->numpipes = arg;
659e1051a39Sopenharmony_ci            pipe_ctx->inbufs = (unsigned char **)ptr;
660e1051a39Sopenharmony_ci            break;
661e1051a39Sopenharmony_ci
662e1051a39Sopenharmony_ci        case EVP_CTRL_SET_PIPELINE_INPUT_LENS:
663e1051a39Sopenharmony_ci            pipe_ctx->numpipes = arg;
664e1051a39Sopenharmony_ci            pipe_ctx->lens = (size_t *)ptr;
665e1051a39Sopenharmony_ci            break;
666e1051a39Sopenharmony_ci
667e1051a39Sopenharmony_ci        case EVP_CTRL_AEAD_SET_MAC_KEY:
668e1051a39Sopenharmony_ci            if (!aeadcapable)
669e1051a39Sopenharmony_ci                return -1;
670e1051a39Sopenharmony_ci            EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
671e1051a39Sopenharmony_ci            ret = EVP_CIPHER_meth_get_ctrl(EVP_aes_128_cbc_hmac_sha1())
672e1051a39Sopenharmony_ci                                          (ctx, type, arg, ptr);
673e1051a39Sopenharmony_ci            EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);
674e1051a39Sopenharmony_ci            return ret;
675e1051a39Sopenharmony_ci
676e1051a39Sopenharmony_ci        case EVP_CTRL_AEAD_TLS1_AAD:
677e1051a39Sopenharmony_ci        {
678e1051a39Sopenharmony_ci            unsigned char *p = ptr;
679e1051a39Sopenharmony_ci            unsigned int len;
680e1051a39Sopenharmony_ci
681e1051a39Sopenharmony_ci            if (!aeadcapable || arg != EVP_AEAD_TLS1_AAD_LEN)
682e1051a39Sopenharmony_ci                return -1;
683e1051a39Sopenharmony_ci
684e1051a39Sopenharmony_ci            if (pipe_ctx->aadctr >= SSL_MAX_PIPELINES)
685e1051a39Sopenharmony_ci                return -1;
686e1051a39Sopenharmony_ci
687e1051a39Sopenharmony_ci            memcpy(pipe_ctx->tlsaad[pipe_ctx->aadctr], ptr,
688e1051a39Sopenharmony_ci                   EVP_AEAD_TLS1_AAD_LEN);
689e1051a39Sopenharmony_ci            pipe_ctx->aadctr++;
690e1051a39Sopenharmony_ci
691e1051a39Sopenharmony_ci            len = p[arg - 2] << 8 | p[arg - 1];
692e1051a39Sopenharmony_ci
693e1051a39Sopenharmony_ci            if (EVP_CIPHER_CTX_is_encrypting(ctx)) {
694e1051a39Sopenharmony_ci                if ((p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
695e1051a39Sopenharmony_ci                    if (len < AES_BLOCK_SIZE)
696e1051a39Sopenharmony_ci                        return 0;
697e1051a39Sopenharmony_ci                    len -= AES_BLOCK_SIZE;
698e1051a39Sopenharmony_ci                }
699e1051a39Sopenharmony_ci
700e1051a39Sopenharmony_ci                return ((len + SHA_DIGEST_LENGTH + AES_BLOCK_SIZE)
701e1051a39Sopenharmony_ci                        & -AES_BLOCK_SIZE) - len;
702e1051a39Sopenharmony_ci            } else {
703e1051a39Sopenharmony_ci                return SHA_DIGEST_LENGTH;
704e1051a39Sopenharmony_ci            }
705e1051a39Sopenharmony_ci        }
706e1051a39Sopenharmony_ci
707e1051a39Sopenharmony_ci        default:
708e1051a39Sopenharmony_ci            return 0;
709e1051a39Sopenharmony_ci    }
710e1051a39Sopenharmony_ci
711e1051a39Sopenharmony_ci    return 1;
712e1051a39Sopenharmony_ci}
713e1051a39Sopenharmony_ci
714e1051a39Sopenharmony_cistatic int dasync_cipher_init_key_helper(EVP_CIPHER_CTX *ctx,
715e1051a39Sopenharmony_ci                                         const unsigned char *key,
716e1051a39Sopenharmony_ci                                         const unsigned char *iv, int enc,
717e1051a39Sopenharmony_ci                                         const EVP_CIPHER *cipher)
718e1051a39Sopenharmony_ci{
719e1051a39Sopenharmony_ci    int ret;
720e1051a39Sopenharmony_ci    struct dasync_pipeline_ctx *pipe_ctx =
721e1051a39Sopenharmony_ci        (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
722e1051a39Sopenharmony_ci
723e1051a39Sopenharmony_ci    if (pipe_ctx->inner_cipher_data == NULL
724e1051a39Sopenharmony_ci            && EVP_CIPHER_impl_ctx_size(cipher) != 0) {
725e1051a39Sopenharmony_ci        pipe_ctx->inner_cipher_data = OPENSSL_zalloc(
726e1051a39Sopenharmony_ci            EVP_CIPHER_impl_ctx_size(cipher));
727e1051a39Sopenharmony_ci        if (pipe_ctx->inner_cipher_data == NULL) {
728e1051a39Sopenharmony_ci            DASYNCerr(DASYNC_F_DASYNC_CIPHER_INIT_KEY_HELPER,
729e1051a39Sopenharmony_ci                        ERR_R_MALLOC_FAILURE);
730e1051a39Sopenharmony_ci            return 0;
731e1051a39Sopenharmony_ci        }
732e1051a39Sopenharmony_ci    }
733e1051a39Sopenharmony_ci
734e1051a39Sopenharmony_ci    pipe_ctx->numpipes = 0;
735e1051a39Sopenharmony_ci    pipe_ctx->aadctr = 0;
736e1051a39Sopenharmony_ci
737e1051a39Sopenharmony_ci    EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
738e1051a39Sopenharmony_ci    ret = EVP_CIPHER_meth_get_init(cipher)(ctx, key, iv, enc);
739e1051a39Sopenharmony_ci    EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);
740e1051a39Sopenharmony_ci
741e1051a39Sopenharmony_ci    return ret;
742e1051a39Sopenharmony_ci}
743e1051a39Sopenharmony_ci
744e1051a39Sopenharmony_cistatic int dasync_cipher_helper(EVP_CIPHER_CTX *ctx, unsigned char *out,
745e1051a39Sopenharmony_ci                                const unsigned char *in, size_t inl,
746e1051a39Sopenharmony_ci                                const EVP_CIPHER *cipher)
747e1051a39Sopenharmony_ci{
748e1051a39Sopenharmony_ci    int ret = 1;
749e1051a39Sopenharmony_ci    unsigned int i, pipes;
750e1051a39Sopenharmony_ci    struct dasync_pipeline_ctx *pipe_ctx =
751e1051a39Sopenharmony_ci        (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
752e1051a39Sopenharmony_ci
753e1051a39Sopenharmony_ci    pipes = pipe_ctx->numpipes;
754e1051a39Sopenharmony_ci    EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
755e1051a39Sopenharmony_ci    if (pipes == 0) {
756e1051a39Sopenharmony_ci        if (pipe_ctx->aadctr != 0) {
757e1051a39Sopenharmony_ci            if (pipe_ctx->aadctr != 1)
758e1051a39Sopenharmony_ci                return -1;
759e1051a39Sopenharmony_ci            EVP_CIPHER_meth_get_ctrl(cipher)
760e1051a39Sopenharmony_ci                                    (ctx, EVP_CTRL_AEAD_TLS1_AAD,
761e1051a39Sopenharmony_ci                                     EVP_AEAD_TLS1_AAD_LEN,
762e1051a39Sopenharmony_ci                                     pipe_ctx->tlsaad[0]);
763e1051a39Sopenharmony_ci        }
764e1051a39Sopenharmony_ci        ret = EVP_CIPHER_meth_get_do_cipher(cipher)
765e1051a39Sopenharmony_ci                                           (ctx, out, in, inl);
766e1051a39Sopenharmony_ci    } else {
767e1051a39Sopenharmony_ci        if (pipe_ctx->aadctr > 0 && pipe_ctx->aadctr != pipes)
768e1051a39Sopenharmony_ci            return -1;
769e1051a39Sopenharmony_ci        for (i = 0; i < pipes; i++) {
770e1051a39Sopenharmony_ci            if (pipe_ctx->aadctr > 0) {
771e1051a39Sopenharmony_ci                EVP_CIPHER_meth_get_ctrl(cipher)
772e1051a39Sopenharmony_ci                                        (ctx, EVP_CTRL_AEAD_TLS1_AAD,
773e1051a39Sopenharmony_ci                                         EVP_AEAD_TLS1_AAD_LEN,
774e1051a39Sopenharmony_ci                                         pipe_ctx->tlsaad[i]);
775e1051a39Sopenharmony_ci            }
776e1051a39Sopenharmony_ci            ret = ret && EVP_CIPHER_meth_get_do_cipher(cipher)
777e1051a39Sopenharmony_ci                                (ctx, pipe_ctx->outbufs[i], pipe_ctx->inbufs[i],
778e1051a39Sopenharmony_ci                                 pipe_ctx->lens[i]);
779e1051a39Sopenharmony_ci        }
780e1051a39Sopenharmony_ci        pipe_ctx->numpipes = 0;
781e1051a39Sopenharmony_ci    }
782e1051a39Sopenharmony_ci    pipe_ctx->aadctr = 0;
783e1051a39Sopenharmony_ci    EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);
784e1051a39Sopenharmony_ci    return ret;
785e1051a39Sopenharmony_ci}
786e1051a39Sopenharmony_ci
787e1051a39Sopenharmony_cistatic int dasync_cipher_cleanup_helper(EVP_CIPHER_CTX *ctx,
788e1051a39Sopenharmony_ci                                        const EVP_CIPHER *cipher)
789e1051a39Sopenharmony_ci{
790e1051a39Sopenharmony_ci    struct dasync_pipeline_ctx *pipe_ctx =
791e1051a39Sopenharmony_ci        (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
792e1051a39Sopenharmony_ci
793e1051a39Sopenharmony_ci    OPENSSL_clear_free(pipe_ctx->inner_cipher_data,
794e1051a39Sopenharmony_ci                       EVP_CIPHER_impl_ctx_size(cipher));
795e1051a39Sopenharmony_ci
796e1051a39Sopenharmony_ci    return 1;
797e1051a39Sopenharmony_ci}
798e1051a39Sopenharmony_ci
799e1051a39Sopenharmony_ci/*
800e1051a39Sopenharmony_ci * AES128 CBC Implementation
801e1051a39Sopenharmony_ci */
802e1051a39Sopenharmony_ci
803e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
804e1051a39Sopenharmony_ci                                  void *ptr)
805e1051a39Sopenharmony_ci{
806e1051a39Sopenharmony_ci    return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 0, EVP_aes_128_cbc());
807e1051a39Sopenharmony_ci}
808e1051a39Sopenharmony_ci
809e1051a39Sopenharmony_cistatic int dasync_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
810e1051a39Sopenharmony_ci                             const unsigned char *iv, int enc)
811e1051a39Sopenharmony_ci{
812e1051a39Sopenharmony_ci    return dasync_cipher_init_key_helper(ctx, key, iv, enc, EVP_aes_128_cbc());
813e1051a39Sopenharmony_ci}
814e1051a39Sopenharmony_ci
815e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
816e1051a39Sopenharmony_ci                               const unsigned char *in, size_t inl)
817e1051a39Sopenharmony_ci{
818e1051a39Sopenharmony_ci    return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_128_cbc());
819e1051a39Sopenharmony_ci}
820e1051a39Sopenharmony_ci
821e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx)
822e1051a39Sopenharmony_ci{
823e1051a39Sopenharmony_ci    return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc());
824e1051a39Sopenharmony_ci}
825e1051a39Sopenharmony_ci
826e1051a39Sopenharmony_cistatic int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
827e1051a39Sopenharmony_ci                                  void *ptr)
828e1051a39Sopenharmony_ci{
829e1051a39Sopenharmony_ci    return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 0, EVP_aes_256_ctr());
830e1051a39Sopenharmony_ci}
831e1051a39Sopenharmony_ci
832e1051a39Sopenharmony_cistatic int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
833e1051a39Sopenharmony_ci                             const unsigned char *iv, int enc)
834e1051a39Sopenharmony_ci{
835e1051a39Sopenharmony_ci    return dasync_cipher_init_key_helper(ctx, key, iv, enc, EVP_aes_256_ctr());
836e1051a39Sopenharmony_ci}
837e1051a39Sopenharmony_ci
838e1051a39Sopenharmony_cistatic int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
839e1051a39Sopenharmony_ci                               const unsigned char *in, size_t inl)
840e1051a39Sopenharmony_ci{
841e1051a39Sopenharmony_ci    return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_256_ctr());
842e1051a39Sopenharmony_ci}
843e1051a39Sopenharmony_ci
844e1051a39Sopenharmony_cistatic int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx)
845e1051a39Sopenharmony_ci{
846e1051a39Sopenharmony_ci    return dasync_cipher_cleanup_helper(ctx, EVP_aes_256_ctr());
847e1051a39Sopenharmony_ci}
848e1051a39Sopenharmony_ci
849e1051a39Sopenharmony_ci
850e1051a39Sopenharmony_ci/*
851e1051a39Sopenharmony_ci * AES128 CBC HMAC SHA1 Implementation
852e1051a39Sopenharmony_ci */
853e1051a39Sopenharmony_ci
854e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
855e1051a39Sopenharmony_ci                                             int arg, void *ptr)
856e1051a39Sopenharmony_ci{
857e1051a39Sopenharmony_ci    return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 1, EVP_aes_128_cbc_hmac_sha1());
858e1051a39Sopenharmony_ci}
859e1051a39Sopenharmony_ci
860e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
861e1051a39Sopenharmony_ci                                                const unsigned char *key,
862e1051a39Sopenharmony_ci                                                const unsigned char *iv,
863e1051a39Sopenharmony_ci                                                int enc)
864e1051a39Sopenharmony_ci{
865e1051a39Sopenharmony_ci    /*
866e1051a39Sopenharmony_ci     * We can safely assume that EVP_aes_128_cbc_hmac_sha1() != NULL,
867e1051a39Sopenharmony_ci     * see comment before the definition of dasync_aes_128_cbc_hmac_sha1().
868e1051a39Sopenharmony_ci     */
869e1051a39Sopenharmony_ci    return dasync_cipher_init_key_helper(ctx, key, iv, enc,
870e1051a39Sopenharmony_ci                                         EVP_aes_128_cbc_hmac_sha1());
871e1051a39Sopenharmony_ci}
872e1051a39Sopenharmony_ci
873e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,
874e1051a39Sopenharmony_ci                                               unsigned char *out,
875e1051a39Sopenharmony_ci                                               const unsigned char *in,
876e1051a39Sopenharmony_ci                                               size_t inl)
877e1051a39Sopenharmony_ci{
878e1051a39Sopenharmony_ci    return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_128_cbc_hmac_sha1());
879e1051a39Sopenharmony_ci}
880e1051a39Sopenharmony_ci
881e1051a39Sopenharmony_cistatic int dasync_aes128_cbc_hmac_sha1_cleanup(EVP_CIPHER_CTX *ctx)
882e1051a39Sopenharmony_ci{
883e1051a39Sopenharmony_ci    /*
884e1051a39Sopenharmony_ci     * We can safely assume that EVP_aes_128_cbc_hmac_sha1() != NULL,
885e1051a39Sopenharmony_ci     * see comment before the definition of dasync_aes_128_cbc_hmac_sha1().
886e1051a39Sopenharmony_ci     */
887e1051a39Sopenharmony_ci    return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc_hmac_sha1());
888e1051a39Sopenharmony_ci}
889e1051a39Sopenharmony_ci
890e1051a39Sopenharmony_ci
891e1051a39Sopenharmony_ci/*
892e1051a39Sopenharmony_ci * RSA implementation
893e1051a39Sopenharmony_ci */
894e1051a39Sopenharmony_cistatic int dasync_rsa_init(EVP_PKEY_CTX *ctx)
895e1051a39Sopenharmony_ci{
896e1051a39Sopenharmony_ci    static int (*pinit)(EVP_PKEY_CTX *ctx);
897e1051a39Sopenharmony_ci
898e1051a39Sopenharmony_ci    if (pinit == NULL)
899e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_init(dasync_rsa_orig, &pinit);
900e1051a39Sopenharmony_ci    return pinit(ctx);
901e1051a39Sopenharmony_ci}
902e1051a39Sopenharmony_ci
903e1051a39Sopenharmony_cistatic void dasync_rsa_cleanup(EVP_PKEY_CTX *ctx)
904e1051a39Sopenharmony_ci{
905e1051a39Sopenharmony_ci    static void (*pcleanup)(EVP_PKEY_CTX *ctx);
906e1051a39Sopenharmony_ci
907e1051a39Sopenharmony_ci    if (pcleanup == NULL)
908e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_cleanup(dasync_rsa_orig, &pcleanup);
909e1051a39Sopenharmony_ci    pcleanup(ctx);
910e1051a39Sopenharmony_ci}
911e1051a39Sopenharmony_ci
912e1051a39Sopenharmony_cistatic int dasync_rsa_paramgen_init(EVP_PKEY_CTX *ctx)
913e1051a39Sopenharmony_ci{
914e1051a39Sopenharmony_ci    static int (*pparamgen_init)(EVP_PKEY_CTX *ctx);
915e1051a39Sopenharmony_ci
916e1051a39Sopenharmony_ci    if (pparamgen_init == NULL)
917e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_paramgen(dasync_rsa_orig, &pparamgen_init, NULL);
918e1051a39Sopenharmony_ci    return pparamgen_init != NULL ? pparamgen_init(ctx) : 1;
919e1051a39Sopenharmony_ci}
920e1051a39Sopenharmony_ci
921e1051a39Sopenharmony_cistatic int dasync_rsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
922e1051a39Sopenharmony_ci{
923e1051a39Sopenharmony_ci    static int (*pparamgen)(EVP_PKEY_CTX *c, EVP_PKEY *pkey);
924e1051a39Sopenharmony_ci
925e1051a39Sopenharmony_ci    if (pparamgen == NULL)
926e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_paramgen(dasync_rsa_orig, NULL, &pparamgen);
927e1051a39Sopenharmony_ci    return pparamgen != NULL ? pparamgen(ctx, pkey) : 1;
928e1051a39Sopenharmony_ci}
929e1051a39Sopenharmony_ci
930e1051a39Sopenharmony_cistatic int dasync_rsa_keygen_init(EVP_PKEY_CTX *ctx)
931e1051a39Sopenharmony_ci{
932e1051a39Sopenharmony_ci    static int (*pkeygen_init)(EVP_PKEY_CTX *ctx);
933e1051a39Sopenharmony_ci
934e1051a39Sopenharmony_ci    if (pkeygen_init == NULL)
935e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_keygen(dasync_rsa_orig, &pkeygen_init, NULL);
936e1051a39Sopenharmony_ci    return pkeygen_init != NULL ? pkeygen_init(ctx) : 1;
937e1051a39Sopenharmony_ci}
938e1051a39Sopenharmony_ci
939e1051a39Sopenharmony_cistatic int dasync_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
940e1051a39Sopenharmony_ci{
941e1051a39Sopenharmony_ci    static int (*pkeygen)(EVP_PKEY_CTX *c, EVP_PKEY *pkey);
942e1051a39Sopenharmony_ci
943e1051a39Sopenharmony_ci    if (pkeygen == NULL)
944e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_keygen(dasync_rsa_orig, NULL, &pkeygen);
945e1051a39Sopenharmony_ci    return pkeygen(ctx, pkey);
946e1051a39Sopenharmony_ci}
947e1051a39Sopenharmony_ci
948e1051a39Sopenharmony_cistatic int dasync_rsa_encrypt_init(EVP_PKEY_CTX *ctx)
949e1051a39Sopenharmony_ci{
950e1051a39Sopenharmony_ci    static int (*pencrypt_init)(EVP_PKEY_CTX *ctx);
951e1051a39Sopenharmony_ci
952e1051a39Sopenharmony_ci    if (pencrypt_init == NULL)
953e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_encrypt(dasync_rsa_orig, &pencrypt_init, NULL);
954e1051a39Sopenharmony_ci    return pencrypt_init != NULL ? pencrypt_init(ctx) : 1;
955e1051a39Sopenharmony_ci}
956e1051a39Sopenharmony_ci
957e1051a39Sopenharmony_cistatic int dasync_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
958e1051a39Sopenharmony_ci                              size_t *outlen, const unsigned char *in,
959e1051a39Sopenharmony_ci                              size_t inlen)
960e1051a39Sopenharmony_ci{
961e1051a39Sopenharmony_ci    static int (*pencryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out,
962e1051a39Sopenharmony_ci                             size_t *outlen, const unsigned char *in,
963e1051a39Sopenharmony_ci                             size_t inlen);
964e1051a39Sopenharmony_ci
965e1051a39Sopenharmony_ci    if (pencryptfn == NULL)
966e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_encrypt(dasync_rsa_orig, NULL, &pencryptfn);
967e1051a39Sopenharmony_ci    return pencryptfn(ctx, out, outlen, in, inlen);
968e1051a39Sopenharmony_ci}
969e1051a39Sopenharmony_ci
970e1051a39Sopenharmony_cistatic int dasync_rsa_decrypt_init(EVP_PKEY_CTX *ctx)
971e1051a39Sopenharmony_ci{
972e1051a39Sopenharmony_ci    static int (*pdecrypt_init)(EVP_PKEY_CTX *ctx);
973e1051a39Sopenharmony_ci
974e1051a39Sopenharmony_ci    if (pdecrypt_init == NULL)
975e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_decrypt(dasync_rsa_orig, &pdecrypt_init, NULL);
976e1051a39Sopenharmony_ci    return pdecrypt_init != NULL ? pdecrypt_init(ctx) : 1;
977e1051a39Sopenharmony_ci}
978e1051a39Sopenharmony_ci
979e1051a39Sopenharmony_cistatic int dasync_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
980e1051a39Sopenharmony_ci                              size_t *outlen, const unsigned char *in,
981e1051a39Sopenharmony_ci                              size_t inlen)
982e1051a39Sopenharmony_ci{
983e1051a39Sopenharmony_ci    static int (*pdecrypt)(EVP_PKEY_CTX *ctx, unsigned char *out,
984e1051a39Sopenharmony_ci                             size_t *outlen, const unsigned char *in,
985e1051a39Sopenharmony_ci                             size_t inlen);
986e1051a39Sopenharmony_ci
987e1051a39Sopenharmony_ci    if (pdecrypt == NULL)
988e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_encrypt(dasync_rsa_orig, NULL, &pdecrypt);
989e1051a39Sopenharmony_ci    return pdecrypt(ctx, out, outlen, in, inlen);
990e1051a39Sopenharmony_ci}
991e1051a39Sopenharmony_ci
992e1051a39Sopenharmony_cistatic int dasync_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
993e1051a39Sopenharmony_ci{
994e1051a39Sopenharmony_ci    static int (*pctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
995e1051a39Sopenharmony_ci
996e1051a39Sopenharmony_ci    if (pctrl == NULL)
997e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_ctrl(dasync_rsa_orig, &pctrl, NULL);
998e1051a39Sopenharmony_ci    return pctrl(ctx, type, p1, p2);
999e1051a39Sopenharmony_ci}
1000e1051a39Sopenharmony_ci
1001e1051a39Sopenharmony_cistatic int dasync_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
1002e1051a39Sopenharmony_ci                               const char *value)
1003e1051a39Sopenharmony_ci{
1004e1051a39Sopenharmony_ci    static int (*pctrl_str)(EVP_PKEY_CTX *ctx, const char *type,
1005e1051a39Sopenharmony_ci                            const char *value);
1006e1051a39Sopenharmony_ci
1007e1051a39Sopenharmony_ci    if (pctrl_str == NULL)
1008e1051a39Sopenharmony_ci        EVP_PKEY_meth_get_ctrl(dasync_rsa_orig, NULL, &pctrl_str);
1009e1051a39Sopenharmony_ci    return pctrl_str(ctx, type, value);
1010e1051a39Sopenharmony_ci}
1011