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_openssl.h"
7 #if defined(USE_OPENSSL)
9 #include <openssl/aes.h>
10 #include <openssl/evp.h>
13 #include "base/basictypes.h"
14 #include "base/strings/string_util.h"
15 #include "crypto/openssl_util.h"
19 Aead::Aead(AeadAlgorithm algorithm
) : key_(nullptr) {
22 case AES_128_CTR_HMAC_SHA256
:
23 aead_
= EVP_aead_aes_128_ctr_hmac_sha256();
31 void Aead::Init(const std::string
* key
) {
33 DCHECK_EQ(KeyLength(), key
->size());
37 bool Aead::Seal(const base::StringPiece
& plaintext
,
38 const base::StringPiece
& nonce
,
39 const base::StringPiece
& additional_data
,
40 std::string
* ciphertext
) const {
42 DCHECK_EQ(NonceLength(), nonce
.size());
45 if (!EVP_AEAD_CTX_init(&ctx
, aead_
,
46 reinterpret_cast<const uint8
*>(key_
->data()),
47 key_
->size(), EVP_AEAD_DEFAULT_TAG_LENGTH
, nullptr)) {
52 const size_t max_output_length
=
53 EVP_AEAD_max_overhead(aead_
) + plaintext
.size();
56 reinterpret_cast<uint8
*>(WriteInto(&result
, max_output_length
+ 1));
58 if (!EVP_AEAD_CTX_seal(
59 &ctx
, out_ptr
, &output_length
, max_output_length
,
60 reinterpret_cast<const uint8
*>(nonce
.data()), nonce
.size(),
61 reinterpret_cast<const uint8
*>(plaintext
.data()), plaintext
.size(),
62 reinterpret_cast<const uint8
*>(additional_data
.data()),
63 additional_data
.size())) {
64 EVP_AEAD_CTX_cleanup(&ctx
);
68 DCHECK_LE(output_length
, max_output_length
);
69 result
.resize(output_length
);
71 ciphertext
->swap(result
);
72 EVP_AEAD_CTX_cleanup(&ctx
);
77 bool Aead::Open(const base::StringPiece
& ciphertext
,
78 const base::StringPiece
& nonce
,
79 const base::StringPiece
& additional_data
,
80 std::string
* plaintext
) const {
84 if (!EVP_AEAD_CTX_init(&ctx
, aead_
,
85 reinterpret_cast<const uint8
*>(key_
->data()),
86 key_
->size(), EVP_AEAD_DEFAULT_TAG_LENGTH
, nullptr)) {
91 const size_t max_output_length
= ciphertext
.size();
94 reinterpret_cast<uint8
*>(WriteInto(&result
, max_output_length
+ 1));
96 if (!EVP_AEAD_CTX_open(
97 &ctx
, out_ptr
, &output_length
, max_output_length
,
98 reinterpret_cast<const uint8
*>(nonce
.data()), nonce
.size(),
99 reinterpret_cast<const uint8
*>(ciphertext
.data()), ciphertext
.size(),
100 reinterpret_cast<const uint8
*>(additional_data
.data()),
101 additional_data
.size())) {
102 EVP_AEAD_CTX_cleanup(&ctx
);
106 DCHECK_LE(output_length
, max_output_length
);
107 result
.resize(output_length
);
109 plaintext
->swap(result
);
110 EVP_AEAD_CTX_cleanup(&ctx
);
115 size_t Aead::KeyLength() const {
116 return EVP_AEAD_key_length(aead_
);
119 size_t Aead::NonceLength() const {
120 return EVP_AEAD_nonce_length(aead_
);