1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "crypto/aead.h"
11 #include "base/strings/string_util.h"
12 #include "crypto/openssl_util.h"
13 #include "third_party/boringssl/src/include/openssl/aes.h"
14 #include "third_party/boringssl/src/include/openssl/evp.h"
18 Aead::Aead(AeadAlgorithm algorithm) : key_(nullptr) {
21 case AES_128_CTR_HMAC_SHA256:
22 aead_ = EVP_aead_aes_128_ctr_hmac_sha256();
27 Aead::~Aead() = default;
29 void Aead::Init(const std::string* key) {
31 DCHECK_EQ(KeyLength(), key->size());
35 bool Aead::Seal(base::StringPiece plaintext,
36 base::StringPiece nonce,
37 base::StringPiece additional_data,
38 std::string* ciphertext) const {
40 DCHECK_EQ(NonceLength(), nonce.size());
43 if (!EVP_AEAD_CTX_init(&ctx, aead_,
44 reinterpret_cast<const uint8_t*>(key_->data()),
45 key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
50 const size_t max_output_length =
51 EVP_AEAD_max_overhead(aead_) + plaintext.size();
53 uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
54 base::WriteInto(&result, max_output_length + 1));
56 if (!EVP_AEAD_CTX_seal(
57 &ctx, out_ptr, &output_length, max_output_length,
58 reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
59 reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size(),
60 reinterpret_cast<const uint8_t*>(additional_data.data()),
61 additional_data.size())) {
62 EVP_AEAD_CTX_cleanup(&ctx);
66 DCHECK_LE(output_length, max_output_length);
67 result.resize(output_length);
69 ciphertext->swap(result);
70 EVP_AEAD_CTX_cleanup(&ctx);
75 bool Aead::Open(base::StringPiece ciphertext,
76 base::StringPiece nonce,
77 base::StringPiece additional_data,
78 std::string* plaintext) const {
82 if (!EVP_AEAD_CTX_init(&ctx, aead_,
83 reinterpret_cast<const uint8_t*>(key_->data()),
84 key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
89 const size_t max_output_length = ciphertext.size();
91 uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
92 base::WriteInto(&result, max_output_length + 1));
94 if (!EVP_AEAD_CTX_open(
95 &ctx, out_ptr, &output_length, max_output_length,
96 reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
97 reinterpret_cast<const uint8_t*>(ciphertext.data()),
99 reinterpret_cast<const uint8_t*>(additional_data.data()),
100 additional_data.size())) {
101 EVP_AEAD_CTX_cleanup(&ctx);
105 DCHECK_LE(output_length, max_output_length);
106 result.resize(output_length);
108 plaintext->swap(result);
109 EVP_AEAD_CTX_cleanup(&ctx);
114 size_t Aead::KeyLength() const {
115 return EVP_AEAD_key_length(aead_);
118 size_t Aead::NonceLength() const {
119 return EVP_AEAD_nonce_length(aead_);
122 } // namespace crypto