Add error handling for encryption routines

This commit is contained in:
Bernd Schoolmann 2024-04-05 08:05:35 +02:00
parent 6ac5754075
commit f798ef3825
No known key found for this signature in database
2 changed files with 60 additions and 34 deletions

View File

@ -9,6 +9,7 @@ import (
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"errors"
"fmt"
"io"
"math"
@ -170,7 +171,7 @@ func isMacValid(message, messageMAC, key []byte) bool {
return hmac.Equal(messageMAC, expectedMAC)
}
func encryptAESCBC256(data, key []byte) (iv, ciphertext []byte, _ error) {
func encryptAESCBC256(data, key []byte) (iv, ciphertext []byte, err error) {
data = padPKCS7(data, aes.BlockSize)
block, err := aes.NewCipher(key)
if err != nil {
@ -182,12 +183,28 @@ func encryptAESCBC256(data, key []byte) (iv, ciphertext []byte, _ error) {
if _, err := io.ReadFull(cryptorand.Reader, iv); err != nil {
return nil, nil, err
}
defer func() {
if r := recover(); r != nil {
var ok bool
err, ok = r.(error)
if !ok {
iv = nil
ciphertext = nil
err = errors.New("error encrypting AES CBC 256 data")
}
}
}()
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, data)
return iv, ciphertext, nil
}
func decryptAESCBC256(iv, ciphertext, key []byte) ([]byte, error) {
func decryptAESCBC256(iv, ciphertext, key []byte) (decryptedData []byte, err error) {
ciphertextCopy := make([]byte, len(ciphertext))
copy(ciphertextCopy, ciphertext)
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
@ -195,28 +212,50 @@ func decryptAESCBC256(iv, ciphertext, key []byte) ([]byte, error) {
if len(iv) != aes.BlockSize {
return nil, fmt.Errorf("iv length does not match AES block size")
}
if len(ciphertext)%aes.BlockSize != 0 {
if len(ciphertextCopy)%aes.BlockSize != 0 {
return nil, fmt.Errorf("ciphertext is not a multiple of AES block size")
}
defer func() {
if r := recover(); r != nil {
var ok bool
err, ok = r.(error)
if !ok {
decryptedData = nil
err = errors.New("error decrypting AES CBC 256 data")
}
}
}()
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(ciphertext, ciphertext) // decrypt in-place
data, err := unpadPKCS7(ciphertext, aes.BlockSize)
mode.CryptBlocks(ciphertextCopy, ciphertextCopy) // decrypt in-place
data, err := unpadPKCS7(ciphertextCopy, aes.BlockSize)
if err != nil {
return nil, err
}
return data, nil
resultBuffer := make([]byte, len(data))
copy(resultBuffer, data)
return resultBuffer, nil
}
func unpadPKCS7(src []byte, size int) ([]byte, error) {
n := src[len(src)-1]
if len(src)%size != 0 {
return nil, fmt.Errorf("expected PKCS7 padding for block size %d, but have %d bytes", size, len(src))
srcCopy := make([]byte, len(src))
copy(srcCopy, src)
n := srcCopy[len(srcCopy)-1]
if len(srcCopy)%size != 0 {
return nil, fmt.Errorf("expected PKCS7 padding for block size %d, but have %d bytes", size, len(srcCopy))
}
if len(src) <= int(n) {
return nil, fmt.Errorf("cannot unpad %d bytes out of a total of %d", n, len(src))
if len(srcCopy) <= int(n) {
return nil, fmt.Errorf("cannot unpad %d bytes out of a total of %d", n, len(srcCopy))
}
src = src[:len(src)-int(n)]
return src, nil
srcCopy = srcCopy[:len(srcCopy)-int(n)]
resultCopy := make([]byte, len(srcCopy))
copy(resultCopy, srcCopy)
return resultCopy, nil
}
func padPKCS7(src []byte, size int) []byte {

View File

@ -2,8 +2,6 @@ package crypto
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/rand"
"crypto/rsa"
@ -12,12 +10,14 @@ import (
"crypto/x509"
"errors"
"fmt"
"io"
"strconv"
"github.com/awnumar/memguard"
"github.com/quexten/goldwarden/logging"
)
var cryptoLog = logging.GetLogger("Goldwarden", "Crypto")
type EncString struct {
Type EncStringType
IV, CT, MAC []byte
@ -131,11 +131,6 @@ func DecryptWith(s EncString, key SymmetricEncryptionKey) ([]byte, error) {
return nil, err
}
block, err := aes.NewCipher(encKeyData)
if err != nil {
return nil, err
}
switch s.Type {
case AesCbc256_B64, AesCbc256_HmacSha256_B64:
break
@ -161,13 +156,11 @@ func DecryptWith(s EncString, key SymmetricEncryptionKey) ([]byte, error) {
return nil, fmt.Errorf("decrypt: invalid IV length, expected %d, got %d", block.BlockSize(), len(s.IV))
}
mode := cipher.NewCBCDecrypter(block, s.IV)
dst := make([]byte, len(s.CT))
mode.CryptBlocks(dst, s.CT)
dst, err = unpadPKCS7(dst, aes.BlockSize)
dst, err := decryptAESCBC256(s.IV, s.CT, encKeyData)
if err != nil {
return nil, err
}
return dst, nil
}
@ -188,19 +181,13 @@ func EncryptWith(data []byte, encType EncStringType, key SymmetricEncryptionKey)
return s, fmt.Errorf("encrypt: unsupported cipher type %q", s.Type)
}
s.Type = encType
data = padPKCS7(data, aes.BlockSize)
block, err := aes.NewCipher(encKeyData)
iv, ciphertext, err := encryptAESCBC256(data, encKeyData)
if err != nil {
return s, err
}
s.IV = make([]byte, aes.BlockSize)
if _, err := io.ReadFull(rand.Reader, s.IV); err != nil {
return s, err
}
s.CT = make([]byte, len(data))
mode := cipher.NewCBCEncrypter(block, s.IV)
mode.CryptBlocks(s.CT, data)
s.CT = ciphertext
s.IV = iv
if encType == AesCbc256_HmacSha256_B64 {
if len(macKeyData) == 0 {