blob: e0714e8b2b907342bdb9cecb926a434a9e4a8a91 [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
#include "tink/integration/awskms/aws_crypto.h"
#include "aws/core/Aws.h"
#include "aws/core/utils/Outcome.h"
#include "aws/core/utils/crypto/Factories.h"
#include "aws/core/utils/crypto/HashResult.h"
#include "aws/core/utils/crypto/HMAC.h"
#include "aws/core/utils/crypto/Hash.h"
#include "absl/base/attributes.h"
#include "openssl/hmac.h"
#include "openssl/sha.h"
namespace crypto {
namespace tink {
namespace integration {
namespace awskms {
ABSL_CONST_INIT const char* kAwsCryptoAllocationTag = "AwsCryptoAllocation";
class AwsSha256HmacOpenSslImpl : public Aws::Utils::Crypto::HMAC {
public:
AwsSha256HmacOpenSslImpl() {}
virtual ~AwsSha256HmacOpenSslImpl() = default;
Aws::Utils::Crypto::HashResult Calculate(
const Aws::Utils::ByteBuffer& toSign,
const Aws::Utils::ByteBuffer& secret) override {
unsigned int length = SHA256_DIGEST_LENGTH;
Aws::Utils::ByteBuffer digest(length);
memset(digest.GetUnderlyingData(), 0, length);
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, secret.GetUnderlyingData(),
static_cast<int>(secret.GetLength()), EVP_sha256(), NULL);
HMAC_Update(&ctx, toSign.GetUnderlyingData(), toSign.GetLength());
HMAC_Final(&ctx, digest.GetUnderlyingData(), &length);
HMAC_CTX_cleanup(&ctx);
return Aws::Utils::Crypto::HashResult(std::move(digest));
}
};
class AwsSha256OpenSslImpl : public Aws::Utils::Crypto::Hash {
public:
AwsSha256OpenSslImpl() {}
virtual ~AwsSha256OpenSslImpl() = default;
Aws::Utils::Crypto::HashResult Calculate(const Aws::String& str) override {
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, str.data(), str.size());
Aws::Utils::ByteBuffer hash(SHA256_DIGEST_LENGTH);
SHA256_Final(hash.GetUnderlyingData(), &sha256);
return Aws::Utils::Crypto::HashResult(std::move(hash));
}
Aws::Utils::Crypto::HashResult Calculate(Aws::IStream& stream) override {
SHA256_CTX sha256;
SHA256_Init(&sha256);
auto currentPos = stream.tellg();
if (currentPos == std::streampos(std::streamoff(-1))) {
currentPos = 0;
stream.clear();
}
stream.seekg(0, stream.beg);
char streamBuffer
[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE];
while (stream.good()) {
stream.read(streamBuffer,
Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE);
auto bytesRead = stream.gcount();
if (bytesRead > 0) {
SHA256_Update(&sha256, streamBuffer, static_cast<size_t>(bytesRead));
}
}
stream.clear();
stream.seekg(currentPos, stream.beg);
Aws::Utils::ByteBuffer hash(SHA256_DIGEST_LENGTH);
SHA256_Final(hash.GetUnderlyingData(), &sha256);
return Aws::Utils::Crypto::HashResult(std::move(hash));
}
};
std::shared_ptr<Aws::Utils::Crypto::Hash>
AwsSha256Factory::CreateImplementation() const {
return Aws::MakeShared<AwsSha256OpenSslImpl>(kAwsCryptoAllocationTag);
}
std::shared_ptr<Aws::Utils::Crypto::HMAC>
AwsSha256HmacFactory::CreateImplementation() const {
return Aws::MakeShared<AwsSha256HmacOpenSslImpl>(kAwsCryptoAllocationTag);
}
} // namespace awskms
} // namespace integration
} // namespace tink
} // namespace crypto