Documentation
¶
Index ¶
- Constants
- func LoadPattern(name string, dst *HandshakePattern) error
- func MustRegisterAEAD(name string, factory AEADFactory)
- func MustRegisterHash(name string, hash crypto.Hash)
- func MustRegisterPatternSpec(dsl string)
- func ParseProtocol(protoname string, proto *NoiseProto) error
- func RegisterAEAD(name string, factory AEADFactory) error
- func RegisterHash(name string, hash crypto.Hash) error
- func RegisterPattern(name string, pattern *HandshakePattern) error
- type AEAD
- type AEADFactory
- type AEADFactoryFunc
- type AcceptOrRejectAnyKey
- type CipherState
- func (self *CipherState) DecryptWithAd(ad, ciphertext []byte) ([]byte, error)
- func (self *CipherState) EncryptWithAd(ad, plaintext []byte) ([]byte, error)
- func (self *CipherState) HasKey() bool
- func (self *CipherState) Init(cipherFactory AEADFactory) error
- func (self *CipherState) InitializeKey(newkey []byte) error
- func (self *CipherState) Rekey() error
- func (self *CipherState) SetNonce(n uint64)
- type Config
- type CredentialVerifier
- type HandshakeParams
- type HandshakePattern
- type HandshakeState
- func (self *HandshakeState) DHLen() int
- func (self *HandshakeState) Initialize(params HandshakeParams) error
- func (self *HandshakeState) ReadMessage(message []byte, payload io.Writer) (bool, error)
- func (self *HandshakeState) RemoteStaticKey() *PublicKey
- func (self *HandshakeState) SetPsks(psks ...[]byte) error
- func (self *HandshakeState) Split(dst *TransportCipherPair) error
- func (self *HandshakeState) StaticKeypair() *Keypair
- func (self *HandshakeState) WriteMessage(payload []byte, message io.Writer) (bool, error)
- type Hash
- type Keypair
- type NoiseProto
- type PatternModifier
- type PublicKey
- type SymetricState
- func (self *SymetricState) DecryptAndHash(ciphertext []byte) ([]byte, error)
- func (self *SymetricState) EncryptAndHash(plaintext []byte) ([]byte, error)
- func (self *SymetricState) GetHandshakeHash() []byte
- func (self *SymetricState) Init(protoname string, cipherfactory AEADFactory, hash Hash) error
- func (self *SymetricState) InitializeSymetric(protoname string) error
- func (self *SymetricState) MixHash(data []byte)
- func (self *SymetricState) MixKey(ikm []byte) error
- func (self *SymetricState) MixKeyAndHash(ikm []byte) error
- type TestMessage
- type TestVector
- type TransportCipher
- type TransportCipherPair
- type VerifierProvider
Constants ¶
const ( MAX_UINT64 = 0xFFFF_FFFF_FFFF_FFFF CIPHER_MAX_NONCE = MAX_UINT64 - 1 )
const ( CIPHER_AES256_GCM = "AESGCM" CIPHER_CHACHA20_POLY1305 = "ChaChaPoly" )
const ( HASH_SHA256 = "SHA256" HASH_SHA512 = "SHA512" HASH_BLAKE2B = "BLAKE2b" HASH_BLAKE2S = "BLAKE2s" )
const (
// All package errors are wrapping Error
Error = errorFlag("noise: error")
)
Variables ¶
This section is empty.
Functions ¶
func LoadPattern ¶
func LoadPattern(name string, dst *HandshakePattern) error
LoadPattern copies the pattern referenced by name in dst. It errors if name does not correspond to a registered pattern.
func MustRegisterAEAD ¶
func MustRegisterAEAD(name string, factory AEADFactory)
MustRegisterAEAD adds factory to the AEAD registry. It panics if name is already in use or factory is invalid.
func MustRegisterHash ¶
MustRegisterHash adds hash to the Hash registry. It panics if name is already in use or hash is invalid.
func MustRegisterPatternSpec ¶
func MustRegisterPatternSpec(dsl string)
MustRegisterPatternSpec parses dsl which contains name of the pattern and definition of the pattern in noise specification language and stores the resulting HandshakePattern in the pattern registry. It panics if provided dsl is invalid or if the parsed pattern name is already in use.
Refers to noise protocol specs section 7 for a description of the syntax of the language used to specify handshakes.
func ParseProtocol ¶
func ParseProtocol(protoname string, proto *NoiseProto) error
ParseProtocol extracts the noise protocol name components and stores them into proto.
Valid protoname looks like "Noise_XX_25519_AESGCM_SHA256". Refers to noise protocol specs section 8, for details on how valid names are formed.
func RegisterAEAD ¶
func RegisterAEAD(name string, factory AEADFactory) error
RegisterAEAD adds factory to the AEAD registry. It errors if name is already in use or factory is invalid.
func RegisterHash ¶
RegisterHash adds hash to the Hash registry. It errors if name is already in use or hash is invalid.
func RegisterPattern ¶
func RegisterPattern(name string, pattern *HandshakePattern) error
RegisterPattern store the pattern in the pattern registry. It errors if name is already in use or if the pattern is invalid.
Types ¶
type AEAD ¶
type AEAD interface {
cipher.AEAD
// Rekey changes AEAD key to newkey. It errors if newkey is not compatible with AEAD algorithm.
Rekey(newkey []byte, nonce []byte) error
// FillNonce transfers nonce value n to nonce slice.
FillNonce(nonce []byte, n uint64)
}
AEAD extends cipher.AEAD with methods usefull for noise protocol implementation.
type AEADFactory ¶
type AEADFactory interface {
// New returns an AEAD instance. It errors if key is not compatible with AEAD algorithm.
New(key []byte) (AEAD, error)
}
AEADFactory allows obtaining an AEAD instance.
func GetAEADFactory ¶
func GetAEADFactory(name string) (AEADFactory, error)
GetAEADFactory loads an AEADFactory from the registry. It errors if no factory was registered with name.
type AEADFactoryFunc ¶
AEADFactoryFunc is an adapter to allow the use of ordinary functions as AEADFactory.
type AcceptOrRejectAnyKey ¶
type AcceptOrRejectAnyKey struct {
// desired verification status. If nil all verified static keys are valid...
Status error
// contains filtered or unexported fields
}
AcceptOrRejectAnyKey is a CredentialVerifier that allows accepting or rejecting any static key.
AcceptAnyOrRejectAnyKey is provided to help testing noise protocol implementations.
func NewAcceptOrRejectAnyKey ¶
func NewAcceptOrRejectAnyKey() *AcceptOrRejectAnyKey
NewAcceptOrRejectAnyKey returns a CredentialVerifier that always fails. Change the Status field to nil for Verify to always succeed.
func (*AcceptOrRejectAnyKey) ReadSize ¶
func (self *AcceptOrRejectAnyKey) ReadSize(hs *HandshakeState) int
ReadSize returns the byte size of inner configuration DH PublicKey.
func (*AcceptOrRejectAnyKey) Reset ¶
func (self *AcceptOrRejectAnyKey) Reset()
Reset clears internal state to allow reuse with another handshake.
func (*AcceptOrRejectAnyKey) Verify ¶
func (self *AcceptOrRejectAnyKey) Verify(_ *HandshakeState, data []byte) (int, error)
Verify errors if inner Status is not nil.
type CipherState ¶
type CipherState struct {
// contains filtered or unexported fields
}
CipherState holds AEAD cipher usage state, ie nonce and key.
CipherState appears in section 5.1 of the noise protocol specs.
func (*CipherState) DecryptWithAd ¶
func (self *CipherState) DecryptWithAd(ad, ciphertext []byte) ([]byte, error)
DecryptWithAd performs authenticated decryption of ciphertext if the CipherState has a key otherwise it returns ciphertext inchanged.
The ad parameter maybe nil, it shall match the ad used for obtaining ciphertext. ad corresponds to AEAD "additional data" and it was used alongside plaintext and key to calculate the ciphertext authentication tag. DecryptWithAd appears in section 5.1 of the noise protocol specs.
func (*CipherState) EncryptWithAd ¶
func (self *CipherState) EncryptWithAd(ad, plaintext []byte) ([]byte, error)
EncryptWithAd performs authenticated encryption of plaintext if the CipherState has a key otherwise it returns plaintext inchanged.
The ad parameter maybe nil, it corresponds to AEAD "additional data" and it is used alongside plaintext and key to calculate the ciphertext authentication tag. EncryptWithAd appears in section 5.1 of the noise protocol specs.
func (*CipherState) HasKey ¶
func (self *CipherState) HasKey() bool
HasKey returns true if the CipherState contains an initialized aead.
Haskey appears in section 5.1 of the noise protocol specs.
func (*CipherState) Init ¶
func (self *CipherState) Init(cipherFactory AEADFactory) error
Init set inner AEAD factory and zero the key.
Init appears in section 5.1 of the noise protocol specs.
func (*CipherState) InitializeKey ¶
func (self *CipherState) InitializeKey(newkey []byte) error
InitializeKey creates internal aead using newkey. A nil newkey will zero the internal key and aead. InitializeKey errors if newkey is not correctly sized.
InitializeKey appears in section 5.1 of the noise protocol specs.
func (*CipherState) Rekey ¶
func (self *CipherState) Rekey() error
Rekey changes the CipherState internal key. It errors if the CipherState does not have a key.
Rekey appears in section 5.1 of the noise protocol specs.
func (*CipherState) SetNonce ¶
func (self *CipherState) SetNonce(n uint64)
SetNonce set internal nonce value to n.
SetNonce is usefull when the CipherState is used after completion of the noise protocol handshake. If transport messages are produced concurrently or maybe received out of order then application will transfert nonce value with transport message. Receiver shall verify that received nonce was not previously used and use SetNonce prior to attend decryption... SetNonce appears in section 5.1 of the noise protocol specs.
type Config ¶
type Config struct {
// "name" of the noise protocol, eg "Noise_XX_25519_AESGCM_SHA256".
// Refers to noise protocol specs section 8, for details on how valid names are formed.
ProtoName string
// object that defines how to process the handshake messages.
HandshakePattern HandshakePattern
// handshake cipher factory.
CipherFactory AEADFactory
// handshake Hash algorithm.
HashAlgo Hash
// handshake ECDH curve
CurveAlgo algos.Curve
}
Config holds noise protocol handshake configuration
type CredentialVerifier ¶
type CredentialVerifier interface {
// ReadSize returns the expected size of the next data to be passed to Verify.
ReadSize(hs *HandshakeState) int
// Verify uses data to perform some validation. If the validation fails it returns
// a non nil error, otherwise it returns a nil error and an integer in [0..len(data)] range
// that indicates the number of bytes to be removed from the data buffer prior to continue
// processing the handshake.
//
// data to be verified are plaintext extracted from received handshake messages. For example data maybe
// a user identifier, a public key or a public key certificate...
//
// Verify may update the provided HandshakeState. This can be leveraged for example to add psks to an
// HandshakeState after having verified an userId...
//
// Verify shall not retain hs or data.
Verify(hs *HandshakeState, data []byte) (int, error)
// Reset clears internal state to allow reuse with another handshake.
Reset()
}
CredentialVerifier is used to track verification state of a certain credential transmitted in an handshake message.
type HandshakeParams ¶
type HandshakeParams struct {
Cfg Config
Initiator bool
Prologue []byte
StaticKeypair *Keypair
EphemeralKeypair *Keypair
RemoteStaticKey *PublicKey
RemoteEphemeralKey *PublicKey
Psks [][]byte
}
HandshakeParams holds HandshakeState.Initialize parameters.
type HandshakePattern ¶
type HandshakePattern struct {
// contains filtered or unexported fields
}
HandshakePattern holds informations that defines a noise protocol handshake.
func NewPattern ¶
func NewPattern(dsl string) (*HandshakePattern, error)
NewPattern parses dsl that contains a noise protocol handshake description and constructs the corresponding HandshakePattern. It errors if provided dsl is invalid.
Refers to noise protocol specs section 7 for a description of the syntax of the language used to define handshakes.
You should not normally use NewPattern to create the HandshakePattern{} you need. LoadPattern or Config.Load allows you to obtain or safely modify one of the preverified patterns referenced in the noise protocol specs.
func (HandshakePattern) Dsl ¶
func (self HandshakePattern) Dsl() string
Dsl returns a string that encodes the HandshakePattern using noise protocol specs pattern definition language.
Refers to noise protocol specs section 7 for a description of the syntax of the language used to define handshake patterns.
func (HandshakePattern) OneWay ¶
func (self HandshakePattern) OneWay() bool
OneWay returns true if the HandshakePattern is one way.
Refers to noise protocol specs section 7.4 for a description of the oneway patterns.
type HandshakeState ¶
type HandshakeState struct {
SymetricState
// contains filtered or unexported fields
}
HandshakeState holds noise protocol handshake execution state.
HandshakeState appears in section 5.3 of the noise protocol specs.
func (*HandshakeState) DHLen ¶
func (self *HandshakeState) DHLen() int
DHLen returns ECDH PublicKey byte size.
This method is provided to comply with noise specs section 4.1 that mentions the DHLEN constant. noise specs are a bit ambiguous as it states that DHLEN is both the PublicKey size and ECDH shared secret size. This equality holds only for X25519 and X448.
func (*HandshakeState) Initialize ¶
func (self *HandshakeState) Initialize(params HandshakeParams) error
Initialize set handshake initial state. It errors if provided parameters are not compatible with provided cfg.
Initialize appears in section 5.3 of the noise protocol specs.
func (*HandshakeState) ReadMessage ¶
ReadMessage processes incoming handshake message taking into account inner state. The returned bool is true when the handshake is completed.
ReadMessage appears in section 5.3 of the noise protocol specs.
func (*HandshakeState) RemoteStaticKey ¶
func (self *HandshakeState) RemoteStaticKey() *PublicKey
RemoteStaticKey returns the remote static PublicKey.
func (*HandshakeState) SetPsks ¶
func (self *HandshakeState) SetPsks(psks ...[]byte) error
func (*HandshakeState) Split ¶
func (self *HandshakeState) Split(dst *TransportCipherPair) error
Split initializes a TransportCipherPair using internal state.
Split should only be called at the end of the handshake.
Split appears in noise protocol specs section 5.2.
func (*HandshakeState) StaticKeypair ¶
func (self *HandshakeState) StaticKeypair() *Keypair
StaticKeypair returns the local static Keypair.
func (*HandshakeState) WriteMessage ¶
WriteMessage prepares a new handshake message taking into account inner state and payload parameter. The returned bool is true when the handshake is completed.
WriteMessage appears in section 5.3 of the noise protocol specs.
type Hash ¶
Hash embeds the crypto.Hash type and adds methods usefull for noise protocol implementation.
type Keypair ¶
type Keypair = ecdh.PrivateKey
type NoiseProto ¶
type NoiseProto struct {
Name string
HandshakePattern string
HandshakePatternModifiers []string
CurveAlgo string
CipherAlgo string
HashAlgo string
}
NoiseProto holds the components of valid noise protocol names. Refers to noise protocol specs section 8, for details on how valid names are formed.
type PatternModifier ¶
type PatternModifier interface {
Modify(ptrn HandshakePattern) (HandshakePattern, error)
}
PatternModifier is an interface that allows modifying HandshakePattern.
func GetModifier ¶
func GetModifier(name string) (PatternModifier, error)
GetModifier allows retrieving a PatternModifier by name. It errors if the provided name is invalid.
type SymetricState ¶
type SymetricState struct {
CipherState
// contains filtered or unexported fields
}
SymetricState holds noise protocol handshake symetric state.
SymetricState appears in noise protocol specs section 5.2.
func (*SymetricState) DecryptAndHash ¶
func (self *SymetricState) DecryptAndHash(ciphertext []byte) ([]byte, error)
DecryptAndHash returns plaintext decrypted using inner CipherState. After plaintext is decrypted the received ciphertext is mixed into the SymetricState.
DecryptAndHash uses internal state to authenticate received ciphertext. ciphertext can be decrypted only if internal state is exactly same as sender before ciphertext encryption.
DecryptAndHash appears in noise protocol specs section 5.2.
func (*SymetricState) EncryptAndHash ¶
func (self *SymetricState) EncryptAndHash(plaintext []byte) ([]byte, error)
EncryptAndHash returns ciphertext encrypted using inner CipherState. The ciphertext is mixed into the SymetricState before being returned.
EncryptAndHash uses internal state to authenticate returned ciphertext. ciphertext recipient will be able to decrypt the returned ciphertext only if its state is exactly same as self.
EncryptAndHash appears in noise protocol specs section 5.2.
func (*SymetricState) GetHandshakeHash ¶
func (self *SymetricState) GetHandshakeHash() []byte
GetHandshakeHash returns SymetricState h state.
GetHandshakeHash is normally called at the end of the handshake.
GetHandshakeHash appears in noise protocol specs section 5.2.
func (*SymetricState) Init ¶
func (self *SymetricState) Init(protoname string, cipherfactory AEADFactory, hash Hash) error
Init set SymetricState initial state.
func (*SymetricState) InitializeSymetric ¶
func (self *SymetricState) InitializeSymetric(protoname string) error
InitializeSymetric set SymetricState initial state reading configuration information from protoname.
InitializeSymetric is provided as it appears in noise protocol specs section 5.2. In most cases, it is preferrable to initialize SymetricState using Init as it is more efficient.
func (*SymetricState) MixHash ¶
func (self *SymetricState) MixHash(data []byte)
MixHash mixes data into the SymetricState state.
MixHash appears in noise protocol specs section 5.2.
func (*SymetricState) MixKey ¶
func (self *SymetricState) MixKey(ikm []byte) error
MixKey mixes ikm into the SymetricState state.
MixKey appears in noise protocol specs section 5.2.
func (*SymetricState) MixKeyAndHash ¶
func (self *SymetricState) MixKeyAndHash(ikm []byte) error
MixKeyAndHash mixes ikm into the SymetricState state.
MixKeyAndHash appears in noise protocol specs section 5.2.
type TestMessage ¶
type TestMessage struct {
Payload utils.HexBinary `json:"payload"`
CipherText utils.HexBinary `json:"ciphertext"`
}
TestMessage holds noise protocol test vector message fields.
type TestVector ¶
type TestVector struct {
ProtocolName string `json:"protocol_name"`
InitiatorPrologue utils.HexBinary `json:"init_prologue"`
InitiatorEphemeralKey utils.HexBinary `json:"init_ephemeral"`
InitiatorStaticKey utils.HexBinary `json:"init_static"`
InitiatorRemoteEphemeralKey utils.HexBinary `json:"init_remote_ephemeral"`
InitiatorRemoteStaticKey utils.HexBinary `json:"init_remote_static"`
InitiatorPsks []utils.HexBinary `json:"init_psks"`
ResponderPrologue utils.HexBinary `json:"resp_prologue"`
ResponderEphemeralKey utils.HexBinary `json:"resp_ephemeral"`
ResponderStaticKey utils.HexBinary `json:"resp_static"`
ResponderRemoteEphemeralKey utils.HexBinary `json:"resp_remote_ephemeral"`
ResponderRemoteStaticKey utils.HexBinary `json:"resp_remote_static"`
ResponderPsks []utils.HexBinary `json:"resp_psks"`
HandshakeHash utils.HexBinary `json:"handshake_hash"`
Messages []TestMessage `json:"messages"`
}
TestVector holds noise protocol test vector fields.
func LoadTestVectors ¶
func LoadTestVectors(srcpath string) ([]TestVector, error)
LoadTestVector loads test vectors from json file at srcpath.
type TransportCipher ¶
type TransportCipher struct {
CipherState
}
TransportCipher is a CipherState that is used after handshake completion.
func (*TransportCipher) DecryptWithAd ¶
func (self *TransportCipher) DecryptWithAd(ad, ciphertext []byte) ([]byte, error)
DecryptWithAd performs authenticated decryption of ciphertext if the TransportCipher has a key otherwise it errors.
The ad parameter maybe nil, it shall match the ad used for obtaining ciphertext. ad corresponds to AEAD "additional data" and it was used alongside plaintext and key to calculate the ciphertext authentication tag.
The noise protocol specs suggests using CipherState.DecryptWithAd for transport decryption. The problem is that CipherState allows operating with a zero key which is necessary for starting the handshake, but would be insecure during the transport phase.
func (*TransportCipher) EncryptWithAd ¶
func (self *TransportCipher) EncryptWithAd(ad, plaintext []byte) ([]byte, error)
EncryptWithAd performs authenticated encryption of plaintext if the TransportCipher has a key otherwise it errors.
The ad parameter maybe nil, it corresponds to AEAD "additional data" and it is used alongside plaintext and key to calculate the ciphertext authentication tag.
The noise protocol specs suggests using CipherState.EncryptWithAd for transport encryption. The problem is that CipherState allows operating with a zero key which is necessary for starting the handshake, but would be insecure during the transport phase.
type TransportCipherPair ¶
type TransportCipherPair struct {
// contains filtered or unexported fields
}
TransportCipherPair holds TransportCipher used for transport encryption/decryption.
func (*TransportCipherPair) Decryptor ¶
func (self *TransportCipherPair) Decryptor() *TransportCipher
Decryptor returns the TransportCipher to be used for transport decryption.
func (*TransportCipherPair) Encryptor ¶
func (self *TransportCipherPair) Encryptor() *TransportCipher
Encryptor returns the TransportCipher to be used for transport encryption.
type VerifierProvider ¶
type VerifierProvider struct {
// contains filtered or unexported fields
}
VerifierProvider holds CredentialVerifiers to be used in a noise protocol handshake.
func (*VerifierProvider) Get ¶
func (self *VerifierProvider) Get(name string) CredentialVerifier
Get returns the CredentialVerifier that corresponds to name if any.
func (*VerifierProvider) Reset ¶
func (self *VerifierProvider) Reset()
Reset resets all the CredentialVerifier in the VerifierProvider.
It is safe to call Reset on a nil VerifierProvider.
func (*VerifierProvider) SetLoaders ¶
func (self *VerifierProvider) SetLoaders(names ...string)
SetLoaders allows declaring which HandshakeState credentials (eg psks, password...) are loaded by the verifiers registered with the VerifierProvider.
func (*VerifierProvider) SetVerifier ¶
func (self *VerifierProvider) SetVerifier(name string, cv CredentialVerifier)
SetVerifier registers a CredentialVerifier with the VerifierProvider.
registration name normally corresponds to HandshakePattern tokens eg "s", "rs"...
This implementation of VerifierProvider supports registering at most 2 CredentialVerifiers. A static key verifier that can be registered with names "s" or "rs". An "extension" verifier that can be registered with any other name.
func (*VerifierProvider) ShouldLoad ¶
func (self *VerifierProvider) ShouldLoad(name string) bool
ShouldLoad returns true if name corresponds to a loader registered with the VerifierProvider.