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