hbs2/src/Crypto/Saltine/Core/Auth.hs

85 lines
3.1 KiB
Haskell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- |
-- Module : Crypto.Saltine.Core.Auth
-- Copyright : (c) Joseph Abrahamson 2013
-- License : MIT
--
-- Maintainer : me@jspha.com
-- Stability : experimental
-- Portability : non-portable
--
-- Secret-key message authentication:
-- "Crypto.Saltine.Core.Auth"
--
-- The 'auth' function authenticates a message 'ByteString' using a
-- secret key. The function returns an authenticator. The 'verify'
-- function checks if it's passed a correct authenticator of a message
-- under the given secret key.
--
-- The 'auth' function, viewed as a function of the message for a
-- uniform random key, is designed to meet the standard notion of
-- unforgeability. This means that an attacker cannot find
-- authenticators for any messages not authenticated by the sender,
-- even if the attacker has adaptively influenced the messages
-- authenticated by the sender. For a formal definition see, e.g.,
-- Section 2.4 of Bellare, Kilian, and Rogaway, \"The security of the
-- cipher block chaining message authentication code,\" Journal of
-- Computer and System Sciences 61 (2000), 362399;
-- <http://www-cse.ucsd.edu/~mihir/papers/cbc.html>.
--
-- Saltine does not make any promises regarding \"strong\"
-- unforgeability; perhaps one valid authenticator can be converted
-- into another valid authenticator for the same message. NaCl also
-- does not make any promises regarding \"truncated unforgeability.\"
--
-- "Crypto.Saltine.Core.Auth" is currently an implementation of
-- HMAC-SHA-512-256, i.e., the first 256 bits of
-- HMAC-SHA-512. HMAC-SHA-512-256 is conjectured to meet the standard
-- notion of unforgeability.
--
-- This is version 2010.08.30 of the auth.html web page.
module Crypto.Saltine.Core.Auth (
Key, Authenticator,
newKey,
auth, verify
) where
import Crypto.Saltine.Internal.Auth
( c_auth
, c_auth_verify
, Key(..)
, Authenticator(..)
)
import Crypto.Saltine.Internal.Util as U
import Data.ByteString (ByteString)
import qualified Crypto.Saltine.Internal.Auth as Bytes
-- | Creates a random key of the correct size for 'auth' and 'verify'.
newKey :: IO Key
newKey = Key <$> randomByteString Bytes.auth_keybytes
-- | Computes an keyed authenticator 'ByteString' from a message. It
-- is infeasible to forge these authenticators without the key, even
-- if an attacker observes many authenticators and messages and has
-- the ability to influence the messages sent.
auth :: Key
-> ByteString
-- ^ Message
-> Authenticator
auth (Key key) msg =
Au . snd . buildUnsafeByteString Bytes.auth_bytes $ \pa ->
constByteStrings [key, msg] $ \[(pk, _), (pm, mlen)] ->
c_auth pa pm (fromIntegral mlen) pk
-- | Checks to see if an authenticator is a correct proof that a
-- message was signed by some key.
verify :: Key
-> Authenticator
-> ByteString
-- ^ Message
-> Bool
-- ^ Is this message authentic?
verify (Key key) (Au a) msg =
unsafeDidSucceed $ constByteStrings [key, msg, a] $ \[(pk, _), (pm, mlen), (pa, _)] ->
return $ c_auth_verify pa pm (fromIntegral mlen) pk