[M120 Migration][VD] Enable direct rendering for TVPlus
[platform/framework/web/chromium-efl.git] / crypto / aead.cc
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "crypto/aead.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <string>
10
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"
15
16 namespace crypto {
17
18 Aead::Aead(AeadAlgorithm algorithm) {
19   EnsureOpenSSLInit();
20   switch (algorithm) {
21     case AES_128_CTR_HMAC_SHA256:
22       aead_ = EVP_aead_aes_128_ctr_hmac_sha256();
23       break;
24     case AES_256_GCM:
25       aead_ = EVP_aead_aes_256_gcm();
26       break;
27     case AES_256_GCM_SIV:
28       aead_ = EVP_aead_aes_256_gcm_siv();
29       break;
30     case CHACHA20_POLY1305:
31       aead_ = EVP_aead_chacha20_poly1305();
32       break;
33   }
34 }
35
36 Aead::~Aead() = default;
37
38 void Aead::Init(base::span<const uint8_t> key) {
39   DCHECK(!key_);
40   DCHECK_EQ(KeyLength(), key.size());
41   key_ = key;
42 }
43
44 static base::span<const uint8_t> ToSpan(std::string_view sp) {
45   return base::as_bytes(base::make_span(sp));
46 }
47
48 void Aead::Init(const std::string* key) {
49   Init(ToSpan(*key));
50 }
51
52 std::vector<uint8_t> Aead::Seal(
53     base::span<const uint8_t> plaintext,
54     base::span<const uint8_t> nonce,
55     base::span<const uint8_t> additional_data) const {
56   const size_t max_output_length =
57       EVP_AEAD_max_overhead(aead_) + plaintext.size();
58   CHECK(max_output_length >= plaintext.size());
59   std::vector<uint8_t> ret;
60   ret.resize(max_output_length);
61
62   size_t output_length;
63   CHECK(Seal(plaintext, nonce, additional_data, ret.data(), &output_length,
64              max_output_length));
65   ret.resize(output_length);
66   return ret;
67 }
68
69 bool Aead::Seal(std::string_view plaintext,
70                 std::string_view nonce,
71                 std::string_view additional_data,
72                 std::string* ciphertext) const {
73   const size_t max_output_length =
74       EVP_AEAD_max_overhead(aead_) + plaintext.size();
75   CHECK(max_output_length + 1 >= plaintext.size());
76   uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
77       base::WriteInto(ciphertext, max_output_length + 1));
78
79   size_t output_length;
80   if (!Seal(ToSpan(plaintext), ToSpan(nonce), ToSpan(additional_data), out_ptr,
81             &output_length, max_output_length)) {
82     ciphertext->clear();
83     return false;
84   }
85
86   ciphertext->resize(output_length);
87   return true;
88 }
89
90 absl::optional<std::vector<uint8_t>> Aead::Open(
91     base::span<const uint8_t> ciphertext,
92     base::span<const uint8_t> nonce,
93     base::span<const uint8_t> additional_data) const {
94   const size_t max_output_length = ciphertext.size();
95   std::vector<uint8_t> ret;
96   ret.resize(max_output_length);
97
98   size_t output_length;
99   if (!Open(ciphertext, nonce, additional_data, ret.data(), &output_length,
100             max_output_length)) {
101     return absl::nullopt;
102   }
103
104   ret.resize(output_length);
105   return ret;
106 }
107
108 bool Aead::Open(std::string_view ciphertext,
109                 std::string_view nonce,
110                 std::string_view additional_data,
111                 std::string* plaintext) const {
112   const size_t max_output_length = ciphertext.size();
113   CHECK(max_output_length + 1 > max_output_length);
114   uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
115       base::WriteInto(plaintext, max_output_length + 1));
116
117   size_t output_length;
118   if (!Open(ToSpan(ciphertext), ToSpan(nonce), ToSpan(additional_data), out_ptr,
119             &output_length, max_output_length)) {
120     plaintext->clear();
121     return false;
122   }
123
124   plaintext->resize(output_length);
125   return true;
126 }
127
128 size_t Aead::KeyLength() const {
129   return EVP_AEAD_key_length(aead_);
130 }
131
132 size_t Aead::NonceLength() const {
133   return EVP_AEAD_nonce_length(aead_);
134 }
135
136 bool Aead::Seal(base::span<const uint8_t> plaintext,
137                 base::span<const uint8_t> nonce,
138                 base::span<const uint8_t> additional_data,
139                 uint8_t* out,
140                 size_t* output_length,
141                 size_t max_output_length) const {
142   DCHECK(key_);
143   DCHECK_EQ(NonceLength(), nonce.size());
144   bssl::ScopedEVP_AEAD_CTX ctx;
145
146   if (!EVP_AEAD_CTX_init(ctx.get(), aead_, key_->data(), key_->size(),
147                          EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr) ||
148       !EVP_AEAD_CTX_seal(ctx.get(), out, output_length, max_output_length,
149                          nonce.data(), nonce.size(), plaintext.data(),
150                          plaintext.size(), additional_data.data(),
151                          additional_data.size())) {
152     return false;
153   }
154
155   DCHECK_LE(*output_length, max_output_length);
156   return true;
157 }
158
159 bool Aead::Open(base::span<const uint8_t> plaintext,
160                 base::span<const uint8_t> nonce,
161                 base::span<const uint8_t> additional_data,
162                 uint8_t* out,
163                 size_t* output_length,
164                 size_t max_output_length) const {
165   DCHECK(key_);
166   DCHECK_EQ(NonceLength(), nonce.size());
167   bssl::ScopedEVP_AEAD_CTX ctx;
168
169   if (!EVP_AEAD_CTX_init(ctx.get(), aead_, key_->data(), key_->size(),
170                          EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr) ||
171       !EVP_AEAD_CTX_open(ctx.get(), out, output_length, max_output_length,
172                          nonce.data(), nonce.size(), plaintext.data(),
173                          plaintext.size(), additional_data.data(),
174                          additional_data.size())) {
175     return false;
176   }
177
178   DCHECK_LE(*output_length, max_output_length);
179   return true;
180 }
181
182 }  // namespace crypto