# Setting MAC field to all-zero to indicate unencrypted data

I'm currently working on a project where we transmit data between two systems. The data is generally encrypted before transmission, however there are certain transmissions that are unencrypted.

We use the following data format for transmission:

Encrypted-Data [64Bytes] | MAC [16 Bytes]


The receiving system first decrypts and verifies the authenticity of the messages origin, then the data is processed further.

My solution to this problem is setting all bits of the MAC to zero before transmission, to indicate that the message is unencrypted.

Now my questions:

1. can a MAC calculation result in zero (we use Poly1305)?
2. is it good practice to use the MAC set to zero to indicate unencrypted data?
• Why not encrypt everything? My concern is that the unencrypted and unauthenticated data can be mutated by an attacker to trick the receiver into assuming something that is not true. – Awn Jul 11 '19 at 9:36
• I can think of many reasons why encrypting data may not be a good idea (access to key by sender or receiver, performance reasons, too much data encrypted by same key etc.) but yeah, generally good advice to just encrypt it - it should probably be the default. – Maarten Bodewes Jul 11 '19 at 9:46
• @Awn Thanks for your input. We implemented some kind of application pairing with the devices we communicate with. During this pairing process we exchange unencrypted data like the public key (ECDH). We are aware of the secuirty risk by enabling unencrypted data exchange, but make checks according to the messages content, and reject unencrypted messages we expect as encrypted. – david Jul 11 '19 at 9:49
• One can use just 1 bit to indicate the encryption. – kelalaka Jul 11 '19 at 14:52

Yes, a MAC can of course have an all zero result. But that doesn't matter, because the chance of that happening should be the same as taking a random choice out of a set where each element has the same probability, i.e. has a uniform distribution.

So the chance of an all zero popping up should - in this case - be about $$1$$ in $$2^{128}$$, assuming of course that the message changes every time (without pre-knowledge the chance would be the same, but identical input will of course result in identical MAC-values, so there's that). Now that is the same chance of guessing an AES-128 key in one go, i.e. the chance that it will happen is negligible. So in practice your scheme could be used fine.

Remind yourself though that using magical values should be avoided as a general principle. Even worse is of course that you remove all security provided by the MAC if the message is not encrypted. The integrity and authenticity provided by the MAC have value for unencrypted messages as well.

So yeah, you could certainly use the scheme, but I would rather sacrifice any other bit for this. I would not call it good practice. I'd only use the scheme if there was no other bit to sacrifice (i.e. the protocol is already established and I now have to perform a hack to put in extra options).

[EDIT] Note that an adversary in a scheme with optional MAC can send you any (unencrypted) message. Generally we require a MAC to avoid that situation.

• Thanks for your answer. So if I understand you correctly it would be better to use a message format like: | EncryptionFlag | Data | Mac | and use the flag to indicate if the data is encrypted. An then still use the MAC to ensure integrity and authenticity. – david Jul 11 '19 at 9:33
• Yes, exactly. And while you're at it, you could use the other bits in that byte as a version indicator so that you can switch to a new version of the protocol at any stage. Otherwise you're forever stuck at your current design if you want to avoid hacks. – Maarten Bodewes Jul 11 '19 at 9:37

Another option is to use an AEAD scheme (authenticated encryption with additional data). In each packet you can both send some data to be encrypted and authenticated and some data to be only authenticated. For example, ChaCha20-Poly1305 or AES-GCM.

• True, but that doesn't solve the issue on how to indicate which one of the two schemes is being used. This is not something that the algorithms decide by themselves; in other words: it is part of the protocol rather than the algorithm. – Maarten Bodewes Jul 11 '19 at 12:06