csrmesh
1 Introduction
2 Protocol Documentation
2.1 Network Key
2.2 Authenticated Packets
3 API
3.1 Types
Pin
Net  Key
Encrypted-Payload
Payload
Packet
Seq  No
3.2 CSRMesh Packets
string->Pin
network-key
build-packet-with-key
build-packet-with-pin
3.3 Example Sketch
8.12

csrmesh🔗ℹ

Raymond Racine <ray.racine@gmail.com>

1 Introduction🔗ℹ

2 Protocol Documentation🔗ℹ

The following is a quoted description of the protocol as described by Nash Kaminski. See https://kaminski.io Full credit to Mr. Kaminski for his work in explaining the details of creating a CSRMesh packet.

2.1 Network Key🔗ℹ

"The 128 bit network key used in CSRMesh networks is derived by concatenating the ASCII representation of the PIN with a null byte and the string ’MCP’, computing the SHA256 hash of the string, reversing the order of the bytes in the resulting hash, and taking the first 16 bytes as the key."

2.2 Authenticated Packets🔗ℹ

"Packets sent to CSRMesh devices require authentication as well as encryption. All multibyte types are represented in little endian format. To form a valid packet, the sequence/nonce value, constant 0x0080, and 10 null bytes are concatenated together to form a 128 bit initialization vector (IV). This IV, as well as the network key derived earlier is then used to initialize AES-128 in OFB mode. The arbitrary length data payload is then encrypted using this AES-OFB instance to form the encrypted payload. Next, a message authentication code is computed using HMAC-SHA256, using the network key as the secret, of the following data: 8 null bytes, sequence number, constant 0x80 and encrypted payload. The order of the bytes in the resulting hash are then reversed and the hash truncated to 8 bytes. The final output packet can then be built by contatenating the sequence/nonce value, constant 0x80, encrypted payload, truncated HMAC, and the constant 0xff."

3 API🔗ℹ

 (require csrmesh) package: csrmesh

3.1 Types🔗ℹ

value

Pin : bytes? = (pin bytes?)

A (define-new-subtype Pin (pin Bytes)) that represents a 4-digit ascii pin.

value

NetKey : bytes? = (netkey bytes?)

A (define-new-subtype NetKey (netkey Bytes)) that represents a CSRMesh Netkey.

value

Encrypted-Payload : bytes? = (encrypted-payload bytes?)

A (define-new-subtype Encrypted-Payload (encrypted-payload Bytes)) that represents an encrypted CSRMesh payload.

value

Payload : bytes? = (payload bytes?)

A (define-new-subtype Payload (payload Bytes)) that represents a payload of bytes TO BE rendered into the payload of a CSRMech packet.

value

Packet : bytes? = (packet bytes?)

A (define-new-subtype Packet (packet Bytes)) that represents a ready to send CSRMesh packet of some payload/message.

value

SeqNo : Word32 = (seqno Word32)

A (define-new-subtype Seqno (seqno Word32)) that represents a packet sequence number used in the creation of a CSRMesh packet.

The sequence number of a packet is not only essential to the packet encryption but is also used by the mesh network in packet transmission. The mesh "remembers" recently transmitted packet sequence numbers and will drop packets with the same sequence number. An application using this library should ensure non-duplication of packet sequence numbers by either a global incrementing counter, a random generation of the next sequence number or similar scheme.

3.2 CSRMesh Packets🔗ℹ

procedure

(string->Pin pin)  Pin

  pin : String
Constructs a Pin from an ascii string. Typically this is a 4 digit ascii value, e.g. "1234".

procedure

(network-key pin)  NetworkKey

  pin : Pin
Cryptographically calculates the CSRMesh NetworkKey from a given Pin. This is deterministic as the same Pin always creates the same NetworkKey.

procedure

(build-packet-with-key key sno payload)  Packet

  key : NetKey
  sno : SeqNo
  payload : Payload
Creates a ready to transmit CSRMesh Packet for the give payload, network key and sequence number.

procedure

(build-packet-with-pin pin sno payload)  Packet

  pin : Pin
  sno : SeqNo
  payload : Payload
Creates a ready to transmit CSRMesh Packet for the give payload, pin and sequence number.

Re-calculates the NetworkKey from the givein Pin and then calls build-packet-with-key.

As a NetworkKey is uniquely cryptographically generated from a Pin, an application may generate the Network Key once for a Pin via network-key and then using build-packet-with-key directly.

3.3 Example Sketch🔗ℹ

(define pin : Pin (string->Pin "1234"))
(define net-key : NetworkKey (network-key pin))
(define my-payload : Payload  (payload (bytes 1 2 3)))
(define next-seq-no : SeqNo (seqno (random 1000000)))
(define csr-pkt : Packet (build-packet-with-key net-key next-seq-no my-payload))