aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_tunnel.c
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2014-05-14 16:50:43 +0000
committerBart Polot <bart@net.in.tum.de>2014-05-14 16:50:43 +0000
commita7522e8dee3e33942196f43efd621e4b4d0e258e (patch)
treea8e3f7f4dcefd23d6725fee2d194e8e383322144 /src/cadet/gnunet-service-cadet_tunnel.c
parent0797dbbad6ae7d6a30df984c5392c1a53d32115b (diff)
downloadgnunet-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.c112
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 */
631static int
632decrypt (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 */
633static int 660static int
634t_decrypt (struct CadetTunnel *t, void *dst, const void *src, 661t_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 */
702static int
703t_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)