blob: e32168a576b4b8b42fe39a6d53f2f81ea74f3cc8 [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
5#include "crypto/aead_openssl.h"
6
7#if defined(USE_OPENSSL)
8
9#include <openssl/aes.h>
10#include <openssl/evp.h>
11#include <string>
12
13#include "base/basictypes.h"
14#include "base/strings/string_util.h"
15#include "crypto/openssl_util.h"
16
17namespace crypto {
18
19Aead::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;
25 }
26}
27
28Aead::~Aead() {
29}
30
31void Aead::Init(const std::string* key) {
32 DCHECK(!key_);
33 DCHECK_EQ(KeyLength(), key->size());
34 key_ = key;
35}
36
37bool 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;
44
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;
49 }
50
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*>(WriteInto(&result, max_output_length + 1));
57
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;
66 }
67
68 DCHECK_LE(output_length, max_output_length);
69 result.resize(output_length);
70
71 ciphertext->swap(result);
72 EVP_AEAD_CTX_cleanup(&ctx);
73
74 return true;
75}
76
77bool 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;
83
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;
88 }
89
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*>(WriteInto(&result, max_output_length + 1));
95
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;
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
123} // namespace
124
125#endif