-- | -- Module : Crypto.System.CPU -- License : BSD-style -- Maintainer : Olivier Chéron -- Stability : experimental -- Portability : unknown -- -- Gives information about cryptonite runtime environment. -- {-# 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 -- | CPU options impacting cryptography implementation and library performance. data ProcessorOption = AESNI -- ^ Support for AES instructions, with flag @support_aesni@ | PCLMUL -- ^ Support for CLMUL instructions, with flag @support_pclmuldq@ | RDRAND -- ^ Support for RDRAND instruction, with flag @support_rdrand@ deriving (Show,Eq,Enum,Data) -- | Options which have been enabled at compile time and are supported by the -- current CPU. 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)