Add benchmarks for envelope transformer
This commit is contained in:
		| @@ -15,7 +15,6 @@ go_library( | |||||||
|     deps = [ |     deps = [ | ||||||
|         "//vendor/github.com/hashicorp/golang-lru:go_default_library", |         "//vendor/github.com/hashicorp/golang-lru:go_default_library", | ||||||
|         "//vendor/k8s.io/apiserver/pkg/storage/value:go_default_library", |         "//vendor/k8s.io/apiserver/pkg/storage/value:go_default_library", | ||||||
|         "//vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes:go_default_library", |  | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -24,5 +23,8 @@ go_test( | |||||||
|     srcs = ["envelope_test.go"], |     srcs = ["envelope_test.go"], | ||||||
|     library = ":go_default_library", |     library = ":go_default_library", | ||||||
|     tags = ["automanaged"], |     tags = ["automanaged"], | ||||||
|     deps = ["//vendor/k8s.io/apiserver/pkg/storage/value:go_default_library"], |     deps = [ | ||||||
|  |         "//vendor/k8s.io/apiserver/pkg/storage/value:go_default_library", | ||||||
|  |         "//vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes:go_default_library", | ||||||
|  |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -19,12 +19,12 @@ package envelope | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"crypto/aes" | 	"crypto/aes" | ||||||
|  | 	"crypto/cipher" | ||||||
| 	"crypto/rand" | 	"crypto/rand" | ||||||
| 	"encoding/binary" | 	"encoding/binary" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"k8s.io/apiserver/pkg/storage/value" | 	"k8s.io/apiserver/pkg/storage/value" | ||||||
| 	aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" |  | ||||||
|  |  | ||||||
| 	lru "github.com/hashicorp/golang-lru" | 	lru "github.com/hashicorp/golang-lru" | ||||||
| ) | ) | ||||||
| @@ -48,13 +48,16 @@ type envelopeTransformer struct { | |||||||
|  |  | ||||||
| 	// cacheSize is the maximum number of DEKs that are cached. | 	// cacheSize is the maximum number of DEKs that are cached. | ||||||
| 	cacheSize int | 	cacheSize int | ||||||
|  |  | ||||||
|  | 	// baseTransformerFunc creates a new transformer for encrypting the data with the DEK. | ||||||
|  | 	baseTransformerFunc func(cipher.Block) value.Transformer | ||||||
| } | } | ||||||
|  |  | ||||||
| // NewEnvelopeTransformer returns a transformer which implements a KEK-DEK based envelope encryption scheme. | // NewEnvelopeTransformer returns a transformer which implements a KEK-DEK based envelope encryption scheme. | ||||||
| // It uses envelopeService to encrypt and decrypt DEKs. Respective DEKs (in encrypted form) are prepended to | // It uses envelopeService to encrypt and decrypt DEKs. Respective DEKs (in encrypted form) are prepended to | ||||||
| // the data items they encrypt. A cache (of size cacheSize) is maintained to store the most recently | // the data items they encrypt. A cache (of size cacheSize) is maintained to store the most recently | ||||||
| // used decrypted DEKs in memory. | // used decrypted DEKs in memory. | ||||||
| func NewEnvelopeTransformer(envelopeService Service, cacheSize int) (value.Transformer, error) { | func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) (value.Transformer, error) { | ||||||
| 	if cacheSize == 0 { | 	if cacheSize == 0 { | ||||||
| 		cacheSize = defaultCacheSize | 		cacheSize = defaultCacheSize | ||||||
| 	} | 	} | ||||||
| @@ -63,9 +66,10 @@ func NewEnvelopeTransformer(envelopeService Service, cacheSize int) (value.Trans | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return &envelopeTransformer{ | 	return &envelopeTransformer{ | ||||||
| 		envelopeService: envelopeService, | 		envelopeService:     envelopeService, | ||||||
| 		transformers:    cache, | 		transformers:        cache, | ||||||
| 		cacheSize:       cacheSize, | 		cacheSize:           cacheSize, | ||||||
|  | 		baseTransformerFunc: baseTransformerFunc, | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -141,7 +145,7 @@ func (t *envelopeTransformer) addTransformer(encKey string, key []byte) (value.T | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	transformer := aestransformer.NewCBCTransformer(block) | 	transformer := t.baseTransformerFunc(block) | ||||||
| 	t.transformers.Add(encKey, transformer) | 	t.transformers.Add(encKey, transformer) | ||||||
| 	return transformer, nil | 	return transformer, nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ package envelope | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
|  | 	"crypto/aes" | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| @@ -25,6 +26,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"k8s.io/apiserver/pkg/storage/value" | 	"k8s.io/apiserver/pkg/storage/value" | ||||||
|  | 	aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -76,7 +78,7 @@ func newTestEnvelopeService() *testEnvelopeService { | |||||||
| // Throw error if Envelope transformer tries to contact Envelope without hitting cache. | // Throw error if Envelope transformer tries to contact Envelope without hitting cache. | ||||||
| func TestEnvelopeCaching(t *testing.T) { | func TestEnvelopeCaching(t *testing.T) { | ||||||
| 	envelopeService := newTestEnvelopeService() | 	envelopeService := newTestEnvelopeService() | ||||||
| 	envelopeTransformer, err := NewEnvelopeTransformer(envelopeService, testEnvelopeCacheSize) | 	envelopeTransformer, err := NewEnvelopeTransformer(envelopeService, testEnvelopeCacheSize, aestransformer.NewCBCTransformer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("failed to initialize envelope transformer: %v", err) | 		t.Fatalf("failed to initialize envelope transformer: %v", err) | ||||||
| 	} | 	} | ||||||
| @@ -108,7 +110,7 @@ func TestEnvelopeCaching(t *testing.T) { | |||||||
|  |  | ||||||
| // Makes Envelope transformer hit cache limit, throws error if it misbehaves. | // Makes Envelope transformer hit cache limit, throws error if it misbehaves. | ||||||
| func TestEnvelopeCacheLimit(t *testing.T) { | func TestEnvelopeCacheLimit(t *testing.T) { | ||||||
| 	envelopeTransformer, err := NewEnvelopeTransformer(newTestEnvelopeService(), testEnvelopeCacheSize) | 	envelopeTransformer, err := NewEnvelopeTransformer(newTestEnvelopeService(), testEnvelopeCacheSize, aestransformer.NewCBCTransformer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("failed to initialize envelope transformer: %v", err) | 		t.Fatalf("failed to initialize envelope transformer: %v", err) | ||||||
| 	} | 	} | ||||||
| @@ -141,3 +143,61 @@ func TestEnvelopeCacheLimit(t *testing.T) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func BenchmarkEnvelopeCBCRead(b *testing.B) { | ||||||
|  | 	envelopeTransformer, err := NewEnvelopeTransformer(newTestEnvelopeService(), testEnvelopeCacheSize, aestransformer.NewCBCTransformer) | ||||||
|  | 	if err != nil { | ||||||
|  | 		b.Fatalf("failed to initialize envelope transformer: %v", err) | ||||||
|  | 	} | ||||||
|  | 	benchmarkRead(b, envelopeTransformer, 1024) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func BenchmarkAESCBCRead(b *testing.B) { | ||||||
|  | 	block, err := aes.NewCipher(bytes.Repeat([]byte("a"), 32)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		b.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	aesCBCTransformer := aestransformer.NewCBCTransformer(block) | ||||||
|  | 	benchmarkRead(b, aesCBCTransformer, 1024) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func BenchmarkEnvelopeGCMRead(b *testing.B) { | ||||||
|  | 	envelopeTransformer, err := NewEnvelopeTransformer(newTestEnvelopeService(), testEnvelopeCacheSize, aestransformer.NewGCMTransformer) | ||||||
|  | 	if err != nil { | ||||||
|  | 		b.Fatalf("failed to initialize envelope transformer: %v", err) | ||||||
|  | 	} | ||||||
|  | 	benchmarkRead(b, envelopeTransformer, 1024) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func BenchmarkAESGCMRead(b *testing.B) { | ||||||
|  | 	block, err := aes.NewCipher(bytes.Repeat([]byte("a"), 32)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		b.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	aesGCMTransformer := aestransformer.NewGCMTransformer(block) | ||||||
|  | 	benchmarkRead(b, aesGCMTransformer, 1024) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func benchmarkRead(b *testing.B, transformer value.Transformer, valueLength int) { | ||||||
|  | 	context := value.DefaultContext([]byte(testContextText)) | ||||||
|  | 	v := bytes.Repeat([]byte("0123456789abcdef"), valueLength/16) | ||||||
|  |  | ||||||
|  | 	out, err := transformer.TransformToStorage(v, context) | ||||||
|  | 	if err != nil { | ||||||
|  | 		b.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	b.ResetTimer() | ||||||
|  | 	for i := 0; i < b.N; i++ { | ||||||
|  | 		from, stale, err := transformer.TransformFromStorage(out, context) | ||||||
|  | 		if err != nil { | ||||||
|  | 			b.Fatal(err) | ||||||
|  | 		} | ||||||
|  | 		if stale { | ||||||
|  | 			b.Fatalf("unexpected data: %t %q", stale, from) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	b.StopTimer() | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Saksham Sharma
					Saksham Sharma