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() {}
15
16bool NullDecrypter::SetKey(StringPiece key) { return key.empty(); }
17
18bool NullDecrypter::SetNoncePrefix(StringPiece nonce_prefix) {
19  return nonce_prefix.empty();
20}
21
22bool 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
47QuicData* 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
71StringPiece NullDecrypter::GetKey() const { return StringPiece(); }
72
73StringPiece NullDecrypter::GetNoncePrefix() const { return StringPiece(); }
74
75bool 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
88uint128 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