miscreant

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Dec 25, 2017 License: MIT Imports: 11 Imported by: 2

README

miscreant.go Build Status GoDoc Go Report Card MIT licensed Gitter Chat

The best crypto you've never heard of, brought to you by Phil Rogaway

Go implementation of Miscreant: Advanced symmetric encryption library which provides the AES-SIV (RFC 5297), AES-PMAC-SIV, and STREAM constructions. These algorithms are easy-to-use (or rather, hard-to-misuse) and support encryption of individual messages or message streams.

AES-SIV provides nonce-reuse misuse-resistance (NRMR): accidentally reusing a nonce with this construction is not a security catastrophe, unlike it is with more popular AES encryption modes like AES-GCM. With AES-SIV, the worst outcome of reusing a nonce is an attacker can see you've sent the same plaintext twice, as opposed to almost all other AES modes where it can facilitate chosen ciphertext attacks and/or full plaintext recovery.

For more information, see the toplevel README.md.

Help and Discussion

Have questions? Want to suggest a feature or change?

Security Notice

Though this library is written by cryptographic professionals, it has not undergone a thorough security audit, and cryptographic professionals are still humans that make mistakes.

This library makes an effort to use constant time operations throughout its implementation, however actual constant time behavior has not been verified.

Use this library at your own risk.

API

Symmetric Encryption (AEAD)

Miscreant implements the cipher.AEAD interface which provides Authenticated Encryption with Associated Data. This is the main API you should use for most purposes unless you have highly specific needs that are covered more specifically by one of the other APIs described below.

Creating a cipher instance: NewAEAD()

To initialize a cipher.AEAD, you will need to select one of the ciphers below to initialize it with:

  • "AES-SIV": CMAC-based construction described in RFC 5297. Slower but standardized and more common.
  • "AES-PMAC-SIV": PMAC-based construction. Faster but non-standardized and only available in the Miscreant libraries.

For performance reasons we recommend AES-PMAC-SIV but please be aware it is only implemented by the Miscreant libraries.

After selecting a cipher, pass in a 32-byte or 64-byte key. Note that these options are twice the size of what you might be expecting (AES-SIV uses two AES keys).

You can generate a random key using the miscreant.generateKey() method, and then instantiate a cipher instance by calling miscreant.newAEAD(). You will also need to supply a nonce size. We recommend 16-bytes if you would like to use random nonces:

// Create a 32-byte AES-SIV key
k := miscreant.GenerateKey(32)

// Create a new cipher.AEAD instance
c := miscreant.newAEAD("AES-PMAC-SIV", k, 16)
Encrypting data: Seal()

The Seal() method encrypts a message and authenticates a bytestring of associated data under a given key and nonce.

The miscreant.GenerateNonce() function can be used to randomly generate a nonce for the message to be encrypted under. If you wish to use this approach (alternatively you can use a counter for the nonce), please make sure to pass a nonceSize of 16-bytes or greater to newAEAD().

Example:

import "github.com/miscreant/miscreant/go"

// Create a 32-byte AES-SIV key
k := miscreant.GenerateKey(32)

// Create a new cipher.AEAD instance with PMAC as the MAC
c := miscreant.NewAEAD("AES-PMAC-SIV", k, 16)

// Plaintext to be encrypted
pt := []byte("Hello, world!")

// Nonce to encrypt it under
n := miscreant.GenerateNonce(c)

// Associated data to authenticate along with the message
// (or nil if we don't care)
ad := nil

// Create a destination buffer to hold the ciphertext. We need it to be the
// length of the plaintext plus `c.Overhead()` to hold the IV/tag
ct := make([]byte, len(pt) + c.Overhead())

// Perform encryption by calling 'Seal'. The encrypted ciphertext will be
// written into the `ct` buffer
c.Seal(ct, n, pt, ad)
Decryption (#open)

The Open() method decrypts a ciphertext with the given key.

Example:

import "github.com/miscreant/miscreant/go"

// Load an existing cryptographic key
k := ...

// Create a new cipher.AEAD instance
c := miscreant.newAEAD("AES-PMAC-SIV", k, 16)

// Ciphertext to be decrypted
ct := ...

// Nonce under which the ciphertext was originally encrypted
n := ...

// Associated data to authenticate along with the message
// (or nil if we don't care)
ad := nil

// Create a destination buffer to hold the resulting plaintext.
// We need it to be the length of the ciphertext less `c.Overhead()`
l := len(ct) - c.Overhead()
if l < 0 {
    panic("ciphertext too short!")
}
pt := make([]byte, l)

// Perform decryption by calling 'Open'. The decrypted plaintext will be
// written into the `pt` buffer
_, err := c.Open(pt, n, ct, ad)
if err != nil {
    panic(err)
}

Code of Conduct

We abide by the Contributor Covenant and ask that you do as well.

For more information, please see CODE_OF_CONDUCT.md.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/miscreant/miscreant

Copyright (c) 2017 The Miscreant Developers. See LICENSE.txt for further details.

Documentation

Index

Constants

View Source
const MaxAssociatedDataItems = 126

MaxAssociatedDataItems is the maximum number of associated data items

Variables

View Source
var (
	// ErrKeySize indicates the given key size is not supported
	ErrKeySize = errors.New("siv: bad key size")

	// ErrNotAuthentic indicates a ciphertext is malformed or corrupt
	ErrNotAuthentic = errors.New("siv: authentication failed")

	// ErrTooManyAssociatedDataItems indicates more than MaxAssociatedDataItems were given
	ErrTooManyAssociatedDataItems = errors.New("siv: too many associated data items")
)

Functions

func GenerateKey added in v0.2.0

func GenerateKey(length int) []byte

GenerateKey generates a random 32-byte or 64-byte encryption key. Panics if the key size is unsupported or source of randomness fails.

func GenerateNonce added in v0.2.0

func GenerateNonce(c cipher.AEAD) []byte

GenerateNonce generates a random nonce for the given `cipher.AEAD`. Panics if the configured nonce size is less than 16-bytes (128-bits)

func NewAEAD added in v0.2.0

func NewAEAD(alg string, key []byte, nonceSize int) (cipher.AEAD, error)

NewAEAD returns an AES-SIV instance implementing cipher.AEAD interface, with the given cipher, nonce size, and a key which must be twice as long as an AES key, either 32 or 64 bytes to select AES-128 (AES-SIV-256) or AES-256 (AES-SIV-512).

Unless the given nonce size is less than zero, Seal and Open will panic when passed nonce of a different size.

Types

type Cipher

type Cipher struct {
	// contains filtered or unexported fields
}

Cipher is an instance of AES-SIV, configured with either AES-CMAC or AES-PMAC as a message authentication code.

func NewAESCMACSIV added in v0.2.0

func NewAESCMACSIV(key []byte) (c *Cipher, err error)

NewAESCMACSIV returns a new AES-SIV cipher with the given key, which must be twice as long as an AES key, either 32 or 64 bytes to select AES-128 (AES-CMAC-SIV-256), or AES-256 (AES-CMAC-SIV-512).

func NewAESPMACSIV added in v0.2.0

func NewAESPMACSIV(key []byte) (c *Cipher, err error)

NewAESPMACSIV returns a new AES-SIV cipher with the given key, which must be twice as long as an AES key, either 32 or 64 bytes to select AES-128 (AES-PMAC-SIV-256), or AES-256 (AES-PMAC-SIV-512).

func (*Cipher) Open

func (c *Cipher) Open(dst []byte, ciphertext []byte, data ...[]byte) ([]byte, error)

Open decrypts ciphertext, authenticates the decrypted plaintext and the given associated data items and, if successful, appends the resulting plaintext to dst, returning the updated slice. The additional data items must match the items passed to Seal.

The ciphertext and dst may alias exactly or not at all.

For nonce-based encryption, the nonce should be the last associated data item.

func (*Cipher) Overhead

func (c *Cipher) Overhead() int

Overhead returns the difference between plaintext and ciphertext lengths.

func (*Cipher) Seal

func (c *Cipher) Seal(dst []byte, plaintext []byte, data ...[]byte) ([]byte, error)

Seal encrypts and authenticates plaintext, authenticates the given associated data items, and appends the result to dst, returning the updated slice.

The ciphertext and dst may alias exactly or not at all.

For nonce-based encryption, the nonce should be the last associated data item.

type StreamDecryptor added in v0.3.0

type StreamDecryptor struct {
	// contains filtered or unexported fields
}

StreamDecryptor decrypts message streams, selecting the nonces using a 32-bit counter, generalized for any cipher.AEAD algorithm

This construction corresponds to the ℰ stream encryptor object as defined in the paper Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance

func NewStreamDecryptor added in v0.3.0

func NewStreamDecryptor(alg string, key, nonce []byte) (*StreamDecryptor, error)

NewStreamDecryptor returns a STREAM encryptor instance with the given cipher, nonce, and a key which must be twice as long as an AES key, either 32 or 64 bytes to select AES-128 (AES-SIV-256) or AES-256 (AES-SIV-512).

func (*StreamDecryptor) NonceSize added in v0.3.0

func (d *StreamDecryptor) NonceSize() int

NonceSize returns the size of the nonce that must be passed to NewStreamDecryptor

func (*StreamDecryptor) Open added in v0.3.0

func (d *StreamDecryptor) Open(dst, ciphertext, aData []byte, lastBlock bool) ([]byte, error)

Open decrypts and authenticates the next ciphertext in the STREAM, and also authenticates the additional data, ensuring it matches the value passed to Seal.

If successful, it appends the resulting plaintext to dst and returns the updated slice.

The ciphertext and dst may alias exactly or not at all. To reuse ciphertext's storage for the decrypted output, use ciphertext[:0] as dst.

Even if the function fails, the contents of dst, up to its capacity, may be overwritten.

func (*StreamDecryptor) Overhead added in v0.3.0

func (d *StreamDecryptor) Overhead() int

Overhead returns the maximum difference between the lengths of a plaintext and its ciphertext, which in the case of AES-SIV modes is the size of the initialization vector

type StreamEncryptor added in v0.3.0

type StreamEncryptor struct {
	// contains filtered or unexported fields
}

StreamEncryptor encrypts message streams, selecting the nonces using a 32-bit counter, generalized for any cipher.AEAD algorithm

This construction corresponds to the ℰ stream encryptor object as defined in the paper Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance

func NewStreamEncryptor added in v0.3.0

func NewStreamEncryptor(alg string, key, nonce []byte) (*StreamEncryptor, error)

NewStreamEncryptor returns a STREAM encryptor instance with the given cipher, nonce, and a key which must be twice as long as an AES key, either 32 or 64 bytes to select AES-128 (AES-SIV-256) or AES-256 (AES-SIV-512).

func (*StreamEncryptor) NonceSize added in v0.3.0

func (e *StreamEncryptor) NonceSize() int

NonceSize returns the size of the nonce that must be passed to NewStreamEncryptor

func (*StreamEncryptor) Overhead added in v0.3.0

func (e *StreamEncryptor) Overhead() int

Overhead returns the maximum difference between the lengths of a plaintext and its ciphertext, which in the case of AES-SIV modes is the size of the initialization vector

func (*StreamEncryptor) Seal added in v0.3.0

func (e *StreamEncryptor) Seal(dst, plaintext, aData []byte, lastBlock bool) []byte

Seal the next message in the STREAM, which encrypts and authenticates plaintext, authenticates the additional data and appends the result to dst, returning the updated slice.

The plaintext and dst may alias exactly or not at all. To reuse plaintext's storage for the encrypted output, use plaintext[:0] as dst.

The lastBlock argument should be set to true if this is the last message in the STREAM. No further messages can be encrypted after the last one

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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