summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-23 21:41:40 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-23 21:41:40 +0000
commit94d557e93368624bad52722bb4c093d4ac5cc1b9 (patch)
treea2105481bd54d84e9c7e7b0c2ee605089f06a453 /base
parent6acc7562fb3b6c720b050a379ea2c7e3fca22300 (diff)
downloadchromium_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.gypi4
-rw-r--r--base/sha1_portable.cc (renamed from base/sha1.cc)21
-rw-r--r--base/sha1_win.cc115
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