xref: /isa-l_crypto/sha512_mb/sha512_mb_rand_update_test.c (revision 34bf6af21bafe61f414035ed3ba9f4578d60309f)
1 /**********************************************************************
2   Copyright(c) 2011-2016 Intel Corporation All rights reserved.
3 
4   Redistribution and use in source and binary forms, with or without
5   modification, are permitted provided that the following conditions
6   are met:
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9     * Redistributions in binary form must reproduce the above copyright
10       notice, this list of conditions and the following disclaimer in
11       the documentation and/or other materials provided with the
12       distribution.
13     * Neither the name of Intel Corporation nor the names of its
14       contributors may be used to endorse or promote products derived
15       from this software without specific prior written permission.
16 
17   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include "sha512_mb.h"
33 
34 #define TEST_LEN  (1024 * 1024)
35 #define TEST_BUFS 100
36 #ifndef RANDOMS
37 #define RANDOMS 10
38 #endif
39 #ifndef TEST_SEED
40 #define TEST_SEED 0x1234
41 #endif
42 
43 #define UPDATE_SIZE            13 * ISAL_SHA512_BLOCK_SIZE
44 #define MAX_RAND_UPDATE_BLOCKS (TEST_LEN / (16 * ISAL_SHA512_BLOCK_SIZE))
45 
46 #ifdef DEBUG
47 #define debug_char(x) putchar(x)
48 #else
49 #define debug_char(x)                                                                              \
50         do {                                                                                       \
51         } while (0)
52 #endif
53 
54 /* Reference digest global to reduce stack usage */
55 static uint64_t digest_ref[TEST_BUFS][ISAL_SHA512_DIGEST_NWORDS];
56 
57 extern void
58 sha512_ref(uint8_t *input_data, uint64_t *digest, uint32_t len);
59 
60 // Generates pseudo-random data
61 
62 void
rand_buffer(unsigned char * buf,const long buffer_size)63 rand_buffer(unsigned char *buf, const long buffer_size)
64 {
65         long i;
66         for (i = 0; i < buffer_size; i++)
67                 buf[i] = rand();
68 }
69 
70 int
main(void)71 main(void)
72 {
73         ISAL_SHA512_HASH_CTX_MGR *mgr = NULL;
74         ISAL_SHA512_HASH_CTX ctxpool[TEST_BUFS], *ctx = NULL;
75         uint32_t i, j, fail = 0;
76         uint32_t len_done, len_rem, len_rand;
77         unsigned char *bufs[TEST_BUFS];
78         unsigned char *buf_ptr[TEST_BUFS];
79         uint32_t lens[TEST_BUFS];
80         unsigned int joblen, jobs, t;
81         int ret;
82 
83         printf("multibinary_sha512_update test, %d sets of %dx%d max: ", RANDOMS, TEST_BUFS,
84                TEST_LEN);
85 
86         srand(TEST_SEED);
87 
88         ret = posix_memalign((void *) &mgr, 16, sizeof(ISAL_SHA512_HASH_CTX_MGR));
89         if ((ret != 0) || (mgr == NULL)) {
90                 printf("posix_memalign failed test aborted\n");
91                 return 1;
92         }
93 
94         ret = isal_sha512_ctx_mgr_init(mgr);
95         if (ret)
96                 return 1;
97 
98         for (i = 0; i < TEST_BUFS; i++) {
99                 // Allocate and fill buffer
100                 bufs[i] = (unsigned char *) malloc(TEST_LEN);
101                 buf_ptr[i] = bufs[i];
102                 if (bufs[i] == NULL) {
103                         printf("malloc failed test aborted\n");
104                         fail++;
105                         goto end;
106                 }
107                 rand_buffer(bufs[i], TEST_LEN);
108 
109                 // Init ctx contents
110                 isal_hash_ctx_init(&ctxpool[i]);
111                 ctxpool[i].user_data = (void *) ((uint64_t) i);
112 
113                 // Run reference test
114                 sha512_ref(bufs[i], digest_ref[i], TEST_LEN);
115         }
116 
117         // Run sb_sha512 tests
118         for (i = 0; i < TEST_BUFS;) {
119                 len_done = (uint32_t) ((uintptr_t) buf_ptr[i] - (uintptr_t) bufs[i]);
120                 len_rem = TEST_LEN - len_done;
121 
122                 if (len_done == 0)
123                         ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
124                                                          UPDATE_SIZE, ISAL_HASH_FIRST);
125                 else if (len_rem <= UPDATE_SIZE)
126                         ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
127                                                          len_rem, ISAL_HASH_LAST);
128                 else
129                         ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
130                                                          UPDATE_SIZE, ISAL_HASH_UPDATE);
131                 if (ret)
132                         return 1;
133 
134                 // Add jobs while available or finished
135                 if ((ctx == NULL) || isal_hash_ctx_complete(ctx)) {
136                         i++;
137                         continue;
138                 }
139                 // Resubmit unfinished job
140                 i = (unsigned long) (uintptr_t) (ctx->user_data);
141                 buf_ptr[i] += UPDATE_SIZE;
142         }
143 
144         // Start flushing finished jobs, end on last flushed
145         ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
146         if (ret)
147                 return 1;
148         while (ctx) {
149                 if (isal_hash_ctx_complete(ctx)) {
150                         debug_char('-');
151                         ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
152                         if (ret)
153                                 return 1;
154                         continue;
155                 }
156                 // Resubmit unfinished job
157                 i = (unsigned long) (uintptr_t) (ctx->user_data);
158                 buf_ptr[i] += UPDATE_SIZE;
159 
160                 len_done = (int) ((uintptr_t) buf_ptr[i] - (uintptr_t) bufs[i]);
161                 len_rem = TEST_LEN - len_done;
162 
163                 if (len_rem <= UPDATE_SIZE)
164                         ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
165                                                          len_rem, ISAL_HASH_LAST);
166                 else
167                         ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
168                                                          UPDATE_SIZE, ISAL_HASH_UPDATE);
169                 if (ret)
170                         return 1;
171 
172                 if (ctx == NULL) {
173                         ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
174                         if (ret)
175                                 return 1;
176                 }
177         }
178 
179         // Check digests
180         for (i = 0; i < TEST_BUFS; i++) {
181                 for (j = 0; j < ISAL_SHA512_DIGEST_NWORDS; j++) {
182                         if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) {
183                                 fail++;
184                                 printf("Test%d fixed size, digest%d fail %8llX <=> %8llX", i, j,
185                                        (unsigned long long) ctxpool[i].job.result_digest[j],
186                                        (unsigned long long) digest_ref[i][j]);
187                         }
188                 }
189         }
190         putchar('.');
191 
192         // Run tests with random size and number of jobs
193         for (t = 0; t < RANDOMS; t++) {
194                 jobs = rand() % (TEST_BUFS);
195 
196                 for (i = 0; i < jobs; i++) {
197                         joblen = rand() % (TEST_LEN);
198                         rand_buffer(bufs[i], joblen);
199                         lens[i] = joblen;
200                         buf_ptr[i] = bufs[i];
201                         sha512_ref(bufs[i], digest_ref[i], lens[i]);
202                 }
203 
204                 ret = isal_sha512_ctx_mgr_init(mgr);
205                 if (ret)
206                         return 1;
207 
208                 // Run sha512_sb jobs
209                 i = 0;
210                 while (i < jobs) {
211                         // Submit a new job
212                         len_rand = ISAL_SHA512_BLOCK_SIZE +
213                                    ISAL_SHA512_BLOCK_SIZE * (rand() % MAX_RAND_UPDATE_BLOCKS);
214 
215                         if (lens[i] > len_rand)
216                                 ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
217                                                                  len_rand, ISAL_HASH_FIRST);
218                         else
219                                 ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
220                                                                  lens[i], ISAL_HASH_ENTIRE);
221                         if (ret)
222                                 return 1;
223 
224                         // Returned ctx could be:
225                         //  - null context (we are just getting started and lanes aren't full yet),
226                         //  or
227                         //  - finished already (an ENTIRE we submitted or a previous LAST is
228                         //  returned), or
229                         //  - an unfinished ctx, we will resubmit
230 
231                         if ((ctx == NULL) || isal_hash_ctx_complete(ctx)) {
232                                 i++;
233                                 continue;
234                         } else {
235                                 // unfinished ctx returned, choose another random update length and
236                                 // submit either UPDATE or LAST depending on the amount of buffer
237                                 // remaining
238                                 while ((ctx != NULL) && !(isal_hash_ctx_complete(ctx))) {
239                                         j = (unsigned long) (uintptr_t) (ctx->user_data); // Get
240                                                                                           // index
241                                                                                           // of the
242                                                                                           // returned
243                                                                                           // ctx
244                                         buf_ptr[j] = bufs[j] + ctx->total_length;
245                                         len_rand = (rand() % ISAL_SHA512_BLOCK_SIZE) *
246                                                    (rand() % MAX_RAND_UPDATE_BLOCKS);
247                                         len_rem = lens[j] - (uint32_t) ctx->total_length;
248 
249                                         if (len_rem <=
250                                             len_rand) // submit the rest of the job as LAST
251                                                 ret = isal_sha512_ctx_mgr_submit(
252                                                         mgr, &ctxpool[j], &ctx, buf_ptr[j], len_rem,
253                                                         ISAL_HASH_LAST);
254                                         else // submit the random update length as UPDATE
255                                                 ret = isal_sha512_ctx_mgr_submit(
256                                                         mgr, &ctxpool[j], &ctx, buf_ptr[j],
257                                                         len_rand, ISAL_HASH_UPDATE);
258                                         if (ret)
259                                                 return 1;
260                                 } // Either continue submitting any contexts returned here as
261                                   // UPDATE/LAST, or
262                                 // go back to submitting new jobs using the index i.
263 
264                                 i++;
265                         }
266                 }
267 
268                 // Start flushing finished jobs, end on last flushed
269                 ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
270                 if (ret)
271                         return 1;
272                 while (ctx) {
273                         if (isal_hash_ctx_complete(ctx)) {
274                                 debug_char('-');
275                                 ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
276                                 if (ret)
277                                         return 1;
278                                 continue;
279                         }
280                         // Resubmit unfinished job
281                         i = (unsigned long) (uintptr_t) (ctx->user_data);
282                         buf_ptr[i] = bufs[i] + ctx->total_length; // update buffer pointer
283                         len_rem = lens[i] - (uint32_t) ctx->total_length;
284                         len_rand = (rand() % ISAL_SHA512_BLOCK_SIZE) *
285                                    (rand() % MAX_RAND_UPDATE_BLOCKS);
286                         debug_char('+');
287                         if (len_rem <= len_rand)
288                                 ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
289                                                                  len_rem, ISAL_HASH_LAST);
290                         else
291                                 ret = isal_sha512_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, buf_ptr[i],
292                                                                  len_rand, ISAL_HASH_UPDATE);
293                         if (ret)
294                                 return 1;
295 
296                         if (ctx == NULL) {
297                                 ret = isal_sha512_ctx_mgr_flush(mgr, &ctx);
298                                 if (ret)
299                                         return 1;
300                         }
301                 }
302 
303                 // Check result digest
304                 for (i = 0; i < jobs; i++) {
305                         for (j = 0; j < ISAL_SHA512_DIGEST_NWORDS; j++) {
306                                 if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) {
307                                         fail++;
308                                         printf("Test%d, digest%d fail %8llX <=> %8llX\n", i, j,
309                                                (unsigned long long) ctxpool[i].job.result_digest[j],
310                                                (unsigned long long) digest_ref[i][j]);
311                                 }
312                         }
313                 }
314                 if (fail) {
315                         printf("Test failed function check %d\n", fail);
316                         goto end;
317                 }
318 
319                 putchar('.');
320                 fflush(0);
321         } // random test t
322 
323 end:
324         for (i = 0; i < TEST_BUFS; i++)
325                 free(bufs[i]);
326         aligned_free(mgr);
327 
328         if (fail)
329                 printf("Test failed function check %d\n", fail);
330         else
331                 printf(" multibinary_sha512_update rand: Pass\n");
332 
333         return fail;
334 }
335