1 // Copyright 2013 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_NACL_LOADER_NACL_VALIDATION_QUERY_H_ 6 #define COMPONENTS_NACL_LOADER_NACL_VALIDATION_QUERY_H_ 7 8 #include <stddef.h> 9 10 #include <string> 11 12 #include "base/memory/raw_ptr.h" 13 #include "base/strings/string_piece.h" 14 #include "crypto/hmac.h" 15 16 struct NaClValidationCache; 17 class NaClValidationDB; 18 class NaClValidationQuery; 19 20 class NaClValidationQueryContext { 21 public: 22 NaClValidationQueryContext(NaClValidationDB* db, 23 const std::string& profile_key, 24 const std::string& nacl_version); 25 26 NaClValidationQuery* CreateQuery(); 27 28 private: 29 raw_ptr<NaClValidationDB> db_; 30 31 // A key used by HMAC that is specific to this installation of Chrome. 32 std::string profile_key_; 33 34 // Bytes indicating the "version" of the validator being used. This is used 35 // to implicitly invalidate the cache - changing the version will change the 36 // hashes that are produced. 37 std::string nacl_version_; 38 }; 39 40 class NaClValidationQuery { 41 public: 42 // SHA256 digest size. 43 static const size_t kDigestLength = 32; 44 45 NaClValidationQuery(NaClValidationDB* db, const std::string& profile_key); 46 47 NaClValidationQuery(const NaClValidationQuery&) = delete; 48 NaClValidationQuery& operator=(const NaClValidationQuery&) = delete; 49 50 void AddData(const char* data, size_t length); 51 void AddData(const unsigned char* data, size_t length); 52 void AddData(const base::StringPiece& data); 53 54 int QueryKnownToValidate(); 55 56 void SetKnownToValidate(); 57 58 private: 59 enum QueryState { 60 READY, 61 GET_CALLED, 62 SET_CALLED 63 }; 64 65 // The HMAC interface currently does not support incremental signing. To work 66 // around this, each piece of data is signed and the signature is added to a 67 // buffer. If there is not enough space in the buffer to accommodate new 68 // data, the buffer contents are signed and the new signature replaces the 69 // contents of the buffer. CompressBuffer performs this operation. In 70 // affect, a hash tree is constructed to emulate incremental signing. 71 void CompressBuffer(); 72 73 // Track the state of the query to detect suspicious method calls. 74 QueryState state_; 75 76 crypto::HMAC hasher_; 77 raw_ptr<NaClValidationDB> db_; 78 79 // The size of buffer_ is a somewhat arbitrary choice. It needs to be at 80 // at least kDigestLength * 2, but it can be arbitrarily large. In practice 81 // there are 4 calls to AddData (version, architechture, cpu features, and 82 // code), so 4 times digest length means the buffer will not need to be 83 // compressed as an intermediate step in the expected use cases. 84 char buffer_[kDigestLength * 4]; 85 size_t buffer_length_; 86 }; 87 88 // Create a validation cache interface for use by sel_ldr. 89 struct NaClValidationCache* CreateValidationCache( 90 NaClValidationDB* db, const std::string& profile_key, 91 const std::string& nacl_version); 92 93 #endif // COMPONENTS_NACL_LOADER_NACL_VALIDATION_QUERY_H_ 94