2016-07-26 02:18:56 +08:00
|
|
|
// Package pkcs7 implements PKCS#7 padding
|
|
|
|
//
|
|
|
|
// This is a standard way of encoding variable length buffers into
|
|
|
|
// buffers which are a multiple of an underlying crypto block size.
|
|
|
|
package pkcs7
|
|
|
|
|
2021-11-04 18:12:57 +08:00
|
|
|
import "errors"
|
2016-07-26 02:18:56 +08:00
|
|
|
|
|
|
|
// Errors Unpad can return
|
|
|
|
var (
|
2022-06-09 04:54:39 +08:00
|
|
|
ErrorPaddingNotFound = errors.New("bad PKCS#7 padding - not padded")
|
|
|
|
ErrorPaddingNotAMultiple = errors.New("bad PKCS#7 padding - not a multiple of blocksize")
|
|
|
|
ErrorPaddingTooLong = errors.New("bad PKCS#7 padding - too long")
|
|
|
|
ErrorPaddingTooShort = errors.New("bad PKCS#7 padding - too short")
|
|
|
|
ErrorPaddingNotAllTheSame = errors.New("bad PKCS#7 padding - not all the same")
|
2016-07-26 02:18:56 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// Pad buf using PKCS#7 to a multiple of n.
|
|
|
|
//
|
|
|
|
// Appends the padding to buf - make a copy of it first if you don't
|
|
|
|
// want it modified.
|
|
|
|
func Pad(n int, buf []byte) []byte {
|
|
|
|
if n <= 1 || n >= 256 {
|
|
|
|
panic("bad multiple")
|
|
|
|
}
|
|
|
|
length := len(buf)
|
|
|
|
padding := n - (length % n)
|
|
|
|
for i := 0; i < padding; i++ {
|
|
|
|
buf = append(buf, byte(padding))
|
|
|
|
}
|
|
|
|
if (len(buf) % n) != 0 {
|
|
|
|
panic("padding failed")
|
|
|
|
}
|
|
|
|
return buf
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unpad buf using PKCS#7 from a multiple of n returning a slice of
|
|
|
|
// buf or an error if malformed.
|
|
|
|
func Unpad(n int, buf []byte) ([]byte, error) {
|
|
|
|
if n <= 1 || n >= 256 {
|
|
|
|
panic("bad multiple")
|
|
|
|
}
|
|
|
|
length := len(buf)
|
|
|
|
if length == 0 {
|
|
|
|
return nil, ErrorPaddingNotFound
|
|
|
|
}
|
|
|
|
if (length % n) != 0 {
|
|
|
|
return nil, ErrorPaddingNotAMultiple
|
|
|
|
}
|
|
|
|
padding := int(buf[length-1])
|
|
|
|
if padding > n {
|
|
|
|
return nil, ErrorPaddingTooLong
|
|
|
|
}
|
|
|
|
if padding == 0 {
|
|
|
|
return nil, ErrorPaddingTooShort
|
|
|
|
}
|
|
|
|
for i := 0; i < padding; i++ {
|
|
|
|
if buf[length-1-i] != byte(padding) {
|
|
|
|
return nil, ErrorPaddingNotAllTheSame
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return buf[:length-padding], nil
|
|
|
|
}
|