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

Side by Side Diff: components/webcrypto/algorithms/aes_cbc.cc

Issue 2528243002: Fix silent truncations when extracting values from CheckedNumeric (Closed)
Patch Set: compile cleanup and fix Created 4 years 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
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 <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/numerics/safe_math.h" 10 #include "base/numerics/safe_math.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 return Status::ErrorIncorrectSizeAesCbcIv(); 48 return Status::ErrorIncorrectSizeAesCbcIv();
49 49
50 // According to the openssl docs, the amount of data written may be as large 50 // According to the openssl docs, the amount of data written may be as large
51 // as (data_size + cipher_block_size - 1), constrained to a multiple of 51 // as (data_size + cipher_block_size - 1), constrained to a multiple of
52 // cipher_block_size. 52 // cipher_block_size.
53 base::CheckedNumeric<int> output_max_len = data.byte_length(); 53 base::CheckedNumeric<int> output_max_len = data.byte_length();
54 output_max_len += AES_BLOCK_SIZE - 1; 54 output_max_len += AES_BLOCK_SIZE - 1;
55 if (!output_max_len.IsValid()) 55 if (!output_max_len.IsValid())
56 return Status::ErrorDataTooLarge(); 56 return Status::ErrorDataTooLarge();
57 57
58 const unsigned remainder = output_max_len.ValueOrDie() % AES_BLOCK_SIZE; 58 const unsigned remainder =
59 (output_max_len % AES_BLOCK_SIZE).template ValueOrDie<unsigned>();
59 if (remainder != 0) 60 if (remainder != 0)
Tom Sepez 2016/11/29 20:06:26 I'm not grokking this. Can you explain? May be t
jschuh 2016/11/29 21:04:47 It's the template disambiguator for dependent name
jschuh 2016/11/30 23:38:52 I added some helpers and am using those at the cal
60 output_max_len += AES_BLOCK_SIZE - remainder; 61 output_max_len += AES_BLOCK_SIZE - remainder;
61 if (!output_max_len.IsValid()) 62 if (!output_max_len.IsValid())
62 return Status::ErrorDataTooLarge(); 63 return Status::ErrorDataTooLarge();
63 64
64 // Note: PKCS padding is enabled by default 65 // Note: PKCS padding is enabled by default
65 const EVP_CIPHER* const cipher = GetAESCipherByKeyLength(raw_key.size()); 66 const EVP_CIPHER* const cipher = GetAESCipherByKeyLength(raw_key.size());
66 DCHECK(cipher); 67 DCHECK(cipher);
67 68
68 bssl::ScopedEVP_CIPHER_CTX context; 69 bssl::ScopedEVP_CIPHER_CTX context;
69 if (!EVP_CipherInit_ex(context.get(), cipher, NULL, &raw_key[0], 70 if (!EVP_CipherInit_ex(context.get(), cipher, NULL, &raw_key[0],
70 params->iv().data(), cipher_operation)) { 71 params->iv().data(), cipher_operation)) {
71 return Status::OperationError(); 72 return Status::OperationError();
72 } 73 }
73 74
74 buffer->resize(output_max_len.ValueOrDie()); 75 buffer->resize(output_max_len.template ValueOrDie<size_t>());
75 76
76 int output_len = 0; 77 int output_len = 0;
77 if (!EVP_CipherUpdate(context.get(), buffer->data(), &output_len, 78 if (!EVP_CipherUpdate(context.get(), buffer->data(), &output_len,
78 data.bytes(), data.byte_length())) { 79 data.bytes(), data.byte_length())) {
79 return Status::OperationError(); 80 return Status::OperationError();
80 } 81 }
81 int final_output_chunk_len = 0; 82 int final_output_chunk_len = 0;
82 if (!EVP_CipherFinal_ex(context.get(), buffer->data() + output_len, 83 if (!EVP_CipherFinal_ex(context.get(), buffer->data() + output_len,
83 &final_output_chunk_len)) { 84 &final_output_chunk_len)) {
84 return Status::OperationError(); 85 return Status::OperationError();
(...skipping 27 matching lines...) Expand all
112 } 113 }
113 }; 114 };
114 115
115 } // namespace 116 } // namespace
116 117
117 std::unique_ptr<AlgorithmImplementation> CreateAesCbcImplementation() { 118 std::unique_ptr<AlgorithmImplementation> CreateAesCbcImplementation() {
118 return base::WrapUnique(new AesCbcImplementation); 119 return base::WrapUnique(new AesCbcImplementation);
119 } 120 }
120 121
121 } // namespace webcrypto 122 } // namespace webcrypto
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698