Skip to content

Commit 82f9454

Browse files
singku-chinasingku
andcommitted
S3-Encryption Client Updates
Supported AES/GCM with AAD for platforms including Windows, Linux and Mac. Added nww KMS with context and AES-GCM key wrap algorithms for CEK. The updated S3-Encryption client can read objects encrypted by older client. Co-authored-by: Andrew Tang <[email protected]>
1 parent 92d99ba commit 82f9454

35 files changed

+1771
-272
lines changed

aws-cpp-sdk-core-tests/utils/crypto/CryptoStreamsTest.cpp

-8
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,8 @@ TEST(CryptoStreamsTest, TestCiphersNeverUsedSrc)
250250
TestCiphersNeverUsedSrc(CipherCreateImplementationFunction(CreateAES_CBCImplementation), key, CipherMode::Decrypt);
251251
TestCiphersNeverUsedSrc(CipherCreateImplementationFunction(CreateAES_CTRImplementation), key, CipherMode::Encrypt);
252252
TestCiphersNeverUsedSrc(CipherCreateImplementationFunction(CreateAES_CTRImplementation), key, CipherMode::Decrypt);
253-
#ifndef ENABLE_COMMONCRYPTO_ENCRYPTION
254253
TestCiphersNeverUsedSrc(CipherCreateImplementationFunction(CreateAES_GCMImplementation), key, CipherMode::Encrypt);
255254
TestCiphersNeverUsedSrc(CipherCreateImplementationFunction(CreateAES_GCMImplementation), key, CipherMode::Decrypt);
256-
#endif
257255
Aws::String kek = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
258256
CryptoBuffer kek_raw = HashingUtils::HexDecode(kek);
259257
TestCiphersNeverUsedSrc(CipherCreateImplementationFunction(CreateAES_KeyWrapImplementation), kek_raw, CipherMode::Encrypt);
@@ -268,10 +266,8 @@ TEST(CryptoStreamsTest, TestCiphersNeverUsedSinkDestructorFinalizes)
268266
TestCiphersNeverUsedSinkDestructorFinalizes(CipherCreateImplementationFunction(CreateAES_CBCImplementation), key, CipherMode::Decrypt);
269267
TestCiphersNeverUsedSinkDestructorFinalizes(CipherCreateImplementationFunction(CreateAES_CTRImplementation), key, CipherMode::Encrypt);
270268
TestCiphersNeverUsedSinkDestructorFinalizes(CipherCreateImplementationFunction(CreateAES_CTRImplementation), key, CipherMode::Decrypt);
271-
#ifndef ENABLE_COMMONCRYPTO_ENCRYPTION
272269
TestCiphersNeverUsedSinkDestructorFinalizes(CipherCreateImplementationFunction(CreateAES_GCMImplementation), key, CipherMode::Encrypt);
273270
TestCiphersNeverUsedSinkDestructorFinalizes(CipherCreateImplementationFunction(CreateAES_GCMImplementation), key, CipherMode::Decrypt);
274-
#endif
275271
Aws::String kek = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
276272
CryptoBuffer kek_raw = HashingUtils::HexDecode(kek);
277273
TestCiphersNeverUsedSinkDestructorFinalizes(CipherCreateImplementationFunction(CreateAES_KeyWrapImplementation), kek_raw, CipherMode::Encrypt);
@@ -286,10 +282,8 @@ TEST(CryptoStreamsTest, TestUninitializedCiphersSinkExplicitFinalize)
286282
TestCiphersNeverUsedSinkExplicitFinalize(CipherCreateImplementationFunction(CreateAES_CBCImplementation), key, CipherMode::Decrypt);
287283
TestCiphersNeverUsedSinkExplicitFinalize(CipherCreateImplementationFunction(CreateAES_CTRImplementation), key, CipherMode::Encrypt);
288284
TestCiphersNeverUsedSinkExplicitFinalize(CipherCreateImplementationFunction(CreateAES_CTRImplementation), key, CipherMode::Decrypt);
289-
#ifndef ENABLE_COMMONCRYPTO_ENCRYPTION
290285
TestCiphersNeverUsedSinkExplicitFinalize(CipherCreateImplementationFunction(CreateAES_GCMImplementation), key, CipherMode::Encrypt);
291286
TestCiphersNeverUsedSinkExplicitFinalize(CipherCreateImplementationFunction(CreateAES_GCMImplementation), key, CipherMode::Decrypt);
292-
#endif
293287
Aws::String kek = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
294288
CryptoBuffer kek_raw = HashingUtils::HexDecode(kek);
295289
TestCiphersNeverUsedSinkExplicitFinalize(CipherCreateImplementationFunction(CreateAES_KeyWrapImplementation), kek_raw, CipherMode::Encrypt);
@@ -687,7 +681,6 @@ TEST(CryptoStreamsTest, TestEncryptSrcStreamSeekEnd)
687681
ASSERT_EQ(0u, cipher.m_finalizeDecryptionCalledCount);
688682
}
689683

690-
#ifndef ENABLE_COMMONCRYPTO_ENCRYPTION
691684
TEST(CryptoStreamsTest, TestLiveSymmetricCipher)
692685
{
693686
Aws::String iv_raw = "92f258071d79af3e63672285";
@@ -725,6 +718,5 @@ TEST(CryptoStreamsTest, TestLiveSymmetricCipher)
725718
ASSERT_STREQ(data_raw.c_str(), plainTextOutput.c_str());
726719
}
727720
}
728-
#endif
729721

730722
#endif // NO_SYMMETRIC_ENCRYPTION

aws-cpp-sdk-core-tests/utils/crypto/SymmetricCiphersTest.cpp

+78-33
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#include <aws/core/utils/StringUtils.h>
2323
#include <aws/core/utils/memory/stl/AWSStringStream.h>
2424
#include <aws/core/utils/crypto/CryptoStream.h>
25+
#ifdef ENABLE_COMMONCRYPTO_ENCRYPTION
26+
#include <aws/core/utils/crypto/commoncrypto/CryptoImpl.h>
27+
#endif
2528

2629
using namespace Aws::Utils;
2730
using namespace Aws::Utils::Crypto;
@@ -38,13 +41,11 @@ static void TestCTRSingleBlockBuffers(const Aws::String& iv_raw, const Aws::Stri
3841
static void TestCTRMultipleBlockBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
3942
const Aws::String& data_raw, const Aws::String& expected_raw);
4043

41-
#ifndef ENABLE_COMMONCRYPTO_ENCRYPTION
42-
static void TestGCMBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
43-
const Aws::String& data_raw, const Aws::String& expected_raw, const Aws::String& tag_raw);
44+
static void TestGCMBuffers(const Aws::String& iv_raw, const Aws::String& key_raw, const Aws::String& data_raw,
45+
const Aws::String& expected_raw, const Aws::String& tag_raw, const Aws::String& aad_raw);
4446

45-
static void TestGCMMultipleBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
46-
const Aws::String& data_raw, const Aws::String& expected_raw, const Aws::String& tag_raw);
47-
#endif
47+
static void TestGCMMultipleBuffers(const Aws::String& iv_raw, const Aws::String& key_raw, const Aws::String& data_raw,
48+
const Aws::String& expected_raw, const Aws::String& tag_raw, const Aws::String& aad_raw);
4849

4950
TEST(AES_CBC_TEST, LessThanOneBlockTest)
5051
{
@@ -199,8 +200,6 @@ TEST(AES_CTR_TEST, RFC3686_Case_9)
199200
TestCTRMultipleBlockBuffers(iv_raw, key_raw, data_raw, expected_raw);
200201
}
201202

202-
#ifndef ENABLE_COMMONCRYPTO_ENCRYPTION
203-
204203
TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_128_Test_0)
205204
{
206205
Aws::String iv_raw = "0d18e06c7c725ac9e362e1ce";
@@ -209,11 +208,9 @@ TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_128_Test_0)
209208
Aws::String expected_raw = "fa4362189661d163fcd6a56d8bf0405a";
210209
Aws::String tag_raw = "d636ac1bbedd5cc3ee727dc2ab4a9489";
211210

212-
TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw);
211+
TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
213212
}
214213

215-
#endif
216-
217214
TEST(AES_CTR_TEST, Test_Generated_KEY_AND_IV)
218215
{
219216
CryptoBuffer key = SymmetricCipher::GenerateKey();
@@ -248,8 +245,6 @@ TEST(AES_CTR_TEST, Test_Generated_KEY_AND_IV)
248245
ASSERT_STREQ(data_raw.c_str(), (const char*)plainText.GetUnderlyingData());
249246
}
250247

251-
#ifndef ENABLE_COMMONCRYPTO_ENCRYPTION
252-
253248
TEST(AES_GCM_TEST, TestBadTagCausesFailure)
254249
{
255250
Aws::String iv_raw = "4742357c335913153ff0eb0f";
@@ -278,7 +273,9 @@ TEST(AES_GCM_TEST, TestBadTagCausesFailure)
278273
auto decryptResult = cipher->DecryptBuffer(encryptedResult);
279274
auto finalDecryptBuffer = cipher->FinalizeDecryption();
280275
ASSERT_EQ(0u, finalDecryptBuffer.GetLength());
276+
#if !defined(ENABLE_COMMONCRYPTO_ENCRYPTION) || defined(MAC_14_4_AVAILABLE)
281277
ASSERT_FALSE(*cipher);
278+
#endif
282279
}
283280

284281
TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_104_Test_3)
@@ -289,7 +286,7 @@ TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_104_Test_3)
289286
Aws::String expected_raw = "eb8e6175f1fe38eb1acf95fd51";
290287
Aws::String tag_raw = "88a8b74bb74fda553e91020a23deed45";
291288

292-
TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw);
289+
TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
293290
}
294291

295292
TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_256_Test_6)
@@ -300,8 +297,8 @@ TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_256_Test_6)
300297
Aws::String expected_raw = "44dc868006b21d49284016565ffb3979cc4271d967628bf7cdaf86db888e92e5";
301298
Aws::String tag_raw = "01a2b578aa2f41ec6379a44a31cc019c";
302299

303-
TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw);
304-
TestGCMMultipleBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw);
300+
TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
301+
TestGCMMultipleBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
305302
}
306303

307304
TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_408_Test_8)
@@ -312,8 +309,43 @@ TEST(AES_GCM_TEST, NIST_gcmEncryptExtIV256_PTLen_408_Test_8)
312309
Aws::String expected_raw = "bbca4a9e09ae9690c0f6f8d405e53dccd666aa9c5fa13c8758bc30abe1ddd1bcce0d36a1eaaaaffef20cd3c5970b9673f8a65c";
313310
Aws::String tag_raw = "26ccecb9976fd6ac9c2c0f372c52c821";
314311

315-
TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw);
316-
TestGCMMultipleBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw);
312+
TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
313+
TestGCMMultipleBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, "");
314+
}
315+
316+
TEST(AES_GCM_TEST, AES_GCM_256_KAT_1)
317+
{
318+
Aws::String iv_raw = "FB7B4A824E82DAA6C8BC1251";
319+
Aws::String key_raw = "20142E898CD2FD980FBF34DE6BC85C14DA7D57BD28F4AA5CF1728AB64E843142";
320+
Aws::String data_raw= "";
321+
Aws::String expected_raw = "";
322+
Aws::String aad_raw = "167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D";
323+
Aws::String tag_raw = "81C0E42BB195E262CB3B3A74A0DAE1C8";
324+
TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, aad_raw);
325+
}
326+
327+
TEST(AES_GCM_TEST, AES_GCM_256_KAT_2)
328+
{
329+
Aws::String iv_raw = "6B5CD3705A733C1AD943D58A";
330+
Aws::String key_raw = "D211F278A44EAB666B1021F4B4F60BA6B74464FA9CB7B134934D7891E1479169";
331+
Aws::String data_raw= "167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D";
332+
Aws::String expected_raw = "4C25ABD66D3A1BCCE794ACAAF4CEFDF6D2552F4A82C50A98CB15B4812FF557ABE564A9CEFF15F32DCF5A5AA7894888";
333+
Aws::String aad_raw = "167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D";
334+
Aws::String tag_raw = "03EDE71EC952E65AE7B4B85CFEC7D304";
335+
TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, aad_raw);
336+
TestGCMMultipleBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, aad_raw);
337+
}
338+
339+
TEST(AES_GCM_TEST, AES_GCM_256_KAT_3)
340+
{
341+
Aws::String iv_raw = "5F08EFBFB7BF5BA365D9EB1D";
342+
Aws::String key_raw = "CFE8BFE61B89AF53D2BECE744D27B78C9E4D74D028CE88ED10A422285B1201C9";
343+
Aws::String data_raw= "167B5C226177733A782D616D7A2D63656B2D616C675C223A205C224145532F47434D2F4E6F50616464696E675C227D";
344+
Aws::String expected_raw = "0A7E82F1E5C76C69679671EEAEE455936F2C4FCCD9DDF1FAA27075E2040644938920C5D16C69E4D93375487B9A80D4";
345+
Aws::String aad_raw = "";
346+
Aws::String tag_raw = "04347D0C5B0E0DE89E033D04D0493DCA";
347+
TestGCMBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, aad_raw);
348+
TestGCMMultipleBuffers(iv_raw, key_raw, data_raw, expected_raw, tag_raw, aad_raw);
317349
}
318350

319351
TEST(AES_GCM_TEST, Test_Generated_IV)
@@ -345,8 +377,6 @@ TEST(AES_GCM_TEST, Test_Generated_IV)
345377
ASSERT_STREQ(data_raw.c_str(), (const char*)plainText.GetUnderlyingData());
346378
}
347379

348-
#endif
349-
350380
TEST(AES_KeyWrap_Test, RFC3394_256BitKey256CekTestVector)
351381
{
352382
Aws::String expected_cipher_text = "28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21";
@@ -609,18 +639,17 @@ static void TestCTRSingleBlockBuffers(const Aws::String& iv_raw, const Aws::Stri
609639
ASSERT_EQ(data, plainText);
610640
}
611641

612-
#ifndef ENABLE_COMMONCRYPTO_ENCRYPTION
613-
614-
static void TestGCMBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
615-
const Aws::String& data_raw, const Aws::String& expected_raw, const Aws::String& tag_raw)
642+
static void TestGCMBuffers(const Aws::String& iv_raw, const Aws::String& key_raw, const Aws::String& data_raw,
643+
const Aws::String& expected_raw, const Aws::String& tag_raw, const Aws::String& aad_raw)
616644
{
617645
CryptoBuffer iv = HashingUtils::HexDecode(iv_raw);
618646
CryptoBuffer key = HashingUtils::HexDecode(key_raw);
619-
CryptoBuffer data = HashingUtils::HexDecode(data_raw);
620-
CryptoBuffer expected = HashingUtils::HexDecode(expected_raw);
647+
CryptoBuffer data = data_raw.empty() ? CryptoBuffer(0) : HashingUtils::HexDecode(data_raw);
648+
CryptoBuffer expected = expected_raw.empty() ? CryptoBuffer(0) : HashingUtils::HexDecode(expected_raw);
621649
CryptoBuffer tag = HashingUtils::HexDecode(tag_raw);
650+
CryptoBuffer aad = aad_raw.empty() ? CryptoBuffer(0) : HashingUtils::HexDecode(aad_raw);
622651

623-
auto cipher = CreateAES_GCMImplementation(key, iv);
652+
auto cipher = CreateAES_GCMImplementation(key, iv, CryptoBuffer(0), aad);
624653
ASSERT_NE(cipher, nullptr);
625654
auto encryptResult = cipher->EncryptBuffer(data);
626655
auto finalEncryptedBuffer = cipher->FinalizeEncryption();
@@ -633,6 +662,7 @@ static void TestGCMBuffers(const Aws::String& iv_raw, const Aws::String& key_raw
633662

634663
cipher->Reset();
635664
auto decryptResult = cipher->DecryptBuffer(encryptedResult);
665+
ASSERT_TRUE(*cipher);
636666
auto finalDecryptBuffer = cipher->FinalizeDecryption();
637667
ASSERT_TRUE(*cipher);
638668

@@ -642,18 +672,36 @@ static void TestGCMBuffers(const Aws::String& iv_raw, const Aws::String& key_raw
642672
memcpy(plainText.GetUnderlyingData(), completeDecryptedMessage.GetUnderlyingData(), completeDecryptedMessage.GetLength());
643673

644674
ASSERT_EQ(data, plainText);
675+
676+
// Test modified AAD will lead to wrong decryption.
677+
#if !defined(ENABLE_COMMONCRYPTO_ENCRYPTION) || defined(MAC_14_4_AVAILABLE)
678+
if (aad.GetLength())
679+
{
680+
/**
681+
* Note that CommonCrypto on Mac tests AAD at finalizeDecryption stage,
682+
* While Openssl tests AAD at begining of Decryption (additional Decryption call) stage.
683+
* For BCrypto on Windows, testing of AAD is inside Decryption stage.
684+
* So we can only assert false of cipher after finalize.
685+
*/
686+
auto cipherDe = CreateAES_GCMImplementation(key, iv, cipher->GetTag(), CryptoBuffer());
687+
decryptResult = cipherDe->DecryptBuffer(encryptedResult);
688+
finalDecryptBuffer = cipherDe->FinalizeDecryption();
689+
ASSERT_FALSE(*cipherDe);
690+
}
691+
#endif
645692
}
646693

647-
static void TestGCMMultipleBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
648-
const Aws::String& data_raw, const Aws::String& expected_raw, const Aws::String& tag_raw)
694+
static void TestGCMMultipleBuffers(const Aws::String& iv_raw, const Aws::String& key_raw, const Aws::String& data_raw,
695+
const Aws::String& expected_raw, const Aws::String& tag_raw, const Aws::String& aad_raw)
649696
{
650697
CryptoBuffer iv = HashingUtils::HexDecode(iv_raw);
651698
CryptoBuffer key = HashingUtils::HexDecode(key_raw);
652699
CryptoBuffer data = HashingUtils::HexDecode(data_raw);
653700
CryptoBuffer expected = HashingUtils::HexDecode(expected_raw);
654701
CryptoBuffer tag = HashingUtils::HexDecode(tag_raw);
702+
CryptoBuffer aad = aad_raw.empty() ? CryptoBuffer(0) : HashingUtils::HexDecode(aad_raw);
655703

656-
auto cipher = CreateAES_GCMImplementation(key, iv);
704+
auto cipher = CreateAES_GCMImplementation(key, iv, CryptoBuffer(0), aad);
657705
ASSERT_NE(cipher, nullptr);
658706
//slice on a weird boundary just to force boundary conditions
659707
auto slices = data.Slice(24);
@@ -716,8 +764,6 @@ static void TestGCMMultipleBuffers(const Aws::String& iv_raw, const Aws::String&
716764
ASSERT_EQ(data, plainText);
717765
}
718766

719-
#endif
720-
721767
static void TestCBCMultipleBlockBuffers(const Aws::String& iv_raw, const Aws::String& key_raw,
722768
const Aws::String& data_raw, const Aws::String& expected_raw)
723769
{
@@ -859,4 +905,3 @@ static void TestCTRMultipleBlockBuffers(const Aws::String& iv_raw, const Aws::St
859905
}
860906

861907
#endif // NO_SYMMETRIC_ENCRYPTION
862-

aws-cpp-sdk-core/include/aws/core/Aws.h

-1
Original file line numberDiff line numberDiff line change
@@ -270,4 +270,3 @@ namespace Aws
270270
*/
271271
AWS_CORE_API void ShutdownAPI(const SDKOptions& options);
272272
}
273-

aws-cpp-sdk-core/include/aws/core/Core_EXPORTS.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@
9696

9797
// Due to MSVC can't recognize base class deprecated function in derived class.
9898
// We need AWS_DISABLE_DEPRECATION to make AWS_DEPRECATED useless only on MSVC
99-
#if defined(AWS_DISABLE_DEPRECATION) && defined(_MSC_VER)
99+
// Update: When deprecating a function/components, we won't remove the existing tests
100+
// immediately, so we need AWS_DISABLE_DEPRECATION as well.
101+
#if defined(AWS_DISABLE_DEPRECATION)
100102
#define AWS_DEPRECATED(msg)
101103
#elif defined (__cplusplus) && __cplusplus > 201103L // standard attributes are available since C++14
102104
#define AWS_DEPRECATED(msg) [[deprecated(msg)]]
@@ -109,4 +111,3 @@
109111
#define AWS_DEPRECATED(msg)
110112
#endif
111113
#endif
112-

0 commit comments

Comments
 (0)