X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fl2fwd-crypto%2Fmain.c;h=759953e0fb99484dd1ef19a624690a853d496f52;hb=2661f4fbe93dd44ddb6c4e746402454a03d99b79;hp=779b4fb5cbe84668e8253ed7b2302af60cb3e24c;hpb=4eb45d2d4a99209bc7a67994a171187095af005d;p=dpdk.git diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c index 779b4fb5cb..759953e0fb 100644 --- a/examples/l2fwd-crypto/main.c +++ b/examples/l2fwd-crypto/main.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2015-2016 Intel Corporation. All rights reserved. + * Copyright(c) 2015-2017 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,6 +89,10 @@ enum cdev_type { #define MAX_PKT_BURST 32 #define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ +#define MAXIMUM_IV_LENGTH 16 +#define IV_OFFSET (sizeof(struct rte_crypto_op) + \ + sizeof(struct rte_crypto_sym_op)) + /* * Configurable number of RX/TX ring descriptors */ @@ -126,7 +130,8 @@ enum l2fwd_crypto_xform_chain { L2FWD_CRYPTO_CIPHER_HASH, L2FWD_CRYPTO_HASH_CIPHER, L2FWD_CRYPTO_CIPHER_ONLY, - L2FWD_CRYPTO_HASH_ONLY + L2FWD_CRYPTO_HASH_ONLY, + L2FWD_CRYPTO_AEAD }; struct l2fwd_key { @@ -135,6 +140,11 @@ struct l2fwd_key { phys_addr_t phys_addr; }; +struct l2fwd_iv { + uint8_t *data; + uint16_t length; +}; + /** l2fwd crypto application command line options */ struct l2fwd_crypto_options { unsigned portmask; @@ -151,14 +161,26 @@ struct l2fwd_crypto_options { unsigned ckey_param; int ckey_random_size; - struct l2fwd_key iv; - unsigned iv_param; - int iv_random_size; + struct l2fwd_iv cipher_iv; + unsigned int cipher_iv_param; + int cipher_iv_random_size; struct rte_crypto_sym_xform auth_xform; uint8_t akey_param; int akey_random_size; + struct l2fwd_iv auth_iv; + unsigned int auth_iv_param; + int auth_iv_random_size; + + struct rte_crypto_sym_xform aead_xform; + unsigned int aead_key_param; + int aead_key_random_size; + + struct l2fwd_iv aead_iv; + unsigned int aead_iv_param; + int aead_iv_random_size; + struct l2fwd_key aad; unsigned aad_param; int aad_random_size; @@ -179,16 +201,20 @@ struct l2fwd_crypto_params { unsigned digest_length; unsigned block_size; - struct l2fwd_key iv; + struct l2fwd_iv cipher_iv; + struct l2fwd_iv auth_iv; + struct l2fwd_iv aead_iv; struct l2fwd_key aad; struct rte_cryptodev_sym_session *session; uint8_t do_cipher; uint8_t do_hash; + uint8_t do_aead; uint8_t hash_verify; enum rte_crypto_cipher_algorithm cipher_algo; enum rte_crypto_auth_algorithm auth_algo; + enum rte_crypto_aead_algorithm aead_algo; }; /** lcore configuration */ @@ -444,6 +470,18 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, rte_crypto_op_attach_sym_session(op, cparams->session); if (cparams->do_hash) { + if (cparams->auth_iv.length) { + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, + uint8_t *, + IV_OFFSET + + cparams->cipher_iv.length); + /* + * Copy IV at the end of the crypto operation, + * after the cipher IV, if added + */ + rte_memcpy(iv_ptr, cparams->auth_iv.data, + cparams->auth_iv.length); + } if (!cparams->hash_verify) { /* Append space for digest to end of packet */ op->sym->auth.digest.data = (uint8_t *)rte_pktmbuf_append(m, @@ -455,7 +493,6 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, rte_pktmbuf_pkt_len(m) - cparams->digest_length); - op->sym->auth.digest.length = cparams->digest_length; /* For wireless algorithms, offset/length must be in bits */ if (cparams->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 || @@ -467,22 +504,14 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, op->sym->auth.data.offset = ipdata_offset; op->sym->auth.data.length = data_len; } - - if (cparams->aad.length) { - op->sym->auth.aad.data = cparams->aad.data; - op->sym->auth.aad.phys_addr = cparams->aad.phys_addr; - op->sym->auth.aad.length = cparams->aad.length; - } else { - op->sym->auth.aad.data = NULL; - op->sym->auth.aad.phys_addr = 0; - op->sym->auth.aad.length = 0; - } } if (cparams->do_cipher) { - op->sym->cipher.iv.data = cparams->iv.data; - op->sym->cipher.iv.phys_addr = cparams->iv.phys_addr; - op->sym->cipher.iv.length = cparams->iv.length; + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, + IV_OFFSET); + /* Copy IV at the end of the crypto operation */ + rte_memcpy(iv_ptr, cparams->cipher_iv.data, + cparams->cipher_iv.length); /* For wireless algorithms, offset/length must be in bits */ if (cparams->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2 || @@ -496,6 +525,33 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m, } } + if (cparams->do_aead) { + uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, + IV_OFFSET); + /* Copy IV at the end of the crypto operation */ + rte_memcpy(iv_ptr, cparams->aead_iv.data, cparams->aead_iv.length); + + op->sym->aead.data.offset = ipdata_offset; + op->sym->aead.data.length = data_len; + + if (!cparams->hash_verify) { + /* Append space for digest to end of packet */ + op->sym->aead.digest.data = (uint8_t *)rte_pktmbuf_append(m, + cparams->digest_length); + } else { + op->sym->aead.digest.data = rte_pktmbuf_mtod(m, + uint8_t *) + ipdata_offset + data_len; + } + + op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, + rte_pktmbuf_pkt_len(m) - cparams->digest_length); + + if (cparams->aad.length) { + op->sym->aead.aad.data = cparams->aad.data; + op->sym->aead.aad.phys_addr = cparams->aad.phys_addr; + } + } + op->sym->m_src = m; return l2fwd_crypto_enqueue(op, cparams); @@ -592,7 +648,9 @@ initialize_crypto_session(struct l2fwd_crypto_options *options, { struct rte_crypto_sym_xform *first_xform; - if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH) { + if (options->xform_chain == L2FWD_CRYPTO_AEAD) { + first_xform = &options->aead_xform; + } else if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH) { first_xform = &options->cipher_xform; first_xform->next = &options->auth_xform; } else if (options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER) { @@ -644,8 +702,12 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) for (i = 0; i < qconf->nb_crypto_devs; i++) { port_cparams[i].do_cipher = 0; port_cparams[i].do_hash = 0; + port_cparams[i].do_aead = 0; switch (options->xform_chain) { + case L2FWD_CRYPTO_AEAD: + port_cparams[i].do_aead = 1; + break; case L2FWD_CRYPTO_CIPHER_HASH: case L2FWD_CRYPTO_HASH_CIPHER: port_cparams[i].do_cipher = 1; @@ -665,13 +727,34 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) port_cparams[i].block_size = options->block_size; if (port_cparams[i].do_hash) { + port_cparams[i].auth_iv.data = options->auth_iv.data; + port_cparams[i].auth_iv.length = options->auth_iv.length; + if (!options->auth_iv_param) + generate_random_key(port_cparams[i].auth_iv.data, + port_cparams[i].auth_iv.length); + if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) + port_cparams[i].hash_verify = 1; + else + port_cparams[i].hash_verify = 0; + + port_cparams[i].auth_algo = options->auth_xform.auth.algo; + /* Set IV parameters */ + if (options->auth_iv.length) { + options->auth_xform.auth.iv.offset = + IV_OFFSET + options->cipher_iv.length; + options->auth_xform.auth.iv.length = + options->auth_iv.length; + } + } + + if (port_cparams[i].do_aead) { + port_cparams[i].aead_algo = options->aead_xform.aead.algo; port_cparams[i].digest_length = - options->auth_xform.auth.digest_length; - if (options->auth_xform.auth.add_auth_data_length) { + options->aead_xform.aead.digest_length; + if (options->aead_xform.aead.add_auth_data_length) { port_cparams[i].aad.data = options->aad.data; - port_cparams[i].aad.length = - options->auth_xform.auth.add_auth_data_length; port_cparams[i].aad.phys_addr = options->aad.phys_addr; + port_cparams[i].aad.length = options->aad.length; if (!options->aad_param) generate_random_key(port_cparams[i].aad.data, port_cparams[i].aad.length); @@ -679,23 +762,28 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) } else port_cparams[i].aad.length = 0; - if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) + if (options->aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_DECRYPT) port_cparams[i].hash_verify = 1; else port_cparams[i].hash_verify = 0; - port_cparams[i].auth_algo = options->auth_xform.auth.algo; + /* Set IV parameters */ + options->aead_xform.aead.iv.offset = IV_OFFSET; + options->aead_xform.aead.iv.length = options->aead_iv.length; } if (port_cparams[i].do_cipher) { - port_cparams[i].iv.data = options->iv.data; - port_cparams[i].iv.length = options->iv.length; - port_cparams[i].iv.phys_addr = options->iv.phys_addr; - if (!options->iv_param) - generate_random_key(port_cparams[i].iv.data, - port_cparams[i].iv.length); + port_cparams[i].cipher_iv.data = options->cipher_iv.data; + port_cparams[i].cipher_iv.length = options->cipher_iv.length; + if (!options->cipher_iv_param) + generate_random_key(port_cparams[i].cipher_iv.data, + port_cparams[i].cipher_iv.length); port_cparams[i].cipher_algo = options->cipher_xform.cipher.algo; + /* Set IV parameters */ + options->cipher_xform.cipher.iv.offset = IV_OFFSET; + options->cipher_xform.cipher.iv.length = + options->cipher_iv.length; } port_cparams[i].session = initialize_crypto_session(options, @@ -843,21 +931,31 @@ l2fwd_crypto_usage(const char *prgname) " --cdev_type HW / SW / ANY\n" " --chain HASH_CIPHER / CIPHER_HASH / CIPHER_ONLY /" - " HASH_ONLY\n" + " HASH_ONLY / AEAD\n" " --cipher_algo ALGO\n" " --cipher_op ENCRYPT / DECRYPT\n" " --cipher_key KEY (bytes separated with \":\")\n" " --cipher_key_random_size SIZE: size of cipher key when generated randomly\n" - " --iv IV (bytes separated with \":\")\n" - " --iv_random_size SIZE: size of IV when generated randomly\n" + " --cipher_iv IV (bytes separated with \":\")\n" + " --cipher_iv_random_size SIZE: size of cipher IV when generated randomly\n" " --auth_algo ALGO\n" " --auth_op GENERATE / VERIFY\n" " --auth_key KEY (bytes separated with \":\")\n" " --auth_key_random_size SIZE: size of auth key when generated randomly\n" + " --auth_iv IV (bytes separated with \":\")\n" + " --auth_iv_random_size SIZE: size of auth IV when generated randomly\n" + + " --aead_algo ALGO\n" + " --aead_op ENCRYPT / DECRYPT\n" + " --aead_key KEY (bytes separated with \":\")\n" + " --aead_key_random_size SIZE: size of AEAD key when generated randomly\n" + " --aead_iv IV (bytes separated with \":\")\n" + " --aead_iv_random_size SIZE: size of AEAD IV when generated randomly\n" " --aad AAD (bytes separated with \":\")\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" @@ -899,6 +997,9 @@ parse_crypto_opt_chain(struct l2fwd_crypto_options *options, char *optarg) } else if (strcmp("HASH_ONLY", optarg) == 0) { options->xform_chain = L2FWD_CRYPTO_HASH_ONLY; return 0; + } else if (strcmp("AEAD", optarg) == 0) { + options->xform_chain = L2FWD_CRYPTO_AEAD; + return 0; } return -1; @@ -1005,6 +1106,32 @@ parse_auth_op(enum rte_crypto_auth_operation *op, char *optarg) return -1; } +static int +parse_aead_algo(enum rte_crypto_aead_algorithm *algo, char *optarg) +{ + if (rte_cryptodev_get_aead_algo_enum(algo, optarg) < 0) { + RTE_LOG(ERR, USER1, "AEAD algorithm specified " + "not supported!\n"); + return -1; + } + + return 0; +} + +static int +parse_aead_op(enum rte_crypto_aead_operation *op, char *optarg) +{ + if (strcmp("ENCRYPT", optarg) == 0) { + *op = RTE_CRYPTO_AEAD_OP_ENCRYPT; + return 0; + } else if (strcmp("DECRYPT", optarg) == 0) { + *op = RTE_CRYPTO_AEAD_OP_DECRYPT; + return 0; + } + + printf("AEAD operation specified not supported!\n"); + return -1; +} static int parse_cryptodev_mask(struct l2fwd_crypto_options *options, const char *q_arg) @@ -1066,18 +1193,18 @@ l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options, 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) { - options->iv_param = 1; - options->iv.length = - parse_key(options->iv.data, optarg); - if (options->iv.length > 0) + else if (strcmp(lgopts[option_index].name, "cipher_iv") == 0) { + options->cipher_iv_param = 1; + options->cipher_iv.length = + parse_key(options->cipher_iv.data, optarg); + if (options->cipher_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); + else if (strcmp(lgopts[option_index].name, "cipher_iv_random_size") == 0) + return parse_size(&options->cipher_iv_random_size, optarg); /* Authentication options */ else if (strcmp(lgopts[option_index].name, "auth_algo") == 0) { @@ -1103,6 +1230,56 @@ l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options, return parse_size(&options->akey_random_size, optarg); } + else if (strcmp(lgopts[option_index].name, "auth_iv") == 0) { + options->auth_iv_param = 1; + options->auth_iv.length = + parse_key(options->auth_iv.data, optarg); + if (options->auth_iv.length > 0) + return 0; + else + return -1; + } + + else if (strcmp(lgopts[option_index].name, "auth_iv_random_size") == 0) + return parse_size(&options->auth_iv_random_size, optarg); + + /* AEAD options */ + else if (strcmp(lgopts[option_index].name, "aead_algo") == 0) { + return parse_aead_algo(&options->aead_xform.aead.algo, + optarg); + } + + else if (strcmp(lgopts[option_index].name, "aead_op") == 0) + return parse_aead_op(&options->aead_xform.aead.op, + optarg); + + else if (strcmp(lgopts[option_index].name, "aead_key") == 0) { + options->aead_key_param = 1; + options->aead_xform.aead.key.length = + parse_key(options->aead_xform.aead.key.data, optarg); + if (options->aead_xform.aead.key.length > 0) + return 0; + else + return -1; + } + + else if (strcmp(lgopts[option_index].name, "aead_key_random_size") == 0) + return parse_size(&options->aead_key_random_size, optarg); + + + else if (strcmp(lgopts[option_index].name, "aead_iv") == 0) { + options->aead_iv_param = 1; + options->aead_iv.length = + parse_key(options->aead_iv.data, optarg); + if (options->aead_iv.length > 0) + return 0; + else + return -1; + } + + else if (strcmp(lgopts[option_index].name, "aead_iv_random_size") == 0) + return parse_size(&options->aead_iv_random_size, optarg); + else if (strcmp(lgopts[option_index].name, "aad") == 0) { options->aad_param = 1; options->aad.length = @@ -1221,9 +1398,9 @@ l2fwd_crypto_default_options(struct l2fwd_crypto_options *options) options->ckey_param = 0; options->ckey_random_size = -1; options->cipher_xform.cipher.key.length = 0; - options->iv_param = 0; - options->iv_random_size = -1; - options->iv.length = 0; + options->cipher_iv_param = 0; + options->cipher_iv_random_size = -1; + options->cipher_iv.length = 0; options->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; options->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; @@ -1234,13 +1411,28 @@ l2fwd_crypto_default_options(struct l2fwd_crypto_options *options) options->akey_param = 0; options->akey_random_size = -1; options->auth_xform.auth.key.length = 0; + options->auth_iv_param = 0; + options->auth_iv_random_size = -1; + options->auth_iv.length = 0; + + options->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; + options->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + + /* AEAD Data */ + options->aead_xform.type = RTE_CRYPTO_SYM_XFORM_AEAD; + options->aead_xform.next = NULL; + options->aead_key_param = 0; + options->aead_key_random_size = -1; + options->aead_xform.aead.key.length = 0; + options->aead_iv_param = 0; + options->aead_iv_random_size = -1; + options->aead_iv.length = 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.op = RTE_CRYPTO_AUTH_OP_GENERATE; + options->digest_size = -1; options->type = CDEV_TYPE_ANY; options->cryptodev_mask = UINT64_MAX; @@ -1255,7 +1447,7 @@ display_cipher_info(struct l2fwd_crypto_options *options) rte_hexdump(stdout, "Cipher key:", options->cipher_xform.cipher.key.data, options->cipher_xform.cipher.key.length); - rte_hexdump(stdout, "IV:", options->iv.data, options->iv.length); + rte_hexdump(stdout, "IV:", options->cipher_iv.data, options->cipher_iv.length); } static void @@ -1267,6 +1459,19 @@ display_auth_info(struct l2fwd_crypto_options *options) rte_hexdump(stdout, "Auth key:", options->auth_xform.auth.key.data, options->auth_xform.auth.key.length); + rte_hexdump(stdout, "IV:", options->auth_iv.data, options->auth_iv.length); +} + +static void +display_aead_info(struct l2fwd_crypto_options *options) +{ + printf("\n---- AEAD information ---\n"); + printf("Algorithm: %s\n", + rte_crypto_aead_algorithm_strings[options->aead_xform.aead.algo]); + rte_hexdump(stdout, "AEAD key:", + options->aead_xform.aead.key.data, + options->aead_xform.aead.key.length); + rte_hexdump(stdout, "IV:", options->aead_iv.data, options->aead_iv.length); rte_hexdump(stdout, "AAD:", options->aad.data, options->aad.length); } @@ -1275,6 +1480,7 @@ l2fwd_crypto_options_print(struct l2fwd_crypto_options *options) { char string_cipher_op[MAX_STR_LEN]; char string_auth_op[MAX_STR_LEN]; + char string_aead_op[MAX_STR_LEN]; if (options->cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) strcpy(string_cipher_op, "Encrypt"); @@ -1286,6 +1492,12 @@ l2fwd_crypto_options_print(struct l2fwd_crypto_options *options) else strcpy(string_auth_op, "Auth verify"); + if (options->aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT) + strcpy(string_aead_op, "Authenticated encryption"); + else + strcpy(string_aead_op, "Authenticated decryption"); + + printf("Options:-\nn"); printf("portmask: %x\n", options->portmask); printf("ports per lcore: %u\n", options->nb_ports_per_lcore); @@ -1304,14 +1516,21 @@ l2fwd_crypto_options_print(struct l2fwd_crypto_options *options) if (options->akey_param && (options->akey_random_size != -1)) printf("Auth key already parsed, ignoring size of random key\n"); - if (options->iv_param && (options->iv_random_size != -1)) - printf("IV already parsed, ignoring size of random IV\n"); + if (options->cipher_iv_param && (options->cipher_iv_random_size != -1)) + printf("Cipher IV already parsed, ignoring size of random IV\n"); + + if (options->auth_iv_param && (options->auth_iv_random_size != -1)) + printf("Auth IV already parsed, ignoring size of random IV\n"); if (options->aad_param && (options->aad_random_size != -1)) printf("AAD already parsed, ignoring size of random AAD\n"); printf("\nCrypto chain: "); switch (options->xform_chain) { + case L2FWD_CRYPTO_AEAD: + printf("Input --> %s --> Output\n", string_aead_op); + display_aead_info(options); + break; case L2FWD_CRYPTO_CIPHER_HASH: printf("Input --> %s --> %s --> Output\n", string_cipher_op, string_auth_op); @@ -1353,16 +1572,26 @@ l2fwd_crypto_parse_args(struct l2fwd_crypto_options *options, { "cipher_op", required_argument, 0, 0 }, { "cipher_key", required_argument, 0, 0 }, { "cipher_key_random_size", required_argument, 0, 0 }, + { "cipher_iv", required_argument, 0, 0 }, + { "cipher_iv_random_size", required_argument, 0, 0 }, { "auth_algo", required_argument, 0, 0 }, { "auth_op", required_argument, 0, 0 }, { "auth_key", required_argument, 0, 0 }, { "auth_key_random_size", required_argument, 0, 0 }, + { "auth_iv", required_argument, 0, 0 }, + { "auth_iv_random_size", required_argument, 0, 0 }, + + { "aead_algo", required_argument, 0, 0 }, + { "aead_op", required_argument, 0, 0 }, + { "aead_key", required_argument, 0, 0 }, + { "aead_key_random_size", required_argument, 0, 0 }, + { "aead_iv", required_argument, 0, 0 }, + { "aead_iv_random_size", required_argument, 0, 0 }, - { "iv", required_argument, 0, 0 }, - { "iv_random_size", 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 }, @@ -1493,7 +1722,8 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) /* Check if device has to be HW/SW or any */ static int -check_type(struct l2fwd_crypto_options *options, struct rte_cryptodev_info *dev_info) +check_type(const struct l2fwd_crypto_options *options, + const struct rte_cryptodev_info *dev_info) { if (options->type == CDEV_TYPE_HW && (dev_info->feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)) @@ -1507,6 +1737,108 @@ check_type(struct l2fwd_crypto_options *options, struct rte_cryptodev_info *dev_ return -1; } +static const struct rte_cryptodev_capabilities * +check_device_support_cipher_algo(const struct l2fwd_crypto_options *options, + const struct rte_cryptodev_info *dev_info, + uint8_t cdev_id) +{ + unsigned int i = 0; + const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; + enum rte_crypto_cipher_algorithm cap_cipher_algo; + enum rte_crypto_cipher_algorithm opt_cipher_algo = + options->cipher_xform.cipher.algo; + + 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) { + if (cap_cipher_algo == opt_cipher_algo) { + if (check_type(options, dev_info) == 0) + break; + } + } + cap = &dev_info->capabilities[++i]; + } + + if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { + printf("Algorithm %s not supported by cryptodev %u" + " or device not of preferred type (%s)\n", + rte_crypto_cipher_algorithm_strings[opt_cipher_algo], + cdev_id, + options->string_type); + return NULL; + } + + return cap; +} + +static const struct rte_cryptodev_capabilities * +check_device_support_auth_algo(const struct l2fwd_crypto_options *options, + const struct rte_cryptodev_info *dev_info, + uint8_t cdev_id) +{ + unsigned int i = 0; + const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; + enum rte_crypto_auth_algorithm cap_auth_algo; + enum rte_crypto_auth_algorithm opt_auth_algo = + options->auth_xform.auth.algo; + + while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { + cap_auth_algo = cap->sym.auth.algo; + if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AUTH) { + if (cap_auth_algo == opt_auth_algo) { + if (check_type(options, dev_info) == 0) + break; + } + } + cap = &dev_info->capabilities[++i]; + } + + if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { + printf("Algorithm %s not supported by cryptodev %u" + " or device not of preferred type (%s)\n", + rte_crypto_auth_algorithm_strings[opt_auth_algo], + cdev_id, + options->string_type); + return NULL; + } + + return cap; +} + +static const struct rte_cryptodev_capabilities * +check_device_support_aead_algo(const struct l2fwd_crypto_options *options, + const struct rte_cryptodev_info *dev_info, + uint8_t cdev_id) +{ + unsigned int i = 0; + const struct rte_cryptodev_capabilities *cap = &dev_info->capabilities[0]; + enum rte_crypto_aead_algorithm cap_aead_algo; + enum rte_crypto_aead_algorithm opt_aead_algo = + options->aead_xform.aead.algo; + + while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { + cap_aead_algo = cap->sym.aead.algo; + if (cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AEAD) { + if (cap_aead_algo == opt_aead_algo) { + if (check_type(options, dev_info) == 0) + break; + } + } + cap = &dev_info->capabilities[++i]; + } + + if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { + printf("Algorithm %s not supported by cryptodev %u" + " or device not of preferred type (%s)\n", + rte_crypto_aead_algorithm_strings[opt_aead_algo], + cdev_id, + options->string_type); + return NULL; + } + + return cap; +} + /* Check if the device is enabled by cryptodev_mask */ static int check_cryptodev_mask(struct l2fwd_crypto_options *options, @@ -1540,16 +1872,52 @@ check_supported_size(uint16_t length, uint16_t min, uint16_t max, return -1; } + +static int +check_iv_param(const struct rte_crypto_param_range *iv_range_size, + unsigned int iv_param, int iv_random_size, + uint16_t *iv_length) +{ + /* + * Check if length of provided IV is supported + * by the algorithm chosen. + */ + if (iv_param) { + if (check_supported_size(*iv_length, + iv_range_size->min, + iv_range_size->max, + iv_range_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 (iv_random_size != -1) { + if (check_supported_size(iv_random_size, + iv_range_size->min, + iv_range_size->max, + iv_range_size->increment) + != 0) { + printf("Unsupported IV length\n"); + return -1; + } + *iv_length = iv_random_size; + /* No size provided, use minimum size. */ + } else + *iv_length = iv_range_size->min; + + return 0; +} + static int initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, uint8_t *enabled_cdevs) { - unsigned i, cdev_id, cdev_count, enabled_cdev_count = 0; + unsigned int cdev_id, cdev_count, enabled_cdev_count = 0; const struct rte_cryptodev_capabilities *cap; - enum rte_crypto_auth_algorithm cap_auth_algo; - enum rte_crypto_auth_algorithm opt_auth_algo; - enum rte_crypto_cipher_algorithm cap_cipher_algo; - enum rte_crypto_cipher_algorithm opt_cipher_algo; int retval; cdev_count = rte_cryptodev_count(); @@ -1577,66 +1945,128 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, rte_cryptodev_info_get(cdev_id, &dev_info); - /* Set cipher parameters */ - if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || - options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || - options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) { - /* Check if device supports cipher algo */ - i = 0; - opt_cipher_algo = options->cipher_xform.cipher.algo; - 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) { - if (cap_cipher_algo == opt_cipher_algo) { - if (check_type(options, &dev_info) == 0) - break; - } + /* Set AEAD parameters */ + if (options->xform_chain == L2FWD_CRYPTO_AEAD) { + /* Check if device supports AEAD algo */ + cap = check_device_support_aead_algo(options, &dev_info, + cdev_id); + if (cap == NULL) + continue; + + options->block_size = cap->sym.aead.block_size; + + check_iv_param(&cap->sym.aead.iv_size, + options->aead_iv_param, + options->aead_iv_random_size, + &options->aead_iv.length); + + /* + * Check if length of provided AEAD key is supported + * by the algorithm chosen. + */ + if (options->aead_key_param) { + if (check_supported_size( + options->aead_xform.aead.key.length, + cap->sym.aead.key_size.min, + cap->sym.aead.key_size.max, + cap->sym.aead.key_size.increment) + != 0) { + printf("Unsupported aead key length\n"); + return -1; } - cap = &dev_info.capabilities[++i]; - } + /* + * Check if length of the aead key to be randomly generated + * is supported by the algorithm chosen. + */ + } else if (options->aead_key_random_size != -1) { + if (check_supported_size(options->ckey_random_size, + cap->sym.aead.key_size.min, + cap->sym.aead.key_size.max, + cap->sym.aead.key_size.increment) + != 0) { + printf("Unsupported aead key length\n"); + return -1; + } + options->aead_xform.aead.key.length = + options->ckey_random_size; + /* No size provided, use minimum size. */ + } else + options->aead_xform.aead.key.length = + cap->sym.aead.key_size.min; - if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { - printf("Algorithm %s not supported by cryptodev %u" - " or device not of preferred type (%s)\n", - rte_crypto_cipher_algorithm_strings[opt_cipher_algo], - cdev_id, - options->string_type); - continue; - } + if (!options->aead_key_param) + generate_random_key( + options->aead_xform.aead.key.data, + options->aead_xform.aead.key.length); - options->block_size = cap->sym.cipher.block_size; /* - * Check if length of provided IV is supported + * Check if length of provided AAD 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) + if (options->aad_param) { + if (check_supported_size(options->aad.length, + cap->sym.aead.aad_size.min, + cap->sym.aead.aad_size.max, + cap->sym.aead.aad_size.increment) != 0) { - printf("Unsupported IV length\n"); + printf("Unsupported AAD length\n"); return -1; } /* - * Check if length of IV to be randomly generated + * Check if length of AAD 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) + } else if (options->aad_random_size != -1) { + if (check_supported_size(options->aad_random_size, + cap->sym.aead.aad_size.min, + cap->sym.aead.aad_size.max, + cap->sym.aead.aad_size.increment) != 0) { - printf("Unsupported IV length\n"); + printf("Unsupported AAD length\n"); return -1; } - options->iv.length = options->iv_random_size; + options->aad.length = options->aad_random_size; /* No size provided, use minimum size. */ } else - options->iv.length = cap->sym.cipher.iv_size.min; + options->aad.length = cap->sym.auth.aad_size.min; + + options->aead_xform.aead.add_auth_data_length = + options->aad.length; + + /* Check if digest size is supported by the algorithm. */ + if (options->digest_size != -1) { + if (check_supported_size(options->digest_size, + cap->sym.aead.digest_size.min, + cap->sym.aead.digest_size.max, + cap->sym.aead.digest_size.increment) + != 0) { + printf("Unsupported digest length\n"); + return -1; + } + options->aead_xform.aead.digest_length = + options->digest_size; + /* No size provided, use minimum size. */ + } else + options->aead_xform.aead.digest_length = + cap->sym.aead.digest_size.min; + } + + /* Set cipher parameters */ + if (options->xform_chain == L2FWD_CRYPTO_CIPHER_HASH || + options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || + options->xform_chain == L2FWD_CRYPTO_CIPHER_ONLY) { + /* Check if device supports cipher algo */ + cap = check_device_support_cipher_algo(options, &dev_info, + cdev_id); + if (cap == NULL) + continue; + + options->block_size = cap->sym.cipher.block_size; + + check_iv_param(&cap->sym.cipher.iv_size, + options->cipher_iv_param, + options->cipher_iv_random_size, + &options->cipher_iv.length); /* * Check if length of provided cipher key is supported @@ -1684,62 +2114,15 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, options->xform_chain == L2FWD_CRYPTO_HASH_CIPHER || options->xform_chain == L2FWD_CRYPTO_HASH_ONLY) { /* Check if device supports auth algo */ - i = 0; - opt_auth_algo = options->auth_xform.auth.algo; - cap = &dev_info.capabilities[i]; - while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { - cap_auth_algo = cap->sym.auth.algo; - if ((cap->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AUTH) && - (cap_auth_algo == opt_auth_algo) && - (check_type(options, &dev_info) == 0)) { - break; - } - cap = &dev_info.capabilities[++i]; - } - - if (cap->op == RTE_CRYPTO_OP_TYPE_UNDEFINED) { - printf("Algorithm %s not supported by cryptodev %u" - " or device not of preferred type (%s)\n", - rte_crypto_auth_algorithm_strings[opt_auth_algo], - cdev_id, - options->string_type); + cap = check_device_support_auth_algo(options, &dev_info, + cdev_id); + if (cap == NULL) continue; - } - - /* - * 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->aad.length; + check_iv_param(&cap->sym.auth.iv_size, + options->auth_iv_param, + options->auth_iv_random_size, + &options->auth_iv.length); /* * Check if length of provided auth key is supported * by the algorithm chosen. @@ -1941,16 +2324,27 @@ reserve_key_memory(struct l2fwd_crypto_options *options) if (options->cipher_xform.cipher.key.data == NULL) rte_exit(EXIT_FAILURE, "Failed to allocate memory for cipher key"); - options->auth_xform.auth.key.data = rte_malloc("auth key", MAX_KEY_SIZE, 0); if (options->auth_xform.auth.key.data == NULL) rte_exit(EXIT_FAILURE, "Failed to allocate memory for auth key"); - options->iv.data = rte_malloc("iv", MAX_KEY_SIZE, 0); - if (options->iv.data == NULL) - rte_exit(EXIT_FAILURE, "Failed to allocate memory for IV"); - options->iv.phys_addr = rte_malloc_virt2phy(options->iv.data); + options->aead_xform.aead.key.data = rte_malloc("aead key", + MAX_KEY_SIZE, 0); + if (options->aead_xform.aead.key.data == NULL) + rte_exit(EXIT_FAILURE, "Failed to allocate memory for AEAD key"); + + options->cipher_iv.data = rte_malloc("cipher iv", MAX_KEY_SIZE, 0); + if (options->cipher_iv.data == NULL) + rte_exit(EXIT_FAILURE, "Failed to allocate memory for cipher IV"); + + options->auth_iv.data = rte_malloc("auth iv", MAX_KEY_SIZE, 0); + if (options->auth_iv.data == NULL) + rte_exit(EXIT_FAILURE, "Failed to allocate memory for auth IV"); + + options->aead_iv.data = rte_malloc("aead_iv", MAX_KEY_SIZE, 0); + if (options->aead_iv.data == NULL) + rte_exit(EXIT_FAILURE, "Failed to allocate memory for AEAD iv"); options->aad.data = rte_malloc("aad", MAX_KEY_SIZE, 0); if (options->aad.data == NULL) @@ -1993,7 +2387,7 @@ main(int argc, char **argv) /* create crypto op pool */ l2fwd_crypto_op_pool = rte_crypto_op_pool_create("crypto_op_pool", - RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MBUF, 128, 0, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MBUF, 128, MAXIMUM_IV_LENGTH, rte_socket_id()); if (l2fwd_crypto_op_pool == NULL) rte_exit(EXIT_FAILURE, "Cannot create crypto op pool\n");