1 /**
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  * SPDX-License-Identifier: Apache-2.0.
4  */
5 
6 
7 #include <aws/core/utils/crypto/Factories.h>
8 #include <aws/core/utils/crypto/Hash.h>
9 #include <aws/core/utils/crypto/HMAC.h>
10 
11 #if ENABLE_BCRYPT_ENCRYPTION
12     #include <aws/core/utils/crypto/bcrypt/CryptoImpl.h>
13 #elif ENABLE_OPENSSL_ENCRYPTION
14     #include <aws/core/utils/crypto/openssl/CryptoImpl.h>
15 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
16     #include <aws/core/utils/crypto/commoncrypto/CryptoImpl.h>
17     #include <aws/core/utils/logging/LogMacros.h>
18 #else
19     // if you don't have any encryption you still need to pull in the interface definitions
20     #include <aws/core/utils/crypto/Hash.h>
21     #include <aws/core/utils/crypto/HMAC.h>
22     #include <aws/core/utils/crypto/Cipher.h>
23     #include <aws/core/utils/crypto/SecureRandom.h>
24     #define NO_ENCRYPTION
25 #endif
26 
27 using namespace Aws::Utils;
28 using namespace Aws::Utils::Crypto;
29 
30 static const char *s_allocationTag = "CryptoFactory";
31 
GetMD5Factory()32 static std::shared_ptr<HashFactory>& GetMD5Factory()
33 {
34     static std::shared_ptr<HashFactory> s_MD5Factory(nullptr);
35     return s_MD5Factory;
36 }
37 
GetSha1Factory()38 static std::shared_ptr<HashFactory>& GetSha1Factory()
39 {
40     static std::shared_ptr<HashFactory> s_Sha1Factory(nullptr);
41     return s_Sha1Factory;
42 }
43 
GetSha256Factory()44 static std::shared_ptr<HashFactory>& GetSha256Factory()
45 {
46     static std::shared_ptr<HashFactory> s_Sha256Factory(nullptr);
47     return s_Sha256Factory;
48 }
49 
GetSha256HMACFactory()50 static std::shared_ptr<HMACFactory>& GetSha256HMACFactory()
51 {
52     static std::shared_ptr<HMACFactory> s_Sha256HMACFactory(nullptr);
53     return s_Sha256HMACFactory;
54 }
55 
GetAES_CBCFactory()56 static std::shared_ptr<SymmetricCipherFactory>& GetAES_CBCFactory()
57 {
58     static std::shared_ptr<SymmetricCipherFactory> s_AES_CBCFactory(nullptr);
59     return s_AES_CBCFactory;
60 }
61 
GetAES_CTRFactory()62 static std::shared_ptr<SymmetricCipherFactory>& GetAES_CTRFactory()
63 {
64     static std::shared_ptr<SymmetricCipherFactory> s_AES_CTRFactory(nullptr);
65     return s_AES_CTRFactory;
66 }
67 
GetAES_GCMFactory()68 static std::shared_ptr<SymmetricCipherFactory>& GetAES_GCMFactory()
69 {
70     static std::shared_ptr<SymmetricCipherFactory> s_AES_GCMFactory(nullptr);
71     return s_AES_GCMFactory;
72 }
73 
GetAES_KeyWrapFactory()74 static std::shared_ptr<SymmetricCipherFactory>& GetAES_KeyWrapFactory()
75 {
76     static std::shared_ptr<SymmetricCipherFactory> s_AES_KeyWrapFactory(nullptr);
77     return s_AES_KeyWrapFactory;
78 }
79 
GetSecureRandomFactory()80 static std::shared_ptr<SecureRandomFactory>& GetSecureRandomFactory()
81 {
82     static std::shared_ptr<SecureRandomFactory> s_SecureRandomFactory(nullptr);
83     return s_SecureRandomFactory;
84 }
85 
GetSecureRandom()86 static std::shared_ptr<SecureRandomBytes>& GetSecureRandom()
87 {
88     static std::shared_ptr<SecureRandomBytes> s_SecureRandom(nullptr);
89     return s_SecureRandom;
90 }
91 
92 static bool s_InitCleanupOpenSSLFlag(false);
93 
94 class DefaultMD5Factory : public HashFactory
95 {
96 public:
CreateImplementation() const97     std::shared_ptr<Hash> CreateImplementation() const override
98     {
99 #if ENABLE_BCRYPT_ENCRYPTION
100         return Aws::MakeShared<MD5BcryptImpl>(s_allocationTag);
101 #elif ENABLE_OPENSSL_ENCRYPTION
102         return Aws::MakeShared<MD5OpenSSLImpl>(s_allocationTag);
103 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
104         return Aws::MakeShared<MD5CommonCryptoImpl>(s_allocationTag);
105 #else
106     return nullptr;
107 #endif
108     }
109 
110     /**
111      * Opportunity to make any static initialization calls you need to make.
112      * Will only be called once.
113      */
InitStaticState()114     void InitStaticState() override
115     {
116 #if ENABLE_OPENSSL_ENCRYPTION
117         if(s_InitCleanupOpenSSLFlag)
118         {
119             OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
120         }
121 #endif
122     }
123 
124     /**
125      * Opportunity to make any static cleanup calls you need to make.
126      * will only be called at the end of the application.
127      */
CleanupStaticState()128     void CleanupStaticState() override
129     {
130 #if ENABLE_OPENSSL_ENCRYPTION
131         if(s_InitCleanupOpenSSLFlag)
132         {
133             OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
134         }
135 #endif
136     }
137 };
138 
139 class DefaultSHA1Factory : public HashFactory
140 {
141 public:
CreateImplementation() const142     std::shared_ptr<Hash> CreateImplementation() const override
143     {
144 #if ENABLE_BCRYPT_ENCRYPTION
145         return Aws::MakeShared<Sha1BcryptImpl>(s_allocationTag);
146 #elif ENABLE_OPENSSL_ENCRYPTION
147         return Aws::MakeShared<Sha1OpenSSLImpl>(s_allocationTag);
148 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
149         return Aws::MakeShared<Sha1CommonCryptoImpl>(s_allocationTag);
150 #else
151         return nullptr;
152 #endif
153     }
154 
155     /**
156      * Opportunity to make any static initialization calls you need to make.
157      * Will only be called once.
158      */
InitStaticState()159     void InitStaticState() override
160     {
161 #if ENABLE_OPENSSL_ENCRYPTION
162         if(s_InitCleanupOpenSSLFlag)
163         {
164             OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
165         }
166 #endif
167     }
168 
169     /**
170      * Opportunity to make any static cleanup calls you need to make.
171      * will only be called at the end of the application.
172      */
CleanupStaticState()173     void CleanupStaticState() override
174     {
175 #if ENABLE_OPENSSL_ENCRYPTION
176         if(s_InitCleanupOpenSSLFlag)
177         {
178             OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
179         }
180 #endif
181     }
182 };
183 
184 class DefaultSHA256Factory : public HashFactory
185 {
186 public:
CreateImplementation() const187     std::shared_ptr<Hash> CreateImplementation() const override
188     {
189 #if ENABLE_BCRYPT_ENCRYPTION
190         return Aws::MakeShared<Sha256BcryptImpl>(s_allocationTag);
191 #elif ENABLE_OPENSSL_ENCRYPTION
192         return Aws::MakeShared<Sha256OpenSSLImpl>(s_allocationTag);
193 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
194         return Aws::MakeShared<Sha256CommonCryptoImpl>(s_allocationTag);
195 #else
196     return nullptr;
197 #endif
198     }
199 
200     /**
201      * Opportunity to make any static initialization calls you need to make.
202      * Will only be called once.
203      */
InitStaticState()204     void InitStaticState() override
205     {
206 #if ENABLE_OPENSSL_ENCRYPTION
207         if(s_InitCleanupOpenSSLFlag)
208         {
209             OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
210         }
211 #endif
212     }
213 
214     /**
215      * Opportunity to make any static cleanup calls you need to make.
216      * will only be called at the end of the application.
217      */
CleanupStaticState()218     void CleanupStaticState() override
219     {
220 #if ENABLE_OPENSSL_ENCRYPTION
221         if(s_InitCleanupOpenSSLFlag)
222         {
223             OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
224         }
225 #endif
226     }
227 };
228 
229 class DefaultSHA256HmacFactory : public HMACFactory
230 {
231 public:
CreateImplementation() const232     std::shared_ptr<Aws::Utils::Crypto::HMAC> CreateImplementation() const override
233     {
234 #if ENABLE_BCRYPT_ENCRYPTION
235         return Aws::MakeShared<Sha256HMACBcryptImpl>(s_allocationTag);
236 #elif ENABLE_OPENSSL_ENCRYPTION
237         return Aws::MakeShared<Sha256HMACOpenSSLImpl>(s_allocationTag);
238 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
239         return Aws::MakeShared<Sha256HMACCommonCryptoImpl>(s_allocationTag);
240 #else
241     return nullptr;
242 #endif
243     }
244 
245     /**
246      * Opportunity to make any static initialization calls you need to make.
247      * Will only be called once.
248      */
InitStaticState()249     void InitStaticState() override
250     {
251 #if ENABLE_OPENSSL_ENCRYPTION
252         if(s_InitCleanupOpenSSLFlag)
253         {
254             OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
255         }
256 #endif
257     }
258 
259     /**
260      * Opportunity to make any static cleanup calls you need to make.
261      * will only be called at the end of the application.
262      */
CleanupStaticState()263     void CleanupStaticState() override
264     {
265 #if ENABLE_OPENSSL_ENCRYPTION
266         if(s_InitCleanupOpenSSLFlag)
267         {
268             OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
269         }
270 #endif
271     }
272 };
273 
274 
275 class DefaultAES_CBCFactory : public SymmetricCipherFactory
276 {
277 public:
CreateImplementation(const CryptoBuffer & key) const278     std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override
279     {
280 #if ENABLE_BCRYPT_ENCRYPTION
281         return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key);
282 #elif ENABLE_OPENSSL_ENCRYPTION
283         return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key);
284 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
285         return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key);
286 #else
287         AWS_UNREFERENCED_PARAM(key);
288         return nullptr;
289 #endif
290     }
291     /**
292      * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
293      */
CreateImplementation(const CryptoBuffer & key,const CryptoBuffer & iv,const CryptoBuffer &,const CryptoBuffer &) const294     std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer&, const CryptoBuffer&) const override
295     {
296 #if ENABLE_BCRYPT_ENCRYPTION
297         return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key, iv);
298 #elif ENABLE_OPENSSL_ENCRYPTION
299         return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key, iv);
300 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
301         return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key, iv);
302 #else
303         AWS_UNREFERENCED_PARAM(key);
304         AWS_UNREFERENCED_PARAM(iv);
305 
306         return nullptr;
307 #endif
308     }
309     /**
310      * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
311      */
CreateImplementation(CryptoBuffer && key,CryptoBuffer && iv,CryptoBuffer &&,CryptoBuffer &&) const312     std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&&, CryptoBuffer&&) const override
313     {
314 #if ENABLE_BCRYPT_ENCRYPTION
315         return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key, iv);
316 #elif ENABLE_OPENSSL_ENCRYPTION
317         return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key, iv);
318 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
319         return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key, iv);
320 #else
321         AWS_UNREFERENCED_PARAM(key);
322         AWS_UNREFERENCED_PARAM(iv);
323 
324         return nullptr;
325 #endif
326     }
327 
328     /**
329      * Opportunity to make any static initialization calls you need to make.
330      * Will only be called once.
331      */
InitStaticState()332     void InitStaticState() override
333     {
334 #if ENABLE_OPENSSL_ENCRYPTION
335         if(s_InitCleanupOpenSSLFlag)
336         {
337             OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
338         }
339 #endif
340     }
341 
342     /**
343      * Opportunity to make any static cleanup calls you need to make.
344      * will only be called at the end of the application.
345      */
CleanupStaticState()346     void CleanupStaticState() override
347     {
348 #if ENABLE_OPENSSL_ENCRYPTION
349         if(s_InitCleanupOpenSSLFlag)
350         {
351             OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
352         }
353 #endif
354     }
355 };
356 
357 class DefaultAES_CTRFactory : public SymmetricCipherFactory
358 {
359 public:
CreateImplementation(const CryptoBuffer & key) const360     std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override
361     {
362 #if ENABLE_BCRYPT_ENCRYPTION
363        return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key);
364 #elif ENABLE_OPENSSL_ENCRYPTION
365         return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key);
366 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
367         return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key);
368 #else
369         AWS_UNREFERENCED_PARAM(key);
370         return nullptr;
371 #endif
372     }
373     /**
374      * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
375      */
CreateImplementation(const CryptoBuffer & key,const CryptoBuffer & iv,const CryptoBuffer &,const CryptoBuffer &) const376     std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer&, const CryptoBuffer&) const override
377     {
378 #if ENABLE_BCRYPT_ENCRYPTION
379         return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key, iv);
380 #elif ENABLE_OPENSSL_ENCRYPTION
381         return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key, iv);
382 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
383         return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key, iv);
384 #else
385         AWS_UNREFERENCED_PARAM(key);
386         AWS_UNREFERENCED_PARAM(iv);
387 
388         return nullptr;
389 #endif
390     }
391     /**
392      * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
393      */
CreateImplementation(CryptoBuffer && key,CryptoBuffer && iv,CryptoBuffer &&,CryptoBuffer &&) const394     std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&&, CryptoBuffer&&) const override
395     {
396 #if ENABLE_BCRYPT_ENCRYPTION
397         return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key, iv);
398 #elif ENABLE_OPENSSL_ENCRYPTION
399         return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key, iv);
400 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
401         return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key, iv);
402 #else
403         AWS_UNREFERENCED_PARAM(key);
404         AWS_UNREFERENCED_PARAM(iv);
405 
406         return nullptr;
407 #endif
408     }
409 
410     /**
411      * Opportunity to make any static initialization calls you need to make.
412      * Will only be called once.
413      */
InitStaticState()414     void InitStaticState() override
415     {
416 #if ENABLE_OPENSSL_ENCRYPTION
417         if(s_InitCleanupOpenSSLFlag)
418         {
419             OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
420         }
421 #endif
422     }
423 
424     /**
425      * Opportunity to make any static cleanup calls you need to make.
426      * will only be called at the end of the application.
427      */
CleanupStaticState()428     void CleanupStaticState() override
429     {
430 #if ENABLE_OPENSSL_ENCRYPTION
431         if(s_InitCleanupOpenSSLFlag)
432         {
433             OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
434         }
435 #endif
436     }
437 };
438 
439 class DefaultAES_GCMFactory : public SymmetricCipherFactory
440 {
441 public:
CreateImplementation(const CryptoBuffer & key) const442     std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override
443     {
444 #if ENABLE_BCRYPT_ENCRYPTION
445         return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, key);
446 #elif ENABLE_OPENSSL_ENCRYPTION
447         return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, key);
448 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
449         return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, key);
450 #else
451         AWS_UNREFERENCED_PARAM(key);
452 
453         return nullptr;
454 #endif
455     }
456 
CreateImplementation(const CryptoBuffer & key,const CryptoBuffer * aad) const457     std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer* aad) const override
458     {
459 #if ENABLE_BCRYPT_ENCRYPTION
460         return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, key, aad);
461 #elif ENABLE_OPENSSL_ENCRYPTION
462         return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, key, aad);
463 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
464         return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, key, aad);
465 #else
466         AWS_UNREFERENCED_PARAM(key);
467         AWS_UNREFERENCED_PARAM(aad);
468         return nullptr;
469 #endif
470     }
471 
472     /**
473      * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
474      */
CreateImplementation(const CryptoBuffer & key,const CryptoBuffer & iv,const CryptoBuffer & tag,const CryptoBuffer & aad) const475     std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer& tag, const CryptoBuffer& aad) const override
476     {
477 #if ENABLE_BCRYPT_ENCRYPTION
478         return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, key, iv, tag, aad);
479 #elif ENABLE_OPENSSL_ENCRYPTION
480         return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, key, iv, tag, aad);
481 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
482         return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, key, iv, tag, aad);
483 #else
484         AWS_UNREFERENCED_PARAM(key);
485         AWS_UNREFERENCED_PARAM(iv);
486         AWS_UNREFERENCED_PARAM(tag);
487         AWS_UNREFERENCED_PARAM(aad);
488         return nullptr;
489 #endif
490     }
491     /**
492      * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
493      */
CreateImplementation(CryptoBuffer && key,CryptoBuffer && iv,CryptoBuffer && tag,CryptoBuffer && aad) const494     std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&& tag, CryptoBuffer&& aad) const override
495     {
496 #if ENABLE_BCRYPT_ENCRYPTION
497         return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, std::move(key), std::move(iv), std::move(tag), std::move(aad));
498 #elif ENABLE_OPENSSL_ENCRYPTION
499         return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, std::move(key), std::move(iv), std::move(tag), std::move(aad));
500 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
501         return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, std::move(key), std::move(iv), std::move(tag), std::move(aad));
502 #else
503         AWS_UNREFERENCED_PARAM(key);
504         AWS_UNREFERENCED_PARAM(iv);
505         AWS_UNREFERENCED_PARAM(tag);
506         AWS_UNREFERENCED_PARAM(aad);
507         return nullptr;
508 #endif
509     }
510 
511     /**
512      * Opportunity to make any static initialization calls you need to make.
513      * Will only be called once.
514      */
InitStaticState()515     void InitStaticState() override
516     {
517 #if ENABLE_OPENSSL_ENCRYPTION
518         if(s_InitCleanupOpenSSLFlag)
519         {
520             OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
521         }
522 #endif
523     }
524 
525     /**
526      * Opportunity to make any static cleanup calls you need to make.
527      * will only be called at the end of the application.
528      */
CleanupStaticState()529     void CleanupStaticState() override
530     {
531 #if ENABLE_OPENSSL_ENCRYPTION
532         if(s_InitCleanupOpenSSLFlag)
533         {
534             OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
535         }
536 #endif
537     }
538 };
539 
540 class DefaultAES_KeyWrapFactory : public SymmetricCipherFactory
541 {
542 public:
CreateImplementation(const CryptoBuffer & key) const543     std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override
544     {
545 #if ENABLE_BCRYPT_ENCRYPTION
546         return Aws::MakeShared<AES_KeyWrap_Cipher_BCrypt>(s_allocationTag, key);
547 #elif ENABLE_OPENSSL_ENCRYPTION
548         return Aws::MakeShared<AES_KeyWrap_Cipher_OpenSSL>(s_allocationTag, key);
549 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
550         return Aws::MakeShared<AES_KeyWrap_Cipher_CommonCrypto>(s_allocationTag, key);
551 #else
552         AWS_UNREFERENCED_PARAM(key);
553         return nullptr;
554 #endif
555     }
556     /**
557     * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
558     */
CreateImplementation(const CryptoBuffer & key,const CryptoBuffer & iv,const CryptoBuffer & tag,const CryptoBuffer &) const559     std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer& tag, const CryptoBuffer&) const override
560     {
561         AWS_UNREFERENCED_PARAM(key);
562         AWS_UNREFERENCED_PARAM(iv);
563         AWS_UNREFERENCED_PARAM(tag);
564         return nullptr;
565     }
566     /**
567     * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
568     */
CreateImplementation(CryptoBuffer && key,CryptoBuffer && iv,CryptoBuffer && tag,CryptoBuffer &&) const569     std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&& tag, CryptoBuffer&&) const override
570     {
571         AWS_UNREFERENCED_PARAM(key);
572         AWS_UNREFERENCED_PARAM(iv);
573         AWS_UNREFERENCED_PARAM(tag);
574         return nullptr;
575     }
576 
577     /**
578     * Opportunity to make any static initialization calls you need to make.
579     * Will only be called once.
580     */
InitStaticState()581     void InitStaticState() override
582     {
583 #if ENABLE_OPENSSL_ENCRYPTION
584         if (s_InitCleanupOpenSSLFlag)
585         {
586             OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
587         }
588 #endif
589     }
590 
591     /**
592     * Opportunity to make any static cleanup calls you need to make.
593     * will only be called at the end of the application.
594     */
CleanupStaticState()595     void CleanupStaticState() override
596     {
597 #if ENABLE_OPENSSL_ENCRYPTION
598         if (s_InitCleanupOpenSSLFlag)
599         {
600             OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
601         }
602 #endif
603     }
604 };
605 
606 class DefaultSecureRandFactory : public SecureRandomFactory
607 {
608     /**
609      * Factory method. Returns SecureRandom implementation.
610      */
CreateImplementation() const611     std::shared_ptr<SecureRandomBytes> CreateImplementation() const override
612     {
613 #if ENABLE_BCRYPT_ENCRYPTION
614         return Aws::MakeShared<SecureRandomBytes_BCrypt>(s_allocationTag);
615 #elif ENABLE_OPENSSL_ENCRYPTION
616         return Aws::MakeShared<SecureRandomBytes_OpenSSLImpl>(s_allocationTag);
617 #elif ENABLE_COMMONCRYPTO_ENCRYPTION
618         return Aws::MakeShared<SecureRandomBytes_CommonCrypto>(s_allocationTag);
619 #else
620         return nullptr;
621 #endif
622     }
623 
624     /**
625  * Opportunity to make any static initialization calls you need to make.
626  * Will only be called once.
627  */
InitStaticState()628     void InitStaticState() override
629     {
630 #if ENABLE_OPENSSL_ENCRYPTION
631         if(s_InitCleanupOpenSSLFlag)
632         {
633             OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
634         }
635 #endif
636     }
637 
638     /**
639      * Opportunity to make any static cleanup calls you need to make.
640      * will only be called at the end of the application.
641      */
CleanupStaticState()642     void CleanupStaticState() override
643     {
644 #if ENABLE_OPENSSL_ENCRYPTION
645         if(s_InitCleanupOpenSSLFlag)
646         {
647             OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
648         }
649 #endif
650     }
651 };
652 
SetInitCleanupOpenSSLFlag(bool initCleanupFlag)653 void Aws::Utils::Crypto::SetInitCleanupOpenSSLFlag(bool initCleanupFlag)
654 {
655     s_InitCleanupOpenSSLFlag = initCleanupFlag;
656 }
657 
InitCrypto()658 void Aws::Utils::Crypto::InitCrypto()
659 {
660     if(GetMD5Factory())
661     {
662         GetMD5Factory()->InitStaticState();
663     }
664     else
665     {
666         GetMD5Factory() = Aws::MakeShared<DefaultMD5Factory>(s_allocationTag);
667         GetMD5Factory()->InitStaticState();
668     }
669 
670     if(GetSha1Factory())
671     {
672         GetSha1Factory()->InitStaticState();
673     }
674     else
675     {
676         GetSha1Factory() = Aws::MakeShared<DefaultSHA1Factory>(s_allocationTag);
677         GetSha1Factory()->InitStaticState();
678     }
679 
680     if(GetSha256Factory())
681     {
682         GetSha256Factory()->InitStaticState();
683     }
684     else
685     {
686         GetSha256Factory() = Aws::MakeShared<DefaultSHA256Factory>(s_allocationTag);
687         GetSha256Factory()->InitStaticState();
688     }
689 
690     if(GetSha256HMACFactory())
691     {
692         GetSha256HMACFactory()->InitStaticState();
693     }
694     else
695     {
696         GetSha256HMACFactory() = Aws::MakeShared<DefaultSHA256HmacFactory>(s_allocationTag);
697         GetSha256HMACFactory()->InitStaticState();
698     }
699 
700     if(GetAES_CBCFactory())
701     {
702         GetAES_CBCFactory()->InitStaticState();
703     }
704     else
705     {
706         GetAES_CBCFactory() = Aws::MakeShared<DefaultAES_CBCFactory>(s_allocationTag);
707         GetAES_CBCFactory()->InitStaticState();
708     }
709 
710     if(GetAES_CTRFactory())
711     {
712         GetAES_CTRFactory()->InitStaticState();
713     }
714     else
715     {
716         GetAES_CTRFactory() = Aws::MakeShared<DefaultAES_CTRFactory>(s_allocationTag);
717         GetAES_CTRFactory()->InitStaticState();
718     }
719 
720     if(GetAES_GCMFactory())
721     {
722         GetAES_GCMFactory()->InitStaticState();
723     }
724     else
725     {
726         GetAES_GCMFactory() = Aws::MakeShared<DefaultAES_GCMFactory>(s_allocationTag);
727         GetAES_GCMFactory()->InitStaticState();
728     }
729 
730     if (!GetAES_KeyWrapFactory())
731     {
732         GetAES_KeyWrapFactory() = Aws::MakeShared<DefaultAES_KeyWrapFactory>(s_allocationTag);
733     }
734     GetAES_KeyWrapFactory()->InitStaticState();
735 
736     if(GetSecureRandomFactory())
737     {
738         GetSecureRandomFactory()->InitStaticState();
739     }
740     else
741     {
742         GetSecureRandomFactory() = Aws::MakeShared<DefaultSecureRandFactory>(s_allocationTag);
743         GetSecureRandomFactory()->InitStaticState();
744     }
745 
746     GetSecureRandom() = GetSecureRandomFactory()->CreateImplementation();
747 }
748 
CleanupCrypto()749 void Aws::Utils::Crypto::CleanupCrypto()
750 {
751     if(GetMD5Factory())
752     {
753         GetMD5Factory()->CleanupStaticState();
754         GetMD5Factory() = nullptr;
755     }
756 
757     if(GetSha1Factory())
758     {
759         GetSha1Factory()->CleanupStaticState();
760         GetSha1Factory() = nullptr;
761     }
762 
763     if(GetSha256Factory())
764     {
765         GetSha256Factory()->CleanupStaticState();
766         GetSha256Factory() = nullptr;
767     }
768 
769     if(GetSha256HMACFactory())
770     {
771         GetSha256HMACFactory()->CleanupStaticState();
772         GetSha256HMACFactory() =  nullptr;
773     }
774 
775     if(GetAES_CBCFactory())
776     {
777         GetAES_CBCFactory()->CleanupStaticState();
778         GetAES_CBCFactory() = nullptr;
779     }
780 
781     if(GetAES_CTRFactory())
782     {
783         GetAES_CTRFactory()->CleanupStaticState();
784         GetAES_CTRFactory() = nullptr;
785     }
786 
787     if(GetAES_GCMFactory())
788     {
789         GetAES_GCMFactory()->CleanupStaticState();
790         GetAES_GCMFactory() = nullptr;
791     }
792 
793     if(GetAES_KeyWrapFactory())
794     {
795         GetAES_KeyWrapFactory()->CleanupStaticState();
796         GetAES_KeyWrapFactory() = nullptr;
797     }
798 
799     if(GetSecureRandomFactory())
800     {
801         GetSecureRandom() = nullptr;
802         GetSecureRandomFactory()->CleanupStaticState();
803         GetSecureRandomFactory() = nullptr;
804     }
805 }
806 
SetMD5Factory(const std::shared_ptr<HashFactory> & factory)807 void Aws::Utils::Crypto::SetMD5Factory(const std::shared_ptr<HashFactory>& factory)
808 {
809     GetMD5Factory() = factory;
810 }
811 
SetSha1Factory(const std::shared_ptr<HashFactory> & factory)812 void Aws::Utils::Crypto::SetSha1Factory(const std::shared_ptr<HashFactory>& factory)
813 {
814     GetSha1Factory() = factory;
815 }
816 
SetSha256Factory(const std::shared_ptr<HashFactory> & factory)817 void Aws::Utils::Crypto::SetSha256Factory(const std::shared_ptr<HashFactory>& factory)
818 {
819     GetSha256Factory() = factory;
820 }
821 
SetSha256HMACFactory(const std::shared_ptr<HMACFactory> & factory)822 void Aws::Utils::Crypto::SetSha256HMACFactory(const std::shared_ptr<HMACFactory>& factory)
823 {
824     GetSha256HMACFactory() = factory;
825 }
826 
SetAES_CBCFactory(const std::shared_ptr<SymmetricCipherFactory> & factory)827 void Aws::Utils::Crypto::SetAES_CBCFactory(const std::shared_ptr<SymmetricCipherFactory>& factory)
828 {
829     GetAES_CBCFactory() = factory;
830 }
831 
SetAES_CTRFactory(const std::shared_ptr<SymmetricCipherFactory> & factory)832 void Aws::Utils::Crypto::SetAES_CTRFactory(const std::shared_ptr<SymmetricCipherFactory>& factory)
833 {
834     GetAES_CTRFactory() = factory;
835 }
836 
SetAES_GCMFactory(const std::shared_ptr<SymmetricCipherFactory> & factory)837 void Aws::Utils::Crypto::SetAES_GCMFactory(const std::shared_ptr<SymmetricCipherFactory>& factory)
838 {
839     GetAES_GCMFactory() = factory;
840 }
841 
SetAES_KeyWrapFactory(const std::shared_ptr<SymmetricCipherFactory> & factory)842 void Aws::Utils::Crypto::SetAES_KeyWrapFactory(const std::shared_ptr<SymmetricCipherFactory>& factory)
843 {
844     GetAES_KeyWrapFactory() = factory;
845 }
846 
SetSecureRandomFactory(const std::shared_ptr<SecureRandomFactory> & factory)847 void Aws::Utils::Crypto::SetSecureRandomFactory(const std::shared_ptr<SecureRandomFactory>& factory)
848 {
849     GetSecureRandomFactory() = factory;
850 }
851 
CreateMD5Implementation()852 std::shared_ptr<Hash> Aws::Utils::Crypto::CreateMD5Implementation()
853 {
854     return GetMD5Factory()->CreateImplementation();
855 }
856 
CreateSha1Implementation()857 std::shared_ptr<Hash> Aws::Utils::Crypto::CreateSha1Implementation()
858 {
859     return GetSha1Factory()->CreateImplementation();
860 }
861 
CreateSha256Implementation()862 std::shared_ptr<Hash> Aws::Utils::Crypto::CreateSha256Implementation() {
863     return GetSha256Factory()->CreateImplementation();
864 }
865 
CreateSha256HMACImplementation()866 std::shared_ptr<Aws::Utils::Crypto::HMAC> Aws::Utils::Crypto::CreateSha256HMACImplementation()
867 {
868     return GetSha256HMACFactory()->CreateImplementation();
869 }
870 
871 #ifdef _WIN32
872 #pragma warning( push )
873 #pragma warning( disable : 4702 )
874 #endif
875 
CreateAES_CBCImplementation(const CryptoBuffer & key)876 std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(const CryptoBuffer& key)
877 {
878 #ifdef NO_SYMMETRIC_ENCRYPTION
879     return nullptr;
880 #endif
881     return GetAES_CBCFactory()->CreateImplementation(key);
882 }
883 
CreateAES_CBCImplementation(const CryptoBuffer & key,const CryptoBuffer & iv)884 std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(const CryptoBuffer& key, const CryptoBuffer& iv)
885 {
886 #ifdef NO_SYMMETRIC_ENCRYPTION
887     return nullptr;
888 #endif
889     return GetAES_CBCFactory()->CreateImplementation(key, iv);
890 }
891 
CreateAES_CBCImplementation(CryptoBuffer && key,CryptoBuffer && iv)892 std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(CryptoBuffer&& key, CryptoBuffer&& iv)
893 {
894 #ifdef NO_SYMMETRIC_ENCRYPTION
895     return nullptr;
896 #endif
897     return GetAES_CBCFactory()->CreateImplementation(std::move(key), std::move(iv));
898 }
899 
CreateAES_CTRImplementation(const CryptoBuffer & key)900 std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(const CryptoBuffer& key)
901 {
902 #ifdef NO_SYMMETRIC_ENCRYPTION
903     return nullptr;
904 #endif
905     return GetAES_CTRFactory()->CreateImplementation(key);
906 }
907 
CreateAES_CTRImplementation(const CryptoBuffer & key,const CryptoBuffer & iv)908 std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(const CryptoBuffer& key, const CryptoBuffer& iv)
909 {
910 #ifdef NO_SYMMETRIC_ENCRYPTION
911     return nullptr;
912 #endif
913     return GetAES_CTRFactory()->CreateImplementation(key, iv);
914 }
915 
CreateAES_CTRImplementation(CryptoBuffer && key,CryptoBuffer && iv)916 std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(CryptoBuffer&& key, CryptoBuffer&& iv)
917 {
918 #ifdef NO_SYMMETRIC_ENCRYPTION
919     return nullptr;
920 #endif
921     return GetAES_CTRFactory()->CreateImplementation(std::move(key), std::move(iv));
922 }
923 
CreateAES_GCMImplementation(const CryptoBuffer & key)924 std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(const CryptoBuffer& key)
925 {
926 #ifdef NO_SYMMETRIC_ENCRYPTION
927     return nullptr;
928 #endif
929     return GetAES_GCMFactory()->CreateImplementation(key);
930 }
931 
CreateAES_GCMImplementation(const CryptoBuffer & key,const CryptoBuffer * aad)932 std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(const CryptoBuffer& key, const CryptoBuffer* aad)
933 {
934 #ifdef NO_SYMMETRIC_ENCRYPTION
935     return nullptr;
936 #endif
937     return GetAES_GCMFactory()->CreateImplementation(key, aad);
938 }
939 
CreateAES_GCMImplementation(const CryptoBuffer & key,const CryptoBuffer & iv,const CryptoBuffer & tag,const CryptoBuffer & aad)940 std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer& tag, const CryptoBuffer& aad)
941 {
942 #ifdef NO_SYMMETRIC_ENCRYPTION
943     return nullptr;
944 #endif
945     return GetAES_GCMFactory()->CreateImplementation(key, iv, tag, aad);
946 }
947 
CreateAES_GCMImplementation(CryptoBuffer && key,CryptoBuffer && iv,CryptoBuffer && tag,CryptoBuffer && aad)948 std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&& tag, CryptoBuffer&& aad)
949 {
950 #ifdef NO_SYMMETRIC_ENCRYPTION
951     return nullptr;
952 #endif
953     return GetAES_GCMFactory()->CreateImplementation(std::move(key), std::move(iv), std::move(tag), std::move(aad));
954 }
955 
CreateAES_KeyWrapImplementation(const CryptoBuffer & key)956 std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_KeyWrapImplementation(const CryptoBuffer& key)
957 {
958 #ifdef NO_SYMMETRIC_ENCRYPTION
959     return nullptr;
960 #endif
961     return GetAES_KeyWrapFactory()->CreateImplementation(key);
962 }
963 
964 #ifdef _WIN32
965 #pragma warning(pop)
966 #endif
967 
CreateSecureRandomBytesImplementation()968 std::shared_ptr<SecureRandomBytes> Aws::Utils::Crypto::CreateSecureRandomBytesImplementation()
969 {
970     return GetSecureRandomFactory()->CreateImplementation();
971 }
972