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 }