examples/l2fwd-crypto: fix ambiguous input key size
Some crypto algorithms support more than one key size
(including cipher key, authentication key, IV and AAD),
but the app was using always the minimum size.
These changes allows the user to use an specific size,
either from the string provided with cipher_key, auth_key, iv and ADD
parameters, or from the values provided with cipher_key_random_size,
auth_key_random_size, iv_random_size and aad_random_size.
This also allows the user to specify the digest size.
Fixes: 1df9c0109f
("examples/l2fwd-crypto: parse key parameters")
Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Tested-by: Min Cao <min.cao@intel.com>
Acked-by: Declan Doherty <declan.doherty@intel.com>
This commit is contained in:
parent
a158899a80
commit
a061e50a0d
@ -147,15 +147,21 @@ struct l2fwd_crypto_options {
|
|||||||
|
|
||||||
struct rte_crypto_sym_xform cipher_xform;
|
struct rte_crypto_sym_xform cipher_xform;
|
||||||
unsigned ckey_param;
|
unsigned ckey_param;
|
||||||
|
int ckey_random_size;
|
||||||
|
|
||||||
struct l2fwd_key iv;
|
struct l2fwd_key iv;
|
||||||
unsigned iv_param;
|
unsigned iv_param;
|
||||||
|
int iv_random_size;
|
||||||
|
|
||||||
struct rte_crypto_sym_xform auth_xform;
|
struct rte_crypto_sym_xform auth_xform;
|
||||||
uint8_t akey_param;
|
uint8_t akey_param;
|
||||||
|
int akey_random_size;
|
||||||
|
|
||||||
struct l2fwd_key aad;
|
struct l2fwd_key aad;
|
||||||
unsigned aad_param;
|
unsigned aad_param;
|
||||||
|
int aad_random_size;
|
||||||
|
|
||||||
|
int digest_size;
|
||||||
|
|
||||||
uint16_t block_size;
|
uint16_t block_size;
|
||||||
char string_auth_algo[MAX_STR_LEN];
|
char string_auth_algo[MAX_STR_LEN];
|
||||||
@ -799,12 +805,17 @@ l2fwd_crypto_usage(const char *prgname)
|
|||||||
" --cipher_algo ALGO\n"
|
" --cipher_algo ALGO\n"
|
||||||
" --cipher_op ENCRYPT / DECRYPT\n"
|
" --cipher_op ENCRYPT / DECRYPT\n"
|
||||||
" --cipher_key KEY\n"
|
" --cipher_key KEY\n"
|
||||||
|
" --cipher_key_random_size SIZE: size of cipher key when generated randomly\n"
|
||||||
" --iv IV\n"
|
" --iv IV\n"
|
||||||
|
" --iv_random_size SIZE: size of IV when generated randomly\n"
|
||||||
|
|
||||||
" --auth_algo ALGO\n"
|
" --auth_algo ALGO\n"
|
||||||
" --auth_op GENERATE / VERIFY\n"
|
" --auth_op GENERATE / VERIFY\n"
|
||||||
" --auth_key KEY\n"
|
" --auth_key KEY\n"
|
||||||
|
" --auth_key_random_size SIZE: size of auth key when generated randomly\n"
|
||||||
" --aad AAD\n"
|
" --aad AAD\n"
|
||||||
|
" --aad_random_size SIZE: size of AAD when generated randomly\n"
|
||||||
|
" --digest_size SIZE: size of digest to be generated/verified\n"
|
||||||
|
|
||||||
" --sessionless\n",
|
" --sessionless\n",
|
||||||
prgname);
|
prgname);
|
||||||
@ -906,6 +917,27 @@ parse_key(uint8_t *data, char *input_arg)
|
|||||||
data[byte_count++] = (uint8_t)number;
|
data[byte_count++] = (uint8_t)number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return byte_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Parse size param*/
|
||||||
|
static int
|
||||||
|
parse_size(int *size, const char *q_arg)
|
||||||
|
{
|
||||||
|
char *end = NULL;
|
||||||
|
unsigned long n;
|
||||||
|
|
||||||
|
/* parse hexadecimal string */
|
||||||
|
n = strtoul(q_arg, &end, 10);
|
||||||
|
if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0'))
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
printf("invalid size\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*size = n;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -993,14 +1025,30 @@ l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options,
|
|||||||
|
|
||||||
else if (strcmp(lgopts[option_index].name, "cipher_key") == 0) {
|
else if (strcmp(lgopts[option_index].name, "cipher_key") == 0) {
|
||||||
options->ckey_param = 1;
|
options->ckey_param = 1;
|
||||||
return parse_key(options->cipher_xform.cipher.key.data, optarg);
|
options->cipher_xform.cipher.key.length =
|
||||||
|
parse_key(options->cipher_xform.cipher.key.data, optarg);
|
||||||
|
if (options->cipher_xform.cipher.key.length > 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (strcmp(lgopts[option_index].name, "cipher_key_random_size") == 0)
|
||||||
|
return parse_size(&options->ckey_random_size, optarg);
|
||||||
|
|
||||||
else if (strcmp(lgopts[option_index].name, "iv") == 0) {
|
else if (strcmp(lgopts[option_index].name, "iv") == 0) {
|
||||||
options->iv_param = 1;
|
options->iv_param = 1;
|
||||||
return parse_key(options->iv.data, optarg);
|
options->iv.length =
|
||||||
|
parse_key(options->iv.data, optarg);
|
||||||
|
if (options->iv.length > 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (strcmp(lgopts[option_index].name, "iv_random_size") == 0)
|
||||||
|
return parse_size(&options->iv_random_size, optarg);
|
||||||
|
|
||||||
/* Authentication options */
|
/* Authentication options */
|
||||||
else if (strcmp(lgopts[option_index].name, "auth_algo") == 0) {
|
else if (strcmp(lgopts[option_index].name, "auth_algo") == 0) {
|
||||||
retval = parse_auth_algo(&options->auth_xform.auth.algo,
|
retval = parse_auth_algo(&options->auth_xform.auth.algo,
|
||||||
@ -1016,12 +1064,34 @@ l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options,
|
|||||||
|
|
||||||
else if (strcmp(lgopts[option_index].name, "auth_key") == 0) {
|
else if (strcmp(lgopts[option_index].name, "auth_key") == 0) {
|
||||||
options->akey_param = 1;
|
options->akey_param = 1;
|
||||||
return parse_key(options->auth_xform.auth.key.data, optarg);
|
options->auth_xform.auth.key.length =
|
||||||
|
parse_key(options->auth_xform.auth.key.data, optarg);
|
||||||
|
if (options->auth_xform.auth.key.length > 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (strcmp(lgopts[option_index].name, "auth_key_random_size") == 0) {
|
||||||
|
return parse_size(&options->akey_random_size, optarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strcmp(lgopts[option_index].name, "aad") == 0) {
|
else if (strcmp(lgopts[option_index].name, "aad") == 0) {
|
||||||
options->aad_param = 1;
|
options->aad_param = 1;
|
||||||
return parse_key(options->aad.data, optarg);
|
options->aad.length =
|
||||||
|
parse_key(options->aad.data, optarg);
|
||||||
|
if (options->aad.length > 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (strcmp(lgopts[option_index].name, "aad_random_size") == 0) {
|
||||||
|
return parse_size(&options->aad_random_size, optarg);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (strcmp(lgopts[option_index].name, "digest_size") == 0) {
|
||||||
|
return parse_size(&options->digest_size, optarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strcmp(lgopts[option_index].name, "sessionless") == 0) {
|
else if (strcmp(lgopts[option_index].name, "sessionless") == 0) {
|
||||||
@ -1121,7 +1191,11 @@ l2fwd_crypto_default_options(struct l2fwd_crypto_options *options)
|
|||||||
options->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
|
options->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
|
||||||
options->cipher_xform.next = NULL;
|
options->cipher_xform.next = NULL;
|
||||||
options->ckey_param = 0;
|
options->ckey_param = 0;
|
||||||
|
options->ckey_random_size = -1;
|
||||||
|
options->cipher_xform.cipher.key.length = 0;
|
||||||
options->iv_param = 0;
|
options->iv_param = 0;
|
||||||
|
options->iv_random_size = -1;
|
||||||
|
options->iv.length = 0;
|
||||||
|
|
||||||
options->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC;
|
options->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC;
|
||||||
options->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
|
options->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
|
||||||
@ -1130,7 +1204,12 @@ l2fwd_crypto_default_options(struct l2fwd_crypto_options *options)
|
|||||||
options->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
|
options->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
|
||||||
options->auth_xform.next = NULL;
|
options->auth_xform.next = NULL;
|
||||||
options->akey_param = 0;
|
options->akey_param = 0;
|
||||||
|
options->akey_random_size = -1;
|
||||||
|
options->auth_xform.auth.key.length = 0;
|
||||||
options->aad_param = 0;
|
options->aad_param = 0;
|
||||||
|
options->aad_random_size = -1;
|
||||||
|
options->aad.length = 0;
|
||||||
|
options->digest_size = -1;
|
||||||
|
|
||||||
options->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC;
|
options->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC;
|
||||||
options->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
|
options->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
|
||||||
@ -1171,13 +1250,18 @@ l2fwd_crypto_parse_args(struct l2fwd_crypto_options *options,
|
|||||||
{ "cipher_algo", required_argument, 0, 0 },
|
{ "cipher_algo", required_argument, 0, 0 },
|
||||||
{ "cipher_op", required_argument, 0, 0 },
|
{ "cipher_op", required_argument, 0, 0 },
|
||||||
{ "cipher_key", required_argument, 0, 0 },
|
{ "cipher_key", required_argument, 0, 0 },
|
||||||
|
{ "cipher_key_random_size", required_argument, 0, 0 },
|
||||||
|
|
||||||
{ "auth_algo", required_argument, 0, 0 },
|
{ "auth_algo", required_argument, 0, 0 },
|
||||||
{ "auth_op", required_argument, 0, 0 },
|
{ "auth_op", required_argument, 0, 0 },
|
||||||
{ "auth_key", required_argument, 0, 0 },
|
{ "auth_key", required_argument, 0, 0 },
|
||||||
|
{ "auth_key_random_size", required_argument, 0, 0 },
|
||||||
|
|
||||||
{ "iv", required_argument, 0, 0 },
|
{ "iv", required_argument, 0, 0 },
|
||||||
|
{ "iv_random_size", required_argument, 0, 0 },
|
||||||
{ "aad", required_argument, 0, 0 },
|
{ "aad", required_argument, 0, 0 },
|
||||||
|
{ "aad_random_size", required_argument, 0, 0 },
|
||||||
|
{ "digest_size", required_argument, 0, 0 },
|
||||||
|
|
||||||
{ "sessionless", no_argument, 0, 0 },
|
{ "sessionless", no_argument, 0, 0 },
|
||||||
|
|
||||||
@ -1320,6 +1404,19 @@ check_type(struct l2fwd_crypto_options *options, struct rte_cryptodev_info *dev_
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
check_supported_size(uint16_t length, uint16_t min, uint16_t max,
|
||||||
|
uint16_t increment)
|
||||||
|
{
|
||||||
|
uint16_t supp_size;
|
||||||
|
|
||||||
|
for (supp_size = min; supp_size <= max; supp_size += increment) {
|
||||||
|
if (length == supp_size)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
static int
|
static int
|
||||||
initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
|
initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
|
||||||
uint8_t *enabled_cdevs)
|
uint8_t *enabled_cdevs)
|
||||||
@ -1383,9 +1480,71 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
|
|||||||
}
|
}
|
||||||
|
|
||||||
options->block_size = cap->sym.cipher.block_size;
|
options->block_size = cap->sym.cipher.block_size;
|
||||||
|
/*
|
||||||
|
* Check if length of provided IV is supported
|
||||||
|
* by the algorithm chosen.
|
||||||
|
*/
|
||||||
|
if (options->iv_param) {
|
||||||
|
if (check_supported_size(options->iv.length,
|
||||||
|
cap->sym.cipher.iv_size.min,
|
||||||
|
cap->sym.cipher.iv_size.max,
|
||||||
|
cap->sym.cipher.iv_size.increment)
|
||||||
|
!= 0) {
|
||||||
|
printf("Unsupported IV length\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Check if length of IV to be randomly generated
|
||||||
|
* is supported by the algorithm chosen.
|
||||||
|
*/
|
||||||
|
} else if (options->iv_random_size != -1) {
|
||||||
|
if (check_supported_size(options->iv_random_size,
|
||||||
|
cap->sym.cipher.iv_size.min,
|
||||||
|
cap->sym.cipher.iv_size.max,
|
||||||
|
cap->sym.cipher.iv_size.increment)
|
||||||
|
!= 0) {
|
||||||
|
printf("Unsupported IV length\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
options->iv.length = options->iv_random_size;
|
||||||
|
/* No size provided, use minimum size. */
|
||||||
|
} else
|
||||||
options->iv.length = cap->sym.cipher.iv_size.min;
|
options->iv.length = cap->sym.cipher.iv_size.min;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if length of provided cipher key is supported
|
||||||
|
* by the algorithm chosen.
|
||||||
|
*/
|
||||||
|
if (options->ckey_param) {
|
||||||
|
if (check_supported_size(
|
||||||
|
options->cipher_xform.cipher.key.length,
|
||||||
|
cap->sym.cipher.key_size.min,
|
||||||
|
cap->sym.cipher.key_size.max,
|
||||||
|
cap->sym.cipher.key_size.increment)
|
||||||
|
!= 0) {
|
||||||
|
printf("Unsupported cipher key length\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Check if length of the cipher key to be randomly generated
|
||||||
|
* is supported by the algorithm chosen.
|
||||||
|
*/
|
||||||
|
} else if (options->ckey_random_size != -1) {
|
||||||
|
if (check_supported_size(options->ckey_random_size,
|
||||||
|
cap->sym.cipher.key_size.min,
|
||||||
|
cap->sym.cipher.key_size.max,
|
||||||
|
cap->sym.cipher.key_size.increment)
|
||||||
|
!= 0) {
|
||||||
|
printf("Unsupported cipher key length\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
options->cipher_xform.cipher.key.length =
|
||||||
|
options->ckey_random_size;
|
||||||
|
/* No size provided, use minimum size. */
|
||||||
|
} else
|
||||||
options->cipher_xform.cipher.key.length =
|
options->cipher_xform.cipher.key.length =
|
||||||
cap->sym.cipher.key_size.min;
|
cap->sym.cipher.key_size.min;
|
||||||
|
|
||||||
if (!options->ckey_param)
|
if (!options->ckey_param)
|
||||||
generate_random_key(
|
generate_random_key(
|
||||||
options->cipher_xform.cipher.key.data,
|
options->cipher_xform.cipher.key.data,
|
||||||
@ -1420,10 +1579,71 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
|
|||||||
}
|
}
|
||||||
|
|
||||||
options->block_size = cap->sym.auth.block_size;
|
options->block_size = cap->sym.auth.block_size;
|
||||||
|
/*
|
||||||
|
* Check if length of provided AAD is supported
|
||||||
|
* by the algorithm chosen.
|
||||||
|
*/
|
||||||
|
if (options->aad_param) {
|
||||||
|
if (check_supported_size(options->aad.length,
|
||||||
|
cap->sym.auth.aad_size.min,
|
||||||
|
cap->sym.auth.aad_size.max,
|
||||||
|
cap->sym.auth.aad_size.increment)
|
||||||
|
!= 0) {
|
||||||
|
printf("Unsupported AAD length\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Check if length of AAD to be randomly generated
|
||||||
|
* is supported by the algorithm chosen.
|
||||||
|
*/
|
||||||
|
} else if (options->aad_random_size != -1) {
|
||||||
|
if (check_supported_size(options->aad_random_size,
|
||||||
|
cap->sym.auth.aad_size.min,
|
||||||
|
cap->sym.auth.aad_size.max,
|
||||||
|
cap->sym.auth.aad_size.increment)
|
||||||
|
!= 0) {
|
||||||
|
printf("Unsupported AAD length\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
options->aad.length = options->aad_random_size;
|
||||||
|
/* No size provided, use minimum size. */
|
||||||
|
} else
|
||||||
|
options->aad.length = cap->sym.auth.aad_size.min;
|
||||||
|
|
||||||
options->auth_xform.auth.add_auth_data_length =
|
options->auth_xform.auth.add_auth_data_length =
|
||||||
cap->sym.auth.aad_size.min;
|
options->aad.length;
|
||||||
options->auth_xform.auth.digest_length =
|
|
||||||
cap->sym.auth.digest_size.min;
|
/*
|
||||||
|
* Check if length of provided auth key is supported
|
||||||
|
* by the algorithm chosen.
|
||||||
|
*/
|
||||||
|
if (options->akey_param) {
|
||||||
|
if (check_supported_size(
|
||||||
|
options->auth_xform.auth.key.length,
|
||||||
|
cap->sym.auth.key_size.min,
|
||||||
|
cap->sym.auth.key_size.max,
|
||||||
|
cap->sym.auth.key_size.increment)
|
||||||
|
!= 0) {
|
||||||
|
printf("Unsupported auth key length\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Check if length of the auth key to be randomly generated
|
||||||
|
* is supported by the algorithm chosen.
|
||||||
|
*/
|
||||||
|
} else if (options->akey_random_size != -1) {
|
||||||
|
if (check_supported_size(options->akey_random_size,
|
||||||
|
cap->sym.auth.key_size.min,
|
||||||
|
cap->sym.auth.key_size.max,
|
||||||
|
cap->sym.auth.key_size.increment)
|
||||||
|
!= 0) {
|
||||||
|
printf("Unsupported auth key length\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
options->auth_xform.auth.key.length =
|
||||||
|
options->akey_random_size;
|
||||||
|
/* No size provided, use minimum size. */
|
||||||
|
} else
|
||||||
options->auth_xform.auth.key.length =
|
options->auth_xform.auth.key.length =
|
||||||
cap->sym.auth.key_size.min;
|
cap->sym.auth.key_size.min;
|
||||||
|
|
||||||
@ -1431,6 +1651,23 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
|
|||||||
generate_random_key(
|
generate_random_key(
|
||||||
options->auth_xform.auth.key.data,
|
options->auth_xform.auth.key.data,
|
||||||
options->auth_xform.auth.key.length);
|
options->auth_xform.auth.key.length);
|
||||||
|
|
||||||
|
/* Check if digest size is supported by the algorithm. */
|
||||||
|
if (options->digest_size != -1) {
|
||||||
|
if (check_supported_size(options->digest_size,
|
||||||
|
cap->sym.auth.digest_size.min,
|
||||||
|
cap->sym.auth.digest_size.max,
|
||||||
|
cap->sym.auth.digest_size.increment)
|
||||||
|
!= 0) {
|
||||||
|
printf("Unsupported digest length\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
options->auth_xform.auth.digest_length =
|
||||||
|
options->digest_size;
|
||||||
|
/* No size provided, use minimum size. */
|
||||||
|
} else
|
||||||
|
options->auth_xform.auth.digest_length =
|
||||||
|
cap->sym.auth.digest_size.min;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = rte_cryptodev_configure(cdev_id, &conf);
|
retval = rte_cryptodev_configure(cdev_id, &conf);
|
||||||
|
Loading…
Reference in New Issue
Block a user