Upload upstream chromium 67.0.3396
[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   }
25 }
26
27 Aead::~Aead() = default;
28
29 void Aead::Init(const std::string* key) {
30   DCHECK(!key_);
31   DCHECK_EQ(KeyLength(), key->size());
32   key_ = key;
33 }
34
35 bool Aead::Seal(base::StringPiece plaintext,
36                 base::StringPiece nonce,
37                 base::StringPiece additional_data,
38                 std::string* ciphertext) const {
39   DCHECK(key_);
40   DCHECK_EQ(NonceLength(), nonce.size());
41   EVP_AEAD_CTX ctx;
42
43   if (!EVP_AEAD_CTX_init(&ctx, aead_,
44                          reinterpret_cast<const uint8_t*>(key_->data()),
45                          key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
46     return false;
47   }
48
49   std::string result;
50   const size_t max_output_length =
51       EVP_AEAD_max_overhead(aead_) + plaintext.size();
52   size_t output_length;
53   uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
54       base::WriteInto(&result, max_output_length + 1));
55
56   if (!EVP_AEAD_CTX_seal(
57           &ctx, out_ptr, &output_length, max_output_length,
58           reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
59           reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size(),
60           reinterpret_cast<const uint8_t*>(additional_data.data()),
61           additional_data.size())) {
62     EVP_AEAD_CTX_cleanup(&ctx);
63     return false;
64   }
65
66   DCHECK_LE(output_length, max_output_length);
67   result.resize(output_length);
68
69   ciphertext->swap(result);
70   EVP_AEAD_CTX_cleanup(&ctx);
71
72   return true;
73 }
74
75 bool Aead::Open(base::StringPiece ciphertext,
76                 base::StringPiece nonce,
77                 base::StringPiece additional_data,
78                 std::string* plaintext) const {
79   DCHECK(key_);
80   EVP_AEAD_CTX ctx;
81
82   if (!EVP_AEAD_CTX_init(&ctx, aead_,
83                          reinterpret_cast<const uint8_t*>(key_->data()),
84                          key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
85     return false;
86   }
87
88   std::string result;
89   const size_t max_output_length = ciphertext.size();
90   size_t output_length;
91   uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
92       base::WriteInto(&result, max_output_length + 1));
93
94   if (!EVP_AEAD_CTX_open(
95           &ctx, out_ptr, &output_length, max_output_length,
96           reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
97           reinterpret_cast<const uint8_t*>(ciphertext.data()),
98           ciphertext.size(),
99           reinterpret_cast<const uint8_t*>(additional_data.data()),
100           additional_data.size())) {
101     EVP_AEAD_CTX_cleanup(&ctx);
102     return false;
103   }
104
105   DCHECK_LE(output_length, max_output_length);
106   result.resize(output_length);
107
108   plaintext->swap(result);
109   EVP_AEAD_CTX_cleanup(&ctx);
110
111   return true;
112 }
113
114 size_t Aead::KeyLength() const {
115   return EVP_AEAD_key_length(aead_);
116 }
117
118 size_t Aead::NonceLength() const {
119   return EVP_AEAD_nonce_length(aead_);
120 }
121
122 }  // namespace crypto