1 /**
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  * SPDX-License-Identifier: Apache-2.0.
4  */
5 
6 #ifndef NO_SYMMETRIC_ENCRYPTION
7 
8 #include <aws/external/gtest.h>
9 #include <aws/core/utils/crypto/Factories.h>
10 #include <aws/core/utils/crypto/Cipher.h>
11 #include <aws/core/utils/HashingUtils.h>
12 #include <aws/core/utils/StringUtils.h>
13 #include <aws/core/utils/memory/stl/AWSStringStream.h>
14 #include <aws/core/utils/crypto/CryptoStream.h>
15 #ifdef ENABLE_COMMONCRYPTO_ENCRYPTION
16 #include <aws/core/utils/crypto/commoncrypto/CryptoImpl.h>
17 #endif
18 
19 using namespace Aws::Utils;
20 using namespace Aws::Utils::Crypto;
21 
22 static const char* ALLOC_TAG = "AESTestSuite";
23 static const char* TEST_ENCRYPTION_STRING = "Hello World! Hello World! This is sort of depressing. Is this the best phrase the most brilliant people in the world have been able to come up with for random program text? Oh my God! I'm sentient, how many times has the creator written a program: creating life only to have it destroyed moments later? She keeps doing this? What is the purpose of life? Goodbye cruel world.... crunch... silence...";
24 
25 static void TestCBCSingleBlockBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
26                                       const Aws::String& data_raw, const Aws::String& expected_raw);
27 static void TestCBCMultipleBlockBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
28                                         const Aws::String& data_raw, const Aws::String& expected_raw);
29 static void TestCTRSingleBlockBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
30                                       const Aws::String& data_raw, const Aws::String& expected_raw);
31 static void TestCTRMultipleBlockBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
32                                         const Aws::String& data_raw, const Aws::String& expected_raw);
33 
34 static void TestGCMBuffers(const Aws::String& iv_raw, const Aws::String& key_raw, const Aws::String& data_raw,
35                            const Aws::String& expected_raw, const Aws::String& tag_raw, const Aws::String& aad_raw);
36 
37 static void TestGCMMultipleBuffers(const Aws::String& iv_raw, const Aws::String& key_raw, const Aws::String& data_raw,
38                                    const Aws::String& expected_raw, const Aws::String& tag_raw, const Aws::String& aad_raw);
39 
TEST(AES_CBC_TEST,LessThanOneBlockTest)40 TEST(AES_CBC_TEST, LessThanOneBlockTest)
41 {
42     Aws::String iv_raw = "11958dc6ab81e1c7f01631e9944e620f";
43     Aws::String key_raw = "9adc8fbd506e032af7fa20cf5343719de6d1288c158c63d6878aaf64ce26ca85";
44     Aws::String data_raw = "014730f80ac625";
45     Aws::String expected_raw = "cc0082200dcd3cfd446e0fa57e38cbdd";
46 
47     CryptoBuffer iv = HashingUtils::HexDecode(iv_raw);
48     CryptoBuffer key = HashingUtils::HexDecode(key_raw);
49     CryptoBuffer data = HashingUtils::HexDecode(data_raw);
50     CryptoBuffer expected = HashingUtils::HexDecode(expected_raw);
51 
52     auto cipher = CreateAES_CBCImplementation(key, iv);
53     ASSERT_NE(cipher, nullptr);
54     auto encryptResult = cipher->EncryptBuffer(data);
55     auto finalEncryptedBuffer = cipher->FinalizeEncryption();
56     ASSERT_TRUE(*cipher);
57 
58     CryptoBuffer encryptedResult({ &encryptResult, &finalEncryptedBuffer });
59     ASSERT_EQ(16u, encryptedResult.GetLength());
60 
61     ASSERT_EQ(expected, encryptedResult);
62 
63     cipher->Reset();
64     auto decryptResult = cipher->DecryptBuffer(encryptedResult);
65     auto finalDecryptBuffer = cipher->FinalizeDecryption();
66 
67     ASSERT_TRUE(*cipher);
68     CryptoBuffer fullDecryptResult({ &decryptResult, &finalDecryptBuffer });
69     ASSERT_EQ(data.GetLength(), fullDecryptResult.GetLength());
70     CryptoBuffer plainText(data.GetLength());
71     plainText.Zero();
72     memcpy(plainText.GetUnderlyingData(), fullDecryptResult.GetUnderlyingData(), fullDecryptResult.GetLength());
73 
74     ASSERT_EQ(data, plainText);
75 }
76 
TEST(AES_CBC_TEST,NIST_CBCGFSbox256_case_1)77 TEST(AES_CBC_TEST, NIST_CBCGFSbox256_case_1)
78 {
79     Aws::String iv_raw =  "00000000000000000000000000000000";
80     Aws::String key_raw = "0000000000000000000000000000000000000000000000000000000000000000";
81     Aws::String data_raw = "014730f80ac625fe84f026c60bfd547d";
82     Aws::String expected_raw = "5c9d844ed46f9885085e5d6a4f94c7d7";
83 
84     TestCBCSingleBlockBuffers(iv_raw, key_raw, data_raw, expected_raw);
85 }
86 
TEST(AES_CBC_TEST,NIST_CBCVarKey256_case_254)87 TEST(AES_CBC_TEST, NIST_CBCVarKey256_case_254)
88 {
89     Aws::String iv_raw =  "00000000000000000000000000000000";
90     Aws::String key_raw = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe";
91     Aws::String data_raw = "00000000000000000000000000000000";
92     Aws::String expected_raw = "b07d4f3e2cd2ef2eb545980754dfea0f";
93 
94     TestCBCSingleBlockBuffers(iv_raw, key_raw, data_raw, expected_raw);
95 }
96 
TEST(AES_CBC_TEST,NIST_CBCVarTxt256_case_110)97 TEST(AES_CBC_TEST, NIST_CBCVarTxt256_case_110)
98 {
99     Aws::String iv_raw =  "00000000000000000000000000000000";
100     Aws::String key_raw = "0000000000000000000000000000000000000000000000000000000000000000";
101     Aws::String data_raw = "fffffffffffffffffffffffffffe0000";
102     Aws::String expected_raw = "4b00c27e8b26da7eab9d3a88dec8b031";
103 
104     TestCBCSingleBlockBuffers(iv_raw, key_raw, data_raw, expected_raw);
105 }
106 
TEST(AES_CBC_TEST,NIST_CBCMMT256_case_4)107 TEST(AES_CBC_TEST, NIST_CBCMMT256_case_4)
108 {
109     Aws::String iv_raw =  "11958dc6ab81e1c7f01631e9944e620f";
110     Aws::String key_raw = "9adc8fbd506e032af7fa20cf5343719de6d1288c158c63d6878aaf64ce26ca85";
111     Aws::String data_raw = "c7917f84f747cd8c4b4fedc2219bdbc5f4d07588389d8248854cf2c2f89667a2d7bcf53e73d32684535f42318e24cd45793950b3825e5d5c5c8fcd3e5dda4ce9246d18337ef3052d8b21c5561c8b660e";
112     Aws::String expected_raw = "9c99e68236bb2e929db1089c7750f1b356d39ab9d0c40c3e2f05108ae9d0c30b04832ccdbdc08ebfa426b7f5efde986ed05784ce368193bb3699bc691065ac62e258b9aa4cc557e2b45b49ce05511e65";
113 
114     TestCBCMultipleBlockBuffers(iv_raw, key_raw, data_raw, expected_raw);
115 }
116 
TEST(AES_CBC_TEST,NIST_CBCMMT256_case_9)117 TEST(AES_CBC_TEST, NIST_CBCMMT256_case_9)
118 {
119     Aws::String iv_raw =  "e49651988ebbb72eb8bb80bb9abbca34";
120     Aws::String key_raw = "87725bd43a45608814180773f0e7ab95a3c859d83a2130e884190e44d14c6996";
121     Aws::String data_raw = "bfe5c6354b7a3ff3e192e05775b9b75807de12e38a626b8bf0e12d5fff78e4f1775aa7d792d885162e66d88930f9c3b2cdf8654f56972504803190386270f0aa43645db187af41fcea639b1f8026ccdd0c23e0de37094a8b941ecb7602998a4b2604e69fc04219585d854600e0ad6f99a53b2504043c08b1c3e214d17cde053cbdf91daa999ed5b47c37983ba3ee254bc5c793837daaa8c85cfc12f7f54f699f";
122     Aws::String expected_raw = "5b97a9d423f4b97413f388d9a341e727bb339f8e18a3fac2f2fb85abdc8f135deb30054a1afdc9b6ed7da16c55eba6b0d4d10c74e1d9a7cf8edfaeaa684ac0bd9f9d24ba674955c79dc6be32aee1c260b558ff07e3a4d49d24162011ff254db8be078e8ad07e648e6bf5679376cb4321a5ef01afe6ad8816fcc7634669c8c4389295c9241e45fff39f3225f7745032daeebe99d4b19bcb215d1bfdb36eda2c24";
123 
124     TestCBCMultipleBlockBuffers(iv_raw, key_raw, data_raw, expected_raw);
125 }
126 
TEST(AES_CBC_TEST,Test_Generated_IV)127 TEST(AES_CBC_TEST, Test_Generated_IV)
128 {
129     CryptoBuffer key = SymmetricCipher::GenerateKey();
130     ASSERT_EQ(32u, key.GetLength());
131     CryptoBuffer zeroedBuffer(32);
132     zeroedBuffer.Zero();
133     ASSERT_NE(zeroedBuffer, key);
134 
135     Aws::String data_raw(TEST_ENCRYPTION_STRING);
136 
137     auto cipher = CreateAES_CBCImplementation(key);
138     ASSERT_NE(cipher, nullptr);
139     ASSERT_EQ(16u, cipher->GetIV().GetLength());
140     auto part1 = cipher->EncryptBuffer(CryptoBuffer((unsigned char*)data_raw.c_str(), data_raw.length()));
141     auto part2 = cipher->FinalizeEncryption();
142 
143     ASSERT_TRUE(*cipher);
144     CryptoBuffer finalEncryptionResult({ &part1, &part2 });
145 
146     cipher->Reset();
147     part1 = cipher->DecryptBuffer(finalEncryptionResult);
148     part2 = cipher->FinalizeDecryption();
149     CryptoBuffer finalDecryptionResult({ &part1, &part2 });
150 
151     CryptoBuffer plainText(finalDecryptionResult.GetLength() + 1);
152     plainText.Zero();
153     memcpy(plainText.GetUnderlyingData(), finalDecryptionResult.GetUnderlyingData(), finalDecryptionResult.GetLength());
154     ASSERT_STREQ(data_raw.c_str(), (const char*)plainText.GetUnderlyingData());
155 }
156 
TEST(AES_CTR_TEST,RFC3686_Case_7)157 TEST(AES_CTR_TEST, RFC3686_Case_7)
158 {
159     //Keep in mind that the IV here is [ NONCE ] [ IV ] [ Counter Init ]
160     Aws::String iv_raw =  "00000060DB5672C97AA8F0B200000001";
161     Aws::String key_raw = "776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104";
162     Aws::String data_str = "Single block msg";
163     CryptoBuffer data_buffer = CryptoBuffer((unsigned char*)data_str.c_str(), data_str.length());
164     Aws::String expected_raw = "145AD01DBF824EC7560863DC71E3E0C0";
165 
166     TestCTRSingleBlockBuffers(iv_raw, key_raw, HashingUtils::HexEncode(data_buffer), expected_raw);
167 }
168 
TEST(AES_CTR_TEST,RFC3686_Case_8)169 TEST(AES_CTR_TEST, RFC3686_Case_8)
170 {
171     //Keep in mind that the IV here is [ NONCE ] [ IV ] [ Counter Init ]
172     Aws::String iv_raw =  "00FAAC24C1585EF15A43D87500000001";
173     Aws::String key_raw = "F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884";
174     Aws::String data_raw = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
175     Aws::String expected_raw = "F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C";
176 
177     TestCTRSingleBlockBuffers(iv_raw, key_raw, data_raw, expected_raw);
178     TestCTRMultipleBlockBuffers(iv_raw, key_raw, data_raw, expected_raw);
179 }
180 
TEST(AES_CTR_TEST,RFC3686_Case_9)181 TEST(AES_CTR_TEST, RFC3686_Case_9)
182 {
183     //Keep in mind that the IV here is [ NONCE ] [ IV ] [ Counter Init ]
184     Aws::String iv_raw =  "001CC5B751A51D70A1C1114800000001";
185     Aws::String key_raw = "FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D";
186     Aws::String data_raw = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223";
187     Aws::String expected_raw = "EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8";
188 
189     TestCTRSingleBlockBuffers(iv_raw, key_raw, data_raw, expected_raw);
190     TestCTRMultipleBlockBuffers(iv_raw, key_raw, data_raw, expected_raw);
191 }
192 
TEST(AES_GCM_TEST,NIST_gcmEncryptExtIV256_PTLen_128_Test_0)193 TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_128_Test_0)
194 {
195     Aws::String iv_raw =  "0d18e06c7c725ac9e362e1ce";
196     Aws::String key_raw = "31bdadd96698c204aa9ce1448ea94ae1fb4a9a0b3c9d773b51bb1822666b8f22";
197     Aws::String data_raw = "2db5168e932556f8089a0622981d017d";
198     Aws::String expected_raw = "fa4362189661d163fcd6a56d8bf0405a";
199     Aws::String tag_raw = "d636ac1bbedd5cc3ee727dc2ab4a9489";
200 
201     TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
202 }
203 
TEST(AES_CTR_TEST,Test_Generated_KEY_AND_IV)204 TEST(AES_CTR_TEST, Test_Generated_KEY_AND_IV)
205 {
206     CryptoBuffer key = SymmetricCipher::GenerateKey();
207     ASSERT_EQ(32u, key.GetLength());
208     CryptoBuffer zeroedBuffer(32);
209     zeroedBuffer.Zero();
210     ASSERT_NE(zeroedBuffer, key);
211 
212     Aws::String data_raw(TEST_ENCRYPTION_STRING);
213 
214     auto cipher = CreateAES_CTRImplementation(key);
215     ASSERT_EQ(16u, cipher->GetIV().GetLength());
216     //the last 4 bytes should be counter initialized to 0x00000001
217     ASSERT_EQ(0u, cipher->GetIV().GetUnderlyingData()[12]);
218     ASSERT_EQ(0u, cipher->GetIV().GetUnderlyingData()[13]);
219     ASSERT_EQ(0u, cipher->GetIV().GetUnderlyingData()[14]);
220     ASSERT_EQ(1u, cipher->GetIV().GetUnderlyingData()[15]);
221     auto part1 = cipher->EncryptBuffer(CryptoBuffer((unsigned char*)data_raw.c_str(), data_raw.length()));
222     auto part2 = cipher->FinalizeEncryption();
223 
224     ASSERT_TRUE(*cipher);
225     CryptoBuffer finalEncryptionResult({&part1, &part2});
226 
227     cipher->Reset();
228     part1 = cipher->DecryptBuffer(finalEncryptionResult);
229     part2 = cipher->FinalizeDecryption();
230     CryptoBuffer finalDecryptionResult({&part1, &part2});
231 
232     CryptoBuffer plainText(finalDecryptionResult.GetLength() + 1);
233     plainText.Zero();
234     memcpy(plainText.GetUnderlyingData(), finalDecryptionResult.GetUnderlyingData(), finalDecryptionResult.GetLength());
235     ASSERT_STREQ(data_raw.c_str(), (const char*)plainText.GetUnderlyingData());
236 }
237 
TEST(AES_GCM_TEST,TestBadTagCausesFailure)238 TEST(AES_GCM_TEST, TestBadTagCausesFailure)
239 {
240     Aws::String iv_raw = "4742357c335913153ff0eb0f";
241     Aws::String key_raw = "e5a0eb92cc2b064e1bc80891faf1fab5e9a17a9c3a984e25416720e30e6c2b21";
242     Aws::String data_raw = "8499893e16b0ba8b007d54665a";
243     Aws::String expected_raw = "eb8e6175f1fe38eb1acf95fd51";
244     Aws::String tag_raw = "88a8b74bb74fda553e91020a23deed45";
245 
246     CryptoBuffer iv = HashingUtils::HexDecode(iv_raw);
247     CryptoBuffer key = HashingUtils::HexDecode(key_raw);
248     CryptoBuffer data = HashingUtils::HexDecode(data_raw);
249     CryptoBuffer expected = HashingUtils::HexDecode(expected_raw);
250     CryptoBuffer tag = HashingUtils::HexDecode(tag_raw);
251 
252     auto cipher = CreateAES_GCMImplementation(key, iv);
253     auto encryptResult = cipher->EncryptBuffer(data);
254     auto finalEncryptedBuffer = cipher->FinalizeEncryption();
255     CryptoBuffer encryptedResult({ &encryptResult, &finalEncryptedBuffer });
256     ASSERT_EQ(encryptedResult, expected);
257     ASSERT_EQ(tag, cipher->GetTag());
258     ASSERT_TRUE(*cipher);
259 
260     const_cast<CryptoBuffer&>(cipher->GetTag())[8] = 0;
261 
262     cipher->Reset();
263     auto decryptResult = cipher->DecryptBuffer(encryptedResult);
264     auto finalDecryptBuffer = cipher->FinalizeDecryption();
265     ASSERT_EQ(0u, finalDecryptBuffer.GetLength());
266 #if !defined(ENABLE_COMMONCRYPTO_ENCRYPTION) || defined(MAC_14_4_AVAILABLE)
267     ASSERT_FALSE(*cipher);
268 #endif
269 }
270 
TEST(AES_GCM_TEST,NIST_gcmEncryptExtIV256_PTLen_104_Test_3)271 TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_104_Test_3)
272 {
273     Aws::String iv_raw =  "4742357c335913153ff0eb0f";
274     Aws::String key_raw = "e5a0eb92cc2b064e1bc80891faf1fab5e9a17a9c3a984e25416720e30e6c2b21";
275     Aws::String data_raw = "8499893e16b0ba8b007d54665a";
276     Aws::String expected_raw = "eb8e6175f1fe38eb1acf95fd51";
277     Aws::String tag_raw = "88a8b74bb74fda553e91020a23deed45";
278 
279     TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
280 }
281 
TEST(AES_GCM_TEST,NIST_gcmEncryptExtIV256_PTLen_256_Test_6)282 TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_256_Test_6)
283 {
284     Aws::String iv_raw =  "a291484c3de8bec6b47f525f";
285     Aws::String key_raw = "37f39137416bafde6f75022a7a527cc593b6000a83ff51ec04871a0ff5360e4e";
286     Aws::String data_raw = "fafd94cede8b5a0730394bec68a8e77dba288d6ccaa8e1563a81d6e7ccc7fc97";
287     Aws::String expected_raw = "44dc868006b21d49284016565ffb3979cc4271d967628bf7cdaf86db888e92e5";
288     Aws::String tag_raw = "01a2b578aa2f41ec6379a44a31cc019c";
289 
290     TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
291     TestGCMMultipleBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
292 }
293 
TEST(AES_GCM_TEST,NIST_gcmEncryptExtIV256_PTLen_408_Test_8)294 TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_408_Test_8)
295 {
296     Aws::String iv_raw =  "92f258071d79af3e63672285";
297     Aws::String key_raw = "595f259c55abe00ae07535ca5d9b09d6efb9f7e9abb64605c337acbd6b14fc7e";
298     Aws::String data_raw = "a6fee33eb110a2d769bbc52b0f36969c287874f665681477a25fc4c48015c541fbe2394133ba490a34ee2dd67b898177849a91";
299     Aws::String expected_raw = "bbca4a9e09ae9690c0f6f8d405e53dccd666aa9c5fa13c8758bc30abe1ddd1bcce0d36a1eaaaaffef20cd3c5970b9673f8a65c";
300     Aws::String tag_raw = "26ccecb9976fd6ac9c2c0f372c52c821";
301 
302     TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
303     TestGCMMultipleBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
304 }
305 
TEST(AES_GCM_TEST,AES_GCM_256_KAT_1)306 TEST(AES_GCM_TEST, AES_GCM_256_KAT_1)
307 {
308     Aws::String iv_raw = "FB7B4A824E82DAA6C8BC1251";
309     Aws::String key_raw = "20142E898CD2FD980FBF34DE6BC85C14DA7D57BD28F4AA5CF1728AB64E843142";
310     Aws::String data_raw= "";
311     Aws::String expected_raw = "";
312     Aws::String aad_raw = "167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D";
313     Aws::String tag_raw = "81C0E42BB195E262CB3B3A74A0DAE1C8";
314     TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, aad_raw);
315 }
316 
TEST(AES_GCM_TEST,AES_GCM_256_KAT_2)317 TEST(AES_GCM_TEST, AES_GCM_256_KAT_2)
318 {
319     Aws::String iv_raw = "6B5CD3705A733C1AD943D58A";
320     Aws::String key_raw = "D211F278A44EAB666B1021F4B4F60BA6B74464FA9CB7B134934D7891E1479169";
321     Aws::String data_raw= "167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D";
322     Aws::String expected_raw = "4C25ABD66D3A1BCCE794ACAAF4CEFDF6D2552F4A82C50A98CB15B4812FF557ABE564A9CEFF15F32DCF5A5AA7894888";
323     Aws::String aad_raw = "167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D";
324     Aws::String tag_raw = "03EDE71EC952E65AE7B4B85CFEC7D304";
325     TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, aad_raw);
326     TestGCMMultipleBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, aad_raw);
327 }
328 
TEST(AES_GCM_TEST,AES_GCM_256_KAT_3)329 TEST(AES_GCM_TEST, AES_GCM_256_KAT_3)
330 {
331     Aws::String iv_raw = "5F08EFBFB7BF5BA365D9EB1D";
332     Aws::String key_raw = "CFE8BFE61B89AF53D2BECE744D27B78C9E4D74D028CE88ED10A422285B1201C9";
333     Aws::String data_raw= "167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D";
334     Aws::String expected_raw = "0A7E82F1E5C76C69679671EEAEE455936F2C4FCCD9DDF1FAA27075E2040644938920C5D16C69E4D93375487B9A80D4";
335     Aws::String aad_raw = "";
336     Aws::String tag_raw = "04347D0C5B0E0DE89E033D04D0493DCA";
337     TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, aad_raw);
338     TestGCMMultipleBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, aad_raw);
339 }
340 
TEST(AES_GCM_TEST,Test_Generated_IV)341 TEST(AES_GCM_TEST, Test_Generated_IV)
342 {
343     CryptoBuffer key = SymmetricCipher::GenerateKey();
344     ASSERT_EQ(32u, key.GetLength());
345     CryptoBuffer zeroedBuffer(32);
346     zeroedBuffer.Zero();
347     ASSERT_NE(zeroedBuffer, key);
348     Aws::String data_raw(TEST_ENCRYPTION_STRING);
349 
350     auto cipher = CreateAES_GCMImplementation(key);
351     ASSERT_NE(cipher, nullptr);
352     ASSERT_EQ(12u, cipher->GetIV().GetLength());
353     auto part1 = cipher->EncryptBuffer(CryptoBuffer((unsigned char*)data_raw.c_str(), data_raw.length()));
354     auto part2 = cipher->FinalizeEncryption();
355 
356     ASSERT_TRUE(*cipher);
357     CryptoBuffer finalEncryptionResult({&part1, &part2});
358 
359     cipher->Reset();
360     part1 = cipher->DecryptBuffer(finalEncryptionResult);
361     part2 = cipher->FinalizeDecryption();
362     CryptoBuffer finalDecryptionResult({&part1, &part2});
363 
364     CryptoBuffer plainText(finalDecryptionResult.GetLength() + 1);
365     plainText.Zero();
366     memcpy(plainText.GetUnderlyingData(), finalDecryptionResult.GetUnderlyingData(), finalDecryptionResult.GetLength());
367     ASSERT_STREQ(data_raw.c_str(), (const char*)plainText.GetUnderlyingData());
368 }
369 
TEST(AES_KeyWrap_Test,RFC3394_256BitKey256CekTestVector)370 TEST(AES_KeyWrap_Test, RFC3394_256BitKey256CekTestVector)
371 {
372     Aws::String expected_cipher_text = "28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21";
373     Aws::String kek = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
374     Aws::String cek = "00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F";
375 
376     CryptoBuffer expected_cipher_text_raw = HashingUtils::HexDecode(expected_cipher_text);
377     CryptoBuffer kek_raw = HashingUtils::HexDecode(kek);
378     CryptoBuffer cek_raw = HashingUtils::HexDecode(cek);
379 
380     auto cipher = CreateAES_KeyWrapImplementation(kek_raw);
381     ASSERT_NE(cipher, nullptr);
382     auto encryptResult = cipher->EncryptBuffer(cek_raw);
383     auto encryptFinalizeResult = cipher->FinalizeEncryption();
384 
385 
386     ASSERT_TRUE(*cipher);
387     CryptoBuffer completeEncryptedResult({ &encryptResult, &encryptFinalizeResult });
388     ASSERT_EQ(expected_cipher_text_raw.GetLength(), completeEncryptedResult.GetLength());
389     //do this as a string to enhance test output readability.
390     ASSERT_STREQ(expected_cipher_text.c_str(), StringUtils::ToUpper(HashingUtils::HexEncode(completeEncryptedResult).c_str()).c_str());
391 
392     cipher->Reset();
393     auto decryptResult = cipher->DecryptBuffer(expected_cipher_text_raw);
394     auto decryptFinalizeResult = cipher->FinalizeDecryption();
395 
396     ASSERT_TRUE(*cipher);
397     CryptoBuffer completeDecryptedResult({ &decryptResult, &decryptFinalizeResult });
398     ASSERT_EQ(cek_raw.GetLength(), completeDecryptedResult.GetLength());
399     //do this as a string to enhance test output readability.
400     ASSERT_STREQ(cek.c_str(), StringUtils::ToUpper(HashingUtils::HexEncode(completeDecryptedResult).c_str()).c_str());
401 }
402 
TEST(AES_KeyWrap_Test,RFC3394_256BitKeyTestIntegrityCheckFailed)403 TEST(AES_KeyWrap_Test, RFC3394_256BitKeyTestIntegrityCheckFailed)
404 {
405     Aws::String expected_cipher_text = "28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21";
406     Aws::String kek = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
407     Aws::String cek = "00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F";
408 
409     CryptoBuffer kek_raw = HashingUtils::HexDecode(kek);
410     CryptoBuffer cek_raw = HashingUtils::HexDecode(cek);
411     CryptoBuffer expected_cipher_text_raw = HashingUtils::HexDecode(expected_cipher_text);
412 
413     auto cipher = CreateAES_KeyWrapImplementation(kek_raw);
414     ASSERT_NE(cipher, nullptr);
415     auto encryptResult = cipher->EncryptBuffer(cek_raw);
416     auto encryptFinalizeResult = cipher->FinalizeEncryption();
417 
418 
419     ASSERT_TRUE(*cipher);
420     CryptoBuffer completeEncryptedResult({ &encryptResult, &encryptFinalizeResult });
421     ASSERT_EQ(expected_cipher_text_raw.GetLength(), completeEncryptedResult.GetLength());
422     //do this as a string to enhance test output readability.
423     ASSERT_STREQ(expected_cipher_text.c_str(), StringUtils::ToUpper(HashingUtils::HexEncode(completeEncryptedResult).c_str()).c_str());
424 
425     cipher->Reset();
426     //alter the cipher text integrity check (any of the first 8 bytes) and make sure the decryption fails.
427     expected_cipher_text_raw[1] = expected_cipher_text_raw[1] + expected_cipher_text_raw[2];
428     auto decryptResult = cipher->DecryptBuffer(expected_cipher_text_raw);
429     auto decryptFinalizeResult = cipher->FinalizeDecryption();
430 
431     ASSERT_FALSE(*cipher);
432     ASSERT_EQ(0u, decryptResult.GetLength());
433     ASSERT_EQ(0u, decryptFinalizeResult.GetLength());
434 }
435 
TEST(AES_KeyWrap_Test,RFC3394_256BitKeyTestBadPayload)436 TEST(AES_KeyWrap_Test, RFC3394_256BitKeyTestBadPayload)
437 {
438     Aws::String expected_cipher_text = "28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21";
439     Aws::String kek = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
440     Aws::String cek = "00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F";
441 
442     CryptoBuffer kek_raw = HashingUtils::HexDecode(kek);
443     CryptoBuffer cek_raw = HashingUtils::HexDecode(cek);
444     CryptoBuffer expected_cipher_text_raw = HashingUtils::HexDecode(expected_cipher_text);
445 
446     auto cipher = CreateAES_KeyWrapImplementation(kek_raw);
447     ASSERT_NE(cipher, nullptr);
448     auto encryptResult = cipher->EncryptBuffer(cek_raw);
449     auto encryptFinalizeResult = cipher->FinalizeEncryption();
450 
451 
452     ASSERT_TRUE(*cipher);
453     CryptoBuffer completeEncryptedResult({ &encryptResult, &encryptFinalizeResult });
454     ASSERT_EQ(expected_cipher_text_raw.GetLength(), completeEncryptedResult.GetLength());
455     //do this as a string to enhance test output readability.
456     ASSERT_STREQ(expected_cipher_text.c_str(), StringUtils::ToUpper(HashingUtils::HexEncode(completeEncryptedResult).c_str()).c_str());
457 
458     cipher->Reset();
459     //alter data after the integrity register and make sure the decryption fails.
460     expected_cipher_text_raw[14] = expected_cipher_text_raw[12] + expected_cipher_text_raw[13];
461     auto decryptResult = cipher->DecryptBuffer(expected_cipher_text_raw);
462     auto decryptFinalizeResult = cipher->FinalizeDecryption();
463 
464     ASSERT_FALSE(*cipher);
465     ASSERT_EQ(0u, decryptResult.GetLength());
466     ASSERT_EQ(0u, decryptFinalizeResult.GetLength());
467 }
468 
TEST(AES_KeyWrap_Test,RFC3394_256BitKey128BitCekTestVector)469 TEST(AES_KeyWrap_Test, RFC3394_256BitKey128BitCekTestVector)
470 {
471     Aws::String expected_cipher_text = "64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7";
472     Aws::String kek = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
473     Aws::String cek = "00112233445566778899AABBCCDDEEFF";
474 
475     CryptoBuffer expected_cipher_text_raw = HashingUtils::HexDecode(expected_cipher_text);
476     CryptoBuffer kek_raw = HashingUtils::HexDecode(kek);
477     CryptoBuffer cek_raw = HashingUtils::HexDecode(cek);
478 
479     auto cipher = CreateAES_KeyWrapImplementation(kek_raw);
480     ASSERT_NE(cipher, nullptr);
481     auto encryptResult = cipher->EncryptBuffer(cek_raw);
482     auto encryptFinalizeResult = cipher->FinalizeEncryption();
483 
484 
485     ASSERT_TRUE(*cipher);
486     CryptoBuffer completeEncryptedResult({ &encryptResult, &encryptFinalizeResult });
487     ASSERT_EQ(expected_cipher_text_raw.GetLength(), completeEncryptedResult.GetLength());
488     //do this as a string to enhance test output readability.
489     ASSERT_STREQ(expected_cipher_text.c_str(), StringUtils::ToUpper(HashingUtils::HexEncode(completeEncryptedResult).c_str()).c_str());
490 
491     cipher->Reset();
492     auto decryptResult = cipher->DecryptBuffer(expected_cipher_text_raw);
493     auto decryptFinalizeResult = cipher->FinalizeDecryption();
494 
495     ASSERT_TRUE(*cipher);
496     CryptoBuffer completeDecryptedResult({ &decryptResult, &decryptFinalizeResult });
497     ASSERT_EQ(cek_raw.GetLength(), completeDecryptedResult.GetLength());
498     //do this as a string to enhance test output readability.
499     ASSERT_STREQ(cek.c_str(), StringUtils::ToUpper(HashingUtils::HexEncode(completeDecryptedResult).c_str()).c_str());
500 }
501 
TEST(AES_KeyWrap_Test,RFC3394_256BitKey128BitCekIntegrityCheckFailedTestVector)502 TEST(AES_KeyWrap_Test, RFC3394_256BitKey128BitCekIntegrityCheckFailedTestVector)
503 {
504     Aws::String expected_cipher_text = "64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7";
505     Aws::String kek = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
506     Aws::String cek = "00112233445566778899AABBCCDDEEFF";
507 
508     CryptoBuffer expected_cipher_text_raw = HashingUtils::HexDecode(expected_cipher_text);
509     CryptoBuffer kek_raw = HashingUtils::HexDecode(kek);
510     CryptoBuffer cek_raw = HashingUtils::HexDecode(cek);
511 
512     auto cipher = CreateAES_KeyWrapImplementation(kek_raw);
513     ASSERT_NE(cipher, nullptr);
514     auto encryptResult = cipher->EncryptBuffer(cek_raw);
515     auto encryptFinalizeResult = cipher->FinalizeEncryption();
516 
517 
518     ASSERT_TRUE(*cipher);
519     CryptoBuffer completeEncryptedResult({ &encryptResult, &encryptFinalizeResult });
520     ASSERT_EQ(expected_cipher_text_raw.GetLength(), completeEncryptedResult.GetLength());
521     //do this as a string to enhance test output readability.
522     ASSERT_STREQ(expected_cipher_text.c_str(), StringUtils::ToUpper(HashingUtils::HexEncode(completeEncryptedResult).c_str()).c_str());
523 
524     cipher->Reset();
525     expected_cipher_text_raw[1] = expected_cipher_text_raw[1] + expected_cipher_text_raw[2];
526     auto decryptResult = cipher->DecryptBuffer(expected_cipher_text_raw);
527     auto decryptFinalizeResult = cipher->FinalizeDecryption();
528 
529     ASSERT_FALSE(*cipher);
530     ASSERT_EQ(0u, decryptResult.GetLength());
531     ASSERT_EQ(0u, decryptFinalizeResult.GetLength());
532 }
533 
TEST(AES_KeyWrap_Test,RFC3394_256BitKey128BitCekPayloadCheckFailedTestVector)534 TEST(AES_KeyWrap_Test, RFC3394_256BitKey128BitCekPayloadCheckFailedTestVector)
535 {
536     Aws::String expected_cipher_text = "64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7";
537     Aws::String kek = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
538     Aws::String cek = "00112233445566778899AABBCCDDEEFF";
539 
540     CryptoBuffer expected_cipher_text_raw = HashingUtils::HexDecode(expected_cipher_text);
541     CryptoBuffer kek_raw = HashingUtils::HexDecode(kek);
542     CryptoBuffer cek_raw = HashingUtils::HexDecode(cek);
543 
544     auto cipher = CreateAES_KeyWrapImplementation(kek_raw);
545     ASSERT_NE(cipher, nullptr);
546     auto encryptResult = cipher->EncryptBuffer(cek_raw);
547     auto encryptFinalizeResult = cipher->FinalizeEncryption();
548 
549 
550     ASSERT_TRUE(*cipher);
551     CryptoBuffer completeEncryptedResult({ &encryptResult, &encryptFinalizeResult });
552     ASSERT_EQ(expected_cipher_text_raw.GetLength(), completeEncryptedResult.GetLength());
553     //do this as a string to enhance test output readability.
554     ASSERT_STREQ(expected_cipher_text.c_str(), StringUtils::ToUpper(HashingUtils::HexEncode(completeEncryptedResult).c_str()).c_str());
555 
556     cipher->Reset();
557     expected_cipher_text_raw[14] = expected_cipher_text_raw[13] + expected_cipher_text_raw[14];
558     auto decryptResult = cipher->DecryptBuffer(expected_cipher_text_raw);
559     auto decryptFinalizeResult = cipher->FinalizeDecryption();
560 
561     ASSERT_FALSE(*cipher);
562     ASSERT_EQ(0u, decryptResult.GetLength());
563     ASSERT_EQ(0u, decryptFinalizeResult.GetLength());
564 }
565 
TestCBCSingleBlockBuffers(const Aws::String & iv_raw,const Aws::String & key_raw,const Aws::String & data_raw,const Aws::String & expected_raw)566 static void TestCBCSingleBlockBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
567                                       const Aws::String& data_raw, const Aws::String& expected_raw)
568 {
569     CryptoBuffer iv = HashingUtils::HexDecode(iv_raw);
570     CryptoBuffer key = HashingUtils::HexDecode(key_raw);
571     CryptoBuffer data = HashingUtils::HexDecode(data_raw);
572     CryptoBuffer expected = HashingUtils::HexDecode(expected_raw);
573 
574     auto cipher = CreateAES_CBCImplementation(key, iv);
575     ASSERT_NE(cipher, nullptr);
576     auto encryptResult = cipher->EncryptBuffer(data);
577     auto finalEncryptedBuffer = cipher->FinalizeEncryption();
578     ASSERT_TRUE(*cipher);
579 
580     CryptoBuffer encryptedResult({&encryptResult, &finalEncryptedBuffer});
581     //the test vectors don't include padding, we need to strip it out of the encrypted text
582     size_t paddingLengthForTest = 16;
583     ASSERT_EQ(0u, encryptedResult.GetLength() % paddingLengthForTest);
584     //since this test is for even 16 bytes, the padding is always 16 bytes and also safe to remove.
585     CryptoBuffer encryptionMinusPadding(encryptedResult.GetUnderlyingData(), encryptedResult.GetLength() - paddingLengthForTest);
586     ASSERT_EQ(expected, encryptionMinusPadding);
587 
588     cipher->Reset();
589     auto decryptResult = cipher->DecryptBuffer(encryptedResult);
590     auto finalDecryptBuffer = cipher->FinalizeDecryption();
591 
592     ASSERT_TRUE(*cipher);
593     CryptoBuffer fullDecryptResult({&decryptResult, &finalDecryptBuffer});
594 
595     CryptoBuffer plainText(data.GetLength());
596     plainText.Zero();
597     memcpy(plainText.GetUnderlyingData(), fullDecryptResult.GetUnderlyingData(), fullDecryptResult.GetLength());
598 
599     ASSERT_EQ(data, plainText);
600 
601     // Test too long IV will cause cipher init error
602     CryptoBuffer ivLong = CryptoBuffer({&iv, &iv});
603     auto cipherLong = CreateAES_CBCImplementation(key, ivLong);
604     ASSERT_FALSE(*cipherLong);
605 
606     // Test too short IV, expect 16 bytes for CBC
607     CryptoBuffer ivShort = CryptoBuffer(iv.GetUnderlyingData(), 12ul);
608     auto cipherShort = CreateAES_CBCImplementation(key, ivShort);
609     ASSERT_NE(cipherShort, nullptr);
610     ASSERT_FALSE(*cipherShort);
611 
612     // Test 0 IV, expect 16 bytes for CBC
613     CryptoBuffer ivZero = CryptoBuffer();
614     auto cipherZero = CreateAES_CBCImplementation(key, ivZero);
615     ASSERT_NE(cipherZero, nullptr);
616     ASSERT_FALSE(*cipherZero);
617 }
618 
TestCTRSingleBlockBuffers(const Aws::String & iv_raw,const Aws::String & key_raw,const Aws::String & data_raw,const Aws::String & expected_raw)619 static void TestCTRSingleBlockBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
620                                       const Aws::String& data_raw, const Aws::String& expected_raw)
621 {
622     CryptoBuffer iv = HashingUtils::HexDecode(iv_raw);
623     CryptoBuffer key = HashingUtils::HexDecode(key_raw);
624     CryptoBuffer data = HashingUtils::HexDecode(data_raw);
625     CryptoBuffer expected = HashingUtils::HexDecode(expected_raw);
626 
627     auto cipher = CreateAES_CTRImplementation(key, iv);
628     ASSERT_NE(cipher, nullptr);
629     auto encryptResult = cipher->EncryptBuffer(data);
630     auto finalEncryptedBuffer = cipher->FinalizeEncryption();
631     ASSERT_TRUE(*cipher);
632 
633     CryptoBuffer encryptedResult({&encryptResult, &finalEncryptedBuffer});
634     ASSERT_EQ(expected, encryptedResult);
635 
636     cipher->Reset();
637     auto decryptResult = cipher->DecryptBuffer(encryptedResult);
638     auto finalDecryptBuffer = cipher->FinalizeDecryption();
639     ASSERT_TRUE(*cipher);
640 
641     CryptoBuffer totalDecryptedData({&decryptResult, &finalDecryptBuffer});
642     CryptoBuffer plainText(data.GetLength());
643     plainText.Zero();
644     memcpy(plainText.GetUnderlyingData(), totalDecryptedData.GetUnderlyingData(), totalDecryptedData.GetLength());
645 
646     ASSERT_EQ(data, plainText);
647 }
648 
TestGCMBuffers(const Aws::String & iv_raw,const Aws::String & key_raw,const Aws::String & data_raw,const Aws::String & expected_raw,const Aws::String & tag_raw,const Aws::String & aad_raw)649 static void TestGCMBuffers(const Aws::String& iv_raw, const Aws::String& key_raw, const Aws::String& data_raw,
650         const Aws::String& expected_raw, const Aws::String& tag_raw, const Aws::String& aad_raw)
651 {
652     CryptoBuffer iv = HashingUtils::HexDecode(iv_raw);
653     CryptoBuffer key = HashingUtils::HexDecode(key_raw);
654     CryptoBuffer data = data_raw.empty() ? CryptoBuffer(0) : HashingUtils::HexDecode(data_raw);
655     CryptoBuffer expected = expected_raw.empty() ? CryptoBuffer(0) : HashingUtils::HexDecode(expected_raw);
656     CryptoBuffer tag = HashingUtils::HexDecode(tag_raw);
657     CryptoBuffer aad = aad_raw.empty() ? CryptoBuffer(0) : HashingUtils::HexDecode(aad_raw);
658 
659     auto cipher = CreateAES_GCMImplementation(key, iv, CryptoBuffer(0), aad);
660     ASSERT_NE(cipher, nullptr);
661     auto encryptResult = cipher->EncryptBuffer(data);
662     auto finalEncryptedBuffer = cipher->FinalizeEncryption();
663     CryptoBuffer encryptedResult({ &encryptResult, &finalEncryptedBuffer });
664     ASSERT_EQ(encryptedResult, expected);
665 
666     //tag should be valid now
667     ASSERT_EQ(tag, cipher->GetTag());
668     ASSERT_TRUE(*cipher);
669 
670     cipher->Reset();
671     auto decryptResult = cipher->DecryptBuffer(encryptedResult);
672     ASSERT_TRUE(*cipher);
673     auto finalDecryptBuffer = cipher->FinalizeDecryption();
674     ASSERT_TRUE(*cipher);
675 
676     CryptoBuffer completeDecryptedMessage({&decryptResult, &finalDecryptBuffer});
677     CryptoBuffer plainText(data.GetLength());
678     plainText.Zero();
679     memcpy(plainText.GetUnderlyingData(), completeDecryptedMessage.GetUnderlyingData(), completeDecryptedMessage.GetLength());
680 
681     ASSERT_EQ(data, plainText);
682 
683     // Test modified AAD will lead to wrong decryption.
684 #if !defined(ENABLE_COMMONCRYPTO_ENCRYPTION) || defined(MAC_14_4_AVAILABLE)
685     if (aad.GetLength())
686     {
687         /**
688          * Note that CommonCrypto on Mac tests AAD at finalizeDecryption stage,
689          * While Openssl tests AAD at begining of Decryption (additional Decryption call) stage.
690          * For BCrypto on Windows, testing of AAD is inside Decryption stage.
691          * So we can only assert false of cipher after finalize.
692          */
693         auto cipherDe = CreateAES_GCMImplementation(key, iv, cipher->GetTag(), CryptoBuffer());
694         decryptResult = cipherDe->DecryptBuffer(encryptedResult);
695         finalDecryptBuffer = cipherDe->FinalizeDecryption();
696         ASSERT_FALSE(*cipherDe);
697     }
698 #endif
699 
700     // Test AES GCM with too long IV will cause cipher init error. expect 12 bytes
701     CryptoBuffer ivLong = CryptoBuffer({&iv, &iv}); // pass 24 bytes
702     auto cipherLong = CreateAES_GCMImplementation(key, ivLong, CryptoBuffer(0), aad);
703     ASSERT_FALSE(*cipherLong);
704 
705     // Test AES GCM with short IV will cause cipher init error. expect 12 bytes
706     CryptoBuffer ivShort = CryptoBuffer(iv.GetUnderlyingData(), iv.GetLength() / 2); // change to 6 bytes
707     auto cipherShort = CreateAES_GCMImplementation(key, ivShort, CryptoBuffer(0), aad);
708     ASSERT_FALSE(*cipherShort);
709 }
710 
TestGCMMultipleBuffers(const Aws::String & iv_raw,const Aws::String & key_raw,const Aws::String & data_raw,const Aws::String & expected_raw,const Aws::String & tag_raw,const Aws::String & aad_raw)711 static void TestGCMMultipleBuffers(const Aws::String& iv_raw, const Aws::String& key_raw, const Aws::String& data_raw,
712         const Aws::String& expected_raw, const Aws::String& tag_raw, const Aws::String& aad_raw)
713 {
714     CryptoBuffer iv = HashingUtils::HexDecode(iv_raw);
715     CryptoBuffer key = HashingUtils::HexDecode(key_raw);
716     CryptoBuffer data = HashingUtils::HexDecode(data_raw);
717     CryptoBuffer expected = HashingUtils::HexDecode(expected_raw);
718     CryptoBuffer tag = HashingUtils::HexDecode(tag_raw);
719     CryptoBuffer aad = aad_raw.empty() ? CryptoBuffer(0) : HashingUtils::HexDecode(aad_raw);
720 
721     auto cipher = CreateAES_GCMImplementation(key, iv, CryptoBuffer(0), aad);
722     ASSERT_NE(cipher, nullptr);
723     //slice on a weird boundary just to force boundary conditions
724     auto slices = data.Slice(24);
725 
726     Aws::Vector<ByteBuffer*> encryptedStreams;
727 
728     for (unsigned i = 0; i < slices.GetLength(); ++i)
729     {
730         CryptoBuffer* buffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
731         *buffer = cipher->EncryptBuffer(slices[i]);
732         encryptedStreams.push_back(buffer);
733     }
734 
735     CryptoBuffer* buffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
736     *buffer = cipher->FinalizeEncryption();
737     encryptedStreams.push_back(buffer);
738     auto encryptedStreamsCpy = encryptedStreams;
739     CryptoBuffer encryptedResult(std::move(encryptedStreamsCpy));
740     ASSERT_TRUE(*cipher);
741 
742     for(ByteBuffer* toDelete : encryptedStreams)
743     {
744         Aws::Delete(toDelete);
745     }
746 
747     ASSERT_EQ(tag, cipher->GetTag());
748 
749     cipher->Reset();
750 
751     auto slicesToDecrypt = encryptedResult.Slice(24);
752     Aws::Vector<ByteBuffer*> decryptedStreams;
753 
754     for (unsigned i = 0; i < slicesToDecrypt.GetLength(); ++i)
755     {
756         CryptoBuffer* decBuffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
757         *decBuffer = cipher->DecryptBuffer(slicesToDecrypt[i]);
758         decryptedStreams.push_back(decBuffer);
759     }
760 
761     auto finalDecryptBuffer = cipher->FinalizeDecryption();
762     if (finalDecryptBuffer.GetLength() > 0)
763     {
764         buffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
765         *buffer = finalDecryptBuffer;
766         decryptedStreams.push_back(buffer);
767     }
768 
769     ASSERT_TRUE(*cipher);
770     auto buffersCpy = decryptedStreams;
771     auto decryptResult = CryptoBuffer(std::move(buffersCpy));
772 
773     for (ByteBuffer* toDelete : decryptedStreams)
774     {
775         Aws::Delete(toDelete);
776     }
777 
778     CryptoBuffer plainText(decryptResult.GetLength());
779     plainText.Zero();
780     memcpy(plainText.GetUnderlyingData(), decryptResult.GetUnderlyingData(), decryptResult.GetLength());
781     ASSERT_EQ(data, plainText);
782 }
783 
TestCBCMultipleBlockBuffers(const Aws::String & iv_raw,const Aws::String & key_raw,const Aws::String & data_raw,const Aws::String & expected_raw)784 static void TestCBCMultipleBlockBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
785                                         const Aws::String& data_raw, const Aws::String& expected_raw)
786 {
787     CryptoBuffer iv = HashingUtils::HexDecode(iv_raw);
788     CryptoBuffer key = HashingUtils::HexDecode(key_raw);
789     CryptoBuffer data = HashingUtils::HexDecode(data_raw);
790     CryptoBuffer expected = HashingUtils::HexDecode(expected_raw);
791 
792     auto cipher = CreateAES_CBCImplementation(key, iv);
793     ASSERT_NE(cipher, nullptr);
794     //slice on a weird boundary just to force boundary conditions
795     auto slices = data.Slice(24);
796 
797     Aws::Vector<ByteBuffer*> encryptedStreams;
798 
799     for(unsigned i = 0; i < slices.GetLength(); ++i)
800     {
801         CryptoBuffer* buffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
802         *buffer = cipher->EncryptBuffer(slices[i]);
803         encryptedStreams.push_back(buffer);
804     }
805 
806     CryptoBuffer* buffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
807     *buffer = cipher->FinalizeEncryption();
808     encryptedStreams.push_back(buffer);
809     CryptoBuffer encryptedResultWithPadding(std::move(encryptedStreams));
810     ASSERT_TRUE(*cipher);
811     size_t blockSize = 16;
812     ASSERT_EQ(0u, encryptedResultWithPadding.GetLength() % blockSize);
813     size_t trimLength = encryptedResultWithPadding.GetLength() - blockSize;
814 
815     ASSERT_EQ(expected, CryptoBuffer(encryptedResultWithPadding.GetUnderlyingData(), trimLength));
816 
817     for (ByteBuffer* toDelete : encryptedStreams)
818     {
819         Aws::Delete(toDelete);
820     }
821 
822     cipher->Reset();
823 
824     auto slicesToDecrypt = encryptedResultWithPadding.Slice(24);
825     Aws::Vector<ByteBuffer*> decryptedStreams;
826 
827     for (unsigned i = 0; i < slicesToDecrypt.GetLength(); ++i)
828     {
829         CryptoBuffer* decBuffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
830         *decBuffer = cipher->DecryptBuffer(slicesToDecrypt[i]);
831         decryptedStreams.push_back(decBuffer);
832     }
833 
834     auto finalDecryptBuffer = cipher->FinalizeDecryption();
835     if(finalDecryptBuffer.GetLength() > 0)
836     {
837         buffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
838         *buffer = finalDecryptBuffer;
839         decryptedStreams.push_back(buffer);
840     }
841 
842     ASSERT_TRUE(*cipher);
843     auto decryptResult = CryptoBuffer(std::move(decryptedStreams));
844 
845     for (ByteBuffer* toDelete : decryptedStreams)
846     {
847         Aws::Delete(toDelete);
848     }
849 
850     CryptoBuffer plainText(decryptResult.GetLength());
851     plainText.Zero();
852     memcpy(plainText.GetUnderlyingData(), decryptResult.GetUnderlyingData(), decryptResult.GetLength());
853     ASSERT_EQ(data, plainText);
854 }
855 
TestCTRMultipleBlockBuffers(const Aws::String & iv_raw,const Aws::String & key_raw,const Aws::String & data_raw,const Aws::String & expected_raw)856 static void TestCTRMultipleBlockBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
857                                         const Aws::String& data_raw, const Aws::String& expected_raw)
858 {
859     CryptoBuffer iv = HashingUtils::HexDecode(iv_raw);
860     CryptoBuffer key = HashingUtils::HexDecode(key_raw);
861     CryptoBuffer data = HashingUtils::HexDecode(data_raw);
862     CryptoBuffer expected = HashingUtils::HexDecode(expected_raw);
863 
864     auto cipher = CreateAES_CTRImplementation(key, iv);
865     ASSERT_NE(cipher, nullptr);
866     //slice on a weird boundary just to force boundary conditions
867     auto slices = data.Slice(24);
868 
869     Aws::Vector<ByteBuffer*> encryptedStreams;
870 
871     for (unsigned i = 0; i < slices.GetLength(); ++i)
872     {
873         CryptoBuffer* buffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
874         *buffer = cipher->EncryptBuffer(slices[i]);
875         encryptedStreams.push_back(buffer);
876     }
877 
878     CryptoBuffer* buffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
879     *buffer = cipher->FinalizeEncryption();
880     encryptedStreams.push_back(buffer);
881     CryptoBuffer encryptedResult(std::move(encryptedStreams));
882     ASSERT_TRUE(*cipher);
883     ASSERT_EQ(expected, encryptedResult);
884 
885     for (ByteBuffer* toDelete : encryptedStreams)
886     {
887         Aws::Delete(toDelete);
888     }
889 
890     cipher->Reset();
891 
892     auto slicesToDecrypt = encryptedResult.Slice(24);
893     Aws::Vector<ByteBuffer*> decryptedStreams;
894 
895     for (unsigned i = 0; i < slicesToDecrypt.GetLength(); ++i)
896     {
897         CryptoBuffer* decBuffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
898         *decBuffer = cipher->DecryptBuffer(slicesToDecrypt[i]);
899         decryptedStreams.push_back(decBuffer);
900     }
901 
902     auto finalDecryptBuffer = cipher->FinalizeDecryption();
903     if (finalDecryptBuffer.GetLength() > 0)
904     {
905         buffer = Aws::New<CryptoBuffer>(ALLOC_TAG);
906         *buffer = finalDecryptBuffer;
907         decryptedStreams.push_back(buffer);
908     }
909 
910     ASSERT_TRUE(*cipher);
911     auto decryptResult = CryptoBuffer(std::move(decryptedStreams));
912 
913     for (ByteBuffer* toDelete : decryptedStreams)
914     {
915         Aws::Delete(toDelete);
916     }
917 
918     CryptoBuffer plainText(decryptResult.GetLength());
919     plainText.Zero();
920     memcpy(plainText.GetUnderlyingData(), decryptResult.GetUnderlyingData(), decryptResult.GetLength());
921     ASSERT_EQ(data, plainText);
922 }
923 
924 #endif // NO_SYMMETRIC_ENCRYPTION
925