1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker // Utility class for calculating the HMAC for a given message. We currently only 6*6777b538SAndroid Build Coastguard Worker // support SHA-1 and SHA-256 for the hash algorithm, but this can be extended 7*6777b538SAndroid Build Coastguard Worker // easily. Prefer the base::span and std::vector overloads over the 8*6777b538SAndroid Build Coastguard Worker // std::string_view and std::string overloads. 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #ifndef CRYPTO_HMAC_H_ 11*6777b538SAndroid Build Coastguard Worker #define CRYPTO_HMAC_H_ 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 14*6777b538SAndroid Build Coastguard Worker 15*6777b538SAndroid Build Coastguard Worker #include <memory> 16*6777b538SAndroid Build Coastguard Worker #include <string_view> 17*6777b538SAndroid Build Coastguard Worker #include <vector> 18*6777b538SAndroid Build Coastguard Worker 19*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h" 20*6777b538SAndroid Build Coastguard Worker #include "crypto/crypto_export.h" 21*6777b538SAndroid Build Coastguard Worker 22*6777b538SAndroid Build Coastguard Worker namespace crypto { 23*6777b538SAndroid Build Coastguard Worker 24*6777b538SAndroid Build Coastguard Worker // Simplify the interface and reduce includes by abstracting out the internals. 25*6777b538SAndroid Build Coastguard Worker class SymmetricKey; 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard Worker class CRYPTO_EXPORT HMAC { 28*6777b538SAndroid Build Coastguard Worker public: 29*6777b538SAndroid Build Coastguard Worker // The set of supported hash functions. Extend as required. 30*6777b538SAndroid Build Coastguard Worker enum HashAlgorithm { 31*6777b538SAndroid Build Coastguard Worker SHA1, 32*6777b538SAndroid Build Coastguard Worker SHA256, 33*6777b538SAndroid Build Coastguard Worker }; 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Worker explicit HMAC(HashAlgorithm hash_alg); 36*6777b538SAndroid Build Coastguard Worker 37*6777b538SAndroid Build Coastguard Worker HMAC(const HMAC&) = delete; 38*6777b538SAndroid Build Coastguard Worker HMAC& operator=(const HMAC&) = delete; 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard Worker ~HMAC(); 41*6777b538SAndroid Build Coastguard Worker 42*6777b538SAndroid Build Coastguard Worker // Returns the length of digest that this HMAC will create. 43*6777b538SAndroid Build Coastguard Worker size_t DigestLength() const; 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Worker // TODO(abarth): Add a PreferredKeyLength() member function. 46*6777b538SAndroid Build Coastguard Worker 47*6777b538SAndroid Build Coastguard Worker // Initializes this instance using |key| of the length |key_length|. Call Init 48*6777b538SAndroid Build Coastguard Worker // only once. It returns false on the second or later calls. 49*6777b538SAndroid Build Coastguard Worker // 50*6777b538SAndroid Build Coastguard Worker // NOTE: the US Federal crypto standard FIPS 198, Section 3 says: 51*6777b538SAndroid Build Coastguard Worker // The size of the key, K, shall be equal to or greater than L/2, where L 52*6777b538SAndroid Build Coastguard Worker // is the size of the hash function output. 53*6777b538SAndroid Build Coastguard Worker // In FIPS 198-1 (and SP-800-107, which describes key size recommendations), 54*6777b538SAndroid Build Coastguard Worker // this requirement is gone. But a system crypto library may still enforce 55*6777b538SAndroid Build Coastguard Worker // this old requirement. If the key is shorter than this recommended value, 56*6777b538SAndroid Build Coastguard Worker // Init() may fail. 57*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool Init(const unsigned char* key, size_t key_length); 58*6777b538SAndroid Build Coastguard Worker 59*6777b538SAndroid Build Coastguard Worker // Initializes this instance using |key|. Call Init 60*6777b538SAndroid Build Coastguard Worker // only once. It returns false on the second or later calls. 61*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool Init(const SymmetricKey* key); 62*6777b538SAndroid Build Coastguard Worker 63*6777b538SAndroid Build Coastguard Worker // Initializes this instance using |key|. Call Init only once. It returns 64*6777b538SAndroid Build Coastguard Worker // false on the second or later calls. Init(std::string_view key)65*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool Init(std::string_view key) { 66*6777b538SAndroid Build Coastguard Worker return Init(base::as_bytes(base::make_span(key))); 67*6777b538SAndroid Build Coastguard Worker } 68*6777b538SAndroid Build Coastguard Worker 69*6777b538SAndroid Build Coastguard Worker // Initializes this instance using |key|. Call Init only once. It returns 70*6777b538SAndroid Build Coastguard Worker // false on the second or later calls. Init(base::span<const uint8_t> key)71*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool Init(base::span<const uint8_t> key) { 72*6777b538SAndroid Build Coastguard Worker return Init(key.data(), key.size()); 73*6777b538SAndroid Build Coastguard Worker } 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker // Calculates the HMAC for the message in |data| using the algorithm supplied 76*6777b538SAndroid Build Coastguard Worker // to the constructor and the key supplied to the Init method. The HMAC is 77*6777b538SAndroid Build Coastguard Worker // returned in |digest|, which has |digest_length| bytes of storage available. 78*6777b538SAndroid Build Coastguard Worker // If |digest_length| is smaller than DigestLength(), the output will be 79*6777b538SAndroid Build Coastguard Worker // truncated. If it is larger, this method will fail. 80*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool Sign(std::string_view data, 81*6777b538SAndroid Build Coastguard Worker unsigned char* digest, 82*6777b538SAndroid Build Coastguard Worker size_t digest_length) const; 83*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool Sign(base::span<const uint8_t> data, 84*6777b538SAndroid Build Coastguard Worker base::span<uint8_t> digest) const; 85*6777b538SAndroid Build Coastguard Worker 86*6777b538SAndroid Build Coastguard Worker // Verifies that the HMAC for the message in |data| equals the HMAC provided 87*6777b538SAndroid Build Coastguard Worker // in |digest|, using the algorithm supplied to the constructor and the key 88*6777b538SAndroid Build Coastguard Worker // supplied to the Init method. Use of this method is strongly recommended 89*6777b538SAndroid Build Coastguard Worker // over using Sign() with a manual comparison (such as memcmp), as such 90*6777b538SAndroid Build Coastguard Worker // comparisons may result in side-channel disclosures, such as timing, that 91*6777b538SAndroid Build Coastguard Worker // undermine the cryptographic integrity. |digest| must be exactly 92*6777b538SAndroid Build Coastguard Worker // |DigestLength()| bytes long. 93*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool Verify(std::string_view data, 94*6777b538SAndroid Build Coastguard Worker std::string_view digest) const; 95*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool Verify(base::span<const uint8_t> data, 96*6777b538SAndroid Build Coastguard Worker base::span<const uint8_t> digest) const; 97*6777b538SAndroid Build Coastguard Worker 98*6777b538SAndroid Build Coastguard Worker // Verifies a truncated HMAC, behaving identical to Verify(), except 99*6777b538SAndroid Build Coastguard Worker // that |digest| is allowed to be smaller than |DigestLength()|. 100*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool VerifyTruncated(std::string_view data, 101*6777b538SAndroid Build Coastguard Worker std::string_view digest) const; 102*6777b538SAndroid Build Coastguard Worker [[nodiscard]] bool VerifyTruncated(base::span<const uint8_t> data, 103*6777b538SAndroid Build Coastguard Worker base::span<const uint8_t> digest) const; 104*6777b538SAndroid Build Coastguard Worker 105*6777b538SAndroid Build Coastguard Worker private: 106*6777b538SAndroid Build Coastguard Worker HashAlgorithm hash_alg_; 107*6777b538SAndroid Build Coastguard Worker bool initialized_; 108*6777b538SAndroid Build Coastguard Worker std::vector<unsigned char> key_; 109*6777b538SAndroid Build Coastguard Worker }; 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Worker } // namespace crypto 112*6777b538SAndroid Build Coastguard Worker 113*6777b538SAndroid Build Coastguard Worker #endif // CRYPTO_HMAC_H_ 114