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_decrypter.h" | 5 #include "net/quic/crypto/aes_128_gcm_decrypter.h" |
6 | 6 |
7 #include <openssl/evp.h> | 7 #include <openssl/evp.h> |
8 | 8 |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "net/quic/crypto/scoped_evp_cipher_ctx.h" | 10 #include "net/quic/crypto/scoped_evp_cipher_ctx.h" |
11 | 11 |
12 using base::StringPiece; | 12 using base::StringPiece; |
13 | 13 |
14 namespace net { | 14 namespace net { |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 const size_t kKeySize = 16; | 18 const size_t kKeySize = 16; |
19 const size_t kNoncePrefixSize = 4; | 19 const size_t kNoncePrefixSize = 4; |
20 const size_t kAuthTagSize = 16; | 20 const size_t kAuthTagSize = 16; |
21 | 21 |
22 } // namespace | 22 } // namespace |
23 | 23 |
24 Aes128GcmDecrypter::Aes128GcmDecrypter() { | 24 Aes128GcmDecrypter::Aes128GcmDecrypter() {} |
25 } | |
26 | 25 |
27 // static | 26 // static |
28 bool Aes128GcmDecrypter::IsSupported() { | 27 bool Aes128GcmDecrypter::IsSupported() { return true; } |
29 return true; | |
30 } | |
31 | 28 |
32 bool Aes128GcmDecrypter::SetKey(StringPiece key) { | 29 bool Aes128GcmDecrypter::SetKey(StringPiece key) { |
33 DCHECK_EQ(key.size(), sizeof(key_)); | 30 DCHECK_EQ(key.size(), sizeof(key_)); |
34 if (key.size() != sizeof(key_)) { | 31 if (key.size() != sizeof(key_)) { |
35 return false; | 32 return false; |
36 } | 33 } |
37 memcpy(key_, key.data(), key.size()); | 34 memcpy(key_, key.data(), key.size()); |
38 return true; | 35 return true; |
39 } | 36 } |
40 | 37 |
(...skipping 15 matching lines...) Expand all Loading... |
56 nonce.size() != kNoncePrefixSize + sizeof(QuicPacketSequenceNumber)) { | 53 nonce.size() != kNoncePrefixSize + sizeof(QuicPacketSequenceNumber)) { |
57 return false; | 54 return false; |
58 } | 55 } |
59 const size_t plaintext_size = ciphertext.length() - kAuthTagSize; | 56 const size_t plaintext_size = ciphertext.length() - kAuthTagSize; |
60 // |len| is passed to an OpenSSL function to receive the output length. | 57 // |len| is passed to an OpenSSL function to receive the output length. |
61 int len; | 58 int len; |
62 | 59 |
63 ScopedEVPCipherCtx ctx; | 60 ScopedEVPCipherCtx ctx; |
64 | 61 |
65 // Set the cipher type and the key. The IV (nonce) is set below. | 62 // Set the cipher type and the key. The IV (nonce) is set below. |
66 if (EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, key_, | 63 if (EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, key_, NULL) == 0) { |
67 NULL) == 0) { | |
68 return false; | 64 return false; |
69 } | 65 } |
70 | 66 |
71 // Set the IV (nonce) length. | 67 // Set the IV (nonce) length. |
72 if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, nonce.size(), | 68 if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, nonce.size(), |
73 NULL) == 0) { | 69 NULL) == 0) { |
74 return false; | 70 return false; |
75 } | 71 } |
76 // Set the IV (nonce). | 72 // Set the IV (nonce). |
77 if (EVP_DecryptInit_ex(ctx.get(), NULL, NULL, NULL, | 73 if (EVP_DecryptInit_ex( |
78 reinterpret_cast<const unsigned char*>( | 74 ctx.get(), NULL, NULL, NULL, |
79 nonce.data())) == 0) { | 75 reinterpret_cast<const unsigned char*>(nonce.data())) == 0) { |
80 return false; | 76 return false; |
81 } | 77 } |
82 | 78 |
83 // Set the authentication tag. | 79 // Set the authentication tag. |
84 if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kAuthTagSize, | 80 if (EVP_CIPHER_CTX_ctrl( |
85 const_cast<char*>(ciphertext.data()) + | 81 ctx.get(), EVP_CTRL_GCM_SET_TAG, kAuthTagSize, |
86 plaintext_size) == 0) { | 82 const_cast<char*>(ciphertext.data()) + plaintext_size) == 0) { |
87 return false; | 83 return false; |
88 } | 84 } |
89 | 85 |
90 // If we pass a NULL, zero-length associated data to OpenSSL then it breaks. | 86 // If we pass a NULL, zero-length associated data to OpenSSL then it breaks. |
91 // Thus we only set non-empty associated data. | 87 // Thus we only set non-empty associated data. |
92 if (!associated_data.empty()) { | 88 if (!associated_data.empty()) { |
93 // Set the associated data. The second argument (output buffer) must be | 89 // Set the associated data. The second argument (output buffer) must be |
94 // NULL. | 90 // NULL. |
95 if (EVP_DecryptUpdate(ctx.get(), NULL, &len, | 91 if (EVP_DecryptUpdate( |
96 reinterpret_cast<const unsigned char*>( | 92 ctx.get(), NULL, &len, |
97 associated_data.data()), | 93 reinterpret_cast<const unsigned char*>(associated_data.data()), |
98 associated_data.size()) == 0) { | 94 associated_data.size()) == 0) { |
99 return false; | 95 return false; |
100 } | 96 } |
101 } | 97 } |
102 | 98 |
103 if (EVP_DecryptUpdate(ctx.get(), output, &len, | 99 if (EVP_DecryptUpdate( |
104 reinterpret_cast<const unsigned char*>( | 100 ctx.get(), output, &len, |
105 ciphertext.data()), | 101 reinterpret_cast<const unsigned char*>(ciphertext.data()), |
106 plaintext_size) == 0) { | 102 plaintext_size) == 0) { |
107 return false; | 103 return false; |
108 } | 104 } |
109 output += len; | 105 output += len; |
110 | 106 |
111 if (EVP_DecryptFinal_ex(ctx.get(), output, &len) == 0) { | 107 if (EVP_DecryptFinal_ex(ctx.get(), output, &len) == 0) { |
112 return false; | 108 return false; |
113 } | 109 } |
114 output += len; | 110 output += len; |
115 | 111 |
116 *output_length = plaintext_size; | 112 *output_length = plaintext_size; |
(...skipping 25 matching lines...) Expand all Loading... |
142 | 138 |
143 StringPiece Aes128GcmDecrypter::GetKey() const { | 139 StringPiece Aes128GcmDecrypter::GetKey() const { |
144 return StringPiece(reinterpret_cast<const char*>(key_), sizeof(key_)); | 140 return StringPiece(reinterpret_cast<const char*>(key_), sizeof(key_)); |
145 } | 141 } |
146 | 142 |
147 StringPiece Aes128GcmDecrypter::GetNoncePrefix() const { | 143 StringPiece Aes128GcmDecrypter::GetNoncePrefix() const { |
148 return StringPiece(reinterpret_cast<const char*>(nonce_), kNoncePrefixSize); | 144 return StringPiece(reinterpret_cast<const char*>(nonce_), kNoncePrefixSize); |
149 } | 145 } |
150 | 146 |
151 } // namespace net | 147 } // namespace net |
OLD | NEW |