| 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 |