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