1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
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 "quiche/quic/core/crypto/null_decrypter.h"
6
7 #include <cstdint>
8
9 #include "absl/numeric/int128.h"
10 #include "absl/strings/string_view.h"
11 #include "quiche/quic/core/quic_data_reader.h"
12 #include "quiche/quic/core/quic_utils.h"
13 #include "quiche/quic/platform/api/quic_bug_tracker.h"
14 #include "quiche/common/quiche_endian.h"
15
16 namespace quic {
17
NullDecrypter(Perspective perspective)18 NullDecrypter::NullDecrypter(Perspective perspective)
19 : perspective_(perspective) {}
20
SetKey(absl::string_view key)21 bool NullDecrypter::SetKey(absl::string_view key) { return key.empty(); }
22
SetNoncePrefix(absl::string_view nonce_prefix)23 bool NullDecrypter::SetNoncePrefix(absl::string_view nonce_prefix) {
24 return nonce_prefix.empty();
25 }
26
SetIV(absl::string_view iv)27 bool NullDecrypter::SetIV(absl::string_view iv) { return iv.empty(); }
28
SetHeaderProtectionKey(absl::string_view key)29 bool NullDecrypter::SetHeaderProtectionKey(absl::string_view key) {
30 return key.empty();
31 }
32
SetPreliminaryKey(absl::string_view)33 bool NullDecrypter::SetPreliminaryKey(absl::string_view /*key*/) {
34 QUIC_BUG(quic_bug_10652_1) << "Should not be called";
35 return false;
36 }
37
SetDiversificationNonce(const DiversificationNonce &)38 bool NullDecrypter::SetDiversificationNonce(
39 const DiversificationNonce& /*nonce*/) {
40 QUIC_BUG(quic_bug_10652_2) << "Should not be called";
41 return true;
42 }
43
DecryptPacket(uint64_t,absl::string_view associated_data,absl::string_view ciphertext,char * output,size_t * output_length,size_t max_output_length)44 bool NullDecrypter::DecryptPacket(uint64_t /*packet_number*/,
45 absl::string_view associated_data,
46 absl::string_view ciphertext, char* output,
47 size_t* output_length,
48 size_t max_output_length) {
49 QuicDataReader reader(ciphertext.data(), ciphertext.length(),
50 quiche::HOST_BYTE_ORDER);
51 absl::uint128 hash;
52
53 if (!ReadHash(&reader, &hash)) {
54 return false;
55 }
56
57 absl::string_view plaintext = reader.ReadRemainingPayload();
58 if (plaintext.length() > max_output_length) {
59 QUIC_BUG(quic_bug_10652_3)
60 << "Output buffer must be larger than the plaintext.";
61 return false;
62 }
63 if (hash != ComputeHash(associated_data, plaintext)) {
64 return false;
65 }
66 // Copy the plaintext to output.
67 memcpy(output, plaintext.data(), plaintext.length());
68 *output_length = plaintext.length();
69 return true;
70 }
71
GenerateHeaderProtectionMask(QuicDataReader *)72 std::string NullDecrypter::GenerateHeaderProtectionMask(
73 QuicDataReader* /*sample_reader*/) {
74 return std::string(5, 0);
75 }
76
GetKeySize() const77 size_t NullDecrypter::GetKeySize() const { return 0; }
78
GetNoncePrefixSize() const79 size_t NullDecrypter::GetNoncePrefixSize() const { return 0; }
80
GetIVSize() const81 size_t NullDecrypter::GetIVSize() const { return 0; }
82
GetKey() const83 absl::string_view NullDecrypter::GetKey() const { return absl::string_view(); }
84
GetNoncePrefix() const85 absl::string_view NullDecrypter::GetNoncePrefix() const {
86 return absl::string_view();
87 }
88
cipher_id() const89 uint32_t NullDecrypter::cipher_id() const { return 0; }
90
GetIntegrityLimit() const91 QuicPacketCount NullDecrypter::GetIntegrityLimit() const {
92 return std::numeric_limits<QuicPacketCount>::max();
93 }
94
ReadHash(QuicDataReader * reader,absl::uint128 * hash)95 bool NullDecrypter::ReadHash(QuicDataReader* reader, absl::uint128* hash) {
96 uint64_t lo;
97 uint32_t hi;
98 if (!reader->ReadUInt64(&lo) || !reader->ReadUInt32(&hi)) {
99 return false;
100 }
101 *hash = absl::MakeUint128(hi, lo);
102 return true;
103 }
104
ComputeHash(const absl::string_view data1,const absl::string_view data2) const105 absl::uint128 NullDecrypter::ComputeHash(const absl::string_view data1,
106 const absl::string_view data2) const {
107 absl::uint128 correct_hash;
108 if (perspective_ == Perspective::IS_CLIENT) {
109 // Peer is a server.
110 correct_hash = QuicUtils::FNV1a_128_Hash_Three(data1, data2, "Server");
111 } else {
112 // Peer is a client.
113 correct_hash = QuicUtils::FNV1a_128_Hash_Three(data1, data2, "Client");
114 }
115 absl::uint128 mask = absl::MakeUint128(UINT64_C(0x0), UINT64_C(0xffffffff));
116 mask <<= 96;
117 correct_hash &= ~mask;
118 return correct_hash;
119 }
120
121 } // namespace quic
122