xref: /isa-l_crypto/mh_sha256/mh_sha256_update_test.c (revision 122c17795e4bee7e9242fceb7a09851e8f4e3a31)
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(mh_sha256_update, MH_SHA256_FUNC_TYPE)
52 #define TEST_FINAL_FUNCTION  FUNC_TOKEN(mh_sha256_finalize, MH_SHA256_FUNC_TYPE)
53 
54 #define CHECK_RETURN(state)                                                                        \
55         do {                                                                                       \
56                 if ((state) != 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[SHA256_DIGEST_WORDS], uint32_t hash_test[SHA256_DIGEST_WORDS])
89 {
90         int i;
91         int mh_sha256_fail = 0;
92 
93         for (i = 0; i < SHA256_DIGEST_WORDS; i++) {
94                 if (hash_test[i] != hash_ref[i])
95                         mh_sha256_fail++;
96         }
97 
98         if (mh_sha256_fail) {
99                 printf("mh_sha256 fail test\n");
100                 printf("ref: ");
101                 dump((char *) hash_ref, 20);
102                 printf("test: ");
103                 dump((char *) hash_test, 20);
104         }
105 
106         return mh_sha256_fail;
107 }
108 
109 int
110 main(int argc, char *argv[])
111 {
112         int fail = 0, i;
113         uint32_t hash_test[SHA256_DIGEST_WORDS], hash_ref[SHA256_DIGEST_WORDS];
114         uint8_t *buff = NULL;
115         int update_count;
116         int size1, size2, offset, addr_offset;
117         struct mh_sha256_ctx *update_ctx = NULL;
118         uint8_t *mem_addr = NULL;
119 
120         printf(xstr(TEST_UPDATE_FUNCTION) "_test:");
121 
122         srand(TEST_SEED);
123 
124         buff = malloc(TEST_LEN);
125         update_ctx = malloc(sizeof(*update_ctx));
126 
127         if (buff == NULL || update_ctx == NULL) {
128                 printf("malloc failed test aborted\n");
129                 goto end_ctx;
130         }
131         // Rand test1
132         rand_buffer(buff, TEST_LEN);
133 
134         mh_sha256_ref(buff, TEST_LEN, hash_ref);
135 
136         CHECK_RETURN(mh_sha256_init(update_ctx));
137         CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff, TEST_LEN));
138         CHECK_RETURN(TEST_FINAL_FUNCTION(update_ctx, hash_test));
139 
140         fail = compare_digests(hash_ref, hash_test);
141 
142         if (fail) {
143                 printf("fail rand1 test\n");
144                 goto end_ctx;
145         } else
146                 putchar('.');
147 
148         // Test various size messages by update twice.
149         printf("\n various size messages by update twice tests");
150         for (size1 = TEST_LEN; size1 >= 0; size1--) {
151 
152                 // Fill with rand data
153                 rand_buffer(buff, TEST_LEN);
154 
155                 mh_sha256_ref(buff, TEST_LEN, hash_ref);
156 
157                 // subsequent update
158                 size2 = TEST_LEN - size1; // size2 is different with the former
159                 CHECK_RETURN(mh_sha256_init(update_ctx));
160                 CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff, size1));
161                 CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff + size1, size2));
162                 CHECK_RETURN(TEST_FINAL_FUNCTION(update_ctx, hash_test));
163 
164                 fail = compare_digests(hash_ref, hash_test);
165 
166                 if (fail) {
167                         printf("Fail size1=%d\n", size1);
168                         goto end_ctx;
169                 }
170 
171                 if ((size2 & 0xff) == 0) {
172                         putchar('.');
173                         fflush(0);
174                 }
175         }
176 
177         // Test various update count
178         printf("\n various update count tests");
179         for (update_count = 1; update_count <= TEST_LEN; update_count++) {
180 
181                 // Fill with rand data
182                 rand_buffer(buff, TEST_LEN);
183 
184                 mh_sha256_ref(buff, TEST_LEN, hash_ref);
185 
186                 // subsequent update
187                 size1 = TEST_LEN / update_count;
188                 size2 = TEST_LEN - size1 * (update_count - 1); // size2 is different with the former
189 
190                 CHECK_RETURN(mh_sha256_init(update_ctx));
191                 for (i = 1, offset = 0; i < update_count; i++) {
192                         CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff + offset, size1));
193                         offset += size1;
194                 }
195                 CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff + offset, size2));
196                 CHECK_RETURN(TEST_FINAL_FUNCTION(update_ctx, hash_test));
197 
198                 fail = compare_digests(hash_ref, hash_test);
199 
200                 if (fail) {
201                         printf("Fail size1=%d\n", size1);
202                         goto end_ctx;
203                 }
204 
205                 if ((size2 & 0xff) == 0) {
206                         putchar('.');
207                         fflush(0);
208                 }
209         }
210 
211         // test various start address of ctx.
212         printf("\n various start address of ctx test");
213 
214         free(update_ctx);
215 
216         // test various start address of ctx.
217         printf("\n various start address of ctx test");
218         mem_addr = (uint8_t *) malloc(sizeof(*update_ctx) + AVX512_ALIGNED * 10);
219         if (mem_addr == NULL) {
220                 fail++;
221                 goto end;
222         }
223 
224         for (addr_offset = AVX512_ALIGNED * 10; addr_offset >= 0; addr_offset--) {
225 
226                 // Fill with rand data
227                 rand_buffer(buff, TEST_LEN);
228 
229                 mh_sha256_ref(buff, TEST_LEN, hash_ref);
230 
231                 // a unaligned offset
232                 update_ctx = (struct mh_sha256_ctx *) (mem_addr + addr_offset);
233                 CHECK_RETURN(mh_sha256_init(update_ctx));
234                 CHECK_RETURN(TEST_UPDATE_FUNCTION(update_ctx, buff, TEST_LEN));
235                 CHECK_RETURN(TEST_FINAL_FUNCTION(update_ctx, hash_test));
236 
237                 fail = compare_digests(hash_ref, hash_test);
238 
239                 if (fail) {
240                         printf("Fail addr_offset=%d\n", addr_offset);
241                         goto end;
242                 }
243 
244                 if ((addr_offset & 0xf) == 0) {
245                         putchar('.');
246                         fflush(0);
247                 }
248         }
249 end:
250         if (mem_addr != NULL)
251                 free(mem_addr);
252         if (buff != NULL)
253                 free(buff);
254 
255         printf("\n" xstr(TEST_UPDATE_FUNCTION) "_test: %s\n", fail == 0 ? "Pass" : "Fail");
256 
257         return fail;
258 
259 end_ctx:
260         if (update_ctx != NULL)
261                 free(update_ctx);
262         goto end;
263 }
264