8000 Go: Streaming AEAD decryption keeps a full copy of the stream's contents in memory · Issue #594 · tink-crypto/tink · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
This repository was archived by the owner on Apr 17, 2024. It is now read-only.
This repository was archived by the owner on Apr 17, 2024. It is now read-only.
Go: Streaming AEAD decryption keeps a full copy of the stream's contents in memory #594
Closed
@vonhollen

Description

@vonhollen

Describe the bug:

The reader returned by calling NewDecryptingReader(in) on the result of streamingaead.New(handle) keeps the entire contents of in in-memory until the reader is garbage collected.

This happens because the ciphertext stream is tee'd to a buffer here, and that's what's passed to the primitive's real NewDecryptionReader implementation:
https://github.com/google/tink/blob/645c17cbd121b9db7c6c336521c2c37717003332/go/streamingaead/decrypt_reader.go#L67-L71

That buffer makes it possible to rewind the stream and try another key if the first one fails, but the buffer isn't just used while finding the correct key. It's still referenced by the io.TeeReader implementation, so reading a 1GiB stream will allocate more than 1GiB of memory.

Going around streamingaead.New(handle) by turning the primary primitive into a tink.StreamingAEAD and calling NewDecryptingReader(...) on that works around the problem and the process consumes megabytes of memory instead of gigabytes on large streams.

What was the expected behavior?

Streaming AEAD memory usage during decryption should not increase linearly with the stream length.

One fix is to implement a reader that replaces the tee+buffer with a buffer that can be deactivated once the matching key is found.

How can we reproduce the bug?

Example of the problem and the workaround that shows ideal/expected memory usage:
https://gist.github.com/vonhollen/64d51c56bd9d2294428da57a552ed457

Do you have any debugging information?

When running the example above, you'll see the tee'd buffer in the heap summary near the end:

Top in-use heap objects:
#1 size=1023.05MiB objects=1
      bytes.makeSlice buffer.go:229
      bytes.(*Buffer).grow buffer.go:142
      bytes.(*Buffer).Write buffer.go:172
      io.(*teeReader).Read io.go:574
      io.ReadAtLeast io.go:331
      io.ReadFull io.go:350
      tink/go/streamingaead/subtle/noncebased/noncebased.(*Reader).Read tink/go/streamingaead/subtle/noncebased/noncebased.go:280
      tink/go/streamingaead/streamingaead.(*decryptReader).Read tink/go/streamingaead/decrypt_reader.go:46
      main.main streammemoryusage.go:70

Provide your version information:

  • Language: Go
  • Version:
  • Environment: Debian

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    0