new file mode 100644
@@ -0,0 +1,295 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/**
+ * @file
+ *
+ * ODP crypto
+ */
+
+#ifndef ODP_CRYPTO_H_
+#define ODP_CRYPTO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp_std_types.h>
+#include <odp_buffer.h>
+#include <odp_buffer_pool.h>
+#include <odp_queue.h>
+#include <odp_packet.h>
+
+/** Invalid session handle */
+#define ODP_CRYPTO_SESSION_INVALID (-1ULL)
+
+/**
+ * Crypto API opaque session handle
+ */
+typedef uint64_t odp_crypto_session_t;
+
+/**
+ * Crypto API operation mode
+ */
+enum odp_crypto_op_mode {
+ ODP_CRYPTO_SYNC, /**< Synchronous, return results immediately */
+ ODP_CRYPTO_ASYNC, /**< Aynchronous, return results via posted event */
+};
+
+/**
+ * Crypto API operation type
+ */
+enum odp_crypto_op {
+ ODP_CRYPTO_OP_ENCODE, /**< Encrypt and/or compute authentication ICV */
+ ODP_CRYPTO_OP_DECODE /**< Decrypt and/or verify authentication ICV */
+};
+
+/**
+ * Crypto API cipher algorithm
+ */
+enum odp_cipher_alg {
+ ODP_CIPHER_ALG_NULL, /**< No cipher algorithm specified */
+ ODP_CIPHER_ALG_DES, /**< DES */
+ ODP_CIPHER_ALG_3DES_CBC, /**< Triple DES with cipher block chaining */
+};
+
+/**
+ * Crypto API authentication algorithm
+ */
+enum odp_auth_alg {
+ ODP_AUTH_ALG_NULL, /**< No authentication algorithm specified */
+ ODP_AUTH_ALG_MD5_96, /**< HMAC-MD5 with 96 bit key */
+};
+
+/**
+ * Crypto API operation order
+ */
+enum odp_crypto_combination {
+ ODP_CRYPTO_CIPHER_ONLY, /**< Only perform cipher */
+ ODP_CRYPTO_AUTH_ONLY, /**< Only perform authentication */
+ ODP_CRYPTO_AUTH_CIPHERTEXT /**< Cipher then authentication on encode */
+};
+
+/**
+ * Crypto API key
+ */
+typedef struct odp_key_s {
+ union {
+ /** DES/3DES key definition (set all same for DES) */
+ struct {
+ uint8_t k1[8]; /**< First key */
+ uint8_t k2[8]; /**< Second key */
+ uint8_t k3[8]; /**< Third key */
+ } des;
+ /** MD5 key */
+ struct {
+ uint8_t key[16]; /**< Key up to 128 bits */
+ } md5;
+ };
+} odp_key_t;
+
+/**
+ * Crypto API data range specifier
+ */
+struct odp_data_range {
+ uint16_t offset; /**< Offset from beginning of buffer (chain) */
+ uint16_t length; /**< Length of data to operate on */
+};
+
+/**
+ * Crypto API session creation paramters
+ *
+ * TODO: add "odp_session_proc_info_t"
+ */
+struct odp_crypto_session_params {
+ enum odp_crypto_op op; /**< Encode versus decode */
+ enum odp_crypto_combination comb; /**< Operation order */
+ enum odp_crypto_op_mode pref_mode; /**< Preferred sync vs async */
+ enum odp_cipher_alg cipher_alg; /**< Cipher algorithm */
+ odp_key_t *cipher_key; /**< Cipher key */
+ uint8_t *iv; /**< Cipher Initialization Vector (IV) */
+ size_t iv_len; /**< Cipher IV length */
+ enum odp_auth_alg auth_alg; /**< Authentication algorithm */
+ odp_key_t *auth_key; /**< Authentication key */
+ odp_queue_t compl_queue; /**< Async mode completion event queue */
+};
+
+/**
+ * Crypto API per packet operation parameters
+ */
+struct odp_crypto_op_params {
+ odp_crypto_session_t session; /**< Session handle from creation */
+ odp_packet_t pkt; /**< Input packet buffer */
+ odp_packet_t out_pkt; /**< Output packet buffer (optional) */
+ uint8_t *override_iv_ptr; /**< Override session IV pointer */
+ unsigned hash_result_offset; /**< Offset from start of packet buffer for hash result */
+ struct odp_data_range cipher_range; /**< Data range to apply cipher */
+ struct odp_data_range auth_range; /**< Data range to authenticate */
+};
+
+/**
+ * Crypto API session creation return code
+ *
+ * TODO: seems confusing, maybe _rc instead
+ */
+enum odp_crypto_ses_create_err {
+ ODP_CRYPTO_SES_CREATE_NONE, /**< No session created? need to clarify */
+ ODP_CRYPTO_SES_CREATE_OK, /**< Session created successfully */
+};
+
+/**
+ * Crypto API algorithm return code
+ */
+enum crypto_alg_err {
+ ODP_CRYPTO_ALG_ERR_NONE, /**< Algorithm successful */
+ ODP_CRYPTO_ALG_ERR_DATA_SIZE, /**< Invalid data block size */
+ ODP_CRYPTO_ALG_ERR_KEY_SIZE, /**< Key size invalid for algorithm */
+ ODP_CRYPTO_ALG_ERR_ICV_CHECK, /**< Computed ICV value mismatch */
+};
+
+/**
+ * Crypto API operation return code
+ */
+typedef enum odp_crypto_rc {
+ ODP_CRYPTO_OP_OK, /**< Operation completed, results are valid */
+ ODP_CRYPTO_OP_POSTED, /**< Operation was posted, results delivered via completion queue */
+ ODP_CRYPTO_OP_ERROR, /**< Operation failed */
+} odp_crypto_rc_e;
+
+/**
+ * Crypto API hardware centric return code
+ */
+enum crypto_hw_err {
+ ODP_CRYPTO_HW_ERR_NONE, /**< Operation completed successfully */
+ ODP_CRYPTO_HW_ERR_DMA, /**< Error detected during DMA of data */
+ ODP_CRYPTO_HW_ERR_BP_DEPLETED, /**< Operation failed due to buffer pool depletion */
+};
+
+/**
+ * Crypto API algorithm (cipher or authentication)
+ */
+typedef union odp_crypto_alg_u {
+ enum odp_cipher_alg cipher; /**< Cipher algorithm */
+ enum odp_auth_alg auth; /**< Authentication algorithm */
+} odp_crypto_alg_t;
+
+/**
+ * Cryto API per packet operation completion status
+ */
+struct odp_crypto_compl_status {
+ odp_crypto_alg_t alg; /**< Requested algorithm */
+ enum crypto_alg_err alg_err; /**< Algorithm specific return code */
+ enum crypto_hw_err hw_err; /**< Hardware specific return code */
+};
+
+
+/**
+ * Crypto session creation
+ *
+ * Create a crypto session. Operation occurs asynchronously if a completion
+ * queue is specified else synchronously.
+ *
+ * @param params Session parameters
+ * @param completion_event Event by which the session creation results are
+ * delivered.
+ * @param completion_queue Queue by which the completion event will be
+ * delivered. Ignored if ODP_QUEUE_INVALID.
+ *
+ * @return Operation return code indicating success or failure for
+ * when synchronous operation requested, else POSTED when
+ * asynchronous operation is requested.
+ */
+odp_crypto_rc_e
+odp_crypto_session_create(struct odp_crypto_session_params *params,
+ odp_buffer_t completion_event,
+ odp_queue_t completion_queue);
+
+
+/**
+ * Crypto session creation completion status
+ *
+ * Accessor function for obtaining creation status from the completion event.
+ *
+ * @param completion_event Event containing operation results
+ * @param status Pointer to store creation return code
+ */
+void
+odp_crypto_get_ses_create_compl_status(odp_buffer_t completion_event,
+ enum odp_crypto_ses_create_err *status);
+
+/**
+ * Crypto session creation completion return value
+ *
+ * Accessor function for obtaining handle for newly created session.
+ *
+ * @param completion_event Event containing operation results
+ * @param session Pointer to store session handle
+ */
+void
+odp_crypto_get_ses_create_compl_session(odp_buffer_t completion_event,
+ odp_crypto_session_t *session);
+
+/**
+ * Crypto per packet operation
+ *
+ * Performs the cryptographic operations specified during session creation
+ * on the packet.
+ *
+ * @param params Operation parameters
+ * @param completion_event Event by which the session creation results are
+ * delivered.
+ *
+ * @return Operation return code indicating success or failure when session
+ * indicates synchronous operation, else POSTED for asynchronous
+ * operation.
+ */
+odp_crypto_rc_e
+odp_crypto_operation(struct odp_crypto_op_params *params,
+ odp_buffer_t completion_event);
+
+
+/**
+ * Crypto per packet operation completion status
+ *
+ * Accessor function for obtaining operation status from the completion event.
+ *
+ * @param completion_event Event containing operation results
+ * @param auth Pointer to store authentication results
+ * @param cipher Pointer to store cipher results
+ */
+void
+odp_crypto_get_operation_compl_status(odp_buffer_t completion_event,
+ struct odp_crypto_compl_status *auth,
+ struct odp_crypto_compl_status *cipher);
+
+/**
+ * Generate random byte string
+ *
+ * @param buf Pointer to store result
+ * @param len Pointer to input length value as well as return value
+ * @param use_entropy (TODO: needs description)
+ *
+ * @return 0 if succesful
+ */
+int
+odp_hw_random_get(uint8_t *buf, uint32_t *len, bool use_entropy);
+
+/**
+ * Initialize the crypto subsystem, called once from main thread
+ *
+ * @param max_sessions Maximum number of sessions to support
+ *
+ * @return 0 if succesful
+ */
+int
+odp_crypto_init(uint32_t max_sessions);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
@@ -72,6 +72,7 @@ OBJS += $(OBJ_DIR)/odp_time.o
OBJS += $(OBJ_DIR)/odp_timer.o
OBJS += $(OBJ_DIR)/odp_ring.o
OBJS += $(OBJ_DIR)/odp_rwlock.o
+OBJS += $(OBJ_DIR)/odp_crypto.o
ifeq ($(ODP_HAVE_NETMAP),yes)
OBJS += $(OBJ_DIR)/odp_packet_netmap.o
endif
new file mode 100644
@@ -0,0 +1,86 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef ODP_CRYPTO_INTERNAL_H_
+#define ODP_CRYPTO_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/des.h>
+
+#define OP_RESULT_MAGIC 0x91919191
+
+/** Forward declaration of session structure */
+struct odp_crypto_session_s;
+
+/**
+ * Algorithm handler function prototype
+ */
+typedef
+enum crypto_alg_err (*crypto_func_t)(struct odp_crypto_op_params *params,
+ struct odp_crypto_session_s *session);
+
+/**
+ * Per crypto session data structure
+ */
+struct odp_crypto_session_s {
+ uint32_t index;
+ enum odp_crypto_op op;
+ enum odp_crypto_combination comb;
+ odp_queue_t compl_queue;
+ struct {
+ enum odp_cipher_alg alg;
+ struct {
+ uint8_t *data;
+ size_t len;
+ } iv;
+ union {
+ struct {
+ DES_key_schedule ks1;
+ DES_key_schedule ks2;
+ DES_key_schedule ks3;
+ } des;
+ } data;
+ crypto_func_t func;
+ } cipher;
+ struct {
+ enum odp_auth_alg alg;
+ union {
+ struct {
+ uint8_t key[16];
+ } md5;
+ } data;
+ crypto_func_t func;
+ } auth;
+
+};
+
+/**
+ * Per packet operation result
+ */
+struct odp_operation_result_s {
+ uint32_t magic;
+ struct odp_crypto_compl_status cipher;
+ struct odp_crypto_compl_status auth;
+};
+
+/**
+ * Per session creation operation result
+ */
+struct odp_session_result_s {
+ enum odp_crypto_ses_create_err rc;
+ odp_crypto_session_t session;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
new file mode 100644
@@ -0,0 +1,434 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp_crypto.h>
+#include <odp_internal.h>
+#include <odp_atomic.h>
+#include <odp_spinlock.h>
+#include <odp_sync.h>
+#include <odp_debug.h>
+#include <odp_align.h>
+#include <odp_shared_memory.h>
+#include <odp_crypto_internal.h>
+
+#include <string.h>
+
+#include <openssl/des.h>
+#include <openssl/rand.h>
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+
+#define MAX_SESSIONS 32
+
+typedef struct {
+ odp_atomic_u32_t next;
+ uint32_t max;
+ struct odp_crypto_session_s sessions[0];
+} odp_crypto_global_t;
+
+static odp_crypto_global_t *global;
+
+/*
+ * TODO: This is a serious hack to allow us to use packet buffer to convey
+ * crypto operation results by placing them at the very end of the
+ * packet buffer.
+ */
+static
+struct odp_operation_result_s *get_op_result_from_buffer(odp_buffer_t buf)
+{
+ uint8_t *temp;
+ struct odp_operation_result_s *result;
+
+ temp = odp_buffer_addr(buf);
+ temp += odp_buffer_size(buf);
+ result = (struct odp_operation_result_s *)(temp - sizeof(*result));
+ return result;
+}
+
+static
+struct odp_crypto_session_s *alloc_session(void)
+{
+ uint32_t idx;
+ struct odp_crypto_session_s *session = NULL;
+
+ idx = odp_atomic_fetch_inc_u32(&global->next);
+ if (idx < global->max) {
+ session = &global->sessions[idx];
+ session->index = idx;
+ }
+ return session;
+}
+
+static
+enum crypto_alg_err null_crypto_routine(
+ struct odp_crypto_op_params *params ODP_UNUSED,
+ struct odp_crypto_session_s *session ODP_UNUSED)
+{
+ return ODP_CRYPTO_ALG_ERR_NONE;
+}
+
+static
+enum crypto_alg_err md5_gen(struct odp_crypto_op_params *params,
+ struct odp_crypto_session_s *session)
+{
+ uint8_t *data = odp_packet_buf_addr(params->pkt);
+ uint8_t *icv = data;
+ uint32_t len = params->auth_range.length;
+ uint8_t hash[EVP_MAX_MD_SIZE];
+ uint32_t hlen = 12;
+
+ /* Adjust pointer for beginning of area to auth */
+ data += params->auth_range.offset;
+ icv += params->hash_result_offset;
+
+ /* Hash it */
+ HMAC(EVP_md5(), session->auth.data.md5.key, 16, data, len, hash, &hlen);
+
+ /* Copy to the output location */
+ memcpy(icv, hash, 12);
+
+ return ODP_CRYPTO_ALG_ERR_NONE;
+}
+
+
+static
+enum crypto_alg_err md5_check(struct odp_crypto_op_params *params,
+ struct odp_crypto_session_s *session)
+{
+ uint8_t *data = odp_packet_buf_addr(params->pkt);
+ uint8_t *icv = data;
+ uint32_t len = params->auth_range.length;
+ uint8_t hash[EVP_MAX_MD_SIZE];
+ uint32_t hlen = 12;
+
+ /* Adjust pointer for beginning of area to auth */
+ data += params->auth_range.offset;
+ icv += params->hash_result_offset;
+
+ /* Copy current value out and clear it before authentication */
+ memcpy(hash, icv, hlen);
+ memset(icv, 0, hlen);
+
+ /* Hash it */
+ HMAC(EVP_md5(), session->auth.data.md5.key, 16, data, len, icv, &hlen);
+
+ /* Verify match */
+ if (0 != memcmp(icv, hash, 12))
+ return ODP_CRYPTO_ALG_ERR_ICV_CHECK;
+
+ /* Matched */
+ return ODP_CRYPTO_ALG_ERR_NONE;
+}
+
+static
+enum crypto_alg_err des_encrypt(struct odp_crypto_op_params *params,
+ struct odp_crypto_session_s *session)
+{
+ uint8_t *data = odp_packet_buf_addr(params->pkt);
+ uint32_t len = params->cipher_range.length;
+ DES_cblock *iv = (DES_cblock *)session->cipher.iv.data;
+
+ /* Adjust pointer for beginning of area to cipher */
+ data += params->cipher_range.offset;
+
+ /* Override IV if requested */
+ if (params->override_iv_ptr)
+ iv = (DES_cblock *)params->override_iv_ptr;
+
+ /* Encrypt it */
+ DES_ede3_cbc_encrypt(data,
+ data,
+ len,
+ &session->cipher.data.des.ks1,
+ &session->cipher.data.des.ks2,
+ &session->cipher.data.des.ks3,
+ iv,
+ 1);
+
+ return ODP_CRYPTO_ALG_ERR_NONE;
+}
+
+static
+enum crypto_alg_err des_decrypt(struct odp_crypto_op_params *params,
+ struct odp_crypto_session_s *session)
+{
+ uint8_t *data = odp_packet_buf_addr(params->pkt);
+ uint32_t len = params->cipher_range.length;
+ DES_cblock *iv = (DES_cblock *)session->cipher.iv.data;
+
+ /* Adjust pointer for beginning of area to cipher */
+ data += params->cipher_range.offset;
+
+ /* Override IV if requested */
+ if (params->override_iv_ptr)
+ iv = (DES_cblock *)params->override_iv_ptr;
+
+ /* Decrypt it */
+ DES_ede3_cbc_encrypt(data,
+ data,
+ len,
+ &session->cipher.data.des.ks1,
+ &session->cipher.data.des.ks2,
+ &session->cipher.data.des.ks3,
+ iv,
+ 0);
+
+ return ODP_CRYPTO_ALG_ERR_NONE;
+}
+
+static
+int process_des_params(struct odp_crypto_session_s *session,
+ struct odp_crypto_session_params *params)
+{
+ /* Verify IV len is either 0 or 8 */
+ if (!((0 == params->iv_len) || (8 == params->iv_len)))
+ return -1;
+
+ /* Verify IV pointer */
+ if (params->iv_len && !params->iv)
+ return -1;
+
+ /* Set function */
+ if (ODP_CRYPTO_OP_ENCODE == params->op)
+ session->cipher.func = des_encrypt;
+ else
+ session->cipher.func = des_decrypt;
+
+ /* Convert keys */
+ DES_set_key(¶ms->cipher_key->des.k1, &session->cipher.data.des.ks1);
+ DES_set_key(¶ms->cipher_key->des.k2, &session->cipher.data.des.ks2);
+ DES_set_key(¶ms->cipher_key->des.k3, &session->cipher.data.des.ks3);
+
+ return 0;
+}
+
+static
+int process_md5_params(struct odp_crypto_session_s *session,
+ struct odp_crypto_session_params *params)
+{
+ /* Set function */
+ if (ODP_CRYPTO_OP_ENCODE == params->op)
+ session->auth.func = md5_gen;
+ else
+ session->auth.func = md5_check;
+
+ /* Convert keys */
+ memcpy(session->auth.data.md5.key, params->auth_key->md5.key, 16);
+
+ return 0;
+}
+
+odp_crypto_rc_e
+odp_crypto_session_create(struct odp_crypto_session_params *params,
+ odp_buffer_t completion_event,
+ odp_queue_t completion_queue)
+{
+ int rc;
+ struct odp_crypto_session_s *session;
+ struct odp_session_result_s *result = odp_buffer_addr(completion_event);
+
+ /* Default to failure result */
+ result->rc = ODP_CRYPTO_SES_CREATE_NONE;
+ result->session = ODP_CRYPTO_SESSION_INVALID;
+
+ /* Allocate memory for this session */
+ session = alloc_session();
+ if (NULL == session)
+ return ODP_CRYPTO_OP_ERROR;
+
+ /* Copy stuff over */
+ session->op = params->op;
+ session->comb = params->comb;
+ session->compl_queue = params->compl_queue;
+ session->cipher.alg = params->cipher_alg;
+ session->cipher.iv.data = params->iv;
+ session->cipher.iv.len = params->iv_len;
+ session->auth.alg = params->auth_alg;
+
+ /* Process based on cipher */
+ switch (params->cipher_alg) {
+ case ODP_CIPHER_ALG_NULL:
+ session->cipher.func = null_crypto_routine;
+ rc = 0;
+ break;
+ case ODP_CIPHER_ALG_DES:
+ case ODP_CIPHER_ALG_3DES_CBC:
+ rc = process_des_params(session, params);
+ break;
+ default:
+ rc = -1;
+ }
+
+ /* Check result */
+ if (rc)
+ return ODP_CRYPTO_OP_ERROR;
+
+ /* Process based on auth */
+ switch (params->auth_alg) {
+ case ODP_AUTH_ALG_NULL:
+ session->auth.func = null_crypto_routine;
+ rc = 0;
+ break;
+ case ODP_AUTH_ALG_MD5_96:
+ rc = process_md5_params(session, params);
+ break;
+ default:
+ rc = -1;
+ }
+
+ /* Check result */
+ if (rc)
+ return ODP_CRYPTO_OP_ERROR;
+
+ /* We're happy */
+ result->rc = ODP_CRYPTO_SES_CREATE_OK;
+ result->session = (intptr_t)session;
+
+ /* If there is a queue post else we're good */
+ if (ODP_QUEUE_INVALID != completion_queue) {
+ odp_queue_enq(completion_queue, completion_event);
+ return ODP_CRYPTO_OP_POSTED;
+ }
+
+ return ODP_CRYPTO_OP_OK;
+}
+
+
+odp_crypto_rc_e
+odp_crypto_operation(struct odp_crypto_op_params *params,
+ odp_buffer_t completion_event)
+{
+ enum crypto_alg_err rc_cipher = ODP_CRYPTO_ALG_ERR_NONE;
+ enum crypto_alg_err rc_auth = ODP_CRYPTO_ALG_ERR_NONE;
+ struct odp_crypto_session_s *session;
+ struct odp_operation_result_s *result;
+
+ session = (struct odp_crypto_session_s *)(intptr_t)params->session;
+
+ /*
+ * robking: need to understand infrastructure for scattered packets
+ * for now just don't support them
+ */
+ if (odp_buffer_is_scatter(odp_buffer_from_packet(params->pkt)))
+ return ODP_CRYPTO_OP_ERROR;
+
+ /*
+ * robking: for now we are only going to support in place
+ */
+ if (params->pkt != params->out_pkt)
+ return ODP_CRYPTO_OP_ERROR;
+
+ /* Invoke the functions */
+ switch (session->comb) {
+ case ODP_CRYPTO_CIPHER_ONLY:
+ rc_cipher = session->cipher.func(params, session);
+ break;
+ case ODP_CRYPTO_AUTH_ONLY:
+ rc_auth = session->auth.func(params, session);
+ break;
+ case ODP_CRYPTO_AUTH_CIPHERTEXT:
+ if (ODP_CRYPTO_OP_ENCODE == session->op) {
+ rc_cipher = session->cipher.func(params, session);
+ rc_auth = session->auth.func(params, session);
+ } else {
+ rc_auth = session->auth.func(params, session);
+ rc_cipher = session->cipher.func(params, session);
+ }
+ break;
+ }
+
+ /* Build Result (no HW so no errors) */
+ result = get_op_result_from_buffer(completion_event);
+ result->magic = OP_RESULT_MAGIC;
+ result->cipher.alg.cipher = session->cipher.alg;
+ result->cipher.alg_err = rc_cipher;
+ result->cipher.hw_err = ODP_CRYPTO_HW_ERR_NONE;
+ result->auth.alg.auth = session->auth.alg;
+ result->auth.alg_err = rc_auth;
+ result->auth.hw_err = ODP_CRYPTO_HW_ERR_NONE;
+
+ /*
+ * robking: a) the queue is supposed to come from session
+ * b) ordering question asks whether we must
+ * use the packet to return status
+ */
+ if (ODP_QUEUE_INVALID != session->compl_queue) {
+ odp_queue_enq(session->compl_queue, completion_event);
+ return ODP_CRYPTO_OP_POSTED;
+ }
+
+ return ODP_CRYPTO_OP_OK;
+}
+
+
+int
+odp_crypto_init(uint32_t max_sessions)
+{
+ size_t mem_size;
+
+ /* Force down to our limit */
+ if (MAX_SESSIONS < max_sessions)
+ max_sessions = MAX_SESSIONS;
+
+ /* Calculate the memory size we need */
+ mem_size = sizeof(*global);
+ mem_size += (max_sessions * sizeof(struct odp_crypto_session_s));
+
+ /* Allocate our globally shared memory */
+ global = odp_shm_reserve("crypto_pool", mem_size, ODP_CACHE_LINE_SIZE);
+
+ /* Clear it out */
+ memset(global, 0, mem_size);
+
+ /* Initialize it */
+ global->max = max_sessions;
+
+ return 0;
+}
+
+int
+odp_hw_random_get(uint8_t *buf, uint32_t *len, bool use_entropy ODP_UNUSED)
+{
+ int rc;
+ rc = RAND_bytes(buf, *len);
+ return ((1 == rc) ? 0 : -1);
+}
+
+void
+odp_crypto_get_operation_compl_status(odp_buffer_t completion_event,
+ struct odp_crypto_compl_status *auth,
+ struct odp_crypto_compl_status *cipher)
+{
+ struct odp_operation_result_s *result;
+
+ result = get_op_result_from_buffer(completion_event);
+
+ if (OP_RESULT_MAGIC != result->magic)
+ abort();
+
+ memcpy(auth, &result->auth, sizeof(*auth));
+ memcpy(cipher, &result->cipher, sizeof(*cipher));
+}
+
+void
+odp_crypto_get_ses_create_compl_status(odp_buffer_t completion_event,
+ enum odp_crypto_ses_create_err *status)
+{
+ struct odp_session_result_s *result;
+
+ result = odp_buffer_addr(completion_event);
+ *status = result->rc;
+}
+
+void
+odp_crypto_get_ses_create_compl_session(odp_buffer_t completion_event,
+ odp_crypto_session_t *session)
+{
+ struct odp_session_result_s *result;
+
+ result = odp_buffer_addr(completion_event);
+ *session = result->session;
+}
Initial linux-generic crypto implementation. Note that these changes require installing and linking with libssl-dev. The camel case warnings are also due to calls into libssl-dev. Signed-off-by: Robbie King <robking@cisco.com> --- include/odp_crypto.h | 295 +++++++++++++ platform/linux-generic/Makefile | 1 + .../linux-generic/include/odp_crypto_internal.h | 86 ++++ platform/linux-generic/source/odp_crypto.c | 434 ++++++++++++++++++++ 4 files changed, 816 insertions(+), 0 deletions(-) create mode 100644 include/odp_crypto.h create mode 100644 platform/linux-generic/include/odp_crypto_internal.h create mode 100644 platform/linux-generic/source/odp_crypto.c