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 "sha512_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
43592e639eSPablo de Lara #define UPDATE_SIZE 13 * ISAL_SHA512_BLOCK_SIZE
44592e639eSPablo de Lara #define MAX_RAND_UPDATE_BLOCKS (TEST_LEN / (16 * ISAL_SHA512_BLOCK_SIZE))
456df3ef80SGreg Tucker
466df3ef80SGreg Tucker #ifdef DEBUG
476df3ef80SGreg Tucker #define debug_char(x) putchar(x)
486df3ef80SGreg Tucker #else
493fb7b5f1SMarcel Cornu #define debug_char(x) \
503fb7b5f1SMarcel Cornu do { \
513fb7b5f1SMarcel Cornu } while (0)
526df3ef80SGreg Tucker #endif
536df3ef80SGreg Tucker
546df3ef80SGreg Tucker /* Reference digest global to reduce stack usage */
55592e639eSPablo de Lara static uint64_t digest_ref[TEST_BUFS][ISAL_SHA512_DIGEST_NWORDS];
566df3ef80SGreg Tucker
573fb7b5f1SMarcel Cornu extern void
583fb7b5f1SMarcel Cornu sha512_ref(uint8_t *input_data, uint64_t *digest, uint32_t len);
596df3ef80SGreg Tucker
606df3ef80SGreg Tucker // Generates pseudo-random data
616df3ef80SGreg Tucker
623fb7b5f1SMarcel Cornu void
rand_buffer(unsigned char * buf,const long buffer_size)633fb7b5f1SMarcel 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
703fb7b5f1SMarcel Cornu int
main(void)713fb7b5f1SMarcel Cornu main(void)
726df3ef80SGreg Tucker {
73592e639eSPablo de Lara ISAL_SHA512_HASH_CTX_MGR *mgr = NULL;
74592e639eSPablo de Lara ISAL_SHA512_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;
776df3ef80SGreg Tucker unsigned char *bufs[TEST_BUFS];
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_sha512_update test, %d sets of %dx%d max: ", RANDOMS, TEST_BUFS,
846df3ef80SGreg Tucker TEST_LEN);
856df3ef80SGreg Tucker
866df3ef80SGreg Tucker srand(TEST_SEED);
876df3ef80SGreg Tucker
88592e639eSPablo de Lara ret = posix_memalign((void *) &mgr, 16, sizeof(ISAL_SHA512_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
94*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_init(mgr);
95*34bf6af2SPablo de Lara if (ret)
96*34bf6af2SPablo 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");
1040cabffc5SMarcel Cornu fail++;
1050cabffc5SMarcel Cornu goto end;
1066df3ef80SGreg Tucker }
1076df3ef80SGreg Tucker rand_buffer(bufs[i], TEST_LEN);
1086df3ef80SGreg Tucker
1096df3ef80SGreg Tucker // Init ctx contents
1108cb7fe78SPablo 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 sha512_ref(bufs[i], digest_ref[i], TEST_LEN);
1156df3ef80SGreg Tucker }
1166df3ef80SGreg Tucker
1176df3ef80SGreg Tucker // Run sb_sha512 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)
123*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
124*34bf6af2SPablo de Lara UPDATE_SIZE, ISAL_HASH_FIRST);
1256df3ef80SGreg Tucker else if (len_rem <= UPDATE_SIZE)
126*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
127*34bf6af2SPablo de Lara len_rem, ISAL_HASH_LAST);
1286df3ef80SGreg Tucker else
129*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
130*34bf6af2SPablo de Lara UPDATE_SIZE, ISAL_HASH_UPDATE);
131*34bf6af2SPablo de Lara if (ret)
132*34bf6af2SPablo de Lara return 1;
1336df3ef80SGreg Tucker
1346df3ef80SGreg Tucker // Add jobs while available or finished
1358cb7fe78SPablo de Lara if ((ctx == NULL) || isal_hash_ctx_complete(ctx)) {
1366df3ef80SGreg Tucker i++;
1376df3ef80SGreg Tucker continue;
1386df3ef80SGreg Tucker }
1396df3ef80SGreg Tucker // Resubmit unfinished job
14087dde3adSTomasz Kantecki i = (unsigned long) (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
145*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
146*34bf6af2SPablo de Lara if (ret)
147*34bf6af2SPablo de Lara return 1;
1486df3ef80SGreg Tucker while (ctx) {
1498cb7fe78SPablo de Lara if (isal_hash_ctx_complete(ctx)) {
1506df3ef80SGreg Tucker debug_char('-');
151*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
152*34bf6af2SPablo de Lara if (ret)
153*34bf6af2SPablo de Lara return 1;
1546df3ef80SGreg Tucker continue;
1556df3ef80SGreg Tucker }
1566df3ef80SGreg Tucker // Resubmit unfinished job
15787dde3adSTomasz Kantecki i = (unsigned long) (uintptr_t) (ctx->user_data);
1586df3ef80SGreg Tucker buf_ptr[i] += UPDATE_SIZE;
1596df3ef80SGreg Tucker
16087dde3adSTomasz Kantecki len_done = (int) ((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)
164*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
165*34bf6af2SPablo de Lara len_rem, ISAL_HASH_LAST);
1666df3ef80SGreg Tucker else
167*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
168*34bf6af2SPablo de Lara UPDATE_SIZE, ISAL_HASH_UPDATE);
169*34bf6af2SPablo de Lara if (ret)
170*34bf6af2SPablo de Lara return 1;
1716df3ef80SGreg Tucker
172*34bf6af2SPablo de Lara if (ctx == NULL) {
173*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
174*34bf6af2SPablo de Lara if (ret)
175*34bf6af2SPablo de Lara return 1;
176*34bf6af2SPablo de Lara }
1776df3ef80SGreg Tucker }
1786df3ef80SGreg Tucker
1796df3ef80SGreg Tucker // Check digests
1806df3ef80SGreg Tucker for (i = 0; i < TEST_BUFS; i++) {
181592e639eSPablo de Lara for (j = 0; j < ISAL_SHA512_DIGEST_NWORDS; j++) {
1826df3ef80SGreg Tucker if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) {
1836df3ef80SGreg Tucker fail++;
18487dde3adSTomasz Kantecki printf("Test%d fixed size, digest%d fail %8llX <=> %8llX", i, j,
18587dde3adSTomasz Kantecki (unsigned long long) ctxpool[i].job.result_digest[j],
18687dde3adSTomasz Kantecki (unsigned long long) digest_ref[i][j]);
1876df3ef80SGreg Tucker }
1886df3ef80SGreg Tucker }
1896df3ef80SGreg Tucker }
1906df3ef80SGreg Tucker putchar('.');
1916df3ef80SGreg Tucker
1926df3ef80SGreg Tucker // Run tests with random size and number of jobs
1936df3ef80SGreg Tucker for (t = 0; t < RANDOMS; t++) {
1946df3ef80SGreg Tucker jobs = rand() % (TEST_BUFS);
1956df3ef80SGreg Tucker
1966df3ef80SGreg Tucker for (i = 0; i < jobs; i++) {
1976df3ef80SGreg Tucker joblen = rand() % (TEST_LEN);
1986df3ef80SGreg Tucker rand_buffer(bufs[i], joblen);
1996df3ef80SGreg Tucker lens[i] = joblen;
2006df3ef80SGreg Tucker buf_ptr[i] = bufs[i];
2016df3ef80SGreg Tucker sha512_ref(bufs[i], digest_ref[i], lens[i]);
2026df3ef80SGreg Tucker }
2036df3ef80SGreg Tucker
204*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_init(mgr);
205*34bf6af2SPablo de Lara if (ret)
206*34bf6af2SPablo de Lara return 1;
2076df3ef80SGreg Tucker
2086df3ef80SGreg Tucker // Run sha512_sb jobs
2096df3ef80SGreg Tucker i = 0;
2106df3ef80SGreg Tucker while (i < jobs) {
2116df3ef80SGreg Tucker // Submit a new job
212592e639eSPablo de Lara len_rand = ISAL_SHA512_BLOCK_SIZE +
213592e639eSPablo de Lara ISAL_SHA512_BLOCK_SIZE * (rand() % MAX_RAND_UPDATE_BLOCKS);
2146df3ef80SGreg Tucker
2156df3ef80SGreg Tucker if (lens[i] > len_rand)
216*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
217*34bf6af2SPablo de Lara len_rand, ISAL_HASH_FIRST);
2186df3ef80SGreg Tucker else
219*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
220*34bf6af2SPablo de Lara lens[i], ISAL_HASH_ENTIRE);
221*34bf6af2SPablo de Lara if (ret)
222*34bf6af2SPablo de Lara return 1;
2236df3ef80SGreg Tucker
2246df3ef80SGreg Tucker // Returned ctx could be:
2253fb7b5f1SMarcel Cornu // - null context (we are just getting started and lanes aren't full yet),
2263fb7b5f1SMarcel Cornu // or
2273fb7b5f1SMarcel Cornu // - finished already (an ENTIRE we submitted or a previous LAST is
2283fb7b5f1SMarcel Cornu // returned), or
2296df3ef80SGreg Tucker // - an unfinished ctx, we will resubmit
2306df3ef80SGreg Tucker
2318cb7fe78SPablo de Lara if ((ctx == NULL) || isal_hash_ctx_complete(ctx)) {
2326df3ef80SGreg Tucker i++;
2336df3ef80SGreg Tucker continue;
2346df3ef80SGreg Tucker } else {
2353fb7b5f1SMarcel Cornu // unfinished ctx returned, choose another random update length and
2363fb7b5f1SMarcel Cornu // submit either UPDATE or LAST depending on the amount of buffer
2373fb7b5f1SMarcel Cornu // remaining
2388cb7fe78SPablo de Lara while ((ctx != NULL) && !(isal_hash_ctx_complete(ctx))) {
23987dde3adSTomasz Kantecki j = (unsigned long) (uintptr_t) (ctx->user_data); // Get
24087dde3adSTomasz Kantecki // index
24187dde3adSTomasz Kantecki // of the
24287dde3adSTomasz Kantecki // returned
24387dde3adSTomasz Kantecki // ctx
2446df3ef80SGreg Tucker buf_ptr[j] = bufs[j] + ctx->total_length;
245592e639eSPablo de Lara len_rand = (rand() % ISAL_SHA512_BLOCK_SIZE) *
2463fb7b5f1SMarcel Cornu (rand() % MAX_RAND_UPDATE_BLOCKS);
247122c1779SMarcel Cornu len_rem = lens[j] - (uint32_t) ctx->total_length;
2486df3ef80SGreg Tucker
2493fb7b5f1SMarcel Cornu if (len_rem <=
2503fb7b5f1SMarcel Cornu len_rand) // submit the rest of the job as LAST
251*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_submit(
252*34bf6af2SPablo de Lara mgr, &ctxpool[j], &ctx, buf_ptr[j], len_rem,
2538cb7fe78SPablo de Lara ISAL_HASH_LAST);
2546df3ef80SGreg Tucker else // submit the random update length as UPDATE
255*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_submit(
256*34bf6af2SPablo de Lara mgr, &ctxpool[j], &ctx, buf_ptr[j],
257*34bf6af2SPablo de Lara len_rand, ISAL_HASH_UPDATE);
258*34bf6af2SPablo de Lara if (ret)
259*34bf6af2SPablo de Lara return 1;
2603fb7b5f1SMarcel Cornu } // Either continue submitting any contexts returned here as
2613fb7b5f1SMarcel Cornu // UPDATE/LAST, or
2626df3ef80SGreg Tucker // go back to submitting new jobs using the index i.
2636df3ef80SGreg Tucker
2646df3ef80SGreg Tucker i++;
2656df3ef80SGreg Tucker }
2666df3ef80SGreg Tucker }
2676df3ef80SGreg Tucker
2686df3ef80SGreg Tucker // Start flushing finished jobs, end on last flushed
269*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
270*34bf6af2SPablo de Lara if (ret)
271*34bf6af2SPablo de Lara return 1;
2726df3ef80SGreg Tucker while (ctx) {
2738cb7fe78SPablo de Lara if (isal_hash_ctx_complete(ctx)) {
2746df3ef80SGreg Tucker debug_char('-');
275*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
276*34bf6af2SPablo de Lara if (ret)
277*34bf6af2SPablo de Lara return 1;
2786df3ef80SGreg Tucker continue;
2796df3ef80SGreg Tucker }
2806df3ef80SGreg Tucker // Resubmit unfinished job
28187dde3adSTomasz Kantecki i = (unsigned long) (uintptr_t) (ctx->user_data);
2826df3ef80SGreg Tucker buf_ptr[i] = bufs[i] + ctx->total_length; // update buffer pointer
283122c1779SMarcel Cornu len_rem = lens[i] - (uint32_t) ctx->total_length;
284592e639eSPablo de Lara len_rand = (rand() % ISAL_SHA512_BLOCK_SIZE) *
285592e639eSPablo de Lara (rand() % MAX_RAND_UPDATE_BLOCKS);
2866df3ef80SGreg Tucker debug_char('+');
2876df3ef80SGreg Tucker if (len_rem <= len_rand)
288*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
289*34bf6af2SPablo de Lara len_rem, ISAL_HASH_LAST);
2906df3ef80SGreg Tucker else
291*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
292*34bf6af2SPablo de Lara len_rand, ISAL_HASH_UPDATE);
293*34bf6af2SPablo de Lara if (ret)
294*34bf6af2SPablo de Lara return 1;
2956df3ef80SGreg Tucker
296*34bf6af2SPablo de Lara if (ctx == NULL) {
297*34bf6af2SPablo de Lara ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
298*34bf6af2SPablo de Lara if (ret)
299*34bf6af2SPablo de Lara return 1;
300*34bf6af2SPablo de Lara }
3016df3ef80SGreg Tucker }
3026df3ef80SGreg Tucker
3036df3ef80SGreg Tucker // Check result digest
3046df3ef80SGreg Tucker for (i = 0; i < jobs; i++) {
305592e639eSPablo de Lara for (j = 0; j < ISAL_SHA512_DIGEST_NWORDS; j++) {
3066df3ef80SGreg Tucker if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) {
3076df3ef80SGreg Tucker fail++;
30887dde3adSTomasz Kantecki printf("Test%d, digest%d fail %8llX <=> %8llX\n", i, j,
30987dde3adSTomasz Kantecki (unsigned long long) ctxpool[i].job.result_digest[j],
31087dde3adSTomasz Kantecki (unsigned long long) digest_ref[i][j]);
3116df3ef80SGreg Tucker }
3126df3ef80SGreg Tucker }
3136df3ef80SGreg Tucker }
3146df3ef80SGreg Tucker if (fail) {
3156df3ef80SGreg Tucker printf("Test failed function check %d\n", fail);
3160cabffc5SMarcel Cornu goto end;
3176df3ef80SGreg Tucker }
3186df3ef80SGreg Tucker
3196df3ef80SGreg Tucker putchar('.');
3206df3ef80SGreg Tucker fflush(0);
3216df3ef80SGreg Tucker } // random test t
3226df3ef80SGreg Tucker
3230cabffc5SMarcel Cornu end:
3240cabffc5SMarcel Cornu for (i = 0; i < TEST_BUFS; i++)
3250cabffc5SMarcel Cornu free(bufs[i]);
3260cabffc5SMarcel Cornu aligned_free(mgr);
3270cabffc5SMarcel Cornu
3286df3ef80SGreg Tucker if (fail)
3296df3ef80SGreg Tucker printf("Test failed function check %d\n", fail);
3306df3ef80SGreg Tucker else
3316df3ef80SGreg Tucker printf(" multibinary_sha512_update rand: Pass\n");
3326df3ef80SGreg Tucker
3336df3ef80SGreg Tucker return fail;
3346df3ef80SGreg Tucker }
335