GNUnet  0.10.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, filename) GNUNET_log_from_strerror_file(kind, "util-crypto-hash", syscall, filename)
35 
43 void
44 GNUNET_CRYPTO_hash(const void *block,
45  size_t size,
46  struct GNUNET_HashCode *ret)
47 {
48  BENCHMARK_START(hash);
49  gcry_md_hash_buffer(GCRY_MD_SHA512, ret, block, size);
50  BENCHMARK_END(hash);
51 }
52 
53 
54 /* ***************** binary-ASCII encoding *************** */
55 
56 
68 void
71 {
72  char *np;
73 
74  np = GNUNET_STRINGS_data_to_string((const unsigned char *)block,
75  sizeof(struct GNUNET_HashCode),
76  (char *)result,
77  sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1);
78  GNUNET_assert(NULL != np);
79  *np = '\0';
80 }
81 
82 
91 int
93  size_t enclen,
94  struct GNUNET_HashCode *result)
95 {
96  char upper_enc[enclen];
97  char *up_ptr = upper_enc;
98 
99  GNUNET_STRINGS_utf8_toupper(enc, up_ptr);
100 
101  return GNUNET_STRINGS_string_to_data(upper_enc, enclen,
102  (unsigned char*)result,
103  sizeof(struct GNUNET_HashCode));
104 }
105 
106 
120 unsigned int
122  const struct GNUNET_HashCode *b)
123 {
124  unsigned int x1 = (a->bits[1] - b->bits[1]) >> 16;
125  unsigned int x2 = (b->bits[1] - a->bits[1]) >> 16;
126 
127  return(x1 * x2);
128 }
129 
130 
137 void
139  struct GNUNET_HashCode *result)
140 {
141  int i;
142 
143  for (i = (sizeof(struct GNUNET_HashCode) / sizeof(uint32_t)) - 1; i >= 0; i--)
144  result->bits[i] = GNUNET_CRYPTO_random_u32(mode, UINT32_MAX);
145 }
146 
147 
155 void
157  const struct GNUNET_HashCode *b,
158  struct GNUNET_HashCode *result)
159 {
160  int i;
161 
162  for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0; i--)
163  result->bits[i] = b->bits[i] - a->bits[i];
164 }
165 
166 
174 void
176  const struct GNUNET_HashCode * delta, struct GNUNET_HashCode * result)
177 {
178  int i;
179 
180  for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0; i--)
181  result->bits[i] = delta->bits[i] + a->bits[i];
182 }
183 
184 
192 void
194  const struct GNUNET_HashCode *b,
195  struct GNUNET_HashCode *result)
196 {
197  int i;
198 
199  for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0; i--)
200  result->bits[i] = a->bits[i] ^ b->bits[i];
201 }
202 
203 
211 void
215 {
218  "Hash key derivation", strlen("Hash key derivation"),
219  hc, sizeof(struct GNUNET_HashCode),
220  NULL, 0));
223  "Initialization vector derivation", strlen("Initialization vector derivation"),
224  hc, sizeof(struct GNUNET_HashCode),
225  NULL, 0));
226 }
227 
228 
235 int
236 GNUNET_CRYPTO_hash_get_bit(const struct GNUNET_HashCode * code, unsigned int bit)
237 {
238  GNUNET_assert(bit < 8 * sizeof(struct GNUNET_HashCode));
239  return (((unsigned char *)code)[bit >> 3] & (1 << (bit & 7))) > 0;
240 }
241 
242 
255 unsigned int
257  const struct GNUNET_HashCode * second)
258 {
259  unsigned int i;
260 
261  for (i = 0; i < sizeof(struct GNUNET_HashCode) * 8; i++)
262  if (GNUNET_CRYPTO_hash_get_bit(first, i) !=
263  GNUNET_CRYPTO_hash_get_bit(second, i))
264  return i;
265  return sizeof(struct GNUNET_HashCode) * 8;
266 }
267 
268 
277 int
279  const struct GNUNET_HashCode *h2)
280 {
281  unsigned int *i1;
282  unsigned int *i2;
283  int i;
284 
285  i1 = (unsigned int *)h1;
286  i2 = (unsigned int *)h2;
287  for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0; i--)
288  {
289  if (i1[i] > i2[i])
290  return 1;
291  if (i1[i] < i2[i])
292  return -1;
293  }
294  return 0;
295 }
296 
297 
307 int
309  const struct GNUNET_HashCode *h2,
310  const struct GNUNET_HashCode *target)
311 {
312  int i;
313  unsigned int d1;
314  unsigned int d2;
315 
316  for (i = sizeof(struct GNUNET_HashCode) / sizeof(unsigned int) - 1; i >= 0; i--)
317  {
318  d1 = ((unsigned int *)h1)[i] ^ ((unsigned int *)target)[i];
319  d2 = ((unsigned int *)h2)[i] ^ ((unsigned int *)target)[i];
320  if (d1 > d2)
321  return 1;
322  else if (d1 < d2)
323  return -1;
324  }
325  return 0;
326 }
327 
328 
337 void
339  const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey,
340  const void *salt, size_t salt_len, ...)
341 {
342  va_list argp;
343 
344  va_start(argp, salt_len);
345  GNUNET_CRYPTO_hmac_derive_key_v(key, rkey, salt, salt_len, argp);
346  va_end(argp);
347 }
348 
349 
358 void
360  const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey,
361  const void *salt, size_t salt_len,
362  va_list argp)
363 {
364  GNUNET_CRYPTO_kdf_v(key->key, sizeof(key->key),
365  salt, salt_len,
366  rkey, sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
367  argp);
368 }
369 
370 
382 void
383 GNUNET_CRYPTO_hmac_raw(const void *key, size_t key_len,
384  const void *plaintext, size_t plaintext_len,
385  struct GNUNET_HashCode *hmac)
386 {
387  static int once;
388  static gcry_md_hd_t md;
389  const unsigned char *mc;
390 
391  if (!once)
392  {
393  once = 1;
394  GNUNET_assert(GPG_ERR_NO_ERROR ==
395  gcry_md_open(&md, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC));
396  }
397  else
398  {
399  gcry_md_reset(md);
400  }
401  gcry_md_setkey(md, key, key_len);
402  gcry_md_write(md, plaintext, plaintext_len);
403  mc = gcry_md_read(md, GCRY_MD_SHA512);
404  GNUNET_assert(NULL != mc);
405  GNUNET_memcpy(hmac->bits, mc, sizeof(hmac->bits));
406 }
407 
408 
417 void
419  const void *plaintext, size_t plaintext_len,
420  struct GNUNET_HashCode *hmac)
421 {
422  GNUNET_CRYPTO_hmac_raw((void*)key->key, sizeof(key->key),
423  plaintext, plaintext_len,
424  hmac);
425 }
426 
427 
435  gcry_md_hd_t hd;
436 };
437 
438 
444 struct GNUNET_HashContext *
446 {
447  struct GNUNET_HashContext *hc;
448 
449  BENCHMARK_START(hash_context_start);
450 
451  hc = GNUNET_new(struct GNUNET_HashContext);
452  GNUNET_assert(0 ==
453  gcry_md_open(&hc->hd,
454  GCRY_MD_SHA512,
455  0));
456 
457  BENCHMARK_END(hash_context_start);
458 
459  return hc;
460 }
461 
462 
470 void
472  const void *buf,
473  size_t size)
474 {
475  BENCHMARK_START(hash_context_read);
476  gcry_md_write(hc->hd, buf, size);
477  BENCHMARK_END(hash_context_read);
478 }
479 
480 
487 void
489  struct GNUNET_HashCode *r_hash)
490 {
491  const void *res = gcry_md_read(hc->hd, 0);
492 
493  BENCHMARK_START(hash_context_finish);
494 
495  GNUNET_assert(NULL != res);
496  if (NULL != r_hash)
497  GNUNET_memcpy(r_hash,
498  res,
499  sizeof(struct GNUNET_HashCode));
501  BENCHMARK_END(hash_context_finish);
502 }
503 
504 
510 void
512 {
513  gcry_md_close(hc->hd);
514  GNUNET_free(hc);
515 }
516 
517 
518 /* 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:308
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
#define BENCHMARK_START(opname)
Definition: benchmark.h:53
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start()
Start incremental hashing operation.
Definition: crypto_hash.c:445
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:256
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:54
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:383
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
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:431
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:121
static int ret
Final status code.
Definition: gnunet-arm.c:89
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:418
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:175
void GNUNET_CRYPTO_hash_context_abort(struct GNUNET_HashContext *hc)
Abort hashing, do not bother calculating final result.
Definition: crypto_hash.c:511
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:577
void GNUNET_CRYPTO_hash_create_random(enum GNUNET_CRYPTO_Quality mode, struct GNUNET_HashCode *result)
Create a random hash code.
Definition: crypto_hash.c:138
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Hash block of given size.
Definition: crypto_hash.c:44
static int once
Global to mark if we&#39;ve run the initialization.
Definition: gnsrecord.c:67
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:212
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:69
static unsigned int size
Size of the "table".
Definition: peer.c:66
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:359
int GNUNET_CRYPTO_hash_get_bit(const struct GNUNET_HashCode *code, unsigned int bit)
Obtain a bit from a hashcode.
Definition: crypto_hash.c:236
gcry_md_hd_t hd
Internal state of the hash function.
Definition: crypto_hash.c:435
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:471
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:278
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:193
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:156
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:338
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:488
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:92
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:91
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:953
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:857
static enum @11 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
#define GNUNET_free(ptr)
Wrapper around free.
uint32_t bits[512/8/sizeof(uint32_t)]