Skip to content

Commit b12cf9c

Browse files
committed
cbcutil: optimize memory usage when adding padding and mac
1 parent 522e440 commit b12cf9c

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

util/cbcutil/cbc.go

+15-13
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,16 @@ func DecryptFile(key, iv []byte, file File) error {
108108
Encrypt is a function that encrypts plaintext with a given key and an optional initialization vector(iv).
109109
*/
110110
func Encrypt(key, iv, plaintext []byte) ([]byte, error) {
111-
plaintext = pad(plaintext, aes.BlockSize)
111+
sizeOfLastBlock := len(plaintext) % aes.BlockSize
112+
paddingLen := aes.BlockSize - sizeOfLastBlock
113+
plaintextStart := plaintext[:len(plaintext)-sizeOfLastBlock]
114+
lastBlock := append(plaintext[len(plaintext)-sizeOfLastBlock:], bytes.Repeat([]byte{byte(paddingLen)}, paddingLen)...)
112115

113-
if len(plaintext)%aes.BlockSize != 0 {
114-
return nil, fmt.Errorf("plaintext is not a multiple of the block size: %d / %d", len(plaintext), aes.BlockSize)
116+
if len(plaintextStart)%aes.BlockSize != 0 {
117+
panic(fmt.Errorf("plaintext is not the correct size: %d %% %d != 0", len(plaintextStart), aes.BlockSize))
118+
}
119+
if len(lastBlock) != aes.BlockSize {
120+
panic(fmt.Errorf("last block is not the correct size: %d != %d", len(lastBlock), aes.BlockSize))
115121
}
116122

117123
block, err := aes.NewCipher(key)
@@ -121,30 +127,26 @@ func Encrypt(key, iv, plaintext []byte) ([]byte, error) {
121127

122128
var ciphertext []byte
123129
if iv == nil {
124-
ciphertext = make([]byte, aes.BlockSize+len(plaintext))
130+
ciphertext = make([]byte, aes.BlockSize+len(plaintext)+paddingLen)
125131
iv := ciphertext[:aes.BlockSize]
126132
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
127133
return nil, err
128134
}
129135

130136
cbc := cipher.NewCBCEncrypter(block, iv)
131-
cbc.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
137+
cbc.CryptBlocks(ciphertext[aes.BlockSize:], plaintextStart)
138+
cbc.CryptBlocks(ciphertext[aes.BlockSize+len(plaintextStart):], lastBlock)
132139
} else {
133-
ciphertext = make([]byte, len(plaintext))
140+
ciphertext = make([]byte, len(plaintext)+paddingLen, len(plaintext)+paddingLen+10)
134141

135142
cbc := cipher.NewCBCEncrypter(block, iv)
136-
cbc.CryptBlocks(ciphertext, plaintext)
143+
cbc.CryptBlocks(ciphertext, plaintextStart)
144+
cbc.CryptBlocks(ciphertext[len(plaintextStart):], lastBlock)
137145
}
138146

139147
return ciphertext, nil
140148
}
141149

142-
func pad(ciphertext []byte, blockSize int) []byte {
143-
padding := blockSize - len(ciphertext)%blockSize
144-
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
145-
return append(ciphertext, padtext...)
146-
}
147-
148150
func unpad(src []byte) ([]byte, error) {
149151
length := len(src)
150152
padLen := int(src[length-1])

0 commit comments

Comments
 (0)