• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "crypto/hash.h"
6 
7 #include "base/notreached.h"
8 #include "third_party/boringssl/src/include/openssl/digest.h"
9 #include "third_party/boringssl/src/include/openssl/evp.h"
10 
11 namespace crypto::hash {
12 
13 namespace {
14 
EVPMDForHashKind(HashKind kind)15 const EVP_MD* EVPMDForHashKind(HashKind kind) {
16   switch (kind) {
17     case HashKind::kSha1:
18       return EVP_sha1();
19     case HashKind::kSha256:
20       return EVP_sha256();
21     case HashKind::kSha512:
22       return EVP_sha512();
23   }
24   NOTREACHED();
25 }
26 
27 }  // namespace
28 
Hash(HashKind kind,base::span<const uint8_t> data,base::span<uint8_t> digest)29 void Hash(HashKind kind,
30           base::span<const uint8_t> data,
31           base::span<uint8_t> digest) {
32   const EVP_MD* md = EVPMDForHashKind(kind);
33   CHECK_EQ(digest.size(), EVP_MD_size(md));
34 
35   CHECK(EVP_Digest(data.data(), data.size(), digest.data(), nullptr, md,
36                    nullptr));
37 }
38 
Sha1(base::span<const uint8_t> data)39 std::array<uint8_t, kSha1Size> Sha1(base::span<const uint8_t> data) {
40   std::array<uint8_t, kSha1Size> result;
41   Hash(HashKind::kSha1, data, result);
42   return result;
43 }
44 
Sha256(base::span<const uint8_t> data)45 std::array<uint8_t, kSha256Size> Sha256(base::span<const uint8_t> data) {
46   std::array<uint8_t, kSha256Size> result;
47   Hash(HashKind::kSha256, data, result);
48   return result;
49 }
50 
Sha512(base::span<const uint8_t> data)51 std::array<uint8_t, kSha512Size> Sha512(base::span<const uint8_t> data) {
52   std::array<uint8_t, kSha512Size> result;
53   Hash(HashKind::kSha512, data, result);
54   return result;
55 }
56 
Hasher(HashKind kind)57 Hasher::Hasher(HashKind kind) {
58   CHECK(EVP_DigestInit(ctx_.get(), EVPMDForHashKind(kind)));
59 }
60 
Hasher(const Hasher & other)61 Hasher::Hasher(const Hasher& other) {
62   *this = other;
63 }
64 
Hasher(Hasher && other)65 Hasher::Hasher(Hasher&& other) {
66   *this = other;
67 }
68 
operator =(const Hasher & other)69 Hasher& Hasher::operator=(const Hasher& other) {
70   CHECK(EVP_MD_CTX_copy_ex(ctx_.get(), other.ctx_.get()));
71   return *this;
72 }
73 
operator =(Hasher && other)74 Hasher& Hasher::operator=(Hasher&& other) {
75   ctx_ = std::move(other.ctx_);
76   return *this;
77 }
78 
79 Hasher::~Hasher() = default;
80 
Update(base::span<const uint8_t> data)81 void Hasher::Update(base::span<const uint8_t> data) {
82   CHECK(EVP_DigestUpdate(ctx_.get(), data.data(), data.size()));
83 }
84 
Finish(base::span<uint8_t> digest)85 void Hasher::Finish(base::span<uint8_t> digest) {
86   CHECK_EQ(digest.size(), EVP_MD_CTX_size(ctx_.get()));
87   CHECK(EVP_DigestFinal(ctx_.get(), digest.data(), nullptr));
88 }
89 
90 }  // namespace crypto::hash
91