From 0a749a336c64e3fb82581c3c7941e2de76aa22d5 Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Fri, 29 Sep 2023 08:21:03 -0400
Subject: [PATCH] wip - adding BlockCipher to replace the other uses

---
 src/Tahoe/CHK/Cipher.hs | 15 ++++++++++++++-
 src/Tahoe/CHK/Upload.hs | 16 ++++++++++++----
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/src/Tahoe/CHK/Cipher.hs b/src/Tahoe/CHK/Cipher.hs
index 8bfe38d..380c130 100644
--- a/src/Tahoe/CHK/Cipher.hs
+++ b/src/Tahoe/CHK/Cipher.hs
@@ -10,9 +10,10 @@ module Tahoe.CHK.Cipher (
 ) where
 
 import Control.DeepSeq (NFData)
-import Crypto.Cipher.Types (Cipher (..))
+import Crypto.Cipher.Types (BlockCipher (..), Cipher (..))
 import Data.ByteArray (ScrubbedBytes)
 import qualified Data.ByteArray as BA
+import Data.Coerce (coerce)
 import GHC.Generics (Generic)
 
 data Key cipher = Key {keyBytes :: ScrubbedBytes, keyCipher :: cipher}
@@ -25,6 +26,18 @@ instance forall cipher. Cipher cipher => Cipher (Key cipher) where
     cipherName _ = cipherName @cipher undefined
     cipherKeySize _ = cipherKeySize @cipher undefined
 
+instance forall cipher. BlockCipher cipher => BlockCipher (Key cipher) where
+    blockSize _ = blockSize @cipher undefined
+    ecbEncrypt = ecbEncrypt . keyCipher
+    ecbDecrypt = ecbDecrypt . keyCipher
+    cbcEncrypt (Key _ cipher) iv = cbcEncrypt cipher (coerce iv)
+    cbcDecrypt (Key _ cipher) iv = cbcDecrypt cipher (coerce iv)
+
+    cfbEncrypt (Key _ cipher) iv = cfbEncrypt cipher (coerce iv)
+    cfbDecrypt (Key _ cipher) iv = cfbDecrypt cipher (coerce iv)
+    ctrCombine (Key _ cipher) iv = ctrCombine cipher (coerce iv)
+
+    aeadInit mode (Key _ cipher) iv = xxx
 instance BA.ByteArrayAccess (Key cipher) where
     length (Key ba _) = BA.length ba
     withByteArray (Key ba _) = BA.withByteArray ba
diff --git a/src/Tahoe/CHK/Upload.hs b/src/Tahoe/CHK/Upload.hs
index 2e18f01..53290f6 100644
--- a/src/Tahoe/CHK/Upload.hs
+++ b/src/Tahoe/CHK/Upload.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE PackageImports #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications #-}
 
@@ -35,6 +36,7 @@ import Data.IORef (
  )
 
 import qualified Data.Binary as Binary
+import Data.ByteArray (ScrubbedBytes)
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as BL
 
@@ -60,8 +62,8 @@ import System.IO (
  )
 
 import Crypto.Cipher.AES (AES128)
-import Crypto.Cipher.Types (BlockCipher, Cipher (cipherInit))
-import Crypto.Random (getRandomBytes)
+import Crypto.Cipher.Types (BlockCipher, Cipher (cipherInit, cipherKeySize), KeySizeSpecifier (..))
+import "cryptonite" Crypto.Random (getRandomBytes)
 
 import Tahoe.CHK.Cipher (Key)
 import Tahoe.CHK.Crypto (
@@ -339,8 +341,14 @@ getConvergentKey secret params content =
 
 buildKeyIO :: forall cipher. BlockCipher cipher => IO (Key cipher)
 buildKeyIO = do
-    keyBytes <- getRandomBytes (cipherKeySize @cipher undefined)
-    fromJust . maybeCryptoError . cipherInit $ keyBytes
+    keyBytes <- getRandomBytes @IO @ScrubbedBytes keySize
+    pure . fromJust . maybeCryptoError . cipherInit $ keyBytes
+  where
+    keySize = case cipherKeySize @cipher undefined of
+        KeySizeRange _ high -> high
+        KeySizeEnum [] -> error "no key sizes!"
+        KeySizeEnum (s : _) -> s
+        KeySizeFixed s -> s
 
 -- Create an uploadable with a random key.
 filesystemUploadableRandomConvergence :: FilePath -> Parameters -> IO Uploadable
-- 
GitLab