1 /********************************************************************** 2 Copyright(c) 2011-2016 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 <string.h> 33 #include "sha256_mb.h" 34 35 typedef uint32_t DigestSHA256[SHA256_DIGEST_NWORDS]; 36 37 #define MSGS 7 38 #define NUM_JOBS 1000 39 40 #define PSEUDO_RANDOM_NUM(seed) ((seed) * 5 + ((seed) * (seed)) / 64) % MSGS 41 42 static uint8_t msg1[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; 43 static uint8_t msg2[] = "0123456789:;<=>?@ABCDEFGHIJKLMNO"; 44 static uint8_t msg3[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 45 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 46 "0123456789:;<"; 47 static uint8_t msg4[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 48 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 49 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 50 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQR"; 51 static uint8_t msg5[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 52 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 53 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 54 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 55 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 56 "0123456789:;<=>?"; 57 static uint8_t msg6[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 58 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 59 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 60 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 61 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 62 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 63 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU"; 64 static uint8_t msg7[] = ""; 65 66 static DigestSHA256 expResultDigest1 = { 0x248D6A61, 0xD20638B8, 0xE5C02693, 0x0C3E6039, 67 0xA33CE459, 0x64FF2167, 0xF6ECEDD4, 0x19DB06C1 }; 68 69 static DigestSHA256 expResultDigest2 = { 0xD9C2E699, 0x586B948F, 0x4022C799, 0x4FFE14C6, 70 0x3A4E8E31, 0x2EE2AEE1, 0xEBE51BED, 0x85705CFD }; 71 72 static DigestSHA256 expResultDigest3 = { 0xE3057651, 0x81295681, 0x7ECF1791, 0xFF9A1619, 73 0xB2BC5CAD, 0x2AC00018, 0x92AE489C, 0x48DD10B3 }; 74 75 static DigestSHA256 expResultDigest4 = { 0x0307DAA3, 0x7130A140, 0x270790F9, 0x95B71407, 76 0x8EC752A6, 0x084EC1F3, 0xBD873D79, 0x3FF78383 }; 77 78 static DigestSHA256 expResultDigest5 = { 0x679312F7, 0x2E18D599, 0x5F51BDC6, 0x4ED56AFD, 79 0x9B5704D3, 0x4387E11C, 0xC2331089, 0x2CD45DAA }; 80 81 static DigestSHA256 expResultDigest6 = { 0x8B1767E9, 0x7BA7BBE5, 0xF9A6E8D9, 0x9996904F, 82 0x3AF6562E, 0xA58AF438, 0x5D8D584B, 0x81C808CE }; 83 84 static DigestSHA256 expResultDigest7 = { 0xE3B0C442, 0x98FC1C14, 0x9AFBF4C8, 0x996FB924, 85 0x27AE41E4, 0x649B934C, 0xA495991B, 0x7852B855 }; 86 87 static uint8_t *msgs[MSGS] = { msg1, msg2, msg3, msg4, msg5, msg6, msg7 }; 88 89 static uint32_t *expResultDigest[MSGS] = { expResultDigest1, expResultDigest2, expResultDigest3, 90 expResultDigest4, expResultDigest5, expResultDigest6, 91 expResultDigest7 }; 92 93 #define NUM_CHUNKS 4 94 #define DATA_BUF_LEN 4096 95 int 96 non_blocksize_updates_test(SHA256_HASH_CTX_MGR *mgr) 97 { 98 SHA256_HASH_CTX ctx_refer; 99 SHA256_HASH_CTX ctx_pool[NUM_CHUNKS]; 100 SHA256_HASH_CTX *ctx = NULL; 101 102 const int update_chunks[NUM_CHUNKS] = { 32, 64, 128, 256 }; 103 unsigned char data_buf[DATA_BUF_LEN]; 104 105 memset(data_buf, 0xA, DATA_BUF_LEN); 106 107 // Init contexts before first use 108 hash_ctx_init(&ctx_refer); 109 110 ctx = sha256_ctx_mgr_submit(mgr, &ctx_refer, data_buf, DATA_BUF_LEN, HASH_ENTIRE); 111 if (ctx && ctx->error) { 112 return -1; 113 } 114 ctx = sha256_ctx_mgr_flush(mgr); 115 if ((ctx && ctx->error) || (ctx_refer.status != HASH_CTX_STS_COMPLETE)) { 116 return -1; 117 } 118 119 for (int c = 0; c < NUM_CHUNKS; c++) { 120 int chunk = update_chunks[c]; 121 hash_ctx_init(&ctx_pool[c]); 122 for (int i = 0; i * chunk < DATA_BUF_LEN; i++) { 123 HASH_CTX_FLAG flags = HASH_UPDATE; 124 if (i == 0) { 125 flags = HASH_FIRST; 126 } 127 ctx = sha256_ctx_mgr_submit(mgr, &ctx_pool[c], data_buf + i * chunk, chunk, 128 flags); 129 if (ctx && ctx->error) { 130 return -1; 131 } 132 ctx = sha256_ctx_mgr_flush(mgr); 133 if (ctx && ctx->error) { 134 return -1; 135 } 136 } 137 } 138 139 for (int c = 0; c < NUM_CHUNKS; c++) { 140 ctx = sha256_ctx_mgr_submit(mgr, &ctx_pool[c], NULL, 0, HASH_LAST); 141 if (ctx && ctx->error) { 142 return -1; 143 } 144 ctx = sha256_ctx_mgr_flush(mgr); 145 if (ctx && ctx->error) { 146 return -1; 147 } 148 if (ctx_pool[c].status != HASH_CTX_STS_COMPLETE) { 149 return -1; 150 } 151 for (int i = 0; i < SHA256_DIGEST_NWORDS; i++) { 152 if (ctx_refer.job.result_digest[i] != ctx_pool[c].job.result_digest[i]) { 153 printf("sha256 calc error! chunk %d, digest[%d], (%d) != (%d)\n", 154 update_chunks[c], i, ctx_refer.job.result_digest[i], 155 ctx_pool[c].job.result_digest[i]); 156 return -2; 157 } 158 } 159 } 160 return 0; 161 } 162 163 int 164 main(void) 165 { 166 SHA256_HASH_CTX_MGR *mgr = NULL; 167 SHA256_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 172 rc = posix_memalign((void *) &mgr, 16, sizeof(SHA256_HASH_CTX_MGR)); 173 if ((rc != 0) || (mgr == NULL)) { 174 printf("posix_memalign failed test aborted\n"); 175 return 1; 176 } 177 178 sha256_ctx_mgr_init(mgr); 179 180 // Init contexts before first use 181 for (i = 0; i < MSGS; i++) { 182 hash_ctx_init(&ctxpool[i]); 183 ctxpool[i].user_data = (void *) ((uint64_t) i); 184 } 185 186 for (i = 0; i < MSGS; i++) { 187 ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], msgs[i], 188 (uint32_t) strlen((char *) msgs[i]), HASH_ENTIRE); 189 190 if (ctx) { 191 t = (uint32_t) (uintptr_t) (ctx->user_data); 192 good = expResultDigest[t]; 193 checked++; 194 for (j = 0; j < SHA256_DIGEST_NWORDS; j++) { 195 if (good[j] != ctxpool[t].job.result_digest[j]) { 196 printf("Test %d, digest %d is %08X, should be %08X\n", t, j, 197 ctxpool[t].job.result_digest[j], good[j]); 198 goto end; 199 } 200 } 201 202 if (ctx->error) { 203 printf("Something bad happened during the submit." 204 " Error code: %d", 205 ctx->error); 206 goto end; 207 } 208 } 209 } 210 211 while (1) { 212 ctx = sha256_ctx_mgr_flush(mgr); 213 214 if (ctx) { 215 t = (uint32_t) (uintptr_t) (ctx->user_data); 216 good = expResultDigest[t]; 217 checked++; 218 for (j = 0; j < SHA256_DIGEST_NWORDS; j++) { 219 if (good[j] != ctxpool[t].job.result_digest[j]) { 220 printf("Test %d, digest %d is %08X, should be %08X\n", t, j, 221 ctxpool[t].job.result_digest[j], good[j]); 222 goto end; 223 } 224 } 225 226 if (ctx->error) { 227 printf("Something bad happened during the submit." 228 " Error code: %d", 229 ctx->error); 230 goto end; 231 } 232 } else { 233 break; 234 } 235 } 236 237 // do larger test in pseudo-random order 238 239 // Init contexts before first use 240 for (i = 0; i < NUM_JOBS; i++) { 241 hash_ctx_init(&ctxpool[i]); 242 ctxpool[i].user_data = (void *) ((uint64_t) i); 243 } 244 245 checked = 0; 246 for (i = 0; i < NUM_JOBS; i++) { 247 j = PSEUDO_RANDOM_NUM(i); 248 ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], msgs[j], 249 (uint32_t) strlen((char *) msgs[j]), HASH_ENTIRE); 250 if (ctx) { 251 t = (uint32_t) (uintptr_t) (ctx->user_data); 252 k = PSEUDO_RANDOM_NUM(t); 253 good = expResultDigest[k]; 254 checked++; 255 for (j = 0; j < SHA256_DIGEST_NWORDS; j++) { 256 if (good[j] != ctxpool[t].job.result_digest[j]) { 257 printf("Test %d, digest %d is %08X, should be %08X\n", t, j, 258 ctxpool[t].job.result_digest[j], good[j]); 259 goto end; 260 } 261 } 262 263 if (ctx->error) { 264 printf("Something bad happened during the" 265 " submit. Error code: %d", 266 ctx->error); 267 goto end; 268 } 269 270 t = (uint32_t) (uintptr_t) (ctx->user_data); 271 k = PSEUDO_RANDOM_NUM(t); 272 } 273 } 274 while (1) { 275 ctx = sha256_ctx_mgr_flush(mgr); 276 277 if (ctx) { 278 t = (uint32_t) (uintptr_t) (ctx->user_data); 279 k = PSEUDO_RANDOM_NUM(t); 280 good = expResultDigest[k]; 281 checked++; 282 for (j = 0; j < SHA256_DIGEST_NWORDS; j++) { 283 if (good[j] != ctxpool[t].job.result_digest[j]) { 284 printf("Test %d, digest %d is %08X, should be %08X\n", t, j, 285 ctxpool[t].job.result_digest[j], good[j]); 286 goto end; 287 } 288 } 289 290 if (ctx->error) { 291 printf("Something bad happened during the submit." 292 " Error code: %d", 293 ctx->error); 294 goto end; 295 } 296 } else { 297 break; 298 } 299 } 300 301 if (checked != NUM_JOBS) { 302 printf("only tested %d rather than %d\n", checked, NUM_JOBS); 303 goto end; 304 } 305 306 rc = non_blocksize_updates_test(mgr); 307 if (rc) { 308 printf("multi updates test fail %d\n", rc); 309 goto end; 310 } 311 ret = 0; 312 313 printf(" multibinary_sha256 test: Pass\n"); 314 end: 315 aligned_free(mgr); 316 317 return ret; 318 } 319