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 <string.h>
33 #include "sha1_mb.h"
34 #include "endian_helper.h"
35
36 typedef uint32_t DigestSHA1[ISAL_SHA1_DIGEST_NWORDS];
37
38 #define MSGS 7
39 #define NUM_JOBS 1000
40
41 #define PSEUDO_RANDOM_NUM(seed) ((seed) * 5 + ((seed) * (seed)) / 64) % MSGS
42 static uint8_t msg1[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
43 static DigestSHA1 expResultDigest1 = { 0x84983E44, 0x1C3BD26E, 0xBAAE4AA1, 0xF95129E5, 0xE54670F1 };
44
45 static uint8_t msg2[] = "0123456789:;<=>?@ABCDEFGHIJKLMNO";
46 static DigestSHA1 expResultDigest2 = { 0xB7C66452, 0x0FD122B3, 0x55D539F2, 0xA35E6FAA, 0xC2A5A11D };
47
48 static uint8_t msg3[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
49 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
50 "0123456789:;<";
51 static DigestSHA1 expResultDigest3 = { 0x127729B6, 0xA8B2F8A0, 0xA4DDC819, 0x08E1D8B3, 0x67CEEA55 };
52
53 static uint8_t msg4[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
54 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
55 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
56 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQR";
57 static DigestSHA1 expResultDigest4 = { 0xFDDE2D00, 0xABD5B7A3, 0x699DE6F2, 0x3FF1D1AC, 0x3B872AC2 };
58
59 static uint8_t msg5[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
60 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
61 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
62 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
63 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
64 "0123456789:;<=>?";
65 static DigestSHA1 expResultDigest5 = { 0xE7FCA85C, 0xA4AB3740, 0x6A180B32, 0x0B8D362C, 0x622A96E6 };
66
67 static uint8_t msg6[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
68 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
69 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
70 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
71 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
72 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
73 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU";
74 static DigestSHA1 expResultDigest6 = { 0x505B0686, 0xE1ACDF42, 0xB3588B5A, 0xB043D52C, 0x6D8C7444 };
75
76 static uint8_t msg7[] = "";
77 static DigestSHA1 expResultDigest7 = { 0xDA39A3EE, 0x5E6B4B0D, 0x3255BFEF, 0x95601890, 0xAFD80709 };
78
79 static uint8_t *msgs[MSGS] = { msg1, msg2, msg3, msg4, msg5, msg6, msg7 };
80
81 static uint32_t *expResultDigest[MSGS] = { expResultDigest1, expResultDigest2, expResultDigest3,
82 expResultDigest4, expResultDigest5, expResultDigest6,
83 expResultDigest7 };
84
85 #define NUM_CHUNKS 4
86 #define DATA_BUF_LEN 4096
87 static int
non_blocksize_updates_test(ISAL_SHA1_HASH_CTX_MGR * mgr)88 non_blocksize_updates_test(ISAL_SHA1_HASH_CTX_MGR *mgr)
89 {
90 ISAL_SHA1_HASH_CTX ctx_refer;
91 ISAL_SHA1_HASH_CTX ctx_pool[NUM_CHUNKS];
92 ISAL_SHA1_HASH_CTX *ctx = NULL;
93 int rc;
94
95 const int update_chunks[NUM_CHUNKS] = { 32, 64, 128, 256 };
96 unsigned char data_buf[DATA_BUF_LEN];
97
98 memset(data_buf, 0xA, DATA_BUF_LEN);
99
100 // Init contexts before first use
101 isal_hash_ctx_init(&ctx_refer);
102
103 rc = isal_sha1_ctx_mgr_submit(mgr, &ctx_refer, &ctx, data_buf, DATA_BUF_LEN,
104 ISAL_HASH_ENTIRE);
105 if (rc)
106 return -1;
107
108 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx);
109 if (rc)
110 return -1;
111
112 for (int c = 0; c < NUM_CHUNKS; c++) {
113 int chunk = update_chunks[c];
114 isal_hash_ctx_init(&ctx_pool[c]);
115 rc = isal_sha1_ctx_mgr_submit(mgr, &ctx_pool[c], &ctx, NULL, 0, ISAL_HASH_FIRST);
116 if (rc)
117 return -1;
118 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx);
119 if (rc)
120 return -1;
121 for (int i = 0; i * chunk < DATA_BUF_LEN; i++) {
122 rc = isal_sha1_ctx_mgr_submit(mgr, &ctx_pool[c], &ctx, data_buf + i * chunk,
123 chunk, ISAL_HASH_UPDATE);
124 if (rc)
125 return -1;
126 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx);
127 if (rc)
128 return -1;
129 }
130 }
131
132 for (int c = 0; c < NUM_CHUNKS; c++) {
133 rc = isal_sha1_ctx_mgr_submit(mgr, &ctx_pool[c], &ctx, NULL, 0, ISAL_HASH_LAST);
134 if (rc)
135 return -1;
136 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx);
137 if (rc)
138 return -1;
139 if (ctx_pool[c].status != ISAL_HASH_CTX_STS_COMPLETE) {
140 return -1;
141 }
142 for (int i = 0; i < ISAL_SHA1_DIGEST_NWORDS; i++) {
143 if (ctx_refer.job.result_digest[i] != ctx_pool[c].job.result_digest[i]) {
144 printf("sm3 calc error! chunk %d, digest[%d], (%d) != (%d)\n",
145 update_chunks[c], i, ctx_refer.job.result_digest[i],
146 ctx_pool[c].job.result_digest[i]);
147 return -2;
148 }
149 }
150 }
151 return 0;
152 }
153
154 int
main(void)155 main(void)
156 {
157 ISAL_SHA1_HASH_CTX_MGR *mgr = NULL;
158 ISAL_SHA1_HASH_CTX ctxpool[NUM_JOBS], *ctx = NULL;
159 uint32_t i, j, k, t, checked = 0;
160 uint32_t *good;
161 int rc, ret = -1;
162
163 rc = posix_memalign((void *) &mgr, 16, sizeof(ISAL_SHA1_HASH_CTX_MGR));
164 if ((rc != 0) || (mgr == NULL)) {
165 printf("posix_memalign failed test aborted\n");
166 return 1;
167 }
168
169 rc = isal_sha1_ctx_mgr_init(mgr);
170 if (rc)
171 goto end;
172
173 // Init contexts before first use
174 for (i = 0; i < MSGS; i++) {
175 isal_hash_ctx_init(&ctxpool[i]);
176 ctxpool[i].user_data = (void *) ((uint64_t) i);
177 }
178
179 for (i = 0; i < MSGS; i++) {
180 rc = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, msgs[i],
181 (uint32_t) strlen((char *) msgs[i]),
182 ISAL_HASH_ENTIRE);
183 if (rc)
184 goto end;
185
186 if (ctx) {
187 t = (uint32_t) ((uintptr_t) (ctx->user_data));
188 good = expResultDigest[t];
189 checked++;
190 for (j = 0; j < ISAL_SHA1_DIGEST_NWORDS; j++) {
191 if (good[j] != ctxpool[t].job.result_digest[j]) {
192 printf("Test %d, digest %d is %08X, should be %08X\n", t, j,
193 ctxpool[t].job.result_digest[j], good[j]);
194 goto end;
195 }
196 }
197
198 if (ctx->error) {
199 printf("Something bad happened during the submit."
200 " Error code: %d",
201 ctx->error);
202 goto end;
203 }
204 }
205 }
206
207 while (1) {
208 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx);
209 if (rc)
210 goto end;
211
212 if (ctx) {
213 t = (uint32_t) ((uintptr_t) (ctx->user_data));
214 good = expResultDigest[t];
215 checked++;
216 for (j = 0; j < ISAL_SHA1_DIGEST_NWORDS; j++) {
217 if (good[j] != ctxpool[t].job.result_digest[j]) {
218 printf("Test %d, digest %d is %08X, should be %08X\n", t, j,
219 ctxpool[t].job.result_digest[j], good[j]);
220 goto end;
221 }
222 }
223
224 if (ctx->error) {
225 printf("Something bad happened during the submit."
226 " Error code: %d",
227 ctx->error);
228 goto end;
229 }
230 } else {
231 break;
232 }
233 }
234
235 // do larger test in pseudo-random order
236
237 // Init contexts before first use
238 for (i = 0; i < NUM_JOBS; i++) {
239 isal_hash_ctx_init(&ctxpool[i]);
240 ctxpool[i].user_data = (void *) ((uint64_t) i);
241 }
242
243 checked = 0;
244 for (i = 0; i < NUM_JOBS; i++) {
245 j = PSEUDO_RANDOM_NUM(i);
246 rc = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, msgs[j],
247 (uint32_t) strlen((char *) msgs[j]),
248 ISAL_HASH_ENTIRE);
249 if (rc)
250 goto end;
251 if (ctx) {
252 t = (uint32_t) ((uintptr_t) (ctx->user_data));
253 k = PSEUDO_RANDOM_NUM(t);
254 good = expResultDigest[k];
255 checked++;
256 for (j = 0; j < ISAL_SHA1_DIGEST_NWORDS; j++) {
257 if (good[j] != ctxpool[t].job.result_digest[j]) {
258 printf("Test %d, digest %d is %08X, should be %08X\n", t, j,
259 ctxpool[t].job.result_digest[j], good[j]);
260 goto end;
261 }
262 }
263
264 if (ctx->error) {
265 printf("Something bad happened during the"
266 " submit. Error code: %d",
267 ctx->error);
268 goto end;
269 }
270
271 t = (uint32_t) ((uintptr_t) (ctx->user_data));
272 k = PSEUDO_RANDOM_NUM(t);
273 }
274 }
275 while (1) {
276 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx);
277
278 if (rc)
279 goto end;
280 if (ctx) {
281 t = (uint32_t) ((uintptr_t) (ctx->user_data));
282 k = PSEUDO_RANDOM_NUM(t);
283 good = expResultDigest[k];
284 checked++;
285 for (j = 0; j < ISAL_SHA1_DIGEST_NWORDS; j++) {
286 if (good[j] != ctxpool[t].job.result_digest[j]) {
287 printf("Test %d, digest %d is %08X, should be %08X\n", t, j,
288 ctxpool[t].job.result_digest[j], good[j]);
289 goto end;
290 }
291 }
292
293 if (ctx->error) {
294 printf("Something bad happened during the submit."
295 " Error code: %d",
296 ctx->error);
297 goto end;
298 }
299 } else {
300 break;
301 }
302 }
303
304 if (checked != NUM_JOBS) {
305 printf("only tested %d rather than %d\n", checked, NUM_JOBS);
306 goto end;
307 }
308
309 rc = non_blocksize_updates_test(mgr);
310 if (rc) {
311 printf("multi updates test fail %d\n", rc);
312 goto end;
313 }
314 ret = 0;
315
316 printf(" multibinary_sha1 test: Pass\n");
317 end:
318 aligned_free(mgr);
319
320 return ret;
321 }
322