Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
6.9.1 Problem
You want to provide integrity for messages in such a way that people with a secret key can verify that the message has not changed since the integrity value (often called a tag) was first calculated. 6.9.2 Solution
Use a message integrity check. As with hash functions, there are somewhat standard interfaces, particularly an incremental interface. 6.9.3 Discussion
Libraries that support MACs tend to support incremental operation using a standard structure, very similar to that used by hash functions:
Often, you may have a block cipher or a hash function that you'd like to turn into a MAC, but no associated code comes with the cryptographic primitive. Alternately, you might use a library such as OpenSSL or CryptoAPI that provides very narrow choices. For this reason, the next several recipes provide implementations of MACs we recommend for general-purpose use, particularly OMAC, CMAC, and HMAC.
Some MAC interfaces may not remove key material from memory when done. Be sure to check the particular implementation you're using. OpenSSL provides only a single MAC implementation, HMAC, while CryptoAPI supports both CBC-MAC and HMAC. Neither quite follows the API outlined in this recipe, though they stray in different ways. OpenSSL performs the reset operation the same way as the initialization operation (you just pass in 0 in place of the key and the algorithm arguments). CryptoAPI does not allow resetting the context object, and instead requires that a completely new context object be created. OMAC and HMAC do not take a nonce by default. See Recipe 6.12 to see how to use these algorithms with a nonce. To see how to use the incremental HMAC interface in OpenSSL and CryptoAPI, see Recipe 6.10. CryptoAPI does not have an all-in-one interface, but instead requires use of its incremental API. Most libraries also provide an all-in-one interface to the MACs they provide. For example, the HMAC all-in-one function for OpenSSL looks like this: unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, const unsigned char *msg, int msglen, unsigned char *tag, unsigned int *tag_len); There is some variation in all-in-one APIs. Some are single-pass, like the OpenSSL API described in this section. Others have a separate initialization step and a context object, so that you do not need to specify the underlying cryptographic primitive and rekey every single time you want to use the MAC. That is, such interfaces automatically call functions for resetting, updating, and finalization for you. 6.9.4 See Also
Recipe 4.11, Recipe 6.10, Recipe 6.12, Recipe 6.18, Recipe 6.21 |