github.com/msales/pkg/v3@v3.24.0/cryptox/padding.go (about)

     1  package cryptox
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  )
     7  
     8  var (
     9  	// errInvalidBlockSize indicates hash blocksize <= 0.
    10  	errInvalidBlockSize = errors.New("cryptox: invalid blocksize")
    11  	// errInvalidPKCS7Data indicates bad input to PKCS7 pad or unpad.
    12  	errInvalidPKCS7Data = errors.New("cryptox: invalid PKCS7 data (empty or not padded)")
    13  	// errInvalidPKCS7Padding indicates PKCS7 unpad fail because of bad input.
    14  	errInvalidPKCS7Padding = errors.New("cryptox: invalid padding on input")
    15  )
    16  
    17  // PKCS7Pad right-pads the given byte slice with 1 to n bytes, where
    18  // n is the block size. The size of the result is x times n, where x
    19  // is at least 1.
    20  func PKCS7Pad(b []byte, blocksize int) ([]byte, error) {
    21  	if blocksize <= 0 {
    22  		return nil, errInvalidBlockSize
    23  	}
    24  	if b == nil || len(b) == 0 {
    25  		return nil, errInvalidPKCS7Data
    26  	}
    27  
    28  	n := blocksize - (len(b) % blocksize)
    29  	pb := make([]byte, len(b)+n)
    30  
    31  	copy(pb, b)
    32  	copy(pb[len(b):], bytes.Repeat([]byte{byte(n)}, n))
    33  
    34  	return pb, nil
    35  }
    36  
    37  // PKCS7Unpad validates and unpads THE data from the given bytes slice.
    38  // The returned value will be 1 to n bytes smaller depending on the
    39  // amount of padding, where n is the block size.
    40  func PKCS7Unpad(b []byte, blocksize int) ([]byte, error) {
    41  	if blocksize <= 0 {
    42  		return nil, errInvalidBlockSize
    43  	}
    44  	if b == nil || len(b) == 0 {
    45  		return nil, errInvalidPKCS7Data
    46  	}
    47  	if len(b)%blocksize != 0 {
    48  		return nil, errInvalidPKCS7Padding
    49  	}
    50  
    51  	c := b[len(b)-1]
    52  	n := int(c)
    53  
    54  	if n == 0 || n > len(b) {
    55  		return nil, errInvalidPKCS7Padding
    56  	}
    57  
    58  	for i := 0; i < n; i++ {
    59  		if b[len(b)-n+i] != c {
    60  			return nil, errInvalidPKCS7Padding
    61  		}
    62  	}
    63  
    64  	return b[:len(b)-n], nil
    65  }