aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_hash.c')
-rw-r--r--src/util/crypto_hash.c223
1 files changed, 105 insertions, 118 deletions
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c
index 670f5e73a..c693ed081 100644
--- a/src/util/crypto_hash.c
+++ b/src/util/crypto_hash.c
@@ -115,8 +115,8 @@ struct GNUNET_CRYPTO_FileHashContext
115 * and free associated resources. 115 * and free associated resources.
116 */ 116 */
117static void 117static void
118file_hash_finish (struct GNUNET_CRYPTO_FileHashContext *fhc, 118file_hash_finish (struct GNUNET_CRYPTO_FileHashContext *fhc,
119 const GNUNET_HashCode * res) 119 const GNUNET_HashCode * res)
120{ 120{
121 fhc->callback (fhc->callback_cls, res); 121 fhc->callback (fhc->callback_cls, res);
122 GNUNET_free (fhc->filename); 122 GNUNET_free (fhc->filename);
@@ -146,22 +146,20 @@ file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
146 if (fhc->fsize - fhc->offset < delta) 146 if (fhc->fsize - fhc->offset < delta)
147 delta = fhc->fsize - fhc->offset; 147 delta = fhc->fsize - fhc->offset;
148 if (delta != GNUNET_DISK_file_read (fhc->fh, fhc->buffer, delta)) 148 if (delta != GNUNET_DISK_file_read (fhc->fh, fhc->buffer, delta))
149 { 149 {
150 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 150 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "read", fhc->filename);
151 "read", fhc->filename); 151 file_hash_finish (fhc, NULL);
152 file_hash_finish (fhc, NULL); 152 return;
153 return; 153 }
154 }
155 gcry_md_write (fhc->md, fhc->buffer, delta); 154 gcry_md_write (fhc->md, fhc->buffer, delta);
156 fhc->offset += delta; 155 fhc->offset += delta;
157 if (fhc->offset == fhc->fsize) 156 if (fhc->offset == fhc->fsize)
158 { 157 {
159 res = (GNUNET_HashCode *) gcry_md_read (fhc->md, GCRY_MD_SHA512); 158 res = (GNUNET_HashCode *) gcry_md_read (fhc->md, GCRY_MD_SHA512);
160 file_hash_finish (fhc, res); 159 file_hash_finish (fhc, res);
161 return; 160 return;
162 } 161 }
163 fhc->task 162 fhc->task = GNUNET_SCHEDULER_add_now (&file_hash_task, fhc);
164 = GNUNET_SCHEDULER_add_now (&file_hash_task, fhc);
165} 163}
166 164
167 165
@@ -185,36 +183,36 @@ GNUNET_CRYPTO_hash_file (enum GNUNET_SCHEDULER_Priority priority,
185 struct GNUNET_CRYPTO_FileHashContext *fhc; 183 struct GNUNET_CRYPTO_FileHashContext *fhc;
186 184
187 GNUNET_assert (blocksize > 0); 185 GNUNET_assert (blocksize > 0);
188 fhc = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_FileHashContext) + blocksize); 186 fhc =
187 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_FileHashContext) + blocksize);
189 fhc->callback = callback; 188 fhc->callback = callback;
190 fhc->callback_cls = callback_cls; 189 fhc->callback_cls = callback_cls;
191 fhc->buffer = (unsigned char *) &fhc[1]; 190 fhc->buffer = (unsigned char *) &fhc[1];
192 fhc->filename = GNUNET_strdup (filename); 191 fhc->filename = GNUNET_strdup (filename);
193 if (GPG_ERR_NO_ERROR != gcry_md_open (&fhc->md, GCRY_MD_SHA512, 0)) 192 if (GPG_ERR_NO_ERROR != gcry_md_open (&fhc->md, GCRY_MD_SHA512, 0))
194 { 193 {
195 GNUNET_break (0); 194 GNUNET_break (0);
196 GNUNET_free (fhc); 195 GNUNET_free (fhc);
197 return NULL; 196 return NULL;
198 } 197 }
199 fhc->bsize = blocksize; 198 fhc->bsize = blocksize;
200 if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO)) 199 if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO))
201 { 200 {
202 GNUNET_free (fhc->filename); 201 GNUNET_free (fhc->filename);
203 GNUNET_free (fhc); 202 GNUNET_free (fhc);
204 return NULL; 203 return NULL;
205 } 204 }
206 fhc->fh = GNUNET_DISK_file_open (filename, 205 fhc->fh = GNUNET_DISK_file_open (filename,
207 GNUNET_DISK_OPEN_READ, 206 GNUNET_DISK_OPEN_READ,
208 GNUNET_DISK_PERM_NONE); 207 GNUNET_DISK_PERM_NONE);
209 if (!fhc->fh) 208 if (!fhc->fh)
210 { 209 {
211 GNUNET_free (fhc->filename); 210 GNUNET_free (fhc->filename);
212 GNUNET_free (fhc); 211 GNUNET_free (fhc);
213 return NULL; 212 return NULL;
214 } 213 }
215 fhc->task 214 fhc->task
216 = GNUNET_SCHEDULER_add_with_priority (priority, 215 = GNUNET_SCHEDULER_add_with_priority (priority, &file_hash_task, fhc);
217 &file_hash_task, fhc);
218 return fhc; 216 return fhc;
219} 217}
220 218
@@ -278,23 +276,22 @@ GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block,
278 rpos = 0; 276 rpos = 0;
279 bits = 0; 277 bits = 0;
280 while ((rpos < sizeof (GNUNET_HashCode)) || (vbit > 0)) 278 while ((rpos < sizeof (GNUNET_HashCode)) || (vbit > 0))
279 {
280 if ((rpos < sizeof (GNUNET_HashCode)) && (vbit < 5))
281 {
282 bits = (bits << 8) | ((unsigned char *) block)[rpos++]; /* eat 8 more bits */
283 vbit += 8;
284 }
285 if (vbit < 5)
281 { 286 {
282 if ((rpos < sizeof (GNUNET_HashCode)) && (vbit < 5)) 287 bits <<= (5 - vbit); /* zero-padding */
283 { 288 GNUNET_assert (vbit == 2); /* padding by 3: 512+3 mod 5 == 0 */
284 bits = (bits << 8) | ((unsigned char *) block)[rpos++]; /* eat 8 more bits */ 289 vbit = 5;
285 vbit += 8;
286 }
287 if (vbit < 5)
288 {
289 bits <<= (5 - vbit); /* zero-padding */
290 GNUNET_assert (vbit == 2); /* padding by 3: 512+3 mod 5 == 0 */
291 vbit = 5;
292 }
293 GNUNET_assert (wpos <
294 sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1);
295 result->encoding[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
296 vbit -= 5;
297 } 290 }
291 GNUNET_assert (wpos < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1);
292 result->encoding[wpos++] = encTable__[(bits >> (vbit - 5)) & 31];
293 vbit -= 5;
294 }
298 GNUNET_assert (wpos == sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1); 295 GNUNET_assert (wpos == sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1);
299 GNUNET_assert (vbit == 0); 296 GNUNET_assert (vbit == 0);
300 result->encoding[wpos] = '\0'; 297 result->encoding[wpos] = '\0';
@@ -323,17 +320,17 @@ GNUNET_CRYPTO_hash_from_string (const char *enc, GNUNET_HashCode * result)
323 rpos = sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1; 320 rpos = sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1;
324 bits = getValue__ (enc[--rpos]) >> 3; 321 bits = getValue__ (enc[--rpos]) >> 3;
325 while (wpos > 0) 322 while (wpos > 0)
323 {
324 GNUNET_assert (rpos > 0);
325 bits = (getValue__ (enc[--rpos]) << vbit) | bits;
326 vbit += 5;
327 if (vbit >= 8)
326 { 328 {
327 GNUNET_assert (rpos > 0); 329 ((unsigned char *) result)[--wpos] = (unsigned char) bits;
328 bits = (getValue__ (enc[--rpos]) << vbit) | bits; 330 bits >>= 8;
329 vbit += 5; 331 vbit -= 8;
330 if (vbit >= 8)
331 {
332 ((unsigned char *) result)[--wpos] = (unsigned char) bits;
333 bits >>= 8;
334 vbit -= 8;
335 }
336 } 332 }
333 }
337 GNUNET_assert (rpos == 0); 334 GNUNET_assert (rpos == 0);
338 GNUNET_assert (vbit == 0); 335 GNUNET_assert (vbit == 0);
339 return GNUNET_OK; 336 return GNUNET_OK;
@@ -356,6 +353,7 @@ GNUNET_CRYPTO_hash_distance_u32 (const GNUNET_HashCode * a,
356{ 353{
357 unsigned int x1 = (a->bits[1] - b->bits[1]) >> 16; 354 unsigned int x1 = (a->bits[1] - b->bits[1]) >> 16;
358 unsigned int x2 = (b->bits[1] - a->bits[1]) >> 16; 355 unsigned int x2 = (b->bits[1] - a->bits[1]) >> 16;
356
359 return (x1 * x2); 357 return (x1 * x2);
360} 358}
361 359
@@ -364,6 +362,7 @@ GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode,
364 GNUNET_HashCode * result) 362 GNUNET_HashCode * result)
365{ 363{
366 int i; 364 int i;
365
367 for (i = (sizeof (GNUNET_HashCode) / sizeof (uint32_t)) - 1; i >= 0; i--) 366 for (i = (sizeof (GNUNET_HashCode) / sizeof (uint32_t)) - 1; i >= 0; i--)
368 result->bits[i] = GNUNET_CRYPTO_random_u32 (mode, UINT32_MAX); 367 result->bits[i] = GNUNET_CRYPTO_random_u32 (mode, UINT32_MAX);
369} 368}
@@ -374,31 +373,29 @@ GNUNET_CRYPTO_hash_difference (const GNUNET_HashCode * a,
374 GNUNET_HashCode * result) 373 GNUNET_HashCode * result)
375{ 374{
376 int i; 375 int i;
377 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0; 376
378 i--) 377 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0; i--)
379 result->bits[i] = b->bits[i] - a->bits[i]; 378 result->bits[i] = b->bits[i] - a->bits[i];
380} 379}
381 380
382void 381void
383GNUNET_CRYPTO_hash_sum (const GNUNET_HashCode * a, 382GNUNET_CRYPTO_hash_sum (const GNUNET_HashCode * a,
384 const GNUNET_HashCode * delta, 383 const GNUNET_HashCode * delta, GNUNET_HashCode * result)
385 GNUNET_HashCode * result)
386{ 384{
387 int i; 385 int i;
388 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0; 386
389 i--) 387 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0; i--)
390 result->bits[i] = delta->bits[i] + a->bits[i]; 388 result->bits[i] = delta->bits[i] + a->bits[i];
391} 389}
392 390
393 391
394void 392void
395GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a, 393GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a,
396 const GNUNET_HashCode * b, 394 const GNUNET_HashCode * b, GNUNET_HashCode * result)
397 GNUNET_HashCode * result)
398{ 395{
399 int i; 396 int i;
400 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0; 397
401 i--) 398 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0; i--)
402 result->bits[i] = a->bits[i] ^ b->bits[i]; 399 result->bits[i] = a->bits[i] ^ b->bits[i];
403} 400}
404 401
@@ -409,15 +406,14 @@ GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a,
409void 406void
410GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc, 407GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc,
411 struct GNUNET_CRYPTO_AesSessionKey *skey, 408 struct GNUNET_CRYPTO_AesSessionKey *skey,
412 struct GNUNET_CRYPTO_AesInitializationVector 409 struct GNUNET_CRYPTO_AesInitializationVector *iv)
413 *iv)
414{ 410{
415 GNUNET_assert (sizeof (GNUNET_HashCode) >= 411 GNUNET_assert (sizeof (GNUNET_HashCode) >=
416 GNUNET_CRYPTO_AES_KEY_LENGTH + 412 GNUNET_CRYPTO_AES_KEY_LENGTH +
417 sizeof (struct GNUNET_CRYPTO_AesInitializationVector)); 413 sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
418 memcpy (skey, hc, GNUNET_CRYPTO_AES_KEY_LENGTH); 414 memcpy (skey, hc, GNUNET_CRYPTO_AES_KEY_LENGTH);
419 skey->crc32 = 415 skey->crc32 =
420 htonl (GNUNET_CRYPTO_crc32_n (skey, GNUNET_CRYPTO_AES_KEY_LENGTH)); 416 htonl (GNUNET_CRYPTO_crc32_n (skey, GNUNET_CRYPTO_AES_KEY_LENGTH));
421 memcpy (iv, &((char *) hc)[GNUNET_CRYPTO_AES_KEY_LENGTH], 417 memcpy (iv, &((char *) hc)[GNUNET_CRYPTO_AES_KEY_LENGTH],
422 sizeof (struct GNUNET_CRYPTO_AesInitializationVector)); 418 sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
423} 419}
@@ -430,8 +426,7 @@ GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc,
430 * @return Bit \a bit from hashcode \a code, -1 for invalid index 426 * @return Bit \a bit from hashcode \a code, -1 for invalid index
431 */ 427 */
432int 428int
433GNUNET_CRYPTO_hash_get_bit (const GNUNET_HashCode * code, 429GNUNET_CRYPTO_hash_get_bit (const GNUNET_HashCode * code, unsigned int bit)
434 unsigned int bit)
435{ 430{
436 GNUNET_assert (bit < 8 * sizeof (GNUNET_HashCode)); 431 GNUNET_assert (bit < 8 * sizeof (GNUNET_HashCode));
437 return (((unsigned char *) code)[bit >> 3] & (1 << (bit & 7))) > 0; 432 return (((unsigned char *) code)[bit >> 3] & (1 << (bit & 7))) > 0;
@@ -449,14 +444,15 @@ GNUNET_CRYPTO_hash_get_bit (const GNUNET_HashCode * code,
449 * 444 *
450 * @return the number of bits that match 445 * @return the number of bits that match
451 */ 446 */
452unsigned int 447unsigned int
453GNUNET_CRYPTO_hash_matching_bits(const GNUNET_HashCode *first, 448GNUNET_CRYPTO_hash_matching_bits (const GNUNET_HashCode * first,
454 const GNUNET_HashCode *second) 449 const GNUNET_HashCode * second)
455{ 450{
456 unsigned int i; 451 unsigned int i;
457 452
458 for (i = 0; i < sizeof (GNUNET_HashCode) * 8; i++) 453 for (i = 0; i < sizeof (GNUNET_HashCode) * 8; i++)
459 if (GNUNET_CRYPTO_hash_get_bit (first, i) != GNUNET_CRYPTO_hash_get_bit (second, i)) 454 if (GNUNET_CRYPTO_hash_get_bit (first, i) !=
455 GNUNET_CRYPTO_hash_get_bit (second, i))
460 return i; 456 return i;
461 return sizeof (GNUNET_HashCode) * 8; 457 return sizeof (GNUNET_HashCode) * 8;
462} 458}
@@ -468,8 +464,7 @@ GNUNET_CRYPTO_hash_matching_bits(const GNUNET_HashCode *first,
468 * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2. 464 * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2.
469 */ 465 */
470int 466int
471GNUNET_CRYPTO_hash_cmp (const GNUNET_HashCode * h1, 467GNUNET_CRYPTO_hash_cmp (const GNUNET_HashCode * h1, const GNUNET_HashCode * h2)
472 const GNUNET_HashCode * h2)
473{ 468{
474 unsigned int *i1; 469 unsigned int *i1;
475 unsigned int *i2; 470 unsigned int *i2;
@@ -477,14 +472,13 @@ GNUNET_CRYPTO_hash_cmp (const GNUNET_HashCode * h1,
477 472
478 i1 = (unsigned int *) h1; 473 i1 = (unsigned int *) h1;
479 i2 = (unsigned int *) h2; 474 i2 = (unsigned int *) h2;
480 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0; 475 for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0; i--)
481 i--) 476 {
482 { 477 if (i1[i] > i2[i])
483 if (i1[i] > i2[i]) 478 return 1;
484 return 1; 479 if (i1[i] < i2[i])
485 if (i1[i] < i2[i]) 480 return -1;
486 return -1; 481 }
487 }
488 return 0; 482 return 0;
489} 483}
490 484
@@ -504,14 +498,14 @@ GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1,
504 unsigned int d2; 498 unsigned int d2;
505 499
506 for (i = sizeof (GNUNET_HashCode) / sizeof (unsigned int) - 1; i >= 0; i--) 500 for (i = sizeof (GNUNET_HashCode) / sizeof (unsigned int) - 1; i >= 0; i--)
507 { 501 {
508 d1 = ((unsigned int *) h1)[i] ^ ((unsigned int *) target)[i]; 502 d1 = ((unsigned int *) h1)[i] ^ ((unsigned int *) target)[i];
509 d2 = ((unsigned int *) h2)[i] ^ ((unsigned int *) target)[i]; 503 d2 = ((unsigned int *) h2)[i] ^ ((unsigned int *) target)[i];
510 if (d1 > d2) 504 if (d1 > d2)
511 return 1; 505 return 1;
512 else if (d1 < d2) 506 else if (d1 < d2)
513 return -1; 507 return -1;
514 } 508 }
515 return 0; 509 return 0;
516} 510}
517 511
@@ -525,11 +519,9 @@ GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1,
525 * @param ... pair of void * & size_t for context chunks, terminated by NULL 519 * @param ... pair of void * & size_t for context chunks, terminated by NULL
526 */ 520 */
527void 521void
528GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key, 522GNUNET_CRYPTO_hmac_derive_key (struct GNUNET_CRYPTO_AuthKey *key,
529 const struct GNUNET_CRYPTO_AesSessionKey *rkey, 523 const struct GNUNET_CRYPTO_AesSessionKey *rkey,
530 const void *salt, 524 const void *salt, size_t salt_len, ...)
531 size_t salt_len,
532 ...)
533{ 525{
534 va_list argp; 526 va_list argp;
535 527
@@ -548,18 +540,14 @@ GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key,
548 * @param argp pair of void * & size_t for context chunks, terminated by NULL 540 * @param argp pair of void * & size_t for context chunks, terminated by NULL
549 */ 541 */
550void 542void
551GNUNET_CRYPTO_hmac_derive_key_v(struct GNUNET_CRYPTO_AuthKey *key, 543GNUNET_CRYPTO_hmac_derive_key_v (struct GNUNET_CRYPTO_AuthKey *key,
552 const struct GNUNET_CRYPTO_AesSessionKey *rkey, 544 const struct GNUNET_CRYPTO_AesSessionKey *rkey,
553 const void *salt, 545 const void *salt,
554 size_t salt_len, 546 size_t salt_len, va_list argp)
555 va_list argp)
556{ 547{
557 GNUNET_CRYPTO_kdf_v (key->key, 548 GNUNET_CRYPTO_kdf_v (key->key,
558 sizeof(key->key), 549 sizeof (key->key),
559 salt, salt_len, 550 salt, salt_len, rkey->key, sizeof (rkey->key), argp);
560 rkey->key,
561 sizeof(rkey->key),
562 argp);
563} 551}
564 552
565 553
@@ -571,23 +559,22 @@ GNUNET_CRYPTO_hmac_derive_key_v(struct GNUNET_CRYPTO_AuthKey *key,
571 * @param plaintext_len length of plaintext 559 * @param plaintext_len length of plaintext
572 * @param hmac where to store the hmac 560 * @param hmac where to store the hmac
573 */ 561 */
574void 562void
575GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key, 563GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key,
576 const void *plaintext, 564 const void *plaintext,
577 size_t plaintext_len, 565 size_t plaintext_len, GNUNET_HashCode * hmac)
578 GNUNET_HashCode *hmac)
579{ 566{
580 gcry_md_hd_t md; 567 gcry_md_hd_t md;
581 const unsigned char *mc; 568 const unsigned char *mc;
582 569
583 GNUNET_assert (GPG_ERR_NO_ERROR == gcry_md_open (&md, 570 GNUNET_assert (GPG_ERR_NO_ERROR == gcry_md_open (&md,
584 GCRY_MD_SHA512, 571 GCRY_MD_SHA512,
585 GCRY_MD_FLAG_HMAC)); 572 GCRY_MD_FLAG_HMAC));
586 gcry_md_setkey (md, key->key, sizeof(key->key)); 573 gcry_md_setkey (md, key->key, sizeof (key->key));
587 gcry_md_write (md, plaintext, plaintext_len); 574 gcry_md_write (md, plaintext, plaintext_len);
588 mc = gcry_md_read (md, GCRY_MD_SHA512); 575 mc = gcry_md_read (md, GCRY_MD_SHA512);
589 if (mc != NULL) 576 if (mc != NULL)
590 memcpy (hmac->bits, mc, sizeof(hmac->bits)); 577 memcpy (hmac->bits, mc, sizeof (hmac->bits));
591 gcry_md_close (md); 578 gcry_md_close (md);
592} 579}
593 580