Coder Social home page Coder Social logo

Comments (8)

cbeck88 avatar cbeck88 commented on July 17, 2024 1

i don't think there is, let me look at those two versions to confirm they meet my needs

from aeads.

tarcieri avatar tarcieri commented on July 17, 2024 1

FYI: I just cut a ctr v0.6.0-pre release which includes a Ctr32BE type, which as of #227 is now used by the aes-gcm crate.

You should be able to use this as part of your constant-time aes-gcm (or aes-gcm-siv with Ctr32LE) implementation.

from aeads.

tarcieri avatar tarcieri commented on July 17, 2024

Is there a specific reason you need this to work with AES-GCM? Otherwise AES-GCM-SIV or AES-SIV already provide this property.

from aeads.

cbeck88 avatar cbeck88 commented on July 17, 2024

It seems to me that aes-gcm-siv does this right now:

https://github.com/RustCrypto/AEADs/blob/master/aes-gcm-siv/src/lib.rs#L347

    /// Decrypt the given message, first authenticating ciphertext integrity
    /// and returning an error if it's been tampered with.
    pub(crate) fn decrypt_in_place_detached(
        mut self,
        associated_data: &[u8],
        buffer: &mut [u8],
        tag: &Tag,
    ) -> Result<(), Error> {
        if buffer.len() as u64 > C_MAX || associated_data.len() as u64 > A_MAX {
            return Err(Error);
        }

        self.polyval.update_padded(associated_data);
        let mut ctr = Ctr32::new(tag);

        for chunk in buffer.chunks_mut(BLOCK_SIZE * B::ParBlocks::to_usize()) {
            ctr.apply_keystream(&self.enc_cipher, chunk);
            self.polyval.update_padded(chunk);
        }

        let expected_tag = self.finish_tag(associated_data.len(), buffer.len());

        use subtle::ConstantTimeEq;
        if expected_tag.ct_eq(&tag).unwrap_u8() == 1 {
            Ok(())
        } else {
            // On MAC verify failure, re-encrypt the plaintext buffer to
            // prevent accidental exposure.
            Ctr32::new(tag).apply_keystream(&self.enc_cipher, buffer);
            Err(Error)
        }
    }

So it's still branching on the mac, and conditionally touching the buffer, which
is what I'd like to avoid.

The aes-siv one looks like this:

https://github.com/RustCrypto/AEADs/blob/master/aes-siv/src/lib.rs#L225

    fn decrypt_in_place_detached(
        &self,
        nonce: &GenericArray<u8, Self::NonceSize>,
        associated_data: &[u8],
        buffer: &mut [u8],
        tag: &GenericArray<u8, Self::TagSize>,
    ) -> Result<(), Error> {
        Siv::<C, M>::new(self.key.clone()).decrypt_in_place_detached(
            &[associated_data, nonce.as_slice()],
            buffer,
            tag,
        )
    }

calling out to

https://github.com/RustCrypto/AEADs/blob/master/aes-siv/src/siv.rs#L207

    pub fn decrypt_in_place_detached<I, T>(
        &mut self,
        headers: I,
        ciphertext: &mut [u8],
        siv_tag: &Tag,
    ) -> Result<(), Error>
    where
        I: IntoIterator<Item = T>,
        T: AsRef<[u8]>,
    {
        self.xor_with_keystream(*siv_tag, ciphertext);
        let computed_siv_tag = s2v(&mut self.mac, headers, ciphertext)?;

        // Note: constant-time comparison of `crypto_mac::Output` values
        if crypto_mac::Output::<M>::new(computed_siv_tag) == crypto_mac::Output::new(*siv_tag) {
            Ok(())
        } else {
            // Re-encrypt the decrypted plaintext to avoid revealing it
            self.xor_with_keystream(*siv_tag, ciphertext);
            Err(Error)
        }
    }

So it's very similar to the aes-gcm-siv one.

I think in both of these cases, if there were a ct_decrypt_in_place_detached,
these functions could call that, and then branch on the result of mac check and
do the re-encryption -- but users who need not to have that branch could call
ct_decrypt_in_place_detached?

from aeads.

tarcieri avatar tarcieri commented on July 17, 2024

Yeah, you're right the re-encryption makes it variable-time.

Honestly I think maybe your best bet is to build a special crate for your use case. Avoiding that re-encryption step, in either an AES-GCM implementation that still decrypts the buffer, or an AES-(GCM-)-SIV, risks exposing the buffer containing the unauthenticated decryption, and since everything is built on in-place encryption, I'm not sure how you would avoid that with this sort of interface.

I'm not really a fan of exposing that as part of the API in these crates, but for your use case, it might be fine (especially if you had an always-allocating version which first copies the ciphertext into a Vec return buffer that can be discarded).

from aeads.

cbeck88 avatar cbeck88 commented on July 17, 2024

okay -- thank you!

from aeads.

cbeck88 avatar cbeck88 commented on July 17, 2024

For my understanding -- why is it so bad to expose the buffer containing the unauthenticated decryption? Presumably that buffer is just noise, right? Or is it like, if the attacker can get many such buffers then they can perhaps mount an attack, for some cipher types?

from aeads.

tarcieri avatar tarcieri commented on July 17, 2024

Or is it like, if the attacker can get many such buffers then they can perhaps mount an attack, for some cipher types?

Yes, if the attacker can learn anything from the decryption of the buffer, chosen ciphertext attacks become possible, which is what AEAD modes are supposed to strategically prevent.

from aeads.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.