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