Commit 30459825 authored by ale's avatar ale

Update miscreant dependency

parent 7e0cd4a5
Pipeline #1018 passed with stages
in 55 seconds
Copyright (c) 2017 The Miscreant Developers. The canonical list of project
Copyright (c) 2017-2018 The Miscreant Developers. The canonical list of project
contributors who hold copyright over the project can be found at:
https://github.com/miscreant/miscreant/blob/master/AUTHORS.md
......
# miscreant.go [![Build Status][build-shield]][build-link] [![GoDoc][godoc-shield]][godoc-link] [![Go Report Card][goreport-shield]][goreport-link] [![MIT licensed][license-shield]][license-link] [![Gitter Chat][gitter-image]][gitter-link]
[build-shield]: https://secure.travis-ci.org/miscreant/miscreant.svg?branch=master
[build-link]: http://travis-ci.org/miscreant/miscreant
[build-link]: https://travis-ci.org/miscreant/miscreant
[godoc-shield]: https://godoc.org/github.com/miscreant/miscreant/go?status.svg
[godoc-link]: https://godoc.org/github.com/miscreant/miscreant/go
[goreport-shield]: https://goreportcard.com/badge/github.com/miscreant/miscreant
......@@ -13,10 +13,17 @@
> The best crypto you've never heard of, brought to you by [Phil Rogaway]
Go implementation of **Miscreant**: Advanced symmetric encryption using the
[AES-SIV] ([RFC 5297]) and [CHAIN/STREAM] constructions, providing easy-to-use
(or rather, hard-to-misuse) encryption of individual messages or message
streams.
[Phil Rogaway]: https://en.wikipedia.org/wiki/Phillip_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]: https://github.com/miscreant/miscreant/wiki/AES-SIV
[RFC 5297]: https://tools.ietf.org/html/rfc5297
[AES-PMAC-SIV]: https://github.com/miscreant/miscreant/wiki/AES-PMAC-SIV
[STREAM]: https://github.com/miscreant/miscreant/wiki/STREAM
**AES-SIV** provides [nonce-reuse misuse-resistance] (NRMR): accidentally
reusing a nonce with this construction is not a security catastrophe,
......@@ -28,11 +35,7 @@ full plaintext recovery.
For more information, see the [toplevel README.md].
[Phil Rogaway]: https://en.wikipedia.org/wiki/Phillip_Rogaway
[AES-SIV]: https://www.iacr.org/archive/eurocrypt2006/40040377/40040377.pdf
[RFC 5297]: https://tools.ietf.org/html/rfc5297
[CHAIN/STREAM]: http://web.cs.ucdavis.edu/~rogaway/papers/oae.pdf
[nonce-reuse misuse-resistance]: https://www.lvh.io/posts/nonce-misuse-resistance-101.html
[nonce-reuse misuse-resistance]: https://github.com/miscreant/miscreant/wiki/Nonce-Reuse-Misuse-Resistance
[AES-GCM]: https://en.wikipedia.org/wiki/Galois/Counter_Mode
[chosen ciphertext attacks]: https://en.wikipedia.org/wiki/Chosen-ciphertext_attack
[toplevel README.md]: https://github.com/miscreant/miscreant/blob/master/README.md
......@@ -48,6 +51,13 @@ Have questions? Want to suggest a feature or change?
[Google Group]: https://groups.google.com/forum/#!forum/miscreant-crypto
[miscreant-crypto+subscribe@googlegroups.com]: mailto:miscreant-crypto+subscribe@googlegroups.com?subject=subscribe
## Documentation
[Please see the Miscreant Wiki](https://github.com/miscreant/miscreant/wiki/Go-Documentation)
for API documentation.
[godoc][godoc-link] documentation is also available.
## Security Notice
Though this library is written by cryptographic professionals, it has not
......@@ -59,129 +69,6 @@ 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:
```go
// 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)
```
[cipher.AEAD]: https://golang.org/pkg/crypto/cipher/#AEAD
[Authenticated Encryption with Associated Data]: https://en.wikipedia.org/wiki/Authenticated_encryption
#### 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:
```go
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:
```go
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][cc] and ask that you do as well.
......@@ -197,7 +84,7 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/miscre
## Copyright
Copyright (c) 2017 [The Miscreant Developers][AUTHORS].
Copyright (c) 2017-2018 [The Miscreant Developers][AUTHORS].
See [LICENSE.txt] for further details.
[AUTHORS]: https://github.com/miscreant/miscreant/blob/master/AUTHORS.md
......
......@@ -83,7 +83,7 @@ func (a *aead) Overhead() int { return a.c.Overhead() }
func (a *aead) Seal(dst, nonce, plaintext, data []byte) (out []byte) {
if len(nonce) != a.nonceSize && a.nonceSize >= 0 {
panic("siv.AEAD: incorrect nonce length")
panic("miscreant.AEAD: incorrect nonce length")
}
var err error
if data == nil {
......@@ -92,14 +92,14 @@ func (a *aead) Seal(dst, nonce, plaintext, data []byte) (out []byte) {
out, err = a.c.Seal(dst, plaintext, data, nonce)
}
if err != nil {
panic("siv.AEAD: " + err.Error())
panic("miscreant.AEAD: " + err.Error())
}
return out
}
func (a *aead) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
if len(nonce) != a.nonceSize && a.nonceSize >= 0 {
panic("siv.AEAD: incorrect nonce length")
panic("miscreant.AEAD: incorrect nonce length")
}
if data == nil {
return a.c.Open(dst, ciphertext, nonce)
......
......@@ -105,7 +105,7 @@ func (c *Cipher) Overhead() int {
// associated data items, and appends the result to dst, returning the updated
// slice.
//
// The ciphertext and dst may alias exactly or not at all.
// The plaintext and dst may alias exactly or not at all.
//
// For nonce-based encryption, the nonce should be the last associated data item.
func (c *Cipher) Seal(dst []byte, plaintext []byte, data ...[]byte) ([]byte, error) {
......@@ -166,7 +166,7 @@ func (c *Cipher) s2v(s [][]byte, sn []byte) []byte {
tmp.Clear()
// NOTE(dchest): The standalone S2V returns CMAC(1) if the number of
// passed vectors is zero, however in SIV contruction this case is
// passed vectors is zero, however in SIV construction this case is
// never triggered, since we always pass plaintext as the last vector
// (even if it's zero-length), so we omit this case.
......
package miscreant
import (
"crypto/cipher"
"encoding/binary"
)
// streamNoncePrefixSize is the user-supplied nonce size
const streamNoncePrefixSize = 8
// streamExtendedNonceSize is the nonce prefix + 32-bit counter + 1-byte last block flag
const streamExtendedNonceSize = streamNoncePrefixSize + 4 + 1
// lastBlockFlag indicates that a block is the last in the STREAM
const lastBlockFlag byte = 1
// counterMax is the maximum allowable value for the stream counter
const counterMax uint64 = 0xFFFFFFFF
// 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
type StreamEncryptor struct {
// cipher.AEAD instance underlying this STREAM
a cipher.AEAD
// Nonce encoder instance which computes per-message nonces
n *nonceEncoder32
}
// 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 NewStreamEncryptor(alg string, key, nonce []byte) (*StreamEncryptor, error) {
aead, err := NewAEAD(alg, key, streamExtendedNonceSize)
if err != nil {
return nil, err
}
nonceEncoder, err := newNonceEncoder32(nonce)
if err != nil {
return nil, err
}
return &StreamEncryptor{a: aead, n: nonceEncoder}, nil
}
// NonceSize returns the size of the nonce that must be passed to
// NewStreamEncryptor
func (e *StreamEncryptor) NonceSize() int { return streamNoncePrefixSize }
// 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 (e *StreamEncryptor) Overhead() int { return e.a.Overhead() }
// 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
func (e *StreamEncryptor) Seal(dst, plaintext, aData []byte, lastBlock bool) []byte {
return e.a.Seal(dst, e.n.Next(lastBlock), plaintext, aData)
}
// 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
type StreamDecryptor struct {
// cipher.AEAD instance underlying this STREAM
a cipher.AEAD
// Nonce encoder instance which computes per-message nonces
n *nonceEncoder32
}
// 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 NewStreamDecryptor(alg string, key, nonce []byte) (*StreamDecryptor, error) {
aead, err := NewAEAD(alg, key, streamExtendedNonceSize)
if err != nil {
return nil, err
}
nonceEncoder, err := newNonceEncoder32(nonce)
if err != nil {
return nil, err
}
return &StreamDecryptor{a: aead, n: nonceEncoder}, nil
}
// NonceSize returns the size of the nonce that must be passed to
// NewStreamDecryptor
func (d *StreamDecryptor) NonceSize() int { return streamNoncePrefixSize }
// 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 (d *StreamDecryptor) Overhead() int { return d.a.Overhead() }
// 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 (d *StreamDecryptor) Open(dst, ciphertext, aData []byte, lastBlock bool) ([]byte, error) {
return d.a.Open(dst, d.n.Next(lastBlock), ciphertext, aData)
}
// Computes STREAM nonces based on the current position in the STREAM.
//
// Accepts a 64-bit nonce and uses a 32-bit counter internally.
//
// Panics if the nonce size is incorrect, or the 32-bit counter overflows
type nonceEncoder32 struct {
value [streamExtendedNonceSize]byte
counter uint64
finished bool
}
func newNonceEncoder32(noncePrefix []byte) (*nonceEncoder32, error) {
if len(noncePrefix) != streamNoncePrefixSize {
panic("miscreant.STREAM: incorrect nonce length")
}
value := [streamExtendedNonceSize]byte{0}
copy(value[:streamNoncePrefixSize], noncePrefix)
return &nonceEncoder32{
value: value,
counter: 0,
finished: false,
}, nil
}
func (n *nonceEncoder32) Next(lastBlock bool) []byte {
if n.finished {
panic("miscreant.STREAM: already finished")
}
counterSlice := n.value[streamNoncePrefixSize : streamNoncePrefixSize+4]
binary.BigEndian.PutUint32(counterSlice, uint32(n.counter))
if lastBlock {
n.value[len(n.value)-1] = lastBlockFlag
n.finished = true
} else {
n.counter++
if n.counter > counterMax {
panic("miscreant.STREAM: nonce counter overflowed")
}
}
return n.value[:]
}
......@@ -75,10 +75,10 @@
"revisionTime": "2016-04-24T11:30:07Z"
},
{
"checksumSHA1": "cyZFg627VjHs+qRcnjH//QTINa8=",
"checksumSHA1": "42iE67lnxblPsQnllIZ+m2KJsvg=",
"path": "github.com/miscreant/miscreant/go",
"revision": "834b150f9163806592d075e9e235296ba5c64425",
"revisionTime": "2017-12-04T00:48:37Z"
"revision": "71d82ae9dd614c1ec09d4491e01d5d0ea762c398",
"revisionTime": "2018-06-23T00:14:59Z"
},
{
"checksumSHA1": "KnQFNiyIyIH+V8EbySzLhySrF9s=",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment