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 "sha512_mb.h" 34 35 typedef uint64_t DigestSHA512[SHA512_DIGEST_NWORDS]; 36 37 #define MSGS 8 38 #define NUM_JOBS 1000 39 40 #define PSEUDO_RANDOM_NUM(seed) ((seed) * 5 + ((seed) * (seed)) / 64) % MSGS 41 42 static uint8_t msg1[] = "The quick brown fox jumps over the lazy dog"; 43 static uint8_t msg2[] = "The quick brown fox jumps over the lazy dog."; 44 static uint8_t msg3[] = { 0x0a, 0x55, 0xdb, 0 }; 45 static uint8_t msg4[] = { 0xba, 0xd7, 0xc6, 0x18, 0xf4, 0x5b, 0xe2, 0x07, 0x97, 0x5e, 0 }; 46 47 static uint8_t msg5[] = { 48 0xb1, 0x71, 0x5f, 0x78, 0x2f, 0xf0, 0x2c, 0x6b, 0x88, 0x93, 49 0x7f, 0x05, 0x41, 0x16, 0 50 }; 51 52 static uint8_t msg6[] = { 53 0xc6, 0xa1, 0x70, 0x93, 0x65, 0x68, 0x65, 0x10, 0x20, 0xed, 54 0xfe, 0x15, 0xdf, 0x80, 0x12, 0xac, 0xda, 0x8d, 0 55 }; 56 57 static uint8_t msg7[] = { 58 0xa8, 0xa3, 0x7d, 0xfc, 0x08, 0x3a, 0xd2, 0xf4, 0x7f, 0xff, 59 0x46, 0x87, 0x38, 0xbf, 0x8b, 0x72, 0x8e, 0xb7, 0xf1, 0x90, 60 0x7e, 0x42, 0x7f, 0xa1, 0x5c, 0xb4, 0x42, 0x4b, 0xc6, 0x85, 61 0xe5, 0x5e, 0xd7, 0xb2, 0x82, 0x5c, 0x9c, 0x60, 0xb8, 0x39, 62 0xcc, 0xc2, 0xfe, 0x5f, 0xb3, 0x3e, 0x36, 0xf5, 0x70, 0xcb, 63 0x86, 0x61, 0x60, 0x9e, 0x63, 0x0b, 0xda, 0x05, 0xee, 0x64, 64 0x1d, 0x93, 0x84, 0x28, 0x86, 0x7d, 0x90, 0xe0, 0x07, 0x44, 65 0xa4, 0xaa, 0xd4, 0x94, 0xc9, 0x3c, 0x5f, 0x6d, 0x13, 0x27, 66 0x87, 0x80, 0x78, 0x59, 0x0c, 0xdc, 0xe1, 0xe6, 0x47, 0xc9, 67 0x82, 0x08, 0x18, 0xf4, 0x67, 0x64, 0x1f, 0xcd, 0x50, 0x8e, 68 0x2f, 0x2e, 0xbf, 0xd0, 0xff, 0x3d, 0x4f, 0x27, 0x23, 0x93, 69 0x47, 0x8f, 0x3b, 0x9e, 0x6f, 0x80, 0x6b, 0x43, 0 70 }; 71 72 static uint8_t msg8[] = ""; 73 74 static DigestSHA512 expResultDigest1 = { 75 0x07e547d9586f6a73, 0xf73fbac0435ed769, 0x51218fb7d0c8d788, 0xa309d785436bbb64, 76 0x2e93a252a954f239, 0x12547d1e8a3b5ed6, 0xe1bfd7097821233f, 0xa0538f3db854fee6 77 }; 78 79 static DigestSHA512 expResultDigest2 = { 80 0x91ea1245f20d46ae, 0x9a037a989f54f1f7, 0x90f0a47607eeb8a1, 0x4d12890cea77a1bb, 81 0xc6c7ed9cf205e67b, 0x7f2b8fd4c7dfd3a7, 0xa8617e45f3c463d4, 0x81c7e586c39ac1ed 82 }; 83 84 static DigestSHA512 expResultDigest3 = { 85 0x7952585e5330cb24, 0x7d72bae696fc8a6b, 0x0f7d0804577e347d, 0x99bc1b11e52f3849, 86 0x85a428449382306a, 0x89261ae143c2f3fb, 0x613804ab20b42dc0, 0x97e5bf4a96ef919b 87 }; 88 89 static DigestSHA512 expResultDigest4 = { 90 0x5886828959d1f822, 0x54068be0bd14b6a8, 0x8f59f534061fb203, 0x76a0541052dd3635, 91 0xedf3c6f0ca3d0877, 0x5e13525df9333a21, 0x13c0b2af76515887, 0x529910b6c793c8a5 92 }; 93 94 static DigestSHA512 expResultDigest5 = { 95 0xee1a56ee78182ec4, 0x1d2c3ab33d4c4187, 0x1d437c5c1ca060ee, 0x9e219cb83689b4e5, 96 0xa4174dfdab5d1d10, 0x96a31a7c8d3abda7, 0x5c1b5e6da97e1814, 0x901c505b0bc07f25 97 }; 98 99 static DigestSHA512 expResultDigest6 = { 100 0xc36c100cdb6c8c45, 0xb072f18256d63a66, 0xc9843acb4d07de62, 0xe0600711d4fbe64c, 101 0x8cf314ec3457c903, 0x08147cb7ac7e4d07, 0x3ba10f0ced78ea72, 0x4a474b32dae71231 102 }; 103 104 static DigestSHA512 expResultDigest7 = { 105 0x8e1c91729be8eb40, 0x226f6c58a029380e, 0xf7edb9dc166a5c3c, 0xdbcefe90bd30d85c, 106 0xb7c4b248e66abf0a, 0x3a4c842281299bef, 0x6db88858d9e5ab52, 0x44f70b7969e1c072 107 }; 108 109 static DigestSHA512 expResultDigest8 = { 110 0Xcf83e1357eefb8bd, 0Xf1542850d66d8007, 0Xd620e4050b5715dc, 0X83f4a921d36ce9ce, 111 0X47d0d13c5d85f2b0, 0Xff8318d2877eec2f, 0X63b931bd47417a81, 0Xa538327af927da3e 112 }; 113 114 static uint8_t *msgs[MSGS] = { msg1, msg2, msg3, msg4, msg5, msg6, msg7, msg8 }; 115 116 static uint64_t *expResultDigest[MSGS] = { expResultDigest1, expResultDigest2, 117 expResultDigest3, expResultDigest4, expResultDigest5, expResultDigest6, 118 expResultDigest7, expResultDigest8 119 }; 120 121 #define NUM_CHUNKS 4 122 #define DATA_BUF_LEN 4096 123 int non_blocksize_updates_test(SHA512_HASH_CTX_MGR * mgr) 124 { 125 SHA512_HASH_CTX ctx_refer; 126 SHA512_HASH_CTX ctx_pool[NUM_CHUNKS]; 127 SHA512_HASH_CTX *ctx = NULL; 128 129 const int update_chunks[NUM_CHUNKS] = { 32, 64, 128, 256 }; 130 unsigned char data_buf[DATA_BUF_LEN]; 131 132 memset(data_buf, 0xA, DATA_BUF_LEN); 133 134 // Init contexts before first use 135 hash_ctx_init(&ctx_refer); 136 137 ctx = sha512_ctx_mgr_submit(mgr, &ctx_refer, data_buf, DATA_BUF_LEN, HASH_ENTIRE); 138 if (ctx && ctx->error) { 139 return -1; 140 } 141 ctx = sha512_ctx_mgr_flush(mgr); 142 if ((ctx && ctx->error) || (ctx_refer.status != HASH_CTX_STS_COMPLETE)) { 143 return -1; 144 } 145 146 for (int c = 0; c < NUM_CHUNKS; c++) { 147 int chunk = update_chunks[c]; 148 hash_ctx_init(&ctx_pool[c]); 149 for (int i = 0; i * chunk < DATA_BUF_LEN; i++) { 150 HASH_CTX_FLAG flags = HASH_UPDATE; 151 if (i == 0) { 152 flags = HASH_FIRST; 153 } 154 ctx = sha512_ctx_mgr_submit(mgr, &ctx_pool[c], 155 data_buf + i * chunk, chunk, flags); 156 if (ctx && ctx->error) { 157 return -1; 158 } 159 ctx = sha512_ctx_mgr_flush(mgr); 160 if (ctx && ctx->error) { 161 return -1; 162 } 163 } 164 } 165 166 for (int c = 0; c < NUM_CHUNKS; c++) { 167 ctx = sha512_ctx_mgr_submit(mgr, &ctx_pool[c], NULL, 0, HASH_LAST); 168 if (ctx && ctx->error) { 169 return -1; 170 } 171 ctx = sha512_ctx_mgr_flush(mgr); 172 if (ctx && ctx->error) { 173 return -1; 174 } 175 if (ctx_pool[c].status != HASH_CTX_STS_COMPLETE) { 176 return -1; 177 } 178 for (int i = 0; i < SHA512_DIGEST_NWORDS; i++) { 179 if (ctx_refer.job.result_digest[i] != ctx_pool[c].job.result_digest[i]) { 180 printf 181 ("sha512 calc error! chunk %d, digest[%d], (%ld) != (%ld)\n", 182 update_chunks[c], i, ctx_refer.job.result_digest[i], 183 ctx_pool[c].job.result_digest[i]); 184 return -2; 185 } 186 } 187 } 188 return 0; 189 } 190 191 int main(void) 192 { 193 SHA512_HASH_CTX_MGR *mgr = NULL; 194 SHA512_HASH_CTX ctxpool[NUM_JOBS], *ctx = NULL; 195 uint32_t i, j, k, t, checked = 0; 196 uint64_t *good; 197 int ret; 198 199 #if defined(_WIN32) || defined(_WIN64) 200 mgr = (SHA512_HASH_CTX_MGR *) _aligned_malloc(sizeof(SHA512_HASH_CTX_MGR), 16); 201 if (mgr == NULL) { 202 printf("aligned_malloc failed, test aborted\n"); 203 return 1; 204 } 205 #else 206 ret = posix_memalign((void *)&mgr, 16, sizeof(SHA512_HASH_CTX_MGR)); 207 if ((ret != 0) || (mgr == NULL)) { 208 printf("posix_memalign failed, test aborted\n"); 209 return 1; 210 } 211 #endif 212 213 sha512_ctx_mgr_init(mgr); 214 215 // Init contexts before first use 216 for (i = 0; i < MSGS; i++) { 217 hash_ctx_init(&ctxpool[i]); 218 ctxpool[i].user_data = (void *)((uint64_t) i); 219 } 220 221 for (i = 0; i < MSGS; i++) { 222 ctx = sha512_ctx_mgr_submit(mgr, 223 &ctxpool[i], 224 msgs[i], strlen((char *)msgs[i]), HASH_ENTIRE); 225 226 if (ctx) { 227 t = (unsigned long)(ctx->user_data); 228 good = expResultDigest[t]; 229 checked++; 230 for (j = 0; j < SHA512_DIGEST_NWORDS; j++) { 231 if (good[j] != ctxpool[t].job.result_digest[j]) { 232 printf("Test %d, digest %d is %016lX, " 233 "should be %016lX\n", t, j, 234 ctxpool[t].job.result_digest[j], good[j]); 235 return -1; 236 } 237 } 238 239 if (ctx->error) { 240 printf("Something bad happened during the" 241 " submit. Error code: %d", ctx->error); 242 return -1; 243 } 244 } 245 } 246 247 while (1) { 248 ctx = sha512_ctx_mgr_flush(mgr); 249 250 if (ctx) { 251 t = (unsigned long)(ctx->user_data); 252 good = expResultDigest[t]; 253 checked++; 254 for (j = 0; j < SHA512_DIGEST_NWORDS; j++) { 255 if (good[j] != ctxpool[t].job.result_digest[j]) { 256 printf("Test %d, digest %d is %016lX, " 257 "should be %016lX\n", t, j, 258 ctxpool[t].job.result_digest[j], good[j]); 259 return -1; 260 } 261 } 262 263 if (ctx->error) { 264 printf("Something bad happened during the " 265 "submit. Error code: %d", ctx->error); 266 return -1; 267 } 268 } else { 269 break; 270 } 271 } 272 273 // do larger test in pseudo-random order 274 275 // Init contexts before first use 276 for (i = 0; i < NUM_JOBS; i++) { 277 hash_ctx_init(&ctxpool[i]); 278 ctxpool[i].user_data = (void *)((uint64_t) i); 279 } 280 281 checked = 0; 282 for (i = 0; i < NUM_JOBS; i++) { 283 j = PSEUDO_RANDOM_NUM(i); 284 285 ctx = sha512_ctx_mgr_submit(mgr, 286 &ctxpool[i], 287 msgs[j], strlen((char *)msgs[j]), HASH_ENTIRE); 288 289 if (ctx) { 290 t = (unsigned long)(ctx->user_data); 291 k = PSEUDO_RANDOM_NUM(t); 292 good = expResultDigest[k]; 293 checked++; 294 for (j = 0; j < SHA512_DIGEST_NWORDS; j++) { 295 if (good[j] != ctxpool[t].job.result_digest[j]) { 296 printf("Test %d, digest %d is %016lX, " 297 "should be %016lX\n", t, j, 298 ctxpool[t].job.result_digest[j], good[j]); 299 return -1; 300 } 301 } 302 303 if (ctx->error) { 304 printf("Something bad happened during the" 305 " submit. Error code: %d", ctx->error); 306 return -1; 307 } 308 309 t = (unsigned long)(ctx->user_data); 310 k = PSEUDO_RANDOM_NUM(t); 311 } 312 } 313 while (1) { 314 ctx = sha512_ctx_mgr_flush(mgr); 315 316 if (ctx) { 317 t = (unsigned long)(ctx->user_data); 318 k = PSEUDO_RANDOM_NUM(t); 319 good = expResultDigest[k]; 320 checked++; 321 for (j = 0; j < SHA512_DIGEST_NWORDS; j++) { 322 if (good[j] != ctxpool[t].job.result_digest[j]) { 323 printf("Test %d, digest %d is %016lX, " 324 "should be %016lX\n", t, j, 325 ctxpool[t].job.result_digest[j], good[j]); 326 return -1; 327 } 328 } 329 330 if (ctx->error) { 331 printf("Something bad happened during the" 332 " submit. Error code: %d", ctx->error); 333 return -1; 334 } 335 } else { 336 break; 337 } 338 } 339 340 if (checked != NUM_JOBS) { 341 printf("only tested %d rather than %d\n", checked, NUM_JOBS); 342 return -1; 343 } 344 int rc = non_blocksize_updates_test(mgr); 345 #if defined(_WIN32) || defined(_WIN64) 346 _aligned_free(mgr); 347 #else 348 free(mgr); 349 #endif 350 if (rc) { 351 printf("multi updates test fail %d\n", rc); 352 return rc; 353 } 354 printf(" multibinary_sha512 test: Pass\n"); 355 return 0; 356 } 357