AWS SDK for C++  0.12.9
AWS SDK for C++
CryptoImpl.h
Go to the documentation of this file.
1 /*
2  * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  * http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 #pragma once
17 
18 #include <aws/core/Core_EXPORTS.h>
24 #include <mutex>
25 
26 #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
27 
28 #define WIN32_NO_STATUS
29 #include <windows.h>
30 #include <bcrypt.h>
31 #include <winternl.h>
32 #include <winerror.h>
33 #undef WIN32_NO_STATUS
34 #endif // AWS_SDK_PLATFORM_WINDOWS
35 
36 namespace Aws
37 {
38  namespace Utils
39  {
40  namespace Crypto
41  {
42  static const char* SecureRandom_BCrypt_Tag = "SecureRandom_BCrypt";
43 
45  {
46  public:
49  void GetBytes(unsigned char* buffer, size_t bufferSize) override;
50  private:
51  BCRYPT_ALG_HANDLE m_algHandle;
52  };
53 
54  class BCryptHashContext;
55 
60  {
61  public:
66  BCryptHashImpl(LPCWSTR algorithmName, bool isHMAC);
67  ~BCryptHashImpl();
68 
72  HashResult Calculate(const Aws::String& str);
76  HashResult Calculate(const ByteBuffer& toHash, const ByteBuffer& secret);
80  HashResult Calculate(Aws::IStream& stream);
81 
82  private:
83 
84  bool IsValid() const;
85 
86  HashResult HashData(const BCryptHashContext& context, PBYTE data, ULONG dataLength);
87  bool HashStream(Aws::IStream& stream);
88 
89  void* m_algorithmHandle;
90 
91  DWORD m_hashBufferLength;
92  PBYTE m_hashBuffer;
93 
94  DWORD m_hashObjectLength;
95  PBYTE m_hashObject;
96 
97  //I'm 99% sure the algorithm handle for windows is not thread safe, but I can't
98  //prove or disprove that theory. Therefore, we have to lock to be safe.
99  std::mutex m_algorithmMutex;
100  };
101 
105  class MD5BcryptImpl : public Hash
106  {
107  public:
111  MD5BcryptImpl();
112  virtual ~MD5BcryptImpl() {}
113 
117  virtual HashResult Calculate(const Aws::String& str) override;
121  virtual HashResult Calculate(Aws::IStream& stream) override;
122 
123  private:
124  BCryptHashImpl m_impl;
125  };
126 
130  class Sha256BcryptImpl : public Hash
131  {
132  public:
137  virtual ~Sha256BcryptImpl() {}
138 
142  virtual HashResult Calculate(const Aws::String& str) override;
146  virtual HashResult Calculate(Aws::IStream& stream) override;
147 
148  private:
149  BCryptHashImpl m_impl;
150  };
151 
155  class Sha256HMACBcryptImpl : public HMAC
156  {
157  public:
158 
164 
168  virtual HashResult Calculate(const ByteBuffer& toSign, const ByteBuffer& secret) override;
169 
170  private:
171  BCryptHashImpl m_impl;
172  };
173 
178  {
179  public:
180  BCryptSymmetricCipher(const CryptoBuffer& key, size_t ivSize, bool ctrMode = false);
181 
185  BCryptSymmetricCipher(const CryptoBuffer& key, const CryptoBuffer& initializationVector, const CryptoBuffer& tag = CryptoBuffer(0));
186 
190  BCryptSymmetricCipher(CryptoBuffer&& key, CryptoBuffer&& initializationVector, CryptoBuffer&& tag = std::move(CryptoBuffer(0)));
191 
192  BCryptSymmetricCipher(const BCryptSymmetricCipher& other) = delete;
193  BCryptSymmetricCipher& operator=(const BCryptSymmetricCipher& other) = delete;
194 
201 
207  BCryptSymmetricCipher& operator=(BCryptSymmetricCipher&& toMove);
208 
209  virtual ~BCryptSymmetricCipher();
210 
215  CryptoBuffer EncryptBuffer(const CryptoBuffer& unEncryptedData) override;
220  CryptoBuffer FinalizeEncryption() override;
225  CryptoBuffer DecryptBuffer(const CryptoBuffer& encryptedData) override;
230  CryptoBuffer FinalizeDecryption() override;
231 
232  void Reset() override;
233 
234  protected:
238  virtual void InitEncryptor_Internal() = 0;
239  virtual void InitDecryptor_Internal() = 0;
240  virtual size_t GetBlockSizeBytes() const = 0;
241  virtual size_t GetKeyLengthBits() const = 0;
242 
243  void CheckInitEncryptor();
244  void CheckInitDecryptor();
245 
246  BCRYPT_ALG_HANDLE m_algHandle;
247  BCRYPT_KEY_HANDLE m_keyHandle;
248  DWORD m_flags;
250  PBCRYPT_AUTHENTICATED_CIPHER_MODE_INFO m_authInfoPtr;
254 
255  private:
256  void Init();
257  void InitKey();
258  void Cleanup();
259  };
260 
265  {
266  public:
271 
275  AES_CBC_Cipher_BCrypt(CryptoBuffer&& key, CryptoBuffer&& initializationVector);
276 
280  AES_CBC_Cipher_BCrypt(const CryptoBuffer& key, const CryptoBuffer& initializationVector);
281 
282  AES_CBC_Cipher_BCrypt(const AES_CBC_Cipher_BCrypt& other) = delete;
283 
284  AES_CBC_Cipher_BCrypt& operator=(const AES_CBC_Cipher_BCrypt& other) = delete;
285 
286  AES_CBC_Cipher_BCrypt(AES_CBC_Cipher_BCrypt&& toMove) : BCryptSymmetricCipher(std::move(toMove)), m_blockOverflow(std::move(toMove.m_blockOverflow)) {}
287 
288  CryptoBuffer EncryptBuffer(const CryptoBuffer& unEncryptedData) override;
289  CryptoBuffer FinalizeEncryption() override;
290  CryptoBuffer DecryptBuffer(const CryptoBuffer& encryptedData) override;
291  CryptoBuffer FinalizeDecryption() override;
292 
293  void Reset() override;
294 
295  protected:
296  void InitEncryptor_Internal() override;
297  void InitDecryptor_Internal() override;
298  size_t GetBlockSizeBytes() const override;
299  size_t GetKeyLengthBits() const override;
300 
301  private:
302  CryptoBuffer FillInOverflow(const CryptoBuffer& buffer);
303 
304  CryptoBuffer m_blockOverflow;
305 
306  static size_t BlockSizeBytes;
307  static size_t KeyLengthBits;
308  };
309 
314  {
315  public:
321 
325  AES_CTR_Cipher_BCrypt(CryptoBuffer&& key, CryptoBuffer&& initializationVector);
326 
330  AES_CTR_Cipher_BCrypt(const CryptoBuffer& key, const CryptoBuffer& initializationVector);
331 
332  AES_CTR_Cipher_BCrypt(const AES_CTR_Cipher_BCrypt& other) = delete;
333 
334  AES_CTR_Cipher_BCrypt& operator=(const AES_CTR_Cipher_BCrypt& other) = delete;
335 
336  AES_CTR_Cipher_BCrypt(AES_CTR_Cipher_BCrypt&& toMove) : BCryptSymmetricCipher(std::move(toMove)), m_blockOverflow(std::move(toMove.m_blockOverflow)) {}
337 
338  CryptoBuffer EncryptBuffer(const CryptoBuffer& unEncryptedData) override;
339  CryptoBuffer FinalizeEncryption() override;
340  CryptoBuffer DecryptBuffer(const CryptoBuffer& encryptedData) override;
341  CryptoBuffer FinalizeDecryption() override;
342 
343  void Reset() override;
344 
345  protected:
346  void InitEncryptor_Internal() override;
347  void InitDecryptor_Internal() override;
348 
349  size_t GetBlockSizeBytes() const override;
350  size_t GetKeyLengthBits() const override;
351 
352  private:
353  static void IncrementCounter(CryptoBuffer& buffer);
354  static void InitBuffersToNull(Aws::Vector<ByteBuffer*>& initBuffers);
355  static void CleanupBuffers(Aws::Vector<ByteBuffer*>& cleanupBuffers);
356 
357  CryptoBuffer EncryptWithCtr(const CryptoBuffer& buffer);
358 
359  static size_t BlockSizeBytes;
360  static size_t KeyLengthBits;
361 
362  CryptoBuffer m_blockOverflow;
363  };
364 
369  {
370  public:
375 
379  AES_GCM_Cipher_BCrypt(CryptoBuffer&& key, CryptoBuffer&& initializationVector, CryptoBuffer&& tag = std::move(CryptoBuffer()));
380 
384  AES_GCM_Cipher_BCrypt(const CryptoBuffer& key, const CryptoBuffer& initializationVector, const CryptoBuffer& tag = CryptoBuffer());
385 
386  AES_GCM_Cipher_BCrypt(const AES_GCM_Cipher_BCrypt& other) = delete;
387 
388  AES_GCM_Cipher_BCrypt& operator=(const AES_GCM_Cipher_BCrypt& other) = delete;
389 
391  BCryptSymmetricCipher(std::move(toMove)), m_macBuffer(std::move(toMove.m_macBuffer)), m_finalBuffer(std::move(toMove.m_finalBuffer)),
392  m_authInfo(std::move(toMove.m_authInfo)) {}
393 
394  CryptoBuffer EncryptBuffer(const CryptoBuffer&) override;
395  CryptoBuffer FinalizeEncryption() override;
396  CryptoBuffer DecryptBuffer(const CryptoBuffer&) override;
397  CryptoBuffer FinalizeDecryption() override;
398 
399  void Reset() override;
400 
401  protected:
402  void InitEncryptor_Internal() override;
403  void InitDecryptor_Internal() override;
404 
405  size_t GetBlockSizeBytes() const override;
406  size_t GetKeyLengthBits() const override;
407  size_t GetTagLengthBytes() const;
408 
409  private:
410  void InitCipher();
411 
412  static size_t BlockSizeBytes;
413  static size_t NonceSizeBytes;
414  static size_t KeyLengthBits;
415  static size_t TagLengthBytes;
416 
417  CryptoBuffer m_macBuffer;
418  CryptoBuffer m_finalBuffer;
419  BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO m_authInfo;
420  };
421  } // namespace Crypto
422  } // namespace Utils
423 } // namespace Aws
424 
static const char * SecureRandom_BCrypt_Tag
Definition: CryptoImpl.h:42
void GetBytes(unsigned char *buffer, size_t bufferSize) override
AES_CBC_Cipher_BCrypt(AES_CBC_Cipher_BCrypt &&toMove)
Definition: CryptoImpl.h:286
Definition: json.h:1499
std::vector< T, Aws::Allocator< T > > Vector
Definition: AWSVector.h:27
std::basic_istream< char, std::char_traits< char > > IStream
Definition: AWSStreamFwd.h:30
AES_GCM_Cipher_BCrypt(AES_GCM_Cipher_BCrypt &&toMove)
Definition: CryptoImpl.h:390
PBCRYPT_AUTHENTICATED_CIPHER_MODE_INFO m_authInfoPtr
Definition: CryptoImpl.h:250
std::basic_string< char, std::char_traits< char >, Aws::Allocator< char > > String
Definition: AWSString.h:97
AES_CTR_Cipher_BCrypt(AES_CTR_Cipher_BCrypt &&toMove)
Definition: CryptoImpl.h:336
JSON (JavaScript Object Notation).