summaryrefslogtreecommitdiffhomepage
path: root/Encryption.hs
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"