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