Skip to content

Commit c0ee739

Browse files
authored
IV generation for ChaCha20 poly auth scheme (#283)
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.
1 parent 1dc9949 commit c0ee739

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

pkg/auth/token.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,10 @@ const (
155155
// or data key provided as plaintext.
156156
//
157157
// The returned ciphertext data consists of:
158-
// iv | AEAD ID | nonce | encrypted data
159-
// 32 1 12 ~ len(data)
158+
// AEAD ID | iv | nonce | encrypted data
159+
// 1 16 12 ~ len(data)
160160
func encrypt(plaintext, associatedData []byte) ([]byte, error) {
161-
iv, err := sioutil.Random(32) // 32 bytes IV
161+
iv, err := sioutil.Random(16) // 16 bytes IV
162162
if err != nil {
163163
return nil, err
164164
}
@@ -186,7 +186,7 @@ func encrypt(plaintext, associatedData []byte) ([]byte, error) {
186186
}
187187
case c20p1305:
188188
var sealingKey []byte
189-
sealingKey, err = chacha20.HChaCha20(derivedKey, iv[:16]) // HChaCha20 expects nonce of 16 bytes
189+
sealingKey, err = chacha20.HChaCha20(derivedKey, iv) // HChaCha20 expects nonce of 16 bytes
190190
if err != nil {
191191
return nil, err
192192
}
@@ -202,11 +202,11 @@ func encrypt(plaintext, associatedData []byte) ([]byte, error) {
202202

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

205-
// ciphertext = iv | AEAD ID | nonce | sealed bytes
205+
// ciphertext = AEAD ID | iv | nonce | sealed bytes
206206

207207
var buf bytes.Buffer
208-
buf.Write(iv)
209208
buf.WriteByte(algorithm)
209+
buf.Write(iv)
210210
buf.Write(nonce)
211211
buf.Write(sealedBytes)
212212

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

226226
r := bytes.NewReader(ciphertext)
227-
if _, err := io.ReadFull(r, iv[:]); err != nil {
227+
if _, err := io.ReadFull(r, algorithm[:]); err != nil {
228228
return nil, err
229229
}
230-
if _, err := io.ReadFull(r, algorithm[:]); err != nil {
230+
if _, err := io.ReadFull(r, iv[:]); err != nil {
231231
return nil, err
232232
}
233233
if _, err := io.ReadFull(r, nonce[:]); err != nil {
@@ -249,7 +249,7 @@ func decrypt(ciphertext []byte, associatedData []byte) ([]byte, error) {
249249
return nil, err
250250
}
251251
case c20p1305:
252-
sealingKey, err := chacha20.HChaCha20(derivedKey, iv[:16]) // HChaCha20 expects nonce of 16 bytes
252+
sealingKey, err := chacha20.HChaCha20(derivedKey, iv[:]) // HChaCha20 expects nonce of 16 bytes
253253
if err != nil {
254254
return nil, err
255255
}

0 commit comments

Comments
 (0)