xref: /isa-l_crypto/mh_sha256/mh_sha256_update_test.c (revision 9999e13a5707fddf47ed4073f70fb5ea5ee542b0)
1 /**********************************************************************
2   Copyright(c) 2011-2017 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 "mh_sha256.h"
33 
34 #define TEST_LEN  16 * 1024
35 #define TEST_SIZE 8 * 1024
36 #define TEST_MEM  TEST_LEN
37 #ifndef TEST_SEED
38 #define TEST_SEED 0x1234
39 #endif
40 
41 #define str(s)  #s
42 #define xstr(s) str(s)
43 
44 #define _FUNC_TOKEN(func, type) func##type
45 #define FUNC_TOKEN(func, type)  _FUNC_TOKEN(func, type)
46 
47 #ifndef MH_SHA256_FUNC_TYPE
48 #define MH_SHA256_FUNC_TYPE
49 #endif
50 
51 #define TEST_UPDATE_FUNCTION FUNC_TOKEN(isal_mh_sha256_update, MH_SHA256_FUNC_TYPE)
52 #define TEST_FINAL_FUNCTION  FUNC_TOKEN(isal_mh_sha256_finalize, MH_SHA256_FUNC_TYPE)
53 
54 #define CHECK_RETURN(state)                                                                        \
55         do {                                                                                       \
56                 if ((state) != ISAL_MH_SHA256_CTX_ERROR_NONE) {                                    \
57                         printf("The mh_sha256 function is failed.\n");                             \
58                         return 1;                                                                  \
59                 }                                                                                  \
60         } while (0)
61 
62 extern void
63 mh_sha256_ref(const void *buffer, uint32_t len, uint32_t *mh_sha256_digest);
64 
65 // Generates pseudo-random data
66 void
67 rand_buffer(uint8_t *buf, long buffer_size)
68 {
69         long i;
70         for (i = 0; i < buffer_size; i++)
71                 buf[i] = rand();
72 }
73 
74 void
75 dump(char *buf, int len)
76 {
77         int i;
78         for (i = 0; i < len;) {
79                 printf(" %2x", 0xff & buf[i++]);
80                 if (i % 20 == 0)
81                         printf("\n");
82         }
83         if (i % 20 != 0)
84                 printf("\n");
85 }
86 
87 int
88 compare_digests(uint32_t hash_ref[ISAL_SHA256_DIGEST_WORDS],
89                 uint32_t hash_test[ISAL_SHA256_DIGEST_WORDS])
90 {
91         int i;
92         int mh_sha256_fail = 0;
93 
94         for (i = 0; i < ISAL_SHA256_DIGEST_WORDS; i++) {
95                 if (hash_test[i] != hash_ref[i])
96                         mh_sha256_fail++;
97         }
98 
99         if (mh_sha256_fail) {
100                 printf("mh_sha256 fail test\n");
101                 printf("ref: ");
102                 dump((char *) hash_ref, 20);
103                 printf("test: ");
104                 dump((char *) hash_test, 20);
105         }
106 
107         return mh_sha256_fail;
108 }
109 
110 int
111 main(int argc, char *argv[])
112 {
113         int fail = 0;
114 #ifndef FIPS_MODE
115         uint32_t hash_test[ISAL_SHA256_DIGEST_WORDS], hash_ref[ISAL_SHA256_DIGEST_WORDS];
116         uint8_t *buff = NULL;
117         int i, update_count;
118         int size1, size2, offset, addr_offset;
119         struct mh_sha256_ctx *update_ctx = NULL;
120         uint8_t *mem_addr = NULL;
121 
122         printf(xstr(TEST_UPDATE_FUNCTION) "_test:");
123 
124         srand(TEST_SEED);
125 
126         buff = malloc(TEST_LEN);
127         update_ctx = malloc(sizeof(*update_ctx));
128 
129         if (buff == NULL || update_ctx == NULL) {
130                 printf("malloc failed test aborted\n");
131                 goto end_ctx;
132         }
133         // Rand test1
134         rand_buffer(buff, TEST_LEN);
135 
136         mh_sha256_ref(buff, TEST_LEN, hash_ref);
137 
138         CHECK_RETURN(isal_mh_sha256_init(update_ctx));
139         CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff, TEST_LEN));
140         CHECK_RETURN(TEST_FINAL_FUNCTION(update_ctx, hash_test));
141 
142         fail = compare_digests(hash_ref, hash_test);
143 
144         if (fail) {
145                 printf("fail rand1 test\n");
146                 goto end_ctx;
147         } else
148                 putchar('.');
149 
150         // Test various size messages by update twice.
151         printf("\n various size messages by update twice tests");
152         for (size1 = TEST_LEN; size1 >= 0; size1--) {
153 
154                 // Fill with rand data
155                 rand_buffer(buff, TEST_LEN);
156 
157                 mh_sha256_ref(buff, TEST_LEN, hash_ref);
158 
159                 // subsequent update
160                 size2 = TEST_LEN - size1; // size2 is different with the former
161                 CHECK_RETURN(isal_mh_sha256_init(update_ctx));
162                 CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff, size1));
163                 CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff + size1, size2));
164                 CHECK_RETURN(TEST_FINAL_FUNCTION(update_ctx, hash_test));
165 
166                 fail = compare_digests(hash_ref, hash_test);
167 
168                 if (fail) {
169                         printf("Fail size1=%d\n", size1);
170                         goto end_ctx;
171                 }
172 
173                 if ((size2 & 0xff) == 0) {
174                         putchar('.');
175                         fflush(0);
176                 }
177         }
178 
179         // Test various update count
180         printf("\n various update count tests");
181         for (update_count = 1; update_count <= TEST_LEN; update_count++) {
182 
183                 // Fill with rand data
184                 rand_buffer(buff, TEST_LEN);
185 
186                 mh_sha256_ref(buff, TEST_LEN, hash_ref);
187 
188                 // subsequent update
189                 size1 = TEST_LEN / update_count;
190                 size2 = TEST_LEN - size1 * (update_count - 1); // size2 is different with the former
191 
192                 CHECK_RETURN(isal_mh_sha256_init(update_ctx));
193                 for (i = 1, offset = 0; i < update_count; i++) {
194                         CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff + offset, size1));
195                         offset += size1;
196                 }
197                 CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff + offset, size2));
198                 CHECK_RETURN(TEST_FINAL_FUNCTION(update_ctx, hash_test));
199 
200                 fail = compare_digests(hash_ref, hash_test);
201 
202                 if (fail) {
203                         printf("Fail size1=%d\n", size1);
204                         goto end_ctx;
205                 }
206 
207                 if ((size2 & 0xff) == 0) {
208                         putchar('.');
209                         fflush(0);
210                 }
211         }
212 
213         // test various start address of ctx.
214         printf("\n various start address of ctx test");
215 
216         free(update_ctx);
217 
218         // test various start address of ctx.
219         printf("\n various start address of ctx test");
220         mem_addr = (uint8_t *) malloc(sizeof(*update_ctx) + ISAL_AVX512_ALIGNED * 10);
221         if (mem_addr == NULL) {
222                 fail++;
223                 goto end;
224         }
225 
226         for (addr_offset = ISAL_AVX512_ALIGNED * 10; addr_offset >= 0; addr_offset--) {
227 
228                 // Fill with rand data
229                 rand_buffer(buff, TEST_LEN);
230 
231                 mh_sha256_ref(buff, TEST_LEN, hash_ref);
232 
233                 // a unaligned offset
234                 update_ctx = (struct mh_sha256_ctx *) (mem_addr + addr_offset);
235                 CHECK_RETURN(isal_mh_sha256_init(update_ctx));
236                 CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff, TEST_LEN));
237                 CHECK_RETURN(TEST_FINAL_FUNCTION(update_ctx, hash_test));
238 
239                 fail = compare_digests(hash_ref, hash_test);
240 
241                 if (fail) {
242                         printf("Fail addr_offset=%d\n", addr_offset);
243                         goto end;
244                 }
245 
246                 if ((addr_offset & 0xf) == 0) {
247                         putchar('.');
248                         fflush(0);
249                 }
250         }
251 end:
252         if (mem_addr != NULL)
253                 free(mem_addr);
254         if (buff != NULL)
255                 free(buff);
256 
257         printf("\n" xstr(TEST_UPDATE_FUNCTION) "_test: %s\n", fail == 0 ? "Pass" : "Fail");
258 #else
259         printf("Not Executed\n");
260 #endif /* FIPS_MODE */
261         return fail;
262 
263 #ifndef FIPS_MODE
264 end_ctx:
265         if (update_ctx != NULL)
266                 free(update_ctx);
267         goto end;
268 #endif
269 }
270