From 2f08afabb15d54f84e353cbabb3dfc7a4a0e2c26 Mon Sep 17 00:00:00 2001 From: Mike Crute Date: Thu, 4 Aug 2022 18:44:03 -0700 Subject: Add format documentation --- README.md | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 88 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 1cb0aa8..ad8740f 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,89 @@ -Ubiquiti Inform Protocol in Golang -================================== -This repo contains a Golang implementation of the Ubiquiti Networks Inform -protocol used by the Unifi access points and the mFi machine networking -components. The primary focus is an implementation compatible with mFi -components but the library should also be compatible with Unifi devices. - -This repo is a work in progress and is not yet considered stable. If you find -it useful patches are welcome, just open a pull request. - -There is a feature-complete Python version of this API, a set of tools useful -for reverse engineering the protocol and an in-progress protocol spec at +# Ubiquiti Inform Protocol in Golang +This repo contains a Golang implementation of the Ubiquiti Networks +Inform protocol used by the Unifi access points and the mFi machine +networking components. The primary purpose of this repository is to +implement the core inform protocol for interoperability with Ubiquiti +products. It is not recommended to use this protocol as the base for +any new product development, it's rather Ubiquiti specific and not very +secure in the bootstrap phase (uses well-known keys over plaintext +channels). + +This work is largely based on [ubntmfi](https://github.com/mcrute/ubntmfi/blob/master/inform_protocol.md) + +## Status +This repo is a work in progress and semi-maintained, it is not yet +considered stable. If you find it useful patches are welcome, just open +a pull request. + +This repository should work well with older mFi components and modern +Unifi components as well. The author has tested with devices as new as +the U6-Mesh devices. + +## Missing Features +If you need these then feel free to implement them. Pull requests are +accepted. + +- Support for writing AES GCM packets +- Support for writing zlib compressed packets +- Support for writing snappy compressed packets + +## Protocol +The inform protocol works over HTTP or HTTPS in the case of modern +equipment, older equipment did not support HTTPS. The `mcad` daemon +on the devices is responsible for speaking the inform protocol to the +controller. + +A device will `POST` an HTTP request to the controller with a +content-type of `application/x-binary` which contains a payload encoded +in inform format. The server will respond with a payload that is inform +encoded. + +## Packet Format +Packets are binary and transmitted in big-endian format. + +| Size | Type | Purpose | Notes | +| -------- | -------- | ------------------------ | ------------------------------------ | +| 4 bytes | `int32` | Protocol Magic Number | Must always be `1414414933` (`UBNT`) | +| 4 bytes | `int32` | Packet Version | Currently this is `0` | +| 6 bytes | `[]byte` | Device MAC Address | Used for crypto-key lookup | +| 2 bytes | `int16` | Flags | See below | +| 16 bytes | `[]byte` | Encryption IV | | +| 4 bytes | `int32` | Data Version | Currently this is `1` | +| 4 bytes | `int32` | Encrypted Payload Length | | +| n bytes | `[]byte` | Encrypted Payload | See below | + +### Flags +| Flag | Name | Purpose | +| ---- | ----------------- | ----------------------------------------------- | +| `1` | Encrypted | Indicates that the payload is encrypted | +| `2` | Zlib Compressed | Indicates that payload is zlib compressed | +| `4` | Snappy Compressed | Indicates that payload is snappy compressed | +| `8` | GCM Encrypted | Indicates that packet is encrypted with AES GCM | + +### Encryption +There are two encryption modes AES 128 CBC and AES 128 GCM. GCM is used +in newer devices and CBC in older devices. The same key is used for +either mode. It's stored as `x_authkey` in the Unifi database and is +encoded as hex. The key must be decoded before decryption. + +AES GCM requires authentication data to decrypt the packet. The +authentication data is the following fields encoded in big-endian binary +format. + +- Protocol Magic Number +- Packet Version +- Device MAC Address +- Flags +- Encryption IV +- Data Version +- Data Length + +In CBC mode the data is padded to fit a full AES block. In GCM mode the +final block appears to be a padding/garbage block. + +### Payload +The payload is a JSON string that is device and application specific. +The payload may also (but is not required to be) be compressed using +either [snappy](https://github.com/golang/snappy) or zlib compression as +indicated by the flags. -- cgit v1.2.3