# Safe way to derive IV from the DH shared keys for AES-GCM?

I am preparing to use AES-GCM to make a secure communication program. Here is the procedure

1. DH key exchange to get shared keys
2. SHA256(shared keys)
3. Use AES-GCM to encrypt a message while the key only used once.

However, I was confused about the way to get IV in step3. I know IV/nonuse must be unique. The size of the IV should be 96 bits. I know we can use the timestamp to generate iv. However, I need to generate the IV from the shared key. Is there any method to do it safely?

• Why do you need to generate the nonce from the shared key? The usual practice is using LFSR/Counter as recommended by NIST, or you can combine both as in here. In step 2, better use a KDF, like HKDF. – kelalaka Apr 10 '20 at 9:11
• Hi kelalaka. Thanks for your comment! That requirement is from my supervisor. After doing some research, i'm little confused about the implementation of HKDF. I think the right way to implement it is to do one extract and several expands. However, the package in pycryoptodome combine the extract and expand process together. Therefore, there is no way to do one extract and several expands in this package. Am i misunderstanding the HKDF? – FRANKfisher Apr 10 '20 at 10:35
• As far as I remember, pycryoptodome does that. It is open-source, you can build one for your cause. – kelalaka Apr 10 '20 at 10:42
• You mean the key generated from the HKDF? Just once – FRANKfisher Apr 10 '20 at 13:26
• Thank you so much! – FRANKfisher Apr 10 '20 at 13:46

On a related note, make sure that the same derived key is never used by a given party both to encrypt and decrypt/authenticate because that opens to mirror attacks. If the communication is bidirectional, derivation could use $$\operatorname{HMAC-SHA-xyz}(\mathsf{key}=\text{DH-shared-secret}, \mathsf{message}=\text{sender-ID})$$ as the origin of the session key and IV used by the sender to prepare its message. HMAC internally hashes the shared secret if it more than a certain size (64 bytes for SHA-256), that's fine.
For even stronger assurance: \begin{align} \text{Key}&=\operatorname{HMAC-SHA-xyz}(\mathsf{key}=\text{DH-shared-secret}, \mathsf{message}=\text{'K'}\mathbin\|\text{sender-ID})\\ \text{IV}&=\operatorname{HMAC-SHA-xyz}(\mathsf{key}=\text{DH-shared-secret}, \mathsf{message}=\text{'I'}\mathbin\|\text{sender-ID}) \end{align}