libgocryptfs/internal/siv_aead/siv_aead.go

62 lines
1.6 KiB
Go

// Package siv_aead wraps the functions provided by siv
// in a crypto.AEAD interface.
package siv_aead
import (
"crypto/cipher"
"log"
"github.com/jacobsa/crypto/siv"
)
type sivAead struct {
key []byte
}
var _ cipher.AEAD = &sivAead{}
// New returns a new cipher.AEAD implementation.
func New(key []byte) cipher.AEAD {
return &sivAead{
key: key,
}
}
func (s *sivAead) NonceSize() int {
// SIV supports any nonce size, but in gocryptfs we exclusively use 16.
return 16
}
func (s *sivAead) Overhead() int {
return 16
}
// Seal encrypts "in" using "nonce" and "authData" and append the result to "dst"
func (s *sivAead) Seal(dst, nonce, plaintext, authData []byte) []byte {
if len(nonce) != 16 {
// SIV supports any nonce size, but in gocryptfs we exclusively use 16.
log.Panic("nonce must be 16 bytes long")
}
// https://github.com/jacobsa/crypto/blob/master/siv/encrypt.go#L48:
// As per RFC 5297 section 3, you may use this function for nonce-based
// authenticated encryption by passing a nonce as the last associated
// data element.
associated := [][]byte{authData, nonce}
out, err := siv.Encrypt(dst, s.key, plaintext, associated)
if err != nil {
log.Panic(err)
}
return out
}
// Open decrypts "in" using "nonce" and "authData" and append the result to "dst"
func (s *sivAead) Open(dst, nonce, ciphertext, authData []byte) ([]byte, error) {
if len(nonce) != 16 {
// SIV supports any nonce size, but in gocryptfs we exclusively use 16.
log.Panic("nonce must be 16 bytes long")
}
associated := [][]byte{authData, nonce}
dec, err := siv.Decrypt(s.key, ciphertext, associated)
return append(dst, dec...), err
}