Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto/cipher: io.Reader/Writer implementations for BlockMode #28153

Closed
WillSewell opened this issue Oct 11, 2018 · 5 comments
Closed

crypto/cipher: io.Reader/Writer implementations for BlockMode #28153

WillSewell opened this issue Oct 11, 2018 · 5 comments
Labels
FeatureRequest FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@WillSewell
Copy link

WillSewell commented Oct 11, 2018

The cipher.Stream interface can be wrapped in a cipher.StreamReader or cipher.StreamWriter for io.Reader/io.Writer implementations. It was be nice to have the same interface for cipher.BlockMode.

The challenge with cipher.BlockMode is that CryptBlocks must be run on byte slices whose lengths are multiples of the block size. I don't see this being a fundamental problem, but it will complicate the implementation. For the Reader, I imagine it would consist of two internal buffers as the state: encrypted to store encrypted bytes read from the underlying reader, and decrypted to store decrypted bytes to by copy out whenever Read is called. It would operate in two phases: If len(decrypted) == 0, then call Read on the underlying Reader until there is at least BlockSize bytes in encrypted. Then we can decrypt as many blocks as possible from encrypted into decrypted, and return these whenever Read is called until len(decrypted) == 0 again.

I haven't though as much about the Writer, but I suspect it will operate in a similar way.

The implementation is just a rough idea at the moment. I'm creating this issue mainly to see whether there is interest in the idea. If there is, I am happy to write a prototype.

@bcmills
Copy link
Contributor

bcmills commented Oct 23, 2018

CC @FiloSottile

@bcmills bcmills changed the title Lack of Reader/Writer implementations for cipher.BlockMode crypto/cipher: io.Reader/Writer implementations for BlockMode Oct 23, 2018
@bcmills bcmills added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. FeatureRequest labels Oct 23, 2018
@bcmills bcmills added this to the Unplanned milestone Oct 23, 2018
@connesc
Copy link

connesc commented May 29, 2020

I have faced the same issue recently and ended up writing my own io.Reader and io.Writer.
Interest seems to be rather limited, but in case it can help, here is my package: github.com/connesc/cipherio.

@xaionaro
Copy link
Contributor

xaionaro commented Dec 22, 2021

@FiloSottile : I saw @bcmills CC-ed you and no response followed. Hoping, may be you just forgot to reply here and it is still possible to get your comment on this? :)

Personally do not think one should think about specific implementation right now (as in the issue description), but IMHO it is still worth to decide if one should provide io.Reader/io.Writer for block ciphers (and properly handle paddings). It seems like a pretty fundamental/basic thing (for example this padding handling is happening in tls.Conn). And if one should then how? Should we go to https://github.com/golang/proposal and follow the instruction there?

Another person made a remark that the problem is solved in other languages, for example in Java it is: https://docs.oracle.com/javase/7/docs/api/javax/crypto/CipherOutputStream.html

@FiloSottile
Copy link
Contributor

We won't provide an easy to use API for unauthenticated block modes, because we don't want them to be easy to use.

Approximately no application should be directly using unauthenticated block (or stream) ciphers, as they let the attacker modify the message, which systematically leads to confidentiality breaks (such as with padding oracle attacks). They are just a building block for AEADs, which is what applications should use instead.

Applications that do need to handle streaming data should use chunked AEAD schemes, where each chunk is authenticated before being released, such as STREAM (#43774, #49782 (comment)).

/cc @golang/security

@xaionaro
Copy link
Contributor

xaionaro commented Jan 4, 2022

(#43774, #49782 (comment)).

Thank you for the references. Will track the progress there.

@golang golang locked and limited conversation to collaborators Jan 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FeatureRequest FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

6 participants