xref: /isa-l_crypto/sha512_mb/sha512_mb_test.c (revision e8fe947fd9b938d432400cca9baea7ac68c4978f)
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 "sha512_mb.h"
34 
35 typedef uint64_t DigestSHA512[SHA512_DIGEST_NWORDS];
36 
37 #define MSGS 8
38 #define NUM_JOBS 1000
39 
40 #define PSEUDO_RANDOM_NUM(seed) ((seed) * 5 + ((seed) * (seed)) / 64) % MSGS
41 
42 static uint8_t msg1[] = "The quick brown fox jumps over the lazy dog";
43 static uint8_t msg2[] = "The quick brown fox jumps over the lazy dog.";
44 static uint8_t msg3[] = { 0x0a, 0x55, 0xdb, 0 };
45 static uint8_t msg4[] = { 0xba, 0xd7, 0xc6, 0x18, 0xf4, 0x5b, 0xe2, 0x07, 0x97, 0x5e, 0 };
46 
47 static uint8_t msg5[] = {
48 	0xb1, 0x71, 0x5f, 0x78, 0x2f, 0xf0, 0x2c, 0x6b, 0x88, 0x93,
49 	0x7f, 0x05, 0x41, 0x16, 0
50 };
51 
52 static uint8_t msg6[] = {
53 	0xc6, 0xa1, 0x70, 0x93, 0x65, 0x68, 0x65, 0x10, 0x20, 0xed,
54 	0xfe, 0x15, 0xdf, 0x80, 0x12, 0xac, 0xda, 0x8d, 0
55 };
56 
57 static uint8_t msg7[] = {
58 	0xa8, 0xa3, 0x7d, 0xfc, 0x08, 0x3a, 0xd2, 0xf4, 0x7f, 0xff,
59 	0x46, 0x87, 0x38, 0xbf, 0x8b, 0x72, 0x8e, 0xb7, 0xf1, 0x90,
60 	0x7e, 0x42, 0x7f, 0xa1, 0x5c, 0xb4, 0x42, 0x4b, 0xc6, 0x85,
61 	0xe5, 0x5e, 0xd7, 0xb2, 0x82, 0x5c, 0x9c, 0x60, 0xb8, 0x39,
62 	0xcc, 0xc2, 0xfe, 0x5f, 0xb3, 0x3e, 0x36, 0xf5, 0x70, 0xcb,
63 	0x86, 0x61, 0x60, 0x9e, 0x63, 0x0b, 0xda, 0x05, 0xee, 0x64,
64 	0x1d, 0x93, 0x84, 0x28, 0x86, 0x7d, 0x90, 0xe0, 0x07, 0x44,
65 	0xa4, 0xaa, 0xd4, 0x94, 0xc9, 0x3c, 0x5f, 0x6d, 0x13, 0x27,
66 	0x87, 0x80, 0x78, 0x59, 0x0c, 0xdc, 0xe1, 0xe6, 0x47, 0xc9,
67 	0x82, 0x08, 0x18, 0xf4, 0x67, 0x64, 0x1f, 0xcd, 0x50, 0x8e,
68 	0x2f, 0x2e, 0xbf, 0xd0, 0xff, 0x3d, 0x4f, 0x27, 0x23, 0x93,
69 	0x47, 0x8f, 0x3b, 0x9e, 0x6f, 0x80, 0x6b, 0x43, 0
70 };
71 
72 static uint8_t msg8[] = "";
73 
74 static DigestSHA512 expResultDigest1 = {
75 	0x07e547d9586f6a73, 0xf73fbac0435ed769, 0x51218fb7d0c8d788, 0xa309d785436bbb64,
76 	0x2e93a252a954f239, 0x12547d1e8a3b5ed6, 0xe1bfd7097821233f, 0xa0538f3db854fee6
77 };
78 
79 static DigestSHA512 expResultDigest2 = {
80 	0x91ea1245f20d46ae, 0x9a037a989f54f1f7, 0x90f0a47607eeb8a1, 0x4d12890cea77a1bb,
81 	0xc6c7ed9cf205e67b, 0x7f2b8fd4c7dfd3a7, 0xa8617e45f3c463d4, 0x81c7e586c39ac1ed
82 };
83 
84 static DigestSHA512 expResultDigest3 = {
85 	0x7952585e5330cb24, 0x7d72bae696fc8a6b, 0x0f7d0804577e347d, 0x99bc1b11e52f3849,
86 	0x85a428449382306a, 0x89261ae143c2f3fb, 0x613804ab20b42dc0, 0x97e5bf4a96ef919b
87 };
88 
89 static DigestSHA512 expResultDigest4 = {
90 	0x5886828959d1f822, 0x54068be0bd14b6a8, 0x8f59f534061fb203, 0x76a0541052dd3635,
91 	0xedf3c6f0ca3d0877, 0x5e13525df9333a21, 0x13c0b2af76515887, 0x529910b6c793c8a5
92 };
93 
94 static DigestSHA512 expResultDigest5 = {
95 	0xee1a56ee78182ec4, 0x1d2c3ab33d4c4187, 0x1d437c5c1ca060ee, 0x9e219cb83689b4e5,
96 	0xa4174dfdab5d1d10, 0x96a31a7c8d3abda7, 0x5c1b5e6da97e1814, 0x901c505b0bc07f25
97 };
98 
99 static DigestSHA512 expResultDigest6 = {
100 	0xc36c100cdb6c8c45, 0xb072f18256d63a66, 0xc9843acb4d07de62, 0xe0600711d4fbe64c,
101 	0x8cf314ec3457c903, 0x08147cb7ac7e4d07, 0x3ba10f0ced78ea72, 0x4a474b32dae71231
102 };
103 
104 static DigestSHA512 expResultDigest7 = {
105 	0x8e1c91729be8eb40, 0x226f6c58a029380e, 0xf7edb9dc166a5c3c, 0xdbcefe90bd30d85c,
106 	0xb7c4b248e66abf0a, 0x3a4c842281299bef, 0x6db88858d9e5ab52, 0x44f70b7969e1c072
107 };
108 
109 static DigestSHA512 expResultDigest8 = {
110 	0Xcf83e1357eefb8bd, 0Xf1542850d66d8007, 0Xd620e4050b5715dc, 0X83f4a921d36ce9ce,
111 	0X47d0d13c5d85f2b0, 0Xff8318d2877eec2f, 0X63b931bd47417a81, 0Xa538327af927da3e
112 };
113 
114 static uint8_t *msgs[MSGS] = { msg1, msg2, msg3, msg4, msg5, msg6, msg7, msg8 };
115 
116 static uint64_t *expResultDigest[MSGS] = { expResultDigest1, expResultDigest2,
117 	expResultDigest3, expResultDigest4, expResultDigest5, expResultDigest6,
118 	expResultDigest7, expResultDigest8
119 };
120 
121 #define NUM_CHUNKS	4
122 #define DATA_BUF_LEN	4096
123 int non_blocksize_updates_test(SHA512_HASH_CTX_MGR * mgr)
124 {
125 	SHA512_HASH_CTX ctx_refer;
126 	SHA512_HASH_CTX ctx_pool[NUM_CHUNKS];
127 	SHA512_HASH_CTX *ctx = NULL;
128 
129 	const int update_chunks[NUM_CHUNKS] = { 32, 64, 128, 256 };
130 	unsigned char data_buf[DATA_BUF_LEN];
131 
132 	memset(data_buf, 0xA, DATA_BUF_LEN);
133 
134 	// Init contexts before first use
135 	hash_ctx_init(&ctx_refer);
136 
137 	ctx = sha512_ctx_mgr_submit(mgr, &ctx_refer, data_buf, DATA_BUF_LEN, HASH_ENTIRE);
138 	if (ctx && ctx->error) {
139 		return -1;
140 	}
141 	ctx = sha512_ctx_mgr_flush(mgr);
142 	if ((ctx && ctx->error) || (ctx_refer.status != HASH_CTX_STS_COMPLETE)) {
143 		return -1;
144 	}
145 
146 	for (int c = 0; c < NUM_CHUNKS; c++) {
147 		int chunk = update_chunks[c];
148 		hash_ctx_init(&ctx_pool[c]);
149 		for (int i = 0; i * chunk < DATA_BUF_LEN; i++) {
150 			HASH_CTX_FLAG flags = HASH_UPDATE;
151 			if (i == 0) {
152 				flags = HASH_FIRST;
153 			}
154 			ctx = sha512_ctx_mgr_submit(mgr, &ctx_pool[c],
155 						    data_buf + i * chunk, chunk, flags);
156 			if (ctx && ctx->error) {
157 				return -1;
158 			}
159 			ctx = sha512_ctx_mgr_flush(mgr);
160 			if (ctx && ctx->error) {
161 				return -1;
162 			}
163 		}
164 	}
165 
166 	for (int c = 0; c < NUM_CHUNKS; c++) {
167 		ctx = sha512_ctx_mgr_submit(mgr, &ctx_pool[c], NULL, 0, HASH_LAST);
168 		if (ctx && ctx->error) {
169 			return -1;
170 		}
171 		ctx = sha512_ctx_mgr_flush(mgr);
172 		if (ctx && ctx->error) {
173 			return -1;
174 		}
175 		if (ctx_pool[c].status != HASH_CTX_STS_COMPLETE) {
176 			return -1;
177 		}
178 		for (int i = 0; i < SHA512_DIGEST_NWORDS; i++) {
179 			if (ctx_refer.job.result_digest[i] != ctx_pool[c].job.result_digest[i]) {
180 				printf
181 				    ("sha512 calc error! chunk %d, digest[%d], (%ld) != (%ld)\n",
182 				     update_chunks[c], i, ctx_refer.job.result_digest[i],
183 				     ctx_pool[c].job.result_digest[i]);
184 				return -2;
185 			}
186 		}
187 	}
188 	return 0;
189 }
190 
191 int main(void)
192 {
193 	SHA512_HASH_CTX_MGR *mgr = NULL;
194 	SHA512_HASH_CTX ctxpool[NUM_JOBS], *ctx = NULL;
195 	uint32_t i, j, k, t, checked = 0;
196 	uint64_t *good;
197 	int ret;
198 
199 #if defined(_WIN32) || defined(_WIN64)
200         mgr = (SHA512_HASH_CTX_MGR *) _aligned_malloc(sizeof(SHA512_HASH_CTX_MGR), 16);
201         if (mgr == NULL) {
202 		printf("aligned_malloc failed, test aborted\n");
203 		return 1;
204 	}
205 #else
206 	ret = posix_memalign((void *)&mgr, 16, sizeof(SHA512_HASH_CTX_MGR));
207 	if ((ret != 0) || (mgr == NULL)) {
208 		printf("posix_memalign failed, test aborted\n");
209 		return 1;
210 	}
211 #endif
212 
213 	sha512_ctx_mgr_init(mgr);
214 
215 	// Init contexts before first use
216 	for (i = 0; i < MSGS; i++) {
217 		hash_ctx_init(&ctxpool[i]);
218 		ctxpool[i].user_data = (void *)((uint64_t) i);
219 	}
220 
221 	for (i = 0; i < MSGS; i++) {
222 		ctx = sha512_ctx_mgr_submit(mgr,
223 					    &ctxpool[i],
224 					    msgs[i], strlen((char *)msgs[i]), HASH_ENTIRE);
225 
226 		if (ctx) {
227 			t = (unsigned long)(ctx->user_data);
228 			good = expResultDigest[t];
229 			checked++;
230 			for (j = 0; j < SHA512_DIGEST_NWORDS; j++) {
231 				if (good[j] != ctxpool[t].job.result_digest[j]) {
232 					printf("Test %d, digest %d is %016lX, "
233 					       "should be %016lX\n", t, j,
234 					       ctxpool[t].job.result_digest[j], good[j]);
235 					return -1;
236 				}
237 			}
238 
239 			if (ctx->error) {
240 				printf("Something bad happened during the"
241 				       " submit. Error code: %d", ctx->error);
242 				return -1;
243 			}
244 		}
245 	}
246 
247 	while (1) {
248 		ctx = sha512_ctx_mgr_flush(mgr);
249 
250 		if (ctx) {
251 			t = (unsigned long)(ctx->user_data);
252 			good = expResultDigest[t];
253 			checked++;
254 			for (j = 0; j < SHA512_DIGEST_NWORDS; j++) {
255 				if (good[j] != ctxpool[t].job.result_digest[j]) {
256 					printf("Test %d, digest %d is %016lX, "
257 					       "should be %016lX\n", t, j,
258 					       ctxpool[t].job.result_digest[j], good[j]);
259 					return -1;
260 				}
261 			}
262 
263 			if (ctx->error) {
264 				printf("Something bad happened during the "
265 				       "submit. Error code: %d", ctx->error);
266 				return -1;
267 			}
268 		} else {
269 			break;
270 		}
271 	}
272 
273 	// do larger test in pseudo-random order
274 
275 	// Init contexts before first use
276 	for (i = 0; i < NUM_JOBS; i++) {
277 		hash_ctx_init(&ctxpool[i]);
278 		ctxpool[i].user_data = (void *)((uint64_t) i);
279 	}
280 
281 	checked = 0;
282 	for (i = 0; i < NUM_JOBS; i++) {
283 		j = PSEUDO_RANDOM_NUM(i);
284 
285 		ctx = sha512_ctx_mgr_submit(mgr,
286 					    &ctxpool[i],
287 					    msgs[j], strlen((char *)msgs[j]), HASH_ENTIRE);
288 
289 		if (ctx) {
290 			t = (unsigned long)(ctx->user_data);
291 			k = PSEUDO_RANDOM_NUM(t);
292 			good = expResultDigest[k];
293 			checked++;
294 			for (j = 0; j < SHA512_DIGEST_NWORDS; j++) {
295 				if (good[j] != ctxpool[t].job.result_digest[j]) {
296 					printf("Test %d, digest %d is %016lX, "
297 					       "should be %016lX\n", t, j,
298 					       ctxpool[t].job.result_digest[j], good[j]);
299 					return -1;
300 				}
301 			}
302 
303 			if (ctx->error) {
304 				printf("Something bad happened during the"
305 				       " submit. Error code: %d", ctx->error);
306 				return -1;
307 			}
308 
309 			t = (unsigned long)(ctx->user_data);
310 			k = PSEUDO_RANDOM_NUM(t);
311 		}
312 	}
313 	while (1) {
314 		ctx = sha512_ctx_mgr_flush(mgr);
315 
316 		if (ctx) {
317 			t = (unsigned long)(ctx->user_data);
318 			k = PSEUDO_RANDOM_NUM(t);
319 			good = expResultDigest[k];
320 			checked++;
321 			for (j = 0; j < SHA512_DIGEST_NWORDS; j++) {
322 				if (good[j] != ctxpool[t].job.result_digest[j]) {
323 					printf("Test %d, digest %d is %016lX, "
324 					       "should be %016lX\n", t, j,
325 					       ctxpool[t].job.result_digest[j], good[j]);
326 					return -1;
327 				}
328 			}
329 
330 			if (ctx->error) {
331 				printf("Something bad happened during the"
332 				       " submit. Error code: %d", ctx->error);
333 				return -1;
334 			}
335 		} else {
336 			break;
337 		}
338 	}
339 
340 	if (checked != NUM_JOBS) {
341 		printf("only tested %d rather than %d\n", checked, NUM_JOBS);
342 		return -1;
343 	}
344 	int rc = non_blocksize_updates_test(mgr);
345 #if defined(_WIN32) || defined(_WIN64)
346         _aligned_free(mgr);
347 #else
348         free(mgr);
349 #endif
350 	if (rc) {
351 		printf("multi updates test fail %d\n", rc);
352 		return rc;
353 	}
354 	printf(" multibinary_sha512 test: Pass\n");
355 	return 0;
356 }
357