Home | History | Annotate | Download | only in crypto
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      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/hmac.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/logging.h"
     10 #include "crypto/secure_util.h"
     11 #include "crypto/symmetric_key.h"
     12 
     13 namespace crypto {
     14 
     15 bool HMAC::Init(SymmetricKey* key) {
     16   std::string raw_key;
     17   bool result = key->GetRawKey(&raw_key) && Init(raw_key);
     18   // Zero out key copy.  This might get optimized away, but one can hope.
     19   // Using std::string to store key info at all is a larger problem.
     20   std::fill(raw_key.begin(), raw_key.end(), 0);
     21   return result;
     22 }
     23 
     24 size_t HMAC::DigestLength() const {
     25   switch (hash_alg_) {
     26     case SHA1:
     27       return 20;
     28     case SHA256:
     29       return 32;
     30     default:
     31       NOTREACHED();
     32       return 0;
     33   }
     34 }
     35 
     36 bool HMAC::Verify(const base::StringPiece& data,
     37                   const base::StringPiece& digest) const {
     38   if (digest.size() != DigestLength())
     39     return false;
     40   return VerifyTruncated(data, digest);
     41 }
     42 
     43 bool HMAC::VerifyTruncated(const base::StringPiece& data,
     44                            const base::StringPiece& digest) const {
     45   if (digest.empty())
     46     return false;
     47   size_t digest_length = DigestLength();
     48   scoped_ptr<unsigned char[]> computed_digest(
     49       new unsigned char[digest_length]);
     50   if (!Sign(data, computed_digest.get(), digest_length))
     51     return false;
     52 
     53   return SecureMemEqual(digest.data(), computed_digest.get(),
     54                         std::min(digest.size(), digest_length));
     55 }
     56 
     57 }  // namespace crypto
     58