void gtkhash_hmac_start(struct hash_func_s *func, const uint8_t *key, const size_t key_size) { g_assert(func); g_assert(func->hmac_supported); g_assert(func->block_size > 0); g_assert(key); func->hmac_data = g_new(struct hash_func_s, 1); uint8_t padded_key[func->block_size]; memset(padded_key, 0, func->block_size); if (key_size > func->block_size) { gtkhash_hash_func_init(func->hmac_data, func->id); func->hmac_data->enabled = true; gtkhash_hash_lib_start(func->hmac_data, NULL, 0); gtkhash_hash_lib_update(func->hmac_data, key, key_size); gtkhash_hash_lib_finish(func->hmac_data); size_t newsize = func->hmac_data->digest_size; g_assert((newsize > 0) && (newsize <= func->block_size)); memcpy(padded_key, func->hmac_data->digest->bin, newsize); gtkhash_hash_func_deinit(func->hmac_data); } else memcpy(padded_key, key, key_size); uint8_t pad[func->block_size]; for (int i = 0; i < func->block_size; i++) pad[i] = 0x36 ^ padded_key[i]; gtkhash_hash_lib_update(func, pad, func->block_size); gtkhash_hash_func_init(func->hmac_data, func->id); func->hmac_data->enabled = true; gtkhash_hash_lib_start(func->hmac_data, NULL, 0); for (int i = 0; i < func->block_size; i++) pad[i] = 0x5c ^ padded_key[i]; gtkhash_hash_lib_update(func->hmac_data, pad, func->block_size); }
void gtkhash_hash_string(struct hash_func_s *funcs, const char *str, const enum digest_format_e format) { g_assert(str); g_assert(DIGEST_FORMAT_IS_VALID(format)); for (int i = 0; i < HASH_FUNCS_N; i++) { if (!funcs[i].enabled) continue; gtkhash_hash_lib_start(&funcs[i]); // Assuming this won't take too long gtkhash_hash_lib_update(&funcs[i], (const uint8_t *)str, strlen(str)); gtkhash_hash_lib_finish(&funcs[i]); const char *digest = gtkhash_hash_func_get_digest(&funcs[i], format); gtkhash_hash_string_finish_cb(funcs[i].id, digest); } }
static void gtkhash_hash_file_start(struct hash_file_s *data) { g_assert(data->uri); int funcs_enabled = 0; for (int i = 0; i < HASH_FUNCS_N; i++) { if (data->funcs[i].enabled) { gtkhash_hash_lib_start(&data->funcs[i], data->hmac_key, data->key_size); funcs_enabled++; } } g_assert(funcs_enabled > 0); #ifdef _SC_NPROCESSORS_ONLN const long int cpus = sysconf(_SC_NPROCESSORS_ONLN); if (cpus < 1) g_warning("sysconf(_SC_NPROCESSORS_ONLN) returned %ld", cpus); #else #warning "insert code to find number of CPUs here" const int cpus = 1; #endif const int threads = CLAMP(MIN(funcs_enabled, cpus), 1, HASH_FUNCS_N); g_atomic_int_set(&data->pool_threads_n, 0); data->thread_pool = g_thread_pool_new((GFunc)gtkhash_hash_file_hash_thread, data, threads, true, NULL); data->file = g_file_new_for_uri(data->uri); data->just_read = 0; data->buffer = g_malloc(HASH_FILE_BUFFER_SIZE); data->timer = g_timer_new(); data->priv.total_read = 0; gtkhash_hash_file_set_state(data, HASH_FILE_STATE_OPEN); }