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

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