OLD | NEW |
| (Empty) |
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_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 | |
17 namespace crypto { | |
18 | |
19 Aead::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 | |
28 Aead::~Aead() { | |
29 } | |
30 | |
31 void Aead::Init(const std::string* key) { | |
32 DCHECK(!key_); | |
33 DCHECK_EQ(KeyLength(), key->size()); | |
34 key_ = key; | |
35 } | |
36 | |
37 bool 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 | |
77 bool 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 | |
115 size_t Aead::KeyLength() const { | |
116 return EVP_AEAD_key_length(aead_); | |
117 } | |
118 | |
119 size_t Aead::NonceLength() const { | |
120 return EVP_AEAD_nonce_length(aead_); | |
121 } | |
122 | |
123 } // namespace | |
124 | |
125 #endif | |
OLD | NEW |