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