Protocol ======== The protocol is divided into two parts: message formats and the actual protocol. The protocol and message formats are under development, so this represents the current spec. Messages -------- The RadioHead library's `RF95 `_ driver limits messages to 251 bytes. Note that this driver sends unaddressed and unreliable datagrams; there are manager classes to implement reliability and encryption, but they're not quite suitable. The firmware doesn't define these, but a prototype message structure might look like:: struct Message { // Header uint8_t net; uint8_t from[4]; uint8_t to[4]; uint8_t type; uint8_t time[7]; uint8_t signature[64]; // Body uint8_t message[170]; } The RF95 driver does provide CRC checks on packets, so that doesn't need to be built in. Addressing ---------- The `from` and `to` fields are the 32-bit node IDs as stored in each node's identity, sent little-endian. The `from` field should always contain a valid node ID, but a `to` address of 0 indicates a broadcast message. There is a further filter, `net`, that identifies which net (or group) the message is intended for. The net ID 0 indicates either all nets (for broadcast messages) or direct communications between only a pair of nodes. Message security ---------------- A node's identity key is used to sign all messages; the signature is done over all the other header fields and the message body. This is used to establish authenticity; nodes can use their address book to verify that the public key for a given node ID matches the signature. Message traffic (e.g. messages not intended for control) are encrypted using a traffic encryption key (TEK), established with a key exchange sequence. Nets are a little more complex: the node that establishes a net generates a TEK for the net, and sends this TEK to each node that is invited to the net. Other nodes can also send invites to the net by sending another node the net's TEK. TEKs have a limited lifetime: 90 days or 6500 messages (just over a megabyte of data). This limit is arbitrary and subject to change during the refinement and development of the protocol. The address book ---------------- Nodes should maintain an address book (e.g. on the SD card) that contains entries correlating node IDs, public keys, TEK parameters, and optionally a friendly tag. TEK parameters contain keys, messages counts, and rollover time:: struct TEKParameters { uint8_t ready; uint8_t key[32]; uint16_t count; datetime expires; }; The `ready` field should be set to true once the parameters have been filled in. It allows a faster check to determine if a key exchange with a valid TEK has occurred. The `key` field contains the TEK, `count` should store the message count, and `expires` contains the datetime when the key should be rolled. The address book incorporates these parameters with the other node details:: struct Address { uint8_t tag[15]; uint8_t pub[32]; uint32_t id; struct TEKParameters tekp; }; The `tag` field is used to store a user-friendly name for a node, which would be set in the node management software. The `pub` field contains the node's public key, and `id` stores the node's public key. Message types ------------- + ADV: Advertisements are sent to net 0 with the broadcast node ID; this is how nodes share their public keys. The message body is the 32-byte Ed25519 public key for the node. Nodes may elect to send advertisements at regular intervals with a minimum of five minutes between advertisements. + WHO: Who requests are sent to ask all receiving nodes for their public keys (e.g. sent to the broadcast address). Alternatively, they may be addressed to a node to ask a specific node for its public key. Responses are optional; a node may elect not to respond (e.g. for power conservation). + KEXSYN: Key exchange sync is sent directly to another node to set up a traffic encryption key (TEK). The message is a 32-byte public key that the receiving node uses to derive a secret key and a 7-byte expiration on the key exchange. + KEXACK: Key exchange acknowledgement is sent by the node that receives a KEXSYN. It contains the public key to be used in deriving a TEK. Once this is sent, both sides have a TEK for direct messaging. + INVITE: invitation to join a group. Direct key exchange must be set up. + MSG: standard message. + REKEY: roll a TEK. Open questions -------------- + What data structure makes the most sense for the address book, balancing usability with memory and program space requirements? + How should the address book deal with nets? + How should network reliability be handled? The system right now defaults to a UDP-esque model; would making it reliable require too much bandwidth or dwell time?