nyquist

package module
v0.0.10 Latest Latest
Warning

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

Go to latest
Published: Apr 24, 2024 License: BSD-3-Clause Imports: 17 Imported by: 2

README

nyquist - A Noise Protocol Framework implementation

Yawning Angel (yawning at schwanenlied dot me)

This package implements the Noise Protocol Framework.

Why?

Yeah, well, I'm gonna go build my own theme park with blackjack and hookers. In fact, forget the park.

Notes

It is assumed that developers using this package are familiar with the Noise Protocol Framework specification.

As of revision 34 of the specification, the only standard functionality that is NOT implemented is "10.2. The fallback modifier".

This package used to make a partial attempt to sanitize key material, but the author is now convinced that it is fundementally a lost cause due to several reasons including but not limited to copies on stack growth, the lack of a memset_s equivalent, and lack of support by most cryptographic primitives. And no, memguard is not a good solution either.

This package will panic only if invariants are violated. Under normal use this situation should not occur ("normal" being defined as, "Yes, it will panic if an invalid configuration is provided when initializing a handshake").

Several non-standard protocol extensions are supported by this implementation:

  • The maximum message size can be set to an arbitrary value or entirely disabled, on a per-session basis. The implementation will default to the value in the specification.

  • AEAD algorithms with authentication tags that are not 128 bits (16 bytes) in size should be supported. While the package will not reject algorithms with tags sizes that are less than 128 bits, this is NOT RECOMMENED.

  • Non-standard DH, Cipher and Hash functions are trivial to support by implementing the appropriate interface, as long as the following constraints are met:

    • For any given DH scheme, all public keys must be DHLEN bytes in size.

    • For any given Hash function, HASHLEN must be at least 256 bits (32 bytes) in size. The specification requires exactly 256 or 512 bits, however this package will tollerate any length, greater than or equal to 256 bits.

    • AEAD implementations must be able to tollerate always being passed a key that is 256 bits (32 bytes) in size.

  • Non-standard (or unimplemented) patterns are trivial to support by implementing the appropriate interface. The pattern sub-package includes a pattern validator that can verify a pattern against the specification's pattern validity rules.

  • A Cipher implementation backed by the Deoxys-II-256-128 MRAE primitive is provided.

The test vectors under testdata were shamelessly stolen out of the Snow repository.

Documentation

Overview

Package nyquist implements the Noise Protocol Framework.

Index

Constants

View Source
const (
	// DefaultMaxMessageSize is the default maximum message size.
	DefaultMaxMessageSize = 65535

	// PreSharedKeySize is the size of the pre-shared symmetric key.
	PreSharedKeySize = 32
)
View Source
const (
	// SymmetricKeySize is the size a symmetric key in bytes.
	SymmetricKeySize = 32
)
View Source
const Version = 34

Version is the revision of the Noise specification implemented.

Variables

View Source
var (
	// ErrNonceExhausted is the error returned when the CipherState's
	// nonce space is exhausted.
	ErrNonceExhausted = errors.New("nyquist: nonce exhausted")

	// ErrMessageSize is the error returned when an operation fails due
	// to the message size being exceeded.
	ErrMessageSize = errors.New("nyquist: oversized message")

	// ErrOpen is the error returned on a authenticated decryption failure.
	ErrOpen = errors.New("nyquist: decryption failure")

	// ErrInvalidConfig is the error returned when the configuration is invalid.
	ErrInvalidConfig = errors.New("nyquist: invalid configuration")

	// ErrOutOfOrder is the error returned when ReadMessage/WriteMessage
	// are called out of order, given the handshake's initiator status.
	ErrOutOfOrder = errors.New("nyquist: out of order handshake operation")

	// ErrDone is the error returned when the handshake is complete.
	ErrDone = errors.New("nyquist: handshake complete")

	// ErrProtocolNotSupported is the error returned when a requested protocol
	// is not supported.
	ErrProtocolNotSupported = errors.New("nyquist: protocol not supported")
)

Functions

This section is empty.

Types

type CipherState

type CipherState struct {
	// contains filtered or unexported fields
}

CipherState is a keyed AEAD algorithm instance.

func (*CipherState) DecryptWithAd

func (cs *CipherState) DecryptWithAd(dst, ad, ciphertext []byte) ([]byte, error)

DecryptWihtAd authenticates and decrypts the additional data and ciphertext and increments the nonce iff the CipherState is keyed, and otherwise returns the plaintext. If an authentication failure occurs, the nonce is not incremented.

Note: The plaintext is appended to `dst`, and the new slice is returned.

func (*CipherState) EncryptWithAd

func (cs *CipherState) EncryptWithAd(dst, ad, plaintext []byte) ([]byte, error)

EncryptWithAd encrypts and authenticates the additional data and plaintext and increments the nonce iff the CipherState is keyed, and otherwise returns the plaintext.

Note: The ciphertext is appended to `dst`, and the new slice is returned.

func (*CipherState) HasKey

func (cs *CipherState) HasKey() bool

HasKey returns true iff the CipherState is keyed.

func (*CipherState) InitializeKey

func (cs *CipherState) InitializeKey(key []byte)

InitializeKey initializes sets the cipher key to `key`, and nonce to 0.

func (*CipherState) Rekey

func (cs *CipherState) Rekey() error

Rekey sets the CipherState's key to `REKEY(k)`.

func (*CipherState) Reset

func (cs *CipherState) Reset()

Reset sets the CipherState to a un-keyed state.

func (*CipherState) SetNonce

func (cs *CipherState) SetNonce(nonce uint64)

SetNonce sets the CipherState's nonce to `nonce`.

type DHConfig added in v0.0.2

type DHConfig struct {
	// LocalStatic is the local static keypair, if any (`s`).
	LocalStatic dh.Keypair

	// LocalEphemeral is the local ephemeral keypair, if any (`e`).
	LocalEphemeral dh.Keypair

	// RemoteStatic is the remote static public key, if any (`rs`).
	RemoteStatic dh.PublicKey

	// RemoteEphemeral is the remote ephemeral public key, if any (`re`).
	RemoteEphemeral dh.PublicKey

	// Observer is the optional handshake observer.
	Observer HandshakeObserverDH
}

DHConfig is the Diffie-Hellman (DH) key configuration of a handshake.

type DHStatus added in v0.0.2

type DHStatus struct {
	// LocalEphemeral is the local ephemeral public key, if any (`e`).
	LocalEphemeral dh.PublicKey

	// RemoteStatic is the remote static public key, if any (`rs`).
	RemoteStatic dh.PublicKey

	// RemoteEphemeral is the remote ephemeral public key, if any (`re`).
	RemoteEphemeral dh.PublicKey
}

DHStatus is the Diffie-Hellman (DH) status of a handshake.

type HandshakeConfig

type HandshakeConfig struct {
	// Protocol is the noise protocol to use for this handshake.
	Protocol *Protocol

	// Prologue is the optional pre-handshake prologue input to be included
	// in the handshake hash.
	Prologue []byte

	// DH is the Diffie-Hellman keys for this handshake.
	DH *DHConfig

	// KEM is the Key Encapsulation Mechanism keys for this handshake.
	KEM *KEMConfig

	// PreSharedKeys is the vector of pre-shared symmetric key for PSK mode
	// handshakes.
	PreSharedKeys [][]byte

	// Rng is the entropy source to be used when entropy is required.
	// If the value is `nil`, `crypto/rand.Reader` will be used.
	Rng io.Reader

	// MaxMessageSize specifies the maximum Noise message size the handshake
	// and session will process or generate.  If the value is `0`,
	// `DefaultMaxMessageSize` will be used.  A negative value will disable
	// the maximum message size enforcement entirely.
	//
	// Warning: Values other than the default is a non-standard extension
	// to the protocol.
	MaxMessageSize int

	// IsInitiator should be set to true if this handshake is in the
	// initiator role.
	IsInitiator bool
}

HandshakeConfig is a handshake configuration.

Warning: While the config may contain sensitive material like DH private keys or a pre-shared key, sanitizing such things are the responsibility of the caller, after the handshake completes (or aborts due to an error).

Altering any of the members of this structure while a handshake is in progress will result in undefined behavior.

type HandshakeObserverDH added in v0.0.2

type HandshakeObserverDH interface {
	// OnPeerPublicKey will be called when a public key is received from
	// the peer, with the handshake pattern token (`pattern.Token_e`,
	// `pattern.Token_s`) and public key.
	//
	// Returning a non-nil error will abort the handshake immediately.
	OnPeerPublicKey(pattern.Token, dh.PublicKey) error
}

HandshakeObserverDH is a handshake observer for monitoring Diffie-Hellman based handshake status.

type HandshakeObserverKEM added in v0.0.2

type HandshakeObserverKEM interface {
	// OnPeerPublicKey will be called when a public key is received from
	// the peer, with the handshake pattern token (`pattern.Token_e`,
	// `pattern.Token_s`) and public key.
	//
	// Returning a non-nil error will abort the handshake immediately.
	OnPeerPublicKey(pattern.Token, kem.PublicKey) error
}

HandshakeObseverKEM is a handshake observer for monitoring Key Encapsulation Mechanism based handshake status.

type HandshakeState

type HandshakeState struct {
	// contains filtered or unexported fields
}

HandshakeState is the per-handshake state.

func NewHandshake

func NewHandshake(cfg *HandshakeConfig) (*HandshakeState, error)

NewHandshake constructs a new HandshakeState with the provided configuration. This call is equivalent to the `Initialize` HandshakeState call in the Noise Protocol Framework specification.

func (*HandshakeState) GetStatus

func (hs *HandshakeState) GetStatus() *HandshakeStatus

GetStatus returns the HandshakeState's status.

func (*HandshakeState) ReadMessage

func (hs *HandshakeState) ReadMessage(dst, payload []byte) ([]byte, error)

ReadMessage processes a read step of the handshake protocol, appending the authentiated/decrypted message payload to dst, and returning the potentially new slice.

Iff the handshake is complete, the error returned will be `ErrDone`.

func (*HandshakeState) Reset

func (hs *HandshakeState) Reset()

Reset clears the HandshakeState, to prevent future calls.

Warning: If either of the local keypairs were provided by the HandshakeConfig, they will be left intact.

func (*HandshakeState) SymmetricState

func (hs *HandshakeState) SymmetricState() *SymmetricState

SymmetricState returns the HandshakeState's encapsulated SymmetricState.

Warning: There should be no reason to call this, ever.

func (*HandshakeState) WriteMessage

func (hs *HandshakeState) WriteMessage(dst, payload []byte) ([]byte, error)

WriteMessage processes a write step of the handshake protocol, appending the handshake protocol message to dst, and returning the potentially new slice.

Iff the handshake is complete, the error returned will be `ErrDone`.

type HandshakeStatus

type HandshakeStatus struct {
	// Err is the error representing the status of the handshake.
	//
	// It will be `nil` if the handshake is in progess, `ErrDone` if the
	// handshake is complete, and any other error if the handshake has failed.
	Err error

	// DH is the Diffie-Hellman public keys of the handshake.
	DH *DHStatus

	// KEM is the Key Encapsulation Mechanism public keys of the handshake.
	KEM *KEMStatus

	// CipherStates is the resulting CipherState pair (`(cs1, cs2)`).
	//
	// Note: To prevent misuse, for one-way patterns `cs2` will be nil.
	CipherStates []*CipherState

	// HandshakeHash is the handshake hash (`h`).  This field is only set
	// once the handshake is completed.
	HandshakeHash []byte
}

HandshakeStatus is the status of a handshake.

Warning: It is the caller's responsibility to sanitize the CipherStates if desired. Altering any of the members of this structure while a handshake is in progress will result in undefined behavior.

type KEMConfig added in v0.0.2

type KEMConfig struct {
	// LocalStatic is the local static keypair, if any (`s`).
	LocalStatic kem.PrivateKey

	// LocalEphemeral is the local ephemeral keypair, if any (`e`).
	LocalEphemeral kem.PrivateKey

	// RemoteStatic is the remote static public key, if any (`rs`).
	RemoteStatic kem.PublicKey

	// RemoteEphemeral is the remote ephemeral public key, if any (`re`).
	RemoteEphemeral kem.PublicKey

	// Observer is the optional handshake observer.
	Observer HandshakeObserverKEM

	// GenKey is the SEEC GenKey instance to be used to generate
	// entropy for a KEM scheme when required.  If the value is `nil`,
	// `seec.GenKeyPassthrough` will be used.
	GenKey seec.GenKey
}

KEMConfig is the Key Encapsuation Mechanism (KEM) key configuration of a handshake.

type KEMStatus added in v0.0.2

type KEMStatus struct {
	// LocalEphemeral is the local ephemeral public key, if any (`e`).
	LocalEphemeral kem.PublicKey

	// RemoteStatic is the remote static public key, if any (`rs`).
	RemoteStatic kem.PublicKey

	// RemoteEphemeral is the remote ephemeral public key, if any (`re`).
	RemoteEphemeral kem.PublicKey
}

KEMStatus is the Key Encapsulation Mechanism (KEM) status of a handshake.

type Protocol

type Protocol struct {
	Pattern pattern.Pattern

	DH  dh.DH
	KEM kem.Scheme

	Cipher cipher.Cipher
	Hash   hash.Hash
}

Protocol is a the protocol to be used with a handshake.

func NewProtocol

func NewProtocol(s string) (*Protocol, error)

NewProtocol returns a Protocol from the provided (case-sensitive) protocol name. Returned protocol objects may be reused across multiple HandshakeConfigs.

Note: Only protocols that can be built with the built-in crypto and patterns are supported. Using custom crypto/patterns will require manually building a Protocol object.

func (*Protocol) String

func (pr *Protocol) String() string

String returns the string representation of the protocol name.

type SymmetricState

type SymmetricState struct {
	// contains filtered or unexported fields
}

SymmetricState encapsulates all symmetric cryptography used by the Noise protocol during a handshake.

Warning: There should be no reason to interact directly with this ever.

func (*SymmetricState) CipherState

func (ss *SymmetricState) CipherState() *CipherState

CipherState returns the SymmetricState's encapsualted CipherState.

Warning: There should be no reason to call this, ever.

func (*SymmetricState) DecryptAndHash

func (ss *SymmetricState) DecryptAndHash(dst, ciphertext []byte) ([]byte, error)

DecryptAndHash authenticates and decrypts the ciphertext, mixes the ciphertext with the handshake hash, appends the plaintext to dst, and returns the potentially new slice.

func (*SymmetricState) EncryptAndHash

func (ss *SymmetricState) EncryptAndHash(dst, plaintext []byte) []byte

EncryptAndHash encrypts and authenticates the plaintext, mixes the ciphertext with the handshake hash, appends the ciphertext to dst, and returns the potentially new slice.

func (*SymmetricState) GetHandshakeHash

func (ss *SymmetricState) GetHandshakeHash() []byte

GetHandshakeHash returns the handshake hash `h`.

func (*SymmetricState) InitializeSymmetric

func (ss *SymmetricState) InitializeSymmetric(protocolName []byte)

InitializeSymmetric initializes the SymmetricState with the initial chaining key and handshake hash, based on the protocol name.

func (*SymmetricState) MixHash

func (ss *SymmetricState) MixHash(data []byte)

MixHash mixes the provided data with the handshake hash.

func (*SymmetricState) MixKey

func (ss *SymmetricState) MixKey(inputKeyMaterial []byte)

MixKey mixes the provided material with the chaining key, and initializes the encapsulated CipherState's key with the output.

func (*SymmetricState) MixKeyAndHash

func (ss *SymmetricState) MixKeyAndHash(inputKeyMaterial []byte)

MixKeyAndHash mises the provided material with the chaining key, and mixes the handshake and initializes the encapsulated CipherState with the output.

func (*SymmetricState) Reset

func (ss *SymmetricState) Reset()

Reset clears the SymmetricState, to prevent future calls.

Warning: The transcript hash (`h`) is left intact to allow for clearing this state as early as possible, while preserving the ability to call `GetHandshakeHash`.

func (*SymmetricState) Split

func (ss *SymmetricState) Split() (*CipherState, *CipherState)

Split returns a pair of CipherState objects for encrypted transport messages.

Directories

Path Synopsis
Package cipher implments the Noise Protocol Framework cipher function abstract interface and standard cipher functions.
Package cipher implments the Noise Protocol Framework cipher function abstract interface and standard cipher functions.
Package dh implments the Noise Protocol Framework Diffie-Hellman function abstract interface and standard DH functions.
Package dh implments the Noise Protocol Framework Diffie-Hellman function abstract interface and standard DH functions.
Package hash implments the Noise Protocol Framework hash function abstract interface and standard hash functions.
Package hash implments the Noise Protocol Framework hash function abstract interface and standard hash functions.
internal
tuplehash
Package tuplehash implements TupleHash from NIST SP 800-15.
Package tuplehash implements TupleHash from NIST SP 800-15.
Package kem implments the PQNoise Key Encapsulation Mechanism function abstract interface and "standard" functions.
Package kem implments the PQNoise Key Encapsulation Mechanism function abstract interface and "standard" functions.
Package pattern implements the Noise Protocol Framework handshake pattern abstract interface and standard patterns.
Package pattern implements the Noise Protocol Framework handshake pattern abstract interface and standard patterns.
Package SEEC implments the Static-Ephemeral Entropy Combination (SEEC) scheme abstract interface and some predefined implementations.
Package SEEC implments the Static-Ephemeral Entropy Combination (SEEC) scheme abstract interface and some predefined implementations.
Package vectors provides types for the JSON formatted test vectors.
Package vectors provides types for the JSON formatted test vectors.

Jump to

Keyboard shortcuts

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