{-# LANGUAGE OverloadedStrings #-} module Encryption where import Types import Cost import Tunables import ExpensiveHash import qualified Data.ByteString as B import Raaz.Core.Encode import qualified Raaz.Cipher.AES as AES import Data.Word import Data.Monoid -- | An AES key, which is used to encrypt the key that is stored -- in keysafe. data KeyEncryptionKey = KeyEncryptionKey AES.KEY256 (Cost DecryptionOp) (CostCalc BruteForceOp UnknownPassword) -- | The ExpensiveHash of the Password is combined with a -- RandomObstacle to form the AES key. Combination method is logical OR. genKeyEncryptionKey :: Tunables -> KeyIdent -> Password -> KeyEncryptionKey genKeyEncryptionKey tunables keyident password = KeyEncryptionKey k decryptcost bruteforcecalc where k = undefined -- hashb <> ob -- TODO use logical OR (ExpensiveHash hashcost hashb) = expensiveHash tunables salt password salt = Salt keyident (RandomObstacle ob) = genRandomObstacle decryptcost decryptcost = CombinedCost (decryptionCost tunables) (castCost hashcost) -- To brute force data encrypted with this key, -- an attacker needs to pay the decryptcost for each password -- checked. bruteforcecalc = bruteForceLinearSearch decryptcost -- | A random value which adds difficulty to decrypting, since it's never -- written down anywhere and must always be brute-forced. -- -- It's always 64 bits long, and is left padded with 0's, -- which are followed by a series of random bits (which necessarily always -- starts with 1). Eg: -- -- > 0000000000000000000000000000000000000000000000000000000100011100 -- -- The fewer leading 0's and thus longer the random bits, -- the harder it is. data RandomObstacle = RandomObstacle B.ByteString -- | Generate a random obstacle that will add the specified cost to AES -- decryption. -- -- AES can be calculated more efficiently by a GPU, so the cost must be -- a GPU cost. genRandomObstacle :: Cost DecryptionOp -> RandomObstacle genRandomObstacle (GPUCost c) = undefined genRandomObstacle _ = error "decryptionCost must be a GPUCost"