@@ -31,6 +31,14 @@
#define MAX_SESSIONS 2048
#define NB_MBUF 8192
+enum crypto_chain_order {
+ CRYPTO_CHAIN_ONLY_CIPHER,
+ CRYPTO_CHAIN_ONLY_AUTH,
+ CRYPTO_CHAIN_CIPHER_AUTH,
+ CRYPTO_CHAIN_AUTH_CIPHER,
+ CRYPTO_CHAIN_NOT_SUPPORTED
+};
+
typedef struct crypto_session_entry_s crypto_session_entry_t;
struct crypto_session_entry_s {
struct crypto_session_entry_s *next;
@@ -122,29 +130,24 @@ static int auth_alg_odp_to_rte(odp_auth_alg_t auth_alg,
case ODP_AUTH_ALG_MD5_96:
#endif
auth_xform->auth.algo = RTE_CRYPTO_AUTH_MD5_HMAC;
- auth_xform->auth.digest_length = 12;
break;
case ODP_AUTH_ALG_SHA256_HMAC:
#if ODP_DEPRECATED_API
case ODP_AUTH_ALG_SHA256_128:
#endif
auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA256_HMAC;
- auth_xform->auth.digest_length = 16;
break;
case ODP_AUTH_ALG_SHA1_HMAC:
auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC;
- auth_xform->auth.digest_length = 20;
break;
case ODP_AUTH_ALG_SHA512_HMAC:
auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA512_HMAC;
- auth_xform->auth.digest_length = 64;
break;
case ODP_AUTH_ALG_AES_GCM:
#if ODP_DEPRECATED_API
case ODP_AUTH_ALG_AES128_GCM:
#endif
auth_xform->auth.algo = RTE_CRYPTO_AUTH_AES_GCM;
- auth_xform->auth.digest_length = 16;
break;
default:
rc = -1;
@@ -538,9 +541,9 @@ int odp_crypto_cipher_capability(odp_cipher_alg_t cipher,
i = 0;
cap = &dev_info.capabilities[i];
while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) {
- cap_cipher_algo = cap->sym.cipher.algo;
if (cap->sym.xform_type ==
RTE_CRYPTO_SYM_XFORM_CIPHER) {
+ cap_cipher_algo = cap->sym.cipher.algo;
if (cap_cipher_algo == cipher_xform.cipher.algo)
break;
}
@@ -615,7 +618,7 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth,
while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) {
cap_auth_algo = cap->sym.auth.algo;
if (cap->sym.xform_type ==
- RTE_CRYPTO_SYM_XFORM_CIPHER) {
+ RTE_CRYPTO_SYM_XFORM_AUTH) {
if (cap_auth_algo == auth_xform.auth.algo)
break;
}
@@ -663,76 +666,105 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth,
return idx;
}
-static int get_crypto_dev(struct rte_crypto_sym_xform *cipher_xform,
- struct rte_crypto_sym_xform *auth_xform,
+static int get_crypto_dev(struct rte_crypto_sym_xform *first_xform,
+ enum crypto_chain_order res,
uint16_t iv_length, uint8_t *dev_id)
{
uint8_t cdev_id, id;
const struct rte_cryptodev_capabilities *cap;
+ struct rte_crypto_sym_xform *auth_xform = NULL;
+ struct rte_crypto_sym_xform *cipher_xform = NULL;
enum rte_crypto_cipher_algorithm cap_cipher_algo;
enum rte_crypto_auth_algorithm cap_auth_algo;
enum rte_crypto_cipher_algorithm app_cipher_algo;
enum rte_crypto_auth_algorithm app_auth_algo;
+ switch (res) {
+ case CRYPTO_CHAIN_ONLY_CIPHER:
+ cipher_xform = first_xform;
+ break;
+ case CRYPTO_CHAIN_ONLY_AUTH:
+ auth_xform = first_xform;
+ break;
+ case CRYPTO_CHAIN_CIPHER_AUTH:
+ cipher_xform = first_xform;
+ auth_xform = first_xform->next;
+ break;
+ case CRYPTO_CHAIN_AUTH_CIPHER:
+ auth_xform = first_xform;
+ cipher_xform = first_xform->next;
+ break;
+ default:
+ return -1;
+ }
+
for (id = 0; id < global->enabled_crypto_devs; id++) {
struct rte_cryptodev_info dev_info;
int i = 0;
cdev_id = global->enabled_crypto_dev_ids[id];
rte_cryptodev_info_get(cdev_id, &dev_info);
- app_cipher_algo = cipher_xform->cipher.algo;
cap = &dev_info.capabilities[i];
- while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) {
- cap_cipher_algo = cap->sym.cipher.algo;
+ while (cipher_xform && cap->op !=
+ RTE_CRYPTO_OP_TYPE_UNDEFINED) {
if (cap->sym.xform_type ==
RTE_CRYPTO_SYM_XFORM_CIPHER) {
+ app_cipher_algo = cipher_xform->cipher.algo;
+ cap_cipher_algo = cap->sym.cipher.algo;
if (cap_cipher_algo == app_cipher_algo)
break;
}
- cap = &dev_info.capabilities[++i];
+ cap = &dev_info.capabilities[++i];
}
if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED)
continue;
- /* Check if key size is supported by the algorithm. */
- if (cipher_xform->cipher.key.length) {
- if (is_valid_size(cipher_xform->cipher.key.length,
- cap->sym.cipher.key_size.min,
- cap->sym.cipher.key_size.max,
- cap->sym.cipher.key_size.
- increment) != 0) {
- ODP_ERR("Unsupported cipher key length\n");
- return -1;
- }
- /* No size provided, use minimum size. */
- } else
- cipher_xform->cipher.key.length =
- cap->sym.cipher.key_size.min;
-
- /* Check if iv length is supported by the algorithm. */
- if (iv_length) {
- if (is_valid_size(iv_length,
- cap->sym.cipher.iv_size.min,
- cap->sym.cipher.iv_size.max,
- cap->sym.cipher.iv_size.
- increment) != 0) {
- ODP_ERR("Unsupported iv length\n");
- return -1;
+ if (cipher_xform) {
+ /* Check if key size is supported by the algorithm. */
+ if (cipher_xform->cipher.key.length) {
+ if (is_valid_size(
+ cipher_xform->cipher.key.length,
+ cap->sym.cipher.key_size.min,
+ cap->sym.cipher.key_size.max,
+ cap->sym.cipher.key_size.
+ increment) != 0) {
+ ODP_ERR("Invalid cipher key length\n");
+ return -1;
+ }
+ /* No size provided, use minimum size. */
+ } else
+ cipher_xform->cipher.key.length =
+ cap->sym.cipher.key_size.min;
+
+ /* Check if iv length is supported by the algorithm. */
+ if (iv_length) {
+ if (is_valid_size(iv_length,
+ cap->sym.cipher.iv_size.min,
+ cap->sym.cipher.iv_size.max,
+ cap->sym.cipher.iv_size.
+ increment) != 0) {
+ ODP_ERR("Invalid iv length\n");
+ return -1;
+ }
}
}
+ if (cipher_xform && !auth_xform) {
+ memcpy(dev_id, &cdev_id, sizeof(cdev_id));
+ return 0;
+ }
+
i = 0;
- app_auth_algo = auth_xform->auth.algo;
cap = &dev_info.capabilities[i];
- while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) {
- cap_auth_algo = cap->sym.auth.algo;
+ while (auth_xform && cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) {
if ((cap->sym.xform_type ==
- RTE_CRYPTO_SYM_XFORM_AUTH) &
- (cap_auth_algo == app_auth_algo)) {
- break;
+ RTE_CRYPTO_SYM_XFORM_AUTH)) {
+ app_auth_algo = auth_xform->auth.algo;
+ cap_auth_algo = cap->sym.auth.algo;
+ if (cap_auth_algo == app_auth_algo)
+ break;
}
-
cap = &dev_info.capabilities[++i];
}
@@ -776,6 +808,22 @@ static int get_crypto_dev(struct rte_crypto_sym_xform *cipher_xform,
return -1;
}
+static void set_chain_order(struct rte_crypto_sym_xform **first_xform,
+ struct rte_crypto_sym_xform *auth_xform,
+ struct rte_crypto_sym_xform *cipher_xform,
+ enum crypto_chain_order *res)
+{
+ if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_NULL) {
+ *first_xform = cipher_xform;
+ (*first_xform)->next = NULL;
+ *res = CRYPTO_CHAIN_ONLY_CIPHER;
+ } else if (cipher_xform->cipher.algo == RTE_CRYPTO_CIPHER_NULL) {
+ *first_xform = auth_xform;
+ (*first_xform)->next = NULL;
+ *res = CRYPTO_CHAIN_ONLY_AUTH;
+ }
+}
+
int odp_crypto_session_create(odp_crypto_session_param_t *param,
odp_crypto_session_t *session_out,
odp_crypto_ses_create_err_t *status)
@@ -784,8 +832,9 @@ int odp_crypto_session_create(odp_crypto_session_param_t *param,
uint8_t cdev_id = 0;
struct rte_crypto_sym_xform cipher_xform;
struct rte_crypto_sym_xform auth_xform;
- struct rte_crypto_sym_xform *first_xform;
+ struct rte_crypto_sym_xform *first_xform = NULL;
struct rte_cryptodev_sym_session *session;
+ enum crypto_chain_order res = CRYPTO_CHAIN_NOT_SUPPORTED;
crypto_session_entry_t *entry;
*session_out = ODP_CRYPTO_SESSION_INVALID;
@@ -810,6 +859,16 @@ int odp_crypto_session_create(odp_crypto_session_param_t *param,
cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
cipher_xform.next = NULL;
+ rc = cipher_alg_odp_to_rte(param->cipher_alg, &cipher_xform);
+
+ /* Check result */
+ if (rc) {
+ *status = ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER;
+ /* remove the crypto_session_entry_t */
+ memset(entry, 0, sizeof(*entry));
+ free_session(entry);
+ return -1;
+ }
if (param->cipher_key.length) {
/* Cipher Data */
@@ -828,12 +887,22 @@ int odp_crypto_session_create(odp_crypto_session_param_t *param,
param->cipher_key.data,
param->cipher_key.length);
} else {
- cipher_xform.cipher.key.data = 0;
cipher_xform.cipher.key.length = 0;
+ cipher_xform.cipher.key.data = 0;
}
auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
auth_xform.next = NULL;
+ rc = auth_alg_odp_to_rte(param->auth_alg, &auth_xform);
+
+ /* Check result */
+ if (rc) {
+ *status = ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH;
+ /* remove the crypto_session_entry_t */
+ memset(entry, 0, sizeof(*entry));
+ free_session(entry);
+ return -1;
+ }
if (param->auth_key.length) {
/* Authentication Data */
@@ -855,48 +924,51 @@ int odp_crypto_session_create(odp_crypto_session_param_t *param,
auth_xform.auth.key.length = 0;
}
+ auth_xform.auth.digest_length = 0;
+ if (param->auth_digest_len)
+ auth_xform.auth.digest_length = param->auth_digest_len;
/* Derive order */
- if (ODP_CRYPTO_OP_ENCODE == param->op)
- entry->do_cipher_first = param->auth_cipher_text;
- else
- entry->do_cipher_first = !param->auth_cipher_text;
-
- /* Process based on cipher */
- /* Derive order */
- if (entry->do_cipher_first) {
+ if (ODP_CRYPTO_OP_ENCODE == param->op) {
cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
- first_xform = &cipher_xform;
- first_xform->next = &auth_xform;
+ entry->do_cipher_first = param->auth_cipher_text;
} else {
cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT;
auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
- first_xform = &auth_xform;
- first_xform->next = &cipher_xform;
- }
-
- rc = cipher_alg_odp_to_rte(param->cipher_alg, &cipher_xform);
-
- /* Check result */
- if (rc) {
- *status = ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER;
- return -1;
+ entry->do_cipher_first = !param->auth_cipher_text;
}
- rc = auth_alg_odp_to_rte(param->auth_alg, &auth_xform);
-
- /* Check result */
- if (rc) {
- *status = ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH;
- /* remove the crypto_session_entry_t */
- memset(entry, 0, sizeof(*entry));
- free_session(entry);
- return -1;
+ /* Process based on cipher */
+ /* Derive order */
+ if (entry->do_cipher_first) {
+ if (auth_xform.auth.algo != RTE_CRYPTO_AUTH_NULL &&
+ cipher_xform.cipher.algo != RTE_CRYPTO_CIPHER_NULL) {
+ first_xform = &cipher_xform;
+ first_xform->next = &auth_xform;
+ res = CRYPTO_CHAIN_CIPHER_AUTH;
+ } else {
+ set_chain_order(&first_xform,
+ &auth_xform,
+ &cipher_xform,
+ &res);
+ }
+ } else {
+ if (auth_xform.auth.algo != RTE_CRYPTO_AUTH_NULL &&
+ cipher_xform.cipher.algo != RTE_CRYPTO_CIPHER_NULL) {
+ first_xform = &auth_xform;
+ first_xform->next = &cipher_xform;
+ res = CRYPTO_CHAIN_AUTH_CIPHER;
+ } else {
+ set_chain_order(&first_xform,
+ &auth_xform,
+ &cipher_xform,
+ &res);
+ }
}
- rc = get_crypto_dev(&cipher_xform,
- &auth_xform,
+ rc = get_crypto_dev(first_xform,
+ res,
param->iv.length,
&cdev_id);
@@ -1269,15 +1341,13 @@ int odp_crypto_int(odp_packet_t pkt_in,
op->sym->auth.aad.length = aad_len;
}
- if (entry->iv.length == 0) {
- ODP_ERR("Wrong IV length");
- goto err_op_free;
- }
- op->sym->cipher.iv.data = rte_malloc("iv", entry->iv.length, 0);
- if (op->sym->cipher.iv.data == NULL) {
- ODP_ERR("Failed to allocate memory for IV");
- goto err_op_free;
+ if (entry->iv.length) {
+ op->sym->cipher.iv.data = rte_malloc("iv", entry->iv.length, 0);
+ if (op->sym->cipher.iv.data == NULL) {
+ ODP_ERR("Failed to allocate memory for IV");
+ goto err_op_free;
+ }
}
if (param->override_iv_ptr) {
@@ -1,6 +1,7 @@
#!/bin/bash
-export ODP_PLATFORM_PARAMS=${ODP_PLATFORM_PARAMS:--n 4 --vdev "crypto_openssl"}
+export ODP_PLATFORM_PARAMS=${ODP_PLATFORM_PARAMS:--n 4 "--vdev \
+"crypto_openssl" --vdev "crypto_null""}
# where to mount huge pages
export HUGEPAGEDIR=${HUGEPAGEDIR:-/mnt/huge}
@@ -303,6 +303,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
case ODP_CIPHER_ALG_3DES_CBC:
ipsec_sa->esp_iv_len = 8;
ipsec_sa->esp_block_len = 8;
+ crypto_param.iv.length = 8;
break;
#if ODP_DEPRECATED_API
case ODP_CIPHER_ALG_AES128_CBC:
@@ -310,6 +311,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
case ODP_CIPHER_ALG_AES_CBC:
ipsec_sa->esp_iv_len = 16;
ipsec_sa->esp_block_len = 16;
+ crypto_param.iv.length = 16;
break;
#if ODP_DEPRECATED_API
case ODP_CIPHER_ALG_AES128_GCM:
@@ -45,6 +45,21 @@ static uint8_t test_key24[24] = { 0x01, 0x02, 0x03, 0x04, 0x05,
0x15, 0x16, 0x17, 0x18
};
+static uint8_t test_key64[64] = { 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19,
+ 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
+ 0x1f, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
+ 0x2e, 0x2f, 0x30, 0x31, 0x32,
+ 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c,
+ 0x3d, 0x3e, 0x3f, 0x40
+};
+
/**
* Structure that holds template for session create call
* for different algorithms supported by test
@@ -226,6 +241,18 @@ static crypto_alg_config_t algs_config[] = {
.auth_digest_len = 12,
},
},
+ {
+ .name = "null-hmac-md5-96",
+ .session = {
+ .cipher_alg = ODP_CIPHER_ALG_NULL,
+ .auth_alg = ODP_AUTH_ALG_MD5_HMAC,
+ .auth_key = {
+ .data = test_key64,
+ .length = sizeof(test_key64)
+ },
+ .auth_digest_len = 16,
+ },
+ },
};
/**
@@ -429,6 +456,7 @@ create_session_from_config(odp_crypto_session_t *session,
odp_crypto_session_param_init(¶ms);
memcpy(¶ms, &config->session, sizeof(odp_crypto_session_param_t));
params.op = ODP_CRYPTO_OP_ENCODE;
+ params.auth_cipher_text = 1;
params.pref_mode = ODP_CRYPTO_SYNC;
/* Lookup the packet pool */
@@ -119,7 +119,8 @@ static void pktio_stop(odp_pktio_t pktio)
int ipsec_check(odp_bool_t ah,
odp_cipher_alg_t cipher,
uint32_t cipher_bits,
- odp_auth_alg_t auth)
+ odp_auth_alg_t auth,
+ uint32_t auth_bits)
{
odp_ipsec_capability_t capa;
odp_crypto_cipher_capability_t cipher_capa[MAX_ALG_CAPA];
@@ -220,52 +221,65 @@ int ipsec_check(odp_bool_t ah,
}
if (!found) {
- fprintf(stderr, "Unsupported key length\n");
+ fprintf(stderr, "Unsupported cipher key length\n");
return ODP_TEST_INACTIVE;
}
+ found = false;
num = odp_ipsec_auth_capability(auth, auth_capa, MAX_ALG_CAPA);
if (num <= 0) {
fprintf(stderr, "Wrong auth capabilities\n");
return ODP_TEST_INACTIVE;
}
+ for (i = 0; i < num; i++) {
+ if (auth_capa[i].key_len == auth_bits / 8) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ fprintf(stderr, "Unsupported auth key length\n");
+ return ODP_TEST_INACTIVE;
+ }
+
return ODP_TEST_ACTIVE;
}
int ipsec_check_ah_sha256(void)
{
- return ipsec_check_ah(ODP_AUTH_ALG_SHA256_HMAC);
+ return ipsec_check_ah(ODP_AUTH_ALG_SHA256_HMAC, 256);
}
int ipsec_check_esp_null_sha256(void)
{
return ipsec_check_esp(ODP_CIPHER_ALG_NULL, 0,
- ODP_AUTH_ALG_SHA256_HMAC);
+ ODP_AUTH_ALG_SHA256_HMAC, 256);
}
int ipsec_check_esp_aes_cbc_128_null(void)
{
return ipsec_check_esp(ODP_CIPHER_ALG_AES_CBC, 128,
- ODP_AUTH_ALG_NULL);
+ ODP_AUTH_ALG_NULL, 0);
}
int ipsec_check_esp_aes_cbc_128_sha256(void)
{
return ipsec_check_esp(ODP_CIPHER_ALG_AES_CBC, 128,
- ODP_AUTH_ALG_SHA256_HMAC);
+ ODP_AUTH_ALG_SHA256_HMAC, 256);
}
int ipsec_check_esp_aes_gcm_128(void)
{
return ipsec_check_esp(ODP_CIPHER_ALG_AES_GCM, 128,
- ODP_AUTH_ALG_AES_GCM);
+ ODP_AUTH_ALG_AES_GCM, 128);
}
int ipsec_check_esp_aes_gcm_256(void)
{
return ipsec_check_esp(ODP_CIPHER_ALG_AES_GCM, 256,
- ODP_AUTH_ALG_AES_GCM);
+ ODP_AUTH_ALG_AES_GCM, 256);
}
void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param,
@@ -74,16 +74,16 @@ void ipsec_check_out_in_one(const ipsec_test_part *part,
int ipsec_check(odp_bool_t ah,
odp_cipher_alg_t cipher,
uint32_t cipher_bits,
- odp_auth_alg_t auth);
-#define ipsec_check_ah(auth) \
- ipsec_check(true, ODP_CIPHER_ALG_NULL, 0, auth)
-#define ipsec_check_esp(cipher, cipher_bits, auth) \
- ipsec_check(false, cipher, cipher_bits, auth)
+ odp_auth_alg_t auth,
+ uint32_t auth_bits);
+#define ipsec_check_ah(auth, auth_bits) \
+ ipsec_check(true, ODP_CIPHER_ALG_NULL, 0, auth, auth_bits)
+#define ipsec_check_esp(cipher, cipher_bits, auth, auth_bits) \
+ ipsec_check(false, cipher, cipher_bits, auth, auth_bits)
int ipsec_check_ah_sha256(void);
int ipsec_check_esp_null_sha256(void);
int ipsec_check_esp_aes_cbc_128_null(void);
int ipsec_check_esp_aes_cbc_128_sha256(void);
int ipsec_check_esp_aes_gcm_128(void);
int ipsec_check_esp_aes_gcm_256(void);
-
#endif