summaryrefslogtreecommitdiffstats
path: root/base/crypto/symmetric_key_nss.cc
diff options
context:
space:
mode:
authoralbertb@chromium.org <albertb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-25 19:13:00 +0000
committeralbertb@chromium.org <albertb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-25 19:13:00 +0000
commit39422e3082cc5b3633183b53ff21f93a5c17e5f0 (patch)
treef7bced4c1c84b34858abafc629aa8da7434d4ffc /base/crypto/symmetric_key_nss.cc
parent91968bc1e60c8ee2a3cab902c7f8246565974850 (diff)
downloadchromium_src-39422e3082cc5b3633183b53ff21f93a5c17e5f0.zip
chromium_src-39422e3082cc5b3633183b53ff21f93a5c17e5f0.tar.gz
chromium_src-39422e3082cc5b3633183b53ff21f93a5c17e5f0.tar.bz2
Implement random key generation and AES encryption using NSS.
BUG=none TEST=unit test Review URL: http://codereview.chromium.org/1142004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42649 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/crypto/symmetric_key_nss.cc')
-rw-r--r--base/crypto/symmetric_key_nss.cc67
1 files changed, 67 insertions, 0 deletions
diff --git a/base/crypto/symmetric_key_nss.cc b/base/crypto/symmetric_key_nss.cc
index 2c6c1ac..7196ae4 100644
--- a/base/crypto/symmetric_key_nss.cc
+++ b/base/crypto/symmetric_key_nss.cc
@@ -7,10 +7,77 @@
#include <nss.h>
#include <pk11pub.h>
+#include "base/nss_util.h"
#include "base/logging.h"
namespace base {
+// static
+SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm, size_t key_size) {
+ DCHECK_EQ(AES, algorithm);
+
+ EnsureNSSInit();
+ if (key_size == 0)
+ return NULL;
+
+ ScopedPK11Slot slot(PK11_GetBestSlot(CKM_AES_KEY_GEN, NULL));
+ if (!slot.get())
+ return NULL;
+
+ PK11SymKey* sym_key = PK11_KeyGen(slot.get(), CKM_AES_KEY_GEN, NULL, key_size,
+ NULL);
+ if (!sym_key)
+ return NULL;
+
+ return new SymmetricKey(sym_key);
+}
+
+// static
+SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
+ const std::string& password,
+ const std::string& salt,
+ size_t iterations,
+ size_t key_size) {
+ EnsureNSSInit();
+ if (salt.empty() || iterations == 0 || key_size == 0)
+ return NULL;
+
+ SECItem password_item;
+ password_item.type = siBuffer;
+ password_item.data = reinterpret_cast<unsigned char*>(
+ const_cast<char *>(password.data()));
+ password_item.len = password.size();
+
+ SECItem salt_item;
+ salt_item.type = siBuffer;
+ salt_item.data = reinterpret_cast<unsigned char*>(
+ const_cast<char *>(salt.data()));
+ salt_item.len = salt.size();
+
+
+ SECOidTag cipher_algorithm =
+ algorithm == AES ? SEC_OID_AES_256_CBC : SEC_OID_HMAC_SHA1;
+ ScopedSECAlgorithmID alg_id(PK11_CreatePBEV2AlgorithmID(SEC_OID_PKCS5_PBKDF2,
+ cipher_algorithm,
+ SEC_OID_HMAC_SHA1,
+ key_size,
+ iterations,
+ &salt_item));
+ if (!alg_id.get())
+ return NULL;
+
+ ScopedPK11Slot slot(PK11_GetBestSlot(SEC_OID_PKCS5_PBKDF2, NULL));
+ if (!slot.get())
+ return NULL;
+
+ PK11SymKey* sym_key = PK11_PBEKeyGen(slot.get(), alg_id.get(), &password_item,
+ PR_FALSE, NULL);
+ if (!sym_key)
+ return NULL;
+
+ return new SymmetricKey(sym_key);
+}
+
bool SymmetricKey::GetRawKey(std::string* raw_key) {
SECStatus rv = PK11_ExtractKeyValue(key_.get());
if (SECSuccess != rv)