summaryrefslogtreecommitdiffhomepage
path: root/Encryption.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2016-09-12 22:35:47 -0400
committerJoey Hess <joeyh@joeyh.name>2016-09-12 22:39:21 -0400
commit13c408d2295597540f0b2dfb6f7b86e739876c90 (patch)
treecac72a6d5a75fb15d71d5e86395543829fe2f2df /Encryption.hs
parent483cc9e1fe40899c7f045d71d75aaa5ca99db3fb (diff)
downloadkeysafe-13c408d2295597540f0b2dfb6f7b86e739876c90.tar.gz
implement client-server Proof Of Work
Mashed up a argon2-based PoW with token buckets and bloom filters. This is intended to prevent a few abuses including: * Using a keysafe server for general file storage, by storing a whole lot of chunks. * An attacker guessing names that people will use, and uploading junk to keysafe servers under those names, to make it harder for others to use keysafe later. * An attacker trying to guess the names used for objects on keysafe servers in order to download them and start password cracking. (As a second level of defense, since the name generation hash is expensive already.) Completely untested, but it builds! This commit was sponsored by Andreas on Patreon.
Diffstat (limited to 'Encryption.hs')
-rw-r--r--Encryption.hs31
1 files changed, 6 insertions, 25 deletions
diff --git a/Encryption.hs b/Encryption.hs
index b084c27..12edbc6 100644
--- a/Encryption.hs
+++ b/Encryption.hs
@@ -12,9 +12,11 @@ import Types
import Tunables
import Cost
import ExpensiveHash
+import ByteStrings
import Data.Monoid
import Data.Maybe
import Data.Word
+import Control.Monad
import qualified Raaz
import qualified Raaz.Cipher.AES as Raaz
import qualified Raaz.Cipher.Internal as Raaz
@@ -31,7 +33,7 @@ cipher = Raaz.aes256cbc
encrypt :: Tunables -> KeyEncryptionKey -> SecretKey -> EncryptedSecretKey
encrypt tunables kek (SecretKey secret) =
- EncryptedSecretKey (chunk (objectSize tunables) b) (keyBruteForceCalc kek)
+ EncryptedSecretKey (chunkByteString (objectSize tunables) b) (keyBruteForceCalc kek)
where
-- Raaz does not seem to provide a high-level interface
-- for AES encryption, so use unsafeEncrypt. The use of
@@ -138,24 +140,6 @@ candidateKeyEncryptionKeys tunables name password =
saltprefixes = allByteStringsOfLength $
randomSaltBytes $ keyEncryptionKeyTunable tunables
-allByteStringsOfLength :: Int -> [B.ByteString]
-allByteStringsOfLength = go []
- where
- go ws n
- | n == 0 = return (B.pack ws)
- | otherwise = do
- w <- [0..255]
- go (w:ws) (n-1)
-
-chunk :: Int -> B.ByteString -> [B.ByteString]
-chunk n = go []
- where
- go cs b
- | B.length b <= n = reverse (b:cs)
- | otherwise =
- let (h, t) = B.splitAt n b
- in go (h:cs) t
-
-- Use the sha256 of the name (truncated) as the IV.
genIV :: Name -> Raaz.IV
genIV (Name name) =
@@ -168,13 +152,10 @@ genIV (Name name) =
type SaltPrefix = B.ByteString
genRandomSaltPrefix :: Raaz.SystemPRG -> Tunables -> IO SaltPrefix
-genRandomSaltPrefix prg tunables = go []
- (randomSaltBytes $ keyEncryptionKeyTunable tunables)
+genRandomSaltPrefix prg tunables = B.pack <$> replicateM n randbyte
where
- go ws 0 = return (B.pack ws)
- go ws n = do
- b <- Raaz.random prg :: IO Word8
- go (b:ws) (n-1)
+ n = randomSaltBytes $ keyEncryptionKeyTunable tunables
+ randbyte = Raaz.random prg :: IO Word8
instance Raaz.Random Word8