diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-23 21:41:40 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-23 21:41:40 +0000 |
commit | 94d557e93368624bad52722bb4c093d4ac5cc1b9 (patch) | |
tree | a2105481bd54d84e9c7e7b0c2ee605089f06a453 /base | |
parent | 6acc7562fb3b6c720b050a379ea2c7e3fca22300 (diff) | |
download | chromium_src-94d557e93368624bad52722bb4c093d4ac5cc1b9.zip chromium_src-94d557e93368624bad52722bb4c093d4ac5cc1b9.tar.gz chromium_src-94d557e93368624bad52722bb4c093d4ac5cc1b9.tar.bz2 |
Implement the SecureHashAlgorithm class using Windows CryptoAPI.
sha1.cc is renamed sha1_portable.cc. Change the swapends function
to take a pointer instead of a non-const reference parameter.
R=jhawkins,davidben,eroman
BUG=47218
TEST=SHA1Test.* in base_unittests should pass.
Review URL: http://codereview.chromium.org/2849018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50648 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/base.gypi | 4 | ||||
-rw-r--r-- | base/sha1_portable.cc (renamed from base/sha1.cc) | 21 | ||||
-rw-r--r-- | base/sha1_win.cc | 115 |
3 files changed, 128 insertions, 12 deletions
diff --git a/base/base.gypi b/base/base.gypi index 807181a..53d097e 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -200,8 +200,9 @@ 'scoped_variant_win.cc', 'scoped_variant_win.h', 'scoped_vector.h', - 'sha1.cc', 'sha1.h', + 'sha1_portable.cc', + 'sha1_win.cc', 'shared_memory.h', 'shared_memory_posix.cc', 'shared_memory_win.cc', @@ -348,6 +349,7 @@ 'event_recorder_stubs.cc', 'file_descriptor_shuffle.cc', 'message_pump_libevent.cc', + 'sha1_portable.cc', 'string16.cc', 'trace_event.cc', ], diff --git a/base/sha1.cc b/base/sha1_portable.cc index 620dd56..d0f3c1c 100644 --- a/base/sha1.cc +++ b/base/sha1_portable.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -11,8 +11,6 @@ namespace base { // Implementation of SHA-1. Only handles data in byte-sized blocks, // which simplifies the code a fair bit. -// This file also contains an HMAC implementation using SHA-1 - // Identifier names follow notation in FIPS PUB 180-3, where you'll // also find a description of the algorithm: // http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf @@ -28,7 +26,8 @@ namespace base { // to reuse the instance of sha, call sha.Init(); // TODO(jhawkins): Replace this implementation with a per-platform -// implementation using each platform's crypto library. +// implementation using each platform's crypto library. See +// http://crbug.com/47218 class SecureHashAlgorithm { public: @@ -90,11 +89,11 @@ static inline uint32 K(uint32 t) { } } -static inline void swapends(uint32& t) { - t = ((t & 0xff000000) >> 24) | - ((t & 0xff0000) >> 8) | - ((t & 0xff00) << 8) | - ((t & 0xff) << 24); +static inline void swapends(uint32* t) { + *t = ((*t & 0xff000000) >> 24) | + ((*t & 0xff0000) >> 8) | + ((*t & 0xff00) << 8) | + ((*t & 0xff) << 24); } const int SecureHashAlgorithm::kDigestSizeBytes = 20; @@ -114,7 +113,7 @@ void SecureHashAlgorithm::Final() { Process(); for (int t = 0; t < 5; ++t) - swapends(H[t]); + swapends(&H[t]); } void SecureHashAlgorithm::Update(const void* data, size_t nbytes) { @@ -157,7 +156,7 @@ void SecureHashAlgorithm::Process() { // W and M are in a union, so no need to memcpy. // memcpy(W, M, sizeof(M)); for (t = 0; t < 16; ++t) - swapends(W[t]); + swapends(&W[t]); // b. for (t = 16; t < 80; ++t) diff --git a/base/sha1_win.cc b/base/sha1_win.cc new file mode 100644 index 0000000..b79ac38 --- /dev/null +++ b/base/sha1_win.cc @@ -0,0 +1,115 @@ +// Copyright (c) 2010 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 "base/sha1.h" + +#include <windows.h> +#include <wincrypt.h> + +#include "base/logging.h" +#include "base/string_util.h" + +namespace base { + +// Implementation of SHA-1 using Windows CryptoAPI. + +// Usage example: +// +// SecureHashAlgorithm sha; +// while(there is data to hash) +// sha.Update(moredata, size of data); +// sha.Final(); +// memcpy(somewhere, sha.Digest(), 20); +// +// to reuse the instance of sha, call sha.Init(); + +class SecureHashAlgorithm { + public: + SecureHashAlgorithm() : prov_(NULL), hash_(NULL) { Init(); } + + void Init(); + void Update(const void* data, size_t nbytes); + void Final(); + + // 20 bytes of message digest. + const unsigned char* Digest() const { + return reinterpret_cast<const unsigned char*>(result_.data()); + } + + private: + // Cleans up prov_, hash_, and result_. + void Cleanup(); + + HCRYPTPROV prov_; + HCRYPTHASH hash_; + std::string result_; +}; + +void SecureHashAlgorithm::Init() { + Cleanup(); + + if (!CryptAcquireContext(&prov_, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + LOG(ERROR) << "CryptAcquireContext failed: " << GetLastError(); + return; + } + + // Initialize the hash. + if (!CryptCreateHash(prov_, CALG_SHA1, 0, 0, &hash_)) { + LOG(ERROR) << "CryptCreateHash failed: " << GetLastError(); + return; + } +} + +void SecureHashAlgorithm::Update(const void* data, size_t nbytes) { + BOOL ok = CryptHashData(hash_, reinterpret_cast<CONST BYTE*>(data), + static_cast<DWORD>(nbytes), 0); + CHECK(ok) << "CryptHashData failed: " << GetLastError(); +} + +void SecureHashAlgorithm::Final() { + DWORD hash_len = 0; + DWORD buffer_size = sizeof(hash_len); + if (!CryptGetHashParam(hash_, HP_HASHSIZE, + reinterpret_cast<unsigned char*>(&hash_len), + &buffer_size, 0)) { + LOG(ERROR) << "CryptGetHashParam(HP_HASHSIZE) failed: " << GetLastError(); + result_.assign(SHA1_LENGTH, '\0'); + return; + } + + // Get the hash data. + if (!CryptGetHashParam(hash_, HP_HASHVAL, + reinterpret_cast<BYTE*>(WriteInto(&result_, + hash_len + 1)), + &hash_len, 0)) { + LOG(ERROR) << "CryptGetHashParam(HP_HASHVAL) failed: " << GetLastError(); + result_.assign(SHA1_LENGTH, '\0'); + return; + } +} + +void SecureHashAlgorithm::Cleanup() { + BOOL ok; + if (hash_) { + ok = CryptDestroyHash(hash_); + DCHECK(ok); + hash_ = NULL; + } + if (prov_) { + ok = CryptReleaseContext(prov_, 0); + DCHECK(ok); + prov_ = NULL; + } + result_.clear(); +} + +std::string SHA1HashString(const std::string& str) { + SecureHashAlgorithm sha; + sha.Update(str.c_str(), str.length()); + sha.Final(); + std::string out(reinterpret_cast<const char*>(sha.Digest()), SHA1_LENGTH); + return out; +} + +} // namespace base |