diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2024-03-12 13:55:44 +0100 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2024-03-12 13:55:44 +0100 |
commit | 04ee4a5031dd96d317900e9067581667b02c9c26 (patch) | |
tree | 23cf64124274a205e87c41e17c2be994ba8dfda7 | |
parent | a824180e81738fd7e9ffdf967d830f0603c2aeb9 (diff) | |
download | gnunet-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.h | 90 | ||||
-rw-r--r-- | src/service/core/gnunet-service-core_kx.c | 298 |
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 | ||
54 | GNUNET_NETWORK_STRUCT_BEGIN | 58 | GNUNET_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 | */ | ||
115 | struct 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 | */ | ||
152 | struct 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 | ||
169 | GNUNET_NETWORK_STRUCT_END | 259 | GNUNET_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 | ||
77 | GNUNET_NETWORK_STRUCT_BEGIN | ||
78 | |||
79 | /** | ||
80 | * Encapsulation for encrypted messages exchanged between | ||
81 | * peers. Followed by the actual encrypted data. | ||
82 | */ | ||
83 | struct 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 | }; | ||
122 | GNUNET_NETWORK_STRUCT_END | ||
123 | |||
124 | #else | ||
125 | |||
75 | GNUNET_NETWORK_STRUCT_BEGIN | 126 | GNUNET_NETWORK_STRUCT_BEGIN |
76 | 127 | ||
77 | /** | 128 | /** |
@@ -118,13 +169,14 @@ struct EncryptedMessage | |||
118 | }; | 169 | }; |
119 | GNUNET_NETWORK_STRUCT_END | 170 | GNUNET_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 | */ |
285 | static struct GNUNET_NotificationContext *nc; | 351 | static 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 | */ | ||
522 | static void | ||
523 | derive_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 | ||