michael@0: // Copyright (c) 2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "base/hmac.h" michael@0: michael@0: #include michael@0: michael@0: #include "base/logging.h" michael@0: michael@0: namespace base { michael@0: michael@0: struct HMACPlatformData { michael@0: std::string key_; michael@0: }; michael@0: michael@0: HMAC::HMAC(HashAlgorithm hash_alg) michael@0: : hash_alg_(hash_alg), plat_(new HMACPlatformData()) { michael@0: // Only SHA-1 digest is supported now. michael@0: DCHECK(hash_alg_ == SHA1); michael@0: } michael@0: michael@0: bool HMAC::Init(const unsigned char *key, int key_length) { michael@0: if (!plat_->key_.empty()) { michael@0: // Init must not be called more than once on the same HMAC object. michael@0: NOTREACHED(); michael@0: return false; michael@0: } michael@0: michael@0: plat_->key_.assign(reinterpret_cast(key), key_length); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: HMAC::~HMAC() { michael@0: // Zero out key copy. michael@0: plat_->key_.assign(plat_->key_.length(), std::string::value_type()); michael@0: plat_->key_.clear(); michael@0: plat_->key_.reserve(0); michael@0: } michael@0: michael@0: bool HMAC::Sign(const std::string& data, michael@0: unsigned char* digest, michael@0: int digest_length) { michael@0: CCHmacAlgorithm algorithm; michael@0: int algorithm_digest_length; michael@0: switch (hash_alg_) { michael@0: case SHA1: michael@0: algorithm = kCCHmacAlgSHA1; michael@0: algorithm_digest_length = CC_SHA1_DIGEST_LENGTH; michael@0: break; michael@0: default: michael@0: NOTREACHED(); michael@0: return false; michael@0: } michael@0: michael@0: if (digest_length < algorithm_digest_length) { michael@0: NOTREACHED(); michael@0: return false; michael@0: } michael@0: michael@0: CCHmac(algorithm, michael@0: plat_->key_.data(), plat_->key_.length(), data.data(), data.length(), michael@0: digest); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: } // namespace base