xref: /isa-l_crypto/sm3_mb/sm3_mb_test.c (revision 46bddbb784bcf0d2d12d16395f565df9044ef0fc)
1 /**********************************************************************
2   Copyright(c) 2020 Arm 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 Arm 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 
34 #ifndef FIPS_MODE
35 #include "sm3_mb.h"
36 
37 typedef struct {
38         const char *msg;
39         uint32_t resultDigest[ISAL_SM3_DIGEST_NWORDS];
40 } TestData;
41 
42 static TestData test_data[] = {
43         { .msg = "abc",
44           .resultDigest = { 0xf4f0c766, 0xd9edee62, 0x6bd4f2d1, 0xe2e410dc, 0x87c46741, 0xa2f7f25c,
45                             0x2ba07d29, 0xe0a84b8f } },
46         { .msg = "abcdabcdabcdabcdabcdabcdabcdabcd"
47                  "abcdabcdabcdabcdabcdabcdabcdabcd",
48           .resultDigest = { 0xf99fbede, 0xa1b87522, 0x89486038, 0x4d5a8ec1, 0xe570db6f, 0x65577e38,
49                             0xa3cb3d29, 0x32570c9c }
50 
51         },
52         { .msg = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
53           .resultDigest = { 0xc56c9b63, 0x379e4de6, 0x92b190a3, 0xeaa14fdf, 0x74ab2007, 0xb992f67f,
54                             0x664e8cf3, 0x058c7bad } },
55 
56         { .msg = "0123456789:;<=>?@ABCDEFGHIJKLMNO",
57           .resultDigest = { 0x076833d0, 0xd089ec39, 0xad857685, 0x8089797a, 0x9df9e8fd, 0x4126eb9a,
58                             0xf38c22e8, 0x054bb846 } },
59         { .msg = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
60                  "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
61                  "0123456789:;<",
62           .resultDigest = { 0x6cb9d38e, 0x846ac99e, 0x6d05634b, 0x3fe1bb26, 0x90368c4b, 0xee8c4299,
63                             0x08c0e96a, 0x2233cdc7 } },
64         { .msg = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
65                  "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
66                  "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
67                  "0123456789:;<=>?@ABCDEFGHIJKLMNOPQR",
68           .resultDigest = { 0x83758189, 0x050f14d1, 0x91d8a730, 0x4a2825e4, 0x11723273, 0x2114ee3f,
69                             0x18cac172, 0xa9c5b07a } },
70         {
71                 .msg = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
72                        "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
73                        "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
74                        "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
75                        "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
76                        "0123456789:;<=>?",
77                 .resultDigest = { 0xb80f8aba, 0x55e96119, 0x851ac77b, 0xae31b3a5, 0x1333e764,
78                                   0xc86ac40d, 0x34878db1, 0x7da873f6 },
79         },
80         { .msg = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
81                  "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
82                  "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
83                  "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
84                  "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
85                  "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX"
86                  "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU",
87           .resultDigest = { 0xbd5736a7, 0x55977d13, 0xa950c78a, 0x71eeb7cb, 0xe9ef0ba5, 0x95a9302e,
88                             0x155e5c33, 0xad96ce3c } },
89         { .msg = "",
90           .resultDigest = { 0x831db21a, 0x7fa1cf55, 0x4819618e, 0x8f1ae831, 0xc7c8be22, 0x74fbfe28,
91                             0xeb35d07e, 0x2baa8250 }
92 
93         },
94 
95 };
96 
97 #define MSGS     sizeof(test_data) / sizeof(TestData)
98 #define NUM_JOBS 1000
99 
100 #define PSEUDO_RANDOM_NUM(seed) ((seed) * 5 + ((seed) * (seed)) / 64) % MSGS
101 
102 #define NUM_CHUNKS   4
103 #define DATA_BUF_LEN 4096
104 int
105 non_blocksize_updates_test(ISAL_SM3_HASH_CTX_MGR *mgr)
106 {
107         ISAL_SM3_HASH_CTX ctx_refer;
108         ISAL_SM3_HASH_CTX ctx_pool[NUM_CHUNKS];
109         ISAL_SM3_HASH_CTX *ctx = NULL;
110 
111         const int update_chunks[NUM_CHUNKS] = { 32, 64, 128, 256 };
112         unsigned char data_buf[DATA_BUF_LEN];
113 
114         memset(data_buf, 0xA, DATA_BUF_LEN);
115 
116         // Init contexts before first use
117         isal_hash_ctx_init(&ctx_refer);
118 
119         if (isal_sm3_ctx_mgr_submit(mgr, &ctx_refer, &ctx, data_buf, DATA_BUF_LEN,
120                                     ISAL_HASH_ENTIRE) != 0)
121                 return -1;
122 
123         if (isal_sm3_ctx_mgr_flush(mgr, &ctx) != 0)
124                 return -1;
125 
126         for (int c = 0; c < NUM_CHUNKS; c++) {
127                 const int chunk = update_chunks[c];
128 
129                 isal_hash_ctx_init(&ctx_pool[c]);
130                 for (int i = 0; i * chunk < DATA_BUF_LEN; i++) {
131                         const ISAL_HASH_CTX_FLAG flags =
132                                 (i == 0) ? ISAL_HASH_FIRST : ISAL_HASH_UPDATE;
133 
134                         if (isal_sm3_ctx_mgr_submit(mgr, &ctx_pool[c], &ctx, data_buf + i * chunk,
135                                                     chunk, flags) != 0)
136                                 return -1;
137                         if (isal_sm3_ctx_mgr_flush(mgr, &ctx) != 0)
138                                 return -1;
139                 }
140         }
141 
142         for (int c = 0; c < NUM_CHUNKS; c++) {
143                 if (isal_sm3_ctx_mgr_submit(mgr, &ctx_pool[c], &ctx, NULL, 0, ISAL_HASH_LAST) != 0)
144                         return -1;
145                 if (isal_sm3_ctx_mgr_flush(mgr, &ctx) != 0)
146                         return -1;
147                 if (ctx_pool[c].status != ISAL_HASH_CTX_STS_COMPLETE)
148                         return -1;
149                 for (int i = 0; i < ISAL_SM3_DIGEST_NWORDS; i++) {
150                         if (ctx_refer.job.result_digest[i] != ctx_pool[c].job.result_digest[i]) {
151                                 printf("sm3 calc error! chunk %d, digest[%d], (%d) != (%d)\n",
152                                        update_chunks[c], i, ctx_refer.job.result_digest[i],
153                                        ctx_pool[c].job.result_digest[i]);
154                                 return -2;
155                         }
156                 }
157         }
158         return 0;
159 }
160 #endif /* !FIPS_MODE */
161 
162 int
163 main(void)
164 {
165 #ifndef FIPS_MODE
166         ISAL_SM3_HASH_CTX_MGR *mgr = NULL;
167         ISAL_SM3_HASH_CTX ctxpool[NUM_JOBS], *ctx = NULL;
168         uint32_t i, j, k, t, checked = 0;
169         uint32_t *good;
170         int rc, ret = -1;
171         rc = posix_memalign((void *) &mgr, 16, sizeof(ISAL_SM3_HASH_CTX_MGR));
172         if (rc) {
173                 printf("alloc error: Fail");
174                 return -1;
175         }
176         isal_sm3_ctx_mgr_init(mgr);
177         // Init contexts before first use
178         for (i = 0; i < MSGS; i++) {
179                 isal_hash_ctx_init(&ctxpool[i]);
180                 ctxpool[i].user_data = (void *) ((uint64_t) i);
181         }
182 
183         for (i = 0; i < MSGS; i++) {
184                 const int errc = isal_sm3_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, test_data[i].msg,
185                                                          strlen((char *) test_data[i].msg),
186                                                          ISAL_HASH_ENTIRE);
187 
188                 if (errc == 0) {
189                         if (ctx != NULL) {
190                                 t = (unsigned long) (uintptr_t) (ctx->user_data);
191                                 good = test_data[t].resultDigest;
192                                 checked++;
193                                 for (j = 0; j < ISAL_SM3_DIGEST_NWORDS; j++) {
194                                         if (good[j] != ctxpool[t].job.result_digest[j]) {
195                                                 printf("Test %d, digest %d is %08X, should be "
196                                                        "%08X\n",
197                                                        t, j, ctxpool[t].job.result_digest[j],
198                                                        good[j]);
199                                                 goto end;
200                                         }
201                                 }
202                         }
203                 } else {
204                         printf("Something bad happened during the submit. Error code: %d", errc);
205                         goto end;
206                 }
207         }
208 
209         while (1) {
210                 const int errc = isal_sm3_ctx_mgr_flush(mgr, &ctx);
211 
212                 if (errc == 0) {
213                         if (ctx == NULL)
214                                 break;
215 
216                         t = (unsigned long) (uintptr_t) (ctx->user_data);
217                         good = test_data[t].resultDigest;
218                         checked++;
219                         for (j = 0; j < ISAL_SM3_DIGEST_NWORDS; j++) {
220                                 if (good[j] != ctxpool[t].job.result_digest[j]) {
221                                         printf("Test %d, digest %d is %08X, should be %08X\n", t, j,
222                                                ctxpool[t].job.result_digest[j], good[j]);
223                                         goto end;
224                                 }
225                         }
226                 } else {
227                         printf("Something bad happened during the flush. Error code: %d", errc);
228                         goto end;
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                 isal_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 
244                 const int errc = isal_sm3_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, test_data[j].msg,
245                                                          strlen((char *) test_data[j].msg),
246                                                          ISAL_HASH_ENTIRE);
247                 if (errc == 0) {
248                         if (ctx != NULL) {
249                                 t = (unsigned long) (uintptr_t) (ctx->user_data);
250                                 k = PSEUDO_RANDOM_NUM(t);
251                                 good = test_data[k].resultDigest;
252                                 checked++;
253                                 for (j = 0; j < ISAL_SM3_DIGEST_NWORDS; j++) {
254                                         if (good[j] != ctxpool[t].job.result_digest[j]) {
255                                                 printf("Test %d, digest %d is %08X, should be "
256                                                        "%08X\n",
257                                                        t, j, ctxpool[t].job.result_digest[j],
258                                                        good[j]);
259                                                 goto end;
260                                         }
261                                 }
262                         }
263                 } else {
264                         printf("Something bad happened during the submit. Error code: %d", errc);
265                         goto end;
266                 }
267         }
268         while (1) {
269                 const int errc = isal_sm3_ctx_mgr_flush(mgr, &ctx);
270 
271                 if (errc == 0) {
272                         if (ctx == NULL)
273                                 break;
274 
275                         t = (unsigned long) (uintptr_t) (ctx->user_data);
276                         k = PSEUDO_RANDOM_NUM(t);
277                         good = test_data[k].resultDigest;
278                         checked++;
279                         for (j = 0; j < ISAL_SM3_DIGEST_NWORDS; j++) {
280                                 if (good[j] != ctxpool[t].job.result_digest[j]) {
281                                         printf("Test %d, digest %d is %08X, should be %08X\n", t, j,
282                                                ctxpool[t].job.result_digest[j], good[j]);
283                                         goto end;
284                                 }
285                         }
286                 } else {
287                         printf("Something bad happened during the flush. Error code: %d", errc);
288                         goto end;
289                 }
290         }
291 
292         if (checked != NUM_JOBS) {
293                 printf("only tested %d rather than %d\n", checked, NUM_JOBS);
294                 goto end;
295         }
296 
297         rc = non_blocksize_updates_test(mgr);
298         if (rc) {
299                 printf("multi updates test fail %d\n", rc);
300                 goto end;
301         }
302         ret = 0;
303 
304         printf(" multibinary_sm3 test: Pass\n");
305 end:
306         aligned_free(mgr);
307 
308         return ret;
309 #else
310         printf("Not Executed\n");
311         return 0;
312 #endif /* FIPS_MODE */
313 }
314