OLD | NEW |
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_encrypter.h" | 5 #include "net/quic/crypto/aes_128_gcm_encrypter.h" |
6 | 6 |
7 #include <openssl/evp.h> | 7 #include <openssl/evp.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "net/quic/crypto/scoped_evp_cipher_ctx.h" | 11 #include "net/quic/crypto/scoped_evp_cipher_ctx.h" |
12 | 12 |
13 using base::StringPiece; | 13 using base::StringPiece; |
14 | 14 |
15 namespace net { | 15 namespace net { |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 const size_t kKeySize = 16; | 19 const size_t kKeySize = 16; |
20 const size_t kNoncePrefixSize = 4; | 20 const size_t kNoncePrefixSize = 4; |
21 const size_t kAuthTagSize = 16; | 21 const size_t kAuthTagSize = 16; |
22 | 22 |
23 } // namespace | 23 } // namespace |
24 | 24 |
25 Aes128GcmEncrypter::Aes128GcmEncrypter() { | 25 Aes128GcmEncrypter::Aes128GcmEncrypter() { |
26 } | 26 } |
27 | 27 |
28 // static | 28 // static |
29 bool Aes128GcmEncrypter::IsSupported() { | 29 bool Aes128GcmEncrypter::IsSupported() { return true; } |
30 return true; | |
31 } | |
32 | 30 |
33 bool Aes128GcmEncrypter::SetKey(StringPiece key) { | 31 bool Aes128GcmEncrypter::SetKey(StringPiece key) { |
34 DCHECK_EQ(key.size(), sizeof(key_)); | 32 DCHECK_EQ(key.size(), sizeof(key_)); |
35 if (key.size() != sizeof(key_)) { | 33 if (key.size() != sizeof(key_)) { |
36 return false; | 34 return false; |
37 } | 35 } |
38 memcpy(key_, key.data(), key.size()); | 36 memcpy(key_, key.data(), key.size()); |
39 return true; | 37 return true; |
40 } | 38 } |
41 | 39 |
(...skipping 14 matching lines...) Expand all Loading... |
56 // length. | 54 // length. |
57 int output_len; | 55 int output_len; |
58 | 56 |
59 if (nonce.size() != kNoncePrefixSize + sizeof(QuicPacketSequenceNumber)) { | 57 if (nonce.size() != kNoncePrefixSize + sizeof(QuicPacketSequenceNumber)) { |
60 return false; | 58 return false; |
61 } | 59 } |
62 | 60 |
63 ScopedEVPCipherCtx ctx; | 61 ScopedEVPCipherCtx ctx; |
64 | 62 |
65 // Set the cipher type and the key. The IV (nonce) is set below. | 63 // Set the cipher type and the key. The IV (nonce) is set below. |
66 if (EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, key_, | 64 if (EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, key_, NULL) == 0) { |
67 NULL) == 0) { | |
68 return false; | 65 return false; |
69 } | 66 } |
70 | 67 |
71 // Set the IV (nonce) length. | 68 // Set the IV (nonce) length. |
72 if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, nonce.size(), | 69 if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, nonce.size(), |
73 NULL) == 0) { | 70 NULL) == 0) { |
74 return false; | 71 return false; |
75 } | 72 } |
76 // Set the IV (nonce). | 73 // Set the IV (nonce). |
77 if (EVP_EncryptInit_ex(ctx.get(), NULL, NULL, NULL, | 74 if (EVP_EncryptInit_ex( |
78 reinterpret_cast<const unsigned char*>( | 75 ctx.get(), NULL, NULL, NULL, |
79 nonce.data())) == 0) { | 76 reinterpret_cast<const unsigned char*>(nonce.data())) == 0) { |
80 return false; | 77 return false; |
81 } | 78 } |
82 | 79 |
83 // If we pass a NULL, zero-length associated data to OpenSSL then it breaks. | 80 // If we pass a NULL, zero-length associated data to OpenSSL then it breaks. |
84 // Thus we only set non-empty associated data. | 81 // Thus we only set non-empty associated data. |
85 if (!associated_data.empty()) { | 82 if (!associated_data.empty()) { |
86 // Set the associated data. The second argument (output buffer) must be | 83 // Set the associated data. The second argument (output buffer) must be |
87 // NULL. | 84 // NULL. |
88 if (EVP_EncryptUpdate(ctx.get(), NULL, &output_len, | 85 if (EVP_EncryptUpdate( |
89 reinterpret_cast<const unsigned char*>( | 86 ctx.get(), NULL, &output_len, |
90 associated_data.data()), | 87 reinterpret_cast<const unsigned char*>(associated_data.data()), |
91 associated_data.size()) == 0) { | 88 associated_data.size()) == 0) { |
92 return false; | 89 return false; |
93 } | 90 } |
94 } | 91 } |
95 | 92 |
96 if (EVP_EncryptUpdate(ctx.get(), output, &output_len, | 93 if (EVP_EncryptUpdate( |
97 reinterpret_cast<const unsigned char*>( | 94 ctx.get(), output, &output_len, |
98 plaintext.data()), | 95 reinterpret_cast<const unsigned char*>(plaintext.data()), |
99 plaintext.size()) == 0) { | 96 plaintext.size()) == 0) { |
100 return false; | 97 return false; |
101 } | 98 } |
102 output += output_len; | 99 output += output_len; |
103 | 100 |
104 if (EVP_EncryptFinal_ex(ctx.get(), output, &output_len) == 0) { | 101 if (EVP_EncryptFinal_ex(ctx.get(), output, &output_len) == 0) { |
105 return false; | 102 return false; |
106 } | 103 } |
107 output += output_len; | 104 output += output_len; |
108 | 105 |
109 if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kAuthTagSize, | 106 if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kAuthTagSize, |
(...skipping 17 matching lines...) Expand all Loading... |
127 | 124 |
128 if (!Encrypt(StringPiece(reinterpret_cast<char*>(nonce_), sizeof(nonce_)), | 125 if (!Encrypt(StringPiece(reinterpret_cast<char*>(nonce_), sizeof(nonce_)), |
129 associated_data, plaintext, | 126 associated_data, plaintext, |
130 reinterpret_cast<unsigned char*>(ciphertext.get()))) { | 127 reinterpret_cast<unsigned char*>(ciphertext.get()))) { |
131 return NULL; | 128 return NULL; |
132 } | 129 } |
133 | 130 |
134 return new QuicData(ciphertext.release(), ciphertext_size, true); | 131 return new QuicData(ciphertext.release(), ciphertext_size, true); |
135 } | 132 } |
136 | 133 |
137 size_t Aes128GcmEncrypter::GetKeySize() const { | 134 size_t Aes128GcmEncrypter::GetKeySize() const { return kKeySize; } |
138 return kKeySize; | |
139 } | |
140 | 135 |
141 size_t Aes128GcmEncrypter::GetNoncePrefixSize() const { | 136 size_t Aes128GcmEncrypter::GetNoncePrefixSize() const { |
142 return kNoncePrefixSize; | 137 return kNoncePrefixSize; |
143 } | 138 } |
144 | 139 |
145 size_t Aes128GcmEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const { | 140 size_t Aes128GcmEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const { |
146 return ciphertext_size - kAuthTagSize; | 141 return ciphertext_size - kAuthTagSize; |
147 } | 142 } |
148 | 143 |
149 // An AEAD_AES_128_GCM ciphertext is exactly 16 bytes longer than its | 144 // An AEAD_AES_128_GCM ciphertext is exactly 16 bytes longer than its |
150 // corresponding plaintext. | 145 // corresponding plaintext. |
151 size_t Aes128GcmEncrypter::GetCiphertextSize(size_t plaintext_size) const { | 146 size_t Aes128GcmEncrypter::GetCiphertextSize(size_t plaintext_size) const { |
152 return plaintext_size + kAuthTagSize; | 147 return plaintext_size + kAuthTagSize; |
153 } | 148 } |
154 | 149 |
155 StringPiece Aes128GcmEncrypter::GetKey() const { | 150 StringPiece Aes128GcmEncrypter::GetKey() const { |
156 return StringPiece(reinterpret_cast<const char*>(key_), sizeof(key_)); | 151 return StringPiece(reinterpret_cast<const char*>(key_), sizeof(key_)); |
157 } | 152 } |
158 | 153 |
159 StringPiece Aes128GcmEncrypter::GetNoncePrefix() const { | 154 StringPiece Aes128GcmEncrypter::GetNoncePrefix() const { |
160 return StringPiece(reinterpret_cast<const char*>(nonce_), kNoncePrefixSize); | 155 return StringPiece(reinterpret_cast<const char*>(nonce_), kNoncePrefixSize); |
161 } | 156 } |
162 | 157 |
163 } // namespace net | 158 } // namespace net |
OLD | NEW |