AWS SDK for C++  0.14.3
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 
193  BCryptSymmetricCipher& operator=(const BCryptSymmetricCipher&) = 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  static BCRYPT_KEY_HANDLE ImportKeyBlob(BCRYPT_ALG_HANDLE handle, CryptoBuffer& key);
256 
257  private:
258  void Init();
259  void InitKey();
260  void Cleanup();
261  };
262 
267  {
268  public:
273 
277  AES_CBC_Cipher_BCrypt(CryptoBuffer&& key, CryptoBuffer&& initializationVector);
278 
282  AES_CBC_Cipher_BCrypt(const CryptoBuffer& key, const CryptoBuffer& initializationVector);
283 
285 
286  AES_CBC_Cipher_BCrypt& operator=(const AES_CBC_Cipher_BCrypt&) = delete;
287 
288  AES_CBC_Cipher_BCrypt(AES_CBC_Cipher_BCrypt&& toMove) : BCryptSymmetricCipher(std::move(toMove)), m_blockOverflow(std::move(toMove.m_blockOverflow)) {}
289 
290  CryptoBuffer EncryptBuffer(const CryptoBuffer& unEncryptedData) override;
291  CryptoBuffer FinalizeEncryption() override;
292  CryptoBuffer DecryptBuffer(const CryptoBuffer& encryptedData) override;
293  CryptoBuffer FinalizeDecryption() override;
294 
295  void Reset() override;
296 
297  protected:
298  void InitEncryptor_Internal() override;
299  void InitDecryptor_Internal() override;
300  size_t GetBlockSizeBytes() const override;
301  size_t GetKeyLengthBits() const override;
302 
303  private:
304  CryptoBuffer FillInOverflow(const CryptoBuffer& buffer);
305 
306  CryptoBuffer m_blockOverflow;
307 
308  static size_t BlockSizeBytes;
309  static size_t KeyLengthBits;
310  };
311 
316  {
317  public:
323 
327  AES_CTR_Cipher_BCrypt(CryptoBuffer&& key, CryptoBuffer&& initializationVector);
328 
332  AES_CTR_Cipher_BCrypt(const CryptoBuffer& key, const CryptoBuffer& initializationVector);
333 
335 
336  AES_CTR_Cipher_BCrypt& operator=(const AES_CTR_Cipher_BCrypt&) = delete;
337 
338  AES_CTR_Cipher_BCrypt(AES_CTR_Cipher_BCrypt&& toMove) : BCryptSymmetricCipher(std::move(toMove)), m_blockOverflow(std::move(toMove.m_blockOverflow)) {}
339 
340  CryptoBuffer EncryptBuffer(const CryptoBuffer& unEncryptedData) override;
341  CryptoBuffer FinalizeEncryption() override;
342  CryptoBuffer DecryptBuffer(const CryptoBuffer& encryptedData) override;
343  CryptoBuffer FinalizeDecryption() override;
344 
345  void Reset() override;
346 
347  protected:
348  void InitEncryptor_Internal() override;
349  void InitDecryptor_Internal() override;
350 
351  size_t GetBlockSizeBytes() const override;
352  size_t GetKeyLengthBits() const override;
353 
354  private:
355  static void IncrementCounter(CryptoBuffer& buffer);
356  static void InitBuffersToNull(Aws::Vector<ByteBuffer*>& initBuffers);
357  static void CleanupBuffers(Aws::Vector<ByteBuffer*>& cleanupBuffers);
358 
359  CryptoBuffer EncryptWithCtr(const CryptoBuffer& buffer);
360 
361  static size_t BlockSizeBytes;
362  static size_t KeyLengthBits;
363 
364  CryptoBuffer m_blockOverflow;
365  };
366 
371  {
372  public:
377 
381  AES_GCM_Cipher_BCrypt(CryptoBuffer&& key, CryptoBuffer&& initializationVector, CryptoBuffer&& tag = std::move(CryptoBuffer()));
382 
386  AES_GCM_Cipher_BCrypt(const CryptoBuffer& key, const CryptoBuffer& initializationVector, const CryptoBuffer& tag = CryptoBuffer());
387 
389 
390  AES_GCM_Cipher_BCrypt& operator=(const AES_GCM_Cipher_BCrypt&) = delete;
391 
393  BCryptSymmetricCipher(std::move(toMove)), m_macBuffer(std::move(toMove.m_macBuffer)), m_finalBuffer(std::move(toMove.m_finalBuffer)),
394  m_authInfo(std::move(toMove.m_authInfo)) {}
395 
396  CryptoBuffer EncryptBuffer(const CryptoBuffer&) override;
397  CryptoBuffer FinalizeEncryption() override;
398  CryptoBuffer DecryptBuffer(const CryptoBuffer&) override;
399  CryptoBuffer FinalizeDecryption() override;
400 
401  void Reset() override;
402 
403  protected:
404  void InitEncryptor_Internal() override;
405  void InitDecryptor_Internal() override;
406 
407  size_t GetBlockSizeBytes() const override;
408  size_t GetKeyLengthBits() const override;
409  size_t GetTagLengthBytes() const;
410 
411  private:
412  void InitCipher();
413 
414  static size_t BlockSizeBytes;
415  static size_t NonceSizeBytes;
416  static size_t KeyLengthBits;
417  static size_t TagLengthBytes;
418 
419  CryptoBuffer m_macBuffer;
420  CryptoBuffer m_finalBuffer;
421  BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO m_authInfo;
422  };
423 
429  {
430  public:
436 
438 
439  AES_KeyWrap_Cipher_BCrypt& operator=(const AES_KeyWrap_Cipher_BCrypt&) = delete;
440 
442 
443  CryptoBuffer EncryptBuffer(const CryptoBuffer& unEncryptedData) override;
444  CryptoBuffer FinalizeEncryption() override;
445  CryptoBuffer DecryptBuffer(const CryptoBuffer& encryptedData) override;
446  CryptoBuffer FinalizeDecryption() override;
447 
448  void Reset() override;
449 
450  protected:
451  void InitEncryptor_Internal() override;
452  void InitDecryptor_Internal() override;
453 
454  size_t GetBlockSizeBytes() const override;
455  size_t GetKeyLengthBits() const override;
456 
457  private:
458  static size_t BlockSizeBytes;
459  static size_t KeyLengthBits;
460 
461  CryptoBuffer m_operatingKeyBuffer;
462  };
463  } // namespace Crypto
464  } // namespace Utils
465 } // namespace Aws
466 
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:288
AES_KeyWrap_Cipher_BCrypt(AES_CTR_Cipher_BCrypt &&toMove)
Definition: CryptoImpl.h:441
STL namespace.
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:392
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:338
JSON (JavaScript Object Notation).