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 "net/quic/crypto/null_decrypter.h"
6 #include "net/quic/quic_utils.h"
7 #include "net/quic/quic_data_reader.h"
8
9 using base::StringPiece;
10 using std::string;
11
12 namespace net {
13
NullDecrypter()14 NullDecrypter::NullDecrypter() {}
15
SetKey(StringPiece key)16 bool NullDecrypter::SetKey(StringPiece key) { return key.empty(); }
17
SetNoncePrefix(StringPiece nonce_prefix)18 bool NullDecrypter::SetNoncePrefix(StringPiece nonce_prefix) {
19 return nonce_prefix.empty();
20 }
21
Decrypt(StringPiece,StringPiece associated_data,StringPiece ciphertext,unsigned char * output,size_t * output_length)22 bool NullDecrypter::Decrypt(StringPiece /*nonce*/,
23 StringPiece associated_data,
24 StringPiece ciphertext,
25 unsigned char* output,
26 size_t* output_length) {
27 QuicDataReader reader(ciphertext.data(), ciphertext.length());
28
29 uint128 hash;
30 if (!ReadHash(&reader, &hash)) {
31 return false;
32 }
33
34 StringPiece plaintext = reader.ReadRemainingPayload();
35
36 // TODO(rch): avoid buffer copy here
37 string buffer = associated_data.as_string();
38 plaintext.AppendToString(&buffer);
39 if (hash != ComputeHash(buffer)) {
40 return false;
41 }
42 memcpy(output, plaintext.data(), plaintext.length());
43 *output_length = plaintext.length();
44 return true;
45 }
46
DecryptPacket(QuicPacketSequenceNumber,StringPiece associated_data,StringPiece ciphertext)47 QuicData* NullDecrypter::DecryptPacket(QuicPacketSequenceNumber /*seq_number*/,
48 StringPiece associated_data,
49 StringPiece ciphertext) {
50 // It's worth duplicating |Decrypt|, above, in order to save a copy by using
51 // the shared-data QuicData constructor directly.
52 QuicDataReader reader(ciphertext.data(), ciphertext.length());
53
54 uint128 hash;
55 if (!ReadHash(&reader, &hash)) {
56 return NULL;
57 }
58
59 StringPiece plaintext = reader.ReadRemainingPayload();
60
61 // TODO(rch): avoid buffer copy here
62 string buffer = associated_data.as_string();
63 plaintext.AppendToString(&buffer);
64
65 if (hash != ComputeHash(buffer)) {
66 return NULL;
67 }
68 return new QuicData(plaintext.data(), plaintext.length());
69 }
70
GetKey() const71 StringPiece NullDecrypter::GetKey() const { return StringPiece(); }
72
GetNoncePrefix() const73 StringPiece NullDecrypter::GetNoncePrefix() const { return StringPiece(); }
74
ReadHash(QuicDataReader * reader,uint128 * hash)75 bool NullDecrypter::ReadHash(QuicDataReader* reader, uint128* hash) {
76 uint64 lo;
77 uint32 hi;
78 if (!reader->ReadUInt64(&lo) ||
79 !reader->ReadUInt32(&hi)) {
80 return false;
81 }
82 *hash = hi;
83 *hash <<= 64;
84 *hash += lo;
85 return true;
86 }
87
ComputeHash(const string & data) const88 uint128 NullDecrypter::ComputeHash(const string& data) const {
89 uint128 correct_hash = QuicUtils::FNV1a_128_Hash(data.data(), data.length());
90 uint128 mask(GG_UINT64_C(0x0), GG_UINT64_C(0xffffffff));
91 mask <<= 96;
92 correct_hash &= ~mask;
93 return correct_hash;
94 }
95
96 } // namespace net
97