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