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 #ifndef CRYPTO_HASH_H_
6 #define CRYPTO_HASH_H_
7
8 #include "base/containers/span.h"
9 #include "base/notreached.h"
10 #include "crypto/crypto_export.h"
11 #include "third_party/boringssl/src/include/openssl/digest.h"
12
13 namespace crypto::hash {
14
15 inline constexpr size_t kSha1Size = 20;
16 inline constexpr size_t kSha256Size = 32;
17 inline constexpr size_t kSha512Size = 64;
18
19 // Unless your code needs to be generic over HashKind, use one of these
20 // kind-specific functions:
21 CRYPTO_EXPORT std::array<uint8_t, kSha1Size> Sha1(
22 base::span<const uint8_t> data);
23
24 CRYPTO_EXPORT std::array<uint8_t, kSha256Size> Sha256(
25 base::span<const uint8_t> data);
26
27 CRYPTO_EXPORT std::array<uint8_t, kSha512Size> Sha512(
28 base::span<const uint8_t> data);
29
30 // If you do need to be generic, you can use the Hash() function and pass a
31 // HashKind instead.
32 enum HashKind {
33 kSha1,
34 kSha256,
35 kSha512,
36 };
37
DigestSizeForHashKind(HashKind k)38 inline constexpr size_t DigestSizeForHashKind(HashKind k) {
39 switch (k) {
40 case kSha1:
41 return kSha1Size;
42 case kSha256:
43 return kSha256Size;
44 case kSha512:
45 return kSha512Size;
46 }
47 NOTREACHED();
48 }
49
50 // One-shot hashing. The passed-in digest span must be the correct size for the
51 // digest; use DigestSizeForHashKind() if your HashKind is variable.
52 CRYPTO_EXPORT void Hash(HashKind kind,
53 base::span<const uint8_t> data,
54 base::span<uint8_t> digest);
55
56 // A streaming hasher interface. Calling Finish() resets the hash context to the
57 // initial state after computing the digest.
58 class Hasher {
59 public:
60 explicit Hasher(HashKind kind);
61 Hasher(const Hasher& other);
62 Hasher(Hasher&& other);
63 Hasher& operator=(const Hasher& other);
64 Hasher& operator=(Hasher&& other);
65 ~Hasher();
66
67 void Update(base::span<const uint8_t> data);
68
69 // The digest span must be the right size.
70 void Finish(base::span<uint8_t> digest);
71
72 private:
73 bssl::ScopedEVP_MD_CTX ctx_;
74 };
75
76 } // namespace crypto::hash
77
78 #endif // CRYPTO_HASH_H_
79