[lng-odp] [RFC OPNESSL-ODP 2/2] Adding Async ODP engine for AES cipher
--- README | 21 +++ engine/eng_odp.c | 437 +++ 2 files changed, 458 insertions(+) create mode 100644 README create mode 100644 engine/eng_odp.c diff --git a/README b/README new file mode 100644 index 000..b13393a --- /dev/null +++ b/README @@ -0,0 +1,21 @@ +Copyright (c) 2013-2014, Linaro Limited +All rights reserved. + +SPDX-License-Identifier:BSD-3-Clause + +OpenDataPlane (ODP) project source code. +http://www.opendataplane.org/ + +How to build: +Following are the steep to build this object: +./bootstrap +./configure --with-openssl-path= --with-odp-path= +make + +How to run. +Copy the shared object engine/.libs/libsslodp.so to "opnessl path"/lib/engines/. +Execute any openssl application with arguments "-engine libsslodp". + +Currently, we have tested openssl speed application with NXP platform. + + diff --git a/engine/eng_odp.c b/engine/eng_odp.c new file mode 100644 index 000..91151ae --- /dev/null +++ b/engine/eng_odp.c @@ -0,0 +1,437 @@ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +odp_pool_t pool; +int num_queue = 8; +odp_queue_t out_queue[8]; + +typedef struct ossl_odp_status { + bool is_complete; + bool is_successful; +} ossl_odp_status_t; + +/* Engine Id and Name */ +static const char *engine_odp_id = "libsslodp"; +static const char *engine_odp_name = "ODP based engine"; + +/* Engine Lifetime functions */ +static int ossl_odp_destroy(ENGINE *e); +static int ossl_odp_init(ENGINE *e); +static int ossl_odp_finish(ENGINE *e); + +/* Set up digests. Just SHA1 for now */ +static int ossl_odp_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid); + +/* + * Holds the EVP_MD object for sha1 in this engine. Set up once only during + * engine bind and can then be reused many times. + */ +static EVP_MD *_hidden_sha1_md = NULL; +static const EVP_MD *ossl_odp_sha1(void) +{ + return _hidden_sha1_md; +} +static void destroy_digests(void) +{ + EVP_MD_meth_free(_hidden_sha1_md); + _hidden_sha1_md = NULL; +} + + +static int ossl_odp_digest_nids(const int **nids) +{ + static int digest_nids[2] = { 0, 0 }; + static int pos = 0; + static int init = 0; + + if (!init) { + const EVP_MD *md; + if ((md = ossl_odp_sha1()) != NULL) + digest_nids[pos++] = EVP_MD_type(md); + digest_nids[pos] = 0; + init = 1; + } + *nids = digest_nids; + return pos; +} + +/* AES */ + +static int ossl_odp_aes128_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *key, const unsigned char *iv, int enc); +static int ossl_odp_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +static int ossl_odp_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx); + +struct ossl_odp_ctx { + odp_crypto_session_t session; +}; + +/* + * Holds the EVP_CIPHER object for aes_128_cbc in this engine. Set up once only + * during engine bind and can then be reused many times. + */ +static EVP_CIPHER *_hidden_aes_128_cbc; +static const EVP_CIPHER *ossl_odp_aes_128_cbc(void) +{ + return _hidden_aes_128_cbc; +} + +static void destroy_ciphers(void) +{ + EVP_CIPHER_meth_free(_hidden_aes_128_cbc); + _hidden_aes_128_cbc = NULL; +} + +static int ossl_odp_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); + +static int ossl_odp_cipher_nids[] = { + NID_aes_128_cbc, + 0 +}; + + +static int bind_odp(ENGINE *e) +{ + odp_queue_param_t qparam; + odp_pool_param_t params; + int i; + if (0 != odp_init_global(NULL, NULL)) { + printf("error: odp_init_global() failed.\n"); + return -1; + } + + if (0 != odp_init_local(ODP_THREAD_WORKER)) { + printf("error: odp_init_local() failed.\n"); + return -1; + } + + memset(¶ms, 0, sizeof(params)); + params.pkt.seg_len = 20480; + params.pkt.len = 20480; + params.pkt.num = 4096; + params.type = ODP_POOL_PACKET; + + pool = odp_pool_create("ossl_odp_pool", ¶ms); + + if (ODP_POOL_INVALID == pool) { + printf("Packet pool creation failed.\n"); + odp_term_local(); + odp_term_global(); + return -1; + } + odp_queue_param_init(&qparam); + qparam.sched.prio = ODP_SCHED_PRIO_HIGHEST; + qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; + qparam.sched.group = ODP_SCHED_GROUP_ALL; + for (i = 0; i < num_queue; i++) { + char queue_name[256] = {0}; + sprintf(queue_name, "%s%d", "ossl_out_queue_", i); + out_queue[i] = odp_queue_create(queue_name, +
Re: [lng-odp] [RFC OPNESSL-ODP 2/2] Adding Async ODP engine for AES cipher
On Fri, Jun 3, 2016 at 12:59 PM, Nikhil Agarwal wrote: > --- > engine/eng_odp.c | 375 > +++ > 1 file changed, 375 insertions(+) > create mode 100644 engine/eng_odp.c > > diff --git a/engine/eng_odp.c b/engine/eng_odp.c > new file mode 100644 > index 000..3340649 > --- /dev/null > +++ b/engine/eng_odp.c > @@ -0,0 +1,375 @@ > + > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define DUMMY_CHAR 'X' > +odp_pool_t pool; > +int num_queue = 8; > +odp_queue_t out_queue[8]; > +OSSL_ASYNC_FD pipefds[2] = {0, 0}; > + > +/* Engine Id and Name */ > +static const char *engine_odp_id = "libsslodp"; > +static const char *engine_odp_name = "ODP based engine"; > + > +/* Engine Lifetime functions */ > +static int ossl_odp_destroy(ENGINE *e); > +static int ossl_odp_init(ENGINE *e); > +static int ossl_odp_finish(ENGINE *e); > + > +/* Set up digests. Just SHA1 for now */ > +static int ossl_odp_digests(ENGINE *e, const EVP_MD **digest, > + const int **nids, int nid); > + > +/* > + * Holds the EVP_MD object for sha1 in this engine. Set up once only > during > + * engine bind and can then be reused many times. > + */ > +static void destroy_digests(void) > +{ > + /*Nothing for now*/ > +} > + > +static int ossl_odp_digest_nids(const int **nids) > +{ > + int digest_nids[2] = { 0, 0 }; > + > + *nids = digest_nids; > + return 1; > +} > + > +/* AES */ > + > +static int ossl_odp_aes128_init_key(EVP_CIPHER_CTX *ctx, > + const unsigned char *key, const unsigned char *iv, int > enc); > +static int ossl_odp_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char > *out, > + const unsigned char *in, size_t inl); > +static int ossl_odp_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx); > + > +struct ossl_odp_ctx { > + odp_crypto_session_t session; > +}; > + > +/* > + * Holds the EVP_CIPHER object for aes_128_cbc in this engine. Set up > once only > + * during engine bind and can then be reused many times. > + */ > +static EVP_CIPHER *_hidden_aes_128_cbc; > +static const EVP_CIPHER *ossl_odp_aes_128_cbc(void) > +{ > + return _hidden_aes_128_cbc; > +} > + > +static void destroy_ciphers(void) > +{ > + EVP_CIPHER_meth_free(_hidden_aes_128_cbc); > + _hidden_aes_128_cbc = NULL; > +} > + > +static int ossl_odp_ciphers(ENGINE *e, const EVP_CIPHER **cipher, > + const int **nids, int nid); > + > +static int ossl_odp_cipher_nids[] = { > + NID_aes_128_cbc, > + 0 > +}; > + > +static int bind_odp(ENGINE *e) > +{ > + if (!ENGINE_set_id(e, engine_odp_id) > + || !ENGINE_set_name(e, engine_odp_name) > + || !ENGINE_set_ciphers(e, ossl_odp_ciphers) > + || !ENGINE_set_destroy_function(e, > ossl_odp_destroy) > + || !ENGINE_set_init_function(e, ossl_odp_init) > + || !ENGINE_set_finish_function(e, > ossl_odp_finish)) { > + return 0; > + } > + > + _hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc, > + 16 /* block size */, > + 16 /* key len */); > + if (_hidden_aes_128_cbc == NULL > + || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc, 16) > + || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc, > + EVP_CIPH_FLAG_DEFAULT_ASN1 > + | EVP_CIPH_CBC_MODE) > + || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc, > + ossl_odp_aes128_init_key) > + || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc, > + ossl_odp_aes128_cbc_cipher) > + || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc, > + ossl_odp_aes128_cbc_cleanup) > + || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc, > + sizeof(struct ossl_odp_ctx))) { > + EVP_CIPHER_meth_free(_hidden_aes_128_cbc); > + _hidden_aes_128_cbc = NULL; > + } > + return 1; > +} > + > +static int bind_helper(ENGINE *e, const char *id) > +{ > + if (id && (strcmp(id, engine_odp_id) != 0)) > + return 0; > + if (!bind_odp(e)) > + return 0; > + return 1; > +} > + > +IMPLEMENT_DYNAMIC_CHECK_FN() > +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) > + > +static int ossl_odp_init(ENGINE *e) > +{ > + odp_queue_param_t qparam; > + odp_pool_param_t params; > + int i; > + char buf = DUMMY_CHAR; > + > + if (0 != odp_init_global(NULL, NULL)) { > odp_init_global() now takes an instance output variable as it's first argument. You need to save that for use in both odp_init_local() as well as odp_term_global() > + printf("error:
[lng-odp] [RFC OPNESSL-ODP 2/2] Adding Async ODP engine for AES cipher
--- engine/eng_odp.c | 375 +++ 1 file changed, 375 insertions(+) create mode 100644 engine/eng_odp.c diff --git a/engine/eng_odp.c b/engine/eng_odp.c new file mode 100644 index 000..3340649 --- /dev/null +++ b/engine/eng_odp.c @@ -0,0 +1,375 @@ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DUMMY_CHAR 'X' +odp_pool_t pool; +int num_queue = 8; +odp_queue_t out_queue[8]; +OSSL_ASYNC_FD pipefds[2] = {0, 0}; + +/* Engine Id and Name */ +static const char *engine_odp_id = "libsslodp"; +static const char *engine_odp_name = "ODP based engine"; + +/* Engine Lifetime functions */ +static int ossl_odp_destroy(ENGINE *e); +static int ossl_odp_init(ENGINE *e); +static int ossl_odp_finish(ENGINE *e); + +/* Set up digests. Just SHA1 for now */ +static int ossl_odp_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid); + +/* + * Holds the EVP_MD object for sha1 in this engine. Set up once only during + * engine bind and can then be reused many times. + */ +static void destroy_digests(void) +{ + /*Nothing for now*/ +} + +static int ossl_odp_digest_nids(const int **nids) +{ + int digest_nids[2] = { 0, 0 }; + + *nids = digest_nids; + return 1; +} + +/* AES */ + +static int ossl_odp_aes128_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *key, const unsigned char *iv, int enc); +static int ossl_odp_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +static int ossl_odp_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx); + +struct ossl_odp_ctx { + odp_crypto_session_t session; +}; + +/* + * Holds the EVP_CIPHER object for aes_128_cbc in this engine. Set up once only + * during engine bind and can then be reused many times. + */ +static EVP_CIPHER *_hidden_aes_128_cbc; +static const EVP_CIPHER *ossl_odp_aes_128_cbc(void) +{ + return _hidden_aes_128_cbc; +} + +static void destroy_ciphers(void) +{ + EVP_CIPHER_meth_free(_hidden_aes_128_cbc); + _hidden_aes_128_cbc = NULL; +} + +static int ossl_odp_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); + +static int ossl_odp_cipher_nids[] = { + NID_aes_128_cbc, + 0 +}; + +static int bind_odp(ENGINE *e) +{ + if (!ENGINE_set_id(e, engine_odp_id) + || !ENGINE_set_name(e, engine_odp_name) + || !ENGINE_set_ciphers(e, ossl_odp_ciphers) + || !ENGINE_set_destroy_function(e, ossl_odp_destroy) + || !ENGINE_set_init_function(e, ossl_odp_init) + || !ENGINE_set_finish_function(e, ossl_odp_finish)) { + return 0; + } + + _hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc, + 16 /* block size */, + 16 /* key len */); + if (_hidden_aes_128_cbc == NULL + || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc, 16) + || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc, + EVP_CIPH_FLAG_DEFAULT_ASN1 + | EVP_CIPH_CBC_MODE) + || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc, + ossl_odp_aes128_init_key) + || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc, + ossl_odp_aes128_cbc_cipher) + || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc, + ossl_odp_aes128_cbc_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc, + sizeof(struct ossl_odp_ctx))) { + EVP_CIPHER_meth_free(_hidden_aes_128_cbc); + _hidden_aes_128_cbc = NULL; + } + return 1; +} + +static int bind_helper(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_odp_id) != 0)) + return 0; + if (!bind_odp(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) + +static int ossl_odp_init(ENGINE *e) +{ + odp_queue_param_t qparam; + odp_pool_param_t params; + int i; + char buf = DUMMY_CHAR; + + if (0 != odp_init_global(NULL, NULL)) { + printf("error: odp_init_global() failed.\n"); + return -1; + } + if (0 != odp_init_local(ODP_THREAD_WORKER)) { + printf("error: odp_init_local() failed.\n"); + return -1; + } + + memset(¶ms, 0, sizeof(params)); + params.pkt.seg_len = 20480; + params.pkt.len = 20480; + params.pkt.num = 4096; + params.type = ODP_POOL_PACKET; + + pool = odp_pool_create("packet_pool", ¶ms); + + if (ODP_POOL_INVALID == pool) { + printf("Packet pool creation fai