{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module Crypto.System.CPU
( ProcessorOption (..)
, processorOptions
) where
import Data.Data
import Data.List (findIndices)
#ifdef SUPPORT_RDRAND
import Data.Maybe (isJust)
#endif
import Data.Word (Word8)
import Foreign.Ptr
import Foreign.Storable
import Crypto.Internal.Compat
#ifdef SUPPORT_RDRAND
import Crypto.Random.Entropy.RDRand
import Crypto.Random.Entropy.Source
#endif
data ProcessorOption
= AESNI
| PCLMUL
| RDRAND
deriving (Show,Eq,Enum,Data)
processorOptions :: [ProcessorOption]
processorOptions = unsafeDoIO $ do
p <- cryptonite_aes_cpu_init
options <- traverse (getOption p) aesOptions
rdrand <- hasRDRand
return (decodeOptions options ++ [ RDRAND | rdrand ])
where
aesOptions = [ AESNI .. PCLMUL ]
getOption p = peekElemOff p . fromEnum
decodeOptions = map toEnum . findIndices (> 0)
{-# NOINLINE processorOptions #-}
hasRDRand :: IO Bool
#ifdef SUPPORT_RDRAND
hasRDRand = fmap isJust getRDRand
where getRDRand = entropyOpen :: IO (Maybe RDRand)
#else
hasRDRand = return False
#endif
foreign import ccall unsafe "cryptonite_aes_cpu_init"
cryptonite_aes_cpu_init :: IO (Ptr Word8)