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