2016-07-12 22:20:06 -04:00
// Package noise implements the Noise Protocol Framework.
//
// Noise is a low-level framework for building crypto protocols. Noise protocols
// support mutual and optional authentication, identity hiding, forward secrecy,
// zero round-trip encryption, and other advanced features. For more details,
2017-12-28 18:13:51 -05:00
// visit https://noiseprotocol.org.
2015-11-15 12:49:59 -05:00
package noise
import (
2016-07-12 22:20:06 -04:00
"crypto/rand"
2015-11-15 12:49:59 -05:00
"errors"
2017-05-11 15:56:03 +02:00
"fmt"
2022-12-14 12:10:23 -04:00
"hash"
2015-11-15 12:49:59 -05:00
"io"
2017-07-11 17:07:19 +00:00
"math"
2015-11-15 12:49:59 -05:00
)
2016-07-12 22:20:06 -04:00
// A CipherState provides symmetric encryption and decryption after a successful
// handshake.
2015-11-15 12:49:59 -05:00
type CipherState struct {
cs CipherSuite
c Cipher
k [ 32 ] byte
n uint64
2016-07-12 21:32:38 -04:00
2018-01-24 15:22:32 -05:00
invalid bool
2015-11-15 12:49:59 -05:00
}
2021-04-20 18:02:02 -04:00
// MaxNonce is the maximum value of n that is allowed. ErrMaxNonce is returned
// by Encrypt and Decrypt after this has been reached. 2^64-1 is reserved for rekeys.
const MaxNonce = uint64 ( math . MaxUint64 ) - 1
var ErrMaxNonce = errors . New ( "noise: cipherstate has reached maximum n, a new handshake must be performed" )
2021-04-20 16:35:37 -04:00
var ErrCipherSuiteCopied = errors . New ( "noise: CipherSuite has been copied, state is invalid" )
2016-07-12 22:20:06 -04:00
// Encrypt encrypts the plaintext and then appends the ciphertext and an
// authentication tag across the ciphertext and optional authenticated data to
// out. This method automatically increments the nonce after every call, so
2021-04-20 18:02:02 -04:00
// messages must be decrypted in the same order. ErrMaxNonce is returned after
// the maximum nonce of 2^64-2 is reached.
2021-04-20 16:35:37 -04:00
func ( s * CipherState ) Encrypt ( out , ad , plaintext [ ] byte ) ( [ ] byte , error ) {
2018-01-24 15:22:32 -05:00
if s . invalid {
2021-04-20 16:35:37 -04:00
return nil , ErrCipherSuiteCopied
2018-01-24 15:22:32 -05:00
}
2021-04-20 18:02:02 -04:00
if s . n > MaxNonce {
return nil , ErrMaxNonce
}
2015-11-15 12:49:59 -05:00
out = s . c . Encrypt ( out , s . n , ad , plaintext )
s . n ++
2021-04-20 16:35:37 -04:00
return out , nil
2015-11-15 12:49:59 -05:00
}
2016-07-12 22:20:06 -04:00
// Decrypt checks the authenticity of the ciphertext and authenticated data and
// then decrypts and appends the plaintext to out. This method automatically
// increments the nonce after every call, messages must be provided in the same
2021-04-20 18:02:02 -04:00
// order that they were encrypted with no missing messages. ErrMaxNonce is
// returned after the maximum nonce of 2^64-2 is reached.
2015-11-15 12:49:59 -05:00
func ( s * CipherState ) Decrypt ( out , ad , ciphertext [ ] byte ) ( [ ] byte , error ) {
2018-01-24 15:22:32 -05:00
if s . invalid {
2021-04-20 16:35:37 -04:00
return nil , ErrCipherSuiteCopied
2018-01-24 15:22:32 -05:00
}
2021-04-20 18:02:02 -04:00
if s . n > MaxNonce {
return nil , ErrMaxNonce
}
2015-11-15 12:49:59 -05:00
out , err := s . c . Decrypt ( out , s . n , ad , ciphertext )
2021-04-22 13:09:18 -04:00
if err != nil {
return nil , err
}
2015-11-15 12:49:59 -05:00
s . n ++
2021-04-22 13:09:18 -04:00
return out , nil
2015-11-15 12:49:59 -05:00
}
2018-01-24 15:22:32 -05:00
// Cipher returns the low-level symmetric encryption primitive. It should only
// be used if nonces need to be managed manually, for example with a network
// protocol that can deliver out-of-order messages. This is dangerous, users
// must ensure that they are incrementing a nonce after every encrypt operation.
// After calling this method, it is an error to call Encrypt/Decrypt on the
// CipherState.
func ( s * CipherState ) Cipher ( ) Cipher {
s . invalid = true
return s . c
}
2021-04-20 18:02:02 -04:00
// Nonce returns the current value of n. This can be used to determine if a
// new handshake should be performed due to approaching MaxNonce.
func ( s * CipherState ) Nonce ( ) uint64 {
return s . n
}
2021-10-03 16:05:55 -06:00
// SetNonce sets the current value of n.
func ( s * CipherState ) SetNonce ( n uint64 ) {
s . n = n
}
2017-07-11 17:07:19 +00:00
func ( s * CipherState ) Rekey ( ) {
var zeros [ 32 ] byte
var out [ ] byte
out = s . c . Encrypt ( out , math . MaxUint64 , [ ] byte { } , zeros [ : ] )
copy ( s . k [ : ] , out [ : 32 ] )
s . c = s . cs . Cipher ( s . k )
}
2016-07-12 21:25:40 -04:00
type symmetricState struct {
2015-11-15 12:49:59 -05:00
CipherState
2017-07-11 17:07:04 +00:00
hasK bool
ck [ ] byte
h [ ] byte
2016-07-14 21:27:05 -04:00
prevCK [ ] byte
prevH [ ] byte
2015-11-15 12:49:59 -05:00
}
2016-07-12 21:25:40 -04:00
func ( s * symmetricState ) InitializeSymmetric ( handshakeName [ ] byte ) {
2015-11-15 12:49:59 -05:00
h := s . cs . Hash ( )
if len ( handshakeName ) <= h . Size ( ) {
s . h = make ( [ ] byte , h . Size ( ) )
copy ( s . h , handshakeName )
} else {
h . Write ( handshakeName )
s . h = h . Sum ( nil )
}
s . ck = make ( [ ] byte , len ( s . h ) )
copy ( s . ck , s . h )
}
2016-07-12 21:25:40 -04:00
func ( s * symmetricState ) MixKey ( dhOutput [ ] byte ) {
2015-11-15 12:49:59 -05:00
s . n = 0
2015-11-16 11:37:33 -05:00
s . hasK = true
2015-11-15 12:49:59 -05:00
var hk [ ] byte
2017-05-11 15:56:03 +02:00
s . ck , hk , _ = hkdf ( s . cs . Hash , 2 , s . ck [ : 0 ] , s . k [ : 0 ] , nil , s . ck , dhOutput )
2015-11-15 12:49:59 -05:00
copy ( s . k [ : ] , hk )
s . c = s . cs . Cipher ( s . k )
}
2016-07-12 21:25:40 -04:00
func ( s * symmetricState ) MixHash ( data [ ] byte ) {
2015-11-15 12:49:59 -05:00
h := s . cs . Hash ( )
h . Write ( s . h )
h . Write ( data )
s . h = h . Sum ( s . h [ : 0 ] )
}
2017-05-11 15:56:03 +02:00
func ( s * symmetricState ) MixKeyAndHash ( data [ ] byte ) {
var hk [ ] byte
2015-11-16 11:37:33 -05:00
var temp [ ] byte
2017-05-11 15:56:03 +02:00
s . ck , temp , hk = hkdf ( s . cs . Hash , 3 , s . ck [ : 0 ] , temp , s . k [ : 0 ] , s . ck , data )
2015-11-16 11:37:33 -05:00
s . MixHash ( temp )
2017-05-11 15:56:03 +02:00
copy ( s . k [ : ] , hk )
s . c = s . cs . Cipher ( s . k )
s . n = 0
s . hasK = true
2015-11-16 11:37:33 -05:00
}
2022-12-14 12:10:23 -04:00
// Note that by setting extraAd, it is possible to pass extra additional data that will be concatenated to the ad specified by Noise (can be used to authenticate messageNametag)
func ( s * symmetricState ) EncryptAndHash ( out , plaintext [ ] byte , extraAd ... byte ) ( [ ] byte , error ) {
2015-11-16 11:37:33 -05:00
if ! s . hasK {
2015-11-15 12:49:59 -05:00
s . MixHash ( plaintext )
2021-04-20 16:35:37 -04:00
return append ( out , plaintext ... ) , nil
}
2022-12-14 12:10:23 -04:00
ad := append ( [ ] byte ( nil ) , s . h ... )
ad = append ( ad , extraAd ... )
ciphertext , err := s . Encrypt ( out , ad , plaintext )
2021-04-20 16:35:37 -04:00
if err != nil {
return nil , err
2015-11-15 12:49:59 -05:00
}
s . MixHash ( ciphertext [ len ( out ) : ] )
2021-04-20 16:35:37 -04:00
return ciphertext , nil
2015-11-15 12:49:59 -05:00
}
2022-12-14 12:10:23 -04:00
func ( s * symmetricState ) DecryptAndHash ( out , data [ ] byte , extraAd ... byte ) ( [ ] byte , error ) {
2015-11-16 11:37:33 -05:00
if ! s . hasK {
2015-11-15 12:49:59 -05:00
s . MixHash ( data )
return append ( out , data ... ) , nil
}
2022-12-14 12:10:23 -04:00
ad := append ( [ ] byte ( nil ) , s . h ... )
ad = append ( ad , extraAd ... )
plaintext , err := s . Decrypt ( out , ad , data )
2015-11-15 12:49:59 -05:00
if err != nil {
return nil , err
}
s . MixHash ( data )
return plaintext , nil
}
2016-07-12 21:25:40 -04:00
func ( s * symmetricState ) Split ( ) ( * CipherState , * CipherState ) {
2015-11-15 12:49:59 -05:00
s1 , s2 := & CipherState { cs : s . cs } , & CipherState { cs : s . cs }
2017-05-11 15:56:03 +02:00
hk1 , hk2 , _ := hkdf ( s . cs . Hash , 2 , s1 . k [ : 0 ] , s2 . k [ : 0 ] , nil , s . ck , nil )
2015-11-15 12:49:59 -05:00
copy ( s1 . k [ : ] , hk1 )
copy ( s2 . k [ : ] , hk2 )
s1 . c = s . cs . Cipher ( s1 . k )
s2 . c = s . cs . Cipher ( s2 . k )
return s1 , s2
}
2016-07-14 21:27:05 -04:00
func ( s * symmetricState ) Checkpoint ( ) {
if len ( s . ck ) > cap ( s . prevCK ) {
s . prevCK = make ( [ ] byte , len ( s . ck ) )
}
s . prevCK = s . prevCK [ : len ( s . ck ) ]
copy ( s . prevCK , s . ck )
if len ( s . h ) > cap ( s . prevH ) {
s . prevH = make ( [ ] byte , len ( s . h ) )
}
s . prevH = s . prevH [ : len ( s . h ) ]
copy ( s . prevH , s . h )
}
func ( s * symmetricState ) Rollback ( ) {
s . ck = s . ck [ : len ( s . prevCK ) ]
copy ( s . ck , s . prevCK )
s . h = s . h [ : len ( s . prevH ) ]
copy ( s . h , s . prevH )
}
2016-07-12 22:20:06 -04:00
// A MessagePattern is a single message or operation used in a Noise handshake.
2015-11-15 12:49:59 -05:00
type MessagePattern int
2016-07-12 22:20:06 -04:00
// A HandshakePattern is a list of messages and operations that are used to
// perform a specific Noise handshake.
2015-11-15 12:49:59 -05:00
type HandshakePattern struct {
Name string
InitiatorPreMessages [ ] MessagePattern
ResponderPreMessages [ ] MessagePattern
Messages [ ] [ ] MessagePattern
}
const (
MessagePatternS MessagePattern = iota
MessagePatternE
MessagePatternDHEE
MessagePatternDHES
MessagePatternDHSE
MessagePatternDHSS
2017-05-11 15:56:03 +02:00
MessagePatternPSK
2015-11-15 12:49:59 -05:00
)
2016-07-12 22:20:06 -04:00
// MaxMsgLen is the maximum number of bytes that can be sent in a single Noise
// message.
2015-11-15 12:49:59 -05:00
const MaxMsgLen = 65535
2016-07-12 22:20:06 -04:00
// A HandshakeState tracks the state of a Noise handshake. It may be discarded
// after the handshake is complete.
2015-11-15 12:49:59 -05:00
type HandshakeState struct {
2016-07-12 21:25:40 -04:00
ss symmetricState
2015-11-15 12:49:59 -05:00
s DHKey // local static keypair
e DHKey // local ephemeral keypair
rs [ ] byte // remote party's static public key
re [ ] byte // remote party's ephemeral public key
2017-07-11 17:07:04 +00:00
psk [ ] byte // preshared key, maybe zero length
2015-11-15 12:49:59 -05:00
messagePatterns [ ] [ ] MessagePattern
shouldWrite bool
2017-09-28 00:37:07 +01:00
initiator bool
2015-11-15 12:49:59 -05:00
msgIdx int
rng io . Reader
}
2016-07-12 22:20:06 -04:00
// A Config provides the details necessary to process a Noise handshake. It is
2016-07-12 22:44:26 -04:00
// never modified by this package, and can be reused.
2015-11-16 13:09:47 -05:00
type Config struct {
2016-07-12 22:20:06 -04:00
// CipherSuite is the set of cryptographic primitives that will be used.
CipherSuite CipherSuite
// Random is the source for cryptographically appropriate random bytes. If
2016-07-12 22:45:26 -04:00
// zero, it is automatically configured.
2016-07-12 22:20:06 -04:00
Random io . Reader
// Pattern is the pattern for the handshake.
Pattern HandshakePattern
// Initiator must be true if the first message in the handshake will be sent
// by this peer.
Initiator bool
// Prologue is an optional message that has already be communicated and must
// be identical on both sides for the handshake to succeed.
Prologue [ ] byte
2017-05-11 15:56:03 +02:00
// PresharedKey is the optional preshared key for the handshake.
2016-07-12 22:20:06 -04:00
PresharedKey [ ] byte
2017-05-11 15:56:03 +02:00
// PresharedKeyPlacement specifies the placement position of the PSK token
// when PresharedKey is specified
PresharedKeyPlacement int
2016-07-12 22:44:26 -04:00
// StaticKeypair is this peer's static keypair, required if part of the
// handshake.
2016-07-12 22:20:06 -04:00
StaticKeypair DHKey
2016-07-12 22:44:26 -04:00
// EphemeralKeypair is this peer's ephemeral keypair that was provided as
// a pre-message in the handshake.
2015-11-16 13:09:47 -05:00
EphemeralKeypair DHKey
2016-07-12 22:20:06 -04:00
2016-07-12 22:44:26 -04:00
// PeerStatic is the static public key of the remote peer that was provided
// as a pre-message in the handshake.
2016-07-12 22:20:06 -04:00
PeerStatic [ ] byte
2016-07-12 22:44:26 -04:00
// PeerEphemeral is the ephemeral public key of the remote peer that was
// provided as a pre-message in the handshake.
2016-07-12 22:20:06 -04:00
PeerEphemeral [ ] byte
2015-11-16 13:09:47 -05:00
}
2016-07-12 22:20:06 -04:00
// NewHandshakeState starts a new handshake using the provided configuration.
2018-01-09 20:48:36 -06:00
func NewHandshakeState ( c Config ) ( * HandshakeState , error ) {
2015-11-15 12:49:59 -05:00
hs := & HandshakeState {
2015-11-16 13:09:47 -05:00
s : c . StaticKeypair ,
e : c . EphemeralKeypair ,
rs : c . PeerStatic ,
2017-05-11 15:56:03 +02:00
psk : c . PresharedKey ,
2015-11-16 13:09:47 -05:00
messagePatterns : c . Pattern . Messages ,
shouldWrite : c . Initiator ,
2017-09-28 00:37:07 +01:00
initiator : c . Initiator ,
2015-11-16 13:09:47 -05:00
rng : c . Random ,
2015-11-15 12:49:59 -05:00
}
2016-07-12 22:20:06 -04:00
if hs . rng == nil {
hs . rng = rand . Reader
}
2015-11-16 22:07:11 -05:00
if len ( c . PeerEphemeral ) > 0 {
hs . re = make ( [ ] byte , len ( c . PeerEphemeral ) )
copy ( hs . re , c . PeerEphemeral )
}
2016-07-12 21:25:40 -04:00
hs . ss . cs = c . CipherSuite
2017-05-11 15:56:03 +02:00
pskModifier := ""
if len ( hs . psk ) > 0 {
if len ( hs . psk ) != 32 {
2018-01-09 20:48:36 -06:00
return nil , errors . New ( "noise: specification mandates 256-bit preshared keys" )
2017-05-11 15:56:03 +02:00
}
pskModifier = fmt . Sprintf ( "psk%d" , c . PresharedKeyPlacement )
hs . messagePatterns = append ( [ ] [ ] MessagePattern ( nil ) , hs . messagePatterns ... )
2017-07-11 17:07:04 +00:00
if c . PresharedKeyPlacement == 0 {
2017-05-11 15:56:03 +02:00
hs . messagePatterns [ 0 ] = append ( [ ] MessagePattern { MessagePatternPSK } , hs . messagePatterns [ 0 ] ... )
} else {
2017-07-11 17:07:04 +00:00
hs . messagePatterns [ c . PresharedKeyPlacement - 1 ] = append ( hs . messagePatterns [ c . PresharedKeyPlacement - 1 ] , MessagePatternPSK )
2017-05-11 15:56:03 +02:00
}
2015-11-15 17:18:33 -05:00
}
2017-05-11 15:56:03 +02:00
hs . ss . InitializeSymmetric ( [ ] byte ( "Noise_" + c . Pattern . Name + pskModifier + "_" + string ( hs . ss . cs . Name ( ) ) ) )
2016-07-12 21:25:40 -04:00
hs . ss . MixHash ( c . Prologue )
2015-11-16 13:09:47 -05:00
for _ , m := range c . Pattern . InitiatorPreMessages {
2015-11-15 12:49:59 -05:00
switch {
2015-11-16 13:09:47 -05:00
case c . Initiator && m == MessagePatternS :
2016-07-12 21:25:40 -04:00
hs . ss . MixHash ( hs . s . Public )
2015-11-16 13:09:47 -05:00
case c . Initiator && m == MessagePatternE :
2016-07-12 21:25:40 -04:00
hs . ss . MixHash ( hs . e . Public )
2015-11-16 13:09:47 -05:00
case ! c . Initiator && m == MessagePatternS :
2016-07-12 21:25:40 -04:00
hs . ss . MixHash ( hs . rs )
2015-11-16 13:09:47 -05:00
case ! c . Initiator && m == MessagePatternE :
2016-07-12 21:25:40 -04:00
hs . ss . MixHash ( hs . re )
2015-11-15 12:49:59 -05:00
}
}
2015-11-16 13:09:47 -05:00
for _ , m := range c . Pattern . ResponderPreMessages {
2015-11-15 12:49:59 -05:00
switch {
2015-11-16 13:09:47 -05:00
case ! c . Initiator && m == MessagePatternS :
2016-07-12 21:25:40 -04:00
hs . ss . MixHash ( hs . s . Public )
2015-11-16 13:09:47 -05:00
case ! c . Initiator && m == MessagePatternE :
2016-07-12 21:25:40 -04:00
hs . ss . MixHash ( hs . e . Public )
2015-11-16 13:09:47 -05:00
case c . Initiator && m == MessagePatternS :
2016-07-12 21:25:40 -04:00
hs . ss . MixHash ( hs . rs )
2015-11-16 13:09:47 -05:00
case c . Initiator && m == MessagePatternE :
2016-07-12 21:25:40 -04:00
hs . ss . MixHash ( hs . re )
2015-11-15 12:49:59 -05:00
}
}
2018-01-09 20:48:36 -06:00
return hs , nil
2015-11-15 12:49:59 -05:00
}
2022-12-14 12:10:23 -04:00
func ( s * HandshakeState ) H ( ) [ ] byte {
return append ( [ ] byte ( nil ) , s . ss . h ... )
}
func ( s * HandshakeState ) RS ( ) [ ] byte {
return append ( [ ] byte ( nil ) , s . rs ... )
}
2016-07-12 22:20:06 -04:00
// WriteMessage appends a handshake message to out. The message will include the
// optional payload if provided. If the handshake is completed by the call, two
// CipherStates will be returned, one is used for encryption of messages to the
// remote peer, the other is used for decryption of messages from the remote
// peer. It is an error to call this method out of sync with the handshake
// pattern.
2022-12-14 12:10:23 -04:00
func ( s * HandshakeState ) WriteMessage ( out , payload [ ] byte , extraAd ... byte ) ( [ ] byte , * CipherState , * CipherState , error ) {
out , _ , cs1 , cs2 , err := s . WriteMessageAndGetPK ( out , [ ] [ ] byte { } , payload , extraAd )
2022-10-23 09:01:24 -04:00
return out , cs1 , cs2 , err
2022-06-26 09:01:10 -04:00
}
// WriteMessageAndGetPK appends a handshake message to out. outPK can possibly contain the
// party public keys. The message will include the optional payload if provided.
// If the handshake is completed by the call, two CipherStates will be returned,
// one is used for encryption of messages to the remote peer, the other is used
// for decryption of messages from the remote peer. It is an error to call this
// method out of sync with the handshake pattern.
2022-12-14 12:10:23 -04:00
func ( s * HandshakeState ) WriteMessageAndGetPK ( out [ ] byte , outPK [ ] [ ] byte , payload [ ] byte , extraAd [ ] byte ) ( [ ] byte , [ ] [ ] byte , * CipherState , * CipherState , error ) {
2022-06-26 09:01:10 -04:00
if ! s . shouldWrite {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , errors . New ( "noise: unexpected call to WriteMessage should be ReadMessage" )
2022-06-26 09:01:10 -04:00
}
if s . msgIdx > len ( s . messagePatterns ) - 1 {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , errors . New ( "noise: no handshake messages left" )
2022-06-26 09:01:10 -04:00
}
if len ( payload ) > MaxMsgLen {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , errors . New ( "noise: message is too long" )
2022-06-26 09:01:10 -04:00
}
var err error
for _ , msg := range s . messagePatterns [ s . msgIdx ] {
switch msg {
case MessagePatternE :
e , err := s . ss . cs . GenerateKeypair ( s . rng )
if err != nil {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , err
2022-06-26 09:01:10 -04:00
}
s . e = e
out = append ( out , s . e . Public ... )
2022-10-23 09:01:24 -04:00
outPK = append ( outPK , s . e . Public )
2022-06-26 09:01:10 -04:00
s . ss . MixHash ( s . e . Public )
if len ( s . psk ) > 0 {
s . ss . MixKey ( s . e . Public )
}
case MessagePatternS :
if len ( s . s . Public ) == 0 {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , errors . New ( "noise: invalid state, s.Public is nil" )
2022-06-26 09:01:10 -04:00
}
out , err = s . ss . EncryptAndHash ( out , s . s . Public )
2022-10-23 09:01:24 -04:00
outPK = append ( outPK , out )
2022-06-26 09:01:10 -04:00
if err != nil {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , err
2022-06-26 09:01:10 -04:00
}
2022-10-23 09:01:24 -04:00
2022-06-26 09:01:10 -04:00
case MessagePatternDHEE :
dh , err := s . ss . cs . DH ( s . e . Private , s . re )
if err != nil {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , err
2022-06-26 09:01:10 -04:00
}
s . ss . MixKey ( dh )
case MessagePatternDHES :
if s . initiator {
dh , err := s . ss . cs . DH ( s . e . Private , s . rs )
if err != nil {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , err
2021-04-22 13:00:17 -04:00
}
s . ss . MixKey ( dh )
2017-09-28 00:37:07 +01:00
} else {
2021-04-22 13:00:17 -04:00
dh , err := s . ss . cs . DH ( s . s . Private , s . re )
if err != nil {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , err
2021-04-22 13:00:17 -04:00
}
s . ss . MixKey ( dh )
2017-09-28 00:37:07 +01:00
}
2015-11-15 12:49:59 -05:00
case MessagePatternDHSE :
2017-09-28 00:37:07 +01:00
if s . initiator {
2021-04-22 13:00:17 -04:00
dh , err := s . ss . cs . DH ( s . s . Private , s . re )
if err != nil {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , err
2021-04-22 13:00:17 -04:00
}
s . ss . MixKey ( dh )
2017-09-28 00:37:07 +01:00
} else {
2021-04-22 13:00:17 -04:00
dh , err := s . ss . cs . DH ( s . e . Private , s . rs )
if err != nil {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , err
2021-04-22 13:00:17 -04:00
}
s . ss . MixKey ( dh )
2017-09-28 00:37:07 +01:00
}
2015-11-15 12:49:59 -05:00
case MessagePatternDHSS :
2021-04-22 13:00:17 -04:00
dh , err := s . ss . cs . DH ( s . s . Private , s . rs )
if err != nil {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , err
2021-04-22 13:00:17 -04:00
}
s . ss . MixKey ( dh )
2017-05-11 15:56:03 +02:00
case MessagePatternPSK :
s . ss . MixKeyAndHash ( s . psk )
2015-11-15 12:49:59 -05:00
}
}
s . shouldWrite = false
s . msgIdx ++
2022-12-14 12:10:23 -04:00
out , err = s . ss . EncryptAndHash ( out , payload , extraAd ... )
2021-04-20 16:35:37 -04:00
if err != nil {
2022-10-23 09:01:24 -04:00
return nil , nil , nil , nil , err
2021-04-20 16:35:37 -04:00
}
2015-11-15 12:49:59 -05:00
if s . msgIdx >= len ( s . messagePatterns ) {
2016-07-12 21:25:40 -04:00
cs1 , cs2 := s . ss . Split ( )
2022-10-23 09:01:24 -04:00
return out , outPK , cs1 , cs2 , nil
2015-11-15 12:49:59 -05:00
}
2022-10-23 09:01:24 -04:00
return out , outPK , nil , nil , nil
2015-11-15 12:49:59 -05:00
}
2022-12-14 12:10:23 -04:00
func ( s * HandshakeState ) Hash ( ) hash . Hash {
return s . ss . cs . Hash ( )
}
2016-07-12 22:20:06 -04:00
// ErrShortMessage is returned by ReadMessage if a message is not as long as it should be.
2015-11-15 12:49:59 -05:00
var ErrShortMessage = errors . New ( "noise: message is too short" )
2016-07-12 22:20:06 -04:00
// ReadMessage processes a received handshake message and appends the payload,
// if any to out. If the handshake is completed by the call, two CipherStates
// will be returned, one is used for encryption of messages to the remote peer,
// the other is used for decryption of messages from the remote peer. It is an
// error to call this method out of sync with the handshake pattern.
2022-12-14 12:10:23 -04:00
func ( s * HandshakeState ) ReadMessage ( out , message [ ] byte , extraAd ... byte ) ( [ ] byte , * CipherState , * CipherState , error ) {
2015-11-15 12:49:59 -05:00
if s . shouldWrite {
2018-01-09 20:48:36 -06:00
return nil , nil , nil , errors . New ( "noise: unexpected call to ReadMessage should be WriteMessage" )
2015-11-15 12:49:59 -05:00
}
if s . msgIdx > len ( s . messagePatterns ) - 1 {
2018-01-09 20:48:36 -06:00
return nil , nil , nil , errors . New ( "noise: no handshake messages left" )
2015-11-15 12:49:59 -05:00
}
2021-03-24 20:23:37 -05:00
rsSet := false
2016-07-14 21:27:05 -04:00
s . ss . Checkpoint ( )
2015-11-15 12:49:59 -05:00
var err error
for _ , msg := range s . messagePatterns [ s . msgIdx ] {
switch msg {
case MessagePatternE , MessagePatternS :
2016-07-12 21:25:40 -04:00
expected := s . ss . cs . DHLen ( )
if msg == MessagePatternS && s . ss . hasK {
2015-11-15 12:49:59 -05:00
expected += 16
}
if len ( message ) < expected {
return nil , nil , nil , ErrShortMessage
}
switch msg {
case MessagePatternE :
2016-07-12 21:25:40 -04:00
if cap ( s . re ) < s . ss . cs . DHLen ( ) {
s . re = make ( [ ] byte , s . ss . cs . DHLen ( ) )
2015-11-15 17:18:33 -05:00
}
2016-07-12 21:25:40 -04:00
s . re = s . re [ : s . ss . cs . DHLen ( ) ]
2015-11-15 17:18:33 -05:00
copy ( s . re , message )
2016-07-12 21:25:40 -04:00
s . ss . MixHash ( s . re )
2017-05-11 15:56:03 +02:00
if len ( s . psk ) > 0 {
2016-07-12 21:25:40 -04:00
s . ss . MixKey ( s . re )
2015-11-15 17:18:33 -05:00
}
2015-11-15 12:49:59 -05:00
case MessagePatternS :
2015-11-15 12:56:24 -05:00
if len ( s . rs ) > 0 {
2018-01-09 20:48:36 -06:00
return nil , nil , nil , errors . New ( "noise: invalid state, rs is not nil" )
2015-11-15 12:56:24 -05:00
}
2016-07-12 21:25:40 -04:00
s . rs , err = s . ss . DecryptAndHash ( s . rs [ : 0 ] , message [ : expected ] )
2021-03-24 20:23:37 -05:00
rsSet = true
2015-11-15 12:49:59 -05:00
}
if err != nil {
2016-07-14 21:27:05 -04:00
s . ss . Rollback ( )
2021-03-24 20:23:37 -05:00
if rsSet {
s . rs = nil
}
2015-11-15 12:49:59 -05:00
return nil , nil , nil , err
}
message = message [ expected : ]
case MessagePatternDHEE :
2021-04-22 13:00:17 -04:00
dh , err := s . ss . cs . DH ( s . e . Private , s . re )
if err != nil {
return nil , nil , nil , err
}
s . ss . MixKey ( dh )
2015-11-15 12:49:59 -05:00
case MessagePatternDHES :
2017-09-28 00:37:07 +01:00
if s . initiator {
2021-04-22 13:00:17 -04:00
dh , err := s . ss . cs . DH ( s . e . Private , s . rs )
if err != nil {
return nil , nil , nil , err
}
s . ss . MixKey ( dh )
2017-09-28 00:37:07 +01:00
} else {
2021-04-22 13:00:17 -04:00
dh , err := s . ss . cs . DH ( s . s . Private , s . re )
if err != nil {
return nil , nil , nil , err
}
s . ss . MixKey ( dh )
2017-09-28 00:37:07 +01:00
}
2015-11-15 12:49:59 -05:00
case MessagePatternDHSE :
2017-09-28 00:37:07 +01:00
if s . initiator {
2021-04-22 13:00:17 -04:00
dh , err := s . ss . cs . DH ( s . s . Private , s . re )
if err != nil {
return nil , nil , nil , err
}
s . ss . MixKey ( dh )
2017-09-28 00:37:07 +01:00
} else {
2021-04-22 13:00:17 -04:00
dh , err := s . ss . cs . DH ( s . e . Private , s . rs )
if err != nil {
return nil , nil , nil , err
}
s . ss . MixKey ( dh )
2017-09-28 00:37:07 +01:00
}
2015-11-15 12:49:59 -05:00
case MessagePatternDHSS :
2021-04-22 13:00:17 -04:00
dh , err := s . ss . cs . DH ( s . s . Private , s . rs )
if err != nil {
return nil , nil , nil , err
}
s . ss . MixKey ( dh )
2017-05-11 15:56:03 +02:00
case MessagePatternPSK :
s . ss . MixKeyAndHash ( s . psk )
2015-11-15 12:49:59 -05:00
}
}
2022-12-14 12:10:23 -04:00
out , err = s . ss . DecryptAndHash ( out , message , extraAd ... )
2015-11-15 12:49:59 -05:00
if err != nil {
2016-07-14 21:27:05 -04:00
s . ss . Rollback ( )
2021-03-24 20:23:37 -05:00
if rsSet {
s . rs = nil
}
2015-11-15 12:49:59 -05:00
return nil , nil , nil , err
}
2016-07-14 21:27:05 -04:00
s . shouldWrite = true
s . msgIdx ++
2015-11-15 12:49:59 -05:00
if s . msgIdx >= len ( s . messagePatterns ) {
2016-07-12 21:25:40 -04:00
cs1 , cs2 := s . ss . Split ( )
2015-11-15 12:49:59 -05:00
return out , cs1 , cs2 , nil
}
return out , nil , nil , nil
}
2016-07-13 15:28:03 -04:00
// ChannelBinding provides a value that uniquely identifies the session and can
// be used as a channel binding. It is an error to call this method before the
// handshake is complete.
func ( s * HandshakeState ) ChannelBinding ( ) [ ] byte {
return s . ss . h
}
2016-07-13 19:53:24 -04:00
// PeerStatic returns the static key provided by the remote peer during
// a handshake. It is an error to call this method if a handshake message
// containing a static key has not been read.
func ( s * HandshakeState ) PeerStatic ( ) [ ] byte {
return s . rs
}
2018-03-08 12:40:28 -08:00
// MessageIndex returns the current handshake message id
func ( s * HandshakeState ) MessageIndex ( ) int {
return s . msgIdx
}
2018-03-26 14:13:16 -07:00
// PeerEphemeral returns the ephemeral key provided by the remote peer during
// a handshake. It is an error to call this method if a handshake message
// containing a static key has not been read.
func ( s * HandshakeState ) PeerEphemeral ( ) [ ] byte {
return s . re
}
// LocalEphemeral returns the local ephemeral key pair generated during
// a handshake.
func ( s * HandshakeState ) LocalEphemeral ( ) DHKey {
return s . e
}