| 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
|
|
|
|
|