diff --git a/cmd/randomd/randomd.go b/cmd/randomd/randomd.go new file mode 100644 index 0000000..ac5dd67 --- /dev/null +++ b/cmd/randomd/randomd.go @@ -0,0 +1,92 @@ +package main + +import ( + "io" + "io/ioutil" + "os" + "os/signal" + "router7/internal/teelogger" + "syscall" + "time" + "unsafe" + + "golang.org/x/sys/unix" +) + +var log = teelogger.NewConsole() + +func seed() error { + sf, err := os.OpenFile("/perm/random.seed", os.O_RDWR|os.O_CREATE, 0600) + if err != nil { + return err + } + defer sf.Close() + + rf, err := os.OpenFile("/dev/urandom", os.O_RDWR, 0600) + if err != nil { + return err + } + defer rf.Close() + + seed := make([]byte, 512) + if _, err := sf.Read(seed); err != nil { + // fall back to seeding with the current time + seed = []byte(time.Now().String()) + } else { + log.Printf("seeding RNG from /perm/random.seed") + } + + entropy := struct { + entropyCount int64 + bufSize int64 + buf [512]byte + }{ + entropyCount: int64(len(seed) * 8), + bufSize: int64(len(seed)), + } + copy(entropy.buf[:], seed) + const RNDADDENTROPY = 0x40085203 + if _, _, errno := unix.Syscall(unix.SYS_IOCTL, rf.Fd(), RNDADDENTROPY, uintptr(unsafe.Pointer(&entropy))); errno != 0 { + return errno + } + + // Overwrite the seed (re-using a seed compromises security): + if _, err := sf.Seek(0, io.SeekStart); err != nil { + return err + } + + if _, err := io.CopyN(sf, rf, 512); err != nil { + return err + } + + return sf.Close() +} + +func saveSeed() error { + rf, err := os.OpenFile("/dev/urandom", os.O_RDWR, 0600) + if err != nil { + return err + } + defer rf.Close() + + seed := make([]byte, 512) + if _, err := rf.Read(seed); err != nil { + return err + } + return ioutil.WriteFile("/perm/random.seed", seed, 0600) +} + +func main() { + if err := seed(); err != nil { + log.Printf("seeding random pool failed: %v", err) + } + + // Wait for SIGTERM to store new randomness seed on /perm + ch := make(chan os.Signal, 1) + signal.Notify(ch, syscall.SIGTERM) + <-ch + + if err := saveSeed(); err != nil { + log.Printf("persisting random seed failed: %v", err) + } +}