Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc

Issue 189893002: Add ChaCha20Poly1305Encrypter, based on (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Remove the six svn copy files from the CL Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" 5 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
6 6
7 #include <openssl/err.h>
8 #include <openssl/evp.h> 7 #include <openssl/evp.h>
9 #include <string.h>
10
11 #include "base/memory/scoped_ptr.h"
12
13 using base::StringPiece;
14 8
15 namespace net { 9 namespace net {
16 10
17 namespace { 11 namespace {
18 12
19 const size_t kKeySize = 16; 13 const size_t kKeySize = 16;
20 const size_t kNoncePrefixSize = 4; 14 const size_t kNoncePrefixSize = 4;
21 const size_t kAESNonceSize = 12;
22
23 void ClearOpenSslErrors() {
24 #ifdef NDEBUG
25 while (ERR_get_error()) {}
26 #else
27 while (long error = ERR_get_error()) {
28 char buf[120];
29 ERR_error_string_n(error, buf, arraysize(buf));
30 DLOG(ERROR) << "OpenSSL error: " << buf;
31 }
32 #endif
33 }
34 15
35 } // namespace 16 } // namespace
36 17
37 Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() {} 18 Aes128Gcm12Encrypter::Aes128Gcm12Encrypter()
19 : AeadBaseEncrypter(EVP_aead_aes_128_gcm(), kKeySize, kAuthTagSize,
20 kNoncePrefixSize) {
21 COMPILE_ASSERT(kKeySize <= kMaxKeySize, key_size_too_big);
22 COMPILE_ASSERT(kNoncePrefixSize <= kMaxNoncePrefixSize,
23 nonce_prefix_size_too_big);
24 }
38 25
39 Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {} 26 Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {}
40 27
41 bool Aes128Gcm12Encrypter::SetKey(StringPiece key) {
42 DCHECK_EQ(key.size(), sizeof(key_));
43 if (key.size() != sizeof(key_)) {
44 return false;
45 }
46 memcpy(key_, key.data(), key.size());
47
48 EVP_AEAD_CTX_cleanup(ctx_.get());
49
50 if (!EVP_AEAD_CTX_init(ctx_.get(), EVP_aead_aes_128_gcm(), key_,
51 sizeof(key_), kAuthTagSize, NULL)) {
52 ClearOpenSslErrors();
53 return false;
54 }
55
56 return true;
57 }
58
59 bool Aes128Gcm12Encrypter::SetNoncePrefix(StringPiece nonce_prefix) {
60 DCHECK_EQ(nonce_prefix.size(), kNoncePrefixSize);
61 if (nonce_prefix.size() != kNoncePrefixSize) {
62 return false;
63 }
64 COMPILE_ASSERT(sizeof(nonce_prefix_) == kNoncePrefixSize, bad_nonce_length);
65 memcpy(nonce_prefix_, nonce_prefix.data(), nonce_prefix.size());
66 return true;
67 }
68
69 bool Aes128Gcm12Encrypter::Encrypt(StringPiece nonce,
70 StringPiece associated_data,
71 StringPiece plaintext,
72 unsigned char* output) {
73 if (nonce.size() != kNoncePrefixSize + sizeof(QuicPacketSequenceNumber)) {
74 return false;
75 }
76
77 ssize_t len = EVP_AEAD_CTX_seal(
78 ctx_.get(), output, plaintext.size() + kAuthTagSize,
79 reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
80 reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size(),
81 reinterpret_cast<const uint8_t*>(associated_data.data()),
82 associated_data.size());
83
84 if (len < 0) {
85 ClearOpenSslErrors();
86 return false;
87 }
88
89 return true;
90 }
91
92 QuicData* Aes128Gcm12Encrypter::EncryptPacket(
93 QuicPacketSequenceNumber sequence_number,
94 StringPiece associated_data,
95 StringPiece plaintext) {
96 size_t ciphertext_size = GetCiphertextSize(plaintext.length());
97 scoped_ptr<char[]> ciphertext(new char[ciphertext_size]);
98
99 // TODO(ianswett): Introduce a check to ensure that we don't encrypt with the
100 // same sequence number twice.
101 uint8 nonce[kNoncePrefixSize + sizeof(sequence_number)];
102 COMPILE_ASSERT(sizeof(nonce) == kAESNonceSize, bad_sequence_number_size);
103 memcpy(nonce, nonce_prefix_, kNoncePrefixSize);
104 memcpy(nonce + kNoncePrefixSize, &sequence_number, sizeof(sequence_number));
105 if (!Encrypt(StringPiece(reinterpret_cast<char*>(nonce), sizeof(nonce)),
106 associated_data, plaintext,
107 reinterpret_cast<unsigned char*>(ciphertext.get()))) {
108 return NULL;
109 }
110
111 return new QuicData(ciphertext.release(), ciphertext_size, true);
112 }
113
114 size_t Aes128Gcm12Encrypter::GetKeySize() const { return kKeySize; }
115
116 size_t Aes128Gcm12Encrypter::GetNoncePrefixSize() const {
117 return kNoncePrefixSize;
118 }
119
120 size_t Aes128Gcm12Encrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
121 return ciphertext_size - kAuthTagSize;
122 }
123
124 // An AEAD_AES_128_GCM_12 ciphertext is exactly 12 bytes longer than its
125 // corresponding plaintext.
126 size_t Aes128Gcm12Encrypter::GetCiphertextSize(size_t plaintext_size) const {
127 return plaintext_size + kAuthTagSize;
128 }
129
130 StringPiece Aes128Gcm12Encrypter::GetKey() const {
131 return StringPiece(reinterpret_cast<const char*>(key_), sizeof(key_));
132 }
133
134 StringPiece Aes128Gcm12Encrypter::GetNoncePrefix() const {
135 return StringPiece(reinterpret_cast<const char*>(nonce_prefix_),
136 kNoncePrefixSize);
137 }
138
139 } // namespace net 28 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc ('k') | net/quic/crypto/aes_128_gcm_12_encrypter_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698