-
Notifications
You must be signed in to change notification settings - Fork 125
/
docs.go
90 lines (66 loc) · 2.99 KB
/
docs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
Package memguard implements a secure software enclave for the storage of sensitive information in memory.
package main
import (
"fmt"
"os"
"github.com/awnumar/memguard"
)
func main() {
// Safely terminate in case of an interrupt signal
memguard.CatchInterrupt()
// Purge the session when we return
defer memguard.Purge()
// Generate a key sealed inside an encrypted container
key := memguard.NewEnclaveRandom(32)
// Passing the key off to another function
key = invert(key)
// Decrypt the result returned from invert
keyBuf, err := key.Open()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
defer keyBuf.Destroy()
// Um output it
fmt.Println(keyBuf.Bytes())
}
func invert(key *memguard.Enclave) *memguard.Enclave {
// Decrypt the key into a local copy
b, err := key.Open()
if err != nil {
memguard.SafePanic(err)
}
defer b.Destroy() // Destroy the copy when we return
// Open returns the data in an immutable buffer, so make it mutable
b.Melt()
// Set every element to its complement
for i := range b.Bytes() {
b.Bytes()[i] = ^b.Bytes()[i]
}
// Return the new data in encrypted form
return b.Seal() // <- sealing also destroys b
}
There are two main container objects exposed in this API. Enclave objects encrypt data and store the ciphertext whereas LockedBuffers are more like guarded memory allocations. There is a limit on the maximum number of LockedBuffer objects that can exist at any one time, imposed by the system's mlock limits. There is no limit on Enclaves.
The general workflow is to store sensitive information in Enclaves when it is not immediately needed and decrypt it when and where it is. After use, the LockedBuffer should be destroyed.
If you need access to the data inside a LockedBuffer in a type not covered by any methods provided by this API, you can type-cast the allocation's memory to whatever type you want.
key := memguard.NewBuffer(32)
keyArrayPtr := (*[32]byte)(unsafe.Pointer(&key.Bytes()[0])) // do not dereference
This is of course an unsafe operation and so care must be taken to ensure that the cast is valid and does not result in memory unsafety. Further examples of code and interesting use-cases can be found in the examples subpackage.
Several functions exist to make the mass purging of data very easy. It is recommended to make use of them when appropriate.
// Start an interrupt handler that will clean up memory before exiting
memguard.CatchInterrupt()
// Purge the session when returning from the main function of your program
defer memguard.Purge()
// Use the safe variants of exit functions provided in the stdlib
memguard.SafeExit(1)
memguard.SafePanic(err)
// Destroy LockedBuffers as soon as possible after using them
b, err := enclave.Open()
if err != nil {
memguard.SafePanic(err)
}
defer b.Destroy()
Core dumps are disabled by default. If you absolutely require them, you can enable them by using unix.Setrlimit to set RLIMIT_CORE to an appropriate value.
*/
package memguard