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