Index: crypto/hmac_nss.cc |
=================================================================== |
--- crypto/hmac_nss.cc (revision 0) |
+++ crypto/hmac_nss.cc (revision 0) |
@@ -0,0 +1,117 @@ |
+// 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 <nss.h> |
+#include <pk11pub.h> |
+ |
+#include "base/logging.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "crypto/nss_util.h" |
+#include "crypto/scoped_nss_types.h" |
+ |
+namespace crypto { |
+ |
+struct HMACPlatformData { |
+ CK_MECHANISM_TYPE mechanism_; |
+ ScopedPK11Slot slot_; |
+ ScopedPK11SymKey sym_key_; |
+}; |
+ |
+HMAC::HMAC(HashAlgorithm hash_alg) |
+ : hash_alg_(hash_alg), plat_(new HMACPlatformData()) { |
+ // Only SHA-1 and SHA-256 hash algorithms are supported. |
+ switch (hash_alg_) { |
+ case SHA1: |
+ plat_->mechanism_ = CKM_SHA_1_HMAC; |
+ break; |
+ case SHA256: |
+ plat_->mechanism_ = CKM_SHA256_HMAC; |
+ break; |
+ default: |
+ NOTREACHED() << "Unsupported hash algorithm"; |
+ break; |
+ } |
+} |
+ |
+HMAC::~HMAC() { |
+} |
+ |
+bool HMAC::Init(const unsigned char *key, int key_length) { |
+ EnsureNSSInit(); |
+ |
+ if (plat_->slot_.get()) { |
+ // Init must not be called more than twice on the same HMAC object. |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ plat_->slot_.reset(PK11_GetBestSlot(plat_->mechanism_, NULL)); |
+ if (!plat_->slot_.get()) { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ SECItem key_item; |
+ key_item.type = siBuffer; |
+ key_item.data = const_cast<unsigned char*>(key); // NSS API isn't const. |
+ key_item.len = key_length; |
+ |
+ plat_->sym_key_.reset(PK11_ImportSymKey(plat_->slot_.get(), |
+ plat_->mechanism_, |
+ PK11_OriginUnwrap, |
+ CKA_SIGN, |
+ &key_item, |
+ NULL)); |
+ if (!plat_->sym_key_.get()) { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+bool HMAC::Sign(const std::string& data, |
+ unsigned char* digest, |
+ int digest_length) { |
+ if (!plat_->sym_key_.get()) { |
+ // Init has not been called before Sign. |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ SECItem param = { siBuffer, NULL, 0 }; |
+ ScopedPK11Context context(PK11_CreateContextBySymKey(plat_->mechanism_, |
+ CKA_SIGN, |
+ plat_->sym_key_.get(), |
+ ¶m)); |
+ if (!context.get()) { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ if (PK11_DigestBegin(context.get()) != SECSuccess) { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ if (PK11_DigestOp(context.get(), |
+ reinterpret_cast<const unsigned char*>(data.data()), |
+ data.length()) != SECSuccess) { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ unsigned int len = 0; |
+ if (PK11_DigestFinal(context.get(), |
+ digest, &len, digest_length) != SECSuccess) { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+} // namespace crypto |
Property changes on: crypto\hmac_nss.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |