v0.0.0-...-8b1022e Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Jun 17, 2016 License: Apache-2.0, BSD-2-Clause, BSD-3-Clause Imports: 8 Imported by: 0



Package framing implements the obfs4 link framing and cryptography.

The Encoder/Decoder shared secret format is:

uint8_t[32] NaCl secretbox key
uint8_t[16] NaCl Nonce prefix
uint8_t[16] SipHash-2-4 key (used to obfsucate length)
uint8_t[8]  SipHash-2-4 IV

The frame format is:

uint16_t length (obfsucated, big endian)
NaCl secretbox (Poly1305/XSalsa20) containing:
  uint8_t[16] tag (Part of the secretbox construct)
  uint8_t[]   payload

The length field is length of the NaCl secretbox XORed with the truncated SipHash-2-4 digest ran in OFB mode.

Initialize K, IV[0] with values from the shared secret.
On each packet, IV[n] = H(K, IV[n - 1])
mask[n] = IV[n][0:2]
obfsLen = length ^ mask[n]

The NaCl secretbox (Poly1305/XSalsa20) nonce format is:

uint8_t[24] prefix (Fixed)
uint64_t    counter (Big endian)

The counter is initialized to 1, and is incremented on each frame. Since the protocol is designed to be used over a reliable medium, the nonce is not transmitted over the wire as both sides of the conversation know the prefix and the initial counter value. It is imperative that the counter does not wrap, and sessions MUST terminate before 2^64 frames are sent.



View Source
const (
	// MaximumSegmentLength is the length of the largest possible segment
	// including overhead.
	MaximumSegmentLength = 1500 - (40 + 12)

	// FrameOverhead is the length of the framing overhead.
	FrameOverhead = lengthLength + secretbox.Overhead

	// MaximumFramePayloadLength is the length of the maximum allowed payload
	// per frame.
	MaximumFramePayloadLength = MaximumSegmentLength - FrameOverhead

	// KeyLength is the length of the Encoder/Decoder secret key.
	KeyLength = keyLength + noncePrefixLength + drbg.SeedLength


View Source
var ErrAgain = errors.New("framing: More data needed to decode")

Error returned when Decoder.Decode() requires more data to continue.

View Source
var ErrNonceCounterWrapped = errors.New("framing: Nonce counter wrapped")

Error returned when the NaCl secretbox nonce's counter wraps (FATAL).

View Source
var ErrTagMismatch = errors.New("framing: Poly1305 tag mismatch")

Error returned when Decoder.Decode() failes to authenticate a frame.


This section is empty.


type Decoder

type Decoder struct {
	// contains filtered or unexported fields

Decoder is a frame decoder instance.

func NewDecoder

func NewDecoder(key []byte) *Decoder

NewDecoder creates a new Decoder instance. It must be supplied a slice containing exactly KeyLength bytes of keying material.

func (*Decoder) Decode

func (decoder *Decoder) Decode(data []byte, frames *bytes.Buffer) (int, error)

Decode decodes a stream of data and returns the length if any. ErrAgain is a temporary failure, all other errors MUST be treated as fatal and the session aborted.

type Encoder

type Encoder struct {
	// contains filtered or unexported fields

Encoder is a frame encoder instance.

func NewEncoder

func NewEncoder(key []byte) *Encoder

NewEncoder creates a new Encoder instance. It must be supplied a slice containing exactly KeyLength bytes of keying material.

func (*Encoder) Encode

func (encoder *Encoder) Encode(frame, payload []byte) (n int, err error)

Encode encodes a single frame worth of payload and returns the encoded length. InvalidPayloadLengthError is recoverable, all other errors MUST be treated as fatal and the session aborted.

type InvalidPayloadLengthError

type InvalidPayloadLengthError int

InvalidPayloadLengthError is the error returned when Encoder.Encode() rejects the payload length.

func (InvalidPayloadLengthError) Error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL