Skip to content

Commit

Permalink
IV generation for ChaCha20 poly auth scheme (#283)
Browse files Browse the repository at this point in the history
Generate 16 bytes IV instead of an IV of 32 bytes (and then use half of it) when using ChaCha20 to
encrypt tokens, this is to prevent tokens to become malleable.
  • Loading branch information
Alevsk committed Sep 22, 2020
1 parent 1dc9949 commit c0ee739
Showing 1 changed file with 10 additions and 10 deletions.
20 changes: 10 additions & 10 deletions pkg/auth/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,10 @@ const (
// or data key provided as plaintext.
//
// The returned ciphertext data consists of:
// iv | AEAD ID | nonce | encrypted data
// 32 1 12 ~ len(data)
// AEAD ID | iv | nonce | encrypted data
// 1 16 12 ~ len(data)
func encrypt(plaintext, associatedData []byte) ([]byte, error) {
iv, err := sioutil.Random(32) // 32 bytes IV
iv, err := sioutil.Random(16) // 16 bytes IV
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -186,7 +186,7 @@ func encrypt(plaintext, associatedData []byte) ([]byte, error) {
}
case c20p1305:
var sealingKey []byte
sealingKey, err = chacha20.HChaCha20(derivedKey, iv[:16]) // HChaCha20 expects nonce of 16 bytes
sealingKey, err = chacha20.HChaCha20(derivedKey, iv) // HChaCha20 expects nonce of 16 bytes
if err != nil {
return nil, err
}
Expand All @@ -202,11 +202,11 @@ func encrypt(plaintext, associatedData []byte) ([]byte, error) {

sealedBytes := aead.Seal(nil, nonce, plaintext, associatedData)

// ciphertext = iv | AEAD ID | nonce | sealed bytes
// ciphertext = AEAD ID | iv | nonce | sealed bytes

var buf bytes.Buffer
buf.Write(iv)
buf.WriteByte(algorithm)
buf.Write(iv)
buf.Write(nonce)
buf.Write(sealedBytes)

Expand All @@ -218,16 +218,16 @@ func encrypt(plaintext, associatedData []byte) ([]byte, error) {
// and a pbkdf2 derived key
func decrypt(ciphertext []byte, associatedData []byte) ([]byte, error) {
var (
iv [32]byte
algorithm [1]byte
iv [16]byte
nonce [12]byte // This depends on the AEAD but both used ciphers have the same nonce length.
)

r := bytes.NewReader(ciphertext)
if _, err := io.ReadFull(r, iv[:]); err != nil {
if _, err := io.ReadFull(r, algorithm[:]); err != nil {
return nil, err
}
if _, err := io.ReadFull(r, algorithm[:]); err != nil {
if _, err := io.ReadFull(r, iv[:]); err != nil {
return nil, err
}
if _, err := io.ReadFull(r, nonce[:]); err != nil {
Expand All @@ -249,7 +249,7 @@ func decrypt(ciphertext []byte, associatedData []byte) ([]byte, error) {
return nil, err
}
case c20p1305:
sealingKey, err := chacha20.HChaCha20(derivedKey, iv[:16]) // HChaCha20 expects nonce of 16 bytes
sealingKey, err := chacha20.HChaCha20(derivedKey, iv[:]) // HChaCha20 expects nonce of 16 bytes
if err != nil {
return nil, err
}
Expand Down

0 comments on commit c0ee739

Please sign in to comment.