crypto

package
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Feb 2, 2017 License: MPL-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Easy to use crypto package for a variety of usages.

Catgi Security packages

It provides a secure and fast HMAC function using Blake2b

It provides a secure and deterministic key derivation mechanism using keypaths and Blake2b.

It provides a secure and easy symmetric encryption using Polycha20 and the key derivatino mechanism. Each encryption gets it's own key thusly preventing nonce reuse for multiple calls to the encryption method.

Index

Constants

View Source
const (
	CipherDefault = CipherPolyCha20

	// Encrypt and Decrypt using Chacha20 with Poly1305
	CipherPolyCha20 = iota
)
View Source
const (
	CryptModeWhole  = "fullkey"
	CryptModeStream = "streamkey"
	CryptModeBlock  = "blockkey"
)
View Source
const (
	BlockSize       = 4 * 1024
	BlockHeaderSize = 8
)

Variables

View Source
var ErrEmptyBlock = errors.New("Empty Block")

This is a non-critical error. It indicates that some block had the size 0, containing only a header.

View Source
var HMACVerificationFail = errors.New("HMAC Verification failed")

HMACVerificationFail is returned by VerifyHMAC when the hmac given did not match the given datastream.

Functions

func DecryptBlockData

func DecryptBlockData(key SecretKey, data io.Reader) (io.Reader, <-chan error, error)

func DecryptBytes

func DecryptBytes(key SecretKey, data []byte) ([]byte, error)

func DecryptStreamData

func DecryptStreamData(key SecretKey, data io.Reader) (io.Reader, <-chan error, error)

func EncryptBlockData

func EncryptBlockData(key SecretKey, data io.Reader) (io.Reader, <-chan error, error)

func EncryptBytes

func EncryptBytes(key SecretKey, data []byte) ([]byte, error)

func EncryptStreamData

func EncryptStreamData(key SecretKey, data io.Reader) (io.Reader, <-chan error, error)

EncryptStreamData will accept a secret key and a incoming io.Reader to read from. It will encrypt all incoming data using 4KiB blocks. If an error occurs during initialization, it will return a nil error channel and nil io.Reader. If the initialization is correct, it will start the cipher worker in a go routine. The Worker will return an error over the given error channel and close the io.Reader on it's side. The worker will block waiting for either input or output, it's output is not buffered. The Encryption will derive all secrets from the given SecretKey in such a way that the function DecryptStreamData can decrypt it given it has the same key.

func GetKey

func GetKey(key SecretKey, cipher Cipher, mode CryptMode) ([]byte, []byte, error)

GetKey is a wrapper for GetKeyFromSalt that generates a random salt to be used for the key using a random nonce. Internally it combines a PreKey with a randomly generated nonce.

func GetKeyFromPrekey

func GetKeyFromPrekey(key SecretKey, salt []byte) ([]byte, error)

GetKeyFromPreKey applies the given salt to a PreKey. You should not use this to derive from anything but the data you get from GetPreKey.

func HMAC

func HMAC(key []byte, data io.Reader) ([]byte, error)

HMAC will read the given reader and return the MAC for the given key As lng as the Blake2b Algorithm can be initialized, this function returns a hash.

func VerifyHMAC

func VerifyHMAC(hmac, key []byte, data io.Reader) (err error)

VerifyHMAC will take an HMAC and a to-be-verified data stream plus key. It will generate the HMAC for that datastream and then perform a constant-time comparison of the two HMACs.

Types

type Cipher

type Cipher uint16

Cipher represents a encryption mode used by this package The default cipher is CipherPolyCha20

type CryptMode

type CryptMode string

type DecryptWorker

type DecryptWorker struct {
	Key    SecretKey
	Input  io.Reader
	Output io.Writer
}

func (*DecryptWorker) DecipherAll

func (c *DecryptWorker) DecipherAll() error

func (*DecryptWorker) DecipherStreamOrBlock

func (c *DecryptWorker) DecipherStreamOrBlock() error

type EncryptWorker

type EncryptWorker struct {
	AEAD   cipher.AEAD // AEAD cipher used
	Salt   []byte      // Salt used for key derivation
	Input  io.Reader   // Data Input Reader
	Output io.Writer   // Cipher Output Writer
}

EncryptWorker is used to cipher a stream of data. It'll read atleast blockSize of bytes and encrypt them

func (*EncryptWorker) CipherAll

func (c *EncryptWorker) CipherAll() error

Cipher all reads the entire plaintext and ciphers it at once and encrypts them in a single block When all data is encrypted or an error occurs, the output is closed and the error returned.

func (*EncryptWorker) CipherBlock

func (c *EncryptWorker) CipherBlock() error

CipherBlock works like CipherStream but the output blocks have a fixed size, making it more suitable for disk/file operations.

func (*EncryptWorker) CipherStream

func (c *EncryptWorker) CipherStream() error

CipherStream will read from input and output a ciphered stream of data.

type EncryptedBlock

type EncryptedBlock struct {
	Cipher  uint16 `msgpack:"cipher"`  // Cipher is a constant determining the cipher algorithm
	Padding uint16 `msgpack:"padding"` // Padding is the number of bytes added to the data. Whe not used set to 0x0000
	Nonce   []byte `msgpack:"nonce"`   // Nonce is the encryption nonce used
	Salt    []byte `msgpack:"salt"`    // Salt is used to derive the key used for decryption
	Data    []byte `msgpack:"data"`    // Data is the actual ciphertext
}

EncryptedBlock contains an encrypted block of data with necessary information to decrypt it again. When used in Block-Mode, the maximum size that should be used is 2^16-1 In Stream- or Whole-Mode the maximum safe size is a bit under 2^32, depending on nonce, salt and encoding overhead.

type SecretKey

type SecretKey [64]byte

SecretKey is a special 64 byte long secret that can be used to derive an arbitrary amount of subkeys. All subkeys are deterministically based on their path and their parent, allowing an application or library to reuse a secret for many operations in different locations. As a bonus, if a subkey is compromised, it's parents are not, so you can expose as many keys as you like to less trustworthy clients without fearing that someone could forge more keys.

Keep in mind that keys are deterministic, so if a key is compromised the specific path used will remain forever compromised for the same parent key. You need to change the path or the master secret to regain security.

Since this key uses HMACs, you can also utilize it to generate encryption keys. If a key and it's path are compromised, an attacker cannot forge other keys unless they have knowledge of the parent.

To protect the master, it is recommended to use a path depth of atleast 2. Ex.: /myapp/example/org/ would be an acceptable derivative secret of a master key.

func GetPreKey

func GetPreKey(key SecretKey, cipher Cipher, mode CryptMode) (SecretKey, error)

GetPreKey derives a so called prekey. This prekey is used when decrypting data streams that use the same cipher and cryptmode, allowing the AEAD mode to operate at least-depth while still being able to decrypt as much data as possible.

func NewSecretKey

func NewSecretKey(master []byte) SecretKey

NewSecretKey will take the given master secret and generate a SecretKey from it. If the master is shorter than 64 bytes, it will first be hashed using Blake2b. If the master is longer than 64 bytes, the excessive data is discarded.

func (SecretKey) DeriveKey

func (s SecretKey) DeriveKey(path ...string) (SecretKey, error)

DeriveKey will compute a new secret based on the given path and the defined secret key.

Applications should derive to a depth of 3 path segments before externalizing a key, ie transmitting it over network.

The path is computed recursively on the result of the previous path such that the path computation can be split at any point. If no path is specified, then the given master is returned.

Illustration:

DeriveKey(path1, path2) == DeriveKey(DeriveKey(path1), path2)

SecretKey.DeriveKey() == SecretKey

func (SecretKey) GetNSecretBytes

func (s SecretKey) GetNSecretBytes(n int, salt []byte) ([]byte, error)

GetNSecretBytes reads N bytes from a HKDF with an optional salt. (Set salt to nil if no salt is used) Keep in mind that HKDF has an upper limit on entropy, you should not read excessive amounts of random data from here. I recommend not using more than 4096 bytes of data, this has worked for my tests so far with good reliability and should be sufficient for 99% of applications.

func (SecretKey) MustDeriveKey

func (s SecretKey) MustDeriveKey(path ...string) SecretKey

MustDeriveKey works like DeriveKey but panics on an error.

func (SecretKey) MustGetNSecretBytes

func (s SecretKey) MustGetNSecretBytes(n int, salt []byte) []byte

MustGetNSecretBytes works like GetNSecretBytes but will panic if it encounters an error.

Jump to

Keyboard shortcuts

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