Home | History | Annotate | Download | only in crypto
      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