1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #ifndef RTC_BASE_MESSAGE_DIGEST_H_
12 #define RTC_BASE_MESSAGE_DIGEST_H_
13
14 #include <stddef.h>
15
16 #include <string>
17
18 #include "absl/strings/string_view.h"
19
20 namespace rtc {
21
22 // Definitions for the digest algorithms.
23 extern const char DIGEST_MD5[];
24 extern const char DIGEST_SHA_1[];
25 extern const char DIGEST_SHA_224[];
26 extern const char DIGEST_SHA_256[];
27 extern const char DIGEST_SHA_384[];
28 extern const char DIGEST_SHA_512[];
29
30 // A general class for computing hashes.
31 class MessageDigest {
32 public:
33 enum { kMaxSize = 64 }; // Maximum known size (SHA-512)
~MessageDigest()34 virtual ~MessageDigest() {}
35 // Returns the digest output size (e.g. 16 bytes for MD5).
36 virtual size_t Size() const = 0;
37 // Updates the digest with `len` bytes from `buf`.
38 virtual void Update(const void* buf, size_t len) = 0;
39 // Outputs the digest value to `buf` with length `len`.
40 // Returns the number of bytes written, i.e., Size().
41 virtual size_t Finish(void* buf, size_t len) = 0;
42 };
43
44 // A factory class for creating digest objects.
45 class MessageDigestFactory {
46 public:
47 static MessageDigest* Create(absl::string_view alg);
48 };
49
50 // A check that an algorithm is in a list of approved digest algorithms
51 // from RFC 4572 (FIPS 180).
52 bool IsFips180DigestAlgorithm(absl::string_view alg);
53
54 // Functions to create hashes.
55
56 // Computes the hash of `in_len` bytes of `input`, using the `digest` hash
57 // implementation, and outputs the hash to the buffer `output`, which is
58 // `out_len` bytes long. Returns the number of bytes written to `output` if
59 // successful, or 0 if `out_len` was too small.
60 size_t ComputeDigest(MessageDigest* digest,
61 const void* input,
62 size_t in_len,
63 void* output,
64 size_t out_len);
65 // Like the previous function, but creates a digest implementation based on
66 // the desired digest name `alg`, e.g. DIGEST_SHA_1. Returns 0 if there is no
67 // digest with the given name.
68 size_t ComputeDigest(absl::string_view alg,
69 const void* input,
70 size_t in_len,
71 void* output,
72 size_t out_len);
73 // Computes the hash of `input` using the `digest` hash implementation, and
74 // returns it as a hex-encoded string.
75 std::string ComputeDigest(MessageDigest* digest, absl::string_view input);
76 // Like the previous function, but creates a digest implementation based on
77 // the desired digest name `alg`, e.g. DIGEST_SHA_1. Returns empty string if
78 // there is no digest with the given name.
79 std::string ComputeDigest(absl::string_view alg, absl::string_view input);
80 // Like the previous function, but returns an explicit result code.
81 bool ComputeDigest(absl::string_view alg,
82 absl::string_view input,
83 std::string* output);
84
85 // Shorthand way to compute a hex-encoded hash using MD5.
MD5(absl::string_view input)86 inline std::string MD5(absl::string_view input) {
87 return ComputeDigest(DIGEST_MD5, input);
88 }
89
90 // Functions to compute RFC 2104 HMACs.
91
92 // Computes the HMAC of `in_len` bytes of `input`, using the `digest` hash
93 // implementation and `key_len` bytes of `key` to key the HMAC, and outputs
94 // the HMAC to the buffer `output`, which is `out_len` bytes long. Returns the
95 // number of bytes written to `output` if successful, or 0 if `out_len` was too
96 // small.
97 size_t ComputeHmac(MessageDigest* digest,
98 const void* key,
99 size_t key_len,
100 const void* input,
101 size_t in_len,
102 void* output,
103 size_t out_len);
104 // Like the previous function, but creates a digest implementation based on
105 // the desired digest name `alg`, e.g. DIGEST_SHA_1. Returns 0 if there is no
106 // digest with the given name.
107 size_t ComputeHmac(absl::string_view alg,
108 const void* key,
109 size_t key_len,
110 const void* input,
111 size_t in_len,
112 void* output,
113 size_t out_len);
114 // Computes the HMAC of `input` using the `digest` hash implementation and `key`
115 // to key the HMAC, and returns it as a hex-encoded string.
116 std::string ComputeHmac(MessageDigest* digest,
117 absl::string_view key,
118 absl::string_view input);
119 // Like the previous function, but creates a digest implementation based on
120 // the desired digest name `alg`, e.g. DIGEST_SHA_1. Returns empty string if
121 // there is no digest with the given name.
122 std::string ComputeHmac(absl::string_view alg,
123 absl::string_view key,
124 absl::string_view input);
125 // Like the previous function, but returns an explicit result code.
126 bool ComputeHmac(absl::string_view alg,
127 absl::string_view key,
128 absl::string_view input,
129 std::string* output);
130
131 } // namespace rtc
132
133 #endif // RTC_BASE_MESSAGE_DIGEST_H_
134