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