github.com/aavshr/aws-sdk-go@v1.41.3/service/s3/s3crypto/aes_gcm_test.go (about)

     1  //go:build go1.9
     2  // +build go1.9
     3  
     4  package s3crypto
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/hex"
     9  	"encoding/json"
    10  	"fmt"
    11  	"io"
    12  	"io/ioutil"
    13  	"strings"
    14  	"testing"
    15  )
    16  
    17  // AES GCM
    18  func TestAES_GCM_NIST_gcmEncryptExtIV256_PTLen_128_Test_0(t *testing.T) {
    19  	iv, _ := hex.DecodeString("0d18e06c7c725ac9e362e1ce")
    20  	key, _ := hex.DecodeString("31bdadd96698c204aa9ce1448ea94ae1fb4a9a0b3c9d773b51bb1822666b8f22")
    21  	plaintext, _ := hex.DecodeString("2db5168e932556f8089a0622981d017d")
    22  	expected, _ := hex.DecodeString("fa4362189661d163fcd6a56d8bf0405a")
    23  	tag, _ := hex.DecodeString("d636ac1bbedd5cc3ee727dc2ab4a9489")
    24  	aesgcmTest(t, iv, key, plaintext, expected, tag)
    25  }
    26  
    27  func TestAES_GCM_NIST_gcmEncryptExtIV256_PTLen_104_Test_3(t *testing.T) {
    28  	iv, _ := hex.DecodeString("4742357c335913153ff0eb0f")
    29  	key, _ := hex.DecodeString("e5a0eb92cc2b064e1bc80891faf1fab5e9a17a9c3a984e25416720e30e6c2b21")
    30  	plaintext, _ := hex.DecodeString("8499893e16b0ba8b007d54665a")
    31  	expected, _ := hex.DecodeString("eb8e6175f1fe38eb1acf95fd51")
    32  	tag, _ := hex.DecodeString("88a8b74bb74fda553e91020a23deed45")
    33  	aesgcmTest(t, iv, key, plaintext, expected, tag)
    34  }
    35  
    36  func TestAES_GCM_NIST_gcmEncryptExtIV256_PTLen_256_Test_6(t *testing.T) {
    37  	iv, _ := hex.DecodeString("a291484c3de8bec6b47f525f")
    38  	key, _ := hex.DecodeString("37f39137416bafde6f75022a7a527cc593b6000a83ff51ec04871a0ff5360e4e")
    39  	plaintext, _ := hex.DecodeString("fafd94cede8b5a0730394bec68a8e77dba288d6ccaa8e1563a81d6e7ccc7fc97")
    40  	expected, _ := hex.DecodeString("44dc868006b21d49284016565ffb3979cc4271d967628bf7cdaf86db888e92e5")
    41  	tag, _ := hex.DecodeString("01a2b578aa2f41ec6379a44a31cc019c")
    42  	aesgcmTest(t, iv, key, plaintext, expected, tag)
    43  }
    44  
    45  func TestAES_GCM_NIST_gcmEncryptExtIV256_PTLen_408_Test_8(t *testing.T) {
    46  	iv, _ := hex.DecodeString("92f258071d79af3e63672285")
    47  	key, _ := hex.DecodeString("595f259c55abe00ae07535ca5d9b09d6efb9f7e9abb64605c337acbd6b14fc7e")
    48  	plaintext, _ := hex.DecodeString("a6fee33eb110a2d769bbc52b0f36969c287874f665681477a25fc4c48015c541fbe2394133ba490a34ee2dd67b898177849a91")
    49  	expected, _ := hex.DecodeString("bbca4a9e09ae9690c0f6f8d405e53dccd666aa9c5fa13c8758bc30abe1ddd1bcce0d36a1eaaaaffef20cd3c5970b9673f8a65c")
    50  	tag, _ := hex.DecodeString("26ccecb9976fd6ac9c2c0f372c52c821")
    51  	aesgcmTest(t, iv, key, plaintext, expected, tag)
    52  }
    53  
    54  type KAT struct {
    55  	IV         string `json:"iv"`
    56  	Key        string `json:"key"`
    57  	Plaintext  string `json:"pt"`
    58  	AAD        string `json:"aad"`
    59  	CipherText string `json:"ct"`
    60  	Tag        string `json:"tag"`
    61  }
    62  
    63  func TestAES_GCM_KATS(t *testing.T) {
    64  	fileContents, err := ioutil.ReadFile("testdata/aes_gcm.json")
    65  	if err != nil {
    66  		t.Fatalf("failed to read KAT file: %v", err)
    67  	}
    68  
    69  	var kats []KAT
    70  	err = json.Unmarshal(fileContents, &kats)
    71  	if err != nil {
    72  		t.Fatalf("failed to unmarshal KAT json file: %v", err)
    73  	}
    74  
    75  	for i, kat := range kats {
    76  		t.Run(fmt.Sprintf("Case%d", i), func(t *testing.T) {
    77  			if len(kat.AAD) > 0 {
    78  				t.Skip("Skipping... SDK implementation does not expose additional authenticated data")
    79  			}
    80  			iv, err := hex.DecodeString(kat.IV)
    81  			if err != nil {
    82  				t.Fatalf("failed to decode iv: %v", err)
    83  			}
    84  			key, err := hex.DecodeString(kat.Key)
    85  			if err != nil {
    86  				t.Fatalf("failed to decode key: %v", err)
    87  			}
    88  			plaintext, err := hex.DecodeString(kat.Plaintext)
    89  			if err != nil {
    90  				t.Fatalf("failed to decode plaintext: %v", err)
    91  			}
    92  			ciphertext, err := hex.DecodeString(kat.CipherText)
    93  			if err != nil {
    94  				t.Fatalf("failed to decode ciphertext: %v", err)
    95  			}
    96  			tag, err := hex.DecodeString(kat.Tag)
    97  			if err != nil {
    98  				t.Fatalf("failed to decode tag: %v", err)
    99  			}
   100  			aesgcmTest(t, iv, key, plaintext, ciphertext, tag)
   101  		})
   102  	}
   103  }
   104  
   105  func TestGCMEncryptReader_SourceError(t *testing.T) {
   106  	gcm := &gcmEncryptReader{
   107  		encrypter: &mockCipherAEAD{},
   108  		src:       &mockSourceReader{err: fmt.Errorf("test read error")},
   109  	}
   110  
   111  	b := make([]byte, 10)
   112  	n, err := gcm.Read(b)
   113  	if err == nil {
   114  		t.Fatalf("expected error, but got nil")
   115  	} else if err != nil && !strings.Contains(err.Error(), "test read error") {
   116  		t.Fatalf("expected source read error, but got %v", err)
   117  	}
   118  
   119  	if n != 0 {
   120  		t.Errorf("expected number of read bytes to be zero, but got %v", n)
   121  	}
   122  }
   123  
   124  func TestGCMDecryptReader_SourceError(t *testing.T) {
   125  	gcm := &gcmDecryptReader{
   126  		decrypter: &mockCipherAEAD{},
   127  		src:       &mockSourceReader{err: fmt.Errorf("test read error")},
   128  	}
   129  
   130  	b := make([]byte, 10)
   131  	n, err := gcm.Read(b)
   132  	if err == nil {
   133  		t.Fatalf("expected error, but got nil")
   134  	} else if err != nil && !strings.Contains(err.Error(), "test read error") {
   135  		t.Fatalf("expected source read error, but got %v", err)
   136  	}
   137  
   138  	if n != 0 {
   139  		t.Errorf("expected number of read bytes to be zero, but got %v", n)
   140  	}
   141  }
   142  
   143  func TestGCMDecryptReader_DecrypterOpenError(t *testing.T) {
   144  	gcm := &gcmDecryptReader{
   145  		decrypter: &mockCipherAEAD{openError: fmt.Errorf("test open error")},
   146  		src:       &mockSourceReader{err: io.EOF},
   147  	}
   148  
   149  	b := make([]byte, 10)
   150  	n, err := gcm.Read(b)
   151  	if err == nil {
   152  		t.Fatalf("expected error, but got nil")
   153  	} else if err != nil && !strings.Contains(err.Error(), "test open error") {
   154  		t.Fatalf("expected source read error, but got %v", err)
   155  	}
   156  
   157  	if n != 0 {
   158  		t.Errorf("expected number of read bytes to be zero, but got %v", n)
   159  	}
   160  }
   161  
   162  func aesgcmTest(t *testing.T, iv, key, plaintext, expected, tag []byte) {
   163  	t.Helper()
   164  	const gcmTagSize = 16
   165  	cd := CipherData{
   166  		Key: key,
   167  		IV:  iv,
   168  	}
   169  	gcm, err := newAESGCM(cd)
   170  	if err != nil {
   171  		t.Errorf("expected no error, but received %v", err)
   172  	}
   173  
   174  	cipherdata := gcm.Encrypt(bytes.NewReader(plaintext))
   175  
   176  	ciphertext, err := ioutil.ReadAll(cipherdata)
   177  	if err != nil {
   178  		t.Errorf("expected no error, but received %v", err)
   179  	}
   180  
   181  	// splitting tag and ciphertext
   182  	etag := ciphertext[len(ciphertext)-gcmTagSize:]
   183  	if !bytes.Equal(etag, tag) {
   184  		t.Errorf("expected tags to be equivalent")
   185  	}
   186  	if !bytes.Equal(ciphertext[:len(ciphertext)-gcmTagSize], expected) {
   187  		t.Errorf("expected ciphertext to be equivalent")
   188  	}
   189  
   190  	data := gcm.Decrypt(bytes.NewReader(ciphertext))
   191  	text, err := ioutil.ReadAll(data)
   192  	if err != nil {
   193  		t.Errorf("expected no error, but received %v", err)
   194  	}
   195  	if !bytes.Equal(plaintext, text) {
   196  		t.Errorf("expected ciphertext to be equivalent")
   197  	}
   198  }
   199  
   200  type mockSourceReader struct {
   201  	n   int
   202  	err error
   203  }
   204  
   205  func (b mockSourceReader) Read(p []byte) (n int, err error) {
   206  	return b.n, b.err
   207  }
   208  
   209  type mockCipherAEAD struct {
   210  	seal      []byte
   211  	openError error
   212  }
   213  
   214  func (m mockCipherAEAD) NonceSize() int {
   215  	panic("implement me")
   216  }
   217  
   218  func (m mockCipherAEAD) Overhead() int {
   219  	panic("implement me")
   220  }
   221  
   222  func (m mockCipherAEAD) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
   223  	return m.seal
   224  }
   225  
   226  func (m mockCipherAEAD) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
   227  	return []byte("mocked decrypt"), m.openError
   228  }