Home | History | Annotate | Line # | Download | only in engines
      1 /*
      2  * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the OpenSSL license (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 #if defined(_WIN32)
     11 # include <windows.h>
     12 #endif
     13 
     14 #include <stdio.h>
     15 #include <string.h>
     16 
     17 #include <openssl/engine.h>
     18 #include <openssl/sha.h>
     19 #include <openssl/aes.h>
     20 #include <openssl/rsa.h>
     21 #include <openssl/evp.h>
     22 #include <openssl/async.h>
     23 #include <openssl/bn.h>
     24 #include <openssl/crypto.h>
     25 #include <openssl/ssl.h>
     26 #include <openssl/modes.h>
     27 
     28 #if defined(OPENSSL_SYS_UNIX) && defined(OPENSSL_THREADS)
     29 # undef ASYNC_POSIX
     30 # define ASYNC_POSIX
     31 # include <unistd.h>
     32 #elif defined(_WIN32)
     33 # undef ASYNC_WIN
     34 # define ASYNC_WIN
     35 #endif
     36 
     37 #include "e_dasync_err.c"
     38 
     39 /* Engine Id and Name */
     40 static const char *engine_dasync_id = "dasync";
     41 static const char *engine_dasync_name = "Dummy Async engine support";
     42 
     43 
     44 /* Engine Lifetime functions */
     45 static int dasync_destroy(ENGINE *e);
     46 static int dasync_init(ENGINE *e);
     47 static int dasync_finish(ENGINE *e);
     48 void engine_load_dasync_int(void);
     49 
     50 
     51 /* Set up digests. Just SHA1 for now */
     52 static int dasync_digests(ENGINE *e, const EVP_MD **digest,
     53                           const int **nids, int nid);
     54 
     55 static void dummy_pause_job(void);
     56 
     57 /* SHA1 */
     58 static int dasync_sha1_init(EVP_MD_CTX *ctx);
     59 static int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data,
     60                              size_t count);
     61 static int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md);
     62 
     63 /*
     64  * Holds the EVP_MD object for sha1 in this engine. Set up once only during
     65  * engine bind and can then be reused many times.
     66  */
     67 static EVP_MD *_hidden_sha1_md = NULL;
     68 static const EVP_MD *dasync_sha1(void)
     69 {
     70     return _hidden_sha1_md;
     71 }
     72 static void destroy_digests(void)
     73 {
     74     EVP_MD_meth_free(_hidden_sha1_md);
     75     _hidden_sha1_md = NULL;
     76 }
     77 
     78 static int dasync_digest_nids(const int **nids)
     79 {
     80     static int digest_nids[2] = { 0, 0 };
     81     static int pos = 0;
     82     static int init = 0;
     83 
     84     if (!init) {
     85         const EVP_MD *md;
     86         if ((md = dasync_sha1()) != NULL)
     87             digest_nids[pos++] = EVP_MD_type(md);
     88         digest_nids[pos] = 0;
     89         init = 1;
     90     }
     91     *nids = digest_nids;
     92     return pos;
     93 }
     94 
     95 /* RSA */
     96 
     97 static int dasync_pub_enc(int flen, const unsigned char *from,
     98                     unsigned char *to, RSA *rsa, int padding);
     99 static int dasync_pub_dec(int flen, const unsigned char *from,
    100                     unsigned char *to, RSA *rsa, int padding);
    101 static int dasync_rsa_priv_enc(int flen, const unsigned char *from,
    102                       unsigned char *to, RSA *rsa, int padding);
    103 static int dasync_rsa_priv_dec(int flen, const unsigned char *from,
    104                       unsigned char *to, RSA *rsa, int padding);
    105 static int dasync_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
    106                               BN_CTX *ctx);
    107 
    108 static int dasync_rsa_init(RSA *rsa);
    109 static int dasync_rsa_finish(RSA *rsa);
    110 
    111 static RSA_METHOD *dasync_rsa_method = NULL;
    112 
    113 /* AES */
    114 
    115 static int dasync_aes128_cbc_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
    116                                   void *ptr);
    117 static int dasync_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
    118                                   const unsigned char *iv, int enc);
    119 static int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
    120                                     const unsigned char *in, size_t inl);
    121 static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx);
    122 
    123 static int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
    124                                              int arg, void *ptr);
    125 static int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
    126                                                  const unsigned char *key,
    127                                                  const unsigned char *iv,
    128                                                  int enc);
    129 static int dasync_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,
    130                                                unsigned char *out,
    131                                                const unsigned char *in,
    132                                                size_t inl);
    133 static int dasync_aes128_cbc_hmac_sha1_cleanup(EVP_CIPHER_CTX *ctx);
    134 
    135 struct dasync_pipeline_ctx {
    136     void *inner_cipher_data;
    137     unsigned int numpipes;
    138     unsigned char **inbufs;
    139     unsigned char **outbufs;
    140     size_t *lens;
    141     unsigned char tlsaad[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN];
    142     unsigned int aadctr;
    143 };
    144 
    145 /*
    146  * Holds the EVP_CIPHER object for aes_128_cbc in this engine. Set up once only
    147  * during engine bind and can then be reused many times.
    148  */
    149 static EVP_CIPHER *_hidden_aes_128_cbc = NULL;
    150 static const EVP_CIPHER *dasync_aes_128_cbc(void)
    151 {
    152     return _hidden_aes_128_cbc;
    153 }
    154 
    155 /*
    156  * Holds the EVP_CIPHER object for aes_128_cbc_hmac_sha1 in this engine. Set up
    157  * once only during engine bind and can then be reused many times.
    158  *
    159  * This 'stitched' cipher depends on the EVP_aes_128_cbc_hmac_sha1() cipher,
    160  * which is implemented only if the AES-NI instruction set extension is available
    161  * (see OPENSSL_IA32CAP(3)). If that's not the case, then this cipher will not
    162  * be available either.
    163  *
    164  * Note: Since it is a legacy mac-then-encrypt cipher, modern TLS peers (which
    165  * negotiate the encrypt-then-mac extension) won't negotiate it anyway.
    166  */
    167 static EVP_CIPHER *_hidden_aes_128_cbc_hmac_sha1 = NULL;
    168 static const EVP_CIPHER *dasync_aes_128_cbc_hmac_sha1(void)
    169 {
    170     return _hidden_aes_128_cbc_hmac_sha1;
    171 }
    172 
    173 static void destroy_ciphers(void)
    174 {
    175     EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
    176     EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);
    177     _hidden_aes_128_cbc = NULL;
    178     _hidden_aes_128_cbc_hmac_sha1 = NULL;
    179 }
    180 
    181 static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
    182                                    const int **nids, int nid);
    183 
    184 static int dasync_cipher_nids[] = {
    185     NID_aes_128_cbc_hmac_sha1,
    186     NID_aes_128_cbc,
    187     0
    188 };
    189 
    190 static int bind_dasync(ENGINE *e)
    191 {
    192     /* Setup RSA_METHOD */
    193     if ((dasync_rsa_method = RSA_meth_new("Dummy Async RSA method", 0)) == NULL
    194         || RSA_meth_set_pub_enc(dasync_rsa_method, dasync_pub_enc) == 0
    195         || RSA_meth_set_pub_dec(dasync_rsa_method, dasync_pub_dec) == 0
    196         || RSA_meth_set_priv_enc(dasync_rsa_method, dasync_rsa_priv_enc) == 0
    197         || RSA_meth_set_priv_dec(dasync_rsa_method, dasync_rsa_priv_dec) == 0
    198         || RSA_meth_set_mod_exp(dasync_rsa_method, dasync_rsa_mod_exp) == 0
    199         || RSA_meth_set_bn_mod_exp(dasync_rsa_method, BN_mod_exp_mont) == 0
    200         || RSA_meth_set_init(dasync_rsa_method, dasync_rsa_init) == 0
    201         || RSA_meth_set_finish(dasync_rsa_method, dasync_rsa_finish) == 0) {
    202         DASYNCerr(DASYNC_F_BIND_DASYNC, DASYNC_R_INIT_FAILED);
    203         return 0;
    204     }
    205 
    206     /* Ensure the dasync error handling is set up */
    207     ERR_load_DASYNC_strings();
    208 
    209     if (!ENGINE_set_id(e, engine_dasync_id)
    210         || !ENGINE_set_name(e, engine_dasync_name)
    211         || !ENGINE_set_RSA(e, dasync_rsa_method)
    212         || !ENGINE_set_digests(e, dasync_digests)
    213         || !ENGINE_set_ciphers(e, dasync_ciphers)
    214         || !ENGINE_set_destroy_function(e, dasync_destroy)
    215         || !ENGINE_set_init_function(e, dasync_init)
    216         || !ENGINE_set_finish_function(e, dasync_finish)) {
    217         DASYNCerr(DASYNC_F_BIND_DASYNC, DASYNC_R_INIT_FAILED);
    218         return 0;
    219     }
    220 
    221     /*
    222      * Set up the EVP_CIPHER and EVP_MD objects for the ciphers/digests
    223      * supplied by this engine
    224      */
    225     _hidden_sha1_md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption);
    226     if (_hidden_sha1_md == NULL
    227         || !EVP_MD_meth_set_result_size(_hidden_sha1_md, SHA_DIGEST_LENGTH)
    228         || !EVP_MD_meth_set_input_blocksize(_hidden_sha1_md, SHA_CBLOCK)
    229         || !EVP_MD_meth_set_app_datasize(_hidden_sha1_md,
    230                                          sizeof(EVP_MD *) + sizeof(SHA_CTX))
    231         || !EVP_MD_meth_set_flags(_hidden_sha1_md, EVP_MD_FLAG_DIGALGID_ABSENT)
    232         || !EVP_MD_meth_set_init(_hidden_sha1_md, dasync_sha1_init)
    233         || !EVP_MD_meth_set_update(_hidden_sha1_md, dasync_sha1_update)
    234         || !EVP_MD_meth_set_final(_hidden_sha1_md, dasync_sha1_final)) {
    235         EVP_MD_meth_free(_hidden_sha1_md);
    236         _hidden_sha1_md = NULL;
    237     }
    238 
    239     _hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc,
    240                                               16 /* block size */,
    241                                               16 /* key len */);
    242     if (_hidden_aes_128_cbc == NULL
    243             || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc,16)
    244             || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc,
    245                                           EVP_CIPH_FLAG_DEFAULT_ASN1
    246                                           | EVP_CIPH_CBC_MODE
    247                                           | EVP_CIPH_FLAG_PIPELINE
    248                                           | EVP_CIPH_CUSTOM_COPY)
    249             || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc,
    250                                          dasync_aes128_init_key)
    251             || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc,
    252                                               dasync_aes128_cbc_cipher)
    253             || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc,
    254                                             dasync_aes128_cbc_cleanup)
    255             || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc,
    256                                          dasync_aes128_cbc_ctrl)
    257             || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc,
    258                                 sizeof(struct dasync_pipeline_ctx))) {
    259         EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
    260         _hidden_aes_128_cbc = NULL;
    261     }
    262 
    263     _hidden_aes_128_cbc_hmac_sha1 = EVP_CIPHER_meth_new(
    264                                                 NID_aes_128_cbc_hmac_sha1,
    265                                                 16 /* block size */,
    266                                                 16 /* key len */);
    267     if (_hidden_aes_128_cbc_hmac_sha1 == NULL
    268             || EVP_aes_128_cbc_hmac_sha1() == NULL
    269             || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc_hmac_sha1,16)
    270             || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc_hmac_sha1,
    271                                             EVP_CIPH_CBC_MODE
    272                                           | EVP_CIPH_FLAG_DEFAULT_ASN1
    273                                           | EVP_CIPH_FLAG_AEAD_CIPHER
    274                                           | EVP_CIPH_FLAG_PIPELINE
    275                                           | EVP_CIPH_CUSTOM_COPY)
    276             || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc_hmac_sha1,
    277                                          dasync_aes128_cbc_hmac_sha1_init_key)
    278             || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc_hmac_sha1,
    279                                             dasync_aes128_cbc_hmac_sha1_cipher)
    280             || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc_hmac_sha1,
    281                                             dasync_aes128_cbc_hmac_sha1_cleanup)
    282             || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc_hmac_sha1,
    283                                          dasync_aes128_cbc_hmac_sha1_ctrl)
    284             || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc_hmac_sha1,
    285                                 sizeof(struct dasync_pipeline_ctx))) {
    286         EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);
    287         _hidden_aes_128_cbc_hmac_sha1 = NULL;
    288     }
    289 
    290     return 1;
    291 }
    292 
    293 # ifndef OPENSSL_NO_DYNAMIC_ENGINE
    294 static int bind_helper(ENGINE *e, const char *id)
    295 {
    296     if (id && (strcmp(id, engine_dasync_id) != 0))
    297         return 0;
    298     if (!bind_dasync(e))
    299         return 0;
    300     return 1;
    301 }
    302 
    303 IMPLEMENT_DYNAMIC_CHECK_FN()
    304     IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
    305 # endif
    306 
    307 static ENGINE *engine_dasync(void)
    308 {
    309     ENGINE *ret = ENGINE_new();
    310     if (!ret)
    311         return NULL;
    312     if (!bind_dasync(ret)) {
    313         ENGINE_free(ret);
    314         return NULL;
    315     }
    316     return ret;
    317 }
    318 
    319 void engine_load_dasync_int(void)
    320 {
    321     ENGINE *toadd = engine_dasync();
    322     if (!toadd)
    323         return;
    324     ENGINE_add(toadd);
    325     ENGINE_free(toadd);
    326     ERR_clear_error();
    327 }
    328 
    329 static int dasync_init(ENGINE *e)
    330 {
    331     return 1;
    332 }
    333 
    334 
    335 static int dasync_finish(ENGINE *e)
    336 {
    337     return 1;
    338 }
    339 
    340 
    341 static int dasync_destroy(ENGINE *e)
    342 {
    343     destroy_digests();
    344     destroy_ciphers();
    345     RSA_meth_free(dasync_rsa_method);
    346     ERR_unload_DASYNC_strings();
    347     return 1;
    348 }
    349 
    350 static int dasync_digests(ENGINE *e, const EVP_MD **digest,
    351                           const int **nids, int nid)
    352 {
    353     int ok = 1;
    354     if (!digest) {
    355         /* We are returning a list of supported nids */
    356         return dasync_digest_nids(nids);
    357     }
    358     /* We are being asked for a specific digest */
    359     switch (nid) {
    360     case NID_sha1:
    361         *digest = dasync_sha1();
    362         break;
    363     default:
    364         ok = 0;
    365         *digest = NULL;
    366         break;
    367     }
    368     return ok;
    369 }
    370 
    371 static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
    372                                    const int **nids, int nid)
    373 {
    374     int ok = 1;
    375     if (cipher == NULL) {
    376         /* We are returning a list of supported nids */
    377         if (dasync_aes_128_cbc_hmac_sha1() == NULL) {
    378             *nids = dasync_cipher_nids + 1;
    379             return 1;
    380         }
    381         *nids = dasync_cipher_nids;
    382         return (sizeof(dasync_cipher_nids) -
    383                 1) / sizeof(dasync_cipher_nids[0]);
    384     }
    385     /* We are being asked for a specific cipher */
    386     switch (nid) {
    387     case NID_aes_128_cbc:
    388         *cipher = dasync_aes_128_cbc();
    389         break;
    390     case NID_aes_128_cbc_hmac_sha1:
    391         *cipher = dasync_aes_128_cbc_hmac_sha1();
    392         break;
    393     default:
    394         ok = 0;
    395         *cipher = NULL;
    396         break;
    397     }
    398     return ok;
    399 }
    400 
    401 static void wait_cleanup(ASYNC_WAIT_CTX *ctx, const void *key,
    402                          OSSL_ASYNC_FD readfd, void *pvwritefd)
    403 {
    404     OSSL_ASYNC_FD *pwritefd = (OSSL_ASYNC_FD *)pvwritefd;
    405 #if defined(ASYNC_WIN)
    406     CloseHandle(readfd);
    407     CloseHandle(*pwritefd);
    408 #elif defined(ASYNC_POSIX)
    409     close(readfd);
    410     close(*pwritefd);
    411 #endif
    412     OPENSSL_free(pwritefd);
    413 }
    414 
    415 #define DUMMY_CHAR 'X'
    416 
    417 static void dummy_pause_job(void) {
    418     ASYNC_JOB *job;
    419     ASYNC_WAIT_CTX *waitctx;
    420     OSSL_ASYNC_FD pipefds[2] = {0, 0};
    421     OSSL_ASYNC_FD *writefd;
    422 #if defined(ASYNC_WIN)
    423     DWORD numwritten, numread;
    424     char buf = DUMMY_CHAR;
    425 #elif defined(ASYNC_POSIX)
    426     char buf = DUMMY_CHAR;
    427 #endif
    428 
    429     if ((job = ASYNC_get_current_job()) == NULL)
    430         return;
    431 
    432     waitctx = ASYNC_get_wait_ctx(job);
    433 
    434     if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_dasync_id, &pipefds[0],
    435                               (void **)&writefd)) {
    436         pipefds[1] = *writefd;
    437     } else {
    438         writefd = OPENSSL_malloc(sizeof(*writefd));
    439         if (writefd == NULL)
    440             return;
    441 #if defined(ASYNC_WIN)
    442         if (CreatePipe(&pipefds[0], &pipefds[1], NULL, 256) == 0) {
    443             OPENSSL_free(writefd);
    444             return;
    445         }
    446 #elif defined(ASYNC_POSIX)
    447         if (pipe(pipefds) != 0) {
    448             OPENSSL_free(writefd);
    449             return;
    450         }
    451 #endif
    452         *writefd = pipefds[1];
    453 
    454         if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_dasync_id, pipefds[0],
    455                                         writefd, wait_cleanup)) {
    456             wait_cleanup(waitctx, engine_dasync_id, pipefds[0], writefd);
    457             return;
    458         }
    459     }
    460     /*
    461      * In the Dummy async engine we are cheating. We signal that the job
    462      * is complete by waking it before the call to ASYNC_pause_job(). A real
    463      * async engine would only wake when the job was actually complete
    464      */
    465 #if defined(ASYNC_WIN)
    466     WriteFile(pipefds[1], &buf, 1, &numwritten, NULL);
    467 #elif defined(ASYNC_POSIX)
    468     if (write(pipefds[1], &buf, 1) < 0)
    469         return;
    470 #endif
    471 
    472     /* Ignore errors - we carry on anyway */
    473     ASYNC_pause_job();
    474 
    475     /* Clear the wake signal */
    476 #if defined(ASYNC_WIN)
    477     ReadFile(pipefds[0], &buf, 1, &numread, NULL);
    478 #elif defined(ASYNC_POSIX)
    479     if (read(pipefds[0], &buf, 1) < 0)
    480         return;
    481 #endif
    482 }
    483 
    484 /*
    485  * SHA1 implementation. At the moment we just defer to the standard
    486  * implementation
    487  */
    488 #undef data
    489 #define data(ctx) ((SHA_CTX *)EVP_MD_CTX_md_data(ctx))
    490 static int dasync_sha1_init(EVP_MD_CTX *ctx)
    491 {
    492     dummy_pause_job();
    493 
    494     return SHA1_Init(data(ctx));
    495 }
    496 
    497 static int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data,
    498                              size_t count)
    499 {
    500     dummy_pause_job();
    501 
    502     return SHA1_Update(data(ctx), data, (size_t)count);
    503 }
    504 
    505 static int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
    506 {
    507     dummy_pause_job();
    508 
    509     return SHA1_Final(md, data(ctx));
    510 }
    511 
    512 /*
    513  * RSA implementation
    514  */
    515 
    516 static int dasync_pub_enc(int flen, const unsigned char *from,
    517                     unsigned char *to, RSA *rsa, int padding) {
    518     /* Ignore errors - we carry on anyway */
    519     dummy_pause_job();
    520     return RSA_meth_get_pub_enc(RSA_PKCS1_OpenSSL())
    521         (flen, from, to, rsa, padding);
    522 }
    523 
    524 static int dasync_pub_dec(int flen, const unsigned char *from,
    525                     unsigned char *to, RSA *rsa, int padding) {
    526     /* Ignore errors - we carry on anyway */
    527     dummy_pause_job();
    528     return RSA_meth_get_pub_dec(RSA_PKCS1_OpenSSL())
    529         (flen, from, to, rsa, padding);
    530 }
    531 
    532 static int dasync_rsa_priv_enc(int flen, const unsigned char *from,
    533                       unsigned char *to, RSA *rsa, int padding)
    534 {
    535     /* Ignore errors - we carry on anyway */
    536     dummy_pause_job();
    537     return RSA_meth_get_priv_enc(RSA_PKCS1_OpenSSL())
    538         (flen, from, to, rsa, padding);
    539 }
    540 
    541 static int dasync_rsa_priv_dec(int flen, const unsigned char *from,
    542                       unsigned char *to, RSA *rsa, int padding)
    543 {
    544     /* Ignore errors - we carry on anyway */
    545     dummy_pause_job();
    546     return RSA_meth_get_priv_dec(RSA_PKCS1_OpenSSL())
    547         (flen, from, to, rsa, padding);
    548 }
    549 
    550 static int dasync_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
    551 {
    552     /* Ignore errors - we carry on anyway */
    553     dummy_pause_job();
    554     return RSA_meth_get_mod_exp(RSA_PKCS1_OpenSSL())(r0, I, rsa, ctx);
    555 }
    556 
    557 static int dasync_rsa_init(RSA *rsa)
    558 {
    559     return RSA_meth_get_init(RSA_PKCS1_OpenSSL())(rsa);
    560 }
    561 static int dasync_rsa_finish(RSA *rsa)
    562 {
    563     return RSA_meth_get_finish(RSA_PKCS1_OpenSSL())(rsa);
    564 }
    565 
    566 /* Cipher helper functions */
    567 
    568 static int dasync_cipher_ctrl_helper(EVP_CIPHER_CTX *ctx, int type, int arg,
    569                                      void *ptr, int aeadcapable)
    570 {
    571     int ret;
    572     struct dasync_pipeline_ctx *pipe_ctx =
    573         (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
    574 
    575     if (pipe_ctx == NULL)
    576         return 0;
    577 
    578     switch (type) {
    579         case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS:
    580             pipe_ctx->numpipes = arg;
    581             pipe_ctx->outbufs = (unsigned char **)ptr;
    582             break;
    583 
    584         case EVP_CTRL_SET_PIPELINE_INPUT_BUFS:
    585             pipe_ctx->numpipes = arg;
    586             pipe_ctx->inbufs = (unsigned char **)ptr;
    587             break;
    588 
    589         case EVP_CTRL_SET_PIPELINE_INPUT_LENS:
    590             pipe_ctx->numpipes = arg;
    591             pipe_ctx->lens = (size_t *)ptr;
    592             break;
    593 
    594         case EVP_CTRL_AEAD_SET_MAC_KEY:
    595             if (!aeadcapable)
    596                 return -1;
    597             EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
    598             ret = EVP_CIPHER_meth_get_ctrl(EVP_aes_128_cbc_hmac_sha1())
    599                                           (ctx, type, arg, ptr);
    600             EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);
    601             return ret;
    602 
    603         case EVP_CTRL_AEAD_TLS1_AAD:
    604         {
    605             unsigned char *p = ptr;
    606             unsigned int len;
    607 
    608             if (!aeadcapable || arg != EVP_AEAD_TLS1_AAD_LEN)
    609                 return -1;
    610 
    611             if (pipe_ctx->aadctr >= SSL_MAX_PIPELINES)
    612                 return -1;
    613 
    614             memcpy(pipe_ctx->tlsaad[pipe_ctx->aadctr], ptr,
    615                    EVP_AEAD_TLS1_AAD_LEN);
    616             pipe_ctx->aadctr++;
    617 
    618             len = p[arg - 2] << 8 | p[arg - 1];
    619 
    620             if (EVP_CIPHER_CTX_encrypting(ctx)) {
    621                 if ((p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
    622                     if (len < AES_BLOCK_SIZE)
    623                         return 0;
    624                     len -= AES_BLOCK_SIZE;
    625                 }
    626 
    627                 return ((len + SHA_DIGEST_LENGTH + AES_BLOCK_SIZE)
    628                         & -AES_BLOCK_SIZE) - len;
    629             } else {
    630                 return SHA_DIGEST_LENGTH;
    631             }
    632         }
    633 
    634         case EVP_CTRL_COPY:
    635         {
    636             const EVP_CIPHER *cipher = aeadcapable
    637                                        ? EVP_aes_128_cbc_hmac_sha1()
    638                                        : EVP_aes_128_cbc();
    639             size_t data_size = EVP_CIPHER_impl_ctx_size(cipher);
    640             void *cipher_data = OPENSSL_malloc(data_size);
    641 
    642             if (cipher_data == NULL)
    643                 return 0;
    644             memcpy(cipher_data, pipe_ctx->inner_cipher_data, data_size);
    645             pipe_ctx->inner_cipher_data = cipher_data;
    646             return 1;
    647         }
    648 
    649         default:
    650             return 0;
    651     }
    652 
    653     return 1;
    654 }
    655 
    656 static int dasync_cipher_init_key_helper(EVP_CIPHER_CTX *ctx,
    657                                          const unsigned char *key,
    658                                          const unsigned char *iv, int enc,
    659                                          const EVP_CIPHER *cipher)
    660 {
    661     int ret;
    662     struct dasync_pipeline_ctx *pipe_ctx =
    663         (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
    664 
    665     if (pipe_ctx->inner_cipher_data == NULL
    666             && EVP_CIPHER_impl_ctx_size(cipher) != 0) {
    667         pipe_ctx->inner_cipher_data = OPENSSL_zalloc(
    668             EVP_CIPHER_impl_ctx_size(cipher));
    669         if (pipe_ctx->inner_cipher_data == NULL) {
    670             DASYNCerr(DASYNC_F_DASYNC_CIPHER_INIT_KEY_HELPER,
    671                         ERR_R_MALLOC_FAILURE);
    672             return 0;
    673         }
    674     }
    675 
    676     pipe_ctx->numpipes = 0;
    677     pipe_ctx->aadctr = 0;
    678 
    679     EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
    680     ret = EVP_CIPHER_meth_get_init(cipher)(ctx, key, iv, enc);
    681     EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);
    682 
    683     return ret;
    684 }
    685 
    686 static int dasync_cipher_helper(EVP_CIPHER_CTX *ctx, unsigned char *out,
    687                                 const unsigned char *in, size_t inl,
    688                                 const EVP_CIPHER *cipher)
    689 {
    690     int ret = 1;
    691     unsigned int i, pipes;
    692     struct dasync_pipeline_ctx *pipe_ctx =
    693         (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
    694 
    695     pipes = pipe_ctx->numpipes;
    696     EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
    697     if (pipes == 0) {
    698         if (pipe_ctx->aadctr != 0) {
    699             if (pipe_ctx->aadctr != 1)
    700                 return -1;
    701             EVP_CIPHER_meth_get_ctrl(cipher)
    702                                     (ctx, EVP_CTRL_AEAD_TLS1_AAD,
    703                                      EVP_AEAD_TLS1_AAD_LEN,
    704                                      pipe_ctx->tlsaad[0]);
    705         }
    706         ret = EVP_CIPHER_meth_get_do_cipher(cipher)
    707                                            (ctx, out, in, inl);
    708     } else {
    709         if (pipe_ctx->aadctr > 0 && pipe_ctx->aadctr != pipes)
    710             return -1;
    711         for (i = 0; i < pipes; i++) {
    712             if (pipe_ctx->aadctr > 0) {
    713                 EVP_CIPHER_meth_get_ctrl(cipher)
    714                                         (ctx, EVP_CTRL_AEAD_TLS1_AAD,
    715                                          EVP_AEAD_TLS1_AAD_LEN,
    716                                          pipe_ctx->tlsaad[i]);
    717             }
    718             ret = ret && EVP_CIPHER_meth_get_do_cipher(cipher)
    719                                 (ctx, pipe_ctx->outbufs[i], pipe_ctx->inbufs[i],
    720                                  pipe_ctx->lens[i]);
    721         }
    722         pipe_ctx->numpipes = 0;
    723     }
    724     pipe_ctx->aadctr = 0;
    725     EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);
    726     return ret;
    727 }
    728 
    729 static int dasync_cipher_cleanup_helper(EVP_CIPHER_CTX *ctx,
    730                                         const EVP_CIPHER *cipher)
    731 {
    732     struct dasync_pipeline_ctx *pipe_ctx =
    733         (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
    734 
    735     OPENSSL_clear_free(pipe_ctx->inner_cipher_data,
    736                        EVP_CIPHER_impl_ctx_size(cipher));
    737 
    738     return 1;
    739 }
    740 
    741 /*
    742  * AES128 CBC Implementation
    743  */
    744 
    745 static int dasync_aes128_cbc_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
    746                                   void *ptr)
    747 {
    748     return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 0);
    749 }
    750 
    751 static int dasync_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
    752                              const unsigned char *iv, int enc)
    753 {
    754     return dasync_cipher_init_key_helper(ctx, key, iv, enc, EVP_aes_128_cbc());
    755 }
    756 
    757 static int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
    758                                const unsigned char *in, size_t inl)
    759 {
    760     return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_128_cbc());
    761 }
    762 
    763 static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx)
    764 {
    765     return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc());
    766 }
    767 
    768 
    769 /*
    770  * AES128 CBC HMAC SHA1 Implementation
    771  */
    772 
    773 static int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
    774                                              int arg, void *ptr)
    775 {
    776     return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 1);
    777 }
    778 
    779 static int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
    780                                                 const unsigned char *key,
    781                                                 const unsigned char *iv,
    782                                                 int enc)
    783 {
    784     /*
    785      * We can safely assume that EVP_aes_128_cbc_hmac_sha1() != NULL,
    786      * see comment before the definition of dasync_aes_128_cbc_hmac_sha1().
    787      */
    788     return dasync_cipher_init_key_helper(ctx, key, iv, enc,
    789                                          EVP_aes_128_cbc_hmac_sha1());
    790 }
    791 
    792 static int dasync_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,
    793                                                unsigned char *out,
    794                                                const unsigned char *in,
    795                                                size_t inl)
    796 {
    797     return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_128_cbc_hmac_sha1());
    798 }
    799 
    800 static int dasync_aes128_cbc_hmac_sha1_cleanup(EVP_CIPHER_CTX *ctx)
    801 {
    802     /*
    803      * We can safely assume that EVP_aes_128_cbc_hmac_sha1() != NULL,
    804      * see comment before the definition of dasync_aes_128_cbc_hmac_sha1().
    805      */
    806     return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc_hmac_sha1());
    807 }
    808