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/core/crypto/strike_register.h" | 5 #include "net/quic/core/crypto/strike_register.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 | 11 |
12 using std::pair; | |
13 using std::set; | |
14 using std::vector; | |
15 | |
16 namespace net { | 12 namespace net { |
17 | 13 |
18 namespace { | 14 namespace { |
19 | 15 |
20 uint32_t GetInitialHorizon(uint32_t current_time_internal, | 16 uint32_t GetInitialHorizon(uint32_t current_time_internal, |
21 uint32_t window_secs, | 17 uint32_t window_secs, |
22 StrikeRegister::StartupType startup) { | 18 StrikeRegister::StartupType startup) { |
23 if (startup == StrikeRegister::DENY_REQUESTS_AT_STARTUP) { | 19 if (startup == StrikeRegister::DENY_REQUESTS_AT_STARTUP) { |
24 // The horizon is initially set |window_secs| into the future because, if | 20 // The horizon is initially set |window_secs| into the future because, if |
25 // we just crashed, then we may have accepted nonces in the span | 21 // we just crashed, then we may have accepted nonces in the span |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 const uint32_t current_time = ExternalTimeToInternal(current_time_external); | 139 const uint32_t current_time = ExternalTimeToInternal(current_time_external); |
144 | 140 |
145 // Check to see if the orbit is correct. | 141 // Check to see if the orbit is correct. |
146 if (memcmp(nonce + sizeof(current_time), orbit_, sizeof(orbit_))) { | 142 if (memcmp(nonce + sizeof(current_time), orbit_, sizeof(orbit_))) { |
147 return NONCE_INVALID_ORBIT_FAILURE; | 143 return NONCE_INVALID_ORBIT_FAILURE; |
148 } | 144 } |
149 | 145 |
150 const uint32_t nonce_time = ExternalTimeToInternal(TimeFromBytes(nonce)); | 146 const uint32_t nonce_time = ExternalTimeToInternal(TimeFromBytes(nonce)); |
151 | 147 |
152 // Check that the timestamp is in the valid range. | 148 // Check that the timestamp is in the valid range. |
153 pair<uint32_t, uint32_t> valid_range = | 149 std::pair<uint32_t, uint32_t> valid_range = |
154 StrikeRegister::GetValidRange(current_time); | 150 StrikeRegister::GetValidRange(current_time); |
155 if (nonce_time < valid_range.first || nonce_time > valid_range.second) { | 151 if (nonce_time < valid_range.first || nonce_time > valid_range.second) { |
156 return NONCE_INVALID_TIME_FAILURE; | 152 return NONCE_INVALID_TIME_FAILURE; |
157 } | 153 } |
158 | 154 |
159 // We strip the orbit out of the nonce. | 155 // We strip the orbit out of the nonce. |
160 uint8_t value[24]; | 156 uint8_t value[24]; |
161 memcpy(value, nonce, sizeof(nonce_time)); | 157 memcpy(value, nonce, sizeof(nonce_time)); |
162 memcpy(value + sizeof(nonce_time), | 158 memcpy(value + sizeof(nonce_time), |
163 nonce + sizeof(nonce_time) + sizeof(orbit_), | 159 nonce + sizeof(nonce_time) + sizeof(orbit_), |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 return NONCE_OK; | 265 return NONCE_OK; |
270 } | 266 } |
271 | 267 |
272 const uint8_t* StrikeRegister::orbit() const { | 268 const uint8_t* StrikeRegister::orbit() const { |
273 return orbit_; | 269 return orbit_; |
274 } | 270 } |
275 | 271 |
276 uint32_t StrikeRegister::GetCurrentValidWindowSecs( | 272 uint32_t StrikeRegister::GetCurrentValidWindowSecs( |
277 uint32_t current_time_external) const { | 273 uint32_t current_time_external) const { |
278 uint32_t current_time = ExternalTimeToInternal(current_time_external); | 274 uint32_t current_time = ExternalTimeToInternal(current_time_external); |
279 pair<uint32_t, uint32_t> valid_range = | 275 std::pair<uint32_t, uint32_t> valid_range = |
280 StrikeRegister::GetValidRange(current_time); | 276 StrikeRegister::GetValidRange(current_time); |
281 if (valid_range.second >= valid_range.first) { | 277 if (valid_range.second >= valid_range.first) { |
282 return valid_range.second - current_time + 1; | 278 return valid_range.second - current_time + 1; |
283 } else { | 279 } else { |
284 return 0; | 280 return 0; |
285 } | 281 } |
286 } | 282 } |
287 | 283 |
288 void StrikeRegister::Validate() { | 284 void StrikeRegister::Validate() { |
289 set<uint32_t> free_internal_nodes; | 285 std::set<uint32_t> free_internal_nodes; |
290 for (uint32_t i = internal_node_free_head_; i != kNil; | 286 for (uint32_t i = internal_node_free_head_; i != kNil; |
291 i = internal_nodes_[i].next()) { | 287 i = internal_nodes_[i].next()) { |
292 CHECK_LT(i, max_entries_); | 288 CHECK_LT(i, max_entries_); |
293 CHECK_EQ(free_internal_nodes.count(i), 0u); | 289 CHECK_EQ(free_internal_nodes.count(i), 0u); |
294 free_internal_nodes.insert(i); | 290 free_internal_nodes.insert(i); |
295 } | 291 } |
296 | 292 |
297 set<uint32_t> free_external_nodes; | 293 std::set<uint32_t> free_external_nodes; |
298 for (uint32_t i = external_node_free_head_; i != kNil; | 294 for (uint32_t i = external_node_free_head_; i != kNil; |
299 i = external_node_next_ptr(i)) { | 295 i = external_node_next_ptr(i)) { |
300 CHECK_LT(i, max_entries_); | 296 CHECK_LT(i, max_entries_); |
301 CHECK_EQ(free_external_nodes.count(i), 0u); | 297 CHECK_EQ(free_external_nodes.count(i), 0u); |
302 free_external_nodes.insert(i); | 298 free_external_nodes.insert(i); |
303 } | 299 } |
304 | 300 |
305 set<uint32_t> used_external_nodes; | 301 std::set<uint32_t> used_external_nodes; |
306 set<uint32_t> used_internal_nodes; | 302 std::set<uint32_t> used_internal_nodes; |
307 | 303 |
308 if (internal_node_head_ != kNil && | 304 if (internal_node_head_ != kNil && |
309 ((internal_node_head_ >> 8) & kExternalFlag) == 0) { | 305 ((internal_node_head_ >> 8) & kExternalFlag) == 0) { |
310 vector<pair<unsigned, bool>> bits; | 306 std::vector<std::pair<unsigned, bool>> bits; |
311 ValidateTree(internal_node_head_ >> 8, -1, bits, free_internal_nodes, | 307 ValidateTree(internal_node_head_ >> 8, -1, bits, free_internal_nodes, |
312 free_external_nodes, &used_internal_nodes, | 308 free_external_nodes, &used_internal_nodes, |
313 &used_external_nodes); | 309 &used_external_nodes); |
314 } | 310 } |
315 } | 311 } |
316 | 312 |
317 // static | 313 // static |
318 uint32_t StrikeRegister::TimeFromBytes(const uint8_t d[4]) { | 314 uint32_t StrikeRegister::TimeFromBytes(const uint8_t d[4]) { |
319 return static_cast<uint32_t>(d[0]) << 24 | static_cast<uint32_t>(d[1]) << 16 | | 315 return static_cast<uint32_t>(d[0]) << 24 | static_cast<uint32_t>(d[1]) << 16 | |
320 static_cast<uint32_t>(d[2]) << 8 | static_cast<uint32_t>(d[3]); | 316 static_cast<uint32_t>(d[2]) << 8 | static_cast<uint32_t>(d[3]); |
321 } | 317 } |
322 | 318 |
323 pair<uint32_t, uint32_t> StrikeRegister::GetValidRange( | 319 std::pair<uint32_t, uint32_t> StrikeRegister::GetValidRange( |
324 uint32_t current_time_internal) const { | 320 uint32_t current_time_internal) const { |
325 if (current_time_internal < horizon_) { | 321 if (current_time_internal < horizon_) { |
326 // Empty valid range. | 322 // Empty valid range. |
327 return std::make_pair(std::numeric_limits<uint32_t>::max(), 0); | 323 return std::make_pair(std::numeric_limits<uint32_t>::max(), 0); |
328 } | 324 } |
329 | 325 |
330 uint32_t lower_bound; | 326 uint32_t lower_bound; |
331 if (current_time_internal >= window_secs_) { | 327 if (current_time_internal >= window_secs_) { |
332 lower_bound = std::max(horizon_, current_time_internal - window_secs_); | 328 lower_bound = std::max(horizon_, current_time_internal - window_secs_); |
333 } else { | 329 } else { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 void StrikeRegister::FreeExternalNode(uint32_t index) { | 431 void StrikeRegister::FreeExternalNode(uint32_t index) { |
436 external_node_next_ptr(index) = external_node_free_head_; | 432 external_node_next_ptr(index) = external_node_free_head_; |
437 external_node_free_head_ = index; | 433 external_node_free_head_ = index; |
438 } | 434 } |
439 | 435 |
440 void StrikeRegister::FreeInternalNode(uint32_t index) { | 436 void StrikeRegister::FreeInternalNode(uint32_t index) { |
441 internal_nodes_[index].SetNextPtr(internal_node_free_head_); | 437 internal_nodes_[index].SetNextPtr(internal_node_free_head_); |
442 internal_node_free_head_ = index; | 438 internal_node_free_head_ = index; |
443 } | 439 } |
444 | 440 |
445 void StrikeRegister::ValidateTree(uint32_t internal_node, | 441 void StrikeRegister::ValidateTree( |
446 int last_bit, | 442 uint32_t internal_node, |
447 const vector<pair<unsigned, bool>>& bits, | 443 int last_bit, |
448 const set<uint32_t>& free_internal_nodes, | 444 const std::vector<std::pair<unsigned, bool>>& bits, |
449 const set<uint32_t>& free_external_nodes, | 445 const std::set<uint32_t>& free_internal_nodes, |
450 set<uint32_t>* used_internal_nodes, | 446 const std::set<uint32_t>& free_external_nodes, |
451 set<uint32_t>* used_external_nodes) { | 447 std::set<uint32_t>* used_internal_nodes, |
| 448 std::set<uint32_t>* used_external_nodes) { |
452 CHECK_LT(internal_node, max_entries_); | 449 CHECK_LT(internal_node, max_entries_); |
453 const InternalNode* i = &internal_nodes_[internal_node]; | 450 const InternalNode* i = &internal_nodes_[internal_node]; |
454 unsigned bit = 0; | 451 unsigned bit = 0; |
455 switch (i->otherbits()) { | 452 switch (i->otherbits()) { |
456 case 0xff & ~(1 << 7): | 453 case 0xff & ~(1 << 7): |
457 bit = 0; | 454 bit = 0; |
458 break; | 455 break; |
459 case 0xff & ~(1 << 6): | 456 case 0xff & ~(1 << 6): |
460 bit = 1; | 457 bit = 1; |
461 break; | 458 break; |
(...skipping 26 matching lines...) Expand all Loading... |
488 | 485 |
489 CHECK_EQ(free_internal_nodes.count(internal_node), 0u); | 486 CHECK_EQ(free_internal_nodes.count(internal_node), 0u); |
490 | 487 |
491 for (unsigned child = 0; child < 2; child++) { | 488 for (unsigned child = 0; child < 2; child++) { |
492 if (i->child(child) & kExternalFlag) { | 489 if (i->child(child) & kExternalFlag) { |
493 uint32_t ext = i->child(child) & ~kExternalFlag; | 490 uint32_t ext = i->child(child) & ~kExternalFlag; |
494 CHECK_EQ(free_external_nodes.count(ext), 0u); | 491 CHECK_EQ(free_external_nodes.count(ext), 0u); |
495 CHECK_EQ(used_external_nodes->count(ext), 0u); | 492 CHECK_EQ(used_external_nodes->count(ext), 0u); |
496 used_external_nodes->insert(ext); | 493 used_external_nodes->insert(ext); |
497 const uint8_t* bytes = external_node(ext); | 494 const uint8_t* bytes = external_node(ext); |
498 for (const pair<unsigned, bool>& pair : bits) { | 495 for (const std::pair<unsigned, bool>& pair : bits) { |
499 unsigned byte = pair.first / 8; | 496 unsigned byte = pair.first / 8; |
500 DCHECK_LE(byte, 0xffu); | 497 DCHECK_LE(byte, 0xffu); |
501 unsigned bit_new = pair.first % 8; | 498 unsigned bit_new = pair.first % 8; |
502 static const uint8_t kMasks[8] = {0x80, 0x40, 0x20, 0x10, | 499 static const uint8_t kMasks[8] = {0x80, 0x40, 0x20, 0x10, |
503 0x08, 0x04, 0x02, 0x01}; | 500 0x08, 0x04, 0x02, 0x01}; |
504 CHECK_EQ((bytes[byte] & kMasks[bit_new]) != 0, pair.second); | 501 CHECK_EQ((bytes[byte] & kMasks[bit_new]) != 0, pair.second); |
505 } | 502 } |
506 } else { | 503 } else { |
507 uint32_t inter = i->child(child); | 504 uint32_t inter = i->child(child); |
508 vector<pair<unsigned, bool>> new_bits(bits); | 505 std::vector<std::pair<unsigned, bool>> new_bits(bits); |
509 new_bits.push_back(pair<unsigned, bool>(bit, child != 0)); | 506 new_bits.push_back(std::pair<unsigned, bool>(bit, child != 0)); |
510 CHECK_EQ(free_internal_nodes.count(inter), 0u); | 507 CHECK_EQ(free_internal_nodes.count(inter), 0u); |
511 CHECK_EQ(used_internal_nodes->count(inter), 0u); | 508 CHECK_EQ(used_internal_nodes->count(inter), 0u); |
512 used_internal_nodes->insert(inter); | 509 used_internal_nodes->insert(inter); |
513 ValidateTree(inter, bit, bits, free_internal_nodes, free_external_nodes, | 510 ValidateTree(inter, bit, bits, free_internal_nodes, free_external_nodes, |
514 used_internal_nodes, used_external_nodes); | 511 used_internal_nodes, used_external_nodes); |
515 } | 512 } |
516 } | 513 } |
517 } | 514 } |
518 | 515 |
519 } // namespace net | 516 } // namespace net |
OLD | NEW |