summaryrefslogtreecommitdiffstats
path: root/src/spdk/intel-ipsec-mb/LibTestApp/cmac_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/spdk/intel-ipsec-mb/LibTestApp/cmac_test.c')
-rw-r--r--src/spdk/intel-ipsec-mb/LibTestApp/cmac_test.c382
1 files changed, 382 insertions, 0 deletions
diff --git a/src/spdk/intel-ipsec-mb/LibTestApp/cmac_test.c b/src/spdk/intel-ipsec-mb/LibTestApp/cmac_test.c
new file mode 100644
index 00000000..bb5f6ba6
--- /dev/null
+++ b/src/spdk/intel-ipsec-mb/LibTestApp/cmac_test.c
@@ -0,0 +1,382 @@
+/*****************************************************************************
+ Copyright (c) 2018, Intel Corporation
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Intel Corporation nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <intel-ipsec-mb.h>
+#include "gcm_ctr_vectors_test.h"
+
+int cmac_test(const enum arch_type arch, struct MB_MGR *mb_mgr);
+
+/*
+ * Test vectors from https://tools.ietf.org/html/rfc4493
+ */
+
+/*
+ * Subkey Generation
+ * K 2b7e1516 28aed2a6 abf71588 09cf4f3c
+ * AES-128(key,0) 7df76b0c 1ab899b3 3e42f047 b91b546f
+ * K1 fbeed618 35713366 7c85e08f 7236a8de
+ * K2 f7ddac30 6ae266cc f90bc11e e46d513b
+ */
+static const uint8_t key[16] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
+};
+static const uint8_t sub_key1[16] = {
+ 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
+ 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
+};
+static const uint8_t sub_key2[16] = {
+ 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
+ 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
+};
+
+/*
+ * Example 1: len = 0
+ * M <empty string>
+ * AES-CMAC bb1d6929 e9593728 7fa37d12 9b756746
+ */
+static const uint8_t T_1[16] = {
+ 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
+ 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
+};
+
+/*
+ * Example 2: len = 16
+ * M 6bc1bee2 2e409f96 e93d7e11 7393172a
+ * AES-CMAC 070a16b4 6b4d4144 f79bdd9d d04a287c
+ */
+static const uint8_t T_2[16] = {
+ 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
+ 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
+};
+
+/*
+ * Example 3: len = 40
+ * M 6bc1bee2 2e409f96 e93d7e11 7393172a
+ * ae2d8a57 1e03ac9c 9eb76fac 45af8e51
+ * 30c81c46 a35ce411
+ * AES-CMAC dfa66747 de9ae630 30ca3261 1497c827
+ */
+static const uint8_t T_3[16] = {
+ 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
+ 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
+};
+
+/*
+ * Example 4: len = 64
+ * M 6bc1bee2 2e409f96 e93d7e11 7393172a
+ * ae2d8a57 1e03ac9c 9eb76fac 45af8e51
+ * 30c81c46 a35ce411 e5fbc119 1a0a52ef
+ * f69f2445 df4f9b17 ad2b417b e66c3710
+ * AES-CMAC 51f0bebf 7e3b9d92 fc497417 79363cfe
+ */
+static const uint8_t T_4[16] = {
+ 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
+ 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
+};
+
+static const uint8_t M[64] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+ 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
+ 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
+};
+
+static const struct cmac_rfc4493_vector {
+ const uint8_t *key;
+ const uint8_t *sub_key1;
+ const uint8_t *sub_key2;
+ const uint8_t *M;
+ size_t len;
+ const uint8_t *T;
+ size_t T_len;
+} cmac_vectors[] = {
+ { key, sub_key1, sub_key2, M, 0, T_1, 16 },
+ { key, sub_key1, sub_key2, M, 16, T_2, 16 },
+ { key, sub_key1, sub_key2, M, 40, T_3, 16 },
+ { key, sub_key1, sub_key2, M, 64, T_4, 16 },
+ { key, sub_key1, sub_key2, M, 0, T_1, 12 },
+ { key, sub_key1, sub_key2, M, 16, T_2, 12 },
+ { key, sub_key1, sub_key2, M, 40, T_3, 12 },
+ { key, sub_key1, sub_key2, M, 64, T_4, 12 },
+};
+
+#ifdef _WIN32
+#define snprintf _snprintf
+#endif
+
+static void
+hexdump(FILE *fp,
+ const char *msg,
+ const void *p,
+ size_t len)
+{
+ unsigned int i, out, ofs;
+ const unsigned char *data = p;
+
+ fprintf(fp, "%s\n", msg);
+
+ ofs = 0;
+ while (ofs < len) {
+ char line[120];
+
+ out = snprintf(line, sizeof(line), "%08x:", ofs);
+ for (i = 0; ((ofs + i) < len) && (i < 16); i++)
+ out += snprintf(line + out, sizeof(line) - out,
+ " %02x", (data[ofs + i] & 0xff));
+ for (; i <= 16; i++)
+ out += snprintf(line + out, sizeof(line) - out, " | ");
+ for (i = 0; (ofs < len) && (i < 16); i++, ofs++) {
+ unsigned char c = data[ofs];
+
+ if ((c < ' ') || (c > '~'))
+ c = '.';
+ out += snprintf(line + out,
+ sizeof(line) - out, "%c", c);
+ }
+ fprintf(fp, "%s\n", line);
+ }
+}
+
+static int
+cmac_job_ok(const struct cmac_rfc4493_vector *vec,
+ const struct JOB_AES_HMAC *job,
+ const uint8_t *auth,
+ const uint8_t *padding,
+ const size_t sizeof_padding)
+{
+ const size_t auth_len = job->auth_tag_output_len_in_bytes;
+
+ if (job->status != STS_COMPLETED) {
+ printf("%d Error status:%d", __LINE__, job->status);
+ return 0;
+ }
+
+ /* hash checks */
+ if (memcmp(padding, &auth[sizeof_padding + auth_len],
+ sizeof_padding)) {
+ printf("hash overwrite tail\n");
+ hexdump(stderr, "Target",
+ &auth[sizeof_padding + auth_len], sizeof_padding);
+ return 0;
+ }
+
+ if (memcmp(padding, &auth[0], sizeof_padding)) {
+ printf("hash overwrite head\n");
+ hexdump(stderr, "Target", &auth[0], sizeof_padding);
+ return 0;
+ }
+
+ if (memcmp(vec->T, &auth[sizeof_padding], auth_len)) {
+ printf("hash mismatched\n");
+ hexdump(stderr, "Received", &auth[sizeof_padding],
+ auth_len);
+ hexdump(stderr, "Expected", vec->T,
+ auth_len);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+test_cmac(struct MB_MGR *mb_mgr,
+ const struct cmac_rfc4493_vector *vec,
+ const int dir,
+ const int num_jobs)
+{
+ DECLARE_ALIGNED(uint32_t expkey[4*15], 16);
+ DECLARE_ALIGNED(uint32_t dust[4*15], 16);
+ uint32_t skey1[4], skey2[4];
+ struct JOB_AES_HMAC *job;
+ uint8_t padding[16];
+ uint8_t **auths = malloc(num_jobs * sizeof(void *));
+ int i = 0, jobs_rx = 0, ret = -1;
+
+ if (auths == NULL) {
+ fprintf(stderr, "Can't allocate buffer memory\n");
+ goto end2;
+ }
+
+ memset(padding, -1, sizeof(padding));
+ memset(auths, 0, num_jobs * sizeof(void *));
+
+ for (i = 0; i < num_jobs; i++) {
+ auths[i] = malloc(16 + (sizeof(padding) * 2));
+ if (auths[i] == NULL) {
+ fprintf(stderr, "Can't allocate buffer memory\n");
+ goto end;
+ }
+
+ memset(auths[i], -1, 16 + (sizeof(padding) * 2));
+ }
+
+ IMB_AES_KEYEXP_128(mb_mgr, vec->key, expkey, dust);
+ IMB_AES_CMAC_SUBKEY_GEN_128(mb_mgr, expkey, skey1, skey2);
+
+ if (memcmp(vec->sub_key1, skey1, sizeof(skey1))) {
+ printf("sub-key1 mismatched\n");
+ hexdump(stderr, "Received", &skey1[0], sizeof(skey1));
+ hexdump(stderr, "Expected", vec->sub_key1, sizeof(skey1));
+ goto end;
+ }
+
+ if (memcmp(vec->sub_key2, skey2, sizeof(skey2))) {
+ printf("sub-key2 mismatched\n");
+ hexdump(stderr, "Received", &skey2[0], sizeof(skey2));
+ hexdump(stderr, "Expected", vec->sub_key2, sizeof(skey2));
+ goto end;
+ }
+
+ while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL)
+ ;
+
+ for (i = 0; i < num_jobs; i++) {
+ job = IMB_GET_NEXT_JOB(mb_mgr);
+ job->cipher_direction = dir;
+ job->chain_order = HASH_CIPHER;
+ job->cipher_mode = NULL_CIPHER;
+
+ job->hash_alg = AES_CMAC;
+ job->src = vec->M;
+ job->hash_start_src_offset_in_bytes = 0;
+ job->msg_len_to_hash_in_bytes = vec->len;
+ job->auth_tag_output = auths[i] + sizeof(padding);
+ job->auth_tag_output_len_in_bytes = vec->T_len;
+
+ job->u.CMAC._key_expanded = expkey;
+ job->u.CMAC._skey1 = skey1;
+ job->u.CMAC._skey2 = skey2;
+
+ job->user_data = auths[i];
+
+ job = IMB_SUBMIT_JOB(mb_mgr);
+ if (job) {
+ jobs_rx++;
+ if (num_jobs < 4) {
+ printf("%d Unexpected return from submit_job\n",
+ __LINE__);
+ goto end;
+ }
+ if (!cmac_job_ok(vec, job, job->user_data, padding,
+ sizeof(padding)))
+ goto end;
+ }
+ }
+
+ while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL) {
+ jobs_rx++;
+
+ if (!cmac_job_ok(vec, job, job->user_data, padding,
+ sizeof(padding)))
+ goto end;
+ }
+
+ if (jobs_rx != num_jobs) {
+ printf("Expected %d jobs, received %d\n", num_jobs, jobs_rx);
+ goto end;
+ }
+ ret = 0;
+
+ end:
+ for (i = 0; i < num_jobs; i++) {
+ if (auths[i] != NULL)
+ free(auths[i]);
+ }
+
+ end2:
+ if (auths != NULL)
+ free(auths);
+
+ return ret;
+}
+
+static int
+test_cmac_std_vectors(struct MB_MGR *mb_mgr, const int num_jobs)
+{
+ const int vectors_cnt = sizeof(cmac_vectors) / sizeof(cmac_vectors[0]);
+ int vect;
+ int errors = 0;
+
+ printf("AES-CMAC standard test vectors (N jobs = %d):\n", num_jobs);
+ for (vect = 1; vect <= vectors_cnt; vect++) {
+ const int idx = vect - 1;
+#ifdef DEBUG
+ printf("Standard vector [%d/%d] M len: %d, T len:%d\n",
+ vect, vectors_cnt,
+ (int) cmac_vectors[idx].len,
+ (int) cmac_vectors[idx].T_len);
+#else
+ printf(".");
+#endif
+
+ if (test_cmac(mb_mgr, &cmac_vectors[idx], ENCRYPT, num_jobs)) {
+ printf("error #%d encrypt\n", vect);
+ errors++;
+ }
+
+ if (test_cmac(mb_mgr, &cmac_vectors[idx], DECRYPT, num_jobs)) {
+ printf("error #%d decrypt\n", vect);
+ errors++;
+ }
+
+ }
+ printf("\n");
+ return errors;
+}
+
+int
+cmac_test(const enum arch_type arch,
+ struct MB_MGR *mb_mgr)
+{
+ int errors = 0;
+
+ (void) arch; /* unused */
+
+ errors += test_cmac_std_vectors(mb_mgr, 1);
+ errors += test_cmac_std_vectors(mb_mgr, 3);
+ errors += test_cmac_std_vectors(mb_mgr, 4);
+ errors += test_cmac_std_vectors(mb_mgr, 5);
+ errors += test_cmac_std_vectors(mb_mgr, 7);
+ errors += test_cmac_std_vectors(mb_mgr, 8);
+ errors += test_cmac_std_vectors(mb_mgr, 9);
+
+ if (0 == errors)
+ printf("...Pass\n");
+ else
+ printf("...Fail\n");
+
+ return errors;
+}