-- Copyright © 2015 Bart Massey
-- [This work is licensed under the "MIT License"]
-- Please see the file LICENSE in the source
-- distribution of this software for license terms.
-- CipherSaber driver for UNIX-like systems with "/dev/random".
import Control.Monad
import qualified Data.ByteString.Char8 as BS
import Data.CipherSaber2
import System.Console.ParseArgs
import System.IO
data ArgInd = ArgEncrypt | ArgDecrypt | ArgKey | ArgReps
deriving (Ord, Eq, Show)
argd :: [ Arg ArgInd ]
argd = [
Arg {
argIndex = ArgEncrypt,
argName = Just "encrypt",
argAbbr = Just 'e',
argData = Nothing,
argDesc = "Use decryption mode."
},
Arg {
argIndex = ArgDecrypt,
argName = Just "decrypt",
argAbbr = Just 'd',
argData = Nothing,
argDesc = "Use encryption mode."
},
Arg {
argIndex = ArgReps,
argName = Just "reps",
argAbbr = Just 'r',
argData = argDataDefaulted "number" ArgtypeInt 20,
argDesc = "Number of key scheduling reps " ++
"(use 1 for CipherSaber-1, default 20)."
},
Arg {
argIndex = ArgKey,
argName = Nothing,
argAbbr = Nothing,
argData = argDataRequired "key" ArgtypeString,
argDesc = "Encryption or decryption key."
} ]
makeIV :: IO BS.ByteString
makeIV =
withBinaryFile "/dev/urandom" ReadMode $ \h ->
do
hSetBuffering h NoBuffering
BS.hGet h 10
main :: IO ()
main = do
hSetBinaryMode stdin True
hSetBinaryMode stdout True
argv <- parseArgsIO ArgsComplete argd
let k = toByteString $ getRequiredArg argv ArgKey
let e = gotArg argv ArgEncrypt
let d = gotArg argv ArgDecrypt
let r = getRequiredArg argv ArgReps :: Int
unless ((e && not d) || (d && not e)) $
usageError argv "Exactly one of -e or -d is required."
case e of
True -> do
iv <- makeIV
BS.interact (encrypt r k iv)
False -> do
BS.interact (decrypt r k)