|
Packit |
141393 |
-- |
|
|
Packit |
141393 |
-- Module : Crypto.Data.Padding
|
|
Packit |
141393 |
-- License : BSD-style
|
|
Packit |
141393 |
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
|
|
Packit |
141393 |
-- Stability : experimental
|
|
Packit |
141393 |
-- Portability : unknown
|
|
Packit |
141393 |
--
|
|
Packit |
141393 |
-- Various cryptographic padding commonly used for block ciphers
|
|
Packit |
141393 |
-- or assymetric systems.
|
|
Packit |
141393 |
--
|
|
Packit |
141393 |
module Crypto.Data.Padding
|
|
Packit |
141393 |
( Format(..)
|
|
Packit |
141393 |
, pad
|
|
Packit |
141393 |
, unpad
|
|
Packit |
141393 |
) where
|
|
Packit |
141393 |
|
|
Packit |
141393 |
import Data.ByteArray (ByteArray, Bytes)
|
|
Packit |
141393 |
import qualified Data.ByteArray as B
|
|
Packit |
141393 |
|
|
Packit |
141393 |
-- | Format of padding
|
|
Packit |
141393 |
data Format =
|
|
Packit |
141393 |
PKCS5 -- ^ PKCS5: PKCS7 with hardcoded size of 8
|
|
Packit |
141393 |
| PKCS7 Int -- ^ PKCS7 with padding size between 1 and 255
|
|
Packit |
141393 |
| ZERO Int -- ^ zero padding with block size
|
|
Packit |
141393 |
deriving (Show, Eq)
|
|
Packit |
141393 |
|
|
Packit |
141393 |
-- | Apply some pad to a bytearray
|
|
Packit |
141393 |
pad :: ByteArray byteArray => Format -> byteArray -> byteArray
|
|
Packit |
141393 |
pad PKCS5 bin = pad (PKCS7 8) bin
|
|
Packit |
141393 |
pad (PKCS7 sz) bin = bin `B.append` paddingString
|
|
Packit |
141393 |
where
|
|
Packit |
141393 |
paddingString = B.replicate paddingByte (fromIntegral paddingByte)
|
|
Packit |
141393 |
paddingByte = sz - (B.length bin `mod` sz)
|
|
Packit |
141393 |
pad (ZERO sz) bin = bin `B.append` paddingString
|
|
Packit |
141393 |
where
|
|
Packit |
141393 |
paddingString = B.replicate paddingSz 0
|
|
Packit |
141393 |
paddingSz
|
|
Packit |
141393 |
| len == 0 = sz
|
|
Packit |
141393 |
| m == 0 = 0
|
|
Packit |
141393 |
| otherwise = sz - m
|
|
Packit |
141393 |
m = len `mod` sz
|
|
Packit |
141393 |
len = B.length bin
|
|
Packit |
141393 |
|
|
Packit |
141393 |
-- | Try to remove some padding from a bytearray.
|
|
Packit |
141393 |
unpad :: ByteArray byteArray => Format -> byteArray -> Maybe byteArray
|
|
Packit |
141393 |
unpad PKCS5 bin = unpad (PKCS7 8) bin
|
|
Packit |
141393 |
unpad (PKCS7 sz) bin
|
|
Packit |
141393 |
| len == 0 = Nothing
|
|
Packit |
141393 |
| (len `mod` sz) /= 0 = Nothing
|
|
Packit |
141393 |
| paddingSz < 1 || paddingSz > len = Nothing
|
|
Packit |
141393 |
| paddingWitness `B.constEq` padding = Just content
|
|
Packit |
141393 |
| otherwise = Nothing
|
|
Packit |
141393 |
where
|
|
Packit |
141393 |
len = B.length bin
|
|
Packit |
141393 |
paddingByte = B.index bin (len - 1)
|
|
Packit |
141393 |
paddingSz = fromIntegral paddingByte
|
|
Packit |
141393 |
(content, padding) = B.splitAt (len - paddingSz) bin
|
|
Packit |
141393 |
paddingWitness = B.replicate paddingSz paddingByte :: Bytes
|
|
Packit |
141393 |
unpad (ZERO sz) bin
|
|
Packit |
141393 |
| len == 0 = Nothing
|
|
Packit |
141393 |
| (len `mod` sz) /= 0 = Nothing
|
|
Packit |
141393 |
| B.index bin (len - 1) /= 0 = Just bin
|
|
Packit |
141393 |
| otherwise = Nothing
|
|
Packit |
141393 |
where
|
|
Packit |
141393 |
len = B.length bin
|