Index: crypto/encryptor_nss.cc |
=================================================================== |
--- crypto/encryptor_nss.cc (revision 0) |
+++ crypto/encryptor_nss.cc (revision 0) |
@@ -0,0 +1,125 @@ |
+// 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/encryptor.h" |
+ |
+#include <cryptohi.h> |
+#include <vector> |
+ |
+#include "base/logging.h" |
+#include "crypto/nss_util.h" |
+#include "crypto/symmetric_key.h" |
+ |
+namespace crypto { |
+ |
+Encryptor::Encryptor() |
+ : key_(NULL), |
+ mode_(CBC) { |
+ EnsureNSSInit(); |
+} |
+ |
+Encryptor::~Encryptor() { |
+} |
+ |
+bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) { |
+ DCHECK(key); |
+ DCHECK_EQ(CBC, mode); |
+ |
+ key_ = key; |
+ mode_ = mode; |
+ |
+ if (iv.size() != AES_BLOCK_SIZE) |
+ return false; |
+ |
+ slot_.reset(PK11_GetBestSlot(CKM_AES_CBC_PAD, NULL)); |
+ if (!slot_.get()) |
+ return false; |
+ |
+ SECItem iv_item; |
+ iv_item.type = siBuffer; |
+ iv_item.data = reinterpret_cast<unsigned char*>( |
+ const_cast<char *>(iv.data())); |
+ iv_item.len = iv.size(); |
+ |
+ param_.reset(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item)); |
+ if (!param_.get()) |
+ return false; |
+ |
+ return true; |
+} |
+ |
+bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) { |
+ ScopedPK11Context context(PK11_CreateContextBySymKey(CKM_AES_CBC_PAD, |
+ CKA_ENCRYPT, |
+ key_->key(), |
+ param_.get())); |
+ if (!context.get()) |
+ return false; |
+ |
+ size_t ciphertext_len = plaintext.size() + AES_BLOCK_SIZE; |
+ std::vector<unsigned char> buffer(ciphertext_len); |
+ |
+ int op_len; |
+ SECStatus rv = PK11_CipherOp(context.get(), |
+ &buffer[0], |
+ &op_len, |
+ ciphertext_len, |
+ reinterpret_cast<unsigned char*>( |
+ const_cast<char*>(plaintext.data())), |
+ plaintext.size()); |
+ if (SECSuccess != rv) |
+ return false; |
+ |
+ unsigned int digest_len; |
+ rv = PK11_DigestFinal(context.get(), |
+ &buffer[op_len], |
+ &digest_len, |
+ ciphertext_len - op_len); |
+ if (SECSuccess != rv) |
+ return false; |
+ |
+ ciphertext->assign(reinterpret_cast<char *>(&buffer[0]), |
+ op_len + digest_len); |
+ return true; |
+} |
+ |
+bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) { |
+ if (ciphertext.empty()) |
+ return false; |
+ |
+ ScopedPK11Context context(PK11_CreateContextBySymKey(CKM_AES_CBC_PAD, |
+ CKA_DECRYPT, |
+ key_->key(), |
+ param_.get())); |
+ if (!context.get()) |
+ return false; |
+ |
+ size_t plaintext_len = ciphertext.size(); |
+ std::vector<unsigned char> buffer(plaintext_len); |
+ |
+ int op_len; |
+ SECStatus rv = PK11_CipherOp(context.get(), |
+ &buffer[0], |
+ &op_len, |
+ plaintext_len, |
+ reinterpret_cast<unsigned char*>( |
+ const_cast<char*>(ciphertext.data())), |
+ ciphertext.size()); |
+ if (SECSuccess != rv) |
+ return false; |
+ |
+ unsigned int digest_len; |
+ rv = PK11_DigestFinal(context.get(), |
+ &buffer[op_len], |
+ &digest_len, |
+ plaintext_len - op_len); |
+ if (SECSuccess != rv) |
+ return false; |
+ |
+ plaintext->assign(reinterpret_cast<char *>(&buffer[0]), |
+ op_len + digest_len); |
+ return true; |
+} |
+ |
+} // namespace crypto |
Property changes on: crypto\encryptor_nss.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |