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 "sha1_mb.h" 34 #include "endian_helper.h" 35 36 typedef uint32_t DigestSHA1[SHA1_DIGEST_NWORDS]; 37 38 #define MSGS 7 39 #define NUM_JOBS 1000 40 41 #define PSEUDO_RANDOM_NUM(seed) ((seed) * 5 + ((seed) * (seed)) / 64) % MSGS 42 static uint8_t msg1[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; 43 static DigestSHA1 expResultDigest1 = { 0x84983E44, 0x1C3BD26E, 0xBAAE4AA1, 0xF95129E5, 0xE54670F1 }; 44 45 static uint8_t msg2[] = "0123456789:;<=>?@ABCDEFGHIJKLMNO"; 46 static DigestSHA1 expResultDigest2 = { 0xB7C66452, 0x0FD122B3, 0x55D539F2, 0xA35E6FAA, 0xC2A5A11D }; 47 48 static uint8_t msg3[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 49 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 50 "0123456789:;<"; 51 static DigestSHA1 expResultDigest3 = { 0x127729B6, 0xA8B2F8A0, 0xA4DDC819, 0x08E1D8B3, 0x67CEEA55 }; 52 53 static uint8_t msg4[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 54 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 55 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 56 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQR"; 57 static DigestSHA1 expResultDigest4 = { 0xFDDE2D00, 0xABD5B7A3, 0x699DE6F2, 0x3FF1D1AC, 0x3B872AC2 }; 58 59 static uint8_t msg5[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 60 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 61 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 62 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 63 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 64 "0123456789:;<=>?"; 65 static DigestSHA1 expResultDigest5 = { 0xE7FCA85C, 0xA4AB3740, 0x6A180B32, 0x0B8D362C, 0x622A96E6 }; 66 67 static uint8_t msg6[] = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 68 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 69 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 70 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 71 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 72 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX" 73 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU"; 74 static DigestSHA1 expResultDigest6 = { 0x505B0686, 0xE1ACDF42, 0xB3588B5A, 0xB043D52C, 0x6D8C7444 }; 75 76 static uint8_t msg7[] = ""; 77 static DigestSHA1 expResultDigest7 = { 0xDA39A3EE, 0x5E6B4B0D, 0x3255BFEF, 0x95601890, 0xAFD80709 }; 78 79 static uint8_t *msgs[MSGS] = { msg1, msg2, msg3, msg4, msg5, msg6, msg7 }; 80 81 static uint32_t *expResultDigest[MSGS] = { expResultDigest1, expResultDigest2, expResultDigest3, 82 expResultDigest4, expResultDigest5, expResultDigest6, 83 expResultDigest7 }; 84 85 #define NUM_CHUNKS 4 86 #define DATA_BUF_LEN 4096 87 static int 88 non_blocksize_updates_test(SHA1_HASH_CTX_MGR *mgr) 89 { 90 SHA1_HASH_CTX ctx_refer; 91 SHA1_HASH_CTX ctx_pool[NUM_CHUNKS]; 92 SHA1_HASH_CTX *ctx = NULL; 93 int rc; 94 95 const int update_chunks[NUM_CHUNKS] = { 32, 64, 128, 256 }; 96 unsigned char data_buf[DATA_BUF_LEN]; 97 98 memset(data_buf, 0xA, DATA_BUF_LEN); 99 100 // Init contexts before first use 101 hash_ctx_init(&ctx_refer); 102 103 rc = isal_sha1_ctx_mgr_submit(mgr, &ctx_refer, &ctx, data_buf, DATA_BUF_LEN, HASH_ENTIRE); 104 if (rc) 105 return -1; 106 107 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx); 108 if (rc) 109 return -1; 110 111 for (int c = 0; c < NUM_CHUNKS; c++) { 112 int chunk = update_chunks[c]; 113 hash_ctx_init(&ctx_pool[c]); 114 rc = isal_sha1_ctx_mgr_submit(mgr, &ctx_pool[c], &ctx, NULL, 0, HASH_FIRST); 115 if (rc) 116 return -1; 117 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx); 118 if (rc) 119 return -1; 120 for (int i = 0; i * chunk < DATA_BUF_LEN; i++) { 121 rc = isal_sha1_ctx_mgr_submit(mgr, &ctx_pool[c], &ctx, data_buf + i * chunk, 122 chunk, HASH_UPDATE); 123 if (rc) 124 return -1; 125 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx); 126 if (rc) 127 return -1; 128 } 129 } 130 131 for (int c = 0; c < NUM_CHUNKS; c++) { 132 rc = isal_sha1_ctx_mgr_submit(mgr, &ctx_pool[c], &ctx, NULL, 0, HASH_LAST); 133 if (rc) 134 return -1; 135 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx); 136 if (rc) 137 return -1; 138 if (ctx_pool[c].status != HASH_CTX_STS_COMPLETE) { 139 return -1; 140 } 141 for (int i = 0; i < SHA1_DIGEST_NWORDS; i++) { 142 if (ctx_refer.job.result_digest[i] != ctx_pool[c].job.result_digest[i]) { 143 printf("sm3 calc error! chunk %d, digest[%d], (%d) != (%d)\n", 144 update_chunks[c], i, ctx_refer.job.result_digest[i], 145 ctx_pool[c].job.result_digest[i]); 146 return -2; 147 } 148 } 149 } 150 return 0; 151 } 152 153 int 154 main(void) 155 { 156 SHA1_HASH_CTX_MGR *mgr = NULL; 157 SHA1_HASH_CTX ctxpool[NUM_JOBS], *ctx = NULL; 158 uint32_t i, j, k, t, checked = 0; 159 uint32_t *good; 160 int rc, ret = -1; 161 162 rc = posix_memalign((void *) &mgr, 16, sizeof(SHA1_HASH_CTX_MGR)); 163 if ((rc != 0) || (mgr == NULL)) { 164 printf("posix_memalign failed test aborted\n"); 165 return 1; 166 } 167 168 rc = isal_sha1_ctx_mgr_init(mgr); 169 if (rc) 170 goto end; 171 172 // Init contexts before first use 173 for (i = 0; i < MSGS; i++) { 174 hash_ctx_init(&ctxpool[i]); 175 ctxpool[i].user_data = (void *) ((uint64_t) i); 176 } 177 178 for (i = 0; i < MSGS; i++) { 179 rc = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, msgs[i], 180 (uint32_t) strlen((char *) msgs[i]), HASH_ENTIRE); 181 if (rc) 182 goto end; 183 184 if (ctx) { 185 t = (uint32_t) ((uintptr_t) (ctx->user_data)); 186 good = expResultDigest[t]; 187 checked++; 188 for (j = 0; j < SHA1_DIGEST_NWORDS; j++) { 189 if (good[j] != ctxpool[t].job.result_digest[j]) { 190 printf("Test %d, digest %d is %08X, should be %08X\n", t, j, 191 ctxpool[t].job.result_digest[j], good[j]); 192 goto end; 193 } 194 } 195 196 if (ctx->error) { 197 printf("Something bad happened during the submit." 198 " Error code: %d", 199 ctx->error); 200 goto end; 201 } 202 } 203 } 204 205 while (1) { 206 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx); 207 208 if (ctx) { 209 t = (uint32_t) ((uintptr_t) (ctx->user_data)); 210 good = expResultDigest[t]; 211 checked++; 212 for (j = 0; j < SHA1_DIGEST_NWORDS; j++) { 213 if (good[j] != ctxpool[t].job.result_digest[j]) { 214 printf("Test %d, digest %d is %08X, should be %08X\n", t, j, 215 ctxpool[t].job.result_digest[j], good[j]); 216 goto end; 217 } 218 } 219 220 if (ctx->error) { 221 printf("Something bad happened during the submit." 222 " Error code: %d", 223 ctx->error); 224 goto end; 225 } 226 } else { 227 break; 228 } 229 } 230 231 // do larger test in pseudo-random order 232 233 // Init contexts before first use 234 for (i = 0; i < NUM_JOBS; i++) { 235 hash_ctx_init(&ctxpool[i]); 236 ctxpool[i].user_data = (void *) ((uint64_t) i); 237 } 238 239 checked = 0; 240 for (i = 0; i < NUM_JOBS; i++) { 241 j = PSEUDO_RANDOM_NUM(i); 242 rc = isal_sha1_ctx_mgr_submit(mgr, &ctxpool[i], &ctx, msgs[j], 243 (uint32_t) strlen((char *) msgs[j]), HASH_ENTIRE); 244 if (rc) 245 goto end; 246 if (ctx) { 247 t = (uint32_t) ((uintptr_t) (ctx->user_data)); 248 k = PSEUDO_RANDOM_NUM(t); 249 good = expResultDigest[k]; 250 checked++; 251 for (j = 0; j < SHA1_DIGEST_NWORDS; j++) { 252 if (good[j] != ctxpool[t].job.result_digest[j]) { 253 printf("Test %d, digest %d is %08X, should be %08X\n", t, j, 254 ctxpool[t].job.result_digest[j], good[j]); 255 goto end; 256 } 257 } 258 259 if (ctx->error) { 260 printf("Something bad happened during the" 261 " submit. Error code: %d", 262 ctx->error); 263 goto end; 264 } 265 266 t = (uint32_t) ((uintptr_t) (ctx->user_data)); 267 k = PSEUDO_RANDOM_NUM(t); 268 } 269 } 270 while (1) { 271 rc = isal_sha1_ctx_mgr_flush(mgr, &ctx); 272 273 if (rc) 274 goto end; 275 if (ctx) { 276 t = (uint32_t) ((uintptr_t) (ctx->user_data)); 277 k = PSEUDO_RANDOM_NUM(t); 278 good = expResultDigest[k]; 279 checked++; 280 for (j = 0; j < SHA1_DIGEST_NWORDS; j++) { 281 if (good[j] != ctxpool[t].job.result_digest[j]) { 282 printf("Test %d, digest %d is %08X, should be %08X\n", t, j, 283 ctxpool[t].job.result_digest[j], good[j]); 284 goto end; 285 } 286 } 287 288 if (ctx->error) { 289 printf("Something bad happened during the submit." 290 " Error code: %d", 291 ctx->error); 292 goto end; 293 } 294 } else { 295 break; 296 } 297 } 298 299 if (checked != NUM_JOBS) { 300 printf("only tested %d rather than %d\n", checked, NUM_JOBS); 301 goto end; 302 } 303 304 rc = non_blocksize_updates_test(mgr); 305 if (rc) { 306 printf("multi updates test fail %d\n", rc); 307 goto end; 308 } 309 ret = 0; 310 311 printf(" multibinary_sha1 test: Pass\n"); 312 end: 313 aligned_free(mgr); 314 315 return ret; 316 } 317