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

     1  package padding
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/emmansun/gmsm/internal/alias"
     7  )
     8  
     9  // Add a single bit with value 1 to the end of the data. 
    10  // Then if necessary add bits with value 0 to the end of the data until the padded data is a multiple of n.
    11  //
    12  // https://en.wikipedia.org/wiki/ISO/IEC_9797-1
    13  // also GB/T 17964-2021 C.2 Padding method 2
    14  type iso9797M2Padding uint
    15  
    16  func (pad iso9797M2Padding) BlockSize() int {
    17  	return int(pad)
    18  }
    19  
    20  func (pad iso9797M2Padding) Pad(src []byte) []byte {
    21  	overhead := pad.BlockSize() - len(src)%pad.BlockSize()
    22  	ret, out := alias.SliceForAppend(src, overhead)
    23  	out[0] = 0x80
    24  	for i := 1; i < overhead; i++ {
    25  		out[i] = 0
    26  	}
    27  	return ret
    28  }
    29  
    30  // Unpad decrypted plaintext, non-constant-time
    31  func (pad iso9797M2Padding) Unpad(src []byte) ([]byte, error) {
    32  	srcLen := len(src)
    33  	if srcLen == 0 || srcLen%pad.BlockSize() != 0 {
    34  		return nil, errors.New("padding: src length is not multiple of block size")
    35  	}
    36  	padStart := -1
    37  
    38  	for i, b := range src[srcLen-pad.BlockSize() : srcLen] {
    39  		if b == 0x80 {
    40  			padStart = i
    41  		} else if b != 0 && padStart >=0 {
    42  			padStart = -1
    43  		}
    44  	}
    45  	if padStart >= 0 {
    46  		return src[:srcLen-pad.BlockSize()+padStart], nil	
    47  	}
    48  	return src, nil
    49  }