-- BlockCipher.hs: OpenPGP (RFC4880) block cipher stuff
-- Copyright © 2013  Clint Adams
-- This software is released under the terms of the Expat license.
-- (See the LICENSE file).

{-# LANGUAGE ExistentialQuantification #-}

module Codec.Encryption.OpenPGP.BlockCipher (
    BCipher(..)
  , bcBlockSize
  , saBlockSize
  , keySize
) where

import Codec.Encryption.OpenPGP.Types

import Crypto.Cipher.Types (BlockCipher(..))
import qualified Crypto.Cipher as CC
import qualified Crypto.Nettle.Ciphers as CNC

data BCipher = forall a. (BlockCipher a) => BCipher a

bcBlockSize :: BCipher -> Int
bcBlockSize (BCipher bc) = blockSize bc

saBlockSize :: SymmetricAlgorithm -> Int
saBlockSize = bcBlockSize . saToBCipher

saToBCipher :: SymmetricAlgorithm -> BCipher
saToBCipher Plaintext = error "this shouldn't have happened" -- FIXME: orphan instance?
saToBCipher IDEA = error "IDEA not yet implemented" -- FIXME: IDEA
saToBCipher ReservedSAFER = error "SAFER not implemented" -- FIXME: or not?
saToBCipher ReservedDES = error "DES not implemented" -- FIXME: or not?
saToBCipher (OtherSA _) = error "Unknown, unimplemented symmetric algorithm"
saToBCipher CAST5 = BCipher (undefined :: CNC.CAST128)
saToBCipher Twofish = BCipher (undefined :: CNC.TWOFISH)
saToBCipher TripleDES = BCipher (undefined :: CC.DES_EDE3)
saToBCipher Blowfish = BCipher (undefined :: CC.Blowfish128)
saToBCipher AES128 = BCipher (undefined :: CC.AES128)
saToBCipher AES192 = BCipher (undefined :: CC.AES192)
saToBCipher AES256 = BCipher (undefined :: CC.AES256)

-- in octets; FIXME: co-opt Cipher's cipherKeySize or not?
keySize :: SymmetricAlgorithm -> Int
keySize Plaintext = 0
keySize IDEA = 16 -- according to https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm
keySize TripleDES = 24 -- RFC 4880 says 168 bits (derived from 192 bits) but we don't know who does the derivation
keySize CAST5 = 16
keySize Blowfish = 16
keySize ReservedSAFER = undefined
keySize ReservedDES = undefined
keySize AES128 = 16
keySize AES192 = 24
keySize AES256 = 32
keySize Twofish = 32
keySize (OtherSA _) = undefined