Add a method to HMAC to indicate how large a digest it produces.

Review URL: http://codereview.chromium.org/6904148

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83681 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/crypto/crypto.gyp b/crypto/crypto.gyp
index c875b3e..f6bb591a 100644
--- a/crypto/crypto.gyp
+++ b/crypto/crypto.gyp
@@ -119,6 +119,7 @@
         'encryptor_nss.cc',
         'encryptor_openssl.cc',
         'encryptor_win.cc',
+        'hmac.cc',
         'hmac.h',
         'hmac_mac.cc',
         'hmac_nss.cc',
diff --git a/crypto/hmac.cc b/crypto/hmac.cc
new file mode 100644
index 0000000..a38f514
--- /dev/null
+++ b/crypto/hmac.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "crypto/hmac.h"
+
+#include "base/logging.h"
+
+namespace crypto {
+
+size_t HMAC::DigestLength() const {
+  switch (hash_alg_) {
+    case SHA1:
+      return 20;
+    case SHA256:
+      return 32;
+    default:
+      NOTREACHED();
+      return 0;
+  }
+}
+
+}  // namespace crypto
diff --git a/crypto/hmac.h b/crypto/hmac.h
index 816bf60..fcd2657 100644
--- a/crypto/hmac.h
+++ b/crypto/hmac.h
@@ -30,8 +30,13 @@
   explicit HMAC(HashAlgorithm hash_alg);
   ~HMAC();
 
+  size_t DigestLength() const;
+
+  // TODO(abarth): Add a PreferredKeyLength() member function.
+
   // Initializes this instance using |key| of the length |key_length|. Call Init
   // only once. It returns false on the second or later calls.
+  // TODO(abarth): key_length should be a size_t.
   bool Init(const unsigned char* key, int key_length);
 
   // Initializes this instance using |key|. Call Init only once. It returns
@@ -44,6 +49,7 @@
   // Calculates the HMAC for the message in |data| using the algorithm supplied
   // to the constructor and the key supplied to the Init method. The HMAC is
   // returned in |digest|, which has |digest_length| bytes of storage available.
+  // TODO(abarth): digest_length should be a size_t.
   bool Sign(const std::string& data, unsigned char* digest, int digest_length);
 
   // TODO(albertb): Add a Verify method.
diff --git a/crypto/hmac_unittest.cc b/crypto/hmac_unittest.cc
index c537c36..0f8f0ec 100644
--- a/crypto/hmac_unittest.cc
+++ b/crypto/hmac_unittest.cc
@@ -7,8 +7,8 @@
 #include "crypto/hmac.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-static const int kSHA1DigestSize = 20;
-static const int kSHA256DigestSize = 32;
+static const size_t kSHA1DigestSize = 20;
+static const size_t kSHA256DigestSize = 32;
 
 TEST(HMACTest, HmacSafeBrowsingResponseTest) {
   const int kKeySize = 16;
@@ -151,6 +151,7 @@
   ASSERT_TRUE(hmac.Init(key, sizeof(key)));
   unsigned char calculated_hmac[kSHA256DigestSize];
 
+  EXPECT_EQ(kSHA256DigestSize, hmac.DigestLength());
   EXPECT_TRUE(hmac.Sign(data, calculated_hmac, kSHA256DigestSize));
   EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac, kSHA256DigestSize));
 }
@@ -191,6 +192,7 @@
   ASSERT_TRUE(hmac.Init(kKnownSecretKey, kKnownSecretKeySize));
   unsigned char calculated_hmac[kSHA1DigestSize];
 
+  EXPECT_EQ(kSHA1DigestSize, hmac.DigestLength());
   EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize));
   EXPECT_EQ(0, memcmp(kKnownHMACSHA1, calculated_hmac, kSHA1DigestSize));