Path: blob/main/crypto/openssl/engines/e_dasync.c
104855 views
/*1* Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89/* We need to use some engine deprecated APIs */10#define OPENSSL_SUPPRESS_DEPRECATED1112/*13* SHA-1 low level APIs are deprecated for public use, but still ok for14* internal use. Note, that due to symbols not being exported, only the15* #defines and structures can be accessed, in this case SHA_CBLOCK and16* sizeof(SHA_CTX).17*/18#include "internal/deprecated.h"1920#include <openssl/opensslconf.h>21#if defined(_WIN32)22#include <windows.h>23#endif2425#include <stdio.h>26#include <string.h>2728#include <openssl/engine.h>29#include <openssl/sha.h>30#include <openssl/aes.h>31#include <openssl/rsa.h>32#include <openssl/evp.h>33#include <openssl/async.h>34#include <openssl/bn.h>35#include <openssl/crypto.h>36#include <openssl/ssl.h>37#include <openssl/modes.h>3839#if defined(OPENSSL_SYS_UNIX) && defined(OPENSSL_THREADS)40#undef ASYNC_POSIX41#define ASYNC_POSIX42#include <unistd.h>43#elif defined(_WIN32)44#undef ASYNC_WIN45#define ASYNC_WIN46#endif4748/* clang-format off */49#include "e_dasync_err.c"50/* clang-format on */5152/* Engine Id and Name */53static const char *engine_dasync_id = "dasync";54static const char *engine_dasync_name = "Dummy Async engine support";5556/* Engine Lifetime functions */57static int dasync_destroy(ENGINE *e);58static int dasync_init(ENGINE *e);59static int dasync_finish(ENGINE *e);60void engine_load_dasync_int(void);6162/* Set up digests. Just SHA1 for now */63static int dasync_digests(ENGINE *e, const EVP_MD **digest,64const int **nids, int nid);6566static void dummy_pause_job(void);6768/* SHA1 */69static int dasync_sha1_init(EVP_MD_CTX *ctx);70static int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data,71size_t count);72static int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md);7374/*75* Holds the EVP_MD object for sha1 in this engine. Set up once only during76* engine bind and can then be reused many times.77*/78static EVP_MD *_hidden_sha1_md = NULL;79static const EVP_MD *dasync_sha1(void)80{81return _hidden_sha1_md;82}83static void destroy_digests(void)84{85EVP_MD_meth_free(_hidden_sha1_md);86_hidden_sha1_md = NULL;87}8889static int dasync_digest_nids(const int **nids)90{91static int digest_nids[2] = { 0, 0 };92static int pos = 0;93static int init = 0;9495if (!init) {96const EVP_MD *md;97if ((md = dasync_sha1()) != NULL)98digest_nids[pos++] = EVP_MD_get_type(md);99digest_nids[pos] = 0;100init = 1;101}102*nids = digest_nids;103return pos;104}105106/* RSA */107static int dasync_pkey(ENGINE *e, EVP_PKEY_METHOD **pmeth,108const int **pnids, int nid);109110static int dasync_rsa_init(EVP_PKEY_CTX *ctx);111static void dasync_rsa_cleanup(EVP_PKEY_CTX *ctx);112static int dasync_rsa_paramgen_init(EVP_PKEY_CTX *ctx);113static int dasync_rsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);114static int dasync_rsa_keygen_init(EVP_PKEY_CTX *ctx);115static int dasync_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);116static int dasync_rsa_encrypt_init(EVP_PKEY_CTX *ctx);117static int dasync_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out,118size_t *outlen, const unsigned char *in,119size_t inlen);120static int dasync_rsa_decrypt_init(EVP_PKEY_CTX *ctx);121static int dasync_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out,122size_t *outlen, const unsigned char *in,123size_t inlen);124static int dasync_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);125static int dasync_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,126const char *value);127128static EVP_PKEY_METHOD *dasync_rsa;129static const EVP_PKEY_METHOD *dasync_rsa_orig;130131/* AES */132133static int dasync_aes128_cbc_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,134void *ptr);135static int dasync_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,136const unsigned char *iv, int enc);137static int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,138const unsigned char *in, size_t inl);139static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx);140141static int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,142void *ptr);143static int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,144const unsigned char *iv, int enc);145static int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,146const unsigned char *in, size_t inl);147static int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx);148149static int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,150int arg, void *ptr);151static int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,152const unsigned char *key,153const unsigned char *iv,154int enc);155static int dasync_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,156unsigned char *out,157const unsigned char *in,158size_t inl);159static int dasync_aes128_cbc_hmac_sha1_cleanup(EVP_CIPHER_CTX *ctx);160161struct dasync_pipeline_ctx {162void *inner_cipher_data;163unsigned int numpipes;164unsigned char **inbufs;165unsigned char **outbufs;166size_t *lens;167unsigned char tlsaad[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN];168unsigned int aadctr;169};170171/*172* Holds the EVP_CIPHER object for aes_128_cbc in this engine. Set up once only173* during engine bind and can then be reused many times.174*/175static EVP_CIPHER *_hidden_aes_128_cbc = NULL;176static const EVP_CIPHER *dasync_aes_128_cbc(void)177{178return _hidden_aes_128_cbc;179}180181static EVP_CIPHER *_hidden_aes_256_ctr = NULL;182static const EVP_CIPHER *dasync_aes_256_ctr(void)183{184return _hidden_aes_256_ctr;185}186187/*188* Holds the EVP_CIPHER object for aes_128_cbc_hmac_sha1 in this engine. Set up189* once only during engine bind and can then be reused many times.190*191* This 'stitched' cipher depends on the EVP_aes_128_cbc_hmac_sha1() cipher,192* which is implemented only if the AES-NI instruction set extension is available193* (see OPENSSL_IA32CAP(3)). If that's not the case, then this cipher will not194* be available either.195*196* Note: Since it is a legacy mac-then-encrypt cipher, modern TLS peers (which197* negotiate the encrypt-then-mac extension) won't negotiate it anyway.198*/199static EVP_CIPHER *_hidden_aes_128_cbc_hmac_sha1 = NULL;200static const EVP_CIPHER *dasync_aes_128_cbc_hmac_sha1(void)201{202return _hidden_aes_128_cbc_hmac_sha1;203}204205static void destroy_ciphers(void)206{207EVP_CIPHER_meth_free(_hidden_aes_128_cbc);208EVP_CIPHER_meth_free(_hidden_aes_256_ctr);209EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);210_hidden_aes_128_cbc = NULL;211_hidden_aes_256_ctr = NULL;212_hidden_aes_128_cbc_hmac_sha1 = NULL;213}214215static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher,216const int **nids, int nid);217218static int dasync_cipher_nids[] = {219NID_aes_128_cbc,220NID_aes_256_ctr,221NID_aes_128_cbc_hmac_sha1,2220223};224225static int bind_dasync(ENGINE *e)226{227/* Setup RSA */228if ((dasync_rsa_orig = EVP_PKEY_meth_find(EVP_PKEY_RSA)) == NULL229|| (dasync_rsa = EVP_PKEY_meth_new(EVP_PKEY_RSA,230EVP_PKEY_FLAG_AUTOARGLEN))231== NULL)232return 0;233EVP_PKEY_meth_set_init(dasync_rsa, dasync_rsa_init);234EVP_PKEY_meth_set_cleanup(dasync_rsa, dasync_rsa_cleanup);235EVP_PKEY_meth_set_paramgen(dasync_rsa, dasync_rsa_paramgen_init,236dasync_rsa_paramgen);237EVP_PKEY_meth_set_keygen(dasync_rsa, dasync_rsa_keygen_init,238dasync_rsa_keygen);239EVP_PKEY_meth_set_encrypt(dasync_rsa, dasync_rsa_encrypt_init,240dasync_rsa_encrypt);241EVP_PKEY_meth_set_decrypt(dasync_rsa, dasync_rsa_decrypt_init,242dasync_rsa_decrypt);243EVP_PKEY_meth_set_ctrl(dasync_rsa, dasync_rsa_ctrl,244dasync_rsa_ctrl_str);245246/* Ensure the dasync error handling is set up */247ERR_load_DASYNC_strings();248249if (!ENGINE_set_id(e, engine_dasync_id)250|| !ENGINE_set_name(e, engine_dasync_name)251|| !ENGINE_set_pkey_meths(e, dasync_pkey)252|| !ENGINE_set_digests(e, dasync_digests)253|| !ENGINE_set_ciphers(e, dasync_ciphers)254|| !ENGINE_set_destroy_function(e, dasync_destroy)255|| !ENGINE_set_init_function(e, dasync_init)256|| !ENGINE_set_finish_function(e, dasync_finish)) {257DASYNCerr(DASYNC_F_BIND_DASYNC, DASYNC_R_INIT_FAILED);258return 0;259}260261/*262* Set up the EVP_CIPHER and EVP_MD objects for the ciphers/digests263* supplied by this engine264*/265_hidden_sha1_md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption);266if (_hidden_sha1_md == NULL267|| !EVP_MD_meth_set_result_size(_hidden_sha1_md, SHA_DIGEST_LENGTH)268|| !EVP_MD_meth_set_input_blocksize(_hidden_sha1_md, SHA_CBLOCK)269|| !EVP_MD_meth_set_app_datasize(_hidden_sha1_md,270sizeof(EVP_MD *) + sizeof(SHA_CTX))271|| !EVP_MD_meth_set_flags(_hidden_sha1_md, EVP_MD_FLAG_DIGALGID_ABSENT)272|| !EVP_MD_meth_set_init(_hidden_sha1_md, dasync_sha1_init)273|| !EVP_MD_meth_set_update(_hidden_sha1_md, dasync_sha1_update)274|| !EVP_MD_meth_set_final(_hidden_sha1_md, dasync_sha1_final)) {275EVP_MD_meth_free(_hidden_sha1_md);276_hidden_sha1_md = NULL;277}278279_hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc,28016 /* block size */,28116 /* key len */);282if (_hidden_aes_128_cbc == NULL283|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc, 16)284|| !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc,285EVP_CIPH_FLAG_DEFAULT_ASN1286| EVP_CIPH_CBC_MODE287| EVP_CIPH_FLAG_PIPELINE288| EVP_CIPH_CUSTOM_COPY)289|| !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc,290dasync_aes128_init_key)291|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc,292dasync_aes128_cbc_cipher)293|| !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc,294dasync_aes128_cbc_cleanup)295|| !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc,296dasync_aes128_cbc_ctrl)297|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc,298sizeof(struct dasync_pipeline_ctx))) {299EVP_CIPHER_meth_free(_hidden_aes_128_cbc);300_hidden_aes_128_cbc = NULL;301}302303_hidden_aes_256_ctr = EVP_CIPHER_meth_new(NID_aes_256_ctr,3041 /* block size */,30532 /* key len */);306if (_hidden_aes_256_ctr == NULL307|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_256_ctr, 16)308|| !EVP_CIPHER_meth_set_flags(_hidden_aes_256_ctr,309EVP_CIPH_FLAG_DEFAULT_ASN1310| EVP_CIPH_CTR_MODE311| EVP_CIPH_FLAG_PIPELINE312| EVP_CIPH_CUSTOM_COPY)313|| !EVP_CIPHER_meth_set_init(_hidden_aes_256_ctr,314dasync_aes256_init_key)315|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_256_ctr,316dasync_aes256_ctr_cipher)317|| !EVP_CIPHER_meth_set_cleanup(_hidden_aes_256_ctr,318dasync_aes256_ctr_cleanup)319|| !EVP_CIPHER_meth_set_ctrl(_hidden_aes_256_ctr,320dasync_aes256_ctr_ctrl)321|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_256_ctr,322sizeof(struct dasync_pipeline_ctx))) {323EVP_CIPHER_meth_free(_hidden_aes_256_ctr);324_hidden_aes_256_ctr = NULL;325}326327_hidden_aes_128_cbc_hmac_sha1 = EVP_CIPHER_meth_new(328NID_aes_128_cbc_hmac_sha1,32916 /* block size */,33016 /* key len */);331if (_hidden_aes_128_cbc_hmac_sha1 == NULL332|| !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc_hmac_sha1, 16)333|| !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc_hmac_sha1,334EVP_CIPH_CBC_MODE335| EVP_CIPH_FLAG_DEFAULT_ASN1336| EVP_CIPH_FLAG_AEAD_CIPHER337| EVP_CIPH_FLAG_PIPELINE338| EVP_CIPH_CUSTOM_COPY)339|| !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc_hmac_sha1,340dasync_aes128_cbc_hmac_sha1_init_key)341|| !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc_hmac_sha1,342dasync_aes128_cbc_hmac_sha1_cipher)343|| !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc_hmac_sha1,344dasync_aes128_cbc_hmac_sha1_cleanup)345|| !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc_hmac_sha1,346dasync_aes128_cbc_hmac_sha1_ctrl)347|| !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc_hmac_sha1,348sizeof(struct dasync_pipeline_ctx))) {349EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);350_hidden_aes_128_cbc_hmac_sha1 = NULL;351}352353return 1;354}355356static void destroy_pkey(void)357{358/*359* We don't actually need to free the dasync_rsa method since this is360* automatically freed for us by libcrypto.361*/362dasync_rsa_orig = NULL;363dasync_rsa = NULL;364}365366#ifndef OPENSSL_NO_DYNAMIC_ENGINE367static int bind_helper(ENGINE *e, const char *id)368{369if (id && (strcmp(id, engine_dasync_id) != 0))370return 0;371if (!bind_dasync(e))372return 0;373return 1;374}375376IMPLEMENT_DYNAMIC_CHECK_FN()377IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)378#endif379380static ENGINE *engine_dasync(void)381{382ENGINE *ret = ENGINE_new();383if (!ret)384return NULL;385if (!bind_dasync(ret)) {386ENGINE_free(ret);387return NULL;388}389return ret;390}391392void engine_load_dasync_int(void)393{394ENGINE *toadd = engine_dasync();395if (!toadd)396return;397ERR_set_mark();398ENGINE_add(toadd);399/*400* If the "add" worked, it gets a structural reference. So either way, we401* release our just-created reference.402*/403ENGINE_free(toadd);404/*405* If the "add" didn't work, it was probably a conflict because it was406* already added (eg. someone calling ENGINE_load_blah then calling407* ENGINE_load_builtin_engines() perhaps).408*/409ERR_pop_to_mark();410}411412static int dasync_init(ENGINE *e)413{414return 1;415}416417static int dasync_finish(ENGINE *e)418{419return 1;420}421422static int dasync_destroy(ENGINE *e)423{424destroy_digests();425destroy_ciphers();426destroy_pkey();427ERR_unload_DASYNC_strings();428return 1;429}430431static int dasync_pkey(ENGINE *e, EVP_PKEY_METHOD **pmeth,432const int **pnids, int nid)433{434static const int rnid = EVP_PKEY_RSA;435436if (pmeth == NULL) {437*pnids = &rnid;438return 1;439}440441if (nid == EVP_PKEY_RSA) {442*pmeth = dasync_rsa;443return 1;444}445446*pmeth = NULL;447return 0;448}449450static int dasync_digests(ENGINE *e, const EVP_MD **digest,451const int **nids, int nid)452{453int ok = 1;454if (!digest) {455/* We are returning a list of supported nids */456return dasync_digest_nids(nids);457}458/* We are being asked for a specific digest */459switch (nid) {460case NID_sha1:461*digest = dasync_sha1();462break;463default:464ok = 0;465*digest = NULL;466break;467}468return ok;469}470471static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher,472const int **nids, int nid)473{474int ok = 1;475if (cipher == NULL) {476/* We are returning a list of supported nids */477*nids = dasync_cipher_nids;478return (sizeof(dasync_cipher_nids) - 1) / sizeof(dasync_cipher_nids[0]);479}480/* We are being asked for a specific cipher */481switch (nid) {482case NID_aes_128_cbc:483*cipher = dasync_aes_128_cbc();484break;485case NID_aes_256_ctr:486*cipher = dasync_aes_256_ctr();487break;488case NID_aes_128_cbc_hmac_sha1:489*cipher = dasync_aes_128_cbc_hmac_sha1();490break;491default:492ok = 0;493*cipher = NULL;494break;495}496return ok;497}498499static void wait_cleanup(ASYNC_WAIT_CTX *ctx, const void *key,500OSSL_ASYNC_FD readfd, void *pvwritefd)501{502OSSL_ASYNC_FD *pwritefd = (OSSL_ASYNC_FD *)pvwritefd;503#if defined(ASYNC_WIN)504CloseHandle(readfd);505CloseHandle(*pwritefd);506#elif defined(ASYNC_POSIX)507close(readfd);508close(*pwritefd);509#endif510OPENSSL_free(pwritefd);511}512513#define DUMMY_CHAR 'X'514515static void dummy_pause_job(void)516{517ASYNC_JOB *job;518ASYNC_WAIT_CTX *waitctx;519ASYNC_callback_fn callback;520void *callback_arg;521OSSL_ASYNC_FD pipefds[2] = { 0, 0 };522OSSL_ASYNC_FD *writefd;523#if defined(ASYNC_WIN)524DWORD numwritten, numread;525char buf = DUMMY_CHAR;526#elif defined(ASYNC_POSIX)527char buf = DUMMY_CHAR;528#endif529530if ((job = ASYNC_get_current_job()) == NULL)531return;532533waitctx = ASYNC_get_wait_ctx(job);534535if (ASYNC_WAIT_CTX_get_callback(waitctx, &callback, &callback_arg) && callback != NULL) {536/*537* In the Dummy async engine we are cheating. We call the callback that the job538* is complete before the call to ASYNC_pause_job(). A real539* async engine would only call the callback when the job was actually complete540*/541(*callback)(callback_arg);542ASYNC_pause_job();543return;544}545546if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_dasync_id, &pipefds[0],547(void **)&writefd)) {548pipefds[1] = *writefd;549} else {550writefd = OPENSSL_malloc(sizeof(*writefd));551if (writefd == NULL)552return;553#if defined(ASYNC_WIN)554if (CreatePipe(&pipefds[0], &pipefds[1], NULL, 256) == 0) {555OPENSSL_free(writefd);556return;557}558#elif defined(ASYNC_POSIX)559if (pipe(pipefds) != 0) {560OPENSSL_free(writefd);561return;562}563#endif564*writefd = pipefds[1];565566if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_dasync_id, pipefds[0],567writefd, wait_cleanup)) {568wait_cleanup(waitctx, engine_dasync_id, pipefds[0], writefd);569return;570}571}572/*573* In the Dummy async engine we are cheating. We signal that the job574* is complete by waking it before the call to ASYNC_pause_job(). A real575* async engine would only wake when the job was actually complete576*/577#if defined(ASYNC_WIN)578WriteFile(pipefds[1], &buf, 1, &numwritten, NULL);579#elif defined(ASYNC_POSIX)580if (write(pipefds[1], &buf, 1) < 0)581return;582#endif583584/* Ignore errors - we carry on anyway */585ASYNC_pause_job();586587/* Clear the wake signal */588#if defined(ASYNC_WIN)589ReadFile(pipefds[0], &buf, 1, &numread, NULL);590#elif defined(ASYNC_POSIX)591if (read(pipefds[0], &buf, 1) < 0)592return;593#endif594}595596/*597* SHA1 implementation. At the moment we just defer to the standard598* implementation599*/600static int dasync_sha1_init(EVP_MD_CTX *ctx)601{602dummy_pause_job();603604return EVP_MD_meth_get_init(EVP_sha1())(ctx);605}606607static int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data,608size_t count)609{610dummy_pause_job();611612return EVP_MD_meth_get_update(EVP_sha1())(ctx, data, count);613}614615static int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)616{617dummy_pause_job();618619return EVP_MD_meth_get_final(EVP_sha1())(ctx, md);620}621622/* Cipher helper functions */623624static int dasync_cipher_ctrl_helper(EVP_CIPHER_CTX *ctx, int type, int arg,625void *ptr, int aeadcapable,626const EVP_CIPHER *ciph)627{628int ret;629struct dasync_pipeline_ctx *pipe_ctx = (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);630631if (pipe_ctx == NULL)632return 0;633634switch (type) {635case EVP_CTRL_COPY: {636size_t sz = EVP_CIPHER_impl_ctx_size(ciph);637void *inner_cipher_data = OPENSSL_malloc(sz);638639if (inner_cipher_data == NULL)640return -1;641memcpy(inner_cipher_data, pipe_ctx->inner_cipher_data, sz);642pipe_ctx->inner_cipher_data = inner_cipher_data;643} break;644645case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS:646pipe_ctx->numpipes = arg;647pipe_ctx->outbufs = (unsigned char **)ptr;648break;649650case EVP_CTRL_SET_PIPELINE_INPUT_BUFS:651pipe_ctx->numpipes = arg;652pipe_ctx->inbufs = (unsigned char **)ptr;653break;654655case EVP_CTRL_SET_PIPELINE_INPUT_LENS:656pipe_ctx->numpipes = arg;657pipe_ctx->lens = (size_t *)ptr;658break;659660case EVP_CTRL_AEAD_SET_MAC_KEY:661if (!aeadcapable)662return -1;663EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);664ret = EVP_CIPHER_meth_get_ctrl(EVP_aes_128_cbc_hmac_sha1())(ctx, type, arg, ptr);665EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);666return ret;667668case EVP_CTRL_AEAD_TLS1_AAD: {669unsigned char *p = ptr;670unsigned int len;671672if (!aeadcapable || arg != EVP_AEAD_TLS1_AAD_LEN)673return -1;674675if (pipe_ctx->aadctr >= SSL_MAX_PIPELINES)676return -1;677678memcpy(pipe_ctx->tlsaad[pipe_ctx->aadctr], ptr,679EVP_AEAD_TLS1_AAD_LEN);680pipe_ctx->aadctr++;681682len = p[arg - 2] << 8 | p[arg - 1];683684if (EVP_CIPHER_CTX_is_encrypting(ctx)) {685if ((p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {686if (len < AES_BLOCK_SIZE)687return 0;688len -= AES_BLOCK_SIZE;689}690691return ((len + SHA_DIGEST_LENGTH + AES_BLOCK_SIZE)692& -AES_BLOCK_SIZE)693- len;694} else {695return SHA_DIGEST_LENGTH;696}697}698699default:700return 0;701}702703return 1;704}705706static int dasync_cipher_init_key_helper(EVP_CIPHER_CTX *ctx,707const unsigned char *key,708const unsigned char *iv, int enc,709const EVP_CIPHER *cipher)710{711int ret;712struct dasync_pipeline_ctx *pipe_ctx = (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);713714if (pipe_ctx->inner_cipher_data == NULL715&& EVP_CIPHER_impl_ctx_size(cipher) != 0) {716pipe_ctx->inner_cipher_data = OPENSSL_zalloc(717EVP_CIPHER_impl_ctx_size(cipher));718if (pipe_ctx->inner_cipher_data == NULL)719return 0;720}721722pipe_ctx->numpipes = 0;723pipe_ctx->aadctr = 0;724725EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);726ret = EVP_CIPHER_meth_get_init(cipher)(ctx, key, iv, enc);727EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);728729return ret;730}731732static int dasync_cipher_helper(EVP_CIPHER_CTX *ctx, unsigned char *out,733const unsigned char *in, size_t inl,734const EVP_CIPHER *cipher)735{736int ret = 1;737unsigned int i, pipes;738struct dasync_pipeline_ctx *pipe_ctx = (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);739740pipes = pipe_ctx->numpipes;741EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);742if (pipes == 0) {743if (pipe_ctx->aadctr != 0) {744if (pipe_ctx->aadctr != 1)745return -1;746EVP_CIPHER_meth_get_ctrl(cipher)(ctx, EVP_CTRL_AEAD_TLS1_AAD,747EVP_AEAD_TLS1_AAD_LEN,748pipe_ctx->tlsaad[0]);749}750ret = EVP_CIPHER_meth_get_do_cipher(cipher)(ctx, out, in, inl);751} else {752if (pipe_ctx->aadctr > 0 && pipe_ctx->aadctr != pipes)753return -1;754for (i = 0; i < pipes; i++) {755if (pipe_ctx->aadctr > 0) {756EVP_CIPHER_meth_get_ctrl(cipher)(ctx, EVP_CTRL_AEAD_TLS1_AAD,757EVP_AEAD_TLS1_AAD_LEN,758pipe_ctx->tlsaad[i]);759}760ret = ret && EVP_CIPHER_meth_get_do_cipher(cipher)(ctx, pipe_ctx->outbufs[i], pipe_ctx->inbufs[i], pipe_ctx->lens[i]);761}762pipe_ctx->numpipes = 0;763}764pipe_ctx->aadctr = 0;765EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);766return ret;767}768769static int dasync_cipher_cleanup_helper(EVP_CIPHER_CTX *ctx,770const EVP_CIPHER *cipher)771{772struct dasync_pipeline_ctx *pipe_ctx = (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);773774OPENSSL_clear_free(pipe_ctx->inner_cipher_data,775EVP_CIPHER_impl_ctx_size(cipher));776777return 1;778}779780/*781* AES128 CBC Implementation782*/783784static int dasync_aes128_cbc_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,785void *ptr)786{787return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 0, EVP_aes_128_cbc());788}789790static int dasync_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,791const unsigned char *iv, int enc)792{793return dasync_cipher_init_key_helper(ctx, key, iv, enc, EVP_aes_128_cbc());794}795796static int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,797const unsigned char *in, size_t inl)798{799return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_128_cbc());800}801802static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx)803{804return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc());805}806807static int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,808void *ptr)809{810return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 0, EVP_aes_256_ctr());811}812813static int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,814const unsigned char *iv, int enc)815{816return dasync_cipher_init_key_helper(ctx, key, iv, enc, EVP_aes_256_ctr());817}818819static int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,820const unsigned char *in, size_t inl)821{822return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_256_ctr());823}824825static int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx)826{827return dasync_cipher_cleanup_helper(ctx, EVP_aes_256_ctr());828}829830/*831* AES128 CBC HMAC SHA1 Implementation832*/833834static int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,835int arg, void *ptr)836{837return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 1, EVP_aes_128_cbc_hmac_sha1());838}839840static int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,841const unsigned char *key,842const unsigned char *iv,843int enc)844{845/*846* We can safely assume that EVP_aes_128_cbc_hmac_sha1() != NULL,847* see comment before the definition of dasync_aes_128_cbc_hmac_sha1().848*/849return dasync_cipher_init_key_helper(ctx, key, iv, enc,850EVP_aes_128_cbc_hmac_sha1());851}852853static int dasync_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,854unsigned char *out,855const unsigned char *in,856size_t inl)857{858return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_128_cbc_hmac_sha1());859}860861static int dasync_aes128_cbc_hmac_sha1_cleanup(EVP_CIPHER_CTX *ctx)862{863/*864* We can safely assume that EVP_aes_128_cbc_hmac_sha1() != NULL,865* see comment before the definition of dasync_aes_128_cbc_hmac_sha1().866*/867return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc_hmac_sha1());868}869870/*871* RSA implementation872*/873static int dasync_rsa_init(EVP_PKEY_CTX *ctx)874{875static int (*pinit)(EVP_PKEY_CTX *ctx);876877if (pinit == NULL)878EVP_PKEY_meth_get_init(dasync_rsa_orig, &pinit);879return pinit(ctx);880}881882static void dasync_rsa_cleanup(EVP_PKEY_CTX *ctx)883{884static void (*pcleanup)(EVP_PKEY_CTX *ctx);885886if (pcleanup == NULL)887EVP_PKEY_meth_get_cleanup(dasync_rsa_orig, &pcleanup);888pcleanup(ctx);889}890891static int dasync_rsa_paramgen_init(EVP_PKEY_CTX *ctx)892{893static int (*pparamgen_init)(EVP_PKEY_CTX *ctx);894895if (pparamgen_init == NULL)896EVP_PKEY_meth_get_paramgen(dasync_rsa_orig, &pparamgen_init, NULL);897return pparamgen_init != NULL ? pparamgen_init(ctx) : 1;898}899900static int dasync_rsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)901{902static int (*pparamgen)(EVP_PKEY_CTX *c, EVP_PKEY *pkey);903904if (pparamgen == NULL)905EVP_PKEY_meth_get_paramgen(dasync_rsa_orig, NULL, &pparamgen);906return pparamgen != NULL ? pparamgen(ctx, pkey) : 1;907}908909static int dasync_rsa_keygen_init(EVP_PKEY_CTX *ctx)910{911static int (*pkeygen_init)(EVP_PKEY_CTX *ctx);912913if (pkeygen_init == NULL)914EVP_PKEY_meth_get_keygen(dasync_rsa_orig, &pkeygen_init, NULL);915return pkeygen_init != NULL ? pkeygen_init(ctx) : 1;916}917918static int dasync_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)919{920static int (*pkeygen)(EVP_PKEY_CTX *c, EVP_PKEY *pkey);921922if (pkeygen == NULL)923EVP_PKEY_meth_get_keygen(dasync_rsa_orig, NULL, &pkeygen);924return pkeygen(ctx, pkey);925}926927static int dasync_rsa_encrypt_init(EVP_PKEY_CTX *ctx)928{929static int (*pencrypt_init)(EVP_PKEY_CTX *ctx);930931if (pencrypt_init == NULL)932EVP_PKEY_meth_get_encrypt(dasync_rsa_orig, &pencrypt_init, NULL);933return pencrypt_init != NULL ? pencrypt_init(ctx) : 1;934}935936static int dasync_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out,937size_t *outlen, const unsigned char *in,938size_t inlen)939{940static int (*pencryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out,941size_t *outlen, const unsigned char *in,942size_t inlen);943944if (pencryptfn == NULL)945EVP_PKEY_meth_get_encrypt(dasync_rsa_orig, NULL, &pencryptfn);946return pencryptfn(ctx, out, outlen, in, inlen);947}948949static int dasync_rsa_decrypt_init(EVP_PKEY_CTX *ctx)950{951static int (*pdecrypt_init)(EVP_PKEY_CTX *ctx);952953if (pdecrypt_init == NULL)954EVP_PKEY_meth_get_decrypt(dasync_rsa_orig, &pdecrypt_init, NULL);955return pdecrypt_init != NULL ? pdecrypt_init(ctx) : 1;956}957958static int dasync_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out,959size_t *outlen, const unsigned char *in,960size_t inlen)961{962static int (*pdecrypt)(EVP_PKEY_CTX *ctx, unsigned char *out,963size_t *outlen, const unsigned char *in,964size_t inlen);965966if (pdecrypt == NULL)967EVP_PKEY_meth_get_decrypt(dasync_rsa_orig, NULL, &pdecrypt);968return pdecrypt(ctx, out, outlen, in, inlen);969}970971static int dasync_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)972{973static int (*pctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);974975if (pctrl == NULL)976EVP_PKEY_meth_get_ctrl(dasync_rsa_orig, &pctrl, NULL);977return pctrl(ctx, type, p1, p2);978}979980static int dasync_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,981const char *value)982{983static int (*pctrl_str)(EVP_PKEY_CTX *ctx, const char *type,984const char *value);985986if (pctrl_str == NULL)987EVP_PKEY_meth_get_ctrl(dasync_rsa_orig, NULL, &pctrl_str);988return pctrl_str(ctx, type, value);989}990991992