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 #include <openssl/aes.h> | |
8 #include <openssl/evp.h> | |
9 #include <stddef.h> | |
10 #include <stdint.h> | |
11 #include <string> | |
12 | |
13 #include "base/strings/string_util.h" | |
14 #include "crypto/openssl_util.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() { | |
28 } | |
29 | |
30 void Aead::Init(const std::string* key) { | |
31 DCHECK(!key_); | |
32 DCHECK_EQ(KeyLength(), key->size()); | |
33 key_ = key; | |
34 } | |
35 | |
36 bool 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_, | |
45 reinterpret_cast<const uint8_t*>(key_->data()), | |
46 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; | |
54 uint8_t* out_ptr = reinterpret_cast<uint8_t*>( | |
55 base::WriteInto(&result, max_output_length + 1)); | |
56 | |
57 if (!EVP_AEAD_CTX_seal( | |
58 &ctx, out_ptr, &output_length, max_output_length, | |
59 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()), | |
62 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 | |
76 bool 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_, | |
84 reinterpret_cast<const uint8_t*>(key_->data()), | |
85 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; | |
92 uint8_t* out_ptr = reinterpret_cast<uint8_t*>( | |
93 base::WriteInto(&result, max_output_length + 1)); | |
94 | |
95 if (!EVP_AEAD_CTX_open( | |
96 &ctx, out_ptr, &output_length, max_output_length, | |
97 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()), | |
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 | |
OLD | NEW |