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

Need to dynamically configure counter limits in CTR stream cipher #4

Open
cryptographix opened this issue Dec 23, 2021 · 5 comments
Open

Comments

@cryptographix
Copy link

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.

@newpavlov
Copy link
Member

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.

@cryptographix
Copy link
Author

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.

@newpavlov
Copy link
Member

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.

@cryptographix
Copy link
Author

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?

@newpavlov
Copy link
Member

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 newpavlov transferred this issue from RustCrypto/stream-ciphers Jan 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants