6.4 Choosing a Message Authentication Code
6.4.1 Problem
You need to use a MAC (which yields a
tag that can only be computed correctly on a piece of data by an
entity with a particular secret key), and you want to understand the
important concerns so you can determine which algorithm best suits
your needs.
6.4.2 Solution
In most cases, instead of using a standalone MAC, we recommend that you use a
dual-use mode that provides both authentication and encryption all at
once (such as CWC mode, discussed in Recipe 5.10). Dual-use modes can
also be used for authentication when encryption is not required.
If a dual-use mode does not suit your needs, the best solution
depends on your particular requirements. In general, HMAC is a
popular and well-supported alternative based on hash functions
(it's good for compatibility), and OMAC is a good
solution based on a block cipher (which we see as a strong
advantage). If you care about maximizing efficiency, a hash127-based
MAC is a reasonable solution (though it has some limitations, so CMAC
may be better in such cases; see Recipe 6.13
and Recipe 6.14).
We recommend against using RMAC and UMAC, for reasons discussed in
the following section.
6.4.3 Discussion
|
Do not use the same key for encryption that you use in a MAC. See
Recipe 4.11 for how to overcome this
restriction.
|
|
As with hash functions, there are a large number of available
algorithms for performing message authentication, each with its own
advantages and drawbacks. Besides algorithms designed explicitly for
message authentication, some encryption modes such as CWC provide
message authentication as a side effect. (See Recipe 5.4 for an overview of several such modes, and
Recipe 6.10 for a discussion of CWC.) Such
dual-use modes are designed for general-purpose needs, and they are
high-level enough that it is far more difficult to use these modes in
an insecure manner than regular cryptography.
Table 6-2 lists interesting message authentication
functions, all with provable security properties assuming the
security of the underlying primitive upon which they were based. This
table also compares important properties of those functions. When
comparing speeds, we used an x86-based machine and unoptimized
implementations for testing. Results will vary depending on platform
and other operating conditions. Speeds are measured in cycles per
byte; lower numbers are better.
Table 6-2. MACs and their properties|
CMAC
|
A universal hash and AES
|
~18 cpb
|
~18 cpb
|
Yes
|
No
|
Yes
|
HMAC-SHA1
|
Message digest function
|
90 cpb
|
20 cpb
|
Yes
|
No
|
No
|
MAC127
|
hash127 + AES
|
~6 cpb
|
~6 cpb
|
Yes
|
No
|
Yes
|
OMAC1
|
AES
|
29.5 cpb
|
37 cpb
|
Yes
|
No
|
No
|
OMAC2
|
AES
|
29.5 cpb
|
37 cpb
|
Yes
|
No
|
No
|
PMAC-AES
|
Block cipher
|
72 cpb
|
70 cpb
|
Yes
|
Yes
|
Yes
|
RMAC
|
Block cipher
|
89 cpb
|
80 cpb
|
Yes
|
No
|
No
|
UMAC32
|
UHASH and AES
|
19 cpb
|
cpb
|
No
|
No
|
Yes
|
XMACC-SHA1
|
Any cipher or MD function
|
162 cpb
|
29 cpb
|
Yes
|
Yes
|
Yes
|
Note that our considerations for comparing MACs are different from
our considerations for comparing cryptographic hash functions. First,
all of the MACs we discuss provide a reasonable amount of assurance,
assuming that the underlying construct is secure (though MACs without
nonces do not resist the birthday attack without additional work; see
Recipe 6.12). Second, all of the
cryptographic hash functions we discussed are suitable for hardware,
patent-free, and not parallelizable.
Let's look briefly at the pros and cons of using
these functions.
- CMAC
-
CMAC is the MAC portion of the CWC encryption mode, which can be used
in a standalone fashion. It's built upon a universal
hash function that can be made to run very fast, especially in
hardware. CMAC is discussed in Recipe 6.14.
- HMAC
-
HMAC, discussed in Recipe 6.10, is a widely
used MAC, largely because it was one of the first MAC constructs with
provable security—even though the other MACs on this list also
have provable security (and the proofs for those other MACs tend to
be based on somewhat more favorable assumptions). HMAC is fairly
fast, largely because it performs only two cryptographic operations,
both hashes. One of the hashes is constant time; and the other takes
time proportional to the length of the input, but it
doesn't have the large overhead block ciphers
typically do as a result of hash functions having a very large block
size internally (usually 64 bytes).
HMAC is designed to take a one-way hash function with an arbitrary
input and a key to produce a fixed-sized digest. Therefore, it cannot
use block ciphers, unless you use a construction to turn a block
cipher into a strong hash function, which will significantly slow
down HMAC. If you want to use a block cipher to MAC (which we
recommend), we strongly recommend that you use another alternative.
Note that HMAC does not use a nonce by default, making HMAC
vulnerable to capture replay attacks (and theoretically vulnerable to
a birthday attack). Additional effort can thwart such attacks, as
shown in Recipe 6.12.
- MAC127
-
MAC127 is a MAC we define in Recipe 6.14 that
is based on Dan Bernstein's hash127. This MAC is
very similar to CMAC, but it runs faster in software.
It's the fastest MAC in software that we would
actually recommend using.
- OMAC1, OMAC2
-
OMAC1 and OMAC2, which we discuss in Recipe 6.11, are MACs built upon AES. They are almost
identical to each other, working by running the block cipher in CBC
mode and performing a bit of additional magic at the end. These are
"fixed" versions of a well-known
MAC called CBC-MAC. CBC-MAC, without the kinds of modifications OMAC1
and OMAC2 make, was insecure unless all messages
MAC'd with it were exactly the same size. The OMAC
algorithms are a nice, general-purpose pair of MACs for when you want
to keep your system simple, with only one cryptographic primitive.
What's more, if you use an OMAC with AES in CTR
mode, you need only have an implementation of the AES encryption
operation (which is quite different code from the decryption
operation). There is little practical difference between OMAC1 and
OMAC2, although they both give different outputs. OMAC1 is slightly
preferable, as it has a very slight speed advantage. Neither OMAC1
nor OMAC2 takes a nonce. As of this writing, NIST is expected to
standardize OMAC1.
- PMAC
-
PMAC is also parallelizable, but it is protected by patent. We
won't discuss this MAC further because there are
reasonable free alternatives.
- RMAC
-
RMAC is another MAC built upon a block cipher. It works by running
the block cipher in CBC mode and performing a bit of additional magic
at the end. This is a mode created by NIST, but cryptographers have
found theoretical problems with it under certain
conditions; thus, we do not recommend it for any
use.
- UMAC32
-
On many platforms, UMAC is the reigning speed champion for MACs
implemented in software. The version of UMAC timed for Table 6-2 uses 64-bit tags, which are sufficient for
most applications, if a bit liberal. That size is sufficient because
tags generally need to have security for only a fraction of a second,
assuming some resistance to capture replay attacks. 64 bits of
strength should easily last years. The 128-bit version generally does
a bit better than half the speed of the 64-bit version. Nevertheless,
although there are a few things out there using UMAC, we
don't recommend it. The algorithm is complex enough
that, as of this writing, the reference implementation of UMAC
apparently has never been validated. In addition, interoperability
with UMAC is exceptionally difficult because there are many different
parameters that can be tweaked.
- XMACC
-
XMACC can be built from a large variety of cryptographic primitives.
It provides good performance characteristics, and it is fully
parallelizable. Unfortunately, it is patented, and for this reason we
won't discuss it further in this book.
All in all, we personally prefer MAC127 or CMAC. When you want to
avoid using a nonce, OMAC1 is an excellent choice.
6.4.4 See Also
Recipe 4.11, Recipe 5.4,
Recipe 5.10, Recipe 6.9 through
Recipe 6.14
|