I'm applying the Arduino Crypto Library for the code fragments.

In the above library, example of encryption and decryption using GCM given as follows:

For encryption:

GCM<AES256> gcm;
gcm.setKey(key, sizeof(key));
gcm.setIV(iv, sizeof(iv));
gcm.addAuthData(adata, sizeof(adata));
gcm.encrypt(ciphertext, plaintext, sizeof(plaintext));
gcm.computeTag(tag, sizeof(tag));

For decryption:

GCM<AES256> gcm;
gcm.setKey(key, sizeof(key));
gcm.setIV(iv, sizeof(iv));
gcm.addAuthData(adata, sizeof(adata));
gcm.decrypt(ciphertext, plaintext, sizeof(plaintext));
if (!gcm.checkTag(tag, sizeof(tag))) {
    // The data was invalid - do not use it.

These are my questions:

  1. Should the IV be unique for each 128 bit text or for each message? How should the next IV be generated? Should we increment the IV by one for each message or for each block of 128 bit?
  2. Does adding the IV in authentication data makes it less secure?
  3. Does sending the computed tag by prepending / appending to the ciphertext, create any vulnerability?
  4. What is the standard way to share the IV & computed tag?
  • 1
    $\begingroup$ All of your questions' answers are actually in the NIST standard 800-38d ,1) No, AES-GCM uses CTR mode. incrementing for each message is insecure. must be randomly generated. 2) It is the standard, IV used for both. 3) The standard way is sending together. 4) See page 14 in the standard $\endgroup$ – kelalaka Dec 10 '18 at 15:58
  • $\begingroup$ @kelalaka incrementing for each message is insecure. must be randomly generated. I think generating the iv randomly, is insecure as there is still a chance that iv become repetitive. So incrementing the iv by message_length_in_bit/128 would be the best way to go. What do you think? It is hard for me to read the specification as I have very little knowledge about cryptography mathematically. $\endgroup$ – QNANK Dec 10 '18 at 16:11
  • $\begingroup$ Correction on the IV part see this. AES-GC $\endgroup$ – kelalaka Dec 10 '18 at 16:35
  • $\begingroup$ Assuming the typically 12 byte IV, using a counter for the IV is cryptographically fine as with GCM the IV is only a nonce. However, implementing a counter securely in the face of all possible issues can be challenging which is why many avoid it. Randomly generating is fine. While there is a possibility for a recurring IVs this is handled in the spec referred to by @kelalaka, see the beginning of Section 8. $\endgroup$ – Swashbuckler Dec 10 '18 at 16:35

1.The IV should be unique for each 128 bit text or for each massage?

Per message. Using an IV of 0 for the first message, 1 for the second, etc is just fine (no matter how long each message is), and is actually fairly common.

2.Is adding the IV in auth data makes it less secure?

No, it doesn't. It also doesn't make it any more secure; however if it makes you feel better, feel free.

3.Is sending the computed tag by pepending/appending to the ciphertext, creates any vulnerability?

No, it doesn't create any problems; as long as the decryptor can unambigiously derive the computed tag, IV and raw ciphertext, any method of transport is fine. In fact:

4.What is the standard way to share the IV & computed Tag?

The most common way is the prepend the IV, and append the computed tag to the ciphertext, and send that as a unit; as above, we don't mind revealing the IV and the tag to an evesdropper; and we'll detect any modification to the IV and the computed tag by an active attacker (except for the possibility that he rolls back the entire message to a previously sent one; GCM can't detect that).

The most common variation I've seen to that is not to send the entire IV, but only a portion (64 bits), and have the other 32 bits shared between the sender and the receiver; this reduces the bandwidth used a tad, and we still can send $2^{64}$ messages per key, which is plenty. Of course, this is an implementation trade-off, with no security implications; you don't need to follow this example.

Also, unrelated to your question, but the Arduino API is not very well thought out. For one, in the decryption phase, the application is supposed to ask for a decryption, and then separately ask for the tag validation. That means that it's up to the application to maintain cryptographic safety; if the application forgets to ask for the validation, then everyone looks like it's working, but you're not actually secure. This is the sort of 'rake-in-the-grass' behavior that we like to stay away from; if they got this wrong, one can only wonder what other things the crypto library authors messed up on...

| improve this answer | |
  • $\begingroup$ Should we point out RFC 5116? I'm always a bit skeptical about it: first of all I think it should be up to the protocol where to put an IV and tag, second, I don't think the tag should be considered part of the ciphertext. $\endgroup$ – Maarten Bodewes Dec 10 '18 at 16:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.