blob: 7b9bb52e3e9286d71a83a6773e60b14210e25573 [file] [log] [blame]
estark03206a12015-04-25 04:52:251// 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
svaldez22de42fe2016-04-21 19:42:225#include "crypto/aead.h"
estark03206a12015-04-25 04:52:256
avidd373b8b2015-12-21 21:34:437#include <stddef.h>
8#include <stdint.h>
estark03206a12015-04-25 04:52:259#include <string>
10
estark03206a12015-04-25 04:52:2511#include "base/strings/string_util.h"
12#include "crypto/openssl_util.h"
tfarina29a3a1742016-10-28 18:47:3313#include "third_party/boringssl/src/include/openssl/aes.h"
14#include "third_party/boringssl/src/include/openssl/evp.h"
estark03206a12015-04-25 04:52:2515
16namespace crypto {
17
18Aead::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
27Aead::~Aead() {
28}
29
30void Aead::Init(const std::string* key) {
31 DCHECK(!key_);
32 DCHECK_EQ(KeyLength(), key->size());
33 key_ = key;
34}
35
36bool Aead::Seal(const base::StringPiece& plaintext,
37 const base::StringPiece& nonce,
38 const base::StringPiece& additional_data,
39 std::string* ciphertext) const {
40 DCHECK(key_);
41 DCHECK_EQ(NonceLength(), nonce.size());
42 EVP_AEAD_CTX ctx;
43
44 if (!EVP_AEAD_CTX_init(&ctx, aead_,
avidd373b8b2015-12-21 21:34:4345 reinterpret_cast<const uint8_t*>(key_->data()),
estark03206a12015-04-25 04:52:2546 key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
47 return false;
48 }
49
50 std::string result;
51 const size_t max_output_length =
52 EVP_AEAD_max_overhead(aead_) + plaintext.size();
53 size_t output_length;
avidd373b8b2015-12-21 21:34:4354 uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
55 base::WriteInto(&result, max_output_length + 1));
estark03206a12015-04-25 04:52:2556
57 if (!EVP_AEAD_CTX_seal(
58 &ctx, out_ptr, &output_length, max_output_length,
avidd373b8b2015-12-21 21:34:4359 reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
60 reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size(),
61 reinterpret_cast<const uint8_t*>(additional_data.data()),
estark03206a12015-04-25 04:52:2562 additional_data.size())) {
63 EVP_AEAD_CTX_cleanup(&ctx);
64 return false;
65 }
66
67 DCHECK_LE(output_length, max_output_length);
68 result.resize(output_length);
69
70 ciphertext->swap(result);
71 EVP_AEAD_CTX_cleanup(&ctx);
72
73 return true;
74}
75
76bool Aead::Open(const base::StringPiece& ciphertext,
77 const base::StringPiece& nonce,
78 const base::StringPiece& additional_data,
79 std::string* plaintext) const {
80 DCHECK(key_);
81 EVP_AEAD_CTX ctx;
82
83 if (!EVP_AEAD_CTX_init(&ctx, aead_,
avidd373b8b2015-12-21 21:34:4384 reinterpret_cast<const uint8_t*>(key_->data()),
estark03206a12015-04-25 04:52:2585 key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
86 return false;
87 }
88
89 std::string result;
90 const size_t max_output_length = ciphertext.size();
91 size_t output_length;
avidd373b8b2015-12-21 21:34:4392 uint8_t* out_ptr = reinterpret_cast<uint8_t*>(
93 base::WriteInto(&result, max_output_length + 1));
estark03206a12015-04-25 04:52:2594
95 if (!EVP_AEAD_CTX_open(
96 &ctx, out_ptr, &output_length, max_output_length,
avidd373b8b2015-12-21 21:34:4397 reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
98 reinterpret_cast<const uint8_t*>(ciphertext.data()),
99 ciphertext.size(),
100 reinterpret_cast<const uint8_t*>(additional_data.data()),
estark03206a12015-04-25 04:52:25101 additional_data.size())) {
102 EVP_AEAD_CTX_cleanup(&ctx);
103 return false;
104 }
105
106 DCHECK_LE(output_length, max_output_length);
107 result.resize(output_length);
108
109 plaintext->swap(result);
110 EVP_AEAD_CTX_cleanup(&ctx);
111
112 return true;
113}
114
115size_t Aead::KeyLength() const {
116 return EVP_AEAD_key_length(aead_);
117}
118
119size_t Aead::NonceLength() const {
120 return EVP_AEAD_nonce_length(aead_);
121}
122
davidben6004dc52017-02-03 04:15:29123} // namespace crypto