Roll src/third_party/WebKit cbc5016:24ba3b7 (svn 202399:202403)
[chromium-blink-merge.git] / crypto / aead_openssl.cc
blob54795b8a40607276f329a6a22d516865f791a341
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>
11 #include <string>
13 #include "base/basictypes.h"
14 #include "base/strings/string_util.h"
15 #include "crypto/openssl_util.h"
17 namespace crypto {
19 Aead::Aead(AeadAlgorithm algorithm) : key_(nullptr) {
20 EnsureOpenSSLInit();
21 switch (algorithm) {
22 case AES_128_CTR_HMAC_SHA256:
23 aead_ = EVP_aead_aes_128_ctr_hmac_sha256();
24 break;
28 Aead::~Aead() {
31 void Aead::Init(const std::string* key) {
32 DCHECK(!key_);
33 DCHECK_EQ(KeyLength(), key->size());
34 key_ = key;
37 bool Aead::Seal(const base::StringPiece& plaintext,
38 const base::StringPiece& nonce,
39 const base::StringPiece& additional_data,
40 std::string* ciphertext) const {
41 DCHECK(key_);
42 DCHECK_EQ(NonceLength(), nonce.size());
43 EVP_AEAD_CTX ctx;
45 if (!EVP_AEAD_CTX_init(&ctx, aead_,
46 reinterpret_cast<const uint8*>(key_->data()),
47 key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
48 return false;
51 std::string result;
52 const size_t max_output_length =
53 EVP_AEAD_max_overhead(aead_) + plaintext.size();
54 size_t output_length;
55 uint8* out_ptr =
56 reinterpret_cast<uint8*>(base::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);
65 return false;
68 DCHECK_LE(output_length, max_output_length);
69 result.resize(output_length);
71 ciphertext->swap(result);
72 EVP_AEAD_CTX_cleanup(&ctx);
74 return true;
77 bool Aead::Open(const base::StringPiece& ciphertext,
78 const base::StringPiece& nonce,
79 const base::StringPiece& additional_data,
80 std::string* plaintext) const {
81 DCHECK(key_);
82 EVP_AEAD_CTX ctx;
84 if (!EVP_AEAD_CTX_init(&ctx, aead_,
85 reinterpret_cast<const uint8*>(key_->data()),
86 key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
87 return false;
90 std::string result;
91 const size_t max_output_length = ciphertext.size();
92 size_t output_length;
93 uint8* out_ptr =
94 reinterpret_cast<uint8*>(base::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);
103 return false;
106 DCHECK_LE(output_length, max_output_length);
107 result.resize(output_length);
109 plaintext->swap(result);
110 EVP_AEAD_CTX_cleanup(&ctx);
112 return true;
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_);
123 } // namespace
125 #endif