This module contains functions to add and validate PKCS#7 padding.
module Padding.PKCS7
(
padPKCS7
, validatePKCS7
) where
import Bytes ( HasBytes(..), Bytes, splitEnd )
import qualified Data.ByteString as BPKCS#7 padding appends enough bytes to the text to fill it out to a whole number of blocks, with all of the appended bytes being the number of bytes appended. Thus, if we have to add one byte, that byte is 0x01; if we have to add six, those six bytes are all 0x06. If the text is already the length of a whole number of blocks, we add an entire extra block of padding.
padPKCS7 :: HasBytes text => Int -> text -> Bytes
padPKCS7 blockSize text =
let bytes = toBytes text
paddingLength = blockSize - (B.length bytes `rem` blockSize)
padding = B.replicate paddingLength (toEnum paddingLength)
in bytes <> paddingWe can validate PKCS#7 by checking that the last n characters are just n.
validatePKCS7 :: Bytes -> Maybe Bytes
validatePKCS7 bsNo valid padding ends in a zero byte.
| lastVal == 0 = NothingThe entire message must be at least as long as the final byte.
| numBytes bs < fromIntegral lastVal = NothingThe last lastVal bytes must be equal to lastVal.
| B.any (/= lastVal) lastBunch = NothingOtherwise, we can just return the message stripped of the final lastVal bytes.
| otherwise = Just message
where
lastVal = B.last bs
(message,lastBunch) = splitEnd (fromIntegral lastVal) bs