blob: 23da288e405c6338b2c9608d8dd72d046a51d6e6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
{-# LANGUAGE OverloadedStrings, MultiParamTypeClasses #-}
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)
instance Bruteforceable KeyEncryptionKey UnknownPassword where
getBruteCostCalc (KeyEncryptionKey _ _ c) = c
-- | 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"
|