+ vec_validate_aligned (encrypted_data, computed_data_total_len - 1,
+ CLIB_CACHE_LINE_BYTES);
+ vec_validate_aligned (decrypted_data, computed_data_total_len - 1,
+ CLIB_CACHE_LINE_BYTES);
+ vec_validate_aligned (ops, n_ops - 1, CLIB_CACHE_LINE_BYTES);
+ computed_data_total_len = 0;
+
+ op = ops;
+ /* first stage: encrypt only */
+
+ vec_foreach_index (i, rv)
+ {
+ r = rv[i];
+ int t;
+ ad = vec_elt_at_index (cm->algs, r->alg);
+ for (t = 0; t < VNET_CRYPTO_OP_N_TYPES; t++)
+ {
+ vnet_crypto_op_id_t id = ad->op_by_type[t];
+
+ if (id == 0)
+ continue;
+
+ switch (t)
+ {
+ case VNET_CRYPTO_OP_TYPE_ENCRYPT:
+ vnet_crypto_op_init (op, id);
+ op->iv = tm->inc_data;
+ op->key_index = vnet_crypto_key_add (vm, r->alg,
+ tm->inc_data, r->key.length);
+ vec_add1 (key_indices, op->key_index);
+ op->len = r->plaintext_incremental;
+ op->src = tm->inc_data;
+ op->dst = encrypted_data + computed_data_total_len;
+ computed_data_total_len += r->plaintext_incremental;
+ op->user_data = i;
+ op++;
+ break;
+ case VNET_CRYPTO_OP_TYPE_AEAD_ENCRYPT:
+ vnet_crypto_op_init (op, id);
+ op->iv = tm->inc_data;
+ op->key_index = vnet_crypto_key_add (vm, r->alg,
+ tm->inc_data, r->key.length);
+ vec_add1 (key_indices, op->key_index);
+ op->aad = tm->inc_data;
+ op->aad_len = r->aad.length;
+ op->len = r->plaintext_incremental;
+ op->dst = encrypted_data + computed_data_total_len;
+ computed_data_total_len += r->plaintext_incremental;
+ op->src = tm->inc_data;
+ op->tag = encrypted_data + computed_data_total_len;
+ computed_data_total_len += r->tag.length;
+ op->tag_len = r->tag.length;
+ op->user_data = i;
+ op++;
+ break;
+ case VNET_CRYPTO_OP_TYPE_HMAC:
+ /* compute hmac in the next stage */
+ op->op = VNET_CRYPTO_OP_NONE;
+ computed_data_total_len += r->digest.length;
+ op->user_data = i;
+ op++;
+ break;
+ default:
+ break;
+ };
+ }
+ }
+
+ vnet_crypto_process_ops (vm, ops, n_ops);
+ computed_data_total_len = 0;
+
+ /* second stage: hash/decrypt previously encrypted data */
+ op = ops;
+
+ vec_foreach_index (i, rv)
+ {
+ r = rv[i];
+ int t;
+ ad = vec_elt_at_index (cm->algs, r->alg);
+ for (t = 0; t < VNET_CRYPTO_OP_N_TYPES; t++)
+ {
+ vnet_crypto_op_id_t id = ad->op_by_type[t];
+
+ if (id == 0)
+ continue;
+
+ switch (t)
+ {
+ case VNET_CRYPTO_OP_TYPE_DECRYPT:
+ vnet_crypto_op_init (op, id);
+ op->iv = tm->inc_data;
+ op->key_index = vnet_crypto_key_add (vm, r->alg,
+ tm->inc_data, r->key.length);
+ vec_add1 (key_indices, op->key_index);
+ op->len = r->plaintext_incremental;
+ op->src = encrypted_data + computed_data_total_len;
+ op->dst = decrypted_data + computed_data_total_len;
+ computed_data_total_len += r->plaintext_incremental;
+ op->user_data = i;
+ op++;
+ break;
+ case VNET_CRYPTO_OP_TYPE_AEAD_DECRYPT:
+ vnet_crypto_op_init (op, id);
+ op->iv = tm->inc_data;
+ op->key_index = vnet_crypto_key_add (vm, r->alg,
+ tm->inc_data, r->key.length);
+ vec_add1 (key_indices, op->key_index);
+ op->aad = tm->inc_data;
+ op->aad_len = r->aad.length;
+ op->len = r->plaintext_incremental;
+ op->dst = decrypted_data + computed_data_total_len;
+ op->src = encrypted_data + computed_data_total_len;
+ computed_data_total_len += r->plaintext_incremental;
+
+ op->tag = encrypted_data + computed_data_total_len;
+ computed_data_total_len += r->tag.length;
+ op->tag_len = r->tag.length;
+ op->user_data = i;
+ op++;
+ break;
+ case VNET_CRYPTO_OP_TYPE_HMAC:
+ vnet_crypto_op_init (op, id);
+ op->key_index = vnet_crypto_key_add (vm, r->alg,
+ tm->inc_data, r->key.length);
+ vec_add1 (key_indices, op->key_index);
+ op->src = tm->inc_data;
+ op->len = r->plaintext_incremental;
+ op->digest_len = r->digest.length;
+ op->digest = encrypted_data + computed_data_total_len;
+ computed_data_total_len += r->digest.length;
+ op->user_data = i;
+ op++;
+ break;
+ default:
+ break;
+ };
+
+ }
+ }
+
+ vnet_crypto_process_ops (vm, ops, n_ops);
+ print_results (vm, rv, ops, 0, n_ops, tm);
+
+ vec_foreach_index (i, key_indices) vnet_crypto_key_del (vm, key_indices[i]);
+ vec_free (tm->inc_data);
+ vec_free (ops);
+ vec_free (encrypted_data);
+ vec_free (decrypted_data);
+ vec_free (err);
+ vec_free (s);
+ return 0;
+}
+
+static clib_error_t *
+test_crypto_static (vlib_main_t * vm, crypto_test_main_t * tm,
+ unittest_crypto_test_registration_t ** rv, u32 n_ops,
+ u32 n_chained_ops, u32 computed_data_total_len)
+{
+ unittest_crypto_test_data_t *pt, *ct;
+ vnet_crypto_op_chunk_t *chunks = 0, ch;
+ unittest_crypto_test_registration_t *r;
+ vnet_crypto_op_t *ops = 0, *op, *chained_ops = 0;
+ vnet_crypto_op_t *current_chained_op = 0, *current_op = 0;
+ vnet_crypto_main_t *cm = &crypto_main;
+ vnet_crypto_alg_data_t *ad;
+ vnet_crypto_key_index_t *key_indices = 0;
+ u8 *computed_data = 0;
+ u32 i;
+