randombit / botan

Cryptography Toolkit
https://botan.randombit.net
BSD 2-Clause "Simplified" License
2.56k stars 562 forks source link

AES/GCM and empty nonce #2612

Open RobLinux opened 3 years ago

RobLinux commented 3 years ago

I'm trying to get this example working (cyberchef link) : https://tinyurl.com/y3avb7w6 in botan.

I've tried this : `std::unique_ptr enc = Botan::AEAD_Mode::create("AES-256/GCM", Botan::DECRYPTION); enc->set_key(unwrappedKey.GetBytes(), (std::size_t)unwrappedKey.Size());

                        enc->start_msg(nullptr, 0);

                        Botan::SecureVector<uint8_t> secEncrypted(cryptedData.GetBytes(), cryptedData.GetBytes() + cryptedData.Size());
                        enc->finish(secEncrypted);

                        decryptedData.Write(secEncrypted.data(), secEncrypted.size());
                        decryptedData.ToLog(0, decryptedData.Size(), decryptedData.Size());  `

but it seems botan is not allowing for an empty IV. I've tried many IVs wihout success (16 bytes array of 0, 1 byte array of 0, ...)

What am I doing wrong here ?

randombit commented 3 years ago

GCM specification does not allow for length zero nonces. Any other size nonce should work though.

RobLinux commented 3 years ago

Yeah I read the SP800-38d specifications and you're right.

But is Cyberchef (which is https://github.com/digitalbazaar/forge behind) having a custom implementation allowing an empty IV? (and yes always them, Apple CoreCrypto allows it too).

How could I decrypt that still using Botan ?

randombit commented 3 years ago

Many implementations do support it as an extension of sorts. In fact up to 59af940718918e Botan behaved the same but was changed to prohibit it as it is not allowed by FIPS.

Can you confirm, CoreCrypto allows this? If so I think we should probably accept it, FIPS or no.

RobLinux commented 3 years ago

After reviewing the code I could see that it has a legacy function because they still use some GCM without IV within their iCloud protocol. I guess it was pre FIPS validation

: /*! @function ccgcm_set_iv_legacy @abstract Set the IV for encryption.

@param mode Descriptor for the mode @param ctx Context for this instance @param iv_nbytes Length of the IV in bytes @param iv Initialization vector

@result 0 iff successful.

@discussion Identical to @p ccgcm_set_iv except that it allows zero-length IVs.

@warning Zero-length IVs nullify the authenticity guarantees of GCM.

@warning Do not use this function in new applications. / int ccgcm_set_iv_legacy(const struct ccmode_gcm mode, ccgcm_ctx ctx, size_t iv_nbytes, const void iv);

I’ll check the commit and maybe implement a custom GCM mode that allows it in the mean time. Thanks for the quick answer as always!

randombit commented 3 years ago

The answer here

https://crypto.stackexchange.com/questions/87886/what-are-the-implications-of-allowing-a-zero-length-gcm-nonce

seems to me to be correct and does imply that it in at least some circumstances using an empty nonce with GCM, even just once (without any nonce-reuse) results in a rather catastrophic failure. So I'm hesitant to support this.

OTOH it does appear that OpenSSL and BoringSSL both allow this. So maybe we can enable it using some special build flag or something? IDK. Can you give any background on why you need empty GCM nonce?

mouse07410 commented 3 years ago

I'm rather doubtful of the usefulness (and safety!) of the enough nonce for GCM, and write recommend not implementing it.

There's AES-GCM-SIV mode, which I hope Botan would support. There an empty nonce would be fine.

randombit commented 3 years ago

Yes AES-GCM-SIV is fine (though TBH I prefer SIV-PMAC on ascetic grounds), it will be supported whenever either someone sends a patch or when I have the time to take up any of the 2 or 3 orgs who have offered to pay for it.