app/test: add integrity check for crypto mbuf data
authorFiona Trahe <fiona.trahe@intel.com>
Thu, 22 Dec 2016 16:51:07 +0000 (16:51 +0000)
committerPablo de Lara <pablo.de.lara.guarch@intel.com>
Wed, 18 Jan 2017 20:48:56 +0000 (21:48 +0100)
In block cipher test cases, add checks that the source
and destination mbufs are not modified except where expected.

Signed-off-by: Fiona Trahe <fiona.trahe@intel.com>
Acked-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
app/test/test_cryptodev_blockcipher.c

index 03dd073..f1fe624 100644 (file)
@@ -45,6 +45,7 @@
 #include "test_cryptodev_aes_test_vectors.h"
 #include "test_cryptodev_des_test_vectors.h"
 #include "test_cryptodev_hash_test_vectors.h"
+#include "test_cryptodev.h"
 
 static int
 test_blockcipher_one_case(const struct blockcipher_test_case *t,
@@ -71,6 +72,10 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
        uint32_t buf_len = tdata->ciphertext.len;
        uint32_t digest_len = 0;
        char *buf_p = NULL;
+       uint8_t src_pattern = 0xa5;
+       uint8_t dst_pattern = 0xb6;
+       uint8_t tmp_src_buf[MBUF_SIZE];
+       uint8_t tmp_dst_buf[MBUF_SIZE];
 
        if (tdata->cipher_key.len)
                memcpy(cipher_key, tdata->cipher_key.data,
@@ -104,6 +109,7 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
                status = TEST_FAILED;
                goto error_exit;
        }
+       memset(ibuf->buf_addr, src_pattern, ibuf->buf_len);
 
        if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
                buf_len += tdata->iv.len;
@@ -152,6 +158,7 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
                        status = TEST_FAILED;
                        goto error_exit;
                }
+               memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
 
                buf_p = rte_pktmbuf_append(obuf, buf_len);
                if (!buf_p) {
@@ -342,6 +349,17 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
                rte_crypto_op_attach_sym_session(op, sess);
        }
 
+       TEST_HEXDUMP(stdout, "m_src(before):",
+                       sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
+       rte_memcpy(tmp_src_buf, sym_op->m_src->buf_addr,
+                                               sym_op->m_src->buf_len);
+       if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
+               TEST_HEXDUMP(stdout, "m_dst(before):",
+                       sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
+               rte_memcpy(tmp_dst_buf, sym_op->m_dst->buf_addr,
+                                               sym_op->m_dst->buf_len);
+       }
+
        /* Process crypto operation */
        if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
                snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
@@ -364,12 +382,11 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
                goto error_exit;
        }
 
-       TEST_HEXDUMP(stdout, "m_src:",
-               rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len);
+       TEST_HEXDUMP(stdout, "m_src(after):",
+                       sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
        if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP)
-               TEST_HEXDUMP(stdout, "m_dst:",
-                       rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *),
-                       buf_len);
+               TEST_HEXDUMP(stdout, "m_dst(after):",
+                       sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
 
        /* Verify results */
        if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
@@ -430,6 +447,120 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
                }
        }
 
+       /* The only parts that should have changed in the buffer are
+        * plaintext/ciphertext and digest.
+        * In OOP only the dest buffer should change.
+        */
+       if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
+               struct rte_mbuf *mbuf;
+               uint8_t value;
+               uint32_t head_unchanged_len = 0, changed_len = 0;
+               uint32_t i;
+
+               mbuf = sym_op->m_src;
+               if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) {
+                       /* white-box test: PMDs use some of the
+                        * tailroom as temp storage in verify case
+                        */
+                       head_unchanged_len = rte_pktmbuf_headroom(mbuf)
+                                       + rte_pktmbuf_data_len(mbuf);
+                       changed_len = digest_len;
+               } else {
+                       head_unchanged_len = mbuf->buf_len;
+                       changed_len = 0;
+               }
+
+               for (i = 0; i < mbuf->buf_len; i++) {
+                       if (i == head_unchanged_len)
+                               i += changed_len;
+                       value = *((uint8_t *)(mbuf->buf_addr)+i);
+                       if (value != tmp_src_buf[i]) {
+                               snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
+       "line %u FAILED: OOP src outer mbuf data (0x%x) not as expected (0x%x)",
+                                       __LINE__, value, tmp_src_buf[i]);
+                               status = TEST_FAILED;
+                               goto error_exit;
+                       }
+               }
+
+               mbuf = sym_op->m_dst;
+               if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
+                       head_unchanged_len = rte_pktmbuf_headroom(mbuf) +
+                                               sym_op->auth.data.offset;
+                       changed_len = sym_op->auth.data.length;
+                       if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
+                               changed_len += sym_op->auth.digest.length;
+               } else {
+                       /* cipher-only */
+                       head_unchanged_len = rte_pktmbuf_headroom(mbuf) +
+                                       sym_op->cipher.data.offset;
+                       changed_len = sym_op->cipher.data.length;
+               }
+
+               for (i = 0; i < mbuf->buf_len; i++) {
+                       if (i == head_unchanged_len)
+                               i += changed_len;
+                       value = *((uint8_t *)(mbuf->buf_addr)+i);
+                       if (value != tmp_dst_buf[i]) {
+                               snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
+                               "line %u FAILED: OOP dst outer mbuf data "
+                               "(0x%x) not as expected (0x%x)",
+                               __LINE__, value, tmp_dst_buf[i]);
+                               status = TEST_FAILED;
+                               goto error_exit;
+                       }
+               }
+       } else {
+               /* In-place operation */
+               struct rte_mbuf *mbuf;
+               uint8_t value;
+               uint32_t head_unchanged_len = 0, changed_len = 0;
+               uint32_t i;
+
+               mbuf = sym_op->m_src;
+               if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
+                       head_unchanged_len = rte_pktmbuf_headroom(mbuf) +
+                                       sym_op->cipher.data.offset;
+                       changed_len = sym_op->cipher.data.length;
+               } else {
+                       /* auth-only */
+                       head_unchanged_len = rte_pktmbuf_headroom(mbuf) +
+                                       sym_op->auth.data.offset +
+                                       sym_op->auth.data.length;
+                       changed_len = 0;
+               }
+
+               if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
+                       changed_len += sym_op->auth.digest.length;
+
+               if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) {
+                       /* white-box test: PMDs use some of the
+                        * tailroom as temp storage in verify case
+                        */
+                       if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
+                               /* This is simplified, not checking digest*/
+                               changed_len += digest_len*2;
+                       } else {
+                               head_unchanged_len += digest_len;
+                               changed_len += digest_len;
+                       }
+               }
+
+               for (i = 0; i < mbuf->buf_len; i++) {
+                       if (i == head_unchanged_len)
+                               i += changed_len;
+                       value = *((uint8_t *)(mbuf->buf_addr)+i);
+                       if (value != tmp_src_buf[i]) {
+                               snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
+                               "line %u FAILED: outer mbuf data (0x%x) "
+                               "not as expected (0x%x)",
+                               __LINE__, value, tmp_src_buf[i]);
+                               status = TEST_FAILED;
+                               goto error_exit;
+                       }
+               }
+       }
+
        snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS");
 
 error_exit: