feat: prepare KMS data encryption for migration to AES-GCM

Signed-off-by: Anish Ramasekar <anish.ramasekar@gmail.com>
Co-authored-by: Monis Khan <mok@vmware.com>
Signed-off-by: Anish Ramasekar <anish.ramasekar@gmail.com>

Kubernetes-commit: 90b42f91fd904b71fd52ca9ae55a5de73e6b779a
This commit is contained in:
Anish Ramasekar 2022-03-16 17:54:10 +00:00 committed by Kubernetes Publisher
parent 4a77293840
commit e442eafb33
2 changed files with 35 additions and 3 deletions

View File

@ -17,6 +17,7 @@ limitations under the License.
package encryptionconfig
import (
"context"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
@ -32,6 +33,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
apiserverconfig "k8s.io/apiserver/pkg/apis/config"
apiserverconfigv1 "k8s.io/apiserver/pkg/apis/config/v1"
"k8s.io/apiserver/pkg/apis/config/validation"
@ -365,7 +367,13 @@ func secretboxPrefixTransformer(config *apiserverconfig.SecretboxConfiguration)
}
func envelopePrefixTransformer(config *apiserverconfig.KMSConfiguration, envelopeService envelope.Service, prefix string) (value.PrefixTransformer, error) {
envelopeTransformer, err := envelope.NewEnvelopeTransformer(envelopeService, int(*config.CacheSize), aestransformer.NewCBCTransformer)
baseTransformerFunc := func(block cipher.Block) value.Transformer {
// v1.24: write using AES-CBC only but support reads via AES-CBC and AES-GCM (so we can move to AES-GCM)
// TODO(aramase): swap this ordering in v1.25
return unionTransformers{aestransformer.NewCBCTransformer(block), aestransformer.NewGCMTransformer(block)}
}
envelopeTransformer, err := envelope.NewEnvelopeTransformer(envelopeService, int(*config.CacheSize), baseTransformerFunc)
if err != nil {
return value.PrefixTransformer{}, err
}
@ -374,3 +382,27 @@ func envelopePrefixTransformer(config *apiserverconfig.KMSConfiguration, envelop
Prefix: []byte(prefix + config.Name + ":"),
}, nil
}
type unionTransformers []value.Transformer
func (u unionTransformers) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) (out []byte, stale bool, err error) {
var errs []error
for i, transformer := range u {
result, stale, err := transformer.TransformFromStorage(ctx, data, dataCtx)
if err != nil {
errs = append(errs, err)
continue
}
// when i != 0, we have transformed the data from storage using the new transformer,
// we want to issue a write to etcd even if the contents of the data haven't changed
return result, stale || i != 0, nil
}
if err := utilerrors.Reduce(utilerrors.NewAggregate(errs)); err != nil {
return nil, false, err
}
return nil, false, fmt.Errorf("unionTransformers: unable to transform from storage")
}
func (u unionTransformers) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) (out []byte, err error) {
return u[0].TransformToStorage(ctx, data, dataCtx)
}

View File

@ -96,7 +96,7 @@ func NewCBCTransformer(block cipher.Block) value.Transformer {
}
var (
errInvalidBlockSize = fmt.Errorf("the stored data is not a multiple of the block size")
ErrInvalidBlockSize = fmt.Errorf("the stored data is not a multiple of the block size")
errInvalidPKCS7Data = errors.New("invalid PKCS7 data (empty or not padded)")
errInvalidPKCS7Padding = errors.New("invalid padding on input")
)
@ -110,7 +110,7 @@ func (t *cbc) TransformFromStorage(ctx context.Context, data []byte, dataCtx val
data = data[blockSize:]
if len(data)%blockSize != 0 {
return nil, false, errInvalidBlockSize
return nil, false, ErrInvalidBlockSize
}
result := make([]byte, len(data))