xref: /isa-l_crypto/sha256_mb/sha256_mb_test.c (revision 2a268c597b745b55509ea38d00753e5caa85e9ac)
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 "sha256_mb.h"
34 
35 typedef uint32_t DigestSHA256[SHA256_DIGEST_NWORDS];
36 
37 #define MSGS 7
38 #define NUM_JOBS 1000
39 
40 #define PSEUDO_RANDOM_NUM(seed) ((seed) * 5 + ((seed) * (seed)) / 64) % MSGS
41 
42 static uint8_t msg1[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
43 static uint8_t msg2[] = "0123456789:;<=>?@ABCDEFGHIJKLMNO";
44 static uint8_t msg3[] =
45     "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
46     "0123456789:;<";
47 static uint8_t msg4[] =
48     "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
49     "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" "0123456789:;<=>?@ABCDEFGHIJKLMNOPQR";
50 static uint8_t msg5[] =
51     "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
52     "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
53     "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" "0123456789:;<=>?";
54 static uint8_t msg6[] =
55     "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
56     "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
57     "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
58     "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU";
59 static uint8_t msg7[] = "";
60 
61 static DigestSHA256 expResultDigest1 = { 0x248D6A61, 0xD20638B8, 0xE5C02693, 0x0C3E6039,
62 	0xA33CE459, 0x64FF2167, 0xF6ECEDD4, 0x19DB06C1
63 };
64 
65 static DigestSHA256 expResultDigest2 = { 0xD9C2E699, 0x586B948F, 0x4022C799, 0x4FFE14C6,
66 	0x3A4E8E31, 0x2EE2AEE1, 0xEBE51BED, 0x85705CFD
67 };
68 
69 static DigestSHA256 expResultDigest3 = { 0xE3057651, 0x81295681, 0x7ECF1791, 0xFF9A1619,
70 	0xB2BC5CAD, 0x2AC00018, 0x92AE489C, 0x48DD10B3
71 };
72 
73 static DigestSHA256 expResultDigest4 = { 0x0307DAA3, 0x7130A140, 0x270790F9, 0x95B71407,
74 	0x8EC752A6, 0x084EC1F3, 0xBD873D79, 0x3FF78383
75 };
76 
77 static DigestSHA256 expResultDigest5 = { 0x679312F7, 0x2E18D599, 0x5F51BDC6, 0x4ED56AFD,
78 	0x9B5704D3, 0x4387E11C, 0xC2331089, 0x2CD45DAA
79 };
80 
81 static DigestSHA256 expResultDigest6 = { 0x8B1767E9, 0x7BA7BBE5, 0xF9A6E8D9, 0x9996904F,
82 	0x3AF6562E, 0xA58AF438, 0x5D8D584B, 0x81C808CE
83 };
84 
85 static DigestSHA256 expResultDigest7 = { 0xE3B0C442, 0x98FC1C14, 0x9AFBF4C8, 0x996FB924,
86 	0x27AE41E4, 0x649B934C, 0xA495991B, 0x7852B855
87 };
88 
89 static uint8_t *msgs[MSGS] = { msg1, msg2, msg3, msg4, msg5, msg6, msg7 };
90 
91 static uint32_t *expResultDigest[MSGS] = {
92 	expResultDigest1, expResultDigest2, expResultDigest3,
93 	expResultDigest4, expResultDigest5, expResultDigest6,
94 	expResultDigest7
95 };
96 
97 #define NUM_CHUNKS	4
98 #define DATA_BUF_LEN	4096
99 int non_blocksize_updates_test(SHA256_HASH_CTX_MGR * mgr)
100 {
101 	SHA256_HASH_CTX ctx_refer;
102 	SHA256_HASH_CTX ctx_pool[NUM_CHUNKS];
103 	SHA256_HASH_CTX *ctx = NULL;
104 
105 	const int update_chunks[NUM_CHUNKS] = { 32, 64, 128, 256 };
106 	unsigned char data_buf[DATA_BUF_LEN];
107 
108 	memset(data_buf, 0xA, DATA_BUF_LEN);
109 
110 	// Init contexts before first use
111 	hash_ctx_init(&ctx_refer);
112 
113 	ctx = sha256_ctx_mgr_submit(mgr, &ctx_refer, data_buf, DATA_BUF_LEN, HASH_ENTIRE);
114 	if (ctx && ctx->error) {
115 		return -1;
116 	}
117 	ctx = sha256_ctx_mgr_flush(mgr);
118 	if ((ctx && ctx->error) || (ctx_refer.status != HASH_CTX_STS_COMPLETE)) {
119 		return -1;
120 	}
121 
122 	for (int c = 0; c < NUM_CHUNKS; c++) {
123 		int chunk = update_chunks[c];
124 		hash_ctx_init(&ctx_pool[c]);
125 		for (int i = 0; i * chunk < DATA_BUF_LEN; i++) {
126 			HASH_CTX_FLAG flags = HASH_UPDATE;
127 			if (i == 0) {
128 				flags = HASH_FIRST;
129 			}
130 			ctx = sha256_ctx_mgr_submit(mgr, &ctx_pool[c],
131 						    data_buf + i * chunk, chunk, flags);
132 			if (ctx && ctx->error) {
133 				return -1;
134 			}
135 			ctx = sha256_ctx_mgr_flush(mgr);
136 			if (ctx && ctx->error) {
137 				return -1;
138 			}
139 		}
140 	}
141 
142 	for (int c = 0; c < NUM_CHUNKS; c++) {
143 		ctx = sha256_ctx_mgr_submit(mgr, &ctx_pool[c], NULL, 0, HASH_LAST);
144 		if (ctx && ctx->error) {
145 			return -1;
146 		}
147 		ctx = sha256_ctx_mgr_flush(mgr);
148 		if (ctx && ctx->error) {
149 			return -1;
150 		}
151 		if (ctx_pool[c].status != HASH_CTX_STS_COMPLETE) {
152 			return -1;
153 		}
154 		for (int i = 0; i < SHA256_DIGEST_NWORDS; i++) {
155 			if (ctx_refer.job.result_digest[i] != ctx_pool[c].job.result_digest[i]) {
156 				printf
157 				    ("sha256 calc error! chunk %d, digest[%d], (%d) != (%d)\n",
158 				     update_chunks[c], i, ctx_refer.job.result_digest[i],
159 				     ctx_pool[c].job.result_digest[i]);
160 				return -2;
161 			}
162 		}
163 	}
164 	return 0;
165 }
166 
167 int main(void)
168 {
169 	SHA256_HASH_CTX_MGR *mgr = NULL;
170 	SHA256_HASH_CTX ctxpool[NUM_JOBS], *ctx = NULL;
171 	uint32_t i, j, k, t, checked = 0;
172 	uint32_t *good;
173 	int rc, ret = -1;
174 
175 	rc = posix_memalign((void *)&mgr, 16, sizeof(SHA256_HASH_CTX_MGR));
176 	if ((rc != 0) || (mgr == NULL)) {
177 		printf("posix_memalign failed test aborted\n");
178 		return 1;
179 	}
180 
181 	sha256_ctx_mgr_init(mgr);
182 
183 	// Init contexts before first use
184 	for (i = 0; i < MSGS; i++) {
185 		hash_ctx_init(&ctxpool[i]);
186 		ctxpool[i].user_data = (void *)((uint64_t) i);
187 	}
188 
189 	for (i = 0; i < MSGS; i++) {
190 		ctx = sha256_ctx_mgr_submit(mgr,
191 					    &ctxpool[i],
192 					    msgs[i], strlen((char *)msgs[i]), HASH_ENTIRE);
193 
194 		if (ctx) {
195 			t = (unsigned long)(ctx->user_data);
196 			good = expResultDigest[t];
197 			checked++;
198 			for (j = 0; j < SHA256_DIGEST_NWORDS; j++) {
199 				if (good[j] != ctxpool[t].job.result_digest[j]) {
200 					printf("Test %d, digest %d is %08X, should be %08X\n",
201 					       t, j, ctxpool[t].job.result_digest[j], good[j]);
202 					goto end;
203 				}
204 			}
205 
206 			if (ctx->error) {
207 				printf("Something bad happened during the submit."
208 				       " Error code: %d", ctx->error);
209 				goto end;
210 			}
211 
212 		}
213 	}
214 
215 	while (1) {
216 		ctx = sha256_ctx_mgr_flush(mgr);
217 
218 		if (ctx) {
219 			t = (unsigned long)(ctx->user_data);
220 			good = expResultDigest[t];
221 			checked++;
222 			for (j = 0; j < SHA256_DIGEST_NWORDS; j++) {
223 				if (good[j] != ctxpool[t].job.result_digest[j]) {
224 					printf("Test %d, digest %d is %08X, should be %08X\n",
225 					       t, j, ctxpool[t].job.result_digest[j], good[j]);
226 					goto end;
227 				}
228 			}
229 
230 			if (ctx->error) {
231 				printf("Something bad happened during the submit."
232 				       " Error code: %d", ctx->error);
233 				goto end;
234 			}
235 		} else {
236 			break;
237 		}
238 	}
239 
240 	// do larger test in pseudo-random order
241 
242 	// Init contexts before first use
243 	for (i = 0; i < NUM_JOBS; i++) {
244 		hash_ctx_init(&ctxpool[i]);
245 		ctxpool[i].user_data = (void *)((uint64_t) i);
246 	}
247 
248 	checked = 0;
249 	for (i = 0; i < NUM_JOBS; i++) {
250 		j = PSEUDO_RANDOM_NUM(i);
251 		ctx = sha256_ctx_mgr_submit(mgr,
252 					    &ctxpool[i],
253 					    msgs[j], strlen((char *)msgs[j]), HASH_ENTIRE);
254 		if (ctx) {
255 			t = (unsigned long)(ctx->user_data);
256 			k = PSEUDO_RANDOM_NUM(t);
257 			good = expResultDigest[k];
258 			checked++;
259 			for (j = 0; j < SHA256_DIGEST_NWORDS; j++) {
260 				if (good[j] != ctxpool[t].job.result_digest[j]) {
261 					printf("Test %d, digest %d is %08X, should be %08X\n",
262 					       t, j, ctxpool[t].job.result_digest[j], good[j]);
263 					goto end;
264 				}
265 			}
266 
267 			if (ctx->error) {
268 				printf("Something bad happened during the"
269 				       " submit. Error code: %d", ctx->error);
270 				goto end;
271 			}
272 
273 			t = (unsigned long)(ctx->user_data);
274 			k = PSEUDO_RANDOM_NUM(t);
275 		}
276 	}
277 	while (1) {
278 		ctx = sha256_ctx_mgr_flush(mgr);
279 
280 		if (ctx) {
281 			t = (unsigned long)(ctx->user_data);
282 			k = PSEUDO_RANDOM_NUM(t);
283 			good = expResultDigest[k];
284 			checked++;
285 			for (j = 0; j < SHA256_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",
288 					       t, j, 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", ctx->error);
296 				goto end;
297 			}
298 		} else {
299 			break;
300 		}
301 	}
302 
303 	if (checked != NUM_JOBS) {
304 		printf("only tested %d rather than %d\n", checked, NUM_JOBS);
305 		goto end;
306 	}
307 
308 	rc = non_blocksize_updates_test(mgr);
309 	if (rc) {
310 		printf("multi updates test fail %d\n", rc);
311 		goto end;
312 	}
313 	ret = 0;
314 
315 	printf(" multibinary_sha256 test: Pass\n");
316       end:
317 	aligned_free(mgr);
318 
319 	return ret;
320 }
321