block-modes icon indicating copy to clipboard operation
block-modes copied to clipboard

Need to dynamically configure counter limits in CTR stream cipher

Open cryptographix opened this issue 3 years ago • 5 comments

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.

cryptographix avatar Dec 23 '21 00:12 cryptographix

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.

newpavlov avatar Dec 23 '21 03:12 newpavlov

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.

cryptographix avatar Dec 23 '21 07:12 cryptographix

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.

newpavlov avatar Dec 23 '21 08:12 newpavlov

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.

@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:

  1. Add counterLength property to CtrFlavor
  • not easily possible because of conversion to/from Backend block.
  1. Pass counterLength as param to CtrFlavor::generateBlock for 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?

cryptographix avatar Jan 03 '22 17:01 cryptographix

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.

newpavlov avatar Jan 11 '22 00:01 newpavlov