15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/crypto/null_decrypter.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_utils.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_data_reader.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece; 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::string; 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NullDecrypter::NullDecrypter() {} 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool NullDecrypter::SetKey(StringPiece key) { return key.empty(); } 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NullDecrypter::SetNoncePrefix(StringPiece nonce_prefix) { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return nonce_prefix.empty(); 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool NullDecrypter::Decrypt(StringPiece /*nonce*/, 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringPiece associated_data, 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringPiece ciphertext, 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned char* output, 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t* output_length) { 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDataReader reader(ciphertext.data(), ciphertext.length()); 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint128 hash; 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!ReadHash(&reader, &hash)) { 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringPiece plaintext = reader.ReadRemainingPayload(); 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(rch): avoid buffer copy here 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) string buffer = associated_data.as_string(); 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) plaintext.AppendToString(&buffer); 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (hash != ComputeHash(buffer)) { 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) memcpy(output, plaintext.data(), plaintext.length()); 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *output_length = plaintext.length(); 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicData* NullDecrypter::DecryptPacket(QuicPacketSequenceNumber /*seq_number*/, 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringPiece associated_data, 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringPiece ciphertext) { 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // It's worth duplicating |Decrypt|, above, in order to save a copy by using 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the shared-data QuicData constructor directly. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicDataReader reader(ciphertext.data(), ciphertext.length()); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint128 hash; 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!ReadHash(&reader, &hash)) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringPiece plaintext = reader.ReadRemainingPayload(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(rch): avoid buffer copy here 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string buffer = associated_data.as_string(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plaintext.AppendToString(&buffer); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (hash != ComputeHash(buffer)) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new QuicData(plaintext.data(), plaintext.length()); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)StringPiece NullDecrypter::GetKey() const { return StringPiece(); } 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 73b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)StringPiece NullDecrypter::GetNoncePrefix() const { return StringPiece(); } 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool NullDecrypter::ReadHash(QuicDataReader* reader, uint128* hash) { 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint64 lo; 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32 hi; 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!reader->ReadUInt64(&lo) || 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) !reader->ReadUInt32(&hi)) { 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *hash = hi; 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *hash <<= 64; 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *hash += lo; 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)uint128 NullDecrypter::ComputeHash(const string& data) const { 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint128 correct_hash = QuicUtils::FNV1a_128_Hash(data.data(), data.length()); 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint128 mask(GG_UINT64_C(0x0), GG_UINT64_C(0xffffffff)); 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) mask <<= 96; 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) correct_hash &= ~mask; 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return correct_hash; 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 97