github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/bccsp/pkcs11/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 pkcs11
    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  )
    27  
    28  // TestCBCPKCS7EncryptCBCPKCS7Decrypt encrypts using CBCPKCS7Encrypt and decrypts using CBCPKCS7Decrypt.
    29  func TestCBCPKCS7EncryptCBCPKCS7Decrypt(t *testing.T) {
    30  
    31  	// Note: The purpose of this test is not to test AES-256 in CBC mode's strength
    32  	// ... but rather to verify the code wrapping/unwrapping the cipher.
    33  	key := make([]byte, 32)
    34  	rand.Reader.Read(key)
    35  
    36  	//                  123456789012345678901234567890123456789012
    37  	var ptext = []byte("a message with arbitrary length (42 bytes)")
    38  
    39  	encrypted, encErr := AESCBCPKCS7Encrypt(key, ptext)
    40  	if encErr != nil {
    41  		t.Fatalf("Error encrypting '%s': %s", ptext, encErr)
    42  	}
    43  
    44  	decrypted, dErr := AESCBCPKCS7Decrypt(key, encrypted)
    45  	if dErr != nil {
    46  		t.Fatalf("Error decrypting the encrypted '%s': %v", ptext, dErr)
    47  	}
    48  
    49  	if string(ptext[:]) != string(decrypted[:]) {
    50  		t.Fatal("Decrypt( Encrypt( ptext ) ) != ptext: Ciphertext decryption with the same key must result in the original plaintext!")
    51  	}
    52  
    53  }
    54  
    55  // TestPKCS7Padding verifies the PKCS#7 padding, using a human readable plaintext.
    56  func TestPKCS7Padding(t *testing.T) {
    57  
    58  	// 0 byte/length ptext
    59  	ptext := []byte("")
    60  	expected := []byte{16, 16, 16, 16,
    61  		16, 16, 16, 16,
    62  		16, 16, 16, 16,
    63  		16, 16, 16, 16}
    64  	result := pkcs7Padding(ptext)
    65  
    66  	if !bytes.Equal(expected, result) {
    67  		t.Fatal("Padding error! Expected: ", expected, "', received: '", result, "'")
    68  	}
    69  
    70  	// 1 byte/length ptext
    71  	ptext = []byte("1")
    72  	expected = []byte{'1', 15, 15, 15,
    73  		15, 15, 15, 15,
    74  		15, 15, 15, 15,
    75  		15, 15, 15, 15}
    76  	result = pkcs7Padding(ptext)
    77  
    78  	if !bytes.Equal(expected, result) {
    79  		t.Fatal("Padding error! Expected: '", expected, "', received: '", result, "'")
    80  	}
    81  
    82  	// 2 byte/length ptext
    83  	ptext = []byte("12")
    84  	expected = []byte{'1', '2', 14, 14,
    85  		14, 14, 14, 14,
    86  		14, 14, 14, 14,
    87  		14, 14, 14, 14}
    88  	result = pkcs7Padding(ptext)
    89  
    90  	if !bytes.Equal(expected, result) {
    91  		t.Fatal("Padding error! Expected: '", expected, "', received: '", result, "'")
    92  	}
    93  
    94  	// 3 to aes.BlockSize-1 byte plaintext
    95  	ptext = []byte("1234567890ABCDEF")
    96  	for i := 3; i < aes.BlockSize; i++ {
    97  		result := pkcs7Padding(ptext[:i])
    98  
    99  		padding := aes.BlockSize - i
   100  		expectedPadding := bytes.Repeat([]byte{byte(padding)}, padding)
   101  		expected = append(ptext[:i], expectedPadding...)
   102  
   103  		if !bytes.Equal(result, expected) {
   104  			t.Fatal("Padding error! Expected: '", expected, "', received: '", result, "'")
   105  		}
   106  
   107  	}
   108  
   109  	// aes.BlockSize length ptext
   110  	ptext = bytes.Repeat([]byte{byte('x')}, aes.BlockSize)
   111  	result = pkcs7Padding(ptext)
   112  
   113  	expectedPadding := bytes.Repeat([]byte{byte(aes.BlockSize)}, aes.BlockSize)
   114  	expected = append(ptext, expectedPadding...)
   115  
   116  	if len(result) != 2*aes.BlockSize {
   117  		t.Fatal("Padding error: expected the length of the returned slice to be 2 times aes.BlockSize")
   118  	}
   119  
   120  	if !bytes.Equal(expected, result) {
   121  		t.Fatal("Padding error! Expected: '", expected, "', received: '", result, "'")
   122  	}
   123  
   124  }
   125  
   126  // TestPKCS7UnPadding verifies the PKCS#7 unpadding, using a human readable plaintext.
   127  func TestPKCS7UnPadding(t *testing.T) {
   128  
   129  	// 0 byte/length ptext
   130  	expected := []byte("")
   131  	ptext := []byte{16, 16, 16, 16,
   132  		16, 16, 16, 16,
   133  		16, 16, 16, 16,
   134  		16, 16, 16, 16}
   135  
   136  	result, _ := pkcs7UnPadding(ptext)
   137  
   138  	if !bytes.Equal(expected, result) {
   139  		t.Fatal("UnPadding error! Expected: '", expected, "', received: '", result, "'")
   140  	}
   141  
   142  	// 1 byte/length ptext
   143  	expected = []byte("1")
   144  	ptext = []byte{'1', 15, 15, 15,
   145  		15, 15, 15, 15,
   146  		15, 15, 15, 15,
   147  		15, 15, 15, 15}
   148  
   149  	result, _ = pkcs7UnPadding(ptext)
   150  
   151  	if !bytes.Equal(expected, result) {
   152  		t.Fatal("UnPadding error! Expected: '", expected, "', received: '", result, "'")
   153  	}
   154  
   155  	// 2 byte/length ptext
   156  	expected = []byte("12")
   157  	ptext = []byte{'1', '2', 14, 14,
   158  		14, 14, 14, 14,
   159  		14, 14, 14, 14,
   160  		14, 14, 14, 14}
   161  
   162  	result, _ = pkcs7UnPadding(ptext)
   163  
   164  	if !bytes.Equal(expected, result) {
   165  		t.Fatal("UnPadding error! Expected: '", expected, "', received: '", result, "'")
   166  	}
   167  
   168  	// 3 to aes.BlockSize-1 byte plaintext
   169  	base := []byte("1234567890ABCDEF")
   170  	for i := 3; i < aes.BlockSize; i++ {
   171  		iPad := aes.BlockSize - i
   172  		padding := bytes.Repeat([]byte{byte(iPad)}, iPad)
   173  		ptext = append(base[:i], padding...)
   174  
   175  		expected := base[:i]
   176  		result, _ := pkcs7UnPadding(ptext)
   177  
   178  		if !bytes.Equal(result, expected) {
   179  			t.Fatal("UnPadding error! Expected: '", expected, "', received: '", result, "'")
   180  		}
   181  
   182  	}
   183  
   184  	// aes.BlockSize length ptext
   185  	expected = bytes.Repeat([]byte{byte('x')}, aes.BlockSize)
   186  	padding := bytes.Repeat([]byte{byte(aes.BlockSize)}, aes.BlockSize)
   187  	ptext = append(expected, padding...)
   188  
   189  	result, _ = pkcs7UnPadding(ptext)
   190  
   191  	if !bytes.Equal(expected, result) {
   192  		t.Fatal("UnPadding error! Expected: '", expected, "', received: '", result, "'")
   193  	}
   194  }
   195  
   196  // TestCBCEncryptCBCPKCS7Decrypt_BlockSizeLengthPlaintext verifies that CBCPKCS7Decrypt returns an error
   197  // when attempting to decrypt ciphertext of an irreproducible length.
   198  func TestCBCEncryptCBCPKCS7Decrypt_BlockSizeLengthPlaintext(t *testing.T) {
   199  
   200  	// One of the purposes of this test is to also document and clarify the expected behavior, i.e., that an extra
   201  	// block is appended to the message at the padding stage, as per the spec of PKCS#7 v1.5 [see RFC-2315 p.21]
   202  	key := make([]byte, 32)
   203  	rand.Reader.Read(key)
   204  
   205  	//                  1234567890123456
   206  	var ptext = []byte("a 16 byte messag")
   207  
   208  	encrypted, encErr := aesCBCEncrypt(key, ptext)
   209  	if encErr != nil {
   210  		t.Fatalf("Error encrypting '%s': %v", ptext, encErr)
   211  	}
   212  
   213  	decrypted, dErr := AESCBCPKCS7Decrypt(key, encrypted)
   214  	if dErr == nil {
   215  		t.Fatalf("Expected an error decrypting ptext '%s'. Decrypted to '%v'", dErr, decrypted)
   216  	}
   217  }
   218  
   219  // TestCBCPKCS7EncryptCBCDecrypt_ExpectingCorruptMessage verifies that CBCDecrypt can decrypt the unpadded
   220  // version of the ciphertext, of a message of BlockSize length.
   221  func TestCBCPKCS7EncryptCBCDecrypt_ExpectingCorruptMessage(t *testing.T) {
   222  
   223  	// One of the purposes of this test is to also document and clarify the expected behavior, i.e., that an extra
   224  	// block is appended to the message at the padding stage, as per the spec of PKCS#7 v1.5 [see RFC-2315 p.21]
   225  	key := make([]byte, 32)
   226  	rand.Reader.Read(key)
   227  
   228  	//                  0123456789ABCDEF
   229  	var ptext = []byte("a 16 byte messag")
   230  
   231  	encrypted, encErr := AESCBCPKCS7Encrypt(key, ptext)
   232  	if encErr != nil {
   233  		t.Fatalf("Error encrypting ptext %v", encErr)
   234  	}
   235  
   236  	decrypted, dErr := aesCBCDecrypt(key, encrypted)
   237  	if dErr != nil {
   238  		t.Fatalf("Error encrypting ptext %v, %v", dErr, decrypted)
   239  	}
   240  
   241  	if string(ptext[:]) != string(decrypted[:aes.BlockSize]) {
   242  		t.Log("ptext: ", ptext)
   243  		t.Log("decrypted: ", decrypted[:aes.BlockSize])
   244  		t.Fatal("Encryption->Decryption with same key should result in original ptext")
   245  	}
   246  
   247  	if !bytes.Equal(decrypted[aes.BlockSize:], bytes.Repeat([]byte{byte(aes.BlockSize)}, aes.BlockSize)) {
   248  		t.Fatal("Expected extra block with padding in encrypted ptext", decrypted)
   249  	}
   250  
   251  }
   252  
   253  // TestCBCPKCS7Encrypt_EmptyPlaintext encrypts and pad an empty ptext. Verifying as well that the ciphertext length is as expected.
   254  func TestCBCPKCS7Encrypt_EmptyPlaintext(t *testing.T) {
   255  
   256  	key := make([]byte, 32)
   257  	rand.Reader.Read(key)
   258  
   259  	t.Log("Generated key: ", key)
   260  
   261  	var emptyPlaintext = []byte("")
   262  	t.Log("Plaintext length: ", len(emptyPlaintext))
   263  
   264  	ciphertext, encErr := AESCBCPKCS7Encrypt(key, emptyPlaintext)
   265  	if encErr != nil {
   266  		t.Fatalf("Error encrypting '%v'", encErr)
   267  	}
   268  
   269  	// Expected ciphertext length: 32 (=32)
   270  	// As part of the padding, at least one block gets encrypted (while the first block is the IV)
   271  	const expectedLength = aes.BlockSize + aes.BlockSize
   272  	if len(ciphertext) != expectedLength {
   273  		t.Fatalf("Wrong ciphertext length. Expected %d, recieved %d", expectedLength, len(ciphertext))
   274  	}
   275  
   276  	t.Log("Ciphertext length: ", len(ciphertext))
   277  	t.Log("Cipher: ", ciphertext)
   278  }
   279  
   280  // TestCBCEncrypt_EmptyPlaintext encrypts an empty message. Verifying as well that the ciphertext length is as expected.
   281  func TestCBCEncrypt_EmptyPlaintext(t *testing.T) {
   282  
   283  	key := make([]byte, 32)
   284  	rand.Reader.Read(key)
   285  	t.Log("Generated key: ", key)
   286  
   287  	var emptyPlaintext = []byte("")
   288  	t.Log("Message length: ", len(emptyPlaintext))
   289  
   290  	ciphertext, encErr := aesCBCEncrypt(key, emptyPlaintext)
   291  	if encErr != nil {
   292  	}
   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  }