Except for few minor comments below, the patch looks good to me.
Acked-by: Gowrishankar Muthukrishnan <[email protected]>
> Add a Wycheproof JSON vector validation example for cryptodev PMDs.
>
<CUT>
> +static int
> +app_init(void)
> +{
> + struct rte_cryptodev_config config = { rte_socket_id(), 1, 0 };
> + struct rte_cryptodev_qp_conf queue_pair = { 128, NULL };
Could this be through a macro ? and have a check for max_nb_queue_pairs from
dev info.
> + uint32_t session_size;
> + int ret;
> +
> + ret = rte_cryptodev_configure(env.dev_id, &config);
> + if (ret < 0)
> + return ret;
> +
> + env.mbuf_pool =
> rte_pktmbuf_pool_create("WYCHEPROOF_MBUF_POOL", 64, 0, 0,
> + env.mbuf_data_room, rte_socket_id());
> + if (env.mbuf_pool == NULL) {
> + ret = -rte_errno;
> + goto error;
> + }
> +
<CUT>
> +
> +static int
> +run_aead(const struct wycheproof_data *vector, enum
> rte_crypto_aead_algorithm algorithm,
> + enum rte_crypto_aead_operation operation, uint8_t **output,
> uint8_t **digest,
> + enum rte_crypto_op_status *status)
> +{
> + struct rte_crypto_sym_xform xform = { 0 };
> + struct rte_cryptodev_sym_session *session = NULL;
> + struct rte_crypto_op *operation_op = NULL;
> + struct rte_mbuf *mbuf = NULL;
> + struct rte_crypto_op *completed = NULL;
> + struct rte_crypto_sym_op *sym_op;
> + uint8_t *aad = NULL;
> + uint8_t *input;
> + uint32_t input_len;
> + int ret = -ENOMEM;
> +
> + *output = NULL;
> + *digest = NULL;
> + xform.type = RTE_CRYPTO_SYM_XFORM_AEAD;
> + xform.aead.algo = algorithm;
> + xform.aead.op = operation;
> + xform.aead.key.data = vector->key;
> + xform.aead.key.length = vector->key_len;
> + xform.aead.iv.offset = IV_OFFSET;
> + xform.aead.iv.length = vector->iv_len;
> + xform.aead.aad_length = vector->aad_len;
> + xform.aead.digest_length = vector->tag_len;
> +
> + session = rte_cryptodev_sym_session_create(env.dev_id, &xform,
> env.session_pool);
> + if (session == NULL)
> + goto out;
> +
> + operation_op = rte_crypto_op_alloc(env.op_pool,
> RTE_CRYPTO_OP_TYPE_SYMMETRIC);
> + if (operation_op == NULL)
> + goto out;
> +
> + mbuf = rte_pktmbuf_alloc(env.mbuf_pool);
> + if (mbuf == NULL)
> + goto out;
> + input = operation == RTE_CRYPTO_AEAD_OP_ENCRYPT ? vector->msg
> : vector->ct;
> + input_len = operation == RTE_CRYPTO_AEAD_OP_ENCRYPT ? vector-
> >msg_len : vector->ct_len;
> + if (input_len > rte_pktmbuf_tailroom(mbuf)) {
> + ret = -EMSGSIZE;
> + goto out;
> + }
> + if (input_len != 0)
> + memcpy(rte_pktmbuf_append(mbuf, input_len), input,
> input_len);
> +
> + *digest = rte_malloc(NULL, vector->tag_len, RTE_CACHE_LINE_SIZE);
> + if (*digest == NULL && vector->tag_len != 0)
> + goto out;
> + if (operation == RTE_CRYPTO_AEAD_OP_DECRYPT && vector->tag_len
> != 0)
> + memcpy(*digest, vector->tag, vector->tag_len);
> +
> + sym_op = operation_op->sym;
> + sym_op->m_src = mbuf;
> + sym_op->aead.data.offset = 0;
> + sym_op->aead.data.length = input_len;
> + if (algorithm == RTE_CRYPTO_AEAD_AES_CCM) {
> + aad = rte_zmalloc(NULL, RTE_ALIGN_CEIL(vector->aad_len +
> 18, 16), 0);
> + if (aad == NULL)
> + goto out;
> + if (vector->aad_len != 0)
> + memcpy(aad + 18, vector->aad, vector->aad_len);
Can 18 be set through a macro ?
> + sym_op->aead.aad.data = aad;
> + sym_op->aead.aad.phys_addr = rte_malloc_virt2iova(aad);
> + memcpy(rte_crypto_op_ctod_offset(operation_op, uint8_t *,
> IV_OFFSET) + 1,
> + vector->iv, vector->iv_len);
> + } else {
> + sym_op->aead.aad.data = vector->aad;
> + sym_op->aead.aad.phys_addr = rte_malloc_virt2iova(vector-
> >aad);
> + memcpy(rte_crypto_op_ctod_offset(operation_op, uint8_t *,
> IV_OFFSET), vector->iv,
> + vector->iv_len);
> + }
<CUT>
> +
> +static int
> +process_file(const char *path, struct app_stats *stats)
> +{
> + json_error_t error;
> + json_t *root;
> + const char *algorithm;
> + const char *schema;
> + int ret;
> +
> + root = json_load_file(path, 0, &error);
> + if (root == NULL) {
> + if (env.debug)
> + printf("SKIP %s: JSON error at line %d: %s\n", path,
> error.line,
> + error.text);
> + return 0;
> + }
> + algorithm = json_string_value(json_object_get(root, "algorithm"));
Can error check here help avoid below repeated error check for algorithm and
schema ?
If !(json_is_string(json_object_get(root, "schema"))
Return ..
..
> + schema = json_string_value(json_object_get(root, "schema"));
> + if (algorithm != NULL && schema != NULL && strcmp(algorithm, "AES-
> GCM") == 0 &&
> + strcmp(schema, "aead_test_schema_v1.json") == 0) {
> + printf("Processing AES-GCM vectors: %s\n", path);
> + ret = process_aead(root, RTE_CRYPTO_AEAD_AES_GCM,
> "AES-GCM", stats);
> + } else if (algorithm != NULL && schema != NULL && strcmp(algorithm,
> "AES-CCM") == 0 &&
> + strcmp(schema, "aead_test_schema_v1.json") == 0) {
> + printf("Processing AES-CCM vectors: %s\n", path);
> + ret = process_aead(root, RTE_CRYPTO_AEAD_AES_CCM,
> "AES-CCM", stats);
<CUT>
> + } else if (algorithm != NULL && schema != NULL && strcmp(algorithm,
> "ECDSA") == 0 &&
> + strcmp(schema,
> "ecdsa_p1363_verify_schema_v1.json") == 0) {
> + printf("Processing ECDSA (P1363) vectors: %s\n", path);
> + ret = process_ecdsa_p1363(root, "ECDSA", stats);
> + } else if (algorithm != NULL &&
> + (strncmp(algorithm, "AES-", strlen("AES-")) == 0 ||
> + strncmp(algorithm, "SEED-", strlen("SEED-")) == 0 ||
> + strcmp(algorithm, "SM4-CCM") == 0 ||
> + strncmp(algorithm, "HMAC", strlen("HMAC")) == 0 ||
> + strncmp(algorithm, "RSA", strlen("RSA")) == 0 ||
> + strcmp(algorithm, "DSA") == 0 ||
> + strcmp(algorithm, "ECDH") == 0 ||
> + strcmp(algorithm, "ECDSA") == 0)) {
> + debug_file("SKIP", path, algorithm);
> + stats->skipped_unsupported++;
> + ret = 0;
> + } else {
> + debug_file("SKIP", path, "unsupported vector file");
> + stats->skipped_unsupported++;
> + ret = 0;
> + }
> + json_decref(root);
> + return ret;
> +}
> +
Regards,
Gowrishankar