3

I have a library which implements AES GCM algorithm. However, as you know even a single nonce reuse can have catastrophic results.

As we can't guarantee a unique IV every time, I would like to run the SIV (Synthetic Initialization Vector) on the nonce every time.

I want to implement the SIV outside of the AES GCM. As, I am not a fan of mathematics, I really find it hard to understand the AES-GCM-SIV spec.

However, I can't find any sample implementation of the SIV anywhere. Can you please kindly help me in understanding and in implementation of SIV?

1 Answers1

5

It sounds like you're thinking of AES-GCM-SIV as "AES-GCM with an SIV layer on top." It's not. Rather, AES-GCM-SIV is a separate encryption mode build out of similar (but not identical) components as AES-GCM, and where the components are combined in a different way. While AES-GCM-SIV is in some ways similar to AES-GCM, you can't actually implement AES-GCM-SIV as a wrapper on top of an existing library that implements AES-GCM.

What makes things a bit confusing is that there is also something called the generic "SIV construction" that allows a nonce-misuse-resistant authenticated encryption mode to be constructed out of any conventional (non-authenticated) encryption mode meeting certain technical criteria plus any pseurodandom function (PRF) on the plaintext space. For example, AES-SIV (RFC 5297) is an instance of the SIV construction with AES-CTR as the encryption mode and CMAC* (a multi-input variant of CMAC) as the pseudorandom function, while AES-GCM-SIV is essentially an instance of the SIV construction with (again) AES-CTR as the encryption mode and POLYVAL (a variant of the AES-GCM pseudorandom function GHASH) as the PRF.

But that doesn't mean that you can just take an AES-GCM implementation and use it to implement AES-GCM-SIV, at least not without first pulling it apart into its component parts. And even then, the components of the two schemes (as standardized in their respective RFCs) differ in some details (like byte order; see RFC 8452 appendix A), so you can't just reuse the parts without modification, either.

Technically, I believe you could implement AES-GCM-SIV on top of GHASH and AES-CTR, if your crypto library exposes both of those directly. However, that would require implementing POLYVAL on top of GHASH, which, while technically possible, is somewhat awkward and inefficient due different byte orders used by the two hashes.

Ilmari Karonen
  • 46,120
  • 5
  • 105
  • 181
  • 1
    Note that technically neither GHASH nor POLYVAL are PRFs nor claim to be. And the implementation of POLYVAL on top if GHASH isn't really that slow, especially if you can use the GHASH code in a non black-box way to eg change the input decoding from big to little endian. – SEJPM Jan 30 '21 at 19:26
  • 1
    @SEJPM: True. GHASH/POLYVAL plus AES encryption of the result is a PRF, though, and is used as such in AES-GCM-SIV. (And I was specifically thinking of black-box implementation reuse; if you can modify the code, the adjustments needed to convert between GHASH and POLYVAL are indeed not that major.) – Ilmari Karonen Jan 30 '21 at 19:33
  • @IlmariKaronen Is there any way to achieve the concept of unique initialization vector around AES-GCM even though a nonce is reused? – cpp_enthusiast Feb 09 '21 at 15:07
  • @cpp_enthusiast: if you're just using AES-GCM as a black box, no. At least not practically. Technically, if you had AES-GCM and a PRF, then I guess you could use the PRF to derive a synthetic IV from the key and the plaintext. And technically you could use AES-GCM itself as a PRF, e.g. by encrypting an empty plaintext with the PRF input as associated data. But it would be a huge ugly kluge (about as ugly as the "PBKDF2-SIV" construction I jokingly proposed here), and also needlessly slow since you'd basically be authenticating the message twice. – Ilmari Karonen Feb 09 '21 at 15:31
  • @IlmariKaronen then I can use HMAC and feed the key and data (possibly a monotonic counter) to generate the unique IV. Does it make sense? – cpp_enthusiast Feb 09 '21 at 15:35
  • @cpp_enthusiast: If you don't also feed the plaintext to HMAC (and verify it after decryption) you don't really have SIV, but just plain old AES-GCM with an encrypted (well, hashed) counter as the IV. In particular, counter repeats will still lead to IV repeats. And if you can ensure that the counter never repeats, you might as well just use it directly as the AES-GCM IV. (Conversely, if you do also feed the plaintext to HMAC, you can in principle obtain a secure SIV construction. But then using AES-GCM adds no value over plain AES-CTR, since you already have message authentication from HMAC.) – Ilmari Karonen Feb 09 '21 at 15:43