module Crypto.Data.Padding
( Format(..)
, pad
, unpad
) where
import Data.ByteArray (ByteArray, Bytes)
import qualified Data.ByteArray as B
data Format =
PKCS5
| PKCS7 Int
| ZERO Int
deriving (Int -> Format -> ShowS
[Format] -> ShowS
Format -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Format] -> ShowS
$cshowList :: [Format] -> ShowS
show :: Format -> String
$cshow :: Format -> String
showsPrec :: Int -> Format -> ShowS
$cshowsPrec :: Int -> Format -> ShowS
Show, Format -> Format -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Format -> Format -> Bool
$c/= :: Format -> Format -> Bool
== :: Format -> Format -> Bool
$c== :: Format -> Format -> Bool
Eq)
pad :: ByteArray byteArray => Format -> byteArray -> byteArray
pad :: forall byteArray.
ByteArray byteArray =>
Format -> byteArray -> byteArray
pad Format
PKCS5 byteArray
bin = forall byteArray.
ByteArray byteArray =>
Format -> byteArray -> byteArray
pad (Int -> Format
PKCS7 Int
8) byteArray
bin
pad (PKCS7 Int
sz) byteArray
bin = byteArray
bin forall bs. ByteArray bs => bs -> bs -> bs
`B.append` byteArray
paddingString
where
paddingString :: byteArray
paddingString = forall ba. ByteArray ba => Int -> Word8 -> ba
B.replicate Int
paddingByte (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
paddingByte)
paddingByte :: Int
paddingByte = Int
sz forall a. Num a => a -> a -> a
- (forall ba. ByteArrayAccess ba => ba -> Int
B.length byteArray
bin forall a. Integral a => a -> a -> a
`mod` Int
sz)
pad (ZERO Int
sz) byteArray
bin = byteArray
bin forall bs. ByteArray bs => bs -> bs -> bs
`B.append` byteArray
paddingString
where
paddingString :: byteArray
paddingString = forall ba. ByteArray ba => Int -> Word8 -> ba
B.replicate Int
paddingSz Word8
0
paddingSz :: Int
paddingSz
| Int
len forall a. Eq a => a -> a -> Bool
== Int
0 = Int
sz
| Int
m forall a. Eq a => a -> a -> Bool
== Int
0 = Int
0
| Bool
otherwise = Int
sz forall a. Num a => a -> a -> a
- Int
m
m :: Int
m = Int
len forall a. Integral a => a -> a -> a
`mod` Int
sz
len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length byteArray
bin
unpad :: ByteArray byteArray => Format -> byteArray -> Maybe byteArray
unpad :: forall byteArray.
ByteArray byteArray =>
Format -> byteArray -> Maybe byteArray
unpad Format
PKCS5 byteArray
bin = forall byteArray.
ByteArray byteArray =>
Format -> byteArray -> Maybe byteArray
unpad (Int -> Format
PKCS7 Int
8) byteArray
bin
unpad (PKCS7 Int
sz) byteArray
bin
| Int
len forall a. Eq a => a -> a -> Bool
== Int
0 = forall a. Maybe a
Nothing
| (Int
len forall a. Integral a => a -> a -> a
`mod` Int
sz) forall a. Eq a => a -> a -> Bool
/= Int
0 = forall a. Maybe a
Nothing
| Int
paddingSz forall a. Ord a => a -> a -> Bool
< Int
1 Bool -> Bool -> Bool
|| Int
paddingSz forall a. Ord a => a -> a -> Bool
> Int
len = forall a. Maybe a
Nothing
| Bytes
paddingWitness forall bs1 bs2.
(ByteArrayAccess bs1, ByteArrayAccess bs2) =>
bs1 -> bs2 -> Bool
`B.constEq` byteArray
padding = forall a. a -> Maybe a
Just byteArray
content
| Bool
otherwise = forall a. Maybe a
Nothing
where
len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length byteArray
bin
paddingByte :: Word8
paddingByte = forall a. ByteArrayAccess a => a -> Int -> Word8
B.index byteArray
bin (Int
len forall a. Num a => a -> a -> a
- Int
1)
paddingSz :: Int
paddingSz = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
paddingByte
(byteArray
content, byteArray
padding) = forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt (Int
len forall a. Num a => a -> a -> a
- Int
paddingSz) byteArray
bin
paddingWitness :: Bytes
paddingWitness = forall ba. ByteArray ba => Int -> Word8 -> ba
B.replicate Int
paddingSz Word8
paddingByte :: Bytes
unpad (ZERO Int
sz) byteArray
bin
| Int
len forall a. Eq a => a -> a -> Bool
== Int
0 = forall a. Maybe a
Nothing
| (Int
len forall a. Integral a => a -> a -> a
`mod` Int
sz) forall a. Eq a => a -> a -> Bool
/= Int
0 = forall a. Maybe a
Nothing
| forall a. ByteArrayAccess a => a -> Int -> Word8
B.index byteArray
bin (Int
len forall a. Num a => a -> a -> a
- Int
1) forall a. Eq a => a -> a -> Bool
/= Word8
0 = forall a. a -> Maybe a
Just byteArray
bin
| Bool
otherwise = forall a. Maybe a
Nothing
where
len :: Int
len = forall ba. ByteArrayAccess ba => ba -> Int
B.length byteArray
bin