//crypto: start reworking hash & hmac interfaces
This change adds: crypto:#️⃣:Sha1 crypto:#️⃣:Sha256 crypto:#️⃣:Sha512 crypto::hmac::SignSha1 crypto::hmac::SignSha256 crypto::hmac::SignSha512 crypto::hmac::VerifySha1 crypto::hmac::VerifySha256 crypto::hmac::VerifySha512 and also three more generic functions that take a HashKind: crypto:#️⃣:Hash crypto::hmac::Sign crypto::hmac::Verify These functions should be able to replace most users of the existing SecureHash and HMAC APIs with single-shot calls. The kind-specific wrapper functions exist primarily because they allow for compile-time checking that the right digest sizes are being used. This change also adds: crypto:#️⃣:Hasher which is a streaming, spanified interface to replace crypto::SecureHash and which does not require a factory function or heap allocations. Bug: 374310081, 374334448 Change-Id: Ie18904063099eb5376b01f9e0deaf4c5eba134ab Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5943830 Commit-Queue: Elly FJ <ellyjones@chromium.org> Reviewed-by: David Benjamin <davidben@chromium.org> Cr-Commit-Position: refs/heads/main@{#1372836}
This commit is contained in:
@ -31,6 +31,8 @@ component("crypto") {
|
||||
"encryptor.h",
|
||||
"features.cc",
|
||||
"features.h",
|
||||
"hash.cc",
|
||||
"hash.h",
|
||||
"hkdf.cc",
|
||||
"hkdf.h",
|
||||
"hmac.cc",
|
||||
@ -182,6 +184,7 @@ test("crypto_unittests") {
|
||||
"ec_private_key_unittest.cc",
|
||||
"ec_signature_creator_unittest.cc",
|
||||
"encryptor_unittest.cc",
|
||||
"hash_unittest.cc",
|
||||
"hmac_unittest.cc",
|
||||
"kdf_unittest.cc",
|
||||
"process_bound_string_unittest.cc",
|
||||
|
90
crypto/hash.cc
Normal file
90
crypto/hash.cc
Normal file
@ -0,0 +1,90 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "crypto/hash.h"
|
||||
|
||||
#include "base/notreached.h"
|
||||
#include "third_party/boringssl/src/include/openssl/digest.h"
|
||||
#include "third_party/boringssl/src/include/openssl/evp.h"
|
||||
|
||||
namespace crypto::hash {
|
||||
|
||||
namespace {
|
||||
|
||||
const EVP_MD* EVPMDForHashKind(HashKind kind) {
|
||||
switch (kind) {
|
||||
case HashKind::kSha1:
|
||||
return EVP_sha1();
|
||||
case HashKind::kSha256:
|
||||
return EVP_sha256();
|
||||
case HashKind::kSha512:
|
||||
return EVP_sha512();
|
||||
}
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void Hash(HashKind kind,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<uint8_t> digest) {
|
||||
const EVP_MD* md = EVPMDForHashKind(kind);
|
||||
CHECK_EQ(digest.size(), EVP_MD_size(md));
|
||||
|
||||
CHECK(EVP_Digest(data.data(), data.size(), digest.data(), nullptr, md,
|
||||
nullptr));
|
||||
}
|
||||
|
||||
std::array<uint8_t, kSha1Size> Sha1(base::span<const uint8_t> data) {
|
||||
std::array<uint8_t, kSha1Size> result;
|
||||
Hash(HashKind::kSha1, data, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::array<uint8_t, kSha256Size> Sha256(base::span<const uint8_t> data) {
|
||||
std::array<uint8_t, kSha256Size> result;
|
||||
Hash(HashKind::kSha256, data, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::array<uint8_t, kSha512Size> Sha512(base::span<const uint8_t> data) {
|
||||
std::array<uint8_t, kSha512Size> result;
|
||||
Hash(HashKind::kSha512, data, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Hasher::Hasher(HashKind kind) {
|
||||
CHECK(EVP_DigestInit(ctx_.get(), EVPMDForHashKind(kind)));
|
||||
}
|
||||
|
||||
Hasher::Hasher(const Hasher& other) {
|
||||
*this = other;
|
||||
}
|
||||
|
||||
Hasher::Hasher(Hasher&& other) {
|
||||
*this = other;
|
||||
}
|
||||
|
||||
Hasher& Hasher::operator=(const Hasher& other) {
|
||||
CHECK(EVP_MD_CTX_copy_ex(ctx_.get(), other.ctx_.get()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Hasher& Hasher::operator=(Hasher&& other) {
|
||||
ctx_ = std::move(other.ctx_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Hasher::~Hasher() = default;
|
||||
|
||||
void Hasher::Update(base::span<const uint8_t> data) {
|
||||
CHECK(EVP_DigestUpdate(ctx_.get(), data.data(), data.size()));
|
||||
}
|
||||
|
||||
void Hasher::Finish(base::span<uint8_t> digest) {
|
||||
CHECK_EQ(digest.size(), EVP_MD_CTX_size(ctx_.get()));
|
||||
CHECK(EVP_DigestFinal(ctx_.get(), digest.data(), nullptr));
|
||||
}
|
||||
|
||||
} // namespace crypto::hash
|
78
crypto/hash.h
Normal file
78
crypto/hash.h
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CRYPTO_HASH_H_
|
||||
#define CRYPTO_HASH_H_
|
||||
|
||||
#include "base/containers/span.h"
|
||||
#include "base/notreached.h"
|
||||
#include "crypto/crypto_export.h"
|
||||
#include "third_party/boringssl/src/include/openssl/digest.h"
|
||||
|
||||
namespace crypto::hash {
|
||||
|
||||
inline constexpr size_t kSha1Size = 20;
|
||||
inline constexpr size_t kSha256Size = 32;
|
||||
inline constexpr size_t kSha512Size = 64;
|
||||
|
||||
// Unless your code needs to be generic over HashKind, use one of these
|
||||
// kind-specific functions:
|
||||
CRYPTO_EXPORT std::array<uint8_t, kSha1Size> Sha1(
|
||||
base::span<const uint8_t> data);
|
||||
|
||||
CRYPTO_EXPORT std::array<uint8_t, kSha256Size> Sha256(
|
||||
base::span<const uint8_t> data);
|
||||
|
||||
CRYPTO_EXPORT std::array<uint8_t, kSha512Size> Sha512(
|
||||
base::span<const uint8_t> data);
|
||||
|
||||
// If you do need to be generic, you can use the Hash() function and pass a
|
||||
// HashKind instead.
|
||||
enum HashKind {
|
||||
kSha1,
|
||||
kSha256,
|
||||
kSha512,
|
||||
};
|
||||
|
||||
inline constexpr size_t DigestSizeForHashKind(HashKind k) {
|
||||
switch (k) {
|
||||
case kSha1:
|
||||
return kSha1Size;
|
||||
case kSha256:
|
||||
return kSha256Size;
|
||||
case kSha512:
|
||||
return kSha512Size;
|
||||
}
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
// One-shot hashing. The passed-in digest span must be the correct size for the
|
||||
// digest; use DigestSizeForHashKind() if your HashKind is variable.
|
||||
CRYPTO_EXPORT void Hash(HashKind kind,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<uint8_t> digest);
|
||||
|
||||
// A streaming hasher interface. Calling Finish() resets the hash context to the
|
||||
// initial state after computing the digest.
|
||||
class Hasher {
|
||||
public:
|
||||
explicit Hasher(HashKind kind);
|
||||
Hasher(const Hasher& other);
|
||||
Hasher(Hasher&& other);
|
||||
Hasher& operator=(const Hasher& other);
|
||||
Hasher& operator=(Hasher&& other);
|
||||
~Hasher();
|
||||
|
||||
void Update(base::span<const uint8_t> data);
|
||||
|
||||
// The digest span must be the right size.
|
||||
void Finish(base::span<uint8_t> digest);
|
||||
|
||||
private:
|
||||
bssl::ScopedEVP_MD_CTX ctx_;
|
||||
};
|
||||
|
||||
} // namespace crypto::hash
|
||||
|
||||
#endif // CRYPTO_HASH_H_
|
93
crypto/hash_unittest.cc
Normal file
93
crypto/hash_unittest.cc
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "crypto/hash.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
struct TestCase {
|
||||
const char* message;
|
||||
const char* digest;
|
||||
};
|
||||
|
||||
void PrepareTestCase(const TestCase& c,
|
||||
std::vector<uint8_t>* message,
|
||||
base::span<uint8_t> digest) {
|
||||
CHECK(base::HexStringToBytes(c.message, message));
|
||||
CHECK(base::HexStringToSpan(c.digest, digest));
|
||||
}
|
||||
|
||||
TEST(HashTest, Sha1) {
|
||||
const auto cases = std::to_array<TestCase>(
|
||||
{// FIPS 180-4 "SHA1ShortMsg" test vector:
|
||||
{
|
||||
.message = "3552694cdf663fd94b224747ac406aaf",
|
||||
.digest = "a150de927454202d94e656de4c7c0ca691de955d",
|
||||
}});
|
||||
|
||||
for (const auto& c : cases) {
|
||||
std::vector<uint8_t> message;
|
||||
std::array<uint8_t, 20> digest;
|
||||
|
||||
PrepareTestCase(c, &message, digest);
|
||||
auto computed_digest = crypto::hash::Sha1(base::as_byte_span(message));
|
||||
EXPECT_EQ(digest, computed_digest);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HashTest, Sha256) {
|
||||
const auto cases = std::to_array<TestCase>(
|
||||
{// FIPS 180-4 "SHA256ShortMsg" test vector:
|
||||
{
|
||||
.message = "0a27847cdc98bd6f62220b046edd762b",
|
||||
.digest = "80c25ec1600587e7f28b18b1b18e3cdc89928e39cab3bc25e4d4a4c13"
|
||||
"9bcedc4",
|
||||
}});
|
||||
|
||||
for (const auto& c : cases) {
|
||||
std::vector<uint8_t> message;
|
||||
std::array<uint8_t, 32> digest;
|
||||
|
||||
PrepareTestCase(c, &message, digest);
|
||||
auto computed_digest = crypto::hash::Sha256(base::as_byte_span(message));
|
||||
EXPECT_EQ(digest, computed_digest);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HashTest, Sha512) {
|
||||
const auto cases = std::to_array<TestCase>(
|
||||
{// FIPS 180-4 "SHA512ShortMsg" test vector:
|
||||
{
|
||||
.message = "cd67bd4054aaa3baa0db178ce232fd5a",
|
||||
.digest = "0d8521f8f2f3900332d1a1a55c60ba81d04d28dfe8c504b6328ae7879"
|
||||
"25fe018"
|
||||
"8f2ba91c3a9f0c1653c4bf0ada356455ea36fd31f8e73e3951cad4ebb"
|
||||
"a8c6e04",
|
||||
}});
|
||||
|
||||
for (const auto& c : cases) {
|
||||
std::vector<uint8_t> message;
|
||||
std::array<uint8_t, 64> digest;
|
||||
|
||||
PrepareTestCase(c, &message, digest);
|
||||
auto computed_digest = crypto::hash::Sha512(base::as_byte_span(message));
|
||||
EXPECT_EQ(digest, computed_digest);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HashTest, WrongDigestSizeDies) {
|
||||
std::array<uint8_t, 16> small_digest;
|
||||
std::array<uint8_t, 128> big_digest;
|
||||
std::array<uint8_t, 16> input;
|
||||
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
crypto::hash::Hash(crypto::hash::HashKind::kSha256, input, small_digest),
|
||||
"size");
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
crypto::hash::Hash(crypto::hash::HashKind::kSha256, input, big_digest),
|
||||
"size");
|
||||
}
|
@ -116,4 +116,95 @@ bool HMAC::VerifyTruncated(base::span<const uint8_t> data,
|
||||
return SecureMemEqual(digest, computed_digest);
|
||||
}
|
||||
|
||||
namespace hmac {
|
||||
|
||||
namespace {
|
||||
|
||||
const EVP_MD* EVPMDForHashKind(crypto::hash::HashKind kind) {
|
||||
switch (kind) {
|
||||
case crypto::hash::HashKind::kSha1:
|
||||
return EVP_sha1();
|
||||
case crypto::hash::HashKind::kSha256:
|
||||
return EVP_sha256();
|
||||
case crypto::hash::HashKind::kSha512:
|
||||
return EVP_sha512();
|
||||
}
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void Sign(crypto::hash::HashKind kind,
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<uint8_t> hmac) {
|
||||
const EVP_MD* md = EVPMDForHashKind(kind);
|
||||
CHECK_EQ(hmac.size(), EVP_MD_size(md));
|
||||
|
||||
bssl::ScopedHMAC_CTX ctx;
|
||||
CHECK(HMAC_Init_ex(ctx.get(), key.data(), key.size(), EVPMDForHashKind(kind),
|
||||
nullptr));
|
||||
CHECK(HMAC_Update(ctx.get(), data.data(), data.size()));
|
||||
CHECK(HMAC_Final(ctx.get(), hmac.data(), nullptr));
|
||||
}
|
||||
|
||||
bool Verify(crypto::hash::HashKind kind,
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<const uint8_t> hmac) {
|
||||
const EVP_MD* md = EVPMDForHashKind(kind);
|
||||
CHECK_EQ(hmac.size(), EVP_MD_size(md));
|
||||
|
||||
std::array<uint8_t, EVP_MAX_MD_SIZE> computed_buf;
|
||||
base::span<uint8_t> computed =
|
||||
base::span(computed_buf).first(EVP_MD_size(md));
|
||||
|
||||
Sign(kind, key, data, computed);
|
||||
return crypto::SecureMemEqual(computed, hmac);
|
||||
}
|
||||
|
||||
std::array<uint8_t, crypto::hash::kSha1Size> SignSha1(
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data) {
|
||||
std::array<uint8_t, crypto::hash::kSha1Size> result;
|
||||
Sign(crypto::hash::HashKind::kSha1, key, data, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::array<uint8_t, crypto::hash::kSha256Size> SignSha256(
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data) {
|
||||
std::array<uint8_t, crypto::hash::kSha256Size> result;
|
||||
Sign(crypto::hash::HashKind::kSha256, key, data, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::array<uint8_t, crypto::hash::kSha512Size> SignSha512(
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data) {
|
||||
std::array<uint8_t, crypto::hash::kSha512Size> result;
|
||||
Sign(crypto::hash::HashKind::kSha512, key, data, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool VerifySha1(base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<const uint8_t, 20> hmac) {
|
||||
return Verify(crypto::hash::HashKind::kSha1, key, data, hmac);
|
||||
}
|
||||
|
||||
bool VerifySha256(base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<const uint8_t, 32> hmac) {
|
||||
return Verify(crypto::hash::HashKind::kSha256, key, data, hmac);
|
||||
}
|
||||
|
||||
bool VerifySha512(base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<const uint8_t, 64> hmac) {
|
||||
return Verify(crypto::hash::HashKind::kSha512, key, data, hmac);
|
||||
}
|
||||
|
||||
} // namespace hmac
|
||||
|
||||
} // namespace crypto
|
||||
|
@ -18,12 +18,15 @@
|
||||
|
||||
#include "base/containers/span.h"
|
||||
#include "crypto/crypto_export.h"
|
||||
#include "crypto/hash.h"
|
||||
|
||||
namespace crypto {
|
||||
|
||||
// Simplify the interface and reduce includes by abstracting out the internals.
|
||||
class SymmetricKey;
|
||||
|
||||
// TODO(https://issues.chromium.org/issues/374334448): Rework this interface and
|
||||
// delete much of it.
|
||||
class CRYPTO_EXPORT HMAC {
|
||||
public:
|
||||
// The set of supported hash functions. Extend as required.
|
||||
@ -108,6 +111,52 @@ class CRYPTO_EXPORT HMAC {
|
||||
std::vector<unsigned char> key_;
|
||||
};
|
||||
|
||||
namespace hmac {
|
||||
|
||||
// Single-shot interfaces for working with HMACs. Unless your code needs to be
|
||||
// generic over hash kinds, you should use the convenience interfaces that are
|
||||
// named after a specific kind, since they allow compile-time error checking of
|
||||
// the hmac size.
|
||||
CRYPTO_EXPORT std::array<uint8_t, crypto::hash::kSha1Size> SignSha1(
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data);
|
||||
|
||||
CRYPTO_EXPORT std::array<uint8_t, crypto::hash::kSha256Size> SignSha256(
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data);
|
||||
|
||||
CRYPTO_EXPORT std::array<uint8_t, crypto::hash::kSha512Size> SignSha512(
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data);
|
||||
|
||||
[[nodiscard]] CRYPTO_EXPORT bool VerifySha1(
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<const uint8_t, crypto::hash::kSha1Size> hmac);
|
||||
|
||||
[[nodiscard]] CRYPTO_EXPORT bool VerifySha256(
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<const uint8_t, crypto::hash::kSha256Size> hmac);
|
||||
|
||||
[[nodiscard]] CRYPTO_EXPORT bool VerifySha512(
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<const uint8_t, crypto::hash::kSha512Size> hmac);
|
||||
|
||||
// If you need to be generic over hash types, you can instead use these, but you
|
||||
// must pass the correct size buffer for |hmac|:
|
||||
CRYPTO_EXPORT void Sign(crypto::hash::HashKind kind,
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<uint8_t> hmac);
|
||||
[[nodiscard]] CRYPTO_EXPORT bool Verify(crypto::hash::HashKind kind,
|
||||
base::span<const uint8_t> key,
|
||||
base::span<const uint8_t> data,
|
||||
base::span<const uint8_t> hmac);
|
||||
|
||||
} // namespace hmac
|
||||
|
||||
} // namespace crypto
|
||||
|
||||
#endif // CRYPTO_HMAC_H_
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
static const size_t kSHA1DigestSize = 20;
|
||||
@ -355,3 +356,74 @@ TEST(HMACTest, Bytes) {
|
||||
EXPECT_FALSE(hmac.VerifyTruncated(
|
||||
data, base::make_span(calculated_hmac, kSHA256DigestSize / 2)));
|
||||
}
|
||||
|
||||
TEST(HMACTest, OneShotSha1) {
|
||||
// RFC 2202 test case 3:
|
||||
std::vector<uint8_t> key(20, 0xaa);
|
||||
std::vector<uint8_t> data(50, 0xdd);
|
||||
std::vector<uint8_t> expected;
|
||||
CHECK(base::HexStringToBytes("125d7342b9ac11cd91a39af48aa17b4f63f175d3",
|
||||
&expected));
|
||||
|
||||
auto result = crypto::hmac::SignSha1(key, data);
|
||||
EXPECT_EQ(base::as_byte_span(result), base::as_byte_span(expected));
|
||||
EXPECT_TRUE(crypto::hmac::VerifySha1(key, data, result));
|
||||
result[0] ^= 0x01;
|
||||
EXPECT_FALSE(crypto::hmac::VerifySha1(key, data, result));
|
||||
}
|
||||
|
||||
TEST(HMACTest, OneShotSha256) {
|
||||
// RFC 4231 test case 3:
|
||||
std::vector<uint8_t> key(20, 0xaa);
|
||||
std::vector<uint8_t> data(50, 0xdd);
|
||||
std::vector<uint8_t> expected;
|
||||
CHECK(base::HexStringToBytes(
|
||||
"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
|
||||
&expected));
|
||||
|
||||
auto result = crypto::hmac::SignSha256(key, data);
|
||||
EXPECT_EQ(base::as_byte_span(result), base::as_byte_span(expected));
|
||||
EXPECT_TRUE(crypto::hmac::VerifySha256(key, data, result));
|
||||
result[0] ^= 0x01;
|
||||
EXPECT_FALSE(crypto::hmac::VerifySha256(key, data, result));
|
||||
}
|
||||
|
||||
TEST(HMACTest, OneShotSha512) {
|
||||
// RFC 4231 test case 3:
|
||||
std::vector<uint8_t> key(20, 0xaa);
|
||||
std::vector<uint8_t> data(50, 0xdd);
|
||||
std::vector<uint8_t> expected;
|
||||
CHECK(base::HexStringToBytes(
|
||||
"fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39"
|
||||
"bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb",
|
||||
&expected));
|
||||
|
||||
auto result = crypto::hmac::SignSha512(key, data);
|
||||
EXPECT_EQ(base::as_byte_span(result), base::as_byte_span(expected));
|
||||
EXPECT_TRUE(crypto::hmac::VerifySha512(key, data, result));
|
||||
result[0] ^= 0x01;
|
||||
EXPECT_FALSE(crypto::hmac::VerifySha512(key, data, result));
|
||||
}
|
||||
|
||||
TEST(HMACTest, OneShotWrongLengthDies) {
|
||||
std::array<uint8_t, 32> key;
|
||||
std::array<uint8_t, 32> data;
|
||||
std::array<uint8_t, 16> small_hmac;
|
||||
std::array<uint8_t, 128> big_hmac;
|
||||
|
||||
EXPECT_DEATH_IF_SUPPORTED(crypto::hmac::Sign(crypto::hash::HashKind::kSha256,
|
||||
key, data, small_hmac),
|
||||
"size");
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
crypto::hmac::Sign(crypto::hash::HashKind::kSha256, key, data, big_hmac),
|
||||
"size");
|
||||
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
(void)crypto::hmac::Verify(crypto::hash::HashKind::kSha256, key, data,
|
||||
small_hmac),
|
||||
"size");
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
(void)crypto::hmac::Verify(crypto::hash::HashKind::kSha256, key, data,
|
||||
big_hmac),
|
||||
"size");
|
||||
}
|
||||
|
@ -17,6 +17,9 @@ namespace crypto {
|
||||
// A wrapper to calculate secure hashes incrementally, allowing to
|
||||
// be used when the full input is not known in advance. The end result will the
|
||||
// same as if we have the full input in advance.
|
||||
//
|
||||
// TODO(https://issues.chromium.org/issues/374310081): Move this into
|
||||
// crypto/hash.h along with the oneshot functions.
|
||||
class CRYPTO_EXPORT SecureHash {
|
||||
public:
|
||||
enum Algorithm {
|
||||
|
@ -19,6 +19,9 @@ namespace crypto {
|
||||
// These functions perform SHA-256 operations.
|
||||
//
|
||||
// Functions for SHA-384 and SHA-512 can be added when the need arises.
|
||||
//
|
||||
// Deprecated: use the interface in crypto/hash.h instead.
|
||||
// TODO(https://issues.chromium.org/issues/374310081): Delete these.
|
||||
|
||||
static const size_t kSHA256Length = 32; // Length in bytes of a SHA-256 hash.
|
||||
|
||||
|
Reference in New Issue
Block a user