aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-12-09 23:00:07 +0100
committerChristian Grothoff <christian@grothoff.org>2020-12-09 23:00:13 +0100
commit7d9592f201f2e4801e9989a88d9f0d1b81d8f71d (patch)
tree2d19ce4c24f17eff2ceee0f52d1a99e08110bf08
parent813d74fafbd7d6556edeb94d8654838682624c27 (diff)
downloadgnunet-7d9592f201f2e4801e9989a88d9f0d1b81d8f71d.tar.gz
gnunet-7d9592f201f2e4801e9989a88d9f0d1b81d8f71d.zip
add GNUNET_CRYPTO_hash_context_copy() function
-rw-r--r--src/util/crypto_hash.c249
1 files changed, 41 insertions, 208 deletions
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c
index 55676917e..d62ec8012 100644
--- a/src/util/crypto_hash.c
+++ b/src/util/crypto_hash.c
@@ -37,13 +37,6 @@
37 syscall, \ 37 syscall, \
38 filename) 38 filename)
39 39
40/**
41 * Hash block of given size.
42 *
43 * @param block the data to #GNUNET_CRYPTO_hash, length is given as a second argument
44 * @param size the length of the data to #GNUNET_CRYPTO_hash in @a block
45 * @param ret pointer to where to write the hashcode
46 */
47void 40void
48GNUNET_CRYPTO_hash (const void *block, 41GNUNET_CRYPTO_hash (const void *block,
49 size_t size, 42 size_t size,
@@ -58,17 +51,6 @@ GNUNET_CRYPTO_hash (const void *block,
58/* ***************** binary-ASCII encoding *************** */ 51/* ***************** binary-ASCII encoding *************** */
59 52
60 53
61/**
62 * Convert GNUNET_CRYPTO_hash to ASCII encoding. The ASCII encoding is rather
63 * GNUnet specific. It was chosen such that it only uses characters
64 * in [0-9A-V], can be produced without complex arithmetic and uses a
65 * small number of characters. The GNUnet encoding uses 103
66 * characters plus a null terminator.
67 *
68 * @param block the hash code
69 * @param result where to store the encoding (struct GNUNET_CRYPTO_HashAsciiEncoded can be
70 * safely cast to char*, a '\\0' termination is set).
71 */
72void 54void
73GNUNET_CRYPTO_hash_to_enc (const struct GNUNET_HashCode *block, 55GNUNET_CRYPTO_hash_to_enc (const struct GNUNET_HashCode *block,
74 struct GNUNET_CRYPTO_HashAsciiEncoded *result) 56 struct GNUNET_CRYPTO_HashAsciiEncoded *result)
@@ -86,14 +68,6 @@ GNUNET_CRYPTO_hash_to_enc (const struct GNUNET_HashCode *block,
86} 68}
87 69
88 70
89/**
90 * Convert ASCII encoding back to hash code.
91 *
92 * @param enc the encoding
93 * @param enclen number of characters in @a enc (without 0-terminator, which can be missing)
94 * @param result where to store the hash code
95 * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong encoding
96 */
97enum GNUNET_GenericReturnValue 71enum GNUNET_GenericReturnValue
98GNUNET_CRYPTO_hash_from_string2 (const char *enc, 72GNUNET_CRYPTO_hash_from_string2 (const char *enc,
99 size_t enclen, 73 size_t enclen,
@@ -110,19 +84,6 @@ GNUNET_CRYPTO_hash_from_string2 (const char *enc,
110} 84}
111 85
112 86
113/**
114 * @ingroup hash
115 *
116 * Compute the distance between 2 hashcodes. The computation must be
117 * fast, not involve bits[0] or bits[4] (they're used elsewhere), and be
118 * somewhat consistent. And of course, the result should be a positive
119 * number.
120 *
121 * @param a some hash code
122 * @param b some hash code
123 * @return a positive number which is a measure for
124 * hashcode proximity.
125 */
126unsigned int 87unsigned int
127GNUNET_CRYPTO_hash_distance_u32 (const struct GNUNET_HashCode *a, 88GNUNET_CRYPTO_hash_distance_u32 (const struct GNUNET_HashCode *a,
128 const struct GNUNET_HashCode *b) 89 const struct GNUNET_HashCode *b)
@@ -134,90 +95,53 @@ GNUNET_CRYPTO_hash_distance_u32 (const struct GNUNET_HashCode *a,
134} 95}
135 96
136 97
137/**
138 * Create a random hash code.
139 *
140 * @param mode desired quality level
141 * @param result hash code that is randomized
142 */
143void 98void
144GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode, 99GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode,
145 struct GNUNET_HashCode *result) 100 struct GNUNET_HashCode *result)
146{ 101{
147 int i; 102 for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(uint32_t)) - 1;
148 103 i >= 0;
149 for (i = (sizeof(struct GNUNET_HashCode) / sizeof(uint32_t)) - 1; i >= 0; i--) 104 i--)
150 result->bits[i] = GNUNET_CRYPTO_random_u32 (mode, UINT32_MAX); 105 result->bits[i] = GNUNET_CRYPTO_random_u32 (mode, UINT32_MAX);
151} 106}
152 107
153 108
154/**
155 * compute result(delta) = b - a
156 *
157 * @param a some hash code
158 * @param b some hash code
159 * @param result set to b - a
160 */
161void 109void
162GNUNET_CRYPTO_hash_difference (const struct GNUNET_HashCode *a, 110GNUNET_CRYPTO_hash_difference (const struct GNUNET_HashCode *a,
163 const struct GNUNET_HashCode *b, 111 const struct GNUNET_HashCode *b,
164 struct GNUNET_HashCode *result) 112 struct GNUNET_HashCode *result)
165{ 113{
166 int i; 114 for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1;
167 115 i >= 0;
168 for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0;
169 i--) 116 i--)
170 result->bits[i] = b->bits[i] - a->bits[i]; 117 result->bits[i] = b->bits[i] - a->bits[i];
171} 118}
172 119
173 120
174/**
175 * compute result(b) = a + delta
176 *
177 * @param a some hash code
178 * @param delta some hash code
179 * @param result set to a + delta
180 */
181void 121void
182GNUNET_CRYPTO_hash_sum (const struct GNUNET_HashCode *a, 122GNUNET_CRYPTO_hash_sum (const struct GNUNET_HashCode *a,
183 const struct GNUNET_HashCode *delta, struct 123 const struct GNUNET_HashCode *delta, struct
184 GNUNET_HashCode *result) 124 GNUNET_HashCode *result)
185{ 125{
186 int i; 126 for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1;
187 127 i >= 0;
188 for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0;
189 i--) 128 i--)
190 result->bits[i] = delta->bits[i] + a->bits[i]; 129 result->bits[i] = delta->bits[i] + a->bits[i];
191} 130}
192 131
193 132
194/**
195 * compute result = a ^ b
196 *
197 * @param a some hash code
198 * @param b some hash code
199 * @param result set to a ^ b
200 */
201void 133void
202GNUNET_CRYPTO_hash_xor (const struct GNUNET_HashCode *a, 134GNUNET_CRYPTO_hash_xor (const struct GNUNET_HashCode *a,
203 const struct GNUNET_HashCode *b, 135 const struct GNUNET_HashCode *b,
204 struct GNUNET_HashCode *result) 136 struct GNUNET_HashCode *result)
205{ 137{
206 int i; 138 for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1;
207 139 i >= 0;
208 for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0;
209 i--) 140 i--)
210 result->bits[i] = a->bits[i] ^ b->bits[i]; 141 result->bits[i] = a->bits[i] ^ b->bits[i];
211} 142}
212 143
213 144
214/**
215 * Convert a hashcode into a key.
216 *
217 * @param hc hash code that serves to generate the key
218 * @param skey set to a valid session key
219 * @param iv set to a valid initialization vector
220 */
221void 145void
222GNUNET_CRYPTO_hash_to_aes_key (const struct GNUNET_HashCode *hc, 146GNUNET_CRYPTO_hash_to_aes_key (const struct GNUNET_HashCode *hc,
223 struct GNUNET_CRYPTO_SymmetricSessionKey *skey, 147 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
@@ -225,29 +149,24 @@ GNUNET_CRYPTO_hash_to_aes_key (const struct GNUNET_HashCode *hc,
225 GNUNET_CRYPTO_SymmetricInitializationVector *iv) 149 GNUNET_CRYPTO_SymmetricInitializationVector *iv)
226{ 150{
227 GNUNET_assert (GNUNET_YES == 151 GNUNET_assert (GNUNET_YES ==
228 GNUNET_CRYPTO_kdf (skey, sizeof(struct 152 GNUNET_CRYPTO_kdf (
229 GNUNET_CRYPTO_SymmetricSessionKey), 153 skey,
230 "Hash key derivation", strlen ( 154 sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
231 "Hash key derivation"), 155 "Hash key derivation",
232 hc, sizeof(struct GNUNET_HashCode), 156 strlen ("Hash key derivation"),
233 NULL, 0)); 157 hc, sizeof(struct GNUNET_HashCode),
158 NULL, 0));
234 GNUNET_assert (GNUNET_YES == 159 GNUNET_assert (GNUNET_YES ==
235 GNUNET_CRYPTO_kdf (iv, sizeof(struct 160 GNUNET_CRYPTO_kdf (
236 GNUNET_CRYPTO_SymmetricInitializationVector), 161 iv,
237 "Initialization vector derivation", strlen ( 162 sizeof(struct GNUNET_CRYPTO_SymmetricInitializationVector),
238 "Initialization vector derivation"), 163 "Initialization vector derivation",
239 hc, sizeof(struct GNUNET_HashCode), 164 strlen ("Initialization vector derivation"),
240 NULL, 0)); 165 hc, sizeof(struct GNUNET_HashCode),
166 NULL, 0));
241} 167}
242 168
243 169
244/**
245 * Obtain a bit from a hashcode.
246 * @param code the GNUNET_CRYPTO_hash to index bit-wise
247 * @param bit index into the hashcode, [0...511] where 0 is the leftmost bit
248 * (bytes in code interpreted big endian)
249 * @return Bit \a bit from hashcode \a code, -1 for invalid index
250 */
251int 170int
252GNUNET_CRYPTO_hash_get_bit_ltr (const struct GNUNET_HashCode *code, 171GNUNET_CRYPTO_hash_get_bit_ltr (const struct GNUNET_HashCode *code,
253 unsigned int bit) 172 unsigned int bit)
@@ -257,13 +176,6 @@ GNUNET_CRYPTO_hash_get_bit_ltr (const struct GNUNET_HashCode *code,
257} 176}
258 177
259 178
260/**
261 * Obtain a bit from a hashcode.
262 * @param code the GNUNET_CRYPTO_hash to index bit-wise
263 * @param bit index into the hashcode, [0...511] where 0 is the rightmost bit
264 * (bytes in code interpreted little endian)
265 * @return Bit \a bit from hashcode \a code, -1 for invalid index
266 */
267int 179int
268GNUNET_CRYPTO_hash_get_bit_rtl (const struct GNUNET_HashCode *code, 180GNUNET_CRYPTO_hash_get_bit_rtl (const struct GNUNET_HashCode *code,
269 unsigned int bit) 181 unsigned int bit)
@@ -273,25 +185,11 @@ GNUNET_CRYPTO_hash_get_bit_rtl (const struct GNUNET_HashCode *code,
273} 185}
274 186
275 187
276/**
277 * Determine how many low order bits match in two
278 * `struct GNUNET_HashCode`s. i.e. - 010011 and 011111 share
279 * the first two lowest order bits, and therefore the
280 * return value is two (NOT XOR distance, nor how many
281 * bits match absolutely!).
282 *
283 * @param first the first hashcode
284 * @param second the hashcode to compare first to
285 *
286 * @return the number of bits that match
287 */
288unsigned int 188unsigned int
289GNUNET_CRYPTO_hash_matching_bits (const struct GNUNET_HashCode *first, 189GNUNET_CRYPTO_hash_matching_bits (const struct GNUNET_HashCode *first,
290 const struct GNUNET_HashCode *second) 190 const struct GNUNET_HashCode *second)
291{ 191{
292 unsigned int i; 192 for (unsigned int i = 0; i < sizeof(struct GNUNET_HashCode) * 8; i++)
293
294 for (i = 0; i < sizeof(struct GNUNET_HashCode) * 8; i++)
295 if (GNUNET_CRYPTO_hash_get_bit_rtl (first, i) != 193 if (GNUNET_CRYPTO_hash_get_bit_rtl (first, i) !=
296 GNUNET_CRYPTO_hash_get_bit_rtl (second, i)) 194 GNUNET_CRYPTO_hash_get_bit_rtl (second, i))
297 return i; 195 return i;
@@ -299,25 +197,17 @@ GNUNET_CRYPTO_hash_matching_bits (const struct GNUNET_HashCode *first,
299} 197}
300 198
301 199
302/**
303 * Compare function for HashCodes, producing a total ordering
304 * of all hashcodes.
305 *
306 * @param h1 some hash code
307 * @param h2 some hash code
308 * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2.
309 */
310int 200int
311GNUNET_CRYPTO_hash_cmp (const struct GNUNET_HashCode *h1, 201GNUNET_CRYPTO_hash_cmp (const struct GNUNET_HashCode *h1,
312 const struct GNUNET_HashCode *h2) 202 const struct GNUNET_HashCode *h2)
313{ 203{
314 unsigned int *i1; 204 unsigned int *i1;
315 unsigned int *i2; 205 unsigned int *i2;
316 int i;
317 206
318 i1 = (unsigned int *) h1; 207 i1 = (unsigned int *) h1;
319 i2 = (unsigned int *) h2; 208 i2 = (unsigned int *) h2;
320 for (i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; i >= 0; 209 for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1;
210 i >= 0;
321 i--) 211 i--)
322 { 212 {
323 if (i1[i] > i2[i]) 213 if (i1[i] > i2[i])
@@ -329,25 +219,16 @@ GNUNET_CRYPTO_hash_cmp (const struct GNUNET_HashCode *h1,
329} 219}
330 220
331 221
332/**
333 * Find out which of the two `struct GNUNET_HashCode`s is closer to target
334 * in the XOR metric (Kademlia).
335 *
336 * @param h1 some hash code
337 * @param h2 some hash code
338 * @param target some hash code
339 * @return -1 if h1 is closer, 1 if h2 is closer and 0 if h1==h2.
340 */
341int 222int
342GNUNET_CRYPTO_hash_xorcmp (const struct GNUNET_HashCode *h1, 223GNUNET_CRYPTO_hash_xorcmp (const struct GNUNET_HashCode *h1,
343 const struct GNUNET_HashCode *h2, 224 const struct GNUNET_HashCode *h2,
344 const struct GNUNET_HashCode *target) 225 const struct GNUNET_HashCode *target)
345{ 226{
346 int i;
347 unsigned int d1; 227 unsigned int d1;
348 unsigned int d2; 228 unsigned int d2;
349 229
350 for (i = sizeof(struct GNUNET_HashCode) / sizeof(unsigned int) - 1; i >= 0; 230 for (ssize_t i = sizeof(struct GNUNET_HashCode) / sizeof(unsigned int) - 1;
231 i >= 0;
351 i--) 232 i--)
352 { 233 {
353 d1 = ((unsigned int *) h1)[i] ^ ((unsigned int *) target)[i]; 234 d1 = ((unsigned int *) h1)[i] ^ ((unsigned int *) target)[i];
@@ -361,14 +242,6 @@ GNUNET_CRYPTO_hash_xorcmp (const struct GNUNET_HashCode *h1,
361} 242}
362 243
363 244
364/**
365 * @brief Derive an authentication key
366 * @param key authentication key
367 * @param rkey root key
368 * @param salt salt
369 * @param salt_len size of the @a salt
370 * @param ... pair of void * & size_t for context chunks, terminated by NULL
371 */
372void 245void
373GNUNET_CRYPTO_hmac_derive_key (struct GNUNET_CRYPTO_AuthKey *key, 246GNUNET_CRYPTO_hmac_derive_key (struct GNUNET_CRYPTO_AuthKey *key,
374 const struct 247 const struct
@@ -383,14 +256,6 @@ GNUNET_CRYPTO_hmac_derive_key (struct GNUNET_CRYPTO_AuthKey *key,
383} 256}
384 257
385 258
386/**
387 * @brief Derive an authentication key
388 * @param key authentication key
389 * @param rkey root key
390 * @param salt salt
391 * @param salt_len size of the @a salt
392 * @param argp pair of void * & size_t for context chunks, terminated by NULL
393 */
394void 259void
395GNUNET_CRYPTO_hmac_derive_key_v (struct GNUNET_CRYPTO_AuthKey *key, 260GNUNET_CRYPTO_hmac_derive_key_v (struct GNUNET_CRYPTO_AuthKey *key,
396 const struct 261 const struct
@@ -405,17 +270,6 @@ GNUNET_CRYPTO_hmac_derive_key_v (struct GNUNET_CRYPTO_AuthKey *key,
405} 270}
406 271
407 272
408/**
409 * Calculate HMAC of a message (RFC 2104)
410 * TODO: Shouldn' this be the standard hmac function and
411 * the above be renamed?
412 *
413 * @param key secret key
414 * @param key_len secret key length
415 * @param plaintext input plaintext
416 * @param plaintext_len length of @a plaintext
417 * @param hmac where to store the hmac
418 */
419void 273void
420GNUNET_CRYPTO_hmac_raw (const void *key, size_t key_len, 274GNUNET_CRYPTO_hmac_raw (const void *key, size_t key_len,
421 const void *plaintext, size_t plaintext_len, 275 const void *plaintext, size_t plaintext_len,
@@ -443,14 +297,6 @@ GNUNET_CRYPTO_hmac_raw (const void *key, size_t key_len,
443} 297}
444 298
445 299
446/**
447 * Calculate HMAC of a message (RFC 2104)
448 *
449 * @param key secret key
450 * @param plaintext input plaintext
451 * @param plaintext_len length of @a plaintext
452 * @param hmac where to store the hmac
453 */
454void 300void
455GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key, 301GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key,
456 const void *plaintext, size_t plaintext_len, 302 const void *plaintext, size_t plaintext_len,
@@ -462,9 +308,6 @@ GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key,
462} 308}
463 309
464 310
465/**
466 * Context for cumulative hashing.
467 */
468struct GNUNET_HashContext 311struct GNUNET_HashContext
469{ 312{
470 /** 313 /**
@@ -474,11 +317,6 @@ struct GNUNET_HashContext
474}; 317};
475 318
476 319
477/**
478 * Start incremental hashing operation.
479 *
480 * @return context for incremental hash computation
481 */
482struct GNUNET_HashContext * 320struct GNUNET_HashContext *
483GNUNET_CRYPTO_hash_context_start () 321GNUNET_CRYPTO_hash_context_start ()
484{ 322{
@@ -498,13 +336,6 @@ GNUNET_CRYPTO_hash_context_start ()
498} 336}
499 337
500 338
501/**
502 * Add data to be hashed.
503 *
504 * @param hc cumulative hash context
505 * @param buf data to add
506 * @param size number of bytes in @a buf
507 */
508void 339void
509GNUNET_CRYPTO_hash_context_read (struct GNUNET_HashContext *hc, 340GNUNET_CRYPTO_hash_context_read (struct GNUNET_HashContext *hc,
510 const void *buf, 341 const void *buf,
@@ -516,12 +347,19 @@ GNUNET_CRYPTO_hash_context_read (struct GNUNET_HashContext *hc,
516} 347}
517 348
518 349
519/** 350struct GNUNET_HashContext *
520 * Finish the hash computation. 351GNUNET_CRYPTO_hash_context_copy (const struct GNUNET_HashContext *hc)
521 * 352{
522 * @param hc hash context to use 353 struct GNUNET_HashContext *cp;
523 * @param r_hash where to write the latest / final hash code 354
524 */ 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
525void 363void
526GNUNET_CRYPTO_hash_context_finish (struct GNUNET_HashContext *hc, 364GNUNET_CRYPTO_hash_context_finish (struct GNUNET_HashContext *hc,
527 struct GNUNET_HashCode *r_hash) 365 struct GNUNET_HashCode *r_hash)
@@ -540,11 +378,6 @@ GNUNET_CRYPTO_hash_context_finish (struct GNUNET_HashContext *hc,
540} 378}
541 379
542 380
543/**
544 * Abort hashing, do not bother calculating final result.
545 *
546 * @param hc hash context to destroy
547 */
548void 381void
549GNUNET_CRYPTO_hash_context_abort (struct GNUNET_HashContext *hc) 382GNUNET_CRYPTO_hash_context_abort (struct GNUNET_HashContext *hc)
550{ 383{