GNUnet  0.11.x
crypto_hash.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001-2013 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 
20  */
26 #include "platform.h"
27 #include "gnunet_crypto_lib.h"
28 #include "gnunet_strings_lib.h"
29 #include "benchmark.h"
30 #include <gcrypt.h>
31 
32 #define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-hash", __VA_ARGS__)
33 
34 #define LOG_STRERROR_FILE(kind, syscall, \
35  filename) GNUNET_log_from_strerror_file (kind, \
36  "util-crypto-hash", \
37  syscall, \
38  filename)
39 
47 void
48 GNUNET_CRYPTO_hash (const void *block,
49  size_t size,
50  struct GNUNET_HashCode *ret)
51 {
52  BENCHMARK_START (hash);
53  gcry_md_hash_buffer (GCRY_MD_SHA512, ret, block, size);
54  BENCHMARK_END (hash);
55 }
56 
57 
58 /* ***************** binary-ASCII encoding *************** */
59 
60 
72 void
75 {
76  char *np;
77 
78  np = GNUNET_STRINGS_data_to_string ((const unsigned char *) block,
79  sizeof(struct GNUNET_HashCode),
80  (char *) result,
81  sizeof(struct
83  - 1);
84  GNUNET_assert (NULL != np);
85  *np = '\0';
86 }
87 
88 
97 int
99  size_t enclen,
100  struct GNUNET_HashCode *result)
101 {
102  char upper_enc[enclen];
103  char *up_ptr = upper_enc;
104 
105  GNUNET_STRINGS_utf8_toupper (enc, up_ptr);
106 
107  return GNUNET_STRINGS_string_to_data (upper_enc, enclen,
108  (unsigned char*) result,
109  sizeof(struct GNUNET_HashCode));
110 }
111 
112 
126 unsigned int
128  const struct GNUNET_HashCode *b)
129 {
130  unsigned int x1 = (a->bits[1] - b->bits[1]) >> 16;
131  unsigned int x2 = (b->bits[1] - a->bits[1]) >> 16;
132 
133  return(x1 * x2);
134 }
135 
136 
143 void
145  struct GNUNET_HashCode *result)
146 {
147  int i;
148 
149  for (i = (sizeof(struct GNUNET_HashCode) / sizeof(uint32_t)) - 1; i >= 0; i--)
150  result->bits[i] = GNUNET_CRYPTO_random_u32 (mode, UINT32_MAX);
151 }
152 
153 
161 void
163  const struct GNUNET_HashCode *b,
164  struct GNUNET_HashCode *result)
165 {
166  int i;
167 
168  for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0;
169  i--)
170  result->bits[i] = b->bits[i] - a->bits[i];
171 }
172 
173 
181 void
183  const struct GNUNET_HashCode *delta, struct
185 {
186  int i;
187 
188  for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0;
189  i--)
190  result->bits[i] = delta->bits[i] + a->bits[i];
191 }
192 
193 
201 void
203  const struct GNUNET_HashCode *b,
204  struct GNUNET_HashCode *result)
205 {
206  int i;
207 
208  for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0;
209  i--)
210  result->bits[i] = a->bits[i] ^ b->bits[i];
211 }
212 
213 
221 void
224  struct
226 {
228  GNUNET_CRYPTO_kdf (skey, sizeof(struct
230  "Hash key derivation", strlen (
231  "Hash key derivation"),
232  hc, sizeof(struct GNUNET_HashCode),
233  NULL, 0));
235  GNUNET_CRYPTO_kdf (iv, sizeof(struct
237  "Initialization vector derivation", strlen (
238  "Initialization vector derivation"),
239  hc, sizeof(struct GNUNET_HashCode),
240  NULL, 0));
241 }
242 
243 
250 int
251 GNUNET_CRYPTO_hash_get_bit (const struct GNUNET_HashCode *code, unsigned int
252  bit)
253 {
254  GNUNET_assert (bit < 8 * sizeof(struct GNUNET_HashCode));
255  return (((unsigned char *) code)[bit >> 3] & (1 << (bit & 7))) > 0;
256 }
257 
258 
271 unsigned int
273  const struct GNUNET_HashCode *second)
274 {
275  unsigned int i;
276 
277  for (i = 0; i < sizeof(struct GNUNET_HashCode) * 8; i++)
278  if (GNUNET_CRYPTO_hash_get_bit (first, i) !=
279  GNUNET_CRYPTO_hash_get_bit (second, i))
280  return i;
281  return sizeof(struct GNUNET_HashCode) * 8;
282 }
283 
284 
293 int
295  const struct GNUNET_HashCode *h2)
296 {
297  unsigned int *i1;
298  unsigned int *i2;
299  int i;
300 
301  i1 = (unsigned int *) h1;
302  i2 = (unsigned int *) h2;
303  for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0;
304  i--)
305  {
306  if (i1[i] > i2[i])
307  return 1;
308  if (i1[i] < i2[i])
309  return -1;
310  }
311  return 0;
312 }
313 
314 
324 int
326  const struct GNUNET_HashCode *h2,
327  const struct GNUNET_HashCode *target)
328 {
329  int i;
330  unsigned int d1;
331  unsigned int d2;
332 
333  for (i = sizeof(struct GNUNET_HashCode) / sizeof(unsigned int) - 1; i >= 0;
334  i--)
335  {
336  d1 = ((unsigned int *) h1)[i] ^ ((unsigned int *) target)[i];
337  d2 = ((unsigned int *) h2)[i] ^ ((unsigned int *) target)[i];
338  if (d1 > d2)
339  return 1;
340  else if (d1 < d2)
341  return -1;
342  }
343  return 0;
344 }
345 
346 
355 void
357  const struct
359  const void *salt, size_t salt_len, ...)
360 {
361  va_list argp;
362 
363  va_start (argp, salt_len);
364  GNUNET_CRYPTO_hmac_derive_key_v (key, rkey, salt, salt_len, argp);
365  va_end (argp);
366 }
367 
368 
377 void
379  const struct
381  const void *salt, size_t salt_len,
382  va_list argp)
383 {
384  GNUNET_CRYPTO_kdf_v (key->key, sizeof(key->key),
385  salt, salt_len,
386  rkey, sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
387  argp);
388 }
389 
390 
402 void
403 GNUNET_CRYPTO_hmac_raw (const void *key, size_t key_len,
404  const void *plaintext, size_t plaintext_len,
405  struct GNUNET_HashCode *hmac)
406 {
407  static int once;
408  static gcry_md_hd_t md;
409  const unsigned char *mc;
410 
411  if (! once)
412  {
413  once = 1;
414  GNUNET_assert (GPG_ERR_NO_ERROR ==
415  gcry_md_open (&md, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC));
416  }
417  else
418  {
419  gcry_md_reset (md);
420  }
421  gcry_md_setkey (md, key, key_len);
422  gcry_md_write (md, plaintext, plaintext_len);
423  mc = gcry_md_read (md, GCRY_MD_SHA512);
424  GNUNET_assert (NULL != mc);
425  GNUNET_memcpy (hmac->bits, mc, sizeof(hmac->bits));
426 }
427 
428 
437 void
439  const void *plaintext, size_t plaintext_len,
440  struct GNUNET_HashCode *hmac)
441 {
442  GNUNET_CRYPTO_hmac_raw ((void*) key->key, sizeof(key->key),
443  plaintext, plaintext_len,
444  hmac);
445 }
446 
447 
452 {
456  gcry_md_hd_t hd;
457 };
458 
459 
465 struct GNUNET_HashContext *
467 {
468  struct GNUNET_HashContext *hc;
469 
470  BENCHMARK_START (hash_context_start);
471 
472  hc = GNUNET_new (struct GNUNET_HashContext);
473  GNUNET_assert (0 ==
474  gcry_md_open (&hc->hd,
475  GCRY_MD_SHA512,
476  0));
477 
478  BENCHMARK_END (hash_context_start);
479 
480  return hc;
481 }
482 
483 
491 void
493  const void *buf,
494  size_t size)
495 {
496  BENCHMARK_START (hash_context_read);
497  gcry_md_write (hc->hd, buf, size);
498  BENCHMARK_END (hash_context_read);
499 }
500 
501 
508 void
510  struct GNUNET_HashCode *r_hash)
511 {
512  const void *res = gcry_md_read (hc->hd, 0);
513 
514  BENCHMARK_START (hash_context_finish);
515 
516  GNUNET_assert (NULL != res);
517  if (NULL != r_hash)
518  GNUNET_memcpy (r_hash,
519  res,
520  sizeof(struct GNUNET_HashCode));
522  BENCHMARK_END (hash_context_finish);
523 }
524 
525 
531 void
533 {
534  gcry_md_close (hc->hd);
535  GNUNET_free (hc);
536 }
537 
538 
539 /* end of crypto_hash.c */
int GNUNET_CRYPTO_hash_xorcmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2, const struct GNUNET_HashCode *target)
Find out which of the two struct GNUNET_HashCodes is closer to target in the XOR metric (Kademlia)...
Definition: crypto_hash.c:325
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
#define BENCHMARK_START(opname)
Definition: benchmark.h:57
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start()
Start incremental hashing operation.
Definition: crypto_hash.c:466
unsigned int GNUNET_CRYPTO_hash_matching_bits(const struct GNUNET_HashCode *first, const struct GNUNET_HashCode *second)
Determine how many low order bits match in two struct GNUNET_HashCodes.
Definition: crypto_hash.c:272
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define BENCHMARK_END(opname)
Definition: benchmark.h:58
void GNUNET_CRYPTO_hmac_raw(const void *key, size_t key_len, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104) TODO: Shouldn&#39; this be the standard hmac function and the abov...
Definition: crypto_hash.c:403
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
GNUNET_CRYPTO_Quality
Desired quality level for random numbers.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Context for cummulative hashing.
Definition: crypto_hash.c:451
uint32_t GNUNET_CRYPTO_hash_distance_u32(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b)
Compute the distance between 2 hashcodes.
Definition: crypto_hash.c:127
static enum @8 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
void GNUNET_CRYPTO_hmac(const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104)
Definition: crypto_hash.c:438
void GNUNET_CRYPTO_hash_sum(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *delta, struct GNUNET_HashCode *result)
compute result(b) = a + delta
Definition: crypto_hash.c:182
void GNUNET_CRYPTO_hash_context_abort(struct GNUNET_HashContext *hc)
Abort hashing, do not bother calculating final result.
Definition: crypto_hash.c:532
cryptographic primitives for GNUnet
void GNUNET_STRINGS_utf8_toupper(const char *input, char *output)
Convert the utf-8 input string to upper case.
Definition: strings.c:578
void GNUNET_CRYPTO_hash_create_random(enum GNUNET_CRYPTO_Quality mode, struct GNUNET_HashCode *result)
Create a random hash code.
Definition: crypto_hash.c:144
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Hash block of given size.
Definition: crypto_hash.c:48
static int once
Global to mark if we&#39;ve run the initialization.
Definition: gnsrecord.c:68
static char buf[2048]
static int result
Global testing status.
unsigned char key[(512/8)]
A 512-bit hashcode.
static struct GNUNET_TESTBED_Controller * mc
Handle to the master controller.
static int res
void GNUNET_CRYPTO_hash_to_aes_key(const struct GNUNET_HashCode *hc, struct GNUNET_CRYPTO_SymmetricSessionKey *skey, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
Convert a hashcode into a key.
Definition: crypto_hash.c:222
struct GNUNET_HashCode key
The key used in the DHT.
void GNUNET_CRYPTO_hash_to_enc(const struct GNUNET_HashCode *block, struct GNUNET_CRYPTO_HashAsciiEncoded *result)
Convert GNUNET_CRYPTO_hash to ASCII encoding.
Definition: crypto_hash.c:73
static unsigned int size
Size of the "table".
Definition: peer.c:67
void GNUNET_CRYPTO_hmac_derive_key_v(struct GNUNET_CRYPTO_AuthKey *key, const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, const void *salt, size_t salt_len, va_list argp)
Derive an authentication key.
Definition: crypto_hash.c:378
int GNUNET_CRYPTO_hash_get_bit(const struct GNUNET_HashCode *code, unsigned int bit)
Obtain a bit from a hashcode.
Definition: crypto_hash.c:251
gcry_md_hd_t hd
Internal state of the hash function.
Definition: crypto_hash.c:456
0-terminated ASCII encoding of a struct GNUNET_HashCode.
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
Definition: crypto_hash.c:492
int GNUNET_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
Definition: crypto_hash.c:294
static OpusEncoder * enc
OPUS encoder.
int GNUNET_CRYPTO_kdf_v(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len, va_list argp)
Derive key.
Definition: crypto_kdf.c:47
#define GNUNET_YES
Definition: gnunet_common.h:77
void GNUNET_CRYPTO_hash_xor(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = a ^ b
Definition: crypto_hash.c:202
benchmarking for various operations
void GNUNET_CRYPTO_hash_difference(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result(delta) = b - a
Definition: crypto_hash.c:162
void GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key, const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, const void *salt, size_t salt_len,...)
Derive an authentication key.
Definition: crypto_hash.c:356
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:509
int GNUNET_CRYPTO_hash_from_string2(const char *enc, size_t enclen, struct GNUNET_HashCode *result)
Convert ASCII encoding back to hash code.
Definition: crypto_hash.c:98
int GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:89
type for (message) authentication keys
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:952
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:856
#define GNUNET_free(ptr)
Wrapper around free.
uint32_t bits[512/8/sizeof(uint32_t)]