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