securememory

package module
v0.0.0-...-dbb41f6 Latest Latest
Warning

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

Go to latest
Published: Feb 20, 2020 License: MIT Imports: 1 Imported by: 0

README

Secure Memory Go Edition

TODO Fill these in once we move to public repo

Build StatusCoverage Maintainability Quality Gate

This package provides a way for applications to keep secret information (like cryptographic keys) in an area of memory that is secure in the described ways.

Currently supported / tested platforms

  • MacOS x86-64
  • Linux x86-64

Guarantees

Any implementation must have the following guarantees in so far as secret information stored in secure memory

  • Values stored will not show up in core dumps
  • Values stored will not be swapped
  • Values stored will be securely / explicitly zeroed out when no longer in use

Protected Memory Implementation

The protected memory implementation of secure memory:

  • Uses mlock to lock the pages to prevent swapping
  • Uses mprotect to mark the pages no-access until needed
  • Uses setrlimit to disable core dumps entirely
Usage
package main

import (
    "fmt"
    
    "github.com/godaddy/asherah/languages/go/securememory"
    "github.com/godaddy/asherah/languages/go/securememory/protectedmemory"
)

func main() {
    factory := new(protectedmemory.SecretFactory)

    secret, err := factory.New(getSecretFromStore())
    if err != nil {
        panic("unexpected error!")
    }
    defer secret.Close()

    err = secret.WithBytes(func(b []byte) error {
        doSomethingWithSecretBytes(b)
        return nil
    })
    if err != nil {
        panic("unexpected error!")
    }
}

Memguard Implementation

The memguard-based implementation has identical guarantees as the protected memory implementation. It also makes use of guard pages and canary data to add further protections. Note the user of the guard pages will add an additional 2 pages of unmanaged memory being used per Secret (as of this writing).

In addition, we have included the no-access support that we have provided in our other language implementations.

The memguard based implementation:

  • Uses mlock to lock the pages to prevent swapping
  • Uses mprotect to mark the pages no-access until needed
  • Uses setrlimit to disable core dumps entirely
Usage
package main

import (
    "fmt"
    
    "github.com/godaddy/asherah/languages/go/securememory"
    "github.com/godaddy/asherah/languages/go/securememory/memguard"
)

func main() {
    factory := memguard.SecretFactory{}

    secret, err := factory.New(getSecretFromStore())
    if err != nil {
        panic("unexpected error!")
    }
    defer secret.Close()

    err = secret.WithBytes(func(b []byte) error {
        doSomethingWithSecretBytes(b)
        return nil
    })
    if err != nil {
        panic("unexpected error!")
    }
}

TODO

  • Add unit tests that generate core dumps and scan them for secrets (need to extract gcore source)
  • If the operating system supports it, uses madvise to request that mapped pages be zeroed on exit
  • If the operating system supports it, uses madvise to disable core dumps for the data region instead of globally

Documentation

Overview

This package provides a way for applications to keep secret information (like cryptographic keys) in an area of memory that is secure.

package main

import (
	"fmt"

	"github.com/godaddy/asherah/languages/go/securememory"
	"github.com/godaddy/asherah/languages/go/securememory/protectedmemory"
)

func main() {
	factory := protectedmemory.SecretFactory{}

	secret, err := factory.New(getSecretFromStore())
	if err != nil {
		panic("unexpected error!")
	}
	defer secret.Close()

	err = secret.WithBytes(func(b []byte) error {
		doSomethingWithSecretBytes(b)
		return nil
	})
	if err != nil {
		panic("unexpected error!")
	}
}

Index

Constants

This section is empty.

Variables

View Source
var (
	// AllocCounter is used to track secret allocations.
	// nolint - Needs to be global to track allocations
	AllocCounter = metrics.GetOrRegisterCounter("secret.allocated", nil)
)

Functions

This section is empty.

Types

type Secret

type Secret interface {
	// WithBytes makes the underlying bytes readable and passes them to the function provided.
	// A reference MUST not be kept to the bytes passed to the function as the underlying array will no
	// longer be readable after the function exits.
	WithBytes(action func([]byte) error) error
	// WithBytes makes the underlying bytes readable and passes them to the function provided.
	// A reference MUST not be kept to the bytes passed to the function as the underlying array will no
	// longer be readable after the function exits.
	WithBytesFunc(action func([]byte) ([]byte, error)) ([]byte, error)
	// IsClosed returns true if the underlying data container has already been closed.
	IsClosed() bool
	// Close closes the data container and frees any associated memory.
	Close() error
}

Secret contains sensitive memory and stores data in protected page(s) in memory. Always call close after use to avoid memory leaks.

type SecretFactory

type SecretFactory interface {
	// New takes in a byte slice and returns a Secret containing that data.
	New(b []byte) (Secret, error)
	// CreateRandom returns a Secret that contains a random byte slice of the specified size.
	CreateRandom(size int) (Secret, error)
}

SecretFactory is the interface for creating specific implementations of a Secret.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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