Need to dynamically configure counter limits in CTR stream cipher
Currently working on AES-CTR support in Deno .. and W3C WebCrypto requires that the counter increments be limited in "N" RHS bits, such that the LHS is constant during stream operations. This is based on SP800-38 Annex B1.
Tried to hack something based on modified Ctr128BE trait but have been unable to configure the increment due to, for example, visibility of counter property of Ctr<..> or difficulties in passing in as part of Nonce due to inicialization route via NewCipher/FromBlockCipher.
Will happily code this and open a PR, but would like some advice about how to best fit this into current structure and future directions.
If I understood your problem correctly, then it should be possible by implementing a custom CTR flavor. Note that the Ctr type is generic over flavors and Ctr128BE is a simple type alias around the relevant flavor:
type Ctr128BE<B> = Ctr<B, Ctr128BE>;
Your flavor would be generic over counter width represented using typenum.
Your flavor would be generic over counter width represented using
typenum. Thanks for your answer @newpavlov.
Maybe I am missing something, but I tried that with no success. The situation is that we need a Ctrflavor for u128 (aes block size) but with an additional "runtime" parameter, which is the length of the incremented part of counter. The initial nonce value, full width u128 is needed, but only length bits are incremented per block.
For example, 128 bits of nonce .. but counter-length parameter (set by caller) is 4, thus counter has 124 fixed bits from nonce and 4 bits that increment and wrap, repeating the counter values every 16 blocks. Of course, security-wise nobody would do that, but the WebCrypto API allows any value of length between 1 and 128.
Ah, so you need to set the counter width at runtime. Yeah, the current version of the ctr crate can not support it. I think the best approach probably would be to implement it in a separate crate. I've registered webcrypto-ctr for this purpose.
API-wise I think it can be done by not implementing the initialization traits and instead adding inherent methods which would accept width in addition to key/IV or block cipher/IV.
Ah, so you need to set the counter width at runtime. Yeah, the current version of the
ctrcrate can not support it. I think the best approach probably would be to implement it in a separate crate. I've registeredwebcrypto-ctrfor this purpose.API-wise I think it can be done by not implementing the initialization traits and instead adding inherent methods which would accept width in addition to key/IV or block cipher/IV.
@newpavlov I had a go at implementing variable length, based on ciphers-v0.3. In essence, CtrFlavor::generateBlock needs access to counterLength param in order to combine counter and nonce correctly.
Strategies I investigated:
- Add
counterLengthproperty toCtrFlavor
- not easily possible because of conversion to/from
Backendblock.
- Pass
counterLengthas param toCtrFlavor::generateBlockfor each block generated
- Need to modify call sites, specifically guts of
<StreamCipher for Ctr>::try_apply_keystream(). - Need to include redundant param in existing impls of
CtrFlavor - Maybe need to pass param to
Ctr::check_data_len
So, option to either fork/copy the Ctr implementation to webcrypto-ctr, or alter the internals of Ctr/CtrFlavor and adjust. Either approach shall need some peer-review from RustCrypto experts.
What do you suggest? Any trait-trickery you can think of to help here?
So, option to either fork/copy the Ctr implementation to webcrypto-ctr, or alter the internals of Ctr/CtrFlavor and adjust.
I think the best option will be to implement it in a separate crate. Making runtime-variable nonce part of the ctr crate would have a negative performance impact, which we would strongly like to avoid since it's used as an important building block in higher-level crates.
We are currently in the process of block mode crates migration to the RustCrypto/block-modes repository and cipher v0.4. So you probably may want wait a bit before submitting a PR.