diff mbox

linux-generic crypto

Message ID 538330F0.4000701@linaro.org
State New
Headers show

Commit Message

Maxim Uvarov May 26, 2014, 12:17 p.m. UTC
Robbie,

for arm you need this fix:
armeb-linux-gnueabihf-gcc -c -MD -I../../include -I./include 
-I./include/api -DODP_DEBUG_PRINT=1 -O3 -pthread -W -Wall -Werror 
-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations 
-Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs 
-Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef 
-Wwrite-strings 
-I/opt/LINARO/ODPrelease/ReleaseCommit2/openssl/openssl-1.0.1/include -o 
obj/odp_crypto.o source/odp_crypto.c
source/odp_crypto.c: In function 'get_op_result_from_buffer':
source/odp_crypto.c:47:11: error: cast increases required alignment of 
target type [-Werror=cast-align]
   result = (struct odp_operation_result_s *)(temp - sizeof(*result));
            ^
cc1: all warnings being treated as errors


  }

Best regards,
Maxim.

On 05/24/2014 06:15 PM, Robbie King wrote:
> 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
>
> diff --git a/include/odp_crypto.h b/include/odp_crypto.h
> new file mode 100644
> index 0000000..c733875
> --- /dev/null
> +++ b/include/odp_crypto.h
> @@ -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
> diff --git a/platform/linux-generic/Makefile b/platform/linux-generic/Makefile
> index ec5d4a7..57f6d18 100644
> --- a/platform/linux-generic/Makefile
> +++ b/platform/linux-generic/Makefile
> @@ -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
> diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h
> new file mode 100644
> index 0000000..e558864
> --- /dev/null
> +++ b/platform/linux-generic/include/odp_crypto_internal.h
> @@ -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
> diff --git a/platform/linux-generic/source/odp_crypto.c b/platform/linux-generic/source/odp_crypto.c
> new file mode 100644
> index 0000000..6162510
> --- /dev/null
> +++ b/platform/linux-generic/source/odp_crypto.c
> @@ -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(&params->cipher_key->des.k1, &session->cipher.data.des.ks1);
> +	DES_set_key(&params->cipher_key->des.k2, &session->cipher.data.des.ks2);
> +	DES_set_key(&params->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;
> +}
diff mbox

Patch

--- a/platform/linux-generic/source/odp_crypto.c
+++ b/platform/linux-generic/source/odp_crypto.c
@@ -44,7 +44,7 @@  struct odp_operation_result_s 
*get_op_result_from_buffer(odp_buffer_t buf)

         temp  = odp_buffer_addr(buf);
         temp += odp_buffer_size(buf);
-       result = (struct odp_operation_result_s *)(temp - sizeof(*result));
+       result = (struct odp_operation_result_s *)(void*)(temp - 
sizeof(*result));
         return result;