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
33 #ifndef FIPS_MODE
34 #include "sm3_mb.h"
35 #include "endian_helper.h"
36
37 #define TEST_LEN (1024 * 1024)
38 #define TEST_BUFS 100
39 #ifndef RANDOMS
40 #define RANDOMS 10
41 #endif
42 #ifndef TEST_SEED
43 #define TEST_SEED 0x1234
44 #endif
45
46 static uint8_t digest_ref[TEST_BUFS][4 * ISAL_SM3_DIGEST_NWORDS];
47
48 // Compare against reference function
49 extern void
50 sm3_ossl(const unsigned char *buf, size_t length, unsigned char *digest);
51
52 // Generates pseudo-random data
53 static void
rand_buffer(unsigned char * buf,const long buffer_size)54 rand_buffer(unsigned char *buf, const long buffer_size)
55 {
56 long i;
57 for (i = 0; i < buffer_size; i++)
58 buf[i] = rand();
59 }
60 #endif /* !FIPS_MODE */
61
62 int
main(void)63 main(void)
64 {
65 #ifndef FIPS_MODE
66 ISAL_SM3_HASH_CTX_MGR *mgr = NULL;
67 ISAL_SM3_HASH_CTX ctxpool[TEST_BUFS];
68 ISAL_SM3_HASH_CTX *ctx = NULL;
69 uint32_t i, j, fail = 0;
70 unsigned char *bufs[TEST_BUFS];
71 uint32_t lens[TEST_BUFS];
72 unsigned int jobs, t;
73 uint8_t *tmp_buf;
74 int ret;
75
76 printf("multibinary_sm3 test, %d sets of %dx%d max: ", RANDOMS, TEST_BUFS, TEST_LEN);
77
78 ret = posix_memalign((void *) &mgr, 16, sizeof(ISAL_SM3_HASH_CTX_MGR));
79 if ((ret != 0) || (mgr == NULL)) {
80 printf("posix_memalign failed test aborted\n");
81 return 1;
82 }
83
84 isal_sm3_ctx_mgr_init(mgr);
85
86 srand(TEST_SEED);
87
88 for (i = 0; i < TEST_BUFS; i++) {
89 // Allocate and fill buffer
90 bufs[i] = (unsigned char *) malloc(TEST_LEN);
91 if (bufs[i] == NULL) {
92 printf("malloc failed test aborted\n");
93 return 1;
94 }
95 rand_buffer(bufs[i], TEST_LEN);
96
97 // Init ctx contexts
98 isal_hash_ctx_init(&ctxpool[i]);
99 ctxpool[i].user_data = (void *) ((uint64_t) i);
100
101 // Run reference test
102 sm3_ossl(bufs[i], TEST_LEN, digest_ref[i]);
103
104 // Run sb_sm3 test
105 isal_sm3_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, bufs[i], TEST_LEN,
106 ISAL_HASH_ENTIRE);
107 }
108
109 while (isal_sm3_ctx_mgr_flush(mgr, &ctx) == 0)
110 if (ctx == NULL)
111 break;
112
113 for (i = 0; i < TEST_BUFS; i++) {
114 for (j = 0; j < ISAL_SM3_DIGEST_NWORDS; j++) {
115 if (ctxpool[i].job.result_digest[j] !=
116 to_le32(((uint32_t *) digest_ref[i])[j])) {
117 fail++;
118 printf("Test%d fixed size, digest%d "
119 "fail 0x%08X <=> 0x%08X \n",
120 i, j, ctxpool[i].job.result_digest[j],
121 to_le32(((uint32_t *) digest_ref[i])[j]));
122 }
123 }
124 }
125
126 if (fail) {
127 printf("Test failed function check %d\n", fail);
128 return fail;
129 }
130 // Run tests with random size and number of jobs
131 for (t = 0; t < RANDOMS; t++) {
132 jobs = rand() % (TEST_BUFS);
133
134 isal_sm3_ctx_mgr_init(mgr);
135
136 for (i = 0; i < jobs; i++) {
137 // Use buffer with random len and contents
138 lens[i] = rand() % (TEST_LEN);
139 rand_buffer(bufs[i], lens[i]);
140
141 // Run reference test
142 sm3_ossl(bufs[i], lens[i], digest_ref[i]);
143
144 // Run sm3_mb test
145 isal_sm3_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, bufs[i], lens[i],
146 ISAL_HASH_ENTIRE);
147 }
148
149 while (isal_sm3_ctx_mgr_flush(mgr, &ctx) == 0)
150 if (ctx == NULL)
151 break;
152
153 for (i = 0; i < jobs; i++) {
154 for (j = 0; j < ISAL_SM3_DIGEST_NWORDS; j++) {
155 if (ctxpool[i].job.result_digest[j] !=
156 to_le32(((uint32_t *) digest_ref[i])[j])) {
157 fail++;
158 printf("Test%d, digest%d fail "
159 "0x%08X <=> 0x%08X\n",
160 i, j, ctxpool[i].job.result_digest[j],
161 to_le32(((uint32_t *) digest_ref[i])[j]));
162 }
163 }
164 }
165 if (fail) {
166 printf("Test failed function check %d\n", fail);
167 return fail;
168 }
169
170 putchar('.');
171 fflush(0);
172 } // random test t
173
174 // Test at the end of buffer
175 jobs = rand() % TEST_BUFS;
176 tmp_buf = (uint8_t *) malloc(sizeof(uint8_t) * jobs);
177 if (!tmp_buf) {
178 printf("malloc failed, end test aborted.\n");
179 return 1;
180 }
181
182 rand_buffer(tmp_buf, jobs);
183
184 isal_sm3_ctx_mgr_init(mgr);
185
186 // Extend to the end of allocated buffer to construct jobs
187 for (i = 0; i < jobs; i++) {
188 bufs[i] = (uint8_t *) &tmp_buf[i];
189 lens[i] = jobs - i;
190
191 // Reference test
192 sm3_ossl(bufs[i], lens[i], digest_ref[i]);
193
194 // sb_sm3 test
195 isal_sm3_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, bufs[i], lens[i], ISAL_HASH_ENTIRE);
196 }
197
198 while (isal_sm3_ctx_mgr_flush(mgr, &ctx) == 0)
199 if (ctx == NULL)
200 break;
201
202 for (i = 0; i < jobs; i++) {
203 for (j = 0; j < ISAL_SM3_DIGEST_NWORDS; j++) {
204 if (ctxpool[i].job.result_digest[j] !=
205 to_le32(((uint32_t *) digest_ref[i])[j])) {
206 fail++;
207 printf("End test failed at offset %d - result: 0x%08X"
208 ", ref: 0x%08X\n",
209 i, ctxpool[i].job.result_digest[j],
210 to_le32(((uint32_t *) digest_ref[i])[j]));
211 }
212 }
213 }
214
215 putchar('.');
216
217 if (fail)
218 printf("Test failed function check %d\n", fail);
219 else
220 printf(" multibinary_sm3 rand: Pass\n");
221
222 return fail;
223 #else
224 printf("Not Executed\n");
225 return 0;
226 #endif /* FIPS_MODE */
227 }
228