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