aboutsummaryrefslogtreecommitdiffstats
path: root/doc/api_ref/message_auth_codes.rst
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2019-05-31 23:08:48 -0400
committerJack Lloyd <[email protected]>2019-05-31 23:34:34 -0400
commit924bb1a52ec3dad476a5f8567a7411b18a3e7056 (patch)
treebe6ecc03c2cf7b6da23f51c85ab3d5170566d150 /doc/api_ref/message_auth_codes.rst
parentc610d318d37c899260a2d3f3e3692970c6f8d9ba (diff)
Reorg documentation layout. Rename manual to handbook.
Diffstat (limited to 'doc/api_ref/message_auth_codes.rst')
-rw-r--r--doc/api_ref/message_auth_codes.rst255
1 files changed, 255 insertions, 0 deletions
diff --git a/doc/api_ref/message_auth_codes.rst b/doc/api_ref/message_auth_codes.rst
new file mode 100644
index 000000000..70b6c9c3b
--- /dev/null
+++ b/doc/api_ref/message_auth_codes.rst
@@ -0,0 +1,255 @@
+
+.. _mac:
+
+Message Authentication Codes (MAC)
+===================================
+
+A Message Authentication Code algorithm computes a tag over a message utilizing
+a shared secret key. Thus a valid tag confirms the authenticity and integrity of
+the message. Only entities in possession of the shared secret key are able to
+verify the tag.
+
+.. note::
+
+ When combining a MAC with unauthenticated encryption mode, prefer to first
+ encrypt the message and then MAC the ciphertext. The alternative is to MAC
+ the plaintext, which depending on exact usage can suffer serious security
+ issues. For a detailed discussion of this issue see the paper "The Order of
+ Encryption and Authentication for Protecting Communications" by Hugo
+ Krawczyk
+
+The Botan MAC computation is split into five stages.
+
+#. Instantiate the MAC algorithm.
+#. Set the secret key.
+#. Process IV.
+#. Process data.
+#. Finalize the MAC computation.
+
+.. cpp:class:: MessageAuthenticationCode
+
+ .. cpp:function:: std::string name() const
+
+ Returns a human-readable string of the name of this algorithm.
+
+ .. cpp:function:: void clear()
+
+ Clear the key.
+
+ .. cpp:function:: MessageAuthenticationCode* clone() const
+
+ Return a newly allocated object of the same type as this one.
+
+ .. cpp:function:: void set_key(const uint8_t* key, size_t length)
+
+ Set the shared MAC key for the calculation. This function has to be called before the data is processed.
+
+ .. cpp:function:: bool valid_keylength(size_t length) const
+
+ This function returns true if and only if *length* is a valid
+ keylength for the algorithm.
+
+ .. cpp:function:: size_t minimum_keylength() const
+
+ Return the smallest key length (in bytes) that is acceptable for the
+ algorithm.
+
+ .. cpp:function:: size_t maximum_keylength() const
+
+ Return the largest key length (in bytes) that is acceptable for the
+ algorithm.
+
+ .. cpp:function:: void start(const uint8_t* nonce, size_t nonce_len)
+
+ Set the IV for the MAC calculation. Note that not all MAC algorithms require an IV.
+ If an IV is required, the function has to be called before the data is processed.
+ For algorithms that don't require it, the call can be omitted, or else called
+ with ``nonce_len`` of zero.
+
+ .. cpp:function:: void update(const uint8_t* input, size_t length)
+
+ Process the passed data.
+
+ .. cpp:function:: void update(const secure_vector<uint8_t>& in)
+
+ Process the passed data.
+
+ .. cpp:function:: void update(uint8_t in)
+
+ Process a single byte.
+
+ .. cpp:function:: void final(uint8_t* out)
+
+ Complete the MAC computation and write the calculated tag to the passed byte array.
+
+ .. cpp:function:: secure_vector<uint8_t> final()
+
+ Complete the MAC computation and return the calculated tag.
+
+ .. cpp:function:: bool verify_mac(const uint8_t* mac, size_t length)
+
+ Finalize the current MAC computation and compare the result to the passed
+ ``mac``. Returns ``true``, if the verification is successful and false
+ otherwise.
+
+
+Code Examples
+------------------------
+
+The following example computes an HMAC with a random key then verifies the tag.
+
+ #include <botan/mac.h>
+ #include <botan/hex.h>
+ #include <botan/system_rng.h>
+ #include <assert.h>
+
+ std::string compute_mac(const std::string& msg, const Botan::secure_vector<uint8_t>& key)
+ {
+ auto hmac = Botan::MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)");
+
+ hmac->set_key(key);
+ hmac->update(msg);
+
+ return Botan::hex_encode(hmac->final());
+ }
+
+ int main()
+ {
+ Botan::System_RNG rng;
+
+ const auto key = rng.random_vec(32); // 256 bit random key
+
+ // "Message" != "Mussage" so tags will also not match
+ std::string tag1 = compute_mac("Message", key);
+ std::string tag2 = compute_mac("Mussage", key);
+ assert(tag1 != tag2);
+
+ // Recomputing with original input message results in identical tag
+ std::string tag3 = compute_mac("Message", key);
+ assert(tag1 == tag3);
+ }
+
+
+The following example code computes a AES-256 GMAC and subsequently verifies the
+tag. Unlike most other MACs, GMAC requires a nonce *which must not repeat or
+all security is lost*.
+
+.. code-block:: cpp
+
+ #include <botan/mac.h>
+ #include <botan/hex.h>
+ #include <iostream>
+
+ int main()
+ {
+ const std::vector<uint8_t> key = Botan::hex_decode("1337133713371337133713371337133713371337133713371337133713371337");
+ const std::vector<uint8_t> nonce = Botan::hex_decode("FFFFFFFFFFFFFFFFFFFFFFFF");
+ const std::vector<uint8_t> data = Botan::hex_decode("6BC1BEE22E409F96E93D7E117393172A");
+ std::unique_ptr<Botan::MessageAuthenticationCode> mac(Botan::MessageAuthenticationCode::create("GMAC(AES-256)"));
+ if(!mac)
+ return 1;
+ mac->set_key(key);
+ mac->start(nonce);
+ mac->update(data);
+ Botan::secure_vector<uint8_t> tag = mac->final();
+ std::cout << mac->name() << ": " << Botan::hex_encode(tag) << std::endl;
+
+ //Verify created MAC
+ mac->start(nonce);
+ mac->update(data);
+ std::cout << "Verification: " << (mac->verify_mac(tag) ? "success" : "failure");
+ return 0;
+ }
+
+The following example code computes a valid AES-128 CMAC tag and modifies the
+data to demonstrate a MAC verification failure.
+
+.. code-block:: cpp
+
+ #include <botan/mac.h>
+ #include <botan/hex.h>
+ #include <iostream>
+
+ int main()
+ {
+ const std::vector<uint8_t> key = Botan::hex_decode("2B7E151628AED2A6ABF7158809CF4F3C");
+ std::vector<uint8_t> data = Botan::hex_decode("6BC1BEE22E409F96E93D7E117393172A");
+ std::unique_ptr<Botan::MessageAuthenticationCode> mac(Botan::MessageAuthenticationCode::create("CMAC(AES-128)"));
+ if(!mac)
+ return 1;
+ mac->set_key(key);
+ mac->update(data);
+ Botan::secure_vector<uint8_t> tag = mac->final();
+ //Corrupting data
+ data.back()++;
+ //Verify with corrupted data
+ mac->update(data);
+ std::cout << "Verification with malformed data: " << (mac->verify_mac(tag) ? "success" : "failure");
+ return 0;
+ }
+
+Available MACs
+------------------------------------------
+
+Currently the following MAC algorithms are available in Botan. In new code,
+default to HMAC with a strong hash like SHA-256 or SHA-384.
+
+CBC-MAC
+~~~~~~~~~~~~
+
+An older authentication code based on a block cipher. Serious security problems,
+in particular **insecure** if messages of several different lengths are
+authenticated. Avoid unless required for compatibility.
+
+Available if ``BOTAN_HAS_CBC_MAC`` is defined.
+
+CMAC
+~~~~~~~~~~~~
+
+A modern CBC-MAC variant that avoids the security problems of plain CBC-MAC.
+Approved by NIST. Also sometimes called OMAC.
+
+Available if ``BOTAN_HAS_CMAC`` is defined.
+
+GMAC
+~~~~~~~~~~~~
+
+GMAC is related to the GCM authenticated cipher mode. It is quite slow unless
+hardware support for carryless multiplications is available. A new nonce
+must be used with **each** message authenticated, or otherwise all security is
+lost.
+
+Available if ``BOTAN_HAS_GMAC`` is defined.
+
+HMAC
+~~~~~~~~~~~~
+
+A message authentication code based on a hash function. Very commonly used.
+
+Available if ``BOTAN_HAS_HMAC`` is defined.
+
+Poly1305
+~~~~~~~~~~~~
+
+A polynomial mac (similar to GMAC). Very fast, but tricky to use safely. Forms
+part of the ChaCha20Poly1305 AEAD mode. A new key must be used for **each**
+message, or all security is lost.
+
+Available if ``BOTAN_HAS_POLY1305`` is defined.
+
+SipHash
+~~~~~~~~~~~~
+
+A modern and very fast PRF. Produces only a 64-bit output. Defaults to
+"SipHash(2,4)" which is the recommended configuration, using 2 rounds for each
+input block and 4 rounds for finalization.
+
+Available if ``BOTAN_HAS_SIPHASH`` is defined.
+
+X9.19-MAC
+~~~~~~~~~~~~
+
+A CBC-MAC variant sometimes used in finance. Always uses DES. Avoid unless
+required.
+
+Available if ``BOTAN_HAS_X919_MAC`` is defined.