github.com/artpar/rclone@v1.67.3/backend/crypt/pkcs7/pkcs7.go (about) 1 // Package pkcs7 implements PKCS#7 padding 2 // 3 // This is a standard way of encoding variable length buffers into 4 // buffers which are a multiple of an underlying crypto block size. 5 package pkcs7 6 7 import "errors" 8 9 // Errors Unpad can return 10 var ( 11 ErrorPaddingNotFound = errors.New("bad PKCS#7 padding - not padded") 12 ErrorPaddingNotAMultiple = errors.New("bad PKCS#7 padding - not a multiple of blocksize") 13 ErrorPaddingTooLong = errors.New("bad PKCS#7 padding - too long") 14 ErrorPaddingTooShort = errors.New("bad PKCS#7 padding - too short") 15 ErrorPaddingNotAllTheSame = errors.New("bad PKCS#7 padding - not all the same") 16 ) 17 18 // Pad buf using PKCS#7 to a multiple of n. 19 // 20 // Appends the padding to buf - make a copy of it first if you don't 21 // want it modified. 22 func Pad(n int, buf []byte) []byte { 23 if n <= 1 || n >= 256 { 24 panic("bad multiple") 25 } 26 length := len(buf) 27 padding := n - (length % n) 28 for i := 0; i < padding; i++ { 29 buf = append(buf, byte(padding)) 30 } 31 if (len(buf) % n) != 0 { 32 panic("padding failed") 33 } 34 return buf 35 } 36 37 // Unpad buf using PKCS#7 from a multiple of n returning a slice of 38 // buf or an error if malformed. 39 func Unpad(n int, buf []byte) ([]byte, error) { 40 if n <= 1 || n >= 256 { 41 panic("bad multiple") 42 } 43 length := len(buf) 44 if length == 0 { 45 return nil, ErrorPaddingNotFound 46 } 47 if (length % n) != 0 { 48 return nil, ErrorPaddingNotAMultiple 49 } 50 padding := int(buf[length-1]) 51 if padding > n { 52 return nil, ErrorPaddingTooLong 53 } 54 if padding == 0 { 55 return nil, ErrorPaddingTooShort 56 } 57 for i := 0; i < padding; i++ { 58 if buf[length-1-i] != byte(padding) { 59 return nil, ErrorPaddingNotAllTheSame 60 } 61 } 62 return buf[:length-padding], nil 63 }