Avi Drissman | e4622aa | 2022-09-08 20:36:06 | [diff] [blame] | 1 | // Copyright 2016 The Chromium Authors |
tguilbert | 4a5ac60 | 2016-09-19 21:11:25 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "base/unguessable_token.h" |
| 6 | |
Hans Wennborg | 9f3bb63d | 2020-04-21 11:12:38 | [diff] [blame] | 7 | #include <ostream> |
| 8 | |
Maksim Ivanov | 6177f0e | 2022-12-14 00:32:49 | [diff] [blame] | 9 | #include "base/check.h" |
tguilbert | 4a5ac60 | 2016-09-19 21:11:25 | [diff] [blame] | 10 | #include "base/format_macros.h" |
| 11 | #include "base/rand_util.h" |
Liza Burakova | e7e94301 | 2021-07-16 14:09:05 | [diff] [blame] | 12 | #include "build/build_config.h" |
| 13 | |
Xiaohan Wang | 38e4ebb | 2022-01-19 06:57:43 | [diff] [blame] | 14 | #if !BUILDFLAG(IS_NACL) |
Liza Burakova | e7e94301 | 2021-07-16 14:09:05 | [diff] [blame] | 15 | #include "third_party/boringssl/src/include/openssl/mem.h" |
| 16 | #endif |
tguilbert | 4a5ac60 | 2016-09-19 21:11:25 | [diff] [blame] | 17 | |
| 18 | namespace base { |
| 19 | |
Ken Rockot | 8c6991c7 | 2018-11-07 21:23:19 | [diff] [blame] | 20 | UnguessableToken::UnguessableToken(const base::Token& token) : token_(token) {} |
tguilbert | 4a5ac60 | 2016-09-19 21:11:25 | [diff] [blame] | 21 | |
| 22 | // static |
| 23 | UnguessableToken UnguessableToken::Create() { |
Maksim Ivanov | 6177f0e | 2022-12-14 00:32:49 | [diff] [blame] | 24 | Token token = Token::CreateRandom(); |
| 25 | DCHECK(!token.is_zero()); |
| 26 | return UnguessableToken(token); |
tguilbert | 4a5ac60 | 2016-09-19 21:11:25 | [diff] [blame] | 27 | } |
| 28 | |
| 29 | // static |
Daniel Cheng | 1f3b3e2 | 2018-08-04 18:54:01 | [diff] [blame] | 30 | const UnguessableToken& UnguessableToken::Null() { |
Avi Drissman | ded7717 | 2021-07-02 18:23:00 | [diff] [blame] | 31 | static const UnguessableToken null_token{}; |
| 32 | return null_token; |
Daniel Cheng | 1f3b3e2 | 2018-08-04 18:54:01 | [diff] [blame] | 33 | } |
| 34 | |
| 35 | // static |
Andrew Williams | 228be95c | 2023-01-26 15:13:01 | [diff] [blame] | 36 | absl::optional<UnguessableToken> UnguessableToken::Deserialize(uint64_t high, |
| 37 | uint64_t low) { |
Andrew Williams | 6e56276f | 2023-01-05 16:53:44 | [diff] [blame] | 38 | // Receiving a zeroed out UnguessableToken from another process means that it |
| 39 | // was never initialized via Create(). Since this method might also be used to |
| 40 | // create an UnguessableToken from data on disk, we will handle this case more |
| 41 | // gracefully since data could have been corrupted. |
| 42 | if (high == 0 && low == 0) { |
| 43 | return absl::nullopt; |
| 44 | } |
| 45 | return UnguessableToken(Token{high, low}); |
| 46 | } |
| 47 | |
Liza Burakova | e7e94301 | 2021-07-16 14:09:05 | [diff] [blame] | 48 | bool UnguessableToken::operator==(const UnguessableToken& other) const { |
Xiaohan Wang | 38e4ebb | 2022-01-19 06:57:43 | [diff] [blame] | 49 | #if BUILDFLAG(IS_NACL) |
Liza Burakova | e7e94301 | 2021-07-16 14:09:05 | [diff] [blame] | 50 | // BoringSSL is unavailable for NaCl builds so it remains timing dependent. |
| 51 | return token_ == other.token_; |
| 52 | #else |
| 53 | auto bytes = token_.AsBytes(); |
| 54 | auto other_bytes = other.token_.AsBytes(); |
| 55 | return CRYPTO_memcmp(bytes.data(), other_bytes.data(), bytes.size()) == 0; |
| 56 | #endif |
| 57 | } |
| 58 | |
tguilbert | 13be8a3 | 2016-09-20 02:04:50 | [diff] [blame] | 59 | std::ostream& operator<<(std::ostream& out, const UnguessableToken& token) { |
Pavel Feldman | 7bbfbc8 | 2017-12-29 01:42:56 | [diff] [blame] | 60 | return out << "(" << token.ToString() << ")"; |
tguilbert | 13be8a3 | 2016-09-20 02:04:50 | [diff] [blame] | 61 | } |
| 62 | |
tguilbert | 4a5ac60 | 2016-09-19 21:11:25 | [diff] [blame] | 63 | } // namespace base |