gnunet-service-core_kx.c (130655B)
1 /* 2 This file is part of GNUnet. 3 Copyright (C) 2009-2013, 2016, 2024-2026 GNUnet e.V. 4 5 GNUnet is free software: you can redistribute it and/or modify it 6 under the terms of the GNU Affero General Public License as published 7 by the Free Software Foundation, either version 3 of the License, 8 or (at your option) any later version. 9 10 GNUnet is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Affero General Public License for more details. 14 15 You should have received a copy of the GNU Affero General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 SPDX-License-Identifier: AGPL3.0-or-later 19 */ 20 21 /** 22 * TODO: 23 * - We need to implement a rekey (+ACK) that periodically rekeys. 24 * - We may want to reintroduce a heartbeat that needs to be ACKed. Maybe use / merge 25 * with KeyUpdate message. It already contains an update_requested field. 26 * Maybe rename to Heartbeat and add key_updated field to indicate a field update. 27 * That message then always MUST be Acked, if update_requested, then a Heartbeat is 28 * expected in response (w/o update_requested of course). 29 */ 30 31 /** 32 * @file core/gnunet-service-core_kx.c 33 * @brief code for managing the key exchange (SET_KEY, PING, PONG) with other 34 * peers 35 * @author Christian Grothoff, ch3 36 */ 37 #include "platform.h" 38 #include "gnunet_common.h" 39 #include "gnunet_util_lib.h" 40 #include "gnunet-service-core_kx.h" 41 #include "gnunet_transport_core_service.h" 42 #include "gnunet-service-core_sessions.h" 43 #include "gnunet-service-core.h" 44 #include "gnunet_constants.h" 45 #include "gnunet_protocols.h" 46 #include "gnunet_pils_service.h" 47 48 /** 49 * Enable expensive (and possibly problematic for privacy!) logging of KX. 50 */ 51 #define DEBUG_KX 0 52 53 /** 54 * Enable expensive logging of decryption failures. 55 * Note that protocol violating peers may always cause those 56 * en masse. 57 */ 58 #define DECRYPTION_FAILURES_LOG_LEVEL GNUNET_ERROR_TYPE_DEBUG 59 60 /** 61 * Number of times we retransmit a handshake flight before giving up on it 62 * and starting a fresh exchange. With the exponential backoff of RFC 9147, 63 * Section 5.8, the retransmissions go out 1, 3, 7, 15 and 31 seconds into 64 * the flight; the flight is then abandoned one further interval after the 65 * last of them, at 63s. 66 * 67 * Note that the give-up is observed by the *next* firing of @e resend_task, 68 * which #schedule_resend() has already armed with the doubled delay -- so 69 * the flight always outlasts its last retransmission by one interval, and 70 * raising this by one costs far more than the interval it adds. 71 */ 72 #define RESEND_MAX_TRIES 5 73 74 /** 75 * libsodium has very long symbol names 76 */ 77 #define AEAD_KEY_BYTES crypto_aead_xchacha20poly1305_ietf_KEYBYTES 78 79 /** 80 * libsodium has very long symbol names 81 */ 82 #define AEAD_NONCE_BYTES crypto_aead_xchacha20poly1305_ietf_NPUBBYTES 83 84 /** 85 * libsodium has very long symbol names 86 */ 87 #define AEAD_TAG_BYTES crypto_aead_xchacha20poly1305_ietf_ABYTES 88 89 /** 90 * Initial handshake retransmission timer. RFC 9147, Section 5.8: 91 * "implementations SHOULD use an initial timer value of 1000 ms and double 92 * the value at each retransmission, up to no less than 60 seconds." 93 */ 94 #define RESEND_TIMEOUT \ 95 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) 96 97 /** 98 * Ceiling for the handshake retransmission timer (RFC 9147, Section 5.8). 99 */ 100 #define RESEND_TIMEOUT_MAX \ 101 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) 102 103 /** 104 * Size of the per-epoch anti-replay window, in records. RFC 9147, 105 * Section 4.5.1: "The receiver SHOULD pick a window large enough to handle 106 * any plausible reordering, which depends on the data rate." One machine 107 * word is the largest window we can check in constant time. 108 */ 109 #define REPLAY_WINDOW_SIZE 64 110 111 /** 112 * How long we wait for the Ack to a heartbeat before sending another one. 113 * 114 * Every heartbeat is answered -- #handle_heartbeat() sends a 115 * #GNUNET_MESSAGE_TYPE_CORE_ACK unconditionally -- so this is also how long 116 * an association may go unconfirmed before we probe it again. 117 */ 118 #define HEARTBEAT_PROBE_FREQUENCY \ 119 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) 120 121 /** 122 * How many heartbeats in a row may go unanswered before we give up on the 123 * association. Together with #HEARTBEAT_PROBE_FREQUENCY this bounds how 124 * long a dead association can look alive to us (90s). 125 */ 126 #define MAX_UNANSWERED_HEARTBEATS 3 127 128 /** 129 * What is the minimum frequency for a HEARTBEAT message? 130 */ 131 #define MIN_HEARTBEAT_FREQUENCY \ 132 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) 133 134 /** 135 * How often do we send a heartbeat? 136 */ 137 #define HEARTBEAT_FREQUENCY \ 138 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12) 139 140 /** 141 * Maximum number of epochs we keep on hand. 142 * This implicitly defines the maximum age of 143 * messages we accept from other peers, depending 144 * on their rekey interval. 145 */ 146 #define MAX_EPOCHS 10 147 148 /** 149 * How often do we rekey/switch to a new epoch? 150 */ 151 #define EPOCH_EXPIRATION \ 152 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12) 153 154 /** 155 * What time difference do we tolerate? 156 */ 157 #define REKEY_TOLERANCE \ 158 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) 159 160 /** 161 * String for expanding early transport secret 162 * (See https://lsd.gnunet.org/lsd0012/draft-schanzen-cake.html) 163 */ 164 #define EARLY_DATA_STR "early data" 165 166 /** 167 * String for expanding RHTS 168 * (See https://lsd.gnunet.org/lsd0012/draft-schanzen-cake.html) 169 */ 170 #define R_HS_TRAFFIC_STR "r hs traffic" 171 172 /** 173 * String for expanding IHTS 174 * (See https://lsd.gnunet.org/lsd0012/draft-schanzen-cake.html) 175 */ 176 #define I_HS_TRAFFIC_STR "i hs traffic" 177 178 /** 179 * String for expanding RATS 180 * (See https://lsd.gnunet.org/lsd0012/draft-schanzen-cake.html) 181 */ 182 #define R_AP_TRAFFIC_STR "r ap traffic" 183 184 /** 185 * String for expanding IATS 186 * (See https://lsd.gnunet.org/lsd0012/draft-schanzen-cake.html) 187 */ 188 #define I_AP_TRAFFIC_STR "i ap traffic" 189 190 /** 191 * String for expanding derived keys (Handshake and Early) 192 * (See https://lsd.gnunet.org/lsd0012/draft-schanzen-cake.html) 193 */ 194 #define DERIVED_STR "derived" 195 196 /** 197 * String for expanding fk_R used for ResponderFinished field 198 * (See https://lsd.gnunet.org/lsd0012/draft-schanzen-cake.html) 199 */ 200 #define R_FINISHED_STR "r finished" 201 202 /** 203 * String for expanding fk_I used for InitiatorFinished field 204 * (See https://lsd.gnunet.org/lsd0012/draft-schanzen-cake.html) 205 */ 206 #define I_FINISHED_STR "i finished" 207 208 /** 209 * Labeled expand label for CAKE 210 */ 211 #define CAKE_LABEL "cake10" 212 213 /** 214 * String for expanding derived keys (Handshake and Early) 215 * (See https://lsd.gnunet.org/lsd0012/draft-schanzen-cake.html) 216 */ 217 #define KEY_STR "key" 218 219 /** 220 * String for expanding derived keys (Handshake and Early) 221 * (See https://lsd.gnunet.org/lsd0012/draft-schanzen-cake.html) 222 */ 223 #define TRAFFIC_UPD_STR "traffic upd" 224 225 /** 226 * String for expanding derived keys (Handshake and Early) 227 * (See https://lsd.gnunet.org/lsd0012/draft-schanzen-cake.html) 228 */ 229 #define IV_STR "iv" 230 231 232 /** 233 * Indicates whether a peer is in the initiating or receiving role. 234 */ 235 enum GSC_KX_Role 236 { 237 /* Peer is supposed to initiate the key exchange */ 238 ROLE_INITIATOR = 0, 239 240 /* Peer is supposed to wait for the key exchange */ 241 ROLE_RESPONDER = 1, 242 }; 243 244 245 /** 246 * Information about the status of a key exchange with another peer. 247 */ 248 struct GSC_KeyExchangeInfo 249 { 250 /** 251 * DLL. 252 */ 253 struct GSC_KeyExchangeInfo *next; 254 255 /** 256 * DLL. 257 */ 258 struct GSC_KeyExchangeInfo *prev; 259 260 /** 261 * Identity of the peer. 262 */ 263 struct GNUNET_PeerIdentity peer; 264 265 /** 266 * Message queue for sending messages to @a peer. 267 */ 268 struct GNUNET_MQ_Handle *mq; 269 270 /** 271 * Env for resending messages 272 */ 273 struct GNUNET_MQ_Envelope *resend_env; 274 275 /** 276 * Our message stream tokenizer (for encrypted payload). 277 */ 278 struct GNUNET_MessageStreamTokenizer *mst; 279 280 // TODO check ordering - might make it less confusing 281 // TODO consistent naming: ss_e, shared_secret_e or ephemeral_shared_secret? 282 // TODO consider making all the structs here pointers 283 // - they can be checked to be NULL 284 // - valgrind can detect memory issues better (I guess?) 285 286 /** 287 * Own role in the key exchange. Are we supposed to initiate or receive the 288 * handshake? 289 */ 290 enum GSC_KX_Role role; 291 292 // TODO 293 struct GNUNET_ShortHashCode ss_R; 294 struct GNUNET_ShortHashCode ss_e; 295 struct GNUNET_ShortHashCode ss_I; 296 297 /** 298 * Initiator secret key 299 */ 300 struct GNUNET_CRYPTO_HpkePrivateKey sk_e; 301 302 /** 303 * Initiator ephemeral key 304 */ 305 struct GNUNET_CRYPTO_HpkePublicKey pk_e; 306 307 /** 308 * Hash over the entire InitiatorHello we are currently answering, or all 309 * zeroes if there is none. A retransmitted flight is byte-identical to 310 * the one that was lost (#GNUNET_MQ_send_copy() of @e resend_env), so this 311 * is what tells a retransmission apart from a genuinely new exchange. 312 * Only meaningful while we are the responder. 313 */ 314 struct GNUNET_HashCode ih_hash; 315 316 /** 317 * Hash over the entire ResponderHello we are currently answering, or all 318 * zeroes if there is none. Counterpart of @e ih_hash; only meaningful 319 * while we are the initiator. 320 */ 321 struct GNUNET_HashCode rh_hash; 322 323 /** 324 * The transcript hash context. 325 * It is fed data from the handshake to be implicitly validated and used to 326 * derive key material. 327 */ 328 struct GNUNET_HashContext *transcript_hash_ctx; 329 330 /** 331 * ES - Early Secret Key 332 * TODO uniform naming: _key? 333 */ 334 struct GNUNET_ShortHashCode early_secret_key; 335 336 /** 337 * ETS - Early traffic secret 338 * TODO 339 */ 340 struct GNUNET_ShortHashCode early_traffic_secret; /* Decrypts InitiatorHello */ 341 342 /** 343 * HS - Handshake secret 344 * TODO 345 */ 346 struct GNUNET_ShortHashCode handshake_secret; 347 348 /** 349 * RHTS - Responder handshake secret 350 * TODO 351 */ 352 struct GNUNET_ShortHashCode rhts; 353 354 /** 355 * IHTS - Initiator handshake secret 356 * TODO 357 */ 358 struct GNUNET_ShortHashCode ihts; 359 360 /** 361 * Master secret key 362 * TODO 363 */ 364 struct GNUNET_ShortHashCode master_secret; 365 366 /** 367 * *ATS - our current application traffic secret by epoch 368 */ 369 struct GNUNET_ShortHashCode current_ats; 370 371 /** 372 * *ATS - other peers application traffic secret by epoch 373 */ 374 struct GNUNET_ShortHashCode their_ats[MAX_EPOCHS]; 375 376 /** 377 * Our currently used epoch for sending. 378 */ 379 uint64_t current_epoch; 380 381 /** 382 * Expiration time of our current epoch 383 */ 384 struct GNUNET_TIME_Absolute current_epoch_expiration; 385 386 /** 387 * Highest seen (or used) epoch of 388 * responder resp initiator.. 389 */ 390 uint64_t their_max_epoch; 391 392 /** 393 * Highest sequence number we have successfully deprotected in each 394 * epoch; the right edge of that epoch's anti-replay window. 395 * See RFC 9147, Section 4.5.1. 396 */ 397 uint64_t replay_max[MAX_EPOCHS]; 398 399 /** 400 * Anti-replay window for each epoch: bit @a k is set if the record with 401 * sequence number `replay_max[i] - k' has been deprotected. Bit 0 is 402 * `replay_max[i]' itself. See RFC 9147, Section 4.5.1. 403 */ 404 uint64_t replay_bitmap[MAX_EPOCHS]; 405 406 /** 407 * Our current sequence number 408 */ 409 uint64_t current_sqn; 410 411 /** 412 * When should the session time out (if there are no Acks to HEARTBEATs)? 413 */ 414 struct GNUNET_TIME_Absolute timeout; 415 416 /** 417 * Last time we notified monitors 418 */ 419 struct GNUNET_TIME_Absolute last_notify_timeout; 420 421 /** 422 * Task for resending messages during handshake. 423 */ 424 struct GNUNET_SCHEDULER_Task *resend_task; 425 426 /** 427 * How long to wait before the next retransmission of the handshake 428 * message in @e resend_env. Doubles with every retransmission, capped 429 * at #RESEND_TIMEOUT_MAX. See RFC 9147, Section 5.8. 430 */ 431 struct GNUNET_TIME_Relative resend_delay; 432 433 /** 434 * Resend tries left 435 */ 436 unsigned int resend_tries_left; 437 438 /** 439 * ID of task used for sending keep-alive pings. 440 * TODO still needed? 441 */ 442 struct GNUNET_SCHEDULER_Task *heartbeat_task; 443 444 /** 445 * Heartbeats sent since the last record we deprotected from this peer. 446 * Reset by #update_timeout(); once it reaches 447 * #MAX_UNANSWERED_HEARTBEATS the association is gone. 448 */ 449 unsigned int heartbeats_unanswered; 450 451 /** 452 * #GNUNET_YES if this peer currently has excess bandwidth. 453 * TODO still needed? 454 */ 455 int has_excess_bandwidth; 456 457 /** 458 * #GNUNET_YES once application traffic keys are installed for this peer, 459 * i.e. once we have an association in the sense of RFC 9147. 460 * 461 * This is deliberately *not* derived from @e status. RFC 9147, 462 * Section 5.11 requires that a peer which starts a new handshake over an 463 * existing association does not destroy that association until it has 464 * "demonstrated reachability [...] by completing a complete handshake 465 * including delivering a verifiable Finished message" -- so a handshake 466 * can be in flight while an association is up, and the record layer has 467 * to keep deprotecting records for the old epoch throughout. @e status 468 * tracks the handshake, this tracks the association. 469 */ 470 int association_up; 471 472 /** 473 * What is our connection state? 474 */ 475 enum GNUNET_CORE_KxState status; 476 477 /** 478 * Peer class of the other peer 479 * TODO still needed? 480 */ 481 enum GNUNET_CORE_PeerClass class; 482 483 }; 484 485 /** 486 * Transport service. 487 */ 488 static struct GNUNET_TRANSPORT_CoreHandle *transport; 489 490 /** 491 * DLL head. 492 */ 493 static struct GSC_KeyExchangeInfo *kx_head; 494 495 /** 496 * DLL tail. 497 */ 498 static struct GSC_KeyExchangeInfo *kx_tail; 499 500 /** 501 * Task scheduled for periodic re-generation (and thus rekeying) of our 502 * ephemeral key. 503 */ 504 static struct GNUNET_SCHEDULER_Task *rekey_task; 505 506 /** 507 * Notification context for broadcasting to monitors. 508 */ 509 static struct GNUNET_NotificationContext *nc; 510 511 /** 512 * Our services info string TODO 513 */ 514 static char *my_services_info = ""; 515 516 static void 517 buffer_clear (void *buf, size_t len) 518 { 519 #if HAVE_MEMSET_S 520 memset_s (buf, len, 0, len); 521 #elif HAVE_EXPLICIT_BZERO 522 explicit_bzero (buf, len); 523 #else 524 volatile unsigned char *p = buf; 525 while (len--) 526 *p++ = 0; 527 #endif 528 } 529 530 531 static void 532 cleanup_handshake_secrets (struct GSC_KeyExchangeInfo *kx) 533 { 534 buffer_clear (&kx->ihts, 535 sizeof kx->ihts); 536 buffer_clear (&kx->rhts, 537 sizeof kx->rhts); 538 buffer_clear (&kx->sk_e, 539 sizeof kx->sk_e); 540 buffer_clear (&kx->ss_I, 541 sizeof kx->ss_I); 542 buffer_clear (&kx->ss_R, 543 sizeof kx->ss_R); 544 buffer_clear (&kx->ss_e, 545 sizeof kx->ss_e); 546 buffer_clear (&kx->master_secret, 547 sizeof kx->master_secret); 548 buffer_clear (&kx->early_secret_key, 549 sizeof kx->early_secret_key); 550 buffer_clear (&kx->early_traffic_secret, 551 sizeof kx->early_traffic_secret); 552 buffer_clear (&kx->handshake_secret, 553 sizeof kx->handshake_secret); 554 } 555 556 557 /** 558 * Forget the anti-replay window of @a epoch. Called when the key material 559 * behind that slot of the epoch ring is replaced, either by a new 560 * association or by advancing past it, so that a sequence number is never 561 * checked against a window belonging to a different key. 562 * 563 * @param kx key exchange to update 564 * @param epoch epoch whose window to clear 565 */ 566 static void 567 replay_reset (struct GSC_KeyExchangeInfo *kx, 568 uint64_t epoch) 569 { 570 kx->replay_max[epoch % MAX_EPOCHS] = 0; 571 kx->replay_bitmap[epoch % MAX_EPOCHS] = 0; 572 } 573 574 575 /** 576 * Forget every anti-replay window (all of #MAX_EPOCHS). 577 * 578 * @param kx key exchange to update 579 */ 580 static void 581 replay_reset_all (struct GSC_KeyExchangeInfo *kx) 582 { 583 memset (kx->replay_max, 0, sizeof kx->replay_max); 584 memset (kx->replay_bitmap, 0, sizeof kx->replay_bitmap); 585 } 586 587 588 /** 589 * Would a record with sequence number @a sqn in @a epoch be a replay? 590 * 591 * RFC 9147, Section 4.5.1. Note this only *checks*: the window must not 592 * be updated until the record has been deprotected successfully, which is 593 * what #replay_commit() is for. 594 * 595 * @param kx key exchange the record arrived on 596 * @param epoch epoch the record claims 597 * @param sqn sequence number the record claims 598 * @return #GNUNET_OK if the record is new, #GNUNET_SYSERR if it is a 599 * replay or falls off the left edge of the window 600 */ 601 static enum GNUNET_GenericReturnValue 602 replay_check (const struct GSC_KeyExchangeInfo *kx, 603 uint64_t epoch, 604 uint64_t sqn) 605 { 606 unsigned int idx = epoch % MAX_EPOCHS; 607 uint64_t max = kx->replay_max[idx]; 608 uint64_t behind; 609 610 if (sqn > max) 611 return GNUNET_OK; /* to the right of the window */ 612 behind = max - sqn; 613 if (behind >= REPLAY_WINDOW_SIZE) 614 return GNUNET_SYSERR; /* too old to tell, so assume replay */ 615 if (0 != (kx->replay_bitmap[idx] & (1ULL << behind))) 616 return GNUNET_SYSERR; /* seen before */ 617 return GNUNET_OK; 618 } 619 620 621 /** 622 * Record that a record with sequence number @a sqn in @a epoch has been 623 * deprotected successfully, sliding the window right if needed. 624 * 625 * @param kx key exchange the record arrived on 626 * @param epoch epoch of the record 627 * @param sqn sequence number of the record 628 */ 629 static void 630 replay_commit (struct GSC_KeyExchangeInfo *kx, 631 uint64_t epoch, 632 uint64_t sqn) 633 { 634 unsigned int idx = epoch % MAX_EPOCHS; 635 uint64_t max = kx->replay_max[idx]; 636 uint64_t shift; 637 638 if (sqn > max) 639 { 640 shift = sqn - max; 641 kx->replay_bitmap[idx] = (shift >= REPLAY_WINDOW_SIZE) 642 ? 0 643 : (kx->replay_bitmap[idx] << shift); 644 kx->replay_bitmap[idx] |= 1ULL; 645 kx->replay_max[idx] = sqn; 646 return; 647 } 648 kx->replay_bitmap[idx] |= (1ULL << (max - sqn)); 649 } 650 651 652 static void 653 snapshot_transcript (const struct GNUNET_HashContext *ts_hash, 654 struct GNUNET_HashCode *snapshot) 655 { 656 struct GNUNET_HashContext *tmp; 657 658 tmp = GNUNET_CRYPTO_hash_context_copy (ts_hash); 659 GNUNET_CRYPTO_hash_context_finish (tmp, snapshot); 660 } 661 662 663 /** 664 * Inform all monitors about the KX state of the given peer. 665 * 666 * @param kx key exchange state to inform about 667 */ 668 static void 669 monitor_notify_all (struct GSC_KeyExchangeInfo *kx) 670 { 671 struct MonitorNotifyMessage msg; 672 673 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); 674 msg.header.size = htons (sizeof(msg)); 675 msg.state = htonl ((uint32_t) kx->status); 676 msg.peer = kx->peer; 677 msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout); 678 GNUNET_notification_context_broadcast (nc, &msg.header, GNUNET_NO); 679 kx->last_notify_timeout = kx->timeout; 680 } 681 682 683 static void 684 restart_kx (struct GSC_KeyExchangeInfo *kx); 685 686 /** 687 * Task triggered when a neighbour entry is about to time out 688 * (and we should prevent this by sending an Ack in response 689 * to a heartbeat). 690 * 691 * @param cls the `struct GSC_KeyExchangeInfo` 692 */ 693 static void 694 send_heartbeat (void *cls) 695 { 696 struct GSC_KeyExchangeInfo *kx = cls; 697 struct GNUNET_TIME_Relative retry; 698 struct GNUNET_TIME_Relative left; 699 struct Heartbeat hb; 700 701 kx->heartbeat_task = NULL; 702 left = GNUNET_TIME_absolute_get_remaining (kx->timeout); 703 /* A heartbeat is a probe, not a formality: #handle_heartbeat() answers 704 every one of them with an Ack, and that Ack is a record whose 705 deprotection runs #update_timeout() and clears the counter below. So 706 #MAX_UNANSWERED_HEARTBEATS of them in a row without a single record 707 coming back means the association is gone, whatever @e timeout still 708 says. Waiting for @e timeout regardless is what made a lost session 709 cost #GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT (5 min) to notice -- and 710 up to twice that to repair, because the peer that gives up first tears 711 its session down silently and the other one then has to run its own 712 full idle timeout before #restart_kx() gets a chance to re-run the 713 exchange over the virtual link that was there the whole time. */ 714 if ((0 == left.rel_value_us) || 715 (kx->heartbeats_unanswered >= MAX_UNANSWERED_HEARTBEATS)) 716 { 717 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 718 "Session with `%s' timed out (%u heartbeats unanswered)\n", 719 GNUNET_i2s (&kx->peer), 720 kx->heartbeats_unanswered); 721 GNUNET_STATISTICS_update (GSC_stats, 722 gettext_noop ("# sessions terminated by timeout"), 723 1, 724 GNUNET_NO); 725 GSC_SESSIONS_end (&kx->peer); 726 kx->status = GNUNET_CORE_KX_STATE_DOWN; 727 monitor_notify_all (kx); 728 restart_kx (kx); 729 return; 730 } 731 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 732 "Sending HEARTBEAT to `%s'\n", 733 GNUNET_i2s (&kx->peer)); 734 GNUNET_STATISTICS_update (GSC_stats, 735 gettext_noop ("# heartbeat messages sent"), 736 1, 737 GNUNET_NO); 738 hb.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_HEARTBEAT); 739 hb.header.size = htons (sizeof hb); 740 // FIXME when do we request update? 741 hb.flags = 0; 742 kx->heartbeats_unanswered++; 743 GSC_KX_encrypt_and_transmit (kx, &hb, sizeof hb); 744 if (GNUNET_YES != kx->association_up) 745 return; /* #check_rekey() tore it down and restarted the exchange */ 746 /* Do not let @e timeout stretch the probe interval: the point of the 747 counter above is that the answer, not the clock, decides. */ 748 retry = GNUNET_TIME_relative_max (GNUNET_TIME_relative_min ( 749 HEARTBEAT_PROBE_FREQUENCY, 750 left), 751 MIN_HEARTBEAT_FREQUENCY); 752 kx->heartbeat_task = 753 GNUNET_SCHEDULER_add_delayed (retry, &send_heartbeat, kx); 754 } 755 756 757 /** 758 * We've seen a valid message from the other peer. 759 * Update the time when the session would time out 760 * and delay sending our keep alive message further. 761 * 762 * @param kx key exchange where we saw activity 763 */ 764 static void 765 update_timeout (struct GSC_KeyExchangeInfo *kx) 766 { 767 struct GNUNET_TIME_Relative delta; 768 769 kx->timeout = 770 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 771 delta = 772 GNUNET_TIME_absolute_get_difference (kx->last_notify_timeout, kx->timeout); 773 if (delta.rel_value_us > 5LL * 1000LL * 1000LL) 774 { 775 /* we only notify monitors about timeout changes if those 776 are bigger than the threshold (5s) */ 777 monitor_notify_all (kx); 778 } 779 /* The peer answered, so nothing is outstanding any more. */ 780 kx->heartbeats_unanswered = 0; 781 if (NULL != kx->heartbeat_task) 782 GNUNET_SCHEDULER_cancel (kx->heartbeat_task); 783 /* Probe again #HEARTBEAT_PROBE_FREQUENCY after the last thing we heard, 784 not halfway to @e timeout: an idle association that is fine costs one 785 heartbeat and one Ack per interval, while one that is not is noticed 786 within #MAX_UNANSWERED_HEARTBEATS intervals instead of after the full 787 #GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT. A link carrying traffic 788 re-arms this on every record and so still never sends one. */ 789 kx->heartbeat_task = GNUNET_SCHEDULER_add_delayed (HEARTBEAT_PROBE_FREQUENCY, 790 &send_heartbeat, 791 kx); 792 } 793 794 795 /** 796 * Send initiator hello 797 * 798 * @param kx key exchange context 799 */ 800 static void 801 send_initiator_hello (struct GSC_KeyExchangeInfo *kx); 802 803 804 /** 805 * Deliver P2P message to interested clients. Invokes send twice, 806 * once for clients that want the full message, and once for clients 807 * that only want the header 808 * 809 * @param cls the `struct GSC_KeyExchangeInfo` 810 * @param m the message 811 * @return #GNUNET_OK on success, 812 * #GNUNET_NO to stop further processing (no error) 813 * #GNUNET_SYSERR to stop further processing with error 814 */ 815 static int 816 deliver_message (void *cls, const struct GNUNET_MessageHeader *m) 817 { 818 struct GSC_KeyExchangeInfo *kx = cls; 819 820 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 821 "Decrypted message of type %d from %s\n", 822 ntohs (m->type), 823 GNUNET_i2s (&kx->peer)); 824 GSC_CLIENTS_deliver_message (&kx->peer, 825 m, 826 ntohs (m->size), 827 GNUNET_CORE_OPTION_SEND_FULL_INBOUND); 828 GSC_CLIENTS_deliver_message (&kx->peer, 829 m, 830 sizeof(struct GNUNET_MessageHeader), 831 GNUNET_CORE_OPTION_SEND_HDR_INBOUND); 832 return GNUNET_OK; 833 } 834 835 836 /** 837 * Arm @e resend_task for the next retransmission of the flight in 838 * @e resend_env and back the timer off for the one after that. 839 * 840 * RFC 9147, Section 5.8: "implementations SHOULD use an initial timer 841 * value of 1000 ms and double the value at each retransmission, up to no 842 * less than 60 seconds." 843 * 844 * @param kx key exchange whose flight to schedule 845 * @param cb task to run when the timer fires 846 */ 847 static void 848 schedule_resend (struct GSC_KeyExchangeInfo *kx, 849 GNUNET_SCHEDULER_TaskCallback cb) 850 { 851 GNUNET_assert (NULL == kx->resend_task); 852 kx->resend_task = GNUNET_SCHEDULER_add_delayed (kx->resend_delay, cb, kx); 853 kx->resend_delay = 854 GNUNET_TIME_relative_min (RESEND_TIMEOUT_MAX, 855 GNUNET_TIME_relative_multiply (kx->resend_delay, 856 2)); 857 } 858 859 860 /** 861 * Start a handshake flight: @a kx will retransmit it #RESEND_MAX_TRIES 862 * times, starting after #RESEND_TIMEOUT and backing off from there. 863 * 864 * @param kx key exchange whose flight to start 865 * @param cb task to run when the timer fires 866 */ 867 static void 868 start_resend (struct GSC_KeyExchangeInfo *kx, 869 GNUNET_SCHEDULER_TaskCallback cb) 870 { 871 kx->resend_tries_left = RESEND_MAX_TRIES; 872 kx->resend_delay = RESEND_TIMEOUT; 873 schedule_resend (kx, cb); 874 } 875 876 877 /** 878 * Discard the state of the handshake @a kx is in the middle of, so that a 879 * new one can be started. Deliberately leaves the *session* -- traffic 880 * keys, @e heartbeat_task, @e timeout, what clients were told -- alone: 881 * those stay valid until a new handshake actually completes. 882 * 883 * @param kx key exchange whose handshake state to drop 884 */ 885 static void 886 reset_handshake (struct GSC_KeyExchangeInfo *kx) 887 { 888 /* Any handshake message we were still resending belongs to the exchange 889 we are abandoning here. #send_initiator_hello() / 890 #send_responder_hello() overwrite @e resend_env and @e resend_task 891 without clearing them first, so without this the old envelope leaks 892 and -- worse -- the old task keeps running with its handle lost: a 893 second resend chain that no GNUNET_SCHEDULER_cancel() can reach, still 894 firing on @a kx after #handle_transport_notify_disconnect() has freed 895 it. */ 896 if (NULL != kx->resend_task) 897 { 898 GNUNET_SCHEDULER_cancel (kx->resend_task); 899 kx->resend_task = NULL; 900 } 901 if (NULL != kx->resend_env) 902 { 903 GNUNET_MQ_discard (kx->resend_env); 904 kx->resend_env = NULL; 905 } 906 if (NULL != kx->transcript_hash_ctx) 907 { 908 GNUNET_CRYPTO_hash_context_abort (kx->transcript_hash_ctx); 909 kx->transcript_hash_ctx = NULL; 910 } 911 /* There is no flight to recognise a retransmission of any more. */ 912 memset (&kx->ih_hash, 0, sizeof (kx->ih_hash)); 913 memset (&kx->rh_hash, 0, sizeof (kx->rh_hash)); 914 cleanup_handshake_secrets (kx); 915 } 916 917 918 /** 919 * Give up on the exchange @a kx is in *and* on the session it may have 920 * established, and return it to a state in which a fresh handshake can be 921 * run. Leaves @a kx in #GNUNET_CORE_KX_STATE_DOWN without notifying 922 * monitors; every caller either moves on to a new state right away or 923 * notifies itself. 924 * 925 * @param kx key exchange to reset 926 */ 927 static void 928 abandon_exchange (struct GSC_KeyExchangeInfo *kx) 929 { 930 reset_handshake (kx); 931 GSC_SESSIONS_end (&kx->peer); 932 kx->association_up = GNUNET_NO; 933 /* An armed heartbeat task belongs to the association we are dropping 934 here. Left behind it keeps encrypting heartbeats with key material 935 that is no longer current, and #handle_initiator_done() would find it 936 still set. */ 937 if (NULL != kx->heartbeat_task) 938 { 939 GNUNET_SCHEDULER_cancel (kx->heartbeat_task); 940 kx->heartbeat_task = NULL; 941 } 942 kx->heartbeats_unanswered = 0; 943 /* A new association starts over at epoch 0 and sequence number 0. 944 Carrying @e their_max_epoch of a long-lived predecessor into it makes 945 #handle_encrypted_message() reject the first records of the new one as 946 "too old", and a stale anti-replay window would reject them as 947 replays. */ 948 kx->their_max_epoch = 0; 949 kx->current_epoch = 0; 950 kx->current_sqn = 0; 951 replay_reset_all (kx); 952 kx->status = GNUNET_CORE_KX_STATE_DOWN; 953 } 954 955 956 static void 957 restart_kx (struct GSC_KeyExchangeInfo *kx) 958 { 959 const struct GNUNET_HashCode *my_identity_hash; 960 struct GNUNET_HashCode h1; 961 962 // TODO what happens if we're in the middle of a peer id change? 963 // TODO there's a small chance this gets already called when we don't have a 964 // peer id yet. Add a kx, insert into the list, mark it as to be completed 965 // and let the callback to pils finish the rest once we got the peer id 966 967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 968 "Initiating key exchange with peer %s\n", 969 GNUNET_i2s (&kx->peer)); 970 GNUNET_STATISTICS_update (GSC_stats, 971 gettext_noop ("# key exchanges initiated"), 972 1, 973 GNUNET_NO); 974 975 /* Whatever we still had -- an exchange in progress, an established 976 session, an armed heartbeat -- does not survive this. Drop it before 977 telling monitors where we are, so that they do not see the state of the 978 exchange we are leaving reported as if it were still current: that is 979 why a restart from #GNUNET_CORE_KX_STATE_INITIATOR_HELLO_SENT used to 980 show up as two consecutive "Hello sent (I)" notifications. */ 981 abandon_exchange (kx); 982 monitor_notify_all (kx); 983 my_identity_hash = GNUNET_PILS_get_identity_hash (GSC_pils); 984 GNUNET_assert (NULL != my_identity_hash); 985 GNUNET_CRYPTO_hash (&kx->peer, sizeof(struct GNUNET_PeerIdentity), &h1); 986 if (0 < GNUNET_CRYPTO_hash_cmp (&h1, my_identity_hash)) 987 { 988 /* peer with "lower" identity starts KX, otherwise we typically end up 989 with both peers starting the exchange and transmit the 'set key' 990 message twice */ 991 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 992 "I am the initiator, sending hello\n"); 993 kx->role = ROLE_INITIATOR; 994 send_initiator_hello (kx); 995 } 996 else 997 { 998 /* peer with "higher" identity starts a delayed KX, if the "lower" peer 999 * does not start a KX since it sees no reasons to do so */ 1000 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1001 "I am the responder, yielding and await initiator hello\n"); 1002 kx->status = GNUNET_CORE_KX_STATE_AWAIT_INITIATION; 1003 kx->role = ROLE_RESPONDER; 1004 monitor_notify_all (kx); 1005 } 1006 } 1007 1008 1009 /** 1010 * Function called by transport to notify us that 1011 * a peer connected to us (on the network level). 1012 * Starts the key exchange with the given peer. 1013 * 1014 * @param cls closure (NULL) 1015 * @param mq message queue towards peer 1016 * @param peer_id (optional, may be NULL) the peer id of the connecting peer 1017 * @return key exchange information context 1018 */ 1019 static void * 1020 handle_transport_notify_connect (void *cls, 1021 const struct GNUNET_PeerIdentity *peer_id, 1022 struct GNUNET_MQ_Handle *mq) 1023 { 1024 const struct GNUNET_PeerIdentity *my_identity; 1025 struct GSC_KeyExchangeInfo *kx; 1026 (void) cls; 1027 my_identity = GNUNET_PILS_get_identity (GSC_pils); 1028 GNUNET_assert (NULL != my_identity); 1029 if (0 == memcmp (peer_id, my_identity, sizeof *peer_id)) 1030 { 1031 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1032 "Ignoring connection to self\n"); 1033 return NULL; 1034 } 1035 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1036 "Incoming connection of peer with %s\n", 1037 GNUNET_i2s (peer_id)); 1038 1039 /* Set up kx struct */ 1040 kx = GNUNET_new (struct GSC_KeyExchangeInfo); 1041 kx->mst = GNUNET_MST_create (&deliver_message, kx); 1042 kx->mq = mq; 1043 GNUNET_memcpy (&kx->peer, peer_id, sizeof (struct GNUNET_PeerIdentity)); 1044 GNUNET_CONTAINER_DLL_insert (kx_head, kx_tail, kx); 1045 1046 restart_kx (kx); 1047 return kx; 1048 } 1049 1050 1051 /** 1052 * TODO 1053 * propose a new scheme: don't choose an initiator and responder based on 1054 * hashing the peer ids, but: 1055 * let each peer be their own initiator (and responder) when opening a channel 1056 * towards another peer. It should be fine to have two channels in 'both 1057 * directions' (one as responder, one as initiator) under the hood. This can be 1058 * opaque to the upper layers. 1059 * FIXME: (MSC) This is probably a bad idea in terms of security of the AKE! 1060 */ 1061 1062 /** 1063 * Schedule for 1064 * - forwarding the transcript hash context and 1065 * - deriving/generating keys/finished fields 1066 * 1067 * Forwarding: Deriving Messages 1068 * -> pk_e 1069 * -> c_R 1070 * -> r_I 1071 * -> H(pk_R) 1072 * -> ETS 1073 * -> {pk_I, svcinfo_I}ETS 1074 * ---------------------------------------------------- send InitiatorHello 1075 * -> c_e 1076 * -> r_R 1077 * -> *HTS 1078 * -> {svcinfo_R, c_I}RHTS 1079 * -> finished_R 1080 * -> {finished_R}RHTS 1081 * -> finished_I 1082 * -> RATS_0 1083 * -> [{payload}RATS] 1084 * ---------------------------------------------------- send ResponderHello 1085 * -> {finished_I}IHTS 1086 * -> IATS_0 1087 * ---------------------------------------------------- send InitiatorDone 1088 */ 1089 1090 // TODO find a way to assert that a key is not yet existing before generating 1091 // TODO find a way to assert that a key is not already existing before using 1092 /* 1093 * Derive early secret and transport secret. 1094 * @param kx the key exchange info 1095 */ 1096 static void 1097 derive_es_ets (const struct GNUNET_HashCode *transcript, 1098 const struct GNUNET_ShortHashCode *ss_R, 1099 struct GNUNET_ShortHashCode *es, 1100 struct GNUNET_ShortHashCode *ets) 1101 { 1102 uint64_t ret; 1103 1104 ret = GNUNET_CRYPTO_hkdf_extract (es, // prk 1105 0, // salt 1106 0, // salt_len 1107 ss_R, // ikm - initial key material 1108 sizeof (*ss_R)); 1109 if (GNUNET_OK != ret) 1110 { 1111 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Something went wrong extracting ES\n") 1112 ; 1113 GNUNET_assert (0); 1114 } 1115 ret = GNUNET_CRYPTO_hkdf_expand ( 1116 ets, 1117 sizeof (*ets), 1118 es, 1119 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1120 GNUNET_CRYPTO_kdf_arg_string (EARLY_DATA_STR), 1121 GNUNET_CRYPTO_kdf_arg_auto (transcript)); 1122 if (GNUNET_OK != ret) 1123 { 1124 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Something went wrong expanding ETS\n") 1125 ; 1126 GNUNET_assert (0); 1127 } 1128 } 1129 1130 1131 /* 1132 * Derive early secret and transport secret. 1133 * @param kx the key exchange info 1134 */ 1135 static void 1136 derive_sn (const struct GNUNET_ShortHashCode *secret, 1137 unsigned char*sn, 1138 size_t sn_len) 1139 { 1140 GNUNET_assert (GNUNET_OK == 1141 GNUNET_CRYPTO_hkdf_expand ( 1142 sn, 1143 sn_len, 1144 secret, 1145 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1146 GNUNET_CRYPTO_kdf_arg_string ("sn"))); 1147 } 1148 1149 1150 /** 1151 * Derive the handshake secret 1152 * @param kx key exchange info 1153 */ 1154 static void 1155 derive_hs (const struct GNUNET_ShortHashCode *es, 1156 const struct GNUNET_ShortHashCode *ss_e, 1157 struct GNUNET_ShortHashCode *handshake_secret) 1158 { 1159 uint64_t ret; 1160 struct GNUNET_ShortHashCode derived_early_secret; 1161 1162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deriving HS\n"); 1163 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ES: %s\n", GNUNET_B2S (es) 1164 ); 1165 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ss_e: %s\n", GNUNET_B2S (ss_e)); 1166 ret = GNUNET_CRYPTO_hkdf_expand ( 1167 &derived_early_secret, 1168 sizeof (derived_early_secret), 1169 es, 1170 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1171 GNUNET_CRYPTO_kdf_arg_string (DERIVED_STR)); 1172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "dES: %s\n", GNUNET_B2S (& 1173 derived_early_secret)); 1174 if (GNUNET_OK != ret) 1175 { 1176 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Something went wrong expanding dES\n") 1177 ; 1178 GNUNET_assert (0); 1179 } 1180 // Handshake secret 1181 // TODO check: are dES the salt and ss_e the ikm or other way round? 1182 ret = GNUNET_CRYPTO_hkdf_extract (handshake_secret, // prk 1183 &derived_early_secret, // salt - dES 1184 sizeof (derived_early_secret), // salt_len 1185 ss_e, // ikm - initial key material 1186 sizeof (*ss_e)); 1187 if (GNUNET_OK != ret) 1188 { 1189 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Something went wrong extracting HS\n") 1190 ; 1191 GNUNET_assert (0); 1192 } 1193 } 1194 1195 1196 /** 1197 * Derive the initiator handshake secret 1198 * @param kx key exchange info 1199 */ 1200 static void 1201 derive_ihts (const struct GNUNET_HashCode *transcript, 1202 const struct GNUNET_ShortHashCode *hs, 1203 struct GNUNET_ShortHashCode *ihts) 1204 { 1205 GNUNET_assert (GNUNET_OK == 1206 GNUNET_CRYPTO_hkdf_expand ( 1207 ihts, // result 1208 sizeof (*ihts), // result len 1209 hs, // prk? 1210 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1211 GNUNET_CRYPTO_kdf_arg_string (I_HS_TRAFFIC_STR), 1212 GNUNET_CRYPTO_kdf_arg_auto (transcript))); 1213 } 1214 1215 1216 /** 1217 * Derive the responder handshake secret 1218 * @param kx key exchange info 1219 */ 1220 static void 1221 derive_rhts (const struct GNUNET_HashCode *transcript, 1222 const struct GNUNET_ShortHashCode *hs, 1223 struct GNUNET_ShortHashCode *rhts) 1224 { 1225 GNUNET_assert (GNUNET_OK == 1226 GNUNET_CRYPTO_hkdf_expand ( 1227 rhts, 1228 sizeof (*rhts), 1229 hs, // prk? TODO 1230 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1231 GNUNET_CRYPTO_kdf_arg_string (R_HS_TRAFFIC_STR), 1232 GNUNET_CRYPTO_kdf_arg_auto (transcript))); 1233 } 1234 1235 1236 /** 1237 * Derive the master secret 1238 * @param kx key exchange info 1239 */ 1240 static void 1241 derive_ms (const struct GNUNET_ShortHashCode *hs, 1242 const struct GNUNET_ShortHashCode *ss_I, 1243 struct GNUNET_ShortHashCode *ms) 1244 { 1245 uint64_t ret; 1246 struct GNUNET_ShortHashCode derived_handshake_secret; 1247 1248 ret = GNUNET_CRYPTO_hkdf_expand ( 1249 &derived_handshake_secret, 1250 sizeof (derived_handshake_secret), 1251 hs, 1252 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1253 GNUNET_CRYPTO_kdf_arg_string (DERIVED_STR)); 1254 if (GNUNET_OK != ret) 1255 { 1256 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Something went wrong expanding dHS\n") 1257 ; 1258 GNUNET_assert (0); 1259 } 1260 // TODO check: are dHS the salt and ss_I the ikm or other way round? 1261 ret = GNUNET_CRYPTO_hkdf_extract (ms, // prk 1262 &derived_handshake_secret, // salt - dHS 1263 sizeof (derived_handshake_secret), // salt_len 1264 ss_I, // ikm - initial key material 1265 sizeof (*ss_I)); 1266 if (GNUNET_OK != ret) 1267 { 1268 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Something went wrong extracting MS\n") 1269 ; 1270 GNUNET_assert (0); 1271 } 1272 } 1273 1274 1275 /** 1276 * Generate per record nonce as per 1277 * https://www.rfc-editor.org/rfc/rfc8446#section-5.3 1278 * using per key nonce and sequence number 1279 */ 1280 static void 1281 generate_per_record_nonce ( 1282 uint64_t seq, 1283 const uint8_t write_iv[AEAD_NONCE_BYTES], 1284 uint8_t per_record_write_iv[AEAD_NONCE_BYTES]) 1285 { 1286 uint64_t seq_nbo; 1287 uint64_t *write_iv_ptr; 1288 unsigned int byte_offset; 1289 1290 seq_nbo = GNUNET_htonll (seq); 1291 memcpy (per_record_write_iv, 1292 write_iv, 1293 AEAD_NONCE_BYTES); 1294 byte_offset = 1295 AEAD_NONCE_BYTES - sizeof (uint64_t); 1296 write_iv_ptr = (uint64_t*) (per_record_write_iv + byte_offset); 1297 *write_iv_ptr ^= seq_nbo; 1298 } 1299 1300 1301 /** 1302 * key = HKDF-Expand [I,R][A,H]TS, "key", 32) 1303 * nonce = HKDF-Expand ([I,R][A,H]TS, "iv", 24) 1304 */ 1305 static void 1306 derive_per_message_secrets ( 1307 const struct GNUNET_ShortHashCode *ts, 1308 uint64_t seq, 1309 unsigned char key[AEAD_KEY_BYTES], 1310 unsigned char nonce[AEAD_NONCE_BYTES]) 1311 { 1312 unsigned char nonce_tmp[AEAD_NONCE_BYTES]; 1313 /* derive actual key */ 1314 GNUNET_assert (GNUNET_OK == 1315 GNUNET_CRYPTO_hkdf_expand ( 1316 key, 1317 AEAD_KEY_BYTES, 1318 ts, 1319 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1320 GNUNET_CRYPTO_kdf_arg_string (KEY_STR))); 1321 1322 /* derive nonce */ 1323 GNUNET_assert (GNUNET_OK == 1324 GNUNET_CRYPTO_hkdf_expand ( 1325 nonce_tmp, 1326 AEAD_NONCE_BYTES, 1327 ts, 1328 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1329 GNUNET_CRYPTO_kdf_arg_string (IV_STR))); 1330 generate_per_record_nonce (seq, 1331 nonce_tmp, 1332 nonce); 1333 } 1334 1335 1336 /** 1337 * Derive the next application secret 1338 * @param kx key exchange info 1339 */ 1340 static void 1341 derive_next_ats (const struct GNUNET_ShortHashCode *old_ats, 1342 struct GNUNET_ShortHashCode *new_ats) 1343 { 1344 int8_t ret; 1345 1346 // FIXME: Not sure of PRK and output may overlap here! 1347 ret = GNUNET_CRYPTO_hkdf_expand ( 1348 new_ats, 1349 sizeof (*new_ats), 1350 old_ats, 1351 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1352 GNUNET_CRYPTO_kdf_arg_string (TRAFFIC_UPD_STR)); 1353 if (GNUNET_OK != ret) 1354 { 1355 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1356 "Something went wrong deriving next *ATS key\n"); 1357 GNUNET_assert (0); 1358 } 1359 } 1360 1361 1362 /** 1363 * Derive the initiator application secret 1364 * @param kx key exchange info 1365 */ 1366 static void 1367 derive_initial_ats (const struct GNUNET_HashCode *transcript, 1368 const struct GNUNET_ShortHashCode *ms, 1369 enum GSC_KX_Role role, 1370 struct GNUNET_ShortHashCode *initial_ats) 1371 { 1372 const char *traffic_str; 1373 1374 if (ROLE_INITIATOR == role) 1375 traffic_str = I_AP_TRAFFIC_STR; 1376 else 1377 traffic_str = R_AP_TRAFFIC_STR; 1378 GNUNET_assert (GNUNET_OK == 1379 GNUNET_CRYPTO_hkdf_expand ( 1380 initial_ats, // result 1381 sizeof (*initial_ats), // result len 1382 ms, 1383 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1384 GNUNET_CRYPTO_kdf_arg_string (traffic_str), 1385 GNUNET_CRYPTO_kdf_arg_auto (transcript))); 1386 } 1387 1388 1389 /** 1390 * Generate the responder finished field 1391 * @param kx key exchange info 1392 * @param result location to which the responder finished field will be written 1393 * to 1394 */ 1395 static void 1396 generate_responder_finished (const struct GNUNET_HashCode *transcript, 1397 const struct GNUNET_ShortHashCode *ms, 1398 struct GNUNET_HashCode *result) 1399 { 1400 enum GNUNET_GenericReturnValue ret; 1401 struct GNUNET_CRYPTO_AuthKey fk_R; // We might want to save this in kx? 1402 1403 ret = GNUNET_CRYPTO_hkdf_expand ( 1404 &fk_R, // result 1405 sizeof (fk_R), 1406 ms, 1407 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1408 GNUNET_CRYPTO_kdf_arg_string (R_FINISHED_STR)); 1409 if (GNUNET_OK != ret) 1410 { 1411 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1412 "Something went wrong expanding fk_R\n"); 1413 GNUNET_assert (0); 1414 } 1415 1416 GNUNET_CRYPTO_hmac (&fk_R, 1417 transcript, 1418 sizeof (*transcript), 1419 result); 1420 } 1421 1422 1423 /** 1424 * Generate the initiator finished field 1425 * @param kx key exchange info 1426 * @param result location to which the initiator finished field will be written 1427 * to 1428 */ 1429 static void 1430 generate_initiator_finished (const struct GNUNET_HashCode *transcript, 1431 const struct GNUNET_ShortHashCode *ms, 1432 struct GNUNET_HashCode *result) 1433 { 1434 enum GNUNET_GenericReturnValue ret; 1435 struct GNUNET_CRYPTO_AuthKey fk_I; // We might want to save this in kx? 1436 1437 ret = GNUNET_CRYPTO_hkdf_expand ( 1438 &fk_I, // result 1439 sizeof (fk_I), 1440 ms, 1441 GNUNET_CRYPTO_kdf_arg_string (CAKE_LABEL), 1442 GNUNET_CRYPTO_kdf_arg_string (I_FINISHED_STR)); 1443 if (GNUNET_OK != ret) 1444 { 1445 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1446 "Something went wrong expanding fk_I\n"); 1447 GNUNET_assert (0); 1448 } 1449 GNUNET_CRYPTO_hmac (&fk_I, 1450 transcript, 1451 sizeof (*transcript), 1452 result); 1453 } 1454 1455 1456 static void 1457 resend_responder_hello (void *cls) 1458 { 1459 struct GSC_KeyExchangeInfo *kx = cls; 1460 1461 kx->resend_task = NULL; 1462 if (0 == kx->resend_tries_left) 1463 { 1464 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1465 "Restarting KX\n"); 1466 restart_kx (kx); 1467 return; 1468 } 1469 kx->resend_tries_left--; 1470 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1471 "Resending responder hello. Retries left: %u\n", 1472 kx->resend_tries_left); 1473 GNUNET_MQ_send_copy (kx->mq, kx->resend_env); 1474 schedule_resend (kx, &resend_responder_hello); 1475 } 1476 1477 1478 void 1479 send_responder_hello (struct GSC_KeyExchangeInfo *kx) 1480 { 1481 enum GNUNET_GenericReturnValue ret; 1482 struct GNUNET_CRYPTO_HpkeEncapsulation c_I; 1483 struct ResponderHello *rhm_e; /* responder hello message - encrypted pointer */ 1484 struct GNUNET_MQ_Envelope *env; 1485 struct GNUNET_CRYPTO_HpkeEncapsulation ephemeral_kem_challenge; 1486 struct GNUNET_ShortHashCode rhts; 1487 struct GNUNET_ShortHashCode ihts; 1488 struct GNUNET_ShortHashCode hs; 1489 struct GNUNET_ShortHashCode ms; 1490 struct GNUNET_ShortHashCode ss_e; 1491 struct GNUNET_ShortHashCode ss_I; 1492 struct GNUNET_HashContext *hc; 1493 unsigned char enc_key[AEAD_KEY_BYTES]; 1494 unsigned char enc_nonce[AEAD_NONCE_BYTES]; 1495 1496 // 4. encaps -> shared_secret_e, c_e (kemChallenge) 1497 // TODO potentially write this directly into rhm? 1498 ret = GNUNET_CRYPTO_hpke_kem_encaps (&kx->pk_e, // public ephemeral key of initiator 1499 &ephemeral_kem_challenge, // encapsulated key 1500 &ss_e); // key - ss_e 1501 if (GNUNET_OK != ret) 1502 { 1503 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1504 "Something went wrong encapsulating ss_e\n"); 1505 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 1506 return; 1507 } 1508 hc = GNUNET_CRYPTO_hash_context_copy (kx->transcript_hash_ctx); 1509 // 6. encaps -> shared_secret_I, c_I 1510 ret = GNUNET_CRYPTO_eddsa_kem_encaps (&kx->peer.public_key, // public key of I 1511 &c_I, // encapsulated key 1512 &ss_I); // where to write the key material 1513 if (GNUNET_OK != ret) 1514 { 1515 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1516 "Something went wrong encapsulating ss_I\n"); 1517 GNUNET_CRYPTO_hash_context_abort (hc); 1518 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 1519 return; 1520 } 1521 // 7. generate RHTS (responder_handshare_secret_key) and RATS (responder_application_traffic_secret_key) (section 5) 1522 { 1523 struct GNUNET_HashCode transcript; 1524 snapshot_transcript (hc, &transcript); 1525 #if DEBUG_KX 1526 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1527 "Transcript snapshot for derivation of HS, MS: `%s'\n", 1528 GNUNET_h2s (&transcript)); 1529 #endif 1530 derive_hs (&kx->early_secret_key, 1531 &ss_e, 1532 &hs); 1533 derive_ms (&hs, &ss_I, &ms); 1534 } 1535 1536 // send ResponderHello 1537 // TODO fill fields / services_info! 1538 // 1. r_R <- random 1539 struct ResponderHelloPayload *rhp; 1540 size_t rhp_len = sizeof (*rhp) + strlen (my_services_info); 1541 unsigned char rhp_buf[rhp_len]; 1542 size_t ct_len; 1543 1544 rhp = (struct ResponderHelloPayload*) rhp_buf; 1545 ct_len = rhp_len // ResponderHelloPayload, fist PT msg 1546 + sizeof (struct GNUNET_HashCode) // Finished hash, second PT msg 1547 + AEAD_TAG_BYTES * 2; // Two tags; 1548 env = GNUNET_MQ_msg_extra (rhm_e, 1549 ct_len, 1550 GNUNET_MESSAGE_TYPE_CORE_RESPONDER_HELLO); 1551 1552 rhm_e->r_R = 1553 GNUNET_CRYPTO_random_u64 (UINT64_MAX); 1554 1555 // c_e 1556 GNUNET_memcpy (&rhm_e->c_e, 1557 &ephemeral_kem_challenge, 1558 sizeof (ephemeral_kem_challenge)); 1559 GNUNET_CRYPTO_hash_context_read (hc, 1560 rhm_e, 1561 sizeof (struct ResponderHello)); 1562 // 2. Encrypt ServicesInfo and c_I with RHTS 1563 // derive RHTS 1564 { 1565 struct GNUNET_HashCode transcript; 1566 snapshot_transcript (hc, 1567 &transcript); 1568 #if DEBUG_KX 1569 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1570 "Transcript snapshot for derivation of *HTS: `%s'\n", 1571 GNUNET_h2s (&transcript)); 1572 #endif 1573 derive_rhts (&transcript, 1574 &hs, 1575 &rhts); 1576 derive_ihts (&transcript, 1577 &hs, 1578 &ihts); 1579 derive_per_message_secrets (&rhts, 1580 0, 1581 enc_key, 1582 enc_nonce); 1583 } 1584 // c_I 1585 GNUNET_memcpy (&rhp->c_I, &c_I, sizeof (c_I)); 1586 // Services info empty for now. 1587 GNUNET_memcpy (&rhp[1], 1588 my_services_info, 1589 strlen (my_services_info)); 1590 1591 { 1592 unsigned long long out_ct_len; 1593 struct GNUNET_HashCode finished; 1594 struct GNUNET_HashCode transcript; 1595 unsigned char *finished_buf; 1596 GNUNET_assert (0 == crypto_aead_xchacha20poly1305_ietf_encrypt ( 1597 (unsigned char*) &rhm_e[1], /* c - ciphertext */ 1598 &out_ct_len, /* clen_p */ 1599 rhp_buf, /* rhm_p - plaintext message */ 1600 rhp_len, // mlen 1601 NULL, 0, // ad, adlen // FIXME should this not be the other, unencrypted 1602 // fields? 1603 NULL, // nsec - unused 1604 enc_nonce, // npub - nonce // FIXME nonce can be reused 1605 enc_key)); // k - key RHTS 1606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1607 "Encrypted and wrote %llu bytes\n", 1608 out_ct_len); 1609 // 3. Create ResponderFinished (Section 6) 1610 // Derive fk_I <- HKDF-Expand (MS, "r finished", NULL) 1611 /* Forward the transcript */ 1612 /* {svcinfo, c_I}RHTS */ 1613 GNUNET_CRYPTO_hash_context_read ( 1614 hc, 1615 &rhm_e[1], 1616 out_ct_len); 1617 1618 finished_buf = ((unsigned char*) &rhm_e[1]) + out_ct_len; 1619 snapshot_transcript (hc, 1620 &transcript); 1621 #if DEBUG_KX 1622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1623 "Transcript snapshot for derivation of Rfinished: `%s'\n", 1624 GNUNET_h2s (&transcript)); 1625 #endif 1626 generate_responder_finished (&transcript, 1627 &ms, 1628 &finished); 1629 // 4. Encrypt ResponderFinished 1630 derive_per_message_secrets (&rhts, 1631 1, 1632 enc_key, 1633 enc_nonce); 1634 GNUNET_assert (0 == crypto_aead_xchacha20poly1305_ietf_encrypt ( 1635 finished_buf, /* c - ciphertext */ 1636 &out_ct_len, /* clen_p */ 1637 (unsigned char*) &finished, /* rhm_p - plaintext message */ 1638 sizeof (finished), // mlen 1639 NULL, 0, // ad, adlen // FIXME should this not be the other, unencrypted 1640 // fields? 1641 NULL, // nsec - unused 1642 enc_nonce, // npub 1643 enc_key)); // k - key RHTS 1644 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1645 "Encrypted and wrote %llu bytes\n", 1646 out_ct_len); 1647 /* Forward the transcript 1648 * after responder finished, 1649 * before deriving *ATS and generating finished_I 1650 * (finished_I will be generated when receiving the InitiatorFinished message 1651 * in order to check it) */ 1652 GNUNET_CRYPTO_hash_context_read ( 1653 hc, 1654 finished_buf, 1655 out_ct_len); 1656 // 5. optionally send application data - encrypted with RATS 1657 // We do not really have any application data, instead, we send the ACK 1658 snapshot_transcript (hc, 1659 &transcript); 1660 #if DEBUG_KX 1661 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1662 "Transcript snapshot for derivation of *ATS: `%s'\n", 1663 GNUNET_h2s (&transcript)); 1664 #endif 1665 derive_initial_ats (&transcript, 1666 &ms, 1667 ROLE_RESPONDER, 1668 &kx->current_ats); 1669 } 1670 /* Lock into struct */ 1671 GNUNET_CRYPTO_hash_context_abort (kx->transcript_hash_ctx); 1672 kx->transcript_hash_ctx = hc; 1673 kx->master_secret = ms; 1674 kx->handshake_secret = hs; 1675 kx->ss_e = ss_e; 1676 kx->ihts = ihts; 1677 kx->rhts = rhts; 1678 kx->ss_I = ss_I; 1679 kx->current_epoch = 0; 1680 kx->current_sqn = 0; 1681 derive_per_message_secrets (&kx->current_ats, 1682 kx->current_sqn, 1683 enc_key, 1684 enc_nonce); 1685 1686 GNUNET_MQ_send_copy (kx->mq, env); 1687 kx->resend_env = env; 1688 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent ResponderHello: %d %d\n", kx->role, 1689 kx->status); 1690 start_resend (kx, &resend_responder_hello); 1691 kx->status = GNUNET_CORE_KX_STATE_RESPONDER_HELLO_SENT; 1692 monitor_notify_all (kx); 1693 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 1694 } 1695 1696 1697 /** 1698 * Finish handling the InitiatorHello @a ihm_e now that @a ss_R, the 1699 * shared secret decapsulated with our peer identity's private key, is 1700 * available. 1701 * 1702 * @param kx key exchange the hello arrived on 1703 * @param ihm_e the InitiatorHello, still owned by the message handler 1704 * @param ss_R decapsulation of @a ihm_e's @e c_R 1705 */ 1706 static void 1707 handle_initiator_hello_cont (struct GSC_KeyExchangeInfo *kx, 1708 const struct InitiatorHello *ihm_e, 1709 const struct GNUNET_ShortHashCode *ss_R) 1710 { 1711 const struct GNUNET_HashCode *my_identity_hash; 1712 uint32_t ihm_len = ntohs (ihm_e->header.size); 1713 unsigned char enc_key[AEAD_KEY_BYTES]; 1714 unsigned char enc_nonce[AEAD_NONCE_BYTES]; 1715 struct GNUNET_PeerIdentity peer_before = kx->peer; 1716 struct GNUNET_HashCode h1; 1717 struct GNUNET_HashCode transcript; 1718 struct GNUNET_ShortHashCode es; 1719 struct GNUNET_ShortHashCode ets; 1720 enum GNUNET_GenericReturnValue ret; 1721 1722 GNUNET_memcpy (&kx->pk_e.ecdhe_key, 1723 &ihm_e->pk_e, 1724 sizeof (ihm_e->pk_e)); 1725 // 5. generate ETS (early_traffic_secret_key, decrypt pk_i 1726 // expand ETS <- expand ES <- extract ss_R 1727 // use ETS to decrypt 1728 1729 /* Forward the transcript hash context over the unencrypted fields to get it 1730 * to the same status that the initiator had when it needed to derive es and 1731 * ets for the encryption */ 1732 GNUNET_CRYPTO_hash_context_read ( 1733 kx->transcript_hash_ctx, 1734 ihm_e, 1735 sizeof (struct InitiatorHello)); 1736 snapshot_transcript (kx->transcript_hash_ctx, 1737 &transcript); 1738 #if DEBUG_KX 1739 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1740 "Transcript snapshot for derivation of ES, ETS: `%s'\n", 1741 GNUNET_h2s (&transcript)); 1742 #endif 1743 derive_es_ets (&transcript, ss_R, &es, &ets); 1744 derive_per_message_secrets (&ets, 1745 0, 1746 enc_key, 1747 enc_nonce); 1748 { 1749 struct InitiatorHelloPayload *ihmp; 1750 size_t ct_len = ihm_len - sizeof (struct InitiatorHello); 1751 unsigned char ihmp_buf[ct_len - AEAD_TAG_BYTES]; 1752 ihmp = (struct InitiatorHelloPayload*) ihmp_buf; 1753 ret = crypto_aead_xchacha20poly1305_ietf_decrypt ( 1754 ihmp_buf, // unsigned char *m 1755 NULL, // mlen_p message length 1756 NULL, // unsigned char *nsec - unused: NULL 1757 (unsigned char*) &ihm_e[1], // const unsigned char *c - ciphertext 1758 ct_len, // unsigned long long clen - length of ciphertext 1759 // mac, // const unsigned char *mac - authentication tag 1760 NULL, // const unsigned char *ad - additional data (optional) TODO those should be used, right? 1761 0, // unsigned long long adlen 1762 enc_nonce, // const unsigned char *npub - nonce 1763 enc_key // const unsigned char *k - key 1764 ); 1765 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pid_sender: %s\n", 1766 GNUNET_i2s (&ihmp->pk_I)); 1767 if (0 != ret) 1768 { 1769 GNUNET_log (DECRYPTION_FAILURES_LOG_LEVEL, 1770 "Something went wrong decrypting: %d\n", ret); 1771 GNUNET_break_op (0); 1772 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 1773 restart_kx (kx); 1774 return; 1775 } 1776 /* now forward it considering the encrypted messages that the initiator was 1777 * able to send after deriving the es and ets */ 1778 GNUNET_CRYPTO_hash_context_read (kx->transcript_hash_ctx, 1779 &ihm_e[1], 1780 ct_len); 1781 GNUNET_memcpy (&kx->peer, 1782 &ihmp->pk_I, 1783 sizeof (struct GNUNET_PeerIdentity)); 1784 } 1785 1786 /* @e pk_I is the initiator's *claim* about who it is, and nothing has 1787 checked it. It must be the peer transport handed us this @a kx for: 1788 @e role was derived from that identity, GSC_SESSIONS_create() below 1789 keys the session on it, and transport routes everything we send by it. 1790 Letting the claim through means one peer can make us run a session 1791 under another peer's identity, and -- via the role comparison right 1792 below, which is computed over exactly this value -- can pick a @e pk_I 1793 that sends us down the reject path at will. */ 1794 if (0 != GNUNET_memcmp (&kx->peer, &peer_before)) 1795 { 1796 GNUNET_break_op (0); 1797 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1798 "InitiatorHello from `%s' claims to be `%s'\n", 1799 GNUNET_i2s (&peer_before), 1800 GNUNET_i2s2 (&kx->peer)); 1801 kx->peer = peer_before; 1802 GNUNET_CRYPTO_hash_context_abort (kx->transcript_hash_ctx); 1803 kx->transcript_hash_ctx = NULL; 1804 kx->status = GNUNET_CORE_KX_STATE_AWAIT_INITIATION; 1805 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 1806 return; 1807 } 1808 1809 my_identity_hash = GNUNET_PILS_get_identity_hash (GSC_pils); 1810 GNUNET_assert (NULL != my_identity_hash); 1811 1812 // We could follow with the rest of the Key Schedule (dES, HS, ...) for now 1813 /* Check that we are actually in the receiving role */ 1814 GNUNET_CRYPTO_hash (&kx->peer, sizeof(struct GNUNET_PeerIdentity), &h1); 1815 if (0 < GNUNET_CRYPTO_hash_cmp (&h1, my_identity_hash)) 1816 { 1817 /* peer with "lower" identity starts KX, otherwise we typically end up 1818 with both peers starting the exchange and transmit the 'set key' 1819 message twice */ 1820 /* Something went wrong - we have the lower value and should have sent the 1821 * InitiatorHello, but instead received it. TODO handle this case 1822 * We might end up in this case if the initiator didn't initiate the 1823 * handshake long enough and the 'responder' initiates the handshake */ 1824 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1825 "Something went wrong - we have the lower value and should have sent the InitiatorHello, but instead received it.\n"); 1826 GNUNET_CRYPTO_hash_context_abort (kx->transcript_hash_ctx); 1827 kx->transcript_hash_ctx = NULL; 1828 /* Same reason the three other reject paths in #handle_initiator_hello() 1829 do this: that function set @e status to INITIATOR_HELLO_RECEIVED 1830 before calling us, and leaving it there makes every *later* hello hit 1831 the "Already received InitiatorHello" guard and be dropped, forever. 1832 Rejecting this hello must not cost us the next one. */ 1833 kx->status = GNUNET_CORE_KX_STATE_AWAIT_INITIATION; 1834 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 1835 return; 1836 } 1837 1838 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer ID of other peer: %s\n", GNUNET_i2s 1839 (&kx->peer)); 1840 /* We update the monitoring peers here because now we know 1841 * that we can decrypt the message AND know the PID 1842 */ 1843 monitor_notify_all (kx); 1844 kx->ss_R = *ss_R; 1845 kx->early_secret_key = es; 1846 kx->early_traffic_secret = ets; 1847 send_responder_hello (kx); 1848 } 1849 1850 1851 static int 1852 check_initiator_hello (void *cls, const struct InitiatorHello *m) 1853 { 1854 uint16_t size = ntohs (m->header.size); 1855 1856 if (size < sizeof (*m) 1857 + sizeof (struct InitiatorHelloPayload) 1858 + AEAD_TAG_BYTES) 1859 { 1860 return GNUNET_SYSERR; 1861 } 1862 return GNUNET_OK; 1863 } 1864 1865 1866 /** 1867 * Handle the InitiatorHello message 1868 * - derives necessary keys from the plaintext parts 1869 * - decrypts the encrypted part 1870 * - replies with ResponderHello message 1871 * @param cls the key exchange info 1872 * @param ihm_e InitiatorHello message 1873 */ 1874 static void 1875 handle_initiator_hello (void *cls, const struct InitiatorHello *ihm_e) 1876 { 1877 const struct GNUNET_HashCode *my_identity_hash; 1878 const struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; 1879 struct GSC_KeyExchangeInfo *kx = cls; 1880 struct GNUNET_HashCode ih_hash; 1881 struct GNUNET_ShortHashCode ss_R; 1882 size_t ihm_len; 1883 1884 ihm_len = ntohs (ihm_e->header.size); 1885 GNUNET_CRYPTO_hash (ihm_e, 1886 ihm_len, 1887 &ih_hash); 1888 if (ROLE_INITIATOR == kx->role) 1889 { 1890 GNUNET_break_op (0); 1891 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1892 "I am an initiator! Tearing down...\n"); 1893 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 1894 return; 1895 } 1896 if (kx->status == GNUNET_CORE_KX_STATE_INITIATOR_HELLO_RECEIVED) 1897 { 1898 /* Now that the decapsulation is synchronous nothing can observe this 1899 state from the outside -- #handle_initiator_hello_cont() runs before 1900 we return. Keep the guard anyway: reaching it means the state 1901 machine leaked a state, not that a peer did anything. */ 1902 GNUNET_break (0); 1903 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1904 "Already received InitiatorHello: %d %d\n", kx->role, kx->status 1905 ); 1906 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 1907 return; 1908 } 1909 else if (kx->status > GNUNET_CORE_KX_STATE_INITIATOR_HELLO_RECEIVED) 1910 { 1911 if (0 == GNUNET_memcmp (&ih_hash, 1912 &kx->ih_hash)) 1913 { 1914 /* Not a new exchange at all: the initiator resent the very hello we 1915 are already answering, because our ResponderHello did not make it 1916 back in time (#resend_initiator_hello() sends a copy of the same 1917 envelope, so a retransmission is byte-identical). 1918 1919 Starting over here is what breaks the pair. A fresh 1920 #send_responder_hello() picks a new @e ss_e and feeds a new 1921 ResponderHello into the transcript, and the transcript is what both 1922 @e finished_R and @e finished_I are computed over. The initiator 1923 answers whichever ResponderHello reaches it first and binds its 1924 InitiatorDone to *that* transcript, while we have moved on to the 1925 transcript of our latest one -- so #handle_initiator_done() cannot 1926 verify @e finished_I and drops it, every retransmission included. 1927 Neither side can make progress and neither side sees an error: the 1928 initiator sits in #GNUNET_CORE_KX_STATE_INITIATOR_DONE_SENT 1929 reporting "Unexpected ResponderHello", we sit in 1930 #GNUNET_CORE_KX_STATE_RESPONDER_HELLO_SENT, and both merely run out 1931 of retries after RESEND_MAX_TRIES and start over -- with no reason 1932 for the next attempt to be any luckier. One InitiatorHello 1933 retransmission, which any hiccup on the path produces, is enough to 1934 lose the peer indefinitely. 1935 1936 Retransmit our flight instead and leave the handshake state alone, 1937 per RFC 9147, Section 5.8: "implementations MUST retransmit their 1938 last flight in response to a retransmitted flight from the peer". 1939 Our own @e resend_task keeps its schedule; this only adds the 1940 answer the initiator is waiting for. */ 1941 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1942 "InitiatorHello repeated by `%s' in state %d\n", 1943 GNUNET_i2s (&kx->peer), 1944 kx->status); 1945 GNUNET_STATISTICS_update (GSC_stats, 1946 gettext_noop ( 1947 "# InitiatorHello retransmissions received"), 1948 1, 1949 GNUNET_NO); 1950 if ((GNUNET_CORE_KX_STATE_RESPONDER_HELLO_SENT == kx->status) && 1951 (NULL != kx->resend_env)) 1952 GNUNET_MQ_send_copy (kx->mq, 1953 kx->resend_env); 1954 /* Past that state the initiator already had our ResponderHello (we 1955 only leave it once @e finished_I verifies), so this is a duplicate 1956 that crossed with its InitiatorDone. Nothing to answer, and 1957 nothing that may cost us the association we just built. */ 1958 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 1959 return; 1960 } 1961 /* The initiator has given up on whatever we still hold and started 1962 over. Only the initiator drives this handshake, so follow it rather 1963 than dropping the hello. 1964 This used to return, which deadlocks the pair whenever we are in 1965 #GNUNET_CORE_KX_STATE_RESPONDER_CONNECTED: an InitiatorHello is not 1966 an EncryptedMessage and so does not refresh @e timeout, and nothing 1967 else ever leaves that state, so we would reject every retransmit 1968 until our own idle timeout fires -- five minutes during which the 1969 initiator restarts its exchange every 50s and we report the peer as 1970 connected. In #GNUNET_CORE_KX_STATE_RESPONDER_HELLO_SENT it is a 1971 plain retransmit: the initiator resends precisely because it did not 1972 get our ResponderHello, and answering the hello it actually sent 1973 converges instead of leaving both sides to turn over on unrelated 1974 50s timers that need not ever re-phase. 1975 1976 This is RFC 9147, Section 5.11: "In cases where a server believes it 1977 has an existing association [...] and it receives an epoch=0 1978 ClientHello, it SHOULD proceed with a new handshake but MUST NOT 1979 destroy the existing association until the client has demonstrated 1980 reachability [...] by completing a complete handshake including 1981 delivering a verifiable Finished message." 1982 1983 So only the handshake state goes. An InitiatorHello is not 1984 authenticated -- @e finished_I in the InitiatorDone is our Finished 1985 -- and must not be able to cost us an association on its own. What 1986 we have keeps its traffic keys (@e association_up stays set, and the 1987 record layer keys off that rather than off @e status), its 1988 @e heartbeat_task and its @e timeout, and clients keep being told the 1989 peer is connected. #handle_initiator_done() does the swap once, and 1990 only once, @e finished_I verifies. If it never does, the old 1991 association dies of its own idle timeout exactly as it would have. */ 1992 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1993 "Peer `%s' restarted the key exchange in state %d, following\n", 1994 GNUNET_i2s (&kx->peer), 1995 kx->status); 1996 reset_handshake (kx); 1997 } 1998 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received InitiatorHello: %d %d\n", kx-> 1999 role, kx->status); 2000 GNUNET_assert (NULL == kx->transcript_hash_ctx); 2001 kx->transcript_hash_ctx = GNUNET_CRYPTO_hash_context_start (); 2002 GNUNET_assert (NULL != kx->transcript_hash_ctx); 2003 2004 GNUNET_STATISTICS_update (GSC_stats, 2005 gettext_noop ("# key exchanges initiated"), 2006 1, 2007 GNUNET_NO); 2008 2009 kx->status = GNUNET_CORE_KX_STATE_INITIATOR_HELLO_RECEIVED; 2010 2011 my_identity_hash = GNUNET_PILS_get_identity_hash (GSC_pils); 2012 GNUNET_assert (NULL != my_identity_hash); 2013 2014 // 1. verify type _INITIATOR_HELLO 2015 // - This is implicytly done by arriving within this handler 2016 // - or is this about verifying the 'additional data' part of aead? 2017 // should it check the encryption + mac? (is this implicitly done 2018 // while decrypting?) 2019 // 2. verify H(pk_R) matches pk_R 2020 if (0 != memcmp (&ihm_e->h_pk_R, 2021 my_identity_hash, 2022 sizeof (struct GNUNET_HashCode))) 2023 { 2024 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2025 "This message is not meant for us (H(PID) mismatch)\n"); 2026 GNUNET_CRYPTO_hash_context_abort (kx->transcript_hash_ctx); 2027 kx->transcript_hash_ctx = NULL; 2028 /* Leaving @e status at #GNUNET_CORE_KX_STATE_INITIATOR_HELLO_RECEIVED 2029 here wedges the kx: every later hello then hits the "already 2030 received" guard above and is dropped, forever. */ 2031 kx->status = GNUNET_CORE_KX_STATE_AWAIT_INITIATION; 2032 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2033 return; 2034 } 2035 // FIXME this sometimes triggers in the tests - why? 2036 // 3. decaps -> shared_secret_R, c_R (kemChallenge) 2037 /* From here on this is the hello we answer, so a byte-identical one is a 2038 retransmission of it and must not restart the exchange. */ 2039 kx->ih_hash = ih_hash; 2040 my_private_key = GNUNET_PILS_get_private_key (GSC_pils); 2041 if (NULL == my_private_key) 2042 { 2043 /* #GSC_KX_start() enables local key access before we ever talk to 2044 TRANSPORT, so this means the key on disk does not match the identity 2045 PILS announced. We cannot answer any hello in that state. */ 2046 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2047 "No private key for our peer identity, cannot answer hello" 2048 " from `%s'\n", 2049 GNUNET_i2s (&kx->peer)); 2050 GNUNET_CRYPTO_hash_context_abort (kx->transcript_hash_ctx); 2051 kx->transcript_hash_ctx = NULL; 2052 kx->status = GNUNET_CORE_KX_STATE_AWAIT_INITIATION; 2053 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2054 return; 2055 } 2056 if (GNUNET_OK != 2057 GNUNET_CRYPTO_eddsa_kem_decaps (my_private_key, 2058 &ihm_e->c_R, 2059 &ss_R)) 2060 { 2061 GNUNET_break_op (0); 2062 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2063 "Failed to decapsulate c_R of hello from `%s'\n", 2064 GNUNET_i2s (&kx->peer)); 2065 GNUNET_CRYPTO_hash_context_abort (kx->transcript_hash_ctx); 2066 kx->transcript_hash_ctx = NULL; 2067 kx->status = GNUNET_CORE_KX_STATE_AWAIT_INITIATION; 2068 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2069 return; 2070 } 2071 handle_initiator_hello_cont (kx, 2072 ihm_e, 2073 &ss_R); 2074 } 2075 2076 2077 struct ResponderHelloCls 2078 { 2079 /* Current KX session */ 2080 struct GSC_KeyExchangeInfo *kx; 2081 2082 /* responder hello message - encrypted */ 2083 struct ResponderHello rhm_e; 2084 2085 /* responder hello message - plain/decrypted */ 2086 struct ResponderHelloPayload *rhp; 2087 2088 /* Decrypted finish hash */ 2089 struct GNUNET_HashCode decrypted_finish; 2090 2091 /* Encrypted finished CT (for transcript later) */ 2092 char finished_enc[sizeof (struct GNUNET_HashCode) 2093 + AEAD_TAG_BYTES]; 2094 2095 /* Temporary transcript context */ 2096 struct GNUNET_HashContext *hc; 2097 2098 /* Temporary handshake secret */ 2099 struct GNUNET_ShortHashCode hs; 2100 2101 /* Temporary handshake secret */ 2102 struct GNUNET_ShortHashCode ss_e; 2103 2104 /* Temporary handshake secret */ 2105 struct GNUNET_ShortHashCode ihts; 2106 2107 /* Temporary handshake secret */ 2108 struct GNUNET_ShortHashCode rhts; 2109 }; 2110 2111 static void 2112 resend_initiator_done (void *cls) 2113 { 2114 struct GSC_KeyExchangeInfo *kx = cls; 2115 2116 kx->resend_task = NULL; 2117 if (0 == kx->resend_tries_left) 2118 { 2119 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2120 "Restarting KX\n"); 2121 restart_kx (kx); 2122 return; 2123 } 2124 kx->resend_tries_left--; 2125 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2126 "Resending initiator done. Retries left: %u\n", 2127 kx->resend_tries_left); 2128 GNUNET_MQ_send_copy (kx->mq, kx->resend_env); 2129 schedule_resend (kx, &resend_initiator_done); 2130 } 2131 2132 2133 /** 2134 * Finish handling a ResponderHello now that @a ss_I, the shared secret 2135 * decapsulated with our peer identity's private key, is available. 2136 * 2137 * Takes ownership of @a rh_ctx. 2138 * 2139 * @param rh_ctx state accumulated by #handle_responder_hello() 2140 * @param ss_I decapsulation of the ResponderHello's @e c_I 2141 */ 2142 static void 2143 handle_responder_hello_cont (struct ResponderHelloCls *rh_ctx, 2144 const struct GNUNET_ShortHashCode *ss_I) 2145 { 2146 struct GSC_KeyExchangeInfo *kx = rh_ctx->kx; 2147 struct InitiatorDone *idm_e; /* encrypted */ 2148 struct InitiatorDone idm_local; 2149 struct InitiatorDone *idm_p; /* plaintext */ 2150 struct GNUNET_MQ_Envelope *env; 2151 unsigned char enc_key[AEAD_KEY_BYTES]; 2152 unsigned char enc_nonce[AEAD_NONCE_BYTES]; 2153 struct ConfirmationAck ack_i; 2154 struct GNUNET_HashCode transcript; 2155 struct GNUNET_ShortHashCode ms; 2156 2157 // XXX valgrind reports uninitialized memory 2158 // the following is a way to check whether this memory was meant 2159 // memset (&rhm_local, 0, sizeof (rhm_local)); - adapt to cls if still needed 2160 memset (&idm_local, 0, sizeof (idm_local)); 2161 2162 kx->ss_I = *ss_I; 2163 2164 /* derive *ATS */ 2165 derive_ms (&rh_ctx->hs, ss_I, &ms);; 2166 // 5. Create ResponderFinished as per Section 6 and check against decrypted payload. 2167 struct GNUNET_HashCode responder_finished; 2168 // Transcript updates, snapshot again 2169 snapshot_transcript (rh_ctx->hc, 2170 &transcript); 2171 #if DEBUG_KX 2172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2173 "Transcript snapshot for derivation of Rfinished: `%s'\n", 2174 GNUNET_h2s (&transcript)); 2175 #endif 2176 generate_responder_finished (&transcript, 2177 &ms, 2178 &responder_finished); 2179 if (0 != memcmp (&rh_ctx->decrypted_finish, 2180 &responder_finished, 2181 sizeof (struct GNUNET_HashCode))) 2182 { 2183 /* A peer that answers our InitiatorHello with a ResponderHello whose 2184 finished field does not verify must not be able to abort us; this 2185 used to be a GNUNET_assert (0). */ 2186 GNUNET_break_op (0); 2187 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2188 "Could not verify \"responder finished\" from `%s'\n", 2189 GNUNET_i2s (&kx->peer)); 2190 GNUNET_free (rh_ctx->rhp); 2191 GNUNET_CRYPTO_hash_context_abort (rh_ctx->hc); 2192 GNUNET_free (rh_ctx); 2193 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2194 restart_kx (kx); 2195 return; 2196 } 2197 2198 2199 /* Forward the transcript 2200 * after generating finished_R, 2201 * before deriving *ATS */ 2202 GNUNET_CRYPTO_hash_context_read ( 2203 rh_ctx->hc, 2204 rh_ctx->finished_enc, 2205 sizeof (rh_ctx->finished_enc)); 2206 2207 // At this point we cannot fail anymore and may lock into kx 2208 GNUNET_CRYPTO_hash_context_abort (kx->transcript_hash_ctx); 2209 kx->transcript_hash_ctx = rh_ctx->hc; 2210 kx->ss_I = *ss_I; 2211 kx->handshake_secret = rh_ctx->hs; 2212 kx->ss_e = rh_ctx->ss_e; 2213 kx->ihts = rh_ctx->ihts; 2214 kx->rhts = rh_ctx->rhts; 2215 kx->master_secret = ms; 2216 GNUNET_free (rh_ctx->rhp); 2217 GNUNET_free (rh_ctx); 2218 rh_ctx = NULL; 2219 2220 snapshot_transcript (kx->transcript_hash_ctx, 2221 &transcript); 2222 #if DEBUG_KX 2223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2224 "Transcript snapshot for derivation of *ATS: `%s'\n", 2225 GNUNET_h2s (&transcript)); 2226 #endif 2227 derive_initial_ats (&transcript, 2228 &kx->master_secret, 2229 ROLE_RESPONDER, 2230 &kx->their_ats[0]); 2231 for (int i = 0; i < MAX_EPOCHS - 1; i++) 2232 { 2233 derive_next_ats (&kx->their_ats[i], 2234 &kx->their_ats[i + 1]); 2235 } 2236 kx->their_max_epoch = MAX_EPOCHS - 1; 2237 2238 derive_per_message_secrets (&kx->ihts, 2239 0, 2240 enc_key, 2241 enc_nonce); 2242 /* Create InitiatorDone message */ 2243 idm_p = &idm_local; /* plaintext */ 2244 env = GNUNET_MQ_msg_extra (idm_e, 2245 sizeof (ack_i) 2246 + AEAD_TAG_BYTES, 2247 GNUNET_MESSAGE_TYPE_CORE_INITIATOR_DONE); 2248 // 6. Create IteratorFinished as per Section 6. 2249 generate_initiator_finished (&transcript, 2250 &kx->master_secret, 2251 &idm_p->finished); 2252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2253 "InteratorFinished: `%s'\n", 2254 GNUNET_h2s (&idm_p->finished)); 2255 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2256 "Transcript `%s'\n", 2257 GNUNET_h2s (&transcript)); 2258 // 7. Send InteratorFinished message encrypted with the key derived from IHTS to R 2259 2260 GNUNET_assert (0 == crypto_aead_xchacha20poly1305_ietf_encrypt ( 2261 (unsigned char*) &idm_e->finished, /* c - ciphertext */ 2262 NULL, /* clen_p */ 2263 (unsigned char*) &idm_p->finished, /* idm_p - plaintext message */ 2264 sizeof (idm_p->finished), // mlen 2265 NULL, 0, // ad, adlen // FIXME should this not be the other, unencrypted 2266 // fields? 2267 NULL, // nsec - unused 2268 enc_nonce, // npub - nonce 2269 enc_key)); // k - key IHTS 2270 /* Forward the transcript hash context 2271 * after generating finished_I and RATS_0 2272 * before deriving IATS_0 */ 2273 GNUNET_CRYPTO_hash_context_read (kx->transcript_hash_ctx, 2274 &idm_e->finished, 2275 sizeof (idm_e->finished) 2276 + AEAD_TAG_BYTES); 2277 snapshot_transcript (kx->transcript_hash_ctx, 2278 &transcript); 2279 #if DEBUG_KX 2280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2281 "Transcript snapshot for derivation of *ATS: `%s'\n", 2282 GNUNET_h2s (&transcript)); 2283 #endif 2284 derive_initial_ats (&transcript, 2285 &kx->master_secret, 2286 ROLE_INITIATOR, 2287 &kx->current_ats); 2288 kx->current_epoch = 0; 2289 kx->current_sqn = 0; 2290 /* We start sending under this epoch here, so it has to be dated here too. 2291 #check_if_ack_or_heartbeat() only sets @e current_epoch_expiration once 2292 the responder's Ack arrives; until then it holds whatever the previous 2293 association left (zero for a first exchange), and #check_rekey() treats 2294 a past expiration as "rekey now". Anything we send while waiting for 2295 the Ack -- the Ack we answer an early heartbeat with, say -- would then 2296 burn an epoch the responder has no reason to expect. */ 2297 kx->current_epoch_expiration = 2298 GNUNET_TIME_relative_to_absolute (EPOCH_EXPIRATION); 2299 /* Application traffic keys are installed, so from the record layer's 2300 point of view the association exists from here: we have to be able to 2301 deprotect the responder's Ack, which arrives before the handshake is 2302 confirmed. The client-visible session is created only once it does. */ 2303 replay_reset_all (kx); 2304 kx->association_up = GNUNET_YES; 2305 // 8. optionally encrypt payload TODO 2306 derive_per_message_secrets (&kx->current_ats, 2307 kx->current_sqn, 2308 enc_key, 2309 enc_nonce); 2310 kx->current_sqn++; 2311 ack_i.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ACK); 2312 ack_i.header.size = htons (sizeof ack_i); 2313 GNUNET_assert (0 == crypto_aead_xchacha20poly1305_ietf_encrypt ( 2314 (unsigned char*) &idm_e[1], /* c - ciphertext */ 2315 NULL, /* clen_p */ 2316 (unsigned char*) &ack_i, /* rhm_p - plaintext message */ 2317 sizeof ack_i, // mlen 2318 NULL, 0, // ad, adlen // FIXME should this not be the other, unencrypted 2319 // fields? 2320 NULL, // nsec - unused 2321 enc_nonce, // npub - nonce // FIXME nonce can be reused 2322 enc_key)); // k - key RHTS 2323 2324 GNUNET_MQ_send_copy (kx->mq, env); 2325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent InitiatorDone: %d %d\n", kx->role, 2326 kx->status); 2327 2328 2329 kx->resend_env = env; 2330 start_resend (kx, &resend_initiator_done); 2331 kx->status = GNUNET_CORE_KX_STATE_INITIATOR_DONE_SENT; 2332 monitor_notify_all (kx); 2333 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2334 } 2335 2336 2337 static int 2338 check_responder_hello (void *cls, const struct ResponderHello *m) 2339 { 2340 uint16_t size = ntohs (m->header.size); 2341 2342 if (size < sizeof (*m) 2343 + sizeof (struct ResponderHelloPayload) 2344 + sizeof (struct GNUNET_HashCode) 2345 + AEAD_TAG_BYTES * 2) 2346 { 2347 return GNUNET_SYSERR; 2348 } 2349 return GNUNET_OK; 2350 } 2351 2352 2353 /** 2354 * Handle Responder Hello message 2355 * @param cls key exchange info 2356 * @param rhm_e ResponderHello message 2357 */ 2358 static void 2359 handle_responder_hello (void *cls, const struct ResponderHello *rhm_e) 2360 { 2361 struct GSC_KeyExchangeInfo *kx = cls; 2362 const struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; 2363 struct ResponderHelloCls *rh_ctx; 2364 struct GNUNET_HashCode transcript; 2365 struct GNUNET_HashCode rh_hash; 2366 struct GNUNET_HashContext *hc; 2367 struct GNUNET_ShortHashCode ss_I; 2368 unsigned char enc_key[AEAD_KEY_BYTES]; 2369 unsigned char enc_nonce[AEAD_NONCE_BYTES]; 2370 enum GNUNET_GenericReturnValue ret; 2371 2372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ResponderHello: %d %d\n", kx-> 2373 role, kx->status); 2374 2375 GNUNET_CRYPTO_hash (rhm_e, 2376 ntohs (rhm_e->header.size), 2377 &rh_hash); 2378 if (ROLE_RESPONDER == kx->role) 2379 { 2380 GNUNET_break_op (0); 2381 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2382 "I am the responder! Ignoring.\n"); 2383 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2384 return; 2385 } 2386 if (GNUNET_CORE_KX_STATE_INITIATOR_HELLO_SENT != kx->status) 2387 { 2388 if ((GNUNET_CORE_KX_STATE_INITIATOR_DONE_SENT == kx->status) && 2389 (0 == GNUNET_memcmp (&rh_hash, 2390 &kx->rh_hash))) 2391 { 2392 /* The responder resent the ResponderHello we already answered, which 2393 means our InitiatorDone did not reach it. That is an ordinary 2394 retransmission, not a protocol violation -- the GNUNET_break_op() 2395 below used to report it as one, which is what "Unexpected 2396 ResponderHello in state 6" in the logs is. Answer it the way 2397 RFC 9147, Section 5.8 requires: "implementations MUST retransmit 2398 their last flight in response to a retransmitted flight from the 2399 peer". Our @e resend_task would get there on its own eventually; 2400 doing it here converges at the pace of the peer's timer instead of 2401 ours, and both are bounded by RESEND_MAX_TRIES. */ 2402 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2403 "ResponderHello repeated by `%s', resending InitiatorDone\n", 2404 GNUNET_i2s (&kx->peer)); 2405 GNUNET_STATISTICS_update (GSC_stats, 2406 gettext_noop ( 2407 "# ResponderHello retransmissions received"), 2408 1, 2409 GNUNET_NO); 2410 if (NULL != kx->resend_env) 2411 GNUNET_MQ_send_copy (kx->mq, 2412 kx->resend_env); 2413 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2414 return; 2415 } 2416 /* Outside of that state there is no handshake this message could 2417 belong to. In particular @e transcript_hash_ctx is then NULL, and 2418 #GNUNET_CRYPTO_hash_context_copy() dereferences its argument -- so 2419 a peer could crash us by sending a ResponderHello at any other 2420 time. Note that @e resend_task and @e resend_env below belong to 2421 the exchange we *are* in the middle of and must not be cleared 2422 before this point either. */ 2423 GNUNET_break_op (0); 2424 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2425 "Unexpected ResponderHello in state %d, ignoring\n", 2426 kx->status); 2427 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2428 return; 2429 } 2430 /* From here on this is the hello we answer; recognising a retransmission 2431 of it is what lets us resend our InitiatorDone above instead of 2432 dropping the peer's flight on the floor. */ 2433 kx->rh_hash = rh_hash; 2434 GNUNET_assert (NULL != kx->transcript_hash_ctx); 2435 hc = GNUNET_CRYPTO_hash_context_copy (kx->transcript_hash_ctx); 2436 if (NULL != kx->resend_task) 2437 { 2438 GNUNET_SCHEDULER_cancel (kx->resend_task); 2439 kx->resend_task = NULL; 2440 } 2441 if (NULL != kx->resend_env) 2442 { 2443 GNUNET_MQ_discard (kx->resend_env); 2444 kx->resend_env = NULL; 2445 } 2446 2447 /* Forward the transcript hash context */ 2448 GNUNET_CRYPTO_hash_context_read (hc, 2449 rhm_e, 2450 sizeof (struct ResponderHello)); 2451 // 1. Verify that the message type is CORE_RESPONDER_HELLO 2452 // - implicitly done by handling this message? 2453 // - or is this about verifying the 'additional data' part of aead? 2454 // should it check the encryption + mac? (is this implicitly done 2455 // while decrypting?) 2456 // 2. sse <- Decaps(ske,ce) 2457 rh_ctx = GNUNET_new (struct ResponderHelloCls); 2458 ret = GNUNET_CRYPTO_hpke_kem_decaps (&kx->sk_e, // secret/private ephemeral key of initiator (us) 2459 &rhm_e->c_e, // encapsulated key 2460 &rh_ctx->ss_e); // key - ss_e 2461 if (GNUNET_OK != ret) 2462 { 2463 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2464 "Something went wrong decapsulating ss_e\n"); 2465 GNUNET_CRYPTO_hash_context_abort (hc); 2466 GNUNET_free (rh_ctx); 2467 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2468 return; 2469 } 2470 // 3. Generate IHTS and RHTS from Section 5 and decrypt ServicesInfo, cI and ResponderFinished. 2471 snapshot_transcript (hc, &transcript); 2472 #if DEBUG_KX 2473 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2474 "Transcript snapshot for derivation of HS, *HTS: `%s'\n", 2475 GNUNET_h2s (&transcript)); 2476 #endif 2477 derive_hs (&kx->early_secret_key, 2478 &rh_ctx->ss_e, 2479 &rh_ctx->hs); 2480 derive_rhts (&transcript, 2481 &rh_ctx->hs, 2482 &rh_ctx->rhts); 2483 derive_ihts (&transcript, 2484 &rh_ctx->hs, 2485 &rh_ctx->ihts); 2486 derive_per_message_secrets (&rh_ctx->rhts, 2487 0, 2488 enc_key, 2489 enc_nonce); 2490 rh_ctx->kx = kx; 2491 GNUNET_memcpy (&rh_ctx->rhm_e, rhm_e, sizeof (*rhm_e)); 2492 { 2493 unsigned long long int c_len; 2494 unsigned char *finished_buf; 2495 // use RHTS to decrypt 2496 c_len = ntohs (rhm_e->header.size) - sizeof (*rhm_e) 2497 - sizeof (struct GNUNET_HashCode) 2498 - AEAD_TAG_BYTES; // finished ct 2499 rh_ctx->rhp = GNUNET_malloc (c_len 2500 - 2501 AEAD_TAG_BYTES); 2502 rh_ctx->hc = hc; 2503 finished_buf = ((unsigned char*) &rhm_e[1]) + c_len; 2504 /* Forward the transcript_hash_ctx 2505 * after rhts has been generated, 2506 * before generating finished_R*/ 2507 GNUNET_CRYPTO_hash_context_read ( 2508 hc, 2509 &rhm_e[1], 2510 c_len); 2511 2512 ret = crypto_aead_xchacha20poly1305_ietf_decrypt ( 2513 (unsigned char*) rh_ctx->rhp, // unsigned char *m 2514 NULL, // mlen_p message length 2515 NULL, // unsigned char *nsec - unused: NULL 2516 (unsigned char*) &rhm_e[1], // const unsigned char *c - ciphertext 2517 c_len, // unsigned long long clen - length of ciphertext 2518 NULL, // const unsigned char *ad - additional data (optional) TODO those should be used, right? 2519 0, // unsigned long long adlen 2520 enc_nonce, // const unsigned char *npub - nonce 2521 enc_key // const unsigned char *k - key 2522 ); 2523 if (0 != ret) 2524 { 2525 GNUNET_log (DECRYPTION_FAILURES_LOG_LEVEL, 2526 "Something went wrong decrypting: %d\n", ret); 2527 GNUNET_free (rh_ctx->rhp); 2528 GNUNET_free (rh_ctx); 2529 GNUNET_CRYPTO_hash_context_abort (hc); 2530 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2531 return; 2532 } 2533 // FIXME nonce reuse (see encryption) 2534 derive_per_message_secrets (&rh_ctx->rhts, 2535 1, 2536 enc_key, 2537 enc_nonce); 2538 c_len = sizeof (struct GNUNET_HashCode) 2539 + AEAD_TAG_BYTES; 2540 ret = crypto_aead_xchacha20poly1305_ietf_decrypt ( 2541 (unsigned char*) &rh_ctx->decrypted_finish, // unsigned char *m 2542 NULL, // mlen_p message length 2543 NULL, // unsigned char *nsec - unused: NULL 2544 finished_buf, // const unsigned char *c - ciphertext 2545 c_len, // unsigned long long clen - length of ciphertext 2546 NULL, // const unsigned char *ad - additional data (optional) TODO those should be used, right? 2547 0, // unsigned long long adlen 2548 enc_nonce, // const unsigned char *npub - nonce 2549 enc_key // const unsigned char *k - key 2550 ); 2551 if (0 != ret) 2552 { 2553 GNUNET_log (DECRYPTION_FAILURES_LOG_LEVEL, 2554 "Something went wrong decrypting finished field: %d\n", ret); 2555 GNUNET_free (rh_ctx->rhp); 2556 GNUNET_free (rh_ctx); 2557 GNUNET_CRYPTO_hash_context_abort (hc); 2558 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2559 return; 2560 } 2561 GNUNET_memcpy (rh_ctx->finished_enc, 2562 finished_buf, 2563 c_len); 2564 } 2565 // 4. ssI <- Decaps(skI,cI). 2566 my_private_key = GNUNET_PILS_get_private_key (GSC_pils); 2567 if ( (NULL == my_private_key) || 2568 (GNUNET_OK != 2569 GNUNET_CRYPTO_eddsa_kem_decaps (my_private_key, 2570 &rh_ctx->rhp->c_I, 2571 &ss_I)) ) 2572 { 2573 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2574 "Failed to decapsulate c_I of ResponderHello from `%s'\n", 2575 GNUNET_i2s (&kx->peer)); 2576 GNUNET_free (rh_ctx->rhp); 2577 GNUNET_free (rh_ctx); 2578 GNUNET_CRYPTO_hash_context_abort (hc); 2579 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2580 restart_kx (kx); 2581 return; 2582 } 2583 handle_responder_hello_cont (rh_ctx, 2584 &ss_I); 2585 } 2586 2587 2588 static int 2589 check_initiator_done (void *cls, const struct InitiatorDone *m) 2590 { 2591 uint16_t size = ntohs (m->header.size); 2592 2593 if (size < sizeof (*m) + sizeof (struct ConfirmationAck)) 2594 { 2595 return GNUNET_SYSERR; 2596 } 2597 return GNUNET_OK; 2598 } 2599 2600 2601 /** 2602 * Handle InitiatorDone message 2603 * @param cls key exchange info 2604 * @param idm_e InitiatorDone message 2605 */ 2606 static void 2607 handle_initiator_done (void *cls, const struct InitiatorDone *idm_e) 2608 { 2609 struct GSC_KeyExchangeInfo *kx = cls; 2610 struct InitiatorDone idm_local; 2611 struct InitiatorDone *idm_p = &idm_local; /* plaintext */ 2612 struct GNUNET_HashCode initiator_finished; 2613 struct GNUNET_HashCode transcript; 2614 struct GNUNET_ShortHashCode their_ats; 2615 struct GNUNET_HashContext *hc; 2616 unsigned char enc_key[AEAD_KEY_BYTES]; 2617 unsigned char enc_nonce[AEAD_NONCE_BYTES]; 2618 struct ConfirmationAck ack_i; 2619 struct ConfirmationAck ack_r; 2620 int8_t ret; 2621 2622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received InitiatorDone: %d %d\n", kx-> 2623 role, kx->status); 2624 if (ROLE_INITIATOR == kx->role) 2625 { 2626 GNUNET_break_op (0); 2627 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2628 "I am the initiator! Tearing down...\n"); 2629 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2630 return; 2631 } 2632 if (GNUNET_CORE_KX_STATE_RESPONDER_CONNECTED == kx->status) 2633 { 2634 /* The initiator did not see our ConfirmationAck and is resending (it 2635 tries #RESEND_MAX_TRIES times). Our handshake secrets are gone -- 2636 #cleanup_handshake_secrets() zeroed @e ihts -- so verifying this 2637 message again is not possible and would only look like a decryption 2638 failure. Send what the initiator is actually missing instead. */ 2639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2640 "InitiatorDone repeated by `%s', resending our Ack\n", 2641 GNUNET_i2s (&kx->peer)); 2642 ack_r.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ACK); 2643 ack_r.header.size = htons (sizeof ack_r); 2644 GSC_KX_encrypt_and_transmit (kx, 2645 &ack_r, 2646 sizeof ack_r); 2647 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2648 return; 2649 } 2650 if (GNUNET_CORE_KX_STATE_RESPONDER_HELLO_SENT != kx->status) 2651 { 2652 /* We have no handshake state this message could be checked against. 2653 Note that @e resend_task and @e resend_env below belong to whatever 2654 exchange we *are* in the middle of, so they must not be cleared 2655 before this point. */ 2656 GNUNET_break_op (0); 2657 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2658 "Unexpected InitiatorDone in state %d, ignoring\n", 2659 kx->status); 2660 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2661 return; 2662 } 2663 if (NULL != kx->resend_task) 2664 { 2665 GNUNET_SCHEDULER_cancel (kx->resend_task); 2666 kx->resend_task = NULL; 2667 } 2668 if (NULL != kx->resend_env) 2669 { 2670 GNUNET_MQ_discard (kx->resend_env); 2671 kx->resend_env = NULL; 2672 } 2673 derive_per_message_secrets (&kx->ihts, 2674 0, 2675 enc_key, 2676 enc_nonce); 2677 ret = crypto_aead_xchacha20poly1305_ietf_decrypt ( 2678 (unsigned char*) &idm_p->finished, // unsigned char *m 2679 NULL, // mlen_p message length 2680 NULL, // unsigned char *nsec - unused: NULL 2681 (unsigned char*) &idm_e->finished, // const unsigned char *c - ciphertext 2682 sizeof (idm_p->finished) // unsigned long long clen - length of ciphertext 2683 + AEAD_TAG_BYTES, 2684 NULL, // const unsigned char *ad - additional data (optional) TODO those should be used, right? 2685 0, // unsigned long long adlen 2686 enc_nonce, // const unsigned char *npub - nonce 2687 enc_key // const unsigned char *k - key 2688 ); 2689 if (0 != ret) 2690 { 2691 GNUNET_log (DECRYPTION_FAILURES_LOG_LEVEL, 2692 "Something went wrong decrypting: %d\n", ret); 2693 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2694 return; 2695 } 2696 2697 // - verify finished_I 2698 /* Generate finished_I 2699 * after Forwarding until {finished_R}RHTS 2700 * (did so while we prepared responder hello) 2701 * before forwarding to [{payload}RATS and] {finished_I}IHTS */ 2702 // (look at the end of handle_initiator_hello()) 2703 snapshot_transcript (kx->transcript_hash_ctx, &transcript); 2704 generate_initiator_finished (&transcript, 2705 &kx->master_secret, 2706 &initiator_finished); 2707 if (0 != memcmp (&idm_p->finished, 2708 &initiator_finished, 2709 sizeof (struct GNUNET_HashCode))) 2710 { 2711 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2712 "Could not verify \"initiator finished\" hash.\n"); 2713 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2714 "Want: `%s'\n", 2715 GNUNET_h2s (&initiator_finished)); 2716 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2717 "Have: `%s'\n", 2718 GNUNET_h2s (&idm_p->finished)); 2719 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2720 "Transcript `%s'\n", 2721 GNUNET_h2s (&transcript)); 2722 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2723 return; 2724 } 2725 2726 /* Forward the transcript hash_context_read */ 2727 hc = GNUNET_CRYPTO_hash_context_copy (kx->transcript_hash_ctx); 2728 GNUNET_CRYPTO_hash_context_read (hc, 2729 &idm_e->finished, 2730 sizeof (idm_e->finished) 2731 + AEAD_TAG_BYTES); 2732 snapshot_transcript (hc, &transcript); 2733 derive_initial_ats (&transcript, 2734 &kx->master_secret, 2735 ROLE_INITIATOR, 2736 &their_ats); 2737 derive_per_message_secrets (&their_ats, // FIXME other HS epoch? 2738 0, 2739 enc_key, 2740 enc_nonce); 2741 ret = crypto_aead_xchacha20poly1305_ietf_decrypt ( 2742 (unsigned char*) &ack_i, // unsigned char *m 2743 NULL, // mlen_p message length 2744 NULL, // unsigned char *nsec - unused: NULL 2745 (unsigned char*) &idm_e[1], // const unsigned char *c - ciphertext 2746 sizeof (ack_i) + AEAD_TAG_BYTES, // unsigned long long clen - length of ciphertext 2747 NULL, // const unsigned char *ad - additional data (optional) TODO those should be used, right? 2748 0, // unsigned long long adlen 2749 enc_nonce, // const unsigned char *npub - nonce 2750 enc_key // const unsigned char *k - key 2751 ); 2752 if (0 != ret) 2753 { 2754 GNUNET_log (DECRYPTION_FAILURES_LOG_LEVEL, 2755 "Something went wrong decrypting the Ack: %d\n", ret); 2756 GNUNET_CRYPTO_hash_context_abort (hc); 2757 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2758 return; 2759 } 2760 if ((sizeof ack_i != ntohs (ack_i.header.size)) || 2761 (GNUNET_MESSAGE_TYPE_CORE_ACK != ntohs (ack_i.header.type))) 2762 { 2763 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2764 "Ack invalid!\n"); 2765 GNUNET_CRYPTO_hash_context_abort (hc); 2766 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2767 return; 2768 } 2769 GNUNET_memcpy (&kx->their_ats[0], 2770 &their_ats, 2771 sizeof their_ats); 2772 /** 2773 * FIXME we do not really have to calculate all this now 2774 */ 2775 for (int i = 0; i < MAX_EPOCHS - 1; i++) 2776 { 2777 derive_next_ats (&kx->their_ats[i], 2778 &kx->their_ats[i + 1]); 2779 } 2780 GNUNET_CRYPTO_hash_context_abort (kx->transcript_hash_ctx); 2781 kx->transcript_hash_ctx = hc; 2782 kx->status = GNUNET_CORE_KX_STATE_RESPONDER_CONNECTED; 2783 kx->current_epoch_expiration = 2784 GNUNET_TIME_relative_to_absolute (EPOCH_EXPIRATION); 2785 cleanup_handshake_secrets (kx); 2786 monitor_notify_all (kx); 2787 /* @e finished_I has verified. RFC 9147, Section 5.11: the peer has now 2788 "demonstrated reachability [...] by completing a complete handshake 2789 including delivering a verifiable Finished message", so this is the 2790 point -- and the only point -- at which the old association may be 2791 destroyed. #handle_initiator_hello() deliberately left it running. 2792 GSC_SESSIONS_create() puts into @e sessions with 2793 #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY under a 2794 GNUNET_assert(), so a leftover session is not merely untidy. */ 2795 GSC_SESSIONS_end (&kx->peer); 2796 if (NULL != kx->heartbeat_task) 2797 { 2798 GNUNET_SCHEDULER_cancel (kx->heartbeat_task); 2799 kx->heartbeat_task = NULL; 2800 } 2801 /* #send_initiator_done() starts the initiator at epoch 0 and we have to 2802 agree: on a kx that had an association before, these still hold the 2803 predecessor's values, and none of them was ever reset here. */ 2804 kx->current_epoch = 0; 2805 kx->their_max_epoch = 0; 2806 kx->current_sqn = 1; 2807 replay_reset_all (kx); 2808 kx->association_up = GNUNET_YES; 2809 GSC_SESSIONS_create (&kx->peer, kx, kx->class); 2810 update_timeout (kx); 2811 ack_r.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ACK); 2812 ack_r.header.size = htons (sizeof ack_r); 2813 GSC_KX_encrypt_and_transmit (kx, 2814 &ack_r, 2815 sizeof ack_r); 2816 2817 GNUNET_TRANSPORT_core_receive_continue (transport, 2818 &kx->peer); 2819 } 2820 2821 2822 /** 2823 * Check an incoming encrypted message before handling it 2824 * @param cls key exchange info 2825 * @param m the encrypted message 2826 */ 2827 static int 2828 check_encrypted_message (void *cls, const struct EncryptedMessage *m) 2829 { 2830 uint16_t size = ntohs (m->header.size) - sizeof(*m); 2831 2832 // TODO check (see check_encrypted ()) 2833 // - check epoch 2834 // - check sequence number 2835 if (size < sizeof(struct GNUNET_MessageHeader)) 2836 { 2837 GNUNET_break_op (0); 2838 return GNUNET_SYSERR; 2839 } 2840 return GNUNET_OK; 2841 } 2842 2843 2844 /** 2845 * Handle a key update 2846 * @param cls key exchange info 2847 * @param m KeyUpdate message 2848 */ 2849 static void 2850 handle_heartbeat (struct GSC_KeyExchangeInfo *kx, 2851 const struct Heartbeat *m) 2852 { 2853 struct GNUNET_ShortHashCode new_ats; 2854 struct ConfirmationAck ack; 2855 2856 if (m->flags & GSC_HEARTBEAT_KEY_UPDATE_REQUESTED) 2857 { 2858 if (kx->current_epoch == UINT64_MAX) 2859 { 2860 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2861 "Max epoch reached (you probably will never see this)\n"); 2862 } 2863 else 2864 { 2865 kx->current_epoch++; 2866 kx->current_epoch_expiration = 2867 GNUNET_TIME_relative_to_absolute (EPOCH_EXPIRATION); 2868 kx->current_sqn = 0; 2869 derive_next_ats (&kx->current_ats, 2870 &new_ats); 2871 memcpy (&kx->current_ats, 2872 &new_ats, 2873 sizeof new_ats); 2874 } 2875 } 2876 update_timeout (kx); 2877 ack.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ACK); 2878 ack.header.size = htons (sizeof ack); 2879 GSC_KX_encrypt_and_transmit (kx, 2880 &ack, 2881 sizeof ack); 2882 /* NOTE: no GNUNET_TRANSPORT_core_receive_continue() here. We are called 2883 from #handle_encrypted_message(), which owns the message and issues 2884 exactly one call for it. */ 2885 } 2886 2887 2888 static enum GNUNET_GenericReturnValue 2889 check_if_ack_or_heartbeat (struct GSC_KeyExchangeInfo *kx, 2890 const char *buf, 2891 size_t buf_len) 2892 { 2893 struct GNUNET_MessageHeader *msg; 2894 struct ConfirmationAck *ack; 2895 struct Heartbeat *hb; 2896 2897 if (sizeof *msg > buf_len) 2898 return GNUNET_NO; 2899 msg = (struct GNUNET_MessageHeader*) buf; 2900 if (GNUNET_MESSAGE_TYPE_CORE_ACK == ntohs (msg->type)) 2901 { 2902 ack = (struct ConfirmationAck *) buf; 2903 if (sizeof *ack != ntohs (ack->header.size)) 2904 return GNUNET_NO; 2905 } 2906 else if (GNUNET_MESSAGE_TYPE_CORE_HEARTBEAT == ntohs (msg->type)) 2907 { 2908 hb = (struct Heartbeat*) buf; 2909 if (sizeof *hb != ntohs (hb->header.size)) 2910 return GNUNET_NO; 2911 handle_heartbeat (kx, hb); 2912 } 2913 else 2914 { 2915 return GNUNET_NO; 2916 } 2917 2918 /** 2919 * Waiting for ACK or heartbeat 2920 */ 2921 if (kx->status == GNUNET_CORE_KX_STATE_INITIATOR_DONE_SENT) 2922 { 2923 GSC_SESSIONS_create (&kx->peer, kx, kx->class); 2924 kx->status = GNUNET_CORE_KX_STATE_INITIATOR_CONNECTED; 2925 kx->current_epoch_expiration = 2926 GNUNET_TIME_relative_to_absolute (EPOCH_EXPIRATION); 2927 cleanup_handshake_secrets (kx); 2928 if (NULL != kx->resend_task) 2929 GNUNET_SCHEDULER_cancel (kx->resend_task); 2930 kx->resend_task = NULL; 2931 if (NULL != kx->resend_env) 2932 GNUNET_MQ_discard (kx->resend_env); 2933 kx->resend_env = NULL; 2934 monitor_notify_all (kx); 2935 } 2936 update_timeout (kx); 2937 2938 return GNUNET_YES; 2939 } 2940 2941 2942 /** 2943 * handle an encrypted message 2944 * @param cls key exchange info 2945 * @param m encrypted message 2946 */ 2947 static void 2948 handle_encrypted_message (void *cls, const struct EncryptedMessage *m) 2949 { 2950 struct GSC_KeyExchangeInfo *kx = cls; 2951 uint16_t size = ntohs (m->header.size); 2952 char buf[size - sizeof (*m)] GNUNET_ALIGN; 2953 unsigned char seq_enc_k[crypto_stream_chacha20_ietf_KEYBYTES]; 2954 const unsigned char *seq_enc_nonce; 2955 unsigned char enc_key[AEAD_KEY_BYTES]; 2956 unsigned char enc_nonce[AEAD_NONCE_BYTES]; 2957 struct GNUNET_ShortHashCode new_ats[MAX_EPOCHS]; 2958 uint32_t seq_enc_ctr; 2959 uint64_t epoch; 2960 uint64_t m_seq; 2961 uint64_t m_seq_nbo; 2962 uint64_t c_len; 2963 int8_t ret; 2964 2965 // TODO look at handle_encrypted 2966 // - statistics 2967 2968 /* The record layer answers to @e association_up, not to @e status: a 2969 handshake may be in flight over an association that is still live 2970 (RFC 9147, Section 5.11), and records of the old epoch have to keep 2971 being deprotected while it is. Conversely a record we have no keys 2972 for is simply an invalid record -- RFC 9147, Section 4.5.2: "In 2973 general, invalid records SHOULD be silently discarded, thus preserving 2974 the association" -- so it must not end a session or restart anything. 2975 If we are idle it does tell us the peer believes in an association we 2976 do not have, which is worth one exchange. */ 2977 if (GNUNET_YES != kx->association_up) 2978 { 2979 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2980 "Discarding record from `%s': no keys for epoch %" PRIu64 "\n", 2981 GNUNET_i2s (&kx->peer), 2982 GNUNET_ntohll (m->epoch)); 2983 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 2984 if (GNUNET_CORE_KX_STATE_DOWN == kx->status) 2985 restart_kx (kx); 2986 return; 2987 } 2988 epoch = GNUNET_ntohll (m->epoch); 2989 /** 2990 * Derive temporarily as we want to discard on 2991 * decryption failure(s) 2992 */ 2993 memcpy (new_ats, 2994 kx->their_ats, 2995 MAX_EPOCHS * sizeof (struct GNUNET_ShortHashCode)); 2996 // FIXME here we could introduce logic that sends heartbeats 2997 // with key update request if we have not seen a new 2998 // epoch after a while (e.g. EPOCH_EXPIRATION) 2999 if (kx->their_max_epoch < epoch) 3000 { 3001 /** 3002 * Prevent DoS 3003 * FIXME maybe requires its own limit. 3004 */ 3005 if ((epoch - kx->their_max_epoch) > 2 * MAX_EPOCHS) 3006 { 3007 /* @e epoch is plaintext and not covered by the AEAD tag, so this is 3008 reached by a single flipped bit as readily as by a peer that really 3009 did skip ahead. Drop the message like the "too old" case below 3010 does; tearing the session down here means one unauthenticated 3011 header field costs a full re-handshake. */ 3012 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 3013 "Epoch %" PRIu64 " is too new, will not decrypt...\n", 3014 epoch); 3015 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 3016 return; 3017 } 3018 for (uint64_t i = kx->their_max_epoch; i < epoch; i++) 3019 { 3020 derive_next_ats (&new_ats[i % MAX_EPOCHS], 3021 &new_ats[(i + 1) % MAX_EPOCHS]); 3022 /* This slot of the ring now holds a different key, so the window 3023 that went with the old one no longer means anything. */ 3024 replay_reset (kx, i + 1); 3025 } 3026 } 3027 else if ((kx->their_max_epoch - epoch) > MAX_EPOCHS) 3028 { 3029 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 3030 "Epoch %" PRIu64 " is too old, cannot decrypt...\n", 3031 epoch); 3032 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 3033 return; 3034 } 3035 derive_sn ( 3036 &new_ats[epoch % MAX_EPOCHS], 3037 seq_enc_k, 3038 sizeof seq_enc_k); 3039 /* compute the sequence number */ 3040 seq_enc_ctr = *((uint32_t*) m->tag); 3041 seq_enc_nonce = &m->tag[sizeof (uint32_t)]; 3042 #if DEBUG_KX 3043 GNUNET_print_bytes (&new_ats[epoch % MAX_EPOCHS], 3044 sizeof (struct GNUNET_ShortHashCode), 3045 8, 3046 GNUNET_NO); 3047 GNUNET_print_bytes (seq_enc_k, 3048 sizeof seq_enc_k, 3049 8, 3050 GNUNET_NO); 3051 GNUNET_print_bytes ((char*) &seq_enc_ctr, 3052 sizeof seq_enc_ctr, 3053 8, 3054 GNUNET_NO); 3055 #endif 3056 crypto_stream_chacha20_ietf_xor_ic ( 3057 (unsigned char*) &m_seq_nbo, 3058 (unsigned char*) &m->sequence_number, 3059 sizeof (uint64_t), 3060 seq_enc_nonce, 3061 ntohl (seq_enc_ctr), 3062 seq_enc_k); 3063 m_seq = GNUNET_ntohll (m_seq_nbo); 3064 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3065 "Received encrypted message in epoch %" PRIu64 3066 " with E(SQN=%" PRIu64 ")=%" PRIu64 3067 "\n", 3068 epoch, 3069 m_seq, 3070 m->sequence_number); 3071 /* RFC 9147, Section 4.5.1. Cheap enough to do before deprotection, and 3072 doing it first means a flood of replayed records costs no AEAD work. 3073 The window itself is only moved once the record verifies, below. */ 3074 if (GNUNET_OK != replay_check (kx, epoch, m_seq)) 3075 { 3076 GNUNET_STATISTICS_update (GSC_stats, 3077 gettext_noop ("# replayed records discarded"), 3078 1, 3079 GNUNET_NO); 3080 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3081 "Discarding replayed record %" PRIu64 "/%" PRIu64 3082 " from `%s'\n", 3083 epoch, 3084 m_seq, 3085 GNUNET_i2s (&kx->peer)); 3086 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 3087 return; 3088 } 3089 /* We are the initiator and as we are going to receive, 3090 * we are using the responder key material */ 3091 derive_per_message_secrets (&new_ats[epoch % MAX_EPOCHS], 3092 m_seq, 3093 enc_key, 3094 enc_nonce); 3095 // TODO checking sequence numbers - handle the case of out-of-sync messages! 3096 // for now only decrypt the payload 3097 // TODO encrypt other fields, too! 3098 // TODO 3099 // c_len = size - offsetof (); 3100 c_len = size - sizeof (struct EncryptedMessage); 3101 ret = crypto_aead_xchacha20poly1305_ietf_decrypt_detached ( 3102 (unsigned char*) buf, // m - plain message 3103 NULL, // nsec - unused 3104 (unsigned char*) &m[1], // c - ciphertext 3105 c_len, // clen 3106 (const unsigned char*) &m->tag, // mac 3107 NULL, // ad - additional data TODO 3108 0, // adlen 3109 enc_nonce, // npub 3110 enc_key // k 3111 ); 3112 if (0 != ret) 3113 { 3114 /* RFC 9147, Section 4.5.2: "invalid records SHOULD be silently 3115 discarded, thus preserving the association; however, an error MAY be 3116 logged for diagnostic purposes." Not a protocol violation on the 3117 peer's part either -- anything at all can arrive here -- so no 3118 GNUNET_break_op(). */ 3119 GNUNET_STATISTICS_update (GSC_stats, 3120 gettext_noop ("# invalid records discarded"), 3121 1, 3122 GNUNET_NO); 3123 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 3124 "Discarding record %" PRIu64 "/%" PRIu64 " from `%s':" 3125 " does not deprotect\n", 3126 epoch, 3127 m_seq, 3128 GNUNET_i2s (&kx->peer)); 3129 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 3130 return; 3131 } 3132 /* Deprotected, so the record is authentic and everything derived from it 3133 may now be committed: the epoch ring, the anti-replay window (RFC 9147, 3134 Section 4.5.1: "The window MUST NOT be updated due to a received record 3135 until that record has been deprotected successfully") and @e timeout. 3136 @e timeout is the only liveness signal CORE has and is what 3137 `gnunet-core -m' reports, so refreshing it any earlier would let 3138 anything merely shaped like a record keep a session nominally alive. */ 3139 /* Only ever forward: @e their_max_epoch is the *highest* epoch we have 3140 seen, and the ratchet above keys off it. A record that was merely 3141 reordered across an epoch boundary -- entirely normal, the peer starts 3142 the new epoch at sequence number 0 while the old one is still in flight 3143 -- used to pull it back, so the next record of the newer epoch looked 3144 like a fresh advance and ran the loop again, wiping that epoch's 3145 anti-replay window (RFC 9147, Section 4.5.1) every single time. */ 3146 if (kx->their_max_epoch < epoch) 3147 kx->their_max_epoch = epoch; 3148 memcpy (&kx->their_ats, 3149 new_ats, 3150 MAX_EPOCHS * sizeof (struct GNUNET_ShortHashCode)); 3151 replay_commit (kx, epoch, m_seq); 3152 update_timeout (kx); 3153 3154 if (GNUNET_NO == check_if_ack_or_heartbeat (kx, 3155 buf, 3156 sizeof buf)) 3157 { 3158 if (kx->status == GNUNET_CORE_KX_STATE_INITIATOR_DONE_SENT) 3159 { 3160 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 3161 "Dropping message as we are still waiting for handshake ACK\n"); 3162 GNUNET_break_op (0); 3163 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 3164 return; 3165 } 3166 if (GNUNET_OK != 3167 GNUNET_MST_from_buffer (kx->mst, 3168 buf, 3169 sizeof buf, 3170 GNUNET_YES, 3171 GNUNET_NO)) 3172 GNUNET_break_op (0); 3173 } 3174 GNUNET_TRANSPORT_core_receive_continue (transport, &kx->peer); 3175 } 3176 3177 3178 /** 3179 * Function called by transport telling us that a peer 3180 * disconnected. 3181 * Stop key exchange with the given peer. Clean up key material. 3182 * 3183 * @param cls closure 3184 * @param peer the peer that disconnected 3185 * @param handler_cls the `struct GSC_KeyExchangeInfo` of the peer 3186 */ 3187 static void 3188 handle_transport_notify_disconnect (void *cls, 3189 const struct GNUNET_PeerIdentity *peer, 3190 void *handler_cls) 3191 { 3192 struct GSC_KeyExchangeInfo *kx = handler_cls; 3193 (void) cls; 3194 3195 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3196 "Peer `%s' disconnected from us.\n", 3197 GNUNET_i2s (&kx->peer)); 3198 GSC_SESSIONS_end (&kx->peer); 3199 GNUNET_STATISTICS_update (GSC_stats, 3200 gettext_noop ("# key exchanges stopped"), 3201 1, 3202 GNUNET_NO); 3203 if (NULL != kx->resend_task) 3204 { 3205 GNUNET_SCHEDULER_cancel (kx->resend_task); 3206 kx->resend_task = NULL; 3207 } 3208 if (NULL != kx->resend_env) 3209 { 3210 GNUNET_MQ_discard (kx->resend_env); 3211 kx->resend_env = NULL; 3212 } 3213 if (NULL != kx->heartbeat_task) 3214 { 3215 GNUNET_SCHEDULER_cancel (kx->heartbeat_task); 3216 kx->heartbeat_task = NULL; 3217 } 3218 kx->status = GNUNET_CORE_KX_PEER_DISCONNECT; 3219 monitor_notify_all (kx); 3220 if (kx->transcript_hash_ctx) 3221 { 3222 GNUNET_CRYPTO_hash_context_abort (kx->transcript_hash_ctx); 3223 kx->transcript_hash_ctx = NULL; 3224 } 3225 GNUNET_CONTAINER_DLL_remove (kx_head, kx_tail, kx); 3226 GNUNET_MST_destroy (kx->mst); 3227 GNUNET_free (kx); 3228 } 3229 3230 3231 static void 3232 resend_initiator_hello (void *cls) 3233 { 3234 struct GSC_KeyExchangeInfo *kx = cls; 3235 3236 kx->resend_task = NULL; 3237 if (0 == kx->resend_tries_left) 3238 { 3239 /* The InitiatorHello we keep repeating carries the ephemeral public key 3240 generated by #send_initiator_hello(), and only #restart_kx() ever 3241 generates a new one. Retrying the same message forever therefore 3242 never recovers from a responder that has dropped the exchange -- it 3243 just keeps a retransmit timer running against a peer that is not 3244 answering. Give up like #resend_responder_hello() and 3245 #resend_initiator_done() do and start a fresh exchange. */ 3246 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 3247 "InitiatorHello not answered by `%s', restarting KX\n", 3248 GNUNET_i2s (&kx->peer)); 3249 restart_kx (kx); 3250 return; 3251 } 3252 kx->resend_tries_left--; 3253 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 3254 "Resending InitiatorHello. Retries left: %u\n", 3255 kx->resend_tries_left); 3256 GNUNET_MQ_send_copy (kx->mq, kx->resend_env); 3257 schedule_resend (kx, &resend_initiator_hello); 3258 } 3259 3260 3261 /** 3262 * Send initiator hello 3263 * 3264 * @param kx key exchange context 3265 */ 3266 static void 3267 send_initiator_hello (struct GSC_KeyExchangeInfo *kx) 3268 { 3269 const struct GNUNET_PeerIdentity *my_identity; 3270 struct GNUNET_MQ_Envelope *env; 3271 struct GNUNET_ShortHashCode es; 3272 struct GNUNET_ShortHashCode ets; 3273 struct GNUNET_ShortHashCode ss_R; 3274 struct InitiatorHelloPayload *ihmp; /* initiator hello message - buffer on stack */ 3275 struct InitiatorHello *ihm_e; /* initiator hello message - encrypted */ 3276 long long unsigned int c_len; 3277 unsigned char enc_key[AEAD_KEY_BYTES]; 3278 unsigned char enc_nonce[AEAD_NONCE_BYTES]; 3279 enum GNUNET_GenericReturnValue ret; 3280 size_t pt_len; 3281 3282 my_identity = GNUNET_PILS_get_identity (GSC_pils); 3283 GNUNET_assert (NULL != my_identity); 3284 3285 pt_len = sizeof (*ihmp) + strlen (my_services_info); 3286 c_len = pt_len + AEAD_TAG_BYTES; 3287 env = GNUNET_MQ_msg_extra (ihm_e, 3288 c_len, 3289 GNUNET_MESSAGE_TYPE_CORE_INITIATOR_HELLO); 3290 ihmp = (struct InitiatorHelloPayload*) &ihm_e[1]; 3291 ihmp->peer_class = htons (GNUNET_CORE_CLASS_UNKNOWN); // TODO set this to a meaningful 3292 GNUNET_memcpy (&ihmp->pk_I, 3293 my_identity, 3294 sizeof (struct GNUNET_PeerIdentity)); 3295 GNUNET_CRYPTO_hash (&kx->peer, /* what to hash */ // TODO do we do this twice? 3296 sizeof (struct GNUNET_PeerIdentity), 3297 &ihm_e->h_pk_R); /* result */ 3298 // TODO init hashcontext/transcript_hash 3299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send InitiatorHello: %d %d\n", kx->role, 3300 kx->status); 3301 GNUNET_assert (NULL == kx->transcript_hash_ctx); 3302 kx->transcript_hash_ctx = GNUNET_CRYPTO_hash_context_start (); 3303 GNUNET_assert (NULL != kx->transcript_hash_ctx); 3304 // TODO fill services_info 3305 3306 // 1. Encaps 3307 ret = GNUNET_CRYPTO_eddsa_kem_encaps (&kx->peer.public_key, // public ephemeral key of initiator 3308 &ihm_e->c_R, // encapsulated key 3309 &ss_R); // key - ss_R 3310 if (GNUNET_OK != ret) 3311 { 3312 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3313 "Something went wrong encapsulating ss_R\n"); 3314 // TODO handle 3315 } 3316 // 2. generate rR (uint64_t) - is this the nonce? Naming seems not quite 3317 // consistent 3318 ihm_e->r_I = 3319 GNUNET_CRYPTO_random_u64 (UINT64_MAX); 3320 // 3. generate sk_e/pk_e - ephemeral key 3321 GNUNET_CRYPTO_ecdhe_key_create (&kx->sk_e.ecdhe_key); 3322 GNUNET_CRYPTO_ecdhe_key_get_public ( 3323 &kx->sk_e.ecdhe_key, 3324 &kx->pk_e.ecdhe_key); 3325 GNUNET_memcpy (&ihm_e->pk_e, 3326 &kx->pk_e.ecdhe_key, 3327 sizeof (kx->pk_e.ecdhe_key)); 3328 // 4. generate ETS to encrypt 3329 // generate ETS (early_traffic_secret_key, decrypt pk_i 3330 // expand ETS <- expand ES <- extract ss_R 3331 // use ETS to decrypt 3332 GNUNET_CRYPTO_hash_context_read (kx->transcript_hash_ctx, 3333 ihm_e, 3334 sizeof (struct InitiatorHello)); 3335 { 3336 struct GNUNET_HashCode transcript; 3337 snapshot_transcript (kx->transcript_hash_ctx, 3338 &transcript); 3339 derive_es_ets (&transcript, 3340 &ss_R, 3341 &es, 3342 &ets); 3343 derive_per_message_secrets (&ets, 3344 0, 3345 enc_key, 3346 enc_nonce); 3347 } 3348 // 5. encrypt 3349 3350 ret = crypto_aead_xchacha20poly1305_ietf_encrypt ( 3351 (unsigned char*) &ihm_e[1], /* c - ciphertext */ 3352 // mac, 3353 // NULL, // maclen_p 3354 &c_len, /* clen_p */ 3355 (unsigned char*) ihmp, /* m - plaintext message */ 3356 pt_len, // mlen 3357 NULL, 0, // ad, adlen // FIXME maybe over the unencrypted header? 3358 // fields? 3359 NULL, // nsec - unused 3360 enc_nonce, // npub - nonce 3361 enc_key); // k - key 3362 if (0 != ret) 3363 { 3364 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Something went wrong encrypting\n"); 3365 GNUNET_CRYPTO_hash_context_abort (kx->transcript_hash_ctx); 3366 kx->transcript_hash_ctx = NULL; 3367 GNUNET_MQ_discard (env); 3368 return; 3369 } 3370 /* Forward the transcript */ 3371 GNUNET_CRYPTO_hash_context_read ( 3372 kx->transcript_hash_ctx, 3373 &ihm_e[1], 3374 c_len); 3375 3376 kx->status = GNUNET_CORE_KX_STATE_INITIATOR_HELLO_SENT; 3377 kx->early_secret_key = es; 3378 kx->early_traffic_secret = ets; 3379 kx->ss_R = ss_R; 3380 monitor_notify_all (kx); 3381 GNUNET_MQ_send_copy (kx->mq, env); 3382 kx->resend_env = env; 3383 start_resend (kx, &resend_initiator_hello); 3384 } 3385 3386 3387 /** 3388 * Move to the next epoch if the current one is exhausted. 3389 * 3390 * @param kx key exchange to check 3391 * @return #GNUNET_OK if @a kx may be used to send, #GNUNET_SYSERR if the 3392 * association had to be torn down instead 3393 */ 3394 static enum GNUNET_GenericReturnValue 3395 check_rekey (struct GSC_KeyExchangeInfo *kx) 3396 { 3397 struct GNUNET_ShortHashCode new_ats; 3398 3399 if ((UINT64_MAX == kx->current_sqn) || 3400 (GNUNET_TIME_absolute_is_past (kx->current_epoch_expiration))) 3401 { 3402 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3403 "Epoch expiration %" PRIu64 " SQN %" PRIu64 3404 ", incrementing epoch...\n", 3405 kx->current_epoch_expiration.abs_value_us, 3406 kx->current_sqn); 3407 if (UINT64_MAX == kx->current_epoch) 3408 { 3409 /* RFC 9147, Section 6.1: "Implementations MUST NOT allow the epoch to 3410 wrap, but instead MUST establish a new association, terminating the 3411 old association". This used to be a GNUNET_assert(). */ 3412 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 3413 "Epoch exhausted for `%s', starting a new association\n", 3414 GNUNET_i2s (&kx->peer)); 3415 restart_kx (kx); 3416 return GNUNET_SYSERR; 3417 } 3418 kx->current_epoch++; 3419 kx->current_epoch_expiration = 3420 GNUNET_TIME_relative_to_absolute (EPOCH_EXPIRATION); 3421 kx->current_sqn = 0; 3422 derive_next_ats (&kx->current_ats, 3423 &new_ats); 3424 memcpy (&kx->current_ats, 3425 &new_ats, 3426 sizeof new_ats); 3427 } 3428 return GNUNET_OK; 3429 } 3430 3431 3432 /** 3433 * Encrypt and transmit payload 3434 * @param kx key exchange info 3435 * @param payload the payload 3436 * @param payload_size size of the payload 3437 */ 3438 void 3439 GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, 3440 const void *payload, 3441 size_t payload_size) 3442 { 3443 struct GNUNET_MQ_Envelope *env; 3444 struct EncryptedMessage *encrypted_msg; 3445 unsigned char enc_key[AEAD_KEY_BYTES]; 3446 unsigned char enc_nonce[AEAD_NONCE_BYTES]; 3447 unsigned char seq_enc_k[crypto_stream_chacha20_ietf_KEYBYTES]; 3448 uint64_t sqn; 3449 uint64_t epoch; 3450 int8_t ret; 3451 3452 encrypted_msg = NULL; 3453 3454 if (GNUNET_YES != kx->association_up) 3455 { 3456 /* No application traffic keys installed -- there is nothing to protect 3457 this with. Callers reach this through a session, which only exists 3458 while the association does, so this is a should-not-happen. */ 3459 GNUNET_break (0); 3460 return; 3461 } 3462 if (GNUNET_OK != check_rekey (kx)) 3463 return; /* association was torn down, @e current_ats is gone */ 3464 sqn = kx->current_sqn; 3465 epoch = kx->current_epoch; 3466 /* We are the sender and as we are going to send, 3467 * we are using the initiator key material */ 3468 derive_per_message_secrets (&kx->current_ats, 3469 sqn, 3470 enc_key, 3471 enc_nonce); 3472 kx->current_sqn++; 3473 derive_sn (&kx->current_ats, 3474 seq_enc_k, 3475 sizeof seq_enc_k); 3476 env = GNUNET_MQ_msg_extra (encrypted_msg, 3477 payload_size, 3478 GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE_CAKE); 3479 // only encrypt the payload for now 3480 // TODO encrypt other fields as well 3481 ret = crypto_aead_xchacha20poly1305_ietf_encrypt_detached ( 3482 (unsigned char*) &encrypted_msg[1], // c - resulting ciphertext 3483 (unsigned char*) &encrypted_msg->tag, // mac - resulting mac/tag 3484 NULL, // maclen 3485 (unsigned char*) payload, // m - plain message 3486 payload_size, // mlen 3487 NULL, // ad - additional data TODO also cover the unencrypted part (epoch) 3488 0, // adlen 3489 NULL, // nsec - unused 3490 enc_nonce, // npub nonce 3491 enc_key // k - key 3492 ); 3493 if (0 != ret) 3494 { 3495 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3496 "Something went wrong encrypting message\n"); 3497 GNUNET_assert (0); 3498 } 3499 { 3500 /* compute the sequence number */ 3501 unsigned char *seq_enc_nonce; 3502 uint64_t seq_nbo; 3503 uint32_t seq_enc_ctr; 3504 3505 seq_nbo = GNUNET_htonll (sqn); 3506 seq_enc_ctr = *((uint32_t*) encrypted_msg->tag); 3507 seq_enc_nonce = &encrypted_msg->tag[sizeof (uint32_t)]; 3508 crypto_stream_chacha20_ietf_xor_ic ( 3509 (unsigned char*) &encrypted_msg->sequence_number, 3510 (unsigned char*) &seq_nbo, 3511 sizeof seq_nbo, 3512 seq_enc_nonce, 3513 ntohl (seq_enc_ctr), 3514 seq_enc_k); 3515 #if DEBUG_KX 3516 GNUNET_print_bytes (seq_enc_k, 3517 sizeof seq_enc_k, 3518 8, 3519 GNUNET_NO); 3520 GNUNET_print_bytes ((char*) &seq_enc_ctr, 3521 sizeof seq_enc_ctr, 3522 8, 3523 GNUNET_NO); 3524 #endif 3525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3526 "Sending encrypted message with E(SQN=%" PRIu64 ")=%" PRIu64 3527 "\n", 3528 sqn, 3529 encrypted_msg->sequence_number); 3530 } 3531 encrypted_msg->epoch = GNUNET_htonll (epoch); 3532 3533 // TODO actually copy payload 3534 GNUNET_MQ_send (kx->mq, env); 3535 } 3536 3537 3538 void 3539 GSC_KX_start (void) 3540 { 3541 const struct GNUNET_PeerIdentity *my_identity; 3542 struct GNUNET_MQ_MessageHandler handlers[] = { 3543 GNUNET_MQ_hd_var_size (initiator_hello, 3544 GNUNET_MESSAGE_TYPE_CORE_INITIATOR_HELLO, 3545 struct InitiatorHello, 3546 NULL), 3547 GNUNET_MQ_hd_var_size (initiator_done, 3548 GNUNET_MESSAGE_TYPE_CORE_INITIATOR_DONE, 3549 struct InitiatorDone, 3550 NULL), 3551 GNUNET_MQ_hd_var_size (responder_hello, 3552 GNUNET_MESSAGE_TYPE_CORE_RESPONDER_HELLO, 3553 struct ResponderHello, 3554 NULL), 3555 GNUNET_MQ_hd_var_size (encrypted_message, // TODO rename? 3556 GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE_CAKE, // TODO rename! 3557 struct EncryptedMessage, 3558 NULL), 3559 GNUNET_MQ_handler_end () 3560 }; 3561 3562 my_identity = GNUNET_PILS_get_identity (GSC_pils); 3563 GNUNET_assert (NULL != my_identity); 3564 3565 /* Decapsulate with our peer identity's private key directly instead of 3566 round-tripping through the PILS service. The shared secret is needed 3567 in the middle of processing a handshake message, and an asynchronous 3568 answer meant that every InitiatorHello and ResponderHello had to be 3569 parked with its kx across a callback: the kx could be torn down or 3570 freed underneath it, two hellos could be in flight at once, and if 3571 the answer never came (PILS restarting) the handshake stalled *and* 3572 the message was never acknowledged to TRANSPORT. */ 3573 if (GNUNET_OK != 3574 GNUNET_PILS_enable_private_key (GSC_pils)) 3575 { 3576 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3577 _ ("Failed to load our private key, " 3578 "cannot run key exchange\n")); 3579 GSC_KX_done (); 3580 return; 3581 } 3582 3583 nc = GNUNET_notification_context_create (1); 3584 transport = 3585 GNUNET_TRANSPORT_core_connect (GSC_cfg, 3586 my_identity, 3587 handlers, 3588 NULL, // cls - this connection-independant 3589 // cls seems not to be needed. 3590 // the connection-specific cls 3591 // will be set as a return value 3592 // of 3593 // handle_transport_notify_connect 3594 &handle_transport_notify_connect, 3595 &handle_transport_notify_disconnect); 3596 if (NULL == transport) 3597 { 3598 GSC_KX_done (); 3599 return; 3600 } 3601 3602 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3603 "Connected to TRANSPORT\n"); 3604 3605 GSC_complete_initialization_cb (); 3606 } 3607 3608 3609 void 3610 pid_change_cb (void *cls, 3611 const struct GNUNET_HELLO_Parser *parser, 3612 const struct GNUNET_HashCode *hash) 3613 { 3614 if (NULL != transport) 3615 return; 3616 3617 GSC_KX_start (); 3618 } 3619 3620 3621 /** 3622 * Initialize KX subsystem. 3623 * 3624 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 3625 */ 3626 int 3627 GSC_KX_init (void) 3628 { 3629 GSC_pils = GNUNET_PILS_connect (GSC_cfg, 3630 &pid_change_cb, 3631 NULL); 3632 if (NULL == GSC_pils) 3633 { 3634 GSC_KX_done (); 3635 return GNUNET_SYSERR; 3636 } 3637 3638 return GNUNET_OK; 3639 } 3640 3641 3642 /** 3643 * Shutdown KX subsystem. 3644 */ 3645 void 3646 GSC_KX_done () 3647 { 3648 if (NULL != GSC_pils) 3649 { 3650 GNUNET_PILS_disconnect (GSC_pils); 3651 GSC_pils = NULL; 3652 } 3653 if (NULL != transport) 3654 { 3655 GNUNET_TRANSPORT_core_disconnect (transport); 3656 transport = NULL; 3657 } 3658 if (NULL != rekey_task) 3659 { 3660 GNUNET_SCHEDULER_cancel (rekey_task); 3661 rekey_task = NULL; 3662 } 3663 if (NULL != nc) 3664 { 3665 GNUNET_notification_context_destroy (nc); 3666 nc = NULL; 3667 } 3668 } 3669 3670 3671 /** 3672 * Check how many messages are queued for the given neighbour. 3673 * 3674 * @param kxinfo data about neighbour to check 3675 * @return number of items in the message queue 3676 */ 3677 unsigned int 3678 GSC_NEIGHBOURS_get_queue_length (const struct GSC_KeyExchangeInfo *kxinfo) 3679 { 3680 return GNUNET_MQ_get_length (kxinfo->mq); 3681 } 3682 3683 3684 int 3685 GSC_NEIGHBOURS_check_excess_bandwidth (const struct GSC_KeyExchangeInfo *kxinfo) 3686 { 3687 return kxinfo->has_excess_bandwidth; 3688 } 3689 3690 3691 /** 3692 * Handle #GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request. For this 3693 * request type, the client does not have to have transmitted an INIT 3694 * request. All current peers are returned, regardless of which 3695 * message types they accept. 3696 * 3697 * @param mq message queue to add for monitoring 3698 */ 3699 void 3700 GSC_KX_handle_client_monitor_peers (struct GNUNET_MQ_Handle *mq) 3701 { 3702 struct GNUNET_MQ_Envelope *env; 3703 struct MonitorNotifyMessage *done_msg; 3704 struct GSC_KeyExchangeInfo *kx; 3705 3706 GNUNET_notification_context_add (nc, mq); 3707 for (kx = kx_head; NULL != kx; kx = kx->next) 3708 { 3709 struct GNUNET_MQ_Envelope *env_notify; 3710 struct MonitorNotifyMessage *msg; 3711 3712 env_notify = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); 3713 msg->state = htonl ((uint32_t) kx->status); 3714 msg->peer = kx->peer; 3715 msg->timeout = GNUNET_TIME_absolute_hton (kx->timeout); 3716 GNUNET_MQ_send (mq, env_notify); 3717 } 3718 env = GNUNET_MQ_msg (done_msg, GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); 3719 done_msg->state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED); 3720 done_msg->timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS); 3721 GNUNET_MQ_send (mq, env); 3722 } 3723 3724 3725 /* end of gnunet-service-core_kx.c */