diff --git a/README.md b/README.md index afdbe94..38acc3e 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,20 @@ Should any of these properties _not_ be required, the user has to intentionally There is some more detail in [SPEC.md](./SPEC.md). +### Known Issues + +#### Secure Key Deletion + +Go currently does not provide functionality to securely handle sensitive data, such as key material, in memory. Thus, it cannot be guaranteed that key material is correctly wiped from memory and won't leak when swapping memory to disk. + +There is an [issue in the Golang project](https://github.com/golang/go/issues/21865) about this. + +We evaluated two existing workarounds for this: +1) Using `reflect` to dive into the internals of all algorithms to (possibly) delete key material. This is used in the Go implementation of Wireguard, for example. This still does not guarantee that Go internally deletes the key material. +2) Use of the [Go memguard package](https://github.com/awnumar/memguard). While this would improve handling of key material that we directly manage, it will still not solve protecting all the intermediate values used in the implementations of the algorithms. + +We currently settled on waiting for further progress on the issue by the Go development team, and will reevaluate the progress regularly. + ### Testing Basically, tests are run like this: diff --git a/core-wire.go b/core-wire.go index 453b579..ddfd285 100644 --- a/core-wire.go +++ b/core-wire.go @@ -418,7 +418,7 @@ func (w *WireSession) unwrapKeys(keyMaterial [][]byte) ([][]byte, error) { return keyMaterial, nil } -// burnEphemeralKeys burns all the ephemeral key material in the session. +// burnEphemeralKeys burns all the ephemeral key material in the session. This is currently ineffective, see known issues in the project's README. func (w *WireSession) burnEphemeralKeys() error { var lastErr error diff --git a/helper.go b/helper.go index 8356554..63ec8dd 100644 --- a/helper.go +++ b/helper.go @@ -70,7 +70,7 @@ func (h *Helper) RandomBytes(n int) ([]byte, error) { return RandomBytes(n) } -// Burn gets rid of the given []byte slice(s). +// Burn gets rid of the given []byte slice(s). This is currently ineffective, see known issues in the project's README. func (h *Helper) Burn(data ...[]byte) { Burn(data...) } @@ -99,7 +99,7 @@ func (h *Helper) MaxSecurityLevel() int { return defaultSecurityLevel } -// Burn gets rid of the given []byte slice(s). +// Burn gets rid of the given []byte slice(s). This is currently ineffective, see known issues in the project's README. func Burn(data ...[]byte) { for _, slice := range data { for i := 0; i < len(slice); i++ { diff --git a/signet.go b/signet.go index 423599a..f6724cb 100644 --- a/signet.go +++ b/signet.go @@ -224,7 +224,7 @@ func (signet *Signet) Verify() error { return errors.New("NIY") } -// Burn destroys all the key material and renders the Signet unusable. +// Burn destroys all the key material and renders the Signet unusable. This is currently ineffective, see known issues in the project's README. func (signet *Signet) Burn() error { // load tool err := signet.loadTool() diff --git a/tools/ecdh/nist.go b/tools/ecdh/nist.go index accd941..84c3550 100644 --- a/tools/ecdh/nist.go +++ b/tools/ecdh/nist.go @@ -147,7 +147,7 @@ func (ec *NistCurve) GenerateKey(signet tools.SignetInt) error { return nil } -// BurnKey implements the ToolLogic interface. +// BurnKey implements the ToolLogic interface. This is currently ineffective, see known issues in the project's README. func (ec *NistCurve) BurnKey(signet tools.SignetInt) error { pubKey := signet.PublicKey() privKey := signet.PrivateKey() diff --git a/tools/ecdh/x25519.go b/tools/ecdh/x25519.go index 7b799a4..e4090cc 100644 --- a/tools/ecdh/x25519.go +++ b/tools/ecdh/x25519.go @@ -115,7 +115,7 @@ func (ec *X25519Curve) GenerateKey(signet tools.SignetInt) error { return nil } -// BurnKey implements the ToolLogic interface. +// BurnKey implements the ToolLogic interface. This is currently ineffective, see known issues in the project's README. func (ec *X25519Curve) BurnKey(signet tools.SignetInt) error { pubKey := signet.PublicKey() privKey := signet.PrivateKey() diff --git a/tools/gostdlib/ed25519.go b/tools/gostdlib/ed25519.go index 163c7f8..d7b3e08 100644 --- a/tools/gostdlib/ed25519.go +++ b/tools/gostdlib/ed25519.go @@ -148,7 +148,7 @@ func (ed *Ed25519) GenerateKey(signet tools.SignetInt) error { return nil } -// BurnKey implements the ToolLogic interface. +// BurnKey implements the ToolLogic interface. This is currently ineffective, see known issues in the project's README. func (ed *Ed25519) BurnKey(signet tools.SignetInt) error { pubKey := signet.PublicKey() privKey := signet.PrivateKey() diff --git a/tools/gostdlib/rsa-keys.go b/tools/gostdlib/rsa-keys.go index 3e87645..03fc981 100644 --- a/tools/gostdlib/rsa-keys.go +++ b/tools/gostdlib/rsa-keys.go @@ -104,7 +104,7 @@ func (base *rsaBase) GenerateKey(signet tools.SignetInt) error { return nil } -// BurnKey implements the ToolLogic interface. +// BurnKey implements the ToolLogic interface. This is currently ineffective, see known issues in the project's README. func (base *rsaBase) BurnKey(signet tools.SignetInt) error { pubKey := signet.PublicKey() privKey := signet.PrivateKey() diff --git a/tools/interfaces.go b/tools/interfaces.go index 01c638c..8b7b5e8 100644 --- a/tools/interfaces.go +++ b/tools/interfaces.go @@ -22,7 +22,7 @@ type HelperInt interface { // RandomBytes returns the specified amount of random bytes in a []byte slice. RandomBytes(n int) ([]byte, error) - // Burn gets rid of the given []byte slice(s). + // Burn gets rid of the given []byte slice(s). This is currently ineffective, see known issues in the project's README. Burn(data ...[]byte) // DefaultSymmetricKeySize returns the default key size for this session. diff --git a/tools/toollogic.go b/tools/toollogic.go index 198b8b9..b93a564 100644 --- a/tools/toollogic.go +++ b/tools/toollogic.go @@ -119,6 +119,7 @@ type ToolLogic interface { // BurnKey deletes the loaded keys in the Signet. // Must work with a static (no Setup()) ToolLogic. // Must be overridden by tools that declare FeatureKeyExchange, FeatureKeyEncapsulation or FeatureSigning. + // Implementations of this are currently ineffective, see known issues in the project's README. BurnKey(signet SignetInt) error // SecurityLevel returns the security level (approximate attack complexity as 2^n) of the given tool. @@ -289,7 +290,7 @@ func (tlb *ToolLogicBase) GenerateKey(signet SignetInt) error { return ErrNotImplemented } -// BurnKey implements the ToolLogic interface. +// BurnKey implements the ToolLogic interface. This is currently ineffective, see known issues in the project's README. func (tlb *ToolLogicBase) BurnKey(signet SignetInt) error { return ErrNotImplemented }