summaryrefslogtreecommitdiffstats
path: root/src/spdk/intel-ipsec-mb/LibTestApp/hmac_md5_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/spdk/intel-ipsec-mb/LibTestApp/hmac_md5_test.c')
-rw-r--r--src/spdk/intel-ipsec-mb/LibTestApp/hmac_md5_test.c558
1 files changed, 558 insertions, 0 deletions
diff --git a/src/spdk/intel-ipsec-mb/LibTestApp/hmac_md5_test.c b/src/spdk/intel-ipsec-mb/LibTestApp/hmac_md5_test.c
new file mode 100644
index 000000000..ede7fe22c
--- /dev/null
+++ b/src/spdk/intel-ipsec-mb/LibTestApp/hmac_md5_test.c
@@ -0,0 +1,558 @@
+/*****************************************************************************
+ 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"
+#include "utils.h"
+
+int hmac_md5_test(const enum arch_type arch, struct MB_MGR *mb_mgr);
+
+#define block_size 64
+#define digest_size 16
+#define digest96_size 12
+
+/*
+ * Test vectors from https://tools.ietf.org/html/rfc2202
+ */
+
+/*
+ * 2. Test Case 1
+ *
+ * Key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
+ *
+ * Key length = 16
+ *
+ * Data = "Hi There"
+ *
+ * Data length = 8
+ *
+ * Digest = 0x9294727a3638bb1c13f48ef8158bfc9d
+ *
+ * Digest96 = 0x9294727a3638bb1c13f48ef8
+ */
+#define test_case1 "1"
+#define test_case_l1 "1_long"
+#define key_len1 16
+#define data_len1 8
+#define digest_len1 digest96_size
+#define digest_len_l1 digest_size
+static const uint8_t key1[key_len1] = {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
+};
+static const char data1[] = "Hi There";
+static const uint8_t digest1[digest_len_l1] = {
+ 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
+ 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d
+};
+
+/*
+ * 2. Test Case 2
+ *
+ * Key = "Jefe"
+ *
+ * Key length = 4
+ *
+ * Data = "what do ya want for nothing?"
+ *
+ * Data length = 28
+ *
+ * Digest = 0x750c783e6ab0b503eaa86e310a5db738
+ *
+ * Digest96 = 0x750c783e6ab0b503eaa86e31
+ */
+#define test_case2 "2"
+#define test_case_l2 "2_long"
+#define key_len2 4
+#define data_len2 28
+#define digest_len2 digest96_size
+#define digest_len_l2 digest_size
+static const char key2[] = "Jefe";
+static const char data2[] = "what do ya want for nothing?";
+static const uint8_t digest2[digest_len_l2] = {
+ 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
+ 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38
+};
+
+/*
+ * 2. Test Case 3
+ *
+ * Key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ *
+ * Key length = 16
+ *
+ * Data = 0xdd (repeated 50 times)
+ *
+ * Data length = 50
+ *
+ * Digest = 0x56be34521d144c88dbb8c733f0e8b3f6
+ *
+ * Digest96 = 0x56be34521d144c88dbb8c733
+ */
+#define test_case3 "3"
+#define test_case_l3 "3_long"
+#define key_len3 16
+#define data_len3 50
+#define digest_len3 digest96_size
+#define digest_len_l3 digest_size
+static const uint8_t key3[key_len3] = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
+};
+static const uint8_t data3[data_len3] = {
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd
+};
+static const uint8_t digest3[digest_len_l3] = {
+ 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
+ 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6
+};
+
+/*
+ * 2. Test Case 4
+ *
+ * Key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819
+ *
+ * Key length = 25
+ *
+ * Data = 0xcd (repeated 50 times)
+ *
+ * Data length = 50
+ *
+ * Digest = 0x697eaf0aca3a3aea3a75164746ffaa79
+ *
+ * Digest96 = 0x697eaf0aca3a3aea3a751647
+ */
+#define test_case4 "4"
+#define test_case_l4 "4_long"
+#define key_len4 25
+#define data_len4 50
+#define digest_len4 digest96_size
+#define digest_len_l4 digest_size
+static const uint8_t key4[key_len4] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19
+};
+static const uint8_t data4[data_len4] = {
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd
+};
+static const uint8_t digest4[digest_len_l4] = {
+ 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
+ 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79
+};
+
+/*
+ * 2. Test Case 5
+ *
+ * Key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
+ *
+ * Key length = 16
+ *
+ * Data = "Test With Truncation"
+ *
+ * Data length = 20
+ *
+ * Digest = 0x56461ef2342edc00f9bab995690efd4c
+ *
+ * Digest96 = 0x56461ef2342edc00f9bab995
+ */
+#define test_case5 "5"
+#define test_case_l5 "5_long"
+#define key_len5 16
+#define data_len5 20
+#define digest_len5 digest96_size
+#define digest_len_l5 digest_size
+static const uint8_t key5[key_len5] = {
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c
+};
+static const char data5[] = "Test With Truncation";
+static const uint8_t digest5[digest_len_l5] = {
+ 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00,
+ 0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c
+};
+
+/*
+ * 2. Test Case 6
+ *
+ * Key = 0xaa (repeated 80 times)
+ *
+ * Key length = 80
+ *
+ * Data = "Test Using Larger Than Block-Size Key - Hash Key First"
+ *
+ * Data length = 54
+ *
+ * Digest = 0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd
+ *
+ * Digest96 = 0x6b1ab7fe4bd7bf8f0b62e6ce
+ */
+/* #define test_case6 "6" */
+/* #define key_len6 80 */
+/* #define data_len6 54 */
+/* #define digest_len6 digest96_size */
+/* static const uint8_t key6[key_len6] = { */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa */
+/* }; */
+/* static const char data6[] = "Test Using Larger Than Block-Size " */
+/* "Key - Hash Key First"; */
+/* static const uint8_t digest6[digest_len6] = { */
+/* 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, */
+/* 0x0b, 0x62, 0xe6, 0xce */
+/* }; */
+
+/*
+ * 2. Test Case 7
+ *
+ * Key = 0xaa (repeated 80 times)
+ *
+ * Key length = 80
+ *
+ * Data = "Test Using Larger Than Block-Size Key and Larger"
+ *
+ * Data length = 73
+ *
+ * Digest = 0x6f630fad67cda0ee1fb1f562db3aa53e
+ *
+ * Digest96 = 0x6f630fad67cda0ee1fb1f562
+ */
+/* #define test_case7 "7" */
+/* #define key_len7 80 */
+/* #define data_len7 73 */
+/* #define digest_len7 digest96_size */
+/* static const uint8_t key7[key_len7] = { */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, */
+/* 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa */
+/* }; */
+/* static const char data7[] = "Test Using Larger Than Block-Size " */
+/* "Key and Larger Than One Block-Size Data"; */
+/* static const uint8_t digest7[digest_len7] = { */
+/* 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, */
+/* 0x1f, 0xb1, 0xf5, 0x62 */
+/* }; */
+
+#define HMAC_MD5_TEST_VEC(num) \
+ { test_case##num, \
+ (const uint8_t *) key##num, key_len##num, \
+ (const uint8_t *) data##num, data_len##num, \
+ (const uint8_t *) digest##num, digest_len##num }
+#define HMAC_MD5_TEST_VEC_LONG(num) \
+ { test_case_l##num, \
+ (const uint8_t *) key##num, key_len##num, \
+ (const uint8_t *) data##num, data_len##num, \
+ (const uint8_t *) digest##num, digest_len_l##num }
+
+static const struct hmac_md5_rfc2202_vector {
+ const char *test_case;
+ const uint8_t *key;
+ size_t key_len;
+ const uint8_t *data;
+ size_t data_len;
+ const uint8_t *digest;
+ size_t digest_len;
+} hmac_md5_vectors[] = {
+ HMAC_MD5_TEST_VEC(1),
+ HMAC_MD5_TEST_VEC(2),
+ HMAC_MD5_TEST_VEC(3),
+ HMAC_MD5_TEST_VEC(4),
+ HMAC_MD5_TEST_VEC(5),
+ /* HMAC_MD5_TEST_VEC(6), */
+ /* HMAC_MD5_TEST_VEC(7), */
+ HMAC_MD5_TEST_VEC_LONG(1),
+ HMAC_MD5_TEST_VEC_LONG(2),
+ HMAC_MD5_TEST_VEC_LONG(3),
+ HMAC_MD5_TEST_VEC_LONG(4),
+ HMAC_MD5_TEST_VEC_LONG(5),
+};
+
+static int
+hmac_md5_job_ok(const struct hmac_md5_rfc2202_vector *vec,
+ const struct JOB_AES_HMAC *job,
+ const uint8_t *auth,
+ const uint8_t *padding,
+ const size_t sizeof_padding)
+{
+ if (job->status != STS_COMPLETED) {
+ printf("line:%d job error status:%d ", __LINE__, job->status);
+ return 0;
+ }
+
+ /* hash checks */
+ if (memcmp(padding, &auth[sizeof_padding + vec->digest_len],
+ sizeof_padding)) {
+ printf("hash overwrite tail\n");
+ hexdump(stderr, "Target",
+ &auth[sizeof_padding + vec->digest_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->digest, &auth[sizeof_padding],
+ vec->digest_len)) {
+ printf("hash mismatched\n");
+ hexdump(stderr, "Received", &auth[sizeof_padding],
+ vec->digest_len);
+ hexdump(stderr, "Expected", vec->digest,
+ vec->digest_len);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+test_hmac_md5(struct MB_MGR *mb_mgr,
+ const struct hmac_md5_rfc2202_vector *vec,
+ const int num_jobs)
+{
+ 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;
+ uint8_t key[block_size];
+ uint8_t buf[block_size];
+ DECLARE_ALIGNED(uint8_t ipad_hash[digest_size], 16);
+ DECLARE_ALIGNED(uint8_t opad_hash[digest_size], 16);
+ int key_len = 0;
+
+ 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++) {
+ const size_t alloc_len =
+ vec->digest_len + (sizeof(padding) * 2);
+
+ auths[i] = malloc(alloc_len);
+ if (auths[i] == NULL) {
+ fprintf(stderr, "Can't allocate buffer memory\n");
+ goto end;
+ }
+ memset(auths[i], -1, alloc_len);
+ }
+
+ /* prepare the key */
+ memset(key, 0, sizeof(key));
+ if (vec->key_len <= block_size) {
+ memcpy(key, vec->key, vec->key_len);
+ key_len = (int) vec->key_len;
+ } else {
+ printf("Key length longer than block size is not supported "
+ "by MD5\n");
+ ret = 0;
+ goto end;
+ }
+
+ /* compute ipad hash */
+ memset(buf, 0x36, sizeof(buf));
+ for (i = 0; i < key_len; i++)
+ buf[i] ^= key[i];
+ IMB_MD5_ONE_BLOCK(mb_mgr, buf, ipad_hash);
+
+ /* compute opad hash */
+ memset(buf, 0x5c, sizeof(buf));
+ for (i = 0; i < key_len; i++)
+ buf[i] ^= key[i];
+ IMB_MD5_ONE_BLOCK(mb_mgr, buf, opad_hash);
+
+ /* empty the manager */
+ while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL)
+ ;
+
+ for (i = 0; i < num_jobs; i++) {
+ job = IMB_GET_NEXT_JOB(mb_mgr);
+ job->aes_enc_key_expanded = NULL;
+ job->aes_dec_key_expanded = NULL;
+ job->cipher_direction = ENCRYPT;
+ job->chain_order = HASH_CIPHER;
+ job->dst = NULL;
+ job->aes_key_len_in_bytes = 0;
+ job->auth_tag_output = auths[i] + sizeof(padding);
+ job->auth_tag_output_len_in_bytes = vec->digest_len;
+ job->iv = NULL;
+ job->iv_len_in_bytes = 0;
+ job->src = vec->data;
+ job->cipher_start_src_offset_in_bytes = 0;
+ job->msg_len_to_cipher_in_bytes = 0;
+ job->hash_start_src_offset_in_bytes = 0;
+ job->msg_len_to_hash_in_bytes = vec->data_len;
+ job->u.HMAC._hashed_auth_key_xor_ipad = ipad_hash;
+ job->u.HMAC._hashed_auth_key_xor_opad = opad_hash;
+ job->cipher_mode = NULL_CIPHER;
+ job->hash_alg = MD5;
+
+ job->user_data = auths[i];
+
+ job = IMB_SUBMIT_JOB(mb_mgr);
+ if (job) {
+ jobs_rx++;
+ /*
+ * HMAC-MD5 requires 8 submissions to get one back
+ */
+ if (num_jobs < 8) {
+ printf("%d Unexpected return from submit_job\n",
+ __LINE__);
+ goto end;
+ }
+ if (!hmac_md5_job_ok(vec, job, job->user_data,
+ padding, sizeof(padding)))
+ goto end;
+ }
+ }
+
+ while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL) {
+ jobs_rx++;
+ if (!hmac_md5_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:
+ /* empty the manager before next tests */
+ while ((job = IMB_FLUSH_JOB(mb_mgr)) != NULL)
+ ;
+
+ 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_hmac_md5_std_vectors(struct MB_MGR *mb_mgr, const int num_jobs)
+{
+ const int vectors_cnt =
+ sizeof(hmac_md5_vectors) / sizeof(hmac_md5_vectors[0]);
+ int vect;
+ int errors = 0;
+
+ printf("HMAC-MD5 standard test vectors (N jobs = %d):\n", num_jobs);
+ for (vect = 1; vect <= vectors_cnt; vect++) {
+ const int idx = vect - 1;
+#ifdef DEBUG
+ printf("[%d/%d] RFC2202 Test Case %s key_len:%d data_len:%d "
+ "digest_len:%d\n",
+ vect, vectors_cnt,
+ hmac_md5_vectors[idx].test_case,
+ (int) hmac_md5_vectors[idx].key_len,
+ (int) hmac_md5_vectors[idx].data_len,
+ (int) hmac_md5_vectors[idx].digest_len);
+#else
+ printf(".");
+#endif
+
+ if (test_hmac_md5(mb_mgr, &hmac_md5_vectors[idx], num_jobs)) {
+ printf("error #%d\n", vect);
+ errors++;
+ }
+ }
+ printf("\n");
+ return errors;
+}
+
+int
+hmac_md5_test(const enum arch_type arch,
+ struct MB_MGR *mb_mgr)
+{
+ int errors = 0;
+
+ (void) arch; /* unused */
+
+ errors += test_hmac_md5_std_vectors(mb_mgr, 1);
+ errors += test_hmac_md5_std_vectors(mb_mgr, 3);
+ errors += test_hmac_md5_std_vectors(mb_mgr, 4);
+ errors += test_hmac_md5_std_vectors(mb_mgr, 5);
+ errors += test_hmac_md5_std_vectors(mb_mgr, 7);
+ errors += test_hmac_md5_std_vectors(mb_mgr, 8);
+ errors += test_hmac_md5_std_vectors(mb_mgr, 9);
+ errors += test_hmac_md5_std_vectors(mb_mgr, 15);
+ errors += test_hmac_md5_std_vectors(mb_mgr, 16);
+ errors += test_hmac_md5_std_vectors(mb_mgr, 17);
+
+ if (0 == errors)
+ printf("...Pass\n");
+ else
+ printf("...Fail\n");
+
+ return errors;
+}