Skip to content

Commit

Permalink
Update some things
Browse files Browse the repository at this point in the history
  • Loading branch information
awnumar committed May 20, 2020
1 parent 126bbdd commit acb56a4
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 30 deletions.
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
<p align="center">
<img src="https://cdn.rawgit.com/awnumar/memguard/master/logo.svg" height="140" />
<h3 align="center">MemGuard</h3>
<p align="center">Secure software enclave for storage of sensitive information in memory.</p>
<p align="center">Software enclave for storage of sensitive information in memory.</p>
<p align="center">
<a href="https://cirrus-ci.com/github/awnumar/memguard"><img src="https://api.cirrus-ci.com/github/awnumar/memguard.svg"></a>
<a href="https://www.codacy.com/app/awnumar/memguard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=awnumar/memguard&amp;utm_campaign=Badge_Grade"><img src="https://api.codacy.com/project/badge/Grade/eebb7ecd6e794890999cfcf26328e9cb"/></a>
<a href="https://pkg.go.dev/github.com/awnumar/memguard?tab=doc"><img src="https://godoc.org/github.com/awnumar/memguard?status.svg"></a>
</p>
</p>

---

This package attempts to reduce the likelihood of sensitive data being exposed. It supports all major operating systems and is written in pure Go.
This package attempts to reduce the likelihood of sensitive data being exposed when in memory. It aims to support all major operating systems and is written in pure Go.

## Features

* Sensitive data is encrypted and authenticated in memory using xSalsa20 and Poly1305 respectively. The scheme also defends against cold-boot attacks.
* Memory allocation bypasses the language runtime by using system calls to query the kernel for resources directly. This avoids interference from the garbage-collector.
* Sensitive data is encrypted and authenticated in memory with XSalsa20Poly1305. The [scheme](https://spacetime.dev/encrypting-secrets-in-memory) used also [defends against cold-boot attacks](https://spacetime.dev/memory-retention-attacks).
* Memory allocation bypasses the language runtime by [using system calls](https://github.com/awnumar/memcall) to query the kernel for resources directly. This avoids interference from the garbage-collector.
* Buffers that store plaintext data are fortified with guard pages and canary values to detect spurious accesses and overflows.
* Effort is taken to prevent sensitive data from touching the disk. This includes locking memory to prevent swapping and handling core dumps.
* Kernel-level immutability is implemented so that attempted modification of protected regions results in an access violation.
Expand Down
5 changes: 5 additions & 0 deletions core/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package core

import (
"errors"
"fmt"
"sync"

"github.com/awnumar/memcall"
Expand Down Expand Up @@ -269,6 +270,8 @@ func (l *bufferList) add(b ...*Buffer) {
l.Lock()
defer l.Unlock()

fmt.Printf("\n\nThere are %d buffers\n\n\n", len(buffers.list))

l.list = append(l.list, b...)
}

Expand All @@ -288,6 +291,8 @@ func (l *bufferList) remove(b *Buffer) {
l.Lock()
defer l.Unlock()

fmt.Printf("\n\nThere are %d buffers\n\n\n", len(buffers.list))

for i, v := range l.list {
if v == b {
l.list = append(l.list[:i], l.list[i+1:]...)
Expand Down
51 changes: 40 additions & 11 deletions core/coffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package core

import (
"errors"
"fmt"
"sync"
"time"
)
Expand Down Expand Up @@ -94,25 +95,39 @@ func (s *Coffer) initialise() error {
View returns a snapshot of the contents of a Coffer inside a Buffer. As usual the Buffer should be destroyed as soon as possible after use by calling the Destroy method.
*/
func (s *Coffer) View() (*Buffer, error) {
fmt.Printf("\n\nThere are %d buffers\n\n\n", len(buffers.list))

// Check if it's destroyed.
if s.Destroyed() {
return nil, ErrCofferExpired
}
fmt.Printf("\n\n%s\n\n\n", "s is not destroyed")

// Create a new Buffer for the data.
b, _ := NewBuffer(32)

fmt.Printf("\n\n%s\n\n\n", "made buffer")

// Attain a read-only lock.
s.RLock()
defer s.RUnlock()

fmt.Printf("\n\n%s\n\n\n", "got lock")

fmt.Println(s.right.Data(), s.left.Data())

// data = hash(right) XOR left
h := Hash(s.right.Data())

fmt.Printf("\n\n%s\n\n\n", "got hash")
for i := range b.Data() {
b.Data()[i] = h[i] ^ s.left.Data()[i]
}
fmt.Printf("\n\n%s\n\n\n", "computed plaintext")
Wipe(h)

fmt.Printf("\n\n%s\n\n\n", "got data")

// Return the view.
return b, nil
}
Expand Down Expand Up @@ -175,27 +190,41 @@ func (s *Coffer) destroy() error {
defer s.Unlock()

// Destroy the partitions.
if err := s.left.destroy(); err != nil {
return err
err1 := s.left.destroy()
if err1 == nil {
buffers.remove(s.left)
}
buffers.remove(s.rand)

if err := s.right.destroy(); err != nil {
return err
err2 := s.right.destroy()
if err2 == nil {
buffers.remove(s.right)
}
buffers.remove(s.rand)

if err := s.rand.destroy(); err != nil {
return err
err3 := s.rand.destroy()
if err3 == nil {
buffers.remove(s.rand)
}
buffers.remove(s.rand)
return nil

errS := ""
if err1 != nil {
errS = errS + err1.Error() + "\n"
}
if err2 != nil {
errS = errS + err2.Error() + "\n"
}
if err3 != nil {
errS = errS + err3.Error() + "\n"
}
if errS == "" {
return nil
}
return errors.New(errS)
}

// Destroyed returns a boolean value indicating if a Coffer has been destroyed.
func (s *Coffer) Destroyed() bool {
s.RLock()
defer s.RUnlock()

return (!s.left.Alive()) && (!s.right.Alive())
return s.left.data == nil || s.right.data == nil
}
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ You own your intellectual property and so you are free to choose any licence for
1. [`Apache-2.0`] [casting](casting) :: Some examples of representing the data in allocated buffers as different types.
2. [`Apache-2.0`] [stdin](stdin) :: Reading from standard input directly into a guarded memory region and then sealing it.
3. [`Apache-2.0`] [stream](stream) :: Some examples of working with Stream objects which encrypt data in memory.
4. [[`#132`](https://github.com/awnumar/memguard/issues/132)] [deadlock](deadlock) :: Some conditions causing crashes.
5. [`Apache-2.0`] [streams](streams) :: Multi-threaded test of streams objects.
Binary file added examples/deadlock/deadlock.test
Binary file not shown.
File renamed without changes.
31 changes: 17 additions & 14 deletions examples/unsound/poc_test.go → examples/deadlock/poc_test.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
package unsound

import (
"context"
"os"
"os/signal"
"syscall"
"testing"
"time"
)

const duration = 30 * time.Second

// uncomment to run
//
// func TestPanicsPoC(t *testing.T) {
// sigs := make(chan os.Signal, 1)
// signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
func TestPanicsPoC(t *testing.T) {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

// ctx, cancel := context.WithTimeout(context.Background(), duration)
// go func() {
// select {
// case <-sigs:
// cancel()
// }
// }()
// OpenEnclave(ctx)
// }
ctx, cancel := context.WithTimeout(context.Background(), duration)
go func() {
select {
case <-sigs:
cancel()
}
}()
OpenEnclave(ctx)
}

// #############

Expand Down
6 changes: 6 additions & 0 deletions examples/streams/streams.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package streams

// MakeStreams ...
func MakeStreams() {
//concurrent stream access over multiple streams test
}

0 comments on commit acb56a4

Please sign in to comment.