librats 1.0.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -331
- package/binding.gyp +16 -3
- package/lib/index.d.ts +288 -696
- package/lib/index.js +407 -44
- package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
- package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
- package/native-src/CMakeLists.txt +404 -179
- package/native-src/LICENSE +1 -1
- package/native-src/src/librats/bindings/rats.cpp +762 -0
- package/native-src/src/librats/bindings/rats.h +380 -0
- package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
- package/native-src/src/librats/bittorrent/bencode.h +176 -0
- package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
- package/native-src/src/librats/bittorrent/bitfield.h +76 -0
- package/native-src/src/librats/bittorrent/byte_io.h +58 -0
- package/native-src/src/librats/bittorrent/choker.cpp +25 -0
- package/native-src/src/librats/bittorrent/choker.h +46 -0
- package/native-src/src/librats/bittorrent/client.cpp +413 -0
- package/native-src/src/librats/bittorrent/client.h +227 -0
- package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
- package/native-src/src/librats/bittorrent/disk_io.h +150 -0
- package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
- package/native-src/src/librats/bittorrent/extensions.h +94 -0
- package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
- package/native-src/src/librats/bittorrent/file_storage.h +79 -0
- package/native-src/src/librats/bittorrent/log.h +42 -0
- package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
- package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
- package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
- package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
- package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
- package/native-src/src/librats/bittorrent/peer_list.h +75 -0
- package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
- package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
- package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
- package/native-src/src/librats/bittorrent/reactor.h +89 -0
- package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
- package/native-src/src/librats/bittorrent/resume_data.h +41 -0
- package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
- package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
- package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
- package/native-src/src/librats/bittorrent/torrent.h +260 -0
- package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
- package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
- package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
- package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
- package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
- package/native-src/src/librats/bittorrent/tracker.h +108 -0
- package/native-src/src/librats/bittorrent/types.cpp +206 -0
- package/native-src/src/librats/bittorrent/types.h +86 -0
- package/native-src/src/librats/core/address.cpp +35 -0
- package/native-src/src/librats/core/address.h +78 -0
- package/native-src/src/librats/core/bytes.h +69 -0
- package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
- package/native-src/src/librats/core/chained_send_buffer.h +183 -0
- package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
- package/native-src/src/librats/core/endpoint_parse.h +31 -0
- package/native-src/src/librats/core/event_bus.h +70 -0
- package/native-src/src/librats/core/host_endpoint.h +56 -0
- package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
- package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
- package/native-src/src/librats/core/ip_address.cpp +120 -0
- package/native-src/src/librats/core/ip_address.h +109 -0
- package/native-src/src/librats/core/mpsc_queue.h +47 -0
- package/native-src/src/librats/core/notifier.h +74 -0
- package/native-src/src/librats/core/receive_buffer.cpp +219 -0
- package/native-src/src/librats/core/receive_buffer.h +171 -0
- package/native-src/src/librats/core/service_registry.h +58 -0
- package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
- package/native-src/src/librats/core/socket.h +496 -0
- package/native-src/src/librats/core/timer_queue.h +105 -0
- package/native-src/src/librats/core/types.cpp +43 -0
- package/native-src/src/librats/core/types.h +103 -0
- package/native-src/src/librats/core/wakeup_pipe.h +83 -0
- package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
- package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
- package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
- package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
- package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
- package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
- package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
- package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
- package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
- package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
- package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
- package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
- package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
- package/native-src/src/librats/crypto/hkdf.c +266 -0
- package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
- package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
- package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
- package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
- package/native-src/src/librats/crypto/poly1305.h +37 -0
- package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
- package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
- package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
- package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
- package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
- package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
- package/native-src/src/librats/dht/announce.cpp +37 -0
- package/native-src/src/librats/dht/announce.h +41 -0
- package/native-src/src/librats/dht/bep42.cpp +109 -0
- package/native-src/src/librats/dht/bep42.h +48 -0
- package/native-src/src/librats/dht/dht.cpp +501 -0
- package/native-src/src/librats/dht/dht.h +119 -0
- package/native-src/src/librats/dht/dht_runner.cpp +103 -0
- package/native-src/src/librats/dht/dht_runner.h +71 -0
- package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
- package/native-src/src/librats/dht/dos_blocker.h +47 -0
- package/native-src/src/librats/dht/find_peers.cpp +52 -0
- package/native-src/src/librats/dht/find_peers.h +73 -0
- package/native-src/src/librats/dht/id.h +167 -0
- package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
- package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
- package/native-src/src/librats/dht/log.h +38 -0
- package/native-src/src/librats/dht/node.cpp +473 -0
- package/native-src/src/librats/dht/node.h +164 -0
- package/native-src/src/librats/dht/node_entry.h +81 -0
- package/native-src/src/librats/dht/observer.h +72 -0
- package/native-src/src/librats/dht/persistence.cpp +90 -0
- package/native-src/src/librats/dht/persistence.h +32 -0
- package/native-src/src/librats/dht/routing_table.cpp +559 -0
- package/native-src/src/librats/dht/routing_table.h +185 -0
- package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
- package/native-src/src/librats/dht/rpc_manager.h +77 -0
- package/native-src/src/librats/dht/storage.cpp +92 -0
- package/native-src/src/librats/dht/storage.h +74 -0
- package/native-src/src/librats/dht/transport.h +27 -0
- package/native-src/src/librats/dht/traversal.cpp +326 -0
- package/native-src/src/librats/dht/traversal.h +120 -0
- package/native-src/src/librats/dht/udp_transport.cpp +49 -0
- package/native-src/src/librats/dht/udp_transport.h +51 -0
- package/native-src/src/librats/mdns/log.h +22 -0
- package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
- package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
- package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
- package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
- package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
- package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
- package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
- package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
- package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
- package/native-src/src/librats/node/circuit_service.h +84 -0
- package/native-src/src/librats/node/config.h +110 -0
- package/native-src/src/librats/node/dial_service.h +54 -0
- package/native-src/src/librats/node/dialer.cpp +264 -0
- package/native-src/src/librats/node/dialer.h +188 -0
- package/native-src/src/librats/node/host_events.h +26 -0
- package/native-src/src/librats/node/identify.cpp +130 -0
- package/native-src/src/librats/node/identify.h +71 -0
- package/native-src/src/librats/node/nat_status.cpp +103 -0
- package/native-src/src/librats/node/nat_status.h +118 -0
- package/native-src/src/librats/node/node.cpp +865 -0
- package/native-src/src/librats/node/node.h +344 -0
- package/native-src/src/librats/node/node_context.h +33 -0
- package/native-src/src/librats/node/peer_network.h +91 -0
- package/native-src/src/librats/peer/peer.h +49 -0
- package/native-src/src/librats/peer/peer_book.cpp +181 -0
- package/native-src/src/librats/peer/peer_book.h +88 -0
- package/native-src/src/librats/peer/peer_id.cpp +72 -0
- package/native-src/src/librats/peer/peer_id.h +62 -0
- package/native-src/src/librats/peer/peer_info.h +37 -0
- package/native-src/src/librats/peer/peer_table.cpp +170 -0
- package/native-src/src/librats/peer/peer_table.h +148 -0
- package/native-src/src/librats/security/handshaker.h +66 -0
- package/native-src/src/librats/security/identity.h +43 -0
- package/native-src/src/librats/security/noise_security.cpp +122 -0
- package/native-src/src/librats/security/noise_security.h +37 -0
- package/native-src/src/librats/security/plaintext_security.h +106 -0
- package/native-src/src/librats/security/session.h +37 -0
- package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
- package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
- package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
- package/native-src/src/librats/subsystems/bittorrent.h +136 -0
- package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
- package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
- package/native-src/src/librats/subsystems/dht_service.h +36 -0
- package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
- package/native-src/src/librats/subsystems/file_transfer.h +367 -0
- package/native-src/src/librats/subsystems/hole_punch.cpp +605 -0
- package/native-src/src/librats/subsystems/hole_punch.h +290 -0
- package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
- package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
- package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
- package/native-src/src/librats/subsystems/message_json.cpp +112 -0
- package/native-src/src/librats/subsystems/message_json.h +88 -0
- package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
- package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
- package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
- package/native-src/src/librats/subsystems/ping_service.h +66 -0
- package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
- package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
- package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
- package/native-src/src/librats/subsystems/pubsub.h +175 -0
- package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
- package/native-src/src/librats/subsystems/reconnection.h +126 -0
- package/native-src/src/librats/subsystems/relay.cpp +1142 -0
- package/native-src/src/librats/subsystems/relay.h +211 -0
- package/native-src/src/librats/subsystems/relay_service.h +46 -0
- package/native-src/src/librats/transport/connection.cpp +343 -0
- package/native-src/src/librats/transport/connection.h +283 -0
- package/native-src/src/librats/transport/link.h +96 -0
- package/native-src/src/librats/transport/reactor.cpp +588 -0
- package/native-src/src/librats/transport/reactor.h +262 -0
- package/native-src/src/librats/transport/reactor_pool.h +81 -0
- package/native-src/src/librats/transport/relay_link.cpp +208 -0
- package/native-src/src/librats/transport/relay_link.h +303 -0
- package/native-src/src/librats/transport/tcp_link.cpp +49 -0
- package/native-src/src/librats/transport/tcp_link.h +43 -0
- package/native-src/src/librats/transport/udp_mux.cpp +617 -0
- package/native-src/src/librats/transport/udp_mux.h +363 -0
- package/native-src/src/librats/transport/udp_packet.cpp +121 -0
- package/native-src/src/librats/transport/udp_packet.h +190 -0
- package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
- package/native-src/src/librats/transport/udp_stream.h +614 -0
- package/native-src/src/librats/util/features.h.in +51 -0
- package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
- package/native-src/src/librats/util/fs.h +136 -0
- package/native-src/src/librats/util/json.cpp +1002 -0
- package/native-src/src/librats/util/json.h +444 -0
- package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
- package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
- package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
- package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
- package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
- package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
- package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
- package/native-src/src/librats/util/rats_export.h +69 -0
- package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
- package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
- package/native-src/src/librats/wire/frame.cpp +76 -0
- package/native-src/src/librats/wire/frame.h +111 -0
- package/native-src/src/librats/wire/message_router.cpp +45 -0
- package/native-src/src/librats/wire/message_router.h +47 -0
- package/package.json +5 -4
- package/scripts/build-librats.js +1 -0
- package/scripts/postinstall.js +3 -3
- package/scripts/prepare-package.js +4 -4
- package/scripts/verify-installation.js +63 -105
- package/src/librats_node.cpp +1067 -1323
- package/native-src/src/bencode.cpp +0 -485
- package/native-src/src/bencode.h +0 -145
- package/native-src/src/bittorrent.cpp +0 -14
- package/native-src/src/bittorrent.h +0 -74
- package/native-src/src/bt_bitfield.cpp +0 -372
- package/native-src/src/bt_bitfield.h +0 -316
- package/native-src/src/bt_choker.cpp +0 -228
- package/native-src/src/bt_choker.h +0 -147
- package/native-src/src/bt_client.cpp +0 -1047
- package/native-src/src/bt_client.h +0 -445
- package/native-src/src/bt_create_torrent.cpp +0 -677
- package/native-src/src/bt_create_torrent.h +0 -473
- package/native-src/src/bt_extension.cpp +0 -469
- package/native-src/src/bt_extension.h +0 -309
- package/native-src/src/bt_file_storage.cpp +0 -261
- package/native-src/src/bt_file_storage.h +0 -298
- package/native-src/src/bt_handshake.cpp +0 -134
- package/native-src/src/bt_handshake.h +0 -157
- package/native-src/src/bt_messages.cpp +0 -364
- package/native-src/src/bt_messages.h +0 -324
- package/native-src/src/bt_network.cpp +0 -1007
- package/native-src/src/bt_network.h +0 -417
- package/native-src/src/bt_peer_connection.cpp +0 -742
- package/native-src/src/bt_peer_connection.h +0 -592
- package/native-src/src/bt_piece_picker.cpp +0 -786
- package/native-src/src/bt_piece_picker.h +0 -473
- package/native-src/src/bt_resume_data.cpp +0 -410
- package/native-src/src/bt_resume_data.h +0 -249
- package/native-src/src/bt_torrent.cpp +0 -2120
- package/native-src/src/bt_torrent.h +0 -641
- package/native-src/src/bt_torrent_info.cpp +0 -659
- package/native-src/src/bt_torrent_info.h +0 -418
- package/native-src/src/bt_types.h +0 -621
- package/native-src/src/chained_send_buffer.cpp +0 -75
- package/native-src/src/chained_send_buffer.h +0 -137
- package/native-src/src/crypto/hkdf.c +0 -266
- package/native-src/src/crypto/poly1305.h +0 -36
- package/native-src/src/dht.cpp +0 -3311
- package/native-src/src/dht.h +0 -717
- package/native-src/src/disk_io.cpp +0 -632
- package/native-src/src/disk_io.h +0 -315
- package/native-src/src/file_transfer.cpp +0 -1415
- package/native-src/src/file_transfer.h +0 -286
- package/native-src/src/fs.h +0 -108
- package/native-src/src/gossipsub.cpp +0 -1139
- package/native-src/src/gossipsub.h +0 -403
- package/native-src/src/ice.cpp +0 -893
- package/native-src/src/ice.h +0 -559
- package/native-src/src/json.hpp +0 -25526
- package/native-src/src/librats.cpp +0 -2378
- package/native-src/src/librats.h +0 -2324
- package/native-src/src/librats_bittorrent.cpp +0 -601
- package/native-src/src/librats_c.cpp +0 -1557
- package/native-src/src/librats_c.h +0 -323
- package/native-src/src/librats_discovery.cpp +0 -402
- package/native-src/src/librats_encryption.cpp +0 -275
- package/native-src/src/librats_file_transfer.cpp +0 -144
- package/native-src/src/librats_gossipsub.cpp +0 -289
- package/native-src/src/librats_ice.cpp +0 -213
- package/native-src/src/librats_log_macros.h +0 -36
- package/native-src/src/librats_logging.cpp +0 -173
- package/native-src/src/librats_mdns.cpp +0 -166
- package/native-src/src/librats_persistence.cpp +0 -796
- package/native-src/src/librats_portmap.cpp +0 -419
- package/native-src/src/librats_reconnection.cpp +0 -218
- package/native-src/src/librats_statistic.cpp +0 -105
- package/native-src/src/librats_storage.cpp +0 -189
- package/native-src/src/rats_export.h +0 -17
- package/native-src/src/receive_buffer.cpp +0 -82
- package/native-src/src/receive_buffer.h +0 -127
- package/native-src/src/socket.h +0 -228
- package/native-src/src/threadmanager.cpp +0 -105
- package/native-src/src/threadmanager.h +0 -53
- package/native-src/src/tracker.cpp +0 -1264
- package/native-src/src/tracker.h +0 -319
- package/native-src/src/turn.cpp +0 -762
- package/native-src/src/turn.h +0 -460
- package/native-src/src/wakeup_pipe.h +0 -60
- /package/native-src/src/{os.h → librats/util/os.h} +0 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* HKDF-SHA256 implementation for Noise Protocol
|
|
3
|
+
* Based on RFC 5869
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
#include "librats/crypto/hkdf.h"
|
|
7
|
+
#include "librats/crypto/sha256.h"
|
|
8
|
+
#include <string.h>
|
|
9
|
+
|
|
10
|
+
#define RATS_SHA256_BLOCK_SIZE 64
|
|
11
|
+
#define RATS_SHA256_HASH_SIZE 32
|
|
12
|
+
|
|
13
|
+
/* Zero memory securely */
|
|
14
|
+
static void secure_zero(void *ptr, size_t len) {
|
|
15
|
+
volatile uint8_t *p = (volatile uint8_t *)ptr;
|
|
16
|
+
while (len--) {
|
|
17
|
+
*p++ = 0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
void rats_hmac_sha256(
|
|
22
|
+
const uint8_t *key, size_t key_len,
|
|
23
|
+
const uint8_t *data, size_t data_len,
|
|
24
|
+
uint8_t output[RATS_HKDF_SHA256_HASH_LEN]
|
|
25
|
+
) {
|
|
26
|
+
rats_sha256_context_t ctx;
|
|
27
|
+
uint8_t k_pad[RATS_SHA256_BLOCK_SIZE];
|
|
28
|
+
uint8_t temp_key[RATS_SHA256_HASH_SIZE];
|
|
29
|
+
const uint8_t *k;
|
|
30
|
+
size_t k_len;
|
|
31
|
+
size_t i;
|
|
32
|
+
|
|
33
|
+
/* If key is longer than block size, hash it first */
|
|
34
|
+
if (key_len > RATS_SHA256_BLOCK_SIZE) {
|
|
35
|
+
rats_sha256_hash(temp_key, key, key_len);
|
|
36
|
+
k = temp_key;
|
|
37
|
+
k_len = RATS_SHA256_HASH_SIZE;
|
|
38
|
+
} else {
|
|
39
|
+
k = key;
|
|
40
|
+
k_len = key_len;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Prepare inner padding (key XOR 0x36) */
|
|
44
|
+
memset(k_pad, 0x36, RATS_SHA256_BLOCK_SIZE);
|
|
45
|
+
for (i = 0; i < k_len; i++) {
|
|
46
|
+
k_pad[i] ^= k[i];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Inner hash: H(K XOR ipad || data) */
|
|
50
|
+
rats_sha256_reset(&ctx);
|
|
51
|
+
rats_sha256_update(&ctx, k_pad, RATS_SHA256_BLOCK_SIZE);
|
|
52
|
+
rats_sha256_update(&ctx, data, data_len);
|
|
53
|
+
rats_sha256_finish(&ctx, output);
|
|
54
|
+
|
|
55
|
+
/* Prepare outer padding (key XOR 0x5c) */
|
|
56
|
+
memset(k_pad, 0x5c, RATS_SHA256_BLOCK_SIZE);
|
|
57
|
+
for (i = 0; i < k_len; i++) {
|
|
58
|
+
k_pad[i] ^= k[i];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* Outer hash: H(K XOR opad || inner_hash) */
|
|
62
|
+
rats_sha256_reset(&ctx);
|
|
63
|
+
rats_sha256_update(&ctx, k_pad, RATS_SHA256_BLOCK_SIZE);
|
|
64
|
+
rats_sha256_update(&ctx, output, RATS_SHA256_HASH_SIZE);
|
|
65
|
+
rats_sha256_finish(&ctx, output);
|
|
66
|
+
|
|
67
|
+
/* Clean up */
|
|
68
|
+
secure_zero(k_pad, sizeof(k_pad));
|
|
69
|
+
secure_zero(temp_key, sizeof(temp_key));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
void rats_hmac_sha256_2(
|
|
73
|
+
const uint8_t *key, size_t key_len,
|
|
74
|
+
const uint8_t *data1, size_t data1_len,
|
|
75
|
+
const uint8_t *data2, size_t data2_len,
|
|
76
|
+
uint8_t output[RATS_HKDF_SHA256_HASH_LEN]
|
|
77
|
+
) {
|
|
78
|
+
rats_sha256_context_t ctx;
|
|
79
|
+
uint8_t k_pad[RATS_SHA256_BLOCK_SIZE];
|
|
80
|
+
uint8_t temp_key[RATS_SHA256_HASH_SIZE];
|
|
81
|
+
const uint8_t *k;
|
|
82
|
+
size_t k_len;
|
|
83
|
+
size_t i;
|
|
84
|
+
|
|
85
|
+
/* If key is longer than block size, hash it first */
|
|
86
|
+
if (key_len > RATS_SHA256_BLOCK_SIZE) {
|
|
87
|
+
rats_sha256_hash(temp_key, key, key_len);
|
|
88
|
+
k = temp_key;
|
|
89
|
+
k_len = RATS_SHA256_HASH_SIZE;
|
|
90
|
+
} else {
|
|
91
|
+
k = key;
|
|
92
|
+
k_len = key_len;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Prepare inner padding (key XOR 0x36) */
|
|
96
|
+
memset(k_pad, 0x36, RATS_SHA256_BLOCK_SIZE);
|
|
97
|
+
for (i = 0; i < k_len; i++) {
|
|
98
|
+
k_pad[i] ^= k[i];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* Inner hash: H(K XOR ipad || data1 || data2) */
|
|
102
|
+
rats_sha256_reset(&ctx);
|
|
103
|
+
rats_sha256_update(&ctx, k_pad, RATS_SHA256_BLOCK_SIZE);
|
|
104
|
+
rats_sha256_update(&ctx, data1, data1_len);
|
|
105
|
+
rats_sha256_update(&ctx, data2, data2_len);
|
|
106
|
+
rats_sha256_finish(&ctx, output);
|
|
107
|
+
|
|
108
|
+
/* Prepare outer padding (key XOR 0x5c) */
|
|
109
|
+
memset(k_pad, 0x5c, RATS_SHA256_BLOCK_SIZE);
|
|
110
|
+
for (i = 0; i < k_len; i++) {
|
|
111
|
+
k_pad[i] ^= k[i];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* Outer hash: H(K XOR opad || inner_hash) */
|
|
115
|
+
rats_sha256_reset(&ctx);
|
|
116
|
+
rats_sha256_update(&ctx, k_pad, RATS_SHA256_BLOCK_SIZE);
|
|
117
|
+
rats_sha256_update(&ctx, output, RATS_SHA256_HASH_SIZE);
|
|
118
|
+
rats_sha256_finish(&ctx, output);
|
|
119
|
+
|
|
120
|
+
/* Clean up */
|
|
121
|
+
secure_zero(k_pad, sizeof(k_pad));
|
|
122
|
+
secure_zero(temp_key, sizeof(temp_key));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
void rats_hkdf_sha256_extract(
|
|
126
|
+
const uint8_t *salt, size_t salt_len,
|
|
127
|
+
const uint8_t *ikm, size_t ikm_len,
|
|
128
|
+
uint8_t prk[RATS_HKDF_SHA256_HASH_LEN]
|
|
129
|
+
) {
|
|
130
|
+
static const uint8_t default_salt[RATS_HKDF_SHA256_HASH_LEN] = {0};
|
|
131
|
+
|
|
132
|
+
if (salt == NULL || salt_len == 0) {
|
|
133
|
+
salt = default_salt;
|
|
134
|
+
salt_len = RATS_HKDF_SHA256_HASH_LEN;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
rats_hmac_sha256(salt, salt_len, ikm, ikm_len, prk);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
void rats_hkdf_sha256_expand(
|
|
141
|
+
const uint8_t prk[RATS_HKDF_SHA256_HASH_LEN],
|
|
142
|
+
const uint8_t *info, size_t info_len,
|
|
143
|
+
uint8_t *okm, size_t okm_len
|
|
144
|
+
) {
|
|
145
|
+
rats_sha256_context_t ctx;
|
|
146
|
+
uint8_t k_pad[RATS_SHA256_BLOCK_SIZE];
|
|
147
|
+
uint8_t T[RATS_SHA256_HASH_SIZE];
|
|
148
|
+
uint8_t counter;
|
|
149
|
+
size_t t_len = 0;
|
|
150
|
+
size_t copy_len;
|
|
151
|
+
size_t i;
|
|
152
|
+
|
|
153
|
+
/* Key is always 32 bytes (hash length) */
|
|
154
|
+
/* Prepare inner padding template */
|
|
155
|
+
memset(k_pad, 0x36, RATS_SHA256_BLOCK_SIZE);
|
|
156
|
+
for (i = 0; i < RATS_HKDF_SHA256_HASH_LEN; i++) {
|
|
157
|
+
k_pad[i] ^= prk[i];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
counter = 1;
|
|
161
|
+
while (okm_len > 0) {
|
|
162
|
+
uint8_t outer_result[RATS_SHA256_HASH_SIZE];
|
|
163
|
+
uint8_t k_pad_outer[RATS_SHA256_BLOCK_SIZE];
|
|
164
|
+
|
|
165
|
+
/* Inner hash: H(K XOR ipad || T || info || counter) */
|
|
166
|
+
rats_sha256_reset(&ctx);
|
|
167
|
+
rats_sha256_update(&ctx, k_pad, RATS_SHA256_BLOCK_SIZE);
|
|
168
|
+
if (t_len > 0) {
|
|
169
|
+
rats_sha256_update(&ctx, T, t_len);
|
|
170
|
+
}
|
|
171
|
+
if (info_len > 0) {
|
|
172
|
+
rats_sha256_update(&ctx, info, info_len);
|
|
173
|
+
}
|
|
174
|
+
rats_sha256_update(&ctx, &counter, 1);
|
|
175
|
+
rats_sha256_finish(&ctx, T);
|
|
176
|
+
|
|
177
|
+
/* Prepare outer padding */
|
|
178
|
+
memset(k_pad_outer, 0x5c, RATS_SHA256_BLOCK_SIZE);
|
|
179
|
+
for (i = 0; i < RATS_HKDF_SHA256_HASH_LEN; i++) {
|
|
180
|
+
k_pad_outer[i] ^= prk[i];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* Outer hash: H(K XOR opad || inner_hash) */
|
|
184
|
+
rats_sha256_reset(&ctx);
|
|
185
|
+
rats_sha256_update(&ctx, k_pad_outer, RATS_SHA256_BLOCK_SIZE);
|
|
186
|
+
rats_sha256_update(&ctx, T, RATS_SHA256_HASH_SIZE);
|
|
187
|
+
rats_sha256_finish(&ctx, T);
|
|
188
|
+
|
|
189
|
+
/* Copy to output */
|
|
190
|
+
copy_len = okm_len < RATS_SHA256_HASH_SIZE ? okm_len : RATS_SHA256_HASH_SIZE;
|
|
191
|
+
memcpy(okm, T, copy_len);
|
|
192
|
+
okm += copy_len;
|
|
193
|
+
okm_len -= copy_len;
|
|
194
|
+
|
|
195
|
+
t_len = RATS_SHA256_HASH_SIZE;
|
|
196
|
+
counter++;
|
|
197
|
+
|
|
198
|
+
secure_zero(k_pad_outer, sizeof(k_pad_outer));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
secure_zero(k_pad, sizeof(k_pad));
|
|
202
|
+
secure_zero(T, sizeof(T));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
void rats_hkdf_sha256(
|
|
206
|
+
const uint8_t *salt, size_t salt_len,
|
|
207
|
+
const uint8_t *ikm, size_t ikm_len,
|
|
208
|
+
const uint8_t *info, size_t info_len,
|
|
209
|
+
uint8_t *okm, size_t okm_len
|
|
210
|
+
) {
|
|
211
|
+
uint8_t prk[RATS_HKDF_SHA256_HASH_LEN];
|
|
212
|
+
|
|
213
|
+
rats_hkdf_sha256_extract(salt, salt_len, ikm, ikm_len, prk);
|
|
214
|
+
rats_hkdf_sha256_expand(prk, info, info_len, okm, okm_len);
|
|
215
|
+
|
|
216
|
+
secure_zero(prk, sizeof(prk));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
void rats_noise_hkdf_2(
|
|
220
|
+
const uint8_t chaining_key[RATS_HKDF_SHA256_HASH_LEN],
|
|
221
|
+
const uint8_t *input_key, size_t input_len,
|
|
222
|
+
uint8_t output1[RATS_HKDF_SHA256_HASH_LEN],
|
|
223
|
+
uint8_t output2[RATS_HKDF_SHA256_HASH_LEN]
|
|
224
|
+
) {
|
|
225
|
+
uint8_t temp_key[RATS_HKDF_SHA256_HASH_LEN];
|
|
226
|
+
uint8_t counter1 = 0x01;
|
|
227
|
+
uint8_t counter2 = 0x02;
|
|
228
|
+
|
|
229
|
+
/* temp_key = HMAC(ck, input) */
|
|
230
|
+
rats_hmac_sha256(chaining_key, RATS_HKDF_SHA256_HASH_LEN, input_key, input_len, temp_key);
|
|
231
|
+
|
|
232
|
+
/* output1 = HMAC(temp_key, 0x01) */
|
|
233
|
+
rats_hmac_sha256(temp_key, RATS_HKDF_SHA256_HASH_LEN, &counter1, 1, output1);
|
|
234
|
+
|
|
235
|
+
/* output2 = HMAC(temp_key, output1 || 0x02) */
|
|
236
|
+
rats_hmac_sha256_2(temp_key, RATS_HKDF_SHA256_HASH_LEN, output1, RATS_HKDF_SHA256_HASH_LEN, &counter2, 1, output2);
|
|
237
|
+
|
|
238
|
+
secure_zero(temp_key, sizeof(temp_key));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
void rats_noise_hkdf_3(
|
|
242
|
+
const uint8_t chaining_key[RATS_HKDF_SHA256_HASH_LEN],
|
|
243
|
+
const uint8_t *input_key, size_t input_len,
|
|
244
|
+
uint8_t output1[RATS_HKDF_SHA256_HASH_LEN],
|
|
245
|
+
uint8_t output2[RATS_HKDF_SHA256_HASH_LEN],
|
|
246
|
+
uint8_t output3[RATS_HKDF_SHA256_HASH_LEN]
|
|
247
|
+
) {
|
|
248
|
+
uint8_t temp_key[RATS_HKDF_SHA256_HASH_LEN];
|
|
249
|
+
uint8_t counter1 = 0x01;
|
|
250
|
+
uint8_t counter2 = 0x02;
|
|
251
|
+
uint8_t counter3 = 0x03;
|
|
252
|
+
|
|
253
|
+
/* temp_key = HMAC(ck, input) */
|
|
254
|
+
rats_hmac_sha256(chaining_key, RATS_HKDF_SHA256_HASH_LEN, input_key, input_len, temp_key);
|
|
255
|
+
|
|
256
|
+
/* output1 = HMAC(temp_key, 0x01) */
|
|
257
|
+
rats_hmac_sha256(temp_key, RATS_HKDF_SHA256_HASH_LEN, &counter1, 1, output1);
|
|
258
|
+
|
|
259
|
+
/* output2 = HMAC(temp_key, output1 || 0x02) */
|
|
260
|
+
rats_hmac_sha256_2(temp_key, RATS_HKDF_SHA256_HASH_LEN, output1, RATS_HKDF_SHA256_HASH_LEN, &counter2, 1, output2);
|
|
261
|
+
|
|
262
|
+
/* output3 = HMAC(temp_key, output2 || 0x03) */
|
|
263
|
+
rats_hmac_sha256_2(temp_key, RATS_HKDF_SHA256_HASH_LEN, output2, RATS_HKDF_SHA256_HASH_LEN, &counter3, 1, output3);
|
|
264
|
+
|
|
265
|
+
secure_zero(temp_key, sizeof(temp_key));
|
|
266
|
+
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
extern "C" {
|
|
14
14
|
#endif
|
|
15
15
|
|
|
16
|
-
#define
|
|
16
|
+
#define RATS_HKDF_SHA256_HASH_LEN 32
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* HMAC-SHA256 function
|
|
@@ -24,10 +24,10 @@ extern "C" {
|
|
|
24
24
|
* @param data_len Length of data
|
|
25
25
|
* @param output Output buffer (32 bytes)
|
|
26
26
|
*/
|
|
27
|
-
void
|
|
27
|
+
void rats_hmac_sha256(
|
|
28
28
|
const uint8_t *key, size_t key_len,
|
|
29
29
|
const uint8_t *data, size_t data_len,
|
|
30
|
-
uint8_t output[
|
|
30
|
+
uint8_t output[RATS_HKDF_SHA256_HASH_LEN]
|
|
31
31
|
);
|
|
32
32
|
|
|
33
33
|
/**
|
|
@@ -41,11 +41,11 @@ void hmac_sha256(
|
|
|
41
41
|
* @param data2_len Length of second data block
|
|
42
42
|
* @param output Output buffer (32 bytes)
|
|
43
43
|
*/
|
|
44
|
-
void
|
|
44
|
+
void rats_hmac_sha256_2(
|
|
45
45
|
const uint8_t *key, size_t key_len,
|
|
46
46
|
const uint8_t *data1, size_t data1_len,
|
|
47
47
|
const uint8_t *data2, size_t data2_len,
|
|
48
|
-
uint8_t output[
|
|
48
|
+
uint8_t output[RATS_HKDF_SHA256_HASH_LEN]
|
|
49
49
|
);
|
|
50
50
|
|
|
51
51
|
/**
|
|
@@ -57,10 +57,10 @@ void hmac_sha256_2(
|
|
|
57
57
|
* @param ikm_len Length of IKM
|
|
58
58
|
* @param prk Output pseudorandom key (32 bytes)
|
|
59
59
|
*/
|
|
60
|
-
void
|
|
60
|
+
void rats_hkdf_sha256_extract(
|
|
61
61
|
const uint8_t *salt, size_t salt_len,
|
|
62
62
|
const uint8_t *ikm, size_t ikm_len,
|
|
63
|
-
uint8_t prk[
|
|
63
|
+
uint8_t prk[RATS_HKDF_SHA256_HASH_LEN]
|
|
64
64
|
);
|
|
65
65
|
|
|
66
66
|
/**
|
|
@@ -72,8 +72,8 @@ void hkdf_sha256_extract(
|
|
|
72
72
|
* @param okm Output keying material
|
|
73
73
|
* @param okm_len Length of OKM (max 255 * 32 = 8160 bytes)
|
|
74
74
|
*/
|
|
75
|
-
void
|
|
76
|
-
const uint8_t prk[
|
|
75
|
+
void rats_hkdf_sha256_expand(
|
|
76
|
+
const uint8_t prk[RATS_HKDF_SHA256_HASH_LEN],
|
|
77
77
|
const uint8_t *info, size_t info_len,
|
|
78
78
|
uint8_t *okm, size_t okm_len
|
|
79
79
|
);
|
|
@@ -90,7 +90,7 @@ void hkdf_sha256_expand(
|
|
|
90
90
|
* @param okm Output keying material
|
|
91
91
|
* @param okm_len Length of OKM
|
|
92
92
|
*/
|
|
93
|
-
void
|
|
93
|
+
void rats_hkdf_sha256(
|
|
94
94
|
const uint8_t *salt, size_t salt_len,
|
|
95
95
|
const uint8_t *ikm, size_t ikm_len,
|
|
96
96
|
const uint8_t *info, size_t info_len,
|
|
@@ -108,11 +108,11 @@ void hkdf_sha256(
|
|
|
108
108
|
* @param output1 First output key (32 bytes)
|
|
109
109
|
* @param output2 Second output key (32 bytes)
|
|
110
110
|
*/
|
|
111
|
-
void
|
|
112
|
-
const uint8_t chaining_key[
|
|
111
|
+
void rats_noise_hkdf_2(
|
|
112
|
+
const uint8_t chaining_key[RATS_HKDF_SHA256_HASH_LEN],
|
|
113
113
|
const uint8_t *input_key, size_t input_len,
|
|
114
|
-
uint8_t output1[
|
|
115
|
-
uint8_t output2[
|
|
114
|
+
uint8_t output1[RATS_HKDF_SHA256_HASH_LEN],
|
|
115
|
+
uint8_t output2[RATS_HKDF_SHA256_HASH_LEN]
|
|
116
116
|
);
|
|
117
117
|
|
|
118
118
|
/**
|
|
@@ -126,12 +126,12 @@ void noise_hkdf_2(
|
|
|
126
126
|
* @param output2 Second output key (32 bytes)
|
|
127
127
|
* @param output3 Third output key (32 bytes)
|
|
128
128
|
*/
|
|
129
|
-
void
|
|
130
|
-
const uint8_t chaining_key[
|
|
129
|
+
void rats_noise_hkdf_3(
|
|
130
|
+
const uint8_t chaining_key[RATS_HKDF_SHA256_HASH_LEN],
|
|
131
131
|
const uint8_t *input_key, size_t input_len,
|
|
132
|
-
uint8_t output1[
|
|
133
|
-
uint8_t output2[
|
|
134
|
-
uint8_t output3[
|
|
132
|
+
uint8_t output1[RATS_HKDF_SHA256_HASH_LEN],
|
|
133
|
+
uint8_t output2[RATS_HKDF_SHA256_HASH_LEN],
|
|
134
|
+
uint8_t output3[RATS_HKDF_SHA256_HASH_LEN]
|
|
135
135
|
);
|
|
136
136
|
|
|
137
137
|
#ifdef __cplusplus
|
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
* Implements Noise_XX_25519_ChaChaPoly_SHA256
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
#include "noise.h"
|
|
7
|
-
#include "logger.h"
|
|
6
|
+
#include "librats/crypto/noise.h"
|
|
7
|
+
#include "librats/util/logger.h"
|
|
8
8
|
#include <cstring>
|
|
9
9
|
#include <random>
|
|
10
10
|
#include <iomanip>
|
|
11
11
|
#include <sstream>
|
|
12
12
|
|
|
13
13
|
extern "C" {
|
|
14
|
-
#include "crypto/chachapoly.h"
|
|
15
|
-
#include "crypto/hkdf.h"
|
|
16
|
-
#include "crypto/sha256.h"
|
|
17
|
-
#include "crypto/curve25519.h"
|
|
14
|
+
#include "librats/crypto/chachapoly.h"
|
|
15
|
+
#include "librats/crypto/hkdf.h"
|
|
16
|
+
#include "librats/crypto/sha256.h"
|
|
17
|
+
#include "librats/crypto/curve25519.h"
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// Noise Protocol logging macros
|
|
@@ -23,7 +23,7 @@ extern "C" {
|
|
|
23
23
|
#define LOG_NOISE_WARN(message) LOG_WARN("noise", message)
|
|
24
24
|
#define LOG_NOISE_ERROR(message) LOG_ERROR("noise", message)
|
|
25
25
|
|
|
26
|
-
namespace
|
|
26
|
+
namespace librats {
|
|
27
27
|
|
|
28
28
|
/* Helper to format public key prefix for logging (first 8 hex chars) */
|
|
29
29
|
static std::string format_key_prefix(const uint8_t* key) {
|
|
@@ -96,7 +96,7 @@ size_t NoiseCipherState::encrypt_with_ad(
|
|
|
96
96
|
uint8_t nonce[12];
|
|
97
97
|
make_nonce(nonce, nonce_);
|
|
98
98
|
|
|
99
|
-
size_t result =
|
|
99
|
+
size_t result = rats_chachapoly_encrypt(
|
|
100
100
|
key_, nonce,
|
|
101
101
|
ad, ad_len,
|
|
102
102
|
plaintext, pt_len,
|
|
@@ -127,48 +127,28 @@ size_t NoiseCipherState::decrypt_with_ad(
|
|
|
127
127
|
|
|
128
128
|
if (ct_len < NOISE_TAG_SIZE) {
|
|
129
129
|
LOG_NOISE_ERROR("Ciphertext too small: " << ct_len << " bytes (min: " << NOISE_TAG_SIZE << ")");
|
|
130
|
-
return
|
|
130
|
+
return NOISE_DECRYPT_FAILED;
|
|
131
131
|
}
|
|
132
|
-
|
|
132
|
+
|
|
133
133
|
uint8_t nonce[12];
|
|
134
134
|
make_nonce(nonce, nonce_);
|
|
135
|
-
|
|
136
|
-
size_t result =
|
|
135
|
+
|
|
136
|
+
size_t result = rats_chachapoly_decrypt(
|
|
137
137
|
key_, nonce,
|
|
138
138
|
ad, ad_len,
|
|
139
139
|
ciphertext, ct_len,
|
|
140
140
|
plaintext
|
|
141
141
|
);
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
|
|
143
|
+
/* A valid decryption may return 0 (empty authenticated payload); only the
|
|
144
|
+
* sentinel signals failure. */
|
|
145
|
+
if (result != RATS_CHACHAPOLY_DECRYPT_FAILED) {
|
|
144
146
|
nonce_++;
|
|
145
147
|
LOG_NOISE_DEBUG("Decrypted " << ct_len << " bytes -> " << result << " bytes (nonce: " << nonce_ << ")");
|
|
146
|
-
|
|
147
|
-
LOG_NOISE_ERROR("Decryption failed for " << ct_len << " bytes - authentication failed");
|
|
148
|
+
return result;
|
|
148
149
|
}
|
|
149
|
-
|
|
150
|
-
return
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
void NoiseCipherState::rekey() {
|
|
154
|
-
if (!has_key_) {
|
|
155
|
-
LOG_NOISE_WARN("Rekey called but no key is set");
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
uint8_t zeros[NOISE_KEY_SIZE] = {0};
|
|
160
|
-
uint8_t new_key[NOISE_KEY_SIZE + NOISE_TAG_SIZE];
|
|
161
|
-
|
|
162
|
-
uint8_t nonce[12];
|
|
163
|
-
/* Use max nonce value for rekey */
|
|
164
|
-
memset(nonce, 0xFF, 12);
|
|
165
|
-
|
|
166
|
-
chachapoly_encrypt(key_, nonce, nullptr, 0, zeros, NOISE_KEY_SIZE, new_key);
|
|
167
|
-
|
|
168
|
-
memcpy(key_, new_key, NOISE_KEY_SIZE);
|
|
169
|
-
secure_zero(new_key, sizeof(new_key));
|
|
170
|
-
|
|
171
|
-
LOG_NOISE_INFO("CipherState rekeyed successfully");
|
|
150
|
+
LOG_NOISE_ERROR("Decryption failed for " << ct_len << " bytes - authentication failed");
|
|
151
|
+
return NOISE_DECRYPT_FAILED;
|
|
172
152
|
}
|
|
173
153
|
|
|
174
154
|
void NoiseCipherState::clear() {
|
|
@@ -197,7 +177,7 @@ void NoiseSymmetricState::initialize_symmetric(const char* protocol_name) {
|
|
|
197
177
|
memcpy(h_, protocol_name, name_len);
|
|
198
178
|
} else {
|
|
199
179
|
/* Otherwise, hash the protocol name */
|
|
200
|
-
|
|
180
|
+
rats_sha256_hash(h_, protocol_name, name_len);
|
|
201
181
|
}
|
|
202
182
|
|
|
203
183
|
/* ck = h */
|
|
@@ -210,7 +190,7 @@ void NoiseSymmetricState::mix_key(const uint8_t* input_key_material, size_t len)
|
|
|
210
190
|
uint8_t temp_k[NOISE_KEY_SIZE];
|
|
211
191
|
|
|
212
192
|
/* HKDF(ck, input_key_material) -> (new_ck, temp_k) */
|
|
213
|
-
|
|
193
|
+
rats_noise_hkdf_2(ck_, input_key_material, len, ck_, temp_k);
|
|
214
194
|
|
|
215
195
|
/* Initialize cipher with temp_k */
|
|
216
196
|
cipher_.initialize_key(temp_k);
|
|
@@ -222,11 +202,11 @@ void NoiseSymmetricState::mix_key(const uint8_t* input_key_material, size_t len)
|
|
|
222
202
|
|
|
223
203
|
void NoiseSymmetricState::mix_hash(const uint8_t* data, size_t len) {
|
|
224
204
|
/* h = SHA256(h || data) */
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
205
|
+
rats_sha256_context_t ctx;
|
|
206
|
+
rats_sha256_reset(&ctx);
|
|
207
|
+
rats_sha256_update(&ctx, h_, NOISE_HASH_SIZE);
|
|
208
|
+
rats_sha256_update(&ctx, data, len);
|
|
209
|
+
rats_sha256_finish(&ctx, h_);
|
|
230
210
|
|
|
231
211
|
LOG_NOISE_DEBUG("MixHash: mixed " << len << " bytes into handshake hash");
|
|
232
212
|
}
|
|
@@ -243,7 +223,21 @@ size_t NoiseSymmetricState::encrypt_and_hash(const uint8_t* plaintext, size_t pt
|
|
|
243
223
|
return ct_len;
|
|
244
224
|
}
|
|
245
225
|
|
|
246
|
-
size_t NoiseSymmetricState::decrypt_and_hash(const uint8_t* ciphertext, size_t ct_len, uint8_t* plaintext) {
|
|
226
|
+
size_t NoiseSymmetricState::decrypt_and_hash(const uint8_t* ciphertext, size_t ct_len, uint8_t* plaintext, size_t plaintext_cap) {
|
|
227
|
+
/* Bound the write before touching `plaintext`. A keyed decrypt yields
|
|
228
|
+
* ct_len - NOISE_TAG_SIZE bytes; a passthrough copy (no key) yields ct_len.
|
|
229
|
+
* Refuse anything that would overflow the caller's buffer — this is the
|
|
230
|
+
* guard against an oversized handshake message smashing a fixed-size
|
|
231
|
+
* payload buffer (the ciphertext length is attacker-controlled). */
|
|
232
|
+
const size_t pt_max = cipher_has_key()
|
|
233
|
+
? (ct_len >= NOISE_TAG_SIZE ? ct_len - NOISE_TAG_SIZE : 0)
|
|
234
|
+
: ct_len;
|
|
235
|
+
if (pt_max > plaintext_cap) {
|
|
236
|
+
LOG_NOISE_ERROR("decrypt_and_hash: plaintext " << pt_max
|
|
237
|
+
<< " exceeds output buffer capacity " << plaintext_cap);
|
|
238
|
+
return NOISE_DECRYPT_FAILED;
|
|
239
|
+
}
|
|
240
|
+
|
|
247
241
|
/* Save ciphertext for mixing (before decryption modifies anything) */
|
|
248
242
|
/* Mix ciphertext into hash first */
|
|
249
243
|
uint8_t h_backup[NOISE_HASH_SIZE];
|
|
@@ -263,7 +257,7 @@ void NoiseSymmetricState::split(NoiseCipherState& c1, NoiseCipherState& c2) {
|
|
|
263
257
|
uint8_t temp_k2[NOISE_KEY_SIZE];
|
|
264
258
|
|
|
265
259
|
/* HKDF(ck, empty) -> (temp_k1, temp_k2) */
|
|
266
|
-
|
|
260
|
+
rats_noise_hkdf_2(ck_, nullptr, 0, temp_k1, temp_k2);
|
|
267
261
|
|
|
268
262
|
c1.initialize_key(temp_k1);
|
|
269
263
|
c2.initialize_key(temp_k2);
|
|
@@ -303,7 +297,7 @@ void NoiseHandshakeState::generate_ephemeral() {
|
|
|
303
297
|
e_.private_key[31] |= 64;
|
|
304
298
|
|
|
305
299
|
/* Derive public key */
|
|
306
|
-
|
|
300
|
+
rats_curve25519_donna(e_.public_key, e_.private_key, rats_curve25519_basepoint);
|
|
307
301
|
e_.has_keys = true;
|
|
308
302
|
|
|
309
303
|
LOG_NOISE_DEBUG("Generated ephemeral keypair (pub: " << format_key_prefix(e_.public_key) << "...)");
|
|
@@ -312,7 +306,7 @@ void NoiseHandshakeState::generate_ephemeral() {
|
|
|
312
306
|
void NoiseHandshakeState::mix_dh(const uint8_t* local_private, const uint8_t* remote_public) {
|
|
313
307
|
uint8_t dh_output[NOISE_DH_SIZE];
|
|
314
308
|
|
|
315
|
-
|
|
309
|
+
rats_curve25519_donna(dh_output, local_private, remote_public);
|
|
316
310
|
symmetric_.mix_key(dh_output, NOISE_DH_SIZE);
|
|
317
311
|
|
|
318
312
|
secure_zero(dh_output, NOISE_DH_SIZE);
|
|
@@ -366,7 +360,7 @@ size_t NoiseHandshakeState::read_s(const uint8_t* in, size_t len) {
|
|
|
366
360
|
return 0;
|
|
367
361
|
}
|
|
368
362
|
|
|
369
|
-
size_t pt_len = symmetric_.decrypt_and_hash(in, expected_len, rs_.public_key);
|
|
363
|
+
size_t pt_len = symmetric_.decrypt_and_hash(in, expected_len, rs_.public_key, NOISE_DH_SIZE);
|
|
370
364
|
if (pt_len != NOISE_DH_SIZE) {
|
|
371
365
|
LOG_NOISE_ERROR("Read static failed: decryption returned " << pt_len << " bytes (expected " << NOISE_DH_SIZE << ")");
|
|
372
366
|
return 0;
|
|
@@ -392,9 +386,12 @@ NoiseError NoiseHandshakeState::initialize(
|
|
|
392
386
|
/* Initialize symmetric state with protocol name */
|
|
393
387
|
symmetric_.initialize_symmetric(NOISE_PROTOCOL_NAME);
|
|
394
388
|
|
|
395
|
-
/* Mix in prologue
|
|
396
|
-
|
|
397
|
-
|
|
389
|
+
/* Mix in the prologue unconditionally. Per the Noise spec MixHash(prologue) is
|
|
390
|
+
* always applied — an empty prologue is still hashed (over zero bytes), which
|
|
391
|
+
* alters the handshake hash, so both peers must do it whether or not one is set. */
|
|
392
|
+
{
|
|
393
|
+
static const uint8_t empty = 0;
|
|
394
|
+
symmetric_.mix_hash(prologue != nullptr ? prologue : &empty, prologue_len);
|
|
398
395
|
LOG_NOISE_DEBUG("Mixed prologue into handshake hash: " << prologue_len << " bytes");
|
|
399
396
|
}
|
|
400
397
|
|
|
@@ -495,14 +492,20 @@ NoiseError NoiseHandshakeState::write_message(
|
|
|
495
492
|
}
|
|
496
493
|
}
|
|
497
494
|
|
|
498
|
-
/*
|
|
499
|
-
|
|
500
|
-
|
|
495
|
+
/* Append the payload. Per the Noise spec EncryptAndHash runs on every message,
|
|
496
|
+
* even with an empty payload: once a key is established this still emits a
|
|
497
|
+
* 16-byte auth tag and mixes it into the handshake hash (so the message length
|
|
498
|
+
* and transcript match a spec-compliant peer). */
|
|
499
|
+
{
|
|
500
|
+
const uint8_t* pl = (payload != nullptr) ? payload : reinterpret_cast<const uint8_t*>("");
|
|
501
|
+
const size_t pll = (payload != nullptr) ? payload_len : 0;
|
|
502
|
+
const size_t tag = symmetric_.cipher_.has_key() ? NOISE_TAG_SIZE : 0;
|
|
503
|
+
if (offset + pll + tag > max_len) {
|
|
501
504
|
LOG_NOISE_ERROR("Buffer too small for payload");
|
|
502
505
|
return NoiseError::MESSAGE_TOO_LARGE;
|
|
503
506
|
}
|
|
504
|
-
offset += symmetric_.encrypt_and_hash(
|
|
505
|
-
LOG_NOISE_DEBUG("Encrypted payload: " <<
|
|
507
|
+
offset += symmetric_.encrypt_and_hash(pl, pll, message_out + offset);
|
|
508
|
+
LOG_NOISE_DEBUG("Encrypted payload: " << pll << " bytes");
|
|
506
509
|
}
|
|
507
510
|
|
|
508
511
|
*message_out_len = offset;
|
|
@@ -528,7 +531,11 @@ NoiseError NoiseHandshakeState::read_message(
|
|
|
528
531
|
}
|
|
529
532
|
|
|
530
533
|
LOG_NOISE_DEBUG("Reading handshake message " << message_index_ << " (" << (is_initiator_ ? "initiator" : "responder") << "): " << message_len << " bytes");
|
|
531
|
-
|
|
534
|
+
|
|
535
|
+
/* On input, *payload_out_len carries the capacity of payload_out; capture it
|
|
536
|
+
* before we overwrite it with the decrypted length below. */
|
|
537
|
+
const size_t payload_cap = (payload_out_len != nullptr) ? *payload_out_len : 0;
|
|
538
|
+
|
|
532
539
|
size_t offset = 0;
|
|
533
540
|
size_t consumed;
|
|
534
541
|
|
|
@@ -590,18 +597,19 @@ NoiseError NoiseHandshakeState::read_message(
|
|
|
590
597
|
}
|
|
591
598
|
}
|
|
592
599
|
|
|
593
|
-
/* Decrypt payload
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
600
|
+
/* Decrypt-and-hash the trailing payload. This runs on every message, even when
|
|
601
|
+
* empty: DecryptAndHash mixes the (possibly empty) ciphertext into the handshake
|
|
602
|
+
* hash, and once keyed it verifies the trailing auth tag. A successful decrypt
|
|
603
|
+
* may legitimately yield 0 plaintext bytes, so only the sentinel means failure. */
|
|
604
|
+
{
|
|
605
|
+
const size_t remaining = message_len - offset;
|
|
606
|
+
const size_t pt_len = symmetric_.decrypt_and_hash(message + offset, remaining, payload_out, payload_cap);
|
|
607
|
+
if (pt_len == NOISE_DECRYPT_FAILED) {
|
|
598
608
|
LOG_NOISE_ERROR("Failed to decrypt payload in handshake message");
|
|
599
609
|
return NoiseError::DECRYPT_FAILED;
|
|
600
610
|
}
|
|
601
611
|
*payload_out_len = pt_len;
|
|
602
612
|
LOG_NOISE_DEBUG("Decrypted payload: " << pt_len << " bytes");
|
|
603
|
-
} else {
|
|
604
|
-
*payload_out_len = 0;
|
|
605
613
|
}
|
|
606
614
|
|
|
607
615
|
message_index_++;
|
|
@@ -654,10 +662,11 @@ NoiseSession::~NoiseSession() {
|
|
|
654
662
|
clear();
|
|
655
663
|
}
|
|
656
664
|
|
|
657
|
-
NoiseError NoiseSession::start(bool is_initiator, const NoiseKeyPair* static_keypair
|
|
665
|
+
NoiseError NoiseSession::start(bool is_initiator, const NoiseKeyPair* static_keypair,
|
|
666
|
+
const uint8_t* prologue, size_t prologue_len) {
|
|
658
667
|
LOG_NOISE_INFO("Session starting as " << (is_initiator ? "initiator" : "responder"));
|
|
659
668
|
transport_ready_ = false;
|
|
660
|
-
NoiseError err = handshake_.initialize(is_initiator, static_keypair);
|
|
669
|
+
NoiseError err = handshake_.initialize(is_initiator, static_keypair, prologue, prologue_len);
|
|
661
670
|
if (err != NoiseError::OK) {
|
|
662
671
|
LOG_NOISE_ERROR("Session start failed: " << static_cast<int>(err));
|
|
663
672
|
}
|
|
@@ -745,8 +754,10 @@ size_t NoiseSession::decrypt(const uint8_t* ciphertext, size_t ct_len, uint8_t*
|
|
|
745
754
|
}
|
|
746
755
|
|
|
747
756
|
size_t result = recv_cipher_.decrypt_with_ad(nullptr, 0, ciphertext, ct_len, plaintext);
|
|
748
|
-
if (result
|
|
757
|
+
if (result != NOISE_DECRYPT_FAILED) {
|
|
749
758
|
LOG_NOISE_DEBUG("Session decrypted " << ct_len << " bytes -> " << result << " bytes");
|
|
759
|
+
} else {
|
|
760
|
+
LOG_NOISE_ERROR("Session decrypt failed for " << ct_len << " bytes");
|
|
750
761
|
}
|
|
751
762
|
return result;
|
|
752
763
|
}
|
|
@@ -778,7 +789,7 @@ void noise_generate_keypair(NoiseKeyPair& keypair) {
|
|
|
778
789
|
keypair.private_key[31] |= 64;
|
|
779
790
|
|
|
780
791
|
/* Derive public key */
|
|
781
|
-
|
|
792
|
+
rats_curve25519_donna(keypair.public_key, keypair.private_key, rats_curve25519_basepoint);
|
|
782
793
|
keypair.has_keys = true;
|
|
783
794
|
|
|
784
795
|
LOG_NOISE_DEBUG("Generated static keypair (pub: " << format_key_prefix(keypair.public_key) << "...)");
|
|
@@ -793,11 +804,11 @@ void noise_derive_public_key(const uint8_t private_key[NOISE_DH_SIZE],
|
|
|
793
804
|
clamped[31] &= 127;
|
|
794
805
|
clamped[31] |= 64;
|
|
795
806
|
|
|
796
|
-
|
|
807
|
+
rats_curve25519_donna(public_key, clamped, rats_curve25519_basepoint);
|
|
797
808
|
|
|
798
809
|
secure_zero(clamped, NOISE_DH_SIZE);
|
|
799
810
|
|
|
800
811
|
LOG_NOISE_DEBUG("Derived public key from private key (pub: " << format_key_prefix(public_key) << "...)");
|
|
801
812
|
}
|
|
802
813
|
|
|
803
|
-
} /* namespace
|
|
814
|
+
} /* namespace librats */
|