aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2024-03-12 13:55:44 +0100
committerMartin Schanzenbach <schanzen@gnunet.org>2024-03-12 13:55:44 +0100
commit04ee4a5031dd96d317900e9067581667b02c9c26 (patch)
tree23cf64124274a205e87c41e17c2be994ba8dfda7
parenta824180e81738fd7e9ffdf967d830f0603c2aeb9 (diff)
downloadgnunet-dev/schanzen/core_xchacha.tar.gz
gnunet-dev/schanzen/core_xchacha.zip
CORE: Add code for XChaCha20-Poly1305. Issue #8630dev/schanzen/core_xchacha
-rw-r--r--src/include/gnunet_core_service.h90
-rw-r--r--src/service/core/gnunet-service-core_kx.c298
2 files changed, 355 insertions, 33 deletions
diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h
index c3069be81..c7e8b9022 100644
--- a/src/include/gnunet_core_service.h
+++ b/src/include/gnunet_core_service.h
@@ -50,6 +50,10 @@ extern "C" {
50 * Version number of GNUnet-core API. 50 * Version number of GNUnet-core API.
51 */ 51 */
52#define GNUNET_CORE_VERSION 0x00000001 52#define GNUNET_CORE_VERSION 0x00000001
53/**
54 * Enable XChaCha20-Poly1305 crypto https://bugs.gnunet.org/view.php?id=8630
55 */
56#define CONG_CRYPTO_ENABLED 0
53 57
54GNUNET_NETWORK_STRUCT_BEGIN 58GNUNET_NETWORK_STRUCT_BEGIN
55 59
@@ -102,6 +106,89 @@ struct EphemeralKeyMessage
102 struct GNUNET_PeerIdentity origin_identity; 106 struct GNUNET_PeerIdentity origin_identity;
103}; 107};
104 108
109#if CONG_CRYPTO_ENABLED
110/**
111 * We're sending an (encrypted) PING to the other peer to check if it
112 * can decrypt. The other peer should respond with a PONG with the
113 * same content, except this time encrypted with the receiver's key.
114 */
115struct PingMessage
116{
117 /**
118 * Message type is #GNUNET_MESSAGE_TYPE_CORE_PING.
119 */
120 struct GNUNET_MessageHeader header;
121
122 /**
123 * XChaCha20 nonce
124 */
125 unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES];
126
127 /**
128 * The Poly1305 tag of the encrypted message
129 * (which is starting at @e target),
130 * used to verify message integrity. Everything after this value
131 * (excluding this value itself) will be encrypted and
132 * authenticated.
133 */
134 unsigned char tag[crypto_aead_xchacha20poly1305_ietf_ABYTES];
135
136 /**
137 * Intended target of the PING, used primarily to check
138 * that decryption actually worked.
139 */
140 struct GNUNET_PeerIdentity target;
141
142 /**
143 * Random number chosen to make replay harder.
144 */
145 uint32_t challenge GNUNET_PACKED;
146};
147
148
149/**
150 * Response to a PING. Includes data from the original PING.
151 */
152struct PongMessage
153{
154 /**
155 * Message type is #GNUNET_MESSAGE_TYPE_CORE_PONG.
156 */
157 struct GNUNET_MessageHeader header;
158
159 /**
160 * XChaCha20 nonce
161 */
162 unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES];
163
164 /**
165 * The Poly1305 tag of the encrypted message
166 * (which is starting at @e target),
167 * used to verify message integrity. Everything after this value
168 * (excluding this value itself) will be encrypted and
169 * authenticated.
170 */
171 unsigned char tag[crypto_aead_xchacha20poly1305_ietf_ABYTES];
172
173
174 /**
175 * Random number to make replay attacks harder.
176 */
177 uint32_t challenge GNUNET_PACKED;
178
179 /**
180 * Reserved, always zero.
181 */
182 uint32_t reserved;
183
184 /**
185 * Intended target of the PING, used primarily to check
186 * that decryption actually worked.
187 */
188 struct GNUNET_PeerIdentity target;
189};
190
191#else
105 192
106/** 193/**
107 * We're sending an (encrypted) PING to the other peer to check if it 194 * We're sending an (encrypted) PING to the other peer to check if it
@@ -165,6 +252,9 @@ struct PongMessage
165 struct GNUNET_PeerIdentity target; 252 struct GNUNET_PeerIdentity target;
166}; 253};
167 254
255#endif
256
257
168 258
169GNUNET_NETWORK_STRUCT_END 259GNUNET_NETWORK_STRUCT_END
170 260
diff --git a/src/service/core/gnunet-service-core_kx.c b/src/service/core/gnunet-service-core_kx.c
index c5a1de769..2dc9974bf 100644
--- a/src/service/core/gnunet-service-core_kx.c
+++ b/src/service/core/gnunet-service-core_kx.c
@@ -38,29 +38,30 @@
38 */ 38 */
39#define DEBUG_KX 0 39#define DEBUG_KX 0
40 40
41
41/** 42/**
42 * How long do we wait for SET_KEY confirmation initially? 43 * How long do we wait for SET_KEY confirmation initially?
43 */ 44 */
44#define INITIAL_SET_KEY_RETRY_FREQUENCY \ 45#define INITIAL_SET_KEY_RETRY_FREQUENCY \
45 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) 46 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
46 47
47/** 48/**
48 * What is the minimum frequency for a PING message? 49 * What is the minimum frequency for a PING message?
49 */ 50 */
50#define MIN_PING_FREQUENCY \ 51#define MIN_PING_FREQUENCY \
51 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) 52 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
52 53
53/** 54/**
54 * How often do we rekey? 55 * How often do we rekey?
55 */ 56 */
56#define REKEY_FREQUENCY \ 57#define REKEY_FREQUENCY \
57 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12) 58 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12)
58 59
59/** 60/**
60 * What time difference do we tolerate? 61 * What time difference do we tolerate?
61 */ 62 */
62#define REKEY_TOLERANCE \ 63#define REKEY_TOLERANCE \
63 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) 64 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
64 65
65/** 66/**
66 * What is the maximum age of a message for us to consider processing 67 * What is the maximum age of a message for us to consider processing
@@ -72,6 +73,56 @@
72#define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS 73#define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS
73 74
74 75
76#if CONG_CRYPTO_ENABLED
77GNUNET_NETWORK_STRUCT_BEGIN
78
79/**
80 * Encapsulation for encrypted messages exchanged between
81 * peers. Followed by the actual encrypted data.
82 */
83struct EncryptedMessage
84{
85 /**
86 * Message type is #GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE.
87 */
88 struct GNUNET_MessageHeader header;
89
90 /**
91 * The nonce.
92 */
93 unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES];
94
95 /**
96 * The Poly1305 tag of the encrypted message
97 * (which is starting at @e sequence_number),
98 * used to verify message integrity. Everything after this value
99 * (excluding this value itself) will be encrypted and
100 * authenticated. #ENCRYPTED_HEADER_SIZE must be set to the offset
101 * of the *next* field.
102 */
103 unsigned char tag[crypto_aead_xchacha20poly1305_ietf_ABYTES];
104
105 /**
106 * Sequence number, in network byte order. This field
107 * must be the first encrypted/decrypted field
108 */
109 uint32_t sequence_number GNUNET_PACKED;
110
111 /**
112 * Reserved, always zero.
113 */
114 uint32_t reserved GNUNET_PACKED;
115
116 /**
117 * Timestamp. Used to prevent replay of ancient messages
118 * (recent messages are caught with the sequence number).
119 */
120 struct GNUNET_TIME_AbsoluteNBO timestamp;
121};
122GNUNET_NETWORK_STRUCT_END
123
124#else
125
75GNUNET_NETWORK_STRUCT_BEGIN 126GNUNET_NETWORK_STRUCT_BEGIN
76 127
77/** 128/**
@@ -118,13 +169,14 @@ struct EncryptedMessage
118}; 169};
119GNUNET_NETWORK_STRUCT_END 170GNUNET_NETWORK_STRUCT_END
120 171
172#endif
121 173
122/** 174/**
123 * Number of bytes (at the beginning) of `struct EncryptedMessage` 175 * Number of bytes (at the beginning) of `struct EncryptedMessage`
124 * that are NOT encrypted. 176 * that are NOT encrypted.
125 */ 177 */
126#define ENCRYPTED_HEADER_SIZE \ 178#define ENCRYPTED_HEADER_SIZE \
127 (offsetof (struct EncryptedMessage, sequence_number)) 179 (offsetof (struct EncryptedMessage, sequence_number))
128 180
129 181
130/** 182/**
@@ -167,6 +219,19 @@ struct GSC_KeyExchangeInfo
167 */ 219 */
168 struct GNUNET_CRYPTO_EcdhePublicKey other_ephemeral_key; 220 struct GNUNET_CRYPTO_EcdhePublicKey other_ephemeral_key;
169 221
222#if CONG_CRYPTO_ENABLED
223 /**
224 * Key we use to encrypt our messages for the other peer
225 * (initialized by us when we do the handshake).
226 */
227 unsigned char encrypt_key[crypto_aead_xchacha20poly1305_ietf_KEYBYTES];
228
229 /**
230 * Key we use to decrypt messages from the other peer
231 * (given to us by the other peer during the handshake).
232 */
233 unsigned char decrypt_key[crypto_aead_xchacha20poly1305_ietf_KEYBYTES];
234#else
170 /** 235 /**
171 * Key we use to encrypt our messages for the other peer 236 * Key we use to encrypt our messages for the other peer
172 * (initialized by us when we do the handshake). 237 * (initialized by us when we do the handshake).
@@ -178,6 +243,7 @@ struct GSC_KeyExchangeInfo
178 * (given to us by the other peer during the handshake). 243 * (given to us by the other peer during the handshake).
179 */ 244 */
180 struct GNUNET_CRYPTO_SymmetricSessionKey decrypt_key; 245 struct GNUNET_CRYPTO_SymmetricSessionKey decrypt_key;
246#endif
181 247
182 /** 248 /**
183 * At what time did the other peer generate the decryption key? 249 * At what time did the other peer generate the decryption key?
@@ -284,7 +350,7 @@ static struct GNUNET_SCHEDULER_Task *rekey_task;
284 */ 350 */
285static struct GNUNET_NotificationContext *nc; 351static struct GNUNET_NotificationContext *nc;
286 352
287 353#if ! CONG_CRYPTO_ENABLED
288/** 354/**
289 * Calculate seed value we should use for a message. 355 * Calculate seed value we should use for a message.
290 * 356 *
@@ -301,6 +367,8 @@ calculate_seed (struct GSC_KeyExchangeInfo *kx)
301} 367}
302 368
303 369
370#endif
371
304/** 372/**
305 * Inform all monitors about the KX state of the given peer. 373 * Inform all monitors about the KX state of the given peer.
306 * 374 *
@@ -321,6 +389,7 @@ monitor_notify_all (struct GSC_KeyExchangeInfo *kx)
321} 389}
322 390
323 391
392#if ! CONG_CRYPTO_ENABLED
324/** 393/**
325 * Derive an authentication key from "set key" information 394 * Derive an authentication key from "set key" information
326 * 395 *
@@ -438,6 +507,49 @@ derive_pong_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
438} 507}
439 508
440 509
510#endif
511
512
513#if CONG_CRYPTO_ENABLED
514/**
515 * Derive an XChacha20 key from key material
516 *
517 * @param sender peer identity of the sender
518 * @param receiver peer identity of the sender
519 * @param key_material high entropy key material to use
520 * @param skey set to derived session key
521 */
522static void
523derive_symmetric_key (const struct GNUNET_PeerIdentity *sender,
524 const struct GNUNET_PeerIdentity *receiver,
525 const struct GNUNET_HashCode *key_material,
526 unsigned char *skey)
527{
528 static const char ctx[] = "xchacha20 key generation vector";
529
530#if DEBUG_KX
531 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
532 "Deriving XChaCha20 Key for %s to %s from %s\n",
533 GNUNET_i2s (sender),
534 GNUNET_i2s2 (receiver),
535 GNUNET_h2s (key_material));
536#endif
537 GNUNET_CRYPTO_kdf (skey,
538 crypto_aead_xchacha20poly1305_ietf_KEYBYTES,
539 ctx,
540 sizeof(ctx),
541 key_material,
542 sizeof(struct GNUNET_HashCode),
543 sender,
544 sizeof(struct GNUNET_PeerIdentity),
545 receiver,
546 sizeof(struct GNUNET_PeerIdentity),
547 NULL);
548}
549
550
551#else
552
441/** 553/**
442 * Derive an AES key from key material 554 * Derive an AES key from key material
443 * 555 *
@@ -478,6 +590,9 @@ derive_aes_key (const struct GNUNET_PeerIdentity *sender,
478} 590}
479 591
480 592
593#endif
594
595#if ! CONG_CRYPTO_ENABLED
481/** 596/**
482 * Encrypt size bytes from @a in and write the result to @a out. Use the 597 * Encrypt size bytes from @a in and write the result to @a out. Use the
483 * @a kx key for outbound traffic of the given neighbour. 598 * @a kx key for outbound traffic of the given neighbour.
@@ -525,6 +640,9 @@ do_encrypt (struct GSC_KeyExchangeInfo *kx,
525} 640}
526 641
527 642
643#endif
644
645#if ! CONG_CRYPTO_ENABLED
528/** 646/**
529 * Decrypt size bytes from @a in and write the result to @a out. Use 647 * Decrypt size bytes from @a in and write the result to @a out. Use
530 * the @a kx key for inbound traffic of the given neighbour. This 648 * the @a kx key for inbound traffic of the given neighbour. This
@@ -583,6 +701,8 @@ do_decrypt (struct GSC_KeyExchangeInfo *kx,
583} 701}
584 702
585 703
704#endif
705
586/** 706/**
587 * Send our key (and encrypted PING) to the other peer. 707 * Send our key (and encrypted PING) to the other peer.
588 * 708 *
@@ -620,23 +740,38 @@ setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
620{ 740{
621 struct PingMessage pp; 741 struct PingMessage pp;
622 struct PingMessage *pm; 742 struct PingMessage *pm;
623 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
624 743
625 pm = &kx->ping; 744 pm = &kx->ping;
626 kx->ping_challenge = 745 kx->ping_challenge =
627 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); 746 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX);
628 pm->header.size = htons (sizeof(struct PingMessage)); 747 pm->header.size = htons (sizeof(struct PingMessage));
629 pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING); 748 pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
630 pm->iv_seed = calculate_seed (kx);
631 derive_iv (&iv, &kx->encrypt_key, pm->iv_seed, kx->peer);
632 pp.challenge = kx->ping_challenge; 749 pp.challenge = kx->ping_challenge;
633 pp.target = *kx->peer; 750 pp.target = *kx->peer;
751#if CONG_CRYPTO_ENABLED
752 randombytes_buf (pm->nonce, sizeof (pm->nonce));
753 GNUNET_assert (0 ==
754 crypto_aead_xchacha20poly1305_ietf_encrypt_detached (
755 (unsigned char*) &pm->target,
756 pm->tag,
757 NULL,
758 (unsigned char*) &pp.target,
759 sizeof(pp.target) + sizeof (pp.challenge),
760 NULL, 0,
761 NULL,
762 pm->nonce,
763 kx->encrypt_key));
764#else
765 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
766 pm->iv_seed = calculate_seed (kx);
767 derive_iv (&iv, &kx->encrypt_key, pm->iv_seed, kx->peer);
634 do_encrypt (kx, 768 do_encrypt (kx,
635 &iv, 769 &iv,
636 &pp.target, 770 &pp.target,
637 &pm->target, 771 &pm->target,
638 sizeof(struct PingMessage) 772 sizeof(struct PingMessage)
639 - ((void *) &pm->target - (void *) pm)); 773 - ((void *) &pm->target - (void *) pm));
774#endif
640} 775}
641 776
642 777
@@ -718,7 +853,7 @@ handle_transport_notify_connect (void *cls,
718 gettext_noop ("# key exchanges initiated"), 853 gettext_noop ("# key exchanges initiated"),
719 1, 854 1,
720 GNUNET_NO); 855 GNUNET_NO);
721 856
722 kx = GNUNET_new (struct GSC_KeyExchangeInfo); 857 kx = GNUNET_new (struct GSC_KeyExchangeInfo);
723 kx->mst = GNUNET_MST_create (&deliver_message, kx); 858 kx->mst = GNUNET_MST_create (&deliver_message, kx);
724 kx->mq = mq; 859 kx->mq = mq;
@@ -830,8 +965,17 @@ derive_session_keys (struct GSC_KeyExchangeInfo *kx)
830 GNUNET_break (0); 965 GNUNET_break (0);
831 return; 966 return;
832 } 967 }
833 derive_aes_key (&GSC_my_identity, kx->peer, &key_material, &kx->encrypt_key); 968#if CONG_CRYPTO_ENABLED
834 derive_aes_key (kx->peer, &GSC_my_identity, &key_material, &kx->decrypt_key); 969 derive_symmetric_key (&GSC_my_identity, kx->peer, &key_material, kx->
970 encrypt_key);
971 derive_symmetric_key (kx->peer, &GSC_my_identity, &key_material, kx->
972 decrypt_key);
973#else
974 derive_aes_key (&GSC_my_identity, kx->peer, &key_material, &kx->
975 encrypt_key);
976 derive_aes_key (kx->peer, &GSC_my_identity, &key_material, &kx->
977 decrypt_key);
978#endif
835 memset (&key_material, 0, sizeof(key_material)); 979 memset (&key_material, 0, sizeof(key_material));
836 /* fresh key, reset sequence numbers */ 980 /* fresh key, reset sequence numbers */
837 kx->last_sequence_number_received = 0; 981 kx->last_sequence_number_received = 0;
@@ -900,16 +1044,18 @@ handle_ephemeral_key (void *cls, const struct EphemeralKeyMessage *m)
900 return; 1044 return;
901 } 1045 }
902 if (do_verify && ((ntohl (m->purpose.size) != 1046 if (do_verify && ((ntohl (m->purpose.size) !=
903 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 1047 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
904 + sizeof(struct GNUNET_TIME_AbsoluteNBO) 1048 + sizeof(struct GNUNET_TIME_AbsoluteNBO)
905 + sizeof(struct GNUNET_TIME_AbsoluteNBO) 1049 + sizeof(struct GNUNET_TIME_AbsoluteNBO)
906 + sizeof(struct GNUNET_CRYPTO_EddsaPublicKey) 1050 + sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
907 + sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) || 1051 + sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) ||
908 (GNUNET_OK != 1052 (GNUNET_OK !=
909 GNUNET_CRYPTO_eddsa_verify_ (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY, 1053 GNUNET_CRYPTO_eddsa_verify_ (
910 &m->purpose, 1054 GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY,
911 &m->signature, 1055 &m->purpose,
912 &m->origin_identity.public_key)))) 1056 &m->signature,
1057 &m->origin_identity.public_key
1058 ))))
913 { 1059 {
914 /* invalid signature */ 1060 /* invalid signature */
915 GNUNET_break_op (0); 1061 GNUNET_break_op (0);
@@ -941,7 +1087,8 @@ handle_ephemeral_key (void *cls, const struct EphemeralKeyMessage *m)
941 (unsigned long long) end_t.abs_value_us); 1087 (unsigned long long) end_t.abs_value_us);
942 GNUNET_STATISTICS_update (GSC_stats, 1088 GNUNET_STATISTICS_update (GSC_stats,
943 gettext_noop ( 1089 gettext_noop (
944 "# EPHEMERAL_KEY messages rejected due to time"), 1090 "# EPHEMERAL_KEY messages rejected due to time")
1091 ,
945 1, 1092 1,
946 GNUNET_NO); 1093 GNUNET_NO);
947 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer); 1094 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer);
@@ -1071,7 +1218,6 @@ handle_ping (void *cls, const struct PingMessage *m)
1071 struct PongMessage tx; 1218 struct PongMessage tx;
1072 struct PongMessage *tp; 1219 struct PongMessage *tp;
1073 struct GNUNET_MQ_Envelope *env; 1220 struct GNUNET_MQ_Envelope *env;
1074 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1075 1221
1076 GNUNET_STATISTICS_update (GSC_stats, 1222 GNUNET_STATISTICS_update (GSC_stats,
1077 gettext_noop ("# PING messages received"), 1223 gettext_noop ("# PING messages received"),
@@ -1093,6 +1239,23 @@ handle_ping (void *cls, const struct PingMessage *m)
1093 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1094 "Core service receives PING request from `%s'.\n", 1240 "Core service receives PING request from `%s'.\n",
1095 GNUNET_i2s (kx->peer)); 1241 GNUNET_i2s (kx->peer));
1242#if CONG_CRYPTO_ENABLED
1243 if (0 != crypto_aead_xchacha20poly1305_ietf_decrypt_detached (
1244 (unsigned char*) &t.target,
1245 NULL,
1246 (unsigned char*) &m->target,
1247 sizeof (m->target) + sizeof (m->challenge),
1248 m->tag,
1249 NULL, 0,
1250 m->nonce,
1251 kx->decrypt_key))
1252 {
1253 GNUNET_break_op (0);
1254 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer);
1255 return;
1256 }
1257#else
1258 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1096 derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity); 1259 derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity);
1097 if (GNUNET_OK != do_decrypt (kx, 1260 if (GNUNET_OK != do_decrypt (kx,
1098 &iv, 1261 &iv,
@@ -1105,6 +1268,7 @@ handle_ping (void *cls, const struct PingMessage *m)
1105 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer); 1268 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer);
1106 return; 1269 return;
1107 } 1270 }
1271#endif
1108 if (0 != 1272 if (0 !=
1109 memcmp (&t.target, &GSC_my_identity, sizeof(struct GNUNET_PeerIdentity))) 1273 memcmp (&t.target, &GSC_my_identity, sizeof(struct GNUNET_PeerIdentity)))
1110 { 1274 {
@@ -1127,6 +1291,21 @@ handle_ping (void *cls, const struct PingMessage *m)
1127 tx.challenge = t.challenge; 1291 tx.challenge = t.challenge;
1128 tx.target = t.target; 1292 tx.target = t.target;
1129 env = GNUNET_MQ_msg (tp, GNUNET_MESSAGE_TYPE_CORE_PONG); 1293 env = GNUNET_MQ_msg (tp, GNUNET_MESSAGE_TYPE_CORE_PONG);
1294#if CONG_CRYPTO_ENABLED
1295 randombytes_buf (tp->nonce, sizeof (tp->nonce));
1296 GNUNET_assert (0 ==
1297 crypto_aead_xchacha20poly1305_ietf_encrypt_detached (
1298 (unsigned char*) &tp->challenge,
1299 tp->tag,
1300 NULL,
1301 (unsigned char*) &tx.challenge,
1302 sizeof(struct PongMessage)
1303 - ((void *) &tp->challenge - (void *) tp),
1304 NULL, 0,
1305 NULL,
1306 tp->nonce,
1307 kx->encrypt_key));
1308#else
1130 tp->iv_seed = calculate_seed (kx); 1309 tp->iv_seed = calculate_seed (kx);
1131 derive_pong_iv (&iv, &kx->encrypt_key, tp->iv_seed, t.challenge, kx->peer); 1310 derive_pong_iv (&iv, &kx->encrypt_key, tp->iv_seed, t.challenge, kx->peer);
1132 do_encrypt (kx, 1311 do_encrypt (kx,
@@ -1135,6 +1314,7 @@ handle_ping (void *cls, const struct PingMessage *m)
1135 &tp->challenge, 1314 &tp->challenge,
1136 sizeof(struct PongMessage) 1315 sizeof(struct PongMessage)
1137 - ((void *) &tp->challenge - (void *) tp)); 1316 - ((void *) &tp->challenge - (void *) tp));
1317#endif
1138 GNUNET_STATISTICS_update (GSC_stats, 1318 GNUNET_STATISTICS_update (GSC_stats,
1139 gettext_noop ("# PONG messages created"), 1319 gettext_noop ("# PONG messages created"),
1140 1, 1320 1,
@@ -1143,7 +1323,8 @@ handle_ping (void *cls, const struct PingMessage *m)
1143 if (NULL != kx->keep_alive_task) 1323 if (NULL != kx->keep_alive_task)
1144 { 1324 {
1145 GNUNET_SCHEDULER_cancel (kx->keep_alive_task); 1325 GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
1146 kx->keep_alive_task = GNUNET_SCHEDULER_add_delayed (MIN_PING_FREQUENCY, &send_keep_alive, kx); 1326 kx->keep_alive_task = GNUNET_SCHEDULER_add_delayed (MIN_PING_FREQUENCY, &
1327 send_keep_alive, kx);
1147 } 1328 }
1148 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer); 1329 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer);
1149} 1330}
@@ -1234,7 +1415,6 @@ handle_pong (void *cls, const struct PongMessage *m)
1234{ 1415{
1235 struct GSC_KeyExchangeInfo *kx = cls; 1416 struct GSC_KeyExchangeInfo *kx = cls;
1236 struct PongMessage t; 1417 struct PongMessage t;
1237 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1238 1418
1239 GNUNET_STATISTICS_update (GSC_stats, 1419 GNUNET_STATISTICS_update (GSC_stats,
1240 gettext_noop ("# PONG messages received"), 1420 gettext_noop ("# PONG messages received"),
@@ -1279,6 +1459,24 @@ handle_pong (void *cls, const struct PongMessage *m)
1279 GNUNET_i2s (kx->peer)); 1459 GNUNET_i2s (kx->peer));
1280 /* mark as garbage, just to be sure */ 1460 /* mark as garbage, just to be sure */
1281 memset (&t, 255, sizeof(t)); 1461 memset (&t, 255, sizeof(t));
1462#if CONG_CRYPTO_ENABLED
1463 if (0 != crypto_aead_xchacha20poly1305_ietf_decrypt_detached (
1464 (unsigned char*) &t.challenge,
1465 NULL,
1466 (unsigned char*) &m->challenge,
1467 sizeof(struct PongMessage)
1468 - ((void *) &m->challenge - (void *) m),
1469 m->tag,
1470 NULL, 0,
1471 m->nonce,
1472 kx->decrypt_key))
1473 {
1474 GNUNET_break_op (0);
1475 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer);
1476 return;
1477 }
1478#else
1479 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1282 derive_pong_iv (&iv, 1480 derive_pong_iv (&iv,
1283 &kx->decrypt_key, 1481 &kx->decrypt_key,
1284 m->iv_seed, 1482 m->iv_seed,
@@ -1295,6 +1493,7 @@ handle_pong (void *cls, const struct PongMessage *m)
1295 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer); 1493 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer);
1296 return; 1494 return;
1297 } 1495 }
1496#endif
1298 GNUNET_STATISTICS_update (GSC_stats, 1497 GNUNET_STATISTICS_update (GSC_stats,
1299 gettext_noop ("# PONG messages decrypted"), 1498 gettext_noop ("# PONG messages decrypted"),
1300 1, 1499 1,
@@ -1429,18 +1628,32 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1429 struct EncryptedMessage *em; /* encrypted message */ 1628 struct EncryptedMessage *em; /* encrypted message */
1430 struct EncryptedMessage *ph; /* plaintext header */ 1629 struct EncryptedMessage *ph; /* plaintext header */
1431 struct GNUNET_MQ_Envelope *env; 1630 struct GNUNET_MQ_Envelope *env;
1432 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1433 struct GNUNET_CRYPTO_AuthKey auth_key;
1434 1631
1435 ph = (struct EncryptedMessage *) pbuf; 1632 ph = (struct EncryptedMessage *) pbuf;
1436 ph->sequence_number = htonl (++kx->last_sequence_number_sent); 1633 ph->sequence_number = htonl (++kx->last_sequence_number_sent);
1437 ph->iv_seed = calculate_seed (kx);
1438 ph->reserved = 0; 1634 ph->reserved = 0;
1439 ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); 1635 ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1440 GNUNET_memcpy (&ph[1], payload, payload_size); 1636 GNUNET_memcpy (&ph[1], payload, payload_size);
1441 env = GNUNET_MQ_msg_extra (em, 1637 env = GNUNET_MQ_msg_extra (em,
1442 payload_size, 1638 payload_size,
1443 GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE); 1639 GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
1640#if CONG_CRYPTO_ENABLED
1641 randombytes_buf (ph->nonce, sizeof (ph->nonce));
1642 GNUNET_assert (0 ==
1643 crypto_aead_xchacha20poly1305_ietf_encrypt_detached (
1644 (unsigned char*) &em->sequence_number,
1645 em->tag,
1646 NULL,
1647 (unsigned char*) &ph->sequence_number,
1648 used - ENCRYPTED_HEADER_SIZE,
1649 NULL, 0,
1650 NULL,
1651 ph->nonce,
1652 kx->encrypt_key));
1653#else
1654 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1655 struct GNUNET_CRYPTO_AuthKey auth_key;
1656 ph->iv_seed = calculate_seed (kx);
1444 em->iv_seed = ph->iv_seed; 1657 em->iv_seed = ph->iv_seed;
1445 derive_iv (&iv, &kx->encrypt_key, ph->iv_seed, kx->peer); 1658 derive_iv (&iv, &kx->encrypt_key, ph->iv_seed, kx->peer);
1446 GNUNET_assert (GNUNET_OK == do_encrypt (kx, 1659 GNUNET_assert (GNUNET_OK == do_encrypt (kx,
@@ -1479,6 +1692,7 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1479 GNUNET_h2s2 (&em->hmac)); 1692 GNUNET_h2s2 (&em->hmac));
1480 } 1693 }
1481#endif 1694#endif
1695#endif
1482 kx->has_excess_bandwidth = GNUNET_NO; 1696 kx->has_excess_bandwidth = GNUNET_NO;
1483 GNUNET_MQ_send (kx->mq, env); 1697 GNUNET_MQ_send (kx->mq, env);
1484} 1698}
@@ -1518,11 +1732,8 @@ handle_encrypted (void *cls, const struct EncryptedMessage *m)
1518{ 1732{
1519 struct GSC_KeyExchangeInfo *kx = cls; 1733 struct GSC_KeyExchangeInfo *kx = cls;
1520 struct EncryptedMessage *pt; /* plaintext */ 1734 struct EncryptedMessage *pt; /* plaintext */
1521 struct GNUNET_HashCode ph;
1522 uint32_t snum; 1735 uint32_t snum;
1523 struct GNUNET_TIME_Absolute t; 1736 struct GNUNET_TIME_Absolute t;
1524 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1525 struct GNUNET_CRYPTO_AuthKey auth_key;
1526 uint16_t size = ntohs (m->header.size); 1737 uint16_t size = ntohs (m->header.size);
1527 char buf[size] GNUNET_ALIGN; 1738 char buf[size] GNUNET_ALIGN;
1528 1739
@@ -1575,6 +1786,26 @@ handle_encrypted (void *cls, const struct EncryptedMessage *m)
1575 GNUNET_i2s (kx->peer)); 1786 GNUNET_i2s (kx->peer));
1576 } 1787 }
1577#endif 1788#endif
1789
1790#if CONG_CRYPTO_ENABLED
1791 if (0 != crypto_aead_xchacha20poly1305_ietf_decrypt_detached (
1792 (unsigned char*) &buf[ENCRYPTED_HEADER_SIZE],
1793 NULL,
1794 (unsigned char*) &m->sequence_number,
1795 size - ENCRYPTED_HEADER_SIZE,
1796 m->tag,
1797 NULL, 0,
1798 m->nonce,
1799 kx->decrypt_key))
1800 {
1801 GNUNET_break_op (0);
1802 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer);
1803 return;
1804 }
1805#else
1806 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1807 struct GNUNET_CRYPTO_AuthKey auth_key;
1808 struct GNUNET_HashCode ph;
1578 derive_auth_key (&auth_key, &kx->decrypt_key, m->iv_seed); 1809 derive_auth_key (&auth_key, &kx->decrypt_key, m->iv_seed);
1579 GNUNET_CRYPTO_hmac (&auth_key, 1810 GNUNET_CRYPTO_hmac (&auth_key,
1580 &m->sequence_number, 1811 &m->sequence_number,
@@ -1613,6 +1844,7 @@ handle_encrypted (void *cls, const struct EncryptedMessage *m)
1613 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer); 1844 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer);
1614 return; 1845 return;
1615 } 1846 }
1847#endif
1616 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1848 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1617 "Decrypted %u bytes from %s\n", 1849 "Decrypted %u bytes from %s\n",
1618 (unsigned int) (size - ENCRYPTED_HEADER_SIZE), 1850 (unsigned int) (size - ENCRYPTED_HEADER_SIZE),
@@ -1708,7 +1940,7 @@ handle_encrypted (void *cls, const struct EncryptedMessage *m)
1708 GNUNET_YES, 1940 GNUNET_YES,
1709 GNUNET_NO)) 1941 GNUNET_NO))
1710 GNUNET_break_op (0); 1942 GNUNET_break_op (0);
1711 1943
1712 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer); 1944 GNUNET_TRANSPORT_core_receive_continue (transport, kx->peer);
1713} 1945}
1714 1946