From 13c408d2295597540f0b2dfb6f7b86e739876c90 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 12 Sep 2016 22:35:47 -0400 Subject: 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. --- Encryption.hs | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) (limited to 'Encryption.hs') 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 -- cgit v1.2.3