Documentation ¶
Overview ¶
Package siv implements the Synthetic Initialization Vector (SIV) authenticated encryption scheme specified in RFC 5297. It also implements AES-GCM-SIV as misuse-resistant version of AES-GCM as proposed by the RFC-draft [1].
AES-GCM-SIV ¶
AES-GCM-SIV is a misuse-resistant AEAD scheme using AES-{128/256} for message privacy and a polynomial authenticator (POLYVAL) for message integrity. In contrast to other AEAD schemes - like AES-GCM - AES-GCM-SIV provides message integrity and message privacy (w.r.t the security of deterministic encryption) even if the nonce is reused. AES-GCM-SIV creates a ciphertext which is 16 bytes longer than the plaintext. The ciphertext consists of the encrypted plaintext followed by the (16 byte) authentication tag. For more details see [1].
AES-SIV-CMAC ¶
AES-SIV-CMAC is a misuse-resistant AEAD scheme using AES-{128/192/256} for message privacy and integrity. In contrast to other AEAD schemes - like AES-GCM - AES-SIV-CMAC provides message integrity and message privacy (w.r.t the security of deterministic encryption) even if the nonce is reused or omitted at all. AES-SIV-CMAC creates a ciphertext which is 16 bytes longer than the plaintext. The ciphertext consists of the authentication tag (16 bytes) followed by the encrypted plaintext. For more details see [2].
Deterministic AEAD ¶
Given the same plaintext and additional data a deterministic AEAD produces always the same ciphertext. Therefore it is not semantically secure. [3] However, any deterministic AEAD implemented by this package accepts a non-nil nonce making the encryption probabilistic. A deterministic AEAD which can be turned into a probabilistic AEAD using a nonce value is called misuse-resistant AEAD.
[1] https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-08 [2] https://tools.ietf.org/html/rfc5297 [3] https://en.wikipedia.org/wiki/Deterministic_encryption
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewCMAC ¶
NewCMAC returns a cipher.AEAD implementing AES-SIV-CMAC as specified in RFC 5297. The key must be twice as large as an AES key - so either 32, 48 or 64 bytes long.
The returned cipher.AEAD accepts an empty or NonceSize() bytes long nonce.
Example (Decrypt) ¶
package main import ( "encoding/hex" "fmt" siv "github.com/secure-io/siv-go" ) func main() { // Load your secret key from a safe place and reuse it across multiple // Seal/Open calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like argon2 (`go doc golang.org/x/crypto/argon2`). // When decoded the key should be 32 bytes (AES-128) or 64 (AES-256). key, _ := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574") ciphertext, _ := hex.DecodeString("485bdd0e072f857e623620ebad3eb1925bcb1cafc1780d625710b6bcdd34bf79b2") var nonce []byte = nil // An empty nonce was used to encrypt the plaintext. aessiv, err := siv.NewCMAC(key) if err != nil { panic(err.Error()) } plaintext, err := aessiv.Open(nil, nonce, ciphertext, nil) if err != nil { panic(err.Error()) } fmt.Printf("%s\n", plaintext) }
Output: example_plaintext
Example (Encrypt) ¶
package main import ( "encoding/hex" "fmt" siv "github.com/secure-io/siv-go" ) func main() { // Load your secret key from a safe place and reuse it across multiple // Seal/Open calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like argon2 (`go doc golang.org/x/crypto/argon2`). // When decoded the key should be 32 bytes (AES-128) or 64 (AES-256). key, _ := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574") plaintext := []byte("example_plaintext") aessiv, err := siv.NewCMAC(key) if err != nil { panic(err.Error()) } // An empty nonce makes AES-SIV-CMAC a deterministic authenticated encryption // scheme (same plaintext && additional data produces the same ciphertext). // You can also use a random 16 byte nonce to make AES-SIV-CMAC non-deterministic. var nonce []byte = nil ciphertext := aessiv.Seal(nil, nonce, plaintext, nil) fmt.Printf("%x\n", ciphertext) }
Output: 485bdd0e072f857e623620ebad3eb1925bcb1cafc1780d625710b6bcdd34bf79b2
Example (EncryptDecrypt) ¶
package main import ( "crypto/rand" "encoding/hex" "fmt" "io" siv "github.com/secure-io/siv-go" ) func main() { // Load your secret key from a safe place and reuse it across multiple // Seal/Open calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like argon2 (`go doc golang.org/x/crypto/argon2`). // When decoded the key should be 32 bytes (AES-128) or 64 (AES-256). key, _ := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574") plaintext := []byte("example_plaintext") aessiv, err := siv.NewCMAC(key) if err != nil { panic(err.Error()) } // We use a random nonce to make AES-SIV-CMAC a probabilistic authenticated // encryption scheme. nonce := make([]byte, aessiv.NonceSize()) if _, err = io.ReadFull(rand.Reader, nonce); err != nil { panic(err.Error()) } ciphertext := aessiv.Seal(nil, nonce, plaintext, nil) plaintext, err = aessiv.Open(plaintext[:0], nonce, ciphertext, nil) if err != nil { panic(err.Error()) } fmt.Printf("%s\n", plaintext) }
Output: example_plaintext
func NewGCM ¶
NewGCM returns a cipher.AEAD implementing the AES-GCM-SIV construction. The key must be either 16 or 32 bytes long.
Example (Decrypt) ¶
package main import ( "encoding/hex" "fmt" siv "github.com/secure-io/siv-go" ) func main() { // Load your secret key from a safe place and reuse it across multiple // Seal/Open calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like argon2 (`go doc golang.org/x/crypto/argon2`). // When decoded the key should be 16 bytes (AES-128) or 32 (AES-256). key, _ := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574") ciphertext, _ := hex.DecodeString("eb87399f2550f35b572b10b1a269b6446dce046bfd35e48208b7efa7a7b934cf69") aessiv, err := siv.NewGCM(key) if err != nil { panic(err.Error()) } nonce := make([]byte, aessiv.NonceSize()) // An fixed nonce was used to encrypt the plaintext. plaintext, err := aessiv.Open(nil, nonce, ciphertext, nil) if err != nil { panic(err.Error()) } fmt.Printf("%s\n", plaintext) }
Output: example_plaintext
Example (Encrypt) ¶
package main import ( "encoding/hex" "fmt" siv "github.com/secure-io/siv-go" ) func main() { // Load your secret key from a safe place and reuse it across multiple // Seal/Open calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like argon2 (`go doc golang.org/x/crypto/argon2`). // When decoded the key should be 16 bytes (AES-128) or 32 (AES-256). key, _ := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574") plaintext := []byte("example_plaintext") aessiv, err := siv.NewGCM(key) if err != nil { panic(err.Error()) } // A fixed nonce makes AES-GCM-SIV a deterministic authenticated encryption // scheme (same plaintext && additional data produces the same ciphertext). // You can also use a random 12 byte nonce to make AES-GCM-SIV non-deterministic. nonce := make([]byte, aessiv.NonceSize()) ciphertext := aessiv.Seal(nil, nonce, plaintext, nil) fmt.Printf("%x\n", ciphertext) }
Output: eb87399f2550f35b572b10b1a269b6446dce046bfd35e48208b7efa7a7b934cf69
Example (EncryptDecrypt) ¶
package main import ( "crypto/rand" "encoding/hex" "fmt" "io" siv "github.com/secure-io/siv-go" ) func main() { // Load your secret key from a safe place and reuse it across multiple // Seal/Open calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like argon2 (`go doc golang.org/x/crypto/argon2`). // When decoded the key should be 16 bytes (AES-128) or 32 (AES-256). key, _ := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574") plaintext := []byte("example_plaintext") aessiv, err := siv.NewGCM(key) if err != nil { panic(err.Error()) } // We use a random nonce to make AES-GCM-SIV a probabilistic authenticated // encryption scheme. nonce := make([]byte, aessiv.NonceSize()) if _, err = io.ReadFull(rand.Reader, nonce); err != nil { panic(err.Error()) } ciphertext := aessiv.Seal(nil, nonce, plaintext, nil) plaintext, err = aessiv.Open(plaintext[:0], nonce, ciphertext, nil) if err != nil { panic(err.Error()) } fmt.Printf("%s\n", plaintext) }
Output: example_plaintext
Types ¶
This section is empty.