use different parts of cipher for hmac and gpg

Per bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing

It may be paranoid to worry about the cipher being recovered
from hmac keys, but yes.. let's be paranoid.
This commit is contained in:
Joey Hess 2011-04-17 01:34:28 -04:00
parent 50cfcdf54b
commit 4d136e1ef5
2 changed files with 29 additions and 10 deletions

View file

@ -45,6 +45,24 @@ import RemoteClass
import Utility import Utility
import CryptoTypes import CryptoTypes
{- The first half of a Cipher is used for HMAC; the remainder
- is used as the GPG symmetric encryption passphrase.
-
- 256 is enough for gpg's symetric cipher; unlike weaker public key
- crypto, the key does not need to be too large.
-}
cipherHalf :: Int
cipherHalf = 256
cipherSize :: Int
cipherSize = cipherHalf * 2
cipherPassphrase :: Cipher -> String
cipherPassphrase (Cipher c) = drop cipherHalf c
cipherHmac :: Cipher -> String
cipherHmac (Cipher c) = take cipherHalf c
{- Creates a new Cipher, encrypted as specified in the remote's configuration -} {- Creates a new Cipher, encrypted as specified in the remote's configuration -}
genCipher :: RemoteConfig -> IO EncryptedCipher genCipher :: RemoteConfig -> IO EncryptedCipher
genCipher c = do genCipher c = do
@ -58,10 +76,10 @@ genCipher c = do
-- newline. -- newline.
[ Params "--gen-random --armor" [ Params "--gen-random --armor"
, Param $ show randomquality , Param $ show randomquality
, Param $ show ciphersize , Param $ show cipherSize
] ]
randomquality = 1 :: Int -- 1 is /dev/urandom; 2 is /dev/random -- 1 is /dev/urandom; 2 is /dev/random
ciphersize = 256 :: Int randomquality = 1 :: Int
{- Updates an existing Cipher, re-encrypting it to add KeyIds specified in {- Updates an existing Cipher, re-encrypting it to add KeyIds specified in
- the remote's configuration. -} - the remote's configuration. -}
@ -110,10 +128,11 @@ decryptCipher _ (EncryptedCipher encipher _) =
- reversable, nor does it need to be the same type of encryption used - reversable, nor does it need to be the same type of encryption used
- on content. It does need to be repeatable. -} - on content. It does need to be repeatable. -}
encryptKey :: Cipher -> Key -> IO Key encryptKey :: Cipher -> Key -> IO Key
encryptKey (Cipher c) k = encryptKey c k =
return Key { return Key {
keyName = showDigest $ keyName = showDigest $ hmacSha1
hmacSha1 (fromString $ show k) (fromString c), (fromString $ show k)
(fromString $ cipherHmac c),
keyBackendName = "GPGHMACSHA1", keyBackendName = "GPGHMACSHA1",
keySize = Nothing, -- size and mtime omitted keySize = Nothing, -- size and mtime omitted
keyMtime = Nothing -- to avoid leaking data keyMtime = Nothing -- to avoid leaking data
@ -153,12 +172,12 @@ gpgPipeStrict params input = do
{- Runs gpg with a cipher and some parameters, feeding it an input, {- Runs gpg with a cipher and some parameters, feeding it an input,
- and passing a handle to its output to an action. -} - and passing a handle to its output to an action. -}
gpgCipherHandle :: [CommandParam] -> Cipher -> L.ByteString -> (Handle -> IO a) -> IO a gpgCipherHandle :: [CommandParam] -> Cipher -> L.ByteString -> (Handle -> IO a) -> IO a
gpgCipherHandle params (Cipher c) input a = do gpgCipherHandle params c input a = do
-- pipe the passphrase into gpg on a fd -- pipe the passphrase into gpg on a fd
(frompipe, topipe) <- createPipe (frompipe, topipe) <- createPipe
_ <- forkIO $ do _ <- forkIO $ do
toh <- fdToHandle topipe toh <- fdToHandle topipe
hPutStrLn toh c hPutStrLn toh $ cipherPassphrase c
hClose toh hClose toh
let Fd passphrasefd = frompipe let Fd passphrasefd = frompipe
let passphrase = [Param "--passphrase-fd", Param $ show passphrasefd] let passphrase = [Param "--passphrase-fd", Param $ show passphrasefd]

View file

@ -4,5 +4,5 @@ Also, ttbomk, HMAC needs two keys, not one. Are you re-using the same key twice?
Compability for old buckets and support for different ones can be maintained by introducing a new option and simply copying over the encryption key's identifier into this new option should it be missing. Compability for old buckets and support for different ones can be maintained by introducing a new option and simply copying over the encryption key's identifier into this new option should it be missing.
> See [[design/encryption]]. I don't think this bug needs to be kept > Bug was filed prematurely, but was a good bit of paranoia, and gpg and
> open. [[done]] --[[Joey]] > hmac are given different secret keys [[done]] --[[Joey]]