Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/ec openssl #1

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.DS_Store

bin/
bespin
coverage.out
node_modules/
tags
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.6.5
3.7.0
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ GO_TEST_DIRS := $(shell \
uniq)

VERSION = `cat VERSION`
PACKAGE = github.com/amanelis/core-zero
PACKAGE = github.com/block27/core-zero

# Aliases
all: configuration build
Expand Down Expand Up @@ -112,7 +112,7 @@ update:
@govendor update -tree

# TESTING ----------------------------------------------------------------------
test: test_richgo
test: prepare_tests test_richgo

test_coverage_func:
@ENVIRONMENT=test go tool cover -func=coverage.out
Expand All @@ -121,10 +121,10 @@ test_coverage_html:
@ENVIRONMENT=test go tool cover -html=coverage.out

test_golang: prepare_tests
@ENVIRONMENT=test go test -v ./... -cover -coverprofile=coverage.out #-bench=.
@ENVIRONMENT=test go test -v ./... -cover -coverprofile=coverage.out -bench=.

test_gotest: prepare_tests
@ENVIRONMENT=test gotest -v ./... -cover -coverprofile=coverage.out #-bench=.
@ENVIRONMENT=test gotest -v ./... -cover -coverprofile=coverage.out -bench=.

test_richgo: prepare_tests
@ENVIRONMENT=test richgo test -v ./... -cover -coverprofile=coverage.out #-bench=.
28 changes: 23 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,38 @@
# Sigma HSM
# CORE ZERO HSM

This source repository contains the code used for creating, signing and encrypting keys and data through the "pseudo" HSM module authored by Alex Manelis.

## General

Below are the main points to be noted on the HSM that can be broken down into their own detailed sections.

- **PSEUDO**, meaning that the keys are generated in a secure hardware environment, but encrypted with a custom Sigma KEY/IV device used to AES encrypt/decrypt pems and store them for safe backup. There is available an AES VHDL package that can be used to generate the keys on FPGA, but that has been a challenge to fetch keys and back them up.

- **RANDOMNESS**, when generating the ECDSA/RSA assymetric keys, the device needs the highest possible amount of entropy. It gains this through the use of two devices cabable of creating close to. 7.9999 bits of Entropy per byte. The first, `/dev/TrueRNG` is capaable of speeds around 3 mb/s. The second is the BitBlabber, `/dev/BB` capable of speeds around 20 mb/s. These have been mapped into the `crypto/rand` module `io.Reader` interface and used directly in Sigma to generate the keys.

- **FPGA**, the motherboard here that will be used to run the application code is a DEC10-NANO from TerASIC. It is capable of complete VHDL programming and hardware managment by switches on board. Plan of importance on methods of implementation below:

- Implement complete golang code base capable of generating soft keys (meaning they can be accessed and passed around only inside of the HSM). These can be encrypted via AES and safely backed up.

- Second is to implement completely in hardware using VHDL. This is harder, but possible.
- Second is to implement completely in hardware using VHDL. This is harder, but possible.

- After either are completed, build out Serial API so the device can be connected to HSM API via USB only.



- After either are completed, build out Serial API so the device can be connected to HSM API via USB only.
The main goal here is to build an HSM like device that can securly generate keys, but also give the ability to back up keys. It's important to note that what is currentlty available on the market is hard to use, minimally documented, bad libraries and very very expensive. I believe it can be done better and safer from a standpoint of hardware failure.


## Practices

Please be very aware of older and out dated versions of software, staying up to date with latest releases and abolished algorithms deemed as unacceptable is the first step to mitigating cyber risk.

- Do NOT support any version of SSL or TLS 1.0. If you see SSL v2 or SSL v3, disable them immediately, as they will expose a range of vulnerabilities including Freak and Poodle.
- Do NOT support MD5, RC4, and DES in cipher suites. MD5 cannot be trusted as it hash signatures can cause collisions. RC4 has cipher weaknesses, and DES only has 56-bit keys, and which can be easily brute forced.
- Do NOT support 1,024-bit (or less) RSA keys.
- Do NOT support the export of 512-bit export suites, as 512-bit Diffie-Hellman keys have been long cracked.
- Only support AEAD ciphers.
- AEAD_CHACHA20_POLY1305 (chacha20-ietf-poly1305)
- AEAD_AES_256_GCM (aes-256-gcm)
- AEAD_AES_192_GCM (aes-192-gcm)
- AEAD_AES_128_GCM (aes-128-gcm)

The main goal here is to build an HSM like device that can securly generate keys, but also give the ability to back up keys. It's important to note that what is currentlty available on the market is hard to use, minimally documented, bad libraries and very very expensive. I believe it can be done better and safer from a standpoint of hardware failure.
62 changes: 31 additions & 31 deletions backend/client.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
package backend

import (
"crypto/subtle"
"encoding/json"
"fmt"
"io/ioutil"
"math/rand"
"runtime"

// "strconv"
"strings"
"time"

"github.com/amanelis/core-zero/config"
"github.com/amanelis/core-zero/crypto"
h "github.com/amanelis/core-zero/helpers"
"github.com/amanelis/core-zero/services/bbolt"
"github.com/amanelis/core-zero/services/serial"
"github.com/block27/core-zero/config"
"github.com/block27/core-zero/crypto"
h "github.com/block27/core-zero/helpers"
"github.com/block27/core-zero/services/bbolt"
"github.com/block27/core-zero/services/serial"

"github.com/google/gousb"
"github.com/awnumar/memguard"
"github.com/briandowns/spinner"
"github.com/google/gousb"
"github.com/sirupsen/logrus"
)

Expand All @@ -36,9 +38,9 @@ type Backend struct {

// device - capture data in from connected AES/Arduino usbmodem
type device struct {
Product uint16 `json:"product"`
Vendor uint16 `json:"vendor"`
Serial string `json:"serial"`
Product uint16 `json:"product"`
Vendor uint16 `json:"vendor"`
Serial string `json:"serial"`
Manufacturer string `json:"manufacturer"`
}

Expand Down Expand Up @@ -77,7 +79,7 @@ func NewBackend() (*Backend, error) {
// work, if removed or altered, HSM code will not run. But key recovery is
// still possible.
func (b *Backend) HardwareAuthenticate() error {
spinners, err := newSpinner(3)
spinners, err := newSpinner(1)
if err != nil {
return err
}
Expand All @@ -90,6 +92,8 @@ func (b *Backend) HardwareAuthenticate() error {

var extB1, extB2 string

// Grab the locaiton of the PIN 1 and 2. Depending on Architecture, this could
// differ, but not hugely.
if runtime.GOOS == "darwin" {
extB1 = fmt.Sprintf("%s/%s", "/Volumes/BASE1", config.ExtBase1Path)
extB2 = fmt.Sprintf("%s/%s", "/Volumes/BASE2", config.ExtBase2Path)
Expand Down Expand Up @@ -129,9 +133,11 @@ func (b *Backend) HardwareAuthenticate() error {
for i := 0; i < len(spinners); i++ {
spinners[i].Stop()
}

return err
}

// Hardware stored, on SBC two values that should equal to the values on the USB devices
hmK, _ := h.ReadFile(config.HostMasterKeyPath)
hmI, _ := h.ReadFile(config.HostMasterIvPath)

Expand Down Expand Up @@ -185,42 +191,31 @@ func (b *Backend) HardwareAuthenticate() error {
)

// Read ext1
b1F, _ := h.ReadFile(extB1)
p1F, _ := h.ReadFile(config.HostPin1)
b1F, _ := h.ReadFileByte(extB1)
p1F, _ := h.ReadFileByte(config.HostPin1)

dec1, _ := c.Decrypt([]byte(b1F))
if string(dec1) != p1F {
dec1, _ := c.Decrypt(b1F)
if subtle.ConstantTimeCompare(dec1, p1F) == 0 {
return fmt.Errorf("%s", h.RFgB("pin1 does not match, invalid ext authentication"))
}

// Read ext2
b2F, _ := h.ReadFile(extB2)
p2F, _ := h.ReadFile(config.HostPin2)
b2F, _ := h.ReadFileByte(extB2)
p2F, _ := h.ReadFileByte(config.HostPin2)

dec2, _ := c.Decrypt([]byte(b2F))
if string(dec2) != p2F {
dec2, _ := c.Decrypt(b2F)
if subtle.ConstantTimeCompare(dec2, p2F) == 0 {
return fmt.Errorf("%s", h.RFgB("pin2 does not match, invalid ext authentication"))
}

return nil
}

func findMPD26(product, vendor uint16) func(desc *gousb.DeviceDesc) bool {
return func(desc *gousb.DeviceDesc) bool {
return desc.Product == gousb.ID(product) && desc.Vendor == gousb.ID(vendor)
}
}

// locateDevice ... temporary fix, but need to find the AES device to starts
func (b *Backend) locateDevice() (string, error) {
data, err := ioutil.ReadDir("/dev")
if err != nil {
return "", err
}

// Run device identification process
// Open our jsonFile
f, err := h.NewFile("/var/data/device")
f, err := h.NewFile("/var/data/device.teensy")
if err != nil {
return "", err
}
Expand All @@ -230,7 +225,7 @@ func (b *Backend) locateDevice() (string, error) {
// Unmarshall data into struct var
jerr := json.Unmarshal([]byte(string(f.GetBody())), &d)
if jerr != nil {
return "", fmt.Errorf(h.RFgB("invalid device mapping file"))
return "", fmt.Errorf(h.RFgB("invalid device mapping file"), jerr)
}

ctx := gousb.NewContext()
Expand All @@ -249,6 +244,11 @@ func (b *Backend) locateDevice() (string, error) {
return "", fmt.Errorf(h.RFgB("device manufacturer and serial did not match"))
}

data, err := ioutil.ReadDir("/dev")
if err != nil {
return "", err
}

for _, f := range data {
// MacOSX
if strings.Contains(f.Name(), "tty.usbmodem") {
Expand Down
14 changes: 7 additions & 7 deletions cmd/dsa.go → cmd/ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (

"github.com/spf13/cobra"

h "github.com/amanelis/core-zero/helpers"
"github.com/amanelis/core-zero/services/dsa/ecdsa"
"github.com/amanelis/core-zero/services/dsa/signature"
h "github.com/block27/core-zero/helpers"
"github.com/block27/core-zero/services/dsa/ecdsa"
"github.com/block27/core-zero/services/dsa/signature"
)

var (
Expand Down Expand Up @@ -45,7 +45,7 @@ var (
func init() {
// Create flags ...
dsaCreateCmd.Flags().StringVarP(&createName, "name", "n", "", "name required")
dsaCreateCmd.Flags().StringVarP(&createCurve, "curve", "c", "prime256v1", "default: prime256v1")
dsaCreateCmd.Flags().StringVarP(&createCurve, "curve", "c", "prime256v1", "")
dsaCreateCmd.MarkFlagRequired("name")

// Get flags ...
Expand Down Expand Up @@ -287,9 +287,9 @@ var dsaExportPubCmd = &cobra.Command{
}

pubKey, err := base64.StdEncoding.DecodeString(key.Struct().PublicKeyB64)
if err != nil {
panic(err)
}
if err != nil {
panic(err)
}

fmt.Println(string(pubKey))
},
Expand Down
4 changes: 2 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package cmd
import (
"fmt"

"github.com/amanelis/core-zero/backend"
h "github.com/amanelis/core-zero/helpers"
"github.com/block27/core-zero/backend"
h "github.com/block27/core-zero/helpers"
"github.com/spf13/cobra"
)

Expand Down
2 changes: 1 addition & 1 deletion cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package cmd
import (
"fmt"

h "github.com/amanelis/core-zero/helpers"
h "github.com/block27/core-zero/helpers"
"github.com/spf13/cobra"
)

Expand Down
2 changes: 1 addition & 1 deletion crypto/encrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"errors"

"github.com/awnumar/memguard"
"github.com/spacemonkeygo/openssl"
"github.com/block27/openssl"
)

type AESCredentials struct {
Expand Down
Loading