xref: /isa-l_crypto/sm3_mb/sm3_ref_test.c (revision a4de01928f9e63e0ef03e8ef48b1b7f5de29b7ec)
1 /**********************************************************************
2   Copyright(c) 2011-2019 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 #define ISAL_UNIT_TEST
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include "sm3_mb.h"
34 #include "endian_helper.h"
35 
36 typedef uint32_t digest_sm3[SM3_DIGEST_NWORDS];
37 
38 #define MSGS 2
39 #define NUM_JOBS 1000
40 
41 #define PSEUDO_RANDOM_NUM(seed) ((seed) * 5 + ((seed) * (seed)) / 64) % MSGS
42 
43 static uint8_t msg1[] = "abc";
44 static uint8_t msg2[] = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";
45 
46 /* small endian */
47 static digest_sm3 exp_result_digest1 = { 0x66c7f0f4, 0x62eeedd9, 0xd1f2d46b, 0xdc10e4e2,
48 	0x4167c487, 0x5cf2f7a2, 0x297da02b, 0x8f4ba8e0
49 };
50 
51 /* small endian */
52 static digest_sm3 exp_result_digest2 = { 0xdebe9ff9, 0x2275b8a1, 0x38604889, 0xc18e5a4d,
53 	0x6fdb70e5, 0x387e5765, 0x293dcba3, 0x9c0c5732
54 };
55 
56 static uint8_t *msgs[MSGS] = { msg1, msg2 };
57 
58 static uint32_t *exp_result_digest[MSGS] = {
59 	exp_result_digest1, exp_result_digest2
60 };
61 
62 int main(void)
63 {
64 	SM3_HASH_CTX_MGR *mgr = NULL;
65 	SM3_HASH_CTX ctxpool[NUM_JOBS], *ctx = NULL;
66 	uint32_t i, j, k, t, checked = 0;
67 	uint32_t *good;
68 	int rc, ret = -1;
69 
70 	rc = posix_memalign((void *)&mgr, 16, sizeof(SM3_HASH_CTX_MGR));
71 	if ((rc != 0) || (mgr == NULL)) {
72 		printf("posix_memalign failed test aborted\n");
73 		return 1;
74 	}
75 
76 	sm3_ctx_mgr_init(mgr);
77 
78 	// Init contexts before first use
79 	for (i = 0; i < MSGS; i++) {
80 		hash_ctx_init(&ctxpool[i]);
81 		ctxpool[i].user_data = (void *)((uint64_t) i);
82 	}
83 
84 	for (i = 0; i < MSGS; i++) {
85 		ctx = sm3_ctx_mgr_submit(mgr,
86 					 &ctxpool[i],
87 					 msgs[i], strlen((char *)msgs[i]), HASH_ENTIRE);
88 
89 		if (ctx) {
90 			t = (unsigned long)(ctx->user_data);
91 			good = exp_result_digest[t];
92 			checked++;
93 			for (j = 0; j < SM3_DIGEST_NWORDS; j++) {
94 				if (byteswap32(good[j]) != ctxpool[t].job.result_digest[j]) {
95 					printf("Test %d, digest %d is %08X, should be %08X\n",
96 					       t, j, ctxpool[t].job.result_digest[j],
97 					       byteswap32(good[j]));
98 					goto end;
99 				}
100 			}
101 
102 			if (ctx->error) {
103 				printf("Something bad happened during the submit."
104 				       " Error code: %d", ctx->error);
105 				goto end;
106 			}
107 
108 		}
109 	}
110 
111 	while (1) {
112 		ctx = sm3_ctx_mgr_flush(mgr);
113 
114 		if (ctx) {
115 			t = (unsigned long)(ctx->user_data);
116 			good = exp_result_digest[t];
117 			checked++;
118 			for (j = 0; j < SM3_DIGEST_NWORDS; j++) {
119 				if (byteswap32(good[j]) != ctxpool[t].job.result_digest[j]) {
120 					printf("Test %d, digest %d is %08X, should be %08X\n",
121 					       t, j, ctxpool[t].job.result_digest[j],
122 					       byteswap32(good[j]));
123 					goto end;
124 				}
125 			}
126 
127 			if (ctx->error) {
128 				printf("Something bad happened during the submit."
129 				       " Error code: %d", ctx->error);
130 				goto end;
131 			}
132 		} else {
133 			break;
134 		}
135 	}
136 
137 	// do larger test in pseudo-random order
138 
139 	// Init contexts before first use
140 	for (i = 0; i < NUM_JOBS; i++) {
141 		hash_ctx_init(&ctxpool[i]);
142 		ctxpool[i].user_data = (void *)((uint64_t) i);
143 	}
144 
145 	checked = 0;
146 	for (i = 0; i < NUM_JOBS; i++) {
147 		j = PSEUDO_RANDOM_NUM(i);
148 		ctx = sm3_ctx_mgr_submit(mgr,
149 					 &ctxpool[i],
150 					 msgs[j], strlen((char *)msgs[j]), HASH_ENTIRE);
151 		if (ctx) {
152 			t = (unsigned long)(ctx->user_data);
153 			k = PSEUDO_RANDOM_NUM(t);
154 			good = exp_result_digest[k];
155 			checked++;
156 			for (j = 0; j < SM3_DIGEST_NWORDS; j++) {
157 				if (byteswap32(good[j]) != ctxpool[t].job.result_digest[j]) {
158 					printf("Test %d, digest %d is %08X, should be %08X\n",
159 					       t, j, ctxpool[t].job.result_digest[j],
160 					       byteswap32(good[j]));
161 					goto end;
162 				}
163 			}
164 
165 			if (ctx->error) {
166 				printf("Something bad happened during the"
167 				       " submit. Error code: %d", ctx->error);
168 				goto end;
169 			}
170 		}
171 	}
172 	while (1) {
173 		ctx = sm3_ctx_mgr_flush(mgr);
174 
175 		if (ctx) {
176 			t = (unsigned long)(ctx->user_data);
177 			k = PSEUDO_RANDOM_NUM(t);
178 			good = exp_result_digest[k];
179 			checked++;
180 			for (j = 0; j < SM3_DIGEST_NWORDS; j++) {
181 				if (byteswap32(good[j]) != ctxpool[t].job.result_digest[j]) {
182 					printf("Test %d, digest %d is %08X, should be %08X\n",
183 					       t, j, ctxpool[t].job.result_digest[j],
184 					       byteswap32(good[j]));
185 					goto end;
186 				}
187 			}
188 
189 			if (ctx->error) {
190 				printf("Something bad happened during the submit."
191 				       " Error code: %d", ctx->error);
192 				goto end;
193 			}
194 		} else {
195 			break;
196 		}
197 	}
198 
199 	if (checked != NUM_JOBS) {
200 		printf("only tested %d rather than %d\n", checked, NUM_JOBS);
201 		goto end;
202 	}
203 	ret = 0;
204 
205 	printf(" multibinary_sm3 test: Pass\n");
206       end:
207 	aligned_free(mgr);
208 
209 	return ret;
210 }
211