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

Side by Side Diff: content/child/webcrypto/openssl/aes_cbc_openssl.cc

Issue 405693002: [refactor] Use base::CheckedNumeric<> in place of manual checks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix testing order for openssl Created 6 years, 5 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
« no previous file with comments | « content/child/webcrypto/nss/rsa_key_nss.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <openssl/aes.h> 5 #include <openssl/aes.h>
6 #include <openssl/evp.h> 6 #include <openssl/evp.h>
7 7
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/numerics/safe_math.h"
9 #include "content/child/webcrypto/crypto_data.h" 10 #include "content/child/webcrypto/crypto_data.h"
10 #include "content/child/webcrypto/openssl/aes_key_openssl.h" 11 #include "content/child/webcrypto/openssl/aes_key_openssl.h"
11 #include "content/child/webcrypto/openssl/key_openssl.h" 12 #include "content/child/webcrypto/openssl/key_openssl.h"
12 #include "content/child/webcrypto/status.h" 13 #include "content/child/webcrypto/status.h"
13 #include "content/child/webcrypto/webcrypto_util.h" 14 #include "content/child/webcrypto/webcrypto_util.h"
14 #include "crypto/scoped_openssl_types.h" 15 #include "crypto/scoped_openssl_types.h"
15 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" 16 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
16 17
17 namespace content { 18 namespace content {
18 19
(...skipping 21 matching lines...) Expand all
40 const blink::WebCryptoKey& key, 41 const blink::WebCryptoKey& key,
41 const CryptoData& data, 42 const CryptoData& data,
42 std::vector<uint8_t>* buffer) { 43 std::vector<uint8_t>* buffer) {
43 const blink::WebCryptoAesCbcParams* params = algorithm.aesCbcParams(); 44 const blink::WebCryptoAesCbcParams* params = algorithm.aesCbcParams();
44 const std::vector<uint8_t>& raw_key = 45 const std::vector<uint8_t>& raw_key =
45 SymKeyOpenSsl::Cast(key)->raw_key_data(); 46 SymKeyOpenSsl::Cast(key)->raw_key_data();
46 47
47 if (params->iv().size() != 16) 48 if (params->iv().size() != 16)
48 return Status::ErrorIncorrectSizeAesCbcIv(); 49 return Status::ErrorIncorrectSizeAesCbcIv();
49 50
50 if (data.byte_length() >= INT_MAX - AES_BLOCK_SIZE) { 51 // According to the openssl docs, the amount of data written may be as large
51 // TODO(padolph): Handle this by chunking the input fed into OpenSSL. Right 52 // as (data_size + cipher_block_size - 1), constrained to a multiple of
52 // now it doesn't make much difference since the one-shot API would end up 53 // cipher_block_size.
53 // blowing out the memory and crashing anyway. 54 base::CheckedNumeric<unsigned int> output_max_len = data.byte_length();
eroman 2014/07/21 18:12:42 I have uploaded a new patchset which fixes a probl
55 output_max_len += AES_BLOCK_SIZE - 1;
56 if (!output_max_len.IsValid())
54 return Status::ErrorDataTooLarge(); 57 return Status::ErrorDataTooLarge();
55 } 58
59 const unsigned remainder = output_max_len.ValueOrDie() % AES_BLOCK_SIZE;
60 if (remainder != 0)
61 output_max_len += AES_BLOCK_SIZE - remainder;
62 if (!output_max_len.IsValid())
63 return Status::ErrorDataTooLarge();
56 64
57 // Note: PKCS padding is enabled by default 65 // Note: PKCS padding is enabled by default
58 crypto::ScopedOpenSSL<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free>::Type context( 66 crypto::ScopedOpenSSL<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free>::Type context(
59 EVP_CIPHER_CTX_new()); 67 EVP_CIPHER_CTX_new());
60 68
61 if (!context.get()) 69 if (!context.get())
62 return Status::OperationError(); 70 return Status::OperationError();
63 71
64 const EVP_CIPHER* const cipher = GetAESCipherByKeyLength(raw_key.size()); 72 const EVP_CIPHER* const cipher = GetAESCipherByKeyLength(raw_key.size());
65 DCHECK(cipher); 73 DCHECK(cipher);
66 74
67 if (!EVP_CipherInit_ex(context.get(), 75 if (!EVP_CipherInit_ex(context.get(),
68 cipher, 76 cipher,
69 NULL, 77 NULL,
70 &raw_key[0], 78 &raw_key[0],
71 params->iv().data(), 79 params->iv().data(),
72 cipher_operation)) { 80 cipher_operation)) {
73 return Status::OperationError(); 81 return Status::OperationError();
74 } 82 }
75 83
76 // According to the openssl docs, the amount of data written may be as large 84 buffer->resize(output_max_len.ValueOrDie());
77 // as (data_size + cipher_block_size - 1), constrained to a multiple of
78 // cipher_block_size.
79 unsigned int output_max_len = data.byte_length() + AES_BLOCK_SIZE - 1;
80 const unsigned remainder = output_max_len % AES_BLOCK_SIZE;
81 if (remainder != 0)
82 output_max_len += AES_BLOCK_SIZE - remainder;
83 DCHECK_GT(output_max_len, data.byte_length());
84
85 buffer->resize(output_max_len);
86 85
87 unsigned char* const buffer_data = Uint8VectorStart(buffer); 86 unsigned char* const buffer_data = Uint8VectorStart(buffer);
88 87
89 int output_len = 0; 88 int output_len = 0;
90 if (!EVP_CipherUpdate(context.get(), 89 if (!EVP_CipherUpdate(context.get(),
91 buffer_data, 90 buffer_data,
92 &output_len, 91 &output_len,
93 data.bytes(), 92 data.bytes(),
94 data.byte_length())) 93 data.byte_length()))
95 return Status::OperationError(); 94 return Status::OperationError();
96 int final_output_chunk_len = 0; 95 int final_output_chunk_len = 0;
97 if (!EVP_CipherFinal_ex( 96 if (!EVP_CipherFinal_ex(
98 context.get(), buffer_data + output_len, &final_output_chunk_len)) { 97 context.get(), buffer_data + output_len, &final_output_chunk_len)) {
99 return Status::OperationError(); 98 return Status::OperationError();
100 } 99 }
101 100
102 const unsigned int final_output_len = 101 const unsigned int final_output_len =
103 static_cast<unsigned int>(output_len) + 102 static_cast<unsigned int>(output_len) +
104 static_cast<unsigned int>(final_output_chunk_len); 103 static_cast<unsigned int>(final_output_chunk_len);
105 DCHECK_LE(final_output_len, output_max_len);
106 104
107 buffer->resize(final_output_len); 105 buffer->resize(final_output_len);
108 106
109 return Status::Success(); 107 return Status::Success();
110 } 108 }
111 109
112 class AesCbcImplementation : public AesAlgorithm { 110 class AesCbcImplementation : public AesAlgorithm {
113 public: 111 public:
114 AesCbcImplementation() : AesAlgorithm("CBC") {} 112 AesCbcImplementation() : AesAlgorithm("CBC") {}
115 113
(...skipping 14 matching lines...) Expand all
130 128
131 } // namespace 129 } // namespace
132 130
133 AlgorithmImplementation* CreatePlatformAesCbcImplementation() { 131 AlgorithmImplementation* CreatePlatformAesCbcImplementation() {
134 return new AesCbcImplementation; 132 return new AesCbcImplementation;
135 } 133 }
136 134
137 } // namespace webcrypto 135 } // namespace webcrypto
138 136
139 } // namespace content 137 } // namespace content
OLDNEW
« no previous file with comments | « content/child/webcrypto/nss/rsa_key_nss.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698