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  }