Rizin
unix-like reverse engineering framework and cli tools
hash.c File Reference
#include "config.h"
#include <rz_hash.h>
#include <rz_util.h>
#include <xxhash.h>

Go to the source code of this file.

Classes

struct  hash_cfg_config_t
 

Macros

#define hash_cfg_can_hmac(c)   ((c)->status == RZ_MSG_DIGEST_STATUS_ALLOC)
 
#define hash_cfg_can_init(c)   ((c)->status == RZ_MSG_DIGEST_STATUS_FINAL || (c)->status == RZ_MSG_DIGEST_STATUS_ALLOC)
 
#define hash_cfg_can_update(c)   ((c)->status == RZ_MSG_DIGEST_STATUS_INIT || (c)->status == RZ_MSG_DIGEST_STATUS_UPDATE)
 
#define hash_cfg_can_final(c)   ((c)->status == RZ_MSG_DIGEST_STATUS_ALLOC || (c)->status == RZ_MSG_DIGEST_STATUS_INIT || (c)->status == RZ_MSG_DIGEST_STATUS_UPDATE)
 
#define hash_cfg_has_finshed(c)   ((c)->status == RZ_MSG_DIGEST_STATUS_FINAL)
 

Typedefs

typedef struct hash_cfg_config_t HashCfgConfig
 

Functions

 RZ_LIB_VERSION (rz_hash)
 
RZ_API ut32 rz_hash_xxhash (RZ_NONNULL RzHash *rh, RZ_NONNULL const ut8 *input, size_t size)
 
RZ_API double rz_hash_entropy (RZ_NONNULL RzHash *rh, RZ_NONNULL const ut8 *data, ut64 len)
 
RZ_API double rz_hash_entropy_fraction (RZ_NONNULL RzHash *rh, RZ_NONNULL const ut8 *data, ut64 len)
 
static int hash_cfg_config_compare (const void *value, const void *data)
 
static void hash_cfg_config_free (HashCfgConfig *mdc)
 
static HashCfgConfighash_cfg_config_new (const RzHashPlugin *plugin)
 
RZ_API RZ_BORROW const RzHashPluginrz_hash_plugin_by_index (RZ_NONNULL RzHash *rh, size_t index)
 
RZ_API RZ_BORROW const RzHashPluginrz_hash_plugin_by_name (RZ_NONNULL RzHash *rh, RZ_NONNULL const char *name)
 
RZ_API RZ_OWN RzHashCfgrz_hash_cfg_new (RZ_NONNULL RzHash *rh)
 
RZ_API RZ_OWN RzHashCfgrz_hash_cfg_new_with_algo (RZ_NONNULL RzHash *rh, RZ_NONNULL const char *name, RZ_NULLABLE const ut8 *key, ut64 key_size)
 Returns a message digest context with the give algo already configured. More...
 
RZ_API void rz_hash_cfg_free (RZ_NONNULL RzHashCfg *md)
 
RZ_API bool rz_hash_cfg_configure (RZ_NONNULL RzHashCfg *md, RZ_NONNULL const char *name)
 Allocates and configures the plugin message digest context. More...
 
RZ_API bool rz_hash_cfg_hmac (RZ_NONNULL RzHashCfg *md, RZ_NONNULL const ut8 *key, ut64 key_size)
 Sets the key for the hmac algorithm. More...
 
RZ_API bool rz_hash_cfg_init (RZ_NONNULL RzHashCfg *md)
 Resets/initialize the message digest contextes. More...
 
RZ_API bool rz_hash_cfg_update (RZ_NONNULL RzHashCfg *md, RZ_NONNULL const ut8 *data, ut64 size)
 Inserts data into each the message digest contextes. More...
 
RZ_API bool rz_hash_cfg_final (RZ_NONNULL RzHashCfg *md)
 Generates the final value of the message digest contextes. More...
 
RZ_API bool rz_hash_cfg_iterate (RZ_NONNULL RzHashCfg *md, size_t iterate)
 Calculate the final hash by iterating its result N times. More...
 
RZ_API RZ_BORROW const ut8rz_hash_cfg_get_result (RZ_NONNULL RzHashCfg *md, RZ_NONNULL const char *name, RZ_NONNULL ut32 *size)
 Returns the digest value of the requested algorithm name. More...
 
RZ_API RZ_OWN char * rz_hash_cfg_get_result_string (RZ_NONNULL RzHashCfg *md, RZ_NONNULL const char *name, RZ_NULLABLE ut32 *size, bool invert)
 Returns the digest value of the requested algorithm name. More...
 
RZ_API RzHashSize rz_hash_cfg_size (RZ_NONNULL RzHashCfg *md, RZ_NONNULL const char *name)
 Returns the digest size of the requested algorithm name. More...
 
RZ_API RZ_OWN ut8rz_hash_cfg_calculate_small_block (RZ_NONNULL RzHash *rh, RZ_NONNULL const char *name, RZ_NONNULL const ut8 *buffer, ut64 bsize, RZ_NONNULL RzHashSize *osize)
 Returns the digest size of the requested algorithm name. More...
 
RZ_API RZ_OWN char * rz_hash_cfg_calculate_small_block_string (RZ_NONNULL RzHash *rh, RZ_NONNULL const char *name, RZ_NONNULL const ut8 *buffer, ut64 bsize, RZ_NULLABLE ut32 *size, bool invert)
 
RZ_API RzHashrz_hash_new (void)
 
RZ_API void rz_hash_free (RzHash *rh)
 
RZ_API bool rz_hash_plugin_add (RZ_NONNULL RzHash *rh, RZ_NONNULL RZ_OWN const RzHashPlugin *plugin)
 Add a new plugin to rh so that RzHashCfg can be created using specific algorithms. More...
 

Variables

static const RzHashPluginhash_static_plugins [] = { RZ_HASH_STATIC_PLUGINS }
 

Macro Definition Documentation

◆ hash_cfg_can_final

#define hash_cfg_can_final (   c)    ((c)->status == RZ_MSG_DIGEST_STATUS_ALLOC || (c)->status == RZ_MSG_DIGEST_STATUS_INIT || (c)->status == RZ_MSG_DIGEST_STATUS_UPDATE)

Definition at line 14 of file hash.c.

◆ hash_cfg_can_hmac

#define hash_cfg_can_hmac (   c)    ((c)->status == RZ_MSG_DIGEST_STATUS_ALLOC)

Definition at line 11 of file hash.c.

◆ hash_cfg_can_init

#define hash_cfg_can_init (   c)    ((c)->status == RZ_MSG_DIGEST_STATUS_FINAL || (c)->status == RZ_MSG_DIGEST_STATUS_ALLOC)

Definition at line 12 of file hash.c.

◆ hash_cfg_can_update

#define hash_cfg_can_update (   c)    ((c)->status == RZ_MSG_DIGEST_STATUS_INIT || (c)->status == RZ_MSG_DIGEST_STATUS_UPDATE)

Definition at line 13 of file hash.c.

◆ hash_cfg_has_finshed

#define hash_cfg_has_finshed (   c)    ((c)->status == RZ_MSG_DIGEST_STATUS_FINAL)

Definition at line 15 of file hash.c.

Typedef Documentation

◆ HashCfgConfig

Function Documentation

◆ hash_cfg_config_compare()

static int hash_cfg_config_compare ( const void *  value,
const void *  data 
)
static

Definition at line 58 of file hash.c.

58  {
59  const HashCfgConfig *mdc = (const HashCfgConfig *)data;
60  const char *name = (const char *)value;
61  return strcmp(name, mdc->plugin->name);
62 }
static int value
Definition: cmd_api.c:93
const RzHashPlugin * plugin
Definition: hash.c:22
Definition: z80asm.h:102
const char * name
Definition: rz_hash.h:27

References rz_hash_plugin_t::name, hash_cfg_config_t::plugin, and value.

Referenced by rz_hash_cfg_configure(), rz_hash_cfg_get_result(), rz_hash_cfg_get_result_string(), and rz_hash_cfg_size().

◆ hash_cfg_config_free()

static void hash_cfg_config_free ( HashCfgConfig mdc)
static

Definition at line 64 of file hash.c.

64  {
65  rz_return_if_fail(mdc && mdc->plugin);
66 
67  mdc->plugin->context_free(mdc->context);
68  free(mdc->hmac_key);
69  free(mdc->digest);
70  free(mdc);
71 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
ut8 * hmac_key
Definition: hash.c:20
ut8 * digest
Definition: hash.c:19
void * context
Definition: hash.c:18
void(* context_free)(void *context)
Definition: rz_hash.h:32

References hash_cfg_config_t::context, rz_hash_plugin_t::context_free, hash_cfg_config_t::digest, free(), hash_cfg_config_t::hmac_key, hash_cfg_config_t::plugin, and rz_return_if_fail.

Referenced by rz_hash_cfg_configure(), and rz_hash_cfg_new().

◆ hash_cfg_config_new()

static HashCfgConfig* hash_cfg_config_new ( const RzHashPlugin plugin)
static

Definition at line 73 of file hash.c.

73  {
74  rz_return_val_if_fail(plugin, NULL);
75 
77  if (!mdc) {
78  RZ_LOG_ERROR("msg digest: cannot allocate memory for config.\n");
79  return NULL;
80  }
81 
82  mdc->context = plugin->context_new();
83  if (!mdc->context) {
84  RZ_LOG_ERROR("msg digest: cannot allocate memory for context.\n");
85  free(mdc);
86  return NULL;
87  }
88 
89  mdc->digest_size = plugin->digest_size(mdc->context);
90  rz_warn_if_fail(mdc->digest_size > 0);
91 
92  mdc->digest = RZ_NEWS0(ut8, mdc->digest_size);
93  if (!mdc->context) {
94  RZ_LOG_ERROR("msg digest: cannot allocate memory for digest.\n");
95  plugin->context_free(mdc->context);
96  free(mdc);
97  return NULL;
98  }
99  mdc->plugin = plugin;
100 
101  return mdc;
102 }
#define NULL
Definition: cris-opc.c:27
uint8_t ut8
Definition: lh5801.h:11
#define rz_warn_if_fail(expr)
Definition: rz_assert.h:35
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
RzHashSize digest_size
Definition: hash.c:21
RzHashSize(* digest_size)(void *context)
Definition: rz_hash.h:33
void *(* context_new)()
Definition: rz_hash.h:31

References hash_cfg_config_t::context, rz_hash_plugin_t::context_free, rz_hash_plugin_t::context_new, hash_cfg_config_t::digest, hash_cfg_config_t::digest_size, rz_hash_plugin_t::digest_size, free(), NULL, hash_cfg_config_t::plugin, RZ_LOG_ERROR, RZ_NEW0, RZ_NEWS0, rz_return_val_if_fail, and rz_warn_if_fail.

Referenced by rz_hash_cfg_configure().

◆ rz_hash_cfg_calculate_small_block()

RZ_API RZ_OWN ut8* rz_hash_cfg_calculate_small_block ( RZ_NONNULL RzHash rh,
RZ_NONNULL const char *  name,
RZ_NONNULL const ut8 buffer,
ut64  bsize,
RZ_NONNULL RzHashSize osize 
)

Returns the digest size of the requested algorithm name.

Returns the digest size of the initialized configuration.

Definition at line 529 of file hash.c.

529  {
531 
532  ut8 *result = NULL;
533  const RzHashPlugin *plugin = rz_hash_plugin_by_name(rh, name);
534  if (!plugin) {
535  return NULL;
536  }
537 
538  if (!plugin->small_block(buffer, bsize, &result, osize)) {
539  RZ_LOG_ERROR("msg digest: cannot calculate small block with %s.\n", plugin->name);
540  return NULL;
541  }
542  return result;
543 }
RZ_API RZ_BORROW const RzHashPlugin * rz_hash_plugin_by_name(RZ_NONNULL RzHash *rh, RZ_NONNULL const char *name)
Definition: hash.c:120
Definition: buffer.h:15
bool(* small_block)(const ut8 *data, ut64 size, ut8 **digest, RzHashSize *digest_size)
Definition: rz_hash.h:38

References rz_hash_plugin_t::name, NULL, rz_hash_plugin_by_name(), RZ_LOG_ERROR, rz_return_val_if_fail, and rz_hash_plugin_t::small_block.

Referenced by handle_entropy(), handle_hash_cfg(), parseCodeDirectory(), rz_debug_snap_get_hash(), and rz_hash_cfg_calculate_small_block_string().

◆ rz_hash_cfg_calculate_small_block_string()

RZ_API RZ_OWN char* rz_hash_cfg_calculate_small_block_string ( RZ_NONNULL RzHash rh,
RZ_NONNULL const char *  name,
RZ_NONNULL const ut8 buffer,
ut64  bsize,
RZ_NULLABLE ut32 size,
bool  invert 
)

Definition at line 545 of file hash.c.

545  {
547 
548  ut32 pos = 0;
549  RzHashSize digest_size = 0;
550  ut8 *digest = NULL;
551  if (!(digest = rz_hash_cfg_calculate_small_block(rh, name, buffer, bsize, &digest_size))) {
552  return NULL;
553  }
554 
555  if (!strncmp(name, "entropy", 7)) {
556  double entropy = rz_read_be_double(digest);
557  free(digest);
558  return rz_str_newf("%.8f", entropy);
559  }
560 
561  char *string = malloc((digest_size * 2) + 1);
562  if (!string) {
563  RZ_LOG_ERROR("msg digest: cannot find allocate memory for string result.\n");
564  free(digest);
565  return NULL;
566  }
567 
568  for (ut32 i = 0; i < digest_size; i++) {
569  pos = invert ? (digest_size - 1 - i) : i;
570  sprintf(&string[i * 2], "%02x", digest[pos]);
571  }
572  string[digest_size * 2] = 0;
573 
574  if (size) {
575  *size = (digest_size * 2) + 1;
576  }
577  free(digest);
578  return string;
579 }
static unsigned invert(unsigned x)
Definition: aesdata.c:73
lzma_index ** i
Definition: index.h:629
uint32_t ut32
RZ_API RZ_OWN ut8 * rz_hash_cfg_calculate_small_block(RZ_NONNULL RzHash *rh, RZ_NONNULL const char *name, RZ_NONNULL const ut8 *buffer, ut64 bsize, RZ_NONNULL RzHashSize *osize)
Returns the digest size of the requested algorithm name.
Definition: hash.c:529
voidpf void uLong size
Definition: ioapi.h:138
sprintf
Definition: kernel.h:365
void * malloc(size_t size)
Definition: malloc.c:123
static double rz_read_be_double(const void *src)
Definition: rz_endian.h:157
ut32 RzHashSize
Definition: rz_hash.h:24
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
int pos
Definition: main.c:11

References free(), i, invert(), malloc(), NULL, pos, rz_hash_cfg_calculate_small_block(), RZ_LOG_ERROR, rz_read_be_double(), rz_return_val_if_fail, rz_str_newf(), and sprintf.

Referenced by rz_core_bin_create_digests(), and search_hash().

◆ rz_hash_cfg_configure()

RZ_API bool rz_hash_cfg_configure ( RZ_NONNULL RzHashCfg md,
RZ_NONNULL const char *  name 
)

Allocates and configures the plugin message digest context.

message digest allocates internally a HashCfgConfig which contains all the needed informations to the plugin to work.

Definition at line 199 of file hash.c.

199  {
200  rz_return_val_if_fail(md && name, false);
201 
202  if (rz_list_find(md->configurations, name, hash_cfg_config_compare)) {
203  RZ_LOG_WARN("msg digest: '%s' was already configured; skipping.\n", name);
204  return false;
205  }
206 
207  bool is_all = !strcmp(name, "all");
208 
209  if (is_all && rz_list_length(md->configurations) > 0) {
210  RZ_LOG_WARN("msg digest: '%s' was already configured; skipping.\n", name);
211  return false;
212  }
213 
214  HashCfgConfig *mdc = NULL;
215  RzListIter *it;
216  const RzHashPlugin *plugin;
217 
218  rz_list_foreach (md->hash->plugins, it, plugin) {
219  if (is_all || !strcmp(plugin->name, name)) {
220  mdc = hash_cfg_config_new(plugin);
221  if (!mdc) {
222  return false;
223  }
224 
225  if (!rz_list_append(md->configurations, mdc)) {
226  RZ_LOG_ERROR("msg digest: cannot allocate memory for list entry.\n");
228  return false;
229  }
230 
231  if (!is_all) {
232  return true;
233  }
234  }
235  }
236 
237  if (is_all) {
238  return true;
239  }
240 
241  RZ_LOG_ERROR("msg digest: '%s' does not exists.\n", name);
242  return false;
243 }
static HashCfgConfig * hash_cfg_config_new(const RzHashPlugin *plugin)
Definition: hash.c:73
static int hash_cfg_config_compare(const void *value, const void *data)
Definition: hash.c:58
static void hash_cfg_config_free(HashCfgConfig *mdc)
Definition: hash.c:64
RZ_API RZ_BORROW RzListIter * rz_list_find(RZ_NONNULL const RzList *list, const void *p, RZ_NONNULL RzListComparator cmp)
Returns RzListIter element which matches via the RzListComparator.
Definition: list.c:620
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56

References hash_cfg_config_compare(), hash_cfg_config_free(), hash_cfg_config_new(), benchmark::md, rz_hash_plugin_t::name, NULL, rz_list_append(), rz_list_find(), rz_list_length(), RZ_LOG_ERROR, RZ_LOG_WARN, and rz_return_val_if_fail.

Referenced by calculate_hash(), rz_bin_file_compute_hashes(), and rz_hash_cfg_new_with_algo().

◆ rz_hash_cfg_final()

RZ_API bool rz_hash_cfg_final ( RZ_NONNULL RzHashCfg md)

Generates the final value of the message digest contextes.

RzHashCfg contains a list of configurations; this method will call the final method of all the plugins stored in its list.

Definition at line 359 of file hash.c.

359  {
361 
362  RzListIter *iter = NULL;
363  HashCfgConfig *mdc = NULL;
364  rz_list_foreach (md->configurations, iter, mdc) {
365  if (!mdc->plugin->final(mdc->context, mdc->digest)) {
366  RZ_LOG_ERROR("msg digest: failed to call final for %s.\n", mdc->plugin->name);
367  return false;
368  }
369 
370  if (mdc->hmac_key) {
371  RzHashSize block_size = mdc->plugin->block_size(mdc->context);
372  ut8 *o_pad = malloc(block_size);
373  if (!o_pad) {
374  RZ_LOG_ERROR("msg digest: failed to allocate memory for opad.\n");
375  return false;
376  }
377 
378  for (ut32 i = 0; i < block_size; i++) {
379  o_pad[i] = 0x5c ^ mdc->hmac_key[i];
380  }
381 
382  if (!mdc->plugin->init(mdc->context)) {
383  RZ_LOG_ERROR("msg digest: failed to call init for hmac %s opad.\n", mdc->plugin->name);
384  free(o_pad);
385  return false;
386  }
387  if (!mdc->plugin->update(mdc->context, o_pad, block_size)) {
388  RZ_LOG_ERROR("msg digest: failed to call update for hmac %s opad.\n", mdc->plugin->name);
389  free(o_pad);
390  return false;
391  }
392  free(o_pad);
393  if (!mdc->plugin->update(mdc->context, mdc->digest, mdc->digest_size)) {
394  RZ_LOG_ERROR("msg digest: failed to call update for hmac %s opad.\n", mdc->plugin->name);
395  return false;
396  }
397  if (!mdc->plugin->final(mdc->context, mdc->digest)) {
398  RZ_LOG_ERROR("msg digest: failed to call final for hmac %s opad.\n", mdc->plugin->name);
399  return false;
400  }
401  }
402  }
403 
404  md->status = RZ_MSG_DIGEST_STATUS_FINAL;
405  return true;
406 }
#define hash_cfg_can_final(c)
Definition: hash.c:14
@ RZ_MSG_DIGEST_STATUS_FINAL
Definition: rz_hash.h:21
RzHashSize(* block_size)(void *context)
Definition: rz_hash.h:34
bool(* update)(void *context, const ut8 *data, ut64 size)
Definition: rz_hash.h:36
bool(* init)(void *context)
Definition: rz_hash.h:35
bool(* final)(void *context, ut8 *digest)
Definition: rz_hash.h:37

References rz_hash_plugin_t::block_size, hash_cfg_config_t::context, hash_cfg_config_t::digest, hash_cfg_config_t::digest_size, rz_hash_plugin_t::final, free(), hash_cfg_can_final, hash_cfg_config_t::hmac_key, i, rz_hash_plugin_t::init, malloc(), benchmark::md, rz_hash_plugin_t::name, NULL, hash_cfg_config_t::plugin, RZ_LOG_ERROR, RZ_MSG_DIGEST_STATUS_FINAL, rz_return_val_if_fail, and rz_hash_plugin_t::update.

Referenced by _createKDNetPacket(), _initializeDatakey(), _verifyhmac(), bin_pe_compute_authentihash(), calculate_hash(), and rz_bin_file_compute_hashes().

◆ rz_hash_cfg_free()

RZ_API void rz_hash_cfg_free ( RZ_NONNULL RzHashCfg md)

Definition at line 186 of file hash.c.

186  {
188 
189  rz_list_free(md->configurations);
190  free(md);
191 }
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137

References free(), benchmark::md, rz_list_free(), and rz_return_if_fail.

Referenced by _createKDNetPacket(), _initializeDatakey(), _verifyhmac(), bin_pe_compute_authentihash(), calculate_hash(), rz_bin_file_compute_hashes(), and rz_hash_cfg_new_with_algo().

◆ rz_hash_cfg_get_result()

RZ_API RZ_BORROW const ut8* rz_hash_cfg_get_result ( RZ_NONNULL RzHashCfg md,
RZ_NONNULL const char *  name,
RZ_NONNULL ut32 size 
)

Returns the digest value of the requested algorithm name.

RzHashCfg contains a list of configurations; this method will search for the configuration with the given name and if found return the digest value.

Definition at line 445 of file hash.c.

445  {
447 
448  RzListIter *it = rz_list_find(md->configurations, name, hash_cfg_config_compare);
449  if (!it) {
450  RZ_LOG_ERROR("msg digest: cannot find configuration for '%s' algorithm.\n", name);
451  return NULL;
452  }
453 
456 
457  if (size) {
458  *size = mdc->digest_size;
459  }
460  return mdc->digest;
461 }
#define hash_cfg_has_finshed(c)
Definition: hash.c:15
RZ_API void * rz_list_iter_get_data(RzListIter *list)
returns the value stored in the list element
Definition: list.c:42

References hash_cfg_config_t::digest, hash_cfg_config_t::digest_size, hash_cfg_config_compare(), hash_cfg_has_finshed, benchmark::md, NULL, rz_list_find(), rz_list_iter_get_data(), RZ_LOG_ERROR, and rz_return_val_if_fail.

Referenced by _createKDNetPacket(), _initializeDatakey(), _verifyhmac(), add_file_hash(), bin_pe_compute_authentihash(), calculate_hash(), and hash_print_digest().

◆ rz_hash_cfg_get_result_string()

RZ_API RZ_OWN char* rz_hash_cfg_get_result_string ( RZ_NONNULL RzHashCfg md,
RZ_NONNULL const char *  name,
RZ_NULLABLE ut32 size,
bool  invert 
)

Returns the digest value of the requested algorithm name.

RzHashCfg contains a list of configurations; this method will search for the configuration with the given name and if found return the digest value.

Definition at line 469 of file hash.c.

469  {
471 
472  ut32 pos = 0;
473  RzListIter *it = rz_list_find(md->configurations, name, hash_cfg_config_compare);
474  if (!it) {
475  RZ_LOG_ERROR("msg digest: cannot find configuration for '%s' algorithm.\n", name);
476  return NULL;
477  }
478 
481 
482  if (!strncmp(name, "entropy", 7)) {
483  double entropy = rz_read_be_double(mdc->digest);
484  return rz_str_newf("%.8f", entropy);
485  }
486 
487  char *string = malloc((mdc->digest_size * 2) + 1);
488  if (!string) {
489  RZ_LOG_ERROR("msg digest: cannot find allocate memory for string result.\n");
490  return NULL;
491  }
492 
493  for (ut32 i = 0; i < mdc->digest_size; i++) {
494  pos = invert ? (mdc->digest_size - 1 - i) : i;
495  sprintf(&string[i * 2], "%02x", mdc->digest[pos]);
496  }
497  string[mdc->digest_size * 2] = 0;
498 
499  if (size) {
500  *size = (mdc->digest_size * 2) + 1;
501  }
502  return string;
503 }

References hash_cfg_config_t::digest, hash_cfg_config_t::digest_size, hash_cfg_config_compare(), hash_cfg_has_finshed, i, invert(), malloc(), benchmark::md, NULL, pos, rz_list_find(), rz_list_iter_get_data(), RZ_LOG_ERROR, rz_read_be_double(), rz_return_val_if_fail, rz_str_newf(), and sprintf.

Referenced by hash_print_digest().

◆ rz_hash_cfg_hmac()

RZ_API bool rz_hash_cfg_hmac ( RZ_NONNULL RzHashCfg md,
RZ_NONNULL const ut8 key,
ut64  key_size 
)

Sets the key for the hmac algorithm.

message digest sets the hmac key

Definition at line 250 of file hash.c.

250  {
251  rz_return_val_if_fail(md && key && key_size && hash_cfg_can_hmac(md), false);
252 
253  RzHashSize block_size = 0;
254  RzListIter *iter = NULL;
255  HashCfgConfig *mdc = NULL;
256  rz_list_foreach (md->configurations, iter, mdc) {
257  if (!mdc->plugin->support_hmac) {
258  // RZ_LOG_ERROR("msg digest: hmac is not supported by %s.\n", mdc->plugin->name);
259  continue;
260  }
261 
262  block_size = mdc->plugin->block_size(mdc->context);
263  if (block_size < 1) {
264  RZ_LOG_ERROR("msg digest: hmac block size is < 1.\n");
265  return false;
266  }
267 
268  mdc->hmac_key = malloc(block_size);
269  if (!mdc->hmac_key) {
270  RZ_LOG_ERROR("msg digest: cannot allocate memory for hmac key.\n");
271  return false;
272  }
273 
274  memset(mdc->hmac_key, 0, block_size);
275  if (block_size < key_size) {
276  RzHashSize tmp_size;
277  ut8 *tmp = NULL;
278  if (!mdc->plugin->small_block(key, key_size, &tmp, &tmp_size)) {
279  RZ_LOG_ERROR("msg digest: failed to call init for hmac %s key.\n", mdc->plugin->name);
280  return false;
281  }
282  memcpy(mdc->hmac_key, tmp, tmp_size);
283  free(tmp);
284  } else {
285  memcpy(mdc->hmac_key, key, key_size);
286  }
287  }
288 
289  return true;
290 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
#define hash_cfg_can_hmac(c)
Definition: hash.c:11
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
bool support_hmac
Definition: rz_hash.h:30

References rz_hash_plugin_t::block_size, hash_cfg_config_t::context, free(), hash_cfg_can_hmac, hash_cfg_config_t::hmac_key, key, malloc(), benchmark::md, memcpy(), memset(), rz_hash_plugin_t::name, NULL, hash_cfg_config_t::plugin, RZ_LOG_ERROR, rz_return_val_if_fail, rz_hash_plugin_t::small_block, rz_hash_plugin_t::support_hmac, and autogen_x86imm::tmp.

Referenced by calculate_hash(), and rz_hash_cfg_new_with_algo().

◆ rz_hash_cfg_init()

RZ_API bool rz_hash_cfg_init ( RZ_NONNULL RzHashCfg md)

Resets/initialize the message digest contextes.

RzHashCfg contains a list of configurations; this method will call the init method of all the plugins stored in its list.

Definition at line 298 of file hash.c.

298  {
300 
301  RzListIter *iter = NULL;
302  HashCfgConfig *mdc = NULL;
303  rz_list_foreach (md->configurations, iter, mdc) {
304  if (!mdc->plugin->init(mdc->context)) {
305  RZ_LOG_ERROR("msg digest: failed to call init for %s.\n", mdc->plugin->name);
306  return false;
307  }
308  if (mdc->hmac_key) {
309  RzHashSize block_size = mdc->plugin->block_size(mdc->context);
310  ut8 *i_pad = malloc(block_size);
311  if (!i_pad) {
312  RZ_LOG_ERROR("msg digest: failed to allocate memory for ipad.\n");
313  return false;
314  }
315  for (ut32 i = 0; i < block_size; i++) {
316  i_pad[i] = 0x36 ^ mdc->hmac_key[i];
317  }
318  if (!mdc->plugin->update(mdc->context, i_pad, block_size)) {
319  RZ_LOG_ERROR("msg digest: failed to call update for hmac %s ipad.\n", mdc->plugin->name);
320  free(i_pad);
321  return false;
322  }
323  free(i_pad);
324  }
325  }
326 
327  md->status = RZ_MSG_DIGEST_STATUS_INIT;
328  return true;
329 }
#define hash_cfg_can_init(c)
Definition: hash.c:12
@ RZ_MSG_DIGEST_STATUS_INIT
Definition: rz_hash.h:19

References rz_hash_plugin_t::block_size, hash_cfg_config_t::context, free(), hash_cfg_can_init, hash_cfg_config_t::hmac_key, i, rz_hash_plugin_t::init, malloc(), benchmark::md, rz_hash_plugin_t::name, NULL, hash_cfg_config_t::plugin, RZ_LOG_ERROR, RZ_MSG_DIGEST_STATUS_INIT, rz_return_val_if_fail, and rz_hash_plugin_t::update.

Referenced by calculate_hash(), rz_bin_file_compute_hashes(), and rz_hash_cfg_new_with_algo().

◆ rz_hash_cfg_iterate()

RZ_API bool rz_hash_cfg_iterate ( RZ_NONNULL RzHashCfg md,
size_t  iterate 
)

Calculate the final hash by iterating its result N times.

RzHashCfg contains a list of configurations; this method will iterate N times each configuration final result.

Definition at line 414 of file hash.c.

414  {
416 
417  RzListIter *iter = NULL;
418  HashCfgConfig *mdc = NULL;
419  rz_list_foreach (md->configurations, iter, mdc) {
420  for (size_t i = 0; i < iterate; ++i) {
421  if (!mdc->plugin->init(mdc->context)) {
422  RZ_LOG_ERROR("msg digest: failed to call init %s for iteration.\n", mdc->plugin->name);
423  return false;
424  }
425  if (!mdc->plugin->update(mdc->context, mdc->digest, mdc->digest_size)) {
426  RZ_LOG_ERROR("msg digest: failed to call update %s for iteration.\n", mdc->plugin->name);
427  return false;
428  }
429  if (!mdc->plugin->final(mdc->context, mdc->digest)) {
430  RZ_LOG_ERROR("msg digest: failed to call final %s for iteration.\n", mdc->plugin->name);
431  return false;
432  }
433  }
434  }
435 
436  return true;
437 }

References hash_cfg_config_t::context, hash_cfg_config_t::digest, hash_cfg_config_t::digest_size, rz_hash_plugin_t::final, hash_cfg_has_finshed, i, rz_hash_plugin_t::init, benchmark::md, rz_hash_plugin_t::name, NULL, hash_cfg_config_t::plugin, RZ_LOG_ERROR, rz_return_val_if_fail, and rz_hash_plugin_t::update.

Referenced by calculate_hash().

◆ rz_hash_cfg_new()

RZ_API RZ_OWN RzHashCfg* rz_hash_cfg_new ( RZ_NONNULL RzHash rh)

Definition at line 134 of file hash.c.

134  {
136 
138  if (!md) {
139  RZ_LOG_ERROR("msg digest: cannot allocate memory.\n");
140  return NULL;
141  }
142 
143  md->configurations = rz_list_newf((RzListFree)hash_cfg_config_free);
144  if (!md->configurations) {
145  RZ_LOG_ERROR("msg digest: cannot allocate memory for the configurations.\n");
146  free(md);
147  return NULL;
148  }
149  md->hash = rh;
150 
151  return md;
152 }
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11

References free(), hash_cfg_config_free(), benchmark::md, NULL, rz_list_newf(), RZ_LOG_ERROR, RZ_NEW0, and rz_return_val_if_fail.

Referenced by calculate_hash(), rz_bin_file_compute_hashes(), and rz_hash_cfg_new_with_algo().

◆ rz_hash_cfg_new_with_algo()

RZ_API RZ_OWN RzHashCfg* rz_hash_cfg_new_with_algo ( RZ_NONNULL RzHash rh,
RZ_NONNULL const char *  name,
RZ_NULLABLE const ut8 key,
ut64  key_size 
)

Returns a message digest context with the give algo already configured.

message digest allocates and configures already the structure with the given algorithm and runs also the algo init. when fails to allocate or configure or initialize, returns NULL.

Definition at line 161 of file hash.c.

161  {
164  if (!md) {
165  return NULL;
166  }
167 
168  if (!rz_hash_cfg_configure(md, name)) {
170  return NULL;
171  }
172 
173  if (key && !rz_hash_cfg_hmac(md, key, key_size)) {
175  return NULL;
176  }
177 
178  if (!rz_hash_cfg_init(md)) {
180  return NULL;
181  }
182 
183  return md;
184 }
RZ_API RZ_OWN RzHashCfg * rz_hash_cfg_new(RZ_NONNULL RzHash *rh)
Definition: hash.c:134
RZ_API void rz_hash_cfg_free(RZ_NONNULL RzHashCfg *md)
Definition: hash.c:186
RZ_API bool rz_hash_cfg_configure(RZ_NONNULL RzHashCfg *md, RZ_NONNULL const char *name)
Allocates and configures the plugin message digest context.
Definition: hash.c:199
RZ_API bool rz_hash_cfg_hmac(RZ_NONNULL RzHashCfg *md, RZ_NONNULL const ut8 *key, ut64 key_size)
Sets the key for the hmac algorithm.
Definition: hash.c:250
RZ_API bool rz_hash_cfg_init(RZ_NONNULL RzHashCfg *md)
Resets/initialize the message digest contextes.
Definition: hash.c:298

References key, benchmark::md, NULL, rz_hash_cfg_configure(), rz_hash_cfg_free(), rz_hash_cfg_hmac(), rz_hash_cfg_init(), rz_hash_cfg_new(), and rz_return_val_if_fail.

Referenced by _createKDNetPacket(), and _verifyhmac().

◆ rz_hash_cfg_size()

RZ_API RzHashSize rz_hash_cfg_size ( RZ_NONNULL RzHashCfg md,
RZ_NONNULL const char *  name 
)

Returns the digest size of the requested algorithm name.

Returns the digest size of the initialized configuration.

Definition at line 510 of file hash.c.

510  {
512 
513  RzListIter *it = rz_list_find(md->configurations, name, hash_cfg_config_compare);
514  if (!it) {
515  RZ_LOG_ERROR("msg digest: cannot find configuration for '%s' algorithm.\n", name);
516  return 0;
517  }
518 
520  rz_return_val_if_fail(mdc, 0);
521  return mdc->plugin->digest_size(mdc->context);
522 }

References hash_cfg_config_t::context, rz_hash_plugin_t::digest_size, hash_cfg_config_compare(), benchmark::md, hash_cfg_config_t::plugin, rz_list_find(), rz_list_iter_get_data(), RZ_LOG_ERROR, and rz_return_val_if_fail.

◆ rz_hash_cfg_update()

RZ_API bool rz_hash_cfg_update ( RZ_NONNULL RzHashCfg md,
RZ_NONNULL const ut8 data,
ut64  size 
)

Inserts data into each the message digest contextes.

RzHashCfg contains a list of configurations; this method will call the update method of all the plugins stored in its list.

Definition at line 337 of file hash.c.

337  {
339 
340  RzListIter *iter = NULL;
341  HashCfgConfig *mdc = NULL;
342  rz_list_foreach (md->configurations, iter, mdc) {
343  if (!mdc->plugin->update(mdc->context, data, size)) {
344  RZ_LOG_ERROR("msg digest: failed to call update for %s.\n", mdc->plugin->name);
345  return false;
346  }
347  }
348 
350  return true;
351 }
#define hash_cfg_can_update(c)
Definition: hash.c:13
@ RZ_MSG_DIGEST_STATUS_UPDATE
Definition: rz_hash.h:20

References hash_cfg_config_t::context, hash_cfg_can_update, benchmark::md, rz_hash_plugin_t::name, NULL, hash_cfg_config_t::plugin, RZ_LOG_ERROR, RZ_MSG_DIGEST_STATUS_UPDATE, rz_return_val_if_fail, and rz_hash_plugin_t::update.

Referenced by _createKDNetPacket(), _initializeDatakey(), _verifyhmac(), buf_compute_hashes(), buf_fwd_hash(), and calculate_hash().

◆ rz_hash_entropy()

RZ_API double rz_hash_entropy ( RZ_NONNULL RzHash rh,
RZ_NONNULL const ut8 data,
ut64  len 
)

Definition at line 32 of file hash.c.

32  {
33  rz_return_val_if_fail(data, 0.0);
34  const RzHashPlugin *plugin = &rz_hash_plugin_entropy;
35  ut8 *digest = NULL;
36  if (!plugin->small_block(data, len, &digest, NULL)) {
37  RZ_LOG_ERROR("msg digest: cannot calculate entropy\n");
38  return 0.0;
39  }
40  double e = rz_read_be_double(digest);
41  free(digest);
42  return e;
43 }
size_t len
Definition: 6502dis.c:15
RzHashPlugin rz_hash_plugin_entropy
Definition: algo_entropy.c:65
#define e(frag)

References e, free(), len, NULL, rz_hash_plugin_entropy, RZ_LOG_ERROR, rz_read_be_double(), rz_return_val_if_fail, and rz_hash_plugin_t::small_block.

Referenced by do_section_search().

◆ rz_hash_entropy_fraction()

RZ_API double rz_hash_entropy_fraction ( RZ_NONNULL RzHash rh,
RZ_NONNULL const ut8 data,
ut64  len 
)

Definition at line 45 of file hash.c.

45  {
46  rz_return_val_if_fail(data, 0.0);
48  ut8 *digest = NULL;
49  if (!plugin->small_block(data, len, &digest, NULL)) {
50  RZ_LOG_ERROR("msg digest: cannot calculate entropy fraction\n");
51  return 0.0;
52  }
53  double e = rz_read_be_double(digest);
54  free(digest);
55  return e;
56 }
RzHashPlugin rz_hash_plugin_entropy_fract

References e, free(), len, NULL, rz_hash_plugin_entropy_fract, RZ_LOG_ERROR, rz_read_be_double(), rz_return_val_if_fail, and rz_hash_plugin_t::small_block.

Referenced by cmd_p_minus_e(), and cmd_print_bars().

◆ rz_hash_free()

RZ_API void rz_hash_free ( RzHash rh)

Definition at line 597 of file hash.c.

597  {
598  if (!rh) {
599  return;
600  }
601  rz_list_free(rh->plugins);
602  free(rh);
603 }
RzList * plugins
Definition: rz_hash.h:42

References free(), rz_hash_t::plugins, and rz_list_free().

Referenced by hash_context_fini(), iob_net_close(), mach0_free(), rz_analysis_free(), rz_bin_free(), rz_bin_pe_free(), rz_core_fini(), and rz_debug_free().

◆ rz_hash_new()

RZ_API RzHash* rz_hash_new ( void  )

Create a new RzHash object where plugins can be registered and specific configurations can be created from.

Definition at line 585 of file hash.c.

585  {
586  RzHash *rh = RZ_NEW0(RzHash);
587  if (!rh) {
588  return NULL;
589  }
590  rh->plugins = rz_list_new();
591  for (int i = 0; i < RZ_ARRAY_SIZE(hash_static_plugins); i++) {
593  }
594  return rh;
595 }
RZ_API bool rz_hash_plugin_add(RZ_NONNULL RzHash *rh, RZ_NONNULL RZ_OWN const RzHashPlugin *plugin)
Add a new plugin to rh so that RzHashCfg can be created using specific algorithms.
Definition: hash.c:609
static const RzHashPlugin * hash_static_plugins[]
Definition: hash.c:25
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300

References hash_static_plugins, i, NULL, rz_hash_t::plugins, RZ_ARRAY_SIZE, rz_hash_plugin_add(), rz_list_new(), and RZ_NEW0.

Referenced by iob_net_open(), rz_analysis_new(), rz_bin_new(), rz_bin_pe_new_buf(), rz_core_init(), rz_debug_new(), and rz_main_rz_hash().

◆ rz_hash_plugin_add()

RZ_API bool rz_hash_plugin_add ( RZ_NONNULL RzHash rh,
RZ_NONNULL RZ_OWN const RzHashPlugin plugin 
)

Add a new plugin to rh so that RzHashCfg can be created using specific algorithms.

Definition at line 609 of file hash.c.

609  {
610  if (!plugin) {
611  return false;
612  }
613  RzListIter *it;
614  RzHashPlugin *p;
615 
616  rz_list_foreach (rh->plugins, it, p) {
617  if (!strcmp(p->name, plugin->name)) {
618  return false;
619  }
620  }
621  rz_list_append(rh->plugins, (RzHashPlugin *)plugin);
622  return true;
623 }
void * p
Definition: libc.cpp:67

References p, and rz_list_append().

Referenced by lib_hash_cb(), and rz_hash_new().

◆ rz_hash_plugin_by_index()

RZ_API RZ_BORROW const RzHashPlugin* rz_hash_plugin_by_index ( RZ_NONNULL RzHash rh,
size_t  index 
)

Definition at line 104 of file hash.c.

104  {
106 
107  RzListIter *it;
108  const RzHashPlugin *rhp;
109  size_t i = 0;
110 
111  rz_list_foreach (rh->plugins, it, rhp) {
112  if (i == index) {
113  return rhp;
114  }
115  i++;
116  }
117  return NULL;
118 }

References i, NULL, and rz_return_val_if_fail.

Referenced by parse_hash_algorithms(), and rz_hash_show_algorithms().

◆ rz_hash_plugin_by_name()

RZ_API RZ_BORROW const RzHashPlugin* rz_hash_plugin_by_name ( RZ_NONNULL RzHash rh,
RZ_NONNULL const char *  name 
)

Definition at line 120 of file hash.c.

120  {
122 
123  RzListIter *it;
124  const RzHashPlugin *rhp;
125 
126  rz_list_foreach (rh->plugins, it, rhp) {
127  if (!strcmp(rhp->name, name)) {
128  return rhp;
129  }
130  }
131  return NULL;
132 }

References rz_hash_plugin_t::name, NULL, and rz_return_val_if_fail.

Referenced by rz_cmd_print_hash_cfg_handler(), rz_core_bin_resources_print(), rz_core_bin_segments_print(), rz_hash_cfg_calculate_small_block(), search_collisions(), and sections_headers_setup().

◆ rz_hash_xxhash()

RZ_API ut32 rz_hash_xxhash ( RZ_NONNULL RzHash rh,
RZ_NONNULL const ut8 input,
size_t  size 
)

Definition at line 27 of file hash.c.

27  {
29  return XXH32(input, size, 0);
30 }
XXH_PUBLIC_API unsigned int XXH32(const void *input, size_t len, unsigned int seed)
Definition: xxhash.c:392
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)

References input(), rz_return_val_if_fail, and XXH32().

Referenced by rz_analysis_block_update_hash(), and rz_analysis_block_was_modified().

◆ RZ_LIB_VERSION()

RZ_LIB_VERSION ( rz_hash  )

Variable Documentation

◆ hash_static_plugins

const RzHashPlugin* hash_static_plugins[] = { RZ_HASH_STATIC_PLUGINS }
static

Definition at line 25 of file hash.c.

Referenced by rz_hash_new().