0

crypto/hash: add string_view overloads of hash functions

Many call sites of these hash functions are operating on strings, and
the ergonomics of:

    crypto:#️⃣:Sha256(base::as_byte_span("foo"));

leave a little bit to be desired, so this change adds some convenience
overloads. The strings do not automatically convert to spans because
they contain signed chars, while the normal span arguments these
functions take are spans of unsigned values. :(

Bug: 374310081
Change-Id: I073146d79338080a3a758fecef82f4f6af8ea2eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6442352
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Cr-Commit-Position: refs/heads/main@{#1444911}
This commit is contained in:
Elly
2025-04-09 13:26:08 -07:00
committed by Chromium LUCI CQ
parent 5aec8f6dab
commit 28ae1ff4c1
3 changed files with 35 additions and 0 deletions

@ -36,24 +36,40 @@ void Hash(HashKind kind,
nullptr));
}
void Hash(HashKind kind, std::string_view data, base::span<uint8_t> digest) {
Hash(kind, base::as_byte_span(data), digest);
}
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, kSha1Size> Sha1(std::string_view data) {
return Sha1(base::as_byte_span(data));
}
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, kSha256Size> Sha256(std::string_view data) {
return Sha256(base::as_byte_span(data));
}
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;
}
std::array<uint8_t, kSha512Size> Sha512(std::string_view data) {
return Sha512(base::as_byte_span(data));
}
Hasher::Hasher(HashKind kind) {
CHECK(EVP_DigestInit(ctx_.get(), EVPMDForHashKind(kind)));
}
@ -82,6 +98,10 @@ void Hasher::Update(base::span<const uint8_t> data) {
CHECK(EVP_DigestUpdate(ctx_.get(), data.data(), data.size()));
}
void Hasher::Update(std::string_view data) {
Update(base::as_byte_span(data));
}
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));

@ -20,12 +20,15 @@ inline constexpr size_t kSha512Size = 64;
// kind-specific functions:
CRYPTO_EXPORT std::array<uint8_t, kSha1Size> Sha1(
base::span<const uint8_t> data);
CRYPTO_EXPORT std::array<uint8_t, kSha1Size> Sha1(std::string_view data);
CRYPTO_EXPORT std::array<uint8_t, kSha256Size> Sha256(
base::span<const uint8_t> data);
CRYPTO_EXPORT std::array<uint8_t, kSha256Size> Sha256(std::string_view data);
CRYPTO_EXPORT std::array<uint8_t, kSha512Size> Sha512(
base::span<const uint8_t> data);
CRYPTO_EXPORT std::array<uint8_t, kSha512Size> Sha512(std::string_view data);
// If you do need to be generic, you can use the Hash() function and pass a
// HashKind instead.
@ -52,6 +55,9 @@ inline constexpr size_t DigestSizeForHashKind(HashKind k) {
CRYPTO_EXPORT void Hash(HashKind kind,
base::span<const uint8_t> data,
base::span<uint8_t> digest);
CRYPTO_EXPORT void Hash(HashKind kind,
std::string_view data,
base::span<uint8_t> digest);
// A streaming hasher interface. Calling Finish() resets the hash context to the
// initial state after computing the digest.
@ -65,6 +71,7 @@ class CRYPTO_EXPORT Hasher {
~Hasher();
void Update(base::span<const uint8_t> data);
void Update(std::string_view data);
// The digest span must be the right size.
void Finish(base::span<uint8_t> digest);

@ -91,3 +91,11 @@ TEST(HashTest, WrongDigestSizeDies) {
crypto::hash::Hash(crypto::hash::HashKind::kSha256, input, big_digest),
"");
}
TEST(HashTest, StringViewHash) {
const std::array<uint8_t, crypto::hash::kSha256Size> hash{
0xdf, 0xfd, 0x60, 0x21, 0xbb, 0x2b, 0xd5, 0xb0, 0xaf, 0x67, 0x62,
0x90, 0x80, 0x9e, 0xc3, 0xa5, 0x31, 0x91, 0xdd, 0x81, 0xc7, 0xf7,
0x0a, 0x4b, 0x28, 0x68, 0x8a, 0x36, 0x21, 0x82, 0x98, 0x6f};
EXPECT_EQ(hash, crypto::hash::Sha256("Hello, World!"));
}