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 
40 void
41 GNUNET_CRYPTO_hash (const void *block,
42  size_t size,
43  struct GNUNET_HashCode *ret)
44 {
45  BENCHMARK_START (hash);
46  gcry_md_hash_buffer (GCRY_MD_SHA512, ret, block, size);
47  BENCHMARK_END (hash);
48 }
49 
50 
51 /* ***************** binary-ASCII encoding *************** */
52 
53 
54 void
57 {
58  char *np;
59 
60  np = GNUNET_STRINGS_data_to_string ((const unsigned char *) block,
61  sizeof(struct GNUNET_HashCode),
62  (char *) result,
63  sizeof(struct
65  - 1);
66  GNUNET_assert (NULL != np);
67  *np = '\0';
68 }
69 
70 
73  size_t enclen,
74  struct GNUNET_HashCode *result)
75 {
76  char upper_enc[enclen];
77  char *up_ptr = upper_enc;
78 
80 
81  return GNUNET_STRINGS_string_to_data (upper_enc, enclen,
82  (unsigned char *) result,
83  sizeof(struct GNUNET_HashCode));
84 }
85 
86 
87 unsigned int
89  const struct GNUNET_HashCode *b)
90 {
91  unsigned int x1 = (a->bits[1] - b->bits[1]) >> 16;
92  unsigned int x2 = (b->bits[1] - a->bits[1]) >> 16;
93 
94  return(x1 * x2);
95 }
96 
97 
98 void
100  struct GNUNET_HashCode *result)
101 {
102  for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(uint32_t)) - 1;
103  i >= 0;
104  i--)
105  result->bits[i] = GNUNET_CRYPTO_random_u32 (mode, UINT32_MAX);
106 }
107 
108 
109 void
111  const struct GNUNET_HashCode *b,
112  struct GNUNET_HashCode *result)
113 {
114  for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1;
115  i >= 0;
116  i--)
117  result->bits[i] = b->bits[i] - a->bits[i];
118 }
119 
120 
121 void
123  const struct GNUNET_HashCode *delta, struct
125 {
126  for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1;
127  i >= 0;
128  i--)
129  result->bits[i] = delta->bits[i] + a->bits[i];
130 }
131 
132 
133 void
135  const struct GNUNET_HashCode *b,
136  struct GNUNET_HashCode *result)
137 {
138  for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1;
139  i >= 0;
140  i--)
141  result->bits[i] = a->bits[i] ^ b->bits[i];
142 }
143 
144 
145 void
148  struct
150 {
153  skey,
154  sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
155  "Hash key derivation",
156  strlen ("Hash key derivation"),
157  hc, sizeof(struct GNUNET_HashCode),
158  NULL, 0));
161  iv,
163  "Initialization vector derivation",
164  strlen ("Initialization vector derivation"),
165  hc, sizeof(struct GNUNET_HashCode),
166  NULL, 0));
167 }
168 
169 
170 int
172  unsigned int bit)
173 {
174  GNUNET_assert (bit < 8 * sizeof(struct GNUNET_HashCode));
175  return (((unsigned char *) code)[bit >> 3] & (128 >> (bit & 7))) > 0;
176 }
177 
178 
179 int
181  unsigned int bit)
182 {
183  GNUNET_assert (bit < 8 * sizeof(struct GNUNET_HashCode));
184  return (((unsigned char *) code)[bit >> 3] & (1 << (bit & 7))) > 0;
185 }
186 
187 
188 unsigned int
190  const struct GNUNET_HashCode *second)
191 {
192  for (unsigned int i = 0; i < sizeof(struct GNUNET_HashCode) * 8; i++)
193  if (GNUNET_CRYPTO_hash_get_bit_rtl (first, i) !=
194  GNUNET_CRYPTO_hash_get_bit_rtl (second, i))
195  return i;
196  return sizeof(struct GNUNET_HashCode) * 8;
197 }
198 
199 
200 int
202  const struct GNUNET_HashCode *h2)
203 {
204  unsigned int *i1;
205  unsigned int *i2;
206 
207  i1 = (unsigned int *) h1;
208  i2 = (unsigned int *) h2;
209  for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1;
210  i >= 0;
211  i--)
212  {
213  if (i1[i] > i2[i])
214  return 1;
215  if (i1[i] < i2[i])
216  return -1;
217  }
218  return 0;
219 }
220 
221 
222 int
224  const struct GNUNET_HashCode *h2,
225  const struct GNUNET_HashCode *target)
226 {
227  unsigned int d1;
228  unsigned int d2;
229 
230  for (ssize_t i = sizeof(struct GNUNET_HashCode) / sizeof(unsigned int) - 1;
231  i >= 0;
232  i--)
233  {
234  d1 = ((unsigned int *) h1)[i] ^ ((unsigned int *) target)[i];
235  d2 = ((unsigned int *) h2)[i] ^ ((unsigned int *) target)[i];
236  if (d1 > d2)
237  return 1;
238  else if (d1 < d2)
239  return -1;
240  }
241  return 0;
242 }
243 
244 
245 void
247  const struct
249  const void *salt, size_t salt_len, ...)
250 {
251  va_list argp;
252 
253  va_start (argp, salt_len);
254  GNUNET_CRYPTO_hmac_derive_key_v (key, rkey, salt, salt_len, argp);
255  va_end (argp);
256 }
257 
258 
259 void
261  const struct
263  const void *salt, size_t salt_len,
264  va_list argp)
265 {
266  GNUNET_CRYPTO_kdf_v (key->key, sizeof(key->key),
267  salt, salt_len,
268  rkey, sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
269  argp);
270 }
271 
272 
273 void
274 GNUNET_CRYPTO_hmac_raw (const void *key, size_t key_len,
275  const void *plaintext, size_t plaintext_len,
276  struct GNUNET_HashCode *hmac)
277 {
278  static int once;
279  static gcry_md_hd_t md;
280  const unsigned char *mc;
281 
282  if (! once)
283  {
284  once = 1;
285  GNUNET_assert (GPG_ERR_NO_ERROR ==
286  gcry_md_open (&md, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC));
287  }
288  else
289  {
290  gcry_md_reset (md);
291  }
292  gcry_md_setkey (md, key, key_len);
293  gcry_md_write (md, plaintext, plaintext_len);
294  mc = gcry_md_read (md, GCRY_MD_SHA512);
295  GNUNET_assert (NULL != mc);
296  GNUNET_memcpy (hmac->bits, mc, sizeof(hmac->bits));
297 }
298 
299 
300 void
302  const void *plaintext, size_t plaintext_len,
303  struct GNUNET_HashCode *hmac)
304 {
305  GNUNET_CRYPTO_hmac_raw ((void *) key->key, sizeof(key->key),
306  plaintext, plaintext_len,
307  hmac);
308 }
309 
310 
312 {
316  gcry_md_hd_t hd;
317 };
318 
319 
320 struct GNUNET_HashContext *
322 {
323  struct GNUNET_HashContext *hc;
324 
325  BENCHMARK_START (hash_context_start);
326 
327  hc = GNUNET_new (struct GNUNET_HashContext);
328  GNUNET_assert (0 ==
329  gcry_md_open (&hc->hd,
330  GCRY_MD_SHA512,
331  0));
332 
333  BENCHMARK_END (hash_context_start);
334 
335  return hc;
336 }
337 
338 
339 void
341  const void *buf,
342  size_t size)
343 {
344  BENCHMARK_START (hash_context_read);
345  gcry_md_write (hc->hd, buf, size);
346  BENCHMARK_END (hash_context_read);
347 }
348 
349 
350 struct GNUNET_HashContext *
352 {
353  struct GNUNET_HashContext *cp;
354 
355  cp = GNUNET_new (struct GNUNET_HashContext);
356  GNUNET_assert (0 ==
357  gcry_md_copy (&cp->hd,
358  hc->hd));
359  return cp;
360 }
361 
362 
363 void
365  struct GNUNET_HashCode *r_hash)
366 {
367  const void *res = gcry_md_read (hc->hd, 0);
368 
369  BENCHMARK_START (hash_context_finish);
370 
371  GNUNET_assert (NULL != res);
372  if (NULL != r_hash)
373  GNUNET_memcpy (r_hash,
374  res,
375  sizeof(struct GNUNET_HashCode));
377  BENCHMARK_END (hash_context_finish);
378 }
379 
380 
381 void
383 {
384  gcry_md_close (hc->hd);
385  GNUNET_free (hc);
386 }
387 
388 
389 /* end of crypto_hash.c */
benchmarking for various operations
#define BENCHMARK_START(opname)
Definition: benchmark.h:57
#define BENCHMARK_END(opname)
Definition: benchmark.h:58
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start()
Start incremental hashing operation.
Definition: crypto_hash.c:321
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:340
int GNUNET_CRYPTO_hash_get_bit_rtl(const struct GNUNET_HashCode *code, unsigned int bit)
Obtain a bit from a hashcode.
Definition: crypto_hash.c:180
void GNUNET_CRYPTO_hash_context_abort(struct GNUNET_HashContext *hc)
Abort hashing, do not bother calculating final result.
Definition: crypto_hash.c:382
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_copy(const struct GNUNET_HashContext *hc)
Make a copy of the hash computation.
Definition: crypto_hash.c:351
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:364
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' this be the standard hmac function and the abov...
Definition: crypto_hash.c:274
static int once
Global to mark if we've run the initialization.
Definition: gnsrecord.c:68
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int res
struct GNUNET_HashCode key
The key used in the DHT.
static OpusEncoder * enc
OPUS encoder.
static struct GNUNET_TESTBED_Controller * mc
Handle to the master controller.
static int result
Global testing status.
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
static char buf[2048]
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:92
@ GNUNET_YES
Definition: gnunet_common.h:97
cryptographic primitives for GNUnet
enum GNUNET_GenericReturnValue 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
static enum @8 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
GNUNET_CRYPTO_Quality
Desired quality level for random numbers.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
void GNUNET_CRYPTO_hash_difference(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result)
compute result = b - a
Definition: crypto_hash.c:110
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
void GNUNET_CRYPTO_hash_to_enc(const struct GNUNET_HashCode *block, struct GNUNET_CRYPTO_HashAsciiEncoded *result)
Convert hash to ASCII encoding.
Definition: crypto_hash.c:55
void GNUNET_CRYPTO_hash_create_random(enum GNUNET_CRYPTO_Quality mode, struct GNUNET_HashCode *result)
Create a random hash code.
Definition: crypto_hash.c:99
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:301
void GNUNET_CRYPTO_hash_sum(const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *delta, struct GNUNET_HashCode *result)
compute result = a + delta
Definition: crypto_hash.c:122
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:134
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:189
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 GNUNET_CRYPTO_hash codes is closer to target in the XOR metric (Kademlia).
Definition: crypto_hash.c:223
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:260
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hash_from_string2(const char *enc, size_t enclen, struct GNUNET_HashCode *result)
Convert ASCII encoding back to a 'struct GNUNET_HashCode'.
Definition: crypto_hash.c:72
int GNUNET_CRYPTO_hash_get_bit_ltr(const struct GNUNET_HashCode *code, unsigned int bit)
Obtain a bit from a hashcode.
Definition: crypto_hash.c:171
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:201
unsigned int 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:88
enum GNUNET_GenericReturnValue 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:90
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:246
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:146
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
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:695
enum GNUNET_GenericReturnValue 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:775
void GNUNET_STRINGS_utf8_toupper(const char *input, char *output)
Convert the utf-8 input string to upper case.
Definition: strings.c:463
static unsigned int size
Size of the "table".
Definition: peer.c:67
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
type for (message) authentication keys
0-terminated ASCII encoding of a struct GNUNET_HashCode.
A 512-bit hashcode.
uint32_t bits[512/8/sizeof(uint32_t)]
gcry_md_hd_t hd
Internal state of the hash function.
Definition: crypto_hash.c:316