github.com/emmansun/gmsm@v0.29.1/padding/pkcs7.go (about)

     1  package padding
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/emmansun/gmsm/internal/alias"
     7  )
     8  
     9  // https://datatracker.ietf.org/doc/html/rfc5652#section-6.3
    10  type pkcs7Padding uint
    11  
    12  func (pad pkcs7Padding) BlockSize() int {
    13  	return int(pad)
    14  }
    15  
    16  func (pad pkcs7Padding) Pad(src []byte) []byte {
    17  	overhead := pad.BlockSize() - len(src)%pad.BlockSize()
    18  	ret, out := alias.SliceForAppend(src, overhead)
    19  	for i := 0; i < overhead; i++ {
    20  		out[i] = byte(overhead)
    21  	}
    22  	return ret
    23  }
    24  
    25  // Unpad decrypted plaintext, non-constant-time
    26  func (pad pkcs7Padding) Unpad(src []byte) ([]byte, error) {
    27  	srcLen := len(src)
    28  	if srcLen == 0 || srcLen%pad.BlockSize() != 0 {
    29  		return nil, errors.New("padding: src length is not multiple of block size")
    30  	}
    31  	paddedLen := src[srcLen-1]
    32  	if paddedLen == 0 || int(paddedLen) > pad.BlockSize() {
    33  		return nil, errors.New("padding: invalid padding byte/length")
    34  	}
    35  	for _, b := range src[srcLen-int(paddedLen) : srcLen-1] {
    36  		if b != paddedLen {
    37  			return nil, errors.New("padding: inconsistent padding bytes")
    38  		}
    39  	}
    40  	return src[:srcLen-int(paddedLen)], nil
    41  }