From 7c316b9194317d950a55d56e0534eed6f986ff65 Mon Sep 17 00:00:00 2001 From: nsa Date: Thu, 30 Jan 2020 13:34:49 -0500 Subject: [PATCH 1/6] brontide: add SetCurveToNil function --- brontide/noise.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/brontide/noise.go b/brontide/noise.go index 7d5f42d4..16263e5f 100644 --- a/brontide/noise.go +++ b/brontide/noise.go @@ -871,3 +871,23 @@ func (b *Machine) ReadBody(r io.Reader, buf []byte) ([]byte, error) { // TODO(roasbeef): modify to let pass in slice return b.recvCipher.Decrypt(nil, nil, buf) } + +// SetCurveToNil sets the 'Curve' parameter to nil on the handshakeState keys. +// This allows us to log the Machine object without spammy log messages. +func (b *Machine) SetCurveToNil() { + if b.localStatic != nil { + b.localStatic.Curve = nil + } + + if b.localEphemeral != nil { + b.localEphemeral.Curve = nil + } + + if b.remoteStatic != nil { + b.remoteStatic.Curve = nil + } + + if b.remoteEphemeral != nil { + b.remoteEphemeral.Curve = nil + } +} From 511fdb2520d865841546f624e1ff7a1d370375ac Mon Sep 17 00:00:00 2001 From: nsa Date: Thu, 30 Jan 2020 13:35:27 -0500 Subject: [PATCH 2/6] fuzz/brontide: add fuzzing helper utilities --- fuzz/brontide/fuzz_utils.go | 137 ++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 fuzz/brontide/fuzz_utils.go diff --git a/fuzz/brontide/fuzz_utils.go b/fuzz/brontide/fuzz_utils.go new file mode 100644 index 00000000..48388dc0 --- /dev/null +++ b/fuzz/brontide/fuzz_utils.go @@ -0,0 +1,137 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "encoding/hex" + "fmt" + + "github.com/btcsuite/btcd/btcec" + "github.com/davecgh/go-spew/spew" + "github.com/lightningnetwork/lnd/brontide" +) + +var ( + initBytes = []byte{ + 0x81, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda, + 0x63, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17, + 0xd, 0xe7, 0x95, 0xe4, 0xb7, 0x25, 0xb8, 0x4d, + 0x1e, 0xb, 0x4c, 0xfd, 0x9e, 0xc5, 0x8c, 0xe9, + } + + respBytes = []byte{ + 0xaa, 0xb6, 0x37, 0xd9, 0xfc, 0xd2, 0xc6, 0xda, + 0x63, 0x59, 0xe6, 0x99, 0x31, 0x13, 0xa1, 0x17, + 0xd, 0xe7, 0x95, 0xe9, 0xb7, 0x25, 0xb8, 0x4d, + 0x1e, 0xb, 0x4c, 0xf9, 0x9e, 0xc5, 0x8c, 0xe9, + } + + // Returns the initiator's ephemeral private key. + initEphemeral = brontide.EphemeralGenerator(func() (*btcec.PrivateKey, error) { + e := "121212121212121212121212121212121212121212121212121212" + + "1212121212" + eBytes, err := hex.DecodeString(e) + if err != nil { + return nil, err + } + + priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), eBytes) + return priv, nil + }) + + // Returns the responder's ephemeral private key. + respEphemeral = brontide.EphemeralGenerator(func() (*btcec.PrivateKey, error) { + e := "222222222222222222222222222222222222222222222222222" + + "2222222222222" + eBytes, err := hex.DecodeString(e) + if err != nil { + return nil, err + } + + priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), eBytes) + return priv, nil + }) +) + +// completeHandshake takes two brontide machines (initiator, responder) +// and completes the brontide handshake between them. If any part of the +// handshake fails, this function will panic. +func completeHandshake(initiator, responder *brontide.Machine) { + if err := handshake(initiator, responder); err != nil { + nilAndPanic(initiator, responder, err) + } +} + +// handshake actually completes the brontide handshake and bubbles up +// an error to the calling function. +func handshake(initiator, responder *brontide.Machine) error { + // Generate ActOne and send to the responder. + actOne, err := initiator.GenActOne() + if err != nil { + return err + } + + if err := responder.RecvActOne(actOne); err != nil { + return err + } + + // Generate ActTwo and send to initiator. + actTwo, err := responder.GenActTwo() + if err != nil { + return err + } + + if err := initiator.RecvActTwo(actTwo); err != nil { + return err + } + + // Generate ActThree and send to responder. + actThree, err := initiator.GenActThree() + if err != nil { + return err + } + + return responder.RecvActThree(actThree) +} + +// nilAndPanic first nils the initiator and responder's Curve fields and then +// panics. +func nilAndPanic(initiator, responder *brontide.Machine, err error) { + if initiator != nil { + initiator.SetCurveToNil() + } + if responder != nil { + responder.SetCurveToNil() + } + panic(fmt.Errorf("error: %v, initiator: %v, responder: %v", err, + spew.Sdump(initiator), spew.Sdump(responder))) +} + +// getBrontideMachines returns two brontide machines that use random keys +// everywhere. +func getBrontideMachines() (*brontide.Machine, *brontide.Machine) { + initPriv, _ := btcec.NewPrivateKey(btcec.S256()) + respPriv, _ := btcec.NewPrivateKey(btcec.S256()) + respPub := (*btcec.PublicKey)(&respPriv.PublicKey) + + initiator := brontide.NewBrontideMachine(true, initPriv, respPub) + responder := brontide.NewBrontideMachine(false, respPriv, nil) + + return initiator, responder +} + +// getStaticBrontideMachines returns two brontide machines that use static keys +// everywhere. +func getStaticBrontideMachines() (*brontide.Machine, *brontide.Machine) { + initPriv, _ := btcec.PrivKeyFromBytes(btcec.S256(), initBytes) + respPriv, respPub := btcec.PrivKeyFromBytes(btcec.S256(), respBytes) + + initiator := brontide.NewBrontideMachine( + true, initPriv, respPub, initEphemeral, + ) + responder := brontide.NewBrontideMachine( + false, respPriv, nil, respEphemeral, + ) + + return initiator, responder +} From 116c5469bc2a51919dcac2d639f14b228641ac73 Mon Sep 17 00:00:00 2001 From: nsa Date: Thu, 30 Jan 2020 13:40:01 -0500 Subject: [PATCH 3/6] fuzz/brontide: random+static harnesses for acts 1-3 --- fuzz/brontide/random_actone.go | 30 +++++++++++++++++++ fuzz/brontide/random_actthree.go | 50 ++++++++++++++++++++++++++++++++ fuzz/brontide/random_acttwo.go | 39 +++++++++++++++++++++++++ fuzz/brontide/static_actone.go | 30 +++++++++++++++++++ fuzz/brontide/static_actthree.go | 50 ++++++++++++++++++++++++++++++++ fuzz/brontide/static_acttwo.go | 39 +++++++++++++++++++++++++ 6 files changed, 238 insertions(+) create mode 100644 fuzz/brontide/random_actone.go create mode 100644 fuzz/brontide/random_actthree.go create mode 100644 fuzz/brontide/random_acttwo.go create mode 100644 fuzz/brontide/static_actone.go create mode 100644 fuzz/brontide/static_actthree.go create mode 100644 fuzz/brontide/static_acttwo.go diff --git a/fuzz/brontide/random_actone.go b/fuzz/brontide/random_actone.go new file mode 100644 index 00000000..259d7d6a --- /dev/null +++ b/fuzz/brontide/random_actone.go @@ -0,0 +1,30 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "github.com/lightningnetwork/lnd/brontide" +) + +// Fuzz_random_actone is a go-fuzz harness for ActOne in the brontide +// handshake. +func Fuzz_random_actone(data []byte) int { + // Check if data is large enough. + if len(data) < brontide.ActOneSize { + return -1 + } + + // This will return brontide machines with random keys. + _, responder := getBrontideMachines() + + // Copy data into [ActOneSize]byte. + var actOne [brontide.ActOneSize]byte + copy(actOne[:], data) + + // Responder receives ActOne, should fail on the MAC check. + if err := responder.RecvActOne(actOne); err == nil { + nilAndPanic(nil, responder, nil) + } + + return 1 +} diff --git a/fuzz/brontide/random_actthree.go b/fuzz/brontide/random_actthree.go new file mode 100644 index 00000000..38a3847f --- /dev/null +++ b/fuzz/brontide/random_actthree.go @@ -0,0 +1,50 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "github.com/lightningnetwork/lnd/brontide" +) + +// Fuzz_random_actthree is a go-fuzz harness for ActThree in the brontide +// handshake. +func Fuzz_random_actthree(data []byte) int { + // Check if data is large enough. + if len(data) < brontide.ActThreeSize { + return -1 + } + + // This will return brontide machines with random keys. + initiator, responder := getBrontideMachines() + + // Generate ActOne and send to the responder. + actOne, err := initiator.GenActOne() + if err != nil { + nilAndPanic(initiator, responder, err) + } + + // Receiving ActOne should succeed, so we panic on error. + if err := responder.RecvActOne(actOne); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Generate ActTwo - this is not sent to the initiator because nothing is + // done with the initiator after this point and it would slow down fuzzing. + // GenActTwo needs to be called to set the appropriate state in the + // responder machine. + _, err = responder.GenActTwo() + if err != nil { + nilAndPanic(initiator, responder, err) + } + + // Copy data into [ActThreeSize]byte. + var actThree [brontide.ActThreeSize]byte + copy(actThree[:], data) + + // Responder receives ActThree, should fail on the MAC check. + if err := responder.RecvActThree(actThree); err == nil { + nilAndPanic(initiator, responder, nil) + } + + return 1 +} diff --git a/fuzz/brontide/random_acttwo.go b/fuzz/brontide/random_acttwo.go new file mode 100644 index 00000000..1cda2f93 --- /dev/null +++ b/fuzz/brontide/random_acttwo.go @@ -0,0 +1,39 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "github.com/lightningnetwork/lnd/brontide" +) + +// Fuzz_random_acttwo is a go-fuzz harness for ActTwo in the brontide +// handshake. +func Fuzz_random_acttwo(data []byte) int { + // Check if data is large enough. + if len(data) < brontide.ActTwoSize { + return -1 + } + + // This will return brontide machines with random keys. + initiator, _ := getBrontideMachines() + + // Generate ActOne - this isn't sent to the responder because nothing is + // done with the responder machine and this would slow down fuzzing. + // GenActOne needs to be called to set the appropriate state in the + // initiator machine. + _, err := initiator.GenActOne() + if err != nil { + nilAndPanic(initiator, nil, err) + } + + // Copy data into [ActTwoSize]byte. + var actTwo [brontide.ActTwoSize]byte + copy(actTwo[:], data) + + // Initiator receives ActTwo, should fail. + if err := initiator.RecvActTwo(actTwo); err == nil { + nilAndPanic(initiator, nil, nil) + } + + return 1 +} diff --git a/fuzz/brontide/static_actone.go b/fuzz/brontide/static_actone.go new file mode 100644 index 00000000..7c351680 --- /dev/null +++ b/fuzz/brontide/static_actone.go @@ -0,0 +1,30 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "github.com/lightningnetwork/lnd/brontide" +) + +// Fuzz_static_actone is a go-fuzz harness for ActOne in the brontide +// handshake. +func Fuzz_static_actone(data []byte) int { + // Check if data is large enough. + if len(data) < brontide.ActOneSize { + return -1 + } + + // This will return brontide machines with static keys. + _, responder := getStaticBrontideMachines() + + // Copy data into [ActOneSize]byte. + var actOne [brontide.ActOneSize]byte + copy(actOne[:], data) + + // Responder receives ActOne, should fail. + if err := responder.RecvActOne(actOne); err == nil { + nilAndPanic(nil, responder, nil) + } + + return 1 +} diff --git a/fuzz/brontide/static_actthree.go b/fuzz/brontide/static_actthree.go new file mode 100644 index 00000000..3f4878bf --- /dev/null +++ b/fuzz/brontide/static_actthree.go @@ -0,0 +1,50 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "github.com/lightningnetwork/lnd/brontide" +) + +// Fuzz_static_actthree is a go-fuzz harness for ActThree in the brontide +// handshake. +func Fuzz_static_actthree(data []byte) int { + // Check if data is large enough. + if len(data) < brontide.ActThreeSize { + return -1 + } + + // This will return brontide machines with static keys. + initiator, responder := getStaticBrontideMachines() + + // Generate ActOne and send to the responder. + actOne, err := initiator.GenActOne() + if err != nil { + nilAndPanic(initiator, responder, err) + } + + // Receiving ActOne should succeed, so we panic on error. + if err := responder.RecvActOne(actOne); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Generate ActTwo - this is not sent to the initiator because nothing is + // done with the initiator after this point and it would slow down fuzzing. + // GenActTwo needs to be called to set the appropriate state in the responder + // machine. + _, err = responder.GenActTwo() + if err != nil { + nilAndPanic(initiator, responder, err) + } + + // Copy data into [ActThreeSize]byte. + var actThree [brontide.ActThreeSize]byte + copy(actThree[:], data) + + // Responder receives ActThree, should fail. + if err := responder.RecvActThree(actThree); err == nil { + nilAndPanic(initiator, responder, nil) + } + + return 1 +} diff --git a/fuzz/brontide/static_acttwo.go b/fuzz/brontide/static_acttwo.go new file mode 100644 index 00000000..4a2b094f --- /dev/null +++ b/fuzz/brontide/static_acttwo.go @@ -0,0 +1,39 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "github.com/lightningnetwork/lnd/brontide" +) + +// Fuzz_static_acttwo is a go-fuzz harness for ActTwo in the brontide +// handshake. +func Fuzz_static_acttwo(data []byte) int { + // Check if data is large enough. + if len(data) < brontide.ActTwoSize { + return -1 + } + + // This will return brontide machines with static keys. + initiator, _ := getStaticBrontideMachines() + + // Generate ActOne - this isn't sent to the responder because nothing is + // done with the responder machine and this would slow down fuzzing. + // GenActOne needs to be called to set the appropriate state in the initiator + // machine. + _, err := initiator.GenActOne() + if err != nil { + nilAndPanic(initiator, nil, err) + } + + // Copy data into [ActTwoSize]byte. + var actTwo [brontide.ActTwoSize]byte + copy(actTwo[:], data) + + // Initiator receives ActTwo, should fail. + if err := initiator.RecvActTwo(actTwo); err == nil { + nilAndPanic(initiator, nil, nil) + } + + return 1 +} From 468e5c03e9290705167b4c3207f54ff1840e08fd Mon Sep 17 00:00:00 2001 From: nsa Date: Thu, 30 Jan 2020 13:41:46 -0500 Subject: [PATCH 4/6] fuzz/brontide: random+static decrypt harnesses --- fuzz/brontide/random_init_decrypt.go | 27 +++++++++++++++++++++++++++ fuzz/brontide/random_resp_decrypt.go | 27 +++++++++++++++++++++++++++ fuzz/brontide/static_init_decrypt.go | 27 +++++++++++++++++++++++++++ fuzz/brontide/static_resp_decrypt.go | 27 +++++++++++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 fuzz/brontide/random_init_decrypt.go create mode 100644 fuzz/brontide/random_resp_decrypt.go create mode 100644 fuzz/brontide/static_init_decrypt.go create mode 100644 fuzz/brontide/static_resp_decrypt.go diff --git a/fuzz/brontide/random_init_decrypt.go b/fuzz/brontide/random_init_decrypt.go new file mode 100644 index 00000000..3328a2b6 --- /dev/null +++ b/fuzz/brontide/random_init_decrypt.go @@ -0,0 +1,27 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" +) + +// Fuzz_random_init_decrypt is a go-fuzz harness that decrypts arbitrary data +// with the initiator. +func Fuzz_random_init_decrypt(data []byte) int { + // This will return brontide machines with random keys. + initiator, responder := getBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Decrypt the encrypted message using ReadMessage w/ initiator machine. + if _, err := initiator.ReadMessage(r); err == nil { + nilAndPanic(initiator, responder, nil) + } + + return 1 +} diff --git a/fuzz/brontide/random_resp_decrypt.go b/fuzz/brontide/random_resp_decrypt.go new file mode 100644 index 00000000..1ae40bd2 --- /dev/null +++ b/fuzz/brontide/random_resp_decrypt.go @@ -0,0 +1,27 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" +) + +// Fuzz_random_resp_decrypt is a go-fuzz harness that decrypts arbitrary data +// with the responder. +func Fuzz_random_resp_decrypt(data []byte) int { + // This will return brontide machines with random keys. + initiator, responder := getBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Decrypt the encrypted message using ReadMessage w/ responder machine. + if _, err := responder.ReadMessage(r); err == nil { + nilAndPanic(initiator, responder, nil) + } + + return 1 +} diff --git a/fuzz/brontide/static_init_decrypt.go b/fuzz/brontide/static_init_decrypt.go new file mode 100644 index 00000000..35525d20 --- /dev/null +++ b/fuzz/brontide/static_init_decrypt.go @@ -0,0 +1,27 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" +) + +// Fuzz_static_init_decrypt is a go-fuzz harness that decrypts arbitrary data +// with the initiator. +func Fuzz_static_init_decrypt(data []byte) int { + // This will return brontide machines with static keys. + initiator, responder := getStaticBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Decrypt the encrypted message using ReadMessage w/ initiator machine. + if _, err := initiator.ReadMessage(r); err == nil { + nilAndPanic(initiator, responder, nil) + } + + return 1 +} diff --git a/fuzz/brontide/static_resp_decrypt.go b/fuzz/brontide/static_resp_decrypt.go new file mode 100644 index 00000000..fee4500b --- /dev/null +++ b/fuzz/brontide/static_resp_decrypt.go @@ -0,0 +1,27 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" +) + +// Fuzz_static_resp_decrypt is a go-fuzz harness that decrypts arbitrary data +// with the responder. +func Fuzz_static_resp_decrypt(data []byte) int { + // This will return brontide machines with static keys. + initiator, responder := getStaticBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Decrypt the encrypted message using ReadMessage w/ responder machine. + if _, err := responder.ReadMessage(r); err == nil { + nilAndPanic(initiator, responder, nil) + } + + return 1 +} From 0be5660a2a6509a38db0d1c203f341e0737f1ec3 Mon Sep 17 00:00:00 2001 From: nsa Date: Thu, 30 Jan 2020 13:43:54 -0500 Subject: [PATCH 5/6] fuzz/brontide: random+static encrypt harnesses --- fuzz/brontide/random_init_encrypt.go | 37 ++++++++++++++++++++++++++++ fuzz/brontide/random_resp_encrypt.go | 37 ++++++++++++++++++++++++++++ fuzz/brontide/static_init_encrypt.go | 37 ++++++++++++++++++++++++++++ fuzz/brontide/static_resp_encrypt.go | 37 ++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+) create mode 100644 fuzz/brontide/random_init_encrypt.go create mode 100644 fuzz/brontide/random_resp_encrypt.go create mode 100644 fuzz/brontide/static_init_encrypt.go create mode 100644 fuzz/brontide/static_resp_encrypt.go diff --git a/fuzz/brontide/random_init_encrypt.go b/fuzz/brontide/random_init_encrypt.go new file mode 100644 index 00000000..c041429e --- /dev/null +++ b/fuzz/brontide/random_init_encrypt.go @@ -0,0 +1,37 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" + "math" +) + +// Fuzz_random_init_encrypt is a go-fuzz harness that encrypts arbitrary data +// with the initiator. +func Fuzz_random_init_encrypt(data []byte) int { + // Ensure that length of message is not greater than max allowed size. + if len(data) > math.MaxUint16 { + return 0 + } + + // This will return brontide machines with random keys. + initiator, responder := getBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + var b bytes.Buffer + + // Encrypt the message using WriteMessage w/ initiator machine. + if err := initiator.WriteMessage(data); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Flush the encrypted message w/ initiator machine. + if _, err := initiator.Flush(&b); err != nil { + nilAndPanic(initiator, responder, err) + } + + return 1 +} diff --git a/fuzz/brontide/random_resp_encrypt.go b/fuzz/brontide/random_resp_encrypt.go new file mode 100644 index 00000000..691bcff5 --- /dev/null +++ b/fuzz/brontide/random_resp_encrypt.go @@ -0,0 +1,37 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" + "math" +) + +// Fuzz_random_resp_encrypt is a go-fuzz harness that encrypts arbitrary data +// with the responder. +func Fuzz_random_resp_encrypt(data []byte) int { + // Ensure that length of message is not greater than max allowed size. + if len(data) > math.MaxUint16 { + return 0 + } + + // This will return brontide machines with random keys. + initiator, responder := getBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + var b bytes.Buffer + + // Encrypt the message using WriteMessage w/ responder machine. + if err := responder.WriteMessage(data); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Flush the encrypted message w/ responder machine. + if _, err := responder.Flush(&b); err != nil { + nilAndPanic(initiator, responder, err) + } + + return 1 +} diff --git a/fuzz/brontide/static_init_encrypt.go b/fuzz/brontide/static_init_encrypt.go new file mode 100644 index 00000000..96040e74 --- /dev/null +++ b/fuzz/brontide/static_init_encrypt.go @@ -0,0 +1,37 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" + "math" +) + +// Fuzz_static_init_encrypt is a go-fuzz harness that encrypts arbitrary data +// with the initiator. +func Fuzz_static_init_encrypt(data []byte) int { + // Ensure that length of message is not greater than max allowed size. + if len(data) > math.MaxUint16 { + return 0 + } + + // This will return brontide machines with static keys. + initiator, responder := getStaticBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + var b bytes.Buffer + + // Encrypt the message using WriteMessage w/ initiator machine. + if err := initiator.WriteMessage(data); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Flush the encrypted message w/ initiator machine. + if _, err := initiator.Flush(&b); err != nil { + nilAndPanic(initiator, responder, err) + } + + return 1 +} diff --git a/fuzz/brontide/static_resp_encrypt.go b/fuzz/brontide/static_resp_encrypt.go new file mode 100644 index 00000000..b97a0390 --- /dev/null +++ b/fuzz/brontide/static_resp_encrypt.go @@ -0,0 +1,37 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" + "math" +) + +// Fuzz_static_resp_encrypt is a go-fuzz harness that encrypts arbitrary data +// with the responder. +func Fuzz_static_resp_encrypt(data []byte) int { + // Ensure that length of message is not greater than max allowed size. + if len(data) > math.MaxUint16 { + return 0 + } + + // This will return brontide machines with static keys. + initiator, responder := getStaticBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + var b bytes.Buffer + + // Encrypt the message using WriteMessage w/ responder machine. + if err := responder.WriteMessage(data); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Flush the encrypted message w/ responder machine. + if _, err := responder.Flush(&b); err != nil { + nilAndPanic(initiator, responder, err) + } + + return 1 +} From 0d42da0cb3d4b16ba65b24972a9ebc48d08cf314 Mon Sep 17 00:00:00 2001 From: nsa Date: Thu, 30 Jan 2020 13:44:55 -0500 Subject: [PATCH 6/6] fuzz/brontide: random+static round-trip encrypt+decrypt harnesses --- fuzz/brontide/random_init_enc_dec.go | 48 +++++++++++++++++++++++++++ fuzz/brontide/random_resp_enc_dec.go | 48 +++++++++++++++++++++++++++ fuzz/brontide/static_init_enc_dec.go | 49 ++++++++++++++++++++++++++++ fuzz/brontide/static_resp_enc_dec.go | 48 +++++++++++++++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 fuzz/brontide/random_init_enc_dec.go create mode 100644 fuzz/brontide/random_resp_enc_dec.go create mode 100644 fuzz/brontide/static_init_enc_dec.go create mode 100644 fuzz/brontide/static_resp_enc_dec.go diff --git a/fuzz/brontide/random_init_enc_dec.go b/fuzz/brontide/random_init_enc_dec.go new file mode 100644 index 00000000..17f5583f --- /dev/null +++ b/fuzz/brontide/random_init_enc_dec.go @@ -0,0 +1,48 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" + "math" +) + +// Fuzz_random_init_enc_dec is a go-fuzz harness that tests round-trip +// encryption and decryption between the initiator and the responder. +func Fuzz_random_init_enc_dec(data []byte) int { + // Ensure that length of message is not greater than max allowed size. + if len(data) > math.MaxUint16 { + return 0 + } + + // This will return brontide machines with random keys. + initiator, responder := getBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + var b bytes.Buffer + + // Encrypt the message using WriteMessage w/ initiator machine. + if err := initiator.WriteMessage(data); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Flush the encrypted message w/ initiator machine. + if _, err := initiator.Flush(&b); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Decrypt the ciphertext using ReadMessage w/ responder machine. + plaintext, err := responder.ReadMessage(&b) + if err != nil { + nilAndPanic(initiator, responder, err) + } + + // Check that the decrypted message and the original message are equal. + if !bytes.Equal(data, plaintext) { + nilAndPanic(initiator, responder, nil) + } + + return 1 +} diff --git a/fuzz/brontide/random_resp_enc_dec.go b/fuzz/brontide/random_resp_enc_dec.go new file mode 100644 index 00000000..e2fad9a5 --- /dev/null +++ b/fuzz/brontide/random_resp_enc_dec.go @@ -0,0 +1,48 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" + "math" +) + +// Fuzz_random_resp_enc_dec is a go-fuzz harness that tests round-trip +// encryption and decryption between the responder and the initiator. +func Fuzz_random_resp_enc_dec(data []byte) int { + // Ensure that length of message is not greater than max allowed size. + if len(data) > math.MaxUint16 { + return 0 + } + + // This will return brontide machines with random keys. + initiator, responder := getBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + var b bytes.Buffer + + // Encrypt the message using WriteMessage w/ responder machine. + if err := responder.WriteMessage(data); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Flush the encrypted message w/ responder machine. + if _, err := responder.Flush(&b); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Decrypt the ciphertext using ReadMessage w/ initiator machine. + plaintext, err := initiator.ReadMessage(&b) + if err != nil { + nilAndPanic(initiator, responder, err) + } + + // Check that the decrypted message and the original message are equal. + if !bytes.Equal(data, plaintext) { + nilAndPanic(initiator, responder, nil) + } + + return 1 +} diff --git a/fuzz/brontide/static_init_enc_dec.go b/fuzz/brontide/static_init_enc_dec.go new file mode 100644 index 00000000..a333c3f4 --- /dev/null +++ b/fuzz/brontide/static_init_enc_dec.go @@ -0,0 +1,49 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" + "math" +) + +// Fuzz_static_init_enc_dec is a go-fuzz harness that tests round-trip +// encryption and decryption +// between the initiator and the responder. +func Fuzz_static_init_enc_dec(data []byte) int { + // Ensure that length of message is not greater than max allowed size. + if len(data) > math.MaxUint16 { + return 0 + } + + // This will return brontide machines with static keys. + initiator, responder := getStaticBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + var b bytes.Buffer + + // Encrypt the message using WriteMessage w/ initiator machine. + if err := initiator.WriteMessage(data); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Flush the encrypted message w/ initiator machine. + if _, err := initiator.Flush(&b); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Decrypt the ciphertext using ReadMessage w/ responder machine. + plaintext, err := responder.ReadMessage(&b) + if err != nil { + nilAndPanic(initiator, responder, err) + } + + // Check that the decrypted message and the original message are equal. + if !bytes.Equal(data, plaintext) { + nilAndPanic(initiator, responder, nil) + } + + return 1 +} diff --git a/fuzz/brontide/static_resp_enc_dec.go b/fuzz/brontide/static_resp_enc_dec.go new file mode 100644 index 00000000..b9a3ad39 --- /dev/null +++ b/fuzz/brontide/static_resp_enc_dec.go @@ -0,0 +1,48 @@ +// +build gofuzz + +package brontidefuzz + +import ( + "bytes" + "math" +) + +// Fuzz_static_resp_enc_dec is a go-fuzz harness that tests round-trip +// encryption and decryption between the responder and the initiator. +func Fuzz_static_resp_enc_dec(data []byte) int { + // Ensure that length of message is not greater than max allowed size. + if len(data) > math.MaxUint16 { + return 0 + } + + // This will return brontide machines with static keys. + initiator, responder := getStaticBrontideMachines() + + // Complete the brontide handshake. + completeHandshake(initiator, responder) + + var b bytes.Buffer + + // Encrypt the message using WriteMessage w/ responder machine. + if err := responder.WriteMessage(data); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Flush the encrypted message w/ responder machine. + if _, err := responder.Flush(&b); err != nil { + nilAndPanic(initiator, responder, err) + } + + // Decrypt the ciphertext using ReadMessage w/ initiator machine. + plaintext, err := initiator.ReadMessage(&b) + if err != nil { + nilAndPanic(initiator, responder, err) + } + + // Check that the decrypted message and the original message are equal. + if !bytes.Equal(data, plaintext) { + nilAndPanic(initiator, responder, nil) + } + + return 1 +}