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