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