153dc9fa0SGreg Tucker /**********************************************************************
253dc9fa0SGreg Tucker Copyright(c) 2011-2017 Intel Corporation All rights reserved.
353dc9fa0SGreg Tucker
453dc9fa0SGreg Tucker Redistribution and use in source and binary forms, with or without
553dc9fa0SGreg Tucker modification, are permitted provided that the following conditions
653dc9fa0SGreg Tucker are met:
753dc9fa0SGreg Tucker * Redistributions of source code must retain the above copyright
853dc9fa0SGreg Tucker notice, this list of conditions and the following disclaimer.
953dc9fa0SGreg Tucker * Redistributions in binary form must reproduce the above copyright
1053dc9fa0SGreg Tucker notice, this list of conditions and the following disclaimer in
1153dc9fa0SGreg Tucker the documentation and/or other materials provided with the
1253dc9fa0SGreg Tucker distribution.
1353dc9fa0SGreg Tucker * Neither the name of Intel Corporation nor the names of its
1453dc9fa0SGreg Tucker contributors may be used to endorse or promote products derived
1553dc9fa0SGreg Tucker from this software without specific prior written permission.
1653dc9fa0SGreg Tucker
1753dc9fa0SGreg Tucker THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1853dc9fa0SGreg Tucker "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1953dc9fa0SGreg Tucker LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2053dc9fa0SGreg Tucker A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2153dc9fa0SGreg Tucker OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2253dc9fa0SGreg Tucker SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2353dc9fa0SGreg Tucker LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2453dc9fa0SGreg Tucker DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2553dc9fa0SGreg Tucker THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2653dc9fa0SGreg Tucker (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2753dc9fa0SGreg Tucker OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2853dc9fa0SGreg Tucker **********************************************************************/
2953dc9fa0SGreg Tucker
3053dc9fa0SGreg Tucker #include <stdlib.h>
3153dc9fa0SGreg Tucker #include <stdint.h>
3253dc9fa0SGreg Tucker #include <stdarg.h>
3353dc9fa0SGreg Tucker #include <stdio.h>
3453dc9fa0SGreg Tucker #include <assert.h>
3577e513c6SMarcel Cornu #include "isal_crypto_api.h"
3653dc9fa0SGreg Tucker #include "rolling_hashx.h"
3753dc9fa0SGreg Tucker #include "sha256_mb.h"
3853dc9fa0SGreg Tucker #include "test.h"
3953dc9fa0SGreg Tucker
4053dc9fa0SGreg Tucker #define MAX_BUFFER_SIZE 128 * 1024 * 1024
410a437795SPablo de Lara #define HASH_POOL_SIZE ISAL_SHA256_MAX_LANES
4253dc9fa0SGreg Tucker
4353dc9fa0SGreg Tucker #ifndef TEST_SEED
4453dc9fa0SGreg Tucker #define TEST_SEED 0x1234
4553dc9fa0SGreg Tucker #endif
4653dc9fa0SGreg Tucker
4753dc9fa0SGreg Tucker #define FILTER_BITS 10
4853dc9fa0SGreg Tucker #define FILTER_SIZE (1 << FILTER_BITS)
4953dc9fa0SGreg Tucker #define FILTER_MASK (FILTER_SIZE - 1)
5053dc9fa0SGreg Tucker
5153dc9fa0SGreg Tucker #define BITS_TO_INDEX_LONG 6
5253dc9fa0SGreg Tucker #define MASK_TO_INDEX_LONG ((1 << BITS_TO_INDEX_LONG) - 1)
5353dc9fa0SGreg Tucker
5453dc9fa0SGreg Tucker // Globals
550a437795SPablo de Lara ISAL_SHA256_HASH_CTX ctxpool[ISAL_SHA256_MAX_LANES], *last_ctx;
560a437795SPablo de Lara ISAL_SHA256_HASH_CTX_MGR mb_hash_mgr;
5753dc9fa0SGreg Tucker uint64_t filter_table[FILTER_SIZE];
5853dc9fa0SGreg Tucker unsigned long chunks_created = 0;
5953dc9fa0SGreg Tucker unsigned long filter_hits = 0;
6053dc9fa0SGreg Tucker
6153dc9fa0SGreg Tucker // Example function to run on each chunk
6253dc9fa0SGreg Tucker
6359ca9063SMarcel Cornu void
run_fragment(ISAL_SHA256_HASH_CTX * ctx)640a437795SPablo de Lara run_fragment(ISAL_SHA256_HASH_CTX *ctx)
6553dc9fa0SGreg Tucker {
6653dc9fa0SGreg Tucker uint64_t lookup, set_hash;
6753dc9fa0SGreg Tucker unsigned int lookup_hash;
6853dc9fa0SGreg Tucker uint32_t idx;
6953dc9fa0SGreg Tucker
7053dc9fa0SGreg Tucker chunks_created++;
7153dc9fa0SGreg Tucker
7253dc9fa0SGreg Tucker // Run a simple lookup filter on chunk using digest
7353dc9fa0SGreg Tucker lookup_hash = ctx->job.result_digest[0] & FILTER_MASK;
7453dc9fa0SGreg Tucker lookup = filter_table[lookup_hash];
7553dc9fa0SGreg Tucker
7653dc9fa0SGreg Tucker idx = ctx->job.result_digest[1];
7753dc9fa0SGreg Tucker
7853dc9fa0SGreg Tucker set_hash = 1 << (idx & MASK_TO_INDEX_LONG) |
7953dc9fa0SGreg Tucker 1 << ((idx >> BITS_TO_INDEX_LONG) & MASK_TO_INDEX_LONG) |
8053dc9fa0SGreg Tucker 1 << ((idx >> (2 * BITS_TO_INDEX_LONG)) & MASK_TO_INDEX_LONG);
8153dc9fa0SGreg Tucker
8253dc9fa0SGreg Tucker if ((lookup & set_hash) == set_hash)
8353dc9fa0SGreg Tucker filter_hits++;
8453dc9fa0SGreg Tucker else
8553dc9fa0SGreg Tucker filter_table[lookup_hash] = lookup | set_hash;
8653dc9fa0SGreg Tucker }
8753dc9fa0SGreg Tucker
88487b772bSPablo de Lara static int
setup_chunk_processing(void)8959ca9063SMarcel Cornu setup_chunk_processing(void)
9053dc9fa0SGreg Tucker {
9153dc9fa0SGreg Tucker int i;
92487b772bSPablo de Lara int ret = isal_sha256_ctx_mgr_init(&mb_hash_mgr);
9353dc9fa0SGreg Tucker
94487b772bSPablo de Lara if (ret)
95487b772bSPablo de Lara return -1;
9653dc9fa0SGreg Tucker
9753dc9fa0SGreg Tucker for (i = 0; i < HASH_POOL_SIZE; i++)
988cb7fe78SPablo de Lara isal_hash_ctx_init(&ctxpool[i]);
9953dc9fa0SGreg Tucker
10053dc9fa0SGreg Tucker last_ctx = &ctxpool[0];
101487b772bSPablo de Lara
102487b772bSPablo de Lara return 0;
10353dc9fa0SGreg Tucker }
10453dc9fa0SGreg Tucker
105487b772bSPablo de Lara static ISAL_SHA256_HASH_CTX *
get_next_job_ctx(void)10659ca9063SMarcel Cornu get_next_job_ctx(void)
10753dc9fa0SGreg Tucker {
108487b772bSPablo de Lara int i, ret;
1090a437795SPablo de Lara ISAL_SHA256_HASH_CTX *ctx;
11053dc9fa0SGreg Tucker
1118cb7fe78SPablo de Lara if (last_ctx && isal_hash_ctx_complete(last_ctx))
11253dc9fa0SGreg Tucker return last_ctx;
11353dc9fa0SGreg Tucker
11453dc9fa0SGreg Tucker for (i = 0; i < HASH_POOL_SIZE; i++) {
1158cb7fe78SPablo de Lara if (isal_hash_ctx_complete(&ctxpool[i]))
11653dc9fa0SGreg Tucker return &ctxpool[i];
11753dc9fa0SGreg Tucker }
118487b772bSPablo de Lara ret = isal_sha256_ctx_mgr_flush(&mb_hash_mgr, &ctx);
119487b772bSPablo de Lara if (ret)
120487b772bSPablo de Lara return NULL;
121487b772bSPablo de Lara
12253dc9fa0SGreg Tucker return ctx;
12353dc9fa0SGreg Tucker }
12453dc9fa0SGreg Tucker
12559ca9063SMarcel Cornu void
put_next_job_ctx(ISAL_SHA256_HASH_CTX * ctx)1260a437795SPablo de Lara put_next_job_ctx(ISAL_SHA256_HASH_CTX *ctx)
12753dc9fa0SGreg Tucker {
1288cb7fe78SPablo de Lara if (ctx && isal_hash_ctx_complete(ctx))
12953dc9fa0SGreg Tucker last_ctx = ctx;
13053dc9fa0SGreg Tucker
13153dc9fa0SGreg Tucker run_fragment(ctx);
13253dc9fa0SGreg Tucker }
13353dc9fa0SGreg Tucker
134487b772bSPablo de Lara static int
process_chunk(uint8_t * buff,int len)13559ca9063SMarcel Cornu process_chunk(uint8_t *buff, int len)
13653dc9fa0SGreg Tucker {
1370a437795SPablo de Lara ISAL_SHA256_HASH_CTX *ctx;
138487b772bSPablo de Lara int ret;
13953dc9fa0SGreg Tucker
14053dc9fa0SGreg Tucker ctx = get_next_job_ctx();
141487b772bSPablo de Lara if (ctx != NULL)
142487b772bSPablo de Lara return -1;
143487b772bSPablo de Lara
144487b772bSPablo de Lara ret = isal_sha256_ctx_mgr_submit(&mb_hash_mgr, ctx, &ctx, buff, len, ISAL_HASH_ENTIRE);
145487b772bSPablo de Lara if (ret)
146487b772bSPablo de Lara return -1;
14753dc9fa0SGreg Tucker
14853dc9fa0SGreg Tucker if (ctx)
14953dc9fa0SGreg Tucker put_next_job_ctx(ctx);
150487b772bSPablo de Lara
151487b772bSPablo de Lara return 0;
15253dc9fa0SGreg Tucker }
15353dc9fa0SGreg Tucker
154487b772bSPablo de Lara static int
finish_chunk_processing(void)15559ca9063SMarcel Cornu finish_chunk_processing(void)
15653dc9fa0SGreg Tucker {
1570a437795SPablo de Lara ISAL_SHA256_HASH_CTX *ctx;
158487b772bSPablo de Lara int ret;
15953dc9fa0SGreg Tucker
160487b772bSPablo de Lara do {
161487b772bSPablo de Lara ret = isal_sha256_ctx_mgr_flush(&mb_hash_mgr, &ctx);
162487b772bSPablo de Lara if (ret)
163487b772bSPablo de Lara return -1;
164487b772bSPablo de Lara if (ctx != NULL)
16553dc9fa0SGreg Tucker run_fragment(ctx);
166487b772bSPablo de Lara } while (ctx != NULL);
167487b772bSPablo de Lara
168487b772bSPablo de Lara return 0;
16953dc9fa0SGreg Tucker }
17053dc9fa0SGreg Tucker
17159ca9063SMarcel Cornu int
main(void)17259ca9063SMarcel Cornu main(void)
17353dc9fa0SGreg Tucker {
174487b772bSPablo de Lara int i, w, match, ret, res = -1;
17553dc9fa0SGreg Tucker uint8_t *buffer, *p;
17653dc9fa0SGreg Tucker uint32_t mask, trigger, offset = 0;
17753dc9fa0SGreg Tucker uint32_t min_chunk, max_chunk, mean_chunk;
17853dc9fa0SGreg Tucker long remain;
179*1e0b122eSMarcel Cornu struct isal_rh_state2 state;
18053dc9fa0SGreg Tucker struct perf start, stop;
18153dc9fa0SGreg Tucker
18253dc9fa0SGreg Tucker // Chunking parameters
18353dc9fa0SGreg Tucker w = 32;
18453dc9fa0SGreg Tucker min_chunk = 1024;
18553dc9fa0SGreg Tucker mean_chunk = 4 * 1024;
18653dc9fa0SGreg Tucker max_chunk = 32 * 1024;
18777e513c6SMarcel Cornu ret = isal_rolling_hashx_mask_gen(mean_chunk, 0, &mask);
18877e513c6SMarcel Cornu
18977e513c6SMarcel Cornu if (ret != ISAL_CRYPTO_ERR_NONE) {
19077e513c6SMarcel Cornu printf(" Error generating mask");
19177e513c6SMarcel Cornu return -1;
19277e513c6SMarcel Cornu }
19377e513c6SMarcel Cornu
19453dc9fa0SGreg Tucker trigger = rand() & mask;
19553dc9fa0SGreg Tucker
19653dc9fa0SGreg Tucker printf("chunk and hash test w=%d, min=%d, target_ave=%d, max=%d:\n", w, min_chunk,
19753dc9fa0SGreg Tucker mean_chunk, max_chunk);
19853dc9fa0SGreg Tucker
19953dc9fa0SGreg Tucker if (min_chunk < w || min_chunk > max_chunk) {
20053dc9fa0SGreg Tucker printf(" Improper parameters selected\n");
20153dc9fa0SGreg Tucker return -1;
20253dc9fa0SGreg Tucker }
20353dc9fa0SGreg Tucker
20453dc9fa0SGreg Tucker if ((buffer = malloc(MAX_BUFFER_SIZE)) == NULL) {
20553dc9fa0SGreg Tucker printf("cannot allocate mem\n");
20653dc9fa0SGreg Tucker return -1;
20753dc9fa0SGreg Tucker }
20853dc9fa0SGreg Tucker // Initialize buffer with random data
20953dc9fa0SGreg Tucker srand(TEST_SEED);
21053dc9fa0SGreg Tucker for (i = 0; i < MAX_BUFFER_SIZE; i++)
21153dc9fa0SGreg Tucker buffer[i] = rand();
21253dc9fa0SGreg Tucker
21353dc9fa0SGreg Tucker // Start chunking test with multi-buffer hashing of results
21453dc9fa0SGreg Tucker perf_start(&start);
21553dc9fa0SGreg Tucker
21677e513c6SMarcel Cornu isal_rolling_hash2_init(&state, w);
217487b772bSPablo de Lara if (setup_chunk_processing() < 0) {
218487b772bSPablo de Lara printf("Setup chunk failed\n");
219487b772bSPablo de Lara goto end;
220487b772bSPablo de Lara }
22153dc9fa0SGreg Tucker
22253dc9fa0SGreg Tucker p = buffer;
22353dc9fa0SGreg Tucker remain = MAX_BUFFER_SIZE;
22453dc9fa0SGreg Tucker
22553dc9fa0SGreg Tucker while (remain > max_chunk) {
22653dc9fa0SGreg Tucker // Skip to min chunk
22777e513c6SMarcel Cornu isal_rolling_hash2_reset(&state, p + min_chunk - w);
22877e513c6SMarcel Cornu isal_rolling_hash2_run(&state, p + min_chunk, max_chunk - min_chunk, mask, trigger,
22977e513c6SMarcel Cornu &offset, &match);
23053dc9fa0SGreg Tucker
23153dc9fa0SGreg Tucker process_chunk(p, min_chunk + offset);
23253dc9fa0SGreg Tucker
23353dc9fa0SGreg Tucker p += offset + min_chunk;
23453dc9fa0SGreg Tucker remain -= (offset + min_chunk);
23553dc9fa0SGreg Tucker }
23653dc9fa0SGreg Tucker
23753dc9fa0SGreg Tucker while (remain > min_chunk) {
23877e513c6SMarcel Cornu isal_rolling_hash2_reset(&state, p + min_chunk - w);
23977e513c6SMarcel Cornu isal_rolling_hash2_run(&state, p + min_chunk, remain - min_chunk, mask, trigger,
24077e513c6SMarcel Cornu &offset, &match);
24153dc9fa0SGreg Tucker
24253dc9fa0SGreg Tucker process_chunk(p, min_chunk + offset);
24353dc9fa0SGreg Tucker
24453dc9fa0SGreg Tucker p += offset + min_chunk;
24553dc9fa0SGreg Tucker remain -= (offset + min_chunk);
24653dc9fa0SGreg Tucker }
24753dc9fa0SGreg Tucker
24853dc9fa0SGreg Tucker if (remain > 0)
24953dc9fa0SGreg Tucker process_chunk(p, remain);
25053dc9fa0SGreg Tucker
251487b772bSPablo de Lara if (finish_chunk_processing() < 0)
252487b772bSPablo de Lara goto end;
253487b772bSPablo de Lara
25453dc9fa0SGreg Tucker perf_stop(&stop);
25553dc9fa0SGreg Tucker
25653dc9fa0SGreg Tucker printf("chunking_with_mb_hash: ");
25753dc9fa0SGreg Tucker perf_print(stop, start, MAX_BUFFER_SIZE);
25853dc9fa0SGreg Tucker
25953dc9fa0SGreg Tucker printf(" found %ld chunks, ave_len=%ld, filter hits=%ld\n", chunks_created,
26053dc9fa0SGreg Tucker MAX_BUFFER_SIZE / chunks_created, filter_hits);
26153dc9fa0SGreg Tucker
262487b772bSPablo de Lara res = 0;
263487b772bSPablo de Lara end:
264487b772bSPablo de Lara free(buffer);
265487b772bSPablo de Lara return res;
26653dc9fa0SGreg Tucker }
267