@@ -23,7 +23,8 @@ typedef struct odp_crypto_generic_session odp_crypto_generic_session_t;
* Algorithm handler function prototype
*/
typedef
-odp_crypto_alg_err_t (*crypto_func_t)(odp_crypto_op_param_t *param,
+odp_crypto_alg_err_t (*crypto_func_t)(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
odp_crypto_generic_session_t *session);
/**
@@ -128,6 +128,9 @@ typedef struct {
/* Classifier destination queue */
odp_queue_t dst_queue;
+ /* Result for crypto packet op */
+ odp_crypto_packet_op_result_t crypto_op_result;
+
/* Packet data storage */
uint8_t data[0];
} odp_packet_hdr_t;
@@ -113,7 +113,8 @@ void free_session(odp_crypto_generic_session_t *session)
}
static odp_crypto_alg_err_t
-null_crypto_routine(odp_crypto_op_param_t *param ODP_UNUSED,
+null_crypto_routine(odp_packet_t pkt ODP_UNUSED,
+ const odp_crypto_packet_op_param_t *param ODP_UNUSED,
odp_crypto_generic_session_t *session ODP_UNUSED)
{
return ODP_CRYPTO_ALG_ERR_NONE;
@@ -121,11 +122,11 @@ null_crypto_routine(odp_crypto_op_param_t *param ODP_UNUSED,
static
void packet_hmac_calculate(HMAC_CTX *ctx,
- odp_crypto_op_param_t *param,
+ odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
odp_crypto_generic_session_t *session,
uint8_t *hash)
{
- odp_packet_t pkt = param->out_pkt;
uint32_t offset = param->auth_range.offset;
uint32_t len = param->auth_range.length;
@@ -152,7 +153,8 @@ void packet_hmac_calculate(HMAC_CTX *ctx,
#if OPENSSL_VERSION_NUMBER < 0x10100000L
static
-void packet_hmac(odp_crypto_op_param_t *param,
+void packet_hmac(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
odp_crypto_generic_session_t *session,
uint8_t *hash)
{
@@ -160,12 +162,13 @@ void packet_hmac(odp_crypto_op_param_t *param,
/* Hash it */
HMAC_CTX_init(&ctx);
- packet_hmac_calculate(&ctx, param, session, hash);
+ packet_hmac_calculate(&ctx, pkt, param, session, hash);
HMAC_CTX_cleanup(&ctx);
}
#else
static
-void packet_hmac(odp_crypto_op_param_t *param,
+void packet_hmac(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
odp_crypto_generic_session_t *session,
uint8_t *hash)
{
@@ -173,22 +176,23 @@ void packet_hmac(odp_crypto_op_param_t *param,
/* Hash it */
ctx = HMAC_CTX_new();
- packet_hmac_calculate(ctx, param, session, hash);
+ packet_hmac_calculate(ctx, pkt, param, session, hash);
HMAC_CTX_free(ctx);
}
#endif
static
-odp_crypto_alg_err_t auth_gen(odp_crypto_op_param_t *param,
+odp_crypto_alg_err_t auth_gen(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
odp_crypto_generic_session_t *session)
{
uint8_t hash[EVP_MAX_MD_SIZE];
/* Hash it */
- packet_hmac(param, session, hash);
+ packet_hmac(pkt, param, session, hash);
/* Copy to the output location */
- odp_packet_copy_from_mem(param->out_pkt,
+ odp_packet_copy_from_mem(pkt,
param->hash_result_offset,
session->auth.bytes,
hash);
@@ -197,7 +201,8 @@ odp_crypto_alg_err_t auth_gen(odp_crypto_op_param_t *param,
}
static
-odp_crypto_alg_err_t auth_check(odp_crypto_op_param_t *param,
+odp_crypto_alg_err_t auth_check(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
odp_crypto_generic_session_t *session)
{
uint32_t bytes = session->auth.bytes;
@@ -205,14 +210,14 @@ odp_crypto_alg_err_t auth_check(odp_crypto_op_param_t *param,
uint8_t hash_out[EVP_MAX_MD_SIZE];
/* Copy current value out and clear it before authentication */
- odp_packet_copy_to_mem(param->out_pkt, param->hash_result_offset,
+ odp_packet_copy_to_mem(pkt, param->hash_result_offset,
bytes, hash_in);
- _odp_packet_set_data(param->out_pkt, param->hash_result_offset,
+ _odp_packet_set_data(pkt, param->hash_result_offset,
0, bytes);
/* Hash it */
- packet_hmac(param, session, hash_out);
+ packet_hmac(pkt, param, session, hash_out);
/* Verify match */
if (0 != memcmp(hash_in, hash_out, bytes))
@@ -223,9 +228,10 @@ odp_crypto_alg_err_t auth_check(odp_crypto_op_param_t *param,
}
static
-int internal_encrypt(EVP_CIPHER_CTX *ctx, odp_crypto_op_param_t *param)
+int internal_encrypt(EVP_CIPHER_CTX *ctx,
+ odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param)
{
- odp_packet_t pkt = param->out_pkt;
unsigned in_pos = param->cipher_range.offset;
unsigned out_pos = param->cipher_range.offset;
unsigned in_len = param->cipher_range.length;
@@ -278,9 +284,10 @@ int internal_encrypt(EVP_CIPHER_CTX *ctx, odp_crypto_op_param_t *param)
}
static
-int internal_decrypt(EVP_CIPHER_CTX *ctx, odp_crypto_op_param_t *param)
+int internal_decrypt(EVP_CIPHER_CTX *ctx,
+ odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param)
{
- odp_packet_t pkt = param->out_pkt;
unsigned in_pos = param->cipher_range.offset;
unsigned out_pos = param->cipher_range.offset;
unsigned in_len = param->cipher_range.length;
@@ -333,7 +340,8 @@ int internal_decrypt(EVP_CIPHER_CTX *ctx, odp_crypto_op_param_t *param)
}
static
-odp_crypto_alg_err_t cipher_encrypt(odp_crypto_op_param_t *param,
+odp_crypto_alg_err_t cipher_encrypt(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
odp_crypto_generic_session_t *session)
{
EVP_CIPHER_CTX *ctx;
@@ -354,7 +362,7 @@ odp_crypto_alg_err_t cipher_encrypt(odp_crypto_op_param_t *param,
EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr);
EVP_CIPHER_CTX_set_padding(ctx, 0);
- ret = internal_encrypt(ctx, param);
+ ret = internal_encrypt(ctx, pkt, param);
EVP_CIPHER_CTX_free(ctx);
@@ -363,7 +371,8 @@ odp_crypto_alg_err_t cipher_encrypt(odp_crypto_op_param_t *param,
}
static
-odp_crypto_alg_err_t cipher_decrypt(odp_crypto_op_param_t *param,
+odp_crypto_alg_err_t cipher_decrypt(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
odp_crypto_generic_session_t *session)
{
EVP_CIPHER_CTX *ctx;
@@ -384,7 +393,7 @@ odp_crypto_alg_err_t cipher_decrypt(odp_crypto_op_param_t *param,
EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr);
EVP_CIPHER_CTX_set_padding(ctx, 0);
- ret = internal_decrypt(ctx, param);
+ ret = internal_decrypt(ctx, pkt, param);
EVP_CIPHER_CTX_free(ctx);
@@ -420,7 +429,8 @@ static int process_cipher_param(odp_crypto_generic_session_t *session,
}
static
-odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param,
+odp_crypto_alg_err_t aes_gcm_encrypt(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
odp_crypto_generic_session_t *session)
{
EVP_CIPHER_CTX *ctx;
@@ -452,11 +462,11 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param,
EVP_EncryptUpdate(ctx, NULL, &dummy_len,
aad_head, aad_len);
- ret = internal_encrypt(ctx, param);
+ ret = internal_encrypt(ctx, pkt, param);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG,
session->p.auth_digest_len, block);
- odp_packet_copy_from_mem(param->out_pkt, param->hash_result_offset,
+ odp_packet_copy_from_mem(pkt, param->hash_result_offset,
session->p.auth_digest_len, block);
EVP_CIPHER_CTX_free(ctx);
@@ -466,7 +476,8 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param,
}
static
-odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param,
+odp_crypto_alg_err_t aes_gcm_decrypt(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
odp_crypto_generic_session_t *session)
{
EVP_CIPHER_CTX *ctx;
@@ -493,7 +504,7 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param,
EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr);
EVP_CIPHER_CTX_set_padding(ctx, 0);
- odp_packet_copy_to_mem(param->out_pkt, param->hash_result_offset,
+ odp_packet_copy_to_mem(pkt, param->hash_result_offset,
session->p.auth_digest_len, block);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG,
session->p.auth_digest_len, block);
@@ -503,7 +514,7 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param,
EVP_DecryptUpdate(ctx, NULL, &dummy_len,
aad_head, aad_len);
- ret = internal_decrypt(ctx, param);
+ ret = internal_decrypt(ctx, pkt, param);
EVP_CIPHER_CTX_free(ctx);
@@ -833,87 +844,59 @@ int odp_crypto_session_destroy(odp_crypto_session_t session)
return 0;
}
+/*
+ * Shim function around packet operation, can be used by other implementations.
+ */
int
odp_crypto_operation(odp_crypto_op_param_t *param,
odp_bool_t *posted,
odp_crypto_op_result_t *result)
{
- odp_crypto_alg_err_t rc_cipher = ODP_CRYPTO_ALG_ERR_NONE;
- odp_crypto_alg_err_t rc_auth = ODP_CRYPTO_ALG_ERR_NONE;
- odp_crypto_generic_session_t *session;
+ odp_crypto_packet_op_param_t packet_param;
+ odp_packet_t out_pkt = param->out_pkt;
+ odp_crypto_packet_op_result_t packet_result;
odp_crypto_op_result_t local_result;
- odp_bool_t allocated = false;
-
- session = (odp_crypto_generic_session_t *)(intptr_t)param->session;
+ int rc;
- /* Resolve output buffer */
- if (ODP_PACKET_INVALID == param->out_pkt &&
- ODP_POOL_INVALID != session->p.output_pool) {
- param->out_pkt = odp_packet_alloc(session->p.output_pool,
- odp_packet_len(param->pkt));
- allocated = true;
- }
+ packet_param.session = param->session;
+ packet_param.override_iv_ptr = param->override_iv_ptr;
+ packet_param.hash_result_offset = param->hash_result_offset;
+ packet_param.aad.ptr = param->aad.ptr;
+ packet_param.aad.length = param->aad.length;
+ packet_param.cipher_range = param->cipher_range;
+ packet_param.auth_range = param->auth_range;
- if (odp_unlikely(ODP_PACKET_INVALID == param->out_pkt)) {
- ODP_DBG("Alloc failed.\n");
- return -1;
- }
+ rc = odp_crypto_packet_op(¶m->pkt, &out_pkt, 1, &packet_param);
+ if (rc < 0)
+ return rc;
- if (param->pkt != param->out_pkt) {
- int ret;
+ rc = odp_crypto_packet_result(&packet_result, out_pkt);
+ if (rc < 0)
+ return rc;
- ret = odp_packet_copy_from_pkt(param->out_pkt,
- 0,
- param->pkt,
- 0,
- odp_packet_len(param->pkt));
- if (odp_unlikely(ret < 0))
- goto err;
+ /* Indicate to caller operation was sync */
+ *posted = 0;
- _odp_packet_copy_md_to_packet(param->pkt, param->out_pkt);
- odp_packet_free(param->pkt);
- param->pkt = ODP_PACKET_INVALID;
- }
-
- /* Invoke the functions */
- if (session->do_cipher_first) {
- rc_cipher = session->cipher.func(param, session);
- rc_auth = session->auth.func(param, session);
- } else {
- rc_auth = session->auth.func(param, session);
- rc_cipher = session->cipher.func(param, session);
- }
+ _odp_buffer_event_subtype_set(_odp_packet_to_buffer(out_pkt),
+ ODP_EVENT_PACKET_BASIC);
/* Fill in result */
#if ODP_DEPRECATED_API
local_result.ctx = param->ctx;
#endif
- local_result.pkt = param->out_pkt;
- local_result.cipher_status.alg_err = rc_cipher;
- local_result.cipher_status.hw_err = ODP_CRYPTO_HW_ERR_NONE;
- local_result.auth_status.alg_err = rc_auth;
- local_result.auth_status.hw_err = ODP_CRYPTO_HW_ERR_NONE;
- local_result.ok =
- (rc_cipher == ODP_CRYPTO_ALG_ERR_NONE) &&
- (rc_auth == ODP_CRYPTO_ALG_ERR_NONE);
+ local_result.pkt = out_pkt;
+ local_result.cipher_status = packet_result.cipher_status;
+ local_result.auth_status = packet_result.auth_status;
+ local_result.ok = packet_result.ok;
- /* Synchronous, simply return results */
- if (!result)
- goto err;
- *result = local_result;
+ /*
+ * Be bug-to-bug compatible. Return output packet also through params.
+ */
+ param->out_pkt = out_pkt;
- /* Indicate to caller operation was sync */
- *posted = 0;
+ *result = local_result;
return 0;
-
-err:
- if (allocated) {
- odp_packet_free(param->out_pkt);
- param->out_pkt = ODP_PACKET_INVALID;
- }
-
- return -1;
}
static void ODP_UNUSED openssl_thread_id(CRYPTO_THREADID ODP_UNUSED *id)
@@ -1094,3 +1077,170 @@ uint64_t odp_crypto_session_to_u64(odp_crypto_session_t hdl)
{
return (uint64_t)hdl;
}
+
+odp_packet_t odp_crypto_packet_from_event(odp_event_t ev)
+{
+ /* This check not mandated by the API specification */
+ ODP_ASSERT(odp_event_type(ev) == ODP_EVENT_PACKET);
+ ODP_ASSERT(odp_event_subtype(ev) == ODP_EVENT_PACKET_CRYPTO);
+
+ return odp_packet_from_event(ev);
+}
+
+odp_event_t odp_crypto_packet_to_event(odp_packet_t pkt)
+{
+ return odp_packet_to_event(pkt);
+}
+
+static
+odp_crypto_packet_op_result_t *get_op_result_from_packet(odp_packet_t pkt)
+{
+ odp_packet_hdr_t *hdr = odp_packet_hdr(pkt);
+
+ return &hdr->crypto_op_result;
+}
+
+int odp_crypto_packet_result(odp_crypto_packet_op_result_t *result, odp_packet_t packet)
+{
+ odp_crypto_packet_op_result_t *op_result;
+
+ ODP_ASSERT(odp_event_subtype(odp_packet_to_event(packet)) ==
+ ODP_EVENT_PACKET_CRYPTO);
+
+ op_result = get_op_result_from_packet(packet);
+
+ memcpy(result, op_result, sizeof(*result));
+
+ return 0;
+}
+
+static
+int odp_crypto_op(odp_packet_t pkt_in,
+ odp_packet_t *pkt_out,
+ const odp_crypto_packet_op_param_t *param)
+{
+ odp_crypto_alg_err_t rc_cipher = ODP_CRYPTO_ALG_ERR_NONE;
+ odp_crypto_alg_err_t rc_auth = ODP_CRYPTO_ALG_ERR_NONE;
+ odp_crypto_generic_session_t *session;
+ odp_crypto_packet_op_result_t local_result;
+ odp_bool_t allocated = false;
+ odp_packet_t out_pkt = *pkt_out;
+ odp_crypto_packet_op_result_t *op_result;
+
+ session = (odp_crypto_generic_session_t *)(intptr_t)param->session;
+
+ /* Resolve output buffer */
+ if (ODP_PACKET_INVALID == out_pkt &&
+ ODP_POOL_INVALID != session->p.output_pool) {
+ out_pkt = odp_packet_alloc(session->p.output_pool,
+ odp_packet_len(pkt_in));
+ allocated = true;
+ }
+
+ if (odp_unlikely(ODP_PACKET_INVALID == out_pkt)) {
+ ODP_DBG("Alloc failed.\n");
+ return -1;
+ }
+
+ if (pkt_in != out_pkt) {
+ int ret;
+
+ ret = odp_packet_copy_from_pkt(out_pkt,
+ 0,
+ pkt_in,
+ 0,
+ odp_packet_len(pkt_in));
+ if (odp_unlikely(ret < 0))
+ goto err;
+
+ _odp_packet_copy_md_to_packet(pkt_in, out_pkt);
+ odp_packet_free(pkt_in);
+ pkt_in = ODP_PACKET_INVALID;
+ }
+
+ /* Invoke the functions */
+ if (session->do_cipher_first) {
+ rc_cipher = session->cipher.func(out_pkt, param, session);
+ rc_auth = session->auth.func(out_pkt, param, session);
+ } else {
+ rc_auth = session->auth.func(out_pkt, param, session);
+ rc_cipher = session->cipher.func(out_pkt, param, session);
+ }
+
+ /* Fill in result */
+ local_result.cipher_status.alg_err = rc_cipher;
+ local_result.cipher_status.hw_err = ODP_CRYPTO_HW_ERR_NONE;
+ local_result.auth_status.alg_err = rc_auth;
+ local_result.auth_status.hw_err = ODP_CRYPTO_HW_ERR_NONE;
+ local_result.ok =
+ (rc_cipher == ODP_CRYPTO_ALG_ERR_NONE) &&
+ (rc_auth == ODP_CRYPTO_ALG_ERR_NONE);
+
+ _odp_buffer_event_subtype_set(_odp_packet_to_buffer(out_pkt),
+ ODP_EVENT_PACKET_CRYPTO);
+ op_result = get_op_result_from_packet(out_pkt);
+ *op_result = local_result;
+
+ /* Synchronous, simply return results */
+ *pkt_out = out_pkt;
+
+ return 0;
+
+err:
+ if (allocated) {
+ odp_packet_free(out_pkt);
+ out_pkt = ODP_PACKET_INVALID;
+ }
+
+ return -1;
+}
+
+int odp_crypto_packet_op(const odp_packet_t pkt_in[],
+ odp_packet_t pkt_out[],
+ int num_in,
+ const odp_crypto_packet_op_param_t param[])
+{
+ int i, rc;
+ odp_crypto_generic_session_t *session;
+
+ session = (odp_crypto_generic_session_t *)(intptr_t)param->session;
+ ODP_ASSERT(ODP_CRYPTO_SYNC == session->p.packet_op_mode);
+
+ for (i = 0; i < num_in; i++) {
+ rc = odp_crypto_op(pkt_in[i], &pkt_out[i], ¶m[i]);
+ if (rc < 0)
+ break;
+ }
+
+ return i;
+}
+
+int odp_crypto_packet_op_enq(const odp_packet_t pkt_in[],
+ const odp_packet_t pkt_out[],
+ int num_in,
+ const odp_crypto_packet_op_param_t param[])
+{
+ odp_packet_t pkt;
+ odp_event_t event;
+ odp_crypto_generic_session_t *session;
+ int i, rc;
+
+ session = (odp_crypto_generic_session_t *)(intptr_t)param->session;
+ ODP_ASSERT(ODP_CRYPTO_ASYNC == session->p.packet_op_mode);
+ ODP_ASSERT(ODP_QUEUE_INVALID != session->p.compl_queue);
+
+ for (i = 0; i < num_in; i++) {
+ pkt = pkt_out[i];
+ rc = odp_crypto_op(pkt_in[i], &pkt, ¶m[i]);
+ if (rc < 0)
+ break;
+
+ event = odp_packet_to_event(pkt);
+ if (odp_queue_enq(session->p.compl_queue, event)) {
+ odp_event_free(event);
+ break;
+ }
+ }
+
+ return i;
+}