Copyright | (c) Leo D 2023 |
---|---|
License | BSD-3-Clause |
Maintainer | leo@apotheca.io |
Stability | experimental |
Portability | POSIX |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
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.
Synopsis
- newtype MAC = MkMAC {
- getMACForeignPtr :: ForeignPtr BotanMACStruct
- type MACName = ByteString
- type MACKey = ByteString
- type MACNonce = ByteString
- type MACDigest = ByteString
- withMAC :: MAC -> (BotanMAC -> IO a) -> IO a
- macInit :: MACName -> IO MAC
- macDestroy :: MAC -> IO ()
- macName :: MAC -> IO ByteString
- macOutputLength :: MAC -> IO Int
- macGetKeyspec :: MAC -> IO (Int, Int, Int)
- macSetKey :: MAC -> ByteString -> IO ()
- macSetNonce :: MAC -> ByteString -> IO ()
- macUpdate :: MAC -> ByteString -> IO ()
- macFinal :: MAC -> IO MACDigest
- macClear :: MAC -> IO ()
- pattern CMAC :: MACName
- cmac :: BlockCipherName -> MACName
- pattern GMAC :: MACName
- gmac :: BlockCipherName -> MACName
- pattern HMAC :: MACName
- hmac :: BlockCipherName -> MACName
- pattern Poly1305 :: MACName
- pattern SipHash :: MACName
- sipHash :: Int -> Int -> MACName
- pattern X9_19_MAC :: MACName
Message authentication codes
A mac
(or message authentication code) is a cryptographic algorithm that uses
a secret key to produce a fixed-size digest from an arbitrarily-sized message,
which is then used to verify the integrity and authenticity of the data.
Usage
Unless you need a specific mac
, it is strongly recommended that you use the
`hmac SHA3` algorithm.
import Botan.Low.MAC import Botan.Low.Hash mac <- macInit (hmac SHA3)
To use a MAC, we first need to generate (if we haven't already) a secret key.
import Botan.Low.RNG rng <- rngInit "user" -- HMAC allows for an arbitrary key size, but we can check the key spec. (keyMin,keyMax,keyMod) <- macGetKeyspec mac -- MAC are randomly generated; 32 bytes is acceptable key <- rngGet rng 32
After the key is generated, we must set it as the mac key:
macSetKey mac key
Then, we may produce an authentication code from a message using the secret key:
macUpdate mac "Fee fi fo fum!" auth <- macFinal mac
To verify an message authentication code, we can reproduce it using the secret key and message, and then check for equality:
verify <- macInit (hmac SHA3) macSetKey verify key macUpdate verify "Fee fi fo fum!" verifyAuth <- macFinal verify auth == verifyAuth -- True
You can completely clear a mac's state, leaving it ready for reuse:
macClear mac -- You'll have to set the key again macSetKey mac anotherKey -- Process another message macUpdate mac anotherMessage anotherAuth <- macFinal mac
Some algorithms (GMAC, Poly1305) have additional requirements for use. Avoid if possible, and consult algorithm-specific documentation for GMAC and Poly1305. If you must use GMAC, a nonce needs to be set:
mac <- macInit (gmac AES256) k <- systemRNGGet 32 n <- systemRNGGet 32 -- Here macSetKey mac k macSetNonce mac n -- Here macUpdate mac "Fee fi fo fum!" auth <- macFinal mac
MkMAC | |
|
type MACName = ByteString Source #
type MACKey = ByteString Source #
type MACNonce = ByteString Source #
type MACDigest = ByteString Source #
Initialize a message authentication code object
macDestroy :: MAC -> IO () Source #
:: MAC | mac: the object to read |
-> IO ByteString | name: output buffer |
Get the name of this MAC
Writes the output length of the message authentication code to *output_length
:: MAC | mac: the object to read |
-> IO (Int, Int, Int) | (min,max,mod): minimum maximum and modulo keylength of MAC |
Get the key length limits of this auth code
:: MAC | mac: mac object |
-> ByteString | key: buffer holding the key |
-> IO () |
Sets the key on the MAC
:: MAC | mac: mac object |
-> ByteString | nonce: buffer holding the nonce |
-> IO () |
Sets the nonce on the MAC
:: MAC | mac: mac object |
-> ByteString | buf: input buffer |
-> IO () |
Send more input to the message authentication code
Finalizes the MAC computation and writes the output to out[0:botan_mac_output_length()] then reinitializes for computing another MAC as if botan_mac_clear had been called.
macClear :: MAC -> IO () Source #
Reinitializes the state of the MAC computation. A MAC can be computed (with update/final) immediately.
MAC algorithms
cmac :: BlockCipherName -> MACName Source #
gmac :: BlockCipherName -> MACName Source #
hmac :: BlockCipherName -> MACName Source #