| Index: crypto/aead_openssl.cc
|
| diff --git a/crypto/aead_openssl.cc b/crypto/aead_openssl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ab939c2d9eb6e39552519d0cdc40c04fbed0dd1f
|
| --- /dev/null
|
| +++ b/crypto/aead_openssl.cc
|
| @@ -0,0 +1,111 @@
|
| +// Copyright 2015 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/aead_openssl.h"
|
| +
|
| +#if defined(USE_OPENSSL)
|
| +
|
| +#include <openssl/aes.h>
|
| +#include <openssl/evp.h>
|
| +#include <string>
|
| +
|
| +#include "base/strings/string_util.h"
|
| +#include "crypto/openssl_util.h"
|
| +#include "crypto/symmetric_key.h"
|
| +
|
| +namespace crypto {
|
| +
|
| +Aead::Aead(const std::string* key) : key_(key) {
|
| + EnsureOpenSSLInit();
|
| + DCHECK_EQ(KeyLength(), key->size());
|
| +}
|
| +
|
| +Aead::~Aead() {
|
| +}
|
| +
|
| +bool Aead::Seal(const base::StringPiece& plaintext,
|
| + const base::StringPiece& nonce,
|
| + std::string* ciphertext) {
|
| + DCHECK_EQ(NonceLength(), nonce.size());
|
| + const EVP_AEAD* aead = EVP_aead_aes_128_ctr_hmac_sha256();
|
| + EVP_AEAD_CTX ctx;
|
| +
|
| + if (!EVP_AEAD_CTX_init(&ctx, aead,
|
| + reinterpret_cast<const uint8*>(key_->data()),
|
| + key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
|
| + return false;
|
| + }
|
| +
|
| + std::string result;
|
| + const size_t max_output_length =
|
| + EVP_AEAD_max_overhead(aead) + plaintext.size();
|
| + size_t output_length;
|
| + uint8* out_ptr =
|
| + reinterpret_cast<uint8*>(WriteInto(&result, max_output_length + 1));
|
| +
|
| + if (!EVP_AEAD_CTX_seal(&ctx, out_ptr, &output_length, max_output_length,
|
| + reinterpret_cast<const uint8*>(nonce.data()),
|
| + nonce.size(),
|
| + reinterpret_cast<const uint8*>(plaintext.data()),
|
| + plaintext.size(), nullptr, 0)) {
|
| + EVP_AEAD_CTX_cleanup(&ctx);
|
| + return false;
|
| + }
|
| +
|
| + DCHECK_LE(output_length, max_output_length);
|
| + result.resize(output_length);
|
| +
|
| + ciphertext->swap(result);
|
| + EVP_AEAD_CTX_cleanup(&ctx);
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool Aead::Open(const base::StringPiece& ciphertext,
|
| + const base::StringPiece& nonce,
|
| + std::string* plaintext) {
|
| + const EVP_AEAD* aead = EVP_aead_aes_128_ctr_hmac_sha256();
|
| + EVP_AEAD_CTX ctx;
|
| +
|
| + if (!EVP_AEAD_CTX_init(&ctx, aead,
|
| + reinterpret_cast<const uint8*>(key_->data()),
|
| + key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
|
| + return false;
|
| + }
|
| +
|
| + std::string result;
|
| + const size_t max_output_length = ciphertext.size();
|
| + size_t output_length;
|
| + uint8* out_ptr =
|
| + reinterpret_cast<uint8*>(WriteInto(&result, max_output_length + 1));
|
| +
|
| + if (!EVP_AEAD_CTX_open(&ctx, out_ptr, &output_length, max_output_length,
|
| + reinterpret_cast<const uint8*>(nonce.data()),
|
| + nonce.size(),
|
| + reinterpret_cast<const uint8*>(ciphertext.data()),
|
| + ciphertext.size(), nullptr, 0)) {
|
| + EVP_AEAD_CTX_cleanup(&ctx);
|
| + return false;
|
| + }
|
| +
|
| + DCHECK_LE(output_length, max_output_length);
|
| + result.resize(output_length);
|
| +
|
| + plaintext->swap(result);
|
| + EVP_AEAD_CTX_cleanup(&ctx);
|
| +
|
| + return true;
|
| +}
|
| +
|
| +size_t Aead::KeyLength() {
|
| + return EVP_AEAD_key_length(EVP_aead_aes_128_ctr_hmac_sha256());
|
| +}
|
| +
|
| +size_t Aead::NonceLength() {
|
| + return EVP_AEAD_nonce_length(EVP_aead_aes_128_ctr_hmac_sha256());
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +#endif
|
|
|