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

GCM allows the empty IV, which is dangerous #169

Open
emillon opened this issue Sep 30, 2019 · 0 comments
Open

GCM allows the empty IV, which is dangerous #169

emillon opened this issue Sep 30, 2019 · 0 comments

Comments

@emillon
Copy link

emillon commented Sep 30, 2019

Hi,

GCM accepts the IV of length 0 and can use it to encrypt data. Quoting Wycheproof tests, this should be rejected with an error:

AES-GCM does not allow an IV of length 0. Encrypting with such an IV leaks the authentication key. Hence using an IV of length 0 is insecure even if the key itself is only used for a single encryption.

Here's a piece of code that demonstrates the issue:

module GCM = Nocrypto.Cipher_block.AES.GCM

let pp_result ppf { GCM.message; tag } =
  Format.fprintf ppf "Message:\n%a\nTag:\n%a\n" Cstruct.hexdump_pp message
    Cstruct.hexdump_pp tag

let () =
  let key =
    GCM.of_secret
      (Cstruct.of_hex "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f")
  in
  let iv = Cstruct.empty in
  GCM.encrypt ~key ~iv (Cstruct.of_string "hello")
  |> Format.printf "%a\n" pp_result

More background:

AES-GCM allows IVs of bit length 1 .. 2^64-1. See NIST SP 800 38d, Section 5.2.1.1
http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
Disallowing IVs of length 0 is necessary for the following reason: if an empty IV is used
then the tag is an evaluation of a polynomial with the hash subkey as the value. Since the
polynomial can be derived from the ciphertext it is known to an attacker. Therefore, any
message encrypted with an empty IV leaks the hash subkey. In particular, encrypting an empty
plaintext with an empty IV results in a ciphertext having a tag that is equal to the hash
subkey used in AES-GCM. I.e. both are the same as encrypting an all zero block.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant