Skip to content

Commit d0ba4a6

Browse files
committed
Add support for CRC64, refactor CRC32
1 parent f09dc50 commit d0ba4a6

File tree

9 files changed

+250
-186
lines changed

9 files changed

+250
-186
lines changed

.cspell.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
// Crypto
4545
"decryptor", "encryptor", "NTSTATUS", "PBYTE", "PUCHAR", "noconf", "HAMC", "PBCRYPT", "BCRYPT", "libcrypto",
4646
"AWSLC", "CBCCTS", "tweaklen", "taglen", "blockcipher", "AESGCM", "compated", "outdata", "Decrypto", "GCMAAD",
47-
"CEKGCM", "HMACRAII", "OSSL", "ossl", "ccrng", "KEYWRAP",
47+
"CEKGCM", "HMACRAII", "OSSL", "ossl", "ccrng", "KEYWRAP", "NVME",
4848
// EC2
4949
"IMDS",
5050
// Eventstream
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
#pragma once
6+
7+
#include <aws/core/utils/crypto/Hash.h>
8+
#include <aws/core/utils/Outcome.h>
9+
#include <aws/core/utils/logging/LogMacros.h>
10+
#include <type_traits>
11+
12+
namespace Aws
13+
{
14+
namespace Utils
15+
{
16+
namespace Crypto
17+
{
18+
template <typename HashT>
19+
ByteBuffer ConvertToBuffer(HashT value)
20+
{
21+
static_assert(std::is_integral<HashT>::value, "Must use integral type to convert to buffer");
22+
Aws::Utils::ByteBuffer buffer(sizeof(HashT));
23+
for (size_t i = 0; i < sizeof(HashT); ++i)
24+
{
25+
size_t shiftSize = (sizeof(HashT) - 1) * 8 - i * 8;
26+
buffer[i] = (value >> shiftSize) & 0xFF;
27+
}
28+
return buffer;
29+
}
30+
31+
template <typename RunningChecksumT,
32+
RunningChecksumT (*CRTChecksumFuncT)(Crt::ByteCursor, RunningChecksumT),
33+
ByteBuffer (*ByteBufferFuncT)(RunningChecksumT)>
34+
class CRCChecksum : public Hash
35+
{
36+
public:
37+
CRCChecksum() : m_runningChecksum{0}
38+
{
39+
}
40+
41+
~CRCChecksum() override = default;
42+
43+
HashResult Calculate(const Aws::String& str) override
44+
{
45+
Aws::Crt::ByteCursor byteCursor = Aws::Crt::ByteCursorFromArray(reinterpret_cast<const uint8_t*>(str.data()), str.size());
46+
m_runningChecksum = CRTChecksumFuncT(byteCursor, m_runningChecksum);
47+
return ByteBufferFuncT(m_runningChecksum);
48+
};
49+
50+
HashResult Calculate(Aws::IStream& stream) override
51+
{
52+
auto currentPos = stream.tellg();
53+
if (currentPos == std::ios::pos_type(-1))
54+
{
55+
currentPos = 0;
56+
stream.clear();
57+
}
58+
59+
stream.seekg(0, Aws::IStream::beg);
60+
61+
uint8_t streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE];
62+
while (stream.good())
63+
{
64+
stream.read(reinterpret_cast<char*>(streamBuffer), Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE);
65+
const auto bytesRead = static_cast<size_t>(stream.gcount());
66+
67+
if (bytesRead > 0)
68+
{
69+
Aws::Crt::ByteCursor byteCursor = Aws::Crt::ByteCursorFromArray(streamBuffer, bytesRead);
70+
m_runningChecksum = CRTChecksumFuncT(byteCursor, m_runningChecksum);
71+
}
72+
}
73+
74+
if (stream.bad())
75+
{
76+
AWS_LOGSTREAM_ERROR("CRCChecksum", "Stream encountered an error while calculating CRC Checksum");
77+
}
78+
79+
stream.clear();
80+
stream.seekg(currentPos, Aws::IStream::beg);
81+
82+
return ByteBufferFuncT(m_runningChecksum);
83+
};
84+
85+
void Update(unsigned char* buffer, size_t bufferSize) override
86+
{
87+
Aws::Crt::ByteCursor byteCursor = Aws::Crt::ByteCursorFromArray(buffer, bufferSize);
88+
m_runningChecksum = CRTChecksumFuncT(byteCursor, m_runningChecksum);
89+
};
90+
91+
HashResult GetHash() override
92+
{
93+
return ByteBufferFuncT(m_runningChecksum);
94+
};
95+
96+
private:
97+
RunningChecksumT m_runningChecksum;
98+
};
99+
}
100+
}
101+
}

src/aws-cpp-sdk-core/include/aws/core/utils/crypto/CRC32.h

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <aws/core/Core_EXPORTS.h>
2424

2525
#include <aws/core/utils/crypto/Hash.h>
26+
#include <aws/core/utils/crypto/CRC.h>
27+
#include <aws/crt/checksum/CRC.h>
2628

2729
namespace Aws
2830
{
@@ -103,44 +105,13 @@ namespace Aws
103105
std::shared_ptr< Hash > m_hashImpl;
104106
};
105107

106-
class AWS_CORE_API CRC32Impl : public Hash
107-
{
108-
public:
109-
110-
CRC32Impl();
111-
virtual ~CRC32Impl() {}
112-
113-
virtual HashResult Calculate(const Aws::String& str) override;
114-
115-
virtual HashResult Calculate(Aws::IStream& stream) override;
116-
117-
virtual void Update(unsigned char* buffer, size_t bufferSize) override;
118-
119-
virtual HashResult GetHash() override;
120-
121-
private:
122-
int m_runningCrc32;
123-
};
124-
125-
class AWS_CORE_API CRC32CImpl : public Hash
126-
{
127-
public:
128-
129-
CRC32CImpl();
130-
virtual ~CRC32CImpl() {}
131-
132-
virtual HashResult Calculate(const Aws::String& str) override;
133-
134-
virtual HashResult Calculate(Aws::IStream& stream) override;
135-
136-
virtual void Update(unsigned char* buffer, size_t bufferSize) override;
137-
138-
virtual HashResult GetHash() override;
139-
140-
private:
141-
int m_runningCrc32c;
142-
};
108+
using CRC32Impl = CRCChecksum<uint32_t,
109+
Aws::Crt::Checksum::ComputeCRC32,
110+
ConvertToBuffer<uint32_t>>;
143111

112+
using CRC32CImpl = CRCChecksum<uint32_t,
113+
Aws::Crt::Checksum::ComputeCRC32C,
114+
ConvertToBuffer<uint32_t>>;
144115
} // namespace Crypto
145116
} // namespace Utils
146117
} // namespace Aws
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
#pragma once
6+
7+
#include <aws/core/Core_EXPORTS.h>
8+
#include <aws/core/utils/crypto/Hash.h>
9+
#include <aws/core/utils/crypto/CRC.h>
10+
#include <aws/crt/checksum/CRC.h>
11+
12+
namespace Aws
13+
{
14+
namespace Utils
15+
{
16+
namespace Crypto
17+
{
18+
/**
19+
* CRC64 hash implementation.
20+
*/
21+
class AWS_CORE_API CRC64 : public Hash
22+
{
23+
public:
24+
CRC64();
25+
~CRC64() override = default;
26+
HashResult Calculate(const Aws::String& str) override;
27+
HashResult Calculate(Aws::IStream& stream) override;
28+
void Update(unsigned char* buffer, size_t bufferSize) override;
29+
HashResult GetHash() override;
30+
31+
private:
32+
std::shared_ptr<Hash> m_hashImpl;
33+
};
34+
35+
using CRC64Impl = CRCChecksum<uint64_t,
36+
Aws::Crt::Checksum::ComputeCRC64NVME,
37+
ConvertToBuffer<uint64_t>>;
38+
}
39+
}
40+
}

src/aws-cpp-sdk-core/include/aws/core/utils/crypto/Factories.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ namespace Aws
5151
* Create a CRC32C Hash provider
5252
*/
5353
AWS_CORE_API std::shared_ptr<Hash> CreateCRC32CImplementation();
54+
/**
55+
* Create a CRC32 Hash provider
56+
*/
57+
AWS_CORE_API std::shared_ptr<Hash> CreateCRC64Implementation();
5458
/**
5559
* Create a Sha1 Hash provider
5660
*/
@@ -129,6 +133,10 @@ namespace Aws
129133
* Set the global factory for CRC32 Hash providers
130134
*/
131135
AWS_CORE_API void SetCRC32Factory(const std::shared_ptr<HashFactory>& factory);
136+
/**
137+
* Set the global factory for CRC32 Hash providers
138+
*/
139+
AWS_CORE_API void SetCRC64Factory(const std::shared_ptr<HashFactory>& factory);
132140
/**
133141
* Set the global factory for CRC32C Hash providers
134142
*/

src/aws-cpp-sdk-core/source/utils/crypto/CRC32.cpp

Lines changed: 0 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,9 @@
77
#include <aws/core/utils/crypto/CRC32.h>
88
#include <aws/core/utils/Outcome.h>
99
#include <aws/core/utils/crypto/Factories.h>
10-
#include <aws/crt/Types.h>
11-
#include <aws/checksums/crc.h>
12-
#include <aws/common/byte_buf.h>
1310

1411
using namespace Aws::Utils::Crypto;
1512

16-
static Aws::Utils::ByteBuffer ByteBufferFromInt32(uint32_t value)
17-
{
18-
Aws::Utils::ByteBuffer buffer(4);
19-
buffer[0] = (value >> 24) & 0xFF;
20-
buffer[1] = (value >> 16) & 0xFF;
21-
buffer[2] = (value >> 8) & 0xFF;
22-
buffer[3] = value & 0xFF;
23-
return buffer;
24-
}
25-
2613
CRC32::CRC32() :
2714
m_hashImpl(CreateCRC32Implementation())
2815
{
@@ -81,138 +68,3 @@ HashResult CRC32C::GetHash()
8168
{
8269
return m_hashImpl->GetHash();
8370
}
84-
85-
86-
CRC32Impl::CRC32Impl() : m_runningCrc32(0) {}
87-
88-
HashResult CRC32Impl::Calculate(const Aws::String& str)
89-
{
90-
Aws::Crt::ByteCursor byteCursor = Aws::Crt::ByteCursorFromArray(reinterpret_cast<const uint8_t*>(str.data()), str.size());
91-
92-
uint32_t runningCrc32 = 0;
93-
while (byteCursor.len > INT_MAX)
94-
{
95-
runningCrc32 = aws_checksums_crc32(byteCursor.ptr, INT_MAX, runningCrc32);
96-
aws_byte_cursor_advance(&byteCursor, INT_MAX);
97-
}
98-
runningCrc32 = aws_checksums_crc32(byteCursor.ptr, static_cast<int>(byteCursor.len), runningCrc32);
99-
const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(runningCrc32);
100-
return HashResult(std::move(hash));
101-
}
102-
103-
HashResult CRC32Impl::Calculate(Aws::IStream& stream)
104-
{
105-
uint32_t runningCrc32 = 0;
106-
107-
auto currentPos = stream.tellg();
108-
if (currentPos == std::ios::pos_type(-1))
109-
{
110-
currentPos = 0;
111-
stream.clear();
112-
}
113-
114-
stream.seekg(0, stream.beg);
115-
116-
uint8_t streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE];
117-
while (stream.good())
118-
{
119-
stream.read(reinterpret_cast<char*>(streamBuffer), Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE);
120-
auto bytesRead = stream.gcount();
121-
122-
if (bytesRead > 0)
123-
{
124-
runningCrc32 = aws_checksums_crc32(streamBuffer, static_cast<int>(bytesRead), runningCrc32);
125-
}
126-
}
127-
128-
stream.clear();
129-
stream.seekg(currentPos, stream.beg);
130-
131-
const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(runningCrc32);
132-
return HashResult(std::move(hash));
133-
}
134-
135-
void CRC32Impl::Update(unsigned char* buffer, size_t bufferSize)
136-
{
137-
Aws::Crt::ByteCursor byteCursor = Aws::Crt::ByteCursorFromArray(buffer, bufferSize);
138-
139-
while (byteCursor.len > INT_MAX)
140-
{
141-
m_runningCrc32 = aws_checksums_crc32(byteCursor.ptr, INT_MAX, m_runningCrc32);
142-
aws_byte_cursor_advance(&byteCursor, INT_MAX);
143-
}
144-
m_runningCrc32 = aws_checksums_crc32(byteCursor.ptr, static_cast<int>(byteCursor.len), m_runningCrc32);
145-
}
146-
147-
HashResult CRC32Impl::GetHash()
148-
{
149-
const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(m_runningCrc32);
150-
return HashResult(std::move(hash));
151-
}
152-
153-
CRC32CImpl::CRC32CImpl() : m_runningCrc32c(0) {}
154-
155-
HashResult CRC32CImpl::Calculate(const Aws::String& str)
156-
{
157-
Aws::Crt::ByteCursor byteCursor = Aws::Crt::ByteCursorFromArray(reinterpret_cast<const uint8_t*>(str.data()), str.size());
158-
159-
uint32_t runningCrc32c = 0;
160-
while (byteCursor.len > INT_MAX)
161-
{
162-
runningCrc32c = aws_checksums_crc32c(byteCursor.ptr, INT_MAX, runningCrc32c);
163-
aws_byte_cursor_advance(&byteCursor, INT_MAX);
164-
}
165-
runningCrc32c = aws_checksums_crc32c(byteCursor.ptr, static_cast<int>(byteCursor.len), runningCrc32c);
166-
const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(runningCrc32c);
167-
return HashResult(std::move(hash));
168-
}
169-
170-
HashResult CRC32CImpl::Calculate(Aws::IStream& stream)
171-
{
172-
uint32_t runningCrc32c = 0;
173-
174-
auto currentPos = stream.tellg();
175-
if (currentPos == std::ios::pos_type(-1))
176-
{
177-
currentPos = 0;
178-
stream.clear();
179-
}
180-
181-
stream.seekg(0, stream.beg);
182-
183-
uint8_t streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE];
184-
while (stream.good())
185-
{
186-
stream.read(reinterpret_cast<char*>(streamBuffer), Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE);
187-
auto bytesRead = stream.gcount();
188-
189-
if (bytesRead > 0)
190-
{
191-
runningCrc32c = aws_checksums_crc32c(streamBuffer, static_cast<int>(bytesRead), runningCrc32c);
192-
}
193-
}
194-
195-
stream.clear();
196-
stream.seekg(currentPos, stream.beg);
197-
198-
const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(runningCrc32c);
199-
return HashResult(std::move(hash));
200-
}
201-
202-
void CRC32CImpl::Update(unsigned char* buffer, size_t bufferSize)
203-
{
204-
Aws::Crt::ByteCursor byteCursor = Aws::Crt::ByteCursorFromArray(buffer, bufferSize);
205-
206-
while (byteCursor.len > INT_MAX)
207-
{
208-
m_runningCrc32c = aws_checksums_crc32c(byteCursor.ptr, INT_MAX, m_runningCrc32c);
209-
aws_byte_cursor_advance(&byteCursor, INT_MAX);
210-
}
211-
m_runningCrc32c = aws_checksums_crc32c(byteCursor.ptr, static_cast<int>(byteCursor.len), m_runningCrc32c);
212-
}
213-
214-
HashResult CRC32CImpl::GetHash()
215-
{
216-
const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(m_runningCrc32c);
217-
return HashResult(std::move(hash));
218-
}

0 commit comments

Comments
 (0)