aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cadet/gnunet-service-cadet_tunnel.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c
index 9740e41d9..3a826a98c 100644
--- a/src/cadet/gnunet-service-cadet_tunnel.c
+++ b/src/cadet/gnunet-service-cadet_tunnel.c
@@ -104,7 +104,22 @@ struct CadetTunnelKXCtx
104 struct GNUNET_CRYPTO_SymmetricSessionKey d_key_old; 104 struct GNUNET_CRYPTO_SymmetricSessionKey d_key_old;
105 105
106 /** 106 /**
107 * Challenge to send in a ping and expect in the pong. 107 * Same as @c e_key_old, for the case of two simultaneous KX.
108 * This can happen if cadet decides to start a re-key while the peer has also
109 * started its re-key (due to network delay this is impossible to avoid).
110 * In this case, the key material generated with the peer's old ephemeral
111 * *might* (but doesn't have to) be incorrect.
112 * Since no more than two re-keys can happen simultaneously, this is enough.
113 */
114 struct GNUNET_CRYPTO_SymmetricSessionKey e_key_old2;
115
116 /**
117 * Same as @c d_key_old, for the case described in @c e_key_old2.
118 */
119 struct GNUNET_CRYPTO_SymmetricSessionKey d_key_old2;
120
121 /**
122 * Challenge to send and expect in the PONG.
108 */ 123 */
109 uint32_t challenge; 124 uint32_t challenge;
110 125
@@ -799,27 +814,34 @@ t_decrypt_and_validate (struct CadetTunnel *t,
799 if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac))) 814 if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac)))
800 return decrypted_size; 815 return decrypted_size;
801 816
802 /* If no key exchange is going on, we just failed */ 817 /* If no key exchange is going on, we just failed. */
803 if (NULL == t->kx_ctx) 818 if (NULL == t->kx_ctx)
804 { 819 {
805 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 820 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
806 "Failed checksum validation on tunnel %s with no KX\n", 821 "Failed checksum validation on tunnel %s with no KX\n",
807 GCT_2s (t)); 822 GCT_2s (t));
808 GNUNET_STATISTICS_update (stats, "# wrong HMAC", 1, GNUNET_NO); 823 GNUNET_STATISTICS_update (stats, "# wrong HMAC no KX", 1, GNUNET_NO);
809 return -1; 824 return -1;
810 } 825 }
811 826
812 /* Try secondary (from previous KX period) key */ 827 /* Try secondary key, from previous KX period. */
813 key = &t->kx_ctx->d_key_old; 828 key = &t->kx_ctx->d_key_old;
814 decrypted_size = decrypt (key, dst, src, size, iv); 829 decrypted_size = decrypt (key, dst, src, size, iv);
815 t_hmac (src, size, iv, key, &hmac); 830 t_hmac (src, size, iv, key, &hmac);
816 if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac))) 831 if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac)))
817 return decrypted_size; 832 return decrypted_size;
818 833
819 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 834 /* Hail Mary, try tertiary, key, in case of parallel re-keys. */
835 key = &t->kx_ctx->d_key_old2;
836 decrypted_size = decrypt (key, dst, src, size, iv);
837 t_hmac (src, size, iv, key, &hmac);
838 if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac)))
839 return decrypted_size;
840
841 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
820 "Failed checksum validation on tunnel %s with KX\n", 842 "Failed checksum validation on tunnel %s with KX\n",
821 GCT_2s (t)); 843 GCT_2s (t));
822 GNUNET_STATISTICS_update (stats, "# wrong HMAC", 1, GNUNET_NO); 844 GNUNET_STATISTICS_update (stats, "# wrong HMAC with KX", 1, GNUNET_NO);
823 return -1; 845 return -1;
824} 846}
825 847