RustCrypto / block-modes

Collection of generic block mode algorithms written in pure Rust
64 stars 13 forks source link

Intermediate IV exposing for save/restore APIs #5

Closed zugzwang closed 2 years ago

zugzwang commented 3 years ago

Hello folks, would you accept a PR similar to block-ciphers/pull/227 as suggested by @newpavlov, allowing to serialize ciphers and continue operation later? Note that even without the exposure, the cryptor can recover the internal IV state at any moment, but this would require additional caching (one full ciphertext block for CFB, and one ciphertext block + one plaintext block + one xor for OFB). Perhaps we could implement the same IvState trait.

Regards

cc. @jethrogb

tarcieri commented 3 years ago

Sounds good to me. @newpavlov, what do you think?

zugzwang commented 3 years ago

One detail is that the IvState extends a BlockMode. In hindsight, I could have made it more general so that a stream cipher can implement it (IvState only needs Self::IvSize). Should I be change it? Or should the stream cipher have its own trait?

tarcieri commented 3 years ago

Unifying it into a single trait sounds good to me and follows the general course of what @newpavlov has been working on in the cipher crate

newpavlov commented 3 years ago

Sounds good to me as well, but, as you've noticed, it's blocked on introduction of a block-level trait for stream ciphers. Right now we have only slice-based traits which handle buffering internally, thus the IvState trait will not be a good fit here. If you need this functionality ASAP, then as a temporary solution we can add CTR to the block-modes crate. We already duplicate the two CFB modes, so I think it will be fine to duplicate CTR as well.

jethrogb commented 3 years ago

it's blocked on introduction of a block-level trait for stream ciphers

I don't understand this part? The whole point is to use the byte-based interface.

zugzwang commented 3 years ago

I should have emphasized on the fact that we currently need this for CFB and OFB (for CTR, current_pos and seek do the job). We prefer to use CFB and OFB within the stream-ciphers crate, since as @jethrogb mentions, we want byte granularity. From what I see, they both define one internal block that would allow serialization and that the client could recover at any time hélas with some effort (Cfb.iv and Ofb.block).

newpavlov commented 2 years ago

I think #2 should resolve this issue. For performance reasons we store encrypted IV, so implementation of the IvState trait in the CFB case also requires BlockDecrypt bound.

Also note that neither cfb, nor cipher crates include built-in buffering for async stream ciphers. We only provide consuming byte-level methods, so you may have to implement your own block buffering.

cfal commented 2 years ago

Also note that neither cfb, nor cipher crates include built-in buffering for async stream ciphers. We only provide consuming byte-level methods, so you may have to implement your own block buffering.

did this used to be supported? AsyncStreamCipher took an &mut self which allowed it to be used in a streaming manner.. is there a replacement for this or another issue relating to this change?

newpavlov commented 2 years ago

@cfal Yes, it was. But I think that for most cases the current non-buffering approach is sufficient. It's still possible to build a buffering wrapper around the AsyncStreamCipher trait, but currently it's not included into cipher. If you need such wrapper, please open an issue in the traits repository.

cfal commented 2 years ago

@newpavlov thank you! created https://github.com/RustCrypto/traits/issues/964