github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/accesscontrol/crypto/utils/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 17 // This package contains unit-tests for the 18 // github.com/hyperledger/fabric/core/crypto/primitives package 19 package utils 20 21 import ( 22 "bytes" 23 "crypto/aes" 24 "crypto/rand" 25 "math/big" 26 "testing" 27 28 "github.com/hyperledger/fabric/core/crypto/primitives" 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, AESKeyLength) 37 rand.Reader.Read(key) 38 39 // 123456789012345678901234567890123456789012 40 var ptext = []byte("a message with arbitrary length (42 bytes)") 41 42 encrypted, encErr := CBCPKCS7Encrypt(key, ptext) 43 if encErr != nil { 44 t.Fatalf("Error encrypting '%s': %s", ptext, encErr) 45 } 46 47 decrypted, dErr := CBCPKCS7Decrypt(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, AESKeyLength) 206 rand.Reader.Read(key) 207 208 // 1234567890123456 209 var ptext = []byte("a 16 byte messag") 210 211 encrypted, encErr := CBCEncrypt(key, ptext) 212 if encErr != nil { 213 t.Fatalf("Error encrypting '%s': %v", ptext, encErr) 214 } 215 216 decrypted, dErr := CBCPKCS7Decrypt(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, AESKeyLength) 229 rand.Reader.Read(key) 230 231 // 0123456789ABCDEF 232 var ptext = []byte("a 16 byte messag") 233 234 encrypted, encErr := CBCPKCS7Encrypt(key, ptext) 235 if encErr != nil { 236 t.Fatalf("Error encrypting ptext %v", encErr) 237 } 238 239 decrypted, dErr := CBCDecrypt(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, AESKeyLength) 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 := CBCPKCS7Encrypt(key, emptyPlaintext) 268 if encErr != nil { 269 t.Fatalf("Error encrypting '%v'", encErr) 270 } 271 272 // Expected ciphertext length: AESKeyLength (=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, recieved %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, AESKeyLength) 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 := CBCEncrypt(key, emptyPlaintext) 294 if encErr != nil { 295 } 296 297 t.Log("Ciphertext length: ", len(ciphertext)) 298 299 // Expected cipher length: aes.BlockSize, the first and only block is the IV 300 var expectedLength = aes.BlockSize 301 302 if len(ciphertext) != expectedLength { 303 t.Fatalf("Wrong ciphertext length. Expected: '%d', received: '%d'", expectedLength, len(ciphertext)) 304 } 305 t.Log("Ciphertext: ", ciphertext) 306 } 307 308 // TestCBCPKCS7Encrypt_VerifyRandomIVs encrypts twice with same key. The first 16 bytes should be different if IV is generated randomly. 309 func TestCBCPKCS7Encrypt_VerifyRandomIVs(t *testing.T) { 310 311 key := make([]byte, aes.BlockSize) 312 rand.Reader.Read(key) 313 t.Log("Key 1", key) 314 315 var ptext = []byte("a message to encrypt") 316 317 ciphertext1, err := CBCPKCS7Encrypt(key, ptext) 318 if err != nil { 319 t.Fatalf("Error encrypting '%s': %s", ptext, err) 320 } 321 322 // Expecting a different IV if same message is encrypted with same key 323 ciphertext2, err := CBCPKCS7Encrypt(key, ptext) 324 if err != nil { 325 t.Fatalf("Error encrypting '%s': %s", ptext, err) 326 } 327 328 iv1 := ciphertext1[:aes.BlockSize] 329 iv2 := ciphertext2[:aes.BlockSize] 330 331 t.Log("Ciphertext1: ", iv1) 332 t.Log("Ciphertext2: ", iv2) 333 t.Log("bytes.Equal: ", bytes.Equal(iv1, iv2)) 334 335 if bytes.Equal(iv1, iv2) { 336 t.Fatal("Error: ciphertexts contain identical initialization vectors (IVs)") 337 } 338 } 339 340 // TestCBCPKCS7Encrypt_CorrectCiphertextLengthCheck verifies that the returned ciphertext lengths are as expected. 341 func TestCBCPKCS7Encrypt_CorrectCiphertextLengthCheck(t *testing.T) { 342 343 key := make([]byte, aes.BlockSize) 344 rand.Reader.Read(key) 345 346 // length of message (in bytes) == aes.BlockSize (16 bytes) 347 // The expected cipher length = IV length (1 block) + 1 block message 348 349 var ptext = []byte("0123456789ABCDEF") 350 351 for i := 1; i < aes.BlockSize; i++ { 352 ciphertext, err := CBCPKCS7Encrypt(key, ptext[:i]) 353 if err != nil { 354 t.Fatal("Error encrypting '", ptext, "'") 355 } 356 357 expectedLength := aes.BlockSize + aes.BlockSize 358 if len(ciphertext) != expectedLength { 359 t.Fatalf("Incorrect ciphertext incorrect: expected '%d', received '%d'", expectedLength, len(ciphertext)) 360 } 361 } 362 } 363 364 // TestCBCEncryptCBCDecrypt_KeyMismatch attempts to decrypt with a different key than the one used for encryption. 365 func TestCBCEncryptCBCDecrypt_KeyMismatch(t *testing.T) { 366 367 // Generate a random key 368 key := make([]byte, aes.BlockSize) 369 rand.Reader.Read(key) 370 371 // Clone & tamper with the key 372 wrongKey := make([]byte, aes.BlockSize) 373 copy(wrongKey, key[:]) 374 wrongKey[0] = key[0] + 1 375 376 var ptext = []byte("1234567890ABCDEF") 377 encrypted, encErr := CBCEncrypt(key, ptext) 378 if encErr != nil { 379 t.Fatalf("Error encrypting '%s': %v", ptext, encErr) 380 } 381 382 decrypted, decErr := CBCDecrypt(wrongKey, encrypted) 383 if decErr != nil { 384 t.Fatalf("Error decrypting '%s': %v", ptext, decErr) 385 } 386 387 if string(ptext[:]) == string(decrypted[:]) { 388 t.Fatal("Decrypting a ciphertext with a different key than the one used for encrypting it - should not result in the original plaintext.") 389 } 390 } 391 392 // TestCBCEncryptCBCDecrypt encrypts with CBCEncrypt and decrypt with CBCDecrypt. 393 func TestCBCEncryptCBCDecrypt(t *testing.T) { 394 395 key := make([]byte, AESKeyLength) 396 rand.Reader.Read(key) 397 398 // 1234567890123456 399 var ptext = []byte("a 16 byte messag") 400 401 encrypted, encErr := CBCEncrypt(key, ptext) 402 if encErr != nil { 403 t.Fatalf("Error encrypting '%s': %v", ptext, encErr) 404 } 405 406 decrypted, decErr := CBCDecrypt(key, encrypted) 407 if decErr != nil { 408 t.Fatalf("Error decrypting '%s': %v", ptext, decErr) 409 } 410 411 if string(ptext[:]) != string(decrypted[:]) { 412 t.Fatal("Encryption->Decryption with same key should result in the original plaintext.") 413 } 414 } 415 416 // TestAESRelatedUtilFunctions tests various functions commonly used in fabric wrt AES 417 func TestAESRelatedUtilFunctions(t *testing.T) { 418 419 key, err := GenAESKey() 420 if err != nil { 421 t.Fatalf("Failed generating AES key [%s]", err) 422 } 423 424 for i := 1; i < 100; i++ { 425 len, err := rand.Int(rand.Reader, big.NewInt(1024)) 426 if err != nil { 427 t.Fatalf("Failed generating AES key [%s]", err) 428 } 429 msg, err := primitives.GetRandomBytes(int(len.Int64()) + 1) 430 if err != nil { 431 t.Fatalf("Failed generating AES key [%s]", err) 432 } 433 434 ct, err := CBCPKCS7Encrypt(key, msg) 435 if err != nil { 436 t.Fatalf("Failed encrypting [%s]", err) 437 } 438 439 msg2, err := CBCPKCS7Decrypt(key, ct) 440 if err != nil { 441 t.Fatalf("Failed decrypting [%s]", err) 442 } 443 444 if 0 != bytes.Compare(msg, msg2) { 445 t.Fatalf("Wrong decryption output [%x][%x]", msg, msg2) 446 } 447 448 } 449 450 } 451 452 // TestVariousAESKeyEncoding tests some AES <-> PEM conversions 453 func TestVariousAESKeyEncoding(t *testing.T) { 454 key, err := GenAESKey() 455 if err != nil { 456 t.Fatalf("Failed generating AES key [%s]", err) 457 } 458 459 // PEM format 460 pem := AEStoPEM(key) 461 keyFromPEM, err := PEMtoAES(pem, nil) 462 if err != nil { 463 t.Fatalf("Failed converting PEM to AES key [%s]", err) 464 } 465 if 0 != bytes.Compare(key, keyFromPEM) { 466 t.Fatalf("Failed converting PEM to AES key. Keys are different [%x][%x]", key, keyFromPEM) 467 } 468 469 // Encrypted PEM format 470 pem, err = AEStoEncryptedPEM(key, []byte("passwd")) 471 if err != nil { 472 t.Fatalf("Failed converting AES key to Encrypted PEM [%s]", err) 473 } 474 keyFromPEM, err = PEMtoAES(pem, []byte("passwd")) 475 if err != nil { 476 t.Fatalf("Failed converting encrypted PEM to AES key [%s]", err) 477 } 478 if 0 != bytes.Compare(key, keyFromPEM) { 479 t.Fatalf("Failed converting encrypted PEM to AES key. Keys are different [%x][%x]", key, keyFromPEM) 480 } 481 }