1/*-
2 * Copyright 2014 Square Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package jose
18
19import (
20	"bytes"
21	"crypto/ecdsa"
22	"crypto/elliptic"
23	"crypto/rand"
24	"crypto/rsa"
25	"fmt"
26	"io"
27	"testing"
28)
29
30// We generate only a single RSA and EC key for testing, speeds up tests.
31var rsaTestKey, _ = rsa.GenerateKey(rand.Reader, 2048)
32
33var ecTestKey256, _ = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
34var ecTestKey384, _ = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
35var ecTestKey521, _ = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
36
37func RoundtripJWE(keyAlg KeyAlgorithm, encAlg ContentEncryption, compressionAlg CompressionAlgorithm, serializer func(*JsonWebEncryption) (string, error), corrupter func(*JsonWebEncryption) bool, aad []byte, encryptionKey interface{}, decryptionKey interface{}) error {
38	enc, err := NewEncrypter(keyAlg, encAlg, encryptionKey)
39	if err != nil {
40		return fmt.Errorf("error on new encrypter: %s", err)
41	}
42
43	enc.SetCompression(compressionAlg)
44
45	input := []byte("Lorem ipsum dolor sit amet")
46	obj, err := enc.EncryptWithAuthData(input, aad)
47	if err != nil {
48		return fmt.Errorf("error in encrypt: %s", err)
49	}
50
51	msg, err := serializer(obj)
52	if err != nil {
53		return fmt.Errorf("error in serializer: %s", err)
54	}
55
56	parsed, err := ParseEncrypted(msg)
57	if err != nil {
58		return fmt.Errorf("error in parse: %s, on msg '%s'", err, msg)
59	}
60
61	// (Maybe) mangle object
62	skip := corrupter(parsed)
63	if skip {
64		return fmt.Errorf("corrupter indicated message should be skipped")
65	}
66
67	if bytes.Compare(parsed.GetAuthData(), aad) != 0 {
68		return fmt.Errorf("auth data in parsed object does not match")
69	}
70
71	output, err := parsed.Decrypt(decryptionKey)
72	if err != nil {
73		return fmt.Errorf("error on decrypt: %s", err)
74	}
75
76	if bytes.Compare(input, output) != 0 {
77		return fmt.Errorf("Decrypted output does not match input, got '%s' but wanted '%s'", output, input)
78	}
79
80	return nil
81}
82
83func TestRoundtripsJWE(t *testing.T) {
84	// Test matrix
85	keyAlgs := []KeyAlgorithm{
86		DIRECT, ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW, A128KW, A192KW, A256KW,
87		RSA1_5, RSA_OAEP, RSA_OAEP_256, A128GCMKW, A192GCMKW, A256GCMKW}
88	encAlgs := []ContentEncryption{A128GCM, A192GCM, A256GCM, A128CBC_HS256, A192CBC_HS384, A256CBC_HS512}
89	zipAlgs := []CompressionAlgorithm{NONE, DEFLATE}
90
91	serializers := []func(*JsonWebEncryption) (string, error){
92		func(obj *JsonWebEncryption) (string, error) { return obj.CompactSerialize() },
93		func(obj *JsonWebEncryption) (string, error) { return obj.FullSerialize(), nil },
94	}
95
96	corrupter := func(obj *JsonWebEncryption) bool { return false }
97
98	// Note: can't use AAD with compact serialization
99	aads := [][]byte{
100		nil,
101		[]byte("Ut enim ad minim veniam"),
102	}
103
104	// Test all different configurations
105	for _, alg := range keyAlgs {
106		for _, enc := range encAlgs {
107			for _, key := range generateTestKeys(alg, enc) {
108				for _, zip := range zipAlgs {
109					for i, serializer := range serializers {
110						err := RoundtripJWE(alg, enc, zip, serializer, corrupter, aads[i], key.enc, key.dec)
111						if err != nil {
112							t.Error(err, alg, enc, zip, i)
113						}
114					}
115				}
116			}
117		}
118	}
119}
120
121func TestRoundtripsJWECorrupted(t *testing.T) {
122	// Test matrix
123	keyAlgs := []KeyAlgorithm{DIRECT, ECDH_ES, ECDH_ES_A128KW, A128KW, RSA1_5, RSA_OAEP, RSA_OAEP_256, A128GCMKW}
124	encAlgs := []ContentEncryption{A128GCM, A192GCM, A256GCM, A128CBC_HS256, A192CBC_HS384, A256CBC_HS512}
125	zipAlgs := []CompressionAlgorithm{NONE, DEFLATE}
126
127	serializers := []func(*JsonWebEncryption) (string, error){
128		func(obj *JsonWebEncryption) (string, error) { return obj.CompactSerialize() },
129		func(obj *JsonWebEncryption) (string, error) { return obj.FullSerialize(), nil },
130	}
131
132	bitflip := func(slice []byte) bool {
133		if len(slice) > 0 {
134			slice[0] ^= 0xFF
135			return false
136		}
137		return true
138	}
139
140	corrupters := []func(*JsonWebEncryption) bool{
141		func(obj *JsonWebEncryption) bool {
142			// Set invalid ciphertext
143			return bitflip(obj.ciphertext)
144		},
145		func(obj *JsonWebEncryption) bool {
146			// Set invalid auth tag
147			return bitflip(obj.tag)
148		},
149		func(obj *JsonWebEncryption) bool {
150			// Set invalid AAD
151			return bitflip(obj.aad)
152		},
153		func(obj *JsonWebEncryption) bool {
154			// Mess with encrypted key
155			return bitflip(obj.recipients[0].encryptedKey)
156		},
157		func(obj *JsonWebEncryption) bool {
158			// Mess with GCM-KW auth tag
159			return bitflip(obj.protected.Tag.bytes())
160		},
161	}
162
163	// Note: can't use AAD with compact serialization
164	aads := [][]byte{
165		nil,
166		[]byte("Ut enim ad minim veniam"),
167	}
168
169	// Test all different configurations
170	for _, alg := range keyAlgs {
171		for _, enc := range encAlgs {
172			for _, key := range generateTestKeys(alg, enc) {
173				for _, zip := range zipAlgs {
174					for i, serializer := range serializers {
175						for j, corrupter := range corrupters {
176							err := RoundtripJWE(alg, enc, zip, serializer, corrupter, aads[i], key.enc, key.dec)
177							if err == nil {
178								t.Error("failed to detect corrupt data", err, alg, enc, zip, i, j)
179							}
180						}
181					}
182				}
183			}
184		}
185	}
186}
187
188func TestEncrypterWithJWKAndKeyID(t *testing.T) {
189	enc, err := NewEncrypter(A128KW, A128GCM, &JsonWebKey{
190		KeyID: "test-id",
191		Key:   []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
192	})
193	if err != nil {
194		t.Error(err)
195	}
196
197	ciphertext, _ := enc.Encrypt([]byte("Lorem ipsum dolor sit amet"))
198
199	serialized1, _ := ciphertext.CompactSerialize()
200	serialized2 := ciphertext.FullSerialize()
201
202	parsed1, _ := ParseEncrypted(serialized1)
203	parsed2, _ := ParseEncrypted(serialized2)
204
205	if parsed1.Header.KeyID != "test-id" {
206		t.Errorf("expected message to have key id from JWK, but found '%s' instead", parsed1.Header.KeyID)
207	}
208	if parsed2.Header.KeyID != "test-id" {
209		t.Errorf("expected message to have key id from JWK, but found '%s' instead", parsed2.Header.KeyID)
210	}
211}
212
213func TestEncrypterWithBrokenRand(t *testing.T) {
214	keyAlgs := []KeyAlgorithm{ECDH_ES_A128KW, A128KW, RSA1_5, RSA_OAEP, RSA_OAEP_256, A128GCMKW}
215	encAlgs := []ContentEncryption{A128GCM, A192GCM, A256GCM, A128CBC_HS256, A192CBC_HS384, A256CBC_HS512}
216
217	serializer := func(obj *JsonWebEncryption) (string, error) { return obj.CompactSerialize() }
218	corrupter := func(obj *JsonWebEncryption) bool { return false }
219
220	// Break rand reader
221	readers := []func() io.Reader{
222		// Totally broken
223		func() io.Reader { return bytes.NewReader([]byte{}) },
224		// Not enough bytes
225		func() io.Reader { return io.LimitReader(rand.Reader, 20) },
226	}
227
228	defer resetRandReader()
229
230	for _, alg := range keyAlgs {
231		for _, enc := range encAlgs {
232			for _, key := range generateTestKeys(alg, enc) {
233				for i, getReader := range readers {
234					randReader = getReader()
235					err := RoundtripJWE(alg, enc, NONE, serializer, corrupter, nil, key.enc, key.dec)
236					if err == nil {
237						t.Error("encrypter should fail if rand is broken", i)
238					}
239				}
240			}
241		}
242	}
243}
244
245func TestNewEncrypterErrors(t *testing.T) {
246	_, err := NewEncrypter("XYZ", "XYZ", nil)
247	if err == nil {
248		t.Error("was able to instantiate encrypter with invalid cipher")
249	}
250
251	_, err = NewMultiEncrypter("XYZ")
252	if err == nil {
253		t.Error("was able to instantiate multi-encrypter with invalid cipher")
254	}
255
256	_, err = NewEncrypter(DIRECT, A128GCM, nil)
257	if err == nil {
258		t.Error("was able to instantiate encrypter with invalid direct key")
259	}
260
261	_, err = NewEncrypter(ECDH_ES, A128GCM, nil)
262	if err == nil {
263		t.Error("was able to instantiate encrypter with invalid EC key")
264	}
265}
266
267func TestMultiRecipientJWE(t *testing.T) {
268	enc, err := NewMultiEncrypter(A128GCM)
269	if err != nil {
270		panic(err)
271	}
272
273	err = enc.AddRecipient(RSA_OAEP, &rsaTestKey.PublicKey)
274	if err != nil {
275		t.Fatal("error when adding RSA recipient", err)
276	}
277
278	sharedKey := []byte{
279		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
280		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
281	}
282
283	err = enc.AddRecipient(A256GCMKW, sharedKey)
284	if err != nil {
285		t.Fatal("error when adding AES recipient: ", err)
286	}
287
288	input := []byte("Lorem ipsum dolor sit amet")
289	obj, err := enc.Encrypt(input)
290	if err != nil {
291		t.Fatal("error in encrypt: ", err)
292	}
293
294	msg := obj.FullSerialize()
295
296	parsed, err := ParseEncrypted(msg)
297	if err != nil {
298		t.Fatal("error in parse: ", err)
299	}
300
301	i, _, output, err := parsed.DecryptMulti(rsaTestKey)
302	if err != nil {
303		t.Fatal("error on decrypt with RSA: ", err)
304	}
305
306	if i != 0 {
307		t.Fatal("recipient index should be 0 for RSA key")
308	}
309
310	if bytes.Compare(input, output) != 0 {
311		t.Fatal("Decrypted output does not match input: ", output, input)
312	}
313
314	i, _, output, err = parsed.DecryptMulti(sharedKey)
315	if err != nil {
316		t.Fatal("error on decrypt with AES: ", err)
317	}
318
319	if i != 1 {
320		t.Fatal("recipient index should be 1 for shared key")
321	}
322
323	if bytes.Compare(input, output) != 0 {
324		t.Fatal("Decrypted output does not match input", output, input)
325	}
326}
327
328func TestMultiRecipientErrors(t *testing.T) {
329	enc, err := NewMultiEncrypter(A128GCM)
330	if err != nil {
331		panic(err)
332	}
333
334	input := []byte("Lorem ipsum dolor sit amet")
335	_, err = enc.Encrypt(input)
336	if err == nil {
337		t.Error("should fail when encrypting to zero recipients")
338	}
339
340	err = enc.AddRecipient(DIRECT, nil)
341	if err == nil {
342		t.Error("should reject DIRECT mode when encrypting to multiple recipients")
343	}
344
345	err = enc.AddRecipient(ECDH_ES, nil)
346	if err == nil {
347		t.Error("should reject ECDH_ES mode when encrypting to multiple recipients")
348	}
349
350	err = enc.AddRecipient(RSA1_5, nil)
351	if err == nil {
352		t.Error("should reject invalid recipient key")
353	}
354}
355
356type testKey struct {
357	enc, dec interface{}
358}
359
360func symmetricTestKey(size int) []testKey {
361	key, _, _ := randomKeyGenerator{size: size}.genKey()
362
363	return []testKey{
364		testKey{
365			enc: key,
366			dec: key,
367		},
368		testKey{
369			enc: &JsonWebKey{KeyID: "test", Key: key},
370			dec: &JsonWebKey{KeyID: "test", Key: key},
371		},
372	}
373}
374
375func generateTestKeys(keyAlg KeyAlgorithm, encAlg ContentEncryption) []testKey {
376	switch keyAlg {
377	case DIRECT:
378		return symmetricTestKey(getContentCipher(encAlg).keySize())
379	case ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
380		return []testKey{
381			testKey{
382				dec: ecTestKey256,
383				enc: &ecTestKey256.PublicKey,
384			},
385			testKey{
386				dec: ecTestKey384,
387				enc: &ecTestKey384.PublicKey,
388			},
389			testKey{
390				dec: ecTestKey521,
391				enc: &ecTestKey521.PublicKey,
392			},
393			testKey{
394				dec: &JsonWebKey{KeyID: "test", Key: ecTestKey256},
395				enc: &JsonWebKey{KeyID: "test", Key: &ecTestKey256.PublicKey},
396			},
397		}
398	case A128GCMKW, A128KW:
399		return symmetricTestKey(16)
400	case A192GCMKW, A192KW:
401		return symmetricTestKey(24)
402	case A256GCMKW, A256KW:
403		return symmetricTestKey(32)
404	case RSA1_5, RSA_OAEP, RSA_OAEP_256:
405		return []testKey{testKey{
406			dec: rsaTestKey,
407			enc: &rsaTestKey.PublicKey,
408		}}
409	}
410
411	panic("Must update test case")
412}
413
414func RunRoundtripsJWE(b *testing.B, alg KeyAlgorithm, enc ContentEncryption, zip CompressionAlgorithm, priv, pub interface{}) {
415	serializer := func(obj *JsonWebEncryption) (string, error) {
416		return obj.CompactSerialize()
417	}
418
419	corrupter := func(obj *JsonWebEncryption) bool { return false }
420
421	b.ResetTimer()
422	for i := 0; i < b.N; i++ {
423		err := RoundtripJWE(alg, enc, zip, serializer, corrupter, nil, pub, priv)
424		if err != nil {
425			b.Error(err)
426		}
427	}
428}
429
430var (
431	chunks = map[string][]byte{
432		"1B":   make([]byte, 1),
433		"64B":  make([]byte, 64),
434		"1KB":  make([]byte, 1024),
435		"64KB": make([]byte, 65536),
436		"1MB":  make([]byte, 1048576),
437		"64MB": make([]byte, 67108864),
438	}
439
440	symKey, _, _ = randomKeyGenerator{size: 32}.genKey()
441
442	encrypters = map[string]Encrypter{
443		"OAEPAndGCM":          mustEncrypter(RSA_OAEP, A128GCM, &rsaTestKey.PublicKey),
444		"PKCSAndGCM":          mustEncrypter(RSA1_5, A128GCM, &rsaTestKey.PublicKey),
445		"OAEPAndCBC":          mustEncrypter(RSA_OAEP, A128CBC_HS256, &rsaTestKey.PublicKey),
446		"PKCSAndCBC":          mustEncrypter(RSA1_5, A128CBC_HS256, &rsaTestKey.PublicKey),
447		"DirectGCM128":        mustEncrypter(DIRECT, A128GCM, symKey),
448		"DirectCBC128":        mustEncrypter(DIRECT, A128CBC_HS256, symKey),
449		"DirectGCM256":        mustEncrypter(DIRECT, A256GCM, symKey),
450		"DirectCBC256":        mustEncrypter(DIRECT, A256CBC_HS512, symKey),
451		"AESKWAndGCM128":      mustEncrypter(A128KW, A128GCM, symKey),
452		"AESKWAndCBC256":      mustEncrypter(A256KW, A256GCM, symKey),
453		"ECDHOnP256AndGCM128": mustEncrypter(ECDH_ES, A128GCM, &ecTestKey256.PublicKey),
454		"ECDHOnP384AndGCM128": mustEncrypter(ECDH_ES, A128GCM, &ecTestKey384.PublicKey),
455		"ECDHOnP521AndGCM128": mustEncrypter(ECDH_ES, A128GCM, &ecTestKey521.PublicKey),
456	}
457)
458
459func BenchmarkEncrypt1BWithOAEPAndGCM(b *testing.B)   { benchEncrypt("1B", "OAEPAndGCM", b) }
460func BenchmarkEncrypt64BWithOAEPAndGCM(b *testing.B)  { benchEncrypt("64B", "OAEPAndGCM", b) }
461func BenchmarkEncrypt1KBWithOAEPAndGCM(b *testing.B)  { benchEncrypt("1KB", "OAEPAndGCM", b) }
462func BenchmarkEncrypt64KBWithOAEPAndGCM(b *testing.B) { benchEncrypt("64KB", "OAEPAndGCM", b) }
463func BenchmarkEncrypt1MBWithOAEPAndGCM(b *testing.B)  { benchEncrypt("1MB", "OAEPAndGCM", b) }
464func BenchmarkEncrypt64MBWithOAEPAndGCM(b *testing.B) { benchEncrypt("64MB", "OAEPAndGCM", b) }
465
466func BenchmarkEncrypt1BWithPKCSAndGCM(b *testing.B)   { benchEncrypt("1B", "PKCSAndGCM", b) }
467func BenchmarkEncrypt64BWithPKCSAndGCM(b *testing.B)  { benchEncrypt("64B", "PKCSAndGCM", b) }
468func BenchmarkEncrypt1KBWithPKCSAndGCM(b *testing.B)  { benchEncrypt("1KB", "PKCSAndGCM", b) }
469func BenchmarkEncrypt64KBWithPKCSAndGCM(b *testing.B) { benchEncrypt("64KB", "PKCSAndGCM", b) }
470func BenchmarkEncrypt1MBWithPKCSAndGCM(b *testing.B)  { benchEncrypt("1MB", "PKCSAndGCM", b) }
471func BenchmarkEncrypt64MBWithPKCSAndGCM(b *testing.B) { benchEncrypt("64MB", "PKCSAndGCM", b) }
472
473func BenchmarkEncrypt1BWithOAEPAndCBC(b *testing.B)   { benchEncrypt("1B", "OAEPAndCBC", b) }
474func BenchmarkEncrypt64BWithOAEPAndCBC(b *testing.B)  { benchEncrypt("64B", "OAEPAndCBC", b) }
475func BenchmarkEncrypt1KBWithOAEPAndCBC(b *testing.B)  { benchEncrypt("1KB", "OAEPAndCBC", b) }
476func BenchmarkEncrypt64KBWithOAEPAndCBC(b *testing.B) { benchEncrypt("64KB", "OAEPAndCBC", b) }
477func BenchmarkEncrypt1MBWithOAEPAndCBC(b *testing.B)  { benchEncrypt("1MB", "OAEPAndCBC", b) }
478func BenchmarkEncrypt64MBWithOAEPAndCBC(b *testing.B) { benchEncrypt("64MB", "OAEPAndCBC", b) }
479
480func BenchmarkEncrypt1BWithPKCSAndCBC(b *testing.B)   { benchEncrypt("1B", "PKCSAndCBC", b) }
481func BenchmarkEncrypt64BWithPKCSAndCBC(b *testing.B)  { benchEncrypt("64B", "PKCSAndCBC", b) }
482func BenchmarkEncrypt1KBWithPKCSAndCBC(b *testing.B)  { benchEncrypt("1KB", "PKCSAndCBC", b) }
483func BenchmarkEncrypt64KBWithPKCSAndCBC(b *testing.B) { benchEncrypt("64KB", "PKCSAndCBC", b) }
484func BenchmarkEncrypt1MBWithPKCSAndCBC(b *testing.B)  { benchEncrypt("1MB", "PKCSAndCBC", b) }
485func BenchmarkEncrypt64MBWithPKCSAndCBC(b *testing.B) { benchEncrypt("64MB", "PKCSAndCBC", b) }
486
487func BenchmarkEncrypt1BWithDirectGCM128(b *testing.B)   { benchEncrypt("1B", "DirectGCM128", b) }
488func BenchmarkEncrypt64BWithDirectGCM128(b *testing.B)  { benchEncrypt("64B", "DirectGCM128", b) }
489func BenchmarkEncrypt1KBWithDirectGCM128(b *testing.B)  { benchEncrypt("1KB", "DirectGCM128", b) }
490func BenchmarkEncrypt64KBWithDirectGCM128(b *testing.B) { benchEncrypt("64KB", "DirectGCM128", b) }
491func BenchmarkEncrypt1MBWithDirectGCM128(b *testing.B)  { benchEncrypt("1MB", "DirectGCM128", b) }
492func BenchmarkEncrypt64MBWithDirectGCM128(b *testing.B) { benchEncrypt("64MB", "DirectGCM128", b) }
493
494func BenchmarkEncrypt1BWithDirectCBC128(b *testing.B)   { benchEncrypt("1B", "DirectCBC128", b) }
495func BenchmarkEncrypt64BWithDirectCBC128(b *testing.B)  { benchEncrypt("64B", "DirectCBC128", b) }
496func BenchmarkEncrypt1KBWithDirectCBC128(b *testing.B)  { benchEncrypt("1KB", "DirectCBC128", b) }
497func BenchmarkEncrypt64KBWithDirectCBC128(b *testing.B) { benchEncrypt("64KB", "DirectCBC128", b) }
498func BenchmarkEncrypt1MBWithDirectCBC128(b *testing.B)  { benchEncrypt("1MB", "DirectCBC128", b) }
499func BenchmarkEncrypt64MBWithDirectCBC128(b *testing.B) { benchEncrypt("64MB", "DirectCBC128", b) }
500
501func BenchmarkEncrypt1BWithDirectGCM256(b *testing.B)   { benchEncrypt("1B", "DirectGCM256", b) }
502func BenchmarkEncrypt64BWithDirectGCM256(b *testing.B)  { benchEncrypt("64B", "DirectGCM256", b) }
503func BenchmarkEncrypt1KBWithDirectGCM256(b *testing.B)  { benchEncrypt("1KB", "DirectGCM256", b) }
504func BenchmarkEncrypt64KBWithDirectGCM256(b *testing.B) { benchEncrypt("64KB", "DirectGCM256", b) }
505func BenchmarkEncrypt1MBWithDirectGCM256(b *testing.B)  { benchEncrypt("1MB", "DirectGCM256", b) }
506func BenchmarkEncrypt64MBWithDirectGCM256(b *testing.B) { benchEncrypt("64MB", "DirectGCM256", b) }
507
508func BenchmarkEncrypt1BWithDirectCBC256(b *testing.B)   { benchEncrypt("1B", "DirectCBC256", b) }
509func BenchmarkEncrypt64BWithDirectCBC256(b *testing.B)  { benchEncrypt("64B", "DirectCBC256", b) }
510func BenchmarkEncrypt1KBWithDirectCBC256(b *testing.B)  { benchEncrypt("1KB", "DirectCBC256", b) }
511func BenchmarkEncrypt64KBWithDirectCBC256(b *testing.B) { benchEncrypt("64KB", "DirectCBC256", b) }
512func BenchmarkEncrypt1MBWithDirectCBC256(b *testing.B)  { benchEncrypt("1MB", "DirectCBC256", b) }
513func BenchmarkEncrypt64MBWithDirectCBC256(b *testing.B) { benchEncrypt("64MB", "DirectCBC256", b) }
514
515func BenchmarkEncrypt1BWithAESKWAndGCM128(b *testing.B)   { benchEncrypt("1B", "AESKWAndGCM128", b) }
516func BenchmarkEncrypt64BWithAESKWAndGCM128(b *testing.B)  { benchEncrypt("64B", "AESKWAndGCM128", b) }
517func BenchmarkEncrypt1KBWithAESKWAndGCM128(b *testing.B)  { benchEncrypt("1KB", "AESKWAndGCM128", b) }
518func BenchmarkEncrypt64KBWithAESKWAndGCM128(b *testing.B) { benchEncrypt("64KB", "AESKWAndGCM128", b) }
519func BenchmarkEncrypt1MBWithAESKWAndGCM128(b *testing.B)  { benchEncrypt("1MB", "AESKWAndGCM128", b) }
520func BenchmarkEncrypt64MBWithAESKWAndGCM128(b *testing.B) { benchEncrypt("64MB", "AESKWAndGCM128", b) }
521
522func BenchmarkEncrypt1BWithAESKWAndCBC256(b *testing.B)   { benchEncrypt("1B", "AESKWAndCBC256", b) }
523func BenchmarkEncrypt64BWithAESKWAndCBC256(b *testing.B)  { benchEncrypt("64B", "AESKWAndCBC256", b) }
524func BenchmarkEncrypt1KBWithAESKWAndCBC256(b *testing.B)  { benchEncrypt("1KB", "AESKWAndCBC256", b) }
525func BenchmarkEncrypt64KBWithAESKWAndCBC256(b *testing.B) { benchEncrypt("64KB", "AESKWAndCBC256", b) }
526func BenchmarkEncrypt1MBWithAESKWAndCBC256(b *testing.B)  { benchEncrypt("1MB", "AESKWAndCBC256", b) }
527func BenchmarkEncrypt64MBWithAESKWAndCBC256(b *testing.B) { benchEncrypt("64MB", "AESKWAndCBC256", b) }
528
529func BenchmarkEncrypt1BWithECDHOnP256AndGCM128(b *testing.B) {
530	benchEncrypt("1B", "ECDHOnP256AndGCM128", b)
531}
532func BenchmarkEncrypt64BWithECDHOnP256AndGCM128(b *testing.B) {
533	benchEncrypt("64B", "ECDHOnP256AndGCM128", b)
534}
535func BenchmarkEncrypt1KBWithECDHOnP256AndGCM128(b *testing.B) {
536	benchEncrypt("1KB", "ECDHOnP256AndGCM128", b)
537}
538func BenchmarkEncrypt64KBWithECDHOnP256AndGCM128(b *testing.B) {
539	benchEncrypt("64KB", "ECDHOnP256AndGCM128", b)
540}
541func BenchmarkEncrypt1MBWithECDHOnP256AndGCM128(b *testing.B) {
542	benchEncrypt("1MB", "ECDHOnP256AndGCM128", b)
543}
544func BenchmarkEncrypt64MBWithECDHOnP256AndGCM128(b *testing.B) {
545	benchEncrypt("64MB", "ECDHOnP256AndGCM128", b)
546}
547
548func BenchmarkEncrypt1BWithECDHOnP384AndGCM128(b *testing.B) {
549	benchEncrypt("1B", "ECDHOnP384AndGCM128", b)
550}
551func BenchmarkEncrypt64BWithECDHOnP384AndGCM128(b *testing.B) {
552	benchEncrypt("64B", "ECDHOnP384AndGCM128", b)
553}
554func BenchmarkEncrypt1KBWithECDHOnP384AndGCM128(b *testing.B) {
555	benchEncrypt("1KB", "ECDHOnP384AndGCM128", b)
556}
557func BenchmarkEncrypt64KBWithECDHOnP384AndGCM128(b *testing.B) {
558	benchEncrypt("64KB", "ECDHOnP384AndGCM128", b)
559}
560func BenchmarkEncrypt1MBWithECDHOnP384AndGCM128(b *testing.B) {
561	benchEncrypt("1MB", "ECDHOnP384AndGCM128", b)
562}
563func BenchmarkEncrypt64MBWithECDHOnP384AndGCM128(b *testing.B) {
564	benchEncrypt("64MB", "ECDHOnP384AndGCM128", b)
565}
566
567func BenchmarkEncrypt1BWithECDHOnP521AndGCM128(b *testing.B) {
568	benchEncrypt("1B", "ECDHOnP521AndGCM128", b)
569}
570func BenchmarkEncrypt64BWithECDHOnP521AndGCM128(b *testing.B) {
571	benchEncrypt("64B", "ECDHOnP521AndGCM128", b)
572}
573func BenchmarkEncrypt1KBWithECDHOnP521AndGCM128(b *testing.B) {
574	benchEncrypt("1KB", "ECDHOnP521AndGCM128", b)
575}
576func BenchmarkEncrypt64KBWithECDHOnP521AndGCM128(b *testing.B) {
577	benchEncrypt("64KB", "ECDHOnP521AndGCM128", b)
578}
579func BenchmarkEncrypt1MBWithECDHOnP521AndGCM128(b *testing.B) {
580	benchEncrypt("1MB", "ECDHOnP521AndGCM128", b)
581}
582func BenchmarkEncrypt64MBWithECDHOnP521AndGCM128(b *testing.B) {
583	benchEncrypt("64MB", "ECDHOnP521AndGCM128", b)
584}
585
586func benchEncrypt(chunkKey, primKey string, b *testing.B) {
587	data, ok := chunks[chunkKey]
588	if !ok {
589		b.Fatalf("unknown chunk size %s", chunkKey)
590	}
591
592	enc, ok := encrypters[primKey]
593	if !ok {
594		b.Fatalf("unknown encrypter %s", primKey)
595	}
596
597	b.SetBytes(int64(len(data)))
598	for i := 0; i < b.N; i++ {
599		enc.Encrypt(data)
600	}
601}
602
603var (
604	decryptionKeys = map[string]interface{}{
605		"OAEPAndGCM": rsaTestKey,
606		"PKCSAndGCM": rsaTestKey,
607		"OAEPAndCBC": rsaTestKey,
608		"PKCSAndCBC": rsaTestKey,
609
610		"DirectGCM128": symKey,
611		"DirectCBC128": symKey,
612		"DirectGCM256": symKey,
613		"DirectCBC256": symKey,
614
615		"AESKWAndGCM128": symKey,
616		"AESKWAndCBC256": symKey,
617
618		"ECDHOnP256AndGCM128": ecTestKey256,
619		"ECDHOnP384AndGCM128": ecTestKey384,
620		"ECDHOnP521AndGCM128": ecTestKey521,
621	}
622)
623
624func BenchmarkDecrypt1BWithOAEPAndGCM(b *testing.B)   { benchDecrypt("1B", "OAEPAndGCM", b) }
625func BenchmarkDecrypt64BWithOAEPAndGCM(b *testing.B)  { benchDecrypt("64B", "OAEPAndGCM", b) }
626func BenchmarkDecrypt1KBWithOAEPAndGCM(b *testing.B)  { benchDecrypt("1KB", "OAEPAndGCM", b) }
627func BenchmarkDecrypt64KBWithOAEPAndGCM(b *testing.B) { benchDecrypt("64KB", "OAEPAndGCM", b) }
628func BenchmarkDecrypt1MBWithOAEPAndGCM(b *testing.B)  { benchDecrypt("1MB", "OAEPAndGCM", b) }
629func BenchmarkDecrypt64MBWithOAEPAndGCM(b *testing.B) { benchDecrypt("64MB", "OAEPAndGCM", b) }
630
631func BenchmarkDecrypt1BWithPKCSAndGCM(b *testing.B)   { benchDecrypt("1B", "PKCSAndGCM", b) }
632func BenchmarkDecrypt64BWithPKCSAndGCM(b *testing.B)  { benchDecrypt("64B", "PKCSAndGCM", b) }
633func BenchmarkDecrypt1KBWithPKCSAndGCM(b *testing.B)  { benchDecrypt("1KB", "PKCSAndGCM", b) }
634func BenchmarkDecrypt64KBWithPKCSAndGCM(b *testing.B) { benchDecrypt("64KB", "PKCSAndGCM", b) }
635func BenchmarkDecrypt1MBWithPKCSAndGCM(b *testing.B)  { benchDecrypt("1MB", "PKCSAndGCM", b) }
636func BenchmarkDecrypt64MBWithPKCSAndGCM(b *testing.B) { benchDecrypt("64MB", "PKCSAndGCM", b) }
637
638func BenchmarkDecrypt1BWithOAEPAndCBC(b *testing.B)   { benchDecrypt("1B", "OAEPAndCBC", b) }
639func BenchmarkDecrypt64BWithOAEPAndCBC(b *testing.B)  { benchDecrypt("64B", "OAEPAndCBC", b) }
640func BenchmarkDecrypt1KBWithOAEPAndCBC(b *testing.B)  { benchDecrypt("1KB", "OAEPAndCBC", b) }
641func BenchmarkDecrypt64KBWithOAEPAndCBC(b *testing.B) { benchDecrypt("64KB", "OAEPAndCBC", b) }
642func BenchmarkDecrypt1MBWithOAEPAndCBC(b *testing.B)  { benchDecrypt("1MB", "OAEPAndCBC", b) }
643func BenchmarkDecrypt64MBWithOAEPAndCBC(b *testing.B) { benchDecrypt("64MB", "OAEPAndCBC", b) }
644
645func BenchmarkDecrypt1BWithPKCSAndCBC(b *testing.B)   { benchDecrypt("1B", "PKCSAndCBC", b) }
646func BenchmarkDecrypt64BWithPKCSAndCBC(b *testing.B)  { benchDecrypt("64B", "PKCSAndCBC", b) }
647func BenchmarkDecrypt1KBWithPKCSAndCBC(b *testing.B)  { benchDecrypt("1KB", "PKCSAndCBC", b) }
648func BenchmarkDecrypt64KBWithPKCSAndCBC(b *testing.B) { benchDecrypt("64KB", "PKCSAndCBC", b) }
649func BenchmarkDecrypt1MBWithPKCSAndCBC(b *testing.B)  { benchDecrypt("1MB", "PKCSAndCBC", b) }
650func BenchmarkDecrypt64MBWithPKCSAndCBC(b *testing.B) { benchDecrypt("64MB", "PKCSAndCBC", b) }
651
652func BenchmarkDecrypt1BWithDirectGCM128(b *testing.B)   { benchDecrypt("1B", "DirectGCM128", b) }
653func BenchmarkDecrypt64BWithDirectGCM128(b *testing.B)  { benchDecrypt("64B", "DirectGCM128", b) }
654func BenchmarkDecrypt1KBWithDirectGCM128(b *testing.B)  { benchDecrypt("1KB", "DirectGCM128", b) }
655func BenchmarkDecrypt64KBWithDirectGCM128(b *testing.B) { benchDecrypt("64KB", "DirectGCM128", b) }
656func BenchmarkDecrypt1MBWithDirectGCM128(b *testing.B)  { benchDecrypt("1MB", "DirectGCM128", b) }
657func BenchmarkDecrypt64MBWithDirectGCM128(b *testing.B) { benchDecrypt("64MB", "DirectGCM128", b) }
658
659func BenchmarkDecrypt1BWithDirectCBC128(b *testing.B)   { benchDecrypt("1B", "DirectCBC128", b) }
660func BenchmarkDecrypt64BWithDirectCBC128(b *testing.B)  { benchDecrypt("64B", "DirectCBC128", b) }
661func BenchmarkDecrypt1KBWithDirectCBC128(b *testing.B)  { benchDecrypt("1KB", "DirectCBC128", b) }
662func BenchmarkDecrypt64KBWithDirectCBC128(b *testing.B) { benchDecrypt("64KB", "DirectCBC128", b) }
663func BenchmarkDecrypt1MBWithDirectCBC128(b *testing.B)  { benchDecrypt("1MB", "DirectCBC128", b) }
664func BenchmarkDecrypt64MBWithDirectCBC128(b *testing.B) { benchDecrypt("64MB", "DirectCBC128", b) }
665
666func BenchmarkDecrypt1BWithDirectGCM256(b *testing.B)   { benchDecrypt("1B", "DirectGCM256", b) }
667func BenchmarkDecrypt64BWithDirectGCM256(b *testing.B)  { benchDecrypt("64B", "DirectGCM256", b) }
668func BenchmarkDecrypt1KBWithDirectGCM256(b *testing.B)  { benchDecrypt("1KB", "DirectGCM256", b) }
669func BenchmarkDecrypt64KBWithDirectGCM256(b *testing.B) { benchDecrypt("64KB", "DirectGCM256", b) }
670func BenchmarkDecrypt1MBWithDirectGCM256(b *testing.B)  { benchDecrypt("1MB", "DirectGCM256", b) }
671func BenchmarkDecrypt64MBWithDirectGCM256(b *testing.B) { benchDecrypt("64MB", "DirectGCM256", b) }
672
673func BenchmarkDecrypt1BWithDirectCBC256(b *testing.B)   { benchDecrypt("1B", "DirectCBC256", b) }
674func BenchmarkDecrypt64BWithDirectCBC256(b *testing.B)  { benchDecrypt("64B", "DirectCBC256", b) }
675func BenchmarkDecrypt1KBWithDirectCBC256(b *testing.B)  { benchDecrypt("1KB", "DirectCBC256", b) }
676func BenchmarkDecrypt64KBWithDirectCBC256(b *testing.B) { benchDecrypt("64KB", "DirectCBC256", b) }
677func BenchmarkDecrypt1MBWithDirectCBC256(b *testing.B)  { benchDecrypt("1MB", "DirectCBC256", b) }
678func BenchmarkDecrypt64MBWithDirectCBC256(b *testing.B) { benchDecrypt("64MB", "DirectCBC256", b) }
679
680func BenchmarkDecrypt1BWithAESKWAndGCM128(b *testing.B)   { benchDecrypt("1B", "AESKWAndGCM128", b) }
681func BenchmarkDecrypt64BWithAESKWAndGCM128(b *testing.B)  { benchDecrypt("64B", "AESKWAndGCM128", b) }
682func BenchmarkDecrypt1KBWithAESKWAndGCM128(b *testing.B)  { benchDecrypt("1KB", "AESKWAndGCM128", b) }
683func BenchmarkDecrypt64KBWithAESKWAndGCM128(b *testing.B) { benchDecrypt("64KB", "AESKWAndGCM128", b) }
684func BenchmarkDecrypt1MBWithAESKWAndGCM128(b *testing.B)  { benchDecrypt("1MB", "AESKWAndGCM128", b) }
685func BenchmarkDecrypt64MBWithAESKWAndGCM128(b *testing.B) { benchDecrypt("64MB", "AESKWAndGCM128", b) }
686
687func BenchmarkDecrypt1BWithAESKWAndCBC256(b *testing.B)   { benchDecrypt("1B", "AESKWAndCBC256", b) }
688func BenchmarkDecrypt64BWithAESKWAndCBC256(b *testing.B)  { benchDecrypt("64B", "AESKWAndCBC256", b) }
689func BenchmarkDecrypt1KBWithAESKWAndCBC256(b *testing.B)  { benchDecrypt("1KB", "AESKWAndCBC256", b) }
690func BenchmarkDecrypt64KBWithAESKWAndCBC256(b *testing.B) { benchDecrypt("64KB", "AESKWAndCBC256", b) }
691func BenchmarkDecrypt1MBWithAESKWAndCBC256(b *testing.B)  { benchDecrypt("1MB", "AESKWAndCBC256", b) }
692func BenchmarkDecrypt64MBWithAESKWAndCBC256(b *testing.B) { benchDecrypt("64MB", "AESKWAndCBC256", b) }
693
694func BenchmarkDecrypt1BWithECDHOnP256AndGCM128(b *testing.B) {
695	benchDecrypt("1B", "ECDHOnP256AndGCM128", b)
696}
697func BenchmarkDecrypt64BWithECDHOnP256AndGCM128(b *testing.B) {
698	benchDecrypt("64B", "ECDHOnP256AndGCM128", b)
699}
700func BenchmarkDecrypt1KBWithECDHOnP256AndGCM128(b *testing.B) {
701	benchDecrypt("1KB", "ECDHOnP256AndGCM128", b)
702}
703func BenchmarkDecrypt64KBWithECDHOnP256AndGCM128(b *testing.B) {
704	benchDecrypt("64KB", "ECDHOnP256AndGCM128", b)
705}
706func BenchmarkDecrypt1MBWithECDHOnP256AndGCM128(b *testing.B) {
707	benchDecrypt("1MB", "ECDHOnP256AndGCM128", b)
708}
709func BenchmarkDecrypt64MBWithECDHOnP256AndGCM128(b *testing.B) {
710	benchDecrypt("64MB", "ECDHOnP256AndGCM128", b)
711}
712
713func BenchmarkDecrypt1BWithECDHOnP384AndGCM128(b *testing.B) {
714	benchDecrypt("1B", "ECDHOnP384AndGCM128", b)
715}
716func BenchmarkDecrypt64BWithECDHOnP384AndGCM128(b *testing.B) {
717	benchDecrypt("64B", "ECDHOnP384AndGCM128", b)
718}
719func BenchmarkDecrypt1KBWithECDHOnP384AndGCM128(b *testing.B) {
720	benchDecrypt("1KB", "ECDHOnP384AndGCM128", b)
721}
722func BenchmarkDecrypt64KBWithECDHOnP384AndGCM128(b *testing.B) {
723	benchDecrypt("64KB", "ECDHOnP384AndGCM128", b)
724}
725func BenchmarkDecrypt1MBWithECDHOnP384AndGCM128(b *testing.B) {
726	benchDecrypt("1MB", "ECDHOnP384AndGCM128", b)
727}
728func BenchmarkDecrypt64MBWithECDHOnP384AndGCM128(b *testing.B) {
729	benchDecrypt("64MB", "ECDHOnP384AndGCM128", b)
730}
731
732func BenchmarkDecrypt1BWithECDHOnP521AndGCM128(b *testing.B) {
733	benchDecrypt("1B", "ECDHOnP521AndGCM128", b)
734}
735func BenchmarkDecrypt64BWithECDHOnP521AndGCM128(b *testing.B) {
736	benchDecrypt("64B", "ECDHOnP521AndGCM128", b)
737}
738func BenchmarkDecrypt1KBWithECDHOnP521AndGCM128(b *testing.B) {
739	benchDecrypt("1KB", "ECDHOnP521AndGCM128", b)
740}
741func BenchmarkDecrypt64KBWithECDHOnP521AndGCM128(b *testing.B) {
742	benchDecrypt("64KB", "ECDHOnP521AndGCM128", b)
743}
744func BenchmarkDecrypt1MBWithECDHOnP521AndGCM128(b *testing.B) {
745	benchDecrypt("1MB", "ECDHOnP521AndGCM128", b)
746}
747func BenchmarkDecrypt64MBWithECDHOnP521AndGCM128(b *testing.B) {
748	benchDecrypt("64MB", "ECDHOnP521AndGCM128", b)
749}
750
751func benchDecrypt(chunkKey, primKey string, b *testing.B) {
752	chunk, ok := chunks[chunkKey]
753	if !ok {
754		b.Fatalf("unknown chunk size %s", chunkKey)
755	}
756
757	enc, ok := encrypters[primKey]
758	if !ok {
759		b.Fatalf("unknown encrypter %s", primKey)
760	}
761
762	dec, ok := decryptionKeys[primKey]
763	if !ok {
764		b.Fatalf("unknown decryption key %s", primKey)
765	}
766
767	data, err := enc.Encrypt(chunk)
768	if err != nil {
769		b.Fatal(err)
770	}
771
772	b.SetBytes(int64(len(chunk)))
773	b.ResetTimer()
774	for i := 0; i < b.N; i++ {
775		data.Decrypt(dec)
776	}
777}
778
779func mustEncrypter(keyAlg KeyAlgorithm, encAlg ContentEncryption, encryptionKey interface{}) Encrypter {
780	enc, err := NewEncrypter(keyAlg, encAlg, encryptionKey)
781	if err != nil {
782		panic(err)
783	}
784	return enc
785}
786