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();
25 aead_ = EVP_aead_aes_256_gcm();
28 aead_ = EVP_aead_aes_256_gcm_siv();
33 Aead::~Aead() = default;
35 void Aead::Init(const std::string* key) {
37 DCHECK_EQ(KeyLength(), key->size());
41 bool Aead::Seal(base::StringPiece plaintext,
42 base::StringPiece nonce,
43 base::StringPiece additional_data,
44 std::string* ciphertext) const {
46 DCHECK_EQ(NonceLength(), nonce.size());
49 if (!EVP_AEAD_CTX_init(&ctx, aead_,
50 reinterpret_cast<const uint8_t*>(key_->data()),
51 key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
56 const size_t max_output_length =
57 EVP_AEAD_max_overhead(aead_) + plaintext.size();
59 uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
60 base::WriteInto(&result, max_output_length + 1));
62 if (!EVP_AEAD_CTX_seal(
63 &ctx, out_ptr, &output_length, max_output_length,
64 reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
65 reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size(),
66 reinterpret_cast<const uint8_t*>(additional_data.data()),
67 additional_data.size())) {
68 EVP_AEAD_CTX_cleanup(&ctx);
72 DCHECK_LE(output_length, max_output_length);
73 result.resize(output_length);
75 ciphertext->swap(result);
76 EVP_AEAD_CTX_cleanup(&ctx);
81 bool Aead::Open(base::StringPiece ciphertext,
82 base::StringPiece nonce,
83 base::StringPiece additional_data,
84 std::string* plaintext) const {
88 if (!EVP_AEAD_CTX_init(&ctx, aead_,
89 reinterpret_cast<const uint8_t*>(key_->data()),
90 key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
95 const size_t max_output_length = ciphertext.size();
97 uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
98 base::WriteInto(&result, max_output_length + 1));
100 if (!EVP_AEAD_CTX_open(
101 &ctx, out_ptr, &output_length, max_output_length,
102 reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
103 reinterpret_cast<const uint8_t*>(ciphertext.data()),
105 reinterpret_cast<const uint8_t*>(additional_data.data()),
106 additional_data.size())) {
107 EVP_AEAD_CTX_cleanup(&ctx);
111 DCHECK_LE(output_length, max_output_length);
112 result.resize(output_length);
114 plaintext->swap(result);
115 EVP_AEAD_CTX_cleanup(&ctx);
120 size_t Aead::KeyLength() const {
121 return EVP_AEAD_key_length(aead_);
124 size_t Aead::NonceLength() const {
125 return EVP_AEAD_nonce_length(aead_);
128 } // namespace crypto