diff options
author | Bart Polot <bart@net.in.tum.de> | 2014-05-14 16:50:43 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2014-05-14 16:50:43 +0000 |
commit | a7522e8dee3e33942196f43efd621e4b4d0e258e (patch) | |
tree | a8e3f7f4dcefd23d6725fee2d194e8e383322144 /src/cadet/gnunet-service-cadet_tunnel.c | |
parent | 0797dbbad6ae7d6a30df984c5392c1a53d32115b (diff) | |
download | gnunet-a7522e8dee3e33942196f43efd621e4b4d0e258e.tar.gz gnunet-a7522e8dee3e33942196f43efd621e4b4d0e258e.zip |
- refactor decryption
Diffstat (limited to 'src/cadet/gnunet-service-cadet_tunnel.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_tunnel.c | 112 |
1 files changed, 86 insertions, 26 deletions
diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c index 8972849c7..a97a05737 100644 --- a/src/cadet/gnunet-service-cadet_tunnel.c +++ b/src/cadet/gnunet-service-cadet_tunnel.c | |||
@@ -620,63 +620,124 @@ t_encrypt (struct CadetTunnel *t, | |||
620 | /** | 620 | /** |
621 | * Decrypt and verify data with the appropriate tunnel key. | 621 | * Decrypt and verify data with the appropriate tunnel key. |
622 | * | 622 | * |
623 | * @param key Key to use. | ||
624 | * @param dst Destination for the plaintext. | ||
625 | * @param src Source of the encrypted data. Can overlap with @c dst. | ||
626 | * @param size Size of the encrypted data. | ||
627 | * @param iv Initialization Vector to use. | ||
628 | * | ||
629 | * @return Size of the decrypted data, -1 if an error was encountered. | ||
630 | */ | ||
631 | static int | ||
632 | decrypt (const struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
633 | void *dst, const void *src, size_t size, uint32_t iv) | ||
634 | { | ||
635 | struct GNUNET_CRYPTO_SymmetricInitializationVector siv; | ||
636 | size_t out_size; | ||
637 | |||
638 | LOG (GNUNET_ERROR_TYPE_DEBUG, " decrypt start\n"); | ||
639 | LOG (GNUNET_ERROR_TYPE_DEBUG, " decrypt iv\n"); | ||
640 | GNUNET_CRYPTO_symmetric_derive_iv (&siv, key, &iv, sizeof (iv), NULL); | ||
641 | LOG (GNUNET_ERROR_TYPE_DEBUG, " decrypt iv done\n"); | ||
642 | out_size = GNUNET_CRYPTO_symmetric_decrypt (src, size, key, &siv, dst); | ||
643 | LOG (GNUNET_ERROR_TYPE_DEBUG, " decrypt end\n"); | ||
644 | |||
645 | return out_size; | ||
646 | } | ||
647 | |||
648 | |||
649 | /** | ||
650 | * Decrypt and verify data with the most recent tunnel key. | ||
651 | * | ||
623 | * @param t Tunnel whose key to use. | 652 | * @param t Tunnel whose key to use. |
624 | * @param dst Destination for the plaintext. | 653 | * @param dst Destination for the plaintext. |
625 | * @param src Source of the encrypted data. Can overlap with @c dst. | 654 | * @param src Source of the encrypted data. Can overlap with @c dst. |
626 | * @param size Size of the encrypted data. | 655 | * @param size Size of the encrypted data. |
627 | * @param iv Initialization Vector to use. | 656 | * @param iv Initialization Vector to use. |
628 | * @param msg_hmac HMAC of the message, or NULL if message does not carry | ||
629 | * integrity verification (PING, PONG) | ||
630 | * | 657 | * |
631 | * @return Size of the decrypted data, -1 if an error was encountered. | 658 | * @return Size of the decrypted data, -1 if an error was encountered. |
632 | */ | 659 | */ |
633 | static int | 660 | static int |
634 | t_decrypt (struct CadetTunnel *t, void *dst, const void *src, | 661 | t_decrypt (struct CadetTunnel *t, void *dst, const void *src, |
635 | size_t size, uint32_t iv, const struct GNUNET_CADET_Hash *msg_hmac) | 662 | size_t size, uint32_t iv) |
636 | { | 663 | { |
637 | struct GNUNET_CRYPTO_SymmetricInitializationVector siv; | 664 | struct GNUNET_CRYPTO_SymmetricInitializationVector siv; |
638 | struct GNUNET_CRYPTO_SymmetricSessionKey *key; | 665 | struct GNUNET_CRYPTO_SymmetricSessionKey *key; |
639 | size_t out_size; | 666 | size_t out_size; |
640 | struct GNUNET_CADET_Hash hmac; | ||
641 | 667 | ||
642 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_decrypt start\n"); | 668 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_decrypt start\n"); |
643 | if (t->estate == CADET_TUNNEL3_KEY_OK || t->estate == CADET_TUNNEL3_KEY_PING) | 669 | if (t->estate == CADET_TUNNEL3_KEY_OK || t->estate == CADET_TUNNEL3_KEY_PING) |
644 | { | 670 | { |
645 | key = &t->d_key; | 671 | key = &t->d_key; |
646 | } | 672 | } |
647 | else if (NULL != t->kx_ctx) | ||
648 | { | ||
649 | key = &t->kx_ctx->d_key_old; | ||
650 | } | ||
651 | else | 673 | else |
652 | { | 674 | { |
653 | GNUNET_STATISTICS_update (stats, "# non decryptable data", 1, GNUNET_NO); | 675 | GNUNET_STATISTICS_update (stats, "# non decryptable data", 1, GNUNET_NO); |
654 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 676 | LOG (GNUNET_ERROR_TYPE_WARNING, |
655 | "WARNING got data on %s without a valid key\n", | 677 | "got data on %s without a valid key\n", |
656 | GCT_2s (t)); | 678 | GCT_2s (t)); |
657 | GCT_debug (t); | 679 | GCT_debug (t); |
658 | return -1; | 680 | return -1; |
659 | } | 681 | } |
660 | 682 | ||
683 | out_size = decrypt (key, dst, src, size, iv); | ||
684 | |||
685 | return out_size; | ||
686 | } | ||
687 | |||
688 | |||
689 | /** | ||
690 | * Decrypt and verify data with the appropriate tunnel key and verify that the | ||
691 | * data has not been altered since it was sent by the remote peer. | ||
692 | * | ||
693 | * @param t Tunnel whose key to use. | ||
694 | * @param dst Destination for the plaintext. | ||
695 | * @param src Source of the encrypted data. Can overlap with @c dst. | ||
696 | * @param size Size of the encrypted data. | ||
697 | * @param iv Initialization Vector to use. | ||
698 | * @param msg_hmac HMAC of the message, cannot be NULL. | ||
699 | * | ||
700 | * @return Size of the decrypted data, -1 if an error was encountered. | ||
701 | */ | ||
702 | static int | ||
703 | t_decrypt_and_validate (struct CadetTunnel *t, | ||
704 | void *dst, const void *src, | ||
705 | size_t size, uint32_t iv, | ||
706 | const struct GNUNET_CADET_Hash *msg_hmac) | ||
707 | { | ||
708 | struct GNUNET_CRYPTO_SymmetricSessionKey *key; | ||
709 | struct GNUNET_CADET_Hash hmac; | ||
710 | int decrypted_size; | ||
711 | |||
712 | /* Try primary (newest) key */ | ||
713 | key = &t->d_key; | ||
714 | decrypted_size = decrypt (key, dst, src, size, iv); | ||
661 | t_hmac (t, src, size, iv, GNUNET_NO, &hmac); | 715 | t_hmac (t, src, size, iv, GNUNET_NO, &hmac); |
662 | if (NULL != msg_hmac && 0 != memcmp (msg_hmac, &hmac, sizeof (hmac))) | 716 | if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac))) |
717 | return decrypted_size; | ||
718 | |||
719 | /* If no key exchange is going on, we just failed */ | ||
720 | if (NULL == t->kx_ctx) | ||
663 | { | 721 | { |
664 | /* checksum failed */ | 722 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
665 | // FIXME try other key | 723 | "Failed checksum validation on tunnel %s with no KX\n", |
666 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
667 | "Failed checksum validation for a message on tunnel `%s'\n", | ||
668 | GCT_2s (t)); | 724 | GCT_2s (t)); |
669 | GNUNET_STATISTICS_update (stats, "# wrong HMAC", 1, GNUNET_NO); | 725 | GNUNET_STATISTICS_update (stats, "# wrong HMAC", 1, GNUNET_NO); |
670 | return -1; | 726 | return -1; |
671 | } | 727 | } |
672 | 728 | ||
673 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_decrypt iv\n"); | 729 | /* Try secondary (from previous KX period) key */ |
674 | GNUNET_CRYPTO_symmetric_derive_iv (&siv, key, &iv, sizeof (iv), NULL); | 730 | key = &t->kx_ctx->d_key_old; |
675 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_decrypt iv done\n"); | 731 | decrypted_size = decrypt (key, dst, src, size, iv); |
676 | out_size = GNUNET_CRYPTO_symmetric_decrypt (src, size, key, &siv, dst); | 732 | t_hmac (t, src, size, iv, GNUNET_NO, &hmac); |
677 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_decrypt end\n"); | 733 | if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac))) |
734 | return decrypted_size; | ||
678 | 735 | ||
679 | return out_size; | 736 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
737 | "Failed checksum validation on tunnel %s with KX\n" place, | ||
738 | GCT_2s (t)); | ||
739 | GNUNET_STATISTICS_update (stats, "# wrong HMAC", 1, GNUNET_NO); | ||
740 | return -1; | ||
680 | } | 741 | } |
681 | 742 | ||
682 | 743 | ||
@@ -1627,8 +1688,7 @@ handle_ping (struct CadetTunnel *t, | |||
1627 | } | 1688 | } |
1628 | 1689 | ||
1629 | LOG (GNUNET_ERROR_TYPE_INFO, "<=== PING for %s\n", GCT_2s (t)); | 1690 | LOG (GNUNET_ERROR_TYPE_INFO, "<=== PING for %s\n", GCT_2s (t)); |
1630 | t_decrypt (t, &res.target, &msg->target, | 1691 | t_decrypt (t, &res.target, &msg->target, ping_encryption_size (), msg->iv); |
1631 | ping_encryption_size (), msg->iv, NULL); | ||
1632 | if (0 != memcmp (&my_full_id, &res.target, sizeof (my_full_id))) | 1692 | if (0 != memcmp (&my_full_id, &res.target, sizeof (my_full_id))) |
1633 | { | 1693 | { |
1634 | GNUNET_STATISTICS_update (stats, "# malformed PINGs", 1, GNUNET_NO); | 1694 | GNUNET_STATISTICS_update (stats, "# malformed PINGs", 1, GNUNET_NO); |
@@ -1666,7 +1726,7 @@ handle_pong (struct CadetTunnel *t, | |||
1666 | GNUNET_STATISTICS_update (stats, "# duplicate PONG messages", 1, GNUNET_NO); | 1726 | GNUNET_STATISTICS_update (stats, "# duplicate PONG messages", 1, GNUNET_NO); |
1667 | return; | 1727 | return; |
1668 | } | 1728 | } |
1669 | t_decrypt (t, &challenge, &msg->nonce, sizeof (uint32_t), msg->iv, NULL); | 1729 | t_decrypt (t, &challenge, &msg->nonce, sizeof (uint32_t), msg->iv); |
1670 | 1730 | ||
1671 | if (challenge != t->kx_ctx->challenge) | 1731 | if (challenge != t->kx_ctx->challenge) |
1672 | { | 1732 | { |
@@ -1775,8 +1835,8 @@ GCT_handle_encrypted (struct CadetTunnel *t, | |||
1775 | struct GNUNET_MessageHeader *msgh; | 1835 | struct GNUNET_MessageHeader *msgh; |
1776 | unsigned int off; | 1836 | unsigned int off; |
1777 | 1837 | ||
1778 | decrypted_size = t_decrypt (t, cbuf, &msg[1], payload_size, | 1838 | decrypted_size = t_decrypt_and_validate (t, cbuf, &msg[1], payload_size, |
1779 | msg->iv, &msg->hmac); | 1839 | msg->iv, &msg->hmac); |
1780 | 1840 | ||
1781 | off = 0; | 1841 | off = 0; |
1782 | while (off < decrypted_size) | 1842 | while (off < decrypted_size) |