diff options
author | Bart Polot <bart@net.in.tum.de> | 2014-06-17 12:13:42 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2014-06-17 12:13:42 +0000 |
commit | 2af3ef48e88b4c6c1d394bcf45681f94c4575a30 (patch) | |
tree | ffa29ee04fc5aa458e522e73e31346c17136fb29 /src/cadet/gnunet-service-cadet_tunnel.c | |
parent | 4e8eadf6acc2f0d1ba8ea3eddd09d3ae8df84e66 (diff) | |
download | gnunet-2af3ef48e88b4c6c1d394bcf45681f94c4575a30.tar.gz gnunet-2af3ef48e88b4c6c1d394bcf45681f94c4575a30.zip |
- refactor key selection, hmac calculation
Diffstat (limited to 'src/cadet/gnunet-service-cadet_tunnel.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_tunnel.c | 99 |
1 files changed, 59 insertions, 40 deletions
diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c index 51112c4ca..227b40f8e 100644 --- a/src/cadet/gnunet-service-cadet_tunnel.c +++ b/src/cadet/gnunet-service-cadet_tunnel.c | |||
@@ -552,37 +552,80 @@ check_ephemeral (struct CadetTunnel *t, | |||
552 | 552 | ||
553 | 553 | ||
554 | /** | 554 | /** |
555 | * Select the best key to use for encryption (send), based on KX status. | ||
556 | * | ||
557 | * Normally, return the current key. If there is a KX in progress and the old | ||
558 | * key is fresh enough, return the old key. | ||
559 | * | ||
560 | * @param t Tunnel to choose the key from. | ||
561 | * | ||
562 | * @return The optimal key to encrypt/hmac outgoing traffic. | ||
563 | */ | ||
564 | static const struct GNUNET_CRYPTO_SymmetricSessionKey * | ||
565 | select_key (const struct CadetTunnel *t) | ||
566 | { | ||
567 | const struct GNUNET_CRYPTO_SymmetricSessionKey *key; | ||
568 | |||
569 | if (NULL != t->kx_ctx | ||
570 | && GNUNET_SCHEDULER_NO_TASK == t->kx_ctx->finish_task) | ||
571 | { | ||
572 | struct GNUNET_TIME_Relative age; | ||
573 | |||
574 | age = GNUNET_TIME_absolute_get_duration (t->kx_ctx->rekey_start_time); | ||
575 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
576 | " key exchange in progress, started %s ago\n", | ||
577 | GNUNET_STRINGS_relative_time_to_string (age, GNUNET_YES)); | ||
578 | // FIXME make duration of old keys configurable | ||
579 | if (age.rel_value_us < GNUNET_TIME_UNIT_MINUTES.rel_value_us) | ||
580 | { | ||
581 | LOG (GNUNET_ERROR_TYPE_DEBUG, " using old key\n"); | ||
582 | key = &t->kx_ctx->e_key_old; | ||
583 | } | ||
584 | else | ||
585 | { | ||
586 | LOG (GNUNET_ERROR_TYPE_DEBUG, " using new key\n"); | ||
587 | key = &t->e_key; | ||
588 | } | ||
589 | } | ||
590 | else | ||
591 | { | ||
592 | key = &t->e_key; | ||
593 | } | ||
594 | return key; | ||
595 | } | ||
596 | |||
597 | |||
598 | /** | ||
555 | * Calculate HMAC. | 599 | * Calculate HMAC. |
556 | * | 600 | * |
557 | * @param t Tunnel to get keys from. | ||
558 | * @param plaintext Content to HMAC. | 601 | * @param plaintext Content to HMAC. |
559 | * @param size Size of @c plaintext. | 602 | * @param size Size of @c plaintext. |
560 | * @param iv Initialization vector for the message. | 603 | * @param iv Initialization vector for the message. |
561 | * @param outgoing Is this an outgoing message that we encrypted? | 604 | * @param key Key to use. |
562 | * @param hmac Destination to store the HMAC. | 605 | * @param hmac[out] Destination to store the HMAC. |
563 | */ | 606 | */ |
564 | static void | 607 | static void |
565 | t_hmac (struct CadetTunnel *t, const void *plaintext, size_t size, uint32_t iv, | 608 | t_hmac (const void *plaintext, size_t size, |
566 | int outgoing, struct GNUNET_CADET_Hash *hmac) | 609 | uint32_t iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *key, |
610 | struct GNUNET_CADET_Hash *hmac) | ||
567 | { | 611 | { |
568 | struct GNUNET_CRYPTO_AuthKey auth_key; | ||
569 | static const char ctx[] = "cadet authentication key"; | 612 | static const char ctx[] = "cadet authentication key"; |
570 | struct GNUNET_CRYPTO_SymmetricSessionKey *key; | 613 | struct GNUNET_CRYPTO_AuthKey auth_key; |
571 | struct GNUNET_HashCode hash; | 614 | struct GNUNET_HashCode hash; |
572 | 615 | ||
573 | key = outgoing ? &t->e_key : &t->d_key; | ||
574 | GNUNET_CRYPTO_hmac_derive_key (&auth_key, key, | 616 | GNUNET_CRYPTO_hmac_derive_key (&auth_key, key, |
575 | &iv, sizeof (iv), | 617 | &iv, sizeof (iv), |
576 | key, sizeof (*key), | 618 | key, sizeof (*key), |
577 | ctx, sizeof (ctx), | 619 | ctx, sizeof (ctx), |
578 | NULL); | 620 | NULL); |
621 | /* Two step: CADET_Hash is only 256 bits, HashCode is 512. */ | ||
579 | GNUNET_CRYPTO_hmac (&auth_key, plaintext, size, &hash); | 622 | GNUNET_CRYPTO_hmac (&auth_key, plaintext, size, &hash); |
580 | memcpy (hmac, &hash, sizeof (*hmac)); | 623 | memcpy (hmac, &hash, sizeof (*hmac)); |
581 | } | 624 | } |
582 | 625 | ||
583 | 626 | ||
584 | /** | 627 | /** |
585 | * Encrypt data with the tunnel key. | 628 | * Encrypt daforce_newest_keyta with the tunnel key. |
586 | * | 629 | * |
587 | * @param t Tunnel whose key to use. | 630 | * @param t Tunnel whose key to use. |
588 | * @param dst Destination for the encrypted data. | 631 | * @param dst Destination for the encrypted data. |
@@ -599,39 +642,15 @@ t_encrypt (struct CadetTunnel *t, void *dst, const void *src, | |||
599 | size_t size, uint32_t iv, int force_newest_key) | 642 | size_t size, uint32_t iv, int force_newest_key) |
600 | { | 643 | { |
601 | struct GNUNET_CRYPTO_SymmetricInitializationVector siv; | 644 | struct GNUNET_CRYPTO_SymmetricInitializationVector siv; |
602 | struct GNUNET_CRYPTO_SymmetricSessionKey *e_key; | 645 | const struct GNUNET_CRYPTO_SymmetricSessionKey *key; |
603 | size_t out_size; | 646 | size_t out_size; |
604 | 647 | ||
605 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_encrypt start\n"); | 648 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_encrypt start\n"); |
606 | if (GNUNET_NO == force_newest_key | ||
607 | && NULL != t->kx_ctx | ||
608 | && GNUNET_SCHEDULER_NO_TASK == t->kx_ctx->finish_task) | ||
609 | { | ||
610 | struct GNUNET_TIME_Relative age; | ||
611 | 649 | ||
612 | age = GNUNET_TIME_absolute_get_duration (t->kx_ctx->rekey_start_time); | 650 | key = GNUNET_YES == force_newest_key ? &t->e_key : select_key (t); |
613 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 651 | GNUNET_CRYPTO_symmetric_derive_iv (&siv, key, &iv, sizeof (iv), NULL); |
614 | " key exchange in progress, started %s ago\n", | ||
615 | GNUNET_STRINGS_relative_time_to_string (age, GNUNET_YES)); | ||
616 | // FIXME make duration of old keys configurable | ||
617 | if (age.rel_value_us < GNUNET_TIME_UNIT_MINUTES.rel_value_us) | ||
618 | { | ||
619 | LOG (GNUNET_ERROR_TYPE_DEBUG, " using old key\n"); | ||
620 | e_key = &t->kx_ctx->e_key_old; | ||
621 | } | ||
622 | else | ||
623 | { | ||
624 | LOG (GNUNET_ERROR_TYPE_DEBUG, " using new key\n"); | ||
625 | e_key = &t->e_key; | ||
626 | } | ||
627 | } | ||
628 | else | ||
629 | { | ||
630 | e_key = &t->e_key; | ||
631 | } | ||
632 | GNUNET_CRYPTO_symmetric_derive_iv (&siv, e_key, &iv, sizeof (iv), NULL); | ||
633 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_encrypt IV derived\n"); | 652 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_encrypt IV derived\n"); |
634 | out_size = GNUNET_CRYPTO_symmetric_encrypt (src, size, e_key, &siv, dst); | 653 | out_size = GNUNET_CRYPTO_symmetric_encrypt (src, size, key, &siv, dst); |
635 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_encrypt end\n"); | 654 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_encrypt end\n"); |
636 | 655 | ||
637 | return out_size; | 656 | return out_size; |
@@ -730,7 +749,7 @@ t_decrypt_and_validate (struct CadetTunnel *t, | |||
730 | /* Try primary (newest) key */ | 749 | /* Try primary (newest) key */ |
731 | key = &t->d_key; | 750 | key = &t->d_key; |
732 | decrypted_size = decrypt (key, dst, src, size, iv); | 751 | decrypted_size = decrypt (key, dst, src, size, iv); |
733 | t_hmac (t, src, size, iv, GNUNET_NO, &hmac); | 752 | t_hmac (src, size, iv, key, &hmac); |
734 | if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac))) | 753 | if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac))) |
735 | return decrypted_size; | 754 | return decrypted_size; |
736 | 755 | ||
@@ -747,7 +766,7 @@ t_decrypt_and_validate (struct CadetTunnel *t, | |||
747 | /* Try secondary (from previous KX period) key */ | 766 | /* Try secondary (from previous KX period) key */ |
748 | key = &t->kx_ctx->d_key_old; | 767 | key = &t->kx_ctx->d_key_old; |
749 | decrypted_size = decrypt (key, dst, src, size, iv); | 768 | decrypted_size = decrypt (key, dst, src, size, iv); |
750 | t_hmac (t, src, size, iv, GNUNET_NO, &hmac); | 769 | t_hmac (src, size, iv, key, &hmac); |
751 | if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac))) | 770 | if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac))) |
752 | return decrypted_size; | 771 | return decrypted_size; |
753 | 772 | ||
@@ -1013,7 +1032,7 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message, | |||
1013 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED); | 1032 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED); |
1014 | msg->iv = iv; | 1033 | msg->iv = iv; |
1015 | GNUNET_assert (t_encrypt (t, &msg[1], message, size, iv, GNUNET_NO) == size); | 1034 | GNUNET_assert (t_encrypt (t, &msg[1], message, size, iv, GNUNET_NO) == size); |
1016 | t_hmac (t, &msg[1], size, iv, GNUNET_YES, &msg->hmac); | 1035 | t_hmac (&msg[1], size, iv, select_key (t), &msg->hmac); |
1017 | msg->header.size = htons (sizeof (struct GNUNET_CADET_Encrypted) + size); | 1036 | msg->header.size = htons (sizeof (struct GNUNET_CADET_Encrypted) + size); |
1018 | 1037 | ||
1019 | if (NULL == c) | 1038 | if (NULL == c) |