Hash.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/crt/crypto/Hash.h>
  6. #include <aws/cal/hash.h>
  7. namespace Aws
  8. {
  9. namespace Crt
  10. {
  11. namespace Crypto
  12. {
  13. bool ComputeSHA256(
  14. Allocator *allocator,
  15. const ByteCursor &input,
  16. ByteBuf &output,
  17. size_t truncateTo) noexcept
  18. {
  19. return aws_sha256_compute(allocator, &input, &output, truncateTo) == AWS_OP_SUCCESS;
  20. }
  21. bool ComputeSHA256(const ByteCursor &input, ByteBuf &output, size_t truncateTo) noexcept
  22. {
  23. return aws_sha256_compute(ApiAllocator(), &input, &output, truncateTo) == AWS_OP_SUCCESS;
  24. }
  25. bool ComputeMD5(Allocator *allocator, const ByteCursor &input, ByteBuf &output, size_t truncateTo) noexcept
  26. {
  27. return aws_md5_compute(allocator, &input, &output, truncateTo) == AWS_OP_SUCCESS;
  28. }
  29. bool ComputeMD5(const ByteCursor &input, ByteBuf &output, size_t truncateTo) noexcept
  30. {
  31. return aws_md5_compute(ApiAllocator(), &input, &output, truncateTo) == AWS_OP_SUCCESS;
  32. }
  33. Hash::Hash(aws_hash *hash) noexcept : m_hash(hash), m_good(false), m_lastError(0)
  34. {
  35. if (hash)
  36. {
  37. m_good = true;
  38. }
  39. else
  40. {
  41. m_lastError = aws_last_error();
  42. }
  43. }
  44. Hash::~Hash()
  45. {
  46. if (m_hash)
  47. {
  48. aws_hash_destroy(m_hash);
  49. m_hash = nullptr;
  50. }
  51. }
  52. Hash::Hash(Hash &&toMove) : m_hash(toMove.m_hash), m_good(toMove.m_good), m_lastError(toMove.m_lastError)
  53. {
  54. toMove.m_hash = nullptr;
  55. toMove.m_good = false;
  56. }
  57. Hash &Hash::operator=(Hash &&toMove)
  58. {
  59. if (&toMove != this)
  60. {
  61. *this = Hash(std::move(toMove));
  62. }
  63. return *this;
  64. }
  65. Hash Hash::CreateSHA256(Allocator *allocator) noexcept { return Hash(aws_sha256_new(allocator)); }
  66. Hash Hash::CreateMD5(Allocator *allocator) noexcept { return Hash(aws_md5_new(allocator)); }
  67. bool Hash::Update(const ByteCursor &toHash) noexcept
  68. {
  69. if (*this)
  70. {
  71. if (aws_hash_update(m_hash, &toHash))
  72. {
  73. m_lastError = aws_last_error();
  74. m_good = false;
  75. return false;
  76. }
  77. return true;
  78. }
  79. return false;
  80. }
  81. bool Hash::Digest(ByteBuf &output, size_t truncateTo) noexcept
  82. {
  83. if (*this)
  84. {
  85. m_good = false;
  86. if (aws_hash_finalize(m_hash, &output, truncateTo))
  87. {
  88. m_lastError = aws_last_error();
  89. return false;
  90. }
  91. return true;
  92. }
  93. return false;
  94. }
  95. aws_hash_vtable ByoHash::s_Vtable = {
  96. "aws-crt-cpp-byo-crypto-hash",
  97. "aws-crt-cpp-byo-crypto",
  98. ByoHash::s_Destroy,
  99. ByoHash::s_Update,
  100. ByoHash::s_Finalize,
  101. };
  102. ByoHash::ByoHash(size_t digestSize, Allocator *allocator)
  103. {
  104. AWS_ZERO_STRUCT(m_hashValue);
  105. m_hashValue.vtable = &s_Vtable;
  106. m_hashValue.allocator = allocator;
  107. m_hashValue.impl = reinterpret_cast<void *>(this);
  108. m_hashValue.digest_size = digestSize;
  109. m_hashValue.good = true;
  110. }
  111. ByoHash::~ByoHash() {}
  112. aws_hash *ByoHash::SeatForCInterop(const std::shared_ptr<ByoHash> &selfRef)
  113. {
  114. AWS_FATAL_ASSERT(this == selfRef.get());
  115. m_selfReference = selfRef;
  116. return &m_hashValue;
  117. }
  118. void ByoHash::s_Destroy(struct aws_hash *hash)
  119. {
  120. auto *byoHash = reinterpret_cast<ByoHash *>(hash->impl);
  121. byoHash->m_selfReference = nullptr;
  122. }
  123. int ByoHash::s_Update(struct aws_hash *hash, const struct aws_byte_cursor *buf)
  124. {
  125. auto *byoHash = reinterpret_cast<ByoHash *>(hash->impl);
  126. if (!byoHash->m_hashValue.good)
  127. {
  128. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  129. }
  130. if (!byoHash->UpdateInternal(*buf))
  131. {
  132. byoHash->m_hashValue.good = false;
  133. return AWS_OP_ERR;
  134. }
  135. return AWS_OP_SUCCESS;
  136. }
  137. int ByoHash::s_Finalize(struct aws_hash *hash, struct aws_byte_buf *out)
  138. {
  139. auto *byoHash = reinterpret_cast<ByoHash *>(hash->impl);
  140. if (!byoHash->m_hashValue.good)
  141. {
  142. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  143. }
  144. bool success = byoHash->DigestInternal(*out);
  145. byoHash->m_hashValue.good = false;
  146. return success ? AWS_OP_SUCCESS : AWS_OP_ERR;
  147. }
  148. } // namespace Crypto
  149. } // namespace Crt
  150. } // namespace Aws