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 }