void debug_printf(const char *format, ...) { size_t i, fbt; char buffer[13]; char fmtbuffer[100]; const char *str; va_list ap; char c; va_start(ap, format); fbt = 0; for (i = 0; format[i]; i++) { if (format[i] == '%') { fmtbuffer[fbt] = '\0'; debug_string(fmtbuffer); fbt = 0; switch (format[i+1]) { case 'x': case 'X': __itoa(buffer, va_arg(ap, int), 16); debug_string(buffer); break; case 'd': case 'i': __itoa(buffer, va_arg(ap, int), 10); debug_string(buffer); break; case 's': str = va_arg(ap, const char*); if (str) { debug_string(str); } else { debug_string("(null)"); } break; case 'c': c = va_arg(ap, int); debug_char(c); break; case '%': c = '%'; debug_char('%'); break; } i++; } else {
void debug_char(struct s_node *head) { if (head) { my_str("("); if (head->prev && (head->prev)->elem) my_char(*((char *)((head->prev)->elem))); else my_str("NULL"); my_str(" <- "); if (head->elem) my_char(*((char *)(head->elem))); else my_str("NULL"); my_str(" -> "); if (head->next) { my_char(*((char *)((head->next)->elem))); my_str("), "); } else my_str("NULL)"); debug_char(head->next); } }
void debug_str(char* s){ while (*s) debug_char(*s++); }
void debug_byte(char b){ char table[] = "0123456789ABCDEF"; debug_char(table[(b>>4) & 0xf]); debug_char(table[b&0xf]); }
int main(void) { SHA256_HASH_CTX_MGR *mgr = NULL; SHA256_HASH_CTX ctxpool[TEST_BUFS], *ctx = NULL; uint32_t i, j, fail = 0; int len_done, len_rem, len_rand; unsigned char *bufs[TEST_BUFS]; unsigned char *buf_ptr[TEST_BUFS]; uint32_t lens[TEST_BUFS]; unsigned int joblen, jobs, t; printf("multibinary_sha256_update test, %d sets of %dx%d max: ", RANDOMS, TEST_BUFS, TEST_LEN); srand(TEST_SEED); posix_memalign((void *)&mgr, 16, sizeof(SHA256_HASH_CTX_MGR)); sha256_ctx_mgr_init(mgr); for (i = 0; i < TEST_BUFS; i++) { // Allocte and fill buffer bufs[i] = (unsigned char *)malloc(TEST_LEN); buf_ptr[i] = bufs[i]; if (bufs[i] == NULL) { printf("malloc failed test aborted\n"); return 1; } rand_buffer(bufs[i], TEST_LEN); // Init ctx contents hash_ctx_init(&ctxpool[i]); ctxpool[i].user_data = (void *)((uint64_t) i); // Run reference test sha256_ref(bufs[i], digest_ref[i], TEST_LEN); } // Run sb_sha256 tests for (i = 0; i < TEST_BUFS;) { len_done = (int)((unsigned long)buf_ptr[i] - (unsigned long)bufs[i]); len_rem = TEST_LEN - len_done; if (len_done == 0) ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], UPDATE_SIZE, HASH_FIRST); else if (len_rem <= UPDATE_SIZE) ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], len_rem, HASH_LAST); else ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], UPDATE_SIZE, HASH_UPDATE); // Add jobs while available or finished if ((ctx == NULL) || hash_ctx_complete(ctx)) { i++; continue; } // Resubmit unfinished job i = (unsigned long)(ctx->user_data); buf_ptr[i] += UPDATE_SIZE; } // Start flushing finished jobs, end on last flushed ctx = sha256_ctx_mgr_flush(mgr); while (ctx) { if (hash_ctx_complete(ctx)) { debug_char('-'); ctx = sha256_ctx_mgr_flush(mgr); continue; } // Resubmit unfinished job i = (unsigned long)(ctx->user_data); buf_ptr[i] += UPDATE_SIZE; len_done = (int)((unsigned long)buf_ptr[i] - (unsigned long)bufs[i]); len_rem = TEST_LEN - len_done; if (len_rem <= UPDATE_SIZE) ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], len_rem, HASH_LAST); else ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], UPDATE_SIZE, HASH_UPDATE); if (ctx == NULL) ctx = sha256_ctx_mgr_flush(mgr); } // Check digests for (i = 0; i < TEST_BUFS; i++) { for (j = 0; j < SHA256_DIGEST_NWORDS; j++) { if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) { fail++; printf("Test%d fixed size, digest%d fail %8X <=> %8X", i, j, ctxpool[i].job.result_digest[j], digest_ref[i][j]); } } } putchar('.'); // Run tests with random size and number of jobs for (t = 0; t < RANDOMS; t++) { jobs = rand() % (TEST_BUFS); for (i = 0; i < jobs; i++) { joblen = rand() % (TEST_LEN); rand_buffer(bufs[i], joblen); lens[i] = joblen; buf_ptr[i] = bufs[i]; sha256_ref(bufs[i], digest_ref[i], lens[i]); } sha256_ctx_mgr_init(mgr); // Run sha256_sb jobs i = 0; while (i < jobs) { // Submit a new job len_rand = SHA256_BLOCK_SIZE + SHA256_BLOCK_SIZE * (rand() % MAX_RAND_UPDATE_BLOCKS); if (lens[i] > len_rand) ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], len_rand, HASH_FIRST); else ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], lens[i], HASH_ENTIRE); // Returned ctx could be: // - null context (we are just getting started and lanes aren't full yet), or // - finished already (an ENTIRE we submitted or a previous LAST is returned), or // - an unfinished ctx, we will resubmit if ((ctx == NULL) || hash_ctx_complete(ctx)) { i++; continue; } else { // unfinished ctx returned, choose another random update length and submit either // UPDATE or LAST depending on the amount of buffer remaining while ((ctx != NULL) && !(hash_ctx_complete(ctx))) { j = (unsigned long)(ctx->user_data); // Get index of the returned ctx buf_ptr[j] = bufs[j] + ctx->total_length; len_rand = (rand() % SHA256_BLOCK_SIZE) * (rand() % MAX_RAND_UPDATE_BLOCKS); len_rem = lens[j] - ctx->total_length; if (len_rem <= len_rand) // submit the rest of the job as LAST ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[j], buf_ptr[j], len_rem, HASH_LAST); else // submit the random update length as UPDATE ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[j], buf_ptr[j], len_rand, HASH_UPDATE); } // Either continue submitting any contexts returned here as UPDATE/LAST, or // go back to submitting new jobs using the index i. i++; } } // Start flushing finished jobs, end on last flushed ctx = sha256_ctx_mgr_flush(mgr); while (ctx) { if (hash_ctx_complete(ctx)) { debug_char('-'); ctx = sha256_ctx_mgr_flush(mgr); continue; } // Resubmit unfinished job i = (unsigned long)(ctx->user_data); buf_ptr[i] = bufs[i] + ctx->total_length; // update buffer pointer len_rem = lens[i] - ctx->total_length; len_rand = (rand() % SHA256_BLOCK_SIZE) * (rand() % MAX_RAND_UPDATE_BLOCKS); debug_char('+'); if (len_rem <= len_rand) ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], len_rem, HASH_LAST); else ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], len_rand, HASH_UPDATE); if (ctx == NULL) ctx = sha256_ctx_mgr_flush(mgr); } // Check result digest for (i = 0; i < jobs; i++) { for (j = 0; j < SHA256_DIGEST_NWORDS; j++) { if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) { fail++; printf("Test%d, digest%d fail %8X <=> %8X\n", i, j, ctxpool[i].job.result_digest[j], digest_ref[i][j]); } } } if (fail) { printf("Test failed function check %d\n", fail); return fail; } putchar('.'); fflush(0); } // random test t if (fail) printf("Test failed function check %d\n", fail); else printf(" multibinary_sha256_update rand: Pass\n"); return fail; }