Encryption DOES NOT automatically protect the data against modification.
For example, let's say we have a stream cipher that is simply a PRNG (random number generator), where the key is the seed. Encryption works by generating random numbers in sequence (the keystream) and exclusing-or'ing them with the plaintext. If an attacker knows some plaintext and ciphertext bytes at a particular point, he can xor them together to recover the keystream for those bytes. From there, he can simply pick some new plaintext bytes and xor them with the keystream.
Often the attacker need not know the plaintext to achieve something. Let's take an example where an attacker simply needs to corrupt one particular field in a packet's internal data. He does not know what its value is, but he doesn't need to. Simply by replacing those bytes of ciphertext with random numbers, he has changed the plaintext.
This is particularly interesting in block ciphers where padding is used, as it opens us up to padding oracle attacks. These attacks involve tweaking ciphertext in a way that alters the padding string, and observing the result. Other attacks such as BEAST and the Lucky Thirteen Attack involve modification of ciphertext in a similar way. These tend to rely on the fact that some implementations blindly decrypt data before performing any kind of integrity checks.
Additionally, it may be possible to re-send an encrypted packet, which might cause some behaviour on the client or server. An example of this might be a command to toggle the enabled state of the firewall. This is called a replay attack, and encryption on its own will not protect against it. In fact, integrity checks often don't fix this problem either.
There are, in fact, three primary properties that are desirable in a secure communications scheme:
- Confidentiality - The ability to prevent eavesdroppers from discovering the plaintext message, or information about the plaintext message (e.g. hamming weight).
- Integrity - The ability to prevent an active attacker from modifying the message without the legitimate users noticing. This is usually provided via a Message Integrity Code (MIC).
- Authenticity - The ability to prove that a message was generated by a particular party, and prevent forgery of new messages. This is usually provided via a Message Authentication Code (MAC). Note that authenticity automatically implies integrity.
The fact that the MAC and MIC can be provided by a single appropriately chosen HMAC hash scheme (sometimes called a MAIC) in certain circumstances is completely incidental. The semantic difference between integrity and authenticity is a real one, in that you can have integrity without authenticity, and such a system may still present problems.
The real distinction between integrity and authenticity is a tricky one to define, as Thomas Pornin pointed out to me in chat:
There's a tricky definition point there. Integrity is that you get the "right data", but according to what notion of "right" ? How comes the data from the attacker is not "right" ? If you answer "because that's from the attacker, not from the right client" then you are doing authentication...
It's a bit of a grey-area, but either way we can all agree that authentication is important.
An alternative to using a separate MAC / MIC is to use an authenticated block cipher mode, such as Gallois/Counter Mode (GCM) or EAX mode.