lightning-dev

Combined summary - [PATCH v3] daemon: encrypted communication (version 3)

Combined summary - [PATCH v3] daemon: encrypted communication (version 3)

Rusty Russell, the developer of the Lightning network protocol, discusses the process of introducing a field that can eventually become compulsory.

He suggests adding the field as two optional fields labeled 11 and 12 to ease the transition. However, in a follow-up message, he corrects himself and states that the intention is to eventually make the field compulsory.The Lightning network protocol uses even and odd numbered protobuf fields to break backwards compatibility in the future. Even numbered fields are required and should be understood by all implementations, while odd numbered fields are optional and can be ignored by existing implementations. This concept is similar to OpenPGP's "critical bit" for packets, which indicates that if the software doesn't understand the packet, it should consider the signature invalid. Rusty explains that this numbering system can be used to deliberately break backwards compatibility in future versions of the protocol.Mats Jerratsch suggests that the 'totlen' field may not be necessary for replay protection, as AES-CTR already provides this. The 'totlen' field was intended to track the total data transmitted and compare it with the value sent from the other party to prevent replayed messages from being decrypted. However, as AES-CTR has a dedicated counter in the IV that keeps track of all messages in each direction, replayed messages cannot be decrypted due to an incorrect IV. While 'totlen' is not required for replay protection, it is still needed for determining how much padding to ignore and for ensuring robustness when nodes crash.In a discussion about encryption details, Rusty and Pierre consider using ECDH to derive a shared secret and generate transmission encoding parameters for each side. These parameters include Session AES-128 key, Session HMAC key, and IV for AES. They also mention that only the first 16 bytes are used for aes_key and aes_iv. When encrypting packets, all data transmitted is covered by an SHA256 HMAC, with totlen referring to the size of the unencrypted serialized protobuf message. Rusty notes that he chose to encode the length on 64 bits to avoid wrapping.Rusty explains how unknown protobuf fields are handled in the protocol. Odd numbered fields are optional and backwards compatible, while even numbered fields are required and cause an abort if received. This numbering system can be used to deliberately break backwards compatibility in the future after some transition. Rusty suggests documenting this information in the lightning-core docs repository.The code related to encrypted packets protected by an HMAC is discussed. The 'totlen' field is meant to track the total data transmitted but actually tracks the size of the unencrypted message. The field includes its own length, which seems unnecessary since it doesn't define the encrypted message boundaries. However, it is necessary for determining how much padding to ignore. Additionally, the author questions why the length is encoded on 64 bits instead of 32 bits.In a conversation between Rusty and Pierre, they discuss handling unknown protobuf fields in the protocol. Odd numbered fields are optional and backwards compatible, while even numbered fields are required and will result in an abort if received. Pierre seeks clarification on this matter.The Lightning Network daemon is implemented using C code, which includes three primary functions: decrypt_pkt(), encrypt_pkt(), and do_read_packet(). These functions handle cryptographic packets and are called by other helper functions. The decrypt_pkt() function checks the HMAC of a packet, decrypts it, and returns it in ProtobufC format. The encrypt_pkt() function encrypts a packet, pads it with zeroes if necessary, and returns it in struct crypto_pkt format. The do_read_packet() function reads packets from a file descriptor and updates the input buffer of the peer using information from its io_data structure.The updated code contains changes to multiple files, including the addition of a new struct called io_data in peer.h and the modification of the "pkt__field_descriptors" variable to add a new field for authentication named "auth". The peer_crypto_setup() function generates a session key used for encryption and returns an IO plan for reading a session key from the peer. Once the session keys are exchanged, the keys_exchanged() function sets up the necessary encryption keys and signs the peer's session key to prove its identity. The authenticate_pkt() function creates an authentication packet from the node id and signature passed as arguments.The code includes several other functions to perform various tasks such as generating a session key, wrapping/unwrapping packets, and freeing memory. In peer.c, a new function called peer_test has been added for testing purposes. The destroy_peer() function has been modified to remove the peer from the state's peers list. The peer_connected_out() and peer_connected_in() functions have been modified to call the peer_crypto_setup() function instead of io_write(), passing in the peer_test() function as the callback argument. The peer_read_packet()

Discussion History

0
Rusty RussellOriginal Post
October 23, 2015 01:33 UTC
1
October 27, 2015 10:34 UTC
2
October 27, 2015 17:00 UTC
3
October 27, 2015 18:01 UTC
4
October 27, 2015 19:41 UTC
5
October 27, 2015 19:44 UTC
6
October 27, 2015 19:48 UTC
7
October 27, 2015 20:40 UTC
8
October 28, 2015 00:32 UTC
9
October 28, 2015 02:17 UTC