Upload upstream chromium 71.0.3578.0
[platform/framework/web/chromium-efl.git] / crypto / aead.cc
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.
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) : key_(nullptr) {
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   }
31 }
32
33 Aead::~Aead() = default;
34
35 void Aead::Init(const std::string* key) {
36   DCHECK(!key_);
37   DCHECK_EQ(KeyLength(), key->size());
38   key_ = key;
39 }
40
41 bool Aead::Seal(base::StringPiece plaintext,
42                 base::StringPiece nonce,
43                 base::StringPiece additional_data,
44                 std::string* ciphertext) const {
45   DCHECK(key_);
46   DCHECK_EQ(NonceLength(), nonce.size());
47   EVP_AEAD_CTX ctx;
48
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)) {
52     return false;
53   }
54
55   std::string result;
56   const size_t max_output_length =
57       EVP_AEAD_max_overhead(aead_) + plaintext.size();
58   size_t output_length;
59   uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
60       base::WriteInto(&result, max_output_length + 1));
61
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);
69     return false;
70   }
71
72   DCHECK_LE(output_length, max_output_length);
73   result.resize(output_length);
74
75   ciphertext->swap(result);
76   EVP_AEAD_CTX_cleanup(&ctx);
77
78   return true;
79 }
80
81 bool Aead::Open(base::StringPiece ciphertext,
82                 base::StringPiece nonce,
83                 base::StringPiece additional_data,
84                 std::string* plaintext) const {
85   DCHECK(key_);
86   EVP_AEAD_CTX ctx;
87
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)) {
91     return false;
92   }
93
94   std::string result;
95   const size_t max_output_length = ciphertext.size();
96   size_t output_length;
97   uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
98       base::WriteInto(&result, max_output_length + 1));
99
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()),
104           ciphertext.size(),
105           reinterpret_cast<const uint8_t*>(additional_data.data()),
106           additional_data.size())) {
107     EVP_AEAD_CTX_cleanup(&ctx);
108     return false;
109   }
110
111   DCHECK_LE(output_length, max_output_length);
112   result.resize(output_length);
113
114   plaintext->swap(result);
115   EVP_AEAD_CTX_cleanup(&ctx);
116
117   return true;
118 }
119
120 size_t Aead::KeyLength() const {
121   return EVP_AEAD_key_length(aead_);
122 }
123
124 size_t Aead::NonceLength() const {
125   return EVP_AEAD_nonce_length(aead_);
126 }
127
128 }  // namespace crypto