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.
Files changed (319) hide show
  1. package/README.md +145 -331
  2. package/binding.gyp +16 -3
  3. package/lib/index.d.ts +288 -696
  4. package/lib/index.js +407 -44
  5. package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
  6. package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
  7. package/native-src/CMakeLists.txt +404 -179
  8. package/native-src/LICENSE +1 -1
  9. package/native-src/src/librats/bindings/rats.cpp +762 -0
  10. package/native-src/src/librats/bindings/rats.h +380 -0
  11. package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
  12. package/native-src/src/librats/bittorrent/bencode.h +176 -0
  13. package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
  14. package/native-src/src/librats/bittorrent/bitfield.h +76 -0
  15. package/native-src/src/librats/bittorrent/byte_io.h +58 -0
  16. package/native-src/src/librats/bittorrent/choker.cpp +25 -0
  17. package/native-src/src/librats/bittorrent/choker.h +46 -0
  18. package/native-src/src/librats/bittorrent/client.cpp +413 -0
  19. package/native-src/src/librats/bittorrent/client.h +227 -0
  20. package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
  21. package/native-src/src/librats/bittorrent/disk_io.h +150 -0
  22. package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
  23. package/native-src/src/librats/bittorrent/extensions.h +94 -0
  24. package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
  25. package/native-src/src/librats/bittorrent/file_storage.h +79 -0
  26. package/native-src/src/librats/bittorrent/log.h +42 -0
  27. package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
  28. package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
  29. package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
  30. package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
  31. package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
  32. package/native-src/src/librats/bittorrent/peer_list.h +75 -0
  33. package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
  34. package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
  35. package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
  36. package/native-src/src/librats/bittorrent/reactor.h +89 -0
  37. package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
  38. package/native-src/src/librats/bittorrent/resume_data.h +41 -0
  39. package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
  40. package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
  41. package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
  42. package/native-src/src/librats/bittorrent/torrent.h +260 -0
  43. package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
  44. package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
  45. package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
  46. package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
  47. package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
  48. package/native-src/src/librats/bittorrent/tracker.h +108 -0
  49. package/native-src/src/librats/bittorrent/types.cpp +206 -0
  50. package/native-src/src/librats/bittorrent/types.h +86 -0
  51. package/native-src/src/librats/core/address.cpp +35 -0
  52. package/native-src/src/librats/core/address.h +78 -0
  53. package/native-src/src/librats/core/bytes.h +69 -0
  54. package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
  55. package/native-src/src/librats/core/chained_send_buffer.h +183 -0
  56. package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
  57. package/native-src/src/librats/core/endpoint_parse.h +31 -0
  58. package/native-src/src/librats/core/event_bus.h +70 -0
  59. package/native-src/src/librats/core/host_endpoint.h +56 -0
  60. package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
  61. package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
  62. package/native-src/src/librats/core/ip_address.cpp +120 -0
  63. package/native-src/src/librats/core/ip_address.h +109 -0
  64. package/native-src/src/librats/core/mpsc_queue.h +47 -0
  65. package/native-src/src/librats/core/notifier.h +74 -0
  66. package/native-src/src/librats/core/receive_buffer.cpp +219 -0
  67. package/native-src/src/librats/core/receive_buffer.h +171 -0
  68. package/native-src/src/librats/core/service_registry.h +58 -0
  69. package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
  70. package/native-src/src/librats/core/socket.h +496 -0
  71. package/native-src/src/librats/core/timer_queue.h +105 -0
  72. package/native-src/src/librats/core/types.cpp +43 -0
  73. package/native-src/src/librats/core/types.h +103 -0
  74. package/native-src/src/librats/core/wakeup_pipe.h +83 -0
  75. package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
  76. package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
  77. package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
  78. package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
  79. package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
  80. package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
  81. package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
  82. package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
  83. package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
  84. package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
  85. package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
  86. package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
  87. package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
  88. package/native-src/src/librats/crypto/hkdf.c +266 -0
  89. package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
  90. package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
  91. package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
  92. package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
  93. package/native-src/src/librats/crypto/poly1305.h +37 -0
  94. package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
  95. package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
  96. package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
  97. package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
  98. package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
  99. package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
  100. package/native-src/src/librats/dht/announce.cpp +37 -0
  101. package/native-src/src/librats/dht/announce.h +41 -0
  102. package/native-src/src/librats/dht/bep42.cpp +109 -0
  103. package/native-src/src/librats/dht/bep42.h +48 -0
  104. package/native-src/src/librats/dht/dht.cpp +501 -0
  105. package/native-src/src/librats/dht/dht.h +119 -0
  106. package/native-src/src/librats/dht/dht_runner.cpp +103 -0
  107. package/native-src/src/librats/dht/dht_runner.h +71 -0
  108. package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
  109. package/native-src/src/librats/dht/dos_blocker.h +47 -0
  110. package/native-src/src/librats/dht/find_peers.cpp +52 -0
  111. package/native-src/src/librats/dht/find_peers.h +73 -0
  112. package/native-src/src/librats/dht/id.h +167 -0
  113. package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
  114. package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
  115. package/native-src/src/librats/dht/log.h +38 -0
  116. package/native-src/src/librats/dht/node.cpp +473 -0
  117. package/native-src/src/librats/dht/node.h +164 -0
  118. package/native-src/src/librats/dht/node_entry.h +81 -0
  119. package/native-src/src/librats/dht/observer.h +72 -0
  120. package/native-src/src/librats/dht/persistence.cpp +90 -0
  121. package/native-src/src/librats/dht/persistence.h +32 -0
  122. package/native-src/src/librats/dht/routing_table.cpp +559 -0
  123. package/native-src/src/librats/dht/routing_table.h +185 -0
  124. package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
  125. package/native-src/src/librats/dht/rpc_manager.h +77 -0
  126. package/native-src/src/librats/dht/storage.cpp +92 -0
  127. package/native-src/src/librats/dht/storage.h +74 -0
  128. package/native-src/src/librats/dht/transport.h +27 -0
  129. package/native-src/src/librats/dht/traversal.cpp +326 -0
  130. package/native-src/src/librats/dht/traversal.h +120 -0
  131. package/native-src/src/librats/dht/udp_transport.cpp +49 -0
  132. package/native-src/src/librats/dht/udp_transport.h +51 -0
  133. package/native-src/src/librats/mdns/log.h +22 -0
  134. package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
  135. package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
  136. package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
  137. package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
  138. package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
  139. package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
  140. package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
  141. package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
  142. package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
  143. package/native-src/src/librats/node/circuit_service.h +84 -0
  144. package/native-src/src/librats/node/config.h +110 -0
  145. package/native-src/src/librats/node/dial_service.h +54 -0
  146. package/native-src/src/librats/node/dialer.cpp +264 -0
  147. package/native-src/src/librats/node/dialer.h +188 -0
  148. package/native-src/src/librats/node/host_events.h +26 -0
  149. package/native-src/src/librats/node/identify.cpp +130 -0
  150. package/native-src/src/librats/node/identify.h +71 -0
  151. package/native-src/src/librats/node/nat_status.cpp +103 -0
  152. package/native-src/src/librats/node/nat_status.h +118 -0
  153. package/native-src/src/librats/node/node.cpp +865 -0
  154. package/native-src/src/librats/node/node.h +344 -0
  155. package/native-src/src/librats/node/node_context.h +33 -0
  156. package/native-src/src/librats/node/peer_network.h +91 -0
  157. package/native-src/src/librats/peer/peer.h +49 -0
  158. package/native-src/src/librats/peer/peer_book.cpp +181 -0
  159. package/native-src/src/librats/peer/peer_book.h +88 -0
  160. package/native-src/src/librats/peer/peer_id.cpp +72 -0
  161. package/native-src/src/librats/peer/peer_id.h +62 -0
  162. package/native-src/src/librats/peer/peer_info.h +37 -0
  163. package/native-src/src/librats/peer/peer_table.cpp +170 -0
  164. package/native-src/src/librats/peer/peer_table.h +148 -0
  165. package/native-src/src/librats/security/handshaker.h +66 -0
  166. package/native-src/src/librats/security/identity.h +43 -0
  167. package/native-src/src/librats/security/noise_security.cpp +122 -0
  168. package/native-src/src/librats/security/noise_security.h +37 -0
  169. package/native-src/src/librats/security/plaintext_security.h +106 -0
  170. package/native-src/src/librats/security/session.h +37 -0
  171. package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
  172. package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
  173. package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
  174. package/native-src/src/librats/subsystems/bittorrent.h +136 -0
  175. package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
  176. package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
  177. package/native-src/src/librats/subsystems/dht_service.h +36 -0
  178. package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
  179. package/native-src/src/librats/subsystems/file_transfer.h +367 -0
  180. package/native-src/src/librats/subsystems/hole_punch.cpp +605 -0
  181. package/native-src/src/librats/subsystems/hole_punch.h +290 -0
  182. package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
  183. package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
  184. package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
  185. package/native-src/src/librats/subsystems/message_json.cpp +112 -0
  186. package/native-src/src/librats/subsystems/message_json.h +88 -0
  187. package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
  188. package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
  189. package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
  190. package/native-src/src/librats/subsystems/ping_service.h +66 -0
  191. package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
  192. package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
  193. package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
  194. package/native-src/src/librats/subsystems/pubsub.h +175 -0
  195. package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
  196. package/native-src/src/librats/subsystems/reconnection.h +126 -0
  197. package/native-src/src/librats/subsystems/relay.cpp +1142 -0
  198. package/native-src/src/librats/subsystems/relay.h +211 -0
  199. package/native-src/src/librats/subsystems/relay_service.h +46 -0
  200. package/native-src/src/librats/transport/connection.cpp +343 -0
  201. package/native-src/src/librats/transport/connection.h +283 -0
  202. package/native-src/src/librats/transport/link.h +96 -0
  203. package/native-src/src/librats/transport/reactor.cpp +588 -0
  204. package/native-src/src/librats/transport/reactor.h +262 -0
  205. package/native-src/src/librats/transport/reactor_pool.h +81 -0
  206. package/native-src/src/librats/transport/relay_link.cpp +208 -0
  207. package/native-src/src/librats/transport/relay_link.h +303 -0
  208. package/native-src/src/librats/transport/tcp_link.cpp +49 -0
  209. package/native-src/src/librats/transport/tcp_link.h +43 -0
  210. package/native-src/src/librats/transport/udp_mux.cpp +617 -0
  211. package/native-src/src/librats/transport/udp_mux.h +363 -0
  212. package/native-src/src/librats/transport/udp_packet.cpp +121 -0
  213. package/native-src/src/librats/transport/udp_packet.h +190 -0
  214. package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
  215. package/native-src/src/librats/transport/udp_stream.h +614 -0
  216. package/native-src/src/librats/util/features.h.in +51 -0
  217. package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
  218. package/native-src/src/librats/util/fs.h +136 -0
  219. package/native-src/src/librats/util/json.cpp +1002 -0
  220. package/native-src/src/librats/util/json.h +444 -0
  221. package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
  222. package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
  223. package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
  224. package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
  225. package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
  226. package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
  227. package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
  228. package/native-src/src/librats/util/rats_export.h +69 -0
  229. package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
  230. package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
  231. package/native-src/src/librats/wire/frame.cpp +76 -0
  232. package/native-src/src/librats/wire/frame.h +111 -0
  233. package/native-src/src/librats/wire/message_router.cpp +45 -0
  234. package/native-src/src/librats/wire/message_router.h +47 -0
  235. package/package.json +5 -4
  236. package/scripts/build-librats.js +1 -0
  237. package/scripts/postinstall.js +3 -3
  238. package/scripts/prepare-package.js +4 -4
  239. package/scripts/verify-installation.js +63 -105
  240. package/src/librats_node.cpp +1067 -1323
  241. package/native-src/src/bencode.cpp +0 -485
  242. package/native-src/src/bencode.h +0 -145
  243. package/native-src/src/bittorrent.cpp +0 -14
  244. package/native-src/src/bittorrent.h +0 -74
  245. package/native-src/src/bt_bitfield.cpp +0 -372
  246. package/native-src/src/bt_bitfield.h +0 -316
  247. package/native-src/src/bt_choker.cpp +0 -228
  248. package/native-src/src/bt_choker.h +0 -147
  249. package/native-src/src/bt_client.cpp +0 -1047
  250. package/native-src/src/bt_client.h +0 -445
  251. package/native-src/src/bt_create_torrent.cpp +0 -677
  252. package/native-src/src/bt_create_torrent.h +0 -473
  253. package/native-src/src/bt_extension.cpp +0 -469
  254. package/native-src/src/bt_extension.h +0 -309
  255. package/native-src/src/bt_file_storage.cpp +0 -261
  256. package/native-src/src/bt_file_storage.h +0 -298
  257. package/native-src/src/bt_handshake.cpp +0 -134
  258. package/native-src/src/bt_handshake.h +0 -157
  259. package/native-src/src/bt_messages.cpp +0 -364
  260. package/native-src/src/bt_messages.h +0 -324
  261. package/native-src/src/bt_network.cpp +0 -1007
  262. package/native-src/src/bt_network.h +0 -417
  263. package/native-src/src/bt_peer_connection.cpp +0 -742
  264. package/native-src/src/bt_peer_connection.h +0 -592
  265. package/native-src/src/bt_piece_picker.cpp +0 -786
  266. package/native-src/src/bt_piece_picker.h +0 -473
  267. package/native-src/src/bt_resume_data.cpp +0 -410
  268. package/native-src/src/bt_resume_data.h +0 -249
  269. package/native-src/src/bt_torrent.cpp +0 -2120
  270. package/native-src/src/bt_torrent.h +0 -641
  271. package/native-src/src/bt_torrent_info.cpp +0 -659
  272. package/native-src/src/bt_torrent_info.h +0 -418
  273. package/native-src/src/bt_types.h +0 -621
  274. package/native-src/src/chained_send_buffer.cpp +0 -75
  275. package/native-src/src/chained_send_buffer.h +0 -137
  276. package/native-src/src/crypto/hkdf.c +0 -266
  277. package/native-src/src/crypto/poly1305.h +0 -36
  278. package/native-src/src/dht.cpp +0 -3311
  279. package/native-src/src/dht.h +0 -717
  280. package/native-src/src/disk_io.cpp +0 -632
  281. package/native-src/src/disk_io.h +0 -315
  282. package/native-src/src/file_transfer.cpp +0 -1415
  283. package/native-src/src/file_transfer.h +0 -286
  284. package/native-src/src/fs.h +0 -108
  285. package/native-src/src/gossipsub.cpp +0 -1139
  286. package/native-src/src/gossipsub.h +0 -403
  287. package/native-src/src/ice.cpp +0 -893
  288. package/native-src/src/ice.h +0 -559
  289. package/native-src/src/json.hpp +0 -25526
  290. package/native-src/src/librats.cpp +0 -2378
  291. package/native-src/src/librats.h +0 -2324
  292. package/native-src/src/librats_bittorrent.cpp +0 -601
  293. package/native-src/src/librats_c.cpp +0 -1557
  294. package/native-src/src/librats_c.h +0 -323
  295. package/native-src/src/librats_discovery.cpp +0 -402
  296. package/native-src/src/librats_encryption.cpp +0 -275
  297. package/native-src/src/librats_file_transfer.cpp +0 -144
  298. package/native-src/src/librats_gossipsub.cpp +0 -289
  299. package/native-src/src/librats_ice.cpp +0 -213
  300. package/native-src/src/librats_log_macros.h +0 -36
  301. package/native-src/src/librats_logging.cpp +0 -173
  302. package/native-src/src/librats_mdns.cpp +0 -166
  303. package/native-src/src/librats_persistence.cpp +0 -796
  304. package/native-src/src/librats_portmap.cpp +0 -419
  305. package/native-src/src/librats_reconnection.cpp +0 -218
  306. package/native-src/src/librats_statistic.cpp +0 -105
  307. package/native-src/src/librats_storage.cpp +0 -189
  308. package/native-src/src/rats_export.h +0 -17
  309. package/native-src/src/receive_buffer.cpp +0 -82
  310. package/native-src/src/receive_buffer.h +0 -127
  311. package/native-src/src/socket.h +0 -228
  312. package/native-src/src/threadmanager.cpp +0 -105
  313. package/native-src/src/threadmanager.h +0 -53
  314. package/native-src/src/tracker.cpp +0 -1264
  315. package/native-src/src/tracker.h +0 -319
  316. package/native-src/src/turn.cpp +0 -762
  317. package/native-src/src/turn.h +0 -460
  318. package/native-src/src/wakeup_pipe.h +0 -60
  319. /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 HKDF_SHA256_HASH_LEN 32
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 hmac_sha256(
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[HKDF_SHA256_HASH_LEN]
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 hmac_sha256_2(
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[HKDF_SHA256_HASH_LEN]
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 hkdf_sha256_extract(
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[HKDF_SHA256_HASH_LEN]
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 hkdf_sha256_expand(
76
- const uint8_t prk[HKDF_SHA256_HASH_LEN],
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 hkdf_sha256(
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 noise_hkdf_2(
112
- const uint8_t chaining_key[HKDF_SHA256_HASH_LEN],
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[HKDF_SHA256_HASH_LEN],
115
- uint8_t output2[HKDF_SHA256_HASH_LEN]
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 noise_hkdf_3(
130
- const uint8_t chaining_key[HKDF_SHA256_HASH_LEN],
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[HKDF_SHA256_HASH_LEN],
133
- uint8_t output2[HKDF_SHA256_HASH_LEN],
134
- uint8_t output3[HKDF_SHA256_HASH_LEN]
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 rats {
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 = chachapoly_encrypt(
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 0;
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 = chachapoly_decrypt(
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
- if (result > 0) {
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
- } else {
147
- LOG_NOISE_ERROR("Decryption failed for " << ct_len << " bytes - authentication failed");
148
+ return result;
148
149
  }
149
-
150
- return result;
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
- sha256_hash(h_, protocol_name, name_len);
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
- noise_hkdf_2(ck_, input_key_material, len, ck_, temp_k);
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
- sha256_context_t ctx;
226
- sha256_reset(&ctx);
227
- sha256_update(&ctx, h_, NOISE_HASH_SIZE);
228
- sha256_update(&ctx, data, len);
229
- sha256_finish(&ctx, h_);
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
- noise_hkdf_2(ck_, nullptr, 0, temp_k1, temp_k2);
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
- curve25519_donna(e_.public_key, e_.private_key, curve25519_basepoint);
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
- curve25519_donna(dh_output, local_private, remote_public);
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 if provided */
396
- if (prologue != nullptr && prologue_len > 0) {
397
- symmetric_.mix_hash(prologue, prologue_len);
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
- /* Add payload if provided */
499
- if (payload != nullptr && payload_len > 0) {
500
- if (offset + payload_len + (symmetric_.cipher_.has_key() ? NOISE_TAG_SIZE : 0) > max_len) {
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(payload, payload_len, message_out + offset);
505
- LOG_NOISE_DEBUG("Encrypted payload: " << payload_len << " bytes");
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 if there's remaining data */
594
- if (offset < message_len) {
595
- size_t remaining = message_len - offset;
596
- size_t pt_len = symmetric_.decrypt_and_hash(message + offset, remaining, payload_out);
597
- if (pt_len == 0 && remaining > 0) {
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 > 0) {
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
- curve25519_donna(keypair.public_key, keypair.private_key, curve25519_basepoint);
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
- curve25519_donna(public_key, clamped, curve25519_basepoint);
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 rats */
814
+ } /* namespace librats */