+ if (retval < 0)
+ return retval;
+
+ if (data_corrupted)
+ data_corruption(ut_params->op->sym->auth.aad.data);
+ else
+ tag_corruption(ut_params->op->sym->auth.aad.data,
+ reference->aad.len);
+
+ ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+ ut_params->op);
+ TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+ TEST_ASSERT_EQUAL(ut_params->op->status,
+ RTE_CRYPTO_OP_STATUS_AUTH_FAILED,
+ "authentication not failed");
+
+ ut_params->obuf = ut_params->op->sym->m_src;
+ TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+ return 0;
+}
+
+static int
+test_authenticated_decryption_fail_when_corruption(
+ struct crypto_testsuite_params *ts_params,
+ struct crypto_unittest_params *ut_params,
+ const struct test_crypto_vector *reference,
+ unsigned int data_corrupted)
+{
+ int retval;
+
+ uint8_t *ciphertext;
+
+ /* Create session */
+ retval = create_auth_cipher_session(ut_params,
+ ts_params->valid_devs[0],
+ reference,
+ RTE_CRYPTO_AUTH_OP_VERIFY,
+ RTE_CRYPTO_CIPHER_OP_DECRYPT);
+ if (retval < 0)
+ return retval;
+
+ ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+ TEST_ASSERT_NOT_NULL(ut_params->ibuf,
+ "Failed to allocate input buffer in mempool");
+
+ /* clear mbuf payload */
+ memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+ rte_pktmbuf_tailroom(ut_params->ibuf));
+
+ ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+ reference->ciphertext.len);
+ TEST_ASSERT_NOT_NULL(ciphertext, "no room to append ciphertext");
+ memcpy(ciphertext, reference->ciphertext.data,
+ reference->ciphertext.len);
+
+ /* Create operation */
+ retval = create_cipher_auth_verify_operation(ts_params,
+ ut_params,
+ reference);
+
+ if (retval < 0)
+ return retval;
+
+ if (data_corrupted)
+ data_corruption(ciphertext);
+ else
+ tag_corruption(ciphertext, reference->ciphertext.len);
+
+ ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+ ut_params->op);
+
+ TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+ TEST_ASSERT_EQUAL(ut_params->op->status,
+ RTE_CRYPTO_OP_STATUS_AUTH_FAILED,
+ "authentication not failed");
+
+ ut_params->obuf = ut_params->op->sym->m_src;
+ TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+ return 0;
+}
+
+static int
+create_gcm_operation_SGL(enum rte_crypto_cipher_operation op,
+ const struct gcm_test_data *tdata,
+ void *digest_mem, uint64_t digest_phys)
+{
+ struct crypto_testsuite_params *ts_params = &testsuite_params;
+ struct crypto_unittest_params *ut_params = &unittest_params;
+
+ const unsigned int auth_tag_len = tdata->auth_tag.len;
+ const unsigned int iv_len = tdata->iv.len;
+ const unsigned int aad_len = tdata->aad.len;
+
+ unsigned int iv_pad_len = 0;
+
+ /* Generate Crypto op data structure */
+ ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
+ RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+ TEST_ASSERT_NOT_NULL(ut_params->op,
+ "Failed to allocate symmetric crypto operation struct");
+
+ struct rte_crypto_sym_op *sym_op = ut_params->op->sym;
+
+ sym_op->auth.digest.data = digest_mem;
+
+ TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
+ "no room to append digest");
+
+ sym_op->auth.digest.phys_addr = digest_phys;
+ sym_op->auth.digest.length = auth_tag_len;
+
+ if (op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {
+ rte_memcpy(sym_op->auth.digest.data, tdata->auth_tag.data,
+ auth_tag_len);
+ TEST_HEXDUMP(stdout, "digest:",
+ sym_op->auth.digest.data,
+ sym_op->auth.digest.length);
+ }
+
+ iv_pad_len = RTE_ALIGN_CEIL(iv_len, 16);
+
+ sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(
+ ut_params->ibuf, iv_pad_len);
+
+ TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data,
+ "no room to prepend iv");
+
+ memset(sym_op->cipher.iv.data, 0, iv_pad_len);
+ sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf);
+ sym_op->cipher.iv.length = iv_len;
+
+ rte_memcpy(sym_op->cipher.iv.data, tdata->iv.data, iv_pad_len);
+
+ sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_prepend(
+ ut_params->ibuf, aad_len);
+ TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data,
+ "no room to prepend aad");
+ sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(
+ ut_params->ibuf);
+ sym_op->auth.aad.length = aad_len;
+
+ memset(sym_op->auth.aad.data, 0, aad_len);
+ rte_memcpy(sym_op->auth.aad.data, tdata->aad.data, aad_len);
+
+ TEST_HEXDUMP(stdout, "iv:", sym_op->cipher.iv.data, iv_pad_len);
+ TEST_HEXDUMP(stdout, "aad:",
+ sym_op->auth.aad.data, aad_len);
+
+ sym_op->cipher.data.length = tdata->plaintext.len;
+ sym_op->cipher.data.offset = aad_len + iv_pad_len;
+
+ sym_op->auth.data.offset = aad_len + iv_pad_len;
+ sym_op->auth.data.length = tdata->plaintext.len;
+
+ return 0;
+}
+
+#define SGL_MAX_NO 16
+
+static int
+test_AES_GCM_authenticated_encryption_SGL(const struct gcm_test_data *tdata,
+ const int oop, uint32_t fragsz, uint32_t fragsz_oop)
+{
+ struct crypto_testsuite_params *ts_params = &testsuite_params;
+ struct crypto_unittest_params *ut_params = &unittest_params;
+ struct rte_mbuf *buf, *buf_oop = NULL, *buf_last_oop = NULL;
+ int retval;
+ int to_trn = 0;
+ int to_trn_tbl[SGL_MAX_NO];
+ int segs = 1;
+ unsigned int trn_data = 0;
+ uint8_t *plaintext, *ciphertext, *auth_tag;
+
+ if (fragsz > tdata->plaintext.len)
+ fragsz = tdata->plaintext.len;
+
+ uint16_t plaintext_len = fragsz;
+ uint16_t frag_size_oop = fragsz_oop ? fragsz_oop : fragsz;
+
+ if (fragsz_oop > tdata->plaintext.len)
+ frag_size_oop = tdata->plaintext.len;
+
+ int ecx = 0;
+ void *digest_mem = NULL;
+
+ uint32_t prepend_len = ALIGN_POW2_ROUNDUP(tdata->iv.len, 16)
+ + tdata->aad.len;
+
+ if (tdata->plaintext.len % fragsz != 0) {
+ if (tdata->plaintext.len / fragsz + 1 > SGL_MAX_NO)
+ return 1;
+ } else {
+ if (tdata->plaintext.len / fragsz > SGL_MAX_NO)
+ return 1;
+ }
+
+ /*
+ * For out-op-place we need to alloc another mbuf
+ */
+ if (oop) {
+ ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+ rte_pktmbuf_append(ut_params->obuf,
+ frag_size_oop + prepend_len);
+ buf_oop = ut_params->obuf;
+ }
+
+ /* Create GCM session */
+ retval = create_gcm_session(ts_params->valid_devs[0],
+ RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+ tdata->key.data, tdata->key.len,
+ tdata->aad.len, tdata->auth_tag.len,
+ RTE_CRYPTO_AUTH_OP_GENERATE);
+ if (retval < 0)
+ return retval;
+
+ ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+
+ /* clear mbuf payload */
+ memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+ rte_pktmbuf_tailroom(ut_params->ibuf));
+
+ plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+ plaintext_len);
+
+ memcpy(plaintext, tdata->plaintext.data, plaintext_len);
+
+ trn_data += plaintext_len;
+
+ buf = ut_params->ibuf;
+
+ /*
+ * Loop until no more fragments
+ */
+
+ while (trn_data < tdata->plaintext.len) {
+ ++segs;
+ to_trn = (tdata->plaintext.len - trn_data < fragsz) ?
+ (tdata->plaintext.len - trn_data) : fragsz;
+
+ to_trn_tbl[ecx++] = to_trn;
+
+ buf->next = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+ buf = buf->next;
+
+ memset(rte_pktmbuf_mtod(buf, uint8_t *), 0,
+ rte_pktmbuf_tailroom(buf));
+
+ /* OOP */
+ if (oop && !fragsz_oop) {
+ buf_last_oop = buf_oop->next =
+ rte_pktmbuf_alloc(ts_params->mbuf_pool);
+ buf_oop = buf_oop->next;
+ memset(rte_pktmbuf_mtod(buf_oop, uint8_t *),
+ 0, rte_pktmbuf_tailroom(buf_oop));
+ rte_pktmbuf_append(buf_oop, to_trn);
+ }
+
+ plaintext = (uint8_t *)rte_pktmbuf_append(buf,
+ to_trn);
+
+ memcpy(plaintext, tdata->plaintext.data + trn_data,
+ to_trn);
+ trn_data += to_trn;
+ if (trn_data == tdata->plaintext.len) {
+ if (oop) {
+ if (!fragsz_oop)
+ digest_mem = rte_pktmbuf_append(buf_oop,
+ tdata->auth_tag.len);
+ } else
+ digest_mem = (uint8_t *)rte_pktmbuf_append(buf,
+ tdata->auth_tag.len);
+ }
+ }
+
+ uint64_t digest_phys = 0;
+
+ ut_params->ibuf->nb_segs = segs;
+
+ segs = 1;
+ if (fragsz_oop && oop) {
+ to_trn = 0;
+ ecx = 0;
+
+ if (frag_size_oop == tdata->plaintext.len) {
+ digest_mem = rte_pktmbuf_append(ut_params->obuf,
+ tdata->auth_tag.len);
+
+ digest_phys = rte_pktmbuf_mtophys_offset(
+ ut_params->obuf,
+ tdata->plaintext.len + prepend_len);
+ }
+
+ trn_data = frag_size_oop;
+ while (trn_data < tdata->plaintext.len) {
+ ++segs;
+ to_trn =
+ (tdata->plaintext.len - trn_data <
+ frag_size_oop) ?
+ (tdata->plaintext.len - trn_data) :
+ frag_size_oop;
+
+ to_trn_tbl[ecx++] = to_trn;
+
+ buf_last_oop = buf_oop->next =
+ rte_pktmbuf_alloc(ts_params->mbuf_pool);
+ buf_oop = buf_oop->next;
+ memset(rte_pktmbuf_mtod(buf_oop, uint8_t *),
+ 0, rte_pktmbuf_tailroom(buf_oop));
+ rte_pktmbuf_append(buf_oop, to_trn);
+
+ trn_data += to_trn;
+
+ if (trn_data == tdata->plaintext.len) {
+ digest_mem = rte_pktmbuf_append(buf_oop,
+ tdata->auth_tag.len);
+ }
+ }
+
+ ut_params->obuf->nb_segs = segs;
+ }
+
+ /*
+ * Place digest at the end of the last buffer
+ */
+ if (!digest_phys)
+ digest_phys = rte_pktmbuf_mtophys(buf) + to_trn;
+ if (oop && buf_last_oop)
+ digest_phys = rte_pktmbuf_mtophys(buf_last_oop) + to_trn;
+
+ if (!digest_mem && !oop) {
+ digest_mem = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+ + tdata->auth_tag.len);
+ digest_phys = rte_pktmbuf_mtophys_offset(ut_params->ibuf,
+ tdata->plaintext.len);
+ }
+
+ /* Create GCM opertaion */
+ retval = create_gcm_operation_SGL(RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+ tdata, digest_mem, digest_phys);
+
+ if (retval < 0)
+ return retval;
+
+ rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess);
+
+ ut_params->op->sym->m_src = ut_params->ibuf;
+ if (oop)
+ ut_params->op->sym->m_dst = ut_params->obuf;
+
+ /* Process crypto operation */
+ TEST_ASSERT_NOT_NULL(process_crypto_request(ts_params->valid_devs[0],
+ ut_params->op), "failed to process sym crypto op");
+
+ TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+ "crypto op processing failed");