github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/bccsp/sw/aes_test.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 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 package sw 17 18 import ( 19 "bytes" 20 "crypto/aes" 21 "crypto/rand" 22 "math/big" 23 "testing" 24 25 "github.com/hyperledger/fabric/bccsp" 26 "github.com/hyperledger/fabric/bccsp/mocks" 27 "github.com/hyperledger/fabric/bccsp/utils" 28 "github.com/stretchr/testify/assert" 29 ) 30 31 // TestCBCPKCS7EncryptCBCPKCS7Decrypt encrypts using CBCPKCS7Encrypt and decrypts using CBCPKCS7Decrypt. 32 func TestCBCPKCS7EncryptCBCPKCS7Decrypt(t *testing.T) { 33 34 // Note: The purpose of this test is not to test AES-256 in CBC mode's strength 35 // ... but rather to verify the code wrapping/unwrapping the cipher. 36 key := make([]byte, 32) 37 rand.Reader.Read(key) 38 39 // 123456789012345678901234567890123456789012 40 var ptext = []byte("a message with arbitrary length (42 bytes)") 41 42 encrypted, encErr := AESCBCPKCS7Encrypt(key, ptext) 43 if encErr != nil { 44 t.Fatalf("Error encrypting '%s': %s", ptext, encErr) 45 } 46 47 decrypted, dErr := AESCBCPKCS7Decrypt(key, encrypted) 48 if dErr != nil { 49 t.Fatalf("Error decrypting the encrypted '%s': %v", ptext, dErr) 50 } 51 52 if string(ptext[:]) != string(decrypted[:]) { 53 t.Fatal("Decrypt( Encrypt( ptext ) ) != ptext: Ciphertext decryption with the same key must result in the original plaintext!") 54 } 55 56 } 57 58 // TestPKCS7Padding verifies the PKCS#7 padding, using a human readable plaintext. 59 func TestPKCS7Padding(t *testing.T) { 60 61 // 0 byte/length ptext 62 ptext := []byte("") 63 expected := []byte{16, 16, 16, 16, 64 16, 16, 16, 16, 65 16, 16, 16, 16, 66 16, 16, 16, 16} 67 result := pkcs7Padding(ptext) 68 69 if !bytes.Equal(expected, result) { 70 t.Fatal("Padding error! Expected: ", expected, "', received: '", result, "'") 71 } 72 73 // 1 byte/length ptext 74 ptext = []byte("1") 75 expected = []byte{'1', 15, 15, 15, 76 15, 15, 15, 15, 77 15, 15, 15, 15, 78 15, 15, 15, 15} 79 result = pkcs7Padding(ptext) 80 81 if !bytes.Equal(expected, result) { 82 t.Fatal("Padding error! Expected: '", expected, "', received: '", result, "'") 83 } 84 85 // 2 byte/length ptext 86 ptext = []byte("12") 87 expected = []byte{'1', '2', 14, 14, 88 14, 14, 14, 14, 89 14, 14, 14, 14, 90 14, 14, 14, 14} 91 result = pkcs7Padding(ptext) 92 93 if !bytes.Equal(expected, result) { 94 t.Fatal("Padding error! Expected: '", expected, "', received: '", result, "'") 95 } 96 97 // 3 to aes.BlockSize-1 byte plaintext 98 ptext = []byte("1234567890ABCDEF") 99 for i := 3; i < aes.BlockSize; i++ { 100 result := pkcs7Padding(ptext[:i]) 101 102 padding := aes.BlockSize - i 103 expectedPadding := bytes.Repeat([]byte{byte(padding)}, padding) 104 expected = append(ptext[:i], expectedPadding...) 105 106 if !bytes.Equal(result, expected) { 107 t.Fatal("Padding error! Expected: '", expected, "', received: '", result, "'") 108 } 109 110 } 111 112 // aes.BlockSize length ptext 113 ptext = bytes.Repeat([]byte{byte('x')}, aes.BlockSize) 114 result = pkcs7Padding(ptext) 115 116 expectedPadding := bytes.Repeat([]byte{byte(aes.BlockSize)}, aes.BlockSize) 117 expected = append(ptext, expectedPadding...) 118 119 if len(result) != 2*aes.BlockSize { 120 t.Fatal("Padding error: expected the length of the returned slice to be 2 times aes.BlockSize") 121 } 122 123 if !bytes.Equal(expected, result) { 124 t.Fatal("Padding error! Expected: '", expected, "', received: '", result, "'") 125 } 126 127 } 128 129 // TestPKCS7UnPadding verifies the PKCS#7 unpadding, using a human readable plaintext. 130 func TestPKCS7UnPadding(t *testing.T) { 131 132 // 0 byte/length ptext 133 expected := []byte("") 134 ptext := []byte{16, 16, 16, 16, 135 16, 16, 16, 16, 136 16, 16, 16, 16, 137 16, 16, 16, 16} 138 139 result, _ := pkcs7UnPadding(ptext) 140 141 if !bytes.Equal(expected, result) { 142 t.Fatal("UnPadding error! Expected: '", expected, "', received: '", result, "'") 143 } 144 145 // 1 byte/length ptext 146 expected = []byte("1") 147 ptext = []byte{'1', 15, 15, 15, 148 15, 15, 15, 15, 149 15, 15, 15, 15, 150 15, 15, 15, 15} 151 152 result, _ = pkcs7UnPadding(ptext) 153 154 if !bytes.Equal(expected, result) { 155 t.Fatal("UnPadding error! Expected: '", expected, "', received: '", result, "'") 156 } 157 158 // 2 byte/length ptext 159 expected = []byte("12") 160 ptext = []byte{'1', '2', 14, 14, 161 14, 14, 14, 14, 162 14, 14, 14, 14, 163 14, 14, 14, 14} 164 165 result, _ = pkcs7UnPadding(ptext) 166 167 if !bytes.Equal(expected, result) { 168 t.Fatal("UnPadding error! Expected: '", expected, "', received: '", result, "'") 169 } 170 171 // 3 to aes.BlockSize-1 byte plaintext 172 base := []byte("1234567890ABCDEF") 173 for i := 3; i < aes.BlockSize; i++ { 174 iPad := aes.BlockSize - i 175 padding := bytes.Repeat([]byte{byte(iPad)}, iPad) 176 ptext = append(base[:i], padding...) 177 178 expected := base[:i] 179 result, _ := pkcs7UnPadding(ptext) 180 181 if !bytes.Equal(result, expected) { 182 t.Fatal("UnPadding error! Expected: '", expected, "', received: '", result, "'") 183 } 184 185 } 186 187 // aes.BlockSize length ptext 188 expected = bytes.Repeat([]byte{byte('x')}, aes.BlockSize) 189 padding := bytes.Repeat([]byte{byte(aes.BlockSize)}, aes.BlockSize) 190 ptext = append(expected, padding...) 191 192 result, _ = pkcs7UnPadding(ptext) 193 194 if !bytes.Equal(expected, result) { 195 t.Fatal("UnPadding error! Expected: '", expected, "', received: '", result, "'") 196 } 197 } 198 199 // TestCBCEncryptCBCPKCS7Decrypt_BlockSizeLengthPlaintext verifies that CBCPKCS7Decrypt returns an error 200 // when attempting to decrypt ciphertext of an irreproducible length. 201 func TestCBCEncryptCBCPKCS7Decrypt_BlockSizeLengthPlaintext(t *testing.T) { 202 203 // One of the purposes of this test is to also document and clarify the expected behavior, i.e., that an extra 204 // block is appended to the message at the padding stage, as per the spec of PKCS#7 v1.5 [see RFC-2315 p.21] 205 key := make([]byte, 32) 206 rand.Reader.Read(key) 207 208 // 1234567890123456 209 var ptext = []byte("a 16 byte messag") 210 211 encrypted, encErr := aesCBCEncrypt(key, ptext) 212 if encErr != nil { 213 t.Fatalf("Error encrypting '%s': %v", ptext, encErr) 214 } 215 216 decrypted, dErr := AESCBCPKCS7Decrypt(key, encrypted) 217 if dErr == nil { 218 t.Fatalf("Expected an error decrypting ptext '%s'. Decrypted to '%v'", dErr, decrypted) 219 } 220 } 221 222 // TestCBCPKCS7EncryptCBCDecrypt_ExpectingCorruptMessage verifies that CBCDecrypt can decrypt the unpadded 223 // version of the ciphertext, of a message of BlockSize length. 224 func TestCBCPKCS7EncryptCBCDecrypt_ExpectingCorruptMessage(t *testing.T) { 225 226 // One of the purposes of this test is to also document and clarify the expected behavior, i.e., that an extra 227 // block is appended to the message at the padding stage, as per the spec of PKCS#7 v1.5 [see RFC-2315 p.21] 228 key := make([]byte, 32) 229 rand.Reader.Read(key) 230 231 // 0123456789ABCDEF 232 var ptext = []byte("a 16 byte messag") 233 234 encrypted, encErr := AESCBCPKCS7Encrypt(key, ptext) 235 if encErr != nil { 236 t.Fatalf("Error encrypting ptext %v", encErr) 237 } 238 239 decrypted, dErr := aesCBCDecrypt(key, encrypted) 240 if dErr != nil { 241 t.Fatalf("Error encrypting ptext %v, %v", dErr, decrypted) 242 } 243 244 if string(ptext[:]) != string(decrypted[:aes.BlockSize]) { 245 t.Log("ptext: ", ptext) 246 t.Log("decrypted: ", decrypted[:aes.BlockSize]) 247 t.Fatal("Encryption->Decryption with same key should result in original ptext") 248 } 249 250 if !bytes.Equal(decrypted[aes.BlockSize:], bytes.Repeat([]byte{byte(aes.BlockSize)}, aes.BlockSize)) { 251 t.Fatal("Expected extra block with padding in encrypted ptext", decrypted) 252 } 253 254 } 255 256 // TestCBCPKCS7Encrypt_EmptyPlaintext encrypts and pad an empty ptext. Verifying as well that the ciphertext length is as expected. 257 func TestCBCPKCS7Encrypt_EmptyPlaintext(t *testing.T) { 258 259 key := make([]byte, 32) 260 rand.Reader.Read(key) 261 262 t.Log("Generated key: ", key) 263 264 var emptyPlaintext = []byte("") 265 t.Log("Plaintext length: ", len(emptyPlaintext)) 266 267 ciphertext, encErr := AESCBCPKCS7Encrypt(key, emptyPlaintext) 268 if encErr != nil { 269 t.Fatalf("Error encrypting '%v'", encErr) 270 } 271 272 // Expected ciphertext length: 32 (=32) 273 // As part of the padding, at least one block gets encrypted (while the first block is the IV) 274 const expectedLength = aes.BlockSize + aes.BlockSize 275 if len(ciphertext) != expectedLength { 276 t.Fatalf("Wrong ciphertext length. Expected %d, received %d", expectedLength, len(ciphertext)) 277 } 278 279 t.Log("Ciphertext length: ", len(ciphertext)) 280 t.Log("Cipher: ", ciphertext) 281 } 282 283 // TestCBCEncrypt_EmptyPlaintext encrypts an empty message. Verifying as well that the ciphertext length is as expected. 284 func TestCBCEncrypt_EmptyPlaintext(t *testing.T) { 285 286 key := make([]byte, 32) 287 rand.Reader.Read(key) 288 t.Log("Generated key: ", key) 289 290 var emptyPlaintext = []byte("") 291 t.Log("Message length: ", len(emptyPlaintext)) 292 293 ciphertext, encErr := aesCBCEncrypt(key, emptyPlaintext) 294 assert.NoError(t, encErr) 295 296 t.Log("Ciphertext length: ", len(ciphertext)) 297 298 // Expected cipher length: aes.BlockSize, the first and only block is the IV 299 var expectedLength = aes.BlockSize 300 301 if len(ciphertext) != expectedLength { 302 t.Fatalf("Wrong ciphertext length. Expected: '%d', received: '%d'", expectedLength, len(ciphertext)) 303 } 304 t.Log("Ciphertext: ", ciphertext) 305 } 306 307 // TestCBCPKCS7Encrypt_VerifyRandomIVs encrypts twice with same key. The first 16 bytes should be different if IV is generated randomly. 308 func TestCBCPKCS7Encrypt_VerifyRandomIVs(t *testing.T) { 309 310 key := make([]byte, aes.BlockSize) 311 rand.Reader.Read(key) 312 t.Log("Key 1", key) 313 314 var ptext = []byte("a message to encrypt") 315 316 ciphertext1, err := AESCBCPKCS7Encrypt(key, ptext) 317 if err != nil { 318 t.Fatalf("Error encrypting '%s': %s", ptext, err) 319 } 320 321 // Expecting a different IV if same message is encrypted with same key 322 ciphertext2, err := AESCBCPKCS7Encrypt(key, ptext) 323 if err != nil { 324 t.Fatalf("Error encrypting '%s': %s", ptext, err) 325 } 326 327 iv1 := ciphertext1[:aes.BlockSize] 328 iv2 := ciphertext2[:aes.BlockSize] 329 330 t.Log("Ciphertext1: ", iv1) 331 t.Log("Ciphertext2: ", iv2) 332 t.Log("bytes.Equal: ", bytes.Equal(iv1, iv2)) 333 334 if bytes.Equal(iv1, iv2) { 335 t.Fatal("Error: ciphertexts contain identical initialization vectors (IVs)") 336 } 337 } 338 339 // TestCBCPKCS7Encrypt_CorrectCiphertextLengthCheck verifies that the returned ciphertext lengths are as expected. 340 func TestCBCPKCS7Encrypt_CorrectCiphertextLengthCheck(t *testing.T) { 341 342 key := make([]byte, aes.BlockSize) 343 rand.Reader.Read(key) 344 345 // length of message (in bytes) == aes.BlockSize (16 bytes) 346 // The expected cipher length = IV length (1 block) + 1 block message 347 348 var ptext = []byte("0123456789ABCDEF") 349 350 for i := 1; i < aes.BlockSize; i++ { 351 ciphertext, err := AESCBCPKCS7Encrypt(key, ptext[:i]) 352 if err != nil { 353 t.Fatal("Error encrypting '", ptext, "'") 354 } 355 356 expectedLength := aes.BlockSize + aes.BlockSize 357 if len(ciphertext) != expectedLength { 358 t.Fatalf("Incorrect ciphertext incorrect: expected '%d', received '%d'", expectedLength, len(ciphertext)) 359 } 360 } 361 } 362 363 // TestCBCEncryptCBCDecrypt_KeyMismatch attempts to decrypt with a different key than the one used for encryption. 364 func TestCBCEncryptCBCDecrypt_KeyMismatch(t *testing.T) { 365 366 // Generate a random key 367 key := make([]byte, aes.BlockSize) 368 rand.Reader.Read(key) 369 370 // Clone & tamper with the key 371 wrongKey := make([]byte, aes.BlockSize) 372 copy(wrongKey, key[:]) 373 wrongKey[0] = key[0] + 1 374 375 var ptext = []byte("1234567890ABCDEF") 376 encrypted, encErr := aesCBCEncrypt(key, ptext) 377 if encErr != nil { 378 t.Fatalf("Error encrypting '%s': %v", ptext, encErr) 379 } 380 381 decrypted, decErr := aesCBCDecrypt(wrongKey, encrypted) 382 if decErr != nil { 383 t.Fatalf("Error decrypting '%s': %v", ptext, decErr) 384 } 385 386 if string(ptext[:]) == string(decrypted[:]) { 387 t.Fatal("Decrypting a ciphertext with a different key than the one used for encrypting it - should not result in the original plaintext.") 388 } 389 } 390 391 // TestCBCEncryptCBCDecrypt encrypts with CBCEncrypt and decrypt with CBCDecrypt. 392 func TestCBCEncryptCBCDecrypt(t *testing.T) { 393 394 key := make([]byte, 32) 395 rand.Reader.Read(key) 396 397 // 1234567890123456 398 var ptext = []byte("a 16 byte messag") 399 400 encrypted, encErr := aesCBCEncrypt(key, ptext) 401 if encErr != nil { 402 t.Fatalf("Error encrypting '%s': %v", ptext, encErr) 403 } 404 405 decrypted, decErr := aesCBCDecrypt(key, encrypted) 406 if decErr != nil { 407 t.Fatalf("Error decrypting '%s': %v", ptext, decErr) 408 } 409 410 if string(ptext[:]) != string(decrypted[:]) { 411 t.Fatal("Encryption->Decryption with same key should result in the original plaintext.") 412 } 413 } 414 415 // TestAESRelatedUtilFunctions tests various functions commonly used in fabric wrt AES 416 func TestAESRelatedUtilFunctions(t *testing.T) { 417 418 key, err := GetRandomBytes(32) 419 if err != nil { 420 t.Fatalf("Failed generating AES key [%s]", err) 421 } 422 423 for i := 1; i < 100; i++ { 424 l, err := rand.Int(rand.Reader, big.NewInt(1024)) 425 if err != nil { 426 t.Fatalf("Failed generating AES key [%s]", err) 427 } 428 msg, err := GetRandomBytes(int(l.Int64()) + 1) 429 if err != nil { 430 t.Fatalf("Failed generating AES key [%s]", err) 431 } 432 433 ct, err := AESCBCPKCS7Encrypt(key, msg) 434 if err != nil { 435 t.Fatalf("Failed encrypting [%s]", err) 436 } 437 438 msg2, err := AESCBCPKCS7Decrypt(key, ct) 439 if err != nil { 440 t.Fatalf("Failed decrypting [%s]", err) 441 } 442 443 if 0 != bytes.Compare(msg, msg2) { 444 t.Fatalf("Wrong decryption output [%x][%x]", msg, msg2) 445 } 446 447 } 448 449 } 450 451 // TestVariousAESKeyEncoding tests some AES <-> PEM conversions 452 func TestVariousAESKeyEncoding(t *testing.T) { 453 key, err := GetRandomBytes(32) 454 if err != nil { 455 t.Fatalf("Failed generating AES key [%s]", err) 456 } 457 458 // PEM format 459 pem := utils.AEStoPEM(key) 460 keyFromPEM, err := utils.PEMtoAES(pem, nil) 461 if err != nil { 462 t.Fatalf("Failed converting PEM to AES key [%s]", err) 463 } 464 if 0 != bytes.Compare(key, keyFromPEM) { 465 t.Fatalf("Failed converting PEM to AES key. Keys are different [%x][%x]", key, keyFromPEM) 466 } 467 468 // Encrypted PEM format 469 pem, err = utils.AEStoEncryptedPEM(key, []byte("passwd")) 470 if err != nil { 471 t.Fatalf("Failed converting AES key to Encrypted PEM [%s]", err) 472 } 473 keyFromPEM, err = utils.PEMtoAES(pem, []byte("passwd")) 474 if err != nil { 475 t.Fatalf("Failed converting encrypted PEM to AES key [%s]", err) 476 } 477 if 0 != bytes.Compare(key, keyFromPEM) { 478 t.Fatalf("Failed converting encrypted PEM to AES key. Keys are different [%x][%x]", key, keyFromPEM) 479 } 480 } 481 482 func TestPkcs7UnPaddingInvalidInputs(t *testing.T) { 483 _, err := pkcs7UnPadding([]byte{1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}) 484 assert.Error(t, err) 485 assert.Equal(t, "Invalid pkcs7 padding (pad[i] != unpadding)", err.Error()) 486 } 487 488 func TestAESCBCEncryptInvalidInputs(t *testing.T) { 489 _, err := aesCBCEncrypt(nil, []byte{0, 1, 2, 3}) 490 assert.Error(t, err) 491 assert.Equal(t, "Invalid plaintext. It must be a multiple of the block size", err.Error()) 492 493 _, err = aesCBCEncrypt([]byte{0}, []byte{1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}) 494 assert.Error(t, err) 495 } 496 497 func TestAESCBCDecryptInvalidInputs(t *testing.T) { 498 _, err := aesCBCDecrypt([]byte{0}, []byte{1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}) 499 assert.Error(t, err) 500 501 _, err = aesCBCDecrypt([]byte{1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, []byte{0}) 502 assert.Error(t, err) 503 504 _, err = aesCBCDecrypt([]byte{1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 505 []byte{1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}) 506 assert.Error(t, err) 507 } 508 509 // TestAESCBCPKCS7EncryptorDecrypt tests the integration of 510 // aescbcpkcs7Encryptor and aescbcpkcs7Decryptor 511 func TestAESCBCPKCS7EncryptorDecrypt(t *testing.T) { 512 raw, err := GetRandomBytes(32) 513 assert.NoError(t, err) 514 515 k := &aesPrivateKey{privKey: raw, exportable: false} 516 517 msg := []byte("Hello World") 518 encryptor := &aescbcpkcs7Encryptor{} 519 520 _, err = encryptor.Encrypt(k, msg, nil) 521 assert.Error(t, err) 522 523 _, err = encryptor.Encrypt(k, msg, &mocks.EncrypterOpts{}) 524 assert.Error(t, err) 525 526 ct, err := encryptor.Encrypt(k, msg, &bccsp.AESCBCPKCS7ModeOpts{}) 527 assert.NoError(t, err) 528 529 decryptor := &aescbcpkcs7Decryptor{} 530 531 _, err = decryptor.Decrypt(k, ct, nil) 532 assert.Error(t, err) 533 534 _, err = decryptor.Decrypt(k, ct, &mocks.EncrypterOpts{}) 535 assert.Error(t, err) 536 537 msg2, err := decryptor.Decrypt(k, ct, &bccsp.AESCBCPKCS7ModeOpts{}) 538 assert.NoError(t, err) 539 assert.Equal(t, msg, msg2) 540 }