aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-17 14:20:59 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-17 14:20:59 +0100
commit23c86a4ca5d1cd879550cd07afed4869475fb765 (patch)
treea8eace7b55bcbf3545e1590c7868f52b6b6dfeb4 /src
parent500842f42c4e51c4c5fc3c1cdfc1c1f7166b2d0d (diff)
downloadgnunet-23c86a4ca5d1cd879550cd07afed4869475fb765.tar.gz
gnunet-23c86a4ca5d1cd879550cd07afed4869475fb765.zip
importing KX logic, integrating encryption logic
Diffstat (limited to 'src')
-rw-r--r--src/cadet/gnunet-service-cadet-new.c35
-rw-r--r--src/cadet/gnunet-service-cadet-new.h15
-rw-r--r--src/cadet/gnunet-service-cadet-new_connection.c24
-rw-r--r--src/cadet/gnunet-service-cadet-new_connection.h12
-rw-r--r--src/cadet/gnunet-service-cadet-new_tunnels.c689
5 files changed, 763 insertions, 12 deletions
diff --git a/src/cadet/gnunet-service-cadet-new.c b/src/cadet/gnunet-service-cadet-new.c
index b2f39b3cd..3bb7d9cdf 100644
--- a/src/cadet/gnunet-service-cadet-new.c
+++ b/src/cadet/gnunet-service-cadet-new.c
@@ -175,6 +175,16 @@ struct GNUNET_CONTAINER_MultiPeerMap *peers;
175 */ 175 */
176struct GNUNET_CONTAINER_MultiHashMap *connections; 176struct GNUNET_CONTAINER_MultiHashMap *connections;
177 177
178/**
179 * How many messages are needed to trigger an AXOLOTL ratchet advance.
180 */
181unsigned long long ratchet_messages;
182
183/**
184 * How long until we trigger a ratched advance due to time.
185 */
186struct GNUNET_TIME_Relative ratchet_time;
187
178 188
179 189
180/** 190/**
@@ -1221,6 +1231,31 @@ run (void *cls,
1221 const struct GNUNET_CONFIGURATION_Handle *c, 1231 const struct GNUNET_CONFIGURATION_Handle *c,
1222 struct GNUNET_SERVICE_Handle *service) 1232 struct GNUNET_SERVICE_Handle *service)
1223{ 1233{
1234 if (GNUNET_OK !=
1235 GNUNET_CONFIGURATION_get_value_number (c,
1236 "CADET",
1237 "RATCHET_MESSAGES",
1238 &ratchet_messages))
1239 {
1240 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1241 "CADET",
1242 "RATCHET_MESSAGES",
1243 "needs to be a number");
1244 ratchet_messages = 64;
1245 }
1246 if (GNUNET_OK !=
1247 GNUNET_CONFIGURATION_get_value_time (c,
1248 "CADET",
1249 "RATCHET_TIME",
1250 &ratchet_time))
1251 {
1252 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1253 "CADET",
1254 "RATCHET_TIME",
1255 "need delay value");
1256 ratchet_time = GNUNET_TIME_UNIT_HOURS;
1257 }
1258
1224 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c); 1259 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c);
1225 if (NULL == my_private_key) 1260 if (NULL == my_private_key)
1226 { 1261 {
diff --git a/src/cadet/gnunet-service-cadet-new.h b/src/cadet/gnunet-service-cadet-new.h
index 416c9d13a..903ceed94 100644
--- a/src/cadet/gnunet-service-cadet-new.h
+++ b/src/cadet/gnunet-service-cadet-new.h
@@ -101,6 +101,10 @@ struct CadetPeerPathEntry
101 101
102}; 102};
103 103
104/**
105 * Entry in list of connections used by tunnel, with metadata.
106 */
107struct CadetTConnection;
104 108
105/** 109/**
106 * Active path through the network (used by a tunnel). There may 110 * Active path through the network (used by a tunnel). There may
@@ -156,6 +160,17 @@ extern struct GNUNET_CONTAINER_MultiHashMap *loose_channels;
156 */ 160 */
157extern struct GNUNET_CONTAINER_MultiPeerMap *peers; 161extern struct GNUNET_CONTAINER_MultiPeerMap *peers;
158 162
163/**
164 * How many messages are needed to trigger an AXOLOTL ratchet advance.
165 */
166extern unsigned long long ratchet_messages;
167
168/**
169 * How long until we trigger a ratched advance due to time.
170 */
171extern struct GNUNET_TIME_Relative ratchet_time;
172
173
159 174
160/** 175/**
161 * Send a message to a client. 176 * Send a message to a client.
diff --git a/src/cadet/gnunet-service-cadet-new_connection.c b/src/cadet/gnunet-service-cadet-new_connection.c
index 1f31331a5..6a9c210b8 100644
--- a/src/cadet/gnunet-service-cadet-new_connection.c
+++ b/src/cadet/gnunet-service-cadet-new_connection.c
@@ -21,7 +21,8 @@
21 21
22/** 22/**
23 * @file cadet/gnunet-service-cadet-new_connection.c 23 * @file cadet/gnunet-service-cadet-new_connection.c
24 * @brief 24 * @brief management of CORE-level end-to-end connections; establishes
25 * end-to-end routes and transmits messages along the route
25 * @author Bartlomiej Polot 26 * @author Bartlomiej Polot
26 * @author Christian Grothoff 27 * @author Christian Grothoff
27 */ 28 */
@@ -88,6 +89,11 @@ struct CadetConnection
88 struct CadetPeer *destination; 89 struct CadetPeer *destination;
89 90
90 /** 91 /**
92 * Which tunnel is using this connection?
93 */
94 struct CadetTConnection *ct;
95
96 /**
91 * Path we are using to our destination. 97 * Path we are using to our destination.
92 */ 98 */
93 struct CadetPeerPath *path; 99 struct CadetPeerPath *path;
@@ -231,6 +237,19 @@ GCC_get_h (const struct CadetConnection *cc)
231 237
232 238
233/** 239/**
240 * Return the tunnel associated with this connection.
241 *
242 * @param cc connection to query
243 * @return corresponding entry in the tunnel's connection list
244 */
245struct CadetTConnection *
246GCC_get_ct (struct CadetConnection *cc)
247{
248 return cc->ct;
249}
250
251
252/**
234 * An ACK was received for this connection, process it. 253 * An ACK was received for this connection, process it.
235 * 254 *
236 * @param cc the connection that got the ACK. 255 * @param cc the connection that got the ACK.
@@ -355,6 +374,7 @@ manage_first_hop_mq (void *cls,
355 * 374 *
356 * @param destination where to go 375 * @param destination where to go
357 * @param path which path to take (may not be the full path) 376 * @param path which path to take (may not be the full path)
377 * @param ct tunnel that uses the connection
358 * @param ready_cb function to call when ready to transmit 378 * @param ready_cb function to call when ready to transmit
359 * @param ready_cb_cls closure for @a cb 379 * @param ready_cb_cls closure for @a cb
360 * @return handle to the connection 380 * @return handle to the connection
@@ -362,6 +382,7 @@ manage_first_hop_mq (void *cls,
362struct CadetConnection * 382struct CadetConnection *
363GCC_create (struct CadetPeer *destination, 383GCC_create (struct CadetPeer *destination,
364 struct CadetPeerPath *path, 384 struct CadetPeerPath *path,
385 struct CadetTConnection *ct,
365 GNUNET_SCHEDULER_TaskCallback ready_cb, 386 GNUNET_SCHEDULER_TaskCallback ready_cb,
366 void *ready_cb_cls) 387 void *ready_cb_cls)
367{ 388{
@@ -373,6 +394,7 @@ GCC_create (struct CadetPeer *destination,
373 destination); 394 destination);
374 GNUNET_assert (UINT_MAX > off); 395 GNUNET_assert (UINT_MAX > off);
375 cc = GNUNET_new (struct CadetConnection); 396 cc = GNUNET_new (struct CadetConnection);
397 cc->ct = ct;
376 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, 398 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
377 &cc->cid, 399 &cc->cid,
378 sizeof (cc->cid)); 400 sizeof (cc->cid));
diff --git a/src/cadet/gnunet-service-cadet-new_connection.h b/src/cadet/gnunet-service-cadet-new_connection.h
index c9738d86e..66d19ae0c 100644
--- a/src/cadet/gnunet-service-cadet-new_connection.h
+++ b/src/cadet/gnunet-service-cadet-new_connection.h
@@ -58,6 +58,7 @@ GCC_destroy (struct CadetConnection *cc);
58 * 58 *
59 * @param destination where to go 59 * @param destination where to go
60 * @param path which path to take (may not be the full path) 60 * @param path which path to take (may not be the full path)
61 * @param ct which tunnel uses this connection
61 * @param ready_cb function to call when ready to transmit 62 * @param ready_cb function to call when ready to transmit
62 * @param ready_cb_cls closure for @a cb 63 * @param ready_cb_cls closure for @a cb
63 * @return handle to the connection 64 * @return handle to the connection
@@ -65,6 +66,7 @@ GCC_destroy (struct CadetConnection *cc);
65struct CadetConnection * 66struct CadetConnection *
66GCC_create (struct CadetPeer *destination, 67GCC_create (struct CadetPeer *destination,
67 struct CadetPeerPath *path, 68 struct CadetPeerPath *path,
69 struct CadetTConnection *ct,
68 GNUNET_SCHEDULER_TaskCallback ready_cb, 70 GNUNET_SCHEDULER_TaskCallback ready_cb,
69 void *ready_cb_cls); 71 void *ready_cb_cls);
70 72
@@ -87,6 +89,16 @@ GCC_transmit (struct CadetConnection *cc,
87 89
88 90
89/** 91/**
92 * Return the tunnel associated with this connection.
93 *
94 * @param cc connection to query
95 * @return corresponding entry in the tunnel's connection list
96 */
97struct CadetTConnection *
98GCC_get_ct (struct CadetConnection *cc);
99
100
101/**
90 * Obtain the path used by this connection. 102 * Obtain the path used by this connection.
91 * 103 *
92 * @param cc connection 104 * @param cc connection
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c
index 18c469b67..b5a4e0112 100644
--- a/src/cadet/gnunet-service-cadet-new_tunnels.c
+++ b/src/cadet/gnunet-service-cadet-new_tunnels.c
@@ -29,6 +29,7 @@
29 * - when managing connections, distinguish those that 29 * - when managing connections, distinguish those that
30 * have (recently) had traffic from those that were 30 * have (recently) had traffic from those that were
31 * never ready (or not recently) 31 * never ready (or not recently)
32 * - clean up KX logic!
32 */ 33 */
33#include "platform.h" 34#include "platform.h"
34#include "gnunet_util_lib.h" 35#include "gnunet_util_lib.h"
@@ -43,11 +44,33 @@
43#include "gnunet-service-cadet-new_paths.h" 44#include "gnunet-service-cadet-new_paths.h"
44 45
45 46
47#define LOG(level, ...) GNUNET_log_from(level,"cadet-tun",__VA_ARGS__)
48
49
46/** 50/**
47 * How long do we wait until tearing down an idle tunnel? 51 * How long do we wait until tearing down an idle tunnel?
48 */ 52 */
49#define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90) 53#define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90)
50 54
55/**
56 * Yuck, replace by 'offsetof' expression?
57 * FIXME.
58 */
59#define AX_HEADER_SIZE (sizeof (uint32_t) * 2\
60 + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey))
61
62
63/**
64 * Maximum number of skipped keys we keep in memory per tunnel.
65 */
66#define MAX_SKIPPED_KEYS 64
67
68/**
69 * Maximum number of keys (and thus ratchet steps) we are willing to
70 * skip before we decide this is either a bogus packet or a DoS-attempt.
71 */
72#define MAX_KEY_GAP 256
73
51 74
52/** 75/**
53 * Struct to old keys for skipped messages while advancing the Axolotl ratchet. 76 * Struct to old keys for skipped messages while advancing the Axolotl ratchet.
@@ -271,6 +294,12 @@ struct CadetTunnelQueueEntry
271 * Envelope of message to send follows. 294 * Envelope of message to send follows.
272 */ 295 */
273 struct GNUNET_MQ_Envelope *env; 296 struct GNUNET_MQ_Envelope *env;
297
298 /**
299 * Where to put the connection identifier into the payload
300 * of the message in @e env once we have it?
301 */
302 struct GNUNET_CADET_ConnectionTunnelIdentifier *cid;
274}; 303};
275 304
276 305
@@ -476,6 +505,619 @@ GCT_get_estate (struct CadetTunnel *t)
476 505
477 506
478/** 507/**
508 * Create a new Axolotl ephemeral (ratchet) key.
509 *
510 * @param t Tunnel.
511 */
512static void
513new_ephemeral (struct CadetTunnel *t)
514{
515 GNUNET_free_non_null (t->ax.DHRs);
516 t->ax.DHRs = GNUNET_CRYPTO_ecdhe_key_create ();
517}
518
519
520/* ************************************** start core crypto ***************************** */
521
522
523/**
524 * Calculate HMAC.
525 *
526 * @param plaintext Content to HMAC.
527 * @param size Size of @c plaintext.
528 * @param iv Initialization vector for the message.
529 * @param key Key to use.
530 * @param hmac[out] Destination to store the HMAC.
531 */
532static void
533t_hmac (const void *plaintext,
534 size_t size,
535 uint32_t iv,
536 const struct GNUNET_CRYPTO_SymmetricSessionKey *key,
537 struct GNUNET_CADET_Hash *hmac)
538{
539 static const char ctx[] = "cadet authentication key";
540 struct GNUNET_CRYPTO_AuthKey auth_key;
541 struct GNUNET_HashCode hash;
542
543 GNUNET_CRYPTO_hmac_derive_key (&auth_key,
544 key,
545 &iv, sizeof (iv),
546 key, sizeof (*key),
547 ctx, sizeof (ctx),
548 NULL);
549 /* Two step: CADET_Hash is only 256 bits, HashCode is 512. */
550 GNUNET_CRYPTO_hmac (&auth_key,
551 plaintext,
552 size,
553 &hash);
554 GNUNET_memcpy (hmac,
555 &hash,
556 sizeof (*hmac));
557}
558
559
560/**
561 * Perform a HMAC.
562 *
563 * @param key Key to use.
564 * @param hash[out] Resulting HMAC.
565 * @param source Source key material (data to HMAC).
566 * @param len Length of @a source.
567 */
568static void
569t_ax_hmac_hash (const struct GNUNET_CRYPTO_SymmetricSessionKey *key,
570 struct GNUNET_HashCode *hash,
571 const void *source,
572 unsigned int len)
573{
574 static const char ctx[] = "axolotl HMAC-HASH";
575 struct GNUNET_CRYPTO_AuthKey auth_key;
576
577 GNUNET_CRYPTO_hmac_derive_key (&auth_key,
578 key,
579 ctx, sizeof (ctx),
580 NULL);
581 GNUNET_CRYPTO_hmac (&auth_key,
582 source,
583 len,
584 hash);
585}
586
587
588/**
589 * Derive a symmetric encryption key from an HMAC-HASH.
590 *
591 * @param key Key to use for the HMAC.
592 * @param[out] out Key to generate.
593 * @param source Source key material (data to HMAC).
594 * @param len Length of @a source.
595 */
596static void
597t_hmac_derive_key (const struct GNUNET_CRYPTO_SymmetricSessionKey *key,
598 struct GNUNET_CRYPTO_SymmetricSessionKey *out,
599 const void *source,
600 unsigned int len)
601{
602 static const char ctx[] = "axolotl derive key";
603 struct GNUNET_HashCode h;
604
605 t_ax_hmac_hash (key,
606 &h,
607 source,
608 len);
609 GNUNET_CRYPTO_kdf (out, sizeof (*out),
610 ctx, sizeof (ctx),
611 &h, sizeof (h),
612 NULL);
613}
614
615
616/**
617 * Encrypt data with the axolotl tunnel key.
618 *
619 * @param t Tunnel whose key to use.
620 * @param dst Destination with @a size bytes for the encrypted data.
621 * @param src Source of the plaintext. Can overlap with @c dst, must contain @a size bytes
622 * @param size Size of the buffers at @a src and @a dst
623 */
624static void
625t_ax_encrypt (struct CadetTunnel *t,
626 void *dst,
627 const void *src,
628 size_t size)
629{
630 struct GNUNET_CRYPTO_SymmetricSessionKey MK;
631 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
632 struct CadetTunnelAxolotl *ax;
633 size_t out_size;
634
635 ax = &t->ax;
636 ax->ratchet_counter++;
637 if ( (GNUNET_YES == ax->ratchet_allowed) &&
638 ( (ratchet_messages <= ax->ratchet_counter) ||
639 (0 == GNUNET_TIME_absolute_get_remaining (ax->ratchet_expiration).rel_value_us)) )
640 {
641 ax->ratchet_flag = GNUNET_YES;
642 }
643 if (GNUNET_YES == ax->ratchet_flag)
644 {
645 /* Advance ratchet */
646 struct GNUNET_CRYPTO_SymmetricSessionKey keys[3];
647 struct GNUNET_HashCode dh;
648 struct GNUNET_HashCode hmac;
649 static const char ctx[] = "axolotl ratchet";
650
651 new_ephemeral (t);
652 ax->HKs = ax->NHKs;
653
654 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
655 GNUNET_CRYPTO_ecc_ecdh (ax->DHRs,
656 &ax->DHRr,
657 &dh);
658 t_ax_hmac_hash (&ax->RK,
659 &hmac,
660 &dh,
661 sizeof (dh));
662 GNUNET_CRYPTO_kdf (keys, sizeof (keys),
663 ctx, sizeof (ctx),
664 &hmac, sizeof (hmac),
665 NULL);
666 ax->RK = keys[0];
667 ax->NHKs = keys[1];
668 ax->CKs = keys[2];
669
670 ax->PNs = ax->Ns;
671 ax->Ns = 0;
672 ax->ratchet_flag = GNUNET_NO;
673 ax->ratchet_allowed = GNUNET_NO;
674 ax->ratchet_counter = 0;
675 ax->ratchet_expiration
676 = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
677 ratchet_time);
678 }
679
680 t_hmac_derive_key (&ax->CKs,
681 &MK,
682 "0",
683 1);
684 GNUNET_CRYPTO_symmetric_derive_iv (&iv,
685 &MK,
686 NULL, 0,
687 NULL);
688
689 out_size = GNUNET_CRYPTO_symmetric_encrypt (src,
690 size,
691 &MK,
692 &iv,
693 dst);
694 GNUNET_assert (size == out_size);
695 t_hmac_derive_key (&ax->CKs,
696 &ax->CKs,
697 "1",
698 1);
699}
700
701
702/**
703 * Decrypt data with the axolotl tunnel key.
704 *
705 * @param t Tunnel whose key to use.
706 * @param dst Destination for the decrypted data, must contain @a size bytes.
707 * @param src Source of the ciphertext. Can overlap with @c dst, must contain @a size bytes.
708 * @param size Size of the @a src and @a dst buffers
709 */
710static void
711t_ax_decrypt (struct CadetTunnel *t,
712 void *dst,
713 const void *src,
714 size_t size)
715{
716 struct GNUNET_CRYPTO_SymmetricSessionKey MK;
717 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
718 struct CadetTunnelAxolotl *ax;
719 size_t out_size;
720
721 ax = &t->ax;
722 t_hmac_derive_key (&ax->CKr,
723 &MK,
724 "0",
725 1);
726 GNUNET_CRYPTO_symmetric_derive_iv (&iv,
727 &MK,
728 NULL, 0,
729 NULL);
730 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
731 out_size = GNUNET_CRYPTO_symmetric_decrypt (src,
732 size,
733 &MK,
734 &iv,
735 dst);
736 GNUNET_assert (out_size == size);
737 t_hmac_derive_key (&ax->CKr,
738 &ax->CKr,
739 "1",
740 1);
741}
742
743
744/**
745 * Encrypt header with the axolotl header key.
746 *
747 * @param t Tunnel whose key to use.
748 * @param msg Message whose header to encrypt.
749 */
750static void
751t_h_encrypt (struct CadetTunnel *t,
752 struct GNUNET_CADET_Encrypted *msg)
753{
754 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
755 struct CadetTunnelAxolotl *ax;
756 size_t out_size;
757
758 ax = &t->ax;
759 GNUNET_CRYPTO_symmetric_derive_iv (&iv,
760 &ax->HKs,
761 NULL, 0,
762 NULL);
763 out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->Ns,
764 AX_HEADER_SIZE,
765 &ax->HKs,
766 &iv,
767 &msg->Ns);
768 GNUNET_assert (AX_HEADER_SIZE == out_size);
769}
770
771
772/**
773 * Decrypt header with the current axolotl header key.
774 *
775 * @param t Tunnel whose current ax HK to use.
776 * @param src Message whose header to decrypt.
777 * @param dst Where to decrypt header to.
778 */
779static void
780t_h_decrypt (struct CadetTunnel *t,
781 const struct GNUNET_CADET_Encrypted *src,
782 struct GNUNET_CADET_Encrypted *dst)
783{
784 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
785 struct CadetTunnelAxolotl *ax;
786 size_t out_size;
787
788 ax = &t->ax;
789 GNUNET_CRYPTO_symmetric_derive_iv (&iv,
790 &ax->HKr,
791 NULL, 0,
792 NULL);
793 out_size = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns,
794 AX_HEADER_SIZE,
795 &ax->HKr,
796 &iv,
797 &dst->Ns);
798 GNUNET_assert (AX_HEADER_SIZE == out_size);
799}
800
801
802/**
803 * Delete a key from the list of skipped keys.
804 *
805 * @param t Tunnel to delete from.
806 * @param key Key to delete.
807 */
808static void
809delete_skipped_key (struct CadetTunnel *t,
810 struct CadetTunnelSkippedKey *key)
811{
812 GNUNET_CONTAINER_DLL_remove (t->ax.skipped_head,
813 t->ax.skipped_tail,
814 key);
815 GNUNET_free (key);
816 t->ax.skipped--;
817}
818
819
820/**
821 * Decrypt and verify data with the appropriate tunnel key and verify that the
822 * data has not been altered since it was sent by the remote peer.
823 *
824 * @param t Tunnel whose key to use.
825 * @param dst Destination for the plaintext.
826 * @param src Source of the message. Can overlap with @c dst.
827 * @param size Size of the message.
828 * @return Size of the decrypted data, -1 if an error was encountered.
829 */
830static ssize_t
831try_old_ax_keys (struct CadetTunnel *t,
832 void *dst,
833 const struct GNUNET_CADET_Encrypted *src,
834 size_t size)
835{
836 struct CadetTunnelSkippedKey *key;
837 struct GNUNET_CADET_Hash *hmac;
838 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
839 struct GNUNET_CADET_Encrypted plaintext_header;
840 struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
841 size_t esize;
842 size_t res;
843 size_t len;
844 unsigned int N;
845
846 LOG (GNUNET_ERROR_TYPE_DEBUG,
847 "Trying skipped keys\n");
848 hmac = &plaintext_header.hmac;
849 esize = size - sizeof (struct GNUNET_CADET_Encrypted);
850
851 /* Find a correct Header Key */
852 valid_HK = NULL;
853 for (key = t->ax.skipped_head; NULL != key; key = key->next)
854 {
855 t_hmac (&src->Ns,
856 AX_HEADER_SIZE + esize,
857 0,
858 &key->HK,
859 hmac);
860 if (0 == memcmp (hmac,
861 &src->hmac,
862 sizeof (*hmac)))
863 {
864 valid_HK = &key->HK;
865 break;
866 }
867 }
868 if (NULL == key)
869 return -1;
870
871 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
872 GNUNET_assert (size > sizeof (struct GNUNET_CADET_Encrypted));
873 len = size - sizeof (struct GNUNET_CADET_Encrypted);
874 GNUNET_assert (len >= sizeof (struct GNUNET_MessageHeader));
875
876 /* Decrypt header */
877 GNUNET_CRYPTO_symmetric_derive_iv (&iv,
878 &key->HK,
879 NULL, 0,
880 NULL);
881 res = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns,
882 AX_HEADER_SIZE,
883 &key->HK,
884 &iv,
885 &plaintext_header.Ns);
886 GNUNET_assert (AX_HEADER_SIZE == res);
887
888 /* Find the correct message key */
889 N = ntohl (plaintext_header.Ns);
890 while ( (NULL != key) &&
891 (N != key->Kn) )
892 key = key->next;
893 if ( (NULL == key) ||
894 (0 != memcmp (&key->HK,
895 valid_HK,
896 sizeof (*valid_HK))) )
897 return -1;
898
899 /* Decrypt payload */
900 GNUNET_CRYPTO_symmetric_derive_iv (&iv,
901 &key->MK,
902 NULL,
903 0,
904 NULL);
905 res = GNUNET_CRYPTO_symmetric_decrypt (&src[1],
906 len,
907 &key->MK,
908 &iv,
909 dst);
910 delete_skipped_key (t,
911 key);
912 return res;
913}
914
915
916/**
917 * Delete a key from the list of skipped keys.
918 *
919 * @param t Tunnel to delete from.
920 * @param HKr Header Key to use.
921 */
922static void
923store_skipped_key (struct CadetTunnel *t,
924 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
925{
926 struct CadetTunnelSkippedKey *key;
927
928 key = GNUNET_new (struct CadetTunnelSkippedKey);
929 key->timestamp = GNUNET_TIME_absolute_get ();
930 key->Kn = t->ax.Nr;
931 key->HK = t->ax.HKr;
932 t_hmac_derive_key (&t->ax.CKr,
933 &key->MK,
934 "0",
935 1);
936 t_hmac_derive_key (&t->ax.CKr,
937 &t->ax.CKr,
938 "1",
939 1);
940 GNUNET_CONTAINER_DLL_insert (t->ax.skipped_head,
941 t->ax.skipped_tail,
942 key);
943 t->ax.skipped++;
944 t->ax.Nr++;
945}
946
947
948/**
949 * Stage skipped AX keys and calculate the message key.
950 * Stores each HK and MK for skipped messages.
951 *
952 * @param t Tunnel where to stage the keys.
953 * @param HKr Header key.
954 * @param Np Received meesage number.
955 * @return #GNUNET_OK if keys were stored.
956 * #GNUNET_SYSERR if an error ocurred (Np not expected).
957 */
958static int
959store_ax_keys (struct CadetTunnel *t,
960 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr,
961 uint32_t Np)
962{
963 int gap;
964
965 gap = Np - t->ax.Nr;
966 LOG (GNUNET_ERROR_TYPE_DEBUG,
967 "Storing skipped keys [%u, %u)\n",
968 t->ax.Nr,
969 Np);
970 if (MAX_KEY_GAP < gap)
971 {
972 /* Avoid DoS (forcing peer to do 2^33 chain HMAC operations) */
973 /* TODO: start new key exchange on return */
974 GNUNET_break_op (0);
975 LOG (GNUNET_ERROR_TYPE_WARNING,
976 "Got message %u, expected %u+\n",
977 Np,
978 t->ax.Nr);
979 return GNUNET_SYSERR;
980 }
981 if (0 > gap)
982 {
983 /* Delayed message: don't store keys, flag to try old keys. */
984 return GNUNET_SYSERR;
985 }
986
987 while (t->ax.Nr < Np)
988 store_skipped_key (t,
989 HKr);
990
991 while (t->ax.skipped > MAX_SKIPPED_KEYS)
992 delete_skipped_key (t,
993 t->ax.skipped_tail);
994 return GNUNET_OK;
995}
996
997
998/**
999 * Decrypt and verify data with the appropriate tunnel key and verify that the
1000 * data has not been altered since it was sent by the remote peer.
1001 *
1002 * @param t Tunnel whose key to use.
1003 * @param dst Destination for the plaintext.
1004 * @param src Source of the message. Can overlap with @c dst.
1005 * @param size Size of the message.
1006 * @return Size of the decrypted data, -1 if an error was encountered.
1007 */
1008static ssize_t
1009t_ax_decrypt_and_validate (struct CadetTunnel *t,
1010 void *dst,
1011 const struct GNUNET_CADET_Encrypted *src,
1012 size_t size)
1013{
1014 struct CadetTunnelAxolotl *ax;
1015 struct GNUNET_CADET_Hash msg_hmac;
1016 struct GNUNET_HashCode hmac;
1017 struct GNUNET_CADET_Encrypted plaintext_header;
1018 uint32_t Np;
1019 uint32_t PNp;
1020 size_t esize; /* Size of encryped payload */
1021
1022 esize = size - sizeof (struct GNUNET_CADET_Encrypted);
1023 ax = &t->ax;
1024
1025 /* Try current HK */
1026 t_hmac (&src->Ns,
1027 AX_HEADER_SIZE + esize,
1028 0, &ax->HKr,
1029 &msg_hmac);
1030 if (0 != memcmp (&msg_hmac,
1031 &src->hmac,
1032 sizeof (msg_hmac)))
1033 {
1034 static const char ctx[] = "axolotl ratchet";
1035 struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */
1036 struct GNUNET_CRYPTO_SymmetricSessionKey HK;
1037 struct GNUNET_HashCode dh;
1038 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1039
1040 /* Try Next HK */
1041 t_hmac (&src->Ns,
1042 AX_HEADER_SIZE + esize,
1043 0,
1044 &ax->NHKr,
1045 &msg_hmac);
1046 if (0 != memcmp (&msg_hmac,
1047 &src->hmac,
1048 sizeof (msg_hmac)))
1049 {
1050 /* Try the skipped keys, if that fails, we're out of luck. */
1051 return try_old_ax_keys (t,
1052 dst,
1053 src,
1054 size);
1055 }
1056 HK = ax->HKr;
1057 ax->HKr = ax->NHKr;
1058 t_h_decrypt (t,
1059 src,
1060 &plaintext_header);
1061 Np = ntohl (plaintext_header.Ns);
1062 PNp = ntohl (plaintext_header.PNs);
1063 DHRp = &plaintext_header.DHRs;
1064 store_ax_keys (t,
1065 &HK,
1066 PNp);
1067
1068 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1069 GNUNET_CRYPTO_ecc_ecdh (ax->DHRs,
1070 DHRp,
1071 &dh);
1072 t_ax_hmac_hash (&ax->RK,
1073 &hmac,
1074 &dh, sizeof (dh));
1075 GNUNET_CRYPTO_kdf (keys, sizeof (keys),
1076 ctx, sizeof (ctx),
1077 &hmac, sizeof (hmac),
1078 NULL);
1079
1080 /* Commit "purported" keys */
1081 ax->RK = keys[0];
1082 ax->NHKr = keys[1];
1083 ax->CKr = keys[2];
1084 ax->DHRr = *DHRp;
1085 ax->Nr = 0;
1086 ax->ratchet_allowed = GNUNET_YES;
1087 }
1088 else
1089 {
1090 t_h_decrypt (t,
1091 src,
1092 &plaintext_header);
1093 Np = ntohl (plaintext_header.Ns);
1094 PNp = ntohl (plaintext_header.PNs);
1095 }
1096 if ( (Np != ax->Nr) &&
1097 (GNUNET_OK != store_ax_keys (t,
1098 &ax->HKr,
1099 Np)) )
1100 {
1101 /* Try the skipped keys, if that fails, we're out of luck. */
1102 return try_old_ax_keys (t,
1103 dst,
1104 src,
1105 size);
1106 }
1107
1108 t_ax_decrypt (t,
1109 dst,
1110 &src[1],
1111 esize);
1112 ax->Nr = Np + 1;
1113 return esize;
1114}
1115
1116
1117/* ************************************** end core crypto ***************************** */
1118
1119
1120/**
479 * Add a channel to a tunnel. 1121 * Add a channel to a tunnel.
480 * 1122 *
481 * @param t Tunnel. 1123 * @param t Tunnel.
@@ -569,6 +1211,8 @@ connection_ready_cb (void *cls)
569 GNUNET_CONTAINER_DLL_remove (t->tq_head, 1211 GNUNET_CONTAINER_DLL_remove (t->tq_head,
570 t->tq_tail, 1212 t->tq_tail,
571 tq); 1213 tq);
1214 if (NULL != tq->cid)
1215 *tq->cid = *GCC_get_id (ct->cc);
572 GCC_transmit (ct->cc, 1216 GCC_transmit (ct->cc,
573 tq->env); 1217 tq->env);
574 tq->cont (tq->cont_cls); 1218 tq->cont (tq->cont_cls);
@@ -694,6 +1338,7 @@ consider_path_cb (void *cls,
694 ct->t = t; 1338 ct->t = t;
695 ct->cc = GCC_create (t->destination, 1339 ct->cc = GCC_create (t->destination,
696 path, 1340 path,
1341 ct,
697 &connection_ready_cb, 1342 &connection_ready_cb,
698 t); 1343 t);
699 /* FIXME: schedule job to kill connection (and path?) if it takes 1344 /* FIXME: schedule job to kill connection (and path?) if it takes
@@ -794,23 +1439,45 @@ GCT_send (struct CadetTunnel *t,
794 GNUNET_SCHEDULER_TaskCallback cont, 1439 GNUNET_SCHEDULER_TaskCallback cont,
795 void *cont_cls) 1440 void *cont_cls)
796{ 1441{
797 struct CadetTunnelQueueEntry *q; 1442 struct CadetTunnelQueueEntry *tq;
798 uint16_t payload_size; 1443 uint16_t payload_size;
1444 struct GNUNET_MQ_Envelope *env;
1445 struct GNUNET_CADET_Encrypted *ax_msg;
799 1446
800 payload_size = ntohs (message->size); 1447 /* FIXME: what about KX not yet being ready? (see "is_ready()" check in old code!) */
801 1448
802 q = GNUNET_malloc (sizeof (*q) + 1449 payload_size = ntohs (message->size);
803 payload_size); 1450 env = GNUNET_MQ_msg_extra (ax_msg,
804 /* FIXME: encrypt 'message' to end of 'q' */ 1451 payload_size,
805 q->t = t; 1452 GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED);
806 q->cont = cont; 1453 t_ax_encrypt (t,
807 q->cont_cls = cont_cls; 1454 &ax_msg[1],
1455 message,
1456 payload_size);
1457 ax_msg->Ns = htonl (t->ax.Ns++);
1458 ax_msg->PNs = htonl (t->ax.PNs);
1459 GNUNET_CRYPTO_ecdhe_key_get_public (t->ax.DHRs,
1460 &ax_msg->DHRs);
1461 t_h_encrypt (t,
1462 ax_msg);
1463 t_hmac (&ax_msg->Ns,
1464 AX_HEADER_SIZE + payload_size,
1465 0,
1466 &t->ax.HKs,
1467 &ax_msg->hmac);
1468 // ax_msg->pid = htonl (GCC_get_pid (c, fwd)); // FIXME: connection flow-control not (re)implemented yet!
1469
1470 tq = GNUNET_malloc (sizeof (*tq));
1471 tq->t = t;
1472 tq->env = env;
1473 tq->cid = &ax_msg->cid;
1474 tq->cont = cont;
1475 tq->cont_cls = cont_cls;
808 GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, 1476 GNUNET_CONTAINER_DLL_insert_tail (t->tq_head,
809 t->tq_tail, 1477 t->tq_tail,
810 q); 1478 tq);
811 /* FIXME: what about KX being ready? */
812 trigger_transmissions (t); 1479 trigger_transmissions (t);
813 return q; 1480 return tq;
814} 1481}
815 1482
816 1483