[lng-odp] [RFC OPNESSL-ODP 2/2] Adding Async ODP engine for AES cipher

2016-07-07 Thread Nikhil Agarwal
---
 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

2016-06-05 Thread Bill Fischofer
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

2016-06-03 Thread Nikhil Agarwal
---
 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