blob: 03563ac2b63602d6401dd4b6f83cc08872d1c10c [file] [log] [blame]
Elly1e2fd412024-10-23 18:06:461// 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
11namespace crypto::hash {
12
13namespace {
14
15const 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
29void 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
39std::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
45std::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
51std::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
57Hasher::Hasher(HashKind kind) {
58 CHECK(EVP_DigestInit(ctx_.get(), EVPMDForHashKind(kind)));
59}
60
61Hasher::Hasher(const Hasher& other) {
62 *this = other;
63}
64
65Hasher::Hasher(Hasher&& other) {
66 *this = other;
67}
68
69Hasher& Hasher::operator=(const Hasher& other) {
70 CHECK(EVP_MD_CTX_copy_ex(ctx_.get(), other.ctx_.get()));
71 return *this;
72}
73
74Hasher& Hasher::operator=(Hasher&& other) {
75 ctx_ = std::move(other.ctx_);
76 return *this;
77}
78
79Hasher::~Hasher() = default;
80
81void Hasher::Update(base::span<const uint8_t> data) {
82 CHECK(EVP_DigestUpdate(ctx_.get(), data.data(), data.size()));
83}
84
85void 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