16df3ef80SGreg Tucker /**********************************************************************
26df3ef80SGreg Tucker Copyright(c) 2011-2016 Intel Corporation All rights reserved.
36df3ef80SGreg Tucker
46df3ef80SGreg Tucker Redistribution and use in source and binary forms, with or without
56df3ef80SGreg Tucker modification, are permitted provided that the following conditions
66df3ef80SGreg Tucker are met:
76df3ef80SGreg Tucker * Redistributions of source code must retain the above copyright
86df3ef80SGreg Tucker notice, this list of conditions and the following disclaimer.
96df3ef80SGreg Tucker * Redistributions in binary form must reproduce the above copyright
106df3ef80SGreg Tucker notice, this list of conditions and the following disclaimer in
116df3ef80SGreg Tucker the documentation and/or other materials provided with the
126df3ef80SGreg Tucker distribution.
136df3ef80SGreg Tucker * Neither the name of Intel Corporation nor the names of its
146df3ef80SGreg Tucker contributors may be used to endorse or promote products derived
156df3ef80SGreg Tucker from this software without specific prior written permission.
166df3ef80SGreg Tucker
176df3ef80SGreg Tucker THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186df3ef80SGreg Tucker "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196df3ef80SGreg Tucker LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206df3ef80SGreg Tucker A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216df3ef80SGreg Tucker OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226df3ef80SGreg Tucker SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236df3ef80SGreg Tucker LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246df3ef80SGreg Tucker DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256df3ef80SGreg Tucker THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266df3ef80SGreg Tucker (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276df3ef80SGreg Tucker OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286df3ef80SGreg Tucker **********************************************************************/
296df3ef80SGreg Tucker
306df3ef80SGreg Tucker #include <stdio.h>
316df3ef80SGreg Tucker #include <stdlib.h>
326df3ef80SGreg Tucker #include "sha1_mb.h"
336df3ef80SGreg Tucker
346df3ef80SGreg Tucker #define TEST_LEN (1024 * 1024)
356df3ef80SGreg Tucker #define TEST_BUFS 100
366df3ef80SGreg Tucker #ifndef RANDOMS
376df3ef80SGreg Tucker #define RANDOMS 10
386df3ef80SGreg Tucker #endif
396df3ef80SGreg Tucker #ifndef TEST_SEED
406df3ef80SGreg Tucker #define TEST_SEED 0x1234
416df3ef80SGreg Tucker #endif
426df3ef80SGreg Tucker
430106da91SPablo de Lara #define UPDATE_SIZE 13 * ISAL_SHA1_BLOCK_SIZE
440106da91SPablo de Lara #define MAX_RAND_UPDATE_BLOCKS (TEST_LEN / (16 * ISAL_SHA1_BLOCK_SIZE))
456df3ef80SGreg Tucker
466df3ef80SGreg Tucker #ifdef DEBUG
476df3ef80SGreg Tucker #define debug_char(x) putchar(x)
486df3ef80SGreg Tucker #else
49868f05eaSMarcel Cornu #define debug_char(x) \
50868f05eaSMarcel Cornu do { \
51868f05eaSMarcel Cornu } while (0)
526df3ef80SGreg Tucker #endif
536df3ef80SGreg Tucker
546df3ef80SGreg Tucker /* Reference digest global to reduce stack usage */
550106da91SPablo de Lara static uint32_t digest_ref[TEST_BUFS][ISAL_SHA1_DIGEST_NWORDS];
566df3ef80SGreg Tucker
57868f05eaSMarcel Cornu extern void
58868f05eaSMarcel Cornu sha1_ref(uint8_t *input_data, uint32_t *digest, uint32_t len);
596df3ef80SGreg Tucker
606df3ef80SGreg Tucker // Generates pseudo-random data
616df3ef80SGreg Tucker
62868f05eaSMarcel Cornu void
rand_buffer(unsigned char * buf,const long buffer_size)63868f05eaSMarcel Cornu rand_buffer(unsigned char *buf, const long buffer_size)
646df3ef80SGreg Tucker {
656df3ef80SGreg Tucker long i;
666df3ef80SGreg Tucker for (i = 0; i < buffer_size; i++)
676df3ef80SGreg Tucker buf[i] = rand();
686df3ef80SGreg Tucker }
696df3ef80SGreg Tucker
70868f05eaSMarcel Cornu int
main(void)71868f05eaSMarcel Cornu main(void)
726df3ef80SGreg Tucker {
730106da91SPablo de Lara ISAL_SHA1_HASH_CTX_MGR *mgr = NULL;
740106da91SPablo de Lara ISAL_SHA1_HASH_CTX ctxpool[TEST_BUFS], *ctx = NULL;
756df3ef80SGreg Tucker uint32_t i, j, fail = 0;
76122c1779SMarcel Cornu uint32_t len_done, len_rem, len_rand;
7704ca2090SMarcel Cornu unsigned char *bufs[TEST_BUFS] = { 0 };
786df3ef80SGreg Tucker unsigned char *buf_ptr[TEST_BUFS];
796df3ef80SGreg Tucker uint32_t lens[TEST_BUFS];
806df3ef80SGreg Tucker unsigned int joblen, jobs, t;
81c91caf97STom Cosgrove int ret;
826df3ef80SGreg Tucker
836df3ef80SGreg Tucker printf("multibinary_sha1_update test, %d sets of %dx%d max: ", RANDOMS, TEST_BUFS,
846df3ef80SGreg Tucker TEST_LEN);
856df3ef80SGreg Tucker
866df3ef80SGreg Tucker srand(TEST_SEED);
876df3ef80SGreg Tucker
880106da91SPablo de Lara ret = posix_memalign((void *) &mgr, 16, sizeof(ISAL_SHA1_HASH_CTX_MGR));
89c91caf97STom Cosgrove if ((ret != 0) || (mgr == NULL)) {
90c91caf97STom Cosgrove printf("posix_memalign failed test aborted\n");
91c91caf97STom Cosgrove return 1;
92c91caf97STom Cosgrove }
93c91caf97STom Cosgrove
9414a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_init(mgr);
9514a3d258SPablo de Lara if (ret)
9614a3d258SPablo de Lara return 1;
976df3ef80SGreg Tucker
986df3ef80SGreg Tucker for (i = 0; i < TEST_BUFS; i++) {
9986058544SPablo de Lara // Allocate and fill buffer
1006df3ef80SGreg Tucker bufs[i] = (unsigned char *) malloc(TEST_LEN);
1016df3ef80SGreg Tucker buf_ptr[i] = bufs[i];
1026df3ef80SGreg Tucker if (bufs[i] == NULL) {
1036df3ef80SGreg Tucker printf("malloc failed test aborted\n");
10404ca2090SMarcel Cornu fail++;
10504ca2090SMarcel Cornu goto end;
1066df3ef80SGreg Tucker }
1076df3ef80SGreg Tucker rand_buffer(bufs[i], TEST_LEN);
1086df3ef80SGreg Tucker
1096df3ef80SGreg Tucker // Init ctx contents
110*8cb7fe78SPablo de Lara isal_hash_ctx_init(&ctxpool[i]);
1116df3ef80SGreg Tucker ctxpool[i].user_data = (void *) ((uint64_t) i);
1126df3ef80SGreg Tucker
1136df3ef80SGreg Tucker // Run reference test
1146df3ef80SGreg Tucker sha1_ref(bufs[i], digest_ref[i], TEST_LEN);
1156df3ef80SGreg Tucker }
1166df3ef80SGreg Tucker
1176df3ef80SGreg Tucker // Run sb_sha1 tests
1186df3ef80SGreg Tucker for (i = 0; i < TEST_BUFS;) {
119122c1779SMarcel Cornu len_done = (uint32_t) ((uintptr_t) buf_ptr[i] - (uintptr_t) bufs[i]);
1206df3ef80SGreg Tucker len_rem = TEST_LEN - len_done;
1216df3ef80SGreg Tucker
1226df3ef80SGreg Tucker if (len_done == 0)
12314a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
124*8cb7fe78SPablo de Lara UPDATE_SIZE, ISAL_HASH_FIRST);
1256df3ef80SGreg Tucker else if (len_rem <= UPDATE_SIZE)
12614a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i], len_rem,
127*8cb7fe78SPablo de Lara ISAL_HASH_LAST);
1286df3ef80SGreg Tucker else
12914a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
130*8cb7fe78SPablo de Lara UPDATE_SIZE, ISAL_HASH_UPDATE);
13114a3d258SPablo de Lara if (ret)
13214a3d258SPablo de Lara return 1;
1336df3ef80SGreg Tucker
1346df3ef80SGreg Tucker // Add jobs while available or finished
135*8cb7fe78SPablo de Lara if ((ctx == NULL) || isal_hash_ctx_complete(ctx)) {
1366df3ef80SGreg Tucker i++;
1376df3ef80SGreg Tucker continue;
1386df3ef80SGreg Tucker }
1396df3ef80SGreg Tucker // Resubmit unfinished job
140122c1779SMarcel Cornu i = (uint32_t) (uintptr_t) (ctx->user_data);
1416df3ef80SGreg Tucker buf_ptr[i] += UPDATE_SIZE;
1426df3ef80SGreg Tucker }
1436df3ef80SGreg Tucker
1446df3ef80SGreg Tucker // Start flushing finished jobs, end on last flushed
14514a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_flush(mgr, &ctx);
14614a3d258SPablo de Lara if (ret)
14714a3d258SPablo de Lara return 1;
1486df3ef80SGreg Tucker while (ctx) {
149*8cb7fe78SPablo de Lara if (isal_hash_ctx_complete(ctx)) {
1506df3ef80SGreg Tucker debug_char('-');
15114a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_flush(mgr, &ctx);
15214a3d258SPablo de Lara if (ret)
15314a3d258SPablo de Lara return 1;
1546df3ef80SGreg Tucker continue;
1556df3ef80SGreg Tucker }
1566df3ef80SGreg Tucker // Resubmit unfinished job
157122c1779SMarcel Cornu i = (uint32_t) (uintptr_t) (ctx->user_data);
1586df3ef80SGreg Tucker buf_ptr[i] += UPDATE_SIZE;
1596df3ef80SGreg Tucker
160122c1779SMarcel Cornu len_done = (uint32_t) ((uintptr_t) buf_ptr[i] - (uintptr_t) bufs[i]);
1616df3ef80SGreg Tucker len_rem = TEST_LEN - len_done;
1626df3ef80SGreg Tucker
1636df3ef80SGreg Tucker if (len_rem <= UPDATE_SIZE)
16414a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i], len_rem,
165*8cb7fe78SPablo de Lara ISAL_HASH_LAST);
1666df3ef80SGreg Tucker else
16714a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
168*8cb7fe78SPablo de Lara UPDATE_SIZE, ISAL_HASH_UPDATE);
16914a3d258SPablo de Lara if (ret)
17014a3d258SPablo de Lara return 1;
1716df3ef80SGreg Tucker
17214a3d258SPablo de Lara if (ctx == NULL) {
17314a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_flush(mgr, &ctx);
17414a3d258SPablo de Lara if (ret)
17514a3d258SPablo de Lara return 1;
17614a3d258SPablo de Lara }
1776df3ef80SGreg Tucker }
1786df3ef80SGreg Tucker
1796df3ef80SGreg Tucker // Check digests
1806df3ef80SGreg Tucker for (i = 0; i < TEST_BUFS; i++) {
1810106da91SPablo de Lara for (j = 0; j < ISAL_SHA1_DIGEST_NWORDS; j++) {
1826df3ef80SGreg Tucker if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) {
1836df3ef80SGreg Tucker fail++;
184868f05eaSMarcel Cornu printf("Test%d fixed size, digest%d fail %8X <=> %8X", i, j,
185868f05eaSMarcel Cornu ctxpool[i].job.result_digest[j], digest_ref[i][j]);
1866df3ef80SGreg Tucker }
1876df3ef80SGreg Tucker }
1886df3ef80SGreg Tucker }
1896df3ef80SGreg Tucker putchar('.');
1906df3ef80SGreg Tucker
1916df3ef80SGreg Tucker // Run tests with random size and number of jobs
1926df3ef80SGreg Tucker for (t = 0; t < RANDOMS; t++) {
1936df3ef80SGreg Tucker jobs = rand() % (TEST_BUFS);
1946df3ef80SGreg Tucker
1956df3ef80SGreg Tucker for (i = 0; i < jobs; i++) {
1966df3ef80SGreg Tucker joblen = rand() % (TEST_LEN);
1976df3ef80SGreg Tucker rand_buffer(bufs[i], joblen);
1986df3ef80SGreg Tucker lens[i] = joblen;
1996df3ef80SGreg Tucker buf_ptr[i] = bufs[i];
2006df3ef80SGreg Tucker sha1_ref(bufs[i], digest_ref[i], lens[i]);
2016df3ef80SGreg Tucker }
2026df3ef80SGreg Tucker
20314a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_init(mgr);
20414a3d258SPablo de Lara if (ret)
20514a3d258SPablo de Lara return 1;
2066df3ef80SGreg Tucker
2076df3ef80SGreg Tucker // Run sha1_sb jobs
2086df3ef80SGreg Tucker i = 0;
2096df3ef80SGreg Tucker while (i < jobs) {
2106df3ef80SGreg Tucker // Submit a new job
2110106da91SPablo de Lara len_rand = ISAL_SHA1_BLOCK_SIZE +
2120106da91SPablo de Lara ISAL_SHA1_BLOCK_SIZE * (rand() % MAX_RAND_UPDATE_BLOCKS);
2136df3ef80SGreg Tucker
2146df3ef80SGreg Tucker if (lens[i] > len_rand)
21514a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
216*8cb7fe78SPablo de Lara len_rand, ISAL_HASH_FIRST);
2176df3ef80SGreg Tucker else
21814a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
219*8cb7fe78SPablo de Lara lens[i], ISAL_HASH_ENTIRE);
22014a3d258SPablo de Lara if (ret)
22114a3d258SPablo de Lara return 1;
2226df3ef80SGreg Tucker
2236df3ef80SGreg Tucker // Returned ctx could be:
224868f05eaSMarcel Cornu // - null context (we are just getting started and lanes aren't full yet),
225868f05eaSMarcel Cornu // or
226868f05eaSMarcel Cornu // - finished already (an ENTIRE we submitted or a previous LAST is
227868f05eaSMarcel Cornu // returned), or
2286df3ef80SGreg Tucker // - an unfinished ctx, we will resubmit
2296df3ef80SGreg Tucker
230*8cb7fe78SPablo de Lara if ((ctx == NULL) || isal_hash_ctx_complete(ctx)) {
2316df3ef80SGreg Tucker i++;
2326df3ef80SGreg Tucker continue;
2336df3ef80SGreg Tucker } else {
234868f05eaSMarcel Cornu // unfinished ctx returned, choose another random update length and
235868f05eaSMarcel Cornu // submit either UPDATE or LAST depending on the amount of buffer
236868f05eaSMarcel Cornu // remaining
237*8cb7fe78SPablo de Lara while ((ctx != NULL) && !(isal_hash_ctx_complete(ctx))) {
238122c1779SMarcel Cornu j = (uint32_t) (uintptr_t) (ctx->user_data); // Get index of
239122c1779SMarcel Cornu // the returned
240122c1779SMarcel Cornu // ctx
2416df3ef80SGreg Tucker buf_ptr[j] = bufs[j] + ctx->total_length;
2420106da91SPablo de Lara len_rand = (rand() % ISAL_SHA1_BLOCK_SIZE) *
243868f05eaSMarcel Cornu (rand() % MAX_RAND_UPDATE_BLOCKS);
244122c1779SMarcel Cornu len_rem = lens[j] - (uint32_t) ctx->total_length;
2456df3ef80SGreg Tucker
246868f05eaSMarcel Cornu if (len_rem <=
247868f05eaSMarcel Cornu len_rand) // submit the rest of the job as LAST
248*8cb7fe78SPablo de Lara ret = isal_sha1_ctx_mgr_submit(
249*8cb7fe78SPablo de Lara mgr, &ctxpool[j], &ctx, buf_ptr[j], len_rem,
250*8cb7fe78SPablo de Lara ISAL_HASH_LAST);
2516df3ef80SGreg Tucker else // submit the random update length as UPDATE
25214a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_submit(
25314a3d258SPablo de Lara mgr, &ctxpool[j], &ctx, buf_ptr[j],
254*8cb7fe78SPablo de Lara len_rand, ISAL_HASH_UPDATE);
25514a3d258SPablo de Lara if (ret)
25614a3d258SPablo de Lara return 1;
257868f05eaSMarcel Cornu } // Either continue submitting any contexts returned here as
258868f05eaSMarcel Cornu // UPDATE/LAST, or
2596df3ef80SGreg Tucker // go back to submitting new jobs using the index i.
2606df3ef80SGreg Tucker
2616df3ef80SGreg Tucker i++;
2626df3ef80SGreg Tucker }
2636df3ef80SGreg Tucker }
2646df3ef80SGreg Tucker
2656df3ef80SGreg Tucker // Start flushing finished jobs, end on last flushed
26614a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_flush(mgr, &ctx);
26714a3d258SPablo de Lara if (ret)
26814a3d258SPablo de Lara return 1;
2696df3ef80SGreg Tucker while (ctx) {
270*8cb7fe78SPablo de Lara if (isal_hash_ctx_complete(ctx)) {
2716df3ef80SGreg Tucker debug_char('-');
27214a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_flush(mgr, &ctx);
27314a3d258SPablo de Lara if (ret)
27414a3d258SPablo de Lara return 1;
2756df3ef80SGreg Tucker continue;
2766df3ef80SGreg Tucker }
2776df3ef80SGreg Tucker // Resubmit unfinished job
278122c1779SMarcel Cornu i = (uint32_t) (uintptr_t) (ctx->user_data);
2796df3ef80SGreg Tucker buf_ptr[i] = bufs[i] + ctx->total_length; // update buffer pointer
280122c1779SMarcel Cornu len_rem = lens[i] - (uint32_t) ctx->total_length;
2810106da91SPablo de Lara len_rand =
2820106da91SPablo de Lara (rand() % ISAL_SHA1_BLOCK_SIZE) * (rand() % MAX_RAND_UPDATE_BLOCKS);
2836df3ef80SGreg Tucker debug_char('+');
2846df3ef80SGreg Tucker if (len_rem <= len_rand)
28514a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
286*8cb7fe78SPablo de Lara len_rem, ISAL_HASH_LAST);
2876df3ef80SGreg Tucker else
28814a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
289*8cb7fe78SPablo de Lara len_rand, ISAL_HASH_UPDATE);
29014a3d258SPablo de Lara if (ret)
29114a3d258SPablo de Lara return 1;
2926df3ef80SGreg Tucker
29314a3d258SPablo de Lara if (ctx == NULL) {
29414a3d258SPablo de Lara ret = isal_sha1_ctx_mgr_flush(mgr, &ctx);
29514a3d258SPablo de Lara if (ret)
29614a3d258SPablo de Lara return 1;
29714a3d258SPablo de Lara }
2986df3ef80SGreg Tucker }
2996df3ef80SGreg Tucker
3006df3ef80SGreg Tucker // Check result digest
3016df3ef80SGreg Tucker for (i = 0; i < jobs; i++) {
3020106da91SPablo de Lara for (j = 0; j < ISAL_SHA1_DIGEST_NWORDS; j++) {
3036df3ef80SGreg Tucker if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) {
3046df3ef80SGreg Tucker fail++;
305868f05eaSMarcel Cornu printf("Test%d, digest%d fail %8X <=> %8X\n", i, j,
306868f05eaSMarcel Cornu ctxpool[i].job.result_digest[j], digest_ref[i][j]);
3076df3ef80SGreg Tucker }
3086df3ef80SGreg Tucker }
3096df3ef80SGreg Tucker }
3106df3ef80SGreg Tucker if (fail) {
3116df3ef80SGreg Tucker printf("Test failed function check %d\n", fail);
31204ca2090SMarcel Cornu goto end;
3136df3ef80SGreg Tucker }
3146df3ef80SGreg Tucker
3156df3ef80SGreg Tucker putchar('.');
3166df3ef80SGreg Tucker fflush(0);
3176df3ef80SGreg Tucker } // random test t
3186df3ef80SGreg Tucker
31904ca2090SMarcel Cornu end:
32004ca2090SMarcel Cornu for (i = 0; i < TEST_BUFS; i++)
32104ca2090SMarcel Cornu free(bufs[i]);
32204ca2090SMarcel Cornu aligned_free(mgr);
32304ca2090SMarcel Cornu
3246df3ef80SGreg Tucker if (fail)
3256df3ef80SGreg Tucker printf("Test failed function check %d\n", fail);
3266df3ef80SGreg Tucker else
3276df3ef80SGreg Tucker printf(" multibinary_sha1_update rand: Pass\n");
3286df3ef80SGreg Tucker
3296df3ef80SGreg Tucker return fail;
3306df3ef80SGreg Tucker }
331