Skip to content

Commit

Permalink
Reuse hmac instance in AES-CTR-HMAC streaming AEAD.
Browse files Browse the repository at this point in the history
For 4k segment size this reduces the number of bytes allocated by almost 5x.

Before:
BenchmarkEncryptDecrypt/AES128_CTR_HMAC_SHA256_4KB-8           9         113506814 ns/op 4923624 B/op       57864 allocs/op

After:
BenchmarkEncryptDecrypt/AES128_CTR_HMAC_SHA256_4KB-8          10         103825294 ns/op 1092451 B/op       33096 allocs/op
PiperOrigin-RevId: 633105527
Change-Id: Ida36ad73c21f014e480cf3ecdd91445d614622f4
  • Loading branch information
juergw authored and copybara-github committed May 13, 2024
1 parent d082851 commit 3b8e748
Showing 1 changed file with 12 additions and 17 deletions.
29 changes: 12 additions & 17 deletions streamingaead/subtle/aes_ctr_hmac.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,7 @@ func (a *AESCTRHMAC) deriveKeys(salt, aad []byte) ([]byte, []byte, error) {

type aesCTRHMACSegmentEncrypter struct {
blockCipher cipher.Block
tagHashFunc func() hash.Hash
tagKey []byte
mac hash.Hash
tagSizeInBytes int
}

Expand All @@ -162,12 +161,11 @@ func (e aesCTRHMACSegmentEncrypter) EncryptSegmentWithDst(dst, segment, nonce []
stream := cipher.NewCTR(e.blockCipher, nonce)
stream.XORKeyStream(ciphertext, segment)

mac := hmac.New(e.tagHashFunc, e.tagKey)
mac.Write(nonce)
mac.Write(ciphertext[:sLen])
tag := mac.Sum(nil)[:e.tagSizeInBytes]
e.mac.Reset()
e.mac.Write(nonce)
e.mac.Write(ciphertext[:sLen])
tag := e.mac.Sum(nil)[:e.tagSizeInBytes]
copy(ciphertext[sLen:], tag)

return ciphertext, nil
}

Expand Down Expand Up @@ -210,8 +208,7 @@ func (a *AESCTRHMAC) NewEncryptingWriter(w io.Writer, aad []byte) (io.WriteClose
W: w,
SegmentEncrypter: aesCTRHMACSegmentEncrypter{
blockCipher: blockCipher,
tagHashFunc: subtle.GetHashFunc(a.tagAlg),
tagKey: hmacKey,
mac: hmac.New(subtle.GetHashFunc(a.tagAlg), hmacKey),
tagSizeInBytes: a.tagSizeInBytes,
},
NonceSize: AESCTRHMACNonceSizeInBytes,
Expand All @@ -227,8 +224,7 @@ func (a *AESCTRHMAC) NewEncryptingWriter(w io.Writer, aad []byte) (io.WriteClose

type aesCTRHMACSegmentDecrypter struct {
blockCipher cipher.Block
tagHashFunc func() hash.Hash
tagKey []byte
mac hash.Hash
tagSizeInBytes int
}

Expand All @@ -253,10 +249,10 @@ func (d aesCTRHMACSegmentDecrypter) DecryptSegmentWithDst(dst, segment, nonce []
}
tag := segment[plaintextLen:]

mac := hmac.New(d.tagHashFunc, d.tagKey)
mac.Write(nonce)
mac.Write(segment[:plaintextLen])
wantTag := mac.Sum(nil)[:d.tagSizeInBytes]
d.mac.Reset()
d.mac.Write(nonce)
d.mac.Write(segment[:plaintextLen])
wantTag := d.mac.Sum(nil)[:d.tagSizeInBytes]
if !hmac.Equal(tag, wantTag) {
return nil, errors.New("tag mismatch")
}
Expand Down Expand Up @@ -307,8 +303,7 @@ func (a *AESCTRHMAC) NewDecryptingReader(r io.Reader, aad []byte) (io.Reader, er
R: r,
SegmentDecrypter: aesCTRHMACSegmentDecrypter{
blockCipher: blockCipher,
tagHashFunc: subtle.GetHashFunc(a.tagAlg),
tagKey: hmacKey,
mac: hmac.New(subtle.GetHashFunc(a.tagAlg), hmacKey),
tagSizeInBytes: a.tagSizeInBytes,
},
NonceSize: AESCTRHMACNonceSizeInBytes,
Expand Down

0 comments on commit 3b8e748

Please sign in to comment.