dpdk-fm10k/app/test/test_cryptodev_asym.c
Bruce Richardson a9de470cc7 test: move to app directory
Since all other apps have been moved to the "app" folder, the autotest app
remains alone in the test folder. Rather than having an entire top-level
folder for this, we can move it back to where it all started in early
versions of DPDK - the "app/" folder.

This move has a couple of advantages:
* This reduces clutter at the top level of the project, due to one less
  folder.
* It eliminates the separate build task necessary for building the
  autotests using make "make test-build" which means that developers are
  less likely to miss something in their own compilation tests
* It re-aligns the final location of the test binary in the app folder when
  building with make with it's location in the source tree.

For meson builds, the autotest app is different from the other apps in that
it needs a series of different test cases defined for it for use by "meson
test". Therefore, it does not get built as part of the main loop in the
app folder, but gets built separately at the end.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
2019-02-26 15:29:27 +01:00

1373 lines
37 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018 Cavium Networks
*/
#include <rte_bus_vdev.h>
#include <rte_common.h>
#include <rte_hexdump.h>
#include <rte_mbuf.h>
#include <rte_malloc.h>
#include <rte_memcpy.h>
#include <rte_pause.h>
#include <rte_cryptodev.h>
#include <rte_cryptodev_pmd.h>
#include <rte_crypto.h>
#include "test_cryptodev.h"
#include "test_cryptodev_dh_test_vectors.h"
#include "test_cryptodev_dsa_test_vectors.h"
#include "test_cryptodev_mod_test_vectors.h"
#include "test_cryptodev_rsa_test_vectors.h"
#include "test_cryptodev_asym_util.h"
#include "test.h"
#define TEST_NUM_BUFS 10
#define TEST_NUM_SESSIONS 4
static int gbl_driver_id;
struct crypto_testsuite_params {
struct rte_mempool *op_mpool;
struct rte_mempool *session_mpool;
struct rte_cryptodev_config conf;
struct rte_cryptodev_qp_conf qp_conf;
uint8_t valid_devs[RTE_CRYPTO_MAX_DEVS];
uint8_t valid_dev_count;
};
struct crypto_unittest_params {
struct rte_cryptodev_asym_session *sess;
struct rte_crypto_op *op;
};
static struct crypto_testsuite_params testsuite_params = { NULL };
static int
test_rsa_sign_verify(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct rte_mempool *op_mpool = ts_params->op_mpool;
struct rte_mempool *sess_mpool = ts_params->session_mpool;
uint8_t dev_id = ts_params->valid_devs[0];
struct rte_crypto_asym_op *asym_op = NULL;
struct rte_crypto_op *op = NULL, *result_op = NULL;
struct rte_cryptodev_asym_session *sess = NULL;
int status = TEST_SUCCESS;
uint8_t output_buf[TEST_DATA_SIZE] = {0};
uint8_t input_buf[TEST_DATA_SIZE] = {0};
sess = rte_cryptodev_asym_session_create(sess_mpool);
if (!sess) {
RTE_LOG(ERR, USER1, "line %u "
"FAILED: %s", __LINE__,
"Session creation failed");
status = TEST_FAILED;
goto error_exit;
}
if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform,
sess_mpool) < 0) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "unabled to config sym session");
status = TEST_FAILED;
goto error_exit;
}
/* set up crypto op data structure */
op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
if (!op) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__,
"Failed to allocate asymmetric crypto "
"operation struct");
status = TEST_FAILED;
goto error_exit;
}
asym_op = op->asym;
/* Compute sign on the test vector */
asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
memcpy(input_buf, &rsaplaintext.data,
rsaplaintext.len);
asym_op->rsa.message.data = input_buf;
asym_op->rsa.message.length = rsaplaintext.len;
asym_op->rsa.sign.data = output_buf;
asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT1;
debug_hexdump(stdout, "message", asym_op->rsa.message.data,
asym_op->rsa.message.length);
/* attach asymmetric crypto session to crypto operations */
rte_crypto_op_attach_asym_session(op, sess);
RTE_LOG(DEBUG, USER1, "Process ASYM operation");
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
debug_hexdump(stdout, "signed message", asym_op->rsa.sign.data,
asym_op->rsa.sign.length);
asym_op = result_op->asym;
/* Verify sign */
asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT2;
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
status = TEST_SUCCESS;
if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
error_exit:
if (sess) {
rte_cryptodev_asym_session_clear(dev_id, sess);
rte_cryptodev_asym_session_free(sess);
}
if (op)
rte_crypto_op_free(op);
TEST_ASSERT_EQUAL(status, 0, "Test failed");
return status;
}
static int
test_rsa_enc_dec(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct rte_mempool *op_mpool = ts_params->op_mpool;
struct rte_mempool *sess_mpool = ts_params->session_mpool;
uint8_t dev_id = ts_params->valid_devs[0];
struct rte_crypto_asym_op *asym_op = NULL;
struct rte_crypto_op *op = NULL, *result_op = NULL;
struct rte_cryptodev_asym_session *sess = NULL;
int status = TEST_SUCCESS;
uint8_t input_buf[TEST_DATA_SIZE] = {0};
sess = rte_cryptodev_asym_session_create(sess_mpool);
if (!sess) {
RTE_LOG(ERR, USER1, "line %u "
"FAILED: %s", __LINE__,
"Session creation failed");
status = TEST_FAILED;
goto error_exit;
}
if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform,
sess_mpool) < 0) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "unabled to config sym session");
status = TEST_FAILED;
goto error_exit;
}
/* set up crypto op data structure */
op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
if (!op) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__,
"Failed to allocate asymmetric crypto "
"operation struct");
status = TEST_FAILED;
goto error_exit;
}
asym_op = op->asym;
/*Compute encryption on the test vector */
asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_ENCRYPT;
memcpy(input_buf, rsaplaintext.data,
rsaplaintext.len);
asym_op->rsa.message.data = input_buf;
asym_op->rsa.message.length = rsaplaintext.len;
asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT2;
debug_hexdump(stdout, "message", asym_op->rsa.message.data,
asym_op->rsa.message.length);
/* attach asymmetric crypto session to crypto operations */
rte_crypto_op_attach_asym_session(op, sess);
RTE_LOG(DEBUG, USER1, "Process ASYM operation");
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
debug_hexdump(stdout, "encrypted message", asym_op->rsa.message.data,
asym_op->rsa.message.length);
/* Use the resulted output as decryption Input vector*/
asym_op = result_op->asym;
asym_op->rsa.op_type = RTE_CRYPTO_ASYM_OP_DECRYPT;
asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT1;
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
status = TEST_SUCCESS;
int ret = 0;
ret = rsa_verify(&rsaplaintext, result_op);
if (ret)
status = TEST_FAILED;
error_exit:
if (sess) {
rte_cryptodev_asym_session_clear(dev_id, sess);
rte_cryptodev_asym_session_free(sess);
}
if (op)
rte_crypto_op_free(op);
TEST_ASSERT_EQUAL(status, 0, "Test failed");
return status;
}
static int
testsuite_setup(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct rte_cryptodev_info info;
uint32_t i = 0, nb_devs, dev_id;
int ret;
uint16_t qp_id;
memset(ts_params, 0, sizeof(*ts_params));
ts_params->op_mpool = rte_crypto_op_pool_create(
"CRYPTO_ASYM_OP_POOL",
RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
TEST_NUM_BUFS, 0,
0,
rte_socket_id());
if (ts_params->op_mpool == NULL) {
RTE_LOG(ERR, USER1, "Can't create ASYM_CRYPTO_OP_POOL\n");
return TEST_FAILED;
}
/* Create an OPENSSL device if required */
if (gbl_driver_id == rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))) {
nb_devs = rte_cryptodev_device_count_by_driver(
rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)));
if (nb_devs < 1) {
ret = rte_vdev_init(
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD),
NULL);
TEST_ASSERT(ret == 0, "Failed to create "
"instance of pmd : %s",
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
}
}
nb_devs = rte_cryptodev_count();
if (nb_devs < 1) {
RTE_LOG(ERR, USER1, "No crypto devices found?\n");
return TEST_FAILED;
}
/* Create list of valid crypto devs */
for (i = 0; i < nb_devs; i++) {
rte_cryptodev_info_get(i, &info);
if (info.driver_id == gbl_driver_id)
ts_params->valid_devs[ts_params->valid_dev_count++] = i;
}
if (ts_params->valid_dev_count < 1)
return TEST_FAILED;
/* Set up all the qps on the first of the valid devices found */
dev_id = ts_params->valid_devs[0];
rte_cryptodev_info_get(dev_id, &info);
/* check if device support asymmetric, skip if not */
if (!(info.feature_flags &
RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) {
RTE_LOG(ERR, USER1, "Device doesn't support asymmetric. "
"Test Skipped.\n");
return TEST_FAILED;
}
/* configure device with num qp */
ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs;
ts_params->conf.socket_id = SOCKET_ID_ANY;
TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id,
&ts_params->conf),
"Failed to configure cryptodev %u with %u qps",
dev_id, ts_params->conf.nb_queue_pairs);
/* configure qp */
ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
ts_params->qp_conf.mp_session = ts_params->session_mpool;
ts_params->qp_conf.mp_session_private = ts_params->session_mpool;
for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
dev_id, qp_id, &ts_params->qp_conf,
rte_cryptodev_socket_id(dev_id)),
"Failed to setup queue pair %u on cryptodev %u ASYM",
qp_id, dev_id);
}
/* setup asym session pool */
unsigned int session_size =
rte_cryptodev_asym_get_private_session_size(dev_id);
/*
* Create mempool with TEST_NUM_SESSIONS * 2,
* to include the session headers
*/
ts_params->session_mpool = rte_mempool_create(
"test_asym_sess_mp",
TEST_NUM_SESSIONS * 2,
session_size,
0, 0, NULL, NULL, NULL,
NULL, SOCKET_ID_ANY,
0);
TEST_ASSERT_NOT_NULL(ts_params->session_mpool,
"session mempool allocation failed");
return TEST_SUCCESS;
}
static void
testsuite_teardown(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
if (ts_params->op_mpool != NULL) {
RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n",
rte_mempool_avail_count(ts_params->op_mpool));
}
/* Free session mempools */
if (ts_params->session_mpool != NULL) {
rte_mempool_free(ts_params->session_mpool);
ts_params->session_mpool = NULL;
}
}
static int
ut_setup(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
uint16_t qp_id;
/* Reconfigure device to default parameters */
ts_params->conf.socket_id = SOCKET_ID_ANY;
TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0],
&ts_params->conf),
"Failed to configure cryptodev %u",
ts_params->valid_devs[0]);
for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs ; qp_id++) {
TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
ts_params->valid_devs[0], qp_id,
&ts_params->qp_conf,
rte_cryptodev_socket_id(ts_params->valid_devs[0])),
"Failed to setup queue pair %u on cryptodev %u",
qp_id, ts_params->valid_devs[0]);
}
rte_cryptodev_stats_reset(ts_params->valid_devs[0]);
/* Start the device */
TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_devs[0]),
"Failed to start cryptodev %u",
ts_params->valid_devs[0]);
return TEST_SUCCESS;
}
static void
ut_teardown(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct rte_cryptodev_stats stats;
rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats);
/* Stop the device */
rte_cryptodev_stop(ts_params->valid_devs[0]);
}
static inline void print_asym_capa(
const struct rte_cryptodev_asymmetric_xform_capability *capa)
{
int i = 0;
printf("\nxform type: %s\n===================\n",
rte_crypto_asym_xform_strings[capa->xform_type]);
printf("operation supported -");
for (i = 0; i < RTE_CRYPTO_ASYM_OP_LIST_END; i++) {
/* check supported operations */
if (rte_cryptodev_asym_xform_capability_check_optype(capa, i))
printf(" %s",
rte_crypto_asym_op_strings[i]);
}
switch (capa->xform_type) {
case RTE_CRYPTO_ASYM_XFORM_RSA:
case RTE_CRYPTO_ASYM_XFORM_MODINV:
case RTE_CRYPTO_ASYM_XFORM_MODEX:
case RTE_CRYPTO_ASYM_XFORM_DH:
case RTE_CRYPTO_ASYM_XFORM_DSA:
printf(" modlen: min %d max %d increment %d\n",
capa->modlen.min,
capa->modlen.max,
capa->modlen.increment);
break;
default:
break;
}
}
static int
test_capability(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
uint8_t dev_id = ts_params->valid_devs[0];
struct rte_cryptodev_info dev_info;
const struct rte_cryptodev_capabilities *dev_capa;
int i = 0;
struct rte_cryptodev_asym_capability_idx idx;
const struct rte_cryptodev_asymmetric_xform_capability *capa;
rte_cryptodev_info_get(dev_id, &dev_info);
if (!(dev_info.feature_flags &
RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) {
RTE_LOG(INFO, USER1,
"Device doesn't support asymmetric. Test Skipped\n");
return TEST_SUCCESS;
}
/* print xform capability */
for (i = 0;
dev_info.capabilities[i].op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
i++) {
dev_capa = &(dev_info.capabilities[i]);
if (dev_info.capabilities[i].op ==
RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
idx.type = dev_capa->asym.xform_capa.xform_type;
capa = rte_cryptodev_asym_capability_get(dev_id,
(const struct
rte_cryptodev_asym_capability_idx *) &idx);
print_asym_capa(capa);
}
}
return TEST_SUCCESS;
}
static int
test_dh_gen_shared_sec(struct rte_crypto_asym_xform *xfrm)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct rte_mempool *op_mpool = ts_params->op_mpool;
struct rte_mempool *sess_mpool = ts_params->session_mpool;
uint8_t dev_id = ts_params->valid_devs[0];
struct rte_crypto_asym_op *asym_op = NULL;
struct rte_crypto_op *op = NULL, *result_op = NULL;
struct rte_cryptodev_asym_session *sess = NULL;
int status = TEST_SUCCESS;
uint8_t output[TEST_DH_MOD_LEN];
struct rte_crypto_asym_xform xform = *xfrm;
uint8_t peer[] = "01234567890123456789012345678901234567890123456789";
sess = rte_cryptodev_asym_session_create(sess_mpool);
if (sess == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s", __LINE__,
"Session creation failed");
status = TEST_FAILED;
goto error_exit;
}
/* set up crypto op data structure */
op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
if (!op) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to allocate asymmetric crypto "
"operation struct");
status = TEST_FAILED;
goto error_exit;
}
asym_op = op->asym;
/* Setup a xform and op to generate private key only */
xform.dh.type = RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE;
xform.next = NULL;
asym_op->dh.priv_key.data = dh_test_params.priv_key.data;
asym_op->dh.priv_key.length = dh_test_params.priv_key.length;
asym_op->dh.pub_key.data = (uint8_t *)peer;
asym_op->dh.pub_key.length = sizeof(peer);
asym_op->dh.shared_secret.data = output;
asym_op->dh.shared_secret.length = sizeof(output);
if (rte_cryptodev_asym_session_init(dev_id, sess, &xform,
sess_mpool) < 0) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "unabled to config sym session");
status = TEST_FAILED;
goto error_exit;
}
/* attach asymmetric crypto session to crypto operations */
rte_crypto_op_attach_asym_session(op, sess);
RTE_LOG(DEBUG, USER1, "Process ASYM operation");
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
debug_hexdump(stdout, "shared secret:",
asym_op->dh.shared_secret.data,
asym_op->dh.shared_secret.length);
error_exit:
if (sess != NULL) {
rte_cryptodev_asym_session_clear(dev_id, sess);
rte_cryptodev_asym_session_free(sess);
}
if (op != NULL)
rte_crypto_op_free(op);
return status;
}
static int
test_dh_gen_priv_key(struct rte_crypto_asym_xform *xfrm)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct rte_mempool *op_mpool = ts_params->op_mpool;
struct rte_mempool *sess_mpool = ts_params->session_mpool;
uint8_t dev_id = ts_params->valid_devs[0];
struct rte_crypto_asym_op *asym_op = NULL;
struct rte_crypto_op *op = NULL, *result_op = NULL;
struct rte_cryptodev_asym_session *sess = NULL;
int status = TEST_SUCCESS;
uint8_t output[TEST_DH_MOD_LEN];
struct rte_crypto_asym_xform xform = *xfrm;
sess = rte_cryptodev_asym_session_create(sess_mpool);
if (sess == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s", __LINE__,
"Session creation failed");
status = TEST_FAILED;
goto error_exit;
}
/* set up crypto op data structure */
op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
if (!op) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to allocate asymmetric crypto "
"operation struct");
status = TEST_FAILED;
goto error_exit;
}
asym_op = op->asym;
/* Setup a xform and op to generate private key only */
xform.dh.type = RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE;
xform.next = NULL;
asym_op->dh.priv_key.data = output;
asym_op->dh.priv_key.length = sizeof(output);
if (rte_cryptodev_asym_session_init(dev_id, sess, &xform,
sess_mpool) < 0) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "unabled to config sym session");
status = TEST_FAILED;
goto error_exit;
}
/* attach asymmetric crypto session to crypto operations */
rte_crypto_op_attach_asym_session(op, sess);
RTE_LOG(DEBUG, USER1, "Process ASYM operation");
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
debug_hexdump(stdout, "private key:",
asym_op->dh.priv_key.data,
asym_op->dh.priv_key.length);
error_exit:
if (sess != NULL) {
rte_cryptodev_asym_session_clear(dev_id, sess);
rte_cryptodev_asym_session_free(sess);
}
if (op != NULL)
rte_crypto_op_free(op);
return status;
}
static int
test_dh_gen_pub_key(struct rte_crypto_asym_xform *xfrm)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct rte_mempool *op_mpool = ts_params->op_mpool;
struct rte_mempool *sess_mpool = ts_params->session_mpool;
uint8_t dev_id = ts_params->valid_devs[0];
struct rte_crypto_asym_op *asym_op = NULL;
struct rte_crypto_op *op = NULL, *result_op = NULL;
struct rte_cryptodev_asym_session *sess = NULL;
int status = TEST_SUCCESS;
uint8_t output[TEST_DH_MOD_LEN];
struct rte_crypto_asym_xform xform = *xfrm;
sess = rte_cryptodev_asym_session_create(sess_mpool);
if (sess == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s", __LINE__,
"Session creation failed");
status = TEST_FAILED;
goto error_exit;
}
/* set up crypto op data structure */
op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
if (!op) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to allocate asymmetric crypto "
"operation struct");
status = TEST_FAILED;
goto error_exit;
}
asym_op = op->asym;
/* Setup a xform chain to generate public key
* using test private key
*
*/
xform.dh.type = RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE;
xform.next = NULL;
asym_op->dh.pub_key.data = output;
asym_op->dh.pub_key.length = sizeof(output);
/* load pre-defined private key */
asym_op->dh.priv_key.data = rte_malloc(NULL,
dh_test_params.priv_key.length,
0);
asym_op->dh.priv_key = dh_test_params.priv_key;
if (rte_cryptodev_asym_session_init(dev_id, sess, &xform,
sess_mpool) < 0) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "unabled to config sym session");
status = TEST_FAILED;
goto error_exit;
}
/* attach asymmetric crypto session to crypto operations */
rte_crypto_op_attach_asym_session(op, sess);
RTE_LOG(DEBUG, USER1, "Process ASYM operation");
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
debug_hexdump(stdout, "pub key:",
asym_op->dh.pub_key.data, asym_op->dh.pub_key.length);
debug_hexdump(stdout, "priv key:",
asym_op->dh.priv_key.data, asym_op->dh.priv_key.length);
error_exit:
if (sess != NULL) {
rte_cryptodev_asym_session_clear(dev_id, sess);
rte_cryptodev_asym_session_free(sess);
}
if (op != NULL)
rte_crypto_op_free(op);
return status;
}
static int
test_dh_gen_kp(struct rte_crypto_asym_xform *xfrm)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct rte_mempool *op_mpool = ts_params->op_mpool;
struct rte_mempool *sess_mpool = ts_params->session_mpool;
uint8_t dev_id = ts_params->valid_devs[0];
struct rte_crypto_asym_op *asym_op = NULL;
struct rte_crypto_op *op = NULL, *result_op = NULL;
struct rte_cryptodev_asym_session *sess = NULL;
int status = TEST_SUCCESS;
uint8_t out_pub_key[TEST_DH_MOD_LEN];
uint8_t out_prv_key[TEST_DH_MOD_LEN];
struct rte_crypto_asym_xform pub_key_xform;
struct rte_crypto_asym_xform xform = *xfrm;
sess = rte_cryptodev_asym_session_create(sess_mpool);
if (sess == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s", __LINE__,
"Session creation failed");
status = TEST_FAILED;
goto error_exit;
}
/* set up crypto op data structure */
op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
if (!op) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to allocate asymmetric crypto "
"operation struct");
status = TEST_FAILED;
goto error_exit;
}
asym_op = op->asym;
/* Setup a xform chain to generate
* private key first followed by
* public key
*/xform.dh.type = RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE;
pub_key_xform.xform_type = RTE_CRYPTO_ASYM_XFORM_DH;
pub_key_xform.dh.type = RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE;
xform.next = &pub_key_xform;
asym_op->dh.pub_key.data = out_pub_key;
asym_op->dh.pub_key.length = sizeof(out_pub_key);
asym_op->dh.priv_key.data = out_prv_key;
asym_op->dh.priv_key.length = sizeof(out_prv_key);
if (rte_cryptodev_asym_session_init(dev_id, sess, &xform,
sess_mpool) < 0) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "unabled to config sym session");
status = TEST_FAILED;
goto error_exit;
}
/* attach asymmetric crypto session to crypto operations */
rte_crypto_op_attach_asym_session(op, sess);
RTE_LOG(DEBUG, USER1, "Process ASYM operation");
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
debug_hexdump(stdout, "priv key:",
out_prv_key, asym_op->dh.priv_key.length);
debug_hexdump(stdout, "pub key:",
out_pub_key, asym_op->dh.pub_key.length);
error_exit:
if (sess != NULL) {
rte_cryptodev_asym_session_clear(dev_id, sess);
rte_cryptodev_asym_session_free(sess);
}
if (op != NULL)
rte_crypto_op_free(op);
return status;
}
static int
test_mod_inv(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct rte_mempool *op_mpool = ts_params->op_mpool;
struct rte_mempool *sess_mpool = ts_params->session_mpool;
uint8_t dev_id = ts_params->valid_devs[0];
struct rte_crypto_asym_op *asym_op = NULL;
struct rte_crypto_op *op = NULL, *result_op = NULL;
struct rte_cryptodev_asym_session *sess = NULL;
int status = TEST_SUCCESS;
struct rte_cryptodev_asym_capability_idx cap_idx;
const struct rte_cryptodev_asymmetric_xform_capability *capability;
uint8_t input[TEST_DATA_SIZE] = {0};
int ret = 0;
if (rte_cryptodev_asym_get_xform_enum(
&modinv_xform.xform_type, "modinv") < 0) {
RTE_LOG(ERR, USER1,
"Invalid ASYNC algorithm specified\n");
return -1;
}
cap_idx.type = modinv_xform.xform_type;
capability = rte_cryptodev_asym_capability_get(dev_id,
&cap_idx);
if (rte_cryptodev_asym_xform_capability_check_modlen(
capability,
modinv_xform.modinv.modulus.length)) {
RTE_LOG(ERR, USER1,
"Invalid MODULOUS length specified\n");
return -1;
}
sess = rte_cryptodev_asym_session_create(sess_mpool);
if (!sess) {
RTE_LOG(ERR, USER1, "line %u "
"FAILED: %s", __LINE__,
"Session creation failed");
status = TEST_FAILED;
goto error_exit;
}
if (rte_cryptodev_asym_session_init(dev_id, sess, &modinv_xform,
sess_mpool) < 0) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "unabled to config sym session");
status = TEST_FAILED;
goto error_exit;
}
/* generate crypto op data structure */
op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
if (!op) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to allocate asymmetric crypto "
"operation struct");
status = TEST_FAILED;
goto error_exit;
}
asym_op = op->asym;
memcpy(input, base, sizeof(base));
asym_op->modinv.base.data = input;
asym_op->modinv.base.length = sizeof(base);
/* attach asymmetric crypto session to crypto operations */
rte_crypto_op_attach_asym_session(op, sess);
RTE_LOG(DEBUG, USER1, "Process ASYM operation");
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
ret = verify_modinv(mod_inv, result_op);
if (ret) {
RTE_LOG(ERR, USER1,
"operation verification failed\n");
status = TEST_FAILED;
}
error_exit:
if (sess) {
rte_cryptodev_asym_session_clear(dev_id, sess);
rte_cryptodev_asym_session_free(sess);
}
if (op)
rte_crypto_op_free(op);
TEST_ASSERT_EQUAL(status, 0, "Test failed");
return status;
}
static int
test_mod_exp(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct rte_mempool *op_mpool = ts_params->op_mpool;
struct rte_mempool *sess_mpool = ts_params->session_mpool;
uint8_t dev_id = ts_params->valid_devs[0];
struct rte_crypto_asym_op *asym_op = NULL;
struct rte_crypto_op *op = NULL, *result_op = NULL;
struct rte_cryptodev_asym_session *sess = NULL;
int status = TEST_SUCCESS;
struct rte_cryptodev_asym_capability_idx cap_idx;
const struct rte_cryptodev_asymmetric_xform_capability *capability;
uint8_t input[TEST_DATA_SIZE] = {0};
int ret = 0;
if (rte_cryptodev_asym_get_xform_enum(&modex_xform.xform_type,
"modexp")
< 0) {
RTE_LOG(ERR, USER1,
"Invalid ASYNC algorithm specified\n");
return -1;
}
/* check for modlen capability */
cap_idx.type = modex_xform.xform_type;
capability = rte_cryptodev_asym_capability_get(dev_id, &cap_idx);
if (rte_cryptodev_asym_xform_capability_check_modlen(
capability, modex_xform.modex.modulus.length)) {
RTE_LOG(ERR, USER1,
"Invalid MODULOUS length specified\n");
return -1;
}
/* generate crypto op data structure */
op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
if (!op) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to allocate asymmetric crypto "
"operation struct");
status = TEST_FAILED;
goto error_exit;
}
sess = rte_cryptodev_asym_session_create(sess_mpool);
if (!sess) {
RTE_LOG(ERR, USER1,
"line %u "
"FAILED: %s", __LINE__,
"Session creation failed");
status = TEST_FAILED;
goto error_exit;
}
if (rte_cryptodev_asym_session_init(dev_id, sess, &modex_xform,
sess_mpool) < 0) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "unabled to config sym session");
status = TEST_FAILED;
goto error_exit;
}
asym_op = op->asym;
memcpy(input, base, sizeof(base));
asym_op->modex.base.data = input;
asym_op->modex.base.length = sizeof(base);
/* attach asymmetric crypto session to crypto operations */
rte_crypto_op_attach_asym_session(op, sess);
RTE_LOG(DEBUG, USER1, "Process ASYM operation");
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
ret = verify_modexp(mod_exp, result_op);
if (ret) {
RTE_LOG(ERR, USER1,
"operation verification failed\n");
status = TEST_FAILED;
}
error_exit:
if (sess != NULL) {
rte_cryptodev_asym_session_clear(dev_id, sess);
rte_cryptodev_asym_session_free(sess);
}
if (op != NULL)
rte_crypto_op_free(op);
TEST_ASSERT_EQUAL(status, 0, "Test failed");
return status;
}
static int
test_dh_keygenration(void)
{
int status;
debug_hexdump(stdout, "p:", dh_xform.dh.p.data, dh_xform.dh.p.length);
debug_hexdump(stdout, "g:", dh_xform.dh.g.data, dh_xform.dh.g.length);
debug_hexdump(stdout, "priv_key:", dh_test_params.priv_key.data,
dh_test_params.priv_key.length);
RTE_LOG(INFO, USER1,
"Test Public and Private key pair generation\n");
status = test_dh_gen_kp(&dh_xform);
TEST_ASSERT_EQUAL(status, 0, "Test failed");
RTE_LOG(INFO, USER1,
"Test Public Key Generation using pre-defined priv key\n");
status = test_dh_gen_pub_key(&dh_xform);
TEST_ASSERT_EQUAL(status, 0, "Test failed");
RTE_LOG(INFO, USER1,
"Test Private Key Generation only\n");
status = test_dh_gen_priv_key(&dh_xform);
TEST_ASSERT_EQUAL(status, 0, "Test failed");
RTE_LOG(INFO, USER1,
"Test shared secret compute\n");
status = test_dh_gen_shared_sec(&dh_xform);
TEST_ASSERT_EQUAL(status, 0, "Test failed");
return status;
}
static int
test_dsa_sign(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
struct rte_mempool *op_mpool = ts_params->op_mpool;
struct rte_mempool *sess_mpool = ts_params->session_mpool;
uint8_t dev_id = ts_params->valid_devs[0];
struct rte_crypto_asym_op *asym_op = NULL;
struct rte_crypto_op *op = NULL, *result_op = NULL;
struct rte_cryptodev_asym_session *sess = NULL;
int status = TEST_SUCCESS;
uint8_t r[TEST_DH_MOD_LEN];
uint8_t s[TEST_DH_MOD_LEN];
uint8_t dgst[] = "35d81554afaad2cf18f3a1770d5fedc4ea5be344";
sess = rte_cryptodev_asym_session_create(sess_mpool);
if (sess == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s", __LINE__,
"Session creation failed");
status = TEST_FAILED;
goto error_exit;
}
/* set up crypto op data structure */
op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
if (!op) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to allocate asymmetric crypto "
"operation struct");
status = TEST_FAILED;
goto error_exit;
}
asym_op = op->asym;
debug_hexdump(stdout, "p: ", dsa_xform.dsa.p.data,
dsa_xform.dsa.p.length);
debug_hexdump(stdout, "q: ", dsa_xform.dsa.q.data,
dsa_xform.dsa.q.length);
debug_hexdump(stdout, "g: ", dsa_xform.dsa.g.data,
dsa_xform.dsa.g.length);
debug_hexdump(stdout, "priv_key: ", dsa_xform.dsa.x.data,
dsa_xform.dsa.x.length);
if (rte_cryptodev_asym_session_init(dev_id, sess, &dsa_xform,
sess_mpool) < 0) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "unabled to config sym session");
status = TEST_FAILED;
goto error_exit;
}
/* attach asymmetric crypto session to crypto operations */
rte_crypto_op_attach_asym_session(op, sess);
asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
asym_op->dsa.message.data = dgst;
asym_op->dsa.message.length = sizeof(dgst);
asym_op->dsa.r.length = sizeof(r);
asym_op->dsa.r.data = r;
asym_op->dsa.s.length = sizeof(s);
asym_op->dsa.s.data = s;
RTE_LOG(DEBUG, USER1, "Process ASYM operation");
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
asym_op = result_op->asym;
debug_hexdump(stdout, "r:",
asym_op->dsa.r.data, asym_op->dsa.r.length);
debug_hexdump(stdout, "s:",
asym_op->dsa.s.data, asym_op->dsa.s.length);
/* Test PMD DSA sign verification using signer public key */
asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
/* copy signer public key */
asym_op->dsa.y.data = dsa_test_params.y.data;
asym_op->dsa.y.length = dsa_test_params.y.length;
/* Process crypto operation */
if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Error sending packet for operation");
status = TEST_FAILED;
goto error_exit;
}
while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
rte_pause();
if (result_op == NULL) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
goto error_exit;
}
if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
RTE_LOG(ERR, USER1,
"line %u FAILED: %s",
__LINE__, "Failed to process asym crypto op");
status = TEST_FAILED;
}
error_exit:
if (sess != NULL) {
rte_cryptodev_asym_session_clear(dev_id, sess);
rte_cryptodev_asym_session_free(sess);
}
if (op != NULL)
rte_crypto_op_free(op);
return status;
}
static int
test_dsa(void)
{
int status;
status = test_dsa_sign();
TEST_ASSERT_EQUAL(status, 0, "Test failed");
return status;
}
static struct unit_test_suite cryptodev_openssl_asym_testsuite = {
.suite_name = "Crypto Device OPENSSL ASYM Unit Test Suite",
.setup = testsuite_setup,
.teardown = testsuite_teardown,
.unit_test_cases = {
TEST_CASE_ST(ut_setup, ut_teardown, test_capability),
TEST_CASE_ST(ut_setup, ut_teardown, test_dsa),
TEST_CASE_ST(ut_setup, ut_teardown, test_dh_keygenration),
TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_enc_dec),
TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_sign_verify),
TEST_CASE_ST(ut_setup, ut_teardown, test_mod_inv),
TEST_CASE_ST(ut_setup, ut_teardown, test_mod_exp),
TEST_CASES_END() /**< NULL terminate unit test array */
}
};
static int
test_cryptodev_openssl_asym(void)
{
gbl_driver_id = rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
if (gbl_driver_id == -1) {
RTE_LOG(ERR, USER1, "OPENSSL PMD must be loaded. Check if "
"CONFIG_RTE_LIBRTE_PMD_OPENSSL is enabled "
"in config file to run this testsuite.\n");
return TEST_FAILED;
}
return unit_test_suite_runner(&cryptodev_openssl_asym_testsuite);
}
REGISTER_TEST_COMMAND(cryptodev_openssl_asym_autotest,
test_cryptodev_openssl_asym);